summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig74
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/atomic.h8
-rw-r--r--arch/alpha/include/asm/checksum.h12
-rw-r--r--arch/alpha/include/asm/dma-mapping.h2
-rw-r--r--arch/alpha/include/asm/gpio.h4
-rw-r--r--arch/alpha/include/asm/pci.h8
-rw-r--r--arch/alpha/include/asm/serial.h8
-rw-r--r--arch/alpha/include/uapi/asm/mman.h4
-rw-r--r--arch/alpha/include/uapi/asm/socket.h5
-rw-r--r--arch/alpha/kernel/module.c2
-rw-r--r--arch/alpha/kernel/smp.c2
-rw-r--r--arch/alpha/lib/checksum.c8
-rw-r--r--arch/arc/Kconfig105
-rw-r--r--arch/arc/Makefile8
-rw-r--r--arch/arc/boot/dts/Makefile6
-rw-r--r--arch/arc/boot/dts/axc001.dtsi2
-rw-r--r--arch/arc/boot/dts/axc003.dtsi2
-rw-r--r--arch/arc/boot/dts/axc003_idu.dtsi2
-rw-r--r--arch/arc/boot/dts/axs10x_mb.dtsi1
-rw-r--r--arch/arc/boot/dts/nsim_hs.dts13
-rw-r--r--arch/arc/boot/dts/skeleton.dtsi2
-rw-r--r--arch/arc/boot/dts/vdk_axc003.dtsi2
-rw-r--r--arch/arc/boot/dts/vdk_axc003_idu.dtsi2
-rw-r--r--arch/arc/configs/axs101_defconfig7
-rw-r--r--arch/arc/configs/axs103_defconfig13
-rw-r--r--arch/arc/configs/axs103_smp_defconfig13
-rw-r--r--arch/arc/configs/nsim_700_defconfig5
-rw-r--r--arch/arc/configs/nsim_hs_defconfig5
-rw-r--r--arch/arc/configs/nsim_hs_smp_defconfig8
-rw-r--r--arch/arc/configs/nsimosci_defconfig2
-rw-r--r--arch/arc/configs/nsimosci_hs_defconfig5
-rw-r--r--arch/arc/configs/nsimosci_hs_smp_defconfig14
-rw-r--r--arch/arc/configs/tb10x_defconfig18
-rw-r--r--arch/arc/configs/vdk_hs38_defconfig2
-rw-r--r--arch/arc/configs/vdk_hs38_smp_defconfig4
-rw-r--r--arch/arc/include/asm/arcregs.h41
-rw-r--r--arch/arc/include/asm/atomic.h8
-rw-r--r--arch/arc/include/asm/cache.h4
-rw-r--r--arch/arc/include/asm/cacheflush.h8
-rw-r--r--arch/arc/include/asm/checksum.h4
-rw-r--r--arch/arc/include/asm/dma-mapping.h187
-rw-r--r--arch/arc/include/asm/dma.h5
-rw-r--r--arch/arc/include/asm/entry-compact.h13
-rw-r--r--arch/arc/include/asm/highmem.h61
-rw-r--r--arch/arc/include/asm/hugepage.h78
-rw-r--r--arch/arc/include/asm/io.h9
-rw-r--r--arch/arc/include/asm/irq.h1
-rw-r--r--arch/arc/include/asm/irqflags-arcv2.h21
-rw-r--r--arch/arc/include/asm/irqflags-compact.h18
-rw-r--r--arch/arc/include/asm/kmap_types.h18
-rw-r--r--arch/arc/include/asm/mach_desc.h10
-rw-r--r--arch/arc/include/asm/mcip.h7
-rw-r--r--arch/arc/include/asm/mmu.h7
-rw-r--r--arch/arc/include/asm/page.h9
-rw-r--r--arch/arc/include/asm/pci.h28
-rw-r--r--arch/arc/include/asm/pgalloc.h12
-rw-r--r--arch/arc/include/asm/pgtable.h125
-rw-r--r--arch/arc/include/asm/processor.h11
-rw-r--r--arch/arc/include/asm/setup.h7
-rw-r--r--arch/arc/include/asm/smp.h7
-rw-r--r--arch/arc/include/asm/tlbflush.h5
-rw-r--r--arch/arc/include/asm/unwind.h4
-rw-r--r--arch/arc/include/uapi/asm/page.h11
-rw-r--r--arch/arc/kernel/Makefile1
-rw-r--r--arch/arc/kernel/ctx_sw.c2
-rw-r--r--arch/arc/kernel/ctx_sw_asm.S3
-rw-r--r--arch/arc/kernel/entry-arcv2.S51
-rw-r--r--arch/arc/kernel/entry-compact.S72
-rw-r--r--arch/arc/kernel/entry.S17
-rw-r--r--arch/arc/kernel/head.S49
-rw-r--r--arch/arc/kernel/intc-arcv2.c56
-rw-r--r--arch/arc/kernel/intc-compact.c87
-rw-r--r--arch/arc/kernel/irq.c45
-rw-r--r--arch/arc/kernel/mcip.c116
-rw-r--r--arch/arc/kernel/pcibios.c22
-rw-r--r--arch/arc/kernel/perf_event.c32
-rw-r--r--arch/arc/kernel/process.c9
-rw-r--r--arch/arc/kernel/setup.c108
-rw-r--r--arch/arc/kernel/smp.c71
-rw-r--r--arch/arc/kernel/time.c11
-rw-r--r--arch/arc/kernel/unwind.c98
-rw-r--r--arch/arc/kernel/vmlinux.lds.S2
-rw-r--r--arch/arc/lib/memcpy-archs.S52
-rw-r--r--arch/arc/mm/Makefile1
-rw-r--r--arch/arc/mm/cache.c95
-rw-r--r--arch/arc/mm/dma.c152
-rw-r--r--arch/arc/mm/fault.c13
-rw-r--r--arch/arc/mm/highmem.c140
-rw-r--r--arch/arc/mm/init.c106
-rw-r--r--arch/arc/mm/tlb.c238
-rw-r--r--arch/arc/mm/tlbex.S55
-rw-r--r--arch/arc/plat-axs10x/Kconfig1
-rw-r--r--arch/arc/plat-axs10x/axs10x.c8
-rw-r--r--arch/arc/plat-sim/platform.c5
-rw-r--r--arch/arm/Kconfig246
-rw-r--r--arch/arm/Kconfig.debug476
-rw-r--r--arch/arm/Makefile7
-rw-r--r--arch/arm/boot/Makefile10
-rw-r--r--arch/arm/boot/compressed/.gitignore6
-rw-r--r--arch/arm/boot/compressed/Makefile46
-rw-r--r--arch/arm/boot/compressed/efi-header.S130
-rw-r--r--arch/arm/boot/compressed/head.S54
-rw-r--r--arch/arm/boot/compressed/piggy.S6
-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.c9
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.S7
-rw-r--r--arch/arm/boot/dts/Makefile121
-rw-r--r--arch/arm/boot/dts/am335x-baltos-ir5221.dts186
-rw-r--r--arch/arm/boot/dts/am335x-base0033.dts48
-rw-r--r--arch/arm/boot/dts/am335x-bone-common.dtsi107
-rw-r--r--arch/arm/boot/dts/am335x-boneblack.dts44
-rw-r--r--arch/arm/boot/dts/am335x-bonegreen.dts53
-rw-r--r--arch/arm/boot/dts/am335x-chiliboard.dts20
-rw-r--r--arch/arm/boot/dts/am335x-chilisom.dtsi80
-rw-r--r--arch/arm/boot/dts/am335x-cm-t335.dts396
-rw-r--r--arch/arm/boot/dts/am335x-evm.dts235
-rw-r--r--arch/arm/boot/dts/am335x-evmsk.dts282
-rw-r--r--arch/arm/boot/dts/am335x-igep0033.dtsi40
-rw-r--r--arch/arm/boot/dts/am335x-lxm.dts120
-rw-r--r--arch/arm/boot/dts/am335x-nano.dts140
-rw-r--r--arch/arm/boot/dts/am335x-pepper.dts217
-rw-r--r--arch/arm/boot/dts/am335x-phycore-som.dtsi96
-rw-r--r--arch/arm/boot/dts/am335x-sbc-t335.dts219
-rw-r--r--arch/arm/boot/dts/am335x-shc.dts577
-rw-r--r--arch/arm/boot/dts/am335x-wega.dtsi71
-rw-r--r--arch/arm/boot/dts/am33xx.dtsi97
-rw-r--r--arch/arm/boot/dts/am3517-craneboard.dts2
-rw-r--r--arch/arm/boot/dts/am4372.dtsi97
-rw-r--r--arch/arm/boot/dts/am437x-cm-t43.dts422
-rw-r--r--arch/arm/boot/dts/am437x-gp-evm.dts414
-rw-r--r--arch/arm/boot/dts/am437x-idk-evm.dts130
-rw-r--r--arch/arm/boot/dts/am437x-sbc-t43.dts180
-rw-r--r--arch/arm/boot/dts/am437x-sk-evm.dts302
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts250
-rw-r--r--arch/arm/boot/dts/am43xx-clocks.dtsi8
-rw-r--r--arch/arm/boot/dts/am57xx-beagle-x15.dts303
-rw-r--r--arch/arm/boot/dts/am57xx-cl-som-am57x.dts617
-rw-r--r--arch/arm/boot/dts/am57xx-sbc-am57x.dts179
-rw-r--r--arch/arm/boot/dts/animeo_ip.dts6
-rw-r--r--arch/arm/boot/dts/arm-realview-pb11mp.dts681
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts3
-rw-r--r--arch/arm/boot/dts/armada-370-dlink-dns327l.dts3
-rw-r--r--arch/arm/boot/dts/armada-370-mirabox.dts7
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn102.dts11
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn104.dts11
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts3
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts36
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts133
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi231
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts51
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts37
-rw-r--r--arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi178
-rw-r--r--arch/arm/boot/dts/armada-370-synology-ds213j.dts3
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi37
-rw-r--r--arch/arm/boot/dts/armada-375-db.dts4
-rw-r--r--arch/arm/boot/dts/armada-375.dtsi33
-rw-r--r--arch/arm/boot/dts/armada-385-db-ap.dts22
-rw-r--r--arch/arm/boot/dts/armada-385-linksys.dtsi4
-rw-r--r--arch/arm/boot/dts/armada-388-clearfog.dts462
-rw-r--r--arch/arm/boot/dts/armada-388-db.dts19
-rw-r--r--arch/arm/boot/dts/armada-388-gp.dts44
-rw-r--r--arch/arm/boot/dts/armada-388-rd.dts4
-rw-r--r--arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi128
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi53
-rw-r--r--arch/arm/boot/dts/armada-xp-axpwifiap.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts21
-rw-r--r--arch/arm/boot/dts/armada-xp-gp.dts21
-rw-r--r--arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts77
-rw-r--r--arch/arm/boot/dts/armada-xp-linksys-mamba.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp-matrix.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp-netgear-rn2120.dts90
-rw-r--r--arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts21
-rw-r--r--arch/arm/boot/dts/armada-xp-synology-ds414.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi54
-rw-r--r--arch/arm/boot/dts/at91-foxg20.dts2
-rw-r--r--arch/arm/boot/dts/at91-kizbox.dts13
-rw-r--r--arch/arm/boot/dts/at91-kizbox2.dts6
-rw-r--r--arch/arm/boot/dts/at91-kizboxmini.dts4
-rw-r--r--arch/arm/boot/dts/at91-qil_a9260.dts2
-rw-r--r--arch/arm/boot/dts/at91-sama5d2_xplained.dts265
-rw-r--r--arch/arm/boot/dts/at91-sama5d3_xplained.dts4
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi127
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts170
-rw-r--r--arch/arm/boot/dts/at91-sama5d4_xplained.dts22
-rw-r--r--arch/arm/boot/dts/at91-sama5d4ek.dts50
-rw-r--r--arch/arm/boot/dts/at91-vinco.dts256
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi8
-rw-r--r--arch/arm/boot/dts/at91rm9200ek.dts9
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9261.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9261ek.dts19
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9263ek.dts13
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_common.dtsi13
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts15
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts21
-rw-r--r--arch/arm/boot/dts/at91sam9rl.dtsi2
-rw-r--r--arch/arm/boot/dts/at91sam9rlek.dts13
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9x5cm.dtsi11
-rw-r--r--arch/arm/boot/dts/at91sam9x5ek.dtsi8
-rw-r--r--arch/arm/boot/dts/axp209.dtsi5
-rw-r--r--arch/arm/boot/dts/axp22x.dtsi143
-rw-r--r--arch/arm/boot/dts/bcm-cygnus.dtsi431
-rw-r--r--arch/arm/boot/dts/bcm-nsp.dtsi309
-rw-r--r--arch/arm/boot/dts/bcm11351.dtsi2
-rw-r--r--arch/arm/boot/dts/bcm21664.dtsi2
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-a-plus.dts31
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b-plus.dts1
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts24
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi-b.dts9
-rw-r--r--arch/arm/boot/dts/bcm2835-rpi.dtsi6
-rw-r--r--arch/arm/boot/dts/bcm2835.dtsi180
-rw-r--r--arch/arm/boot/dts/bcm2836-rpi-2-b.dts35
-rw-r--r--arch/arm/boot/dts/bcm2836.dtsi78
-rw-r--r--arch/arm/boot/dts/bcm283x.dtsi212
-rw-r--r--arch/arm/boot/dts/bcm4708-netgear-r6250.dts11
-rw-r--r--arch/arm/boot/dts/bcm4708.dtsi2
-rw-r--r--arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts1
-rw-r--r--arch/arm/boot/dts/bcm4709-netgear-r7000.dts106
-rw-r--r--arch/arm/boot/dts/bcm4709-netgear-r8000.dts30
-rw-r--r--arch/arm/boot/dts/bcm5301x.dtsi92
-rw-r--r--arch/arm/boot/dts/bcm63138.dtsi36
-rw-r--r--arch/arm/boot/dts/bcm7445.dtsi84
-rw-r--r--arch/arm/boot/dts/bcm911360_entphn.dts28
-rw-r--r--arch/arm/boot/dts/bcm911360k.dts9
-rw-r--r--arch/arm/boot/dts/bcm94708.dts56
-rw-r--r--arch/arm/boot/dts/bcm94709.dts56
-rw-r--r--arch/arm/boot/dts/bcm953012k.dts63
-rw-r--r--arch/arm/boot/dts/bcm958300k.dts44
-rw-r--r--arch/arm/boot/dts/bcm958305k.dts40
-rw-r--r--arch/arm/boot/dts/bcm958625k.dts116
-rw-r--r--arch/arm/boot/dts/bcm9hmidc.dtsi42
-rw-r--r--arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts3
-rw-r--r--arch/arm/boot/dts/berlin2.dtsi46
-rw-r--r--arch/arm/boot/dts/berlin2cd-google-chromecast.dts3
-rw-r--r--arch/arm/boot/dts/berlin2cd.dtsi43
-rw-r--r--arch/arm/boot/dts/berlin2q-marvell-dmp.dts41
-rw-r--r--arch/arm/boot/dts/berlin2q.dtsi65
-rw-r--r--arch/arm/boot/dts/compulab-sb-som.dtsi49
-rw-r--r--arch/arm/boot/dts/cx92755.dtsi7
-rw-r--r--arch/arm/boot/dts/cx92755_equinox.dts9
-rw-r--r--arch/arm/boot/dts/da850-enbw-cmc.dts8
-rw-r--r--arch/arm/boot/dts/da850-evm.dts8
-rw-r--r--arch/arm/boot/dts/da850.dtsi58
-rw-r--r--arch/arm/boot/dts/dm8148-evm.dts55
-rw-r--r--arch/arm/boot/dts/dm8148-t410.dts70
-rw-r--r--arch/arm/boot/dts/dm814x-clocks.dtsi109
-rw-r--r--arch/arm/boot/dts/dm814x.dtsi259
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi22
-rw-r--r--arch/arm/boot/dts/dove-cubox.dts8
-rw-r--r--arch/arm/boot/dts/dove.dtsi39
-rw-r--r--arch/arm/boot/dts/dra62x-clocks.dtsi23
-rw-r--r--arch/arm/boot/dts/dra62x-j5eco-evm.dts80
-rw-r--r--arch/arm/boot/dts/dra62x.dtsi23
-rw-r--r--arch/arm/boot/dts/dra7-evm.dts457
-rw-r--r--arch/arm/boot/dts/dra7.dtsi78
-rw-r--r--arch/arm/boot/dts/dra72-evm.dts342
-rw-r--r--arch/arm/boot/dts/dra72x.dtsi21
-rw-r--r--arch/arm/boot/dts/dra74x.dtsi51
-rw-r--r--arch/arm/boot/dts/ea3250.dts41
-rw-r--r--arch/arm/boot/dts/efm32gg-dk3750.dts8
-rw-r--r--arch/arm/boot/dts/efm32gg.dtsi32
-rw-r--r--arch/arm/boot/dts/emev2.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos3250-monk.dts9
-rw-r--r--arch/arm/boot/dts/exynos3250-rinato.dts11
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi18
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi40
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts19
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts7
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts31
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts52
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi14
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi31
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidu3.dts46
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx.dts8
-rw-r--r--arch/arm/boot/dts/exynos4412-origen.dts19
-rw-r--r--arch/arm/boot/dts/exynos4412-smdk4412.dts4
-rw-r--r--arch/arm/boot/dts/exynos4412-tiny4412.dts9
-rw-r--r--arch/arm/boot/dts/exynos4412-trats2.dts144
-rw-r--r--arch/arm/boot/dts/exynos4412.dtsi28
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi5
-rw-r--r--arch/arm/boot/dts/exynos5.dtsi14
-rw-r--r--arch/arm/boot/dts/exynos5250-arndale.dts8
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts16
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-common.dtsi682
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-rev5.dts47
-rw-r--r--arch/arm/boot/dts/exynos5250-snow.dts671
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi13
-rw-r--r--arch/arm/boot/dts/exynos5410.dtsi14
-rw-r--r--arch/arm/boot/dts/exynos5420-arndale-octa.dts3
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts14
-rw-r--r--arch/arm/boot/dts/exynos5420-smdk5420.dts14
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi19
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi61
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi107
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts51
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3.dts51
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu4.dts48
-rw-r--r--arch/arm/boot/dts/exynos5440-ssdk5440.dts5
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts29
-rw-r--r--arch/arm/boot/dts/hi3620-hi4511.dts3
-rw-r--r--arch/arm/boot/dts/hisi-x5hd2-dkb.dts2
-rw-r--r--arch/arm/boot/dts/imx23.dtsi8
-rw-r--r--arch/arm/boot/dts/imx25-pinfunc.h3
-rw-r--r--arch/arm/boot/dts/imx25.dtsi4
-rw-r--r--arch/arm/boot/dts/imx27.dtsi16
-rw-r--r--arch/arm/boot/dts/imx28-cfa10057.dts4
-rw-r--r--arch/arm/boot/dts/imx28-evk.dts2
-rw-r--r--arch/arm/boot/dts/imx28-m28evk.dts2
-rw-r--r--arch/arm/boot/dts/imx28-tx28.dts3
-rw-r--r--arch/arm/boot/dts/imx28.dtsi19
-rw-r--r--arch/arm/boot/dts/imx31.dtsi2
-rw-r--r--arch/arm/boot/dts/imx35.dtsi2
-rw-r--r--arch/arm/boot/dts/imx50-evk.dts2
-rw-r--r--arch/arm/boot/dts/imx51-ts4800.dts302
-rw-r--r--arch/arm/boot/dts/imx53-smd.dts2
-rw-r--r--arch/arm/boot/dts/imx53-tx53-x03x.dts3
-rw-r--r--arch/arm/boot/dts/imx6dl-nit6xlite.dts49
-rw-r--r--arch/arm/boot/dts/imx6dl-nitrogen6x.dts44
-rw-r--r--arch/arm/boot/dts/imx6dl-rex-basic.dts2
-rw-r--r--arch/arm/boot/dts/imx6dl-sabrelite.dts40
-rw-r--r--arch/arm/boot/dts/imx6dl.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-gw5400-a.dts4
-rw-r--r--arch/arm/boot/dts/imx6q-nitrogen6_max.dts53
-rw-r--r--arch/arm/boot/dts/imx6q-nitrogen6x.dts44
-rw-r--r--arch/arm/boot/dts/imx6q-novena.dts785
-rw-r--r--arch/arm/boot/dts/imx6q-rex-pro.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-sabrelite.dts40
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi52
-rw-r--r--arch/arm/boot/dts/imx6qdl-aristainetos.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw51xx.dtsi38
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw52xx.dtsi50
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw53xx.dtsi35
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw54xx.dtsi49
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw551x.dtsi24
-rw-r--r--arch/arm/boot/dts/imx6qdl-gw552x.dtsi24
-rw-r--r--arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi630
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi873
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi189
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi6
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabreauto.dtsi8
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabrelite.dtsi118
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-tx6.dtsi3
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi72
-rw-r--r--arch/arm/boot/dts/imx6sl-evk.dts2
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi30
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-reva.dts4
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dts4
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi21
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk.dts22
-rw-r--r--arch/arm/boot/dts/imx6ul.dtsi47
-rw-r--r--arch/arm/boot/dts/imx7d-cl-som-imx7.dts286
-rw-r--r--arch/arm/boot/dts/imx7d-pinfunc.h122
-rw-r--r--arch/arm/boot/dts/imx7d-sbc-imx7.dts42
-rw-r--r--arch/arm/boot/dts/imx7d-sdb.dts110
-rw-r--r--arch/arm/boot/dts/imx7d.dtsi187
-rw-r--r--arch/arm/boot/dts/k2e-evm.dts2
-rw-r--r--arch/arm/boot/dts/k2e-netcp.dtsi23
-rw-r--r--arch/arm/boot/dts/k2e.dtsi3
-rw-r--r--arch/arm/boot/dts/k2hk-evm.dts2
-rw-r--r--arch/arm/boot/dts/k2hk-netcp.dtsi24
-rw-r--r--arch/arm/boot/dts/k2hk.dtsi3
-rw-r--r--arch/arm/boot/dts/k2l-evm.dts2
-rw-r--r--arch/arm/boot/dts/k2l-netcp.dtsi25
-rw-r--r--arch/arm/boot/dts/k2l.dtsi3
-rw-r--r--arch/arm/boot/dts/keystone.dtsi7
-rw-r--r--arch/arm/boot/dts/kirkwood-ds112.dts2
-rw-r--r--arch/arm/boot/dts/kirkwood-lswvl.dts25
-rw-r--r--arch/arm/boot/dts/kirkwood-lswxl.dts31
-rw-r--r--arch/arm/boot/dts/kirkwood-net5big.dts60
-rw-r--r--arch/arm/boot/dts/kirkwood-netxbig.dtsi80
-rw-r--r--arch/arm/boot/dts/kirkwood-nsa325.dts238
-rw-r--r--arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts179
-rw-r--r--arch/arm/boot/dts/kirkwood-ts219.dtsi2
-rw-r--r--arch/arm/boot/dts/kirkwood.dtsi29
-rw-r--r--arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts155
-rw-r--r--arch/arm/boot/dts/logicpd-torpedo-som.dtsi37
-rw-r--r--arch/arm/boot/dts/lpc18xx.dtsi145
-rw-r--r--arch/arm/boot/dts/lpc32xx.dtsi142
-rw-r--r--arch/arm/boot/dts/lpc4337-ciaa.dts34
-rw-r--r--arch/arm/boot/dts/lpc4350-hitex-eval.dts175
-rw-r--r--arch/arm/boot/dts/lpc4357-ea4357-devkit.dts100
-rw-r--r--arch/arm/boot/dts/lpc4357.dtsi4
-rw-r--r--arch/arm/boot/dts/ls1021a-qds.dts4
-rw-r--r--arch/arm/boot/dts/ls1021a-twr.dts26
-rw-r--r--arch/arm/boot/dts/ls1021a.dtsi77
-rw-r--r--arch/arm/boot/dts/meson8b-mxq.dts67
-rw-r--r--arch/arm/boot/dts/meson8b-odroidc1.dts78
-rw-r--r--arch/arm/boot/dts/meson8b.dtsi192
-rw-r--r--arch/arm/boot/dts/mt2701-evb.dts29
-rw-r--r--arch/arm/boot/dts/mt2701-pinfunc.h735
-rw-r--r--arch/arm/boot/dts/mt2701.dtsi146
-rw-r--r--arch/arm/boot/dts/mt8127.dtsi27
-rw-r--r--arch/arm/boot/dts/mt8135-evbp1.dts23
-rw-r--r--arch/arm/boot/dts/mt8135.dtsi29
-rw-r--r--arch/arm/boot/dts/nspire.dtsi2
-rw-r--r--arch/arm/boot/dts/omap2420-n8x0-common.dtsi6
-rw-r--r--arch/arm/boot/dts/omap3-beagle-xm.dts22
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts68
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000-common.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-evm-37xx.dts54
-rw-r--r--arch/arm/boot/dts/omap3-evm-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-gta04.dtsi12
-rw-r--r--arch/arm/boot/dts/omap3-gta04a5.dts2
-rw-r--r--arch/arm/boot/dts/omap3-igep.dtsi70
-rw-r--r--arch/arm/boot/dts/omap3-igep0020-common.dtsi60
-rw-r--r--arch/arm/boot/dts/omap3-igep0020-rev-f.dts2
-rw-r--r--arch/arm/boot/dts/omap3-igep0020.dts35
-rw-r--r--arch/arm/boot/dts/omap3-igep0030-common.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3-igep0030-rev-g.dts2
-rw-r--r--arch/arm/boot/dts/omap3-igep0030.dts26
-rw-r--r--arch/arm/boot/dts/omap3-ldp.dts62
-rw-r--r--arch/arm/boot/dts/omap3-lilly-a83x.dtsi6
-rw-r--r--arch/arm/boot/dts/omap3-lilly-dbb056.dts4
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts122
-rw-r--r--arch/arm/boot/dts/omap3-n950-n9.dtsi14
-rw-r--r--arch/arm/boot/dts/omap3-overo-alto35-common.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3-overo-base.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-overo-palo35-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-overo-palo43-common.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-pandora-common.dtsi38
-rw-r--r--arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi2
-rw-r--r--arch/arm/boot/dts/omap3-tao3530.dtsi4
-rw-r--r--arch/arm/boot/dts/omap3-zoom3.dts62
-rw-r--r--arch/arm/boot/dts/omap3.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4-duovero-parlor.dts6
-rw-r--r--arch/arm/boot/dts/omap4-panda-a4.dts6
-rw-r--r--arch/arm/boot/dts/omap4-panda-common.dtsi168
-rw-r--r--arch/arm/boot/dts/omap4-panda-es.dts10
-rw-r--r--arch/arm/boot/dts/omap4-sdp-es23plus.dts6
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts116
-rw-r--r--arch/arm/boot/dts/omap4-var-om44customboard.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4-var-som-om44.dtsi2
-rw-r--r--arch/arm/boot/dts/omap4.dtsi10
-rw-r--r--arch/arm/boot/dts/omap4460.dtsi2
-rw-r--r--arch/arm/boot/dts/omap5-board-common.dtsi688
-rw-r--r--arch/arm/boot/dts/omap5-cm-t54.dts6
-rw-r--r--arch/arm/boot/dts/omap5-igep0050.dts54
-rw-r--r--arch/arm/boot/dts/omap5-uevm.dts618
-rw-r--r--arch/arm/boot/dts/omap5.dtsi2
-rw-r--r--arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts39
-rw-r--r--arch/arm/boot/dts/orion5x.dtsi22
-rw-r--r--arch/arm/boot/dts/phy3250.dts41
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts64
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-ifc6410.dts108
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts436
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi209
-rw-r--r--arch/arm/boot/dts/qcom-apq8074-dragonboard.dts2
-rw-r--r--arch/arm/boot/dts/qcom-apq8084-ifc6540.dts3
-rw-r--r--arch/arm/boot/dts/qcom-apq8084-mtp.dts1
-rw-r--r--arch/arm/boot/dts/qcom-apq8084.dtsi109
-rw-r--r--arch/arm/boot/dts/qcom-msm8960.dtsi23
-rw-r--r--arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts382
-rw-r--r--arch/arm/boot/dts/qcom-msm8974.dtsi106
-rw-r--r--arch/arm/boot/dts/qcom-pm8841.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom-pm8941.dtsi45
-rw-r--r--arch/arm/boot/dts/qcom-pma8084.dtsi12
-rw-r--r--arch/arm/boot/dts/r7s72100.dtsi2
-rw-r--r--arch/arm/boot/dts/r8a73a4-ape6evm.dts4
-rw-r--r--arch/arm/boot/dts/r8a7740-armadillo800eva.dts4
-rw-r--r--arch/arm/boot/dts/r8a7740.dtsi15
-rw-r--r--arch/arm/boot/dts/r8a7778-bockw-reference.dts139
-rw-r--r--arch/arm/boot/dts/r8a7778-bockw.dts33
-rw-r--r--arch/arm/boot/dts/r8a7778.dtsi11
-rw-r--r--arch/arm/boot/dts/r8a7779-marzen.dts6
-rw-r--r--arch/arm/boot/dts/r8a7790-lager.dts72
-rw-r--r--arch/arm/boot/dts/r8a7790.dtsi34
-rw-r--r--arch/arm/boot/dts/r8a7791-henninger.dts320
-rw-r--r--arch/arm/boot/dts/r8a7791-koelsch.dts69
-rw-r--r--arch/arm/boot/dts/r8a7791-porter.dts305
-rw-r--r--arch/arm/boot/dts/r8a7791.dtsi67
-rw-r--r--arch/arm/boot/dts/r8a7793-gose.dts77
-rw-r--r--arch/arm/boot/dts/r8a7793.dtsi534
-rw-r--r--arch/arm/boot/dts/r8a7794-alt.dts140
-rw-r--r--arch/arm/boot/dts/r8a7794-silk.dts160
-rw-r--r--arch/arm/boot/dts/r8a7794.dtsi394
-rw-r--r--arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi41
-rw-r--r--arch/arm/boot/dts/rk3036-evb.dts78
-rw-r--r--arch/arm/boot/dts/rk3036-kylin.dts314
-rw-r--r--arch/arm/boot/dts/rk3036.dtsi661
-rw-r--r--arch/arm/boot/dts/rk3066a-bqcurie2.dts2
-rw-r--r--arch/arm/boot/dts/rk3066a-marsboard.dts8
-rw-r--r--arch/arm/boot/dts/rk3066a-rayeager.dts2
-rw-r--r--arch/arm/boot/dts/rk3066a.dtsi19
-rw-r--r--arch/arm/boot/dts/rk3188-radxarock.dts21
-rw-r--r--arch/arm/boot/dts/rk3188.dtsi35
-rw-r--r--arch/arm/boot/dts/rk3228-evb.dts66
-rw-r--r--arch/arm/boot/dts/rk3228.dtsi442
-rw-r--r--arch/arm/boot/dts/rk3288-evb-act8846.dts44
-rw-r--r--arch/arm/boot/dts/rk3288-evb-rk808.dts27
-rw-r--r--arch/arm/boot/dts/rk3288-evb.dtsi37
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dtsi55
-rw-r--r--arch/arm/boot/dts/rk3288-popmetal.dts85
-rw-r--r--arch/arm/boot/dts/rk3288-r89.dts13
-rw-r--r--arch/arm/boot/dts/rk3288-rock2-som.dtsi278
-rw-r--r--arch/arm/boot/dts/rk3288-rock2-square.dts180
-rw-r--r--arch/arm/boot/dts/rk3288-thermal.dtsi14
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-brain.dts139
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-jaq.dts176
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-mickey.dts250
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-minnie.dts16
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi7
-rw-r--r--arch/arm/boot/dts/rk3288-veyron-speedy.dts8
-rw-r--r--arch/arm/boot/dts/rk3288-veyron.dtsi23
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi194
-rw-r--r--arch/arm/boot/dts/rk3xxx.dtsi1
-rw-r--r--arch/arm/boot/dts/s3c2416.dtsi2
-rw-r--r--arch/arm/boot/dts/s5pv210-aquila.dts2
-rw-r--r--arch/arm/boot/dts/s5pv210-goni.dts4
-rw-r--r--arch/arm/boot/dts/sama5d2-pinfunc.h880
-rw-r--r--arch/arm/boot/dts/sama5d2.dtsi199
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi5
-rw-r--r--arch/arm/boot/dts/sama5d35ek.dts2
-rw-r--r--arch/arm/boot/dts/sama5d3_mci2.dtsi6
-rw-r--r--arch/arm/boot/dts/sama5d3xmb.dtsi2
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi79
-rw-r--r--arch/arm/boot/dts/sh73a0-kzm9g.dts4
-rw-r--r--arch/arm/boot/dts/sh73a0.dtsi86
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi156
-rw-r--r--arch/arm/boot/dts/socfpga_arria10.dtsi8
-rw-r--r--arch/arm/boot/dts/socfpga_arria10_socdk.dtsi27
-rw-r--r--arch/arm/boot/dts/socfpga_arria5_socdk.dts1
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts1
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi34
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts94
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socdk.dts1
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sockit.dts1
-rw-r--r--arch/arm/boot/dts/ste-dbx5x0.dtsi33
-rw-r--r--arch/arm/boot/dts/ste-href-stuib.dtsi23
-rw-r--r--arch/arm/boot/dts/ste-href-tvk1281618.dtsi52
-rw-r--r--arch/arm/boot/dts/ste-hrefv60plus.dtsi18
-rw-r--r--arch/arm/boot/dts/ste-nomadik-s8815.dts2
-rw-r--r--arch/arm/boot/dts/ste-nomadik-stn8815.dtsi43
-rw-r--r--arch/arm/boot/dts/ste-snowball.dts7
-rw-r--r--arch/arm/boot/dts/ste-u300.dts10
-rw-r--r--arch/arm/boot/dts/stih407-b2120.dts1
-rw-r--r--arch/arm/boot/dts/stih407-family.dtsi88
-rw-r--r--arch/arm/boot/dts/stih407-pinctrl.dtsi390
-rw-r--r--arch/arm/boot/dts/stih407.dtsi13
-rw-r--r--arch/arm/boot/dts/stih410-b2120.dts25
-rw-r--r--arch/arm/boot/dts/stih410.dtsi23
-rw-r--r--arch/arm/boot/dts/stih418-b2199.dts8
-rw-r--r--arch/arm/boot/dts/stih418-clock.dtsi2
-rw-r--r--arch/arm/boot/dts/stih418.dtsi6
-rw-r--r--arch/arm/boot/dts/stihxxx-b2120.dtsi60
-rw-r--r--arch/arm/boot/dts/stm32f429.dtsi7
-rw-r--r--arch/arm/boot/dts/sun4i-a10-a1000.dts4
-rw-r--r--arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts12
-rw-r--r--arch/arm/boot/dts/sun4i-a10-cubieboard.dts4
-rw-r--r--arch/arm/boot/dts/sun4i-a10-gemei-g9.dts63
-rw-r--r--arch/arm/boot/dts/sun4i-a10-inet1.dts274
-rw-r--r--arch/arm/boot/dts/sun4i-a10-inet97fv2.dts117
-rw-r--r--arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts391
-rw-r--r--arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts15
-rw-r--r--arch/arm/boot/dts/sun4i-a10-marsboard.dts23
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mk802.dts4
-rw-r--r--arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts12
-rw-r--r--arch/arm/boot/dts/sun4i-a10-pcduino.dts58
-rw-r--r--arch/arm/boot/dts/sun4i-a10-pcduino2.dts78
-rw-r--r--arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts260
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi76
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts159
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts14
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts2
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts224
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi35
-rw-r--r--arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts241
-rw-r--r--arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts227
-rw-r--r--arch/arm/boot/dts/sun5i-a13-q8-tablet.dts60
-rw-r--r--arch/arm/boot/dts/sun5i-a13-utoo-p66.dts30
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi10
-rw-r--r--arch/arm/boot/dts/sun5i-q8-common.dtsi180
-rw-r--r--arch/arm/boot/dts/sun5i-r8-chip.dts218
-rw-r--r--arch/arm/boot/dts/sun5i-r8.dtsi59
-rw-r--r--arch/arm/boot/dts/sun5i.dtsi52
-rw-r--r--arch/arm/boot/dts/sun6i-a31-colombus.dts36
-rw-r--r--arch/arm/boot/dts/sun6i-a31-hummingbird.dts132
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi31
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-primo81.dts256
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi140
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-sina31s.dts153
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts194
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts205
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapi.dts78
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubieboard2.dts23
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubietruck.dts4
-rw-r--r--arch/arm/boot/dts/sun7i-a20-icnova-swac.dts169
-rw-r--r--arch/arm/boot/dts/sun7i-a20-mk808c.dts4
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts275
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts12
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts47
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts6
-rw-r--r--arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts33
-rw-r--r--arch/arm/boot/dts/sun7i-a20-orangepi.dts29
-rw-r--r--arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts69
-rw-r--r--arch/arm/boot/dts/sun7i-a20-pcduino3.dts58
-rw-r--r--arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts90
-rw-r--r--arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts238
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi80
-rw-r--r--arch/arm/boot/dts/sun8i-a23-a33.dtsi72
-rw-r--r--arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts145
l---------[-rw-r--r--]arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts55
l---------[-rw-r--r--]arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts137
-rw-r--r--arch/arm/boot/dts/sun8i-a23-q8-tablet.dts65
-rw-r--r--arch/arm/boot/dts/sun8i-a23.dtsi25
l---------[-rw-r--r--]arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts89
l---------[-rw-r--r--]arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts134
-rw-r--r--arch/arm/boot/dts/sun8i-a33-q8-tablet.dts65
-rw-r--r--arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts4
-rw-r--r--arch/arm/boot/dts/sun8i-a33.dtsi45
-rw-r--r--arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts77
-rw-r--r--arch/arm/boot/dts/sun8i-h3.dtsi497
-rw-r--r--arch/arm/boot/dts/sun8i-q8-common.dtsi101
-rw-r--r--arch/arm/boot/dts/sun9i-a80-cubieboard4.dts30
-rw-r--r--arch/arm/boot/dts/sun9i-a80-optimus.dts24
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi161
-rw-r--r--arch/arm/boot/dts/sunxi-q8-common.dtsi83
-rw-r--r--arch/arm/boot/dts/tango4-common.dtsi130
-rw-r--r--arch/arm/boot/dts/tango4-smp8758.dtsi31
-rw-r--r--arch/arm/boot/dts/tango4-vantage-1172.dts37
-rw-r--r--arch/arm/boot/dts/tegra124-nyan.dtsi15
-rw-r--r--arch/arm/boot/dts/tegra124.dtsi20
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi4
-rw-r--r--arch/arm/boot/dts/tegra30-apalis-eval.dts13
-rw-r--r--arch/arm/boot/dts/tegra30-apalis.dtsi214
-rw-r--r--arch/arm/boot/dts/tegra30-colibri-eval-v3.dts9
-rw-r--r--arch/arm/boot/dts/tegra30-colibri.dtsi196
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi10
-rw-r--r--arch/arm/boot/dts/twl4030_omap3.dtsi2
-rw-r--r--arch/arm/boot/dts/twl6030_omap4.dtsi4
-rw-r--r--arch/arm/boot/dts/uniphier-common32.dtsi135
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts8
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-ld4.dtsi255
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts8
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi2
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts8
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-pro4.dtsi279
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-pro5.dtsi252
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts8
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-sld3.dtsi21
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts8
-rw-r--r--arch/arm/boot/dts/uniphier-ph1-sld8.dtsi256
-rw-r--r--arch/arm/boot/dts/uniphier-proxstream2-gentil.dts78
-rw-r--r--arch/arm/boot/dts/uniphier-proxstream2-vodka.dts78
-rw-r--r--arch/arm/boot/dts/uniphier-proxstream2.dtsi262
-rw-r--r--arch/arm/boot/dts/usb_a9260_common.dtsi2
-rw-r--r--arch/arm/boot/dts/usb_a9263.dts2
-rw-r--r--arch/arm/boot/dts/versatile-ab.dts72
-rw-r--r--arch/arm/boot/dts/versatile-pb.dts20
-rw-r--r--arch/arm/boot/dts/vf-colibri.dtsi65
-rw-r--r--arch/arm/boot/dts/vf500-colibri-eval-v3.dts5
-rw-r--r--arch/arm/boot/dts/vf500-colibri.dtsi47
-rw-r--r--arch/arm/boot/dts/vf610-colibri.dtsi5
-rw-r--r--arch/arm/boot/dts/vf610-twr.dts47
-rw-r--r--arch/arm/boot/dts/vf610.dtsi2
-rw-r--r--arch/arm/boot/dts/vf610m4-cosmic.dts90
-rw-r--r--arch/arm/boot/dts/vfxxx.dtsi54
-rw-r--r--arch/arm/boot/dts/wm8505.dtsi4
-rw-r--r--arch/arm/boot/dts/wm8650.dtsi9
-rw-r--r--arch/arm/boot/dts/wm8750.dtsi2
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi13
-rw-r--r--arch/arm/boot/dts/zynq-zc702.dts4
-rw-r--r--arch/arm/common/Kconfig3
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/edma.c1876
-rw-r--r--arch/arm/common/icst.c9
-rw-r--r--arch/arm/common/mcpm_platsmp.c2
-rw-r--r--arch/arm/common/sa1111.c2
-rw-r--r--arch/arm/common/scoop.c12
-rw-r--r--arch/arm/configs/at91_dt_defconfig16
-rw-r--r--arch/arm/configs/bcm2835_defconfig29
-rw-r--r--arch/arm/configs/bockw_defconfig133
-rw-r--r--arch/arm/configs/colibri_pxa270_defconfig1
-rw-r--r--arch/arm/configs/ep93xx_defconfig1
-rw-r--r--arch/arm/configs/exynos_defconfig38
-rw-r--r--arch/arm/configs/hisi_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig7
-rw-r--r--arch/arm/configs/iop13xx_defconfig1
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/keystone_defconfig54
-rw-r--r--arch/arm/configs/lpc18xx_defconfig32
-rw-r--r--arch/arm/configs/lpc32xx_defconfig1
-rw-r--r--arch/arm/configs/multi_v5_defconfig45
-rw-r--r--arch/arm/configs/multi_v7_defconfig148
-rw-r--r--arch/arm/configs/mv78xx0_defconfig4
-rw-r--r--arch/arm/configs/mvebu_v5_defconfig42
-rw-r--r--arch/arm/configs/mvebu_v7_defconfig9
-rw-r--r--arch/arm/configs/netwinder_defconfig1
-rw-r--r--arch/arm/configs/omap2plus_defconfig45
-rw-r--r--arch/arm/configs/orion5x_defconfig6
-rw-r--r--arch/arm/configs/pxa_defconfig783
-rw-r--r--arch/arm/configs/qcom_defconfig22
-rw-r--r--arch/arm/configs/realview-smp_defconfig38
-rw-r--r--arch/arm/configs/realview_defconfig34
-rw-r--r--arch/arm/configs/s3c6400_defconfig2
-rw-r--r--arch/arm/configs/sama5_defconfig20
-rw-r--r--arch/arm/configs/shmobile_defconfig18
-rw-r--r--arch/arm/configs/socfpga_defconfig8
-rw-r--r--arch/arm/configs/stm32_defconfig2
-rw-r--r--arch/arm/configs/sunxi_defconfig17
-rw-r--r--arch/arm/configs/tegra_defconfig10
-rw-r--r--arch/arm/configs/trizeps4_defconfig1
-rw-r--r--arch/arm/configs/versatile_defconfig14
-rw-r--r--arch/arm/configs/zx_defconfig1
-rw-r--r--arch/arm/crypto/aes-ce-glue.c9
-rw-r--r--arch/arm/crypto/aesbs-glue.c6
-rw-r--r--arch/arm/include/asm/Kbuild3
-rw-r--r--arch/arm/include/asm/arch_gicv3.h190
-rw-r--r--arch/arm/include/asm/atomic.h12
-rw-r--r--arch/arm/include/asm/barrier.h35
-rw-r--r--arch/arm/include/asm/bug.h5
-rw-r--r--arch/arm/include/asm/cacheflush.h1
-rw-r--r--arch/arm/include/asm/checksum.h14
-rw-r--r--arch/arm/include/asm/cmpxchg.h12
-rw-r--r--arch/arm/include/asm/cpuidle.h2
-rw-r--r--arch/arm/include/asm/cputype.h22
-rw-r--r--arch/arm/include/asm/div64.h283
-rw-r--r--arch/arm/include/asm/dma-mapping.h7
-rw-r--r--arch/arm/include/asm/efi.h83
-rw-r--r--arch/arm/include/asm/fixmap.h29
-rw-r--r--arch/arm/include/asm/hardirq.h2
-rw-r--r--arch/arm/include/asm/hardware/cache-uniphier.h46
-rw-r--r--arch/arm/include/asm/highmem.h1
-rw-r--r--arch/arm/include/asm/irq.h5
-rw-r--r--arch/arm/include/asm/irqflags.h10
-rw-r--r--arch/arm/include/asm/kvm_arm.h54
-rw-r--r--arch/arm/include/asm/kvm_asm.h43
-rw-r--r--arch/arm/include/asm/kvm_emulate.h32
-rw-r--r--arch/arm/include/asm/kvm_host.h91
-rw-r--r--arch/arm/include/asm/kvm_hyp.h139
-rw-r--r--arch/arm/include/asm/kvm_mmu.h12
-rw-r--r--arch/arm/include/asm/mach/arch.h2
-rw-r--r--arch/arm/include/asm/mach/map.h2
-rw-r--r--arch/arm/include/asm/mach/pci.h6
-rw-r--r--arch/arm/include/asm/memory.h37
-rw-r--r--arch/arm/include/asm/mmu_context.h14
-rw-r--r--arch/arm/include/asm/paravirt.h20
-rw-r--r--arch/arm/include/asm/pci.h4
-rw-r--r--arch/arm/include/asm/pgtable-3level.h10
-rw-r--r--arch/arm/include/asm/pgtable.h2
-rw-r--r--arch/arm/include/asm/psci.h4
-rw-r--r--arch/arm/include/asm/sections.h8
-rw-r--r--arch/arm/include/asm/setup.h6
-rw-r--r--arch/arm/include/asm/smp.h4
-rw-r--r--arch/arm/include/asm/sparsemem.h7
-rw-r--r--arch/arm/include/asm/uaccess.h4
-rw-r--r--arch/arm/include/asm/unistd.h7
-rw-r--r--arch/arm/include/asm/virt.h9
-rw-r--r--arch/arm/include/asm/xen/hypercall.h7
-rw-r--r--arch/arm/include/asm/xen/hypervisor.h10
-rw-r--r--arch/arm/include/asm/xen/interface.h3
-rw-r--r--arch/arm/include/asm/xen/page-coherent.h33
-rw-r--r--arch/arm/include/asm/xen/page.h22
-rw-r--r--arch/arm/include/debug/at91.S18
-rw-r--r--arch/arm/include/debug/dc21285.S (renamed from arch/arm/mach-footbridge/include/mach/debug-macro.S)0
-rw-r--r--arch/arm/include/uapi/asm/unistd.h2
-rw-r--r--arch/arm/kernel/Makefile7
-rw-r--r--arch/arm/kernel/armksyms.c6
-rw-r--r--arch/arm/kernel/asm-offsets.c40
-rw-r--r--arch/arm/kernel/atags.h6
-rw-r--r--arch/arm/kernel/bios32.c15
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/kernel/cpuidle.c2
-rw-r--r--arch/arm/kernel/devtree.c14
-rw-r--r--arch/arm/kernel/efi.c38
-rw-r--r--arch/arm/kernel/entry-armv.S41
-rw-r--r--arch/arm/kernel/entry-v7m.S2
-rw-r--r--arch/arm/kernel/hibernate.c4
-rw-r--r--arch/arm/kernel/hw_breakpoint.c1
-rw-r--r--arch/arm/kernel/hyp-stub.S24
-rw-r--r--arch/arm/kernel/irq.c5
-rw-r--r--arch/arm/kernel/kgdb.c31
-rw-r--r--arch/arm/kernel/machine_kexec.c16
-rw-r--r--arch/arm/kernel/module-plts.c2
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm/kernel/paravirt.c25
-rw-r--r--arch/arm/kernel/perf_event_v7.c321
-rw-r--r--arch/arm/kernel/pj4-cp0.c4
-rw-r--r--arch/arm/kernel/process.c33
-rw-r--r--arch/arm/kernel/psci-call.S31
-rw-r--r--arch/arm/kernel/psci_smp.c6
-rw-r--r--arch/arm/kernel/reboot.c2
-rw-r--r--arch/arm/kernel/setup.c83
-rw-r--r--arch/arm/kernel/smccc-call.S62
-rw-r--r--arch/arm/kernel/smp.c31
-rw-r--r--arch/arm/kernel/smp_twd.c11
-rw-r--r--arch/arm/kernel/swp_emulate.c6
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c73
-rw-r--r--arch/arm/kernel/time.c2
-rw-r--r--arch/arm/kernel/topology.c4
-rw-r--r--arch/arm/kernel/traps.c52
-rw-r--r--arch/arm/kernel/vdso.c2
-rw-r--r--arch/arm/kernel/vmlinux-xip.lds.S316
-rw-r--r--arch/arm/kernel/vmlinux.lds.S66
-rw-r--r--arch/arm/kernel/xscale-cp0.c7
-rw-r--r--arch/arm/kvm/Kconfig2
-rw-r--r--arch/arm/kvm/Makefile1
-rw-r--r--arch/arm/kvm/arm.c347
-rw-r--r--arch/arm/kvm/coproc.c126
-rw-r--r--arch/arm/kvm/coproc.h24
-rw-r--r--arch/arm/kvm/emulate.c106
-rw-r--r--arch/arm/kvm/guest.c13
-rw-r--r--arch/arm/kvm/handle_exit.c10
-rw-r--r--arch/arm/kvm/hyp/Makefile17
-rw-r--r--arch/arm/kvm/hyp/banked-sr.c77
-rw-r--r--arch/arm/kvm/hyp/cp15-sr.c84
-rw-r--r--arch/arm/kvm/hyp/entry.S101
-rw-r--r--arch/arm/kvm/hyp/hyp-entry.S169
-rw-r--r--arch/arm/kvm/hyp/s2-setup.c33
-rw-r--r--arch/arm/kvm/hyp/switch.c232
-rw-r--r--arch/arm/kvm/hyp/tlb.c70
-rw-r--r--arch/arm/kvm/hyp/vfp.S68
-rw-r--r--arch/arm/kvm/init.S8
-rw-r--r--arch/arm/kvm/interrupts.S480
-rw-r--r--arch/arm/kvm/interrupts_head.S648
-rw-r--r--arch/arm/kvm/mmio.c11
-rw-r--r--arch/arm/kvm/mmu.c54
-rw-r--r--arch/arm/kvm/psci.c34
-rw-r--r--arch/arm/kvm/reset.c2
-rw-r--r--arch/arm/kvm/trace.h10
-rw-r--r--arch/arm/lib/clear_user.S4
-rw-r--r--arch/arm/lib/lib1funcs.S8
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c34
-rw-r--r--arch/arm/mach-alpine/Kconfig3
-rw-r--r--arch/arm/mach-alpine/platsmp.c2
-rw-r--r--arch/arm/mach-at91/Kconfig24
-rw-r--r--arch/arm/mach-at91/pm.c7
-rw-r--r--arch/arm/mach-at91/pm_suspend.S2
-rw-r--r--arch/arm/mach-axxia/Kconfig3
-rw-r--r--arch/arm/mach-axxia/platsmp.c2
-rw-r--r--arch/arm/mach-bcm/Kconfig56
-rw-r--r--arch/arm/mach-bcm/Makefile14
-rw-r--r--arch/arm/mach-bcm/bcm63xx_smp.c2
-rw-r--r--arch/arm/mach-bcm/bcm_5301x.c35
-rw-r--r--arch/arm/mach-bcm/bcm_nsp.c25
-rw-r--r--arch/arm/mach-bcm/board_bcm2835.c5
-rw-r--r--arch/arm/mach-bcm/brcmstb.c9
-rw-r--r--arch/arm/mach-bcm/kona_smp.c202
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c2
-rw-r--r--arch/arm/mach-bcm/platsmp.c290
-rw-r--r--arch/arm/mach-berlin/Kconfig3
-rw-r--r--arch/arm/mach-berlin/berlin.c6
-rw-r--r--arch/arm/mach-berlin/platsmp.c40
-rw-r--r--arch/arm/mach-clps711x/board-autcpu12.c2
-rw-r--r--arch/arm/mach-clps711x/board-p720t.c2
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig3
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c71
-rw-r--r--arch/arm/mach-davinci/Kconfig3
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c8
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c6
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c4
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c4
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c6
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c4
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c7
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c2
-rw-r--r--arch/arm/mach-davinci/clock.c18
-rw-r--r--arch/arm/mach-davinci/common.c4
-rw-r--r--arch/arm/mach-davinci/cp_intc.c2
-rw-r--r--arch/arm/mach-davinci/cp_intc.h (renamed from arch/arm/mach-davinci/include/mach/cp_intc.h)0
-rw-r--r--arch/arm/mach-davinci/cpuidle.c4
-rw-r--r--arch/arm/mach-davinci/cpuidle.h (renamed from arch/arm/mach-davinci/include/mach/cpuidle.h)0
-rw-r--r--arch/arm/mach-davinci/da830.c2
-rw-r--r--arch/arm/mach-davinci/da850.c2
-rw-r--r--arch/arm/mach-davinci/da8xx-dt.c2
-rw-r--r--arch/arm/mach-davinci/ddr2.h (renamed from arch/arm/mach-davinci/include/mach/ddr2.h)0
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c126
-rw-r--r--arch/arm/mach-davinci/dm355.c42
-rw-r--r--arch/arm/mach-davinci/dm365.c27
-rw-r--r--arch/arm/mach-davinci/dm644x.c42
-rw-r--r--arch/arm/mach-davinci/dm646x.c46
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-davinci/pm.c2
-rw-r--r--arch/arm/mach-davinci/psc.c2
-rw-r--r--arch/arm/mach-davinci/psc.h (renamed from arch/arm/mach-davinci/include/mach/psc.h)0
-rw-r--r--arch/arm/mach-davinci/sleep.S4
-rw-r--r--arch/arm/mach-davinci/sram.c2
-rw-r--r--arch/arm/mach-davinci/sram.h (renamed from arch/arm/mach-davinci/include/mach/sram.h)0
-rw-r--r--arch/arm/mach-digicolor/Kconfig3
-rw-r--r--arch/arm/mach-dove/cm-a510.c1
-rw-r--r--arch/arm/mach-dove/common.c43
-rw-r--r--arch/arm/mach-dove/dove-db-setup.c1
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h2
-rw-r--r--arch/arm/mach-dove/include/mach/entry-macro.S33
-rw-r--r--arch/arm/mach-dove/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h20
-rw-r--r--arch/arm/mach-dove/irq.c100
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c4
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c4
-rw-r--r--arch/arm/mach-exynos/Kconfig7
-rw-r--r--arch/arm/mach-exynos/common.h2
-rw-r--r--arch/arm/mach-exynos/platsmp.c2
-rw-r--r--arch/arm/mach-exynos/pmu.c51
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h9
-rw-r--r--arch/arm/mach-exynos/suspend.c58
-rw-r--r--arch/arm/mach-footbridge/Kconfig1
-rw-r--r--arch/arm/mach-gemini/board-nas4220b.c1
-rw-r--r--arch/arm/mach-gemini/board-wbd111.c1
-rw-r--r--arch/arm/mach-gemini/board-wbd222.c1
-rw-r--r--arch/arm/mach-gemini/gpio.c4
-rw-r--r--arch/arm/mach-highbank/Kconfig3
-rw-r--r--arch/arm/mach-hisi/Kconfig12
-rw-r--r--arch/arm/mach-hisi/core.h3
-rw-r--r--arch/arm/mach-hisi/platmcpm.c2
-rw-r--r--arch/arm/mach-hisi/platsmp.c6
-rw-r--r--arch/arm/mach-imx/Kconfig7
-rw-r--r--arch/arm/mach-imx/common.h5
-rw-r--r--arch/arm/mach-imx/devices/devices-common.h4
-rw-r--r--arch/arm/mach-imx/gpc.c73
-rw-r--r--arch/arm/mach-imx/iomux-imx31.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6ul.c11
-rw-r--r--arch/arm/mach-imx/mach-imx7d.c80
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c2
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c4
-rw-r--r--arch/arm/mach-imx/mach-qong.c2
-rw-r--r--arch/arm/mach-imx/platsmp.c4
-rw-r--r--arch/arm/mach-imx/pm-imx6.c46
-rw-r--r--arch/arm/mach-imx/suspend-imx6.S3
-rw-r--r--arch/arm/mach-integrator/Kconfig135
-rw-r--r--arch/arm/mach-iop13xx/include/mach/pci.h57
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c2
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c2
-rw-r--r--arch/arm/mach-iop13xx/irq.c2
-rw-r--r--arch/arm/mach-iop13xx/msi.h (renamed from arch/arm/mach-iop13xx/include/mach/msi.h)0
-rw-r--r--arch/arm/mach-iop13xx/pci.c2
-rw-r--r--arch/arm/mach-iop13xx/pci.h58
-rw-r--r--arch/arm/mach-ixp4xx/common.c4
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h12
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h198
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c6
-rw-r--r--arch/arm/mach-keystone/keystone.c5
-rw-r--r--arch/arm/mach-keystone/keystone.h2
-rw-r--r--arch/arm/mach-keystone/platsmp.c2
-rw-r--r--arch/arm/mach-ks8695/board-acs5k.c2
-rw-r--r--arch/arm/mach-ks8695/board-dsm320.c2
-rw-r--r--arch/arm/mach-ks8695/board-micrel.c2
-rw-r--r--arch/arm/mach-ks8695/board-og.c2
-rw-r--r--arch/arm/mach-ks8695/board-sg.c2
-rw-r--r--arch/arm/mach-ks8695/cpu.c2
-rw-r--r--arch/arm/mach-ks8695/devices.c6
-rw-r--r--arch/arm/mach-ks8695/devices.h (renamed from arch/arm/mach-ks8695/include/mach/devices.h)0
-rw-r--r--arch/arm/mach-ks8695/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-ks8695/pci.c4
-rw-r--r--arch/arm/mach-ks8695/regs-hpna.h (renamed from arch/arm/mach-ks8695/include/mach/regs-hpna.h)0
-rw-r--r--arch/arm/mach-ks8695/regs-lan.h (renamed from arch/arm/mach-ks8695/include/mach/regs-lan.h)0
-rw-r--r--arch/arm/mach-ks8695/regs-mem.h (renamed from arch/arm/mach-ks8695/include/mach/regs-mem.h)0
-rw-r--r--arch/arm/mach-ks8695/regs-pci.h (renamed from arch/arm/mach-ks8695/include/mach/regs-pci.h)0
-rw-r--r--arch/arm/mach-ks8695/regs-sys.h (renamed from arch/arm/mach-ks8695/include/mach/regs-sys.h)0
-rw-r--r--arch/arm/mach-ks8695/regs-wan.h (renamed from arch/arm/mach-ks8695/include/mach/regs-wan.h)0
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c13
-rw-r--r--arch/arm/mach-mediatek/Kconfig3
-rw-r--r--arch/arm/mach-mediatek/Makefile3
-rw-r--r--arch/arm/mach-mediatek/mediatek.c28
-rw-r--r--arch/arm/mach-mediatek/platsmp.c141
-rw-r--r--arch/arm/mach-meson/Kconfig8
-rw-r--r--arch/arm/mach-meson/meson.c1
-rw-r--r--arch/arm/mach-mmp/Kconfig34
-rw-r--r--arch/arm/mach-mmp/Makefile1
-rw-r--r--arch/arm/mach-mmp/addr-map.h44
-rw-r--r--arch/arm/mach-mmp/aspenite.c8
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c8
-rw-r--r--arch/arm/mach-mmp/brownstone.c8
-rw-r--r--arch/arm/mach-mmp/clock-mmp2.c6
-rw-r--r--arch/arm/mach-mmp/clock-pxa168.c6
-rw-r--r--arch/arm/mach-mmp/clock-pxa910.c6
-rw-r--r--arch/arm/mach-mmp/clock.c2
-rw-r--r--arch/arm/mach-mmp/clock.h2
-rw-r--r--arch/arm/mach-mmp/common.c4
-rw-r--r--arch/arm/mach-mmp/common.h3
-rw-r--r--arch/arm/mach-mmp/cputype.h (renamed from arch/arm/mach-mmp/include/mach/cputype.h)0
-rw-r--r--arch/arm/mach-mmp/devices.c13
-rw-r--r--arch/arm/mach-mmp/devices.h (renamed from arch/arm/mach-mmp/include/mach/devices.h)0
-rw-r--r--arch/arm/mach-mmp/flint.c8
-rw-r--r--arch/arm/mach-mmp/gplugd.c6
-rw-r--r--arch/arm/mach-mmp/include/mach/addr-map.h46
-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/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/mmp2.h102
-rw-r--r--arch/arm/mach-mmp/include/mach/pm-mmp2.h61
-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-smc.h37
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-timers.h44
-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/irqs.h (renamed from arch/arm/mach-mmp/include/mach/irqs.h)0
-rw-r--r--arch/arm/mach-mmp/jasper.c8
-rw-r--r--arch/arm/mach-mmp/mfp-mmp2.h395
-rw-r--r--arch/arm/mach-mmp/mfp-pxa168.h354
-rw-r--r--arch/arm/mach-mmp/mfp-pxa910.h169
-rw-r--r--arch/arm/mach-mmp/mfp.h (renamed from arch/arm/mach-mmp/include/mach/mfp.h)0
-rw-r--r--arch/arm/mach-mmp/mmp2.c23
-rw-r--r--arch/arm/mach-mmp/mmp2.h103
-rw-r--r--arch/arm/mach-mmp/pm-mmp2.c12
-rw-r--r--arch/arm/mach-mmp/pm-mmp2.h61
-rw-r--r--arch/arm/mach-mmp/pm-pxa910.c12
-rw-r--r--arch/arm/mach-mmp/pm-pxa910.h (renamed from arch/arm/mach-mmp/include/mach/pm-pxa910.h)0
-rw-r--r--arch/arm/mach-mmp/pxa168.c29
-rw-r--r--arch/arm/mach-mmp/pxa168.h138
-rw-r--r--arch/arm/mach-mmp/pxa910.c24
-rw-r--r--arch/arm/mach-mmp/pxa910.h88
-rw-r--r--arch/arm/mach-mmp/regs-apbc.h22
-rw-r--r--arch/arm/mach-mmp/regs-apmu.h31
-rw-r--r--arch/arm/mach-mmp/regs-icu.h69
-rw-r--r--arch/arm/mach-mmp/regs-timers.h42
-rw-r--r--arch/arm/mach-mmp/regs-usb.h (renamed from arch/arm/mach-mmp/include/mach/regs-usb.h)0
-rw-r--r--arch/arm/mach-mmp/tavorevb.c8
-rw-r--r--arch/arm/mach-mmp/teton_bga.c10
-rw-r--r--arch/arm/mach-mmp/teton_bga.h25
-rw-r--r--arch/arm/mach-mmp/time.c11
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c10
-rw-r--r--arch/arm/mach-moxart/Kconfig3
-rw-r--r--arch/arm/mach-mv78xx0/Kconfig15
-rw-r--r--arch/arm/mach-mv78xx0/Makefile2
-rw-r--r--arch/arm/mach-mv78xx0/bridge-regs.h35
-rw-r--r--arch/arm/mach-mv78xx0/buffalo-wxl-setup.c3
-rw-r--r--arch/arm/mach-mv78xx0/common.c4
-rw-r--r--arch/arm/mach-mv78xx0/db78x00-bp-setup.c3
-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.c35
-rw-r--r--arch/arm/mach-mv78xx0/irqs.h92
-rw-r--r--arch/arm/mach-mv78xx0/mpp.c2
-rw-r--r--arch/arm/mach-mv78xx0/mv78xx0.h127
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c2
-rw-r--r--arch/arm/mach-mv78xx0/rd78x00-masa-setup.c3
-rw-r--r--arch/arm/mach-mvebu/Kconfig37
-rw-r--r--arch/arm/mach-mvebu/Makefile1
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h2
-rw-r--r--arch/arm/mach-mvebu/board-v7.c35
-rw-r--r--arch/arm/mach-mvebu/board.h21
-rw-r--r--arch/arm/mach-mvebu/coherency.c60
-rw-r--r--arch/arm/mach-mvebu/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-mvebu/kirkwood.c4
-rw-r--r--arch/arm/mach-mvebu/netxbig.c191
-rw-r--r--arch/arm/mach-mvebu/platsmp-a9.c4
-rw-r--r--arch/arm/mach-mvebu/platsmp.c2
-rw-r--r--arch/arm/mach-mvebu/pmsu.c33
-rw-r--r--arch/arm/mach-netx/fb.c14
-rw-r--r--arch/arm/mach-netx/include/mach/param.h18
-rw-r--r--arch/arm/mach-netx/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-nspire/clcd.c13
-rw-r--r--arch/arm/mach-omap1/Kconfig7
-rw-r--r--arch/arm/mach-omap1/Makefile1
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c4
-rw-r--r--arch/arm/mach-omap1/board-fsample.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c2
-rw-r--r--arch/arm/mach-omap1/board-h3.c2
-rw-r--r--arch/arm/mach-omap1/board-innovator.c2
-rw-r--r--arch/arm/mach-omap1/board-nand.c2
-rw-r--r--arch/arm/mach-omap1/board-osk.c2
-rw-r--r--arch/arm/mach-omap1/board-palmte.c2
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c2
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c2
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c2
-rw-r--r--arch/arm/mach-omap1/board-sx1-mmc.c2
-rw-r--r--arch/arm/mach-omap1/board-sx1.c4
-rw-r--r--arch/arm/mach-omap1/board-sx1.h (renamed from arch/arm/mach-omap1/include/mach/board-sx1.h)0
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c296
-rw-r--r--arch/arm/mach-omap1/camera.h13
-rw-r--r--arch/arm/mach-omap1/devices.c21
-rw-r--r--arch/arm/mach-omap1/flash.c2
-rw-r--r--arch/arm/mach-omap1/flash.h (renamed from arch/arm/mach-omap1/include/mach/flash.h)0
-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/uncompress.h2
-rw-r--r--arch/arm/mach-omap2/Kconfig6
-rw-r--r--arch/arm/mach-omap2/Makefile5
-rw-r--r--arch/arm/mach-omap2/board-generic.c44
-rw-r--r--arch/arm/mach-omap2/board-ldp.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c6
-rw-r--r--arch/arm/mach-omap2/board-rx51.c2
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c122
-rw-r--r--arch/arm/mach-omap2/clock.c4
-rw-r--r--arch/arm/mach-omap2/clockdomains81xx_data.c29
-rw-r--r--arch/arm/mach-omap2/cm81xx.h6
-rw-r--r--arch/arm/mach-omap2/common.h5
-rw-r--r--arch/arm/mach-omap2/devices.c106
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c20
-rw-r--r--arch/arm/mach-omap2/id.c34
-rw-r--r--arch/arm/mach-omap2/io.c3
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c2
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c66
-rw-r--r--arch/arm/mach-omap2/omap-smp.c8
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c65
-rw-r--r--arch/arm/mach-omap2/omap2-restart.c2
-rw-r--r--arch/arm/mach-omap2/omap_device.c23
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c77
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h6
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c20
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c71
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c51
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c84
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c181
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c78
-rw-r--r--arch/arm/mach-omap2/pm34xx.c4
-rw-r--r--arch/arm/mach-omap2/pm44xx.c2
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c12
-rw-r--r--arch/arm/mach-omap2/prm_common.c8
-rw-r--r--arch/arm/mach-omap2/serial.c4
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S61
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S25
-rw-r--r--arch/arm/mach-omap2/soc.h195
-rw-r--r--arch/arm/mach-omap2/sram.c25
-rw-r--r--arch/arm/mach-omap2/sram.h14
-rw-r--r--arch/arm/mach-omap2/sram34xx.S346
-rw-r--r--arch/arm/mach-omap2/timer.c176
-rw-r--r--arch/arm/mach-omap2/vc.c4
-rw-r--r--arch/arm/mach-orion5x/Kconfig21
-rw-r--r--arch/arm/mach-orion5x/Makefile2
-rw-r--r--arch/arm/mach-orion5x/board-d2net.c2
-rw-r--r--arch/arm/mach-orion5x/board-dt.c4
-rw-r--r--arch/arm/mach-orion5x/board-mss2.c4
-rw-r--r--arch/arm/mach-orion5x/board-rd88f5182.c2
-rw-r--r--arch/arm/mach-orion5x/bridge-regs.h35
-rw-r--r--arch/arm/mach-orion5x/common.c20
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c3
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c56
-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.c13
-rw-r--r--arch/arm/mach-orion5x/irqs.h58
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c3
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c3
-rw-r--r--arch/arm/mach-orion5x/mpp.c2
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c3
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c3
-rw-r--r--arch/arm/mach-orion5x/orion5x.h146
-rw-r--r--arch/arm/mach-orion5x/pci.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c3
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c3
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c3
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c3
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c3
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c3
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c3
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c9
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.c51
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c3
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c3
-rw-r--r--arch/arm/mach-picoxcell/Kconfig3
-rw-r--r--arch/arm/mach-prima2/Kconfig3
-rw-r--r--arch/arm/mach-prima2/common.h2
-rw-r--r--arch/arm/mach-prima2/hotplug.c2
-rw-r--r--arch/arm/mach-prima2/platsmp.c2
-rw-r--r--arch/arm/mach-pxa/am200epd.c4
-rw-r--r--arch/arm/mach-pxa/am300epd.c4
-rw-r--r--arch/arm/mach-pxa/balloon3.c8
-rw-r--r--arch/arm/mach-pxa/capc7117.c4
-rw-r--r--arch/arm/mach-pxa/cm-x255.c2
-rw-r--r--arch/arm/mach-pxa/cm-x270.c2
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c13
-rw-r--r--arch/arm/mach-pxa/cm-x300.c13
-rw-r--r--arch/arm/mach-pxa/colibri-evalboard.c6
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270-income.c13
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c4
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c4
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c8
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c4
-rw-r--r--arch/arm/mach-pxa/colibri.h (renamed from arch/arm/mach-pxa/include/mach/colibri.h)0
-rw-r--r--arch/arm/mach-pxa/corgi.c6
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c2
-rw-r--r--arch/arm/mach-pxa/csb726.c4
-rw-r--r--arch/arm/mach-pxa/csb726.h28
-rw-r--r--arch/arm/mach-pxa/devices.c24
-rw-r--r--arch/arm/mach-pxa/em-x270.c8
-rw-r--r--arch/arm/mach-pxa/eseries-irq.h (renamed from arch/arm/mach-pxa/include/mach/eseries-irq.h)0
-rw-r--r--arch/arm/mach-pxa/eseries.c6
-rw-r--r--arch/arm/mach-pxa/ezx.c26
-rw-r--r--arch/arm/mach-pxa/gumstix.c6
-rw-r--r--arch/arm/mach-pxa/gumstix.h92
-rw-r--r--arch/arm/mach-pxa/h5000.c6
-rw-r--r--arch/arm/mach-pxa/h5000.h113
-rw-r--r--arch/arm/mach-pxa/himalaya.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c5
-rw-r--r--arch/arm/mach-pxa/icontrol.c6
-rw-r--r--arch/arm/mach-pxa/idp.c4
-rw-r--r--arch/arm/mach-pxa/idp.h198
-rw-r--r--arch/arm/mach-pxa/include/mach/csb726.h28
-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/idp.h198
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h70
-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-pxa300.h575
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa320.h461
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa930.h498
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h86
-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/pxa25x-udc.h163
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x.h9
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x.h25
-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/pxa930.h7
-rw-r--r--arch/arm/mach-pxa/littleton.c4
-rw-r--r--arch/arm/mach-pxa/littleton.h (renamed from arch/arm/mach-pxa/include/mach/littleton.h)0
-rw-r--r--arch/arm/mach-pxa/lpd270.c13
-rw-r--r--arch/arm/mach-pxa/lpd270.h (renamed from arch/arm/mach-pxa/include/mach/lpd270.h)0
-rw-r--r--arch/arm/mach-pxa/lubbock.c6
-rw-r--r--arch/arm/mach-pxa/magician.c682
-rw-r--r--arch/arm/mach-pxa/mainstone.c21
-rw-r--r--arch/arm/mach-pxa/mfp-pxa25x.h225
-rw-r--r--arch/arm/mach-pxa/mfp-pxa27x.h471
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c2
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.h (renamed from arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h)0
-rw-r--r--arch/arm/mach-pxa/mfp-pxa300.h575
-rw-r--r--arch/arm/mach-pxa/mfp-pxa320.h461
-rw-r--r--arch/arm/mach-pxa/mfp-pxa3xx.c2
-rw-r--r--arch/arm/mach-pxa/mfp-pxa3xx.h (renamed from arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h)0
-rw-r--r--arch/arm/mach-pxa/mfp-pxa930.h498
-rw-r--r--arch/arm/mach-pxa/mioa701.c23
-rw-r--r--arch/arm/mach-pxa/mioa701.h (renamed from arch/arm/mach-pxa/include/mach/mioa701.h)0
-rw-r--r--arch/arm/mach-pxa/mp900.c2
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c4
-rw-r--r--arch/arm/mach-pxa/mxm8x10.h (renamed from arch/arm/mach-pxa/include/mach/mxm8x10.h)0
-rw-r--r--arch/arm/mach-pxa/palm27x.c15
-rw-r--r--arch/arm/mach-pxa/palm27x.h (renamed from arch/arm/mach-pxa/include/mach/palm27x.h)0
-rw-r--r--arch/arm/mach-pxa/palmld.c4
-rw-r--r--arch/arm/mach-pxa/palmt5.c8
-rw-r--r--arch/arm/mach-pxa/palmt5.h86
-rw-r--r--arch/arm/mach-pxa/palmtc.c13
-rw-r--r--arch/arm/mach-pxa/palmte2.c15
-rw-r--r--arch/arm/mach-pxa/palmte2.h (renamed from arch/arm/mach-pxa/include/mach/palmte2.h)0
-rw-r--r--arch/arm/mach-pxa/palmtreo.c12
-rw-r--r--arch/arm/mach-pxa/palmtreo.h (renamed from arch/arm/mach-pxa/include/mach/palmtreo.h)0
-rw-r--r--arch/arm/mach-pxa/palmtx.c8
-rw-r--r--arch/arm/mach-pxa/palmz72.c12
-rw-r--r--arch/arm/mach-pxa/palmz72.h (renamed from arch/arm/mach-pxa/include/mach/palmz72.h)0
-rw-r--r--arch/arm/mach-pxa/pcm027.c4
-rw-r--r--arch/arm/mach-pxa/pcm027.h86
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c17
-rw-r--r--arch/arm/mach-pxa/pcm990_baseboard.h212
-rw-r--r--arch/arm/mach-pxa/pm.c2
-rw-r--r--arch/arm/mach-pxa/pm.h (renamed from arch/arm/mach-pxa/include/mach/pm.h)0
-rw-r--r--arch/arm/mach-pxa/poodle.c4
-rw-r--r--arch/arm/mach-pxa/pxa25x.c4
-rw-r--r--arch/arm/mach-pxa/pxa25x.h9
-rw-r--r--arch/arm/mach-pxa/pxa27x-udc.h (renamed from arch/arm/mach-pxa/include/mach/pxa27x-udc.h)0
-rw-r--r--arch/arm/mach-pxa/pxa27x.c6
-rw-r--r--arch/arm/mach-pxa/pxa27x.h25
-rw-r--r--arch/arm/mach-pxa/pxa2xx.c2
-rw-r--r--arch/arm/mach-pxa/pxa300.c2
-rw-r--r--arch/arm/mach-pxa/pxa300.h7
-rw-r--r--arch/arm/mach-pxa/pxa320.c2
-rw-r--r--arch/arm/mach-pxa/pxa320.h8
-rw-r--r--arch/arm/mach-pxa/pxa3xx-ulpi.c2
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c2
-rw-r--r--arch/arm/mach-pxa/pxa3xx.h (renamed from arch/arm/mach-pxa/include/mach/pxa3xx.h)0
-rw-r--r--arch/arm/mach-pxa/pxa930.c2
-rw-r--r--arch/arm/mach-pxa/pxa930.h7
-rw-r--r--arch/arm/mach-pxa/raumfeld.c72
-rw-r--r--arch/arm/mach-pxa/regs-rtc.h (renamed from arch/arm/mach-pxa/include/mach/regs-rtc.h)0
-rw-r--r--arch/arm/mach-pxa/regs-u2d.h (renamed from arch/arm/mach-pxa/include/mach/regs-u2d.h)0
-rw-r--r--arch/arm/mach-pxa/saar.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c6
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.h (renamed from arch/arm/mach-pxa/include/mach/sharpsl_pm.h)0
-rw-r--r--arch/arm/mach-pxa/spitz.c6
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c4
-rw-r--r--arch/arm/mach-pxa/stargate2.c6
-rw-r--r--arch/arm/mach-pxa/tavorevb.c15
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c2
-rw-r--r--arch/arm/mach-pxa/tosa.c6
-rw-r--r--arch/arm/mach-pxa/tosa_bt.h (renamed from arch/arm/mach-pxa/include/mach/tosa_bt.h)0
-rw-r--r--arch/arm/mach-pxa/trizeps4.c2
-rw-r--r--arch/arm/mach-pxa/udc.h (renamed from arch/arm/mach-pxa/include/mach/udc.h)0
-rw-r--r--arch/arm/mach-pxa/viper.c13
-rw-r--r--arch/arm/mach-pxa/viper.h (renamed from arch/arm/mach-pxa/include/mach/viper.h)0
-rw-r--r--arch/arm/mach-pxa/vpac270.c6
-rw-r--r--arch/arm/mach-pxa/xcep.c2
-rw-r--r--arch/arm/mach-pxa/z2.c21
-rw-r--r--arch/arm/mach-pxa/zeus.c10
-rw-r--r--arch/arm/mach-pxa/zeus.h (renamed from arch/arm/mach-pxa/include/mach/zeus.h)0
-rw-r--r--arch/arm/mach-pxa/zylonite.c13
-rw-r--r--arch/arm/mach-pxa/zylonite.h (renamed from arch/arm/mach-pxa/include/mach/zylonite.h)0
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c4
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c4
-rw-r--r--arch/arm/mach-qcom/Kconfig3
-rw-r--r--arch/arm/mach-qcom/platsmp.c8
-rw-r--r--arch/arm/mach-realview/Kconfig67
-rw-r--r--arch/arm/mach-realview/Makefile6
-rw-r--r--arch/arm/mach-realview/board-eb.h94
-rw-r--r--arch/arm/mach-realview/board-pb1176.h81
-rw-r--r--arch/arm/mach-realview/board-pb11mp.h96
-rw-r--r--arch/arm/mach-realview/board-pba8.h71
-rw-r--r--arch/arm/mach-realview/board-pbx.h106
-rw-r--r--arch/arm/mach-realview/core.c6
-rw-r--r--arch/arm/mach-realview/core.h4
-rw-r--r--arch/arm/mach-realview/hardware.h40
-rw-r--r--arch/arm/mach-realview/hotplug.c2
-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/irqs-eb.h114
-rw-r--r--arch/arm/mach-realview/irqs-pb1176.h77
-rw-r--r--arch/arm/mach-realview/irqs-pb11mp.h97
-rw-r--r--arch/arm/mach-realview/irqs-pba8.h71
-rw-r--r--arch/arm/mach-realview/irqs-pbx.h87
-rw-r--r--arch/arm/mach-realview/platform.h247
-rw-r--r--arch/arm/mach-realview/platsmp-dt.c91
-rw-r--r--arch/arm/mach-realview/platsmp.c10
-rw-r--r--arch/arm/mach-realview/realview-dt.c1
-rw-r--r--arch/arm/mach-realview/realview_eb.c13
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c6
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c12
-rw-r--r--arch/arm/mach-realview/realview_pba8.c14
-rw-r--r--arch/arm/mach-realview/realview_pbx.c14
-rw-r--r--arch/arm/mach-rockchip/Kconfig3
-rw-r--r--arch/arm/mach-rockchip/platsmp.c47
-rw-r--r--arch/arm/mach-rockchip/rockchip.c3
-rw-r--r--arch/arm/mach-rpc/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/pm-core.h14
-rw-r--r--arch/arm/mach-s3c24xx/irq-pm.c11
-rw-r--r--arch/arm/mach-s3c24xx/mach-h1940.c12
-rw-r--r--arch/arm/mach-s3c24xx/mach-rx1950.c8
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c2
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c2
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig31
-rw-r--r--arch/arm/mach-s3c64xx/Makefile24
-rw-r--r--arch/arm/mach-s3c64xx/common.c5
-rw-r--r--arch/arm/mach-s3c64xx/cpuidle.c5
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c47
-rw-r--r--arch/arm/mach-s3c64xx/dev-backlight.c4
-rw-r--r--arch/arm/mach-s3c64xx/dev-uart.c1
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h52
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h3
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h20
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h9
-rw-r--r--arch/arm/mach-s3c64xx/irq-pm.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c3
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c6
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c17
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c11
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c5
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c6
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c29
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c3
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c18
-rw-r--r--arch/arm/mach-s3c64xx/pl080.c4
-rw-r--r--arch/arm/mach-s3c64xx/pm.c4
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c2
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c2
-rw-r--r--arch/arm/mach-s5pv210/Kconfig3
-rw-r--r--arch/arm/mach-sa1100/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-sa1100/simpad.c8
-rw-r--r--arch/arm/mach-shmobile/Kconfig87
-rw-r--r--arch/arm/mach-shmobile/Makefile14
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot12
-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/clock-r8a7778.c342
-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.h6
-rw-r--r--arch/arm/mach-shmobile/console.c27
-rw-r--r--arch/arm/mach-shmobile/headsmp-scu.S6
-rw-r--r--arch/arm/mach-shmobile/headsmp.S28
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h10
-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.c5
-rw-r--r--arch/arm/mach-shmobile/platsmp-scu.c4
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7779.c99
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c39
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.h9
-rw-r--r--arch/arm/mach-shmobile/r8a7778.h78
-rw-r--r--arch/arm/mach-shmobile/r8a7779.h10
-rw-r--r--arch/arm/mach-shmobile/r8a7790.h2
-rw-r--r--arch/arm/mach-shmobile/r8a7791.h2
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c2
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7778.c564
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c2
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7793.c2
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c2
-rw-r--r--arch/arm/mach-shmobile/sh-gpio.h29
-rw-r--r--arch/arm/mach-shmobile/sh73a0.h2
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c2
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c4
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7790.c2
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7791.c2
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c2
-rw-r--r--arch/arm/mach-shmobile/timer.c21
-rw-r--r--arch/arm/mach-socfpga/Kconfig3
-rw-r--r--arch/arm/mach-socfpga/Makefile2
-rw-r--r--arch/arm/mach-socfpga/core.h2
-rw-r--r--arch/arm/mach-socfpga/l2_cache.c41
-rw-r--r--arch/arm/mach-socfpga/ocram.c49
-rw-r--r--arch/arm/mach-socfpga/platsmp.c4
-rw-r--r--arch/arm/mach-socfpga/socfpga.c5
-rw-r--r--arch/arm/mach-spear/Kconfig3
-rw-r--r--arch/arm/mach-spear/generic.h2
-rw-r--r--arch/arm/mach-spear/hotplug.c2
-rw-r--r--arch/arm/mach-spear/platsmp.c2
-rw-r--r--arch/arm/mach-spear/spear13xx.c2
-rw-r--r--arch/arm/mach-sti/Kconfig4
-rw-r--r--arch/arm/mach-sti/platsmp.c2
-rw-r--r--arch/arm/mach-sti/smp.h2
-rw-r--r--arch/arm/mach-sunxi/Kconfig3
-rw-r--r--arch/arm/mach-sunxi/platsmp.c4
-rw-r--r--arch/arm/mach-sunxi/sunxi.c5
-rw-r--r--arch/arm/mach-tango/Kconfig13
-rw-r--r--arch/arm/mach-tango/Makefile5
-rw-r--r--arch/arm/mach-tango/platsmp.c16
-rw-r--r--arch/arm/mach-tango/setup.c17
-rw-r--r--arch/arm/mach-tango/smc.S9
-rw-r--r--arch/arm/mach-tango/smc.h5
-rw-r--r--arch/arm/mach-tegra/Kconfig55
-rw-r--r--arch/arm/mach-tegra/board-paz00.c21
-rw-r--r--arch/arm/mach-tegra/common.h2
-rw-r--r--arch/arm/mach-tegra/hotplug.c2
-rw-r--r--arch/arm/mach-tegra/platsmp.c2
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S3
-rw-r--r--arch/arm/mach-tegra/sleep-tegra30.S3
-rw-r--r--arch/arm/mach-u300/Kconfig4
-rw-r--r--arch/arm/mach-u300/core.c2
-rw-r--r--arch/arm/mach-u300/dummyspichip.c1
-rw-r--r--arch/arm/mach-uniphier/Kconfig1
-rw-r--r--arch/arm/mach-uniphier/Makefile2
-rw-r--r--arch/arm/mach-uniphier/headsmp.S43
-rw-r--r--arch/arm/mach-uniphier/platsmp.c185
-rw-r--r--arch/arm/mach-ux500/Kconfig5
-rw-r--r--arch/arm/mach-ux500/Makefile2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c2
-rw-r--r--arch/arm/mach-ux500/cpu.c1
-rw-r--r--arch/arm/mach-ux500/hotplug.c2
-rw-r--r--arch/arm/mach-ux500/platsmp.c2
-rw-r--r--arch/arm/mach-ux500/setup.h3
-rw-r--r--arch/arm/mach-ux500/timer.c48
-rw-r--r--arch/arm/mach-versatile/Kconfig41
-rw-r--r--arch/arm/mach-versatile/Makefile6
-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.c376
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c91
-rw-r--r--arch/arm/mach-vexpress/Kconfig3
-rw-r--r--arch/arm/mach-vexpress/core.h2
-rw-r--r--arch/arm/mach-vexpress/hotplug.c2
-rw-r--r--arch/arm/mach-vexpress/platsmp.c2
-rw-r--r--arch/arm/mach-w90x900/cpu.c4
-rw-r--r--arch/arm/mach-w90x900/gpio.c13
-rw-r--r--arch/arm/mach-w90x900/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-w90x900/regs-ebi.h (renamed from arch/arm/mach-w90x900/include/mach/regs-ebi.h)0
-rw-r--r--arch/arm/mach-w90x900/regs-gcr.h (renamed from arch/arm/mach-w90x900/include/mach/regs-gcr.h)0
-rw-r--r--arch/arm/mach-w90x900/regs-timer.h (renamed from arch/arm/mach-w90x900/include/mach/regs-timer.h)0
-rw-r--r--arch/arm/mach-w90x900/regs-usb.h (renamed from arch/arm/mach-w90x900/include/mach/regs-usb.h)0
-rw-r--r--arch/arm/mach-w90x900/time.c2
-rw-r--r--arch/arm/mach-zx/Kconfig5
-rw-r--r--arch/arm/mach-zx/platsmp.c2
-rw-r--r--arch/arm/mach-zynq/Kconfig4
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--arch/arm/mach-zynq/common.h2
-rw-r--r--arch/arm/mach-zynq/platsmp.c2
-rw-r--r--arch/arm/mm/Kconfig90
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/alignment.c2
-rw-r--r--arch/arm/mm/cache-l2x0.c33
-rw-r--r--arch/arm/mm/cache-tauros2.c32
-rw-r--r--arch/arm/mm/cache-uniphier.c544
-rw-r--r--arch/arm/mm/context.c38
-rw-r--r--arch/arm/mm/dma-mapping.c270
-rw-r--r--arch/arm/mm/fault.c24
-rw-r--r--arch/arm/mm/fault.h1
-rw-r--r--arch/arm/mm/flush.c17
-rw-r--r--arch/arm/mm/highmem.c10
-rw-r--r--arch/arm/mm/idmap.c4
-rw-r--r--arch/arm/mm/init.c117
-rw-r--r--arch/arm/mm/ioremap.c9
-rw-r--r--arch/arm/mm/mmap.c3
-rw-r--r--arch/arm/mm/mmu.c144
-rw-r--r--arch/arm/mm/pageattr.c3
-rw-r--r--arch/arm/mm/pgd.c2
-rw-r--r--arch/arm/mm/proc-mohawk.S2
-rw-r--r--arch/arm/mm/proc-v7.S27
-rw-r--r--arch/arm/mm/proc-v7m.S14
-rw-r--r--arch/arm/net/bpf_jit_32.c61
-rw-r--r--arch/arm/net/bpf_jit_32.h5
-rw-r--r--arch/arm/plat-omap/dmtimer.c42
-rw-r--r--arch/arm/plat-orion/common.c21
-rw-r--r--arch/arm/plat-orion/gpio.c24
-rw-r--r--arch/arm/plat-orion/include/plat/common.h2
-rw-r--r--arch/arm/plat-orion/irq.c1
-rw-r--r--arch/arm/plat-orion/mpp.c1
-rw-r--r--arch/arm/plat-orion/time.c13
-rw-r--r--arch/arm/plat-pxa/Makefile3
-rw-r--r--arch/arm/plat-pxa/ssp.c1
-rw-r--r--arch/arm/plat-samsung/Kconfig5
-rw-r--r--arch/arm/plat-samsung/Makefile5
-rw-r--r--arch/arm/plat-samsung/devs.c72
-rw-r--r--arch/arm/plat-samsung/gpio-samsung.c1328
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h8
-rw-r--r--arch/arm/plat-samsung/init.c5
-rw-r--r--arch/arm/plat-samsung/pm-check.c4
-rw-r--r--arch/arm/plat-samsung/pm.c4
-rw-r--r--arch/arm/vdso/vdso.S3
-rw-r--r--arch/arm/vdso/vdsomunge.c2
-rw-r--r--arch/arm/xen/enlighten.c115
-rw-r--r--arch/arm/xen/hypercall.S1
-rw-r--r--arch/arm/xen/mm.c41
-rw-r--r--arch/arm/xen/p2m.c6
-rw-r--r--arch/arm64/Kconfig292
-rw-r--r--arch/arm64/Kconfig.debug26
-rw-r--r--arch/arm64/Kconfig.platforms49
-rw-r--r--arch/arm64/Makefile21
-rw-r--r--arch/arm64/boot/Makefile4
-rw-r--r--arch/arm64/boot/dts/Makefile10
-rw-r--r--arch/arm64/boot/dts/altera/Makefile5
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi358
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts39
-rw-r--r--arch/arm64/boot/dts/amd/amd-overdrive.dts1
-rw-r--r--arch/arm64/boot/dts/apm/Makefile1
-rw-r--r--arch/arm64/boot/dts/apm/apm-merlin.dts84
-rw-r--r--arch/arm64/boot/dts/apm/apm-mustang.dts16
-rw-r--r--arch/arm64/boot/dts/apm/apm-shadowcat.dtsi666
-rw-r--r--arch/arm64/boot/dts/apm/apm-storm.dtsi183
-rw-r--r--arch/arm64/boot/dts/arm/juno-base.dtsi60
-rw-r--r--arch/arm64/boot/dts/arm/juno-motherboard.dtsi15
-rw-r--r--arch/arm64/boot/dts/arm/juno-r1.dts98
-rw-r--r--arch/arm64/boot/dts/arm/juno.dts78
-rw-r--r--arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts2
l---------arch/arm64/boot/dts/arm/vexpress-v2m-rs1.dtsi1
-rw-r--r--arch/arm64/boot/dts/broadcom/ns2-svk.dts26
-rw-r--r--arch/arm64/boot/dts/broadcom/ns2.dtsi200
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-espresso.dts282
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi103
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi14
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile5
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts116
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi527
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts204
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts166
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts70
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi588
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts65
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi163
-rw-r--r--arch/arm64/boot/dts/hisilicon/Makefile2
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts14
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220.dtsi44
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05-d02.dts36
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05.dtsi276
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi190
-rw-r--r--arch/arm64/boot/dts/marvell/Makefile1
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct-stb.dts66
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct.dtsi183
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-evb.dts47
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173.dtsi139
-rw-r--r--arch/arm64/boot/dts/nvidia/Makefile7
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132-norrin.dts1132
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132.dtsi990
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi45
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts9
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts9
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi50
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2571.dts1302
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi1272
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi1270
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210.dtsi805
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi48
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-mtp.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-pins.dtsi83
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi154
-rw-r--r--arch/arm64/boot/dts/qcom/pm8916.dtsi6
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts251
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795.dtsi779
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts176
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi281
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-r88.dts6
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi112
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368.dtsi105
-rw-r--r--arch/arm64/boot/dts/socionext/Makefile4
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts95
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi280
l---------arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi1
l---------arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi1
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp.dtsi2
-rw-r--r--arch/arm64/boot/install.sh14
-rw-r--r--arch/arm64/configs/defconfig77
-rw-r--r--arch/arm64/crypto/aes-ce-cipher.c2
-rw-r--r--arch/arm64/crypto/aes-glue.c9
-rw-r--r--arch/arm64/include/asm/Kbuild3
-rw-r--r--arch/arm64/include/asm/acpi.h25
-rw-r--r--arch/arm64/include/asm/alternative.h64
-rw-r--r--arch/arm64/include/asm/arch_gicv3.h172
-rw-r--r--arch/arm64/include/asm/assembler.h48
-rw-r--r--arch/arm64/include/asm/atomic.h65
-rw-r--r--arch/arm64/include/asm/atomic_ll_sc.h100
-rw-r--r--arch/arm64/include/asm/atomic_lse.h225
-rw-r--r--arch/arm64/include/asm/barrier.h35
-rw-r--r--arch/arm64/include/asm/boot.h6
-rw-r--r--arch/arm64/include/asm/brk-imm.h25
-rw-r--r--arch/arm64/include/asm/bug.h2
-rw-r--r--arch/arm64/include/asm/cache.h2
-rw-r--r--arch/arm64/include/asm/cacheflush.h12
-rw-r--r--arch/arm64/include/asm/cachetype.h4
-rw-r--r--arch/arm64/include/asm/cmpxchg.h280
-rw-r--r--arch/arm64/include/asm/compat.h3
-rw-r--r--arch/arm64/include/asm/cpu.h5
-rw-r--r--arch/arm64/include/asm/cpufeature.h123
-rw-r--r--arch/arm64/include/asm/cputype.h61
-rw-r--r--arch/arm64/include/asm/dcc.h55
-rw-r--r--arch/arm64/include/asm/debug-monitors.h14
-rw-r--r--arch/arm64/include/asm/dma-mapping.h30
-rw-r--r--arch/arm64/include/asm/efi.h9
-rw-r--r--arch/arm64/include/asm/elf.h24
-rw-r--r--arch/arm64/include/asm/fixmap.h18
-rw-r--r--arch/arm64/include/asm/ftrace.h4
-rw-r--r--arch/arm64/include/asm/futex.h14
-rw-r--r--arch/arm64/include/asm/hardirq.h2
-rw-r--r--arch/arm64/include/asm/hugetlb.h44
-rw-r--r--arch/arm64/include/asm/hw_breakpoint.h29
-rw-r--r--arch/arm64/include/asm/hwcap.h8
-rw-r--r--arch/arm64/include/asm/irq.h56
-rw-r--r--arch/arm64/include/asm/kasan.h41
-rw-r--r--arch/arm64/include/asm/kernel-pgtable.h95
-rw-r--r--arch/arm64/include/asm/kvm_arm.h30
-rw-r--r--arch/arm64/include/asm/kvm_asm.h84
-rw-r--r--arch/arm64/include/asm/kvm_emulate.h35
-rw-r--r--arch/arm64/include/asm/kvm_host.h132
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h181
-rw-r--r--arch/arm64/include/asm/kvm_mmio.h1
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h24
-rw-r--r--arch/arm64/include/asm/kvm_perf_event.h68
-rw-r--r--arch/arm64/include/asm/lse.h1
-rw-r--r--arch/arm64/include/asm/memory.h68
-rw-r--r--arch/arm64/include/asm/mmu.h15
-rw-r--r--arch/arm64/include/asm/mmu_context.h151
-rw-r--r--arch/arm64/include/asm/module.h17
-rw-r--r--arch/arm64/include/asm/page.h28
-rw-r--r--arch/arm64/include/asm/paravirt.h20
-rw-r--r--arch/arm64/include/asm/pci.h2
-rw-r--r--arch/arm64/include/asm/pgalloc.h27
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h64
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h92
-rw-r--r--arch/arm64/include/asm/pgtable.h243
-rw-r--r--arch/arm64/include/asm/pmu.h83
-rw-r--r--arch/arm64/include/asm/processor.h11
-rw-r--r--arch/arm64/include/asm/ptrace.h49
-rw-r--r--arch/arm64/include/asm/shmparam.h2
-rw-r--r--arch/arm64/include/asm/smp.h46
-rw-r--r--arch/arm64/include/asm/spinlock.h23
-rw-r--r--arch/arm64/include/asm/stacktrace.h9
-rw-r--r--arch/arm64/include/asm/string.h16
-rw-r--r--arch/arm64/include/asm/sysreg.h201
-rw-r--r--arch/arm64/include/asm/thread_info.h15
-rw-r--r--arch/arm64/include/asm/tlb.h26
-rw-r--r--arch/arm64/include/asm/tlbflush.h18
-rw-r--r--arch/arm64/include/asm/uaccess.h82
-rw-r--r--arch/arm64/include/asm/virt.h10
-rw-r--r--arch/arm64/include/asm/word-at-a-time.h7
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h2
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h8
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h1
-rw-r--r--arch/arm64/kernel/Makefile19
-rw-r--r--arch/arm64/kernel/acpi.c44
-rw-r--r--arch/arm64/kernel/acpi_parking_protocol.c141
-rw-r--r--arch/arm64/kernel/alternative.c6
-rw-r--r--arch/arm64/kernel/arm64ksyms.c8
-rw-r--r--arch/arm64/kernel/armv8_deprecated.c13
-rw-r--r--arch/arm64/kernel/asm-offsets.c50
-rw-r--r--arch/arm64/kernel/cpu_errata.c45
-rw-r--r--arch/arm64/kernel/cpu_ops.c27
-rw-r--r--arch/arm64/kernel/cpufeature.c953
-rw-r--r--arch/arm64/kernel/cpuinfo.c264
-rw-r--r--arch/arm64/kernel/debug-monitors.c79
-rw-r--r--arch/arm64/kernel/efi-entry.S13
-rw-r--r--arch/arm64/kernel/efi-stub.c78
-rw-r--r--arch/arm64/kernel/efi.c339
-rw-r--r--arch/arm64/kernel/entry.S71
-rw-r--r--arch/arm64/kernel/fpsimd.c20
-rw-r--r--arch/arm64/kernel/ftrace.c27
-rw-r--r--arch/arm64/kernel/head.S288
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c19
-rw-r--r--arch/arm64/kernel/image.h88
-rw-r--r--arch/arm64/kernel/insn.c165
-rw-r--r--arch/arm64/kernel/irq.c65
-rw-r--r--arch/arm64/kernel/kaslr.c177
-rw-r--r--arch/arm64/kernel/kgdb.c4
-rw-r--r--arch/arm64/kernel/module-plts.c201
-rw-r--r--arch/arm64/kernel/module.c110
-rw-r--r--arch/arm64/kernel/module.lds3
-rw-r--r--arch/arm64/kernel/paravirt.c25
-rw-r--r--arch/arm64/kernel/pci.c2
-rw-r--r--arch/arm64/kernel/perf_callchain.c5
-rw-r--r--arch/arm64/kernel/perf_event.c1307
-rw-r--r--arch/arm64/kernel/process.c24
-rw-r--r--arch/arm64/kernel/psci-call.S28
-rw-r--r--arch/arm64/kernel/psci.c113
-rw-r--r--arch/arm64/kernel/ptrace.c86
-rw-r--r--arch/arm64/kernel/return_address.c5
-rw-r--r--arch/arm64/kernel/setup.c267
-rw-r--r--arch/arm64/kernel/signal.c4
-rw-r--r--arch/arm64/kernel/signal32.c4
-rw-r--r--arch/arm64/kernel/sleep.S7
-rw-r--r--arch/arm64/kernel/smccc-call.S43
-rw-r--r--arch/arm64/kernel/smp.c123
-rw-r--r--arch/arm64/kernel/stacktrace.c78
-rw-r--r--arch/arm64/kernel/suspend.c32
-rw-r--r--arch/arm64/kernel/time.c13
-rw-r--r--arch/arm64/kernel/traps.c72
-rw-r--r--arch/arm64/kernel/vdso/Makefile3
-rw-r--r--arch/arm64/kernel/vdso/vdso.S3
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S48
-rw-r--r--arch/arm64/kvm/Kconfig16
-rw-r--r--arch/arm64/kvm/Makefile4
-rw-r--r--arch/arm64/kvm/guest.c63
-rw-r--r--arch/arm64/kvm/handle_exit.c6
-rw-r--r--arch/arm64/kvm/hyp-init.S10
-rw-r--r--arch/arm64/kvm/hyp.S1072
-rw-r--r--arch/arm64/kvm/hyp/Makefile18
-rw-r--r--arch/arm64/kvm/hyp/debug-sr.c139
-rw-r--r--arch/arm64/kvm/hyp/entry.S166
-rw-r--r--arch/arm64/kvm/hyp/fpsimd.S33
-rw-r--r--arch/arm64/kvm/hyp/hyp-entry.S175
-rw-r--r--arch/arm64/kvm/hyp/s2-setup.c43
-rw-r--r--arch/arm64/kvm/hyp/switch.c345
-rw-r--r--arch/arm64/kvm/hyp/sysreg-sr.c185
-rw-r--r--arch/arm64/kvm/hyp/tlb.c80
-rw-r--r--arch/arm64/kvm/hyp/vgic-v3-sr.c337
-rw-r--r--arch/arm64/kvm/inject_fault.c40
-rw-r--r--arch/arm64/kvm/reset.c9
-rw-r--r--arch/arm64/kvm/sys_regs.c794
-rw-r--r--arch/arm64/kvm/sys_regs.h8
-rw-r--r--arch/arm64/kvm/sys_regs_generic_v8.c4
-rw-r--r--arch/arm64/kvm/vgic-v2-switch.S134
-rw-r--r--arch/arm64/kvm/vgic-v3-switch.S269
-rw-r--r--arch/arm64/lib/Makefile13
-rw-r--r--arch/arm64/lib/clear_user.S12
-rw-r--r--arch/arm64/lib/copy_from_user.S82
-rw-r--r--arch/arm64/lib/copy_in_user.S71
-rw-r--r--arch/arm64/lib/copy_page.S63
-rw-r--r--arch/arm64/lib/copy_template.S193
-rw-r--r--arch/arm64/lib/copy_to_user.S71
-rw-r--r--arch/arm64/lib/memchr.S2
-rw-r--r--arch/arm64/lib/memcmp.S4
-rw-r--r--arch/arm64/lib/memcpy.S184
-rw-r--r--arch/arm64/lib/memmove.S9
-rw-r--r--arch/arm64/lib/memset.S5
-rw-r--r--arch/arm64/lib/strcmp.S2
-rw-r--r--arch/arm64/lib/strlen.S2
-rw-r--r--arch/arm64/lib/strncmp.S2
-rw-r--r--arch/arm64/lib/strnlen.S2
-rw-r--r--arch/arm64/mm/Makefile3
-rw-r--r--arch/arm64/mm/cache.S38
-rw-r--r--arch/arm64/mm/context.c270
-rw-r--r--arch/arm64/mm/copypage.c3
-rw-r--r--arch/arm64/mm/dma-mapping.c486
-rw-r--r--arch/arm64/mm/dump.c39
-rw-r--r--arch/arm64/mm/extable.c2
-rw-r--r--arch/arm64/mm/fault.c75
-rw-r--r--arch/arm64/mm/flush.c49
-rw-r--r--arch/arm64/mm/hugetlbpage.c260
-rw-r--r--arch/arm64/mm/init.c162
-rw-r--r--arch/arm64/mm/kasan_init.c210
-rw-r--r--arch/arm64/mm/mmap.c8
-rw-r--r--arch/arm64/mm/mmu.c559
-rw-r--r--arch/arm64/mm/pageattr.c72
-rw-r--r--arch/arm64/mm/pgd.c14
-rw-r--r--arch/arm64/mm/proc-macros.S34
-rw-r--r--arch/arm64/mm/proc.S56
-rw-r--r--arch/arm64/net/bpf_jit.h3
-rw-r--r--arch/arm64/net/bpf_jit_comp.c165
-rw-r--r--arch/arm64/xen/hypercall.S1
-rw-r--r--arch/avr32/boards/atngw100/mrmt.c1
-rw-r--r--arch/avr32/boards/merisc/setup.c1
-rw-r--r--arch/avr32/include/asm/atomic.h4
-rw-r--r--arch/avr32/include/asm/checksum.h10
-rw-r--r--arch/avr32/include/asm/cmpxchg.h2
-rw-r--r--arch/avr32/include/asm/dma-mapping.h342
-rw-r--r--arch/avr32/include/asm/page.h8
-rw-r--r--arch/avr32/include/asm/pci.h2
-rw-r--r--arch/avr32/include/uapi/asm/socket.h5
-rw-r--r--arch/avr32/include/uapi/asm/unistd.h5
-rw-r--r--arch/avr32/kernel/module.c12
-rw-r--r--arch/avr32/kernel/setup.c6
-rw-r--r--arch/avr32/kernel/syscall-stubs.S9
-rw-r--r--arch/avr32/kernel/syscall_table.S5
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c40
-rw-r--r--arch/avr32/mach-at32ap/pio.c16
-rw-r--r--arch/avr32/mm/dma-coherent.c115
-rw-r--r--arch/blackfin/Kconfig2
-rw-r--r--arch/blackfin/include/asm/barrier.h4
-rw-r--r--arch/blackfin/include/asm/checksum.h4
-rw-r--r--arch/blackfin/include/asm/cmpxchg.h1
-rw-r--r--arch/blackfin/include/asm/dma-mapping.h127
-rw-r--r--arch/blackfin/include/asm/pci.h1
-rw-r--r--arch/blackfin/include/asm/pgtable.h2
-rw-r--r--arch/blackfin/include/asm/uaccess.h6
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c6
-rw-r--r--arch/blackfin/kernel/debug-mmrs.c2
-rw-r--r--arch/blackfin/kernel/dma-mapping.c52
-rw-r--r--arch/blackfin/kernel/perf_event.c2
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c2
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c2
-rw-r--r--arch/blackfin/mach-bf527/boards/tll6527m.c2
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c4
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf538/ext-gpio.c8
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c2
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/acvilon.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c2
-rw-r--r--arch/blackfin/mach-bf609/boards/ezkit.c8
-rw-r--r--arch/blackfin/mach-common/ints-priority.c2
-rw-r--r--arch/blackfin/mach-common/pm.c2
-rw-r--r--arch/blackfin/mach-common/smp.c2
-rw-r--r--arch/c6x/Kconfig2
-rw-r--r--arch/c6x/include/asm/Kbuild1
-rw-r--r--arch/c6x/include/asm/checksum.h4
-rw-r--r--arch/c6x/include/asm/clkdev.h22
-rw-r--r--arch/c6x/include/asm/cmpxchg.h2
-rw-r--r--arch/c6x/include/asm/dma-mapping.h98
-rw-r--r--arch/c6x/kernel/dma.c95
-rw-r--r--arch/c6x/kernel/setup.c2
-rw-r--r--arch/c6x/mm/dma-coherent.c10
-rw-r--r--arch/c6x/platforms/megamod-pic.c2
-rw-r--r--arch/cris/Kconfig1
-rw-r--r--arch/cris/arch-v10/kernel/debugport.c22
-rw-r--r--arch/cris/arch-v10/kernel/head.S112
-rw-r--r--arch/cris/arch-v10/kernel/kgdb.c89
-rw-r--r--arch/cris/arch-v10/mm/init.c14
-rw-r--r--arch/cris/arch-v32/Kconfig89
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig167
-rw-r--r--arch/cris/arch-v32/drivers/Makefile1
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c40
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c751
-rw-r--r--arch/cris/arch-v32/drivers/i2c.h16
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/Makefile1
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/gpio.c999
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/nandflash.c8
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/Makefile1
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c978
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/nandflash.c8
-rw-r--r--arch/cris/arch-v32/drivers/pci/dma.c54
-rw-r--r--arch/cris/arch-v32/kernel/crisksyms.c3
-rw-r--r--arch/cris/arch-v32/kernel/debugport.c2
-rw-r--r--arch/cris/arch-v32/kernel/head.S10
-rw-r--r--arch/cris/arch-v32/kernel/irq.c6
-rw-r--r--arch/cris/arch-v32/kernel/kgdb.c96
-rw-r--r--arch/cris/arch-v32/kernel/setup.c8
-rw-r--r--arch/cris/arch-v32/mach-a3/Makefile2
-rw-r--r--arch/cris/arch-v32/mach-a3/io.c149
-rw-r--r--arch/cris/arch-v32/mach-fs/Kconfig19
-rw-r--r--arch/cris/arch-v32/mach-fs/Makefile2
-rw-r--r--arch/cris/arch-v32/mach-fs/io.c191
-rw-r--r--arch/cris/boot/dts/artpec3.dtsi46
-rw-r--r--arch/cris/boot/dts/dev88.dts49
-rw-r--r--arch/cris/boot/dts/etraxfs.dtsi8
l---------arch/cris/boot/dts/include/dt-bindings1
-rw-r--r--arch/cris/boot/dts/p1343.dts76
-rw-r--r--arch/cris/boot/rescue/head_v10.S3
-rw-r--r--arch/cris/include/arch-v10/arch/checksum.h4
-rw-r--r--arch/cris/include/arch-v32/arch/checksum.h2
-rw-r--r--arch/cris/include/arch-v32/arch/io.h140
-rw-r--r--arch/cris/include/arch-v32/arch/irq.h2
-rw-r--r--arch/cris/include/asm/checksum.h5
-rw-r--r--arch/cris/include/asm/dma-mapping.h161
-rw-r--r--arch/cris/include/asm/eshlibld.h3
-rw-r--r--arch/cris/include/asm/io.h2
-rw-r--r--arch/cris/include/asm/pci.h3
-rw-r--r--arch/cris/include/uapi/asm/etraxgpio.h157
-rw-r--r--arch/cris/kernel/crisksyms.c2
-rw-r--r--arch/cris/kernel/time.c25
-rw-r--r--arch/cris/kernel/vmlinux.lds.S1
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/frv/include/asm/atomic.h4
-rw-r--r--arch/frv/include/asm/checksum.h10
-rw-r--r--arch/frv/include/asm/cmpxchg.h2
-rw-r--r--arch/frv/include/asm/dma-mapping.h132
-rw-r--r--arch/frv/include/asm/highmem.h2
-rw-r--r--arch/frv/include/asm/io.h17
-rw-r--r--arch/frv/include/asm/page.h2
-rw-r--r--arch/frv/include/asm/pci.h7
-rw-r--r--arch/frv/include/asm/serial.h2
-rw-r--r--arch/frv/include/uapi/asm/socket.h5
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c72
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c74
-rw-r--r--arch/frv/mm/highmem.c5
-rw-r--r--arch/h8300/Kconfig6
-rw-r--r--arch/h8300/Makefile2
-rw-r--r--arch/h8300/boot/compressed/Makefile16
-rw-r--r--arch/h8300/boot/compressed/head.S4
-rw-r--r--arch/h8300/boot/compressed/misc.c13
-rw-r--r--arch/h8300/boot/compressed/vmlinux.lds6
-rw-r--r--arch/h8300/boot/dts/Makefile3
-rw-r--r--arch/h8300/boot/dts/edosk2674.dts6
-rw-r--r--arch/h8300/include/asm/atomic.h4
-rw-r--r--arch/h8300/include/asm/dma-mapping.h2
-rw-r--r--arch/h8300/include/asm/io.h47
-rw-r--r--arch/h8300/include/asm/kgdb.h45
-rw-r--r--arch/h8300/include/asm/thread_info.h14
-rw-r--r--arch/h8300/include/asm/traps.h2
-rw-r--r--arch/h8300/kernel/Makefile2
-rw-r--r--arch/h8300/kernel/entry.S19
-rw-r--r--arch/h8300/kernel/kgdb.c135
-rw-r--r--arch/h8300/kernel/setup.c10
-rw-r--r--arch/h8300/kernel/signal.c8
-rw-r--r--arch/h8300/kernel/traps.c20
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S4
-rw-r--r--arch/hexagon/Kconfig1
-rw-r--r--arch/hexagon/include/asm/atomic.h2
-rw-r--r--arch/hexagon/include/asm/checksum.h8
-rw-r--r--arch/hexagon/include/asm/dma-mapping.h2
-rw-r--r--arch/hexagon/kernel/smp.c2
-rw-r--r--arch/hexagon/lib/checksum.c10
-rw-r--r--arch/ia64/Kconfig5
-rw-r--r--arch/ia64/include/asm/atomic.h8
-rw-r--r--arch/ia64/include/asm/barrier.h24
-rw-r--r--arch/ia64/include/asm/checksum.h16
-rw-r--r--arch/ia64/include/asm/dma-mapping.h2
-rw-r--r--arch/ia64/include/asm/early_ioremap.h10
-rw-r--r--arch/ia64/include/asm/gpio.h4
-rw-r--r--arch/ia64/include/asm/io.h6
-rw-r--r--arch/ia64/include/asm/page.h1
-rw-r--r--arch/ia64/include/asm/pci.h7
-rw-r--r--arch/ia64/include/asm/percpu.h2
-rw-r--r--arch/ia64/include/asm/rwsem.h2
-rw-r--r--arch/ia64/include/asm/unistd.h2
-rw-r--r--arch/ia64/include/uapi/asm/socket.h5
-rw-r--r--arch/ia64/include/uapi/asm/unistd.h2
-rw-r--r--arch/ia64/kernel/efi.c13
-rw-r--r--arch/ia64/kernel/entry.S2
-rw-r--r--arch/ia64/kernel/ftrace.c12
-rw-r--r--arch/ia64/kernel/iosapic.c6
-rw-r--r--arch/ia64/kernel/module.c14
-rw-r--r--arch/ia64/kernel/perfmon.c3
-rw-r--r--arch/ia64/kernel/setup.c6
-rw-r--r--arch/ia64/kernel/smpboot.c2
-rw-r--r--arch/ia64/kernel/unaligned.c7
-rw-r--r--arch/ia64/lib/checksum.c8
-rw-r--r--arch/ia64/mm/hugetlbpage.c2
-rw-r--r--arch/ia64/pci/fixup.c21
-rw-r--r--arch/ia64/pci/pci.c368
-rw-r--r--arch/ia64/sn/kernel/io_acpi_init.c22
-rw-r--r--arch/ia64/sn/kernel/io_init.c51
-rw-r--r--arch/m32r/Kconfig4
-rw-r--r--arch/m32r/include/asm/Kbuild1
-rw-r--r--arch/m32r/include/asm/atomic.h4
-rw-r--r--arch/m32r/include/asm/checksum.h10
-rw-r--r--arch/m32r/include/asm/io.h10
-rw-r--r--arch/m32r/include/uapi/asm/socket.h5
-rw-r--r--arch/m32r/kernel/setup.c7
-rw-r--r--arch/m32r/kernel/smpboot.c2
-rw-r--r--arch/m32r/mm/init.c27
-rw-r--r--arch/m68k/68360/Makefile12
-rw-r--r--arch/m68k/68360/commproc.c309
-rw-r--r--arch/m68k/68360/config.c169
-rw-r--r--arch/m68k/68360/entry.S164
-rw-r--r--arch/m68k/68360/head-ram.S402
-rw-r--r--arch/m68k/68360/head-rom.S413
-rw-r--r--arch/m68k/68360/ints.c138
-rw-r--r--arch/m68k/Kconfig.cpu7
-rw-r--r--arch/m68k/Kconfig.debug2
-rw-r--r--arch/m68k/Kconfig.machine6
-rw-r--r--arch/m68k/Makefile3
-rw-r--r--arch/m68k/atari/config.c4
-rw-r--r--arch/m68k/coldfire/device.c4
-rw-r--r--arch/m68k/coldfire/gpio.c4
-rw-r--r--arch/m68k/coldfire/m54xx.c2
-rw-r--r--arch/m68k/configs/amiga_defconfig13
-rw-r--r--arch/m68k/configs/apollo_defconfig14
-rw-r--r--arch/m68k/configs/atari_defconfig13
-rw-r--r--arch/m68k/configs/bvme6000_defconfig13
-rw-r--r--arch/m68k/configs/hp300_defconfig14
-rw-r--r--arch/m68k/configs/mac_defconfig14
-rw-r--r--arch/m68k/configs/multi_defconfig14
-rw-r--r--arch/m68k/configs/mvme147_defconfig13
-rw-r--r--arch/m68k/configs/mvme16x_defconfig13
-rw-r--r--arch/m68k/configs/q40_defconfig14
-rw-r--r--arch/m68k/configs/sun3_defconfig14
-rw-r--r--arch/m68k/configs/sun3x_defconfig14
-rw-r--r--arch/m68k/emu/nfblock.c3
-rw-r--r--arch/m68k/include/asm/MC68328.h6
-rw-r--r--arch/m68k/include/asm/MC68EZ328.h6
-rw-r--r--arch/m68k/include/asm/MC68VZ328.h6
-rw-r--r--arch/m68k/include/asm/atomic.h4
-rw-r--r--arch/m68k/include/asm/checksum.h2
-rw-r--r--arch/m68k/include/asm/commproc.h664
-rw-r--r--arch/m68k/include/asm/dma-mapping.h112
-rw-r--r--arch/m68k/include/asm/m54xxacr.h4
-rw-r--r--arch/m68k/include/asm/m68360.h13
-rw-r--r--arch/m68k/include/asm/m68360_enet.h177
-rw-r--r--arch/m68k/include/asm/m68360_pram.h431
-rw-r--r--arch/m68k/include/asm/m68360_quicc.h362
-rw-r--r--arch/m68k/include/asm/m68360_regs.h408
-rw-r--r--arch/m68k/include/asm/mac_iop.h2
-rw-r--r--arch/m68k/include/asm/mac_psc.h1
-rw-r--r--arch/m68k/include/asm/mcftimer.h2
-rw-r--r--arch/m68k/include/asm/page.h3
-rw-r--r--arch/m68k/include/asm/pci.h1
-rw-r--r--arch/m68k/include/asm/serial.h8
-rw-r--r--arch/m68k/include/asm/uaccess_no.h4
-rw-r--r--arch/m68k/include/asm/unistd.h2
-rw-r--r--arch/m68k/include/uapi/asm/unistd.h2
-rw-r--r--arch/m68k/kernel/dma.c61
-rw-r--r--arch/m68k/kernel/early_printk.c8
-rw-r--r--arch/m68k/kernel/entry.S6
-rw-r--r--arch/m68k/kernel/setup_no.c16
-rw-r--r--arch/m68k/kernel/signal.c8
-rw-r--r--arch/m68k/kernel/syscalltable.S2
-rw-r--r--arch/m68k/mac/macints.c6
-rw-r--r--arch/m68k/mac/psc.c8
-rw-r--r--arch/m68k/mac/via.c2
-rw-r--r--arch/m68k/mm/motorola.c2
-rw-r--r--arch/m68k/sun3/config.c6
-rw-r--r--arch/m68k/sun3/idprom.c5
-rw-r--r--arch/metag/Kconfig3
-rw-r--r--arch/metag/Makefile2
-rw-r--r--arch/metag/boot/dts/Makefile7
-rw-r--r--arch/metag/include/asm/atomic_lnkget.h2
-rw-r--r--arch/metag/include/asm/atomic_lock1.h2
-rw-r--r--arch/metag/include/asm/barrier.h55
-rw-r--r--arch/metag/include/asm/checksum.h7
-rw-r--r--arch/metag/include/asm/dma-mapping.h179
-rw-r--r--arch/metag/include/asm/gpio.h4
-rw-r--r--arch/metag/include/asm/highmem.h1
-rw-r--r--arch/metag/include/asm/irq.h8
-rw-r--r--arch/metag/kernel/dma.c146
-rw-r--r--arch/metag/kernel/ftrace.c11
-rw-r--r--arch/metag/kernel/module.c4
-rw-r--r--arch/metag/kernel/smp.c4
-rw-r--r--arch/metag/mm/highmem.c14
-rw-r--r--arch/metag/mm/hugetlbpage.c2
-rw-r--r--arch/microblaze/Kconfig7
-rw-r--r--arch/microblaze/configs/mmu_defconfig1
-rw-r--r--arch/microblaze/configs/nommu_defconfig1
-rw-r--r--arch/microblaze/include/asm/checksum.h4
-rw-r--r--arch/microblaze/include/asm/dma-mapping.h2
-rw-r--r--arch/microblaze/include/asm/gpio.h4
-rw-r--r--arch/microblaze/include/asm/highmem.h13
-rw-r--r--arch/microblaze/include/asm/pci.h2
-rw-r--r--arch/microblaze/kernel/dma.c3
-rw-r--r--arch/microblaze/kernel/setup.c4
-rw-r--r--arch/microblaze/pci/pci-common.c56
-rw-r--r--arch/mips/Kbuild1
-rw-r--r--arch/mips/Kbuild.platforms2
-rw-r--r--arch/mips/Kconfig119
-rw-r--r--arch/mips/Kconfig.debug72
-rw-r--r--arch/mips/Makefile14
-rw-r--r--arch/mips/alchemy/common/gpiolib.c14
-rw-r--r--arch/mips/alchemy/devboards/db1200.c2
-rw-r--r--arch/mips/alchemy/devboards/db1300.c2
-rw-r--r--arch/mips/alchemy/devboards/db1550.c2
-rw-r--r--arch/mips/ar7/gpio.c28
-rw-r--r--arch/mips/ath79/common.h1
-rw-r--r--arch/mips/ath79/irq.c249
-rw-r--r--arch/mips/ath79/setup.c18
-rw-r--r--arch/mips/bcm47xx/Kconfig1
-rw-r--r--arch/mips/bcm47xx/setup.c22
-rw-r--r--arch/mips/bcm47xx/sprom.c58
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c14
-rw-r--r--arch/mips/bcm63xx/cpu.c12
-rw-r--r--arch/mips/bcm63xx/dev-pcmcia.c2
-rw-r--r--arch/mips/bcm63xx/dev-spi.c42
-rw-r--r--arch/mips/bcm63xx/gpio.c4
-rw-r--r--arch/mips/bcm63xx/irq.c2
-rw-r--r--arch/mips/bcm63xx/nvram.c35
-rw-r--r--arch/mips/bcm63xx/setup.c8
-rw-r--r--arch/mips/bcm63xx/timer.c2
-rw-r--r--arch/mips/bmips/irq.c10
-rw-r--r--arch/mips/bmips/setup.c2
-rw-r--r--arch/mips/boot/compressed/Makefile15
-rw-r--r--arch/mips/boot/compressed/uart-16550.c2
-rw-r--r--arch/mips/boot/compressed/uart-prom.c7
-rw-r--r--arch/mips/boot/dts/Makefile5
-rw-r--r--arch/mips/boot/dts/brcm/bcm6328.dtsi11
-rw-r--r--arch/mips/boot/dts/brcm/bcm6368.dtsi22
-rw-r--r--arch/mips/boot/dts/brcm/bcm7125.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7346.dtsi116
-rw-r--r--arch/mips/boot/dts/brcm/bcm7358.dtsi64
-rw-r--r--arch/mips/boot/dts/brcm/bcm7360.dtsi64
-rw-r--r--arch/mips/boot/dts/brcm/bcm7362.dtsi96
-rw-r--r--arch/mips/boot/dts/brcm/bcm7420.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm7425.dtsi44
-rw-r--r--arch/mips/boot/dts/brcm/bcm7435.dtsi2
-rw-r--r--arch/mips/boot/dts/brcm/bcm97346dbsmb.dts28
-rw-r--r--arch/mips/boot/dts/brcm/bcm97358svmb.dts16
-rw-r--r--arch/mips/boot/dts/brcm/bcm97360svmb.dts16
-rw-r--r--arch/mips/boot/dts/brcm/bcm97362svmb.dts20
-rw-r--r--arch/mips/boot/dts/ingenic/ci20.dts64
-rw-r--r--arch/mips/boot/dts/ingenic/jz4780.dtsi26
-rw-r--r--arch/mips/boot/dts/mti/malta.dts4
-rw-r--r--arch/mips/boot/dts/pic32/Makefile12
-rw-r--r--arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi236
-rw-r--r--arch/mips/boot/dts/pic32/pic32mzda.dtsi281
-rw-r--r--arch/mips/boot/dts/pic32/pic32mzda_sk.dts151
-rw-r--r--arch/mips/boot/dts/qca/ar9132.dtsi28
-rw-r--r--arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts8
-rw-r--r--arch/mips/boot/dts/xilfpga/Makefile9
-rw-r--r--arch/mips/boot/dts/xilfpga/microAptiv.dtsi21
-rw-r--r--arch/mips/boot/dts/xilfpga/nexys4ddr.dts46
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c4
-rw-r--r--arch/mips/cavium-octeon/setup.c11
-rw-r--r--arch/mips/configs/bigsur_defconfig13
-rw-r--r--arch/mips/configs/bmips_be_defconfig3
-rw-r--r--arch/mips/configs/bmips_stb_defconfig3
-rw-r--r--arch/mips/configs/capcella_defconfig6
-rw-r--r--arch/mips/configs/e55_defconfig6
-rw-r--r--arch/mips/configs/fuloong2e_defconfig14
-rw-r--r--arch/mips/configs/ip22_defconfig1
-rw-r--r--arch/mips/configs/ip27_defconfig1
-rw-r--r--arch/mips/configs/ip32_defconfig1
-rw-r--r--arch/mips/configs/jazz_defconfig1
-rw-r--r--arch/mips/configs/lasat_defconfig10
-rw-r--r--arch/mips/configs/lemote2f_defconfig12
-rw-r--r--arch/mips/configs/malta_defconfig6
-rw-r--r--arch/mips/configs/malta_kvm_defconfig16
-rw-r--r--arch/mips/configs/malta_kvm_guest_defconfig16
-rw-r--r--arch/mips/configs/malta_qemu_32r6_defconfig11
-rw-r--r--arch/mips/configs/maltaaprp_defconfig11
-rw-r--r--arch/mips/configs/maltasmvp_eva_defconfig11
-rw-r--r--arch/mips/configs/maltaup_defconfig11
-rw-r--r--arch/mips/configs/maltaup_xpa_defconfig16
-rw-r--r--arch/mips/configs/mpc30x_defconfig6
-rw-r--r--arch/mips/configs/pic32mzda_defconfig89
-rw-r--r--arch/mips/configs/pistachio_defconfig1
-rw-r--r--arch/mips/configs/rm200_defconfig1
-rw-r--r--arch/mips/configs/sb1250_swarm_defconfig1
-rw-r--r--arch/mips/configs/xilfpga_defconfig40
-rw-r--r--arch/mips/include/asm/abi.h5
-rw-r--r--arch/mips/include/asm/atomic.h10
-rw-r--r--arch/mips/include/asm/barrier.h51
-rw-r--r--arch/mips/include/asm/bcache.h27
-rw-r--r--arch/mips/include/asm/cacheops.h106
-rw-r--r--arch/mips/include/asm/cdmm.h11
-rw-r--r--arch/mips/include/asm/checksum.h8
-rw-r--r--arch/mips/include/asm/clocksource.h29
-rw-r--r--arch/mips/include/asm/compat.h62
-rw-r--r--arch/mips/include/asm/cpu-features.h13
-rw-r--r--arch/mips/include/asm/cpu.h2
-rw-r--r--arch/mips/include/asm/debug.h22
-rw-r--r--arch/mips/include/asm/dma-mapping.h2
-rw-r--r--arch/mips/include/asm/elf.h31
-rw-r--r--arch/mips/include/asm/fpu.h4
-rw-r--r--arch/mips/include/asm/fpu_emulator.h2
-rw-r--r--arch/mips/include/asm/fw/fw.h16
-rw-r--r--arch/mips/include/asm/highmem.h1
-rw-r--r--arch/mips/include/asm/io.h1
-rw-r--r--arch/mips/include/asm/irqflags.h30
-rw-r--r--arch/mips/include/asm/kvm_host.h47
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h5
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx.h5
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h44
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h96
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h14
-rw-r--r--arch/mips/include/asm/mach-malta/malta-dtshim.h29
-rw-r--r--arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h32
-rw-r--r--arch/mips/include/asm/mach-pic32/irq.h22
-rw-r--r--arch/mips/include/asm/mach-pic32/pic32.h44
-rw-r--r--arch/mips/include/asm/mach-pic32/spaces.h24
-rw-r--r--arch/mips/include/asm/mach-ralink/irq.h9
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7620.h8
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7621.h38
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h65
-rw-r--r--arch/mips/include/asm/mach-ralink/ralink_regs.h17
-rw-r--r--arch/mips/include/asm/mach-ralink/rt305x.h21
-rw-r--r--arch/mips/include/asm/mach-xilfpga/irq.h18
-rw-r--r--arch/mips/include/asm/mips-cm.h82
-rw-r--r--arch/mips/include/asm/mips-cpc.h3
-rw-r--r--arch/mips/include/asm/mips-r2-to-r6-emul.h2
-rw-r--r--arch/mips/include/asm/mipsregs.h52
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h9
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h3
-rw-r--r--arch/mips/include/asm/page.h3
-rw-r--r--arch/mips/include/asm/pci.h4
-rw-r--r--arch/mips/include/asm/pgtable-bits.h10
-rw-r--r--arch/mips/include/asm/pgtable.h22
-rw-r--r--arch/mips/include/asm/processor.h10
-rw-r--r--arch/mips/include/asm/smp-ops.h5
-rw-r--r--arch/mips/include/asm/stackframe.h4
-rw-r--r--arch/mips/include/asm/syscall.h4
-rw-r--r--arch/mips/include/asm/uaccess.h52
-rw-r--r--arch/mips/include/asm/vdso.h139
-rw-r--r--arch/mips/include/uapi/asm/Kbuild2
-rw-r--r--arch/mips/include/uapi/asm/auxvec.h17
-rw-r--r--arch/mips/include/uapi/asm/inst.h15
-rw-r--r--arch/mips/include/uapi/asm/mman.h7
-rw-r--r--arch/mips/include/uapi/asm/socket.h5
-rw-r--r--arch/mips/include/uapi/asm/unistd.h18
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c13
-rw-r--r--arch/mips/jz4740/gpio.c12
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c2
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c2
-rw-r--r--arch/mips/kernel/cps-vec-ns16550.S202
-rw-r--r--arch/mips/kernel/cps-vec.S46
-rw-r--r--arch/mips/kernel/cpu-bugs64.c8
-rw-r--r--arch/mips/kernel/cpu-probe.c164
-rw-r--r--arch/mips/kernel/csrc-r4k.c44
-rw-r--r--arch/mips/kernel/elf.c102
-rw-r--r--arch/mips/kernel/gpio_txx9.c6
-rw-r--r--arch/mips/kernel/idle.c17
-rw-r--r--arch/mips/kernel/mips-cm.c114
-rw-r--r--arch/mips/kernel/mips-cpc.c6
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c2
-rw-r--r--arch/mips/kernel/mips_ksyms.c2
-rw-r--r--arch/mips/kernel/process.c6
-rw-r--r--arch/mips/kernel/ptrace.c3
-rw-r--r--arch/mips/kernel/r2300_fpu.S2
-rw-r--r--arch/mips/kernel/r4k_fpu.S2
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/segment.c2
-rw-r--r--arch/mips/kernel/setup.c40
-rw-r--r--arch/mips/kernel/signal.c12
-rw-r--r--arch/mips/kernel/signal32.c7
-rw-r--r--arch/mips/kernel/signal_n32.c5
-rw-r--r--arch/mips/kernel/smp-cmp.c4
-rw-r--r--arch/mips/kernel/smp-cps.c42
-rw-r--r--arch/mips/kernel/smp-gic.c2
-rw-r--r--arch/mips/kernel/smp-mt.c2
-rw-r--r--arch/mips/kernel/smp.c139
-rw-r--r--arch/mips/kernel/spinlock_test.c4
-rw-r--r--arch/mips/kernel/stacktrace.c27
-rw-r--r--arch/mips/kernel/sync-r4k.c32
-rw-r--r--arch/mips/kernel/traps.c101
-rw-r--r--arch/mips/kernel/unaligned.c2
-rw-r--r--arch/mips/kernel/vdso.c207
-rw-r--r--arch/mips/kernel/vmlinux.lds.S15
-rw-r--r--arch/mips/kernel/vpe.c6
-rw-r--r--arch/mips/kvm/callback.c2
-rw-r--r--arch/mips/kvm/dyntrans.c10
-rw-r--r--arch/mips/kvm/emulate.c120
-rw-r--r--arch/mips/kvm/interrupt.c8
-rw-r--r--arch/mips/kvm/locore.S36
-rw-r--r--arch/mips/kvm/mips.c55
-rw-r--r--arch/mips/kvm/opcode.h22
-rw-r--r--arch/mips/kvm/tlb.c91
-rw-r--r--arch/mips/kvm/trap_emul.c1
-rw-r--r--arch/mips/lantiq/clk.c17
-rw-r--r--arch/mips/lantiq/clk.h13
-rw-r--r--arch/mips/lantiq/irq.c8
-rw-r--r--arch/mips/lantiq/prom.c2
-rw-r--r--arch/mips/lantiq/xway/clk.c180
-rw-r--r--arch/mips/lantiq/xway/prom.c35
-rw-r--r--arch/mips/lantiq/xway/reset.c196
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c301
-rw-r--r--arch/mips/lasat/picvue_proc.c18
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/bswapdi.c15
-rw-r--r--arch/mips/lib/bswapsi.c11
-rw-r--r--arch/mips/lib/memset.S2
-rw-r--r--arch/mips/lib/mips-atomic.c30
-rw-r--r--arch/mips/loongson64/Kconfig5
-rw-r--r--arch/mips/loongson64/Platform21
-rw-r--r--arch/mips/loongson64/common/Makefile2
-rw-r--r--arch/mips/loongson64/lemote-2f/Makefile2
-rw-r--r--arch/mips/loongson64/loongson-3/hpet.c10
-rw-r--r--arch/mips/loongson64/loongson-3/smp.c20
-rw-r--r--arch/mips/math-emu/cp1emu.c4
-rw-r--r--arch/mips/math-emu/dp_simple.c38
-rw-r--r--arch/mips/math-emu/dp_tint.c9
-rw-r--r--arch/mips/math-emu/dp_tlong.c9
-rw-r--r--arch/mips/math-emu/dsemul.c77
-rw-r--r--arch/mips/math-emu/ieee754.c6
-rw-r--r--arch/mips/math-emu/ieee754.h42
-rw-r--r--arch/mips/math-emu/ieee754dp.c12
-rw-r--r--arch/mips/math-emu/ieee754int.h12
-rw-r--r--arch/mips/math-emu/ieee754sp.c12
-rw-r--r--arch/mips/math-emu/me-debugfs.c2
-rw-r--r--arch/mips/math-emu/sp_fdp.c13
-rw-r--r--arch/mips/math-emu/sp_simple.c38
-rw-r--r--arch/mips/math-emu/sp_tint.c9
-rw-r--r--arch/mips/math-emu/sp_tlong.c9
-rw-r--r--arch/mips/mm/Makefile1
-rw-r--r--arch/mips/mm/c-r4k.c3
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/gup.c19
-rw-r--r--arch/mips/mm/highmem.c13
-rw-r--r--arch/mips/mm/init.c6
-rw-r--r--arch/mips/mm/mmap.c4
-rw-r--r--arch/mips/mm/pgtable-64.c14
-rw-r--r--arch/mips/mm/sc-debugfs.c81
-rw-r--r--arch/mips/mm/sc-mips.c88
-rw-r--r--arch/mips/mm/tlbex.c100
-rw-r--r--arch/mips/mti-malta/Makefile15
-rw-r--r--arch/mips/mti-malta/malta-dtshim.c162
-rw-r--r--arch/mips/mti-malta/malta-init.c9
-rw-r--r--arch/mips/mti-malta/malta-memory.c131
-rw-r--r--arch/mips/mti-malta/malta-setup.c5
-rw-r--r--arch/mips/mti-sead3/Makefile2
-rw-r--r--arch/mips/mti-sead3/leds-sead3.c77
-rw-r--r--arch/mips/net/bpf_jit.c18
-rw-r--r--arch/mips/netlogic/xlp/dt.c1
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-loongson3.c19
-rw-r--r--arch/mips/pci/pci-mt7620.c426
-rw-r--r--arch/mips/pci/pci-rt2880.c5
-rw-r--r--arch/mips/pci/pci-rt3883.c6
-rw-r--r--arch/mips/pic32/Kconfig51
-rw-r--r--arch/mips/pic32/Makefile6
-rw-r--r--arch/mips/pic32/Platform7
-rw-r--r--arch/mips/pic32/common/Makefile5
-rw-r--r--arch/mips/pic32/common/irq.c21
-rw-r--r--arch/mips/pic32/common/reset.c62
-rw-r--r--arch/mips/pic32/pic32mzda/Makefile9
-rw-r--r--arch/mips/pic32/pic32mzda/config.c126
-rw-r--r--arch/mips/pic32/pic32mzda/early_clk.c106
-rw-r--r--arch/mips/pic32/pic32mzda/early_console.c171
-rw-r--r--arch/mips/pic32/pic32mzda/early_pin.c275
-rw-r--r--arch/mips/pic32/pic32mzda/early_pin.h241
-rw-r--r--arch/mips/pic32/pic32mzda/init.c156
-rw-r--r--arch/mips/pic32/pic32mzda/pic32mzda.h29
-rw-r--r--arch/mips/pic32/pic32mzda/time.c73
-rw-r--r--arch/mips/pistachio/init.c1
-rw-r--r--arch/mips/pistachio/time.c2
-rw-r--r--arch/mips/pmcs-msp71xx/msp_serial.c2
-rw-r--r--arch/mips/pmcs-msp71xx/msp_setup.c5
-rw-r--r--arch/mips/pnx833x/common/platform.c2
-rw-r--r--arch/mips/ralink/Kconfig16
-rw-r--r--arch/mips/ralink/Makefile10
-rw-r--r--arch/mips/ralink/Platform5
-rw-r--r--arch/mips/ralink/cevt-rt3352.c2
-rw-r--r--arch/mips/ralink/clk.c2
-rw-r--r--arch/mips/ralink/early_printk.c26
-rw-r--r--arch/mips/ralink/irq-gic.c25
-rw-r--r--arch/mips/ralink/mt7620.c148
-rw-r--r--arch/mips/ralink/mt7621.c226
-rw-r--r--arch/mips/ralink/of.c2
-rw-r--r--arch/mips/ralink/prom.c5
-rw-r--r--arch/mips/ralink/reset.c13
-rw-r--r--arch/mips/ralink/rt288x.c1
-rw-r--r--arch/mips/ralink/rt305x.c14
-rw-r--r--arch/mips/ralink/rt3883.c3
-rw-r--r--arch/mips/ralink/timer-gic.c24
-rw-r--r--arch/mips/rb532/devices.c2
-rw-r--r--arch/mips/rb532/gpio.c14
-rw-r--r--arch/mips/sni/reset.c8
-rw-r--r--arch/mips/txx9/generic/setup.c12
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c7
-rw-r--r--arch/mips/txx9/generic/spi_eeprom.c1
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c3
-rw-r--r--arch/mips/vdso/.gitignore4
-rw-r--r--arch/mips/vdso/Makefile160
-rw-r--r--arch/mips/vdso/elf.S68
-rw-r--r--arch/mips/vdso/genvdso.c293
-rw-r--r--arch/mips/vdso/genvdso.h187
-rw-r--r--arch/mips/vdso/gettimeofday.c232
-rw-r--r--arch/mips/vdso/sigreturn.S49
-rw-r--r--arch/mips/vdso/vdso.h89
-rw-r--r--arch/mips/vdso/vdso.lds.S105
-rw-r--r--arch/mips/xilfpga/Kconfig9
-rw-r--r--arch/mips/xilfpga/Makefile7
-rw-r--r--arch/mips/xilfpga/Platform3
-rw-r--r--arch/mips/xilfpga/init.c57
-rw-r--r--arch/mips/xilfpga/intc.c25
-rw-r--r--arch/mips/xilfpga/time.c41
-rw-r--r--arch/mn10300/Kconfig6
-rw-r--r--arch/mn10300/include/asm/atomic.h4
-rw-r--r--arch/mn10300/include/asm/checksum.h17
-rw-r--r--arch/mn10300/include/asm/dma-mapping.h161
-rw-r--r--arch/mn10300/include/asm/page.h1
-rw-r--r--arch/mn10300/include/asm/pci.h3
-rw-r--r--arch/mn10300/include/asm/serial.h10
-rw-r--r--arch/mn10300/include/asm/uaccess.h15
-rw-r--r--arch/mn10300/include/uapi/asm/socket.h5
-rw-r--r--arch/mn10300/kernel/fpu-nofpu.c1
-rw-r--r--arch/mn10300/kernel/smp.c2
-rw-r--r--arch/mn10300/mm/dma-alloc.c67
-rw-r--r--arch/nios2/include/asm/checksum.h9
-rw-r--r--arch/nios2/include/asm/cmpxchg.h47
-rw-r--r--arch/nios2/include/asm/dma-mapping.h123
-rw-r--r--arch/nios2/kernel/setup.c2
-rw-r--r--arch/nios2/kernel/time.c2
-rw-r--r--arch/nios2/lib/memmove.c2
-rw-r--r--arch/nios2/lib/memset.c2
-rw-r--r--arch/nios2/mm/cacheflush.c24
-rw-r--r--arch/nios2/mm/dma-mapping.c149
-rw-r--r--arch/openrisc/Kconfig3
-rw-r--r--arch/openrisc/include/asm/dma-mapping.h2
-rw-r--r--arch/openrisc/include/asm/gpio.h4
-rw-r--r--arch/parisc/Kconfig7
-rw-r--r--arch/parisc/configs/712_defconfig1
-rw-r--r--arch/parisc/configs/a500_defconfig1
-rw-r--r--arch/parisc/configs/default_defconfig1
-rw-r--r--arch/parisc/configs/generic-32bit_defconfig1
-rw-r--r--arch/parisc/include/asm/atomic.h2
-rw-r--r--arch/parisc/include/asm/cache.h21
-rw-r--r--arch/parisc/include/asm/cacheflush.h5
-rw-r--r--arch/parisc/include/asm/checksum.h12
-rw-r--r--arch/parisc/include/asm/compat.h4
-rw-r--r--arch/parisc/include/asm/dma-mapping.h189
-rw-r--r--arch/parisc/include/asm/floppy.h2
-rw-r--r--arch/parisc/include/asm/hugetlb.h73
-rw-r--r--arch/parisc/include/asm/page.h13
-rw-r--r--arch/parisc/include/asm/pci.h4
-rw-r--r--arch/parisc/include/asm/pdc.h2
-rw-r--r--arch/parisc/include/asm/pgalloc.h2
-rw-r--r--arch/parisc/include/asm/pgtable.h27
-rw-r--r--arch/parisc/include/asm/processor.h44
-rw-r--r--arch/parisc/include/uapi/asm/ipcbuf.h19
-rw-r--r--arch/parisc/include/uapi/asm/mman.h14
-rw-r--r--arch/parisc/include/uapi/asm/msgbuf.h10
-rw-r--r--arch/parisc/include/uapi/asm/posix_types.h2
-rw-r--r--arch/parisc/include/uapi/asm/sembuf.h6
-rw-r--r--arch/parisc/include/uapi/asm/shmbuf.h8
-rw-r--r--arch/parisc/include/uapi/asm/siginfo.h7
-rw-r--r--arch/parisc/include/uapi/asm/socket.h5
-rw-r--r--arch/parisc/include/uapi/asm/stat.h31
-rw-r--r--arch/parisc/include/uapi/asm/unistd.h6
-rw-r--r--arch/parisc/kernel/asm-offsets.c8
-rw-r--r--arch/parisc/kernel/cache.c26
-rw-r--r--arch/parisc/kernel/drivers.c2
-rw-r--r--arch/parisc/kernel/entry.S56
-rw-r--r--arch/parisc/kernel/head.S4
-rw-r--r--arch/parisc/kernel/module.c32
-rw-r--r--arch/parisc/kernel/pci-dma.c92
-rw-r--r--arch/parisc/kernel/pci.c22
-rw-r--r--arch/parisc/kernel/processor.c10
-rw-r--r--arch/parisc/kernel/ptrace.c16
-rw-r--r--arch/parisc/kernel/setup.c14
-rw-r--r--arch/parisc/kernel/signal.c64
-rw-r--r--arch/parisc/kernel/smp.c2
-rw-r--r--arch/parisc/kernel/syscall.S9
-rw-r--r--arch/parisc/kernel/syscall_table.S4
-rw-r--r--arch/parisc/kernel/traps.c35
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S9
-rw-r--r--arch/parisc/mm/Makefile1
-rw-r--r--arch/parisc/mm/hugetlbpage.c197
-rw-r--r--arch/parisc/mm/init.c62
-rw-r--r--arch/powerpc/Kconfig40
-rw-r--r--arch/powerpc/Kconfig.debug18
-rw-r--r--arch/powerpc/Makefile31
-rw-r--r--arch/powerpc/boot/Makefile5
-rw-r--r--arch/powerpc/boot/dts/b4420qds.dts50
-rw-r--r--arch/powerpc/boot/dts/b4860qds.dts61
-rw-r--r--arch/powerpc/boot/dts/b4qds.dtsi232
-rw-r--r--arch/powerpc/boot/dts/bsc9131rdb.dts34
-rw-r--r--arch/powerpc/boot/dts/bsc9131rdb.dtsi92
-rw-r--r--arch/powerpc/boot/dts/bsc9132qds.dts35
-rw-r--r--arch/powerpc/boot/dts/bsc9132qds.dtsi101
-rw-r--r--arch/powerpc/boot/dts/c293pcie.dts224
-rw-r--r--arch/powerpc/boot/dts/fsl/b4420qds.dts50
-rw-r--r--arch/powerpc/boot/dts/fsl/b4420si-post.dtsi4
-rw-r--r--arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi13
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860qds.dts117
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860si-post.dtsi26
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi20
-rw-r--r--arch/powerpc/boot/dts/fsl/b4qds.dtsi279
-rw-r--r--arch/powerpc/boot/dts/fsl/b4si-post.dtsi38
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9131rdb.dts34
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi104
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132qds.dts50
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi113
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi28
-rw-r--r--arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/c293pcie.dts224
-rw-r--r--arch/powerpc/boot/dts/fsl/cyrus_p5020.dts155
-rw-r--r--arch/powerpc/boot/dts/fsl/ge_imp3a.dts255
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_ppc9a.dts216
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_sbc310.dts260
-rw-r--r--arch/powerpc/boot/dts/fsl/gef_sbc610.dts214
-rw-r--r--arch/powerpc/boot/dts/fsl/kmcoge4.dts179
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536ds.dts109
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi244
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts109
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8540ads.dts359
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8541cds.dts379
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8544ds.dts107
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8544ds.dtsi (renamed from arch/powerpc/boot/dts/mpc8544ds.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8548cds.dtsi (renamed from arch/powerpc/boot/dts/mpc8548cds.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts86
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts86
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8555cds.dts379
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8560ads.dts392
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8568mds.dts314
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8569mds.dts447
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572ds.dts90
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi (renamed from arch/powerpc/boot/dts/mpc8572ds.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts90
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core0.dts (renamed from arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts)0
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core1.dts (renamed from arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts)0
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts420
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts363
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi120
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi58
-rw-r--r--arch/powerpc/boot/dts/fsl/mvme2500.dts280
-rw-r--r--arch/powerpc/boot/dts/fsl/oca4080.dts145
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts23
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pa.dtsi (renamed from arch/powerpc/boot/dts/p1010rdb-pa.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts46
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts35
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts58
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb.dtsi233
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi (renamed from arch/powerpc/boot/dts/p1010rdb_32b.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi (renamed from arch/powerpc/boot/dts/p1010rdb_36b.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi (renamed from arch/powerpc/boot/dts/p1020mbg-pc.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts89
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts89
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi247
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts90
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts90
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core0.dts (renamed from arch/powerpc/boot/dts/p1020rdb-pc_camp_core0.dts)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core1.dts (renamed from arch/powerpc/boot/dts/p1020rdb-pc_camp_core1.dts)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts292
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb.dts66
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb.dtsi246
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts66
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi (renamed from arch/powerpc/boot/dts/p1020utm-pc.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts89
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts89
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021mds.dts323
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi256
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts96
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts96
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022ds.dtsi239
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022ds_32b.dts103
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022ds_36b.dts103
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022rdk.dts188
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/p1023rdb.dts260
-rw-r--r--arch/powerpc/boot/dts/fsl/p1024rdb.dtsi228
-rw-r--r--arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts87
-rw-r--r--arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts87
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb.dtsi326
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts133
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts93
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025twr.dts95
-rw-r--r--arch/powerpc/boot/dts/fsl/p1025twr.dtsi292
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020ds.dts89
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020ds.dtsi (renamed from arch/powerpc/boot/dts/p2020ds.dtsi)0
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi241
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts96
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts96
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020rdb.dts291
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041rdb.dts340
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041si-post.dtsi29
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi10
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041ds.dts394
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041si-post.dtsi29
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi10
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080ds.dts400
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi15
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020ds.dts394
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020si-post.dtsi29
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi10
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040ds.dts486
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-post.dtsi57
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi23
-rw-r--r--arch/powerpc/boot/dts/fsl/ppa8548.dts164
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi62
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi69
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi101
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi61
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi101
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi71
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi71
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi106
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi67
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi106
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi94
-rw-r--r--arch/powerpc/boot/dts/fsl/sbc8641d.dts203
-rw-r--r--arch/powerpc/boot/dts/fsl/t1023rdb.dts203
-rw-r--r--arch/powerpc/boot/dts/fsl/t1023si-post.dtsi105
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024qds.dts251
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024rdb.dts236
-rw-r--r--arch/powerpc/boot/dts/fsl/t1024si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi8
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040d4rdb.dts46
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040qds.dts46
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040rdb.dts78
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040si-post.dtsi125
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042d4rdb.dts53
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042qds.dts46
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb.dts76
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts73
-rw-r--r--arch/powerpc/boot/dts/fsl/t1042si-post.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi215
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xqds.dtsi369
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xrdb.dtsi225
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi13
-rw-r--r--arch/powerpc/boot/dts/fsl/t2080qds.dts213
-rw-r--r--arch/powerpc/boot/dts/fsl/t2080rdb.dts122
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081qds.dts265
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081si-post.dtsi43
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xqds.dtsi277
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xrdb.dtsi211
-rw-r--r--arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi11
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240qds.dts708
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240rdb.dts360
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-post.dtsi88
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi22
-rw-r--r--arch/powerpc/boot/dts/ge_imp3a.dts255
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts425
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts459
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts423
-rw-r--r--arch/powerpc/boot/dts/kmcoge4.dts179
-rw-r--r--arch/powerpc/boot/dts/mpc5121.dtsi11
-rw-r--r--arch/powerpc/boot/dts/mpc5125twr.dts11
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dts109
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dtsi244
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds_36b.dts109
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts359
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts379
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts107
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds_32b.dts86
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds_36b.dts86
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts379
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts392
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts314
-rw-r--r--arch/powerpc/boot/dts/mpc8569mds.dts447
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts90
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_36b.dts90
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts663
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts605
-rw-r--r--arch/powerpc/boot/dts/mvme2500.dts280
-rw-r--r--arch/powerpc/boot/dts/oca4080.dts145
-rw-r--r--arch/powerpc/boot/dts/p1010rdb-pa.dts23
-rw-r--r--arch/powerpc/boot/dts/p1010rdb-pa_36b.dts46
-rw-r--r--arch/powerpc/boot/dts/p1010rdb-pb.dts35
-rw-r--r--arch/powerpc/boot/dts/p1010rdb-pb_36b.dts58
-rw-r--r--arch/powerpc/boot/dts/p1010rdb.dtsi205
-rw-r--r--arch/powerpc/boot/dts/p1020mbg-pc_32b.dts89
-rw-r--r--arch/powerpc/boot/dts/p1020mbg-pc_36b.dts89
-rw-r--r--arch/powerpc/boot/dts/p1020rdb-pc.dtsi247
-rw-r--r--arch/powerpc/boot/dts/p1020rdb-pc_32b.dts90
-rw-r--r--arch/powerpc/boot/dts/p1020rdb-pc_36b.dts90
-rw-r--r--arch/powerpc/boot/dts/p1020rdb-pd.dts280
-rw-r--r--arch/powerpc/boot/dts/p1020rdb.dts66
-rw-r--r--arch/powerpc/boot/dts/p1020rdb.dtsi246
-rw-r--r--arch/powerpc/boot/dts/p1020rdb_36b.dts66
-rw-r--r--arch/powerpc/boot/dts/p1020utm-pc_32b.dts89
-rw-r--r--arch/powerpc/boot/dts/p1020utm-pc_36b.dts89
-rw-r--r--arch/powerpc/boot/dts/p1021mds.dts323
-rw-r--r--arch/powerpc/boot/dts/p1021rdb-pc.dtsi244
-rw-r--r--arch/powerpc/boot/dts/p1021rdb-pc_32b.dts96
-rw-r--r--arch/powerpc/boot/dts/p1021rdb-pc_36b.dts96
-rw-r--r--arch/powerpc/boot/dts/p1022ds.dtsi227
-rw-r--r--arch/powerpc/boot/dts/p1022ds_32b.dts103
-rw-r--r--arch/powerpc/boot/dts/p1022ds_36b.dts103
-rw-r--r--arch/powerpc/boot/dts/p1022rdk.dts188
-rw-r--r--arch/powerpc/boot/dts/p1023rdb.dts260
-rw-r--r--arch/powerpc/boot/dts/p1024rdb.dtsi228
-rw-r--r--arch/powerpc/boot/dts/p1024rdb_32b.dts87
-rw-r--r--arch/powerpc/boot/dts/p1024rdb_36b.dts87
-rw-r--r--arch/powerpc/boot/dts/p1025rdb.dtsi326
-rw-r--r--arch/powerpc/boot/dts/p1025rdb_32b.dts133
-rw-r--r--arch/powerpc/boot/dts/p1025rdb_36b.dts93
-rw-r--r--arch/powerpc/boot/dts/p1025twr.dts95
-rw-r--r--arch/powerpc/boot/dts/p1025twr.dtsi280
-rw-r--r--arch/powerpc/boot/dts/p2020ds.dts89
-rw-r--r--arch/powerpc/boot/dts/p2020rdb-pc.dtsi241
-rw-r--r--arch/powerpc/boot/dts/p2020rdb-pc_32b.dts96
-rw-r--r--arch/powerpc/boot/dts/p2020rdb-pc_36b.dts96
-rw-r--r--arch/powerpc/boot/dts/p2020rdb.dts291
-rw-r--r--arch/powerpc/boot/dts/p2041rdb.dts250
-rw-r--r--arch/powerpc/boot/dts/p3041ds.dts284
-rw-r--r--arch/powerpc/boot/dts/p4080ds.dts218
-rw-r--r--arch/powerpc/boot/dts/p5020ds.dts284
-rw-r--r--arch/powerpc/boot/dts/p5040ds.dts254
-rw-r--r--arch/powerpc/boot/dts/ppa8548.dts164
-rw-r--r--arch/powerpc/boot/dts/prpmc2800.dts297
-rw-r--r--arch/powerpc/boot/dts/sbc8641d.dts455
-rw-r--r--arch/powerpc/boot/dts/t1023rdb.dts162
-rw-r--r--arch/powerpc/boot/dts/t1024qds.dts251
-rw-r--r--arch/powerpc/boot/dts/t1024rdb.dts191
-rw-r--r--arch/powerpc/boot/dts/t1040d4rdb.dts46
-rw-r--r--arch/powerpc/boot/dts/t1040qds.dts46
-rw-r--r--arch/powerpc/boot/dts/t1040rdb.dts48
-rw-r--r--arch/powerpc/boot/dts/t1042d4rdb.dts53
-rw-r--r--arch/powerpc/boot/dts/t1042qds.dts46
-rw-r--r--arch/powerpc/boot/dts/t1042rdb.dts48
-rw-r--r--arch/powerpc/boot/dts/t1042rdb_pi.dts57
-rw-r--r--arch/powerpc/boot/dts/t104xd4rdb.dtsi205
-rw-r--r--arch/powerpc/boot/dts/t104xqds.dtsi193
-rw-r--r--arch/powerpc/boot/dts/t104xrdb.dtsi189
-rw-r--r--arch/powerpc/boot/dts/t2080qds.dts57
-rw-r--r--arch/powerpc/boot/dts/t2080rdb.dts57
-rw-r--r--arch/powerpc/boot/dts/t2081qds.dts46
-rw-r--r--arch/powerpc/boot/dts/t208xqds.dtsi277
-rw-r--r--arch/powerpc/boot/dts/t208xrdb.dtsi211
-rw-r--r--arch/powerpc/boot/dts/t4240qds.dts310
-rw-r--r--arch/powerpc/boot/dts/t4240rdb.dts213
-rw-r--r--arch/powerpc/boot/page.h4
-rw-r--r--arch/powerpc/boot/prpmc2800.c571
-rw-r--r--arch/powerpc/boot/rs6000.h2
-rw-r--r--arch/powerpc/boot/treeboot-akebono.c2
-rw-r--r--arch/powerpc/boot/treeboot-currituck.c2
-rw-r--r--arch/powerpc/boot/treeboot-iss4xx.c2
-rwxr-xr-xarch/powerpc/boot/wrapper27
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itx_defconfig1
-rw-r--r--arch/powerpc/configs/85xx/ksi8560_defconfig1
-rw-r--r--arch/powerpc/configs/85xx/stx_gp3_defconfig2
-rw-r--r--arch/powerpc/configs/86xx-hw.config104
-rw-r--r--arch/powerpc/configs/86xx-smp.config2
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig216
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig214
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig273
-rw-r--r--arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig110
-rw-r--r--arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig156
-rw-r--r--arch/powerpc/configs/86xx/sbc8641d_defconfig246
-rw-r--r--arch/powerpc/configs/c2k_defconfig1
-rw-r--r--arch/powerpc/configs/cell_defconfig2
-rw-r--r--arch/powerpc/configs/mpc512x_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_basic_defconfig1
-rw-r--r--arch/powerpc/configs/mpc86xx_basic_defconfig10
-rw-r--r--arch/powerpc/configs/mpc86xx_defconfig162
-rw-r--r--arch/powerpc/configs/powernv_defconfig313
-rw-r--r--arch/powerpc/configs/ppc64_defconfig1
-rw-r--r--arch/powerpc/configs/ppc6xx_defconfig1
-rw-r--r--arch/powerpc/configs/ps3_defconfig7
-rw-r--r--arch/powerpc/crypto/aes-spe-core.S4
-rw-r--r--arch/powerpc/crypto/aes-spe-glue.c9
-rw-r--r--arch/powerpc/crypto/sha1-spe-glue.c1
-rw-r--r--arch/powerpc/crypto/sha256-spe-glue.c1
-rw-r--r--arch/powerpc/include/asm/atomic.h159
-rw-r--r--arch/powerpc/include/asm/barrier.h33
-rw-r--r--arch/powerpc/include/asm/book3s/32/hash.h46
-rw-r--r--arch/powerpc/include/asm/book3s/32/mmu-hash.h (renamed from arch/powerpc/include/asm/mmu-hash32.h)0
-rw-r--r--arch/powerpc/include/asm/book3s/32/pgtable.h482
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-4k.h102
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash-64k.h303
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h561
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu-hash.h616
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h319
-rw-r--r--arch/powerpc/include/asm/book3s/64/tlbflush-hash.h94
-rw-r--r--arch/powerpc/include/asm/book3s/pgtable.h29
-rw-r--r--arch/powerpc/include/asm/cache.h19
-rw-r--r--arch/powerpc/include/asm/cacheflush.h54
-rw-r--r--arch/powerpc/include/asm/checksum.h141
-rw-r--r--arch/powerpc/include/asm/cmpxchg.h245
-rw-r--r--arch/powerpc/include/asm/code-patching.h21
-rw-r--r--arch/powerpc/include/asm/cpm.h44
-rw-r--r--arch/powerpc/include/asm/cputable.h28
-rw-r--r--arch/powerpc/include/asm/cputhreads.h15
-rw-r--r--arch/powerpc/include/asm/disassemble.h5
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h2
-rw-r--r--arch/powerpc/include/asm/eeh.h6
-rw-r--r--arch/powerpc/include/asm/exception-64e.h15
-rw-r--r--arch/powerpc/include/asm/exception-64s.h40
-rw-r--r--arch/powerpc/include/asm/fadump.h2
-rw-r--r--arch/powerpc/include/asm/firmware.h5
-rw-r--r--arch/powerpc/include/asm/fsl_guts.h192
-rw-r--r--arch/powerpc/include/asm/fsl_pm.h51
-rw-r--r--arch/powerpc/include/asm/ftrace.h5
-rw-r--r--arch/powerpc/include/asm/gpio.h4
-rw-r--r--arch/powerpc/include/asm/highmem.h13
-rw-r--r--arch/powerpc/include/asm/hugetlb.h2
-rw-r--r--arch/powerpc/include/asm/hvcall.h21
-rw-r--r--arch/powerpc/include/asm/hydra.h2
-rw-r--r--arch/powerpc/include/asm/icswx.h1
-rw-r--r--arch/powerpc/include/asm/immap_qe.h491
-rw-r--r--arch/powerpc/include/asm/io.h13
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h4
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h2
-rw-r--r--arch/powerpc/include/asm/kvm_host.h18
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h53
-rw-r--r--arch/powerpc/include/asm/machdep.h6
-rw-r--r--arch/powerpc/include/asm/mmu-8xx.h4
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h611
-rw-r--r--arch/powerpc/include/asm/mmu.h5
-rw-r--r--arch/powerpc/include/asm/module.h14
-rw-r--r--arch/powerpc/include/asm/mpc5121.h59
-rw-r--r--arch/powerpc/include/asm/mpc52xx_psc.h2
-rw-r--r--arch/powerpc/include/asm/msi_bitmap.h1
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgtable.h344
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-40x.h64
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-44x.h97
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-8xx.h65
-rw-r--r--arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h40
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgtable-4k.h92
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgtable-64k.h57
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgtable.h367
-rw-r--r--arch/powerpc/include/asm/nohash/pgtable.h252
-rw-r--r--arch/powerpc/include/asm/nohash/pte-book3e.h87
-rw-r--r--arch/powerpc/include/asm/opal-api.h3
-rw-r--r--arch/powerpc/include/asm/opal.h6
-rw-r--r--arch/powerpc/include/asm/paca.h29
-rw-r--r--arch/powerpc/include/asm/page.h131
-rw-r--r--arch/powerpc/include/asm/page_32.h17
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h11
-rw-r--r--arch/powerpc/include/asm/pci.h6
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h10
-rw-r--r--arch/powerpc/include/asm/pgalloc-32.h34
-rw-r--r--arch/powerpc/include/asm/pgalloc-64.h63
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc32.h340
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-4k.h88
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-64k.h44
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h618
-rw-r--r--arch/powerpc/include/asm/pgtable-types.h103
-rw-r--r--arch/powerpc/include/asm/pgtable.h209
-rw-r--r--arch/powerpc/include/asm/plpar_wrappers.h17
-rw-r--r--arch/powerpc/include/asm/pmac_feature.h2
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h18
-rw-r--r--arch/powerpc/include/asm/processor.h11
-rw-r--r--arch/powerpc/include/asm/pte-40x.h64
-rw-r--r--arch/powerpc/include/asm/pte-44x.h97
-rw-r--r--arch/powerpc/include/asm/pte-8xx.h65
-rw-r--r--arch/powerpc/include/asm/pte-book3e.h87
-rw-r--r--arch/powerpc/include/asm/pte-common.h5
-rw-r--r--arch/powerpc/include/asm/pte-fsl-booke.h40
-rw-r--r--arch/powerpc/include/asm/pte-hash32.h46
-rw-r--r--arch/powerpc/include/asm/pte-hash64-4k.h17
-rw-r--r--arch/powerpc/include/asm/pte-hash64-64k.h102
-rw-r--r--arch/powerpc/include/asm/pte-hash64.h54
-rw-r--r--arch/powerpc/include/asm/qe.h740
-rw-r--r--arch/powerpc/include/asm/qe_ic.h139
-rw-r--r--arch/powerpc/include/asm/reg.h36
-rw-r--r--arch/powerpc/include/asm/reg_8xx.h93
-rw-r--r--arch/powerpc/include/asm/reg_booke.h8
-rw-r--r--arch/powerpc/include/asm/rtas.h3
-rw-r--r--arch/powerpc/include/asm/sections.h12
-rw-r--r--arch/powerpc/include/asm/smp.h8
-rw-r--r--arch/powerpc/include/asm/smu.h2
-rw-r--r--arch/powerpc/include/asm/switch_to.h70
-rw-r--r--arch/powerpc/include/asm/synch.h2
-rw-r--r--arch/powerpc/include/asm/systbl.h14
-rw-r--r--arch/powerpc/include/asm/time.h7
-rw-r--r--arch/powerpc/include/asm/tlbflush.h92
-rw-r--r--arch/powerpc/include/asm/trace.h8
-rw-r--r--arch/powerpc/include/asm/uaccess.h15
-rw-r--r--arch/powerpc/include/asm/ucc.h64
-rw-r--r--arch/powerpc/include/asm/ucc_fast.h244
-rw-r--r--arch/powerpc/include/asm/ucc_slow.h277
-rw-r--r--arch/powerpc/include/asm/uninorth.h2
-rw-r--r--arch/powerpc/include/asm/unistd.h3
-rw-r--r--arch/powerpc/include/asm/vdso_datapage.h2
-rw-r--r--arch/powerpc/include/asm/xics.h3
-rw-r--r--arch/powerpc/include/uapi/asm/cputable.h2
-rw-r--r--arch/powerpc/include/uapi/asm/elf.h2
-rw-r--r--arch/powerpc/include/uapi/asm/epapr_hcalls.h4
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h9
-rw-r--r--arch/powerpc/include/uapi/asm/mman.h1
-rw-r--r--arch/powerpc/include/uapi/asm/socket.h5
-rw-r--r--arch/powerpc/include/uapi/asm/unistd.h2
-rw-r--r--arch/powerpc/kernel/Makefile20
-rw-r--r--arch/powerpc/kernel/align.c2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c13
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S112
-rw-r--r--arch/powerpc/kernel/cpu_setup_power.S49
-rw-r--r--arch/powerpc/kernel/cputable.c31
-rw-r--r--arch/powerpc/kernel/crash.c6
-rw-r--r--arch/powerpc/kernel/eeh.c47
-rw-r--r--arch/powerpc/kernel/eeh_cache.c11
-rw-r--r--arch/powerpc/kernel/eeh_dev.c1
-rw-r--r--arch/powerpc/kernel/eeh_driver.c161
-rw-r--r--arch/powerpc/kernel/eeh_pe.c71
-rw-r--r--arch/powerpc/kernel/entry_64.S285
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S17
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S77
-rw-r--r--arch/powerpc/kernel/fadump.c4
-rw-r--r--arch/powerpc/kernel/fpu.S94
-rw-r--r--arch/powerpc/kernel/ftrace.c132
-rw-r--r--arch/powerpc/kernel/head_44x.S2
-rw-r--r--arch/powerpc/kernel/head_64.S141
-rw-r--r--arch/powerpc/kernel/head_8xx.S108
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S116
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c3
-rw-r--r--arch/powerpc/kernel/idle_power7.S9
-rw-r--r--arch/powerpc/kernel/io-workarounds.c2
-rw-r--r--arch/powerpc/kernel/kgdb.c4
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c18
-rw-r--r--arch/powerpc/kernel/mce_power.c17
-rw-r--r--arch/powerpc/kernel/misc_32.S109
-rw-r--r--arch/powerpc/kernel/misc_64.S88
-rw-r--r--arch/powerpc/kernel/module.c5
-rw-r--r--arch/powerpc/kernel/module_32.c24
-rw-r--r--arch/powerpc/kernel/module_64.c255
-rw-r--r--arch/powerpc/kernel/nvram_64.c34
-rw-r--r--arch/powerpc/kernel/paca.c20
-rw-r--r--arch/powerpc/kernel/pci-common.c1
-rw-r--r--arch/powerpc/kernel/pci-hotplug.c2
-rw-r--r--arch/powerpc/kernel/pci_dn.c19
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c3
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c12
-rw-r--r--arch/powerpc/kernel/ppc_ksyms_32.c1
-rw-r--r--arch/powerpc/kernel/process.c711
-rw-r--r--arch/powerpc/kernel/prom.c18
-rw-r--r--arch/powerpc/kernel/prom_init.c41
-rw-r--r--arch/powerpc/kernel/ptrace.c1
-rw-r--r--arch/powerpc/kernel/rtas.c59
-rw-r--r--arch/powerpc/kernel/rtasd.c9
-rw-r--r--arch/powerpc/kernel/setup_32.c2
-rw-r--r--arch/powerpc/kernel/setup_64.c28
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/signal.h2
-rw-r--r--arch/powerpc/kernel/signal_32.c36
-rw-r--r--arch/powerpc/kernel/signal_64.c26
-rw-r--r--arch/powerpc/kernel/smp.c37
-rw-r--r--arch/powerpc/kernel/stacktrace.c7
-rw-r--r--arch/powerpc/kernel/swsusp.c4
-rw-r--r--arch/powerpc/kernel/systbl_chk.c2
-rw-r--r--arch/powerpc/kernel/systbl_chk.sh2
-rw-r--r--arch/powerpc/kernel/time.c36
-rw-r--r--arch/powerpc/kernel/traps.c24
-rw-r--r--arch/powerpc/kernel/vdso.c2
-rw-r--r--arch/powerpc/kernel/vdso32/Makefile3
-rw-r--r--arch/powerpc/kernel/vdso32/datapage.S14
-rw-r--r--arch/powerpc/kernel/vdso64/Makefile3
-rw-r--r--arch/powerpc/kernel/vdso64/datapage.S14
-rw-r--r--arch/powerpc/kernel/vector.S153
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S6
-rw-r--r--arch/powerpc/kvm/Makefile2
-rw-r--r--arch/powerpc/kvm/book3s.c8
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu_host.c4
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c5
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c4
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c7
-rw-r--r--arch/powerpc/kvm/book3s_64_vio.c158
-rw-r--r--arch/powerpc/kvm/book3s_64_vio_hv.c332
-rw-r--r--arch/powerpc/kvm/book3s_hv.c256
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c3
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c12
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_xics.c131
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S73
-rw-r--r--arch/powerpc/kvm/book3s_paired_singles.c1
-rw-r--r--arch/powerpc/kvm/book3s_pr.c25
-rw-r--r--arch/powerpc/kvm/book3s_pr_papr.c35
-rw-r--r--arch/powerpc/kvm/book3s_xics.c2
-rw-r--r--arch/powerpc/kvm/booke.c6
-rw-r--r--arch/powerpc/kvm/e500.c3
-rw-r--r--arch/powerpc/kvm/e500.h2
-rw-r--r--arch/powerpc/kvm/e500_emulate.c19
-rw-r--r--arch/powerpc/kvm/e500_mmu_host.c14
-rw-r--r--arch/powerpc/kvm/e500mc.c2
-rw-r--r--arch/powerpc/kvm/powerpc.c61
-rw-r--r--arch/powerpc/kvm/trace_pr.h2
-rw-r--r--arch/powerpc/lib/Makefile7
-rw-r--r--arch/powerpc/lib/checksum_32.S398
-rw-r--r--arch/powerpc/lib/checksum_64.S31
-rw-r--r--arch/powerpc/lib/checksum_wrappers.c (renamed from arch/powerpc/lib/checksum_wrappers_64.c)0
-rw-r--r--arch/powerpc/lib/ppc_ksyms.c4
-rw-r--r--arch/powerpc/lib/vmx-helper.c2
-rw-r--r--arch/powerpc/lib/xor_vmx.c4
-rw-r--r--arch/powerpc/mm/40x_mmu.c10
-rw-r--r--arch/powerpc/mm/8xx_mmu.c141
-rw-r--r--arch/powerpc/mm/Makefile10
-rw-r--r--arch/powerpc/mm/dma-noncoherent.c2
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c32
-rw-r--r--arch/powerpc/mm/hash64_4k.c123
-rw-r--r--arch/powerpc/mm/hash64_64k.c327
-rw-r--r--arch/powerpc/mm/hash_low_64.S1003
-rw-r--r--arch/powerpc/mm/hash_native_64.c10
-rw-r--r--arch/powerpc/mm/hash_utils_64.c239
-rw-r--r--arch/powerpc/mm/hugepage-hash64.c37
-rw-r--r--arch/powerpc/mm/hugetlbpage-book3e.c59
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c38
-rw-r--r--arch/powerpc/mm/hugetlbpage.c98
-rw-r--r--arch/powerpc/mm/init_32.c31
-rw-r--r--arch/powerpc/mm/init_64.c72
-rw-r--r--arch/powerpc/mm/mem.c16
-rw-r--r--arch/powerpc/mm/mmap.c4
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c3
-rw-r--r--arch/powerpc/mm/mmu_decl.h33
-rw-r--r--arch/powerpc/mm/numa.c7
-rw-r--r--arch/powerpc/mm/pgtable.c12
-rw-r--r--arch/powerpc/mm/pgtable_32.c52
-rw-r--r--arch/powerpc/mm/pgtable_64.c118
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c4
-rw-r--r--arch/powerpc/mm/slb.c51
-rw-r--r--arch/powerpc/mm/slice.c3
-rw-r--r--arch/powerpc/mm/subpage-prot.c2
-rw-r--r--arch/powerpc/mm/tlb_hash64.c9
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S27
-rw-r--r--arch/powerpc/mm/tlb_nohash.c39
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S67
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c15
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c4
-rw-r--r--arch/powerpc/perf/callchain.c2
-rw-r--r--arch/powerpc/perf/core-book3s.c38
-rw-r--r--arch/powerpc/perf/hv-24x7.c399
-rw-r--r--arch/powerpc/perf/hv-24x7.h3
-rw-r--r--arch/powerpc/perf/hv-gpci.c43
-rw-r--r--arch/powerpc/perf/power7-pmu.c18
-rw-r--r--arch/powerpc/perf/power8-events-list.h51
-rw-r--r--arch/powerpc/perf/power8-pmu.c117
-rw-r--r--arch/powerpc/platforms/512x/Kconfig6
-rw-r--r--arch/powerpc/platforms/512x/Makefile1
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_lpbfifo.c540
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c6
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c10
-rw-r--r--arch/powerpc/platforms/83xx/km83xx.c6
-rw-r--r--arch/powerpc/platforms/83xx/misc.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c6
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c6
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c6
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_rdk.c7
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/bsc913x_qds.c8
-rw-r--r--arch/powerpc/platforms/85xx/common.c6
-rw-r--r--arch/powerpc/platforms/85xx/corenet_generic.c13
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c15
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c6
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c106
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_rdb.c6
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p1022_rdk.c2
-rw-r--r--arch/powerpc/platforms/85xx/smp.c362
-rw-r--r--arch/powerpc/platforms/85xx/smp.h1
-rw-r--r--arch/powerpc/platforms/85xx/twr_p102x.c6
-rw-r--r--arch/powerpc/platforms/86xx/Makefile2
-rw-r--r--arch/powerpc/platforms/86xx/common.c43
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c32
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c32
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c32
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c22
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx.h2
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c21
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c32
-rw-r--r--arch/powerpc/platforms/Kconfig13
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype11
-rw-r--r--arch/powerpc/platforms/cell/Kconfig7
-rw-r--r--arch/powerpc/platforms/cell/Makefile4
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c2
-rw-r--r--arch/powerpc/platforms/cell/qpace_setup.c148
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c9
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c14
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c2
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc10x.h10
-rw-r--r--arch/powerpc/platforms/maple/Kconfig2
-rw-r--r--arch/powerpc/platforms/maple/time.c2
-rw-r--r--arch/powerpc/platforms/pasemi/Kconfig2
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c3
-rw-r--r--arch/powerpc/platforms/pasemi/msi.c6
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig2
-rw-r--r--arch/powerpc/platforms/powermac/Makefile2
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c1
-rw-r--r--arch/powerpc/platforms/powermac/cache.S2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c6
-rw-r--r--arch/powerpc/platforms/powermac/pic.c3
-rw-r--r--arch/powerpc/platforms/powernv/Makefile3
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c393
-rw-r--r--arch/powerpc/platforms/powernv/idle.c8
-rw-r--r--arch/powerpc/platforms/powernv/npu-dma.c348
-rw-r--r--arch/powerpc/platforms/powernv/opal-irqchip.c66
-rw-r--r--arch/powerpc/platforms/powernv/opal-kmsg.c75
-rw-r--r--arch/powerpc/platforms/powernv/opal-msglog.c34
-rw-r--r--arch/powerpc/platforms/powernv/opal-prd.c1
-rw-r--r--arch/powerpc/platforms/powernv/opal-rtc.c5
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/opal-xscom.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal.c50
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c564
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c271
-rw-r--r--arch/powerpc/platforms/powernv/pci.c49
-rw-r--r--arch/powerpc/platforms/powernv/pci.h170
-rw-r--r--arch/powerpc/platforms/powernv/setup.c33
-rw-r--r--arch/powerpc/platforms/powernv/smp.c74
-rw-r--r--arch/powerpc/platforms/powernv/subcore.c2
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig2
-rw-r--r--arch/powerpc/platforms/ps3/gelic_udbg.c72
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c2
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig7
-rw-r--r--arch/powerpc/platforms/pseries/Makefile7
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c228
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c60
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c560
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvcserver.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c10
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c73
-rw-r--r--arch/powerpc/platforms/pseries/of_helpers.c38
-rw-r--r--arch/powerpc/platforms/pseries/of_helpers.h8
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h9
-rw-r--r--arch/powerpc/platforms/pseries/ras.c55
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c34
-rw-r--r--arch/powerpc/platforms/pseries/setup.c20
-rwxr-xr-xarch/powerpc/scripts/gcc-check-mprofile-kernel.sh23
-rw-r--r--arch/powerpc/sysdev/Kconfig5
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/axonram.c15
-rw-r--r--arch/powerpc/sysdev/cpm1.c5
-rw-r--r--arch/powerpc/sysdev/cpm_common.c157
-rw-r--r--arch/powerpc/sysdev/ehv_pic.c3
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c51
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c2
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c131
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h9
-rw-r--r--arch/powerpc/sysdev/fsl_rcpm.c386
-rw-r--r--arch/powerpc/sysdev/fsl_rmu.c2
-rw-r--r--arch/powerpc/sysdev/i8259.c5
-rw-r--r--arch/powerpc/sysdev/ipic.c3
-rw-r--r--arch/powerpc/sysdev/mpc5xxx_clocks.c5
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c30
-rw-r--r--arch/powerpc/sysdev/mpic_msi.c2
-rw-r--r--arch/powerpc/sysdev/msi_bitmap.c18
-rw-r--r--arch/powerpc/sysdev/ppc4xx_gpio.c2
-rw-r--r--arch/powerpc/sysdev/qe_lib/Kconfig27
-rw-r--r--arch/powerpc/sysdev/qe_lib/Makefile10
-rw-r--r--arch/powerpc/sysdev/qe_lib/gpio.c317
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c706
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c501
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.h103
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_io.c192
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c212
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c363
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c374
-rw-r--r--arch/powerpc/sysdev/qe_lib/usb.c56
-rw-r--r--arch/powerpc/sysdev/simple_gpio.c2
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c21
-rw-r--r--arch/powerpc/xmon/Makefile1
-rw-r--r--arch/powerpc/xmon/nonstdio.c64
-rw-r--r--arch/powerpc/xmon/nonstdio.h3
-rw-r--r--arch/powerpc/xmon/xmon.c217
-rw-r--r--arch/s390/Kconfig29
-rw-r--r--arch/s390/Kconfig.debug12
-rw-r--r--arch/s390/Makefile9
-rw-r--r--arch/s390/configs/default_defconfig27
-rw-r--r--arch/s390/configs/gcov_defconfig24
-rw-r--r--arch/s390/configs/performance_defconfig24
-rw-r--r--arch/s390/configs/zfcpdump_defconfig10
-rw-r--r--arch/s390/crypto/aes_s390.c6
-rw-r--r--arch/s390/crypto/sha.h2
-rw-r--r--arch/s390/defconfig30
-rw-r--r--arch/s390/hypfs/hypfs_diag.c10
-rw-r--r--arch/s390/hypfs/hypfs_diag0c.c2
-rw-r--r--arch/s390/hypfs/hypfs_sprp.c9
-rw-r--r--arch/s390/hypfs/hypfs_vm.c2
-rw-r--r--arch/s390/hypfs/inode.c8
-rw-r--r--arch/s390/include/asm/appldata.h2
-rw-r--r--arch/s390/include/asm/atomic.h2
-rw-r--r--arch/s390/include/asm/barrier.h33
-rw-r--r--arch/s390/include/asm/bitops.h55
-rw-r--r--arch/s390/include/asm/checksum.h6
-rw-r--r--arch/s390/include/asm/cio.h11
-rw-r--r--arch/s390/include/asm/clp.h27
-rw-r--r--arch/s390/include/asm/cmb.h1
-rw-r--r--arch/s390/include/asm/cmpxchg.h30
-rw-r--r--arch/s390/include/asm/compat.h2
-rw-r--r--arch/s390/include/asm/cpu_mf.h5
-rw-r--r--arch/s390/include/asm/crw.h14
-rw-r--r--arch/s390/include/asm/ctl_reg.h2
-rw-r--r--arch/s390/include/asm/diag.h29
-rw-r--r--arch/s390/include/asm/dma-mapping.h2
-rw-r--r--arch/s390/include/asm/elf.h25
-rw-r--r--arch/s390/include/asm/etr.h10
-rw-r--r--arch/s390/include/asm/facilities_src.h58
-rw-r--r--arch/s390/include/asm/facility.h17
-rw-r--r--arch/s390/include/asm/fpu-internal.h110
-rw-r--r--arch/s390/include/asm/fpu/api.h30
-rw-r--r--arch/s390/include/asm/fpu/internal.h61
-rw-r--r--arch/s390/include/asm/fpu/types.h25
-rw-r--r--arch/s390/include/asm/gmap.h64
-rw-r--r--arch/s390/include/asm/idle.h2
-rw-r--r--arch/s390/include/asm/ipl.h17
-rw-r--r--arch/s390/include/asm/irq.h14
-rw-r--r--arch/s390/include/asm/irqflags.h9
-rw-r--r--arch/s390/include/asm/kvm_host.h105
-rw-r--r--arch/s390/include/asm/kvm_para.h67
-rw-r--r--arch/s390/include/asm/livepatch.h4
-rw-r--r--arch/s390/include/asm/lowcore.h38
-rw-r--r--arch/s390/include/asm/mmu_context.h16
-rw-r--r--arch/s390/include/asm/nmi.h98
-rw-r--r--arch/s390/include/asm/os_info.h2
-rw-r--r--arch/s390/include/asm/pci.h10
-rw-r--r--arch/s390/include/asm/pci_clp.h30
-rw-r--r--arch/s390/include/asm/pci_dma.h7
-rw-r--r--arch/s390/include/asm/pci_io.h14
-rw-r--r--arch/s390/include/asm/percpu.h1
-rw-r--r--arch/s390/include/asm/perf_event.h2
-rw-r--r--arch/s390/include/asm/pgalloc.h28
-rw-r--r--arch/s390/include/asm/pgtable.h662
-rw-r--r--arch/s390/include/asm/processor.h127
-rw-r--r--arch/s390/include/asm/ptrace.h55
-rw-r--r--arch/s390/include/asm/reset.h3
-rw-r--r--arch/s390/include/asm/rwsem.h2
-rw-r--r--arch/s390/include/asm/sclp.h21
-rw-r--r--arch/s390/include/asm/setup.h49
-rw-r--r--arch/s390/include/asm/smp.h2
-rw-r--r--arch/s390/include/asm/spinlock.h3
-rw-r--r--arch/s390/include/asm/switch_to.h2
-rw-r--r--arch/s390/include/asm/sysinfo.h17
-rw-r--r--arch/s390/include/asm/thread_info.h24
-rw-r--r--arch/s390/include/asm/topology.h6
-rw-r--r--arch/s390/include/asm/trace/diag.h43
-rw-r--r--arch/s390/include/asm/vdso.h6
-rw-r--r--arch/s390/include/asm/xor.h21
-rw-r--r--arch/s390/include/uapi/asm/clp.h28
-rw-r--r--arch/s390/include/uapi/asm/kvm.h13
-rw-r--r--arch/s390/include/uapi/asm/sie.h1
-rw-r--r--arch/s390/include/uapi/asm/socket.h5
-rw-r--r--arch/s390/include/uapi/asm/unistd.h20
-rw-r--r--arch/s390/kernel/Makefile10
-rw-r--r--arch/s390/kernel/asm-offsets.c294
-rw-r--r--arch/s390/kernel/compat_signal.c9
-rw-r--r--arch/s390/kernel/compat_wrapper.c2
-rw-r--r--arch/s390/kernel/cpcmd.c5
-rw-r--r--arch/s390/kernel/crash_dump.c466
-rw-r--r--arch/s390/kernel/debug.c8
-rw-r--r--arch/s390/kernel/diag.c134
-rw-r--r--arch/s390/kernel/dis.c4
-rw-r--r--arch/s390/kernel/dumpstack.c102
-rw-r--r--arch/s390/kernel/early.c33
-rw-r--r--arch/s390/kernel/entry.S321
-rw-r--r--arch/s390/kernel/entry.h3
-rw-r--r--arch/s390/kernel/ftrace.c2
-rw-r--r--arch/s390/kernel/head.S142
-rw-r--r--arch/s390/kernel/head64.S7
-rw-r--r--arch/s390/kernel/ipl.c99
-rw-r--r--arch/s390/kernel/irq.c4
-rw-r--r--arch/s390/kernel/kprobes.c16
-rw-r--r--arch/s390/kernel/machine_kexec.c110
-rw-r--r--arch/s390/kernel/module.c22
-rw-r--r--arch/s390/kernel/nmi.c120
-rw-r--r--arch/s390/kernel/os_info.c7
-rw-r--r--arch/s390/kernel/perf_cpum_cf.c37
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c13
-rw-r--r--arch/s390/kernel/perf_event.c60
-rw-r--r--arch/s390/kernel/process.c55
-rw-r--r--arch/s390/kernel/processor.c11
-rw-r--r--arch/s390/kernel/ptrace.c58
-rw-r--r--arch/s390/kernel/reipl.S94
-rw-r--r--arch/s390/kernel/runtime_instr.c64
-rw-r--r--arch/s390/kernel/s390_ksyms.c3
-rw-r--r--arch/s390/kernel/sclp.c67
-rw-r--r--arch/s390/kernel/setup.c61
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c171
-rw-r--r--arch/s390/kernel/stacktrace.c109
-rw-r--r--arch/s390/kernel/syscalls.S2
-rw-r--r--arch/s390/kernel/sysinfo.c20
-rw-r--r--arch/s390/kernel/time.c45
-rw-r--r--arch/s390/kernel/topology.c35
-rw-r--r--arch/s390/kernel/trace.c32
-rw-r--r--arch/s390/kernel/traps.c74
-rw-r--r--arch/s390/kernel/vdso.c17
-rw-r--r--arch/s390/kernel/vdso32/Makefile2
-rw-r--r--arch/s390/kernel/vdso32/getcpu.S43
-rw-r--r--arch/s390/kernel/vdso32/vdso32.lds.S1
-rw-r--r--arch/s390/kernel/vdso64/Makefile2
-rw-r--r--arch/s390/kernel/vdso64/getcpu.S42
-rw-r--r--arch/s390/kernel/vdso64/vdso64.lds.S1
-rw-r--r--arch/s390/kvm/Kconfig1
-rw-r--r--arch/s390/kvm/Makefile2
-rw-r--r--arch/s390/kvm/diag.c12
-rw-r--r--arch/s390/kvm/gaccess.c95
-rw-r--r--arch/s390/kvm/gaccess.h38
-rw-r--r--arch/s390/kvm/guestdbg.c8
-rw-r--r--arch/s390/kvm/intercept.c123
-rw-r--r--arch/s390/kvm/interrupt.c354
-rw-r--r--arch/s390/kvm/kvm-s390.c723
-rw-r--r--arch/s390/kvm/kvm-s390.h70
-rw-r--r--arch/s390/kvm/priv.c39
-rw-r--r--arch/s390/kvm/sigp.c8
-rw-r--r--arch/s390/kvm/trace-s390.h6
-rw-r--r--arch/s390/lib/Makefile2
-rw-r--r--arch/s390/lib/delay.c30
-rw-r--r--arch/s390/lib/find.c4
-rw-r--r--arch/s390/lib/spinlock.c49
-rw-r--r--arch/s390/lib/xor.c134
-rw-r--r--arch/s390/mm/Makefile4
-rw-r--r--arch/s390/mm/extable.c8
-rw-r--r--arch/s390/mm/extmem.c23
-rw-r--r--arch/s390/mm/fault.c31
-rw-r--r--arch/s390/mm/gmap.c774
-rw-r--r--arch/s390/mm/gup.c25
-rw-r--r--arch/s390/mm/hugetlbpage.c9
-rw-r--r--arch/s390/mm/init.c32
-rw-r--r--arch/s390/mm/maccess.c16
-rw-r--r--arch/s390/mm/mem_detect.c7
-rw-r--r--arch/s390/mm/mmap.c72
-rw-r--r--arch/s390/mm/pageattr.c8
-rw-r--r--arch/s390/mm/pgalloc.c360
-rw-r--r--arch/s390/mm/pgtable.c1547
-rw-r--r--arch/s390/mm/vmem.c10
-rw-r--r--arch/s390/net/bpf_jit_comp.c15
-rw-r--r--arch/s390/numa/mode_emu.c10
-rw-r--r--arch/s390/numa/numa.c6
-rw-r--r--arch/s390/oprofile/Makefile2
-rw-r--r--arch/s390/oprofile/backtrace.c77
-rw-r--r--arch/s390/oprofile/init.c21
-rw-r--r--arch/s390/pci/pci.c75
-rw-r--r--arch/s390/pci/pci_clp.c247
-rw-r--r--arch/s390/pci/pci_debug.c5
-rw-r--r--arch/s390/pci/pci_dma.c154
-rw-r--r--arch/s390/pci/pci_event.c18
-rw-r--r--arch/s390/pci/pci_insn.c6
-rw-r--r--arch/s390/tools/.gitignore1
-rw-r--r--arch/s390/tools/Makefile15
-rw-r--r--arch/s390/tools/gen_facilities.c67
-rw-r--r--arch/score/configs/spct6600_defconfig1
-rw-r--r--arch/score/include/asm/checksum.h15
-rw-r--r--arch/score/kernel/setup.c2
-rw-r--r--arch/sh/Kconfig9
-rw-r--r--arch/sh/boards/Kconfig15
-rw-r--r--arch/sh/boards/Makefile2
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c6
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c10
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c4
-rw-r--r--arch/sh/boards/mach-migor/setup.c8
-rw-r--r--arch/sh/boards/mach-rsk/setup.c3
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c6
-rw-r--r--arch/sh/boards/of-generic.c196
-rw-r--r--arch/sh/boot/compressed/Makefile2
-rw-r--r--arch/sh/include/asm/Kbuild1
-rw-r--r--arch/sh/include/asm/atomic.h4
-rw-r--r--arch/sh/include/asm/barrier.h2
-rw-r--r--arch/sh/include/asm/checksum_32.h9
-rw-r--r--arch/sh/include/asm/clkdev.h33
-rw-r--r--arch/sh/include/asm/cmpxchg-grb.h22
-rw-r--r--arch/sh/include/asm/cmpxchg-irq.h11
-rw-r--r--arch/sh/include/asm/cmpxchg-llsc.h25
-rw-r--r--arch/sh/include/asm/cmpxchg-xchg.h51
-rw-r--r--arch/sh/include/asm/cmpxchg.h3
-rw-r--r--arch/sh/include/asm/dma-mapping.h2
-rw-r--r--arch/sh/include/asm/pci.h3
-rw-r--r--arch/sh/include/asm/smp.h10
-rw-r--r--arch/sh/include/mach-common/mach/magicpanelr2.h2
-rw-r--r--arch/sh/include/uapi/asm/unistd_64.h2
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c1
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S8
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7264.c9
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7269.c16
-rw-r--r--arch/sh/kernel/cpu/sh2a/entry.S8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7734.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c12
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7734.c12
-rw-r--r--arch/sh/kernel/cpu/sh5/unwind.c2
-rw-r--r--arch/sh/kernel/entry-common.S21
-rw-r--r--arch/sh/kernel/ftrace.c12
-rw-r--r--arch/sh/kernel/head_32.S13
-rw-r--r--arch/sh/kernel/localtimer.c60
-rw-r--r--arch/sh/kernel/perf_event.c2
-rw-r--r--arch/sh/kernel/setup.c35
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c3
-rw-r--r--arch/sh/kernel/smp.c26
-rw-r--r--arch/sh/kernel/traps_64.c2
-rw-r--r--arch/sh/lib/ashlsi3.S35
-rw-r--r--arch/sh/lib/ashrsi3.S33
-rw-r--r--arch/sh/lib/lshrsi3.S34
-rw-r--r--arch/sh/mm/cache-sh4.c2
-rw-r--r--arch/sh/mm/cache.c8
-rw-r--r--arch/sh/mm/hugetlbpage.c2
-rw-r--r--arch/sh/mm/kmap.c2
-rw-r--r--arch/sparc/Kconfig5
-rw-r--r--arch/sparc/Makefile6
-rw-r--r--arch/sparc/configs/sparc64_defconfig1
-rw-r--r--arch/sparc/include/asm/atomic_64.h8
-rw-r--r--arch/sparc/include/asm/barrier_32.h1
-rw-r--r--arch/sparc/include/asm/barrier_64.h29
-rw-r--r--arch/sparc/include/asm/checksum_32.h13
-rw-r--r--arch/sparc/include/asm/checksum_64.h9
-rw-r--r--arch/sparc/include/asm/dma-mapping.h17
-rw-r--r--arch/sparc/include/asm/elf_64.h1
-rw-r--r--arch/sparc/include/asm/gpio.h4
-rw-r--r--arch/sparc/include/asm/pci.h3
-rw-r--r--arch/sparc/include/asm/pgtable_64.h19
-rw-r--r--arch/sparc/include/asm/processor.h3
-rw-r--r--arch/sparc/include/asm/topology_64.h3
-rw-r--r--arch/sparc/include/asm/uaccess_32.h65
-rw-r--r--arch/sparc/include/asm/uaccess_64.h40
-rw-r--r--arch/sparc/include/uapi/asm/asi.h2
-rw-r--r--arch/sparc/include/uapi/asm/mman.h1
-rw-r--r--arch/sparc/include/uapi/asm/socket.h5
-rw-r--r--arch/sparc/include/uapi/asm/unistd.h9
-rw-r--r--arch/sparc/kernel/entry.S17
-rw-r--r--arch/sparc/kernel/head_64.S21
-rw-r--r--arch/sparc/kernel/hvcalls.S3
-rw-r--r--arch/sparc/kernel/idprom.c7
-rw-r--r--arch/sparc/kernel/iommu.c12
-rw-r--r--arch/sparc/kernel/ldc.c2
-rw-r--r--arch/sparc/kernel/mdesc.c20
-rw-r--r--arch/sparc/kernel/pci.c7
-rw-r--r--arch/sparc/kernel/pci_common.c17
-rw-r--r--arch/sparc/kernel/pci_impl.h1
-rw-r--r--arch/sparc/kernel/pci_sun4v.c18
-rw-r--r--arch/sparc/kernel/perf_event.c45
-rw-r--r--arch/sparc/kernel/rtrap_64.S8
-rw-r--r--arch/sparc/kernel/setup_64.c9
-rw-r--r--arch/sparc/kernel/signal_64.c2
-rw-r--r--arch/sparc/kernel/smp_32.c2
-rw-r--r--arch/sparc/kernel/smp_64.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms_64.c1
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c4
-rw-r--r--arch/sparc/kernel/syscalls.S36
-rw-r--r--arch/sparc/kernel/systbls_32.S19
-rw-r--r--arch/sparc/kernel/systbls_64.S18
-rw-r--r--arch/sparc/kernel/unaligned_64.c22
-rw-r--r--arch/sparc/lib/NG2copy_from_user.S8
-rw-r--r--arch/sparc/lib/NG2copy_to_user.S8
-rw-r--r--arch/sparc/lib/NG2memcpy.S118
-rw-r--r--arch/sparc/lib/NG4copy_from_user.S8
-rw-r--r--arch/sparc/lib/NG4copy_to_user.S8
-rw-r--r--arch/sparc/lib/NG4memcpy.S40
-rw-r--r--arch/sparc/lib/U1copy_from_user.S8
-rw-r--r--arch/sparc/lib/U1copy_to_user.S8
-rw-r--r--arch/sparc/lib/U1memcpy.S48
-rw-r--r--arch/sparc/lib/U3copy_from_user.S8
-rw-r--r--arch/sparc/lib/U3copy_to_user.S8
-rw-r--r--arch/sparc/lib/U3memcpy.S86
-rw-r--r--arch/sparc/lib/VISsave.S10
-rw-r--r--arch/sparc/mm/fault_64.c3
-rw-r--r--arch/sparc/mm/gup.c16
-rw-r--r--arch/sparc/mm/hugetlbpage.c2
-rw-r--r--arch/sparc/mm/init_64.c79
-rw-r--r--arch/sparc/net/bpf_jit_comp.c19
-rw-r--r--arch/tile/Kconfig21
-rw-r--r--arch/tile/configs/tilegx_defconfig3
-rw-r--r--arch/tile/configs/tilepro_defconfig3
-rw-r--r--arch/tile/include/asm/atomic.h2
-rw-r--r--arch/tile/include/asm/atomic_64.h6
-rw-r--r--arch/tile/include/asm/barrier.h9
-rw-r--r--arch/tile/include/asm/cmpxchg.h2
-rw-r--r--arch/tile/include/asm/dma-mapping.h32
-rw-r--r--arch/tile/include/asm/highmem.h1
-rw-r--r--arch/tile/include/asm/insn.h59
-rw-r--r--arch/tile/include/asm/io.h16
-rw-r--r--arch/tile/include/asm/jump_label.h58
-rw-r--r--arch/tile/include/asm/page.h18
-rw-r--r--arch/tile/include/asm/pci.h3
-rw-r--r--arch/tile/include/asm/pgtable.h10
-rw-r--r--arch/tile/include/asm/processor.h2
-rw-r--r--arch/tile/include/asm/thread_info.h8
-rw-r--r--arch/tile/include/asm/topology.h3
-rw-r--r--arch/tile/include/uapi/asm/mman.h1
-rw-r--r--arch/tile/kernel/Makefile1
-rw-r--r--arch/tile/kernel/ftrace.c13
-rw-r--r--arch/tile/kernel/intvec_32.S51
-rw-r--r--arch/tile/kernel/intvec_64.S56
-rw-r--r--arch/tile/kernel/jump_label.c64
-rw-r--r--arch/tile/kernel/kgdb.c2
-rw-r--r--arch/tile/kernel/kprobes.c4
-rw-r--r--arch/tile/kernel/pci-dma.c29
-rw-r--r--arch/tile/kernel/perf_event.c2
-rw-r--r--arch/tile/kernel/process.c79
-rw-r--r--arch/tile/kernel/ptrace.c15
-rw-r--r--arch/tile/kernel/setup.c13
-rw-r--r--arch/tile/kernel/single_step.c3
-rw-r--r--arch/tile/kernel/smpboot.c2
-rw-r--r--arch/tile/kernel/stack.c17
-rw-r--r--arch/tile/kernel/traps.c13
-rw-r--r--arch/tile/kernel/unaligned.c13
-rw-r--r--arch/tile/mm/fault.c3
-rw-r--r--arch/tile/mm/highmem.c12
-rw-r--r--arch/tile/mm/hugetlbpage.c2
-rw-r--r--arch/tile/mm/init.c11
-rw-r--r--arch/um/Kconfig.common1
-rw-r--r--arch/um/Kconfig.um16
-rw-r--r--arch/um/drivers/hostaudio_kern.c10
-rw-r--r--arch/um/drivers/mconsole_kern.c14
-rw-r--r--arch/um/drivers/net_kern.c17
-rw-r--r--arch/um/drivers/net_user.c10
-rw-r--r--arch/um/drivers/ubd_kern.c27
-rw-r--r--arch/um/include/asm/hardirq.h23
-rw-r--r--arch/um/include/asm/page.h30
-rw-r--r--arch/um/include/asm/pgtable-3level.h4
-rw-r--r--arch/um/include/asm/pgtable.h2
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/include/asm/syscall-generic.h138
-rw-r--r--arch/um/include/asm/thread_info.h2
-rw-r--r--arch/um/include/shared/os.h20
-rw-r--r--arch/um/include/shared/skas/stub-data.h7
-rw-r--r--arch/um/include/shared/timer-internal.h13
-rw-r--r--arch/um/kernel/process.c8
-rw-r--r--arch/um/kernel/reboot.c1
-rw-r--r--arch/um/kernel/skas/clone.c6
-rw-r--r--arch/um/kernel/skas/mmu.c5
-rw-r--r--arch/um/kernel/skas/syscall.c40
-rw-r--r--arch/um/kernel/time.c73
-rw-r--r--arch/um/kernel/tlb.c16
-rw-r--r--arch/um/os-Linux/file.c19
-rw-r--r--arch/um/os-Linux/internal.h1
-rw-r--r--arch/um/os-Linux/main.c7
-rw-r--r--arch/um/os-Linux/mem.c17
-rw-r--r--arch/um/os-Linux/process.c6
-rw-r--r--arch/um/os-Linux/signal.c55
-rw-r--r--arch/um/os-Linux/skas/process.c48
-rw-r--r--arch/um/os-Linux/start_up.c2
-rw-r--r--arch/um/os-Linux/time.c249
-rw-r--r--arch/unicore32/Kconfig7
-rw-r--r--arch/unicore32/Kconfig.debug14
-rw-r--r--arch/unicore32/include/asm/checksum.h4
-rw-r--r--arch/unicore32/include/asm/dma-mapping.h2
-rw-r--r--arch/unicore32/include/asm/pci.h3
-rw-r--r--arch/unicore32/include/mach/hardware.h5
-rw-r--r--arch/unicore32/kernel/gpio.c2
-rw-r--r--arch/unicore32/kernel/puv3-nb0916.c10
-rw-r--r--arch/unicore32/kernel/setup.c6
-rw-r--r--arch/unicore32/mm/fault.c2
-rw-r--r--arch/unicore32/mm/pgd.c2
-rw-r--r--arch/x86/Kbuild3
-rw-r--r--arch/x86/Kconfig164
-rw-r--r--arch/x86/Kconfig.cpu24
-rw-r--r--arch/x86/Kconfig.debug80
-rw-r--r--arch/x86/Makefile12
-rw-r--r--arch/x86/boot/Makefile5
-rw-r--r--arch/x86/boot/boot.h1
-rw-r--r--arch/x86/boot/compressed/Makefile1
-rw-r--r--arch/x86/boot/compressed/eboot.c28
-rw-r--r--arch/x86/boot/cpuflags.h2
-rw-r--r--arch/x86/boot/header.S2
-rw-r--r--arch/x86/boot/mkcpustr.c2
-rw-r--r--arch/x86/boot/tools/build.c1
-rw-r--r--arch/x86/boot/video-mode.c2
-rw-r--r--arch/x86/boot/video.c2
-rw-r--r--arch/x86/configs/i386_defconfig3
-rw-r--r--arch/x86/configs/x86_64_defconfig1
-rw-r--r--arch/x86/crypto/Makefile8
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c11
-rw-r--r--arch/x86/crypto/camellia_aesni_avx2_glue.c3
-rw-r--r--arch/x86/crypto/camellia_aesni_avx_glue.c3
-rw-r--r--arch/x86/crypto/camellia_glue.c10
-rw-r--r--arch/x86/crypto/cast5_avx_glue.c3
-rw-r--r--arch/x86/crypto/cast6_avx_glue.c13
-rw-r--r--arch/x86/crypto/chacha20-ssse3-x86_64.S6
-rw-r--r--arch/x86/crypto/chacha20_glue.c4
-rw-r--r--arch/x86/crypto/crc32-pclmul_glue.c2
-rw-r--r--arch/x86/crypto/crc32c-intel_glue.c4
-rw-r--r--arch/x86/crypto/crc32c-pcl-intel-asm_64.S2
-rw-r--r--arch/x86/crypto/crct10dif-pclmul_glue.c2
-rw-r--r--arch/x86/crypto/ghash-clmulni-intel_glue.c26
-rw-r--r--arch/x86/crypto/poly1305_glue.c2
-rw-r--r--arch/x86/crypto/serpent_avx2_glue.c3
-rw-r--r--arch/x86/crypto/serpent_avx_glue.c14
-rw-r--r--arch/x86/crypto/serpent_sse2_glue.c11
-rw-r--r--arch/x86/crypto/sha-mb/sha1_mb.c35
-rw-r--r--arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S2
-rw-r--r--arch/x86/crypto/sha1_ni_asm.S302
-rw-r--r--arch/x86/crypto/sha1_ssse3_glue.c316
-rw-r--r--arch/x86/crypto/sha256_ni_asm.S353
-rw-r--r--arch/x86/crypto/sha256_ssse3_glue.c331
-rw-r--r--arch/x86/crypto/sha512_ssse3_glue.c251
-rw-r--r--arch/x86/crypto/twofish_avx_glue.c2
-rw-r--r--arch/x86/crypto/twofish_glue_3way.c10
-rw-r--r--arch/x86/entry/calling.h44
-rw-r--r--arch/x86/entry/common.c308
-rw-r--r--arch/x86/entry/entry_32.S442
-rw-r--r--arch/x86/entry/entry_64.S320
-rw-r--r--arch/x86/entry/entry_64_compat.S656
-rw-r--r--arch/x86/entry/syscall_32.c17
-rw-r--r--arch/x86/entry/syscall_64.c15
-rw-r--r--arch/x86/entry/syscalls/syscall_32.tbl16
-rw-r--r--arch/x86/entry/syscalls/syscall_64.tbl24
-rw-r--r--arch/x86/entry/syscalls/syscalltbl.sh58
-rw-r--r--arch/x86/entry/vdso/Makefile40
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c151
-rw-r--r--arch/x86/entry/vdso/vdso-layout.lds.S3
-rw-r--r--arch/x86/entry/vdso/vdso2c.c5
-rw-r--r--arch/x86/entry/vdso/vdso2c.h9
-rw-r--r--arch/x86/entry/vdso/vdso32-setup.c29
-rw-r--r--arch/x86/entry/vdso/vdso32/int80.S56
-rw-r--r--arch/x86/entry/vdso/vdso32/syscall.S75
-rw-r--r--arch/x86/entry/vdso/vdso32/sysenter.S116
-rw-r--r--arch/x86/entry/vdso/vdso32/system_call.S89
-rw-r--r--arch/x86/entry/vdso/vdso32/vclock_gettime.c2
-rw-r--r--arch/x86/entry/vdso/vma.c128
-rw-r--r--arch/x86/entry/vsyscall/vsyscall_64.c9
-rw-r--r--arch/x86/entry/vsyscall/vsyscall_gtod.c9
-rw-r--r--arch/x86/events/Makefile13
-rw-r--r--arch/x86/events/amd/core.c731
-rw-r--r--arch/x86/events/amd/ibs.c959
-rw-r--r--arch/x86/events/amd/iommu.c499
-rw-r--r--arch/x86/events/amd/iommu.h (renamed from arch/x86/kernel/cpu/perf_event_amd_iommu.h)0
-rw-r--r--arch/x86/events/amd/uncore.c603
-rw-r--r--arch/x86/events/core.c2442
-rw-r--r--arch/x86/events/intel/bts.c544
-rw-r--r--arch/x86/events/intel/core.c3796
-rw-r--r--arch/x86/events/intel/cqm.c1381
-rw-r--r--arch/x86/events/intel/cstate.c694
-rw-r--r--arch/x86/events/intel/ds.c1410
-rw-r--r--arch/x86/events/intel/knc.c321
-rw-r--r--arch/x86/events/intel/lbr.c1062
-rw-r--r--arch/x86/events/intel/p4.c1376
-rw-r--r--arch/x86/events/intel/p6.c279
-rw-r--r--arch/x86/events/intel/pt.c1188
-rw-r--r--arch/x86/events/intel/pt.h (renamed from arch/x86/kernel/cpu/intel_pt.h)0
-rw-r--r--arch/x86/events/intel/rapl.c767
-rw-r--r--arch/x86/events/intel/uncore.c1412
-rw-r--r--arch/x86/events/intel/uncore.h378
-rw-r--r--arch/x86/events/intel/uncore_nhmex.c1227
-rw-r--r--arch/x86/events/intel/uncore_snb.c731
-rw-r--r--arch/x86/events/intel/uncore_snbep.c3135
-rw-r--r--arch/x86/events/msr.c241
-rw-r--r--arch/x86/events/perf_event.h960
-rw-r--r--arch/x86/ia32/ia32_signal.c12
-rw-r--r--arch/x86/include/asm/acpi.h23
-rw-r--r--arch/x86/include/asm/alternative.h6
-rw-r--r--arch/x86/include/asm/amd_nb.h28
-rw-r--r--arch/x86/include/asm/apic.h117
-rw-r--r--arch/x86/include/asm/arch_hweight.h2
-rw-r--r--arch/x86/include/asm/asm.h40
-rw-r--r--arch/x86/include/asm/atomic.h5
-rw-r--r--arch/x86/include/asm/atomic64_32.h1
-rw-r--r--arch/x86/include/asm/atomic64_64.h4
-rw-r--r--arch/x86/include/asm/barrier.h51
-rw-r--r--arch/x86/include/asm/bitops.h36
-rw-r--r--arch/x86/include/asm/boot.h2
-rw-r--r--arch/x86/include/asm/cacheflush.h6
-rw-r--r--arch/x86/include/asm/calgary.h2
-rw-r--r--arch/x86/include/asm/checksum_32.h9
-rw-r--r--arch/x86/include/asm/checksum_64.h10
-rw-r--r--arch/x86/include/asm/clocksource.h9
-rw-r--r--arch/x86/include/asm/cmpxchg.h1
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h2
-rw-r--r--arch/x86/include/asm/cmpxchg_64.h2
-rw-r--r--arch/x86/include/asm/cpu.h3
-rw-r--r--arch/x86/include/asm/cpufeature.h489
-rw-r--r--arch/x86/include/asm/cpufeatures.h300
-rw-r--r--arch/x86/include/asm/desc_defs.h23
-rw-r--r--arch/x86/include/asm/device.h10
-rw-r--r--arch/x86/include/asm/dma-mapping.h2
-rw-r--r--arch/x86/include/asm/dmi.h2
-rw-r--r--arch/x86/include/asm/dwarf2.h84
-rw-r--r--arch/x86/include/asm/efi.h3
-rw-r--r--arch/x86/include/asm/elf.h12
-rw-r--r--arch/x86/include/asm/fixmap.h7
-rw-r--r--arch/x86/include/asm/fpu/internal.h188
-rw-r--r--arch/x86/include/asm/fpu/signal.h2
-rw-r--r--arch/x86/include/asm/fpu/types.h148
-rw-r--r--arch/x86/include/asm/fpu/xstate.h15
-rw-r--r--arch/x86/include/asm/frame.h59
-rw-r--r--arch/x86/include/asm/gpio.h4
-rw-r--r--arch/x86/include/asm/highmem.h1
-rw-r--r--arch/x86/include/asm/hpet.h6
-rw-r--r--arch/x86/include/asm/hw_irq.h5
-rw-r--r--arch/x86/include/asm/i8259.h1
-rw-r--r--arch/x86/include/asm/ia32.h4
-rw-r--r--arch/x86/include/asm/imr.h2
-rw-r--r--arch/x86/include/asm/intel_pt.h10
-rw-r--r--arch/x86/include/asm/intel_punit_ipc.h101
-rw-r--r--arch/x86/include/asm/intel_telemetry.h147
-rw-r--r--arch/x86/include/asm/iosf_mbi.h51
-rw-r--r--arch/x86/include/asm/ipi.h60
-rw-r--r--arch/x86/include/asm/irq.h5
-rw-r--r--arch/x86/include/asm/irq_remapping.h10
-rw-r--r--arch/x86/include/asm/irq_work.h2
-rw-r--r--arch/x86/include/asm/jump_label.h63
-rw-r--r--arch/x86/include/asm/kdebug.h6
-rw-r--r--arch/x86/include/asm/kvm_emulate.h10
-rw-r--r--arch/x86/include/asm/kvm_host.h163
-rw-r--r--arch/x86/include/asm/kvm_page_track.h61
-rw-r--r--arch/x86/include/asm/kvm_para.h7
-rw-r--r--arch/x86/include/asm/lguest.h4
-rw-r--r--arch/x86/include/asm/livepatch.h4
-rw-r--r--arch/x86/include/asm/mce.h104
-rw-r--r--arch/x86/include/asm/microcode.h83
-rw-r--r--arch/x86/include/asm/microcode_amd.h3
-rw-r--r--arch/x86/include/asm/microcode_intel.h11
-rw-r--r--arch/x86/include/asm/mmu.h3
-rw-r--r--arch/x86/include/asm/mmu_context.h34
-rw-r--r--arch/x86/include/asm/msi.h6
-rw-r--r--arch/x86/include/asm/msr-index.h26
-rw-r--r--arch/x86/include/asm/msr-trace.h57
-rw-r--r--arch/x86/include/asm/msr.h43
-rw-r--r--arch/x86/include/asm/mwait.h2
-rw-r--r--arch/x86/include/asm/numachip/numachip.h1
-rw-r--r--arch/x86/include/asm/numachip/numachip_csr.h153
-rw-r--r--arch/x86/include/asm/page_64_types.h3
-rw-r--r--arch/x86/include/asm/page_types.h19
-rw-r--r--arch/x86/include/asm/paravirt.h44
-rw-r--r--arch/x86/include/asm/paravirt_types.h40
-rw-r--r--arch/x86/include/asm/pci.h18
-rw-r--r--arch/x86/include/asm/pci_x86.h12
-rw-r--r--arch/x86/include/asm/perf_event.h1
-rw-r--r--arch/x86/include/asm/pgtable.h90
-rw-r--r--arch/x86/include/asm/pgtable_types.h49
-rw-r--r--arch/x86/include/asm/platform_sst_audio.h1
-rw-r--r--arch/x86/include/asm/pmem.h21
-rw-r--r--arch/x86/include/asm/preempt.h5
-rw-r--r--arch/x86/include/asm/processor.h19
-rw-r--r--arch/x86/include/asm/proto.h15
-rw-r--r--arch/x86/include/asm/pvclock.h14
-rw-r--r--arch/x86/include/asm/qspinlock_paravirt.h59
-rw-r--r--arch/x86/include/asm/reboot.h1
-rw-r--r--arch/x86/include/asm/sections.h2
-rw-r--r--arch/x86/include/asm/sigcontext.h75
-rw-r--r--arch/x86/include/asm/sigframe.h8
-rw-r--r--arch/x86/include/asm/sighandling.h1
-rw-r--r--arch/x86/include/asm/signal.h2
-rw-r--r--arch/x86/include/asm/smap.h2
-rw-r--r--arch/x86/include/asm/smp.h13
-rw-r--r--arch/x86/include/asm/stacktrace.h2
-rw-r--r--arch/x86/include/asm/string_64.h13
-rw-r--r--arch/x86/include/asm/suspend_32.h1
-rw-r--r--arch/x86/include/asm/suspend_64.h1
-rw-r--r--arch/x86/include/asm/switch_to.h12
-rw-r--r--arch/x86/include/asm/syscall.h14
-rw-r--r--arch/x86/include/asm/thread_info.h12
-rw-r--r--arch/x86/include/asm/tlbflush.h58
-rw-r--r--arch/x86/include/asm/topology.h11
-rw-r--r--arch/x86/include/asm/trace/mpx.h7
-rw-r--r--arch/x86/include/asm/tsc.h2
-rw-r--r--arch/x86/include/asm/uaccess.h117
-rw-r--r--arch/x86/include/asm/uaccess_32.h26
-rw-r--r--arch/x86/include/asm/uaccess_64.h96
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h2
-rw-r--r--arch/x86/include/asm/vdso.h14
-rw-r--r--arch/x86/include/asm/vgtod.h6
-rw-r--r--arch/x86/include/asm/vmx.h6
-rw-r--r--arch/x86/include/asm/x86_init.h3
-rw-r--r--arch/x86/include/asm/xen/hypercall.h6
-rw-r--r--arch/x86/include/asm/xen/hypervisor.h5
-rw-r--r--arch/x86/include/asm/xen/page.h8
-rw-r--r--arch/x86/include/asm/xen/pci.h4
-rw-r--r--arch/x86/include/asm/xor_32.h2
-rw-r--r--arch/x86/include/uapi/asm/hyperv.h114
-rw-r--r--arch/x86/include/uapi/asm/mce.h4
-rw-r--r--arch/x86/include/uapi/asm/sigcontext.h503
-rw-r--r--arch/x86/include/uapi/asm/sigcontext32.h73
-rw-r--r--arch/x86/include/uapi/asm/svm.h1
-rw-r--r--arch/x86/include/uapi/asm/ucontext.h53
-rw-r--r--arch/x86/include/uapi/asm/vmx.h4
-rw-r--r--arch/x86/kernel/acpi/boot.c22
-rw-r--r--arch/x86/kernel/acpi/sleep.c7
-rw-r--r--arch/x86/kernel/aperture_64.c12
-rw-r--r--arch/x86/kernel/apic/apic.c67
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c21
-rw-r--r--arch/x86/kernel/apic/apic_noop.c2
-rw-r--r--arch/x86/kernel/apic/apic_numachip.c221
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c10
-rw-r--r--arch/x86/kernel/apic/io_apic.c8
-rw-r--r--arch/x86/kernel/apic/ipi.c78
-rw-r--r--arch/x86/kernel/apic/msi.c8
-rw-r--r--arch/x86/kernel/apic/probe_32.c1
-rw-r--r--arch/x86/kernel/apic/vector.c229
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c9
-rw-r--r--arch/x86/kernel/apic/x2apic_phys.c9
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c6
-rw-r--r--arch/x86/kernel/asm-offsets.c25
-rw-r--r--arch/x86/kernel/asm-offsets_32.c7
-rw-r--r--arch/x86/kernel/asm-offsets_64.c11
-rw-r--r--arch/x86/kernel/cpu/Makefile25
-rw-r--r--arch/x86/kernel/cpu/amd.c47
-rw-r--r--arch/x86/kernel/cpu/bugs_64.c2
-rw-r--r--arch/x86/kernel/cpu/centaur.c14
-rw-r--r--arch/x86/kernel/cpu/common.c166
-rw-r--r--arch/x86/kernel/cpu/cyrix.c11
-rw-r--r--arch/x86/kernel/cpu/hypervisor.c2
-rw-r--r--arch/x86/kernel/cpu/intel.c29
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c18
-rw-r--r--arch/x86/kernel/cpu/match.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c15
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c22
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c212
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c231
-rw-r--r--arch/x86/kernel/cpu/mcheck/p5.c18
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c23
-rw-r--r--arch/x86/kernel/cpu/mcheck/threshold.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/winchip.c5
-rw-r--r--arch/x86/kernel/cpu/microcode/Makefile3
-rw-r--r--arch/x86/kernel/cpu/microcode/amd.c514
-rw-r--r--arch/x86/kernel/cpu/microcode/amd_early.c440
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c232
-rw-r--r--arch/x86/kernel/cpu/microcode/core_early.c170
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c824
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_early.c808
-rw-r--r--arch/x86/kernel/cpu/microcode/intel_lib.c59
-rw-r--r--arch/x86/kernel/cpu/mkcapflags.sh6
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c8
-rw-r--r--arch/x86/kernel/cpu/mtrr/centaur.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c55
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c25
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c24
-rw-r--r--arch/x86/kernel/cpu/perf_event.c2373
-rw-r--r--arch/x86/kernel/cpu/perf_event.h957
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c731
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_ibs.c959
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_iommu.c499
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_uncore.c600
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c3669
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_bts.c531
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_cqm.c1391
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c1317
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_lbr.c1024
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_pt.c1178
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_rapl.c802
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c1326
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h343
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c1221
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c687
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c2487
-rw-r--r--arch/x86/kernel/cpu/perf_event_knc.c319
-rw-r--r--arch/x86/kernel/cpu/perf_event_msr.c242
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c1376
-rw-r--r--arch/x86/kernel/cpu/perf_event_p6.c279
-rw-r--r--arch/x86/kernel/cpu/rdrand.c25
-rw-r--r--arch/x86/kernel/cpu/scattered.c20
-rw-r--r--arch/x86/kernel/cpu/topology.c4
-rw-r--r--arch/x86/kernel/cpu/transmeta.c14
-rw-r--r--arch/x86/kernel/cpu/vmware.c5
-rw-r--r--arch/x86/kernel/cpuid.c24
-rw-r--r--arch/x86/kernel/crash.c55
-rw-r--r--arch/x86/kernel/dumpstack.c11
-rw-r--r--arch/x86/kernel/e820.c41
-rw-r--r--arch/x86/kernel/early-quirks.c3
-rw-r--r--arch/x86/kernel/early_printk.c6
-rw-r--r--arch/x86/kernel/fpu/core.c56
-rw-r--r--arch/x86/kernel/fpu/init.c203
-rw-r--r--arch/x86/kernel/fpu/regset.c4
-rw-r--r--arch/x86/kernel/fpu/signal.c21
-rw-r--r--arch/x86/kernel/fpu/xstate.c410
-rw-r--r--arch/x86/kernel/ftrace.c42
-rw-r--r--arch/x86/kernel/head64.c22
-rw-r--r--arch/x86/kernel/head_32.S13
-rw-r--r--arch/x86/kernel/head_64.S13
-rw-r--r--arch/x86/kernel/hpet.c30
-rw-r--r--arch/x86/kernel/hw_breakpoint.c6
-rw-r--r--arch/x86/kernel/i8259.c29
-rw-r--r--arch/x86/kernel/irq.c11
-rw-r--r--arch/x86/kernel/irq_64.c2
-rw-r--r--arch/x86/kernel/irq_work.c2
-rw-r--r--arch/x86/kernel/kgdb.c25
-rw-r--r--arch/x86/kernel/kprobes/core.c2
-rw-r--r--arch/x86/kernel/kvmclock.c57
-rw-r--r--arch/x86/kernel/livepatch.c28
-rw-r--r--arch/x86/kernel/machine_kexec_64.c2
-rw-r--r--arch/x86/kernel/mcount_64.S20
-rw-r--r--arch/x86/kernel/mpparse.c2
-rw-r--r--arch/x86/kernel/msr.c26
-rw-r--r--arch/x86/kernel/nmi.c35
-rw-r--r--arch/x86/kernel/paravirt.c36
-rw-r--r--arch/x86/kernel/paravirt_patch_32.c2
-rw-r--r--arch/x86/kernel/paravirt_patch_64.c3
-rw-r--r--arch/x86/kernel/pci-calgary_64.c4
-rw-r--r--arch/x86/kernel/pci-dma.c2
-rw-r--r--arch/x86/kernel/pci-swiotlb.c2
-rw-r--r--arch/x86/kernel/pmem.c12
-rw-r--r--arch/x86/kernel/process.c7
-rw-r--r--arch/x86/kernel/process_32.c8
-rw-r--r--arch/x86/kernel/process_64.c12
-rw-r--r--arch/x86/kernel/ptrace.c15
-rw-r--r--arch/x86/kernel/pvclock.c24
-rw-r--r--arch/x86/kernel/quirks.c2
-rw-r--r--arch/x86/kernel/reboot.c38
-rw-r--r--arch/x86/kernel/rtc.c3
-rw-r--r--arch/x86/kernel/setup.c114
-rw-r--r--arch/x86/kernel/signal.c144
-rw-r--r--arch/x86/kernel/smp.c4
-rw-r--r--arch/x86/kernel/smpboot.c120
-rw-r--r--arch/x86/kernel/stacktrace.c18
-rw-r--r--arch/x86/kernel/tboot.c2
-rw-r--r--arch/x86/kernel/test_nx.c2
-rw-r--r--arch/x86/kernel/test_rodata.c2
-rw-r--r--arch/x86/kernel/traps.c151
-rw-r--r--arch/x86/kernel/tsc.c104
-rw-r--r--arch/x86/kernel/verify_cpu.S64
-rw-r--r--arch/x86/kernel/vm86_32.c10
-rw-r--r--arch/x86/kernel/vmlinux.lds.S36
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c2
-rw-r--r--arch/x86/kernel/x86_init.c1
-rw-r--r--arch/x86/kvm/Kconfig2
-rw-r--r--arch/x86/kvm/Makefile3
-rw-r--r--arch/x86/kvm/assigned-dev.c76
-rw-r--r--arch/x86/kvm/cpuid.c20
-rw-r--r--arch/x86/kvm/cpuid.h76
-rw-r--r--arch/x86/kvm/emulate.c39
-rw-r--r--arch/x86/kvm/hyperv.c789
-rw-r--r--arch/x86/kvm/hyperv.h55
-rw-r--r--arch/x86/kvm/i8254.c355
-rw-r--r--arch/x86/kvm/i8254.h17
-rw-r--r--arch/x86/kvm/ioapic.c61
-rw-r--r--arch/x86/kvm/ioapic.h35
-rw-r--r--arch/x86/kvm/iommu.c11
-rw-r--r--arch/x86/kvm/irq.c49
-rw-r--r--arch/x86/kvm/irq.h19
-rw-r--r--arch/x86/kvm/irq_comm.c191
-rw-r--r--arch/x86/kvm/lapic.c313
-rw-r--r--arch/x86/kvm/lapic.h29
-rw-r--r--arch/x86/kvm/mmu.c1021
-rw-r--r--arch/x86/kvm/mmu.h11
-rw-r--r--arch/x86/kvm/mmu_audit.c17
-rw-r--r--arch/x86/kvm/mtrr.c25
-rw-r--r--arch/x86/kvm/page_track.c222
-rw-r--r--arch/x86/kvm/paging_tmpl.h83
-rw-r--r--arch/x86/kvm/pmu.c2
-rw-r--r--arch/x86/kvm/svm.c234
-rw-r--r--arch/x86/kvm/trace.h320
-rw-r--r--arch/x86/kvm/vmx.c1111
-rw-r--r--arch/x86/kvm/x86.c718
-rw-r--r--arch/x86/kvm/x86.h22
-rw-r--r--arch/x86/lguest/boot.c10
-rw-r--r--arch/x86/lib/Makefile2
-rw-r--r--arch/x86/lib/clear_page_64.S2
-rw-r--r--arch/x86/lib/cmdline.c60
-rw-r--r--arch/x86/lib/copy_page_64.S2
-rw-r--r--arch/x86/lib/copy_user_64.S144
-rw-r--r--arch/x86/lib/cpu.c35
-rw-r--r--arch/x86/lib/csum-wrappers_64.c2
-rw-r--r--arch/x86/lib/delay.c2
-rw-r--r--arch/x86/lib/memcpy_64.S119
-rw-r--r--arch/x86/lib/memmove_64.S2
-rw-r--r--arch/x86/lib/memset_64.S2
-rw-r--r--arch/x86/lib/msr.c26
-rw-r--r--arch/x86/lib/x86-opcode-map.txt24
-rw-r--r--arch/x86/math-emu/fpu_aux.c70
-rw-r--r--arch/x86/math-emu/fpu_emu.h2
-rw-r--r--arch/x86/math-emu/fpu_entry.c96
-rw-r--r--arch/x86/math-emu/fpu_proto.h12
-rw-r--r--arch/x86/math-emu/load_store.c63
-rw-r--r--arch/x86/math-emu/reg_compare.c128
-rw-r--r--arch/x86/mm/Makefile3
-rw-r--r--arch/x86/mm/debug_pagetables.c46
-rw-r--r--arch/x86/mm/dump_pagetables.c109
-rw-r--r--arch/x86/mm/extable.c100
-rw-r--r--arch/x86/mm/fault.c17
-rw-r--r--arch/x86/mm/gup.c90
-rw-r--r--arch/x86/mm/highmem_32.c14
-rw-r--r--arch/x86/mm/hugetlbpage.c4
-rw-r--r--arch/x86/mm/init.c42
-rw-r--r--arch/x86/mm/init_32.c8
-rw-r--r--arch/x86/mm/init_64.c69
-rw-r--r--arch/x86/mm/ioremap.c4
-rw-r--r--arch/x86/mm/kasan_init_64.c19
-rw-r--r--arch/x86/mm/kmmio.c88
-rw-r--r--arch/x86/mm/mmap.c26
-rw-r--r--arch/x86/mm/mpx.c70
-rw-r--r--arch/x86/mm/numa.c67
-rw-r--r--arch/x86/mm/pageattr.c127
-rw-r--r--arch/x86/mm/pat.c21
-rw-r--r--arch/x86/mm/pat_rbtree.c52
-rw-r--r--arch/x86/mm/pgtable.c20
-rw-r--r--arch/x86/mm/setup_nx.c8
-rw-r--r--arch/x86/mm/srat.c2
-rw-r--r--arch/x86/mm/tlb.c29
-rw-r--r--arch/x86/net/bpf_jit_comp.c42
-rw-r--r--arch/x86/oprofile/backtrace.c3
-rw-r--r--arch/x86/oprofile/op_model_amd.c1
-rw-r--r--arch/x86/pci/Makefile2
-rw-r--r--arch/x86/pci/acpi.c296
-rw-r--r--arch/x86/pci/bus_numa.c13
-rw-r--r--arch/x86/pci/common.c59
-rw-r--r--arch/x86/pci/fixup.c28
-rw-r--r--arch/x86/pci/intel_mid_pci.c9
-rw-r--r--arch/x86/pci/irq.c23
-rw-r--r--arch/x86/pci/legacy.c2
-rw-r--r--arch/x86/pci/pcbios.c108
-rw-r--r--arch/x86/pci/vmd.c756
-rw-r--r--arch/x86/pci/xen.c5
-rw-r--r--arch/x86/platform/atom/punit_atom_debug.c7
-rw-r--r--arch/x86/platform/efi/efi-bgrt.c9
-rw-r--r--arch/x86/platform/efi/efi.c28
-rw-r--r--arch/x86/platform/efi/quirks.c96
-rw-r--r--arch/x86/platform/geode/alix.c14
-rw-r--r--arch/x86/platform/geode/geos.c8
-rw-r--r--arch/x86/platform/geode/net5501.c8
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c10
-rw-r--r--arch/x86/platform/intel-mid/mfld.c5
-rw-r--r--arch/x86/platform/intel-mid/mrfl.c5
-rw-r--r--arch/x86/platform/intel-mid/sfi.c3
-rw-r--r--arch/x86/platform/intel-quark/imr.c103
-rw-r--r--arch/x86/platform/intel-quark/imr_selftest.c30
-rw-r--r--arch/x86/platform/uv/uv_nmi.c54
-rw-r--r--arch/x86/power/cpu.c92
-rw-r--r--arch/x86/ras/Kconfig4
-rw-r--r--arch/x86/ras/mce_amd_inj.c103
-rw-r--r--arch/x86/realmode/rm/Makefile1
-rw-r--r--arch/x86/um/Makefile2
-rw-r--r--arch/x86/um/asm/barrier.h11
-rw-r--r--arch/x86/um/asm/checksum.h9
-rw-r--r--arch/x86/um/asm/checksum_32.h2
-rw-r--r--arch/x86/um/asm/syscall.h5
-rw-r--r--arch/x86/um/os-Linux/task_size.c4
-rw-r--r--arch/x86/um/ptrace_32.c8
-rw-r--r--arch/x86/um/signal.c18
-rw-r--r--arch/x86/um/stub_32.S1
-rw-r--r--arch/x86/um/stub_64.S18
-rw-r--r--arch/x86/um/sys_call_table_32.c9
-rw-r--r--arch/x86/um/sys_call_table_64.c12
-rw-r--r--arch/x86/um/user-offsets.c6
-rw-r--r--arch/x86/xen/apic.c2
-rw-r--r--arch/x86/xen/enlighten.c43
-rw-r--r--arch/x86/xen/grant-table.c2
-rw-r--r--arch/x86/xen/mmu.c11
-rw-r--r--arch/x86/xen/p2m.c19
-rw-r--r--arch/x86/xen/pmu.c2
-rw-r--r--arch/x86/xen/setup.c22
-rw-r--r--arch/x86/xen/smp.c2
-rw-r--r--arch/x86/xen/suspend.c24
-rw-r--r--arch/x86/xen/time.c115
-rw-r--r--arch/x86/xen/xen-asm_32.S14
-rw-r--r--arch/x86/xen/xen-asm_64.S19
-rw-r--r--arch/x86/xen/xen-ops.h3
-rw-r--r--arch/xtensa/Kconfig20
-rw-r--r--arch/xtensa/Makefile4
-rw-r--r--arch/xtensa/boot/boot-elf/boot.lds.S13
-rw-r--r--arch/xtensa/boot/boot-elf/bootstrap.S28
-rw-r--r--arch/xtensa/boot/dts/Makefile7
-rw-r--r--arch/xtensa/boot/dts/kc705_nommu.dts17
-rw-r--r--arch/xtensa/configs/iss_defconfig1
-rw-r--r--arch/xtensa/configs/nommu_kc705_defconfig131
-rw-r--r--arch/xtensa/include/asm/asmmacro.h7
-rw-r--r--arch/xtensa/include/asm/atomic.h4
-rw-r--r--arch/xtensa/include/asm/barrier.h4
-rw-r--r--arch/xtensa/include/asm/cacheasm.h26
-rw-r--r--arch/xtensa/include/asm/cacheflush.h106
-rw-r--r--arch/xtensa/include/asm/checksum.h12
-rw-r--r--arch/xtensa/include/asm/dma-mapping.h14
-rw-r--r--arch/xtensa/include/asm/gpio.h4
-rw-r--r--arch/xtensa/include/asm/initialize_mmu.h13
-rw-r--r--arch/xtensa/include/asm/io.h9
-rw-r--r--arch/xtensa/include/asm/pci.h3
-rw-r--r--arch/xtensa/include/asm/pgtable.h4
-rw-r--r--arch/xtensa/include/asm/vectors.h28
-rw-r--r--arch/xtensa/include/uapi/asm/mman.h7
-rw-r--r--arch/xtensa/include/uapi/asm/socket.h5
-rw-r--r--arch/xtensa/kernel/Makefile1
-rw-r--r--arch/xtensa/kernel/entry.S8
-rw-r--r--arch/xtensa/kernel/head.S2
-rw-r--r--arch/xtensa/kernel/mxhead.S23
-rw-r--r--arch/xtensa/kernel/pci-dma.c45
-rw-r--r--arch/xtensa/kernel/setup.c11
-rw-r--r--arch/xtensa/kernel/smp.c2
-rw-r--r--arch/xtensa/kernel/time.c2
-rw-r--r--arch/xtensa/kernel/vectors.S4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S37
-rw-r--r--arch/xtensa/lib/usercopy.S6
-rw-r--r--arch/xtensa/mm/fault.c2
-rw-r--r--arch/xtensa/mm/tlb.c2
-rw-r--r--arch/xtensa/platforms/iss/console.c4
-rw-r--r--arch/xtensa/platforms/iss/setup.c2
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c15
-rw-r--r--arch/xtensa/platforms/xt2000/setup.c4
-rw-r--r--arch/xtensa/platforms/xtfpga/include/platform/hardware.h6
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c2
-rw-r--r--arch/xtensa/variants/de212/include/variant/core.h594
-rw-r--r--arch/xtensa/variants/de212/include/variant/tie-asm.h170
-rw-r--r--arch/xtensa/variants/de212/include/variant/tie.h136
4120 files changed, 185283 insertions, 123356 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 4e949e5..f6b649d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -205,9 +205,6 @@ config HAVE_NMI_WATCHDOG
config HAVE_ARCH_TRACEHOOK
bool
-config HAVE_DMA_ATTRS
- bool
-
config HAVE_DMA_CONTIGUOUS
bool
@@ -511,6 +508,74 @@ config ARCH_HAS_ELF_RANDOMIZE
- arch_mmap_rnd()
- arch_randomize_brk()
+config HAVE_ARCH_MMAP_RND_BITS
+ bool
+ help
+ An arch should select this symbol if it supports setting a variable
+ number of bits for use in establishing the base address for mmap
+ allocations, has MMU enabled and provides values for both:
+ - ARCH_MMAP_RND_BITS_MIN
+ - ARCH_MMAP_RND_BITS_MAX
+
+config ARCH_MMAP_RND_BITS_MIN
+ int
+
+config ARCH_MMAP_RND_BITS_MAX
+ int
+
+config ARCH_MMAP_RND_BITS_DEFAULT
+ int
+
+config ARCH_MMAP_RND_BITS
+ int "Number of bits to use for ASLR of mmap base address" if EXPERT
+ range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX
+ default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT
+ default ARCH_MMAP_RND_BITS_MIN
+ depends on HAVE_ARCH_MMAP_RND_BITS
+ help
+ This value can be used to select the number of bits to use to
+ determine the random offset to the base address of vma regions
+ resulting from mmap allocations. This value will be bounded
+ by the architecture's minimum and maximum supported values.
+
+ This value can be changed after boot using the
+ /proc/sys/vm/mmap_rnd_bits tunable
+
+config HAVE_ARCH_MMAP_RND_COMPAT_BITS
+ bool
+ help
+ An arch should select this symbol if it supports running applications
+ in compatibility mode, supports setting a variable number of bits for
+ use in establishing the base address for mmap allocations, has MMU
+ enabled and provides values for both:
+ - ARCH_MMAP_RND_COMPAT_BITS_MIN
+ - ARCH_MMAP_RND_COMPAT_BITS_MAX
+
+config ARCH_MMAP_RND_COMPAT_BITS_MIN
+ int
+
+config ARCH_MMAP_RND_COMPAT_BITS_MAX
+ int
+
+config ARCH_MMAP_RND_COMPAT_BITS_DEFAULT
+ int
+
+config ARCH_MMAP_RND_COMPAT_BITS
+ int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT
+ range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX
+ default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT
+ default ARCH_MMAP_RND_COMPAT_BITS_MIN
+ depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS
+ help
+ This value can be used to select the number of bits to use to
+ determine the random offset to the base address of vma regions
+ resulting from mmap allocations for compatible applications This
+ value will be bounded by the architecture's minimum and maximum
+ supported values.
+
+ This value can be changed after boot using the
+ /proc/sys/vm/mmap_rnd_compat_bits tunable
+
config HAVE_COPY_THREAD_TLS
bool
help
@@ -564,4 +629,7 @@ config OLD_SIGACTION
config COMPAT_OLD_SIGACTION
bool
+config ARCH_NO_COHERENT_DMA_MMAP
+ bool
+
source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index f515a4d..9d8a858 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -9,7 +9,6 @@ config ALPHA
select HAVE_OPROFILE
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
- select HAVE_DMA_ATTRS
select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select AUTO_IRQ_AFFINITY if SMP
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
index e8c9560..572b228 100644
--- a/arch/alpha/include/asm/atomic.h
+++ b/arch/alpha/include/asm/atomic.h
@@ -17,11 +17,11 @@
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic64_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic64_read(v) READ_ONCE((v)->counter)
-#define atomic_set(v,i) ((v)->counter = (i))
-#define atomic64_set(v,i) ((v)->counter = (i))
+#define atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
+#define atomic64_set(v,i) WRITE_ONCE((v)->counter, (i))
/*
* To get proper branch prediction for the main line, we must branch
diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h
index d3854bb..f2bbdd2 100644
--- a/arch/alpha/include/asm/checksum.h
+++ b/arch/alpha/include/asm/checksum.h
@@ -13,14 +13,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
-extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum);
+__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum);
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len, unsigned short proto,
- __wsum sum);
+ __u32 len, __u8 proto, __wsum sum);
/*
* computes the checksum of a memory block at buff, length len,
@@ -70,6 +67,5 @@ static inline __sum16 csum_fold(__wsum csum)
#define _HAVE_ARCH_IPV6_CSUM
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum);
+ __u32 len, __u8 proto, __wsum sum);
#endif
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h
index 72a8ca7..3c3451f 100644
--- a/arch/alpha/include/asm/dma-mapping.h
+++ b/arch/alpha/include/asm/dma-mapping.h
@@ -10,8 +10,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return dma_ops;
}
-#include <asm-generic/dma-mapping-common.h>
-
#define dma_cache_sync(dev, va, size, dir) ((void)0)
#endif /* _ALPHA_DMA_MAPPING_H */
diff --git a/arch/alpha/include/asm/gpio.h b/arch/alpha/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/alpha/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index 98f2eee..a06c24b 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -7,7 +7,6 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <asm/machvec.h>
-#include <asm-generic/pci-bridge.h>
/*
* The following structure is used to manage multiple PCI busses.
@@ -66,13 +65,6 @@ extern void pcibios_set_master(struct pci_dev *dev);
decisions. */
#define PCI_DMA_BUS_IS_PHYS 0
-#ifdef CONFIG_PCI
-
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
-#endif
-
/* TODO: integrate with include/asm-generic/pci.h ? */
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
diff --git a/arch/alpha/include/asm/serial.h b/arch/alpha/include/asm/serial.h
index 22909b8..e31557f 100644
--- a/arch/alpha/include/asm/serial.h
+++ b/arch/alpha/include/asm/serial.h
@@ -14,11 +14,11 @@
/* Standard COM flags (except for COM4, because of the 8514 problem) */
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
+#define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
+#define STD_COM4_FLAGS UPF_BOOT_AUTOCONF
#endif
#define SERIAL_PORT_DFNS \
diff --git a/arch/alpha/include/uapi/asm/mman.h b/arch/alpha/include/uapi/asm/mman.h
index 0086b47..fec1947 100644
--- a/arch/alpha/include/uapi/asm/mman.h
+++ b/arch/alpha/include/uapi/asm/mman.h
@@ -37,6 +37,9 @@
#define MCL_CURRENT 8192 /* lock all currently mapped pages */
#define MCL_FUTURE 16384 /* lock all additions to address space */
+#define MCL_ONFAULT 32768 /* lock all pages that are faulted in */
+
+#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */
#define MADV_NORMAL 0 /* no further special treatment */
#define MADV_RANDOM 1 /* expect random page references */
@@ -46,6 +49,7 @@
#define MADV_DONTNEED 6 /* don't need these pages */
/* common/generic parameters */
+#define MADV_FREE 8 /* free pages only if memory pressure */
#define MADV_REMOVE 9 /* remove these pages & resources */
#define MADV_DONTFORK 10 /* don't inherit across fork */
#define MADV_DOFORK 11 /* do inherit across fork */
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 9a20821..9e46d6e 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -92,4 +92,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index 2fd00b7..936bc8f 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
/* The small sections were sorted to the end of the segment.
The following should definitely cover them. */
- gp = (u64)me->module_core + me->core_size - 0x8000;
+ gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
got = sechdrs[me->arch.gotsecindex].sh_addr;
for (i = 0; i < n; i++) {
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 2f24447f..46bf263 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -168,7 +168,7 @@ smp_callin(void)
cpuid, current, current->active_mm));
preempt_disable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
/* Wait until hwrpb->txrdy is clear for cpu. Return -1 on timeout. */
diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
index 199f6ef..377f9e3 100644
--- a/arch/alpha/lib/checksum.c
+++ b/arch/alpha/lib/checksum.c
@@ -42,9 +42,7 @@ static inline unsigned short from64to16(unsigned long x)
* returns a 16-bit checksum, already complemented.
*/
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
@@ -52,9 +50,7 @@ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
}
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
unsigned long result;
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 78c0621..07a5cb9 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -12,13 +12,12 @@ config ARC
select BUILDTIME_EXTABLE_SORT
select COMMON_CLK
select CLONE_BACKWARDS
- # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
- select DEVTMPFS if !INITRAMFS_SOURCE=""
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
select GENERIC_FIND_FIRST_BIT
# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
select GENERIC_IRQ_SHOW
+ select GENERIC_PCI_IOMAP
select GENERIC_PENDING_IRQ if SMP
select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_KGDB
@@ -39,6 +38,9 @@ config ARC
select PERF_USE_VMALLOC
select HAVE_DEBUG_STACKOVERFLOW
+config MIGHT_HAVE_PCI
+ bool
+
config TRACE_IRQFLAGS_SUPPORT
def_bool y
@@ -73,8 +75,9 @@ config STACKTRACE_SUPPORT
def_bool y
select STACKTRACE
-config HAVE_LATENCYTOP_SUPPORT
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
def_bool y
+ depends on ARC_MMU_V4
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -190,6 +193,16 @@ config NR_CPUS
range 2 4096
default "4"
+config ARC_SMP_HALT_ON_RESET
+ bool "Enable Halt-on-reset boot mode"
+ default y if ARC_UBOOT_SUPPORT
+ help
+ In SMP configuration cores can be configured as Halt-on-reset
+ or they could all start at same time. For Halt-on-reset, non
+ masters are parked until Master kicks them so they can start of
+ at designated entry point. For other case, all jump to common
+ entry point and spin wait for Master's signal.
+
endif #SMP
menuconfig ARC_CACHE
@@ -264,20 +277,14 @@ config ARC_DCCM_BASE
default "0xA0000000"
depends on ARC_HAS_DCCM
-config ARC_HAS_HW_MPY
- bool "Use Hardware Multiplier (Normal or Faster XMAC)"
- default y
- help
- Influences how gcc generates code for MPY operations.
- If enabled, MPYxx insns are generated, provided by Standard/XMAC
- Multipler. Otherwise software multipy lib is used
-
choice
prompt "MMU Version"
default ARC_MMU_V3 if ARC_CPU_770
default ARC_MMU_V2 if ARC_CPU_750D
default ARC_MMU_V4 if ARC_CPU_HS
+if ISA_ARCOMPACT
+
config ARC_MMU_V1
bool "MMU v1"
help
@@ -297,6 +304,8 @@ config ARC_MMU_V3
Variable Page size (1k-16k), var JTLB size 128 x (2 or 4)
Shared Address Spaces (SASID)
+endif
+
config ARC_MMU_V4
bool "MMU v4"
depends on ISA_ARCV2
@@ -323,6 +332,19 @@ config ARC_PAGE_SIZE_4K
endchoice
+choice
+ prompt "MMU Super Page Size"
+ depends on ISA_ARCV2 && TRANSPARENT_HUGEPAGE
+ default ARC_HUGEPAGE_2M
+
+config ARC_HUGEPAGE_2M
+ bool "2MB"
+
+config ARC_HUGEPAGE_16M
+ bool "16MB"
+
+endchoice
+
if ISA_ARCOMPACT
config ARC_COMPACT_IRQ_LEVELS
@@ -395,7 +417,7 @@ config ARC_HAS_RTC
default n
depends on !SMP
-config ARC_HAS_GRTC
+config ARC_HAS_GFRC
bool "SMP synchronized 64-bit cycle counter"
default y
depends on SMP
@@ -427,6 +449,29 @@ config LINUX_LINK_BASE
However some customers have peripherals mapped at this addr, so
Linux needs to be scooted a bit.
If you don't know what the above means, leave this setting alone.
+ This needs to match memory start address specified in Device Tree
+
+config HIGHMEM
+ bool "High Memory Support"
+ help
+ With ARC 2G:2G address split, only upper 2G is directly addressable by
+ kernel. Enable this to potentially allow access to rest of 2G and PAE
+ in future
+
+config ARC_HAS_PAE40
+ bool "Support for the 40-bit Physical Address Extension"
+ default n
+ depends on ISA_ARCV2
+ select HIGHMEM
+ help
+ Enable access to physical memory beyond 4G, only supported on
+ ARC cores with 40 bit Physical Addressing support
+
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool ARC_HAS_PAE40
+
+config ARCH_DMA_ADDR_T_64BIT
+ bool
config ARC_CURR_IN_REG
bool "Dedicate Register r25 for current_task pointer"
@@ -491,14 +536,6 @@ config ARC_DBG_TLB_MISS_COUNT
Counts number of I and D TLB Misses and exports them via Debugfs
The counters can be cleared via Debugfs as well
-if SMP
-
-config ARC_IPI_DBG
- bool "Debug Inter Core interrupts"
- default n
-
-endif
-
endif
config ARC_UBOOT_SUPPORT
@@ -528,8 +565,36 @@ endmenu
endmenu # "ARC Architecture Configuration"
source "mm/Kconfig"
+
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order"
+ default "12" if ARC_HUGEPAGE_16M
+ default "11"
+
source "net/Kconfig"
source "drivers/Kconfig"
+
+menu "Bus Support"
+
+config PCI
+ bool "PCI support" if MIGHT_HAVE_PCI
+ help
+ PCI is the name of a bus system, i.e., the way the CPU talks to
+ the other stuff inside your box. Find out if your board/platform
+ has PCI.
+
+ Note: PCIe support for Synopsys Device will be available only
+ when HAPS DX is configured with PCIe RC bitmap. If you have PCI,
+ say Y, otherwise N.
+
+config PCI_SYSCALL
+ def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
+endmenu
+
source "fs/Kconfig"
source "arch/arc/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 8a27a48..c8230f3 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -74,14 +74,10 @@ ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
ldflags-$(upto_gcc44) += -marclinux
-ifndef CONFIG_ARC_HAS_HW_MPY
- cflags-y += -mno-mpy
-endif
-
LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
# Modules with short calls might break for calls into builtin-kernel
-KBUILD_CFLAGS_MODULE += -mlong-calls
+KBUILD_CFLAGS_MODULE += -mlong-calls -mno-millicode
# Finally dump eveything into kernel build system
KBUILD_CFLAGS += $(cflags-y)
@@ -121,7 +117,7 @@ $(boot_targets): vmlinux
$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
dtbs: scripts
- $(Q)$(MAKE) $(build)=$(boot)/dts dtbs
+ $(Q)$(MAKE) $(build)=$(boot)/dts
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
diff --git a/arch/arc/boot/dts/Makefile b/arch/arc/boot/dts/Makefile
index b0e3f19..a09f11b 100644
--- a/arch/arc/boot/dts/Makefile
+++ b/arch/arc/boot/dts/Makefile
@@ -6,10 +6,12 @@ ifneq ($(CONFIG_ARC_BUILTIN_DTB_NAME),"")
endif
obj-y += $(builtindtb-y).dtb.o
-targets += $(builtindtb-y).dtb
+dtb-y := $(builtindtb-y).dtb
.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
-dtbs: $(addprefix $(obj)/, $(builtindtb-y).dtb)
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+always := $(dtb-y)
clean-files := *.dtb *.dtb.S
diff --git a/arch/arc/boot/dts/axc001.dtsi b/arch/arc/boot/dts/axc001.dtsi
index a5e2726..420dcfd 100644
--- a/arch/arc/boot/dts/axc001.dtsi
+++ b/arch/arc/boot/dts/axc001.dtsi
@@ -95,6 +95,6 @@
#size-cells = <1>;
ranges = <0x00000000 0x80000000 0x40000000>;
device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512MiB */
+ reg = <0x80000000 0x20000000>; /* 512MiB */
};
};
diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi
index 846481f..f90fadf 100644
--- a/arch/arc/boot/dts/axc003.dtsi
+++ b/arch/arc/boot/dts/axc003.dtsi
@@ -98,6 +98,6 @@
#size-cells = <1>;
ranges = <0x00000000 0x80000000 0x40000000>;
device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512MiB */
+ reg = <0x80000000 0x20000000>; /* 512MiB */
};
};
diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi
index 2f0b332..06a9f29 100644
--- a/arch/arc/boot/dts/axc003_idu.dtsi
+++ b/arch/arc/boot/dts/axc003_idu.dtsi
@@ -121,6 +121,6 @@
#size-cells = <1>;
ranges = <0x00000000 0x80000000 0x40000000>;
device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512MiB */
+ reg = <0x80000000 0x20000000>; /* 512MiB */
};
};
diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index f3db321..44a578c 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -46,6 +46,7 @@
snps,pbl = < 32 >;
clocks = <&apbclk>;
clock-names = "stmmaceth";
+ max-speed = <100>;
};
ehci@0x40000 {
diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts
index 911f069..fc81879 100644
--- a/arch/arc/boot/dts/nsim_hs.dts
+++ b/arch/arc/boot/dts/nsim_hs.dts
@@ -11,8 +11,17 @@
/ {
compatible = "snps,nsim_hs";
+ #address-cells = <2>;
+ #size-cells = <2>;
interrupt-parent = <&core_intc>;
+ memory {
+ device_type = "memory";
+ /* CONFIG_LINUX_LINK_BASE needs to match low mem start */
+ reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */
+ 0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */
+ };
+
chosen {
bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
};
@@ -26,8 +35,8 @@
#address-cells = <1>;
#size-cells = <1>;
- /* child and parent address space 1:1 mapped */
- ranges;
+ /* only perip space at end of low mem accessible */
+ ranges = <0x80000000 0x0 0x80000000 0x80000000>;
core_intc: core-interrupt-controller {
compatible = "snps,archs-intc";
diff --git a/arch/arc/boot/dts/skeleton.dtsi b/arch/arc/boot/dts/skeleton.dtsi
index a870bdd..296d371 100644
--- a/arch/arc/boot/dts/skeleton.dtsi
+++ b/arch/arc/boot/dts/skeleton.dtsi
@@ -32,6 +32,6 @@
memory {
device_type = "memory";
- reg = <0x00000000 0x10000000>; /* 256M */
+ reg = <0x80000000 0x10000000>; /* 256M */
};
};
diff --git a/arch/arc/boot/dts/vdk_axc003.dtsi b/arch/arc/boot/dts/vdk_axc003.dtsi
index 9393fd9..84226bd 100644
--- a/arch/arc/boot/dts/vdk_axc003.dtsi
+++ b/arch/arc/boot/dts/vdk_axc003.dtsi
@@ -56,6 +56,6 @@
#size-cells = <1>;
ranges = <0x00000000 0x80000000 0x40000000>;
device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512MiB */
+ reg = <0x80000000 0x20000000>; /* 512MiB */
};
};
diff --git a/arch/arc/boot/dts/vdk_axc003_idu.dtsi b/arch/arc/boot/dts/vdk_axc003_idu.dtsi
index 9bee8ed..31f0fb5 100644
--- a/arch/arc/boot/dts/vdk_axc003_idu.dtsi
+++ b/arch/arc/boot/dts/vdk_axc003_idu.dtsi
@@ -71,6 +71,6 @@
#size-cells = <1>;
ranges = <0x00000000 0x80000000 0x40000000>;
device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512MiB */
+ reg = <0x80000000 0x20000000>; /* 512MiB */
};
};
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 562dac6..5d4e2a0 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
@@ -39,6 +39,7 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -73,7 +74,6 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
@@ -89,15 +89,12 @@ CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 83a6d8d..87ee46b 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
@@ -39,14 +39,10 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_AXS=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
@@ -78,14 +74,12 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
@@ -95,15 +89,12 @@ CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index f1e1c84..d80daf4 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
@@ -40,14 +40,10 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_AXS=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
@@ -79,14 +75,12 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
@@ -96,15 +90,12 @@ CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig
index 138f9d8..f410953 100644
--- a/arch/arc/configs/nsim_700_defconfig
+++ b/arch/arc/configs/nsim_700_defconfig
@@ -4,6 +4,7 @@ CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -26,7 +27,6 @@ CONFIG_ARC_PLAT_SIM=y
CONFIG_ARC_BUILTIN_DTB_NAME="nsim_700"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -34,6 +34,7 @@ CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -51,7 +52,6 @@ CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
@@ -63,4 +63,3 @@ CONFIG_NFS_FS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_XZ_DEC=y
diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig
index f761a7c..cfaa33c 100644
--- a/arch/arc/configs/nsim_hs_defconfig
+++ b/arch/arc/configs/nsim_hs_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
@@ -35,6 +35,7 @@ CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -49,7 +50,6 @@ CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
@@ -61,4 +61,3 @@ CONFIG_NFS_FS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_XZ_DEC=y
diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig
index dc6f74f..bb2a8dc 100644
--- a/arch/arc/configs/nsim_hs_smp_defconfig
+++ b/arch/arc/configs/nsim_hs_smp_defconfig
@@ -1,7 +1,8 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -21,13 +22,11 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_SIM=y
-CONFIG_ARC_BOARD_ML509=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs_idu"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -35,6 +34,7 @@ CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -49,7 +49,6 @@ CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
@@ -60,4 +59,3 @@ CONFIG_TMPFS=y
CONFIG_NFS_FS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_XZ_DEC=y
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig
index 31e1d95..646182e 100644
--- a/arch/arc/configs/nsimosci_defconfig
+++ b/arch/arc/configs/nsimosci_defconfig
@@ -33,6 +33,7 @@ CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -58,7 +59,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_HID is not set
diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig
index 3fef0a2..ceca254 100644
--- a/arch/arc/configs/nsimosci_hs_defconfig
+++ b/arch/arc/configs/nsimosci_hs_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
@@ -34,12 +34,12 @@ CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
# CONFIG_BLK_DEV is not set
CONFIG_NETDEVICES=y
-CONFIG_NET_OSCI_LAN=y
CONFIG_INPUT_EVDEV=y
# CONFIG_MOUSE_PS2_ALPS is not set
# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
@@ -58,7 +58,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_HID is not set
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 5178483..4b6da90 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -1,7 +1,8 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
@@ -18,15 +19,11 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_SIM=y
-CONFIG_ARC_BOARD_ML509=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
-CONFIG_ARC_HAS_LL64=y
-# CONFIG_ARC_HAS_RTSC is not set
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
@@ -40,6 +37,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -56,14 +54,11 @@ CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_NET_OSCI_LAN=y
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y
CONFIG_MOUSE_PS2_TOUCHKIT=y
# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_ARC_PS2=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
@@ -75,9 +70,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
-CONFIG_ARCPGU_RGB888=y
-CONFIG_ARCPGU_DISPTYPE=0
-# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_HID is not set
diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig
index 3b4dc9c..9b342ea 100644
--- a/arch/arc/configs/tb10x_defconfig
+++ b/arch/arc/configs/tb10x_defconfig
@@ -3,6 +3,7 @@ CONFIG_CROSS_COMPILE="arc-linux-"
CONFIG_DEFAULT_HOSTNAME="tb10x"
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
@@ -26,12 +27,10 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLOCK is not set
CONFIG_ARC_PLAT_TB10X=y
CONFIG_ARC_CACHE_LINE_SHIFT=5
-CONFIG_ARC_STACK_NONEXEC=y
CONFIG_HZ=250
CONFIG_ARC_BUILTIN_DTB_NAME="abilis_tb100_dvk"
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_COMPACTION is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -44,8 +43,8 @@ CONFIG_IP_MULTICAST=y
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_PROC_DEVICETREE=y
CONFIG_NETDEVICES=y
# CONFIG_NET_CADENCE is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
@@ -55,9 +54,6 @@ CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SEEQ is not set
CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_DEBUG_FS=y
-CONFIG_STMMAC_DA=y
-CONFIG_STMMAC_CHAINED=y
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
@@ -91,7 +87,6 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_DMADEVICES=y
CONFIG_DW_DMAC=y
-CONFIG_NET_DMA=y
CONFIG_ASYNC_TX_DMA=y
# CONFIG_IOMMU_SUPPORT is not set
# CONFIG_DNOTIFY is not set
@@ -100,17 +95,16 @@ CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_DEBUG_INFO=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
-CONFIG_MAGIC_SYSRQ=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig
index ef35ef3..a07f20d 100644
--- a/arch/arc/configs/vdk_hs38_defconfig
+++ b/arch/arc/configs/vdk_hs38_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_CROSS_MEMORY_ATTACH is not set
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig
index 634509e..7359859 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
+CONFIG_CROSS_COMPILE="arc-linux-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -16,7 +16,7 @@ CONFIG_ARC_PLAT_AXS10X=y
CONFIG_AXS103=y
CONFIG_ISA_ARCV2=y
CONFIG_SMP=y
-# CONFIG_ARC_HAS_GRTC is not set
+# CONFIG_ARC_HAS_GFRC is not set
CONFIG_ARC_UBOOT_SUPPORT=y
CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
CONFIG_PREEMPT=y
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index d8023bc..f9f4c6f 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -10,7 +10,8 @@
#define _ASM_ARC_ARCREGS_H
/* Build Configuration Registers */
-#define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */
+#define ARC_REG_AUX_DCCM 0x18 /* DCCM Base Addr ARCv2 */
+#define ARC_REG_DCCM_BASE_BUILD 0x61 /* DCCM Base Addr ARCompact */
#define ARC_REG_CRC_BCR 0x62
#define ARC_REG_VECBASE_BCR 0x68
#define ARC_REG_PERIBASE_BCR 0x69
@@ -18,10 +19,10 @@
#define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */
#define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */
#define ARC_REG_SLC_BCR 0xce
-#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
+#define ARC_REG_DCCM_BUILD 0x74 /* DCCM size (common) */
#define ARC_REG_TIMERS_BCR 0x75
#define ARC_REG_AP_BCR 0x76
-#define ARC_REG_ICCM_BCR 0x78
+#define ARC_REG_ICCM_BUILD 0x78 /* ICCM size (common) */
#define ARC_REG_XY_MEM_BCR 0x79
#define ARC_REG_MAC_BCR 0x7a
#define ARC_REG_MUL_BCR 0x7b
@@ -36,6 +37,7 @@
#define ARC_REG_IRQ_BCR 0xF3
#define ARC_REG_SMART_BCR 0xFF
#define ARC_REG_CLUSTER_BCR 0xcf
+#define ARC_REG_AUX_ICCM 0x208 /* ICCM Base Addr (ARCv2) */
/* status32 Bits Positions */
#define STATUS_AE_BIT 5 /* Exception active */
@@ -120,7 +122,7 @@
/* gcc builtin sr needs reg param to be long immediate */
#define write_aux_reg(reg_immed, val) \
- __builtin_arc_sr((unsigned int)val, reg_immed)
+ __builtin_arc_sr((unsigned int)(val), reg_immed)
#else
@@ -246,7 +248,7 @@ struct bcr_perip {
#endif
};
-struct bcr_iccm {
+struct bcr_iccm_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int base:16, pad:5, sz:3, ver:8;
#else
@@ -254,17 +256,15 @@ struct bcr_iccm {
#endif
};
-/* DCCM Base Address Register: ARC_REG_DCCMBASE_BCR */
-struct bcr_dccm_base {
+struct bcr_iccm_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int addr:24, ver:8;
+ unsigned int pad:8, sz11:4, sz01:4, sz10:4, sz00:4, ver:8;
#else
- unsigned int ver:8, addr:24;
+ unsigned int ver:8, sz00:4, sz10:4, sz01:4, sz11:4, pad:8;
#endif
};
-/* DCCM RAM Configuration Register: ARC_REG_DCCM_BCR */
-struct bcr_dccm {
+struct bcr_dccm_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int res:21, sz:3, ver:8;
#else
@@ -272,6 +272,14 @@ struct bcr_dccm {
#endif
};
+struct bcr_dccm_arcv2 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad2:12, cyc:3, pad1:1, sz1:4, sz0:4, ver:8;
+#else
+ unsigned int ver:8, sz0:4, sz1:4, pad1:1, cyc:3, pad2:12;
+#endif
+};
+
/* ARCompact: Both SP and DP FPU BCRs have same format */
struct bcr_fp_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
@@ -315,9 +323,9 @@ struct bcr_bpu_arcv2 {
struct bcr_generic {
#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad:24, ver:8;
+ unsigned int info:24, ver:8;
#else
- unsigned int ver:8, pad:24;
+ unsigned int ver:8, info:24;
#endif
};
@@ -327,8 +335,8 @@ struct bcr_generic {
*/
struct cpuinfo_arc_mmu {
- unsigned int ver:4, pg_sz_k:8, s_pg_sz_m:8, u_dtlb:6, u_itlb:6;
- unsigned int num_tlb:16, sets:12, ways:4;
+ unsigned int ver:4, pg_sz_k:8, s_pg_sz_m:8, pad:10, sasid:1, pae:1;
+ unsigned int sets:12, ways:4, u_dtlb:8, u_itlb:8;
};
struct cpuinfo_arc_cache {
@@ -349,14 +357,13 @@ struct cpuinfo_arc {
struct cpuinfo_arc_bpu bpu;
struct bcr_identity core;
struct bcr_isa isa;
- struct bcr_timer timers;
unsigned int vec_base;
struct cpuinfo_arc_ccm iccm, dccm;
struct {
unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3,
fpu_sp:1, fpu_dp:1, pad2:6,
debug:1, ap:1, smart:1, rtt:1, pad3:4,
- pad4:8;
+ timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4;
} extn;
struct bcr_mpy extn_mpy;
struct bcr_extn_xymem extn_xymem;
diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index c3ecda0..7730d30 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,11 +17,11 @@
#include <asm/barrier.h>
#include <asm/smp.h>
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
#ifdef CONFIG_ARC_HAS_LLSC
-#define atomic_set(v, i) (((v)->counter) = (i))
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
#ifdef CONFIG_ARC_STAR_9000923308
@@ -107,7 +107,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
#ifndef CONFIG_SMP
/* violating atomic_xxx API locking protocol in UP for optimization sake */
-#define atomic_set(v, i) (((v)->counter) = (i))
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
#else
@@ -125,7 +125,7 @@ static inline void atomic_set(atomic_t *v, int i)
unsigned long flags;
atomic_ops_lock(flags);
- v->counter = i;
+ WRITE_ONCE(v->counter, i);
atomic_ops_unlock(flags);
}
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index e23ea6e..210ef3e 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -62,9 +62,8 @@ extern int ioc_exists;
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
-#if defined(CONFIG_ARC_MMU_V3) || defined(CONFIG_ARC_MMU_V4)
#define ARC_REG_IC_PTAG 0x1E
-#endif
+#define ARC_REG_IC_PTAG_HI 0x1F
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
@@ -77,6 +76,7 @@ extern int ioc_exists;
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#define ARC_REG_DC_PTAG 0x5C
+#define ARC_REG_DC_PTAG_HI 0x5F
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
index 0992d3d..fbe3587 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -31,10 +31,10 @@
void flush_cache_all(void);
-void flush_icache_range(unsigned long start, unsigned long end);
-void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len);
-void __inv_icache_page(unsigned long paddr, unsigned long vaddr);
-void __flush_dcache_page(unsigned long paddr, unsigned long vaddr);
+void flush_icache_range(unsigned long kstart, unsigned long kend);
+void __sync_icache_dcache(phys_addr_t paddr, unsigned long vaddr, int len);
+void __inv_icache_page(phys_addr_t paddr, unsigned long vaddr);
+void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
diff --git a/arch/arc/include/asm/checksum.h b/arch/arc/include/asm/checksum.h
index 1095729..913eb4a 100644
--- a/arch/arc/include/asm/checksum.h
+++ b/arch/arc/include/asm/checksum.h
@@ -70,8 +70,8 @@ ip_fast_csum(const void *iph, unsigned int ihl)
* SA [4], DA [4], zeroes [1], Proto[1], TCP Seg(hdr+data) Len [2]
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
__asm__ __volatile__(
" add.f %0, %0, %1 \n"
diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h
index 2d28ba9..6602054 100644
--- a/arch/arc/include/asm/dma-mapping.h
+++ b/arch/arc/include/asm/dma-mapping.h
@@ -11,192 +11,11 @@
#ifndef ASM_ARC_DMA_MAPPING_H
#define ASM_ARC_DMA_MAPPING_H
-#include <asm-generic/dma-coherent.h>
-#include <asm/cacheflush.h>
+extern struct dma_map_ops arc_dma_ops;
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
-
-void dma_free_coherent(struct device *dev, size_t size, void *kvaddr,
- dma_addr_t dma_handle);
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
-/*
- * streaming DMA Mapping API...
- * CPU accesses page via normal paddr, thus needs to explicitly made
- * consistent before each use
- */
-
-static inline void __inline_dma_cache_sync(unsigned long paddr, size_t size,
- enum dma_data_direction dir)
-{
- switch (dir) {
- case DMA_FROM_DEVICE:
- dma_cache_inv(paddr, size);
- break;
- case DMA_TO_DEVICE:
- dma_cache_wback(paddr, size);
- break;
- case DMA_BIDIRECTIONAL:
- dma_cache_wback_inv(paddr, size);
- break;
- default:
- pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr);
- }
-}
-
-void __arc_dma_cache_sync(unsigned long paddr, size_t size,
- enum dma_data_direction dir);
-
-#define _dma_cache_sync(addr, sz, dir) \
-do { \
- if (__builtin_constant_p(dir)) \
- __inline_dma_cache_sync(addr, sz, dir); \
- else \
- __arc_dma_cache_sync(addr, sz, dir); \
-} \
-while (0);
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
- enum dma_data_direction dir)
-{
- _dma_cache_sync((unsigned long)cpu_addr, size, dir);
- return (dma_addr_t)cpu_addr;
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long paddr = page_to_phys(page) + offset;
- return dma_map_single(dev, (void *)paddr, size, dir);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline int
-dma_map_sg(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)
- s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
- s->length, dir);
-
- return nents;
-}
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- struct scatterlist *s;
- int i;
-
- for_each_sg(sg, s, nents, i)
- dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
- _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
- _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- _dma_cache_sync(dma_handle + offset, size, DMA_FROM_DEVICE);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- _dma_cache_sync(dma_handle + offset, size, DMA_TO_DEVICE);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nelems,
- enum dma_data_direction dir)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction dir)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
-}
-
-static inline int dma_supported(struct device *dev, u64 dma_mask)
-{
- /* Support 32 bit DMA mask exclusively */
- return dma_mask == DMA_BIT_MASK(32);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-static inline int 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;
+ return &arc_dma_ops;
}
#endif
diff --git a/arch/arc/include/asm/dma.h b/arch/arc/include/asm/dma.h
index ca7c451..01e47a6 100644
--- a/arch/arc/include/asm/dma.h
+++ b/arch/arc/include/asm/dma.h
@@ -10,5 +10,10 @@
#define ASM_ARC_DMA_H
#define MAX_DMA_ADDRESS 0xC0000000
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 0
+#endif
#endif
diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 415443c..1aff3be 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -110,13 +110,12 @@
.macro FAKE_RET_FROM_EXCPN
- ld r9, [sp, PT_status32]
- bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK)
- bset r9, r9, STATUS_L_BIT
- sr r9, [erstatus]
- mov r9, 55f
- sr r9, [eret]
-
+ lr r9, [status32]
+ bclr r9, r9, STATUS_AE_BIT
+ or r9, r9, (STATUS_E1_MASK|STATUS_E2_MASK)
+ sr r9, [erstatus]
+ mov r9, 55f
+ sr r9, [eret]
rtie
55:
.endm
diff --git a/arch/arc/include/asm/highmem.h b/arch/arc/include/asm/highmem.h
new file mode 100644
index 0000000..b1585c9
--- /dev/null
+++ b/arch/arc/include/asm/highmem.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef CONFIG_HIGHMEM
+
+#include <uapi/asm/page.h>
+#include <asm/kmap_types.h>
+
+/* start after vmalloc area */
+#define FIXMAP_BASE (PAGE_OFFSET - FIXMAP_SIZE - PKMAP_SIZE)
+#define FIXMAP_SIZE PGDIR_SIZE /* only 1 PGD worth */
+#define KM_TYPE_NR ((FIXMAP_SIZE >> PAGE_SHIFT)/NR_CPUS)
+#define FIXMAP_ADDR(nr) (FIXMAP_BASE + ((nr) << PAGE_SHIFT))
+
+/* start after fixmap area */
+#define PKMAP_BASE (FIXMAP_BASE + FIXMAP_SIZE)
+#define PKMAP_SIZE PGDIR_SIZE
+#define LAST_PKMAP (PKMAP_SIZE >> PAGE_SHIFT)
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
+
+#define kmap_prot PAGE_KERNEL
+
+
+#include <asm/cacheflush.h>
+
+extern void *kmap(struct page *page);
+extern void *kmap_high(struct page *page);
+extern void *kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void kunmap_high(struct page *page);
+
+extern void kmap_init(void);
+
+static inline void flush_cache_kmaps(void)
+{
+ flush_cache_all();
+}
+
+static inline void kunmap(struct page *page)
+{
+ BUG_ON(in_interrupt());
+ if (!PageHighMem(page))
+ return;
+ kunmap_high(page);
+}
+
+
+#endif
+
+#endif
diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h
new file mode 100644
index 0000000..7afe335
--- /dev/null
+++ b/arch/arc/include/asm/hugepage.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013-15 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _ASM_ARC_HUGEPAGE_H
+#define _ASM_ARC_HUGEPAGE_H
+
+#include <linux/types.h>
+#include <asm-generic/pgtable-nopmd.h>
+
+static inline pte_t pmd_pte(pmd_t pmd)
+{
+ return __pte(pmd_val(pmd));
+}
+
+static inline pmd_t pte_pmd(pte_t pte)
+{
+ return __pmd(pte_val(pte));
+}
+
+#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
+#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+#define pmd_mkhuge(pmd) pte_pmd(pte_mkhuge(pmd_pte(pmd)))
+#define pmd_mknotpresent(pmd) pte_pmd(pte_mknotpresent(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
+
+#define pmd_write(pmd) pte_write(pmd_pte(pmd))
+#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
+#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
+
+#define mk_pmd(page, prot) pte_pmd(mk_pte(page, prot))
+
+#define pmd_trans_huge(pmd) (pmd_val(pmd) & _PAGE_HW_SZ)
+
+#define pfn_pmd(pfn, prot) (__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ /*
+ * open-coded pte_modify() with additional retaining of HW_SZ bit
+ * so that pmd_trans_huge() remains true for this PMD
+ */
+ return __pmd((pmd_val(pmd) & (_PAGE_CHG_MASK | _PAGE_HW_SZ)) | pgprot_val(newprot));
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ *pmdp = pmd;
+}
+
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd);
+
+#define has_transparent_hugepage() 1
+
+/* Generic variants assume pgtable_t is struct page *, hence need for these */
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+
+#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
+extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end);
+
+#endif
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 694ece8..947bf0c 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -16,6 +16,15 @@
extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
unsigned long flags);
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ return (void __iomem *)port;
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+}
+
extern void iounmap(const void __iomem *addr);
#define ioremap_nocache(phy, sz) ioremap(phy, sz)
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index bc51036..49014f0 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -19,7 +19,6 @@
#else
#define TIMER0_IRQ 16
#define TIMER1_IRQ 17
-#define IPI_IRQ 19
#endif
#include <linux/interrupt.h>
diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h
index ad481c2..37c2f75 100644
--- a/arch/arc/include/asm/irqflags-arcv2.h
+++ b/arch/arc/include/asm/irqflags-arcv2.h
@@ -22,6 +22,7 @@
#define AUX_IRQ_CTRL 0x00E
#define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */
#define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */
+#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
#define AUX_IRQ_PRIORITY 0x206
#define ICAUSE 0x40a
#define AUX_IRQ_SELECT 0x40b
@@ -30,13 +31,19 @@
/* Was Intr taken in User Mode */
#define AUX_IRQ_ACT_BIT_U 31
-/* 0 is highest level, but taken by FIRQs, if present in design */
-#define ARCV2_IRQ_DEF_PRIO 0
+/*
+ * User space should be interruptable even by lowest prio interrupt
+ * Safe even if actual interrupt priorities is fewer or even one
+ */
+#define ARCV2_IRQ_DEF_PRIO 15
/* seed value for status register */
#define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \
(ARCV2_IRQ_DEF_PRIO << 1))
+/* SLEEP needs default irq priority (<=) which can interrupt the doze */
+#define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO)
+
#ifndef __ASSEMBLY__
/*
@@ -109,6 +116,16 @@ static inline int arch_irqs_disabled(void)
return arch_irqs_disabled_flags(arch_local_save_flags());
}
+static inline void arc_softirq_trigger(int irq)
+{
+ write_aux_reg(AUX_IRQ_HINT, irq);
+}
+
+static inline void arc_softirq_clear(int irq)
+{
+ write_aux_reg(AUX_IRQ_HINT, 0);
+}
+
#else
.macro IRQ_DISABLE scratch
diff --git a/arch/arc/include/asm/irqflags-compact.h b/arch/arc/include/asm/irqflags-compact.h
index aa80557..c1d3645 100644
--- a/arch/arc/include/asm/irqflags-compact.h
+++ b/arch/arc/include/asm/irqflags-compact.h
@@ -23,11 +23,13 @@
#define STATUS_E2_BIT 2 /* Int 2 enable */
#define STATUS_A1_BIT 3 /* Int 1 active */
#define STATUS_A2_BIT 4 /* Int 2 active */
+#define STATUS_AE_BIT 5 /* Exception active */
#define STATUS_E1_MASK (1<<STATUS_E1_BIT)
#define STATUS_E2_MASK (1<<STATUS_E2_BIT)
#define STATUS_A1_MASK (1<<STATUS_A1_BIT)
#define STATUS_A2_MASK (1<<STATUS_A2_BIT)
+#define STATUS_AE_MASK (1<<STATUS_AE_BIT)
#define STATUS_IE_MASK (STATUS_E1_MASK | STATUS_E2_MASK)
/* Other Interrupt Handling related Aux regs */
@@ -41,6 +43,8 @@
#define ISA_INIT_STATUS_BITS STATUS_IE_MASK
+#define ISA_SLEEP_ARG 0x3
+
#ifndef __ASSEMBLY__
/******************************************************************
@@ -91,7 +95,19 @@ static inline void arch_local_irq_restore(unsigned long flags)
/*
* Unconditionally Enable IRQs
*/
-extern void arch_local_irq_enable(void);
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " lr %0, [status32] \n"
+ " or %0, %0, %1 \n"
+ " flag %0 \n"
+ : "=&r"(temp)
+ : "n"((STATUS_E1_MASK | STATUS_E2_MASK))
+ : "cc", "memory");
+}
+
/*
* Unconditionally Disable IRQs
diff --git a/arch/arc/include/asm/kmap_types.h b/arch/arc/include/asm/kmap_types.h
new file mode 100644
index 0000000..f0d7f6a
--- /dev/null
+++ b/arch/arc/include/asm/kmap_types.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+/*
+ * We primarily need to define KM_TYPE_NR here but that in turn
+ * is a function of PGDIR_SIZE etc.
+ * To avoid circular deps issue, put everything in asm/highmem.h
+ */
+#endif
diff --git a/arch/arc/include/asm/mach_desc.h b/arch/arc/include/asm/mach_desc.h
index e8993a2..c28e6c3 100644
--- a/arch/arc/include/asm/mach_desc.h
+++ b/arch/arc/include/asm/mach_desc.h
@@ -23,11 +23,8 @@
* @dt_compat: Array of device tree 'compatible' strings
* (XXX: although only 1st entry is looked at)
* @init_early: Very early callback [called from setup_arch()]
- * @init_irq: setup external IRQ controllers [called from init_IRQ()]
- * @init_smp: for each CPU (e.g. setup IPI)
+ * @init_per_cpu: for each CPU as it is coming up (SMP as well as UP)
* [(M):init_IRQ(), (o):start_kernel_secondary()]
- * @init_time: platform specific clocksource/clockevent registration
- * [called from time_init()]
* @init_machine: arch initcall level callback (e.g. populate static
* platform devices or parse Devicetree)
* @init_late: Late initcall level callback
@@ -36,13 +33,10 @@
struct machine_desc {
const char *name;
const char **dt_compat;
-
void (*init_early)(void);
- void (*init_irq)(void);
#ifdef CONFIG_SMP
- void (*init_smp)(unsigned int);
+ void (*init_per_cpu)(unsigned int);
#endif
- void (*init_time)(void);
void (*init_machine)(void);
void (*init_late)(void);
diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h
index 52c11f0..847e3bb 100644
--- a/arch/arc/include/asm/mcip.h
+++ b/arch/arc/include/asm/mcip.h
@@ -39,8 +39,8 @@ struct mcip_cmd {
#define CMD_DEBUG_SET_MASK 0x34
#define CMD_DEBUG_SET_SELECT 0x36
-#define CMD_GRTC_READ_LO 0x42
-#define CMD_GRTC_READ_HI 0x43
+#define CMD_GFRC_READ_LO 0x42
+#define CMD_GFRC_READ_HI 0x43
#define CMD_IDU_ENABLE 0x71
#define CMD_IDU_DISABLE 0x72
@@ -86,9 +86,6 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
__mcip_cmd(cmd, param);
}
-extern void mcip_init_early_smp(void);
-extern void mcip_init_smp(unsigned int cpu);
-
#endif
#endif
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 0f9c3eb..b144d7c 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -24,6 +24,7 @@
#if (CONFIG_ARC_MMU_VER < 4)
#define ARC_REG_TLBPD0 0x405
#define ARC_REG_TLBPD1 0x406
+#define ARC_REG_TLBPD1HI 0 /* Dummy: allows code sharing with ARC700 */
#define ARC_REG_TLBINDEX 0x407
#define ARC_REG_TLBCOMMAND 0x408
#define ARC_REG_PID 0x409
@@ -31,6 +32,7 @@
#else
#define ARC_REG_TLBPD0 0x460
#define ARC_REG_TLBPD1 0x461
+#define ARC_REG_TLBPD1HI 0x463
#define ARC_REG_TLBINDEX 0x464
#define ARC_REG_TLBCOMMAND 0x465
#define ARC_REG_PID 0x468
@@ -83,6 +85,11 @@ void arc_mmu_init(void);
extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
void read_decode_mmu_bcr(void);
+static inline int is_pae40_enabled(void)
+{
+ return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
+}
+
#endif /* !__ASSEMBLY__ */
#endif
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 9c8aa41..429957f 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -43,7 +43,6 @@ typedef struct {
typedef struct {
unsigned long pgprot;
} pgprot_t;
-typedef unsigned long pgtable_t;
#define pte_val(x) ((x).pte)
#define pgd_val(x) ((x).pgd)
@@ -57,20 +56,26 @@ typedef unsigned long pgtable_t;
#else /* !STRICT_MM_TYPECHECKS */
+#ifdef CONFIG_ARC_HAS_PAE40
+typedef unsigned long long pte_t;
+#else
typedef unsigned long pte_t;
+#endif
typedef unsigned long pgd_t;
typedef unsigned long pgprot_t;
-typedef unsigned long pgtable_t;
#define pte_val(x) (x)
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
#define __pte(x) (x)
+#define __pgd(x) (x)
#define __pgprot(x) (x)
#define pte_pgprot(x) (x)
#endif
+typedef pte_t * pgtable_t;
+
#define ARCH_PFN_OFFSET (CONFIG_LINUX_LINK_BASE >> PAGE_SHIFT)
#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
diff --git a/arch/arc/include/asm/pci.h b/arch/arc/include/asm/pci.h
new file mode 100644
index 0000000..ba56c23
--- /dev/null
+++ b/arch/arc/include/asm/pci.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_ARC_PCI_H
+#define _ASM_ARC_PCI_H
+
+#ifdef __KERNEL__
+#include <linux/ioport.h>
+
+#define PCIBIOS_MIN_IO 0x100
+#define PCIBIOS_MIN_MEM 0x100000
+
+#define pcibios_assign_all_busses() 1
+/*
+ * 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
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_ARC_PCI_H */
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 81208bfd..86ed671 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -49,7 +49,7 @@ pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t ptep)
static inline int __get_order_pgd(void)
{
- return get_order(PTRS_PER_PGD * 4);
+ return get_order(PTRS_PER_PGD * sizeof(pgd_t));
}
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -87,7 +87,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
static inline int __get_order_pte(void)
{
- return get_order(PTRS_PER_PTE * 4);
+ return get_order(PTRS_PER_PTE * sizeof(pte_t));
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
@@ -107,10 +107,10 @@ pte_alloc_one(struct mm_struct *mm, unsigned long address)
pgtable_t pte_pg;
struct page *page;
- pte_pg = __get_free_pages(GFP_KERNEL | __GFP_REPEAT, __get_order_pte());
+ pte_pg = (pgtable_t)__get_free_pages(GFP_KERNEL | __GFP_REPEAT, __get_order_pte());
if (!pte_pg)
return 0;
- memzero((void *)pte_pg, PTRS_PER_PTE * 4);
+ memzero((void *)pte_pg, PTRS_PER_PTE * sizeof(pte_t));
page = virt_to_page(pte_pg);
if (!pgtable_page_ctor(page)) {
__free_page(page);
@@ -128,12 +128,12 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
static inline void pte_free(struct mm_struct *mm, pgtable_t ptep)
{
pgtable_page_dtor(virt_to_page(ptep));
- free_pages(ptep, __get_order_pte());
+ free_pages((unsigned long)ptep, __get_order_pte());
}
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
#define check_pgt_cache() do { } while (0)
-#define pmd_pgtable(pmd) pmd_page_vaddr(pmd)
+#define pmd_pgtable(pmd) ((pgtable_t) pmd_page_vaddr(pmd))
#endif /* _ASM_ARC_PGALLOC_H */
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 1281718..d426d42 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -38,6 +38,7 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm-generic/pgtable-nopmd.h>
+#include <linux/const.h>
/**************************************************************************
* Page Table Flags
@@ -60,7 +61,8 @@
#define _PAGE_EXECUTE (1<<3) /* Page has user execute perm (H) */
#define _PAGE_WRITE (1<<4) /* Page has user write perm (H) */
#define _PAGE_READ (1<<5) /* Page has user read perm (H) */
-#define _PAGE_MODIFIED (1<<6) /* Page modified (dirty) (S) */
+#define _PAGE_DIRTY (1<<6) /* Page modified (dirty) (S) */
+#define _PAGE_SPECIAL (1<<7)
#define _PAGE_GLOBAL (1<<8) /* Page is global (H) */
#define _PAGE_PRESENT (1<<10) /* TLB entry is valid (H) */
@@ -71,7 +73,8 @@
#define _PAGE_WRITE (1<<2) /* Page has user write perm (H) */
#define _PAGE_READ (1<<3) /* Page has user read perm (H) */
#define _PAGE_ACCESSED (1<<4) /* Page is accessed (S) */
-#define _PAGE_MODIFIED (1<<5) /* Page modified (dirty) (S) */
+#define _PAGE_DIRTY (1<<5) /* Page modified (dirty) (S) */
+#define _PAGE_SPECIAL (1<<6)
#if (CONFIG_ARC_MMU_VER >= 4)
#define _PAGE_WTHRU (1<<7) /* Page cache mode write-thru (H) */
@@ -81,32 +84,33 @@
#define _PAGE_PRESENT (1<<9) /* TLB entry is valid (H) */
#if (CONFIG_ARC_MMU_VER >= 4)
-#define _PAGE_SZ (1<<10) /* Page Size indicator (H) */
+#define _PAGE_HW_SZ (1<<10) /* Page Size indicator (H): 0 normal, 1 super */
#endif
#define _PAGE_SHARED_CODE (1<<11) /* Shared Code page with cmn vaddr
usable for shared TLB entries (H) */
+
+#define _PAGE_UNUSED_BIT (1<<12)
#endif
/* vmalloc permissions */
#define _K_PAGE_PERMS (_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ | \
_PAGE_GLOBAL | _PAGE_PRESENT)
-#ifdef CONFIG_ARC_CACHE_PAGES
-#define _PAGE_DEF_CACHEABLE _PAGE_CACHEABLE
-#else
-#define _PAGE_DEF_CACHEABLE (0)
+#ifndef CONFIG_ARC_CACHE_PAGES
+#undef _PAGE_CACHEABLE
+#define _PAGE_CACHEABLE 0
#endif
-/* Helper for every "user" page
- * -kernel can R/W/X
- * -by default cached, unless config otherwise
- * -present in memory
- */
-#define ___DEF (_PAGE_PRESENT | _PAGE_DEF_CACHEABLE)
+#ifndef _PAGE_HW_SZ
+#define _PAGE_HW_SZ 0
+#endif
+
+/* Defaults for every user page */
+#define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE)
/* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED)
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
/* More Abbrevaited helpers */
#define PAGE_U_NONE __pgprot(___DEF)
@@ -122,15 +126,20 @@
* user vaddr space - visible in all addr spaces, but kernel mode only
* Thus Global, all-kernel-access, no-user-access, cached
*/
-#define PAGE_KERNEL __pgprot(_K_PAGE_PERMS | _PAGE_DEF_CACHEABLE)
+#define PAGE_KERNEL __pgprot(_K_PAGE_PERMS | _PAGE_CACHEABLE)
/* ioremap */
#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
/* Masks for actual TLB "PD"s */
-#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT)
+#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ)
#define PTE_BITS_RWX (_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ)
+
+#ifdef CONFIG_ARC_HAS_PAE40
+#define PTE_BITS_NON_RWX_IN_PD1 (0xff00000000 | PAGE_MASK | _PAGE_CACHEABLE)
+#else
#define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE)
+#endif
/**************************************************************************
* Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
@@ -170,47 +179,50 @@
#define __S111 PAGE_U_X_W_R
/****************************************************************
- * Page Table Lookup split
- *
- * We implement 2 tier paging and since this is all software, we are free
- * to customize the span of a PGD / PTE entry to suit us
+ * 2 tier (PGD:PTE) software page walker
*
- * 32 bit virtual address
+ * [31] 32 bit virtual address [0]
* -------------------------------------------------------
- * | BITS_FOR_PGD | BITS_FOR_PTE | BITS_IN_PAGE |
+ * | | <------------ PGDIR_SHIFT ----------> |
+ * | | |
+ * | BITS_FOR_PGD | BITS_FOR_PTE | <-- PAGE_SHIFT --> |
* -------------------------------------------------------
* | | |
* | | --> off in page frame
- * | |
* | ---> index into Page Table
- * |
* ----> index into Page Directory
+ *
+ * In a single page size configuration, only PAGE_SHIFT is fixed
+ * So both PGD and PTE sizing can be tweaked
+ * e.g. 8K page (PAGE_SHIFT 13) can have
+ * - PGDIR_SHIFT 21 -> 11:8:13 address split
+ * - PGDIR_SHIFT 24 -> 8:11:13 address split
+ *
+ * If Super Page is configured, PGDIR_SHIFT becomes fixed too,
+ * so the sizing flexibility is gone.
*/
-#define BITS_IN_PAGE PAGE_SHIFT
-
-/* Optimal Sizing of Pg Tbl - based on MMU page size */
-#if defined(CONFIG_ARC_PAGE_SIZE_8K)
-#define BITS_FOR_PTE 8
-#elif defined(CONFIG_ARC_PAGE_SIZE_16K)
-#define BITS_FOR_PTE 8
-#elif defined(CONFIG_ARC_PAGE_SIZE_4K)
-#define BITS_FOR_PTE 9
+#if defined(CONFIG_ARC_HUGEPAGE_16M)
+#define PGDIR_SHIFT 24
+#elif defined(CONFIG_ARC_HUGEPAGE_2M)
+#define PGDIR_SHIFT 21
+#else
+/*
+ * Only Normal page support so "hackable" (see comment above)
+ * Default value provides 11:8:13 (8K), 11:9:12 (4K)
+ */
+#define PGDIR_SHIFT 21
#endif
-#define BITS_FOR_PGD (32 - BITS_FOR_PTE - BITS_IN_PAGE)
+#define BITS_FOR_PTE (PGDIR_SHIFT - PAGE_SHIFT)
+#define BITS_FOR_PGD (32 - PGDIR_SHIFT)
-#define PGDIR_SHIFT (BITS_FOR_PTE + BITS_IN_PAGE)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT) /* vaddr span, not PDG sz */
#define PGDIR_MASK (~(PGDIR_SIZE-1))
-#ifdef __ASSEMBLY__
-#define PTRS_PER_PTE (1 << BITS_FOR_PTE)
-#define PTRS_PER_PGD (1 << BITS_FOR_PGD)
-#else
-#define PTRS_PER_PTE (1UL << BITS_FOR_PTE)
-#define PTRS_PER_PGD (1UL << BITS_FOR_PGD)
-#endif
+#define PTRS_PER_PTE _BITUL(BITS_FOR_PTE)
+#define PTRS_PER_PGD _BITUL(BITS_FOR_PGD)
+
/*
* Number of entries a user land program use.
* TASK_SIZE is the maximum vaddr that can be used by a userland program.
@@ -270,15 +282,10 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
(unsigned long)(((pte_val(x) - CONFIG_LINUX_LINK_BASE) >> \
PAGE_SHIFT)))
-#define mk_pte(page, pgprot) \
-({ \
- pte_t pte; \
- pte_val(pte) = __pa(page_address(page)) + pgprot_val(pgprot); \
- pte; \
-})
-
+#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
-#define pfn_pte(pfn, prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \
+ pgprot_val(prot)))
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
/*
@@ -295,23 +302,26 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
/* Zoo of pte_xxx function */
#define pte_read(pte) (pte_val(pte) & _PAGE_READ)
#define pte_write(pte) (pte_val(pte) & _PAGE_WRITE)
-#define pte_dirty(pte) (pte_val(pte) & _PAGE_MODIFIED)
+#define pte_dirty(pte) (pte_val(pte) & _PAGE_DIRTY)
#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED)
-#define pte_special(pte) (0)
+#define pte_special(pte) (pte_val(pte) & _PAGE_SPECIAL)
#define PTE_BIT_FUNC(fn, op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+PTE_BIT_FUNC(mknotpresent, &= ~(_PAGE_PRESENT));
PTE_BIT_FUNC(wrprotect, &= ~(_PAGE_WRITE));
PTE_BIT_FUNC(mkwrite, |= (_PAGE_WRITE));
-PTE_BIT_FUNC(mkclean, &= ~(_PAGE_MODIFIED));
-PTE_BIT_FUNC(mkdirty, |= (_PAGE_MODIFIED));
+PTE_BIT_FUNC(mkclean, &= ~(_PAGE_DIRTY));
+PTE_BIT_FUNC(mkdirty, |= (_PAGE_DIRTY));
PTE_BIT_FUNC(mkold, &= ~(_PAGE_ACCESSED));
PTE_BIT_FUNC(mkyoung, |= (_PAGE_ACCESSED));
PTE_BIT_FUNC(exprotect, &= ~(_PAGE_EXECUTE));
PTE_BIT_FUNC(mkexec, |= (_PAGE_EXECUTE));
+PTE_BIT_FUNC(mkspecial, |= (_PAGE_SPECIAL));
+PTE_BIT_FUNC(mkhuge, |= (_PAGE_HW_SZ));
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+#define __HAVE_ARCH_PTE_SPECIAL
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
@@ -357,7 +367,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
#define pgd_offset_fast(mm, addr) pgd_offset(mm, addr)
#endif
-extern void paging_init(void);
extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
pte_t *ptep);
@@ -383,6 +392,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
* remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#include <asm/hugepage.h>
+#endif
+
#include <asm-generic/pgtable.h>
/* to cope with aliasing VIPT cache */
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index ee682d8..1d694c1 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,11 +57,7 @@ struct task_struct;
* A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
* get optimised away by gcc
*/
-#ifdef CONFIG_SMP
#define cpu_relax() __asm__ __volatile__ ("" : : : "memory")
-#else
-#define cpu_relax() do { } while (0)
-#endif
#define cpu_relax_lowlatency() cpu_relax()
@@ -114,7 +110,12 @@ extern unsigned int get_wchan(struct task_struct *p);
* -----------------------------------------------------------------------------
*/
#define VMALLOC_START 0x70000000
-#define VMALLOC_SIZE (PAGE_OFFSET - VMALLOC_START)
+
+/*
+ * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
+ * See asm/highmem.h for details
+ */
+#define VMALLOC_SIZE (PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
#define USER_KERNEL_GUTTER 0x10000000
diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 6e3ef5b..3078466 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -33,4 +33,11 @@ extern int root_mountflags, end_mem;
void setup_processor(void);
void __init setup_arch_memory(void);
+/* Helpers used in arc_*_mumbojumbo routines */
+#define IS_AVAIL1(v, s) ((v) ? s : "")
+#define IS_DISABLED_RUN(v) ((v) ? "" : "(disabled) ")
+#define IS_USED_RUN(v) ((v) ? "" : "(not used) ")
+#define IS_USED_CFG(cfg) IS_USED_RUN(IS_ENABLED(cfg))
+#define IS_AVAIL2(v, s, cfg) IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
+
#endif /* __ASMARC_SETUP_H */
diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 3845b9e..9913804 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -45,12 +45,19 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
* struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP
*
* @info: SoC SMP specific info for /proc/cpuinfo etc
+ * @init_early_smp: A SMP specific h/w block can init itself
+ * Could be common across platforms so not covered by
+ * mach_desc->init_early()
+ * @init_per_cpu: Called for each core so SMP h/w block driver can do
+ * any needed setup per cpu (e.g. IPI request)
* @cpu_kick: For Master to kickstart a cpu (optionally at a PC)
* @ipi_send: To send IPI to a @cpu
* @ips_clear: To clear IPI received at @irq
*/
struct plat_smp_ops {
const char *info;
+ void (*init_early_smp)(void);
+ void (*init_per_cpu)(int cpu);
void (*cpu_kick)(int cpu, unsigned long pc);
void (*ipi_send)(int cpu);
void (*ipi_clear)(int irq);
diff --git a/arch/arc/include/asm/tlbflush.h b/arch/arc/include/asm/tlbflush.h
index 71c7b2e..1fe9c8c 100644
--- a/arch/arc/include/asm/tlbflush.h
+++ b/arch/arc/include/asm/tlbflush.h
@@ -17,6 +17,8 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end);
void local_flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
+void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end);
#ifndef CONFIG_SMP
#define flush_tlb_range(vma, s, e) local_flush_tlb_range(vma, s, e)
@@ -24,6 +26,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma,
#define flush_tlb_kernel_range(s, e) local_flush_tlb_kernel_range(s, e)
#define flush_tlb_all() local_flush_tlb_all()
#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
+#define flush_pmd_tlb_range(vma, s, e) local_flush_pmd_tlb_range(vma, s, e)
#else
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
@@ -31,5 +34,7 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+
#endif /* CONFIG_SMP */
#endif
diff --git a/arch/arc/include/asm/unwind.h b/arch/arc/include/asm/unwind.h
index 7ca628b..c11a25b 100644
--- a/arch/arc/include/asm/unwind.h
+++ b/arch/arc/include/asm/unwind.h
@@ -112,7 +112,6 @@ struct unwind_frame_info {
extern int arc_unwind(struct unwind_frame_info *frame);
extern void arc_unwind_init(void);
-extern void arc_unwind_setup(void);
extern void *unwind_add_table(struct module *module, const void *table_start,
unsigned long table_size);
extern void unwind_remove_table(void *handle, int init_only);
@@ -152,9 +151,6 @@ static inline void arc_unwind_init(void)
{
}
-static inline void arc_unwind_setup(void)
-{
-}
#define unwind_add_table(a, b, c)
#define unwind_remove_table(a, b)
diff --git a/arch/arc/include/uapi/asm/page.h b/arch/arc/include/uapi/asm/page.h
index 9d129a2..059aff3 100644
--- a/arch/arc/include/uapi/asm/page.h
+++ b/arch/arc/include/uapi/asm/page.h
@@ -9,6 +9,8 @@
#ifndef _UAPI__ASM_ARC_PAGE_H
#define _UAPI__ASM_ARC_PAGE_H
+#include <linux/const.h>
+
/* PAGE_SHIFT determines the page size */
#if defined(CONFIG_ARC_PAGE_SIZE_16K)
#define PAGE_SHIFT 14
@@ -25,13 +27,8 @@
#define PAGE_SHIFT 13
#endif
-#ifdef __ASSEMBLY__
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define PAGE_OFFSET (0x80000000)
-#else
-#define PAGE_SIZE (1UL << PAGE_SHIFT) /* Default 8K */
-#define PAGE_OFFSET (0x80000000UL) /* Kernel starts at 2G onwards */
-#endif
+#define PAGE_SIZE _BITUL(PAGE_SHIFT) /* Default 8K */
+#define PAGE_OFFSET _AC(0x80000000, UL) /* Kernel starts at 2G onwrds */
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index e7f3625..1bc2036 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -12,6 +12,7 @@ obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o
obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
+obj-$(CONFIG_PCI) += pcibios.o
obj-$(CONFIG_MODULES) += arcksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5be..5d446df 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -58,8 +58,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
"st sp, [r24] \n\t"
#endif
- "sync \n\t"
-
/*
* setup _current_task with incoming tsk.
* optionally, set r25 to that as well
diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S
index e248594..e6890b1 100644
--- a/arch/arc/kernel/ctx_sw_asm.S
+++ b/arch/arc/kernel/ctx_sw_asm.S
@@ -44,9 +44,6 @@ __switch_to:
* don't need to do anything special to return it
*/
- /* hardware memory barrier */
- sync
-
/*
* switch to new task, contained in r1
* Temp reg r3 is required to get the ptr to store val
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index 8fa7656..c126460 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -24,7 +24,7 @@
.align 4
# Initial 16 slots are Exception Vectors
-VECTOR stext ; Restart Vector (jump to entry point)
+VECTOR res_service ; Reset Vector
VECTOR mem_service ; Mem exception
VECTOR instr_service ; Instrn Error
VECTOR EV_MachineCheck ; Fatal Machine check
@@ -45,11 +45,12 @@ VECTOR reserved ; Reserved slots
VECTOR handle_interrupt ; (16) Timer0
VECTOR handle_interrupt ; unused (Timer1)
VECTOR handle_interrupt ; unused (WDT)
-VECTOR handle_interrupt ; (19) ICI (inter core interrupt)
-VECTOR handle_interrupt
-VECTOR handle_interrupt
-VECTOR handle_interrupt
-VECTOR handle_interrupt ; (23) End of fixed IRQs
+VECTOR handle_interrupt ; (19) Inter core Interrupt (IPI)
+VECTOR handle_interrupt ; (20) perf Interrupt
+VECTOR handle_interrupt ; (21) Software Triggered Intr (Self IPI)
+VECTOR handle_interrupt ; unused
+VECTOR handle_interrupt ; (23) unused
+# End of fixed IRQs
.rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8
VECTOR handle_interrupt
@@ -91,6 +92,25 @@ ENTRY(EV_DCError)
flag 1
END(EV_DCError)
+; ---------------------------------------------
+; Memory Error Exception Handler
+; - Unlike ARCompact, handles Bus errors for both User/Kernel mode,
+; Instruction fetch or Data access, under a single Exception Vector
+; ---------------------------------------------
+
+ENTRY(mem_service)
+
+ EXCEPTION_PROLOGUE
+
+ lr r0, [efa]
+ mov r1, sp
+
+ FAKE_RET_FROM_EXCPN
+
+ bl do_memory_error
+ b ret_from_exception
+END(mem_service)
+
ENTRY(EV_Misaligned)
EXCEPTION_PROLOGUE
@@ -192,7 +212,11 @@ debug_marker_syscall:
; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig
; entry was via Exception in DS which got preempted in kernel).
;
-; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling
+; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
+;
+; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline
+; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly
+
.Lintr_ret_to_delay_slot:
debug_marker_ds:
@@ -203,18 +227,23 @@ debug_marker_ds:
ld r2, [sp, PT_ret]
ld r3, [sp, PT_status32]
+ ; STAT32 for Int return created from scratch
+ ; (No delay dlot, disable Further intr in trampoline)
+
bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
st r0, [sp, PT_status32]
mov r1, .Lintr_ret_to_delay_slot_2
st r1, [sp, PT_ret]
+ ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
st r2, [sp, 0]
st r3, [sp, 4]
b .Lisr_ret_fast_path
.Lintr_ret_to_delay_slot_2:
+ ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
sub sp, sp, SZ_PT_REGS
st r9, [sp, -4]
@@ -224,11 +253,19 @@ debug_marker_ds:
ld r9, [sp, 4]
sr r9, [erstatus]
+ ; restore AUX_USER_SP if returning to U mode
+ bbit0 r9, STATUS_U_BIT, 1f
+ ld r9, [sp, PT_sp]
+ sr r9, [AUX_USER_SP]
+
+1:
ld r9, [sp, 8]
sr r9, [erbta]
ld r9, [sp, -4]
add sp, sp, SZ_PT_REGS
+
+ ; return from pure kernel mode to delay slot
rtie
END(ret_from_exception)
diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S
index 15d457b..4314339 100644
--- a/arch/arc/kernel/entry-compact.S
+++ b/arch/arc/kernel/entry-compact.S
@@ -86,7 +86,7 @@
*/
; ********* Critical System Events **********************
-VECTOR res_service ; 0x0, Restart Vector (0x0)
+VECTOR res_service ; 0x0, Reset Vector (0x0)
VECTOR mem_service ; 0x8, Mem exception (0x1)
VECTOR instr_service ; 0x10, Instrn Error (0x2)
@@ -142,26 +142,18 @@ int1_saved_reg:
.zero 4
/* Each Interrupt level needs its own scratch */
-#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
-
ARCFP_DATA int2_saved_reg
.type int2_saved_reg, @object
.size int2_saved_reg, 4
int2_saved_reg:
.zero 4
-#endif
-
; ---------------------------------------------
.section .text, "ax",@progbits
-res_service: ; processor restart
- flag 0x1 ; not implemented
- nop
- nop
-reserved: ; processor restart
- rtie ; jump to processor initializations
+reserved:
+ flag 1 ; Unexpected event, halt
;##################### Interrupt Handling ##############################
@@ -175,12 +167,25 @@ ENTRY(handle_interrupt_level2)
;------------------------------------------------------
; if L2 IRQ interrupted a L1 ISR, disable preemption
+ ;
+ ; This is to avoid a potential L1-L2-L1 scenario
+ ; -L1 IRQ taken
+ ; -L2 interrupts L1 (before L1 ISR could run)
+ ; -preemption off IRQ, user task in syscall picked to run
+ ; -RTIE to userspace
+ ; Returns from L2 context fine
+ ; But both L1 and L2 re-enabled, so another L1 can be taken
+ ; while prev L1 is still unserviced
+ ;
;------------------------------------------------------
+ ; L2 interrupting L1 implies both L2 and L1 active
+ ; However both A2 and A1 are NOT set in STATUS32, thus
+ ; need to check STATUS32_L2 to determine if L1 was active
+
ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs)
bbit0 r9, STATUS_A1_BIT, 1f ; L1 not active when L2 IRQ, so normal
- ; A1 is set in status32_l2
; bump thread_info->preempt_count (Disable preemption)
GET_CURR_THR_INFO_FROM_SP r10
ld r9, [r10, THREAD_INFO_PREEMPT_COUNT]
@@ -207,6 +212,31 @@ END(handle_interrupt_level2)
#endif
; ---------------------------------------------
+; User Mode Memory Bus Error Interrupt Handler
+; (Kernel mode memory errors handled via seperate exception vectors)
+; ---------------------------------------------
+ENTRY(mem_service)
+
+ INTERRUPT_PROLOGUE 2
+
+ mov r0, ilink2
+ mov r1, sp
+
+ ; User process needs to be killed with SIGBUS, but first need to get
+ ; out of the L2 interrupt context (drop to pure kernel mode) and jump
+ ; off to "C" code where SIGBUS in enqueued
+ lr r3, [status32]
+ bclr r3, r3, STATUS_A2_BIT
+ or r3, r3, (STATUS_E1_MASK|STATUS_E2_MASK)
+ sr r3, [status32_l2]
+ mov ilink2, 1f
+ rtie
+1:
+ bl do_memory_error
+ b ret_from_exception
+END(mem_service)
+
+; ---------------------------------------------
; Level 1 ISR
; ---------------------------------------------
ENTRY(handle_interrupt_level1)
@@ -320,11 +350,10 @@ END(call_do_page_fault)
; Note that we use realtime STATUS32 (not pt_regs->status32) to
; decide that.
- ; if Returning from Exception
- btst r10, STATUS_AE_BIT
- bnz .Lexcep_ret
+ and.f 0, r10, (STATUS_A1_MASK|STATUS_A2_MASK)
+ bz .Lexcep_or_pure_K_ret
- ; Not Exception so maybe Interrupts (Level 1 or 2)
+ ; Returning from Interrupts (Level 1 or 2)
#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
@@ -365,8 +394,7 @@ END(call_do_page_fault)
st r9, [r10, THREAD_INFO_PREEMPT_COUNT]
149:
- ;return from level 2
- INTERRUPT_EPILOGUE 2
+ INTERRUPT_EPILOGUE 2 ; return from level 2 interrupt
debug_marker_l2:
rtie
@@ -374,15 +402,11 @@ not_level2_interrupt:
#endif
- bbit0 r10, STATUS_A1_BIT, .Lpure_k_mode_ret
-
- ;return from level 1
- INTERRUPT_EPILOGUE 1
+ INTERRUPT_EPILOGUE 1 ; return from level 1 interrupt
debug_marker_l1:
rtie
-.Lexcep_ret:
-.Lpure_k_mode_ret:
+.Lexcep_or_pure_K_ret:
;this case is for syscalls or Exceptions or pure kernel mode
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 589abf5..2efb0625 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -93,23 +93,6 @@ ENTRY(instr_service)
END(instr_service)
; ---------------------------------------------
-; Memory Error Exception Handler
-; ---------------------------------------------
-
-ENTRY(mem_service)
-
- EXCEPTION_PROLOGUE
-
- lr r0, [efa]
- mov r1, sp
-
- FAKE_RET_FROM_EXCPN
-
- bl do_memory_error
- b ret_from_exception
-END(mem_service)
-
-; ---------------------------------------------
; Machine Check Exception Handler
; ---------------------------------------------
diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S
index 812f95e..689dd86 100644
--- a/arch/arc/kernel/head.S
+++ b/arch/arc/kernel/head.S
@@ -50,28 +50,37 @@
.endm
.section .init.text, "ax",@progbits
- .type stext, @function
- .globl stext
-stext:
- ;-------------------------------------------------------------------
- ; Don't clobber r0-r2 yet. It might have bootloader provided info
- ;-------------------------------------------------------------------
+
+;----------------------------------------------------------------
+; Default Reset Handler (jumped into from Reset vector)
+; - Don't clobber r0,r1,r2 as they might have u-boot provided args
+; - Platforms can override this weak version if needed
+;----------------------------------------------------------------
+WEAK(res_service)
+ j stext
+END(res_service)
+
+;----------------------------------------------------------------
+; Kernel Entry point
+;----------------------------------------------------------------
+ENTRY(stext)
CPU_EARLY_SETUP
#ifdef CONFIG_SMP
- ; Ensure Boot (Master) proceeds. Others wait in platform dependent way
- ; IDENTITY Reg [ 3 2 1 0 ]
- ; (cpu-id) ^^^ => Zero for UP ARC700
- ; => #Core-ID if SMP (Master 0)
- ; Note that non-boot CPUs might not land here if halt-on-reset and
- ; instead breath life from @first_lines_of_secondary, but we still
- ; need to make sure only boot cpu takes this path.
GET_CPU_ID r5
cmp r5, 0
- mov.ne r0, r5
- jne arc_platform_smp_wait_to_boot
+ mov.nz r0, r5
+#ifdef CONFIG_ARC_SMP_HALT_ON_RESET
+ ; Non-Master can proceed as system would be booted sufficiently
+ jnz first_lines_of_secondary
+#else
+ ; Non-Masters wait for Master to boot enough and bring them up
+ jnz arc_platform_smp_wait_to_boot
#endif
+ ; Master falls thru
+#endif
+
; Clear BSS before updating any globals
; XXX: use ZOL here
mov r5, __bss_start
@@ -102,18 +111,14 @@ stext:
GET_TSK_STACK_BASE r9, sp ; r9 = tsk, sp = stack base(output)
j start_kernel ; "C" entry point
+END(stext)
#ifdef CONFIG_SMP
;----------------------------------------------------------------
; First lines of code run by secondary before jumping to 'C'
;----------------------------------------------------------------
.section .text, "ax",@progbits
- .type first_lines_of_secondary, @function
- .globl first_lines_of_secondary
-
-first_lines_of_secondary:
-
- CPU_EARLY_SETUP
+ENTRY(first_lines_of_secondary)
; setup per-cpu idle task as "current" on this CPU
ld r0, [@secondary_idle_tsk]
@@ -126,5 +131,5 @@ first_lines_of_secondary:
GET_TSK_STACK_BASE r0, sp
j start_kernel_secondary
-
+END(first_lines_of_secondary)
#endif
diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index 26c1568..9425263 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -14,6 +14,8 @@
#include <linux/irqchip.h>
#include <asm/irq.h>
+static int irq_prio;
+
/*
* Early Hardware specific Interrupt setup
* -Called very early (start_kernel -> setup_arch -> setup_processor)
@@ -24,6 +26,14 @@ void arc_init_IRQ(void)
{
unsigned int tmp;
+ struct irq_build {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8;
+#else
+ unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3;
+#endif
+ } irq_bcr;
+
struct aux_irq_ctrl {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int res3:18, save_idx_regs:1, res2:1,
@@ -46,28 +56,25 @@ void arc_init_IRQ(void)
WRITE_AUX(AUX_IRQ_CTRL, ictrl);
- /* setup status32, don't enable intr yet as kernel doesn't want */
- tmp = read_aux_reg(0xa);
- tmp |= ISA_INIT_STATUS_BITS;
- tmp &= ~STATUS_IE_MASK;
- asm volatile("flag %0 \n"::"r"(tmp));
-
/*
* ARCv2 core intc provides multiple interrupt priorities (upto 16).
* Typical builds though have only two levels (0-high, 1-low)
* Linux by default uses lower prio 1 for most irqs, reserving 0 for
* NMI style interrupts in future (say perf)
- *
- * Read the intc BCR to confirm that Linux default priority is avail
- * in h/w
- *
- * Note:
- * IRQ_BCR[27..24] contains N-1 (for N priority levels) and prio level
- * is 0 based.
*/
- tmp = (read_aux_reg(ARC_REG_IRQ_BCR) >> 24 ) & 0xF;
- if (ARCV2_IRQ_DEF_PRIO > tmp)
- panic("Linux default irq prio incorrect\n");
+
+ READ_BCR(ARC_REG_IRQ_BCR, irq_bcr);
+
+ irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */
+ pr_info("archs-intc\t: %d priority levels (default %d)%s\n",
+ irq_prio + 1, irq_prio,
+ irq_bcr.firq ? " FIRQ (not used)":"");
+
+ /* setup status32, don't enable intr yet as kernel doesn't want */
+ tmp = read_aux_reg(0xa);
+ tmp |= STATUS_AD_MASK | (irq_prio << 1);
+ tmp &= ~STATUS_IE_MASK;
+ asm volatile("flag %0 \n"::"r"(tmp));
}
static void arcv2_irq_mask(struct irq_data *data)
@@ -86,7 +93,7 @@ void arcv2_irq_enable(struct irq_data *data)
{
/* set default priority */
write_aux_reg(AUX_IRQ_SELECT, data->irq);
- write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO);
+ write_aux_reg(AUX_IRQ_PRIORITY, irq_prio);
/*
* hw auto enables (linux unmask) all by default
@@ -106,10 +113,21 @@ static struct irq_chip arcv2_irq_chip = {
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
- if (irq == TIMER0_IRQ || irq == IPI_IRQ)
+ /*
+ * core intc IRQs [16, 23]:
+ * Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
+ */
+ if (hw < 24) {
+ /*
+ * A subsequent request_percpu_irq() fails if percpu_devid is
+ * not set. That in turns sets NOAUTOEN, meaning each core needs
+ * to call enable_percpu_irq()
+ */
+ irq_set_percpu_devid(irq);
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
- else
+ } else {
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
+ }
return 0;
}
diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c
index 039fac3..224d1c3 100644
--- a/arch/arc/kernel/intc-compact.c
+++ b/arch/arc/kernel/intc-compact.c
@@ -79,17 +79,13 @@ static struct irq_chip onchip_intc = {
static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
- /*
- * XXX: the IPI IRQ needs to be handled like TIMER too. However ARC core
- * code doesn't own it (like TIMER0). ISS IDU / ezchip define it
- * in platform header which can't be included here as it goes
- * against multi-platform image philisophy
- */
- if (irq == TIMER0_IRQ)
+ switch (irq) {
+ case TIMER0_IRQ:
irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq);
- else
+ break;
+ default:
irq_set_chip_and_handler(irq, &onchip_intc, handle_level_irq);
-
+ }
return 0;
}
@@ -148,78 +144,15 @@ IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ);
void arch_local_irq_enable(void)
{
-
unsigned long flags = arch_local_save_flags();
- /* Allow both L1 and L2 at the onset */
- flags |= (STATUS_E1_MASK | STATUS_E2_MASK);
-
- /* Called from hard ISR (between irq_enter and irq_exit) */
- if (in_irq()) {
-
- /* If in L2 ISR, don't re-enable any further IRQs as this can
- * cause IRQ priorities to get upside down. e.g. it could allow
- * L1 be taken while in L2 hard ISR which is wrong not only in
- * theory, it can also cause the dreaded L1-L2-L1 scenario
- */
- if (flags & STATUS_A2_MASK)
- flags &= ~(STATUS_E1_MASK | STATUS_E2_MASK);
-
- /* Even if in L1 ISR, allowe Higher prio L2 IRQs */
- else if (flags & STATUS_A1_MASK)
- flags &= ~(STATUS_E1_MASK);
- }
-
- /* called from soft IRQ, ideally we want to re-enable all levels */
-
- else if (in_softirq()) {
-
- /* However if this is case of L1 interrupted by L2,
- * re-enabling both may cause whaco L1-L2-L1 scenario
- * because ARC700 allows level 1 to interrupt an active L2 ISR
- * Thus we disable both
- * However some code, executing in soft ISR wants some IRQs
- * to be enabled so we re-enable L2 only
- *
- * How do we determine L1 intr by L2
- * -A2 is set (means in L2 ISR)
- * -E1 is set in this ISR's pt_regs->status32 which is
- * saved copy of status32_l2 when l2 ISR happened
- */
- struct pt_regs *pt = get_irq_regs();
-
- if ((flags & STATUS_A2_MASK) && pt &&
- (pt->status32 & STATUS_A1_MASK)) {
- /*flags &= ~(STATUS_E1_MASK | STATUS_E2_MASK); */
- flags &= ~(STATUS_E1_MASK);
- }
- }
+ if (flags & STATUS_A2_MASK)
+ flags |= STATUS_E2_MASK;
+ else if (flags & STATUS_A1_MASK)
+ flags |= STATUS_E1_MASK;
arch_local_irq_restore(flags);
}
-#else /* ! CONFIG_ARC_COMPACT_IRQ_LEVELS */
-
-/*
- * Simpler version for only 1 level of interrupt
- * Here we only Worry about Level 1 Bits
- */
-void arch_local_irq_enable(void)
-{
- unsigned long flags;
-
- /*
- * ARC IDE Drivers tries to re-enable interrupts from hard-isr
- * context which is simply wrong
- */
- if (in_irq()) {
- WARN_ONCE(1, "IRQ enabled from hard-isr");
- return;
- }
-
- flags = arch_local_save_flags();
- flags |= (STATUS_E1_MASK | STATUS_E2_MASK);
- arch_local_irq_restore(flags);
-}
-#endif
EXPORT_SYMBOL(arch_local_irq_enable);
+#endif
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2989a7b..ba17f85 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/irqchip.h>
#include <asm/mach_desc.h>
+#include <asm/smp.h>
/*
* Late Interrupt system init called from start_kernel for Boot CPU only
@@ -19,17 +20,20 @@
*/
void __init init_IRQ(void)
{
- /* Any external intc can be setup here */
- if (machine_desc->init_irq)
- machine_desc->init_irq();
-
- /* process the entire interrupt tree in one go */
+ /*
+ * process the entire interrupt tree in one go
+ * Any external intc will be setup provided DT chains them
+ * properly
+ */
irqchip_init();
#ifdef CONFIG_SMP
- /* Master CPU can initialize it's side of IPI */
- if (machine_desc->init_smp)
- machine_desc->init_smp(smp_processor_id());
+ /* a SMP H/w block could do IPI IRQ request here */
+ if (plat_smp_ops.init_per_cpu)
+ plat_smp_ops.init_per_cpu(smp_processor_id());
+
+ if (machine_desc->init_per_cpu)
+ machine_desc->init_per_cpu(smp_processor_id());
#endif
}
@@ -47,6 +51,18 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs);
}
+/*
+ * API called for requesting percpu interrupts - called by each CPU
+ * - For boot CPU, actually request the IRQ with genirq core + enables
+ * - For subsequent callers only enable called locally
+ *
+ * Relies on being called by boot cpu first (i.e. request called ahead) of
+ * any enable as expected by genirq. Hence Suitable only for TIMER, IPI
+ * which are guaranteed to be setup on boot core first.
+ * Late probed peripherals such as perf can't use this as there no guarantee
+ * of being called on boot CPU first.
+ */
+
void arc_request_percpu_irq(int irq, int cpu,
irqreturn_t (*isr)(int irq, void *dev),
const char *irq_nm,
@@ -56,14 +72,17 @@ void arc_request_percpu_irq(int irq, int cpu,
if (!cpu) {
int rc;
+#ifdef CONFIG_ISA_ARCOMPACT
/*
- * These 2 calls are essential to making percpu IRQ APIs work
- * Ideally these details could be hidden in irq chip map function
- * but the issue is IPIs IRQs being static (non-DT) and platform
- * specific, so we can't identify them there.
+ * A subsequent request_percpu_irq() fails if percpu_devid is
+ * not set. That in turns sets NOAUTOEN, meaning each core needs
+ * to call enable_percpu_irq()
+ *
+ * For ARCv2, this is done in irq map function since we know
+ * which irqs are strictly per cpu
*/
irq_set_percpu_devid(irq);
- irq_modify_status(irq, IRQ_NOAUTOEN, 0); /* @irq, @clr, @set */
+#endif
rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
if (rc)
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 4ffd185..c41c364 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -11,23 +11,22 @@
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
+#include <asm/irqflags-arcv2.h>
#include <asm/mcip.h>
+#include <asm/setup.h>
+
+#define IPI_IRQ 19
+#define SOFTIRQ_IRQ 21
static char smp_cpuinfo_buf[128];
static int idu_detected;
static DEFINE_RAW_SPINLOCK(mcip_lock);
-/*
- * Any SMP specific init any CPU does when it comes up.
- * Here we setup the CPU to enable Inter-Processor-Interrupts
- * Called for each CPU
- * -Master : init_IRQ()
- * -Other(s) : start_kernel_secondary()
- */
-void mcip_init_smp(unsigned int cpu)
+static void mcip_setup_per_cpu(int cpu)
{
smp_ipi_irq_setup(cpu, IPI_IRQ);
+ smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
}
static void mcip_ipi_send(int cpu)
@@ -35,46 +34,44 @@ static void mcip_ipi_send(int cpu)
unsigned long flags;
int ipi_was_pending;
+ /* ARConnect can only send IPI to others */
+ if (unlikely(cpu == raw_smp_processor_id())) {
+ arc_softirq_trigger(SOFTIRQ_IRQ);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&mcip_lock, flags);
+
/*
- * NOTE: We must spin here if the other cpu hasn't yet
- * serviced a previous message. This can burn lots
- * of time, but we MUST follows this protocol or
- * ipi messages can be lost!!!
- * Also, we must release the lock in this loop because
- * the other side may get to this same loop and not
- * be able to ack -- thus causing deadlock.
+ * If receiver already has a pending interrupt, elide sending this one.
+ * Linux cross core calling works well with concurrent IPIs
+ * coalesced into one
+ * see arch/arc/kernel/smp.c: ipi_send_msg_one()
*/
+ __mcip_cmd(CMD_INTRPT_READ_STATUS, cpu);
+ ipi_was_pending = read_aux_reg(ARC_REG_MCIP_READBACK);
+ if (!ipi_was_pending)
+ __mcip_cmd(CMD_INTRPT_GENERATE_IRQ, cpu);
- do {
- raw_spin_lock_irqsave(&mcip_lock, flags);
- __mcip_cmd(CMD_INTRPT_READ_STATUS, cpu);
- ipi_was_pending = read_aux_reg(ARC_REG_MCIP_READBACK);
- if (ipi_was_pending == 0)
- break; /* break out but keep lock */
- raw_spin_unlock_irqrestore(&mcip_lock, flags);
- } while (1);
-
- __mcip_cmd(CMD_INTRPT_GENERATE_IRQ, cpu);
raw_spin_unlock_irqrestore(&mcip_lock, flags);
-
-#ifdef CONFIG_ARC_IPI_DBG
- if (ipi_was_pending)
- pr_info("IPI ACK delayed from cpu %d\n", cpu);
-#endif
}
static void mcip_ipi_clear(int irq)
{
unsigned int cpu, c;
unsigned long flags;
- unsigned int __maybe_unused copy;
+
+ if (unlikely(irq == SOFTIRQ_IRQ)) {
+ arc_softirq_clear(irq);
+ return;
+ }
raw_spin_lock_irqsave(&mcip_lock, flags);
/* Who sent the IPI */
__mcip_cmd(CMD_INTRPT_CHECK_SOURCE, 0);
- copy = cpu = read_aux_reg(ARC_REG_MCIP_READBACK); /* 1,2,4,8... */
+ cpu = read_aux_reg(ARC_REG_MCIP_READBACK); /* 1,2,4,8... */
/*
* In rare case, multiple concurrent IPIs sent to same target can
@@ -88,53 +85,21 @@ static void mcip_ipi_clear(int irq)
} while (cpu);
raw_spin_unlock_irqrestore(&mcip_lock, flags);
-
-#ifdef CONFIG_ARC_IPI_DBG
- if (c != __ffs(copy))
- pr_info("IPIs from %x coalesced to %x\n",
- copy, raw_smp_processor_id());
-#endif
-}
-
-volatile int wake_flag;
-
-static void mcip_wakeup_cpu(int cpu, unsigned long pc)
-{
- BUG_ON(cpu == 0);
- wake_flag = cpu;
}
-void arc_platform_smp_wait_to_boot(int cpu)
+static void mcip_probe_n_setup(void)
{
- while (wake_flag != cpu)
- ;
-
- wake_flag = 0;
- __asm__ __volatile__("j @first_lines_of_secondary \n");
-}
-
-struct plat_smp_ops plat_smp_ops = {
- .info = smp_cpuinfo_buf,
- .cpu_kick = mcip_wakeup_cpu,
- .ipi_send = mcip_ipi_send,
- .ipi_clear = mcip_ipi_clear,
-};
-
-void mcip_init_early_smp(void)
-{
-#define IS_AVAIL1(var, str) ((var) ? str : "")
-
struct mcip_bcr {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad3:8,
idu:1, llm:1, num_cores:6,
- iocoh:1, grtc:1, dbg:1, pad2:1,
+ iocoh:1, gfrc:1, dbg:1, pad2:1,
msg:1, sem:1, ipi:1, pad:1,
ver:8;
#else
unsigned int ver:8,
pad:1, ipi:1, sem:1, msg:1,
- pad2:1, dbg:1, grtc:1, iocoh:1,
+ pad2:1, dbg:1, gfrc:1, iocoh:1,
num_cores:6, llm:1, idu:1,
pad3:8;
#endif
@@ -143,12 +108,13 @@ void mcip_init_early_smp(void)
READ_BCR(ARC_REG_MCIP_BCR, mp);
sprintf(smp_cpuinfo_buf,
- "Extn [SMP]\t: ARConnect (v%d): %d cores with %s%s%s%s\n",
+ "Extn [SMP]\t: ARConnect (v%d): %d cores with %s%s%s%s%s\n",
mp.ver, mp.num_cores,
IS_AVAIL1(mp.ipi, "IPI "),
IS_AVAIL1(mp.idu, "IDU "),
+ IS_AVAIL1(mp.llm, "LLM "),
IS_AVAIL1(mp.dbg, "DEBUG "),
- IS_AVAIL1(mp.grtc, "GRTC"));
+ IS_AVAIL1(mp.gfrc, "GFRC"));
idu_detected = mp.idu;
@@ -157,10 +123,18 @@ void mcip_init_early_smp(void)
__mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
}
- if (IS_ENABLED(CONFIG_ARC_HAS_GRTC) && !mp.grtc)
- panic("kernel trying to use non-existent GRTC\n");
+ if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc)
+ panic("kernel trying to use non-existent GFRC\n");
}
+struct plat_smp_ops plat_smp_ops = {
+ .info = smp_cpuinfo_buf,
+ .init_early_smp = mcip_probe_n_setup,
+ .init_per_cpu = mcip_setup_per_cpu,
+ .ipi_send = mcip_ipi_send,
+ .ipi_clear = mcip_ipi_clear,
+};
+
/***************************************************************************
* ARCv2 Interrupt Distribution Unit (IDU)
*
diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c
new file mode 100644
index 0000000..72e1d73
--- /dev/null
+++ b/arch/arc/kernel/pcibios.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it 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>
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ return res->start;
+}
+
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c
index 0c08bb1..8b134cf 100644
--- a/arch/arc/kernel/perf_event.c
+++ b/arch/arc/kernel/perf_event.c
@@ -428,12 +428,11 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
#endif /* CONFIG_ISA_ARCV2 */
-void arc_cpu_pmu_irq_init(void)
+static void arc_cpu_pmu_irq_init(void *data)
{
- struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
+ int irq = *(int *)data;
- arc_request_percpu_irq(arc_pmu->irq, smp_processor_id(), arc_pmu_intr,
- "ARC perf counters", pmu_cpu);
+ enable_percpu_irq(irq, IRQ_TYPE_NONE);
/* Clear all pending interrupt flags */
write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
@@ -515,7 +514,6 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
if (has_interrupts) {
int irq = platform_get_irq(pdev, 0);
- unsigned long flags;
if (irq < 0) {
pr_err("Cannot get IRQ number for the platform\n");
@@ -524,24 +522,12 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
arc_pmu->irq = irq;
- /*
- * arc_cpu_pmu_irq_init() needs to be called on all cores for
- * their respective local PMU.
- * However we use opencoded on_each_cpu() to ensure it is called
- * on core0 first, so that arc_request_percpu_irq() sets up
- * AUTOEN etc. Otherwise enable_percpu_irq() fails to enable
- * perf IRQ on non master cores.
- * see arc_request_percpu_irq()
- */
- preempt_disable();
- local_irq_save(flags);
- arc_cpu_pmu_irq_init();
- local_irq_restore(flags);
- smp_call_function((smp_call_func_t)arc_cpu_pmu_irq_init, 0, 1);
- preempt_enable();
-
- /* Clean all pending interrupt flags */
- write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff);
+ /* intc map function ensures irq_set_percpu_devid() called */
+ request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters",
+ this_cpu_ptr(&arc_pmu_cpu));
+
+ on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+
} else
arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 91d5a0f..a3f750e 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -44,11 +44,10 @@ SYSCALL_DEFINE0(arc_gettls)
void arch_cpu_idle(void)
{
/* sleep, but enable all interrupts before committing */
- if (is_isa_arcompact()) {
- __asm__("sleep 0x3");
- } else {
- __asm__("sleep 0x10");
- }
+ __asm__ __volatile__(
+ "sleep %0 \n"
+ :
+ :"I"(ISA_SLEEP_ARG)); /* can't be "r" has to be embedded const */
}
asmlinkage void ret_from_fork(void);
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index cabde9d..cdc821d 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -42,9 +42,57 @@ struct task_struct *_current_task[NR_CPUS]; /* For stack switching */
struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
+static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu)
+{
+ if (is_isa_arcompact()) {
+ struct bcr_iccm_arcompact iccm;
+ struct bcr_dccm_arcompact dccm;
+
+ READ_BCR(ARC_REG_ICCM_BUILD, iccm);
+ if (iccm.ver) {
+ cpu->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */
+ cpu->iccm.base_addr = iccm.base << 16;
+ }
+
+ READ_BCR(ARC_REG_DCCM_BUILD, dccm);
+ if (dccm.ver) {
+ unsigned long base;
+ cpu->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */
+
+ base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD);
+ cpu->dccm.base_addr = base & ~0xF;
+ }
+ } else {
+ struct bcr_iccm_arcv2 iccm;
+ struct bcr_dccm_arcv2 dccm;
+ unsigned long region;
+
+ READ_BCR(ARC_REG_ICCM_BUILD, iccm);
+ if (iccm.ver) {
+ cpu->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */
+ if (iccm.sz00 == 0xF && iccm.sz01 > 0)
+ cpu->iccm.sz <<= iccm.sz01;
+
+ region = read_aux_reg(ARC_REG_AUX_ICCM);
+ cpu->iccm.base_addr = region & 0xF0000000;
+ }
+
+ READ_BCR(ARC_REG_DCCM_BUILD, dccm);
+ if (dccm.ver) {
+ cpu->dccm.sz = 256 << dccm.sz0;
+ if (dccm.sz0 == 0xF && dccm.sz1 > 0)
+ cpu->dccm.sz <<= dccm.sz1;
+
+ region = read_aux_reg(ARC_REG_AUX_DCCM);
+ cpu->dccm.base_addr = region & 0xF0000000;
+ }
+ }
+}
+
static void read_arc_build_cfg_regs(void)
{
struct bcr_perip uncached_space;
+ struct bcr_timer timer;
struct bcr_generic bcr;
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
unsigned long perip_space;
@@ -53,7 +101,11 @@ static void read_arc_build_cfg_regs(void)
READ_BCR(AUX_IDENTITY, cpu->core);
READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa);
- READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers);
+ READ_BCR(ARC_REG_TIMERS_BCR, timer);
+ cpu->extn.timer0 = timer.t0;
+ cpu->extn.timer1 = timer.t1;
+ cpu->extn.rtc = timer.rtc;
+
cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
@@ -71,36 +123,11 @@ static void read_arc_build_cfg_regs(void)
cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0; /* 1,3 */
cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0;
cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */
-
- /* Note that we read the CCM BCRs independent of kernel config
- * This is to catch the cases where user doesn't know that
- * CCMs are present in hardware build
- */
- {
- struct bcr_iccm iccm;
- struct bcr_dccm dccm;
- struct bcr_dccm_base dccm_base;
- unsigned int bcr_32bit_val;
-
- bcr_32bit_val = read_aux_reg(ARC_REG_ICCM_BCR);
- if (bcr_32bit_val) {
- iccm = *((struct bcr_iccm *)&bcr_32bit_val);
- cpu->iccm.base_addr = iccm.base << 16;
- cpu->iccm.sz = 0x2000 << (iccm.sz - 1);
- }
-
- bcr_32bit_val = read_aux_reg(ARC_REG_DCCM_BCR);
- if (bcr_32bit_val) {
- dccm = *((struct bcr_dccm *)&bcr_32bit_val);
- cpu->dccm.sz = 0x800 << (dccm.sz);
-
- READ_BCR(ARC_REG_DCCMBASE_BCR, dccm_base);
- cpu->dccm.base_addr = dccm_base.addr << 8;
- }
- }
-
READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem);
+ /* Read CCM BCRs for boot reporting even if not enabled in Kconfig */
+ read_decode_ccm_bcr(cpu);
+
read_decode_mmu_bcr();
read_decode_cache_bcr();
@@ -160,10 +187,6 @@ static const struct cpuinfo_data arc_cpu_tbl[] = {
{ {0x00, NULL } }
};
-#define IS_AVAIL1(v, s) ((v) ? s : "")
-#define IS_USED_RUN(v) ((v) ? "" : "(not used) ")
-#define IS_USED_CFG(cfg) IS_USED_RUN(IS_ENABLED(cfg))
-#define IS_AVAIL2(v, s, cfg) IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
{
@@ -212,9 +235,9 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
(unsigned int)(arc_get_core_freq() / 10000) % 100);
n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
- IS_AVAIL1(cpu->timers.t0, "Timer0 "),
- IS_AVAIL1(cpu->timers.t1, "Timer1 "),
- IS_AVAIL2(cpu->timers.rtc, "64-bit RTC ",
+ IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
+ IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
+ IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
CONFIG_ARC_HAS_RTC));
n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
@@ -236,8 +259,6 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt);
}
- n += scnprintf(buf + n, len - n, "%s",
- IS_USED_CFG(CONFIG_ARC_HAS_HW_MPY));
}
n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n",
@@ -297,13 +318,13 @@ static void arc_chk_core_config(void)
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
int fpu_enabled;
- if (!cpu->timers.t0)
+ if (!cpu->extn.timer0)
panic("Timer0 is not present!\n");
- if (!cpu->timers.t1)
+ if (!cpu->extn.timer1)
panic("Timer1 is not present!\n");
- if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->timers.rtc)
+ if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc)
panic("RTC is not present\n");
#ifdef CONFIG_ARC_HAS_DCCM
@@ -338,6 +359,7 @@ static void arc_chk_core_config(void)
panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic &&
+ IS_ENABLED(CONFIG_ARC_HAS_LLSC) &&
!IS_ENABLED(CONFIG_ARC_STAR_9000923308))
panic("llock/scond livelock workaround missing\n");
}
@@ -415,8 +437,9 @@ void __init setup_arch(char **cmdline_p)
if (machine_desc->init_early)
machine_desc->init_early();
- setup_processor();
smp_init_cpus();
+
+ setup_processor();
setup_arch_memory();
/* copy flat DT out of .init and then unflatten it */
@@ -432,7 +455,6 @@ void __init setup_arch(char **cmdline_p)
#endif
arc_unwind_init();
- arc_unwind_setup();
}
static int __init customize_machine(void)
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index be13d12..4cb3add 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -42,8 +42,13 @@ void __init smp_prepare_boot_cpu(void)
}
/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
+ * Called from setup_arch() before calling setup_processor()
+ *
+ * - Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ * - Call early smp init hook. This can initialize a specific multi-core
+ * IP which is say common to several platforms (hence not part of
+ * platform specific int_early() hook)
*/
void __init smp_init_cpus(void)
{
@@ -51,6 +56,9 @@ void __init smp_init_cpus(void)
for (i = 0; i < NR_CPUS; i++)
set_cpu_possible(i, true);
+
+ if (plat_smp_ops.init_early_smp)
+ plat_smp_ops.init_early_smp();
}
/* called from init ( ) => process 1 */
@@ -72,35 +80,29 @@ void __init smp_cpus_done(unsigned int max_cpus)
}
/*
- * After power-up, a non Master CPU needs to wait for Master to kick start it
- *
- * The default implementation halts
- *
- * This relies on platform specific support allowing Master to directly set
- * this CPU's PC (to be @first_lines_of_secondary() and kick start it.
- *
- * In lack of such h/w assist, platforms can override this function
- * - make this function busy-spin on a token, eventually set by Master
- * (from arc_platform_smp_wakeup_cpu())
- * - Once token is available, jump to @first_lines_of_secondary
- * (using inline asm).
- *
- * Alert: can NOT use stack here as it has not been determined/setup for CPU.
- * If it turns out to be elaborate, it's better to code it in assembly
- *
+ * Default smp boot helper for Run-on-reset case where all cores start off
+ * together. Non-masters need to wait for Master to start running.
+ * This is implemented using a flag in memory, which Non-masters spin-wait on.
+ * Master sets it to cpu-id of core to "ungate" it.
*/
-void __weak arc_platform_smp_wait_to_boot(int cpu)
+static volatile int wake_flag;
+
+static void arc_default_smp_cpu_kick(int cpu, unsigned long pc)
{
- /*
- * As a hack for debugging - since debugger will single-step over the
- * FLAG insn - wrap the halt itself it in a self loop
- */
- __asm__ __volatile__(
- "1: \n"
- " flag 1 \n"
- " b 1b \n");
+ BUG_ON(cpu == 0);
+ wake_flag = cpu;
+}
+
+void arc_platform_smp_wait_to_boot(int cpu)
+{
+ while (wake_flag != cpu)
+ ;
+
+ wake_flag = 0;
+ __asm__ __volatile__("j @first_lines_of_secondary \n");
}
+
const char *arc_platform_smp_cpuinfo(void)
{
return plat_smp_ops.info ? : "";
@@ -129,14 +131,18 @@ void start_kernel_secondary(void)
pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
- if (machine_desc->init_smp)
- machine_desc->init_smp(cpu);
+ /* Some SMP H/w setup - for each cpu */
+ if (plat_smp_ops.init_per_cpu)
+ plat_smp_ops.init_per_cpu(cpu);
+
+ if (machine_desc->init_per_cpu)
+ machine_desc->init_per_cpu(cpu);
arc_local_timer_setup();
local_irq_enable();
preempt_disable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
/*
@@ -161,6 +167,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (plat_smp_ops.cpu_kick)
plat_smp_ops.cpu_kick(cpu,
(unsigned long)first_lines_of_secondary);
+ else
+ arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
/* wait for 1 sec after kicking the secondary */
wait_till = jiffies + HZ;
@@ -328,11 +336,8 @@ irqreturn_t do_IPI(int irq, void *dev_id)
int rc;
rc = __do_IPI(msg);
-#ifdef CONFIG_ARC_IPI_DBG
- /* IPI received but no valid @msg */
if (rc)
pr_info("IPI with bogus msg %ld in %ld\n", msg, copy);
-#endif
pending &= ~(1U << msg);
} while (pending);
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 4294761..156d983 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -62,7 +62,7 @@
/********** Clock Source Device *********/
-#ifdef CONFIG_ARC_HAS_GRTC
+#ifdef CONFIG_ARC_HAS_GFRC
static int arc_counter_setup(void)
{
@@ -83,10 +83,10 @@ static cycle_t arc_counter_read(struct clocksource *cs)
local_irq_save(flags);
- __mcip_cmd(CMD_GRTC_READ_LO, 0);
+ __mcip_cmd(CMD_GFRC_READ_LO, 0);
stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);
- __mcip_cmd(CMD_GRTC_READ_HI, 0);
+ __mcip_cmd(CMD_GFRC_READ_HI, 0);
stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);
local_irq_restore(flags);
@@ -95,7 +95,7 @@ static cycle_t arc_counter_read(struct clocksource *cs)
}
static struct clocksource arc_counter = {
- .name = "ARConnect GRTC",
+ .name = "ARConnect GFRC",
.rating = 400,
.read = arc_counter_read,
.mask = CLOCKSOURCE_MASK(64),
@@ -285,7 +285,4 @@ void __init time_init(void)
/* sets up the periodic event timer */
arc_local_timer_setup();
-
- if (machine_desc->init_time)
- machine_desc->init_time();
}
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 93c6ea5..0587bf1 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -170,6 +170,23 @@ static struct unwind_table *find_table(unsigned long pc)
static unsigned long read_pointer(const u8 **pLoc,
const void *end, signed ptrType);
+static void init_unwind_hdr(struct unwind_table *table,
+ void *(*alloc) (unsigned long));
+
+/*
+ * wrappers for header alloc (vs. calling one vs. other at call site)
+ * to elide section mismatches warnings
+ */
+static void *__init unw_hdr_alloc_early(unsigned long sz)
+{
+ return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
+ MAX_DMA_ADDRESS);
+}
+
+static void *unw_hdr_alloc(unsigned long sz)
+{
+ return kmalloc(sz, GFP_KERNEL);
+}
static void init_unwind_table(struct unwind_table *table, const char *name,
const void *core_start, unsigned long core_size,
@@ -209,6 +226,8 @@ void __init arc_unwind_init(void)
__start_unwind, __end_unwind - __start_unwind,
NULL, 0);
/*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
+
+ init_unwind_hdr(&root_table, unw_hdr_alloc_early);
}
static const u32 bad_cie, not_fde;
@@ -241,8 +260,8 @@ static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
e2->fde = v;
}
-static void __init setup_unwind_table(struct unwind_table *table,
- void *(*alloc) (unsigned long))
+static void init_unwind_hdr(struct unwind_table *table,
+ void *(*alloc) (unsigned long))
{
const u8 *ptr;
unsigned long tableSize = table->size, hdrSize;
@@ -277,10 +296,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
if (cie == &not_fde)
continue;
if (cie == NULL || cie == &bad_cie)
- return;
+ goto ret_err;
ptrType = fde_pointer_type(cie);
if (ptrType < 0)
- return;
+ goto ret_err;
ptr = (const u8 *)(fde + 2);
if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
@@ -296,13 +315,15 @@ static void __init setup_unwind_table(struct unwind_table *table,
}
if (tableSize || !n)
- return;
+ goto ret_err;
hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+ 2 * n * sizeof(unsigned long);
+
header = alloc(hdrSize);
if (!header)
- return;
+ goto ret_err;
+
header->version = 1;
header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
@@ -340,18 +361,10 @@ static void __init setup_unwind_table(struct unwind_table *table,
table->hdrsz = hdrSize;
smp_wmb();
table->header = (const void *)header;
-}
-
-static void *__init balloc(unsigned long sz)
-{
- return __alloc_bootmem_nopanic(sz,
- sizeof(unsigned int),
- __pa(MAX_DMA_ADDRESS));
-}
+ return;
-void __init arc_unwind_setup(void)
-{
- setup_unwind_table(&root_table, balloc);
+ret_err:
+ panic("Attention !!! Dwarf FDE parsing errors\n");;
}
#ifdef CONFIG_MODULES
@@ -372,11 +385,13 @@ void *unwind_add_table(struct module *module, const void *table_start,
return NULL;
init_unwind_table(table, module->name,
- module->module_core, module->core_size,
- module->module_init, module->init_size,
+ module->core_layout.base, module->core_layout.size,
+ module->init_layout.base, module->init_layout.size,
table_start, table_size,
NULL, 0);
+ init_unwind_hdr(table, unw_hdr_alloc);
+
#ifdef UNWIND_DEBUG
unw_debug("Table added for [%s] %lx %lx\n",
module->name, table->core.pc, table->core.range);
@@ -439,6 +454,7 @@ void unwind_remove_table(void *handle, int init_only)
info.init_only = init_only;
unlink_table(&info); /* XXX: SMP */
+ kfree(table->header);
kfree(table);
}
@@ -588,9 +604,6 @@ static signed fde_pointer_type(const u32 *cie)
const u8 *ptr = (const u8 *)(cie + 2);
unsigned version = *ptr;
- if (version != 1)
- return -1; /* unsupported */
-
if (*++ptr) {
const char *aug;
const u8 *end = (const u8 *)(cie + 1) + *cie;
@@ -986,42 +999,13 @@ int arc_unwind(struct unwind_frame_info *frame)
(const u8 *)(fde +
1) +
*fde, ptrType);
- if (pc >= endLoc)
+ if (pc >= endLoc) {
fde = NULL;
- } else
- fde = NULL;
- }
- if (fde == NULL) {
- for (fde = table->address, tableSize = table->size;
- cie = NULL, tableSize > sizeof(*fde)
- && tableSize - sizeof(*fde) >= *fde;
- tableSize -= sizeof(*fde) + *fde,
- fde += 1 + *fde / sizeof(*fde)) {
- cie = cie_for_fde(fde, table);
- if (cie == &bad_cie) {
cie = NULL;
- break;
}
- if (cie == NULL
- || cie == &not_fde
- || (ptrType = fde_pointer_type(cie)) < 0)
- continue;
- ptr = (const u8 *)(fde + 2);
- startLoc = read_pointer(&ptr,
- (const u8 *)(fde + 1) +
- *fde, ptrType);
- if (!startLoc)
- continue;
- if (!(ptrType & DW_EH_PE_indirect))
- ptrType &=
- DW_EH_PE_FORM | DW_EH_PE_signed;
- endLoc =
- startLoc + read_pointer(&ptr,
- (const u8 *)(fde +
- 1) +
- *fde, ptrType);
- if (pc >= startLoc && pc < endLoc)
- break;
+ } else {
+ fde = NULL;
+ cie = NULL;
}
}
}
@@ -1031,9 +1015,7 @@ int arc_unwind(struct unwind_frame_info *frame)
ptr = (const u8 *)(cie + 2);
end = (const u8 *)(cie + 1) + *cie;
frame->call_frame = 1;
- if ((state.version = *ptr) != 1)
- cie = NULL; /* unsupported version */
- else if (*++ptr) {
+ if (*++ptr) {
/* check if augmentation size is first (thus present) */
if (*ptr == 'z') {
while (++ptr < end && *ptr) {
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index dd35bde..894e696 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -12,7 +12,7 @@
#include <asm/thread_info.h>
OUTPUT_ARCH(arc)
-ENTRY(_stext)
+ENTRY(res_service)
#ifdef CONFIG_CPU_BIG_ENDIAN
jiffies = jiffies_64 + 4;
diff --git a/arch/arc/lib/memcpy-archs.S b/arch/arc/lib/memcpy-archs.S
index 0cab0b8..f96c75e 100644
--- a/arch/arc/lib/memcpy-archs.S
+++ b/arch/arc/lib/memcpy-archs.S
@@ -50,26 +50,26 @@ ENTRY(memcpy)
;;; if size <= 8
cmp r2, 8
- bls.d @smallchunk
+ bls.d @.Lsmallchunk
mov.f lp_count, r2
and.f r4, r0, 0x03
rsub lp_count, r4, 4
- lpnz @aligndestination
+ lpnz @.Laligndestination
;; LOOP BEGIN
ldb.ab r5, [r1,1]
sub r2, r2, 1
stb.ab r5, [r3,1]
-aligndestination:
+.Laligndestination:
;;; Check the alignment of the source
and.f r4, r1, 0x03
- bnz.d @sourceunaligned
+ bnz.d @.Lsourceunaligned
;;; CASE 0: Both source and destination are 32bit aligned
;;; Convert len to Dwords, unfold x4
lsr.f lp_count, r2, ZOLSHFT
- lpnz @copy32_64bytes
+ lpnz @.Lcopy32_64bytes
;; LOOP START
LOADX (r6, r1)
PREFETCH_READ (r1)
@@ -81,25 +81,25 @@ aligndestination:
STOREX (r8, r3)
STOREX (r10, r3)
STOREX (r4, r3)
-copy32_64bytes:
+.Lcopy32_64bytes:
and.f lp_count, r2, ZOLAND ;Last remaining 31 bytes
-smallchunk:
- lpnz @copyremainingbytes
+.Lsmallchunk:
+ lpnz @.Lcopyremainingbytes
;; LOOP START
ldb.ab r5, [r1,1]
stb.ab r5, [r3,1]
-copyremainingbytes:
+.Lcopyremainingbytes:
j [blink]
;;; END CASE 0
-sourceunaligned:
+.Lsourceunaligned:
cmp r4, 2
- beq.d @unalignedOffby2
+ beq.d @.LunalignedOffby2
sub r2, r2, 1
- bhi.d @unalignedOffby3
+ bhi.d @.LunalignedOffby3
ldb.ab r5, [r1, 1]
;;; CASE 1: The source is unaligned, off by 1
@@ -114,7 +114,7 @@ sourceunaligned:
or r5, r5, r6
;; Both src and dst are aligned
- lpnz @copy8bytes_1
+ lpnz @.Lcopy8bytes_1
;; LOOP START
ld.ab r6, [r1, 4]
prefetch [r1, 28] ;Prefetch the next read location
@@ -131,7 +131,7 @@ sourceunaligned:
st.ab r7, [r3, 4]
st.ab r9, [r3, 4]
-copy8bytes_1:
+.Lcopy8bytes_1:
;; Write back the remaining 16bits
EXTRACT_1 (r6, r5, 16)
@@ -141,14 +141,14 @@ copy8bytes_1:
stb.ab r5, [r3, 1]
and.f lp_count, r2, 0x07 ;Last 8bytes
- lpnz @copybytewise_1
+ lpnz @.Lcopybytewise_1
;; LOOP START
ldb.ab r6, [r1,1]
stb.ab r6, [r3,1]
-copybytewise_1:
+.Lcopybytewise_1:
j [blink]
-unalignedOffby2:
+.LunalignedOffby2:
;;; CASE 2: The source is unaligned, off by 2
ldh.ab r5, [r1, 2]
sub r2, r2, 1
@@ -159,7 +159,7 @@ unalignedOffby2:
#ifdef __BIG_ENDIAN__
asl.nz r5, r5, 16
#endif
- lpnz @copy8bytes_2
+ lpnz @.Lcopy8bytes_2
;; LOOP START
ld.ab r6, [r1, 4]
prefetch [r1, 28] ;Prefetch the next read location
@@ -176,7 +176,7 @@ unalignedOffby2:
st.ab r7, [r3, 4]
st.ab r9, [r3, 4]
-copy8bytes_2:
+.Lcopy8bytes_2:
#ifdef __BIG_ENDIAN__
lsr.nz r5, r5, 16
@@ -184,14 +184,14 @@ copy8bytes_2:
sth.ab r5, [r3, 2]
and.f lp_count, r2, 0x07 ;Last 8bytes
- lpnz @copybytewise_2
+ lpnz @.Lcopybytewise_2
;; LOOP START
ldb.ab r6, [r1,1]
stb.ab r6, [r3,1]
-copybytewise_2:
+.Lcopybytewise_2:
j [blink]
-unalignedOffby3:
+.LunalignedOffby3:
;;; CASE 3: The source is unaligned, off by 3
;;; Hence, I need to read 1byte for achieve the 32bit alignment
@@ -201,7 +201,7 @@ unalignedOffby3:
#ifdef __BIG_ENDIAN__
asl.ne r5, r5, 24
#endif
- lpnz @copy8bytes_3
+ lpnz @.Lcopy8bytes_3
;; LOOP START
ld.ab r6, [r1, 4]
prefetch [r1, 28] ;Prefetch the next read location
@@ -218,7 +218,7 @@ unalignedOffby3:
st.ab r7, [r3, 4]
st.ab r9, [r3, 4]
-copy8bytes_3:
+.Lcopy8bytes_3:
#ifdef __BIG_ENDIAN__
lsr.nz r5, r5, 24
@@ -226,11 +226,11 @@ copy8bytes_3:
stb.ab r5, [r3, 1]
and.f lp_count, r2, 0x07 ;Last 8bytes
- lpnz @copybytewise_3
+ lpnz @.Lcopybytewise_3
;; LOOP START
ldb.ab r6, [r1,1]
stb.ab r6, [r3,1]
-copybytewise_3:
+.Lcopybytewise_3:
j [blink]
END(memcpy)
diff --git a/arch/arc/mm/Makefile b/arch/arc/mm/Makefile
index 7beb941..3703a49 100644
--- a/arch/arc/mm/Makefile
+++ b/arch/arc/mm/Makefile
@@ -8,3 +8,4 @@
obj-y := extable.o ioremap.o dma.o fault.o init.o
obj-y += tlb.o tlbex.o cache.o mmap.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index 0d1a6e9..b65f797 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -25,7 +25,7 @@ static int l2_line_sz;
int ioc_exists;
volatile int slc_enable = 1, ioc_enable = 1;
-void (*_cache_line_loop_ic_fn)(unsigned long paddr, unsigned long vaddr,
+void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int cacheop);
void (*__dma_cache_wback_inv)(unsigned long start, unsigned long sz);
@@ -37,7 +37,6 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
int n = 0;
struct cpuinfo_arc_cache *p;
-#define IS_USED_RUN(v) ((v) ? "" : "(disabled) ")
#define PR_CACHE(p, cfg, str) \
if (!(p)->ver) \
n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \
@@ -47,7 +46,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
(p)->sz_k, (p)->assoc, (p)->line_len, \
(p)->vipt ? "VIPT" : "PIPT", \
(p)->alias ? " aliasing" : "", \
- IS_ENABLED(cfg) ? "" : " (not used)");
+ IS_USED_CFG(cfg));
PR_CACHE(&cpuinfo_arc700[c].icache, CONFIG_ARC_HAS_ICACHE, "I-Cache");
PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache");
@@ -63,7 +62,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
if (ioc_exists)
n += scnprintf(buf + n, len - n, "IOC\t\t:%s\n",
- IS_USED_RUN(ioc_enable));
+ IS_DISABLED_RUN(ioc_enable));
return buf;
}
@@ -217,7 +216,7 @@ slc_chk:
*/
static inline
-void __cache_line_loop_v2(unsigned long paddr, unsigned long vaddr,
+void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int op)
{
unsigned int aux_cmd;
@@ -254,8 +253,12 @@ void __cache_line_loop_v2(unsigned long paddr, unsigned long vaddr,
}
}
+/*
+ * For ARC700 MMUv3 I-cache and D-cache flushes
+ * Also reused for HS38 aliasing I-cache configuration
+ */
static inline
-void __cache_line_loop_v3(unsigned long paddr, unsigned long vaddr,
+void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int op)
{
unsigned int aux_cmd, aux_tag;
@@ -290,6 +293,16 @@ void __cache_line_loop_v3(unsigned long paddr, unsigned long vaddr,
if (full_page)
write_aux_reg(aux_tag, paddr);
+ /*
+ * This is technically for MMU v4, using the MMU v3 programming model
+ * Special work for HS38 aliasing I-cache configuratino with PAE40
+ * - upper 8 bits of paddr need to be written into PTAG_HI
+ * - (and needs to be written before the lower 32 bits)
+ * Note that PTAG_HI is hoisted outside the line loop
+ */
+ if (is_pae40_enabled() && op == OP_INV_IC)
+ write_aux_reg(ARC_REG_IC_PTAG_HI, (u64)paddr >> 32);
+
while (num_lines-- > 0) {
if (!full_page) {
write_aux_reg(aux_tag, paddr);
@@ -302,14 +315,20 @@ void __cache_line_loop_v3(unsigned long paddr, unsigned long vaddr,
}
/*
- * In HS38x (MMU v4), although icache is VIPT, only paddr is needed for cache
- * maintenance ops (in IVIL reg), as long as icache doesn't alias.
+ * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT
+ * Here's how cache ops are implemented
+ *
+ * - D-cache: only paddr needed (in DC_IVDL/DC_FLDL)
+ * - I-cache Non Aliasing: Despite VIPT, only paddr needed (in IC_IVIL)
+ * - I-cache Aliasing: Both vaddr and paddr needed (in IC_IVIL, IC_PTAG
+ * respectively, similar to MMU v3 programming model, hence
+ * __cache_line_loop_v3() is used)
*
- * For Aliasing icache, vaddr is also needed (in IVIL), while paddr is
- * specified in PTAG (similar to MMU v3)
+ * If PAE40 is enabled, independent of aliasing considerations, the higher bits
+ * needs to be written into PTAG_HI
*/
static inline
-void __cache_line_loop_v4(unsigned long paddr, unsigned long vaddr,
+void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int cacheop)
{
unsigned int aux_cmd;
@@ -336,6 +355,22 @@ void __cache_line_loop_v4(unsigned long paddr, unsigned long vaddr,
num_lines = DIV_ROUND_UP(sz, L1_CACHE_BYTES);
+ /*
+ * For HS38 PAE40 configuration
+ * - upper 8 bits of paddr need to be written into PTAG_HI
+ * - (and needs to be written before the lower 32 bits)
+ */
+ if (is_pae40_enabled()) {
+ if (cacheop == OP_INV_IC)
+ /*
+ * Non aliasing I-cache in HS38,
+ * aliasing I-cache handled in __cache_line_loop_v3()
+ */
+ write_aux_reg(ARC_REG_IC_PTAG_HI, (u64)paddr >> 32);
+ else
+ write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32);
+ }
+
while (num_lines-- > 0) {
write_aux_reg(aux_cmd, paddr);
paddr += L1_CACHE_BYTES;
@@ -413,7 +448,7 @@ static inline void __dc_entire_op(const int op)
/*
* D-Cache Line ops: Per Line INV (discard or wback+discard) or FLUSH (wback)
*/
-static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
+static inline void __dc_line_op(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int op)
{
unsigned long flags;
@@ -446,7 +481,7 @@ static inline void __ic_entire_inv(void)
}
static inline void
-__ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
+__ic_line_inv_vaddr_local(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz)
{
unsigned long flags;
@@ -463,7 +498,7 @@ __ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
#else
struct ic_inv_args {
- unsigned long paddr, vaddr;
+ phys_addr_t paddr, vaddr;
int sz;
};
@@ -474,7 +509,7 @@ static void __ic_line_inv_vaddr_helper(void *info)
__ic_line_inv_vaddr_local(ic_inv->paddr, ic_inv->vaddr, ic_inv->sz);
}
-static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
+static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz)
{
struct ic_inv_args ic_inv = {
@@ -495,7 +530,7 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
#endif /* CONFIG_ARC_HAS_ICACHE */
-noinline void slc_op(unsigned long paddr, unsigned long sz, const int op)
+noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
{
#ifdef CONFIG_ISA_ARCV2
/*
@@ -582,10 +617,10 @@ void flush_dcache_page(struct page *page)
*/
if (!mapping_mapped(mapping)) {
clear_bit(PG_dc_clean, &page->flags);
- } else if (page_mapped(page)) {
+ } else if (page_mapcount(page)) {
/* kernel reading from page with U-mapping */
- unsigned long paddr = (unsigned long)page_address(page);
+ phys_addr_t paddr = (unsigned long)page_address(page);
unsigned long vaddr = page->index << PAGE_CACHE_SHIFT;
if (addr_not_cache_congruent(paddr, vaddr))
@@ -733,14 +768,14 @@ EXPORT_SYMBOL(flush_icache_range);
* builtin kernel page will not have any virtual mappings.
* kprobe on loadable module will be kernel vaddr.
*/
-void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len)
+void __sync_icache_dcache(phys_addr_t paddr, unsigned long vaddr, int len)
{
__dc_line_op(paddr, vaddr, len, OP_FLUSH_N_INV);
__ic_line_inv_vaddr(paddr, vaddr, len);
}
/* wrapper to compile time eliminate alignment checks in flush loop */
-void __inv_icache_page(unsigned long paddr, unsigned long vaddr)
+void __inv_icache_page(phys_addr_t paddr, unsigned long vaddr)
{
__ic_line_inv_vaddr(paddr, vaddr, PAGE_SIZE);
}
@@ -749,7 +784,7 @@ void __inv_icache_page(unsigned long paddr, unsigned long vaddr)
* wrapper to clearout kernel or userspace mappings of a page
* For kernel mappings @vaddr == @paddr
*/
-void __flush_dcache_page(unsigned long paddr, unsigned long vaddr)
+void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr)
{
__dc_line_op(paddr, vaddr & PAGE_MASK, PAGE_SIZE, OP_FLUSH_N_INV);
}
@@ -807,8 +842,8 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page,
void copy_user_highpage(struct page *to, struct page *from,
unsigned long u_vaddr, struct vm_area_struct *vma)
{
- unsigned long kfrom = (unsigned long)page_address(from);
- unsigned long kto = (unsigned long)page_address(to);
+ void *kfrom = kmap_atomic(from);
+ void *kto = kmap_atomic(to);
int clean_src_k_mappings = 0;
/*
@@ -818,13 +853,16 @@ void copy_user_highpage(struct page *to, struct page *from,
*
* Note that while @u_vaddr refers to DST page's userspace vaddr, it is
* equally valid for SRC page as well
+ *
+ * For !VIPT cache, all of this gets compiled out as
+ * addr_not_cache_congruent() is 0
*/
- if (page_mapped(from) && addr_not_cache_congruent(kfrom, u_vaddr)) {
- __flush_dcache_page(kfrom, u_vaddr);
+ if (page_mapcount(from) && addr_not_cache_congruent(kfrom, u_vaddr)) {
+ __flush_dcache_page((unsigned long)kfrom, u_vaddr);
clean_src_k_mappings = 1;
}
- copy_page((void *)kto, (void *)kfrom);
+ copy_page(kto, kfrom);
/*
* Mark DST page K-mapping as dirty for a later finalization by
@@ -841,11 +879,14 @@ void copy_user_highpage(struct page *to, struct page *from,
* sync the kernel mapping back to physical page
*/
if (clean_src_k_mappings) {
- __flush_dcache_page(kfrom, kfrom);
+ __flush_dcache_page((unsigned long)kfrom, (unsigned long)kfrom);
set_bit(PG_dc_clean, &from->flags);
} else {
clear_bit(PG_dc_clean, &from->flags);
}
+
+ kunmap_atomic(kto);
+ kunmap_atomic(kfrom);
}
void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 29a46bb..01eaf88 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -17,18 +17,14 @@
*/
#include <linux/dma-mapping.h>
-#include <linux/dma-debug.h>
-#include <linux/export.h>
#include <asm/cache.h>
#include <asm/cacheflush.h>
-/*
- * Helpers for Coherent DMA API.
- */
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+
+static void *arc_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
- void *paddr;
+ void *paddr, *kvaddr;
/* This is linear addr (0x8000_0000 based) */
paddr = alloc_pages_exact(size, gfp);
@@ -38,22 +34,6 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
/* This is bus address, platform dependent */
*dma_handle = (dma_addr_t)paddr;
- return paddr;
-}
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
-{
- free_pages_exact((void *)dma_handle, size);
-}
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
-{
- void *paddr, *kvaddr;
-
/*
* IOC relies on all data (even coherent DMA data) being in cache
* Thus allocate normal cached memory
@@ -65,22 +45,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
* -For coherent data, Read/Write to buffers terminate early in cache
* (vs. always going to memory - thus are faster)
*/
- if (is_isa_arcv2() && ioc_exists)
- return dma_alloc_noncoherent(dev, size, dma_handle, gfp);
-
- /* This is linear addr (0x8000_0000 based) */
- paddr = alloc_pages_exact(size, gfp);
- if (!paddr)
- return NULL;
+ if ((is_isa_arcv2() && ioc_exists) ||
+ dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
+ return paddr;
/* This is kernel Virtual address (0x7000_0000 based) */
kvaddr = ioremap_nocache((unsigned long)paddr, size);
if (kvaddr == NULL)
return NULL;
- /* This is bus address, platform dependent */
- *dma_handle = (dma_addr_t)paddr;
-
/*
* Evict any existing L1 and/or L2 lines for the backing page
* in case it was used earlier as a normal "cached" page.
@@ -95,26 +68,111 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return kvaddr;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void dma_free_coherent(struct device *dev, size_t size, void *kvaddr,
- dma_addr_t dma_handle)
+static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
- if (is_isa_arcv2() && ioc_exists)
- return dma_free_noncoherent(dev, size, kvaddr, dma_handle);
-
- iounmap((void __force __iomem *)kvaddr);
+ if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) &&
+ !(is_isa_arcv2() && ioc_exists))
+ iounmap((void __force __iomem *)vaddr);
free_pages_exact((void *)dma_handle, size);
}
-EXPORT_SYMBOL(dma_free_coherent);
/*
- * Helper for streaming DMA...
+ * streaming DMA Mapping API...
+ * CPU accesses page via normal paddr, thus needs to explicitly made
+ * consistent before each use
*/
-void __arc_dma_cache_sync(unsigned long paddr, size_t size,
- enum dma_data_direction dir)
+static void _dma_cache_sync(unsigned long paddr, size_t size,
+ enum dma_data_direction dir)
+{
+ switch (dir) {
+ case DMA_FROM_DEVICE:
+ dma_cache_inv(paddr, size);
+ break;
+ case DMA_TO_DEVICE:
+ dma_cache_wback(paddr, size);
+ break;
+ case DMA_BIDIRECTIONAL:
+ dma_cache_wback_inv(paddr, size);
+ break;
+ default:
+ pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr);
+ }
+}
+
+static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ unsigned long paddr = page_to_phys(page) + offset;
+ _dma_cache_sync(paddr, size, dir);
+ return (dma_addr_t)paddr;
+}
+
+static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+ s->length, dir);
+
+ return nents;
+}
+
+static void arc_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
+{
+ _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
+}
+
+static void arc_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
{
- __inline_dma_cache_sync(paddr, size, dir);
+ _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
}
-EXPORT_SYMBOL(__arc_dma_cache_sync);
+
+static void arc_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sglist, int nelems,
+ enum dma_data_direction dir)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nelems, i)
+ _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
+}
+
+static void arc_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sglist, int nelems,
+ enum dma_data_direction dir)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nelems, i)
+ _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir);
+}
+
+static int arc_dma_supported(struct device *dev, u64 dma_mask)
+{
+ /* Support 32 bit DMA mask exclusively */
+ return dma_mask == DMA_BIT_MASK(32);
+}
+
+struct dma_map_ops arc_dma_ops = {
+ .alloc = arc_dma_alloc,
+ .free = arc_dma_free,
+ .map_page = arc_dma_map_page,
+ .map_sg = arc_dma_map_sg,
+ .sync_single_for_device = arc_dma_sync_single_for_device,
+ .sync_single_for_cpu = arc_dma_sync_single_for_cpu,
+ .sync_sg_for_cpu = arc_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = arc_dma_sync_sg_for_device,
+ .dma_supported = arc_dma_supported,
+};
+EXPORT_SYMBOL(arc_dma_ops);
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index d948e4e9..af63f4a 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -18,7 +18,14 @@
#include <asm/pgalloc.h>
#include <asm/mmu.h>
-static int handle_vmalloc_fault(unsigned long address)
+/*
+ * kernel virtual address is required to implement vmalloc/pkmap/fixmap
+ * Refer to asm/processor.h for System Memory Map
+ *
+ * It simply copies the PMD entry (pointer to 2nd level page table or hugepage)
+ * from swapper pgdir to task pgdir. The 2nd level table/page is thus shared
+ */
+noinline static int handle_kernel_vaddr_fault(unsigned long address)
{
/*
* Synchronize this task's top level page-table
@@ -72,8 +79,8 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
* only copy the information from the master page table,
* nothing more.
*/
- if (address >= VMALLOC_START && address <= VMALLOC_END) {
- ret = handle_vmalloc_fault(address);
+ if (address >= VMALLOC_START) {
+ ret = handle_kernel_vaddr_fault(address);
if (unlikely(ret))
goto bad_area_nosemaphore;
else
diff --git a/arch/arc/mm/highmem.c b/arch/arc/mm/highmem.c
new file mode 100644
index 0000000..92dd92c
--- /dev/null
+++ b/arch/arc/mm/highmem.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bootmem.h>
+#include <linux/export.h>
+#include <linux/highmem.h>
+#include <asm/processor.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+/*
+ * HIGHMEM API:
+ *
+ * kmap() API provides sleep semantics hence refered to as "permanent maps"
+ * It allows mapping LAST_PKMAP pages, using @last_pkmap_nr as the cursor
+ * for book-keeping
+ *
+ * kmap_atomic() can't sleep (calls pagefault_disable()), thus it provides
+ * shortlived ala "temporary mappings" which historically were implemented as
+ * fixmaps (compile time addr etc). Their book-keeping is done per cpu.
+ *
+ * Both these facts combined (preemption disabled and per-cpu allocation)
+ * means the total number of concurrent fixmaps will be limited to max
+ * such allocations in a single control path. Thus KM_TYPE_NR (another
+ * historic relic) is a small'ish number which caps max percpu fixmaps
+ *
+ * ARC HIGHMEM Details
+ *
+ * - the kernel vaddr space from 0x7z to 0x8z (currently used by vmalloc/module)
+ * is now shared between vmalloc and kmap (non overlapping though)
+ *
+ * - Both fixmap/pkmap use a dedicated page table each, hooked up to swapper PGD
+ * This means each only has 1 PGDIR_SIZE worth of kvaddr mappings, which means
+ * 2M of kvaddr space for typical config (8K page and 11:8:13 traversal split)
+ *
+ * - fixmap anyhow needs a limited number of mappings. So 2M kvaddr == 256 PTE
+ * slots across NR_CPUS would be more than sufficient (generic code defines
+ * KM_TYPE_NR as 20).
+ *
+ * - pkmap being preemptible, in theory could do with more than 256 concurrent
+ * mappings. However, generic pkmap code: map_new_virtual(), doesn't traverse
+ * the PGD and only works with a single page table @pkmap_page_table, hence
+ * sets the limit
+ */
+
+extern pte_t * pkmap_page_table;
+static pte_t * fixmap_page_table;
+
+void *kmap(struct page *page)
+{
+ BUG_ON(in_interrupt());
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ return kmap_high(page);
+}
+
+void *kmap_atomic(struct page *page)
+{
+ int idx, cpu_idx;
+ unsigned long vaddr;
+
+ preempt_disable();
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ cpu_idx = kmap_atomic_idx_push();
+ idx = cpu_idx + KM_TYPE_NR * smp_processor_id();
+ vaddr = FIXMAP_ADDR(idx);
+
+ set_pte_at(&init_mm, vaddr, fixmap_page_table + idx,
+ mk_pte(page, kmap_prot));
+
+ return (void *)vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void __kunmap_atomic(void *kv)
+{
+ unsigned long kvaddr = (unsigned long)kv;
+
+ if (kvaddr >= FIXMAP_BASE && kvaddr < (FIXMAP_BASE + FIXMAP_SIZE)) {
+
+ /*
+ * Because preemption is disabled, this vaddr can be associated
+ * with the current allocated index.
+ * But in case of multiple live kmap_atomic(), it still relies on
+ * callers to unmap in right order.
+ */
+ int cpu_idx = kmap_atomic_idx();
+ int idx = cpu_idx + KM_TYPE_NR * smp_processor_id();
+
+ WARN_ON(kvaddr != FIXMAP_ADDR(idx));
+
+ pte_clear(&init_mm, kvaddr, fixmap_page_table + idx);
+ local_flush_tlb_kernel_range(kvaddr, kvaddr + PAGE_SIZE);
+
+ kmap_atomic_idx_pop();
+ }
+
+ pagefault_enable();
+ preempt_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
+
+static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
+{
+ pgd_t *pgd_k;
+ pud_t *pud_k;
+ pmd_t *pmd_k;
+ pte_t *pte_k;
+
+ pgd_k = pgd_offset_k(kvaddr);
+ pud_k = pud_offset(pgd_k, kvaddr);
+ pmd_k = pmd_offset(pud_k, kvaddr);
+
+ pte_k = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd_k, pte_k);
+ return pte_k;
+}
+
+void __init kmap_init(void)
+{
+ /* Due to recursive include hell, we can't do this in processor.h */
+ BUILD_BUG_ON(PAGE_OFFSET < (VMALLOC_END + FIXMAP_SIZE + PKMAP_SIZE));
+
+ BUILD_BUG_ON(KM_TYPE_NR > PTRS_PER_PTE);
+ pkmap_page_table = alloc_kmap_pgtable(PKMAP_BASE);
+
+ BUILD_BUG_ON(LAST_PKMAP > PTRS_PER_PTE);
+ fixmap_page_table = alloc_kmap_pgtable(FIXMAP_BASE);
+}
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index d44eedd..7d2c4fb 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -15,6 +15,7 @@
#endif
#include <linux/swap.h>
#include <linux/module.h>
+#include <linux/highmem.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/sections.h>
@@ -24,16 +25,22 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
EXPORT_SYMBOL(empty_zero_page);
-/* Default tot mem from .config */
-static unsigned long arc_mem_sz = 0x20000000; /* some default */
+static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
+static unsigned long low_mem_sz;
+
+#ifdef CONFIG_HIGHMEM
+static unsigned long min_high_pfn;
+static u64 high_mem_start;
+static u64 high_mem_sz;
+#endif
/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
static int __init setup_mem_sz(char *str)
{
- arc_mem_sz = memparse(str, NULL) & PAGE_MASK;
+ low_mem_sz = memparse(str, NULL) & PAGE_MASK;
/* early console might not be setup yet - it will show up later */
- pr_info("\"mem=%s\": mem sz set to %ldM\n", str, TO_MB(arc_mem_sz));
+ pr_info("\"mem=%s\": mem sz set to %ldM\n", str, TO_MB(low_mem_sz));
return 0;
}
@@ -41,8 +48,24 @@ early_param("mem", setup_mem_sz);
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{
- arc_mem_sz = size & PAGE_MASK;
- pr_info("Memory size set via devicetree %ldM\n", TO_MB(arc_mem_sz));
+ int in_use = 0;
+
+ if (!low_mem_sz) {
+ if (base != low_mem_start)
+ panic("CONFIG_LINUX_LINK_BASE != DT memory { }");
+
+ low_mem_sz = size;
+ in_use = 1;
+ } else {
+#ifdef CONFIG_HIGHMEM
+ high_mem_start = base;
+ high_mem_sz = size;
+ in_use = 1;
+#endif
+ }
+
+ pr_info("Memory @ %llx [%lldM] %s\n",
+ base, TO_MB(size), !in_use ? "Not used":"");
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -72,46 +95,62 @@ early_param("initrd", early_initrd);
void __init setup_arch_memory(void)
{
unsigned long zones_size[MAX_NR_ZONES];
- unsigned long end_mem = CONFIG_LINUX_LINK_BASE + arc_mem_sz;
+ unsigned long zones_holes[MAX_NR_ZONES];
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;
- /*
- * We do it here, so that memory is correctly instantiated
- * even if "mem=xxx" cmline over-ride is given and/or
- * DT has memory node. Each causes an update to @arc_mem_sz
- * and we finally add memory one here
- */
- memblock_add(CONFIG_LINUX_LINK_BASE, arc_mem_sz);
-
- /*------------- externs in mm need setting up ---------------*/
-
/* first page of system - kernel .vector starts here */
min_low_pfn = ARCH_PFN_OFFSET;
- /* Last usable page of low mem (no HIGHMEM yet for ARC port) */
- max_low_pfn = max_pfn = PFN_DOWN(end_mem);
+ /* Last usable page of low mem */
+ max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
- max_mapnr = max_low_pfn - min_low_pfn;
+#ifdef CONFIG_HIGHMEM
+ min_high_pfn = PFN_DOWN(high_mem_start);
+ max_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
+#endif
+
+ max_mapnr = max_pfn - min_low_pfn;
- /*------------- reserve kernel image -----------------------*/
- memblock_reserve(CONFIG_LINUX_LINK_BASE,
- __pa(_end) - CONFIG_LINUX_LINK_BASE);
+ /*------------- bootmem allocator setup -----------------------*/
+
+ /*
+ * seed the bootmem allocator after any DT memory node parsing or
+ * "mem=xxx" cmdline overrides have potentially updated @arc_mem_sz
+ *
+ * Only low mem is added, otherwise we have crashes when allocating
+ * mem_map[] itself. NO_BOOTMEM allocates mem_map[] at the end of
+ * avail memory, ending in highmem with a > 32-bit address. However
+ * it then tries to memset it with a truncaed 32-bit handle, causing
+ * the crash
+ */
+
+ memblock_add(low_mem_start, low_mem_sz);
+ memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
#ifdef CONFIG_BLK_DEV_INITRD
- /*------------- reserve initrd image -----------------------*/
if (initrd_start)
memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
#endif
memblock_dump_all();
- /*-------------- node setup --------------------------------*/
+ /*----------------- node/zones setup --------------------------*/
memset(zones_size, 0, sizeof(zones_size));
- zones_size[ZONE_NORMAL] = max_mapnr;
+ memset(zones_holes, 0, sizeof(zones_holes));
+
+ zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
+ zones_holes[ZONE_NORMAL] = 0;
+
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
+
+ /* This handles the peripheral address space hole */
+ zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn;
+#endif
/*
* We can't use the helper free_area_init(zones[]) because it uses
@@ -122,9 +161,12 @@ void __init setup_arch_memory(void)
free_area_init_node(0, /* node-id */
zones_size, /* num pages per zone */
min_low_pfn, /* first pfn of node */
- NULL); /* NO holes */
+ zones_holes); /* holes */
- high_memory = (void *)end_mem;
+#ifdef CONFIG_HIGHMEM
+ high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
+ kmap_init();
+#endif
}
/*
@@ -135,6 +177,14 @@ void __init setup_arch_memory(void)
*/
void __init mem_init(void)
{
+#ifdef CONFIG_HIGHMEM
+ unsigned long tmp;
+
+ reset_all_zones_managed_pages();
+ for (tmp = min_high_pfn; tmp < max_pfn; tmp++)
+ free_highmem_page(pfn_to_page(tmp));
+#endif
+
free_all_bootmem();
mem_init_print_info(NULL);
}
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 2c7ce8b..daf2bf5 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -109,6 +109,10 @@ DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE;
static inline void __tlb_entry_erase(void)
{
write_aux_reg(ARC_REG_TLBPD1, 0);
+
+ if (is_pae40_enabled())
+ write_aux_reg(ARC_REG_TLBPD1HI, 0);
+
write_aux_reg(ARC_REG_TLBPD0, 0);
write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite);
}
@@ -182,7 +186,7 @@ static void utlb_invalidate(void)
}
-static void tlb_entry_insert(unsigned int pd0, unsigned int pd1)
+static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
{
unsigned int idx;
@@ -225,10 +229,14 @@ static void tlb_entry_erase(unsigned int vaddr_n_asid)
write_aux_reg(ARC_REG_TLBCOMMAND, TLBDeleteEntry);
}
-static void tlb_entry_insert(unsigned int pd0, unsigned int pd1)
+static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
{
write_aux_reg(ARC_REG_TLBPD0, pd0);
write_aux_reg(ARC_REG_TLBPD1, pd1);
+
+ if (is_pae40_enabled())
+ write_aux_reg(ARC_REG_TLBPD1HI, (u64)pd1 >> 32);
+
write_aux_reg(ARC_REG_TLBCOMMAND, TLBInsertEntry);
}
@@ -240,22 +248,39 @@ static void tlb_entry_insert(unsigned int pd0, unsigned int pd1)
noinline void local_flush_tlb_all(void)
{
+ struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
unsigned long flags;
unsigned int entry;
- struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
+ int num_tlb = mmu->sets * mmu->ways;
local_irq_save(flags);
/* Load PD0 and PD1 with template for a Blank Entry */
write_aux_reg(ARC_REG_TLBPD1, 0);
+
+ if (is_pae40_enabled())
+ write_aux_reg(ARC_REG_TLBPD1HI, 0);
+
write_aux_reg(ARC_REG_TLBPD0, 0);
- for (entry = 0; entry < mmu->num_tlb; entry++) {
+ for (entry = 0; entry < num_tlb; entry++) {
/* write this entry to the TLB */
write_aux_reg(ARC_REG_TLBINDEX, entry);
write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite);
}
+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
+ const int stlb_idx = 0x800;
+
+ /* Blank sTLB entry */
+ write_aux_reg(ARC_REG_TLBPD0, _PAGE_HW_SZ);
+
+ for (entry = stlb_idx; entry < stlb_idx + 16; entry++) {
+ write_aux_reg(ARC_REG_TLBINDEX, entry);
+ write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite);
+ }
+ }
+
utlb_invalidate();
local_irq_restore(flags);
@@ -409,6 +434,15 @@ static inline void ipi_flush_tlb_range(void *arg)
local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline void ipi_flush_pmd_tlb_range(void *arg)
+{
+ struct tlb_args *ta = arg;
+
+ local_flush_pmd_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+#endif
+
static inline void ipi_flush_tlb_kernel_range(void *arg)
{
struct tlb_args *ta = (struct tlb_args *)arg;
@@ -449,6 +483,20 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range, &ta, 1);
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ struct tlb_args ta = {
+ .ta_vma = vma,
+ .ta_start = start,
+ .ta_end = end
+ };
+
+ on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_pmd_tlb_range, &ta, 1);
+}
+#endif
+
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
struct tlb_args ta = {
@@ -463,11 +511,12 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
/*
* Routine to create a TLB entry
*/
-void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep)
{
unsigned long flags;
unsigned int asid_or_sasid, rwx;
- unsigned long pd0, pd1;
+ unsigned long pd0;
+ pte_t pd1;
/*
* create_tlb() assumes that current->mm == vma->mm, since
@@ -499,9 +548,9 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
local_irq_save(flags);
- tlb_paranoid_check(asid_mm(vma->vm_mm, smp_processor_id()), address);
+ tlb_paranoid_check(asid_mm(vma->vm_mm, smp_processor_id()), vaddr);
- address &= PAGE_MASK;
+ vaddr &= PAGE_MASK;
/* update this PTE credentials */
pte_val(*ptep) |= (_PAGE_PRESENT | _PAGE_ACCESSED);
@@ -511,7 +560,7 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
/* ASID for this task */
asid_or_sasid = read_aux_reg(ARC_REG_PID) & 0xff;
- pd0 = address | asid_or_sasid | (pte_val(*ptep) & PTE_BITS_IN_PD0);
+ pd0 = vaddr | asid_or_sasid | (pte_val(*ptep) & PTE_BITS_IN_PD0);
/*
* ARC MMU provides fully orthogonal access bits for K/U mode,
@@ -547,7 +596,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
pte_t *ptep)
{
unsigned long vaddr = vaddr_unaligned & PAGE_MASK;
- unsigned long paddr = pte_val(*ptep) & PAGE_MASK;
+ phys_addr_t paddr = pte_val(*ptep) & PAGE_MASK;
struct page *page = pfn_to_page(pte_pfn(*ptep));
create_tlb(vma, vaddr, ptep);
@@ -570,16 +619,105 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
if (dirty) {
- /* wback + inv dcache lines */
+ /* wback + inv dcache lines (K-mapping) */
__flush_dcache_page(paddr, paddr);
- /* invalidate any existing icache lines */
+ /* invalidate any existing icache lines (U-mapping) */
if (vma->vm_flags & VM_EXEC)
__inv_icache_page(paddr, vaddr);
}
}
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+/*
+ * MMUv4 in HS38x cores supports Super Pages which are basis for Linux THP
+ * support.
+ *
+ * Normal and Super pages can co-exist (ofcourse not overlap) in TLB with a
+ * new bit "SZ" in TLB page desciptor to distinguish between them.
+ * Super Page size is configurable in hardware (4K to 16M), but fixed once
+ * RTL builds.
+ *
+ * The exact THP size a Linx configuration will support is a function of:
+ * - MMU page size (typical 8K, RTL fixed)
+ * - software page walker address split between PGD:PTE:PFN (typical
+ * 11:8:13, but can be changed with 1 line)
+ * So for above default, THP size supported is 8K * (2^8) = 2M
+ *
+ * Default Page Walker is 2 levels, PGD:PTE:PFN, which in THP regime
+ * reduces to 1 level (as PTE is folded into PGD and canonically referred
+ * to as PMD).
+ * Thus THP PMD accessors are implemented in terms of PTE (just like sparc)
+ */
+
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd)
+{
+ pte_t pte = __pte(pmd_val(*pmd));
+ update_mmu_cache(vma, addr, &pte);
+}
+
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable)
+{
+ struct list_head *lh = (struct list_head *) pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ if (!pmd_huge_pte(mm, pmdp))
+ INIT_LIST_HEAD(lh);
+ else
+ list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp));
+ pmd_huge_pte(mm, pmdp) = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
+{
+ struct list_head *lh;
+ pgtable_t pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ pgtable = pmd_huge_pte(mm, pmdp);
+ lh = (struct list_head *) pgtable;
+ if (list_empty(lh))
+ pmd_huge_pte(mm, pmdp) = NULL;
+ else {
+ pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next;
+ list_del(lh);
+ }
+
+ pte_val(pgtable[0]) = 0;
+ pte_val(pgtable[1]) = 0;
+
+ return pgtable;
+}
+
+void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ unsigned int cpu;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ cpu = smp_processor_id();
+
+ if (likely(asid_mm(vma->vm_mm, cpu) != MM_CTXT_NO_ASID)) {
+ unsigned int asid = hw_pid(vma->vm_mm, cpu);
+
+ /* No need to loop here: this will always be for 1 Huge Page */
+ tlb_entry_erase(start | _PAGE_HW_SZ | asid);
+ }
+
+ local_irq_restore(flags);
+}
+
+#endif
+
/* Read the Cache Build Confuration Registers, Decode them and save into
* the cpuinfo structure for later use.
* No Validation is done here, simply read/convert the BCRs
@@ -598,10 +736,10 @@ void read_decode_mmu_bcr(void)
struct bcr_mmu_3 {
#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
+ unsigned int ver:8, ways:4, sets:4, res:3, sasid:1, pg_sz:4,
u_itlb:4, u_dtlb:4;
#else
- unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
+ unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, sasid:1, res:3, sets:4,
ways:4, ver:8;
#endif
} *mmu3;
@@ -622,7 +760,7 @@ void read_decode_mmu_bcr(void)
if (mmu->ver <= 2) {
mmu2 = (struct bcr_mmu_1_2 *)&tmp;
- mmu->pg_sz_k = TO_KB(PAGE_SIZE);
+ mmu->pg_sz_k = TO_KB(0x2000);
mmu->sets = 1 << mmu2->sets;
mmu->ways = 1 << mmu2->ways;
mmu->u_dtlb = mmu2->u_dtlb;
@@ -634,6 +772,7 @@ void read_decode_mmu_bcr(void)
mmu->ways = 1 << mmu3->ways;
mmu->u_dtlb = mmu3->u_dtlb;
mmu->u_itlb = mmu3->u_itlb;
+ mmu->sasid = mmu3->sasid;
} else {
mmu4 = (struct bcr_mmu_4 *)&tmp;
mmu->pg_sz_k = 1 << (mmu4->sz0 - 1);
@@ -642,9 +781,9 @@ void read_decode_mmu_bcr(void)
mmu->ways = mmu4->n_ways * 2;
mmu->u_dtlb = mmu4->u_dtlb * 4;
mmu->u_itlb = mmu4->u_itlb * 4;
+ mmu->sasid = mmu4->sasid;
+ mmu->pae = mmu4->pae;
}
-
- mmu->num_tlb = mmu->sets * mmu->ways;
}
char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
@@ -655,14 +794,15 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
if (p_mmu->s_pg_sz_m)
scnprintf(super_pg, 64, "%dM Super Page%s, ",
- p_mmu->s_pg_sz_m, " (not used)");
+ p_mmu->s_pg_sz_m,
+ IS_USED_CFG(CONFIG_TRANSPARENT_HUGEPAGE));
n += scnprintf(buf + n, len - n,
- "MMU [v%x]\t: %dk PAGE, %sJTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n",
+ "MMU [v%x]\t: %dk PAGE, %sJTLB %d (%dx%d), uDTLB %d, uITLB %d %s%s\n",
p_mmu->ver, p_mmu->pg_sz_k, super_pg,
- p_mmu->num_tlb, p_mmu->sets, p_mmu->ways,
+ p_mmu->sets * p_mmu->ways, p_mmu->sets, p_mmu->ways,
p_mmu->u_dtlb, p_mmu->u_itlb,
- IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : "");
+ IS_AVAIL2(p_mmu->pae, "PAE40 ", CONFIG_ARC_HAS_PAE40));
return buf;
}
@@ -690,6 +830,14 @@ void arc_mmu_init(void)
if (mmu->pg_sz_k != TO_KB(PAGE_SIZE))
panic("MMU pg size != PAGE_SIZE (%luk)\n", TO_KB(PAGE_SIZE));
+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
+ mmu->s_pg_sz_m != TO_MB(HPAGE_PMD_SIZE))
+ panic("MMU Super pg size != Linux HPAGE_PMD_SIZE (%luM)\n",
+ (unsigned long)TO_MB(HPAGE_PMD_SIZE));
+
+ if (IS_ENABLED(CONFIG_ARC_HAS_PAE40) && !mmu->pae)
+ panic("Hardware doesn't support PAE40\n");
+
/* Enable the MMU */
write_aux_reg(ARC_REG_PID, MMU_ENABLE);
@@ -725,15 +873,15 @@ void arc_mmu_init(void)
* the duplicate one.
* -Knob to be verbose abt it.(TODO: hook them up to debugfs)
*/
-volatile int dup_pd_verbose = 1;/* Be slient abt it or complain (default) */
+volatile int dup_pd_silent; /* Be slient abt it or complain (default) */
void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
struct pt_regs *regs)
{
- int set, way, n;
- unsigned long flags, is_valid;
struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
- unsigned int pd0[mmu->ways], pd1[mmu->ways];
+ unsigned int pd0[mmu->ways];
+ unsigned long flags;
+ int set;
local_irq_save(flags);
@@ -743,14 +891,16 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
/* loop thru all sets of TLB */
for (set = 0; set < mmu->sets; set++) {
+ int is_valid, way;
+
/* read out all the ways of current set */
for (way = 0, is_valid = 0; way < mmu->ways; way++) {
write_aux_reg(ARC_REG_TLBINDEX,
SET_WAY_TO_IDX(mmu, set, way));
write_aux_reg(ARC_REG_TLBCOMMAND, TLBRead);
pd0[way] = read_aux_reg(ARC_REG_TLBPD0);
- pd1[way] = read_aux_reg(ARC_REG_TLBPD1);
is_valid |= pd0[way] & _PAGE_PRESENT;
+ pd0[way] &= PAGE_MASK;
}
/* If all the WAYS in SET are empty, skip to next SET */
@@ -759,30 +909,28 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
/* Scan the set for duplicate ways: needs a nested loop */
for (way = 0; way < mmu->ways - 1; way++) {
+
+ int n;
+
if (!pd0[way])
continue;
for (n = way + 1; n < mmu->ways; n++) {
- if ((pd0[way] & PAGE_MASK) ==
- (pd0[n] & PAGE_MASK)) {
-
- if (dup_pd_verbose) {
- pr_info("Duplicate PD's @"
- "[%d:%d]/[%d:%d]\n",
- set, way, set, n);
- pr_info("TLBPD0[%u]: %08x\n",
- way, pd0[way]);
- }
-
- /*
- * clear entry @way and not @n. This is
- * critical to our optimised loop
- */
- pd0[way] = pd1[way] = 0;
- write_aux_reg(ARC_REG_TLBINDEX,
+ if (pd0[way] != pd0[n])
+ continue;
+
+ if (!dup_pd_silent)
+ pr_info("Dup TLB PD0 %08x @ set %d ways %d,%d\n",
+ pd0[way], set, way, n);
+
+ /*
+ * clear entry @way and not @n.
+ * This is critical to our optimised loop
+ */
+ pd0[way] = 0;
+ write_aux_reg(ARC_REG_TLBINDEX,
SET_WAY_TO_IDX(mmu, set, way));
- __tlb_entry_erase();
- }
+ __tlb_entry_erase();
}
}
}
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index f6f4c3c..f1967ee 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -88,7 +88,7 @@ ex_saved_reg1:
#ifdef CONFIG_SMP
sr r0, [ARC_REG_SCRATCH_DATA0] ; freeup r0 to code with
GET_CPU_ID r0 ; get to per cpu scratch mem,
- lsl r0, r0, L1_CACHE_SHIFT ; cache line wide per cpu
+ asl r0, r0, L1_CACHE_SHIFT ; cache line wide per cpu
add r0, @ex_saved_reg1, r0
#else
st r0, [@ex_saved_reg1]
@@ -107,7 +107,7 @@ ex_saved_reg1:
.macro TLBMISS_RESTORE_REGS
#ifdef CONFIG_SMP
GET_CPU_ID r0 ; get to per cpu scratch mem
- lsl r0, r0, L1_CACHE_SHIFT ; each is cache line wide
+ asl r0, r0, L1_CACHE_SHIFT ; each is cache line wide
add r0, @ex_saved_reg1, r0
ld_s r3, [r0,12]
ld_s r2, [r0, 8]
@@ -205,20 +205,38 @@ ex_saved_reg1:
#endif
lsr r0, r2, PGDIR_SHIFT ; Bits for indexing into PGD
- ld.as r1, [r1, r0] ; PGD entry corresp to faulting addr
- and.f r1, r1, PAGE_MASK ; Ignoring protection and other flags
- ; contains Ptr to Page Table
- bz.d do_slow_path_pf ; if no Page Table, do page fault
+ ld.as r3, [r1, r0] ; PGD entry corresp to faulting addr
+ tst r3, r3
+ bz do_slow_path_pf ; if no Page Table, do page fault
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ and.f 0, r3, _PAGE_HW_SZ ; Is this Huge PMD (thp)
+ add2.nz r1, r1, r0
+ bnz.d 2f ; YES: PGD == PMD has THP PTE: stop pgd walk
+ mov.nz r0, r3
+
+#endif
+ and r1, r3, PAGE_MASK
; Get the PTE entry: The idea is
; (1) x = addr >> PAGE_SHIFT -> masks page-off bits from @fault-addr
; (2) y = x & (PTRS_PER_PTE - 1) -> to get index
- ; (3) z = pgtbl[y]
- ; To avoid the multiply by in end, we do the -2, <<2 below
+ ; (3) z = (pgtbl + y * 4)
+
+#ifdef CONFIG_ARC_HAS_PAE40
+#define PTE_SIZE_LOG 3 /* 8 == 2 ^ 3 */
+#else
+#define PTE_SIZE_LOG 2 /* 4 == 2 ^ 2 */
+#endif
+
+ ; multiply in step (3) above avoided by shifting lesser in step (1)
+ lsr r0, r2, ( PAGE_SHIFT - PTE_SIZE_LOG )
+ and r0, r0, ( (PTRS_PER_PTE - 1) << PTE_SIZE_LOG )
+ ld.aw r0, [r1, r0] ; r0: PTE (lower word only for PAE40)
+ ; r1: PTE ptr
+
+2:
- lsr r0, r2, (PAGE_SHIFT - 2)
- and r0, r0, ( (PTRS_PER_PTE - 1) << 2)
- ld.aw r0, [r1, r0] ; get PTE and PTE ptr for fault addr
#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
and.f 0, r0, _PAGE_PRESENT
bz 1f
@@ -233,18 +251,23 @@ ex_saved_reg1:
;-----------------------------------------------------------------
; Convert Linux PTE entry into TLB entry
; A one-word PTE entry is programmed as two-word TLB Entry [PD0:PD1] in mmu
+; (for PAE40, two-words PTE, while three-word TLB Entry [PD0:PD1:PD1HI])
; IN: r0 = PTE, r1 = ptr to PTE
.macro CONV_PTE_TO_TLB
- and r3, r0, PTE_BITS_RWX ; r w x
- lsl r2, r3, 3 ; r w x 0 0 0 (GLOBAL, kernel only)
+ and r3, r0, PTE_BITS_RWX ; r w x
+ asl r2, r3, 3 ; Kr Kw Kx 0 0 0 (GLOBAL, kernel only)
and.f 0, r0, _PAGE_GLOBAL
- or.z r2, r2, r3 ; r w x r w x (!GLOBAL, user page)
+ or.z r2, r2, r3 ; Kr Kw Kx Ur Uw Ux (!GLOBAL, user page)
and r3, r0, PTE_BITS_NON_RWX_IN_PD1 ; Extract PFN+cache bits from PTE
or r3, r3, r2
- sr r3, [ARC_REG_TLBPD1] ; these go in PD1
+ sr r3, [ARC_REG_TLBPD1] ; paddr[31..13] | Kr Kw Kx Ur Uw Ux | C
+#ifdef CONFIG_ARC_HAS_PAE40
+ ld r3, [r1, 4] ; paddr[39..32]
+ sr r3, [ARC_REG_TLBPD1HI]
+#endif
and r2, r0, PTE_BITS_IN_PD0 ; Extract other PTE flags: (V)alid, (G)lb
@@ -365,7 +388,7 @@ ENTRY(EV_TLBMissD)
lr r3, [ecr]
or r0, r0, _PAGE_ACCESSED ; Accessed bit always
btst_s r3, ECR_C_BIT_DTLB_ST_MISS ; See if it was a Write Access ?
- or.nz r0, r0, _PAGE_MODIFIED ; if Write, set Dirty bit as well
+ or.nz r0, r0, _PAGE_DIRTY ; if Write, set Dirty bit as well
st_s r0, [r1] ; Write back PTE
CONV_PTE_TO_TLB
diff --git a/arch/arc/plat-axs10x/Kconfig b/arch/arc/plat-axs10x/Kconfig
index d475f9d..426ac4b 100644
--- a/arch/arc/plat-axs10x/Kconfig
+++ b/arch/arc/plat-axs10x/Kconfig
@@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X
select DW_APB_ICTL
select GPIO_DWAPB
select OF_GPIO
+ select MIGHT_HAVE_PCI
select GENERIC_IRQ_CHIP
select ARCH_REQUIRE_GPIOLIB
help
diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
index 0a77b19..1b0f0f4 100644
--- a/arch/arc/plat-axs10x/axs10x.c
+++ b/arch/arc/plat-axs10x/axs10x.c
@@ -455,11 +455,6 @@ static void __init axs103_early_init(void)
axs10x_print_board_ver(AXC003_CREG + 4088, "AXC003 CPU Card");
axs10x_early_init();
-
-#ifdef CONFIG_ARC_MCIP
- /* No Hardware init, but filling the smp ops callbacks */
- mcip_init_early_smp();
-#endif
}
#endif
@@ -487,9 +482,6 @@ static const char *axs103_compat[] __initconst = {
MACHINE_START(AXS103, "axs103")
.dt_compat = axs103_compat,
.init_early = axs103_early_init,
-#ifdef CONFIG_ARC_MCIP
- .init_smp = mcip_init_smp,
-#endif
MACHINE_END
/*
diff --git a/arch/arc/plat-sim/platform.c b/arch/arc/plat-sim/platform.c
index d9e35b4..e4fe514 100644
--- a/arch/arc/plat-sim/platform.c
+++ b/arch/arc/plat-sim/platform.c
@@ -10,7 +10,6 @@
#include <linux/init.h>
#include <asm/mach_desc.h>
-#include <asm/mcip.h>
/*----------------------- Machine Descriptions ------------------------------
*
@@ -30,8 +29,4 @@ static const char *simulation_compat[] __initconst = {
MACHINE_START(SIMULATION, "simulation")
.dt_compat = simulation_compat,
-#ifdef CONFIG_ARC_MCIP
- .init_early = mcip_init_early_smp,
- .init_smp = mcip_init_smp,
-#endif
MACHINE_END
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 639411f..f6c185f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
bool
default y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAVE_CUSTOM_GPIO_H
@@ -20,6 +21,7 @@ config ARM
select GENERIC_ALLOCATOR
select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_EARLY_IOREMAP
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
@@ -33,19 +35,20 @@ config ARM
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 && !CPU_ENDIAN_BE32
- select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32
+ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
+ select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
+ select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_TRACEHOOK
+ select HAVE_ARM_SMCCC if CPU_V7
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) && !CPU_ENDIAN_BE32
+ select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU
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)
@@ -76,6 +79,8 @@ config ARM
select IRQ_FORCED_THREADING
select MODULES_USE_ELF_REL
select NO_BOOTMEM
+ select OF_EARLY_FLATTREE if OF
+ select OF_RESERVED_MEM if OF
select OLD_SIGACTION
select OLD_SIGSUSPEND3
select PERF_USE_VMALLOC
@@ -162,11 +167,6 @@ config STACKTRACE_SUPPORT
bool
default y
-config HAVE_LATENCYTOP_SUPPORT
- bool
- depends on !SMP
- default y
-
config LOCKDEP_SUPPORT
bool
default y
@@ -239,7 +239,6 @@ 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
@@ -306,13 +305,21 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
+config ARCH_MMAP_RND_BITS_MIN
+ default 8
+
+config ARCH_MMAP_RND_BITS_MAX
+ default 14 if PAGE_OFFSET=0x40000000
+ default 15 if PAGE_OFFSET=0x80000000
+ default 16
+
#
# 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 ARM_SINGLE_ARMV7M if !MMU
default ARCH_MULTIPLATFORM if MMU
config ARCH_MULTIPLATFORM
@@ -344,38 +351,6 @@ config ARM_SINGLE_ARMV7M
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"
@@ -510,55 +485,15 @@ config ARCH_DOVE
select CPU_PJ4
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
+ select MULTI_IRQ_HANDLER
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
- select MULTI_IRQ_HANDLER
- 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
+ select PM_GENERIC_DOMAINS if PM
help
- Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+ Support for the Marvell Dove SoC 88AP510
config ARCH_KS8695
bool "Micrel/Kendin KS8695"
@@ -609,6 +544,7 @@ config ARCH_PXA
select AUTO_ZRELADDR
select COMMON_CLK
select CLKDEV_LOOKUP
+ select CLKSRC_PXA
select CLKSRC_MMIO
select CLKSRC_OF
select GENERIC_CLOCKEVENTS
@@ -621,28 +557,6 @@ config ARCH_PXA
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"
depends on MMU
@@ -658,7 +572,6 @@ config ARCH_RPC
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.
@@ -670,6 +583,8 @@ config ARCH_SA1100
select ARCH_SPARSEMEM_ENABLE
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select CLKSRC_PXA
+ select CLKSRC_OF if OF
select CPU_FREQ
select CPU_SA1100
select GENERIC_CLOCKEVENTS
@@ -702,32 +617,6 @@ config ARCH_S3C24XX
(<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
@@ -737,7 +626,6 @@ config ARCH_DAVINCI
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select HAVE_IDE
- select TI_PRIV_EDMA
select USE_OF
select ZONE_DMA
help
@@ -817,9 +705,12 @@ config ARCH_MULTI_CPU_AUTO
endmenu
config ARCH_VIRT
- bool "Dummy Virtual Machine" if ARCH_MULTI_V7
+ bool "Dummy Virtual Machine"
+ depends on ARCH_MULTI_V7
select ARM_AMBA
select ARM_GIC
+ select ARM_GIC_V2M if PCI_MSI
+ select ARM_GIC_V3
select ARM_PSCI
select HAVE_ARM_ARCH_TIMER
@@ -938,6 +829,8 @@ source "arch/arm/mach-sunxi/Kconfig"
source "arch/arm/mach-prima2/Kconfig"
+source "arch/arm/mach-tango/Kconfig"
+
source "arch/arm/mach-tegra/Kconfig"
source "arch/arm/mach-u300/Kconfig"
@@ -1318,7 +1211,6 @@ config PCI_HOST_ITE8152
select DMABOUNCE
source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
source "drivers/pcmcia/Kconfig"
@@ -1411,7 +1303,6 @@ config HAVE_ARM_ARCH_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
@@ -1443,8 +1334,7 @@ config BIG_LITTLE
config BL_SWITCHER
bool "big.LITTLE switcher support"
- depends on BIG_LITTLE && MCPM && HOTPLUG_CPU
- select ARM_CPU_SUSPEND
+ depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC
select CPU_PM
help
The big.LITTLE "switcher" provides the core functionality to
@@ -1471,6 +1361,8 @@ choice
config VMSPLIT_3G
bool "3G/1G user/kernel split"
+ config VMSPLIT_3G_OPT
+ bool "3G/1G user/kernel split (for full 1G low memory)"
config VMSPLIT_2G
bool "2G/2G user/kernel split"
config VMSPLIT_1G
@@ -1482,6 +1374,7 @@ config PAGE_OFFSET
default PHYS_OFFSET if !MMU
default 0x40000000 if VMSPLIT_1G
default 0x80000000 if VMSPLIT_2G
+ default 0xB0000000 if VMSPLIT_3G_OPT
default 0xC0000000
config NR_CPUS
@@ -1499,7 +1392,7 @@ config HOTPLUG_CPU
config ARM_PSCI
bool "Support for the ARM Power State Coordination Interface (PSCI)"
- depends on CPU_V7
+ depends on HAVE_ARM_SMCCC
select ARM_PSCI_FW
help
Say Y here if you want Linux to communicate with system firmware
@@ -1535,7 +1428,6 @@ config HZ_FIXED
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
@@ -1623,6 +1515,24 @@ config THUMB2_AVOID_R_ARM_THM_JUMP11
config ARM_ASM_UNIFIED
bool
+config ARM_PATCH_IDIV
+ bool "Runtime patch udiv/sdiv instructions into __aeabi_{u}idiv()"
+ depends on CPU_32v7 && !XIP_KERNEL
+ default y
+ help
+ The ARM compiler inserts calls to __aeabi_idiv() and
+ __aeabi_uidiv() when it needs to perform division on signed
+ and unsigned integers. Some v7 CPUs have support for the sdiv
+ and udiv instructions that can be used to implement those
+ functions.
+
+ Enabling this option allows the kernel to modify itself to
+ replace the first two instructions of these library functions
+ with the sdiv or udiv plus "bx lr" instructions when the CPU
+ it is running on supports them. Typically this will be faster
+ and less power intensive than running the original library
+ code to do integer division.
+
config AEABI
bool "Use the ARM EABI to compile the kernel"
help
@@ -1696,8 +1606,9 @@ config HIGHMEM
If unsure, say n.
config HIGHPTE
- bool "Allocate 2nd-level pagetables from highmem"
+ bool "Allocate 2nd-level pagetables from highmem" if EXPERT
depends on HIGHMEM
+ default y
help
The VM uses one page of physical memory for each page table.
For systems with a lot of processes, this can use a lot of
@@ -1753,8 +1664,7 @@ config ARM_MODULE_PLTS
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
- int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
- range 11 64 if ARCH_SHMOBILE_LEGACY
+ int "Maximum zone order"
default "12" if SOC_AM33XX
default "9" if SA1111 || ARCH_EFM32
default "11"
@@ -1819,6 +1729,25 @@ config SWIOTLB
config IOMMU_HELPER
def_bool SWIOTLB
+config PARAVIRT
+ bool "Enable paravirtualization code"
+ help
+ This changes the kernel so it can modify itself when it is run
+ under a hypervisor, potentially improving performance significantly
+ over full virtualization.
+
+config PARAVIRT_TIME_ACCOUNTING
+ bool "Paravirtual steal time accounting"
+ select PARAVIRT
+ default n
+ help
+ Select this option to enable fine granularity task steal time
+ accounting. Time spent executing other tasks in parallel with
+ the current vCPU is discounted from the vCPU power. To account for
+ that, there can be a small performance impact.
+
+ If in doubt, say N here.
+
config XEN_DOM0
def_bool y
depends on XEN
@@ -1832,6 +1761,7 @@ config XEN
select ARCH_DMA_ADDR_T_64BIT
select ARM_PSCI
select SWIOTLB_XEN
+ select PARAVIRT
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
@@ -1843,8 +1773,6 @@ 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.
@@ -2061,6 +1989,25 @@ config AUTO_ZRELADDR
0xf8000000. This assumes the zImage being placed in the first 128MB
from start of memory.
+config EFI_STUB
+ bool
+
+config EFI
+ bool "UEFI runtime support"
+ depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL
+ select UCS2_STRING
+ select EFI_PARAMS_FROM_FDT
+ select EFI_STUB
+ select EFI_ARMSTUB
+ select EFI_RUNTIME_WRAPPERS
+ ---help---
+ This option provides support for runtime services provided
+ by UEFI firmware (such as non-volatile variables, realtime
+ clock, and platform reset). A UEFI stub is also provided to
+ allow the kernel to be booted as an EFI application. This
+ is only useful for kernels that may run on systems that have
+ UEFI firmware.
+
endmenu
menu "CPU Power Management"
@@ -2161,7 +2108,8 @@ config ARCH_SUSPEND_POSSIBLE
def_bool y
config ARM_CPU_SUSPEND
- def_bool PM_SLEEP
+ def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW
+ depends on ARCH_SUSPEND_POSSIBLE
config ARCH_HIBERNATION_POSSIBLE
bool
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 0cfd7f9..c6b6175 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -15,20 +15,6 @@ config ARM_PTDUMP
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
@@ -123,33 +109,32 @@ choice
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
+ config DEBUG_AT91_UART
+ bool "Kernel low-level debugging on Atmel SoCs"
depends on ARCH_AT91
- depends on SOC_AT91RM9200 || SOC_AT91SAM9
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port on atmel devices.
- 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
+ SOC DEBUG_UART_PHYS DEBUG_UART_VIRT PORT
+ rm9200, 9260/9g20, 0xfffff200 0xfefff200 DBGU
+ 9261/9g10, 9rl
+ 9263, 9g45, sama5d3 0xffffee00 0xfeffee00 DBGU
+ sama5d4 0xfc00c000 0xfb00c000 USART3
+ sama5d4 0xfc069000 0xfb069000 DBGU
+ sama5d2 0xf8020000 0xf7020000 UART1
- 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 AT91_DEBUG_LL_DBGU3
- bool "Kernel low-level debugging on sama5d2"
- select DEBUG_AT91_UART
- depends on ARCH_AT91
- depends on SOC_SAMA5
+ Please adjust DEBUG_UART_PHYS configuration options based on
+ your needs.
config DEBUG_BCM2835
bool "Kernel low-level debugging on BCM2835 PL011 UART"
- depends on ARCH_BCM2835
+ depends on ARCH_BCM2835 && ARCH_MULTI_V6
+ select DEBUG_UART_PL01X
+
+ config DEBUG_BCM2836
+ bool "Kernel low-level debugging on BCM2836 PL011 UART"
+ depends on ARCH_BCM2835 && ARCH_MULTI_V7
select DEBUG_UART_PL01X
config DEBUG_BCM_5301X
@@ -168,10 +153,9 @@ choice
mobile SoCs in the Kona family of chips (e.g. bcm28155,
bcm11351, etc...)
- config DEBUG_BCM63XX
+ config DEBUG_BCM63XX_UART
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"
@@ -238,23 +222,6 @@ choice
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
@@ -269,13 +236,30 @@ choice
Say Y here if you want the debug print routines to direct
their output to the UA0 serial port in the CX92755.
+ config DEBUG_EP93XX
+ bool "Kernel low-level debugging messages via ep93xx UART"
+ depends on ARCH_EP93XX
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Cirrus Logic EP93xx based platforms.
+
config DEBUG_FOOTBRIDGE_COM1
bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
depends on FOOTBRIDGE
+ select DEBUG_UART_8250
help
Say Y here if you want the debug print routines to direct
their output to the 8250 at PCI COM1.
+ config DEBUG_GEMINI
+ bool "Kernel low-level debugging messages via Cortina Systems Gemini UART"
+ depends on ARCH_GEMINI
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Cortina Gemini based platforms.
+
config DEBUG_HI3620_UART
bool "Hisilicon HI3620 Debug UART"
depends on ARCH_HI3xxx
@@ -431,6 +415,14 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX7D.
+ config DEBUG_INTEGRATOR
+ bool "Kernel low-level debugging messages via ARM Integrator UART"
+ depends on ARCH_INTEGRATOR
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on ARM Integrator platforms.
+
config DEBUG_KEYSTONE_UART0
bool "Kernel low-level debugging on KEYSTONE2 using UART0"
depends on ARCH_KEYSTONE
@@ -462,6 +454,14 @@ choice
Say Y here if you want kernel low-level debugging support
on NXP LPC18xx/43xx UART0.
+ config DEBUG_LPC32XX
+ bool "Kernel low-level debugging messages via NXP LPC32xx UART"
+ depends on ARCH_LPC32XX
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on NXP LPC32xx based platforms.
+
config DEBUG_MESON_UARTAO
bool "Kernel low-level debugging via Meson6 UARTAO"
depends on ARCH_MESON
@@ -485,26 +485,10 @@ choice
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
+ depends on ARCH_MVEBU && CPU_V7
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
@@ -517,17 +501,23 @@ choice
Plathome OpenBlocks AX3, when using the original
bootloader.
+ This option will not work on older Marvell platforms
+ (Kirkwood, Dove, MV78xx0, Orion5x), which should pick
+ the "new bootloader" variant.
+
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
+ depends on ARCH_MVEBU || ARCH_DOVE || ARCH_MV78XX0 || ARCH_ORION5X
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms on UART0.
+ on MVEBU based platforms on UART0. (Armada XP, Armada 3xx,
+ Kirkwood, Dove, MV78xx0, Orion5x).
+
This option should be used with the new bootloaders
that remap the internal registers at 0xf1000000.
@@ -542,21 +532,41 @@ choice
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms on UART1.
+ on MVEBU based platforms on UART1. (Armada XP, Armada 3xx,
+ Kirkwood, Dove, MV78xx0, Orion5x).
This option should be used with the new bootloaders
that remap the internal registers at 0xf1000000.
+ All of the older (pre Armada XP/370) platforms also use
+ this address, regardless of the boot loader version.
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
+ 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
- on Vybrid based platforms.
+ 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_NETX_UART
bool "Kernel low-level debugging messages via NetX UART"
@@ -720,6 +730,23 @@ choice
Say Y here if you want kernel low-level debugging support
on PXA UART1.
+ 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_REALVIEW_STD_PORT
bool "RealView Default UART"
depends on ARCH_REALVIEW
@@ -863,6 +890,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 0 for low-level debug"
help
@@ -874,6 +902,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 1 for low-level debug"
help
@@ -885,6 +914,7 @@ choice
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX
+ select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 2 for low-level debug"
help
@@ -895,6 +925,7 @@ choice
config DEBUG_S3C_UART3
depends on PLAT_SAMSUNG && (ARCH_EXYNOS || ARCH_S5PV210)
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
+ select DEBUG_S3C64XX_UART if ARCH_S3C64XX
select DEBUG_S5PV210_UART if ARCH_S5PV210
bool "Use Samsung S3C UART 3 for low-level debug"
help
@@ -986,6 +1017,70 @@ choice
Say Y here if you want kernel low-level debugging support
on Allwinner A31/A23 based platforms on the R_UART.
+ 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 DEBUG_SPEAR3XX
+ bool "Kernel low-level debugging messages via ST SPEAr 3xx/6xx UART"
+ depends on ARCH_SPEAR3XX || ARCH_SPEAR6XX
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on ST SPEAr based platforms.
+
+ config DEBUG_SPEAR13XX
+ bool "Kernel low-level debugging messages via ST SPEAr 13xx UART"
+ depends on ARCH_SPEAR13XX
+ select DEBUG_UART_PL01X
+ help
+ Say Y here if you want kernel low-level debugging support
+ on ST SPEAr13xx based platforms.
+
+ 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 TEGRA_DEBUG_UART_AUTO_ODMDATA
bool "Kernel low-level debugging messages via Tegra UART via ODMDATA"
depends on ARCH_TEGRA
@@ -1038,54 +1133,6 @@ choice
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
@@ -1101,29 +1148,13 @@ choice
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
+ config DEBUG_VERSATILE
+ bool "Kernel low-level debugging messages via ARM Versatile UART"
+ depends on ARCH_VERSATILE
+ select DEBUG_UART_PL01X
help
Say Y here if you want kernel low-level debugging support
- for Mediatek mt8135 based platforms on UART3.
+ on ARM Versatile platforms.
config DEBUG_VEXPRESS_UART0_DETECT
bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
@@ -1161,6 +1192,13 @@ choice
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_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_VT8500_UART0
bool "Use UART0 on VIA/Wondermedia SoCs"
depends on ARCH_VT8500
@@ -1168,6 +1206,35 @@ choice
This option selects UART0 on VIA/Wondermedia System-on-a-chip
devices, including VT8500, WM8505, WM8650 and WM8850.
+ config DEBUG_ZTE_ZX
+ bool "Use ZTE ZX UART"
+ select DEBUG_UART_PL01X
+ depends on ARCH_ZX
+ help
+ Say Y here if you are enabling ZTE ZX296702 SOC and need
+ debug uart support.
+
+ This option is preferred over the platform specific
+ options; the platform specific options are deprecated
+ and will be soon removed.
+
+ 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_ICEDCC
bool "Kernel low-level debugging via EmbeddedICE DCC channel"
help
@@ -1195,18 +1262,6 @@ choice
For more details about semihosting, please see
chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
- config DEBUG_ZTE_ZX
- bool "Use ZTE ZX UART"
- select DEBUG_UART_PL01X
- depends on ARCH_ZX
- help
- Say Y here if you are enabling ZTE ZX296702 SOC and need
- debug uart support.
-
- This option is preferred over the platform specific
- options; the platform specific options are deprecated
- and will be soon removed.
-
config DEBUG_LL_UART_8250
bool "Kernel low-level debugging via 8250 UART"
help
@@ -1249,10 +1304,6 @@ choice
endchoice
-config DEBUG_AT91_UART
- bool
- depends on ARCH_AT91
-
config DEBUG_EXYNOS_UART
bool
@@ -1263,6 +1314,9 @@ config DEBUG_S3C2410_UART
config DEBUG_S3C24XX_UART
bool
+config DEBUG_S3C64XX_UART
+ bool
+
config DEBUG_S5PV210_UART
bool
@@ -1318,6 +1372,7 @@ config DEBUG_LL_INCLUDE
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/dc21285.S" if DEBUG_DC21285_PORT
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
@@ -1348,7 +1403,7 @@ config DEBUG_LL_INCLUDE
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/s3c24xx.S" if DEBUG_S3C24XX_UART || DEBUG_S3C64XX_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
@@ -1358,7 +1413,7 @@ config DEBUG_LL_INCLUDE
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/bcm63xx.S" if DEBUG_BCM63XX_UART
default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
default "mach/debug-macro.S"
@@ -1368,15 +1423,9 @@ config DEBUG_UART_PL01X
# 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
+ def_bool ARCH_EBSA110 || \
+ ARCH_IOP13XX || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || \
+ ARCH_RPC
config DEBUG_UART_PHYS
hex "Physical base address of debug UART"
@@ -1397,12 +1446,12 @@ config DEBUG_UART_PHYS
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 0x101f1000 if DEBUG_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 0x16000000 if DEBUG_INTEGRATOR
default 0x18000300 if DEBUG_BCM_5301X
default 0x18010000 if DEBUG_SIRFATLAS7_UART0
default 0x18020000 if DEBUG_SIRFATLAS7_UART1
@@ -1412,12 +1461,13 @@ config DEBUG_UART_PHYS
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
default 0x20201000 if DEBUG_BCM2835
+ default 0x3f201000 if DEBUG_BCM2836
default 0x3e000000 if DEBUG_BCM_KONA_UART
default 0x4000e400 if DEBUG_LL_UART_EFM32
default 0x40081000 if DEBUG_LPC18XX_UART0
- default 0x40090000 if ARCH_LPC32XX
+ default 0x40090000 if DEBUG_LPC32XX
default 0x40100000 if DEBUG_PXA_UART1
- default 0x42000000 if ARCH_GEMINI
+ default 0x42000000 if DEBUG_GEMINI
default 0x50000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
DEBUG_S3C2410_UART0)
default 0x50004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
@@ -1425,24 +1475,28 @@ config DEBUG_UART_PHYS
default 0x50008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
DEBUG_S3C2410_UART2)
default 0x78000000 if DEBUG_CNS3XXX
- default 0x7c0003f8 if FOOTBRIDGE
+ default 0x7c0003f8 if DEBUG_FOOTBRIDGE_COM1
+ default 0x7f005000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
+ default 0x7f005400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
+ default 0x7f005800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
+ default 0x7f005c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
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 0x808c0000 if DEBUG_EP93XX || 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 0xd0000000 if DEBUG_SPEAR3XX
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 0xe0000000 if DEBUG_SPEAR13XX
default 0xe4007000 if DEBUG_HIP04_UART
default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
@@ -1454,8 +1508,6 @@ config DEBUG_UART_PHYS
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
@@ -1472,7 +1524,7 @@ config DEBUG_UART_PHYS
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 0xfffe8600 if DEBUG_BCM63XX_UART
default 0xfffff700 if ARCH_IOP33X
depends on ARCH_EP93XX || \
DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
@@ -1484,8 +1536,10 @@ config DEBUG_UART_PHYS
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
+ DEBUG_S3C64XX_UART || \
+ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
+ DEBUG_AT91_UART
config DEBUG_UART_VIRT
hex "Virtual base address of debug UART"
@@ -1494,22 +1548,27 @@ config DEBUG_UART_VIRT
default 0xf0000be0 if ARCH_EBSA110
default 0xf0010000 if DEBUG_ASM9260_UART
default 0xf01fb000 if DEBUG_NOMADIK_UART
- default 0xf0201000 if DEBUG_BCM2835
+ default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836
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 0xf11f1000 if DEBUG_VERSATILE
+ default 0xf1600000 if DEBUG_INTEGRATOR
default 0xf1c28000 if DEBUG_SUNXI_UART0
default 0xf1c28400 if DEBUG_SUNXI_UART1
default 0xf1f02800 if DEBUG_SUNXI_R_UART
+ default 0xf31004c0 if DEBUG_MESON_UARTAO
+ default 0xf4090000 if DEBUG_LPC32XX
+ default 0xf4200000 if DEBUG_GEMINI
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_S3C64XX_UART && DEBUG_S3C_UART0
default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
DEBUG_S3C2410_UART0)
+ default 0xf7000400 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART1
+ default 0xf7000800 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART2
+ default 0xf7000c00 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART3
default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
DEBUG_S3C2410_UART1)
default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
@@ -1524,14 +1583,12 @@ config DEBUG_UART_VIRT
default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
default 0xfc40ab00 if DEBUG_BRCMSTB_UART
default 0xfc705000 if DEBUG_ZTE_ZX
- default 0xfcfe8600 if DEBUG_UART_BCM63XX
- default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
- default 0xfd000000 if ARCH_SPEAR13XX
- default 0xfd012000 if ARCH_MV78XX0
+ default 0xfcfe8600 if DEBUG_BCM63XX_UART
+ default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX
+ default 0xfd012000 if DEBUG_MVEBU_UART0_ALTERNATE && 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 0xfde12000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_DOVE
+ default 0xfe012000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_ORION5X
default 0xfe017000 if DEBUG_MMP_UART2
default 0xfe018000 if DEBUG_MMP_UART3
default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
@@ -1545,7 +1602,7 @@ config DEBUG_UART_VIRT
default 0xfeb31000 if DEBUG_KEYSTONE_UART1
default 0xfec02000 if DEBUG_SOCFPGA_UART0
default 0xfec02100 if DEBUG_SOCFPGA_UART1
- default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xfec12000 if (DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE) && ARCH_MVEBU
default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
@@ -1557,8 +1614,8 @@ config DEBUG_UART_VIRT
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 0xfedc0000 if DEBUG_EP93XX
+ default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1
default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xfee82340 if ARCH_IOP13XX
default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
@@ -1575,13 +1632,14 @@ config DEBUG_UART_VIRT
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_S3C64XX_UART || \
+ DEBUG_BCM63XX_UART || 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 || \
+ default 0 if DEBUG_FOOTBRIDGE_COM1 || ARCH_IOP32X || DEBUG_BCM_5301X || \
DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || DEBUG_OMAP7XXUART3
default 2
@@ -1589,8 +1647,9 @@ 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_UART0 || \
- DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \
+ default y if DEBUG_PICOXCELL_UART || \
+ DEBUG_SOCFPGA_UART0 || DEBUG_SOCFPGA_UART1 || \
+ DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
DEBUG_ALPINE_UART0 || \
DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
DEBUG_DAVINCI_DA8XX_UART2 || \
@@ -1600,7 +1659,7 @@ config DEBUG_UART_8250_WORD
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
+ default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC
config DEBUG_UNCOMPRESS
bool
@@ -1621,8 +1680,7 @@ config DEBUG_UNCOMPRESS
config UNCOMPRESS_INCLUDE
string
default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
- PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \
- ARCH_SHMOBILE_LEGACY
+ PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
default "mach/uncompress.h"
config EARLY_PRINTK
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2c2b28e..46fb1ca 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -30,9 +30,8 @@ GZFLAGS :=-9
# 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
+# This should work on most of the modern platforms
+KBUILD_DEFCONFIG := multi_v7_defconfig
# defines filename extension depending memory management type.
ifeq ($(CONFIG_MMU),)
@@ -211,6 +210,7 @@ machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
machine-$(CONFIG_ARCH_STM32) += stm32
machine-$(CONFIG_ARCH_SUNXI) += sunxi
+machine-$(CONFIG_ARCH_TANGO) += tango
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U300) += u300
machine-$(CONFIG_ARCH_U8500) += ux500
@@ -352,7 +352,6 @@ archclean:
# My testing targets (bypasses dependencies)
bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
-i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
define archhelp
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 9eca7ae..48fab15 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -88,7 +88,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
@$(kecho) ' Kernel: $@ is ready'
-PHONY += initrd FORCE
+PHONY += initrd
initrd:
@test "$(INITRD_PHYS)" != "" || \
(echo This machine does not support INITRD; exit -1)
@@ -107,12 +107,4 @@ 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/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index 0714e03..86b2f5d 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -3,11 +3,7 @@ bswapsdi2.S
font.c
lib1funcs.S
hyp-stub.S
-piggy.gzip
-piggy.lzo
-piggy.lzma
-piggy.xzkern
-piggy.lz4
+piggy_data
vmlinux
vmlinux.lds
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 3f9a9eb..d50430c 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -66,11 +66,11 @@ 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
+compress-$(CONFIG_KERNEL_GZIP) = gzip
+compress-$(CONFIG_KERNEL_LZO) = lzo
+compress-$(CONFIG_KERNEL_LZMA) = lzma
+compress-$(CONFIG_KERNEL_XZ) = xzkern
+compress-$(CONFIG_KERNEL_LZ4) = lz4
# Borrowed libfdt files for the ATAG compatibility mode
@@ -89,15 +89,12 @@ 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)
+targets := vmlinux vmlinux.lds piggy_data piggy.o \
+ lib1funcs.o ashldi3.o bswapsdi2.o \
+ head.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
+clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \
+ $(libfdt) $(libfdt_hdrs) hyp-stub.S
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
@@ -106,6 +103,15 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
+# -fstack-protector-strong triggers protection checks in this code,
+# but it is being used too early to link to meaningful stack_chk logic.
+nossp_flags := $(call cc-option, -fno-stack-protector)
+CFLAGS_atags_to_fdt.o := $(nossp_flags)
+CFLAGS_fdt.o := $(nossp_flags)
+CFLAGS_fdt_ro.o := $(nossp_flags)
+CFLAGS_fdt_rw.o := $(nossp_flags)
+CFLAGS_fdt_wip.o := $(nossp_flags)
+
ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
asflags-y := -DZIMAGE
@@ -167,22 +173,26 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
false; \
fi
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
+efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
- $(bswapsdi2) FORCE
+ $(bswapsdi2) $(efi-obj-y) 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_data: $(obj)/../Image FORCE
+ $(call if_changed,$(compress-y))
-$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE
+$(obj)/piggy.o: $(obj)/piggy_data
CFLAGS_font.o := -Dstatic=
$(obj)/font.c: $(FONTC)
$(call cmd,shipped)
+AFLAGS_hyp-stub.o := -Wa,-march=armv7-a
+
$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
$(call cmd,shipped)
diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S
new file mode 100644
index 0000000..9d5dc4f
--- /dev/null
+++ b/arch/arm/boot/compressed/efi-header.S
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013-2015 Linaro Ltd
+ * Authors: Roy Franz <roy.franz@linaro.org>
+ * 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.
+ */
+
+ .macro __nop
+#ifdef CONFIG_EFI_STUB
+ @ This is almost but not quite a NOP, since it does clobber the
+ @ condition flags. But it is the best we can do for EFI, since
+ @ PE/COFF expects the magic string "MZ" at offset 0, while the
+ @ ARM/Linux boot protocol expects an executable instruction
+ @ there.
+ .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000
+#else
+ mov r0, r0
+#endif
+ .endm
+
+ .macro __EFI_HEADER
+#ifdef CONFIG_EFI_STUB
+ b __efi_start
+
+ .set start_offset, __efi_start - start
+ .org start + 0x3c
+ @
+ @ The PE header can be anywhere in the file, but for
+ @ simplicity we keep it together with the MSDOS header
+ @ The offset to the PE/COFF header needs to be at offset
+ @ 0x3C in the MSDOS header.
+ @ The only 2 fields of the MSDOS header that are used are this
+ @ PE/COFF offset, and the "MZ" bytes at offset 0x0.
+ @
+ .long pe_header - start @ Offset to the PE header.
+
+pe_header:
+ .ascii "PE\0\0"
+
+coff_header:
+ .short 0x01c2 @ ARM or Thumb
+ .short 2 @ nr_sections
+ .long 0 @ TimeDateStamp
+ .long 0 @ PointerToSymbolTable
+ .long 1 @ NumberOfSymbols
+ .short section_table - optional_header
+ @ SizeOfOptionalHeader
+ .short 0x306 @ Characteristics.
+ @ IMAGE_FILE_32BIT_MACHINE |
+ @ IMAGE_FILE_DEBUG_STRIPPED |
+ @ IMAGE_FILE_EXECUTABLE_IMAGE |
+ @ IMAGE_FILE_LINE_NUMS_STRIPPED
+
+optional_header:
+ .short 0x10b @ PE32 format
+ .byte 0x02 @ MajorLinkerVersion
+ .byte 0x14 @ MinorLinkerVersion
+ .long _end - __efi_start @ SizeOfCode
+ .long 0 @ SizeOfInitializedData
+ .long 0 @ SizeOfUninitializedData
+ .long efi_stub_entry - start @ AddressOfEntryPoint
+ .long start_offset @ BaseOfCode
+ .long 0 @ data
+
+extra_header_fields:
+ .long 0 @ ImageBase
+ .long 0x200 @ SectionAlignment
+ .long 0x200 @ FileAlignment
+ .short 0 @ MajorOperatingSystemVersion
+ .short 0 @ MinorOperatingSystemVersion
+ .short 0 @ MajorImageVersion
+ .short 0 @ MinorImageVersion
+ .short 0 @ MajorSubsystemVersion
+ .short 0 @ MinorSubsystemVersion
+ .long 0 @ Win32VersionValue
+
+ .long _end - start @ SizeOfImage
+ .long start_offset @ SizeOfHeaders
+ .long 0 @ CheckSum
+ .short 0xa @ Subsystem (EFI application)
+ .short 0 @ DllCharacteristics
+ .long 0 @ SizeOfStackReserve
+ .long 0 @ SizeOfStackCommit
+ .long 0 @ SizeOfHeapReserve
+ .long 0 @ SizeOfHeapCommit
+ .long 0 @ LoaderFlags
+ .long 0x6 @ NumberOfRvaAndSizes
+
+ .quad 0 @ ExportTable
+ .quad 0 @ ImportTable
+ .quad 0 @ ResourceTable
+ .quad 0 @ ExceptionTable
+ .quad 0 @ CertificationTable
+ .quad 0 @ BaseRelocationTable
+
+section_table:
+ @
+ @ The EFI application loader requires a relocation section
+ @ because EFI applications must be relocatable. This is a
+ @ dummy section as far as we are concerned.
+ @
+ .ascii ".reloc\0\0"
+ .long 0 @ VirtualSize
+ .long 0 @ VirtualAddress
+ .long 0 @ SizeOfRawData
+ .long 0 @ PointerToRawData
+ .long 0 @ PointerToRelocations
+ .long 0 @ PointerToLineNumbers
+ .short 0 @ NumberOfRelocations
+ .short 0 @ NumberOfLineNumbers
+ .long 0x42100040 @ Characteristics
+
+ .ascii ".text\0\0\0"
+ .long _end - __efi_start @ VirtualSize
+ .long __efi_start @ VirtualAddress
+ .long _edata - __efi_start @ SizeOfRawData
+ .long __efi_start @ PointerToRawData
+ .long 0 @ PointerToRelocations
+ .long 0 @ PointerToLineNumbers
+ .short 0 @ NumberOfRelocations
+ .short 0 @ NumberOfLineNumbers
+ .long 0xe0500020 @ Characteristics
+
+ .align 9
+__efi_start:
+#endif
+ .endm
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 06e983f..af11c2f 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -12,6 +12,8 @@
#include <asm/assembler.h>
#include <asm/v7m.h>
+#include "efi-header.S"
+
AR_CLASS( .arch armv7-a )
M_CLASS( .arch armv7-m )
@@ -126,7 +128,7 @@
start:
.type start,#function
.rept 7
- mov r0, r0
+ __nop
.endr
ARM( mov r0, r0 )
ARM( b 1f )
@@ -139,7 +141,8 @@ start:
.word 0x04030201 @ endianness flag
THUMB( .thumb )
-1:
+1: __EFI_HEADER
+
ARM_BE8( setend be ) @ go BE8 if compiled for BE8
AR_CLASS( mrs r9, cpsr )
#ifdef CONFIG_ARM_VIRT_EXT
@@ -1353,6 +1356,53 @@ __enter_kernel:
reloc_code_end:
+#ifdef CONFIG_EFI_STUB
+ .align 2
+_start: .long start - .
+
+ENTRY(efi_stub_entry)
+ @ allocate space on stack for passing current zImage address
+ @ and for the EFI stub to return of new entry point of
+ @ zImage, as EFI stub may copy the kernel. Pointer address
+ @ is passed in r2. r0 and r1 are passed through from the
+ @ EFI firmware to efi_entry
+ adr ip, _start
+ ldr r3, [ip]
+ add r3, r3, ip
+ stmfd sp!, {r3, lr}
+ mov r2, sp @ pass zImage address in r2
+ bl efi_entry
+
+ @ Check for error return from EFI stub. r0 has FDT address
+ @ or error code.
+ cmn r0, #1
+ beq efi_load_fail
+
+ @ Preserve return value of efi_entry() in r4
+ mov r4, r0
+ bl cache_clean_flush
+ bl cache_off
+
+ @ Set parameters for booting zImage according to boot protocol
+ @ put FDT address in r2, it was returned by efi_entry()
+ @ r1 is the machine type, and r0 needs to be 0
+ mov r0, #0
+ mov r1, #0xFFFFFFFF
+ mov r2, r4
+
+ @ Branch to (possibly) relocated zImage that is in [sp]
+ ldr lr, [sp]
+ ldr ip, =start_offset
+ add lr, lr, ip
+ mov pc, lr @ no mode switch
+
+efi_load_fail:
+ @ Return EFI_LOAD_ERROR to EFI firmware on error.
+ ldr r0, =0x80000001
+ ldmfd sp!, {ip, pc}
+ENDPROC(efi_stub_entry)
+#endif
+
.align
.section ".stack", "aw", %nobits
.L_user_stack: .space 4096
diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.S
new file mode 100644
index 0000000..f720884
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy_data"
+ .globl input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S
deleted file mode 100644
index a68adf9..0000000
--- a/arch/arm/boot/compressed/piggy.gzip.S
+++ /dev/null
@@ -1,6 +0,0 @@
- .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
deleted file mode 100644
index 3d9a575..0000000
--- a/arch/arm/boot/compressed/piggy.lz4.S
+++ /dev/null
@@ -1,6 +0,0 @@
- .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
deleted file mode 100644
index d7e69cf..0000000
--- a/arch/arm/boot/compressed/piggy.lzma.S
+++ /dev/null
@@ -1,6 +0,0 @@
- .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
deleted file mode 100644
index a425ad9..0000000
--- a/arch/arm/boot/compressed/piggy.lzo.S
+++ /dev/null
@@ -1,6 +0,0 @@
- .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
deleted file mode 100644
index 5703f30..0000000
--- a/arch/arm/boot/compressed/piggy.xzkern.S
+++ /dev/null
@@ -1,6 +0,0 @@
- .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
index 36e53ef..6894674 100644
--- a/arch/arm/boot/compressed/string.c
+++ b/arch/arm/boot/compressed/string.c
@@ -65,6 +65,15 @@ size_t strlen(const char *s)
return sc - s;
}
+size_t strnlen(const char *s, size_t count)
+{
+ const char *sc;
+
+ for (sc = s; count-- && *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index 2b60b84..81c4931 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -48,6 +48,13 @@ SECTIONS
*(.rodata)
*(.rodata.*)
}
+ .data : {
+ /*
+ * The EFI stub always executes from RAM, and runs strictly before the
+ * decompressor, so we can make an exception for its r/w data, and keep it
+ */
+ *(.data.efistub)
+ }
.piggydata : {
*(.piggydata)
}
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index bb8fa02..a4a6d70 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -48,8 +48,10 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
sama5d34ek.dtb \
sama5d35ek.dtb \
sama5d36ek.dtb \
+ at91-sama5d4_ma5d4evk.dtb \
at91-sama5d4_xplained.dtb \
- at91-sama5d4ek.dtb
+ at91-sama5d4ek.dtb \
+ at91-vinco.dtb
dtb-$(CONFIG_ARCH_ATLAS6) += \
atlas6-evb.dtb
dtb-$(CONFIG_ARCH_ATLAS7) += \
@@ -58,7 +60,10 @@ dtb-$(CONFIG_ARCH_AXXIA) += \
axm5516-amarillo.dtb
dtb-$(CONFIG_ARCH_BCM2835) += \
bcm2835-rpi-b.dtb \
- bcm2835-rpi-b-plus.dtb
+ bcm2835-rpi-b-rev2.dtb \
+ bcm2835-rpi-b-plus.dtb \
+ bcm2835-rpi-a-plus.dtb \
+ bcm2836-rpi-2-b.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm4708-asus-rt-ac56u.dtb \
bcm4708-asus-rt-ac68u.dtb \
@@ -72,7 +77,11 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm47081-buffalo-wzr-900dhp.dtb \
bcm4709-asus-rt-ac87u.dtb \
bcm4709-buffalo-wxr-1900dhp.dtb \
- bcm4709-netgear-r8000.dtb
+ bcm4709-netgear-r7000.dtb \
+ bcm4709-netgear-r8000.dtb \
+ bcm94708.dtb \
+ bcm94709.dtb \
+ bcm953012k.dtb
dtb-$(CONFIG_ARCH_BCM_63XX) += \
bcm963138dvt.dtb
dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
@@ -83,6 +92,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
bcm28155-ap.dtb \
bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BCM_NSP) += \
+ bcm958625k.dtb
dtb-$(CONFIG_ARCH_BERLIN) += \
berlin2-sony-nsz-gs7.dtb \
berlin2cd-google-chromecast.dtb \
@@ -115,6 +126,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
exynos5250-arndale.dtb \
exynos5250-smdk5250.dtb \
exynos5250-snow.dtb \
+ exynos5250-snow-rev5.dtb \
exynos5250-spring.dtb \
exynos5260-xyref5260.dtb \
exynos5410-smdk5410.dtb \
@@ -123,6 +135,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
exynos5420-smdk5420.dtb \
exynos5422-odroidxu3.dtb \
exynos5422-odroidxu3-lite.dtb \
+ exynos5422-odroidxu4.dtb \
exynos5440-sd5v1.dtb \
exynos5440-ssdk5440.dtb \
exynos5800-peach-pi.dtb
@@ -193,12 +206,14 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
kirkwood-ns2mini.dtb \
kirkwood-nsa310.dtb \
kirkwood-nsa310a.dtb \
+ kirkwood-nsa325.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-pogoplug-series-4.dtb \
kirkwood-rd88f6192.dtb \
kirkwood-rd88f6281-z0.dtb \
kirkwood-rd88f6281-a.dtb \
@@ -227,6 +242,9 @@ dtb-$(CONFIG_ARCH_MMP) += \
pxa168-aspenite.dtb \
pxa910-dkb.dtb \
mmp2-brownstone.dtb
+dtb-$(CONFIG_MACH_MESON8B) += \
+ meson8b-mxq.dtb \
+ meson8b-odroidc1.dtb
dtb-$(CONFIG_ARCH_MOXART) += \
moxart-uc7112lx.dtb
dtb-$(CONFIG_SOC_IMX1) += \
@@ -258,7 +276,8 @@ dtb-$(CONFIG_SOC_IMX51) += \
imx51-apf51dev.dtb \
imx51-babbage.dtb \
imx51-digi-connectcore-jsk.dtb \
- imx51-eukrea-mbimxsd51-baseboard.dtb
+ imx51-eukrea-mbimxsd51-baseboard.dtb \
+ imx51-ts4800.dtb
dtb-$(CONFIG_SOC_IMX53) += \
imx53-ard.dtb \
imx53-m53evk.dtb \
@@ -284,6 +303,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-gw551x.dtb \
imx6dl-gw552x.dtb \
imx6dl-hummingboard.dtb \
+ imx6dl-nit6xlite.dtb \
imx6dl-nitrogen6x.dtb \
imx6dl-phytec-pbab01.dtb \
imx6dl-rex-basic.dtb \
@@ -313,6 +333,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-gw552x.dtb \
imx6q-hummingboard.dtb \
imx6q-nitrogen6x.dtb \
+ imx6q-nitrogen6_max.dtb \
+ imx6q-novena.dtb \
imx6q-phytec-pbab01.dtb \
imx6q-rex-pro.dtb \
imx6q-sabreauto.dtb \
@@ -338,6 +360,8 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
dtb-$(CONFIG_SOC_IMX6UL) += \
imx6ul-14x14-evk.dtb
dtb-$(CONFIG_SOC_IMX7D) += \
+ imx7d-cl-som-imx7.dtb \
+ imx7d-sbc-imx7.dtb \
imx7d-sdb.dtb
dtb-$(CONFIG_SOC_LS1021A) += \
ls1021a-qds.dtb \
@@ -347,6 +371,7 @@ dtb-$(CONFIG_SOC_VF610) += \
vf610-colibri-eval-v3.dtb \
vf610m4-colibri.dtb \
vf610-cosmic.dtb \
+ vf610m4-cosmic.dtb \
vf610-twr.dtb
dtb-$(CONFIG_ARCH_MXS) += \
imx23-evk.dtb \
@@ -440,19 +465,24 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
dtb-$(CONFIG_SOC_TI81XX) += \
dm8148-evm.dtb \
dm8148-t410.dtb \
- dm8168-evm.dtb
+ dm8168-evm.dtb \
+ dra62x-j5eco-evm.dtb
dtb-$(CONFIG_SOC_AM33XX) += \
am335x-baltos-ir5221.dtb \
am335x-base0033.dtb \
am335x-bone.dtb \
am335x-boneblack.dtb \
- am335x-sl50.dtb \
+ am335x-bonegreen.dtb \
+ am335x-chiliboard.dtb \
+ am335x-cm-t335.dtb \
am335x-evm.dtb \
am335x-evmsk.dtb \
+ am335x-lxm.dtb \
am335x-nano.dtb \
am335x-pepper.dtb \
- am335x-lxm.dtb \
- am335x-chiliboard.dtb \
+ am335x-shc.dtb \
+ am335x-sbc-t335.dtb \
+ am335x-sl50.dtb \
am335x-wega-rdk.dtb
dtb-$(CONFIG_ARCH_OMAP4) += \
omap4-duovero-parlor.dtb \
@@ -465,16 +495,21 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
omap4-var-stk-om44.dtb
dtb-$(CONFIG_SOC_AM43XX) += \
am43x-epos-evm.dtb \
- am437x-sk-evm.dtb \
+ am437x-cm-t43.dtb \
+ am437x-gp-evm.dtb \
am437x-idk-evm.dtb \
- am437x-gp-evm.dtb
+ am437x-sbc-t43.dtb \
+ am437x-sk-evm.dtb
dtb-$(CONFIG_SOC_OMAP5) += \
omap5-cm-t54.dtb \
+ omap5-igep0050.dtb \
omap5-sbc-t54.dtb \
omap5-uevm.dtb
dtb-$(CONFIG_SOC_DRA7XX) += \
- dra7-evm.dtb \
am57xx-beagle-x15.dtb \
+ am57xx-cl-som-am57x.dtb \
+ am57xx-sbc-am57x.dtb \
+ dra7-evm.dtb \
dra72-evm.dtb
dtb-$(CONFIG_ARCH_ORION5X) += \
orion5x-lacie-d2-network.dtb \
@@ -488,6 +523,7 @@ dtb-$(CONFIG_ARCH_PRIMA2) += \
dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8064-cm-qs600.dtb \
qcom-apq8064-ifc6410.dtb \
+ qcom-apq8064-sony-xperia-yuga.dtb \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
@@ -496,18 +532,27 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8960-cdp.dtb \
qcom-msm8974-sony-xperia-honami.dtb
dtb-$(CONFIG_ARCH_REALVIEW) += \
- arm-realview-pb1176.dtb
+ arm-realview-pb1176.dtb \
+ arm-realview-pb11mp.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+ rk3036-evb.dtb \
+ rk3036-kylin.dtb \
rk3066a-bqcurie2.dtb \
rk3066a-marsboard.dtb \
rk3066a-rayeager.dtb \
rk3188-radxarock.dtb \
+ rk3228-evb.dtb \
rk3288-evb-act8846.dtb \
rk3288-evb-rk808.dtb \
rk3288-firefly-beta.dtb \
rk3288-firefly.dtb \
+ rk3288-popmetal.dtb \
rk3288-r89.dtb \
+ rk3288-rock2-square.dtb \
+ rk3288-veyron-brain.dtb \
+ rk3288-veyron-jaq.dtb \
rk3288-veyron-jerry.dtb \
+ rk3288-veyron-mickey.dtb \
rk3288-veyron-minnie.dtb \
rk3288-veyron-pinky.dtb \
rk3288-veyron-speedy.dtb
@@ -522,9 +567,6 @@ dtb-$(CONFIG_ARCH_S5PV210) += \
s5pv210-smdkc110.dtb \
s5pv210-smdkv210.dtb \
s5pv210-torbreck.dtb
-dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
- r8a7778-bockw.dtb \
- r8a7778-bockw-reference.dtb
dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
emev2-kzm9d.dtb \
r7s72100-genmai.dtb \
@@ -533,8 +575,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
r8a7778-bockw.dtb \
r8a7779-marzen.dtb \
r8a7790-lager.dtb \
- r8a7791-henninger.dtb \
r8a7791-koelsch.dtb \
+ r8a7791-porter.dtb \
r8a7793-gose.dtb \
r8a7794-alt.dtb \
r8a7794-silk.dtb \
@@ -542,6 +584,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
dtb-$(CONFIG_ARCH_SOCFPGA) += \
socfpga_arria5_socdk.dtb \
socfpga_arria10_socdk_sdmmc.dtb \
+ socfpga_cyclone5_mcvevk.dtb \
socfpga_cyclone5_socdk.dtb \
socfpga_cyclone5_de0_sockit.dtb \
socfpga_cyclone5_sockit.dtb \
@@ -577,7 +620,9 @@ dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-gemei-g9.dtb \
sun4i-a10-hackberry.dtb \
sun4i-a10-hyundai-a7hd.dtb \
+ sun4i-a10-inet1.dtb \
sun4i-a10-inet97fv2.dtb \
+ sun4i-a10-inet9f-rev03.dtb \
sun4i-a10-itead-iteaduino-plus.dtb \
sun4i-a10-jesurun-q5.dtb \
sun4i-a10-marsboard.dtb \
@@ -585,16 +630,24 @@ dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-mk802.dtb \
sun4i-a10-mk802ii.dtb \
sun4i-a10-olinuxino-lime.dtb \
- sun4i-a10-pcduino.dtb
+ sun4i-a10-pcduino.dtb \
+ sun4i-a10-pcduino2.dtb \
+ sun4i-a10-pov-protab2-ips9.dtb
dtb-$(CONFIG_MACH_SUN5I) += \
+ sun5i-a10s-auxtek-t003.dtb \
sun5i-a10s-auxtek-t004.dtb \
sun5i-a10s-mk802.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a10s-r7-tv-dongle.dtb \
+ sun5i-a10s-wobo-i5.dtb \
+ sun5i-a13-empire-electronix-d709.dtb \
sun5i-a13-hsg-h702.dtb \
+ sun5i-a13-inet-98v-rev2.dtb \
sun5i-a13-olinuxino.dtb \
sun5i-a13-olinuxino-micro.dtb \
- sun5i-a13-utoo-p66.dtb
+ sun5i-a13-q8-tablet.dtb \
+ sun5i-a13-utoo-p66.dtb \
+ sun5i-r8-chip.dtb
dtb-$(CONFIG_MACH_SUN6I) += \
sun6i-a31-app4-evb1.dtb \
sun6i-a31-colombus.dtb \
@@ -602,7 +655,11 @@ dtb-$(CONFIG_MACH_SUN6I) += \
sun6i-a31-i7.dtb \
sun6i-a31-m9.dtb \
sun6i-a31-mele-a1000g-quad.dtb \
- sun6i-a31s-cs908.dtb
+ sun6i-a31s-cs908.dtb \
+ sun6i-a31s-primo81.dtb \
+ sun6i-a31s-sina31s.dtb \
+ sun6i-a31s-sinovoip-bpi-m2.dtb \
+ sun6i-a31s-yones-toptech-bs1078-v2.dtb
dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-bananapi.dtb \
sun7i-a20-bananapro.dtb \
@@ -610,8 +667,10 @@ dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-cubietruck.dtb \
sun7i-a20-hummingbird.dtb \
sun7i-a20-i12-tvbox.dtb \
+ sun7i-a20-icnova-swac.dtb \
sun7i-a20-m3.dtb \
sun7i-a20-mk808c.dtb \
+ sun7i-a20-olimex-som-evb.dtb \
sun7i-a20-olinuxino-lime.dtb \
sun7i-a20-olinuxino-lime2.dtb \
sun7i-a20-olinuxino-micro.dtb \
@@ -619,18 +678,25 @@ dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-orangepi-mini.dtb \
sun7i-a20-pcduino3.dtb \
sun7i-a20-pcduino3-nano.dtb \
- sun7i-a20-wexler-tab7200.dtb
+ sun7i-a20-wexler-tab7200.dtb \
+ sun7i-a20-wits-pro-a20-dkt.dtb
dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-a23-evb.dtb \
+ sun8i-a23-gt90h-v4.dtb \
sun8i-a23-ippo-q8h-v5.dtb \
sun8i-a23-ippo-q8h-v1.2.dtb \
+ sun8i-a23-q8-tablet.dtb \
sun8i-a33-et-q8-v1.6.dtb \
sun8i-a33-ga10h-v1.1.dtb \
sun8i-a33-ippo-q8h-v1.2.dtb \
- sun8i-a33-sinlinx-sina33.dtb
+ sun8i-a33-q8-tablet.dtb \
+ sun8i-a33-sinlinx-sina33.dtb \
+ sun8i-h3-orangepi-plus.dtb
dtb-$(CONFIG_MACH_SUN9I) += \
sun9i-a80-optimus.dtb \
sun9i-a80-cubieboard4.dtb
+dtb-$(CONFIG_ARCH_TANGO) += \
+ tango4-vantage-1172.dtb
dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
tegra20-harmony.dtb \
tegra20-iris-512.dtb \
@@ -672,7 +738,9 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
uniphier-ph1-ld6b-ref.dtb \
uniphier-ph1-pro4-ref.dtb \
uniphier-ph1-sld3-ref.dtb \
- uniphier-ph1-sld8-ref.dtb
+ uniphier-ph1-sld8-ref.dtb \
+ uniphier-proxstream2-gentil.dtb \
+ uniphier-proxstream2-vodka.dtb
dtb-$(CONFIG_ARCH_VERSATILE) += \
versatile-ab.dtb \
versatile-pb.dtb
@@ -702,6 +770,10 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
armada-370-netgear-rn102.dtb \
armada-370-netgear-rn104.dtb \
armada-370-rd.dtb \
+ armada-370-seagate-nas-2bay.dtb \
+ armada-370-seagate-nas-4bay.dtb \
+ armada-370-seagate-personal-cloud.dtb \
+ armada-370-seagate-personal-cloud-2bay.dtb \
armada-370-synology-ds213j.dtb
dtb-$(CONFIG_MACH_ARMADA_375) += \
armada-375-db.dtb
@@ -709,6 +781,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
armada-385-db-ap.dtb \
armada-385-linksys-caiman.dtb \
armada-385-linksys-cobra.dtb \
+ armada-388-clearfog.dtb \
armada-388-db.dtb \
armada-388-gp.dtb \
armada-388-rd.dtb
@@ -732,6 +805,7 @@ dtb-$(CONFIG_MACH_DOVE) += \
dove-dove-db.dtb \
dove-sbc-a510.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt2701-evb.dtb \
mt6580-evbp1.dtb \
mt6589-aquaris5.dtb \
mt6592-evb.dtb \
@@ -740,5 +814,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
endif
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+
always := $(dtb-y)
clean-files := *.dtb
diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
index 7d36601..ded1eb6 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
@@ -56,175 +56,171 @@
&am33xx_pinmux {
mmc2_pins: pinmux_mmc2_pins {
pinctrl-single,pins = <
- 0x020 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad8.mmc1_dat0_mux0 */
- 0x024 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad9.mmc1_dat1_mux0 */
- 0x028 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad10.mmc1_dat2_mux0 */
- 0x02c (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad11.mmc1_dat3_mux0 */
- 0x080 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk_mux0 */
- 0x084 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd_mux0 */
- 0x1e4 (PIN_INPUT_PULLUP | MUX_MODE7) /* emu0.gpio3[7] */
+ AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad8.mmc1_dat0_mux0 */
+ AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad9.mmc1_dat1_mux0 */
+ AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad10.mmc1_dat2_mux0 */
+ AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad11.mmc1_dat3_mux0 */
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk_mux0 */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd_mux0 */
+ AM33XX_IOPAD(0x9e4, PIN_INPUT_PULLUP | MUX_MODE7) /* emu0.gpio3[7] */
>;
};
wl12xx_gpio: pinmux_wl12xx_gpio {
pinctrl-single,pins = <
- 0x1e8 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* emu1.gpio3[8] */
+ AM33XX_IOPAD(0x9e8, PIN_OUTPUT_PULLUP | MUX_MODE7) /* emu1.gpio3[8] */
>;
};
tps65910_pins: pinmux_tps65910_pins {
pinctrl-single,pins = <
- 0x078 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_ben1.gpio1[28] */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_ben1.gpio1[28] */
>;
};
tca6416_pins: pinmux_tca6416_pins {
pinctrl-single,pins = <
- 0x1b4 (PIN_INPUT_PULLUP | MUX_MODE7) /* xdma_event_intr1.gpio0[20] tca6416 stuff */
+ AM33XX_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE7) /* xdma_event_intr1.gpio0[20] tca6416 stuff */
>;
};
i2c1_pins: pinmux_i2c1_pins {
pinctrl-single,pins = <
- 0x158 0x2a /* spi0_d1.i2c1_sda_mux3, INPUT | MODE2 */
- 0x15c 0x2a /* spi0_cs0.i2c1_scl_mux3, INPUT | MODE2 */
+ AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE2) /* spi0_d1.i2c1_sda_mux3 */
+ AM33XX_IOPAD(0x95c, PIN_INPUT | MUX_MODE2) /* spi0_cs0.i2c1_scl_mux3 */
>;
};
dcan1_pins: pinmux_dcan1_pins {
pinctrl-single,pins = <
- 0x168 0x0a /* uart0_ctsn.dcan1_tx_mux0, OUTPUT | MODE2 */
- 0x16c 0x2a /* uart0_rtsn.dcan1_rx_mux0, INPUT | MODE2 */
+ AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE2) /* uart0_ctsn.dcan1_tx_mux0 */
+ AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE2) /* uart0_rtsn.dcan1_rx_mux0 */
>;
};
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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
>;
};
uart1_pins: pinmux_uart1_pins {
pinctrl-single,pins = <
- 0x180 0x28 /* uart1_rxd, INPUT | MODE0 */
- 0x184 0x28 /* uart1_txd, INPUT | MODE0 */
- /*0x178 0x28*/ /* uart1_ctsn, INPUT | MODE0 */
- /*0x17c 0x08*/ /* uart1_rtsn, OUTPUT | MODE0 */
- 0x178 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* uart1_ctsn, INPUT | MODE0 */
- 0x17c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* uart1_rtsn, OUTPUT | MODE0 */
- 0x0e0 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.gpio2[22] DTR */
- 0x0e4 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_hsync.gpio2[23] DSR */
- 0x0e8 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.gpio2[24] DCD */
- 0x0ec (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_ac_bias_en.gpio2[25] RI */
+ AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE0) /* uart1_rxd */
+ AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE0) /* uart1_txd */
+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLDOWN | MUX_MODE7) /* uart1_ctsn, INPUT | MODE0 */
+ AM33XX_IOPAD(0x97c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* uart1_rtsn, OUTPUT | MODE0 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.gpio2[22] DTR */
+ AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_hsync.gpio2[23] DSR */
+ AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.gpio2[24] DCD */
+ AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_ac_bias_en.gpio2[25] RI */
>;
};
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
- 0x150 0x29 /* spi0_sclk.uart2_rxd_mux3, INPUT | MODE1 */
- 0x154 0x09 /* spi0_d0.uart2_txd_mux3, OUTPUT | MODE1 */
- /*0x188 0x2a*/ /* i2c0_sda.uart2_ctsn_mux0, INPUT | MODE2 */
- /*0x18c 0x2a*/ /* i2c0_scl.uart2_rtsn_mux0, INPUT | MODE2 */
- 0x188 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* i2c0_sda.uart2_ctsn_mux0 */
- 0x18c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* i2c0_scl.uart2_rtsn_mux0 */
- 0x030 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad12.gpio1[12] DTR */
- 0x034 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad13.gpio1[13] DSR */
- 0x038 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad14.gpio1[14] DCD */
- 0x03c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad15.gpio1[15] RI */
-
- 0x1a0 (PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3[18], INPUT_PULLDOWN | MODE7 */
+ AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd_mux3 */
+ AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd_mux3 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE7) /* i2c0_sda.uart2_ctsn_mux0 */
+ AM33XX_IOPAD(0x98c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* i2c0_scl.uart2_rtsn_mux0 */
+ AM33XX_IOPAD(0x830, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad12.gpio1[12] DTR */
+ AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad13.gpio1[13] DSR */
+ AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad14.gpio1[14] DCD */
+ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad15.gpio1[15] RI */
+
+ AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3[18], INPUT_PULLDOWN | MODE7 */
>;
};
cpsw_default: cpsw_default {
pinctrl-single,pins = <
/* Slave 1 */
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */
- 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_tx_en.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_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
- 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_ref_clk.rmii1_refclk */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_tx_en.rmii1_txen */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_ref_clk.rmii1_refclk */
/* 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 */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */
+ AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
>;
};
cpsw_sleep: cpsw_sleep {
pinctrl-single,pins = <
/* Slave 1 reset value */
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x114 (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)
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x944, 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)
+ AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x86c, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-base0033.dts b/arch/arm/boot/dts/am335x-base0033.dts
index 72a9b3f..58a05f7 100644
--- a/arch/arm/boot/dts/am335x-base0033.dts
+++ b/arch/arm/boot/dts/am335x-base0033.dts
@@ -46,39 +46,39 @@
&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 */
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */
+ AM33XX_IOPAD(0x8ec, 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 */
+ AM33XX_IOPAD(0x9b0, 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 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ AM33XX_IOPAD(0x888, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index fec7834..0cc150b 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -67,112 +67,112 @@
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 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
+ AM33XX_IOPAD(0x860, 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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
>;
};
i2c2_pins: pinmux_i2c2_pins {
pinctrl-single,pins = <
- 0x178 (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
- 0x17c (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
+ AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x9b4, 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 */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */
+ AM33XX_IOPAD(0x940, 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)
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
- 0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
+ AM33XX_IOPAD(0x960, 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 */
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
>;
};
};
@@ -383,8 +383,7 @@
bus-width = <0x4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
- cd-inverted;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&aes {
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index eadbba3..55c0e95 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -36,32 +36,32 @@
&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 */
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
>;
};
nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
pinctrl-single,pins = <
- 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-bonegreen.dts b/arch/arm/boot/dts/am335x-bonegreen.dts
new file mode 100644
index 0000000..dce3c86
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-bonegreen.dts
@@ -0,0 +1,53 @@
+/*
+ * 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 Green";
+ compatible = "ti,am335x-bone-green", "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 {
+ uart2_pins: uart2_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */
+ AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd */
+ >;
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "okay";
+};
+
+&rtc {
+ system-power-controller;
+};
diff --git a/arch/arm/boot/dts/am335x-chiliboard.dts b/arch/arm/boot/dts/am335x-chiliboard.dts
index 310da20..15d47ab 100644
--- a/arch/arm/boot/dts/am335x-chiliboard.dts
+++ b/arch/arm/boot/dts/am335x-chiliboard.dts
@@ -37,26 +37,26 @@
&am33xx_pinmux {
usb1_drvvbus: usb1_drvvbus {
pinctrl-single,pins = <
- 0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usb1_drvvbus.usb1_drvvbus */
+ AM33XX_IOPAD(0xa34, 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 */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM33XX_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM33XX_IOPAD(0x960, 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 */
+ AM33XX_IOPAD(0x9e4, PIN_OUTPUT | MUX_MODE7) /* emu0.gpio3_7 */
+ AM33XX_IOPAD(0x9e8, PIN_OUTPUT | MUX_MODE7) /* emu1.gpio3_8 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-chilisom.dtsi b/arch/arm/boot/dts/am335x-chilisom.dtsi
index 7e9a34d..857d989 100644
--- a/arch/arm/boot/dts/am335x-chilisom.dtsi
+++ b/arch/arm/boot/dts/am335x-chilisom.dtsi
@@ -29,81 +29,81 @@
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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ AM33XX_IOPAD(0x944, 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)
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x944, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
/* mdio_clk.mdio_clk */
- 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, 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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts
new file mode 100644
index 0000000..42e9b66
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-cm-t335.dts
@@ -0,0 +1,396 @@
+/*
+ * am335x-cm-t335.dts - Device Tree file for Compulab CM-T335
+ *
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.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.
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ model = "CompuLab CM-T335";
+ compatible = "compulab,cm-t335", "ti,am33xx";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x8000000>; /* 128 MB */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_led_pins>;
+ led@0 {
+ label = "cm_t335:green";
+ gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; /* gpio2_0 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ /* regulator for mmc */
+ vmmc_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&ecap0 0 50000 0>;
+ brightness-levels = <0 51 53 56 62 75 101 152 255>;
+ default-brightness-level = <8>;
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&bluetooth_pins>;
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* i2c0_scl.i2c0_scl */
+ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ /* uart0_ctsn.i2c1_sda */
+ AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE2)
+ /* uart0_rtsn.i2c1_scl */
+ AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE2)
+ >;
+ };
+
+ gpio_led_pins: pinmux_gpio_led_pins {
+ pinctrl-single,pins = <
+ /* gpmc_csn3.gpio2_0 */
+ AM33XX_IOPAD(0x888, PIN_OUTPUT | MUX_MODE7)
+ >;
+ };
+
+ nandflash_pins: pinmux_nandflash_pins {
+ pinctrl-single,pins = <
+ /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* gpmc_wpn.gpio0_30 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7)
+ /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)
+ /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)
+ /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)
+ /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)
+ /* gpmc_ben0_cle.gpmc_ben0_cle */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* uart0_txd.uart0_txd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ /* uart1_ctsn.uart1_ctsn */
+ AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0)
+ /* uart1_rtsn.uart1_rtsn */
+ AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* uart1_txd.uart1_txd */
+ AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+
+ ecap0_pins: pinmux_ecap0_pins {
+ pinctrl-single,pins = <
+ /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+ AM33XX_IOPAD(0x964, 0x0)
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ /* mii1_tx_en.rgmii1_tctl */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxdv.rgmii1_rctl */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_txd3.rgmii1_td3 */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_txd2.rgmii1_td2 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_txd1.rgmii1_td1 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_txd0.rgmii1_td0 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_txclk.rgmii1_tclk */
+ AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxclk.rgmii1_rclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxd3.rgmii1_rd3 */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxd2.rgmii1_rd2 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxd1.rgmii1_rd1 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ /* mii1_rxd0.rgmii1_rd0 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+ /* mdio_clk.mdio_clk */
+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* mmc0_clk.mmc0_clk */
+ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)
+ /* mmc0_cmd.mmc0_cmd */
+ AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ /* wl1271 bluetooth */
+ bluetooth_pins: pinmux_bluetooth_pins {
+ pinctrl-single,pins = <
+ /* XDMA_EVENT_INTR0.gpio0_19 - bluetooth enable */
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+};
+
+/* WLS1271 bluetooth */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+
+status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+ /* CM-T335 board EEPROM */
+ eeprom: 24c02@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+ /* Real Time Clock */
+ ext_rtc: em3027@56 {
+ compatible = "emmicro,em3027";
+ reg = <0x56>;
+ };
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&cppi41dma {
+ 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>;
+ ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */
+ nand@0,0 {
+ reg = <0 0 0>; /* CS0, offset 0 */
+ 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 */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "spl";
+ reg = <0x00000000 0x00200000>;
+ };
+ partition@1 {
+ label = "uboot";
+ reg = <0x00200000 0x00100000>;
+ };
+ partition@2 {
+ label = "uboot environment";
+ reg = <0x00300000 0x00100000>;
+ };
+ partition@3 {
+ label = "dtb";
+ reg = <0x00400000 0x00100000>;
+ };
+ partition@4 {
+ label = "splash";
+ reg = <0x00500000 0x00400000>;
+ };
+ partition@5 {
+ label = "linux";
+ reg = <0x00900000 0x00600000>;
+ };
+ partition@6 {
+ label = "rootfs";
+ reg = <0x00F00000 0>;
+ };
+ };
+};
+
+&elm {
+ status = "okay";
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ slaves = <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";
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmc_fixed>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+};
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 1942a5c..0d6a68c 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -83,14 +83,14 @@
label = "volume-up";
linux,code = <115>;
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
- gpio-key,wakeup;
+ wakeup-source;
};
switch@10 {
label = "volume-down";
linux,code = <114>;
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -168,215 +168,215 @@
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 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */
+ AM33XX_IOPAD(0x86c, 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 */
+ AM33XX_IOPAD(0x950, PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_sclk.gpio0_2 */
+ AM33XX_IOPAD(0x954, 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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ AM33XX_IOPAD(0x95c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
>;
};
uart1_pins: pinmux_uart1_pins {
pinctrl-single,pins = <
- 0x178 (PIN_INPUT | 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 */
+ AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */
+ AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
>;
};
clkout2_pin: pinmux_clkout2_pin {
pinctrl-single,pins = <
- 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ AM33XX_IOPAD(0x9b4, 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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, 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 */
+ AM33XX_IOPAD(0x964, MUX_MODE0) /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */
>;
};
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 */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ AM33XX_IOPAD(0x940, 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)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
- 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
>;
};
mmc3_pins: pinmux_mmc3_pins {
pinctrl-single,pins = <
- 0x44 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0, INPUT_PULLUP | MODE3 */
- 0x48 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1, INPUT_PULLUP | MODE3 */
- 0x4C (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2, INPUT_PULLUP | MODE3 */
- 0x78 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ben1.mmc2_dat3, INPUT_PULLUP | MODE3 */
- 0x88 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */
- 0x8C (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ben1.mmc2_dat3, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */
+ AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk, INPUT_PULLUP | MODE3 */
>;
};
wlan_pins: pinmux_wlan_pins {
pinctrl-single,pins = <
- 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 */
- 0x19C (PIN_INPUT | MUX_MODE7) /* mcasp0_ahclkr.gpio3_17 */
- 0x1AC (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahclkx.gpio3_21 */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 */
+ AM33XX_IOPAD(0x99c, PIN_INPUT | MUX_MODE7) /* mcasp0_ahclkr.gpio3_17 */
+ AM33XX_IOPAD(0x9ac, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahclkx.gpio3_21 */
>;
};
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 */
+ AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data23 */
+ AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data22 */
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data21 */
+ AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data20 */
+ AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data19 */
+ AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data18 */
+ AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data17 */
+ AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data16 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
>;
};
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 */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
>;
};
mcasp1_pins_sleep: mcasp1_pins_sleep {
pinctrl-single,pins = <
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
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 */
+ AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
+ AM33XX_IOPAD(0x96c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
>;
};
};
@@ -737,14 +737,14 @@
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&mmc3 {
/* these are on the crossbar and are outlined in the
xbar-event-map element */
- dmas = <&edma 12
- &edma 13>;
+ dmas = <&edma_xbar 12 0 1
+ &edma_xbar 13 0 2>;
dma-names = "tx", "rx";
status = "okay";
vmmc-supply = <&wlan_en_reg>;
@@ -766,11 +766,6 @@
};
};
-&edma {
- ti,edma-xbar-event-map = /bits/ 16 <1 12
- 2 13>;
-};
-
&sham {
status = "okay";
};
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index 315bb02..282fe1b 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -123,7 +123,7 @@
label = "button2";
linux,code = <0x102>;
gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
- gpio-key,wakeup;
+ wakeup-source;
};
switch@4 {
@@ -204,234 +204,234 @@
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 */
+ AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data23 */
+ AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data22 */
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data21 */
+ AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data20 */
+ AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data19 */
+ AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data18 */
+ AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data17 */
+ AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data16 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8ec, 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 */
+ AM33XX_IOPAD(0x820, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad8.lcd_data23 */
+ AM33XX_IOPAD(0x824, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad9.lcd_data22 */
+ AM33XX_IOPAD(0x828, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad10.lcd_data21 */
+ AM33XX_IOPAD(0x82c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad11.lcd_data20 */
+ AM33XX_IOPAD(0x830, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad12.lcd_data19 */
+ AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad13.lcd_data18 */
+ AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad14.lcd_data17 */
+ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad15.lcd_data16 */
+ AM33XX_IOPAD(0x8a0, PULL_DISABLE | MUX_MODE7) /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PULL_DISABLE | MUX_MODE7) /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PULL_DISABLE | MUX_MODE7) /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PULL_DISABLE | MUX_MODE7) /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PULL_DISABLE | MUX_MODE7) /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PULL_DISABLE | MUX_MODE7) /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PULL_DISABLE | MUX_MODE7) /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PULL_DISABLE | MUX_MODE7) /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PULL_DISABLE | MUX_MODE7) /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PULL_DISABLE | MUX_MODE7) /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PULL_DISABLE | MUX_MODE7) /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PULL_DISABLE | MUX_MODE7) /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PULL_DISABLE | MUX_MODE7) /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PULL_DISABLE | MUX_MODE7) /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PULL_DISABLE | MUX_MODE7) /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PULL_DISABLE | MUX_MODE7) /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8ec, 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 */
+ AM33XX_IOPAD(0x810, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
+ AM33XX_IOPAD(0x814, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
+ AM33XX_IOPAD(0x818, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
+ AM33XX_IOPAD(0x81c, 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 */
+ AM33XX_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_oen_ren.gpio2_3 */
+ AM33XX_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_advn_ale.gpio2_2 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.gpio0_30 */
+ AM33XX_IOPAD(0x89c, 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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x9b4, 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 */
+ AM33XX_IOPAD(0x99c, MUX_MODE4) /* mcasp0_ahclkr.ecap2_in_pwm2_out */
>;
};
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 */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ AM33XX_IOPAD(0x940, 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 */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rctl */
+ AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ AM33XX_IOPAD(0x86c, 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)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, 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)
+ AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x86c, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
- 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ AM33XX_IOPAD(0x960, 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 */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
>;
};
mcasp1_pins_sleep: mcasp1_pins_sleep {
pinctrl-single,pins = <
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
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 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM33XX_IOPAD(0x80c, 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 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
>;
};
};
@@ -647,7 +647,7 @@
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&sham {
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi
index c0e1135..54f1135 100644
--- a/arch/arm/boot/dts/am335x-igep0033.dtsi
+++ b/arch/arm/boot/dts/am335x-igep0033.dtsi
@@ -56,41 +56,41 @@
&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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-lxm.dts b/arch/arm/boot/dts/am335x-lxm.dts
index 5c5667a..d97b0ef 100644
--- a/arch/arm/boot/dts/am335x-lxm.dts
+++ b/arch/arm/boot/dts/am335x-lxm.dts
@@ -46,109 +46,109 @@
&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 */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0 */
+ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk */
+ AM33XX_IOPAD(0x904, 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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_int */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_crs_dv */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rxer */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_txen */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* rmii1_td0 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii1_rd0 */
+ AM33XX_IOPAD(0x944, 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 */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_txen */
+ AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td1 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td0 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd1 */
+ AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd0 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_crs_dv */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rxer */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_int */
+ AM33XX_IOPAD(0x908, 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 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_int */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_crs_dv */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rxer */
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_txen */
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td1 */
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td0 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd0 */
+ AM33XX_IOPAD(0x944, 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 */
+ AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_txen */
+ AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td1 */
+ AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td0 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd1 */
+ AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd0 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_crs_dv */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rxer */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_int */
+ AM33XX_IOPAD(0x908, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, 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)
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, 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 */
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ AM33XX_IOPAD(0x81c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts
index 5ed4ca6..f313999 100644
--- a/arch/arm/boot/dts/am335x-nano.dts
+++ b/arch/arm/boot/dts/am335x-nano.dts
@@ -41,121 +41,121 @@
misc_pins: misc_pins {
pinctrl-single,pins = <
- 0x15c (PIN_OUTPUT | MUX_MODE7) /* spi0_cs0.gpio0_5 */
+ AM33XX_IOPAD(0x95c, 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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad8.gpmc_ad8 */
+ AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad9.gpmc_ad9 */
+ AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad10.gpmc_ad10 */
+ AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad11.gpmc_ad11 */
+ AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad12.gpmc_ad12 */
+ AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad13.gpmc_ad13 */
+ AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad14.gpmc_ad14 */
+ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad15.gpmc_ad15 */
+
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x880, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn1.gpmc_csn1 */
+ AM33XX_IOPAD(0x884, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn2.gpmc_csn2 */
+ AM33XX_IOPAD(0x888, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn3.gpmc_csn3 */
+
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0_cle.gpmc_ben0_cle */
+
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE1) /* lcd_data1.gpmc_a1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE1) /* lcd_data2.gpmc_a2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE1) /* lcd_data3.gpmc_a3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE1) /* lcd_data4.gpmc_a4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE1) /* lcd_data5.gpmc_a5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE1) /* lcd_data6.gpmc_a6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE1) /* lcd_data7.gpmc_a7 */
+
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE1) /* lcd_vsync.gpmc_a8 */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE1) /* lcd_hsync.gpmc_a9 */
+ AM33XX_IOPAD(0x8e8, 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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE7) /* uart1_ctsn.uart1_ctsn */
+ AM33XX_IOPAD(0x97c, PIN_OUTPUT | MUX_MODE7) /* uart1_rtsn.uart1_rtsn */
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x984, 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 */
+ AM33XX_IOPAD(0x8c0, PIN_INPUT_PULLUP | MUX_MODE7) /* lcd_data8.gpio2[14] */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE7) /* lcd_data9.gpio2[15] */
+ AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */
+ AM33XX_IOPAD(0x954, 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 */
+ AM33XX_IOPAD(0x8c8, PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data10.uart3_ctsn */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE6) /* lcd_data11.uart3_rtsn */
+ AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE1) /* spi0_cs1.uart3_rxd */
+ AM33XX_IOPAD(0x964, 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 */
+ AM33XX_IOPAD(0x8d0, PIN_INPUT_PULLUP | MUX_MODE6) /* lcd_data12.uart4_ctsn */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE6) /* lcd_data13.uart4_rtsn */
+ AM33XX_IOPAD(0x968, PIN_INPUT | MUX_MODE1) /* uart0_ctsn.uart4_rxd */
+ AM33XX_IOPAD(0x96c, 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 */
+ AM33XX_IOPAD(0x8d8, PIN_INPUT | MUX_MODE4) /* lcd_data14.uart5_rxd */
+ AM33XX_IOPAD(0x944, 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] */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7) /* emu1.gpio3[8] */
+ AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3[18] */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-pepper.dts b/arch/arm/boot/dts/am335x-pepper.dts
index 7106114..8867aaa 100644
--- a/arch/arm/boot/dts/am335x-pepper.dts
+++ b/arch/arm/boot/dts/am335x-pepper.dts
@@ -93,14 +93,14 @@
&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 */
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, 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 */
+ AM33XX_IOPAD(0x90C, PIN_INPUT_PULLUP | MUX_MODE3) /* mii1_crs,i2c1_sda */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE3) /* mii1_rxerr,i2c1_scl */
>;
};
};
@@ -130,7 +130,7 @@
&am33xx_pinmux {
accel_pins: pinmux_accel {
pinctrl-single,pins = <
- 0x98 (PIN_INPUT | MUX_MODE7) /* gpmc_wen.gpio2_4 */
+ AM33XX_IOPAD(0x898, PIN_INPUT | MUX_MODE7) /* gpmc_wen.gpio2_4 */
>;
};
};
@@ -177,12 +177,12 @@
&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 */
+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+ AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
+ AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
+ AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */
+ AM33XX_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr1.mcasp0_axr1 */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE7) /* gpmc_a0.gpio1_16 */
>;
};
};
@@ -228,36 +228,36 @@
&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 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad8.lcd_data16 */
+ AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad9.lcd_data17 */
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad10.lcd_data18 */
+ AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad11.lcd_data19 */
+ AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad12.lcd_data20 */
+ AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad13.lcd_data21 */
+ AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad14.lcd_data22 */
+ AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1) /* gpmc_ad15.lcd_data23 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
/* Display Enable */
- 0x6c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a11.gpio1_27 */
+ AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a11.gpio1_27 */
>;
};
};
@@ -291,29 +291,29 @@
&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 */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd3.rgmii1_rxd3 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd2.rgmii1_rxd2 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd0 */
/* ethernet interrupt */
- 0x144 (PIN_INPUT_PULLUP | MUX_MODE7) /* rmii2_refclk.gpio0_29 */
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLUP | MUX_MODE7) /* rmii2_refclk.gpio0_29 */
/* ethernet PHY nReset */
- 0x108 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* mii1_col.gpio3_0 */
+ AM33XX_IOPAD(0x908, 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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
};
@@ -339,13 +339,6 @@
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";
@@ -354,8 +347,8 @@
vmmmc-supply = <&v3v3c_reg>;
bus-width = <4>;
ti,non-removable;
- dmas = <&edma 12
- &edma 13>;
+ dmas = <&edma_xbar 12 0 1
+ &edma_xbar 13 0 2>;
dma-names = "tx", "rx";
};
@@ -363,45 +356,45 @@
&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 */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM33XX_IOPAD(0x960, 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 */
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
/* EMMC nReset */
- 0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ AM33XX_IOPAD(0x874, 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 */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0 */
+ AM33XX_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1 */
+ AM33XX_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2 */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ben1.mmc2_dat3 */
+ AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */
+ AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc1_clk */
/* WLAN nReset */
- 0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */
+ AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */
/* WLAN nPower down */
- 0x70 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wait0.gpio0_30 */
+ AM33XX_IOPAD(0x870, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wait0.gpio0_30 */
/* 32kHz Clock */
- 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
+ AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
>;
};
};
@@ -497,10 +490,10 @@
&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 */
+ AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+ AM33XX_IOPAD(0x95C, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
>;
};
};
@@ -538,16 +531,16 @@
&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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, 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 */
+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */
+ AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
>;
};
};
@@ -590,9 +583,9 @@
usb_pins: pinmux_usb {
pinctrl-single,pins = <
/* USB0 Over-Current (active low) */
- 0x64 (PIN_INPUT | MUX_MODE7) /* gpmc_a9.gpio1_25 */
+ AM33XX_IOPAD(0x864, PIN_INPUT | MUX_MODE7) /* gpmc_a9.gpio1_25 */
/* USB1 Over-Current (active low) */
- 0x68 (PIN_INPUT | MUX_MODE7) /* gpmc_a10.gpio1_26 */
+ AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE7) /* gpmc_a10.gpio1_26 */
>;
};
};
@@ -627,37 +620,37 @@
label = "home";
linux,code = <KEY_HOME>;
gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
- gpio-key,wakeup;
+ wakeup-source;
};
button@1 {
label = "menu";
linux,code = <KEY_MENU>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
- gpio-key,wakeup;
+ wakeup-source;
};
buttons@2 {
label = "power";
linux,code = <KEY_POWER>;
gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
&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 */
+ AM33XX_IOPAD(0x850, PIN_OUTPUT | MUX_MODE7) /* gpmc_a4.gpio1_20 */
+ AM33XX_IOPAD(0x854, 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 */
+ AM33XX_IOPAD(0x858, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ AM33XX_IOPAD(0x85C, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a7.gpio1_21 */
+ AM33XX_IOPAD(0x964, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio0_7 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi
index 5dd084f..c20ae6c 100644
--- a/arch/arm/boot/dts/am335x-phycore-som.dtsi
+++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi
@@ -29,8 +29,17 @@
reg = <0x80000000 0x10000000>; /* 256 MB */
};
- vbat: fixedregulator@0 {
- compatible = "regulator-fixed";
+ regulators {
+ compatible = "simple-bus";
+
+ vcc5v: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
};
};
@@ -47,22 +56,22 @@
&am33xx_pinmux {
ethernet0_pins: pinmux_ethernet0 {
pinctrl-single,pins = <
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
- 0x114 (PIN_OUTPUT | MUX_MODE1) /* mii1_txen.rmii1_txen */
- 0x124 (PIN_OUTPUT | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
- 0x128 (PIN_OUTPUT | 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 */
+ AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT | MUX_MODE1) /* mii1_txen.rmii1_txen */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_refclk.rmii1_refclk */
>;
};
mdio_pins: pinmux_mdio {
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 */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
};
@@ -94,8 +103,8 @@
&am33xx_pinmux {
i2c0_pins: pinmux_i2c0 {
pinctrl-single,pins = <
- 0x188 (PIN_INPUT | MUX_MODE0) /* i2c0_sda.i2c0_sda */
- 0x18c (PIN_INPUT | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, PIN_INPUT | MUX_MODE0) /* i2c0_scl.i2c0_scl */
>;
};
};
@@ -128,20 +137,20 @@
&am33xx_pinmux {
nandflash_pins: pinmux_nandflash {
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 */
- 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 */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
>;
};
};
@@ -233,14 +242,14 @@
#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>;
+ vcc1-supply = <&vcc5v>;
+ vcc2-supply = <&vcc5v>;
+ vcc3-supply = <&vcc5v>;
+ vcc4-supply = <&vcc5v>;
+ vcc5-supply = <&vcc5v>;
+ vcc6-supply = <&vcc5v>;
+ vcc7-supply = <&vcc5v>;
+ vccio-supply = <&vcc5v>;
regulators {
vrtc_reg: regulator@0 {
@@ -311,21 +320,14 @@
};
};
-&vbat {
- regulator-name = "vbat";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-boot-on;
-};
-
/* SPI Busses */
&am33xx_pinmux {
spi0_pins: pinmux_spi0 {
pinctrl-single,pins = <
- 0x150 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* spi0_clk.spi0_clk */
- 0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* spi0_d0.spi0_d0 */
- 0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
- 0x15c (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ AM33XX_IOPAD(0x950, PIN_INPUT_PULLDOWN | MUX_MODE0) /* spi0_clk.spi0_clk */
+ AM33XX_IOPAD(0x954, PIN_INPUT_PULLDOWN | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
>;
};
};
diff --git a/arch/arm/boot/dts/am335x-sbc-t335.dts b/arch/arm/boot/dts/am335x-sbc-t335.dts
new file mode 100644
index 0000000..917d7cc
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-sbc-t335.dts
@@ -0,0 +1,219 @@
+/*
+ * am335x-sbc-t335.dts - Device Tree file for Compulab SBC-T335
+ *
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.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 "am335x-cm-t335.dts"
+
+/ {
+ model = "CompuLab CM-T335 on SB-T335";
+ compatible = "compulab,sbc-t335", "compulab,cm-t335", "ti,am33xx";
+
+ /* DRM display driver */
+ panel {
+ compatible = "ti,tilcdc,panel";
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&lcd_pins_default>;
+ pinctrl-1 = <&lcd_pins_sleep>;
+
+ 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 {
+ /* Timing selection performed by U-Boot */
+ timing0: lcd {/* 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>;
+ };
+ timing1: dvi { /* 1024x768p60 */
+ clock-frequency = <65000000>;
+ hactive = <1024>;
+ hfront-porch = <24>;
+ hback-porch = <160>;
+ hsync-len = <136>;
+ vactive = <768>;
+ vfront-porch = <3>;
+ vback-porch = <29>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+ };
+};
+
+&am33xx_pinmux {
+ /* Display */
+ lcd_pins_default: lcd_pins_default {
+ pinctrl-single,pins = <
+ /* gpmc_ad8.lcd_data23 */
+ AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad9.lcd_data22 */
+ AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad10.lcd_data21 */
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad11.lcd_data20 */
+ AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad12.lcd_data19 */
+ AM33XX_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad13.lcd_data18 */
+ AM33XX_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad14.lcd_data17 */
+ AM33XX_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)
+ /* gpmc_ad15.lcd_data16 */
+ AM33XX_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1)
+ /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0)
+ /* lcd_ac_bias_en.lcd_ac_bias_en */
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };
+
+ lcd_pins_sleep: lcd_pins_sleep {
+ pinctrl-single,pins = <
+ /* gpmc_ad8.lcd_data23 */
+ AM33XX_IOPAD(0x820, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad9.lcd_data22 */
+ AM33XX_IOPAD(0x824, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad10.lcd_data21 */
+ AM33XX_IOPAD(0x828, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad11.lcd_data20 */
+ AM33XX_IOPAD(0x82c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad12.lcd_data19 */
+ AM33XX_IOPAD(0x830, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad13.lcd_data18 */
+ AM33XX_IOPAD(0x834, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad14.lcd_data17 */
+ AM33XX_IOPAD(0x838, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* gpmc_ad15.lcd_data16 */
+ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* lcd_data0.lcd_data0 */
+ AM33XX_IOPAD(0x8a0, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data1.lcd_data1 */
+ AM33XX_IOPAD(0x8a4, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data2.lcd_data2 */
+ AM33XX_IOPAD(0x8a8, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data3.lcd_data3 */
+ AM33XX_IOPAD(0x8ac, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data4.lcd_data4 */
+ AM33XX_IOPAD(0x8b0, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data5.lcd_data5 */
+ AM33XX_IOPAD(0x8b4, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data6.lcd_data6 */
+ AM33XX_IOPAD(0x8b8, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data7.lcd_data7 */
+ AM33XX_IOPAD(0x8bc, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data8.lcd_data8 */
+ AM33XX_IOPAD(0x8c0, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data9.lcd_data9 */
+ AM33XX_IOPAD(0x8c4, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data10.lcd_data10 */
+ AM33XX_IOPAD(0x8c8, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data11.lcd_data11 */
+ AM33XX_IOPAD(0x8cc, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data12.lcd_data12 */
+ AM33XX_IOPAD(0x8d0, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data13.lcd_data13 */
+ AM33XX_IOPAD(0x8d4, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data14.lcd_data14 */
+ AM33XX_IOPAD(0x8d8, PULL_DISABLE | MUX_MODE7)
+ /* lcd_data15.lcd_data15 */
+ AM33XX_IOPAD(0x8dc, PULL_DISABLE | MUX_MODE7)
+ /* lcd_vsync.lcd_vsync */
+ AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* lcd_hsync.lcd_hsync */
+ AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* lcd_pclk.lcd_pclk */
+ AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ /* lcd_ac_bias_en.lcd_ac_bias_en */
+ AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+};
+
+&i2c0 {
+ /* GPIO extender */
+ gpio_ext: pca9555@26 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x26>;
+ dvi_ena {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "dvi-enable";
+ };
+ lcd_ena {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "lcd-enable";
+ };
+ };
+};
+
+/* Display */
+&lcdc {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-shc.dts b/arch/arm/boot/dts/am335x-shc.dts
new file mode 100644
index 0000000..865de85
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-shc.dts
@@ -0,0 +1,577 @@
+/*
+ * support for the bosch am335x based shc c3 board
+ *
+ * Copyright, C) 2015 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 "am33xx.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Bosch SHC";
+ compatible = "ti,am335x-shc", "ti,am335x-bone", "ti,am33xx";
+
+ aliases {
+ mmcblk0 = &mmc1;
+ mmcblk1 = &mmc2;
+ };
+
+ cpus {
+ cpu@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 */
+ 594000 1225000
+ 294000 1125000
+ >;
+ voltage-tolerance = <2>; /* 2 percentage */
+ cpu0-supply = <&dcdc2_reg>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ back_button {
+ label = "Back Button";
+ gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_BACK>;
+ debounce-interval = <1000>;
+ wakeup-source;
+ };
+
+ front_button {
+ label = "Front Button";
+ gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_FRONT>;
+ debounce-interval = <1000>;
+ wakeup-source;
+ };
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ compatible = "gpio-leds";
+
+ led@1 {
+ label = "shc:power:red";
+ gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "shc:power:bl";
+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "timer";
+ default-state = "on";
+ };
+
+ led@3 {
+ label = "shc:lan:red";
+ gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "shc:lan:bl";
+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@5 {
+ label = "shc:cloud:red";
+ gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@6 {
+ label = "shc:cloud:bl";
+ gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&aes {
+ status = "okay";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+
+ ethernetphy0: ethernet-phy@0 {
+ reg = <0>;
+ smsc,disable-energy-detect;
+ };
+};
+
+&epwmss1 {
+ status = "okay";
+
+ ehrpwm1: ehrpwm@48302200 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ehrpwm1_pins>;
+ status = "okay";
+ };
+};
+
+&gpio1 {
+ hmtc_rst {
+ gpio-hog;
+ gpios = <24 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "homematic_reset";
+ };
+
+ hmtc_prog {
+ gpio-hog;
+ gpios = <27 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "homematic_program";
+ };
+};
+
+&gpio3 {
+ zgb_rst {
+ gpio-hog;
+ gpios = <18 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "zigbee_reset";
+ };
+
+ zgb_boot {
+ gpio-hog;
+ gpios = <19 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "zigbee_boot";
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ at24@50 {
+ compatible = "at24,24c32";
+ pagesize = <32>;
+ reg = <0x50>;
+ };
+
+ pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+ slaves = <1>;
+ cpsw_emac0: slave@4a100200 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "mii";
+ phy-handle = <&ethernetphy0>;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ bus-width = <0x4>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ max-frequency = <26000000>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ bus-width = <8>;
+ max-frequency = <26000000>;
+ sd-uhs-sdr25;
+ vmmc-supply = <&vmmcsd_fixed>;
+ status = "okay";
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins>;
+ bus-width = <4>;
+ cap-power-off-card;
+ max-frequency = <26000000>;
+ sd-uhs-sdr25;
+ vmmc-supply = <&vmmcsd_fixed>;
+ status = "okay";
+};
+
+&rtc {
+ ti,no-init;
+};
+
+&sham {
+ status = "okay";
+};
+
+&tps {
+ compatible = "ti,tps65217";
+ ti,pmic-shutdown-controller;
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dcdc1_reg: regulator@0 {
+ reg = <0>;
+ regulator-name = "vdds_dpr";
+ regulator-compatible = "dcdc1";
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@1 {
+ reg = <1>;
+ /*
+ * VDD_MPU voltage limits 0.95V - 1.26V with
+ * +/-4% tolerance
+ */
+ regulator-compatible = "dcdc2";
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <70000>;
+ };
+
+ dcdc3_reg: regulator@2 {
+ reg = <2>;
+ /*
+ * VDD_CORE voltage limits 0.95V - 1.1V with
+ * +/-4% tolerance
+ */
+ regulator-name = "vdd_core";
+ regulator-compatible = "dcdc3";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1125000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ reg = <3>;
+ regulator-name = "vio,vrtc,vdds";
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ reg = <4>;
+ regulator-name = "vdd_3v3aux";
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ reg = <5>;
+ regulator-name = "vdd_1v8";
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ reg = <6>;
+ regulator-name = "vdd_3v3a";
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&clkout2_pin>;
+
+ clkout2_pin: pinmux_clkout2_pin {
+ pinctrl-single,pins = <
+ /* xdma_event_intr1.clkout2 */
+ AM33XX_IOPAD(0x9b4, PIN_INPUT | MUX_MODE6)
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)
+ /* mdio_clk.mdio_clk */
+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ ehrpwm1_pins: pinmux_ehrpwm1 {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE6) /* gpmc_a3.gpio1_19 */
+ >;
+ };
+
+ emmc_pins: pinmux_emmc_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x880, PIN_INPUT | MUX_MODE2)
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1)
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x988, PIN_INPUT | MUX_MODE0)
+ AM33XX_IOPAD(0x98c, PIN_INPUT | MUX_MODE0)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE5)
+ >;
+ };
+
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x830, PIN_INPUT | MUX_MODE3)
+ AM33XX_IOPAD(0x834, PIN_INPUT | MUX_MODE3)
+ AM33XX_IOPAD(0x838, PIN_INPUT | MUX_MODE3)
+ AM33XX_IOPAD(0x83c, PIN_INPUT | MUX_MODE3)
+ AM33XX_IOPAD(0x888, PIN_INPUT | MUX_MODE3)
+ AM33XX_IOPAD(0x88c, PIN_INPUT | MUX_MODE3)
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x968, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x96c, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x974, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };
+
+ uart1_pins: pinmux_uart1 {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_IOPAD(0x97C, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE0)
+ AM33XX_IOPAD(0x984, PIN_OUTPUT | MUX_MODE0)
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)
+ AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)
+ >;
+ };
+
+ uart4_pins: pinmux_uart4_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE6)
+ AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE6)
+ >;
+ };
+
+ user_leds_s0: user_leds_s0 {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x820, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x824, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x844, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x858, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_IOPAD(0x860, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x864, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x86c, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x878, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_IOPAD(0x87c, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x894, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x958, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x95c, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x964, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_IOPAD(0x9a0, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x9a4, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi
index 5e541bd..282f6d4 100644
--- a/arch/arm/boot/dts/am335x-wega.dtsi
+++ b/arch/arm/boot/dts/am335x-wega.dtsi
@@ -11,14 +11,25 @@
model = "Phytec AM335x phyBOARD-WEGA";
compatible = "phytec,am335x-wega", "phytec,am335x-phycore-som", "ti,am33xx";
+ regulators {
+ compatible = "simple-bus";
+
+ vcc3v3: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+ };
};
/* CAN Busses */
&am33xx_pinmux {
dcan1_pins: pinmux_dcan1 {
pinctrl-single,pins = <
- 0x168 (PIN_OUTPUT_PULLUP | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
- 0x16c (PIN_INPUT_PULLUP | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
+ AM33XX_IOPAD(0x968, PIN_OUTPUT_PULLUP | MUX_MODE2) /* uart0_ctsn.d_can1_tx */
+ AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE2) /* uart0_rtsn.d_can1_rx */
>;
};
};
@@ -33,20 +44,20 @@
&am33xx_pinmux {
ethernet1_pins: pinmux_ethernet1 {
pinctrl-single,pins = <
- 0x40 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a0.mii2_txen */
- 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a1.mii2_rxdv */
- 0x48 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a2.mii2_txd3 */
- 0x4c (PIN_OUTPUT | MUX_MODE1) /* gpmc_a3.mii2_txd2 */
- 0x50 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a4.mii2_txd1 */
- 0x54 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a5.mii2_txd0 */
- 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a6.mii2_txclk */
- 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a7.mii2_rxclk */
- 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a8.mii2_rxd3 */
- 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a9.mii2_rxd2 */
- 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a10.mii2_rxd1 */
- 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a11.mii2_rxd0 */
- 0x74 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_wpn.mii2_rxerr */
- 0x78 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_ben1.mii2_col */
+ AM33XX_IOPAD(0x840, PIN_OUTPUT | MUX_MODE1) /* gpmc_a0.mii2_txen */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a1.mii2_rxdv */
+ AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE1) /* gpmc_a2.mii2_txd3 */
+ AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE1) /* gpmc_a3.mii2_txd2 */
+ AM33XX_IOPAD(0x850, PIN_OUTPUT | MUX_MODE1) /* gpmc_a4.mii2_txd1 */
+ AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE1) /* gpmc_a5.mii2_txd0 */
+ AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a6.mii2_txclk */
+ AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a7.mii2_rxclk */
+ AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a8.mii2_rxd3 */
+ AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a9.mii2_rxd2 */
+ AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a10.mii2_rxd1 */
+ AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_a11.mii2_rxd0 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_wpn.mii2_rxerr */
+ AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE1) /* gpmc_ben1.mii2_col */
>;
};
};
@@ -68,19 +79,19 @@
&am33xx_pinmux {
mmc1_pins: pinmux_mmc1 {
pinctrl-single,pins = <
- 0x0F0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
- 0x0F4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
- 0x0F8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
- 0x0FC (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
- 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
- 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
- 0x160 (PIN_INPUT_PULLUP | MUX_MODE7) /* spi0_cs1.mmc0_sdcd */
+ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE7) /* spi0_cs1.mmc0_sdcd */
>;
};
};
&mmc1 {
- vmmc-supply = <&vmmc_reg>;
+ vmmc-supply = <&vcc3v3>;
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
@@ -92,17 +103,17 @@
&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 */
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
>;
};
uart1_pins: pinmux_uart1_pins {
pinctrl-single,pins = <
- 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
- 0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
- 0x178 (PIN_INPUT | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */
- 0x17c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+ AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */
+ AM33XX_IOPAD(0x97c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */
>;
};
};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index d23e252..1fafaad 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -161,6 +161,14 @@
mboxes = <&mailbox &mbox_wkupm3>;
};
+ edma_xbar: dma-router@f90 {
+ compatible = "ti,am335x-edma-crossbar";
+ reg = <0xf90 0x40>;
+ #dma-cells = <3>;
+ dma-requests = <32>;
+ dma-masters = <&edma>;
+ };
+
scm_clockdomains: clockdomains {
};
};
@@ -174,12 +182,44 @@
};
edma: edma@49000000 {
- compatible = "ti,edma3";
- ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
- reg = <0x49000000 0x10000>,
- <0x44e10f90 0x40>;
+ compatible = "ti,edma3-tpcc";
+ ti,hwmods = "tpcc";
+ reg = <0x49000000 0x10000>;
+ reg-names = "edma3_cc";
interrupts = <12 13 14>;
- #dma-cells = <1>;
+ interrupt-names = "edma3_ccint", "emda3_mperr",
+ "edma3_ccerrint";
+ dma-requests = <64>;
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+ <&edma_tptc2 0>;
+
+ ti,edma-memcpy-channels = <20 21>;
+ };
+
+ edma_tptc0: tptc@49800000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc0";
+ reg = <0x49800000 0x100000>;
+ interrupts = <112>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc1: tptc@49900000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc1";
+ reg = <0x49900000 0x100000>;
+ interrupts = <113>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc2: tptc@49a00000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc2";
+ reg = <0x49a00000 0x100000>;
+ interrupts = <114>;
+ interrupt-names = "edma3_tcerrint";
};
gpio0: gpio@44e07000 {
@@ -233,7 +273,7 @@
reg = <0x44e09000 0x2000>;
interrupts = <72>;
status = "disabled";
- dmas = <&edma 26>, <&edma 27>;
+ dmas = <&edma 26 0>, <&edma 27 0>;
dma-names = "tx", "rx";
};
@@ -244,7 +284,7 @@
reg = <0x48022000 0x2000>;
interrupts = <73>;
status = "disabled";
- dmas = <&edma 28>, <&edma 29>;
+ dmas = <&edma 28 0>, <&edma 29 0>;
dma-names = "tx", "rx";
};
@@ -255,7 +295,7 @@
reg = <0x48024000 0x2000>;
interrupts = <74>;
status = "disabled";
- dmas = <&edma 30>, <&edma 31>;
+ dmas = <&edma 30 0>, <&edma 31 0>;
dma-names = "tx", "rx";
};
@@ -322,8 +362,8 @@
ti,dual-volt;
ti,needs-special-reset;
ti,needs-special-hs-handling;
- dmas = <&edma 24
- &edma 25>;
+ dmas = <&edma_xbar 24 0 0
+ &edma_xbar 25 0 0>;
dma-names = "tx", "rx";
interrupts = <64>;
interrupt-parent = <&intc>;
@@ -335,8 +375,8 @@
compatible = "ti,omap4-hsmmc";
ti,hwmods = "mmc2";
ti,needs-special-reset;
- dmas = <&edma 2
- &edma 3>;
+ dmas = <&edma 2 0
+ &edma 3 0>;
dma-names = "tx", "rx";
interrupts = <28>;
interrupt-parent = <&intc>;
@@ -399,6 +439,7 @@
ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <8>;
mbox_wkupm3: wkup_m3 {
+ ti,mbox-send-noirq;
ti,mbox-tx = <0 0 0>;
ti,mbox-rx = <0 0 3>;
};
@@ -474,10 +515,10 @@
interrupts = <65>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi0";
- dmas = <&edma 16
- &edma 17
- &edma 18
- &edma 19>;
+ dmas = <&edma 16 0
+ &edma 17 0
+ &edma 18 0
+ &edma 19 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
@@ -490,10 +531,10 @@
interrupts = <125>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi1";
- dmas = <&edma 42
- &edma 43
- &edma 44
- &edma 45>;
+ dmas = <&edma 42 0
+ &edma 43 0
+ &edma 44 0
+ &edma 45 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
@@ -819,6 +860,8 @@
ti,no-idle-on-init;
reg = <0x50000000 0x2000>;
interrupts = <100>;
+ dmas = <&edma 52>;
+ dma-names = "rxtx";
gpmc,num-cs = <7>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
@@ -831,7 +874,7 @@
ti,hwmods = "sham";
reg = <0x53100000 0x200>;
interrupts = <109>;
- dmas = <&edma 36>;
+ dmas = <&edma 36 0>;
dma-names = "rx";
};
@@ -840,8 +883,8 @@
ti,hwmods = "aes";
reg = <0x53500000 0xa0>;
interrupts = <103>;
- dmas = <&edma 6>,
- <&edma 5>;
+ dmas = <&edma 6 0>,
+ <&edma 5 0>;
dma-names = "tx", "rx";
};
@@ -854,8 +897,8 @@
interrupts = <80>, <81>;
interrupt-names = "tx", "rx";
status = "disabled";
- dmas = <&edma 8>,
- <&edma 9>;
+ dmas = <&edma 8 2>,
+ <&edma 9 2>;
dma-names = "tx", "rx";
};
@@ -868,8 +911,8 @@
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
status = "disabled";
- dmas = <&edma 10>,
- <&edma 11>;
+ dmas = <&edma 10 2>,
+ <&edma 11 2>;
dma-names = "tx", "rx";
};
diff --git a/arch/arm/boot/dts/am3517-craneboard.dts b/arch/arm/boot/dts/am3517-craneboard.dts
index 2d40b3f..cb7de1d 100644
--- a/arch/arm/boot/dts/am3517-craneboard.dts
+++ b/arch/arm/boot/dts/am3517-craneboard.dts
@@ -77,7 +77,7 @@
&omap3_pmx_core {
tps_pins: pinmux_tps_pins {
pinctrl-single,pins = <
- 0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
+ OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
>;
};
};
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 0447c04a..92068fb 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -30,6 +30,7 @@
serial5 = &uart5;
ethernet0 = &cpsw_emac0;
ethernet1 = &cpsw_emac1;
+ spi0 = &qspi;
};
cpus {
@@ -72,17 +73,17 @@
global_timer: timer@48240200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x48240200 0x100>;
- interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gic>;
- clocks = <&dpll_mpu_m2_ck>;
+ clocks = <&mpu_periphclk>;
};
local_timer: timer@48240600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x48240600 0x100>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gic>;
- clocks = <&dpll_mpu_m2_ck>;
+ clocks = <&mpu_periphclk>;
};
l2-cache-controller@48242000 {
@@ -171,6 +172,14 @@
mboxes = <&mailbox &mbox_wkupm3>;
};
+ edma_xbar: dma-router@f90 {
+ compatible = "ti,am335x-edma-crossbar";
+ reg = <0xf90 0x40>;
+ #dma-cells = <3>;
+ dma-requests = <64>;
+ dma-masters = <&edma>;
+ };
+
scm_clockdomains: clockdomains {
};
};
@@ -183,14 +192,46 @@
};
edma: edma@49000000 {
- compatible = "ti,edma3";
- ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
- reg = <0x49000000 0x10000>,
- <0x44e10f90 0x10>;
+ compatible = "ti,edma3-tpcc";
+ ti,hwmods = "tpcc";
+ reg = <0x49000000 0x10000>;
+ reg-names = "edma3_cc";
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>;
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma3_ccint", "emda3_mperr",
+ "edma3_ccerrint";
+ dma-requests = <64>;
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+ <&edma_tptc2 0>;
+
+ ti,edma-memcpy-channels = <32 33>;
+ };
+
+ edma_tptc0: tptc@49800000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc0";
+ reg = <0x49800000 0x100000>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc1: tptc@49900000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc1";
+ reg = <0x49900000 0x100000>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc2: tptc@49a00000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc2";
+ reg = <0x49a00000 0x100000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma3_tcerrint";
};
uart0: serial@44e09000 {
@@ -249,6 +290,7 @@
ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <8>;
mbox_wkupm3: wkup_m3 {
+ ti,mbox-send-noirq;
ti,mbox-tx = <0 0 0>;
ti,mbox-rx = <0 0 3>;
};
@@ -495,8 +537,8 @@
ti,hwmods = "mmc1";
ti,dual-volt;
ti,needs-special-reset;
- dmas = <&edma 24
- &edma 25>;
+ dmas = <&edma 24 0>,
+ <&edma 25 0>;
dma-names = "tx", "rx";
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -507,8 +549,8 @@
reg = <0x481d8000 0x1000>;
ti,hwmods = "mmc2";
ti,needs-special-reset;
- dmas = <&edma 2
- &edma 3>;
+ dmas = <&edma 2 0>,
+ <&edma 3 0>;
dma-names = "tx", "rx";
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -591,6 +633,7 @@
cpts_clock_mult = <0x80000000>;
cpts_clock_shift = <29>;
ranges;
+ syscon = <&scm_conf>;
davinci_mdio: mdio@4a101000 {
compatible = "ti,am4372-mdio","ti,davinci_mdio";
@@ -775,7 +818,7 @@
compatible = "ti,omap5-sham";
ti,hwmods = "sham";
reg = <0x53100000 0x300>;
- dmas = <&edma 36>;
+ dmas = <&edma 36 0>;
dma-names = "rx";
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -785,8 +828,8 @@
ti,hwmods = "aes";
reg = <0x53501000 0xa0>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&edma 6
- &edma 5>;
+ dmas = <&edma 6 0>,
+ <&edma 5 0>;
dma-names = "tx", "rx";
};
@@ -795,8 +838,8 @@
ti,hwmods = "des";
reg = <0x53701000 0xa0>;
interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&edma 34
- &edma 33>;
+ dmas = <&edma 34 0>,
+ <&edma 33 0>;
dma-names = "tx", "rx";
};
@@ -809,8 +852,8 @@
interrupts = <80>, <81>;
interrupt-names = "tx", "rx";
status = "disabled";
- dmas = <&edma 8>,
- <&edma 9>;
+ dmas = <&edma 8 2>,
+ <&edma 9 2>;
dma-names = "tx", "rx";
};
@@ -823,8 +866,8 @@
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
status = "disabled";
- dmas = <&edma 10>,
- <&edma 11>;
+ dmas = <&edma 10 2>,
+ <&edma 11 2>;
dma-names = "tx", "rx";
};
@@ -841,6 +884,8 @@
gpmc: gpmc@50000000 {
compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
+ dmas = <&edma 52>;
+ dma-names = "rxtx";
clocks = <&l3s_gclk>;
clock-names = "fck";
reg = <0x50000000 0x2000>;
@@ -962,7 +1007,9 @@
qspi: qspi@47900000 {
compatible = "ti,am4372-qspi";
- reg = <0x47900000 0x100>;
+ reg = <0x47900000 0x100>,
+ <0x30000000 0x4000000>;
+ reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
diff --git a/arch/arm/boot/dts/am437x-cm-t43.dts b/arch/arm/boot/dts/am437x-cm-t43.dts
new file mode 100644
index 0000000..8677f4c
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-cm-t43.dts
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "am4372.dtsi"
+
+/ {
+ model = "CompuLab CM-T43";
+ compatible = "compulab,am437x-cm-t43", "ti,am4372", "ti,am43";
+
+ leds {
+ compatible = "gpio-leds";
+
+ ledb {
+ label = "cm-t43:green";
+ gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vmmc_3v3: fixedregulator-v3_3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ enable-active-high;
+ };
+};
+
+&am43xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cm_t43_led_pins>;
+
+ cm_t43_led_pins: cm_t43_led_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0xa78, MUX_MODE7)
+ >;
+ };
+
+ i2c0_pins: i2c0_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM4372_IOPAD(0x98c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ emmc_pins: emmc_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad8.mmc1_dat0 */
+ AM4372_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad9.mmc1_dat1 */
+ AM4372_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad10.mmc1_dat2 */
+ AM4372_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad11.mmc1_dat3 */
+ AM4372_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad12.mmc1_dat4 */
+ AM4372_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad13.mmc1_dat5 */
+ AM4372_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad14.mmc1_dat6 */
+ AM4372_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_ad15.mmc1_dat7 */
+ AM4372_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM4372_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ >;
+ };
+
+ spi0_pins: pinmux_spi0_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x950, PIN_INPUT | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+ AM4372_IOPAD(0x954, PIN_INPUT | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ AM4372_IOPAD(0x958, PIN_OUTPUT | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ AM4372_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ >;
+ };
+
+ nand_flash_x8: nand_flash_x8 {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x800, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x804, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x808, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x80c, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x810, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x814, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x818, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x81c, PIN_INPUT | PULL_DISABLE | MUX_MODE0)
+ AM4372_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x898, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM4372_IOPAD(0x894, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM4372_IOPAD(0x890, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM4372_IOPAD(0x89c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_txen */
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rxctl */
+ AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd3 */
+ AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd2 */
+ AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd1 */
+ AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd0 */
+ AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd3 */
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd2 */
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd0 */
+ AM4372_IOPAD(0xa74, MUX_MODE3)
+ /* Slave 2 */
+ AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.txen */
+ AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rxctl */
+ AM4372_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.txd3 */
+ AM4372_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.txd2 */
+ AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.txd1 */
+ AM4372_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.txd0 */
+ AM4372_IOPAD(0x858, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.tclk */
+ AM4372_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rclk */
+ AM4372_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rxd3 */
+ AM4372_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rxd2 */
+ AM4372_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rxd1 */
+ AM4372_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rxd0 */
+ AM4372_IOPAD(0xa38, MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM4372_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_flash_x8>;
+ ranges = <0 0 0x08000000 0x1000000>;
+ nand@0,0 {
+ reg = <0 0 0>;
+ 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>;
+
+ gpmc,wait-pin = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* MTD partition table */
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x00980000>;
+ };
+ partition@980000 {
+ label = "dtb";
+ reg = <0x00980000 0x00080000>;
+ };
+ partition@a00000 {
+ label = "rootfs";
+ reg = <0x00a00000 0x0>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+
+ tps65218: tps65218@24 {
+ compatible = "ti,tps65218";
+ reg = <0x24>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
+ interrupt-parent = <&gic>;
+ 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-suspend-enable;
+ 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>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc6: regulator-dcdc6 {
+ compatible = "ti,tps65218-dcdc6";
+ regulator-name = "v1_8bat";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: regulator-ldo1 {
+ compatible = "ti,tps65218-ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+
+ eeprom_module: at24@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio3 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&mmc2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ vmmc-supply = <&vmmc_3v3>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ dmas = <&edma 16
+ &edma 17>;
+ dma-names = "tx0", "rx0";
+
+ flash: w25q64cvzpig@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0xc0000>;
+ };
+
+ partition@c0000 {
+ label = "uboot environment";
+ reg = <0xc0000 0x40000>;
+ };
+
+ partition@100000 {
+ label = "reserved";
+ reg = <0x100000 0x100000>;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&cpsw_default>;
+ dual_emac = <1>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&davinci_mdio_default>;
+ 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>;
+};
+
+&dwc3_1 {
+ status = "okay";
+};
+
+&usb2_phy1 {
+ status = "okay";
+};
+
+&usb1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&dwc3_2 {
+ status = "okay";
+};
+
+&usb2_phy2 {
+ status = "okay";
+};
+
+&usb2 {
+ dr_mode = "host";
+ status = "okay";
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "peripheral", "host", "otg";
+};
+
+&elm {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&tscadc {
+ status = "okay";
+ tsc {
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
+ ti,coordiante-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
+ };
+
+ adc {
+ ti,adc-channels = <4 5 6 7>;
+ };
+};
+
+&cpu {
+ cpu0-supply = <&dcdc2>;
+ operating-points = <1000000 1330000>,
+ <800000 1260000>,
+ <720000 1200000>,
+ <600000 1100000>,
+ <300000 950000>;
+};
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index 22038f2..ecd09ab 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -154,138 +154,138 @@
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 */
+ AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM4372_IOPAD(0x98c, 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 */
+ AM4372_IOPAD(0x95c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ AM4372_IOPAD(0x958, 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 */
+ AM4372_IOPAD(0x960, 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 */
+ AM4372_IOPAD(0x964, 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 */
+ AM4372_IOPAD(0xa64, 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 */
+ AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_txen */
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rxctl */
+ AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd3 */
+ AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd2 */
+ AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd1 */
+ AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd0 */
+ AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd3 */
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd2 */
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */
+ AM4372_IOPAD(0x940, 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)
+ AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x940, 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 */
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM4372_IOPAD(0x94c, 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)
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
nand_flash_x8: nand_flash_x8 {
pinctrl-single,pins = <
- 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 */
+ AM4372_IOPAD(0x800, PIN_INPUT | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM4372_IOPAD(0x804, PIN_INPUT | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM4372_IOPAD(0x808, PIN_INPUT | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM4372_IOPAD(0x80c, PIN_INPUT | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM4372_IOPAD(0x810, PIN_INPUT | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM4372_IOPAD(0x814, PIN_INPUT | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM4372_IOPAD(0x818, PIN_INPUT | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM4372_IOPAD(0x81c, PIN_INPUT | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM4372_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpmc_wpn */
+ AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM4372_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM4372_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM4372_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM4372_IOPAD(0x89c, 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 */
+ AM4372_IOPAD(0x820, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+ AM4372_IOPAD(0x824, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x828, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x82c, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x830, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x834, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x838, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x83c, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+ AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+ AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+ AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+ AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+ AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+ AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
>;
};
@@ -293,194 +293,208 @@
display_mux_pins: display_mux_pins {
pinctrl-single,pins = <
/* GPIO 5_8 to select LCD / HDMI */
- 0x238 (PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM4372_IOPAD(0xa38, 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 */
+ AM4372_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2) /* uart1_ctsn.d_can0_tx */
+ AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE2) /* uart1_rtsn.d_can0_rx */
+ >;
+ };
+
+ dcan0_sleep: dcan0_sleep_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE7) /* uart1_ctsn.gpio0_12 */
+ AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE7) /* uart1_rtsn.gpio0_13 */
>;
};
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 */
+ AM4372_IOPAD(0x980, PIN_OUTPUT | MUX_MODE2) /* uart1_rxd.d_can1_tx */
+ AM4372_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE2) /* uart1_txd.d_can1_rx */
+ >;
+ };
+
+ dcan1_sleep: dcan1_sleep_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE7) /* uart1_rxd.gpio0_14 */
+ AM4372_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE7) /* uart1_txd.gpio0_15 */
>;
};
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*/
+ AM4372_IOPAD(0x9b0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ AM4372_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ AM4372_IOPAD(0x9c4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ AM4372_IOPAD(0x9c8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ AM4372_IOPAD(0xa08, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ AM4372_IOPAD(0xa0c, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ AM4372_IOPAD(0xa10, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ AM4372_IOPAD(0xa14, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ AM4372_IOPAD(0xa18, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ AM4372_IOPAD(0xa1c, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ AM4372_IOPAD(0xa20, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ AM4372_IOPAD(0xa24, 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*/
+ AM4372_IOPAD(0x9b0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_hd mode 0*/
+ AM4372_IOPAD(0x9b4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_vd mode 0*/
+ AM4372_IOPAD(0x9c0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_pclk mode 0*/
+ AM4372_IOPAD(0x9c4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data8 mode 0*/
+ AM4372_IOPAD(0x9c8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data9 mode 0*/
+ AM4372_IOPAD(0xa08, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data0 mode 0*/
+ AM4372_IOPAD(0xa0c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data1 mode 0*/
+ AM4372_IOPAD(0xa10, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data2 mode 0*/
+ AM4372_IOPAD(0xa14, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data3 mode 0*/
+ AM4372_IOPAD(0xa18, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data4 mode 0*/
+ AM4372_IOPAD(0xa1c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data5 mode 0*/
+ AM4372_IOPAD(0xa20, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data6 mode 0*/
+ AM4372_IOPAD(0xa24, 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*/
+ AM4372_IOPAD(0x9cc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0*/
+ AM4372_IOPAD(0x9d0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0*/
+ AM4372_IOPAD(0x9d4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0*/
+ AM4372_IOPAD(0x9d8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0*/
+ AM4372_IOPAD(0x9dC, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0*/
+ AM4372_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0*/
+ AM4372_IOPAD(0x9ec, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0*/
+ AM4372_IOPAD(0x9f0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0*/
+ AM4372_IOPAD(0x9f4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0*/
+ AM4372_IOPAD(0x9f8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0*/
+ AM4372_IOPAD(0x9fc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0*/
+ AM4372_IOPAD(0xa00, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0*/
+ AM4372_IOPAD(0xa04, 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*/
+ AM4372_IOPAD(0x9cc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data9 mode 0*/
+ AM4372_IOPAD(0x9d0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data8 mode 0*/
+ AM4372_IOPAD(0x9d4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_hd mode 0*/
+ AM4372_IOPAD(0x9d8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_vd mode 0*/
+ AM4372_IOPAD(0x9dc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_pclk mode 0*/
+ AM4372_IOPAD(0x9e8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data0 mode 0*/
+ AM4372_IOPAD(0x9ec, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data1 mode 0*/
+ AM4372_IOPAD(0x9f0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data2 mode 0*/
+ AM4372_IOPAD(0x9f4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data3 mode 0*/
+ AM4372_IOPAD(0x9f8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data4 mode 0*/
+ AM4372_IOPAD(0x9fc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data5 mode 0*/
+ AM4372_IOPAD(0xa00, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data6 mode 0*/
+ AM4372_IOPAD(0xa04, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data7 mode 0*/
>;
};
mmc3_pins_default: pinmux_mmc3_pins_default {
pinctrl-single,pins = <
- 0x8c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk */
- 0x88 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */
- 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_be1n.mmc2_dat3 */
+ AM4372_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk */
+ AM4372_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */
+ AM4372_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0 */
+ AM4372_IOPAD(0x848, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1 */
+ AM4372_IOPAD(0x84c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2 */
+ AM4372_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_be1n.mmc2_dat3 */
>;
};
mmc3_pins_sleep: pinmux_mmc3_pins_sleep {
pinctrl-single,pins = <
- 0x8c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_clk.mmc2_clk */
- 0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.mmc2_cmd */
- 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a1.mmc2_dat0 */
- 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a2.mmc2_dat1 */
- 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a3.mmc2_dat2 */
- 0x78 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_be1n.mmc2_dat3 */
+ AM4372_IOPAD(0x88c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_clk.mmc2_clk */
+ AM4372_IOPAD(0x888, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.mmc2_cmd */
+ AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a1.mmc2_dat0 */
+ AM4372_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a2.mmc2_dat1 */
+ AM4372_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a3.mmc2_dat2 */
+ AM4372_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_be1n.mmc2_dat3 */
>;
};
wlan_pins_default: pinmux_wlan_pins_default {
pinctrl-single,pins = <
- 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a4.gpio1_20 WL_EN */
- 0x5c (PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7) /* gpmc_a7.gpio1_23 WL_IRQ*/
- 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 BT_EN*/
+ AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a4.gpio1_20 WL_EN */
+ AM4372_IOPAD(0x85c, PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7) /* gpmc_a7.gpio1_23 WL_IRQ*/
+ AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 BT_EN*/
>;
};
wlan_pins_sleep: pinmux_wlan_pins_sleep {
pinctrl-single,pins = <
- 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a4.gpio1_20 WL_EN */
- 0x5c (PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7) /* gpmc_a7.gpio1_23 WL_IRQ*/
- 0x40 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a0.gpio1_16 BT_EN*/
+ AM4372_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a4.gpio1_20 WL_EN */
+ AM4372_IOPAD(0x85c, PIN_INPUT | WAKEUP_ENABLE | MUX_MODE7) /* gpmc_a7.gpio1_23 WL_IRQ*/
+ AM4372_IOPAD(0x840, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a0.gpio1_16 BT_EN*/
>;
};
uart3_pins: uart3_pins {
pinctrl-single,pins = <
- 0x228 (PIN_INPUT | MUX_MODE0) /* uart3_rxd.uart3_rxd */
- 0x22c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_txd.uart3_txd */
- 0x230 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_ctsn.uart3_ctsn */
- 0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_rtsn.uart3_rtsn */
+ AM4372_IOPAD(0xa28, PIN_INPUT | MUX_MODE0) /* uart3_rxd.uart3_rxd */
+ AM4372_IOPAD(0xa2c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_txd.uart3_txd */
+ AM4372_IOPAD(0xa30, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_ctsn.uart3_ctsn */
+ AM4372_IOPAD(0xa34, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_rtsn.uart3_rtsn */
>;
};
mcasp1_pins: mcasp1_pins {
pinctrl-single,pins = <
- 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+ AM4372_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
>;
};
mcasp1_sleep_pins: mcasp1_sleep_pins {
pinctrl-single,pins = <
- 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
gpio0_pins: gpio0_pins {
pinctrl-single,pins = <
- 0x26c (PIN_OUTPUT | MUX_MODE9) /* spi2_cs0.gpio0_23 SEL_eMMCorNANDn */
+ AM4372_IOPAD(0xa6c, PIN_OUTPUT | MUX_MODE9) /* spi2_cs0.gpio0_23 SEL_eMMCorNANDn */
>;
};
emmc_pins_default: emmc_pins_default {
pinctrl-single,pins = <
- 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 */
- 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
- 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM4372_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM4372_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM4372_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM4372_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ AM4372_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ AM4372_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ AM4372_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ AM4372_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+ AM4372_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM4372_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
>;
};
emmc_pins_sleep: emmc_pins_sleep {
pinctrl-single,pins = <
- 0x00 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad0.gpio1_0 */
- 0x04 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad1.gpio1_1 */
- 0x08 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad2.gpio1_2 */
- 0x0c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad3.gpio1_3 */
- 0x10 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
- 0x14 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
- 0x18 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
- 0x1c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */
- 0x80 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn1.gpio1_30 */
- 0x84 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.gpio1_31 */
+ AM4372_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad0.gpio1_0 */
+ AM4372_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad1.gpio1_1 */
+ AM4372_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad2.gpio1_2 */
+ AM4372_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad3.gpio1_3 */
+ AM4372_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */
+ AM4372_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad5.gpio1_5 */
+ AM4372_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad6.gpio1_6 */
+ AM4372_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad7.gpio1_7 */
+ AM4372_IOPAD(0x880, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn1.gpio1_30 */
+ AM4372_IOPAD(0x884, PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.gpio1_31 */
>;
};
};
@@ -576,13 +590,20 @@
pinctrl-names = "default";
pinctrl-0 = <&pixcir_ts_pins>;
reg = <0x5c>;
- interrupt-parent = <&gpio3>;
- interrupts = <22 0>;
attb-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+ /*
+ * 0x264 represents the offset of padconf register of
+ * gpio3_22 from am43xx_pinmux base.
+ */
+ interrupts-extended = <&gpio3 22 IRQ_TYPE_EDGE_FALLING>,
+ <&am43xx_pinmux 0x264>;
+ interrupt-names = "tsc", "wakeup";
+
touchscreen-size-x = <1024>;
touchscreen-size-y = <600>;
+ wakeup-source;
};
ov2659@30 {
@@ -689,7 +710,7 @@
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
/* eMMC sits on mmc2 */
@@ -711,8 +732,8 @@
status = "okay";
/* these are on the crossbar and are outlined in the
xbar-event-map element */
- dmas = <&edma 30
- &edma 31>;
+ dmas = <&edma_xbar 30 0 1>,
+ <&edma_xbar 31 0 2>;
dma-names = "tx", "rx";
vmmc-supply = <&vmmcwl_fixed>;
bus-width = <4>;
@@ -733,11 +754,6 @@
};
};
-&edma {
- ti,edma-xbar-event-map = /bits/ 16 <1 30
- 2 31>;
-};
-
&uart3 {
status = "okay";
pinctrl-names = "default";
@@ -886,14 +902,16 @@
};
&dcan0 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&dcan0_default>;
+ pinctrl-1 = <&dcan0_sleep>;
status = "okay";
};
&dcan1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&dcan1_default>;
+ pinctrl-1 = <&dcan1_sleep>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts
index af25801..76dcfc6 100644
--- a/arch/arm/boot/dts/am437x-idk-evm.dts
+++ b/arch/arm/boot/dts/am437x-idk-evm.dts
@@ -122,137 +122,137 @@
&am43xx_pinmux {
gpio_keys_pins_default: gpio_keys_pins_default {
pinctrl-single,pins = <
- 0x1b8 (PIN_INPUT | MUX_MODE7) /* cam0_field.gpio4_2 */
+ AM4372_IOPAD(0x9b8, 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 */
+ AM4372_IOPAD(0x988, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM4372_IOPAD(0x98c, 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)
+ AM4372_IOPAD(0x988, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x98c, 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 */
+ AM4372_IOPAD(0x9e8, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE3) /* cam1_data1.i2c2_scl */
+ AM4372_IOPAD(0x9ec, 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)
+ AM4372_IOPAD(0x9e8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9ec, 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 */
+ AM4372_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM4372_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM4372_IOPAD(0x9f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM4372_IOPAD(0x9f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM4372_IOPAD(0x9f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM4372_IOPAD(0x9fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM4372_IOPAD(0x960, 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)
+ AM4372_IOPAD(0x900, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x904, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9f0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9f4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9f8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9fc, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x960, 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 */
+ AM4372_IOPAD(0x964, 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 */
+ AM4372_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ AM4372_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ AM4372_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ AM4372_IOPAD(0x934, 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)
+ AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x934, 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 */
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM4372_IOPAD(0x94c, 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)
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x94c, 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 */
+ AM4372_IOPAD(0x87c, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ AM4372_IOPAD(0x888, PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ AM4372_IOPAD(0x890, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ AM4372_IOPAD(0x894, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ AM4372_IOPAD(0x898, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ AM4372_IOPAD(0x89c, 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)
+ AM4372_IOPAD(0x87c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x888, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x890, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x894, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x898, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x89c, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
};
@@ -325,7 +325,7 @@
pinctrl-1 = <&mmc1_pins_sleep>;
vmmc-supply = <&v3_3d>;
bus-width = <4>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&qspi {
diff --git a/arch/arm/boot/dts/am437x-sbc-t43.dts b/arch/arm/boot/dts/am437x-sbc-t43.dts
new file mode 100644
index 0000000..5f750c0
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-sbc-t43.dts
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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 "am437x-cm-t43.dts"
+#include "compulab-sb-som.dtsi"
+
+/ {
+ model = "CompuLab CM-T43 on SB-SOM-T43";
+ compatible = "compulab,am437x-sbc-t43", "compulab,am437x-cm-t43", "ti,am4372", "ti,am43";
+
+ aliases {
+ display0 = &lcd0;
+ };
+};
+
+&am43xx_pinmux {
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM4372_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM4372_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM4372_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM4372_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM4372_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM4372_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ AM4372_IOPAD(0x964, PIN_INPUT | MUX_MODE7) /* ecap0_in_pwm0_out.gpio0_7 */
+ >;
+ };
+
+ dss_pinctrl_default: dss_pinctrl_default {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE2) /* cam0 hd -> DSS DATA 23 */
+ AM4372_IOPAD(0x9b4, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9b8, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9bc, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9c0, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9c4, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9c8, PIN_OUTPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x9cc, PIN_OUTPUT_PULLUP | MUX_MODE2) /* cam1 data 9 -> DSS DATA 16 */
+
+ AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+ AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+ AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+ AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+ AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+ AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+ AM4372_IOPAD(0xa20, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ >;
+ };
+
+ uart0_pins_default: uart0_pins_default {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x968, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE0)
+ AM4372_IOPAD(0x96C, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE0)
+ AM4372_IOPAD(0x970, PIN_INPUT_PULLUP | SLEWCTRL_FAST | DS0_PULL_UP_DOWN_EN | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM4372_IOPAD(0x974, PIN_INPUT | PULL_DISABLE | SLEWCTRL_FAST | DS0_PULL_UP_DOWN_EN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ i2c1_pins: i2c1_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0xa6c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE1) /* spi2_cs0.i2c1_sda */
+ AM4372_IOPAD(0xa60, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE1) /* spi2_sclk.i2c1_scl */
+ >;
+ };
+
+ i2c2_pins: i2c2_pins {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0x978, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
+ AM4372_IOPAD(0x97c, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
+ >;
+ };
+
+ usb2_phy1_default: usb2_phy1_default {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0xac0, DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+
+ usb2_phy2_default: usb2_phy2_default {
+ pinctrl-single,pins = <
+ AM4372_IOPAD(0xac4, DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+ >;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+
+ pca9555: pca9555@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ eeprom_base: at24@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+};
+
+&mmc1 {
+ status = "okay";
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vsb_3v3>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+};
+
+&dss {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_pinctrl_default>;
+
+ port {
+ dpi_lcd_out: endpoint@0 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_default>;
+};
+
+&dwc3_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_phy1_default>;
+};
+
+&dwc3_2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_phy2_default>;
+};
+
+&lcd0 {
+ enable-gpios = <&pca9555 14 GPIO_ACTIVE_HIGH
+ &gpio4 28 GPIO_ACTIVE_HIGH>;
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_lcd_out>;
+ data-lines = <24>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
index 7da7c2d..d82dd6e 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -157,259 +157,259 @@
&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 */
+ AM4372_IOPAD(0xa4c, PIN_OUTPUT | MUX_MODE7) /* gpio5_13.gpio5_13 */
+ AM4372_IOPAD(0xa50, PIN_OUTPUT | MUX_MODE7) /* spi4_sclk.gpio5_4 */
+ AM4372_IOPAD(0xa54, PIN_INPUT | MUX_MODE7) /* spi4_d0.gpio5_5 */
+ AM4372_IOPAD(0xa58, 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 */
+ AM4372_IOPAD(0xa28, PIN_OUTPUT | MUX_MODE7) /* uart3_rxd.gpio5_2 */
+ AM4372_IOPAD(0xa2c, PIN_OUTPUT | MUX_MODE7) /* uart3_txd.gpio5_3 */
+ AM4372_IOPAD(0xa30, PIN_OUTPUT | MUX_MODE7) /* uart3_ctsn.gpio5_0 */
+ AM4372_IOPAD(0xa34, 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 */
+ AM4372_IOPAD(0x988, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM4372_IOPAD(0x98c, 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 */
+ AM4372_IOPAD(0x95c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ AM4372_IOPAD(0x958, 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 */
+ AM4372_IOPAD(0x8f0, PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ AM4372_IOPAD(0x8f4, PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ AM4372_IOPAD(0x8f8, PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ AM4372_IOPAD(0x8fc, PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ AM4372_IOPAD(0x900, PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ AM4372_IOPAD(0x904, PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ AM4372_IOPAD(0x960, 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 */
+ AM4372_IOPAD(0x964, 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 */
+ AM4372_IOPAD(0x874, PIN_INPUT | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+ AM4372_IOPAD(0x878, 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*/
+ AM4372_IOPAD(0x9b0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ AM4372_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ AM4372_IOPAD(0x9b8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_field mode 0*/
+ AM4372_IOPAD(0x9bc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_wen mode 0*/
+ AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ AM4372_IOPAD(0x9c4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ AM4372_IOPAD(0x9c8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ AM4372_IOPAD(0xa08, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ AM4372_IOPAD(0xa0c, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ AM4372_IOPAD(0xa10, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ AM4372_IOPAD(0xa14, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ AM4372_IOPAD(0xa18, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ AM4372_IOPAD(0xa1c, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ AM4372_IOPAD(0xa20, PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ AM4372_IOPAD(0xa24, 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)
+ AM4372_IOPAD(0x9b0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9b4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9b8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9bc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9c0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9c4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9c8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa08, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa0c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa10, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa14, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa18, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa1c, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa20, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa24, 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 */
+ AM4372_IOPAD(0x92c, PIN_OUTPUT | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ AM4372_IOPAD(0x914, PIN_OUTPUT | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ AM4372_IOPAD(0x928, PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ AM4372_IOPAD(0x924, PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ AM4372_IOPAD(0x920, PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ AM4372_IOPAD(0x91c, PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ AM4372_IOPAD(0x930, PIN_INPUT | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ AM4372_IOPAD(0x918, PIN_INPUT | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ AM4372_IOPAD(0x940, PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ AM4372_IOPAD(0x93c, PIN_INPUT | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ AM4372_IOPAD(0x938, PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ AM4372_IOPAD(0x934, 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 */
+ AM4372_IOPAD(0x858, PIN_OUTPUT | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ AM4372_IOPAD(0x840, PIN_OUTPUT | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ AM4372_IOPAD(0x854, PIN_OUTPUT | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ AM4372_IOPAD(0x850, PIN_OUTPUT | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ AM4372_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ AM4372_IOPAD(0x848, PIN_OUTPUT | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ AM4372_IOPAD(0x85c, PIN_INPUT | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ AM4372_IOPAD(0x844, PIN_INPUT | MUX_MODE2) /* gpmc_a1.rgmii2_rtcl */
+ AM4372_IOPAD(0x86c, PIN_INPUT | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
+ AM4372_IOPAD(0x868, PIN_INPUT | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ AM4372_IOPAD(0x864, PIN_INPUT | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ AM4372_IOPAD(0x860, 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)
+ AM4372_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x934, 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)
+ AM4372_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x860, 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 */
+ AM4372_IOPAD(0x948, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM4372_IOPAD(0x94c, 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)
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x94c, 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 */
+ AM4372_IOPAD(0x820, PIN_OUTPUT | MUX_MODE1) /* gpmc ad 8 -> DSS DATA 23 */
+ AM4372_IOPAD(0x824, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x828, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x82c, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x830, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x834, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x838, PIN_OUTPUT | MUX_MODE1)
+ AM4372_IOPAD(0x83c, PIN_OUTPUT | MUX_MODE1) /* gpmc ad 15 -> DSS DATA 16 */
+ AM4372_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* DSS DATA 0 */
+ AM4372_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)
+ AM4372_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* DSS DATA 15 */
+ AM4372_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* DSS VSYNC */
+ AM4372_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* DSS HSYNC */
+ AM4372_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* DSS PCLK */
+ AM4372_IOPAD(0x8ec, 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 */
+ AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ AM4372_IOPAD(0x888, PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ AM4372_IOPAD(0x890, PIN_INPUT | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ AM4372_IOPAD(0x894, PIN_INPUT | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ AM4372_IOPAD(0x898, PIN_INPUT | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ AM4372_IOPAD(0x89c, 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 */
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
+ AM4372_IOPAD(0x908, PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
+ AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
>;
};
mcasp1_pins_sleep: mcasp1_pins_sleep {
pinctrl-single,pins = <
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
lcd_pins: lcd_pins {
pinctrl-single,pins = <
- 0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpcm_ad7.gpio1_7 */
+ AM4372_IOPAD(0x81c, 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 */
+ AM4372_IOPAD(0xac0, PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
>;
};
usb2_pins: usb2_pins {
pinctrl-single,pins = <
- 0x2c4 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+ AM4372_IOPAD(0xac4, PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
>;
};
};
@@ -502,7 +502,7 @@
reg = <0x38>;
interrupt-parent = <&gpio0>;
- interrupts = <31 0>;
+ interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
@@ -563,7 +563,7 @@
vmmc-supply = <&dcdc4>;
bus-width = <4>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&usb2_phy1 {
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 86c2dfb..d580e2b7 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -144,228 +144,228 @@
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 */
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */
+ AM4372_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxdv.rmii1_rxdv */
+ AM4372_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */
+ AM4372_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */
+ AM4372_IOPAD(0x944, 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)
+ AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x944, 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 */
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM4372_IOPAD(0x94c, 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)
+ AM4372_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x94c, 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 */
+ AM4372_IOPAD(0x988, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM4372_IOPAD(0x98c, 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 */
+ AM4372_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.SELQSPIorNAND/GPIO */
+ AM4372_IOPAD(0x800, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM4372_IOPAD(0x804, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM4372_IOPAD(0x808, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM4372_IOPAD(0x80c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM4372_IOPAD(0x810, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM4372_IOPAD(0x814, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM4372_IOPAD(0x818, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM4372_IOPAD(0x81c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM4372_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM4372_IOPAD(0x874, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpmc_wpn */
+ AM4372_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM4372_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM4372_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM4372_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM4372_IOPAD(0x89c, 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 */
+ AM4372_IOPAD(0x964, 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 */
+ AM4372_IOPAD(0x9c0, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8) /* i2c2_sda.i2c2_sda */
+ AM4372_IOPAD(0x9c4, 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 */
+ AM4372_IOPAD(0x950, PIN_INPUT | MUX_MODE0) /* spi0_clk.spi0_clk */
+ AM4372_IOPAD(0x954, PIN_OUTPUT | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ AM4372_IOPAD(0x958, PIN_INPUT | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ AM4372_IOPAD(0x95c, 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 */
+ AM4372_IOPAD(0x990, PIN_INPUT | MUX_MODE3) /* mcasp0_aclkx.spi1_clk */
+ AM4372_IOPAD(0x994, PIN_OUTPUT | MUX_MODE3) /* mcasp0_fsx.spi1_d0 */
+ AM4372_IOPAD(0x998, PIN_INPUT | MUX_MODE3) /* mcasp0_axr0.spi1_d1 */
+ AM4372_IOPAD(0x99c, 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 */
+ AM4372_IOPAD(0x960, 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)
+ AM4372_IOPAD(0x87c, PIN_INPUT_PULLUP | MUX_MODE3)
+ AM4372_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE2)
+ AM4372_IOPAD(0x890, PIN_INPUT_PULLUP | MUX_MODE3)
+ AM4372_IOPAD(0x894, PIN_INPUT_PULLUP | MUX_MODE3)
+ AM4372_IOPAD(0x898, PIN_INPUT_PULLUP | MUX_MODE3)
+ AM4372_IOPAD(0x89c, PIN_INPUT_PULLUP | MUX_MODE3)
>;
};
pixcir_ts_pins: pixcir_ts_pins {
pinctrl-single,pins = <
- 0x44 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a1.gpio1_17 */
+ AM4372_IOPAD(0x844, 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 */
+ AM4372_IOPAD(0xa34, 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 */
+ AM4372_IOPAD(0x820, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */
+ AM4372_IOPAD(0x824, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x828, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x82c, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x830, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x834, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x838, PIN_OUTPUT_PULLUP | MUX_MODE1)
+ AM4372_IOPAD(0x83c, PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */
+ AM4372_IOPAD(0x8a0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
+ AM4372_IOPAD(0x8a4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8a8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8ac, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8b4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8B8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8bc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8c8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8cc, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d0, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d4, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8d8, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM4372_IOPAD(0x8dc, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
+ AM4372_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
+ AM4372_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
+ AM4372_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
+ AM4372_IOPAD(0x8ec, PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
>;
};
display_mux_pins: display_mux_pins {
pinctrl-single,pins = <
/* GPMC CLK -> GPIO 2_1 to select LCD / HDMI */
- 0x08C (PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM4372_IOPAD(0x88C, 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 */
+ AM4372_IOPAD(0x9cc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0 */
+ AM4372_IOPAD(0x9d0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0 */
+ AM4372_IOPAD(0x9d4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0 */
+ AM4372_IOPAD(0x9d8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0 */
+ AM4372_IOPAD(0x9dc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0 */
+ AM4372_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0 */
+ AM4372_IOPAD(0x9ec, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0 */
+ AM4372_IOPAD(0x9f0, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0 */
+ AM4372_IOPAD(0x9f4, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0 */
+ AM4372_IOPAD(0x9f8, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0 */
+ AM4372_IOPAD(0x9fc, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0 */
+ AM4372_IOPAD(0xa00, PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0 */
+ AM4372_IOPAD(0xa04, 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)
+ AM4372_IOPAD(0x9cc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9d0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9d4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9d8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9dc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9e8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9ec, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9f0, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9f4, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9f8, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0x9fc, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa00, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ AM4372_IOPAD(0xa04, DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
>;
};
mcasp1_pins: mcasp1_pins {
pinctrl-single,pins = <
- 0x1a0 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_ACLKR/MCASP1_ACLKX */
- 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_FSR/MCASP1_FSX */
- 0x1a8 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)/* MCASP0_AXR1/MCASP1_AXR0 */
- 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_AHCLKX/MCASP1_AXR1 */
+ AM4372_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_ACLKR/MCASP1_ACLKX */
+ AM4372_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_FSR/MCASP1_FSX */
+ AM4372_IOPAD(0x9a8, PIN_OUTPUT_PULLDOWN | MUX_MODE3)/* MCASP0_AXR1/MCASP1_AXR0 */
+ AM4372_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE3) /* MCASP0_AHCLKX/MCASP1_AXR1 */
>;
};
mcasp1_sleep_pins: mcasp1_sleep_pins {
pinctrl-single,pins = <
- 0x1a0 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
- 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9a4, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9a8, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM4372_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
};
@@ -376,7 +376,7 @@
bus-width = <4>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
&mac {
@@ -491,7 +491,7 @@
pinctrl-0 = <&pixcir_ts_pins>;
reg = <0x5c>;
interrupt-parent = <&gpio1>;
- interrupts = <17 0>;
+ interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi
index cc88728..a38af2b 100644
--- a/arch/arm/boot/dts/am43xx-clocks.dtsi
+++ b/arch/arm/boot/dts/am43xx-clocks.dtsi
@@ -259,6 +259,14 @@
ti,invert-autoidle-bit;
};
+ mpu_periphclk: mpu_periphclk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&dpll_mpu_m2_ck>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ };
+
dpll_ddr_ck: dpll_ddr_ck {
#clock-cells = <0>;
compatible = "ti,am3-dpll-clock";
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index d55e3ea..592e65c 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -35,6 +35,14 @@
regulator-max-microvolt = <3300000>;
};
+ aic_dvdd: fixedregulator-aic_dvdd {
+ compatible = "regulator-fixed";
+ regulator-name = "aic_dvdd_fixed";
+ vin-supply = <&vdd_3v3>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
vtt_fixed: fixedregulator-vtt {
/* TPS51200 */
compatible = "regulator-fixed";
@@ -142,102 +150,130 @@
};
};
};
+
+ sound0: sound@0 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "BeagleBoard-X15";
+ simple-audio-card,widgets =
+ "Line", "Line Out",
+ "Line", "Line In";
+ simple-audio-card,routing =
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT",
+ "MIC2L", "Line In",
+ "MIC2R", "Line In";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound0_master>;
+ simple-audio-card,frame-master = <&sound0_master>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp3>;
+ };
+
+ sound0_master: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3104>;
+ assigned-clocks = <&clkoutmux2_clk_mux>;
+ assigned-clock-parents = <&sys_clk2_dclk_div>;
+ clocks = <&clkout2_clk>;
+ };
+ };
};
&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 */
+ DRA7XX_CORE_IOPAD(0x37a8, PIN_OUTPUT | MUX_MODE14) /* spi1_d1.gpio7_8 */
+ DRA7XX_CORE_IOPAD(0x37ac, PIN_OUTPUT | MUX_MODE14) /* spi1_d0.gpio7_9 */
+ DRA7XX_CORE_IOPAD(0x37c0, PIN_OUTPUT | MUX_MODE14) /* spi2_sclk.gpio7_14 */
+ DRA7XX_CORE_IOPAD(0x37c4, 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 */
+ DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.sda */
+ DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.scl */
>;
};
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
- 0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
- 0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
+ DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
+ DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
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 */
+ DRA7XX_CORE_IOPAD(0x36a4, PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */
+ DRA7XX_CORE_IOPAD(0x36a8, 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 */
+ DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */
+ DRA7XX_CORE_IOPAD(0x37fc, 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 */
+ DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */
+ DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+ DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+ DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+ DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+ DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+ DRA7XX_CORE_IOPAD(0x3768, 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 */
+ DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+ DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+ DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+ DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+ DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+ DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+ DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+ DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+ DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+ DRA7XX_CORE_IOPAD(0x3498, 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 */
+ DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0) /* rgmii1_tclk */
+ DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0) /* rgmii1_tctl */
+ DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0) /* rgmii1_td3 */
+ DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0) /* rgmii1_td2 */
+ DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0) /* rgmii1_td1 */
+ DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0) /* rgmii1_td0 */
+ DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE0) /* rgmii1_rclk */
+ DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE0) /* rgmii1_rctl */
+ DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE0) /* rgmii1_rd3 */
+ DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE0) /* rgmii1_rd2 */
+ DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE0) /* rgmii1_rd1 */
+ DRA7XX_CORE_IOPAD(0x367c, 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 */
+ DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3) /* rgmii2_tclk */
+ DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3) /* rgmii2_tctl */
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3) /* rgmii2_td3 */
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3) /* rgmii2_td2 */
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3) /* rgmii2_td1 */
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3) /* rgmii2_td0 */
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3) /* rgmii2_rclk */
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3) /* rgmii2_rctl */
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3) /* rgmii2_rd3 */
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3) /* rgmii2_rd2 */
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3) /* rgmii2_rd1 */
+ DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3) /* rgmii2_rd0 */
>;
};
@@ -245,85 +281,115 @@
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)
+ DRA7XX_CORE_IOPAD(0x3650, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3654, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3658, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x365c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3660, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3664, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x367c, 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)
+ DRA7XX_CORE_IOPAD(0x3598, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x359c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c4, 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 */
+ DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_mclk */
+ DRA7XX_CORE_IOPAD(0x3640, 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)
+ DRA7XX_CORE_IOPAD(0x363c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT | MUX_MODE15)
>;
};
tps659038_pins_default: tps659038_pins_default {
pinctrl-single,pins = <
- 0x418 (PIN_INPUT_PULLUP | MUX_MODE14) /* wakeup0.gpio1_0 */
+ DRA7XX_CORE_IOPAD(0x3818, 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 */
+ DRA7XX_CORE_IOPAD(0x37c8, 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 */
+ DRA7XX_CORE_IOPAD(0x3824, PIN_INPUT_PULLUP | MUX_MODE1) /* wakeup3.sys_nirq1 */
>;
};
usb1_pins: pinmux_usb1_pins {
pinctrl-single,pins = <
- 0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ DRA7XX_CORE_IOPAD(0x3680, 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 */
+ DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */
>;
};
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
- 0x3b0 (PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */
- 0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
- 0x370 (PIN_OUTPUT | MUX_MODE14) /* gpio6_28 LS_OE */
+ DRA7XX_CORE_IOPAD(0x37b0, PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */
+ DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
+ DRA7XX_CORE_IOPAD(0x3770, PIN_OUTPUT | MUX_MODE14) /* gpio6_28 LS_OE */
+ >;
+ };
+
+ clkout2_pins_default: clkout2_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3694, PIN_OUTPUT_PULLDOWN | MUX_MODE9) /* xref_clk0.clkout2 */
+ >;
+ };
+
+ clkout2_pins_sleep: clkout2_pins_sleep {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3694, PIN_INPUT | MUX_MODE15) /* xref_clk0.clkout2 */
+ >;
+ };
+
+ mcasp3_pins_default: mcasp3_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+ DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+ DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+ >;
+ };
+
+ mcasp3_pins_sleep: mcasp3_pins_sleep {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT | MUX_MODE15)
>;
};
};
@@ -496,8 +562,7 @@
extcon_usb2: tps659038_usb {
compatible = "ti,palmas-usb-vid";
ti,enable-vbus-detection;
- ti,enable-id-detection;
- id-gpios = <&gpio7 24 GPIO_ACTIVE_HIGH>;
+ vbus-gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
};
};
@@ -511,6 +576,22 @@
interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
#thermal-sensor-cells = <1>;
};
+
+ tlv320aic3104: tlv320aic3104@18 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3104";
+ reg = <0x18>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&clkout2_pins_default>;
+ pinctrl-1 = <&clkout2_pins_sleep>;
+ status = "okay";
+ adc-settle-ms = <40>;
+
+ AVDD-supply = <&vdd_3v3>;
+ IOVDD-supply = <&vdd_3v3>;
+ DRVDD-supply = <&vdd_3v3>;
+ DVDD-supply = <&aic_dvdd>;
+ };
};
&i2c3 {
@@ -524,6 +605,7 @@
reg = <0x6f>;
interrupts-extended = <&crossbar_mpu GIC_SPI 2 IRQ_TYPE_EDGE_RISING>,
<&dra7_pmx_core 0x424>;
+ interrupt-names = "irq", "wakeup";
pinctrl-names = "default";
pinctrl-0 = <&mcp79410_pins_default>;
@@ -586,7 +668,7 @@
vmmc-supply = <&ldo1_reg>;
bus-width = <4>;
- cd-gpios = <&gpio6 27 0>; /* gpio 219 */
+ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */
};
&mmc2 {
@@ -709,3 +791,40 @@
&pcie1 {
gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
};
+
+&mcasp3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mcasp3_pins_default>;
+ pinctrl-1 = <&mcasp3_pins_sleep>;
+ assigned-clocks = <&mcasp3_ahclkx_mux>;
+ assigned-clock-parents = <&sys_clkin2>;
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializers */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 2 0 0
+ >;
+};
+
+&mailbox5 {
+ status = "okay";
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ status = "okay";
+ };
+};
+
+&mailbox6 {
+ status = "okay";
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp2_ipc3x: mbox_dsp2_ipc3x {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
new file mode 100644
index 0000000..1c06cb7
--- /dev/null
+++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts
@@ -0,0 +1,617 @@
+/*
+ * Support for CompuLab CL-SOM-AM57x System-on-Module
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Dmitry Lifshitz <lifshitz@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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "dra74x.dtsi"
+
+/ {
+ model = "CompuLab CL-SOM-AM57x";
+ compatible = "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB - minimal configuration */
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins_default>;
+
+ led@0 {
+ label = "cl-som-am57x:green";
+ gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+
+ vdd_3v3: fixedregulator-vdd_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ads7846reg: fixedregulator-ads7846-reg {
+ compatible = "regulator-fixed";
+ regulator-name = "ads7846-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ sound0: sound@0 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "CL-SOM-AM57x-Sound-Card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&dailink0_master>;
+ simple-audio-card,frame-master = <&dailink0_master>;
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Microphone", "Microphone Jack",
+ "Line", "Line Jack";
+ simple-audio-card,routing =
+ "Headphone Jack", "RHPOUT",
+ "Headphone Jack", "LHPOUT",
+ "LLINEIN", "Line Jack",
+ "MICIN", "Mic Bias",
+ "Mic Bias", "Microphone Jack";
+
+ dailink0_master: simple-audio-card,cpu {
+ sound-dai = <&mcasp3>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8731>;
+ system-clock-frequency = <12000000>;
+ };
+ };
+};
+
+&dra7_pmx_core {
+ leds_pins_default: leds_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x347c, PIN_OUTPUT | MUX_MODE14) /* gpmc_a15.gpio2_5 */
+ >;
+ };
+
+ i2c1_pins_default: i2c1_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda.sda */
+ DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl.scl */
+ >;
+ };
+
+ i2c3_pins_default: i2c3_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x36a4, PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */
+ DRA7XX_CORE_IOPAD(0x36a8, PIN_INPUT| MUX_MODE10) /* mcasp1_fsx.i2c3_scl */
+ >;
+ };
+
+ i2c4_pins_default: i2c4_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x36ac, PIN_INPUT| MUX_MODE10) /* mcasp1_acl.i2c4_sda */
+ DRA7XX_CORE_IOPAD(0x36b0, PIN_INPUT| MUX_MODE10) /* mcasp1_fsr.i2c4_scl */
+ >;
+ };
+
+ tps659038_pins_default: tps659038_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3818, PIN_INPUT_PULLUP | MUX_MODE14) /* wakeup0.gpio1_0 */
+ >;
+ };
+
+ mmc2_pins_default: mmc2_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+ DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+ DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+ DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+ DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+ DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+ DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+ DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+ DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+ DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */
+ >;
+ };
+
+ qspi1_pins: pinmux_qspi1_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3474, PIN_INPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d0 */
+ DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d1 */
+ DRA7XX_CORE_IOPAD(0x3488, PIN_INPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ DRA7XX_CORE_IOPAD(0x34b8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+ DRA7XX_CORE_IOPAD(0x34bc, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs3.qspi1_cs1 */
+ >;
+ };
+
+ cpsw_pins_default: cpsw_pins_default {
+ pinctrl-single,pins = <
+ /* Slave at addr 0x0 */
+ DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0) /* rgmii0_tclk */
+ DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0) /* rgmii0_tctl */
+ DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0) /* rgmii0_td3 */
+ DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0) /* rgmii0_td2 */
+ DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0) /* rgmii0_td1 */
+ DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0) /* rgmii0_td0 */
+ DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rclk */
+ DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rctl */
+ DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd3 */
+ DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd2 */
+ DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd1 */
+ DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rgmii0_rd0 */
+
+ /* Slave at addr 0x1 */
+ DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3) /* vin2a_d12.rgmii1_tclk */
+ DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3) /* vin2a_d13.rgmii1_tctl */
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3) /* vin2a_d14.rgmii1_td3 */
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3) /* vin2a_d15.rgmii1_td2 */
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3) /* vin2a_d16.rgmii1_td1 */
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3) /* vin2a_d17.rgmii1_td0 */
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+ DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
+ >;
+ };
+
+ cpsw_pins_sleep: cpsw_pins_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ DRA7XX_CORE_IOPAD(0x3650, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3654, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3658, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x365c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3660, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3664, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x367c, PIN_INPUT | MUX_MODE15)
+
+ /* Slave 2 */
+ DRA7XX_CORE_IOPAD(0x3598, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x359c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
+ davinci_mdio_pins_default: davinci_mdio_pins_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ DRA7XX_CORE_IOPAD(0x3590, PIN_OUTPUT_PULLUP | MUX_MODE3)/* vin2a_d10.mdio_mclk */
+ DRA7XX_CORE_IOPAD(0x3594, PIN_INPUT_PULLUP | MUX_MODE3) /* vin2a_d11.mdio_d */
+ >;
+ };
+
+ davinci_mdio_pins_sleep: davinci_mdio_pins_sleep {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3590, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3594, PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
+ ads7846_pins: pinmux_ads7846_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3464, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpmc_a9.gpio1_31 */
+ >;
+ };
+
+ mcasp3_pins_default: mcasp3_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+ DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+ DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+ >;
+ };
+
+ mcasp3_pins_sleep: mcasp3_pins_sleep {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT | MUX_MODE15)
+ >;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&i2c4 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_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 = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps45_reg: smps45 {
+ /* VDD_DSPEVE */
+ regulator-name = "smps45";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps6_reg: smps6 {
+ /* VDD_GPU */
+ regulator-name = "smps6";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps7_reg: smps7 {
+ /* VDD_CORE */
+ regulator-name = "smps7";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1160000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps8_reg: smps8 {
+ /* VDD_IVA */
+ regulator-name = "smps8";
+ regulator-min-microvolt = < 850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ smps9_reg: smps9 {
+ /* PMIC_3V3 */
+ regulator-name = "smps9";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+
+ ldo1_reg: ldo1 {
+ /* VDD_SD / VDDSHV8 */
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: ldo2 {
+ /* VDD_1V8 */
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo3_reg: ldo3 {
+ /* VDDA_1V8_PHYA - supplies VDDA_SATA, VDDA_USB1/2/3 */
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo4_reg: ldo4 {
+ /* VDDA_1V8_PHYB - supplies VDDA_HDMI, VDDA_PCIE/0/1 */
+ regulator-name = "ldo4";
+ 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-always-on;
+ regulator-boot-on;
+ };
+
+ /* regen1 not used */
+ };
+ };
+
+ 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>;
+ };
+ };
+
+ rtc0: rtc@56 {
+ compatible = "emmicro,em3027";
+ reg = <0x56>;
+ };
+
+ eeprom_module: atmel@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ wm8731: wm8731@1a {
+ #sound-dai-cells = <0>;
+ compatible = "wlf,wm8731";
+ reg = <0x1a>;
+ status = "okay";
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&smps12_reg>;
+ voltage-tolerance = <1>;
+};
+
+&sata {
+ status = "okay";
+};
+
+&mailbox5 {
+ status = "okay";
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ status = "okay";
+ };
+};
+
+&mailbox6 {
+ status = "okay";
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp2_ipc3x: mbox_dsp2_ipc3x {
+ status = "okay";
+ };
+};
+
+&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;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi1_pins>;
+
+ spi-max-frequency = <48000000>;
+
+ spi_flash: spi_flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,m25p80", "jedec,spi-nor";
+ reg = <0>; /* CS0 */
+ spi-max-frequency = <48000000>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0xc0000>;
+ };
+
+ partition@c0000 {
+ label = "uboot environment";
+ reg = <0xc0000 0x40000>;
+ };
+
+ partition@100000 {
+ label = "reserved";
+ reg = <0x100000 0x0>;
+ };
+ };
+
+ /* touch controller */
+ ads7846@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ads7846_pins>;
+
+ compatible = "ti,ads7846";
+ vcc-supply = <&ads7846reg>;
+
+ reg = <1>; /* CS1 */
+ spi-max-frequency = <1500000>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <31 0>;
+ pendown-gpio = <&gpio1 31 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>;
+
+ wakeup-source;
+ };
+};
+
+&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>, <0>;
+ phy-mode = "rgmii-txid";
+ dual_emac_res_vlan = <0>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii-txid";
+ dual_emac_res_vlan = <1>;
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_pins_default>;
+ pinctrl-1 = <&davinci_mdio_pins_sleep>;
+};
+
+&usb2_phy1 {
+ phy-supply = <&ldousb_reg>;
+};
+
+&usb2_phy2 {
+ phy-supply = <&ldousb_reg>;
+};
+
+&usb1 {
+ dr_mode = "host";
+};
+
+&usb2 {
+ dr_mode = "host";
+};
+
+&mcasp3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mcasp3_pins_default>;
+ pinctrl-1 = <&mcasp3_pins_sleep>;
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializers */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 2 0 0
+ >;
+};
+
+&gpio3 {
+ status = "okay";
+ ti,no-reset-on-init;
+};
+
+&gpio2 {
+ status = "okay";
+ ti,no-reset-on-init;
+};
diff --git a/arch/arm/boot/dts/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/am57xx-sbc-am57x.dts
new file mode 100644
index 0000000..988e996
--- /dev/null
+++ b/arch/arm/boot/dts/am57xx-sbc-am57x.dts
@@ -0,0 +1,179 @@
+/*
+ * Support for CompuLab SBC-AM57x single board computer
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Dmitry Lifshitz <lifshitz@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 "am57xx-cl-som-am57x.dts"
+#include "compulab-sb-som.dtsi"
+
+/ {
+ model = "CompuLab CL-SOM-AM57x on SB-SOM-AM57x";
+ compatible = "compulab,sbc-am57x", "compulab,cl-som-am57x", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
+
+ aliases {
+ display0 = &lcd0;
+ display1 = &hdmi;
+ };
+};
+
+&dra7_pmx_core {
+ uart3_pins_default: uart3_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3648, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
+ DRA7XX_CORE_IOPAD(0x364c, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */
+ >;
+ };
+
+ mmc1_pins_default: mmc1_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+ DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+ DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+ DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+ DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+ DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
+ DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1_sdcd.gpio6_27 */
+ DRA7XX_CORE_IOPAD(0x377c, PIN_INPUT | MUX_MODE14) /* mmc1_sdwp.gpio6_28 */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ >;
+ };
+
+ i2c5_pins_default: i2c5_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT| MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+ DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT| MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+ >;
+ };
+
+ lcd_pins_default: lcd_pins_default {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3564, PIN_OUTPUT | MUX_MODE14) /* vin2a_vsync0.gpio4_0 */
+ >;
+ };
+
+ hdmi_pins: pinmux_hdmi_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
+ DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
+ >;
+ };
+
+ hdmi_conn_pins: pinmux_hdmi_conn_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT | MUX_MODE14) /* spi1_cs2.gpio7_12 */
+ >;
+ };
+};
+
+&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>;
+};
+
+&mmc1 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_default>;
+
+ vmmc-supply = <&ldo1_reg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio6 28 GPIO_ACTIVE_HIGH>;
+};
+
+&usb1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+};
+
+&i2c5 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins_default>;
+ clock-frequency = <400000>;
+
+ eeprom_base: atmel@54 {
+ compatible = "atmel,24c08";
+ reg = <0x54>;
+ pagesize = <16>;
+ };
+
+ pca9555: pca9555@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&dss {
+ status = "ok";
+
+ vdda_video-supply = <&ldoln_reg>;
+
+ port {
+ dpi_lcd_out: endpoint@0 {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&lcd0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins_default>;
+
+ enable-gpios = <&pca9555 14 GPIO_ACTIVE_HIGH
+ &gpio4 0 GPIO_ACTIVE_HIGH>;
+
+ port {
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_lcd_out>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&hdmi {
+ status = "ok";
+ vdda-supply = <&ldo4_reg>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pins>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ lanes = <1 0 3 2 5 4 7 6>;
+ };
+ };
+};
+
+&hdmi_conn {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_conn_pins>;
+
+ hpd-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts
index 4e0ad3b..0962f2f 100644
--- a/arch/arm/boot/dts/animeo_ip.dts
+++ b/arch/arm/boot/dts/animeo_ip.dts
@@ -155,21 +155,21 @@
label = "keyswitch_in";
gpios = <&pioB 1 GPIO_ACTIVE_HIGH>;
linux,code = <28>;
- gpio-key,wakeup;
+ wakeup-source;
};
error_in {
label = "error_in";
gpios = <&pioB 2 GPIO_ACTIVE_HIGH>;
linux,code = <29>;
- gpio-key,wakeup;
+ wakeup-source;
};
btn {
label = "btn";
gpios = <&pioC 23 GPIO_ACTIVE_HIGH>;
linux,code = <31>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts
new file mode 100644
index 0000000..da755c9
--- /dev/null
+++ b/arch/arm/boot/dts/arm-realview-pb11mp.dts
@@ -0,0 +1,681 @@
+/*
+ * Copyright 2015 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 PB11MPcore";
+ compatible = "arm,realview-pb11mp";
+
+ chosen { };
+
+ aliases {
+ serial0 = &pb11mp_serial0;
+ serial1 = &pb11mp_serial1;
+ serial2 = &pb11mp_serial2;
+ serial3 = &pb11mp_serial3;
+ };
+
+ memory {
+ /*
+ * The PB11MPCore has 512 MiB memory @ 0x70000000
+ * and the first 256 are also remapped @ 0x00000000
+ */
+ reg = <0x70000000 0x20000000>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "arm,realview-smp";
+
+ MP11_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ MP11_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ MP11_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ MP11_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,arm11mpcore";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ /* Primary TestChip GIC synthesized with the CPU */
+ intc_tc11mp: interrupt-controller@1f000100 {
+ compatible = "arm,tc11mp-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0x1f001000 0x1000>,
+ <0x1f000100 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,l220-cache";
+ reg = <0x1f002000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>,
+ <0 30 IRQ_TYPE_LEVEL_HIGH>,
+ <0 31 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), probably for safety
+ * since th outer sync operation can cause the
+ * cache to hang unless disabled.
+ */
+ cache-size = <1048576>; // 1MB
+ cache-sets = <4096>;
+ cache-line-size = <32>;
+ arm,shared-override;
+ arm,parity-enable;
+ arm,outer-sync-disable;
+ };
+
+ scu@1f000000 {
+ compatible = "arm,arm11mp-scu";
+ reg = <0x1f000000 0x100>;
+ };
+
+ timer@1f000600 {
+ compatible = "arm,arm11mp-twd-timer";
+ reg = <0x1f000600 0x20>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <1 13 0xf04>;
+ };
+
+ watchdog@1f000620 {
+ compatible = "arm,arm11mp-twd-wdt";
+ reg = <0x1f000620 0x20>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <1 14 0xf04>;
+ };
+
+ /* PMU with one IRQ line per core */
+ pmu {
+ compatible = "arm,arm11mpcore-pmu";
+ interrupt-parent = <&intc_tc11mp>;
+ 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>;
+ interrupt-affinity = <&MP11_0>, <&MP11_1>, <&MP11_2>, <&MP11_3>;
+ };
+
+ /* 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;
+ };
+
+ veth: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "veth";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ xtal24mhz: xtal24mhz@24M {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ refclk32khz: refclk32khz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ 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>;
+ };
+
+ wdogclk: wdogclk@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>;
+ };
+
+ flash0@40000000 {
+ /* 2 * 32MiB NOR Flash memory */
+ compatible = "arm,vexpress-flash", "cfi-flash";
+ reg = <0x40000000 0x04000000>;
+ bank-width = <4>;
+ };
+
+ flash1@44000000 {
+ // 2 * 32MiB NOR Flash memory
+ compatible = "arm,vexpress-flash", "cfi-flash";
+ reg = <0x44000000 0x04000000>;
+ bank-width = <4>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,realview-pb11mp-soc", "simple-bus";
+ regmap = <&pb11mp_syscon>;
+ ranges;
+
+ pb11mp_syscon: syscon@10000000 {
+ compatible = "arm,realview-pb11mp-syscon", "syscon", "simple-mfd";
+ 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";
+ linux,default-trigger = "cpu1";
+ default-state = "off";
+ };
+ led@08.4 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x10>;
+ label = "versatile:4";
+ linux,default-trigger = "cpu2";
+ default-state = "off";
+ };
+ led@08.5 {
+ compatible = "register-bit-led";
+ offset = <0x08>;
+ mask = <0x20>;
+ label = "versatile:5";
+ linux,default-trigger = "cpu3";
+ 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";
+ };
+
+ oscclk0: osc0@0c {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0x0C>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk1: osc1@10 {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0x10>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk2: osc2@14 {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0x14>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk3: osc3@18 {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0x18>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk4: osc4@1c {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0x1c>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk5: osc5@d4 {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0xd4>;
+ clocks = <&xtal24mhz>;
+ };
+ oscclk6: osc6@d8 {
+ compatible = "arm,syscon-icst307";
+ #clock-cells = <0>;
+ lock-offset = <0x20>;
+ vco-offset = <0xd8>;
+ clocks = <&xtal24mhz>;
+ };
+ };
+
+ sp810_syscon: sysctl@10001000 {
+ compatible = "arm,sp810", "arm,primecell";
+ reg = <0x10001000 0x1000>;
+ clocks = <&refclk32khz>, <&timclk>, <&xtal24mhz>;
+ clock-names = "refclk", "timclk", "apb_pclk";
+ #clock-cells = <1>;
+ clock-output-names = "timerclk0",
+ "timerclk1",
+ "timerclk2",
+ "timerclk3";
+ assigned-clocks = <&sp810_syscon 0>,
+ <&sp810_syscon 1>,
+ <&sp810_syscon 2>,
+ <&sp810_syscon 3>;
+ assigned-clock-parents = <&timclk>,
+ <&timclk>,
+ <&timclk>,
+ <&timclk>;
+ };
+
+ i2c0: i2c@10002000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "arm,versatile-i2c";
+ reg = <0x10002000 0x1000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1338";
+ reg = <0x68>;
+ };
+ };
+
+ aaci: aaci@10004000 {
+ compatible = "arm,pl041", "arm,primecell";
+ reg = <0x10004000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ mci: mmcsd@10005000 {
+ compatible = "arm,pl18x", "arm,primecell";
+ reg = <0x10005000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>,
+ <0 15 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 = <&gpio2 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ kmi0: kmi@10006000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x10006000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi1: kmi@10007000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x10007000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&kmiclk>, <&pclk>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ pb11mp_serial0: serial@10009000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x10009000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb11mp_serial1: serial@1000a000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1000a000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb11mp_serial2: serial@1000b000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1000b000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ pb11mp_serial3: serial@1000c000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x1000c000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&pclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ ssp@1000d000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x1000d000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sspclk>, <&pclk>;
+ clock-names = "SSPCLK", "apb_pclk";
+ };
+
+ watchdog@1000f000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x1000f000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&wdogclk>, <&pclk>;
+ clock-names = "wdogclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ watchdog@10010000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0x10010000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&wdogclk>, <&pclk>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ timer01: timer@10011000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10011000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>;
+ arm,sp804-has-irq = <1>;
+ clocks = <&sp810_syscon 0>,
+ <&sp810_syscon 1>,
+ <&pclk>;
+ clock-names = "timerclk0",
+ "timerclk1",
+ "apb_pclk";
+ };
+
+ timer23: timer@10012000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10012000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
+ arm,sp804-has-irq = <1>;
+ clocks = <&sp810_syscon 2>,
+ <&sp810_syscon 3>,
+ <&pclk>;
+ clock-names = "timerclk2",
+ "timerclk3",
+ "apb_pclk";
+ };
+
+ gpio0: gpio@10013000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x10013000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio1: gpio@10014000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x10014000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ gpio2: gpio@10015000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0x10015000 0x1000>;
+ gpio-controller;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ rtc: rtc@10017000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x10017000 0x1000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ };
+
+ timer45: timer@10018000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10018000 0x1000>;
+ clocks = <&timclk>, <&pclk>;
+ clock-names = "timer", "apb_pclk";
+ status = "disabled";
+ };
+
+ timer67: timer@10019000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x10019000 0x1000>;
+ clocks = <&timclk>, <&pclk>;
+ clock-names = "timer", "apb_pclk";
+ status = "disabled";
+ };
+
+
+ clcd@10020000 {
+ compatible = "arm,pl111", "arm,primecell";
+ reg = <0x10020000 0x1000>;
+ interrupt-parent = <&intc_pb11mp>;
+ interrupt-names = "combined";
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&oscclk4>, <&pclk>;
+ 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>;
+ };
+ };
+ };
+
+ /*
+ * This GIC on the Platform Baseboard is cascaded off the
+ * TestChip GIC
+ */
+ intc_pb11mp: interrupt-controller@1e000000 {
+ compatible = "arm,arm11mp-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0x1e001000 0x1000>,
+ <0x1e000000 0x100>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* SMSC 9118 ethernet with PHY and EEPROM */
+ ethernet@4e000000 {
+ compatible = "smsc,lan9118", "smsc,lan9115";
+ reg = <0x4e000000 0x10000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ phy-mode = "mii";
+ reg-io-width = <4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ vdd33a-supply = <&veth>;
+ vddvario-supply = <&veth>;
+ };
+
+ usb@4f000000 {
+ compatible = "nxp,usb-isp1761";
+ reg = <0x4f000000 0x20000>;
+ interrupt-parent = <&intc_tc11mp>;
+ interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>;
+ port1-otg;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 03542f7..bb280de 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -74,7 +74,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
internal-regs {
serial@12000 {
diff --git a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
index af4dc54..e2a363b 100644
--- a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
+++ b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
@@ -69,7 +69,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index 0f40d5d..3aa980a 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -61,7 +61,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
pcie-controller {
status = "okay";
@@ -138,6 +139,10 @@
phy-mode = "rgmii-id";
};
+ crypto@90000 {
+ status = "okay";
+ };
+
mvsdio@d4000 {
pinctrl-0 = <&sdio_pins3>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index a312078..39181b3 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -63,7 +63,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
pcie-controller {
status = "okay";
@@ -82,6 +83,12 @@
};
internal-regs {
+
+ /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+ rtc@10300 {
+ status = "disabled";
+ };
+
serial@12000 {
status = "okay";
};
@@ -120,7 +127,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
- isil,irq2-can-wakeup-machine;
+ wakeup-source;
};
g762: g762@3e {
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index 00540f2..faa4748 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -63,7 +63,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
pcie-controller {
status = "okay";
@@ -82,6 +83,12 @@
};
internal-regs {
+
+ /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+ rtc@10300 {
+ status = "disabled";
+ };
+
serial@12000 {
status = "okay";
};
@@ -126,7 +133,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
- isil,irq2-can-wakeup-machine;
+ wakeup-source;
};
g762: g762@3e {
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index 19475e6..fbef730 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -74,7 +74,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts b/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts
new file mode 100644
index 0000000..fef0110
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts
@@ -0,0 +1,36 @@
+/*
+ * Device Tree file for Seagate NAS 2-Bay (Armada 370 SoC).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort@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.
+ */
+
+/*
+ * Here are some information allowing to identify the device:
+ *
+ * Product name : Seagate NAS 2-Bay
+ * Code name (board/PCB) : Dart 2-Bay
+ * Model name (case sticker) : SRPD20
+ * Material desc (product spec) : STCTxxxxxxx
+ */
+
+/dts-v1/;
+#include "armada-370-seagate-nas-xbay.dtsi"
+
+/ {
+ model = "Seagate NAS 2-Bay (Dart, SRPD20)";
+ compatible = "seagate,dart-2", "marvell,armada370", "marvell,armada-370-xp";
+
+ gpio-fan {
+ gpio-fan,speed-map =
+ < 0 3
+ 950 2
+ 1400 1
+ 1800 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
new file mode 100644
index 0000000..ae2e1fe
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts
@@ -0,0 +1,133 @@
+/*
+ * Device Tree file for Seagate NAS 4-Bay (Armada 370 SoC).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort@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.
+ */
+
+/*
+ * Here are some information allowing to identify the device:
+ *
+ * Product name : Seagate NAS 4-Bay
+ * Code name (board/PCB) : Dart 4-Bay
+ * Model name (case sticker) : SRPD40
+ * Material desc (product spec) : STCUxxxxxxx
+ */
+
+/dts-v1/;
+#include "armada-370-seagate-nas-xbay.dtsi"
+#include <dt-bindings/leds/leds-ns2.h>
+
+/ {
+ model = "Seagate NAS 4-Bay (Dart, SRPD40)";
+ compatible = "seagate,dart-4", "marvell,armada370", "marvell,armada-370-xp";
+
+ soc {
+ pcie-controller {
+ /* SATA AHCI controller 88SE9170 */
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ mdio {
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ ethernet@74000 {
+ status = "okay";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ i2c@11000 {
+ /* I2C GPIO expander (PCA9554A) */
+ pca9554: pca9554@21 {
+ compatible = "nxp,pca9554";
+ reg = <0x21>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+ };
+ };
+ };
+
+ regulators {
+ regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ regulator-name = "SATA2 power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pca9554 6 GPIO_ACTIVE_HIGH>;
+ };
+ regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ regulator-name = "SATA3 power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&pca9554 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ red-sata2 {
+ label = "dart:red:sata2";
+ gpios = <&pca9554 0 GPIO_ACTIVE_LOW>;
+ };
+ red-sata3 {
+ label = "dart:red:sata3";
+ gpios = <&pca9554 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds-ns2 {
+ compatible = "lacie,ns2-leds";
+
+ white-sata2 {
+ label = "dart:white:sata2";
+ cmd-gpio = <&pca9554 1 GPIO_ACTIVE_HIGH>;
+ slow-gpio = <&pca9554 2 GPIO_ACTIVE_HIGH>;
+ num-modes = <4>;
+ modes-map = <NS_V2_LED_SATA 0 0
+ NS_V2_LED_OFF 0 1
+ NS_V2_LED_ON 1 0
+ NS_V2_LED_ON 1 1>;
+ };
+ white-sata3 {
+ label = "dart:white:sata3";
+ cmd-gpio = <&pca9554 4 GPIO_ACTIVE_HIGH>;
+ slow-gpio = <&pca9554 5 GPIO_ACTIVE_HIGH>;
+ num-modes = <4>;
+ modes-map = <NS_V2_LED_SATA 0 0
+ NS_V2_LED_OFF 0 1
+ NS_V2_LED_ON 1 0
+ NS_V2_LED_ON 1 1>;
+ };
+ };
+
+ gpio-fan {
+ gpio-fan,speed-map =
+ < 0 3
+ 800 2
+ 1050 1
+ 1300 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
new file mode 100644
index 0000000..3036e25
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi
@@ -0,0 +1,231 @@
+/*
+ * Device Tree common file for the Seagate NAS 2 and 4-bay (Armada 370 SoC).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort@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.
+ */
+
+/*
+ * TODO: add support for the white SATA LEDs associated with HDD 0 and 1.
+ */
+
+#include "armada-370.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ 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";
+
+ /* USB 3.0 bridge ASM1042A */
+ pcie@2,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";
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ i2c@11000 {
+ status = "okay";
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+
+ /* RTC - NXP 8563T (second source) */
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ interrupts = <110>;
+ };
+ /* RTC - MCP7940NT */
+ rtc@6f {
+ compatible = "microchip,mcp7941x";
+ reg = <0x6f>;
+ interrupts = <110>;
+ };
+ };
+
+ 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 = <0x0 0x300000>;
+ };
+ partition@300000 {
+ label = "device-tree";
+ reg = <0x300000 0x20000>;
+ };
+ partition@320000 {
+ label = "linux";
+ reg = <0x320000 0x2000000>;
+ };
+ partition@2320000 {
+ label = "rootfs";
+ reg = <0x2320000 0xdce0000>;
+ };
+ };
+ };
+
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+
+ 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 18 GPIO_ACTIVE_HIGH>;
+ };
+ 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 22 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio2 0 GPIO_ACTIVE_HIGH
+ &gpio2 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Power button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ button@2 {
+ label = "Backup button";
+ linux,code = <KEY_OPTION>;
+ gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ button@3 {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ white-power {
+ label = "dart:white:power";
+ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "timer";
+
+ };
+ red-power {
+ label = "dart:red:power";
+ gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+ };
+ red-sata0 {
+ label = "dart:red:sata0";
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+ red-sata1 {
+ label = "dart:red:sata1";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&hdd0_led_sata_pin>, <&hdd1_led_sata_pin>;
+ pinctrl-names = "default";
+
+ hdd0_led_sata_pin: hdd0-led-sata-pin {
+ marvell,pins = "mpp48";
+ marvell,function = "sata1";
+ };
+ hdd0_led_gpio_pin: hdd0-led-gpio-pin {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+ hdd1_led_sata_pin: hdd1-led-sata-pin {
+ marvell,pins = "mpp57";
+ marvell,function = "sata0";
+ };
+ hdd1_led_gpio_pin: hdd1-led-gpio-pin {
+ marvell,pins = "mpp57";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts b/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts
new file mode 100644
index 0000000..3c91f98
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts
@@ -0,0 +1,51 @@
+/*
+ * Device Tree file for Seagate Personal Cloud NAS 2-Bay (Armada 370 SoC).
+ *
+ * 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.
+ */
+
+/*
+ * Here are some information allowing to identify the device:
+ *
+ * Product name : Seagate Personal Cloud 2-Bay
+ * Code name (board/PCB) : Cumulus Max
+ * Model name (case sticker) : SRN22C
+ * Material desc (product spec) : STCSxxxxxxx
+ */
+
+/dts-v1/;
+#include "armada-370-seagate-personal-cloud.dtsi"
+
+/ {
+ model = "Seagate Personal Cloud 2-Bay (Cumulus, SRN22C)";
+ compatible = "seagate,cumulus-max", "marvell,armada370", "marvell,armada-370-xp";
+
+ soc {
+ internal-regs {
+ sata@a0000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+ };
+ };
+
+ regulators {
+ 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 22 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts
new file mode 100644
index 0000000..aad39e9
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts
@@ -0,0 +1,37 @@
+/*
+ * Device Tree file for Seagate Personal Cloud NAS (Armada 370 SoC).
+ *
+ * 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.
+ */
+
+/*
+ * Here are some information allowing to identify the device:
+ *
+ * Product name : Seagate Personal Cloud
+ * Code name (board/PCB) : Cumulus
+ * Model name (case sticker) : SRN21C
+ * Material desc (product spec) : STCRxxxxxxx
+ */
+
+/dts-v1/;
+#include "armada-370-seagate-personal-cloud.dtsi"
+
+/ {
+ model = "Seagate Personal Cloud (Cumulus, SRN21C)";
+ compatible = "seagate,cumulus", "marvell,armada370", "marvell,armada-370-xp";
+
+ soc {
+ internal-regs {
+ sata@a0000 {
+ status = "okay";
+ nr-ports = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
new file mode 100644
index 0000000..1aba08e
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi
@@ -0,0 +1,178 @@
+/*
+ * Device Tree common file for the Seagate Personal Cloud NAS 1 and 2-Bay
+ * (Armada 370 SoC).
+ *
+ * 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.
+ */
+
+/*
+ * TODO: add support for the white SATA LED.
+ */
+
+#include "armada-370.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ 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";
+
+ /* USB 3.0 Bridge ASM1042A */
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ coherency-fabric@20200 {
+ broken-idle;
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ ethernet@74000 {
+ status = "okay";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ spi@10600 {
+ status = "okay";
+ pinctrl-0 = <&spi0_pins2>;
+ pinctrl-names = "default";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* MX25L8006E */
+ compatible = "mxicy,mx25l8005", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x100000>;
+ };
+ };
+ };
+
+ usb@50000 {
+ status = "okay";
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio1 27 GPIO_ACTIVE_LOW>;
+ };
+ 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 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@1 {
+ label = "Power button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+ debounce-interval = <100>;
+ };
+ button@2 {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ button@3 {
+ label = "USB VBUS error";
+ linux,code = <KEY_UNKNOWN>;
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ debounce-interval = <100>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ red-sata0 {
+ label = "cumulus:red:sata0";
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = <&sata_led_pin>;
+ pinctrl-names = "default";
+
+ sata_led_pin: sata-led-pin {
+ marvell,pins = "mpp60";
+ marvell,function = "sata0";
+ };
+ gpio_led_pin: gpio-led-pin {
+ marvell,pins = "mpp60";
+ 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
index 4f49243..836bcc0 100644
--- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -77,7 +77,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
internal-regs {
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 53a1a5a..3b06aa8 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -256,6 +256,11 @@
reg = <0x20800 0x8>;
};
+ cpu-config@21000 {
+ compatible = "marvell,armada-370-cpu-config";
+ reg = <0x21000 0x8>;
+ };
+
audio_controller: audio-controller@30000 {
#sound-dai-cells = <1>;
compatible = "marvell,armada370-audio";
@@ -319,6 +324,38 @@
ethernet@74000 {
compatible = "marvell,armada-370-neta";
};
+
+ crypto@90000 {
+ compatible = "marvell,armada-370-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <48>;
+ clocks = <&gateclk 23>;
+ clock-names = "cesa0";
+ marvell,crypto-srams = <&crypto_sram>;
+ marvell,crypto-sram-size = <0x7e0>;
+ };
+ };
+
+ crypto_sram: sa-sram {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x01) 0 0x800>;
+ reg-names = "sram";
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x01) 0 0x800>;
+
+ /*
+ * The Armada 370 has an erratum preventing the use of
+ * the standard workflow for CPU idle support (relying
+ * on the BootROM code to enter/exit idle state).
+ * Reserve some amount of the crypto SRAM to put the
+ * cpuidle workaround.
+ */
+ idle-sram@0 {
+ reg = <0x0 0x20>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
index 5711b97..cded5f0 100644
--- a/arch/arm/boot/dts/armada-375-db.dts
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -65,7 +65,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
internal-regs {
spi@10600 {
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index e9a3817..7ccce75 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -513,6 +513,21 @@
};
};
+ crypto@90000 {
+ compatible = "marvell,armada-375-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>, <&gateclk 31>,
+ <&gateclk 28>, <&gateclk 29>;
+ clock-names = "cesa0", "cesa1",
+ "cesaz0", "cesaz1";
+ marvell,crypto-srams = <&crypto_sram0>,
+ <&crypto_sram1>;
+ marvell,crypto-sram-size = <0x800>;
+ };
+
sata@a0000 {
compatible = "marvell,orion-sata";
reg = <0xa0000 0x5000>;
@@ -619,5 +634,23 @@
};
};
+
+ crypto_sram0: sa-sram0 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x09) 0 0x800>;
+ clocks = <&gateclk 30>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>;
+ };
+
+ crypto_sram1: sa-sram1 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x05) 0 0x800>;
+ clocks = <&gateclk 31>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
index 4047621..5f9451b 100644
--- a/arch/arm/boot/dts/armada-385-db-ap.dts
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -59,7 +59,10 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi1: spi@10680 {
@@ -136,12 +139,18 @@
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
+ bm,pool-short = <3>;
};
ethernet@34000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
ethernet@70000 {
@@ -155,6 +164,13 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <3>;
+ };
+
+ bm@c8000 {
+ status = "okay";
};
nfc: flash@d0000 {
@@ -176,6 +192,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
index 74a9c6b..3710755 100644
--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
@@ -57,7 +57,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
internal-regs {
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
new file mode 100644
index 0000000..c60206e
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-clearfog.dts
@@ -0,0 +1,462 @@
+/*
+ * Device Tree file for SolidRun Clearfog revision A1 rev 2.0 (88F6828)
+ *
+ * Copyright (C) 2015 Russell King
+ *
+ * This board is in development; the contents of this file work with
+ * the A1 rev 2.0 of the board, which does not represent final
+ * production board. Things will change, don't expect this file to
+ * remain compatible info the future.
+ *
+ * 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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"
+#include "armada-38x-solidrun-microsom.dtsi"
+
+/ {
+ model = "SolidRun Clearfog A1";
+ compatible = "solidrun,clearfog-a1", "marvell,armada388",
+ "marvell,armada385", "marvell,armada380";
+
+ aliases {
+ /* So that mvebu u-boot can update the MAC addresses */
+ ethernet1 = &eth0;
+ ethernet2 = &eth1;
+ ethernet3 = &eth2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ soc {
+ internal-regs {
+ ethernet@30000 {
+ phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <1>;
+ status = "okay";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ ethernet@34000 {
+ phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
+ bm,pool-short = <1>;
+ status = "okay";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ i2c@11000 {
+ /* Is there anything on this? */
+ clock-frequency = <100000>;
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ /*
+ * PCA9655 GPIO expander, up to 1MHz clock.
+ * 0-CON3 CLKREQ#
+ * 1-CON3 PERST#
+ * 2-CON2 PERST#
+ * 3-CON3 W_DISABLE
+ * 4-CON2 CLKREQ#
+ * 5-USB3 overcurrent
+ * 6-USB3 power
+ * 7-CON2 W_DISABLE
+ * 8-JP4 P1
+ * 9-JP4 P4
+ * 10-JP4 P5
+ * 11-m.2 DEVSLP
+ * 12-SFP_LOS
+ * 13-SFP_TX_FAULT
+ * 14-SFP_TX_DISABLE
+ * 15-SFP_MOD_DEF0
+ */
+ expander0: gpio-expander@20 {
+ /*
+ * This is how it should be:
+ * compatible = "onnn,pca9655",
+ * "nxp,pca9555";
+ * but you can't do this because of
+ * the way I2C works.
+ */
+ compatible = "nxp,pca9555";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20>;
+
+ pcie1_0_clkreq {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "pcie1.0-clkreq";
+ };
+ pcie1_0_w_disable {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "pcie1.0-w-disable";
+ };
+ pcie2_0_clkreq {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "pcie2.0-clkreq";
+ };
+ pcie2_0_w_disable {
+ gpio-hog;
+ gpios = <7 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "pcie2.0-w-disable";
+ };
+ usb3_ilimit {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "usb3-current-limit";
+ };
+ usb3_power {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "usb3-power";
+ };
+ m2_devslp {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "m.2 devslp";
+ };
+ sfp_los {
+ /* SFP loss of signal */
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "sfp-los";
+ };
+ sfp_tx_fault {
+ /* SFP laser fault */
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "sfp-tx-fault";
+ };
+ sfp_tx_disable {
+ /* SFP transmit disable */
+ gpio-hog;
+ gpios = <14 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "sfp-tx-disable";
+ };
+ sfp_mod_def0 {
+ /* SFP module present */
+ gpio-hog;
+ gpios = <15 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "sfp-mod-def0";
+ };
+ };
+
+ /* The MCP3021 is 100kHz clock only */
+ mikrobus_adc: mcp3021@4c {
+ compatible = "microchip,mcp3021";
+ reg = <0x4c>;
+ };
+
+ /* Also something at 0x64 */
+ };
+
+ i2c@11100 {
+ /*
+ * Routed to SFP, mikrobus, and PCIe.
+ * SFP limits this to 100kHz, and requires
+ * an AT24C01A/02/04 with address pins tied
+ * low, which takes addresses 0x50 and 0x51.
+ * Mikrobus doesn't specify beyond an I2C
+ * bus being present.
+ * PCIe uses ARP to assign addresses, or
+ * 0x63-0x64.
+ */
+ clock-frequency = <100000>;
+ pinctrl-0 = <&clearfog_i2c1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ mdio@72004 {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ phy_dedicated: ethernet-phy@0 {
+ /*
+ * Annoyingly, the marvell phy driver
+ * configures the LED register, rather
+ * than preserving reset-loaded setting.
+ * We undo that rubbish here.
+ */
+ marvell,reg-init = <3 16 0 0x101e>;
+ reg = <0>;
+ };
+ };
+
+ pinctrl@18000 {
+ clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins {
+ marvell,pins = "mpp46";
+ marvell,function = "ref";
+ };
+ clearfog_dsa0_pins: clearfog-dsa0-pins {
+ marvell,pins = "mpp23", "mpp41";
+ marvell,function = "gpio";
+ };
+ clearfog_i2c1_pins: i2c1-pins {
+ /* SFP, PCIe, mSATA, mikrobus */
+ marvell,pins = "mpp26", "mpp27";
+ marvell,function = "i2c1";
+ };
+ clearfog_sdhci_cd_pins: clearfog-sdhci-cd-pins {
+ marvell,pins = "mpp20";
+ marvell,function = "gpio";
+ };
+ clearfog_sdhci_pins: clearfog-sdhci-pins {
+ marvell,pins = "mpp21", "mpp28",
+ "mpp37", "mpp38",
+ "mpp39", "mpp40";
+ marvell,function = "sd0";
+ };
+ clearfog_spi1_cs_pins: spi1-cs-pins {
+ marvell,pins = "mpp55";
+ marvell,function = "spi1";
+ };
+ mikro_pins: mikro-pins {
+ /* int: mpp22 rst: mpp29 */
+ marvell,pins = "mpp22", "mpp29";
+ marvell,function = "gpio";
+ };
+ mikro_spi_pins: mikro-spi-pins {
+ marvell,pins = "mpp43";
+ marvell,function = "spi1";
+ };
+ mikro_uart_pins: mikro-uart-pins {
+ marvell,pins = "mpp24", "mpp25";
+ marvell,function = "ua1";
+ };
+ rear_button_pins: rear-button-pins {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+ };
+
+ sata@a8000 {
+ /* pinctrl? */
+ status = "okay";
+ };
+
+ sata@e0000 {
+ /* pinctrl? */
+ status = "okay";
+ };
+
+ sdhci@d8000 {
+ bus-width = <4>;
+ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ pinctrl-0 = <&clearfog_sdhci_pins
+ &clearfog_sdhci_cd_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ vmmc = <&reg_3p3v>;
+ wp-inverted;
+ };
+
+ serial@12100 {
+ /* mikrobus uart */
+ pinctrl-0 = <&mikro_uart_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ spi@10680 {
+ /*
+ * We don't seem to have the W25Q32 on the
+ * A1 Rev 2.0 boards, so disable SPI.
+ * CS0: W25Q32 (doesn't appear to be present)
+ * CS1:
+ * CS2: mikrobus
+ */
+ pinctrl-0 = <&spi1_pins
+ &clearfog_spi1_cs_pins
+ &mikro_spi_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "w25q32", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <3000000>;
+ status = "disabled";
+ };
+ };
+
+ usb@58000 {
+ /* CON3, nearest power. */
+ status = "okay";
+ };
+
+ usb3@f0000 {
+ /* CON2, nearest CPU, USB2 only. */
+ status = "okay";
+ };
+
+ usb3@f8000 {
+ /* CON7 */
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * the mini-PCIe connectors on the board.
+ */
+ pcie@2,0 {
+ /* Port 1, Lane 0. CON3, nearest power. */
+ reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 2, Lane 0. CON2, nearest CPU. */
+ reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+ };
+ };
+
+ dsa@0 {
+ compatible = "marvell,dsa";
+ dsa,ethernet = <&eth1>;
+ dsa,mii-bus = <&mdio>;
+ pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>;
+ pinctrl-names = "default";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ switch@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4 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@4 {
+ reg = <4>;
+ label = "lan5";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ };
+
+ port@6 {
+ /* 88E1512 external phy */
+ reg = <6>;
+ label = "lan6";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&rear_button_pins>;
+ pinctrl-names = "default";
+
+ button_0 {
+ /* The rear SW3 button */
+ label = "Rear Button";
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ linux,can-disable;
+ linux,code = <BTN_0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts
index 91ac8c1..ea93ed7 100644
--- a/arch/arm/boot/dts/armada-388-db.dts
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -64,7 +64,10 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi@10600 {
@@ -97,6 +100,9 @@
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
usb@58000 {
@@ -107,6 +113,9 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
};
mdio@72004 {
@@ -127,6 +136,10 @@
status = "okay";
};
+ bm@c8000 {
+ status = "okay";
+ };
+
flash@d0000 {
status = "okay";
num-cs = <1>;
@@ -167,6 +180,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
/*
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
index 353c925..466b01e 100644
--- a/arch/arm/boot/dts/armada-388-gp.dts
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -58,7 +58,10 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi@10600 {
@@ -131,6 +134,9 @@
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
/* CON4 */
@@ -150,6 +156,9 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
};
@@ -184,6 +193,10 @@
};
};
+ bm@c8000 {
+ status = "okay";
+ };
+
sata@e0000 {
pinctrl-names = "default";
pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
@@ -205,8 +218,21 @@
sdhci@d8000 {
pinctrl-names = "default";
pinctrl-0 = <&sdhci_pins>;
- cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
no-1-8-v;
+ /*
+ * A388-GP board v1.5 and higher replace
+ * hitherto card detection method based on GPIO
+ * with the one using DAT3 pin. As they are
+ * incompatible, software-based polling is
+ * enabled with 'broken-cd' property. For boards
+ * older than v1.5 it can be replaced with:
+ * 'cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;',
+ * whereas for the newer ones following can be
+ * used instead:
+ * 'dat3-cd;'
+ * 'cd-inverted;'
+ */
+ broken-cd;
wp-inverted;
bus-width = <8>;
status = "okay";
@@ -225,6 +251,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
/*
@@ -288,16 +318,6 @@
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";
diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts
index b657b16..853f973 100644
--- a/arch/arm/boot/dts/armada-388-rd.dts
+++ b/arch/arm/boot/dts/armada-388-rd.dts
@@ -65,7 +65,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
internal-regs {
spi@10600 {
diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
new file mode 100644
index 0000000..8c98422
--- /dev/null
+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
@@ -0,0 +1,128 @@
+/*
+ * Device Tree file for SolidRun Armada 38x Microsom
+ *
+ * Copyright (C) 2015 Russell King
+ *
+ * This board is in development; the contents of this file work with
+ * the A1 rev 2.0 of the board, which does not represent final
+ * production board. Things will change, don't expect this file to
+ * remain compatible info the future.
+ *
+ * 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ 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
+ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
+
+ internal-regs {
+ ethernet@70000 {
+ pinctrl-0 = <&ge0_rgmii_pins>;
+ pinctrl-names = "default";
+ phy = <&phy_dedicated>;
+ phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
+ status = "okay";
+ };
+
+ mdio@72004 {
+ /*
+ * Add the phy clock here, so the phy can be
+ * accessed to read its IDs prior to binding
+ * with the driver.
+ */
+ pinctrl-0 = <&mdio_pins &microsom_phy_clk_pins>;
+ pinctrl-names = "default";
+
+ phy_dedicated: ethernet-phy@0 {
+ /*
+ * Annoyingly, the marvell phy driver
+ * configures the LED register, rather
+ * than preserving reset-loaded setting.
+ * We undo that rubbish here.
+ */
+ marvell,reg-init = <3 16 0 0x101e>;
+ reg = <0>;
+ };
+ };
+
+ pinctrl@18000 {
+ microsom_phy_clk_pins: microsom-phy-clk-pins {
+ marvell,pins = "mpp45";
+ marvell,function = "ref";
+ };
+ };
+
+ rtc@a3800 {
+ /*
+ * If the rtc doesn't work, run "date reset"
+ * twice in u-boot.
+ */
+ status = "okay";
+ };
+
+ serial@12000 {
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ bm@c8000 {
+ status = "okay";
+ };
+ };
+
+ bm-bppi {
+ status = "okay";
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index f9f2347..066a8f0 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -498,6 +498,7 @@
reg = <0x70000 0x4000>;
interrupts-extended = <&mpic 8>;
clocks = <&gateclk 4>;
+ tx-csum-limit = <9800>;
status = "disabled";
};
@@ -509,6 +510,21 @@
clocks = <&gateclk 4>;
};
+ crypto@90000 {
+ compatible = "marvell,armada-38x-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 23>, <&gateclk 21>,
+ <&gateclk 14>, <&gateclk 16>;
+ clock-names = "cesa0", "cesa1",
+ "cesaz0", "cesaz1";
+ marvell,crypto-srams = <&crypto_sram0>,
+ <&crypto_sram1>;
+ marvell,crypto-sram-size = <0x800>;
+ };
+
rtc@a3800 {
compatible = "marvell,armada-380-rtc";
reg = <0xa3800 0x20>, <0x184a0 0x0c>;
@@ -524,6 +540,14 @@
status = "disabled";
};
+ bm: bm@c8000 {
+ compatible = "marvell,armada-380-neta-bm";
+ reg = <0xc8000 0xac>;
+ clocks = <&gateclk 13>;
+ internal-mem = <&bm_bppi>;
+ status = "disabled";
+ };
+
sata@e0000 {
compatible = "marvell,armada-380-ahci";
reg = <0xe0000 0x2000>;
@@ -584,6 +608,35 @@
status = "disabled";
};
};
+
+ crypto_sram0: sa-sram0 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x19) 0 0x800>;
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x19) 0 0x800>;
+ };
+
+ crypto_sram1: sa-sram1 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x15) 0 0x800>;
+ clocks = <&gateclk 21>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x15) 0 0x800>;
+ };
+
+ bm_bppi: bm-bppi {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&gateclk 13>;
+ no-memory-wc;
+ status = "disabled";
+ };
};
clocks {
diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
index 60bbfe3..5c21b23 100644
--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -69,7 +69,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 7dd900f..cca3665 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -75,7 +75,10 @@
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>;
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -179,21 +182,33 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
+ };
+
+ bm@c0000 {
+ status = "okay";
};
mvsdio@d4000 {
@@ -228,5 +243,9 @@
};
};
};
+
+ bm-bppi {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index bf724ca9..061f423 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -94,7 +94,10 @@
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>;
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -194,21 +197,29 @@
status = "okay";
phy = <&phy0>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
};
/* Front-side USB slot */
@@ -233,6 +244,10 @@
};
};
+ bm@c0000 {
+ status = "okay";
+ };
+
nand@d0000 {
status = "okay";
num-cs = <1>;
@@ -241,5 +256,9 @@
nand-on-flash-bbt;
};
};
+
+ bm-bppi {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
index 06a6a6c..8af463f 100644
--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -64,7 +64,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
pcie-controller {
status = "okay";
@@ -149,42 +151,43 @@
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>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x000e0000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "u-boot-env";
+ reg = <0x000e0000 0x00020000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env2";
+ reg = <0x00100000 0x00020000>;
+ read-only;
+ };
+
+ partition@120000 {
+ label = "zImage";
+ reg = <0x00120000 0x00400000>;
+ };
+
+ partition@520000 {
+ label = "initrd";
+ reg = <0x00520000 0x00400000>;
+ };
+
+ partition@e00000 {
+ label = "boot";
+ reg = <0x00e00000 0x3f200000>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index fdd187c..b89e6cf 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -69,7 +69,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
index f894bc8..6522b04 100644
--- a/arch/arm/boot/dts/armada-xp-matrix.dts
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -67,7 +67,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
internal-regs {
serial@12000 {
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index 1516fc2..d19f44c 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -63,7 +63,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
pcie-controller {
status = "okay";
@@ -88,41 +90,10 @@
};
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";
+ /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+ rtc@10300 {
+ status = "disabled";
};
i2c@11000 {
@@ -130,12 +101,6 @@
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 {
@@ -172,6 +137,49 @@
compatible = "gmt,g751";
reg = <0x4c>;
};
+
+ isl12057: isl12057@68 {
+ compatible = "isil,isl12057";
+ reg = <0x68>;
+ wakeup-source;
+ };
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ /* Front USB 2.0 port */
+ usb@50000 {
+ 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";
+ };
+
+ /* Two rear eSATA ports */
+ sata@a0000 {
+ nr-ports = <2>;
+ status = "okay";
};
nand@d0000 {
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index 990e8a2..ed3b889d 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -65,7 +65,10 @@
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>;
+ MBUS_ID(0x01, 0x2f) 0 0 0xe8000000 0x8000000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xd1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -174,21 +177,29 @@
status = "okay";
phy = <&phy0>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
};
i2c@11000 {
status = "okay";
@@ -217,6 +228,14 @@
usb@51000 {
status = "okay";
};
+
+ bm@c0000 {
+ status = "okay";
+ };
+ };
+
+ bm-bppi {
+ status = "okay";
};
};
};
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
index 20267ad..d17dab0 100644
--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -77,7 +77,9 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 3de9b76..553349c 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -184,6 +184,11 @@
reg = <0x20800 0x20>;
};
+ cpu-config@21000 {
+ compatible = "marvell,armada-xp-cpu-config";
+ reg = <0x21000 0x8>;
+ };
+
eth2: ethernet@30000 {
compatible = "marvell,armada-xp-neta";
reg = <0x30000 0x4000>;
@@ -236,6 +241,26 @@
compatible = "marvell,armada-xp-neta";
};
+ crypto@90000 {
+ compatible = "marvell,armada-xp-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <48>, <49>;
+ clocks = <&gateclk 23>, <&gateclk 23>;
+ clock-names = "cesa0", "cesa1";
+ marvell,crypto-srams = <&crypto_sram0>,
+ <&crypto_sram1>;
+ marvell,crypto-sram-size = <0x800>;
+ };
+
+ bm: bm@c0000 {
+ compatible = "marvell,armada-380-neta-bm";
+ reg = <0xc0000 0xac>;
+ clocks = <&gateclk 13>;
+ internal-mem = <&bm_bppi>;
+ status = "disabled";
+ };
+
xor@f0900 {
compatible = "marvell,orion-xor";
reg = <0xF0900 0x100
@@ -256,6 +281,35 @@
};
};
};
+
+ crypto_sram0: sa-sram0 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x09) 0 0x800>;
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>;
+ };
+
+ crypto_sram1: sa-sram1 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x05) 0 0x800>;
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
+ };
+
+ bm_bppi: bm-bppi {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&gateclk 13>;
+ no-memory-wc;
+ status = "disabled";
+ };
};
clocks {
diff --git a/arch/arm/boot/dts/at91-foxg20.dts b/arch/arm/boot/dts/at91-foxg20.dts
index f89598a..6bf873e 100644
--- a/arch/arm/boot/dts/at91-foxg20.dts
+++ b/arch/arm/boot/dts/at91-foxg20.dts
@@ -159,7 +159,7 @@
label = "Button";
gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
linux,code = <0x103>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/at91-kizbox.dts b/arch/arm/boot/dts/at91-kizbox.dts
index bf18ece..229e989 100644
--- a/arch/arm/boot/dts/at91-kizbox.dts
+++ b/arch/arm/boot/dts/at91-kizbox.dts
@@ -24,15 +24,6 @@
};
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>;
};
@@ -94,14 +85,14 @@
label = "PB_RST";
gpios = <&pioB 30 GPIO_ACTIVE_HIGH>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
user {
label = "PB_USER";
gpios = <&pioB 31 GPIO_ACTIVE_HIGH>;
linux,code = <0x101>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-kizbox2.dts b/arch/arm/boot/dts/at91-kizbox2.dts
index f0b1563..50a1456 100644
--- a/arch/arm/boot/dts/at91-kizbox2.dts
+++ b/arch/arm/boot/dts/at91-kizbox2.dts
@@ -171,21 +171,21 @@
label = "PB_PROG";
gpios = <&pioE 27 GPIO_ACTIVE_LOW>;
linux,code = <0x102>;
- gpio-key,wakeup;
+ wakeup-source;
};
reset {
label = "PB_RST";
gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
user {
label = "PB_USER";
gpios = <&pioE 31 GPIO_ACTIVE_HIGH>;
linux,code = <0x101>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-kizboxmini.dts b/arch/arm/boot/dts/at91-kizboxmini.dts
index 9f72b49..9682d10 100644
--- a/arch/arm/boot/dts/at91-kizboxmini.dts
+++ b/arch/arm/boot/dts/at91-kizboxmini.dts
@@ -98,14 +98,14 @@
label = "PB_PROG";
gpios = <&pioC 17 GPIO_ACTIVE_LOW>;
linux,code = <0x102>;
- gpio-key,wakeup;
+ wakeup-source;
};
reset {
label = "PB_RST";
gpios = <&pioC 16 GPIO_ACTIVE_LOW>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-qil_a9260.dts b/arch/arm/boot/dts/at91-qil_a9260.dts
index a9aef53..4f2eebf 100644
--- a/arch/arm/boot/dts/at91-qil_a9260.dts
+++ b/arch/arm/boot/dts/at91-qil_a9260.dts
@@ -183,7 +183,7 @@
label = "user_pb";
gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
linux,code = <28>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index e8d63afd..e683856 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -44,6 +44,8 @@
*/
/dts-v1/;
#include "sama5d2.dtsi"
+#include "sama5d2-pinfunc.h"
+#include <dt-bindings/mfd/atmel-flexcom.h>
/ {
model = "Atmel SAMA5D2 Xplained";
@@ -58,15 +60,6 @@
};
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>;
};
@@ -90,8 +83,26 @@
status = "okay";
};
+ sdmmc0: sdio-host@a0000000 {
+ bus-width = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc0_default>;
+ non-removable;
+ mmc-ddr-1_8v;
+ status = "okay";
+ };
+
+ sdmmc1: sdio-host@b0000000 {
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc1_default>;
+ status = "okay"; /* conflict with qspi0 */
+ };
+
apb {
spi0: spi@f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi0_default>;
status = "okay";
m25p80@0 {
@@ -102,25 +113,151 @@
};
macb0: ethernet@f8008000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_default &pinctrl_macb0_phy_irq>;
phy-mode = "rmii";
status = "okay";
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioA>;
+ interrupts = <73 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ pdmic@f8018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdmic_default>;
+ atmel,model = "PDMIC @ sama5d2_xplained";
+ atmel,mic-min-freq = <1000000>;
+ atmel,mic-max-freq = <3246000>;
+ atmel,mic-offset = <0x0>;
+ status = "okay";
};
uart1: serial@f8020000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
status = "okay";
};
i2c0: i2c@f8028000 {
dmas = <0>, <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+ i2c-sda-hold-time-ns = <350>;
+ status = "okay";
+
+ pmic: act8865@5b {
+ compatible = "active-semi,act8865";
+ reg = <0x5b>;
+ active-semi,vsel-high;
+ status = "okay";
+
+ regulators {
+ vdd_1v35_reg: DCDC_REG1 {
+ regulator-name = "VDD_1V35";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ vdd_1v2_reg: DCDC_REG2 {
+ regulator-name = "VDD_1V2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_reg: DCDC_REG3 {
+ regulator-name = "VDD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_fuse_reg: LDO_REG1 {
+ regulator-name = "VDD_FUSE";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vdd_3v3_lp_reg: LDO_REG2 {
+ regulator-name = "VDD_3V3_LP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_led_reg: LDO_REG3 {
+ regulator-name = "VDD_LED";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_sdhc_1v8_reg: LDO_REG4 {
+ regulator-name = "VDD_SDHC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+ };
+
+ flx0: flexcom@f8034000 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+ status = "disabled"; /* conflict with ISC_D2 & ISC_D3 data pins */
+
+ uart5: serial@200 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0x200 0x200>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&flx0_clk>;
+ clock-names = "usart";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flx0_default>;
+ atmel,fifo-size = <32>;
+ status = "okay";
+ };
+ };
+
+ watchdog@f8048040 {
status = "okay";
};
uart3: serial@fc008000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_default>;
+ status = "okay";
+ };
+
+ flx4: flexcom@fc018000 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
status = "okay";
+
+ i2c2: i2c@600 {
+ compatible = "atmel,sama5d2-i2c";
+ reg = <0x600 0x200>;
+ interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>;
+ dmas = <0>, <0>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&flx4_clk>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flx4_default>;
+ atmel,fifo-size = <16>;
+ status = "okay";
+ };
};
i2c1: i2c@fc028000 {
dmas = <0>, <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_default>;
status = "okay";
at24@54 {
@@ -129,6 +266,116 @@
pagesize = <16>;
};
};
+
+ pinctrl@fc038000 {
+ pinctrl_flx0_default: flx0_default {
+ pinmux = <PIN_PB28__FLEXCOM0_IO0>,
+ <PIN_PB29__FLEXCOM0_IO1>;
+ bias-disable;
+ };
+
+ pinctrl_flx4_default: flx4_default {
+ pinmux = <PIN_PD12__FLEXCOM4_IO0>,
+ <PIN_PD13__FLEXCOM4_IO1>;
+ bias-disable;
+ };
+
+ pinctrl_i2c0_default: i2c0_default {
+ pinmux = <PIN_PD21__TWD0>,
+ <PIN_PD22__TWCK0>;
+ bias-disable;
+ };
+
+ pinctrl_i2c1_default: i2c1_default {
+ pinmux = <PIN_PD4__TWD1>,
+ <PIN_PD5__TWCK1>;
+ bias-disable;
+ };
+
+ pinctrl_macb0_default: macb0_default {
+ pinmux = <PIN_PB14__GTXCK>,
+ <PIN_PB15__GTXEN>,
+ <PIN_PB16__GRXDV>,
+ <PIN_PB17__GRXER>,
+ <PIN_PB18__GRX0>,
+ <PIN_PB19__GRX1>,
+ <PIN_PB20__GTX0>,
+ <PIN_PB21__GTX1>,
+ <PIN_PB22__GMDC>,
+ <PIN_PB23__GMDIO>;
+ bias-disable;
+ };
+
+ pinctrl_macb0_phy_irq: macb0_phy_irq {
+ pinmux = <PIN_PC9__GPIO>;
+ };
+
+ pinctrl_pdmic_default: pdmic_default {
+ pinmux = <PIN_PB26__PDMIC_DAT>,
+ <PIN_PB27__PDMIC_CLK>;
+ bias-disable;
+ };
+
+ pinctrl_sdmmc0_default: sdmmc0_default {
+ cmd_data {
+ pinmux = <PIN_PA1__SDMMC0_CMD>,
+ <PIN_PA2__SDMMC0_DAT0>,
+ <PIN_PA3__SDMMC0_DAT1>,
+ <PIN_PA4__SDMMC0_DAT2>,
+ <PIN_PA5__SDMMC0_DAT3>,
+ <PIN_PA6__SDMMC0_DAT4>,
+ <PIN_PA7__SDMMC0_DAT5>,
+ <PIN_PA8__SDMMC0_DAT6>,
+ <PIN_PA9__SDMMC0_DAT7>;
+ bias-pull-up;
+ };
+
+ ck_cd_rstn_vddsel {
+ pinmux = <PIN_PA0__SDMMC0_CK>,
+ <PIN_PA10__SDMMC0_RSTN>,
+ <PIN_PA11__SDMMC0_VDDSEL>,
+ <PIN_PA13__SDMMC0_CD>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_sdmmc1_default: sdmmc1_default {
+ cmd_data {
+ pinmux = <PIN_PA28__SDMMC1_CMD>,
+ <PIN_PA18__SDMMC1_DAT0>,
+ <PIN_PA19__SDMMC1_DAT1>,
+ <PIN_PA20__SDMMC1_DAT2>,
+ <PIN_PA21__SDMMC1_DAT3>;
+ bias-pull-up;
+ };
+
+ conf-ck_cd {
+ pinmux = <PIN_PA22__SDMMC1_CK>,
+ <PIN_PA30__SDMMC1_CD>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_spi0_default: spi0_default {
+ pinmux = <PIN_PA14__SPI0_SPCK>,
+ <PIN_PA15__SPI0_MOSI>,
+ <PIN_PA16__SPI0_MISO>,
+ <PIN_PA17__SPI0_NPCS0>;
+ bias-disable;
+ };
+
+ pinctrl_uart1_default: uart1_default {
+ pinmux = <PIN_PD2__URXD1>,
+ <PIN_PD3__UTXD1>;
+ bias-disable;
+ };
+
+ pinctrl_uart3_default: uart3_default {
+ pinmux = <PIN_PB11__URXD3>,
+ <PIN_PB12__UTXD3>;
+ bias-disable;
+ };
+ };
};
};
};
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
index d81474e..ff888d2 100644
--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -76,7 +76,7 @@
pmic: act8865@5b {
compatible = "active-semi,act8865";
reg = <0x5b>;
- status = "okay";
+ status = "disabled";
regulators {
vcc_1v8_reg: DCDC_REG1 {
@@ -315,7 +315,7 @@
label = "PB_USER";
gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
linux,code = <0x104>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
new file mode 100644
index 0000000..e7b2109
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 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 "sama5d4.dtsi"
+
+/ {
+ model = "DENX MA5D4";
+ compatible = "denx,ma5d4", "atmel,sama5d4", "atmel,sama5";
+
+ memory {
+ reg = <0x20000000 0x10000000>;
+ };
+
+ clocks {
+ main_clock: main_clock {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+
+ clk20m: clk20m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ clock-output-names = "clk20m";
+ };
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7>;
+ vmmc-supply = <&vcc_mmc0_reg>;
+ vqmmc-supply = <&vcc_3v3_reg>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ broken-cd;
+ };
+ };
+
+ 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";
+ };
+
+ spi1: spi@fc018000 {
+ cs-gpios = <&pioB 22 0>, <&pioB 23 0>, <0>, <0>;
+ status = "okay";
+
+ can0: can@0 {
+ compatible = "microchip,mcp2515";
+ reg = <0>;
+ clocks = <&clk20m>;
+ interrupt-parent = <&pioE>;
+ interrupts = <6 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
+ };
+
+ can1: can@1 {
+ compatible = "microchip,mcp2515";
+ reg = <1>;
+ clocks = <&clk20m>;
+ interrupt-parent = <&pioE>;
+ interrupts = <7 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
+ };
+ };
+
+ adc0: adc@fc034000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ /* external trigger conflicts with USBA_VBUS */
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ >;
+ atmel,adc-vref = <3300>;
+ status = "okay";
+ };
+
+ watchdog@fc068640 {
+ status = "okay";
+ };
+ };
+ };
+
+ vcc_3v3_reg: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC 3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vcc_mmc0_reg: fixedregulator@1 {
+ compatible = "regulator-fixed";
+ gpio = <&pioE 15 GPIO_ACTIVE_HIGH>;
+ regulator-name = "RST_n MCI0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_reg>;
+ regulator-boot-on;
+ };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
new file mode 100644
index 0000000..abaaba5
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4evk.dts
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2015 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 "at91-sama5d4_ma5d4.dtsi"
+
+/ {
+ model = "DENX MA5D4EVK";
+ compatible = "denx,ma5d4evk", "atmel,sama5d4", "atmel,sama5";
+
+ chosen {
+ stdout-path = "serial3:115200n8";
+ };
+
+ ahb {
+ 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_LOW
+ &pioE 14 GPIO_ACTIVE_LOW
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci@00600000 {
+ status = "okay";
+ };
+
+ apb {
+ hlcdc: hlcdc@f0000000 {
+ status = "okay";
+
+ hlcdc-display-controller {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+
+ port@0 {
+ hlcdc_panel_output: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&panel_input>;
+ };
+ };
+ };
+
+ };
+
+ macb0: ethernet@f8020000 {
+ phy-mode = "rmii";
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ usart0: serial@f802c000 {
+ status = "okay";
+ };
+
+ usart1: serial@f8030000 {
+ status = "okay";
+ };
+
+ mmc1: mmc@fc000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ vmmc-supply = <&vcc_mmc1_reg>;
+ vqmmc-supply = <&vcc_3v3_reg>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 5 0>;
+ };
+ };
+
+ adc0: adc@fc034000 {
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ };
+
+
+ pinctrl@fc06a000 {
+ board {
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins = <AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+ };
+ };
+ };
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&hlcdc_pwm 0 50000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ status = "okay";
+
+ user1 {
+ label = "user1";
+ gpios = <&pioD 28 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user2 {
+ label = "user2";
+ gpios = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user3 {
+ label = "user3";
+ gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ panel: panel {
+ /* Actually Ampire 800480R2 */
+ compatible = "foxlink,fl500wvr00-a0t", "simple-panel";
+ backlight = <&backlight>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel_input: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hlcdc_panel_output>;
+ };
+ };
+ };
+
+ vcc_mmc1_reg: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ gpio = <&pioE 17 GPIO_ACTIVE_LOW>;
+ regulator-name = "VDD MCI1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_reg>;
+ };
+};
diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
index 07f4696..569026e 100644
--- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
@@ -50,7 +50,6 @@
compatible = "atmel,sama5d4-xplained", "atmel,sama5d4", "atmel,sama5";
chosen {
- bootargs = "ignore_loglevel earlyprintk";
stdout-path = "serial0:115200n8";
};
@@ -59,15 +58,6 @@
};
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>;
};
@@ -96,10 +86,12 @@
macb0: ethernet@f8020000 {
phy-mode = "rmii";
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
phy0: ethernet-phy@1 {
interrupt-parent = <&pioE>;
- interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
reg = <1>;
};
};
@@ -162,6 +154,10 @@
atmel,pins =
<AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
};
+ pinctrl_macb0_phy_irq: macb0_phy_irq_0 {
+ atmel,pins =
+ <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
};
};
};
@@ -235,7 +231,7 @@
label = "pb_user1";
gpios = <&pioE 8 GPIO_ACTIVE_HIGH>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -246,7 +242,7 @@
d8 {
label = "d8";
gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
- status = "disabled";
+ default-state = "on";
};
d10 {
diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts
index 49a59c7..4e98cda 100644
--- a/arch/arm/boot/dts/at91-sama5d4ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d4ek.dts
@@ -50,7 +50,6 @@
compatible = "atmel,sama5d4ek", "atmel,sama5d4", "atmel,sama5";
chosen {
- bootargs = "ignore_loglevel earlyprintk";
stdout-path = "serial0:115200n8";
};
@@ -59,15 +58,6 @@
};
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>;
};
@@ -148,11 +138,37 @@
clocks = <&pck2>;
clock-names = "mclk";
};
+
+ qt1070:keyboard@1b {
+ compatible = "qt1070";
+ reg = <0x1b>;
+ interrupt-parent = <&pioE>;
+ interrupts = <25 0x0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qt1070_irq>;
+ wakeup-source;
+ };
+
+ atmel_mxt_ts@4c {
+ compatible = "atmel,atmel_mxt_ts";
+ reg = <0x4c>;
+ interrupt-parent = <&pioE>;
+ interrupts = <24 0x0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mxt_ts>;
+ };
};
macb0: ethernet@f8020000 {
+ pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
phy-mode = "rmii";
status = "okay";
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioE>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+ };
};
mmc1: mmc@fc000000 {
@@ -184,6 +200,10 @@
pinctrl@fc06a000 {
board {
+ pinctrl_macb0_phy_irq: macb0_phy_irq {
+ atmel,pins =
+ <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
pinctrl_mmc0_cd: mmc0_cd {
atmel,pins =
<AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
@@ -204,6 +224,14 @@
atmel,pins =
<AT91_PIOE 13 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE13 gpio */
};
+ pinctrl_qt1070_irq: qt1070_irq {
+ atmel,pins =
+ <AT91_PIOE 25 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+ pinctrl_mxt_ts: mxt_irq {
+ atmel,pins =
+ <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
};
};
};
@@ -277,7 +305,7 @@
label = "pb_user1";
gpios = <&pioE 13 GPIO_ACTIVE_HIGH>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91-vinco.dts b/arch/arm/boot/dts/at91-vinco.dts
new file mode 100644
index 0000000..79aec55
--- /dev/null
+++ b/arch/arm/boot/dts/at91-vinco.dts
@@ -0,0 +1,256 @@
+/*
+ * Device Tree file for VInCo platform
+ *
+ * Copyright (C) 2014 Atmel,
+ * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2015 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 "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 = "L+G VInCo platform";
+ compatible = "l+g,vinco", "atmel,sama5d4", "atmel,sama5";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+
+ adc0: adc@fc034000 {
+ 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_dat4_7>;
+ vqmmc-supply = <&vcc_3v3_reg>;
+ vmmc-supply = <&vcc_3v3_reg>;
+ no-1-8-v;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ non-removable;
+ broken-cd;
+ status = "okay";
+ };
+ };
+
+ spi0: spi@f8010000 {
+ cs-gpios = <&pioC 3 0>, <0>, <0>, <0>;
+ status = "okay";
+ m25p80@0 {
+ compatible = "n25q32b", "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ i2c0: i2c@f8014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8018000 {
+ status = "okay";
+ /* kerkey security module */
+ };
+
+ macb0: ethernet@f8020000 {
+ phy-mode = "rmii";
+ status = "okay";
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ reset-gpios = <&pioE 8 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&pioB>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ };
+
+ i2c2: i2c@f8024000 {
+ status = "okay";
+
+ rtc1: rtc@64 {
+ compatible = "epson,rx8900";
+ reg = <0x32>;
+ };
+ };
+
+ usart2: serial@fc008000 {
+ /* MBUS */
+ status = "okay";
+ };
+
+ usart3: serial@fc00c000 {
+ /* debug */
+ status = "okay";
+ };
+
+ usart4: serial@fc010000 {
+ /* LMN */
+ pinctrl-0 = <&pinctrl_usart4 &pinctrl_usart4_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ macb1: ethernet@fc028000 {
+ phy-mode = "rmii";
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ethernet-phy@1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioB>;
+ interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&pioE 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ watchdog@fc068640 {
+ status = "okay";
+ };
+
+ pinctrl@fc06a000 {
+ board {
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+ };
+ };
+ };
+ };
+
+ usb0: gadget@00400000 {
+ atmel,vbus-gpio = <&pioE 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "disable";
+ };
+
+ usb1: ohci@00500000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0
+ &pioE 11 GPIO_ACTIVE_LOW
+ &pioE 12 GPIO_ACTIVE_LOW
+ >;
+ status = "disable";
+ };
+
+ usb2: ehci@00600000 {
+ /* 4G Modem */
+ status = "okay";
+ };
+
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ status = "okay";
+
+ led_err {
+ label = "err";
+ gpios = <&pioA 7 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led_rssi {
+ label = "rssi";
+ gpios = <&pioA 9 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led_tls {
+ label = "tls";
+ gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led_lmc {
+ label = "lmc";
+ gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led_wmt {
+ label = "wmt";
+ gpios = <&pioA 29 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led_pwr {
+ label = "pwr";
+ gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ };
+
+ vcc_3v3_reg: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC 3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 60edd8b..f6cb7a8 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -97,7 +97,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91rm9200-pmc";
+ compatible = "atmel,at91rm9200-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
@@ -426,7 +426,7 @@
pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
clocks = <&ssc0_clk>;
clock-names = "pclk";
- status = "disable";
+ status = "disabled";
};
ssc1: ssc@fffd4000 {
@@ -437,7 +437,7 @@
pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
clocks = <&ssc1_clk>;
clock-names = "pclk";
- status = "disable";
+ status = "disabled";
};
ssc2: ssc@fffd8000 {
@@ -448,7 +448,7 @@
pinctrl-0 = <&pinctrl_ssc2_tx &pinctrl_ssc2_rx>;
clocks = <&ssc2_clk>;
clock-names = "pclk";
- status = "disable";
+ status = "disabled";
};
macb0: ethernet@fffbc000 {
diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts
index 8dab4b7..f90e1c2 100644
--- a/arch/arm/boot/dts/at91rm9200ek.dts
+++ b/arch/arm/boot/dts/at91rm9200ek.dts
@@ -21,15 +21,6 @@
};
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>;
};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index be9c027..d4884dd 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -100,7 +100,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9260-pmc";
+ compatible = "atmel,at91sam9260-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index ce1e3e9..5e09de4 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -568,7 +568,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91rm9200-pmc";
+ compatible = "atmel,at91rm9200-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
index 2e92ac0..55bd51f 100644
--- a/arch/arm/boot/dts/at91sam9261ek.dts
+++ b/arch/arm/boot/dts/at91sam9261ek.dts
@@ -22,15 +22,6 @@
};
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>;
};
@@ -149,7 +140,7 @@
ti,debounce-tol = /bits/ 16 <65535>;
ti,debounce-max = /bits/ 16 <1>;
- linux,wakeup;
+ wakeup-source;
};
};
@@ -193,28 +184,28 @@
label = "button_0";
gpios = <&pioA 27 GPIO_ACTIVE_LOW>;
linux,code = <256>;
- gpio-key,wakeup;
+ wakeup-source;
};
button_1 {
label = "button_1";
gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
linux,code = <257>;
- gpio-key,wakeup;
+ wakeup-source;
};
button_2 {
label = "button_2";
gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
linux,code = <258>;
- gpio-key,wakeup;
+ wakeup-source;
};
button_3 {
label = "button_3";
gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
linux,code = <259>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index f1f5fa3..9344642 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -93,7 +93,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91rm9200-pmc";
+ compatible = "atmel,at91rm9200-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
index 2338127..59df9d7 100644
--- a/arch/arm/boot/dts/at91sam9263ek.dts
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -22,15 +22,6 @@
};
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>;
};
@@ -213,14 +204,14 @@
label = "left_click";
gpios = <&pioC 5 GPIO_ACTIVE_LOW>;
linux,code = <272>;
- gpio-key,wakeup;
+ wakeup-source;
};
right_click {
label = "right_click";
gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
linux,code = <273>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index 57548a2..e9cc99b 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -19,15 +19,6 @@
};
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>;
};
@@ -206,14 +197,14 @@
label = "Button 3";
gpios = <&pioA 30 GPIO_ACTIVE_LOW>;
linux,code = <0x103>;
- gpio-key,wakeup;
+ wakeup-source;
};
btn4 {
label = "Button 4";
gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
linux,code = <0x104>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 18b8b9e..af8b708 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -114,7 +114,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9g45-pmc";
+ compatible = "atmel,at91sam9g45-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index d1ae60a..2400c99 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -24,15 +24,6 @@
};
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>;
};
@@ -198,6 +189,8 @@
isi_0: endpoint {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
+ vsync-active = <1>;
+ hsync-active = <1>;
};
};
};
@@ -321,14 +314,14 @@
label = "left_click";
gpios = <&pioB 6 GPIO_ACTIVE_LOW>;
linux,code = <272>;
- gpio-key,wakeup;
+ wakeup-source;
};
right_click {
label = "right_click";
gpios = <&pioB 7 GPIO_ACTIVE_LOW>;
linux,code = <273>;
- gpio-key,wakeup;
+ wakeup-source;
};
left {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 32bc9a1..95569a8 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -97,7 +97,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9n12-pmc";
+ compatible = "atmel,at91sam9n12-pmc", "syscon";
reg = <0xfffffc00 0x200>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index efa7506..626c67d 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -23,15 +23,6 @@
};
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>;
};
@@ -71,10 +62,6 @@
};
};
- i2c1: i2c@f8014000 {
- status = "okay";
- };
-
mmc0: mmc@f0008000 {
pinctrl-0 = <
&pinctrl_board_mmc0
@@ -204,13 +191,13 @@
};
d9 {
- label = "d6";
+ label = "d9";
gpios = <&pioB 5 GPIO_ACTIVE_LOW>;
linux,default-trigger = "nand-disk";
};
d10 {
- label = "d7";
+ label = "d10";
gpios = <&pioB 6 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
@@ -223,12 +210,12 @@
label = "Enter";
gpios = <&pioB 3 GPIO_ACTIVE_LOW>;
linux,code = <28>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
panel: panel {
- compatible = "qd,qd43003c0-40", "simple-panel";
+ compatible = "qiaodian,qd43003c0-40", "simple-panel";
backlight = <&backlight>;
power-supply = <&panel_reg>;
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index a0b90ae..6d829db 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -814,7 +814,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9g45-pmc";
+ compatible = "atmel,at91sam9g45-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
index 558c9f2..f10566f 100644
--- a/arch/arm/boot/dts/at91sam9rlek.dts
+++ b/arch/arm/boot/dts/at91sam9rlek.dts
@@ -22,15 +22,6 @@
};
clocks {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- main_clock: clock {
- compatible = "atmel,osc", "fixed-clock";
- clock-frequency = <12000000>;
- };
-
slow_xtal {
clock-frequency = <32768>;
};
@@ -225,14 +216,14 @@
label = "right_click";
gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
linux,code = <273>;
- gpio-key,wakeup;
+ wakeup-source;
};
left_click {
label = "left_click";
gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
linux,code = <272>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 747d8f0..0827d59 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -68,7 +68,7 @@
adc_op_clk: adc_op_clk{
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <5000000>;
+ clock-frequency = <1000000>;
};
};
@@ -105,7 +105,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,at91sam9x5-pmc";
+ compatible = "atmel,at91sam9x5-pmc", "syscon";
reg = <0xfffffc00 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
@@ -1043,6 +1043,7 @@
atmel,adc-channels-used = <0xffff>;
atmel,adc-vref = <3300>;
atmel,adc-startup-time = <40>;
+ atmel,adc-sample-hold-time = <11>;
atmel,adc-res = <8 10>;
atmel,adc-res-names = "lowres", "highres";
atmel,adc-use-res = "highres";
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi
index 26112eb..b098ad8 100644
--- a/arch/arm/boot/dts/at91sam9x5cm.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -13,17 +13,6 @@
};
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>;
};
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
index d237c46..52425a4 100644
--- a/arch/arm/boot/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -66,6 +66,8 @@
isi_0: endpoint@0 {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
+ vsync-active = <1>;
+ hsync-active = <1>;
};
};
};
@@ -100,6 +102,12 @@
};
};
+ adc0: adc@f804c000 {
+ atmel,adc-ts-wires = <4>;
+ atmel,adc-ts-pressure-threshold = <10000>;
+ status = "okay";
+ };
+
pinctrl@fffff400 {
camera_sensor {
pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 {
diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index 24c935c..051ab3b 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -89,4 +89,9 @@
regulator-name = "ldo5";
};
};
+
+ usb_power_supply: usb_power_supply {
+ compatible = "x-powers,axp202-usb-power-supply";
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
new file mode 100644
index 0000000..76302f5
--- /dev/null
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * AXP221/221s/223 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP22X.php
+ * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
+ */
+
+&axp22x {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ regulators {
+ /* Default work frequency for buck regulators */
+ x-powers,dcdc-freq = <3000>;
+
+ reg_dcdc1: dcdc1 {
+ regulator-name = "dcdc1";
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-name = "dcdc2";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-name = "dcdc3";
+ };
+
+ reg_dcdc4: dcdc4 {
+ regulator-name = "dcdc4";
+ };
+
+ reg_dcdc5: dcdc5 {
+ regulator-name = "dcdc5";
+ };
+
+ reg_dc1sw: dc1sw {
+ regulator-name = "dc1sw";
+ };
+
+ reg_dc5ldo: dc5ldo {
+ regulator-name = "dc5ldo";
+ };
+
+ reg_aldo1: aldo1 {
+ regulator-name = "aldo1";
+ };
+
+ reg_aldo2: aldo2 {
+ regulator-name = "aldo2";
+ };
+
+ reg_aldo3: aldo3 {
+ regulator-name = "aldo3";
+ };
+
+ reg_dldo1: dldo1 {
+ regulator-name = "dldo1";
+ };
+
+ reg_dldo2: dldo2 {
+ regulator-name = "dldo2";
+ };
+
+ reg_dldo3: dldo3 {
+ regulator-name = "dldo3";
+ };
+
+ reg_dldo4: dldo4 {
+ regulator-name = "dldo4";
+ };
+
+ reg_eldo1: eldo1 {
+ regulator-name = "eldo1";
+ };
+
+ reg_eldo2: eldo2 {
+ regulator-name = "eldo2";
+ };
+
+ reg_eldo3: eldo3 {
+ regulator-name = "eldo3";
+ };
+
+ reg_ldo_io0: ldo_io0 {
+ regulator-name = "ldo_io0";
+ };
+
+ reg_ldo_io1: ldo_io1 {
+ regulator-name = "ldo_io1";
+ };
+
+ reg_rtc_ldo: rtc_ldo {
+ /* RTC_LDO is a fixed, always-on regulator */
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "rtc_ldo";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi
index e1ac07a..3878793 100644
--- a/arch/arm/boot/dts/bcm-cygnus.dtsi
+++ b/arch/arm/boot/dts/bcm-cygnus.dtsi
@@ -32,6 +32,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/bcm-cygnus.h>
#include "skeleton.dtsi"
@@ -54,197 +55,309 @@
/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;
- };
+ core {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x19000000 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
- gpio_asiu: gpio@180a5000 {
- compatible = "brcm,cygnus-asiu-gpio";
- reg = <0x180a5000 0x668>;
- #gpio-cells = <2>;
- gpio-controller;
+ timer@20200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x20200 0x100>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&periph_clk>;
+ };
- pinmux = <&pinctrl>;
+ gic: interrupt-controller@21000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x21000 0x1000>,
+ <0x20100 0x100>;
+ };
- interrupt-controller;
- interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x22000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
};
- amba {
+ axi {
+ compatible = "simple-bus";
+ ranges;
#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";
+ pcie_phy: phy@0301d0a0 {
+ compatible = "brcm,cygnus-pcie-phy";
+ reg = <0x0301d0a0 0x14>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie0_phy: phy@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ pcie1_phy: phy@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
};
- };
- 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";
- };
+ pinctrl: pinctrl@0x0301d0c8 {
+ compatible = "brcm,cygnus-pinmux";
+ reg = <0x0301d0c8 0x30>,
+ <0x0301d24c 0x2c>;
+ };
- 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";
- };
+ gpio_crmu: gpio@03024800 {
+ compatible = "brcm,cygnus-crmu-gpio";
+ reg = <0x03024800 0x50>,
+ <0x03024008 0x18>;
+ ngpios = <6>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
- pcie0: pcie@18012000 {
- compatible = "brcm,iproc-pcie";
- reg = <0x18012000 0x1000>;
+ 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";
+ };
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
+ wdt0: 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";
+ };
- linux,pci-domain = <0>;
+ gpio_ccm: gpio@1800a000 {
+ compatible = "brcm,cygnus-ccm-gpio";
+ reg = <0x1800a000 0x50>,
+ <0x0301d164 0x20>;
+ ngpios = <24>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ };
- bus-range = <0x00 0xff>;
+ 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";
+ };
- #address-cells = <3>;
- #size-cells = <2>;
- device_type = "pci";
- ranges = <0x81000000 0 0 0x28000000 0 0x00010000
- 0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
+ pcie0: pcie@18012000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x18012000 0x1000>;
- status = "disabled";
- };
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
- pcie1: pcie@18013000 {
- compatible = "brcm,iproc-pcie";
- reg = <0x18013000 0x1000>;
+ linux,pci-domain = <0>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
+ bus-range = <0x00 0xff>;
- linux,pci-domain = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x28000000 0 0x00010000
+ 0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
- bus-range = <0x00 0xff>;
+ phys = <&pcie0_phy>;
+ phy-names = "pcie-phy";
- #address-cells = <3>;
- #size-cells = <2>;
- device_type = "pci";
- ranges = <0x81000000 0 0 0x48000000 0 0x00010000
- 0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
+ status = "disabled";
- status = "disabled";
- };
+ msi-parent = <&msi0>;
+ msi0: msi@18012000 {
+ compatible = "brcm,iproc-msi";
+ msi-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_NONE>,
+ <GIC_SPI 97 IRQ_TYPE_NONE>,
+ <GIC_SPI 98 IRQ_TYPE_NONE>,
+ <GIC_SPI 99 IRQ_TYPE_NONE>;
+ };
+ };
- 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";
- };
+ pcie1: pcie@18013000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x18013000 0x1000>;
- 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";
- };
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
- 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";
- };
+ linux,pci-domain = <1>;
- 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";
- };
+ bus-range = <0x00 0xff>;
- nand: nand@18046000 {
- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
- reg = <0x18046000 0x600>, <0xf8105408 0x600>, <0x18046f00 0x20>;
- reg-names = "nand", "iproc-idm", "iproc-ext";
- interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ ranges = <0x81000000 0 0 0x48000000 0 0x00010000
+ 0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
- #address-cells = <1>;
- #size-cells = <0>;
+ phys = <&pcie1_phy>;
+ phy-names = "pcie-phy";
- brcm,nand-has-wp;
- };
+ status = "disabled";
- gic: interrupt-controller@19021000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- #address-cells = <0>;
- interrupt-controller;
- reg = <0x19021000 0x1000>,
- <0x19020100 0x100>;
- };
+ msi-parent = <&msi1>;
+ msi1: msi@18013000 {
+ compatible = "brcm,iproc-msi";
+ msi-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_NONE>,
+ <GIC_SPI 103 IRQ_TYPE_NONE>,
+ <GIC_SPI 104 IRQ_TYPE_NONE>,
+ <GIC_SPI 105 IRQ_TYPE_NONE>;
+ };
+ };
- L2: l2-cache {
- compatible = "arm,pl310-cache";
- reg = <0x19022000 0x1000>;
- cache-unified;
- cache-level = <2>;
- };
+ 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";
+ };
- timer@19020200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x19020200 0x100>;
- interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&periph_clk>;
- };
+ 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";
+ };
+
+ nand: nand@18046000 {
+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1";
+ reg = <0x18046000 0x600>, <0xf8105408 0x600>,
+ <0x18046f00 0x20>;
+ reg-names = "nand", "iproc-idm", "iproc-ext";
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,nand-has-wp;
+ };
+
+ gpio_asiu: gpio@180a5000 {
+ compatible = "brcm,cygnus-asiu-gpio";
+ reg = <0x180a5000 0x668>;
+ ngpios = <146>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ interrupt-controller;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-ranges = <&pinctrl 0 42 1>,
+ <&pinctrl 1 44 3>,
+ <&pinctrl 4 48 1>,
+ <&pinctrl 5 50 3>,
+ <&pinctrl 8 126 1>,
+ <&pinctrl 9 155 1>,
+ <&pinctrl 10 152 1>,
+ <&pinctrl 11 154 1>,
+ <&pinctrl 12 153 1>,
+ <&pinctrl 13 127 3>,
+ <&pinctrl 16 140 1>,
+ <&pinctrl 17 145 7>,
+ <&pinctrl 24 130 10>,
+ <&pinctrl 34 141 4>,
+ <&pinctrl 38 54 1>,
+ <&pinctrl 39 56 3>,
+ <&pinctrl 42 60 3>,
+ <&pinctrl 45 64 3>,
+ <&pinctrl 48 68 2>,
+ <&pinctrl 50 84 6>,
+ <&pinctrl 56 94 6>,
+ <&pinctrl 62 72 1>,
+ <&pinctrl 63 70 1>,
+ <&pinctrl 64 80 1>,
+ <&pinctrl 65 74 3>,
+ <&pinctrl 68 78 1>,
+ <&pinctrl 69 82 1>,
+ <&pinctrl 70 156 17>,
+ <&pinctrl 87 104 12>,
+ <&pinctrl 99 102 2>,
+ <&pinctrl 101 90 4>,
+ <&pinctrl 105 116 6>,
+ <&pinctrl 111 100 2>,
+ <&pinctrl 113 122 4>,
+ <&pinctrl 123 11 1>,
+ <&pinctrl 124 38 4>,
+ <&pinctrl 128 43 1>,
+ <&pinctrl 129 47 1>,
+ <&pinctrl 130 49 1>,
+ <&pinctrl 131 53 1>,
+ <&pinctrl 132 55 1>,
+ <&pinctrl 133 59 1>,
+ <&pinctrl 134 63 1>,
+ <&pinctrl 135 67 1>,
+ <&pinctrl 136 71 1>,
+ <&pinctrl 137 73 1>,
+ <&pinctrl 138 77 1>,
+ <&pinctrl 139 79 1>,
+ <&pinctrl 140 81 1>,
+ <&pinctrl 141 83 1>,
+ <&pinctrl 142 10 1>;
+ };
+
+ touchscreen: tsc@180a6000 {
+ compatible = "brcm,iproc-touchscreen";
+ reg = <0x180a6000 0x40>;
+ clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>;
+ clock-names = "tsc_clk";
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
};
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
new file mode 100644
index 0000000..10bdef5
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/bcm-nsp.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "brcm,nsp";
+ model = "Broadcom Northstar Plus 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>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ enable-method = "brcm,bcm-nsp-smp";
+ secondary-boot-reg = <0xffff042c>;
+ reg = <0x1>;
+ };
+ };
+
+ mpcore {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x19000000 0x00023000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ };
+ };
+
+ a9pll: arm_clk@00000 {
+ #clock-cells = <0>;
+ compatible = "brcm,nsp-armpll";
+ clocks = <&osc>;
+ reg = <0x00000 0x1000>;
+ };
+
+ timer@20200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x20200 0x100>;
+ interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&periph_clk>;
+ };
+
+ twd-timer@20600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x20600 0x20>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&periph_clk>;
+ };
+
+ twd-watchdog@20620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0x20620 0x20>;
+ interrupts = <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&periph_clk>;
+ };
+
+ gic: interrupt-controller@21000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x21000 0x1000>,
+ <0x20100 0x100>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0x22000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ osc: oscillator {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ iprocmed: iprocmed {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ iprocslow: iprocslow {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ };
+
+ periph_clk: periph_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&a9pll>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+ };
+
+ axi {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x18000000 0x0011ba08>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: serial@0300 {
+ compatible = "ns16550a";
+ reg = <0x0300 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ status = "disabled";
+ };
+
+ uart1: serial@0400 {
+ compatible = "ns16550a";
+ reg = <0x0400 0x100>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ status = "disabled";
+ };
+
+ pcie0: pcie@12000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x12000 0x1000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 131 IRQ_TYPE_NONE>;
+
+ linux,pci-domain = <0>;
+
+ bus-range = <0x00 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+
+ /* Note: The HW does not support I/O resources. So,
+ * only the memory resource range is being specified.
+ */
+ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>;
+
+ status = "disabled";
+ };
+
+ pcie1: pcie@13000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x13000 0x1000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 137 IRQ_TYPE_NONE>;
+
+ linux,pci-domain = <1>;
+
+ bus-range = <0x00 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+
+ /* Note: The HW does not support I/O resources. So,
+ * only the memory resource range is being specified.
+ */
+ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>;
+
+ status = "disabled";
+ };
+
+ pcie2: pcie@14000 {
+ compatible = "brcm,iproc-pcie";
+ reg = <0x14000 0x1000>;
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 143 IRQ_TYPE_NONE>;
+
+ linux,pci-domain = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+
+ /* Note: The HW does not support I/O resources. So,
+ * only the memory resource range is being specified.
+ */
+ ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>;
+
+ status = "disabled";
+ };
+
+ nand: nand@26000 {
+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1";
+ reg = <0x026000 0x600>,
+ <0x11b408 0x600>,
+ <0x026f00 0x20>;
+ reg-names = "nand", "iproc-idm", "iproc-ext";
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ brcm,nand-has-wp;
+ };
+
+ i2c0: i2c@38000 {
+ compatible = "brcm,iproc-i2c";
+ reg = <0x38000 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
+ clock-frequency = <100000>;
+ };
+
+ lcpll0: lcpll0@3f100 {
+ #clock-cells = <1>;
+ compatible = "brcm,nsp-lcpll0";
+ reg = <0x3f100 0x14>;
+ clocks = <&osc>;
+ clock-output-names = "lcpll0", "pcie_phy", "sdio",
+ "ddr_phy";
+ };
+
+ genpll: genpll@3f140 {
+ #clock-cells = <1>;
+ compatible = "brcm,nsp-genpll";
+ reg = <0x3f140 0x24>;
+ clocks = <&osc>;
+ clock-output-names = "genpll", "phy", "ethernetclk",
+ "usbclk", "iprocfast", "sata1",
+ "sata2";
+ };
+
+ pinctrl: pinctrl@3f1c0 {
+ compatible = "brcm,nsp-pinmux";
+ reg = <0x3f1c0 0x04>,
+ <0x30028 0x04>,
+ <0x3f408 0x04>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
index 2ddaa51..3dc7a8c 100644
--- a/arch/arm/boot/dts/bcm11351.dtsi
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -31,7 +31,6 @@
#address-cells = <1>;
#size-cells = <0>;
enable-method = "brcm,bcm11351-cpu-method";
- secondary-boot-reg = <0x3500417c>;
cpu0: cpu@0 {
device_type = "cpu";
@@ -42,6 +41,7 @@
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
+ secondary-boot-reg = <0x3500417c>;
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/bcm21664.dtsi b/arch/arm/boot/dts/bcm21664.dtsi
index 2016b72..3f525be 100644
--- a/arch/arm/boot/dts/bcm21664.dtsi
+++ b/arch/arm/boot/dts/bcm21664.dtsi
@@ -31,7 +31,6 @@
#address-cells = <1>;
#size-cells = <0>;
enable-method = "brcm,bcm11351-cpu-method";
- secondary-boot-reg = <0x35004178>;
cpu0: cpu@0 {
device_type = "cpu";
@@ -42,6 +41,7 @@
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
+ secondary-boot-reg = <0x35004178>;
reg = <1>;
};
};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
new file mode 100644
index 0000000..228614f
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -0,0 +1,31 @@
+/dts-v1/;
+#include "bcm2835.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-a-plus", "brcm,bcm2835";
+ model = "Raspberry Pi Model A+";
+
+ 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 = <BCM2835_FSEL_ALT0>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 668442b..ef54050 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -1,4 +1,5 @@
/dts-v1/;
+#include "bcm2835.dtsi"
#include "bcm2835-rpi.dtsi"
/ {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
new file mode 100644
index 0000000..86f1f2f
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -0,0 +1,24 @@
+/dts-v1/;
+#include "bcm2835.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835";
+ model = "Raspberry Pi Model B rev2";
+
+ 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 = <BCM2835_FSEL_ALT2>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index ee89b79..4859e9d 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -1,4 +1,5 @@
/dts-v1/;
+#include "bcm2835.dtsi"
#include "bcm2835-rpi.dtsi"
/ {
@@ -13,11 +14,5 @@
};
&gpio {
- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
- /* I2S interface */
- i2s_alt2: i2s_alt2 {
- brcm,pins = <28 29 30 31>;
- brcm,function = <BCM2835_FSEL_ALT2>;
- };
+ pinctrl-0 = <&gpioout &alt0 &alt3>;
};
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index ab5474e..3afb9fe 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,5 +1,3 @@
-#include "bcm2835.dtsi"
-
/ {
memory {
reg = <0 0x10000000>;
@@ -52,6 +50,10 @@
clock-frequency = <100000>;
};
+&i2c2 {
+ status = "okay";
+};
+
&sdhci {
status = "okay";
bus-width = <4>;
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..b83b326 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,192 +1,14 @@
-#include <dt-bindings/pinctrl/bcm2835.h>
-#include "skeleton.dtsi"
+#include "bcm283x.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>;
dma-ranges = <0x40000000 0x00000000 0x20000000>;
- 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>;
- };
-
- mailbox: mailbox@7e00b800 {
- compatible = "brcm,bcm2835-mbox";
- reg = <0x7e00b880 0x40>;
- interrupts = <0 1>;
- #mbox-cells = <0>;
- };
-
- 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@7e205000 {
- 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/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
new file mode 100644
index 0000000..ff94666
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -0,0 +1,35 @@
+/dts-v1/;
+#include "bcm2836.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+ compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
+ model = "Raspberry Pi 2 Model B";
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ 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 = <BCM2835_FSEL_ALT0>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
new file mode 100644
index 0000000..9d0651d
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -0,0 +1,78 @@
+#include "bcm283x.dtsi"
+
+/ {
+ compatible = "brcm,bcm2836";
+
+ soc {
+ ranges = <0x7e000000 0x3f000000 0x1000000>,
+ <0x40000000 0x40000000 0x00001000>;
+ dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
+
+ local_intc: local_intc {
+ compatible = "brcm,bcm2836-l1-intc";
+ reg = <0x40000000 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&local_intc>;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupt-parent = <&local_intc>;
+ interrupts = <9>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&local_intc>;
+ interrupts = <0>, // PHYS_SECURE_PPI
+ <1>, // PHYS_NONSECURE_PPI
+ <3>, // VIRT_PPI
+ <2>; // HYP_PPI
+ always-on;
+ };
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ v7_cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ clock-frequency = <800000000>;
+ };
+
+ v7_cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf01>;
+ clock-frequency = <800000000>;
+ };
+
+ v7_cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf02>;
+ clock-frequency = <800000000>;
+ };
+
+ v7_cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf03>;
+ clock-frequency = <800000000>;
+ };
+ };
+};
+
+/* Make the BCM2835-style global interrupt controller be a child of the
+ * CPU-local interrupt controller.
+ */
+&intc {
+ compatible = "brcm,bcm2836-armctrl-ic";
+ reg = <0x7e00b200 0x200>;
+ interrupt-parent = <&local_intc>;
+ interrupts = <8>;
+};
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
new file mode 100644
index 0000000..971e741
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -0,0 +1,212 @@
+#include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/clock/bcm2835.h>
+#include "skeleton.dtsi"
+
+/* This include file covers the common peripherals and configuration between
+ * bcm2835 and bcm2836 implementations, leaving the CPU configuration to
+ * bcm2835.dtsi and bcm2836.dtsi.
+ */
+
+/ {
+ compatible = "brcm,bcm2835";
+ model = "BCM2835";
+ interrupt-parent = <&intc>;
+
+ chosen {
+ bootargs = "earlyprintk console=ttyAMA0";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ timer@7e003000 {
+ compatible = "brcm,bcm2835-system-timer";
+ reg = <0x7e003000 0x1000>;
+ interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+ /* This could be a reference to BCM2835_CLOCK_TIMER,
+ * but we don't have the driver using the common clock
+ * support yet.
+ */
+ 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>;
+ };
+
+ clocks: cprman@7e101000 {
+ compatible = "brcm,bcm2835-cprman";
+ #clock-cells = <1>;
+ reg = <0x7e101000 0x2000>;
+
+ /* CPRMAN derives everything from the platform's
+ * oscillator.
+ */
+ clocks = <&clk_osc>;
+ };
+
+ rng@7e104000 {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+ };
+
+ mailbox: mailbox@7e00b800 {
+ compatible = "brcm,bcm2835-mbox";
+ reg = <0x7e00b880 0x40>;
+ interrupts = <0 1>;
+ #mbox-cells = <0>;
+ };
+
+ 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>;
+ };
+
+ uart0: uart@7e201000 {
+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+ reg = <0x7e201000 0x1000>;
+ interrupts = <2 25>;
+ clocks = <&clocks BCM2835_CLOCK_UART>,
+ <&clocks BCM2835_CLOCK_VPU>;
+ clock-names = "uartclk", "apb_pclk";
+ 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 = <&clocks BCM2835_CLOCK_VPU>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@7e205000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e205000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clocks BCM2835_CLOCK_VPU>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ aux: aux@0x7e215000 {
+ compatible = "brcm,bcm2835-aux";
+ #clock-cells = <1>;
+ reg = <0x7e215000 0x8>;
+ clocks = <&clocks BCM2835_CLOCK_VPU>;
+ };
+
+ sdhci: sdhci@7e300000 {
+ compatible = "brcm,bcm2835-sdhci";
+ reg = <0x7e300000 0x100>;
+ interrupts = <2 30>;
+ clocks = <&clocks BCM2835_CLOCK_EMMC>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@7e804000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e804000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clocks BCM2835_CLOCK_VPU>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@7e805000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e805000 0x1000>;
+ interrupts = <2 21>;
+ clocks = <&clocks BCM2835_CLOCK_VPU>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ usb@7e980000 {
+ compatible = "brcm,bcm2835-usb";
+ reg = <0x7e980000 0x10000>;
+ interrupts = <1 9>;
+ };
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* The oscillator is the root of the clock tree. */
+ clk_osc: clock@3 {
+ compatible = "fixed-clock";
+ reg = <3>;
+ #clock-cells = <0>;
+ clock-output-names = "osc";
+ clock-frequency = <19200000>;
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
index 64b8d10..ca92bba 100644
--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
@@ -24,6 +24,17 @@
reg = <0x00000000 0x08000000>;
};
+ axi@18000000 {
+ usb3@23000 {
+ reg = <0x00023000 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/bcm4708.dtsi b/arch/arm/boot/dts/bcm4708.dtsi
index 31141e8..eed4dd1 100644
--- a/arch/arm/boot/dts/bcm4708.dtsi
+++ b/arch/arm/boot/dts/bcm4708.dtsi
@@ -15,6 +15,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
+ enable-method = "brcm,bcm-nsp-smp";
cpu@0 {
device_type = "cpu";
@@ -27,6 +28,7 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
next-level-cache = <&L2>;
+ secondary-boot-reg = <0xffff0400>;
reg = <0x1>;
};
};
diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
index aedf3c4..8ade7de 100644
--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
@@ -10,6 +10,7 @@
/dts-v1/;
#include "bcm4708.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
/ {
compatible = "asus,rt-ac87u", "brcm,bcm4709", "brcm,bcm4708";
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
new file mode 100644
index 0000000..a22ed14
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
@@ -0,0 +1,106 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Netgear R7000
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+/ {
+ compatible = "netgear,r7000", "brcm,bcm4709", "brcm,bcm4708";
+ model = "Netgear R7000";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power-white {
+ label = "bcm53xx:white:power";
+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-on";
+ };
+
+ power-amber {
+ label = "bcm53xx:amber:power";
+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz {
+ label = "bcm53xx:white:5ghz";
+ 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";
+ };
+
+ wps {
+ label = "bcm53xx:white:wps";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless {
+ label = "bcm53xx:white:wireless";
+ gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb3 {
+ label = "bcm53xx:white:usb3";
+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb2 {
+ label = "bcm53xx:white:usb2";
+ gpios = <&chipcommon 18 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>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
index 446c586..b52927c 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -50,6 +50,36 @@
gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
linux,default-trigger = "default-off";
};
+
+ wireless {
+ label = "bcm53xx:white:wireless";
+ gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wps {
+ label = "bcm53xx:white:wps";
+ gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ 5ghz-2 {
+ label = "bcm53xx:white:5ghz-2";
+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb3 {
+ label = "bcm53xx:white:usb3";
+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
+
+ usb2 {
+ label = "bcm53xx:white:usb2";
+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "default-off";
+ };
};
gpio-keys {
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
index 6f50f67..65a1309 100644
--- a/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -8,6 +8,7 @@
* Licensed under the GNU/GPL. See COPYING for details.
*/
+#include <dt-bindings/clock/bcm-nsp.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
@@ -27,7 +28,7 @@
compatible = "ns16550";
reg = <0x0300 0x100>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency = <100000000>;
+ clocks = <&iprocslow>;
status = "disabled";
};
@@ -35,48 +36,55 @@
compatible = "ns16550";
reg = <0x0400 0x100>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency = <100000000>;
+ clocks = <&iprocslow>;
status = "disabled";
};
};
mpcore {
compatible = "simple-bus";
- ranges = <0x00000000 0x19020000 0x00003000>;
+ ranges = <0x00000000 0x19000000 0x00023000>;
#address-cells = <1>;
#size-cells = <1>;
- scu@0000 {
+ a9pll: arm_clk@00000 {
+ #clock-cells = <0>;
+ compatible = "brcm,nsp-armpll";
+ clocks = <&osc>;
+ reg = <0x00000 0x1000>;
+ };
+
+ scu@20000 {
compatible = "arm,cortex-a9-scu";
- reg = <0x0000 0x100>;
+ reg = <0x20000 0x100>;
};
- timer@0200 {
+ timer@20200 {
compatible = "arm,cortex-a9-global-timer";
- reg = <0x0200 0x100>;
+ reg = <0x20200 0x100>;
interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_periph>;
+ clocks = <&periph_clk>;
};
- local-timer@0600 {
+ local-timer@20600 {
compatible = "arm,cortex-a9-twd-timer";
- reg = <0x0600 0x100>;
+ reg = <0x20600 0x100>;
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clk_periph>;
+ clocks = <&periph_clk>;
};
- gic: interrupt-controller@1000 {
+ gic: interrupt-controller@21000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#address-cells = <0>;
interrupt-controller;
- reg = <0x1000 0x1000>,
- <0x0100 0x100>;
+ reg = <0x21000 0x1000>,
+ <0x20100 0x100>;
};
- L2: cache-controller@2000 {
+ L2: cache-controller@22000 {
compatible = "arm,pl310-cache";
- reg = <0x2000 0x1000>;
+ reg = <0x22000 0x1000>;
cache-unified;
arm,shared-override;
prefetch-data = <1>;
@@ -94,14 +102,37 @@
clocks {
#address-cells = <1>;
- #size-cells = <0>;
+ #size-cells = <1>;
+ ranges;
- /* As long as we do not have a real clock driver us this
- * fixed clock */
- clk_periph: periph {
+ osc: oscillator {
+ #clock-cells = <0>;
compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ iprocmed: iprocmed {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ iprocslow: iprocslow {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll BCM_NSP_GENPLL_IPROCFAST_CLK>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ };
+
+ periph_clk: periph_clk {
#clock-cells = <0>;
- clock-frequency = <400000000>;
+ compatible = "fixed-factor-clock";
+ clocks = <&a9pll>;
+ clock-div = <2>;
+ clock-mult = <1>;
};
};
@@ -178,6 +209,25 @@
};
};
+ lcpll0: lcpll0@1800c100 {
+ #clock-cells = <1>;
+ compatible = "brcm,nsp-lcpll0";
+ reg = <0x1800c100 0x14>;
+ clocks = <&osc>;
+ clock-output-names = "lcpll0", "pcie_phy", "sdio",
+ "ddr_phy";
+ };
+
+ genpll: genpll@1800c140 {
+ #clock-cells = <1>;
+ compatible = "brcm,nsp-genpll";
+ reg = <0x1800c140 0x24>;
+ clocks = <&osc>;
+ clock-output-names = "genpll", "phy", "ethernetclk",
+ "usbclk", "iprocfast", "sata1",
+ "sata2";
+ };
+
nand: nand@18028000 {
compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi
index 34cd640..d0560e8 100644
--- a/arch/arm/boot/dts/bcm63138.dtsi
+++ b/arch/arm/boot/dts/bcm63138.dtsi
@@ -43,18 +43,31 @@
#address-cells = <1>;
#size-cells = <0>;
- arm_timer_clk: arm_timer_clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <500000000>;
- };
-
+ /* UBUS peripheral clock */
periph_clk: periph_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
clock-output-names = "periph";
};
+
+ /* peripheral clock for system timer */
+ axi_clk: axi_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&armpll>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /* APB bus clock */
+ apb_clk: apb_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&armpll>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ };
};
/* ARM bus */
@@ -93,14 +106,14 @@
compatible = "arm,cortex-a9-global-timer";
reg = <0x1e200 0x20>;
interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&arm_timer_clk>;
+ clocks = <&axi_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>;
+ clocks = <&axi_clk>;
};
twd_watchdog: watchdog@1e620 {
@@ -109,6 +122,13 @@
interrupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>;
};
+ armpll: armpll {
+ #clock-cells = <0>;
+ compatible = "brcm,bcm63138-armpll";
+ clocks = <&periph_clk>;
+ reg = <0x20000 0xf00>;
+ };
+
pmb0: reset-controller@4800c0 {
compatible = "brcm,bcm63138-pmb";
reg = <0x4800c0 0x10>;
diff --git a/arch/arm/boot/dts/bcm7445.dtsi b/arch/arm/boot/dts/bcm7445.dtsi
index 3b6b175..4791321 100644
--- a/arch/arm/boot/dts/bcm7445.dtsi
+++ b/arch/arm/boot/dts/bcm7445.dtsi
@@ -143,6 +143,12 @@
brcm,irq-can-wake;
};
+ aon-ctrl@410000 {
+ compatible = "brcm,brcmstb-aon-ctrl";
+ reg = <0x410000 0x200>, <0x410200 0x400>;
+ reg-names = "aon-ctrl", "aon-sram";
+ };
+
nand: nand@3e2800 {
status = "disabled";
#address-cells = <1>;
@@ -219,6 +225,84 @@
};
+ memory_controllers {
+ compatible = "simple-bus";
+ ranges = <0x0 0x0 0xf1100000 0x200000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memc@0 {
+ compatible = "brcm,brcmstb-memc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x80000>;
+
+ memc-ddr@2000 {
+ compatible = "brcm,brcmstb-memc-ddr";
+ reg = <0x2000 0x800>;
+ };
+
+ ddr-phy@6000 {
+ compatible = "brcm,brcmstb-ddr-phy-v240.1";
+ reg = <0x6000 0x21c>;
+ };
+
+ shimphy@8000 {
+ compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+ reg = <0x8000 0xe4>;
+ };
+ };
+
+ memc@1 {
+ compatible = "brcm,brcmstb-memc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x80000 0x80000>;
+
+ memc-ddr@2000 {
+ compatible = "brcm,brcmstb-memc-ddr";
+ reg = <0x2000 0x800>;
+ };
+
+ ddr-phy@6000 {
+ compatible = "brcm,brcmstb-ddr-phy-v240.1";
+ reg = <0x6000 0x21c>;
+ };
+
+ shimphy@8000 {
+ compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+ reg = <0x8000 0xe4>;
+ };
+ };
+
+ memc@2 {
+ compatible = "brcm,brcmstb-memc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x100000 0x80000>;
+
+ memc-ddr@2000 {
+ compatible = "brcm,brcmstb-memc-ddr";
+ reg = <0x2000 0x800>;
+ };
+
+ ddr-phy@6000 {
+ compatible = "brcm,brcmstb-ddr-phy-v240.1";
+ reg = <0x6000 0x21c>;
+ };
+
+ shimphy@8000 {
+ compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+ reg = <0x8000 0xe4>;
+ };
+ };
+ };
+
+ sram@ffe00000 {
+ compatible = "brcm,boot-sram", "mmio-sram";
+ reg = <0x0 0xffe00000 0x0 0x10000>;
+ };
+
smpboot {
compatible = "brcm,brcmstb-smpboot";
syscon-cpu = <&hif_cpubiuctrl 0x88 0x178>;
diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts
index 7db4843..8b3800f 100644
--- a/arch/arm/boot/dts/bcm911360_entphn.dts
+++ b/arch/arm/boot/dts/bcm911360_entphn.dts
@@ -39,19 +39,11 @@
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>;
@@ -64,3 +56,23 @@
};
};
};
+
+&uart3 {
+ status = "okay";
+};
+
+&nand {
+ nandcs@1 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-on-flash-bbt;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand-ecc-strength = <24>;
+ nand-ecc-step-size = <1024>;
+
+ brcm,nand-oob-sector-size = <27>;
+ };
+};
diff --git a/arch/arm/boot/dts/bcm911360k.dts b/arch/arm/boot/dts/bcm911360k.dts
index 9658d4f..091c73a 100644
--- a/arch/arm/boot/dts/bcm911360k.dts
+++ b/arch/arm/boot/dts/bcm911360k.dts
@@ -43,11 +43,10 @@
};
chosen {
- stdout-path = &uart3;
- bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
+};
- uart3: serial@18023000 {
- status = "okay";
- };
+&uart3 {
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/bcm94708.dts b/arch/arm/boot/dts/bcm94708.dts
new file mode 100644
index 0000000..251a486
--- /dev/null
+++ b/arch/arm/boot/dts/bcm94708.dts
@@ -0,0 +1,56 @@
+/*
+ * 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 "bcm4708.dtsi"
+
+/ {
+ model = "NorthStar SVK (BCM94708)";
+ compatible = "brcm,bcm94708", "brcm,bcm4708";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm94709.dts b/arch/arm/boot/dts/bcm94709.dts
new file mode 100644
index 0000000..b16cac9
--- /dev/null
+++ b/arch/arm/boot/dts/bcm94709.dts
@@ -0,0 +1,56 @@
+/*
+ * 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 "bcm4708.dtsi"
+
+/ {
+ model = "NorthStar SVK (BCM94709)";
+ compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm953012k.dts b/arch/arm/boot/dts/bcm953012k.dts
new file mode 100644
index 0000000..05a985a
--- /dev/null
+++ b/arch/arm/boot/dts/bcm953012k.dts
@@ -0,0 +1,63 @@
+/*
+ * 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 "bcm4708.dtsi"
+
+/ {
+ model = "NorthStar SVK (BCM953012K)";
+ compatible = "brcm,bcm953012k", "brcm,brcm53012", "brcm,bcm4708";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x00000000 0x10000000>;
+ };
+};
+
+&uart0 {
+ clock-frequency = <62499840>;
+ status = "okay";
+};
+
+&uart1 {
+ clock-frequency = <62499840>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm958300k.dts b/arch/arm/boot/dts/bcm958300k.dts
index 2f63052..b4a1392 100644
--- a/arch/arm/boot/dts/bcm958300k.dts
+++ b/arch/arm/boot/dts/bcm958300k.dts
@@ -33,6 +33,7 @@
/dts-v1/;
#include "bcm-cygnus.dtsi"
+#include "bcm9hmidc.dtsi"
/ {
model = "Cygnus SVK (BCM958300K)";
@@ -43,35 +44,34 @@
};
chosen {
- stdout-path = &uart3;
- bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
+};
- pcie0: pcie@18012000 {
- status = "okay";
- };
+&pcie0 {
+ status = "okay";
+};
- pcie1: pcie@18013000 {
- status = "okay";
- };
+&pcie1 {
+ status = "okay";
+};
- uart3: serial@18023000 {
- status = "okay";
- };
+&uart3 {
+ status = "okay";
+};
- nand: nand@18046000 {
- nandcs@1 {
- compatible = "brcm,nandcs";
- reg = <0>;
- nand-on-flash-bbt;
+&nand {
+ nandcs@1 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-on-flash-bbt;
- #address-cells = <1>;
- #size-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
- nand-ecc-strength = <24>;
- nand-ecc-step-size = <1024>;
+ nand-ecc-strength = <24>;
+ nand-ecc-step-size = <1024>;
- brcm,nand-oob-sector-size = <27>;
- };
+ brcm,nand-oob-sector-size = <27>;
};
};
diff --git a/arch/arm/boot/dts/bcm958305k.dts b/arch/arm/boot/dts/bcm958305k.dts
index 56b429a..3378683 100644
--- a/arch/arm/boot/dts/bcm958305k.dts
+++ b/arch/arm/boot/dts/bcm958305k.dts
@@ -33,6 +33,7 @@
/dts-v1/;
#include "bcm-cygnus.dtsi"
+#include "bcm9hmidc.dtsi"
/ {
model = "Cygnus Wireless Audio (BCM958305K)";
@@ -43,11 +44,42 @@
};
chosen {
- stdout-path = &uart3;
- bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&nand {
+ nandcs@1 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-on-flash-bbt;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand-ecc-strength = <24>;
+ nand-ecc-step-size = <1024>;
- uart3: serial@18023000 {
- status = "okay";
+ brcm,nand-oob-sector-size = <27>;
};
};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
new file mode 100644
index 0000000..e298450
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -0,0 +1,116 @@
+/*
+ * 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-nsp.dtsi"
+
+/ {
+ model = "NorthStar Plus SVK (BCM958625K)";
+ compatible = "brcm,bcm58625", "brcm,nsp";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&pcie2 {
+ status = "okay";
+};
+
+&nand {
+ nandcs@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-on-flash-bbt;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand-ecc-strength = <24>;
+ nand-ecc-step-size = <1024>;
+
+ brcm,nand-oob-sector-size = <27>;
+
+ partition@0 {
+ label = "nboot";
+ reg = <0x00000000 0x00200000>;
+ read-only;
+ };
+ partition@1 {
+ label = "nenv";
+ reg = <0x00200000 0x00400000>;
+ };
+ partition@2 {
+ label = "nsystem";
+ reg = <0x00600000 0x00a00000>;
+ };
+ partition@3 {
+ label = "nrootfs";
+ reg = <0x01000000 0x03000000>;
+ };
+ partition@4 {
+ label = "ncustfs";
+ reg = <0x04000000 0x3c000000>;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_sel>;
+ nand_sel: nand_sel {
+ function = "nand";
+ groups = "nand_grp";
+ };
+};
diff --git a/arch/arm/boot/dts/bcm9hmidc.dtsi b/arch/arm/boot/dts/bcm9hmidc.dtsi
new file mode 100644
index 0000000..65397c0
--- /dev/null
+++ b/arch/arm/boot/dts/bcm9hmidc.dtsi
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/*
+ * Broadcom human machine interface daughter card (bcm9hmidc) installed on
+ * bcm958300k/bcm958305k boards
+ */
+
+&touchscreen {
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
index 5c99fb3..3c0907b 100644
--- a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
+++ b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
@@ -45,7 +45,8 @@
compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
chosen {
- bootargs = "console=ttyS0,115200 earlyprintk";
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
};
memory {
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index ef811de..ae81009 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -47,6 +47,12 @@
model = "Marvell Armada 1500 (BG2) SoC";
compatible = "marvell,berlin2", "marvell,berlin";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -57,6 +63,16 @@
device_type = "cpu";
next-level-cache = <&l2>;
reg = <0>;
+
+ clocks = <&chip_clk CLKID_CPU>;
+ clock-latency = <100000>;
+ operating-points = <
+ /* kHz uV */
+ 1200000 1200000
+ 1000000 1200000
+ 800000 1200000
+ 600000 1200000
+ >;
};
cpu@1 {
@@ -404,6 +420,13 @@
};
};
+ pwm: pwm@f20000 {
+ compatible = "marvell,berlin-pwm";
+ reg = <0xf20000 0x40>;
+ clocks = <&chip_clk CLKID_CFG>;
+ #pwm-cells = <3>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -412,6 +435,29 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;
+ wdt0: watchdog@1000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x1000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <0>;
+ };
+
+ wdt1: watchdog@2000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ wdt2: watchdog@3000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x3000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
sm_gpio1: gpio@5000 {
compatible = "snps,dw-apb-gpio";
reg = <0x5000 0x400>;
diff --git a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
index 772165a..8ba8b50 100644
--- a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
+++ b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
@@ -46,7 +46,8 @@
compatible = "google,chromecast", "marvell,berlin2cd", "marvell,berlin";
chosen {
- bootargs = "console=ttyS0,115200 earlyprintk";
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
};
memory {
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 900213d..6d06b61 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -47,6 +47,11 @@
model = "Marvell Armada 1500-mini (BG2CD) SoC";
compatible = "marvell,berlin2cd", "marvell,berlin";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -56,6 +61,14 @@
device_type = "cpu";
next-level-cache = <&l2>;
reg = <0>;
+
+ clocks = <&chip_clk CLKID_CPU>;
+ clock-latency = <100000>;
+ operating-points = <
+ /* kHz uV */
+ 800000 1200000
+ 600000 1200000
+ >;
};
};
@@ -368,6 +381,13 @@
status = "disabled";
};
+ pwm: pwm@f20000 {
+ compatible = "marvell,berlin-pwm";
+ reg = <0xf20000 0x40>;
+ clocks = <&chip_clk CLKID_CFG>;
+ #pwm-cells = <3>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -376,6 +396,29 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;
+ wdt0: watchdog@1000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x1000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <0>;
+ };
+
+ wdt1: watchdog@2000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ wdt2: watchdog@3000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x3000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
sm_gpio1: gpio@5000 {
compatible = "snps,dw-apb-gpio";
reg = <0x5000 0x400>;
diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
index 4a749e5..33b2875 100644
--- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -49,7 +49,8 @@
};
choosen {
- bootargs = "console=ttyS0,115200 earlyprintk";
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
};
regulators {
@@ -83,17 +84,49 @@
gpio = <&portb 12 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ reg_sdio1_vmmc: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "sdio1_vmmc";
+ enable-active-high;
+ regulator-boot-on;
+ gpio = <&portb 21 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_sdio1_vqmmc: regulator@4 {
+ compatible = "regulator-gpio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "sdio1_vqmmc";
+ regulator-type = "voltage";
+ enable-active-high;
+ gpios = <&portb 16 GPIO_ACTIVE_HIGH>;
+ states = <3300000 0x1
+ 1800000 0x0>;
+ };
+ };
+};
+
+&soc_pinctrl {
+ sd1gpio_pmux: sd1pwr-pmux {
+ groups = "G23", "G32";
+ function = "gpio";
};
};
&sdhci1 {
- broken-cd;
- sdhci,wp-inverted;
+ vmmc-supply = <&reg_sdio1_vmmc>;
+ vqmmc-supply = <&reg_sdio1_vqmmc>;
+ cd-gpios = <&portc 30 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&portd 0 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&sd1gpio_pmux>, <&sd1_pmux>;
+ pinctrl-names = "default";
status = "okay";
};
&sdhci2 {
- broken-cd;
bus-width = <8>;
non-removable;
status = "okay";
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index d4dbd28..2c34bfb 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -43,6 +43,11 @@
model = "Marvell Armada 1500 pro (BG2-Q) SoC";
compatible = "marvell,berlin2q", "marvell,berlin";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -53,6 +58,17 @@
device_type = "cpu";
next-level-cache = <&l2>;
reg = <0>;
+
+ clocks = <&chip_clk CLKID_CPU>;
+ clock-latency = <100000>;
+ /* Can be modified by the bootloader */
+ operating-points = <
+ /* kHz uV */
+ 1200000 1200000
+ 1000000 1200000
+ 800000 1200000
+ 600000 1200000
+ >;
};
cpu@1 {
@@ -102,7 +118,8 @@
sdhci0: sdhci@ab0000 {
compatible = "mrvl,pxav3-mmc";
reg = <0xab0000 0x200>;
- clocks = <&chip_clk CLKID_SDIO1XIN>;
+ clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+ clock-names = "io", "core";
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -110,7 +127,8 @@
sdhci1: sdhci@ab0800 {
compatible = "mrvl,pxav3-mmc";
reg = <0xab0800 0x200>;
- clocks = <&chip_clk CLKID_SDIO1XIN>;
+ clocks = <&chip_clk CLKID_SDIO1XIN>, <&chip_clk CLKID_SDIO>;
+ clock-names = "io", "core";
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -119,7 +137,7 @@
compatible = "mrvl,pxav3-mmc";
reg = <0xab1000 0x200>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_NFC>;
+ clocks = <&chip_clk CLKID_NFC_ECC>, <&chip_clk CLKID_SDIO>;
clock-names = "io", "core";
status = "disabled";
};
@@ -293,7 +311,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x1400 0x100>;
- interrupt-parent = <&aic>;
interrupts = <4>;
clocks = <&chip_clk CLKID_CFG>;
pinctrl-0 = <&twsi0_pmux>;
@@ -306,7 +323,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x1800 0x100>;
- interrupt-parent = <&aic>;
interrupts = <5>;
clocks = <&chip_clk CLKID_CFG>;
pinctrl-0 = <&twsi1_pmux>;
@@ -401,6 +417,11 @@
soc_pinctrl: pin-controller {
compatible = "marvell,berlin2q-soc-pinctrl";
+ sd1_pmux: sd1-pmux {
+ groups = "G31";
+ function = "sd1";
+ };
+
twsi0_pmux: twsi0-pmux {
groups = "G6";
function = "twsi0";
@@ -477,6 +498,13 @@
status = "disabled";
};
+ pwm: pwm@f20000 {
+ compatible = "marvell,berlin-pwm";
+ reg = <0xf20000 0x40>;
+ clocks = <&chip_clk CLKID_CFG>;
+ #pwm-cells = <3>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -485,6 +513,29 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;
+ wdt0: watchdog@1000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x1000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <0>;
+ };
+
+ wdt1: watchdog@2000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ wdt2: watchdog@3000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x3000 0x100>;
+ clocks = <&refclk>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
sm_gpio1: gpio@5000 {
compatible = "snps,dw-apb-gpio";
reg = <0x5000 0x400>;
@@ -505,7 +556,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x7000 0x100>;
- interrupt-parent = <&sic>;
interrupts = <6>;
clocks = <&refclk>;
pinctrl-0 = <&twsi2_pmux>;
@@ -518,7 +568,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x8000 0x100>;
- interrupt-parent = <&sic>;
interrupts = <7>;
clocks = <&refclk>;
pinctrl-0 = <&twsi3_pmux>;
@@ -529,7 +578,6 @@
uart0: uart@9000 {
compatible = "snps,dw-apb-uart";
reg = <0x9000 0x100>;
- interrupt-parent = <&sic>;
interrupts = <8>;
clocks = <&refclk>;
reg-shift = <2>;
@@ -541,7 +589,6 @@
uart1: uart@a000 {
compatible = "snps,dw-apb-uart";
reg = <0xa000 0x100>;
- interrupt-parent = <&sic>;
interrupts = <9>;
clocks = <&refclk>;
reg-shift = <2>;
diff --git a/arch/arm/boot/dts/compulab-sb-som.dtsi b/arch/arm/boot/dts/compulab-sb-som.dtsi
new file mode 100644
index 0000000..93d7e23
--- /dev/null
+++ b/arch/arm/boot/dts/compulab-sb-som.dtsi
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 CompuLab, Ltd. - http://www.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.
+ */
+
+/ {
+ model = "CompuLab SB-SOM";
+ compatible = "compulab,sb-som";
+
+ vsb_3v3: fixedregulator-v3_3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vsb_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ enable-active-high;
+ };
+
+ lcd0: display {
+ compatible = "startek,startek-kd050c", "panel-dpi";
+ label = "lcd";
+
+ 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>;
+ };
+ };
+
+ hdmi_conn: connector@0 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ type = "a";
+ };
+};
diff --git a/arch/arm/boot/dts/cx92755.dtsi b/arch/arm/boot/dts/cx92755.dtsi
index df4c6f1..a5a23c3 100644
--- a/arch/arm/boot/dts/cx92755.dtsi
+++ b/arch/arm/boot/dts/cx92755.dtsi
@@ -95,6 +95,13 @@
timeout-sec = <15>;
};
+ pinctrl: pinctrl@f0000e20 {
+ compatible = "cnxt,cx92755-pinctrl";
+ reg = <0xf0000e20 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
uc_regs: syscon@f00003a0 {
compatible = "cnxt,cx92755-uc", "syscon";
reg = <0xf00003a0 0x10>;
diff --git a/arch/arm/boot/dts/cx92755_equinox.dts b/arch/arm/boot/dts/cx92755_equinox.dts
index 5da0080..026f556c 100644
--- a/arch/arm/boot/dts/cx92755_equinox.dts
+++ b/arch/arm/boot/dts/cx92755_equinox.dts
@@ -70,8 +70,17 @@
&uart0 {
status = "okay";
+ pinctrl-0 = <&uart0_default>;
+ pinctrl-names = "default";
};
&i2c {
status = "okay";
};
+
+&pinctrl {
+ uart0_default: uart0_active {
+ pins = "GP_O0", "GP_O1";
+ function = "client_b";
+ };
+};
diff --git a/arch/arm/boot/dts/da850-enbw-cmc.dts b/arch/arm/boot/dts/da850-enbw-cmc.dts
index e750ab9..645549e 100644
--- a/arch/arm/boot/dts/da850-enbw-cmc.dts
+++ b/arch/arm/boot/dts/da850-enbw-cmc.dts
@@ -28,3 +28,11 @@
};
};
};
+
+&edma0 {
+ ti,edma-reserved-slot-ranges = <32 50>;
+};
+
+&edma1 {
+ ti,edma-reserved-slot-ranges = <32 90>;
+};
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index 4f935ad..ef061e9 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -242,3 +242,11 @@
tx-num-evt = <32>;
rx-num-evt = <32>;
};
+
+&edma0 {
+ ti,edma-reserved-slot-ranges = <32 50>;
+};
+
+&edma1 {
+ ti,edma-reserved-slot-ranges = <32 90>;
+};
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 0bd98cd..226cda7 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -151,10 +151,44 @@
};
edma0: edma@01c00000 {
- compatible = "ti,edma3";
- reg = <0x0 0x10000>;
- interrupts = <11 13 12>;
- #dma-cells = <1>;
+ compatible = "ti,edma3-tpcc";
+ /* eDMA3 CC0: 0x01c0 0000 - 0x01c0 7fff */
+ reg = <0x0 0x8000>;
+ reg-names = "edma3_cc";
+ interrupts = <11 12>;
+ interrupt-names = "edma3_ccint", "edma3_ccerrint";
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+ };
+ edma0_tptc0: tptc@01c08000 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x8000 0x400>;
+ interrupts = <13>;
+ interrupt-names = "edm3_tcerrint";
+ };
+ edma0_tptc1: tptc@01c08400 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x8400 0x400>;
+ interrupts = <32>;
+ interrupt-names = "edm3_tcerrint";
+ };
+ edma1: edma@01e30000 {
+ compatible = "ti,edma3-tpcc";
+ /* eDMA3 CC1: 0x01e3 0000 - 0x01e3 7fff */
+ reg = <0x230000 0x8000>;
+ reg-names = "edma3_cc";
+ interrupts = <93 94>;
+ interrupt-names = "edma3_ccint", "edma3_ccerrint";
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma1_tptc0 7>;
+ };
+ edma1_tptc0: tptc@01e38000 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x238000 0x400>;
+ interrupts = <95>;
+ interrupt-names = "edm3_tcerrint";
};
serial0: serial@1c42000 {
compatible = "ns16550a";
@@ -201,6 +235,16 @@
compatible = "ti,da830-mmc";
reg = <0x40000 0x1000>;
interrupts = <16>;
+ dmas = <&edma0 16 0>, <&edma0 17 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ mmc1: mmc@1e1b000 {
+ compatible = "ti,da830-mmc";
+ reg = <0x21b000 0x1000>;
+ interrupts = <72>;
+ dmas = <&edma1 28 0>, <&edma1 29 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
ehrpwm0: ehrpwm@01f00000 {
@@ -241,6 +285,8 @@
num-cs = <4>;
ti,davinci-spi-intr-line = <1>;
interrupts = <56>;
+ dmas = <&edma0 18 0>, <&edma0 19 0>;
+ dma-names = "rx", "tx";
status = "disabled";
};
mdio: mdio@1e24000 {
@@ -285,8 +331,8 @@
interrupts = <54>;
interrupt-names = "common";
status = "disabled";
- dmas = <&edma0 1>,
- <&edma0 0>;
+ dmas = <&edma0 1 1>,
+ <&edma0 0 1>;
dma-names = "tx", "rx";
};
};
diff --git a/arch/arm/boot/dts/dm8148-evm.dts b/arch/arm/boot/dts/dm8148-evm.dts
index 109fd47..e070862 100644
--- a/arch/arm/boot/dts/dm8148-evm.dts
+++ b/arch/arm/boot/dts/dm8148-evm.dts
@@ -15,6 +15,14 @@
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
};
+
+ /* MIC94060YC6 controlled by SD1_POW pin */
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&cpsw_emac0 {
@@ -26,3 +34,50 @@
phy_id = <&davinci_mdio>, <1>;
phy-mode = "rgmii";
};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+};
+
+&pincntl {
+ sd1_pins: pinmux_sd1_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0800, PIN_INPUT | 0x1) /* SD1_CLK */
+ DM814X_IOPAD(0x0804, PIN_INPUT_PULLUP | 0x1) /* SD1_CMD */
+ DM814X_IOPAD(0x0808, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[0] */
+ DM814X_IOPAD(0x080c, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[1] */
+ DM814X_IOPAD(0x0810, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[2] */
+ DM814X_IOPAD(0x0814, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[3] */
+ DM814X_IOPAD(0x0924, PIN_OUTPUT | 0x40) /* SD1_POW */
+ DM814X_IOPAD(0x093C, PIN_INPUT_PULLUP | 0x80) /* GP1[6] */
+ >;
+ };
+
+ usb0_pins: pinmux_usb0_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1) /* USB0_DRVVBUS */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0834, PIN_OUTPUT | 0x80) /* USB1_DRVVBUS */
+ >;
+ };
+};
+
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins>;
+ dr_mode = "host";
+};
+
+&usb1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+ dr_mode = "host";
+};
diff --git a/arch/arm/boot/dts/dm8148-t410.dts b/arch/arm/boot/dts/dm8148-t410.dts
index 79838dd..5d4313f 100644
--- a/arch/arm/boot/dts/dm8148-t410.dts
+++ b/arch/arm/boot/dts/dm8148-t410.dts
@@ -15,6 +15,24 @@
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
};
+
+ /* gpio9 seems to control USB VBUS regulator and/or hub power */
+ usb_power: regulator@9 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&cpsw_emac0 {
@@ -26,3 +44,55 @@
phy_id = <&davinci_mdio>, <1>;
phy-mode = "rgmii";
};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ dmas = <&edma_xbar 8 0 1 /* use SDTXEVT1 instead of MCASP0TX */
+ &edma_xbar 9 0 2>; /* use SDRXEVT1 instead of MCASP0RX */
+ dma-names = "tx", "rx";
+};
+
+&pincntl {
+ sd2_pins: pinmux_sd2_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x09c0, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[7] */
+ DM814X_IOPAD(0x09c4, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[6] */
+ DM814X_IOPAD(0x09c8, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[5] */
+ DM814X_IOPAD(0x09cc, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[4] */
+ DM814X_IOPAD(0x09d0, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[3] */
+ DM814X_IOPAD(0x09d4, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[2] */
+ DM814X_IOPAD(0x09d8, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[1] */
+ DM814X_IOPAD(0x09dc, PIN_INPUT_PULLUP | 0x1) /* SD2_DAT[0] */
+ DM814X_IOPAD(0x09e0, PIN_INPUT | 0x1) /* SD2_CLK */
+ DM814X_IOPAD(0x09f4, PIN_INPUT_PULLUP | 0x2) /* SD2_CMD */
+ DM814X_IOPAD(0x0920, PIN_INPUT | 40) /* SD2_SDCD */
+ >;
+ };
+
+ usb0_pins: pinmux_usb0_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1) /* USB0_DRVVBUS */
+ >;
+ };
+
+ usb1_pins: pinmux_usb1_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0834, PIN_OUTPUT | 0x80) /* USB1_DRVVBUS */
+ >;
+ };
+};
+
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins>;
+ dr_mode = "host";
+};
+
+&usb1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
+ dr_mode = "host";
+};
diff --git a/arch/arm/boot/dts/dm814x-clocks.dtsi b/arch/arm/boot/dts/dm814x-clocks.dtsi
index ef1e8e7..2600158 100644
--- a/arch/arm/boot/dts/dm814x-clocks.dtsi
+++ b/arch/arm/boot/dts/dm814x-clocks.dtsi
@@ -4,25 +4,74 @@
* published by the Free Software Foundation.
*/
+&pllss_clocks {
+ timer1_fck: timer1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+ &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+ ti,bit-shift = <3>;
+ reg = <0x2e0>;
+ };
+
+ timer2_fck: timer2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+ &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+ ti,bit-shift = <6>;
+ reg = <0x2e0>;
+ };
+
+ sysclk18_ck: sysclk18_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&rtcosc_ck>, <&rtcdivider_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x02f0>;
+ };
+};
+
&scm_clocks {
+ devosc_ck: devosc_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&virt_20000000_ck>, <&virt_19200000_ck>;
+ ti,bit-shift = <21>;
+ reg = <0x0040>;
+ };
- tclkin_ck: tclkin_ck {
+ /* Optional auxosc, 20 - 30 MHz range, assume 27 MHz by default */
+ auxosc_ck: auxosc_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ /* Optional 32768Hz crystal or clock on RTCOSC pins */
+ rtcosc_ck: rtcosc_ck {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
};
- devosc_ck: devosc_ck {
+ /* Optional external clock on TCLKIN pin, set rate in baord dts file */
+ tclkin_ck: tclkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ virt_20000000_ck: virt_20000000_ck {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <20000000>;
};
- /* Optional auxosc, 20 - 30 MHz range, assume 27 MHz by default */
- auxosc_ck: auxosc_ck {
+ virt_19200000_ck: virt_19200000_ck {
#clock-cells = <0>;
compatible = "fixed-clock";
- clock-frequency = <27000000>;
+ clock-frequency = <19200000>;
};
mpu_ck: mpu_ck {
@@ -49,12 +98,6 @@
clock-frequency = <48000000>;
};
- sysclk18_ck: sysclk18_ck {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <32768>;
- };
-
cpsw_125mhz_gclk: cpsw_125mhz_gclk {
#clock-cells = <0>;
compatible = "fixed-clock";
@@ -69,7 +112,31 @@
};
-&pllss_clocks {
+&prcm_clocks {
+ osc_src_ck: osc_src_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&devosc_ck>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ };
+
+ mpu_clksrc_ck: mpu_clksrc_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&devosc_ck>, <&rtcdivider_ck>;
+ ti,bit-shift = <0>;
+ reg = <0x0040>;
+ };
+
+ /* Fixed divider clock 0.0016384 * devosc */
+ rtcdivider_ck: rtcdivider_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&devosc_ck>;
+ clock-mult = <128>;
+ clock-div = <78125>;
+ };
aud_clkin0_ck: aud_clkin0_ck {
#clock-cells = <0>;
@@ -88,22 +155,4 @@
compatible = "fixed-clock";
clock-frequency = <20000000>;
};
-
- timer1_mux_ck: timer1_mux_ck {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
- &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
- ti,bit-shift = <3>;
- reg = <0x2e0>;
- };
-
- timer2_mux_ck: timer2_mux_ck {
- #clock-cells = <0>;
- compatible = "ti,mux-clock";
- clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
- &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
- ti,bit-shift = <6>;
- reg = <0x2e0>;
- };
};
diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi
index 7988b42..a25cd51 100644
--- a/arch/arm/boot/dts/dm814x.dtsi
+++ b/arch/arm/boot/dts/dm814x.dtsi
@@ -5,7 +5,7 @@
*/
#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/omap.h>
+#include <dt-bindings/pinctrl/dm814x.h>
#include "skeleton.dtsi"
@@ -21,6 +21,10 @@
serial2 = &uart3;
ethernet0 = &cpsw_emac0;
ethernet1 = &cpsw_emac1;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ phy0 = &usb0_phy;
+ phy1 = &usb1_phy;
};
cpus {
@@ -57,9 +61,118 @@
ranges;
ti,hwmods = "l3_main";
+ usb: usb@47400000 {
+ compatible = "ti,am33xx-usb";
+ reg = <0x47400000 0x1000>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,hwmods = "usb_otg_hs";
+
+ usb0_phy: usb-phy@47401300 {
+ compatible = "ti,am335x-usb-phy";
+ reg = <0x47401300 0x100>;
+ reg-names = "phy";
+ ti,ctrl_mod = <&usb_ctrl_mod>;
+ };
+
+ usb0: usb@47401000 {
+ compatible = "ti,musb-am33xx";
+ 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: usb@47401800 {
+ compatible = "ti,musb-am33xx";
+ 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>;
+ };
+ };
+
/*
- * See TRM "Table 1-317. L4LS Instance Summary", just deduct
- * 0x1000 from the 1-317 addresses to get the device address
+ * See TRM "Table 1-317. L4LS Instance Summary" for hints.
+ * It shows the module target agent registers though, so the
+ * actual device is typically 0x1000 before the target agent
+ * except in cases where the module is larger than 0x1000.
*/
l4ls: l4ls@48000000 {
compatible = "ti,dm814-l4ls", "simple-bus";
@@ -124,8 +237,8 @@
interrupts = <65>;
ti,spi-num-cs = <4>;
ti,hwmods = "mcspi1";
- dmas = <&edma 16 &edma 17
- &edma 18 &edma 19>;
+ dmas = <&edma 16 0 &edma 17 0
+ &edma 18 0 &edma 19 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
};
@@ -143,7 +256,7 @@
reg = <0x20000 0x2000>;
clock-frequency = <48000000>;
interrupts = <72>;
- dmas = <&edma 26 &edma 27>;
+ dmas = <&edma 26 0 &edma 27 0>;
dma-names = "tx", "rx";
};
@@ -153,7 +266,7 @@
reg = <0x22000 0x2000>;
clock-frequency = <48000000>;
interrupts = <73>;
- dmas = <&edma 28 &edma 29>;
+ dmas = <&edma 28 0 &edma 29 0>;
dma-names = "tx", "rx";
};
@@ -163,7 +276,7 @@
reg = <0x24000 0x2000>;
clock-frequency = <48000000>;
interrupts = <74>;
- dmas = <&edma 30 &edma 31>;
+ dmas = <&edma 30 0 &edma 31 0>;
dma-names = "tx", "rx";
};
@@ -181,12 +294,34 @@
ti,hwmods = "timer3";
};
+ mmc1: mmc@60000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc1";
+ dmas = <&edma 24 0
+ &edma 25 0>;
+ dma-names = "tx", "rx";
+ interrupts = <64>;
+ interrupt-parent = <&intc>;
+ reg = <0x60000 0x1000>;
+ };
+
+ mmc2: mmc@1d8000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc2";
+ dmas = <&edma 2 0
+ &edma 3 0>;
+ dma-names = "tx", "rx";
+ interrupts = <28>;
+ interrupt-parent = <&intc>;
+ reg = <0x1d8000 0x1000>;
+ };
+
control: control@140000 {
compatible = "ti,dm814-scm", "simple-bus";
- reg = <0x140000 0x16d000>;
+ reg = <0x140000 0x20000>;
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0 0x160000 0x16d000>;
+ ranges = <0 0x140000 0x20000>;
scm_conf: scm_conf@0 {
compatible = "syscon";
@@ -203,19 +338,52 @@
};
};
+ usb_ctrl_mod: control@620 {
+ compatible = "ti,am335x-usb-ctrl-module";
+ reg = <0x620 0x10
+ 0x648 0x4>;
+ reg-names = "phy_ctrl", "wakeup";
+ };
+
+ edma_xbar: dma-router@f90 {
+ compatible = "ti,am335x-edma-crossbar";
+ reg = <0xf90 0x40>;
+ #dma-cells = <3>;
+ dma-requests = <32>;
+ dma-masters = <&edma>;
+ };
+
+ /*
+ * Note that silicon revision 2.1 and older
+ * require input enabled (bit 18 set) for all
+ * 3.3V I/Os to avoid cumulative hardware damage.
+ * For more info, see errata advisory 2.1.87.
+ * We leave bit 18 out of function-mask and rely
+ * on the bootloader for it.
+ */
pincntl: pinmux@800 {
compatible = "pinctrl-single";
- reg = <0x800 0xc38>;
+ reg = <0x800 0x438>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-single,register-width = <32>;
- pinctrl-single,function-mask = <0x300ff>;
+ pinctrl-single,function-mask = <0x307ff>;
+ };
+
+ usb1_phy: usb-phy@1b00 {
+ compatible = "ti,am335x-usb-phy";
+ reg = <0x1b00 0x100>;
+ reg-names = "phy";
+ ti,ctrl_mod = <&usb_ctrl_mod>;
};
};
prcm: prcm@180000 {
compatible = "ti,dm814-prcm", "simple-bus";
- reg = <0x180000 0x4000>;
+ reg = <0x180000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x180000 0x2000>;
prcm_clocks: clocks {
#address-cells = <1>;
@@ -226,9 +394,13 @@
};
};
+ /* See TRM PLL_SUBSYS_BASE and "PLLSS Registers" */
pllss: pllss@1c5000 {
compatible = "ti,dm814-pllss", "simple-bus";
- reg = <0x1c5000 0x2000>;
+ reg = <0x1c5000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x1c5000 0x1000>;
pllss_clocks: clocks {
#address-cells = <1>;
@@ -254,13 +426,62 @@
reg = <0x48200000 0x1000>;
};
+ /* Board must configure evtmux with edma_xbar for EDMA */
+ mmc3: mmc@47810000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc3";
+ interrupts = <29>;
+ interrupt-parent = <&intc>;
+ reg = <0x47810000 0x1000>;
+ };
+
edma: edma@49000000 {
- compatible = "ti,edma3";
- ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
- reg = <0x49000000 0x10000>,
- <0x44e10f90 0x40>;
+ compatible = "ti,edma3-tpcc";
+ ti,hwmods = "tpcc";
+ reg = <0x49000000 0x10000>;
+ reg-names = "edma3_cc";
interrupts = <12 13 14>;
- #dma-cells = <1>;
+ interrupt-names = "edma3_ccint", "emda3_mperr",
+ "edma3_ccerrint";
+ dma-requests = <64>;
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
+ <&edma_tptc2 3>, <&edma_tptc3 0>;
+
+ ti,edma-memcpy-channels = <20 21>;
+ };
+
+ edma_tptc0: tptc@49800000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc0";
+ reg = <0x49800000 0x100000>;
+ interrupts = <112>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc1: tptc@49900000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc1";
+ reg = <0x49900000 0x100000>;
+ interrupts = <113>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc2: tptc@49a00000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc2";
+ reg = <0x49a00000 0x100000>;
+ interrupts = <114>;
+ interrupt-names = "edma3_tcerrint";
+ };
+
+ edma_tptc3: tptc@49b00000 {
+ compatible = "ti,edma3-tptc";
+ ti,hwmods = "tptc3";
+ reg = <0x49b00000 0x100000>;
+ interrupts = <115>;
+ interrupt-names = "edma3_tcerrint";
};
/* See TRM "Table 1-318. L4HS Instance Summary" */
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
index 3c99cfa..c3b8811 100644
--- a/arch/arm/boot/dts/dm816x.dtsi
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -64,7 +64,6 @@
#address-cells = <1>;
#size-cells = <1>;
ranges;
- ti,hwmods = "l3_main";
prcm: prcm@48180000 {
compatible = "ti,dm816-prcm";
@@ -180,6 +179,8 @@
#address-cells = <2>;
#size-cells = <1>;
interrupts = <100>;
+ dmas = <&edma 52>;
+ dma-names = "rxtx";
gpmc,num-cs = <6>;
gpmc,num-waitpins = <2>;
};
@@ -218,6 +219,7 @@
reg = <0x480c8000 0x2000>;
interrupts = <77>;
ti,hwmods = "mailbox";
+ #mbox-cells = <1>;
ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <12>;
mbox_dsp: mbox_dsp {
@@ -226,6 +228,13 @@
};
};
+ spinbox: spinbox@480ca000 {
+ compatible = "ti,omap4-hwspinlock";
+ reg = <0x480ca000 0x2000>;
+ ti,hwmods = "spinbox";
+ #hwlock-cells = <1>;
+ };
+
mdio: mdio@4a100800 {
compatible = "ti,davinci_mdio";
#address-cells = <1>;
@@ -279,8 +288,11 @@
ti,spi-num-cs = <4>;
ti,hwmods = "mcspi1";
dmas = <&edma 16 &edma 17
- &edma 18 &edma 19>;
- dma-names = "tx0", "rx0", "tx1", "rx1";
+ &edma 18 &edma 19
+ &edma 20 &edma 21
+ &edma 22 &edma 23>;
+ dma-names = "tx0", "rx0", "tx1", "rx1",
+ "tx2", "rx2", "tx3", "rx3";
};
mmc1: mmc@48060000 {
@@ -319,6 +331,7 @@
reg = <0x48044000 0x2000>;
interrupts = <92>;
ti,hwmods = "timer4";
+ ti,timer-pwm;
};
timer5: timer@48046000 {
@@ -326,6 +339,7 @@
reg = <0x48046000 0x2000>;
interrupts = <93>;
ti,hwmods = "timer5";
+ ti,timer-pwm;
};
timer6: timer@48048000 {
@@ -333,6 +347,7 @@
reg = <0x48048000 0x2000>;
interrupts = <94>;
ti,hwmods = "timer6";
+ ti,timer-pwm;
};
timer7: timer@4804a000 {
@@ -340,6 +355,7 @@
reg = <0x4804a000 0x2000>;
interrupts = <95>;
ti,hwmods = "timer7";
+ ti,timer-pwm;
};
uart1: uart@48020000 {
diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts
index e6fa251..af3cb63 100644
--- a/arch/arm/boot/dts/dove-cubox.dts
+++ b/arch/arm/boot/dts/dove-cubox.dts
@@ -62,6 +62,10 @@
pinctrl-0 = <&pmx_gpio_19>;
pinctrl-names = "default";
};
+
+ gpu-subsystem {
+ status = "okay";
+ };
};
&uart0 { status = "okay"; };
@@ -74,6 +78,10 @@
reg = <1>;
};
+&gpu {
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
clock-frequency = <100000>;
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 1791216..698d58c 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -33,6 +33,12 @@
marvell,tauros2-cache-features = <0>;
};
+ gpu-subsystem {
+ compatible = "marvell,dove-gpu-subsystem";
+ cores = <&gpu>;
+ status = "disabled";
+ };
+
i2c-mux {
compatible = "i2c-mux-pinctrl";
#address-cells = <1>;
@@ -263,12 +269,13 @@
};
crypto: crypto-engine@30000 {
- compatible = "marvell,orion-crypto";
- reg = <0x30000 0x10000>,
- <0xffffe000 0x800>;
- reg-names = "regs", "sram";
+ compatible = "marvell,dove-crypto";
+ reg = <0x30000 0x10000>;
+ reg-names = "regs";
interrupts = <31>;
clocks = <&gate_clk 15>;
+ marvell,crypto-srams = <&crypto_sram>;
+ marvell,crypto-sram-size = <0x800>;
status = "okay";
};
@@ -459,6 +466,12 @@
#clock-cells = <1>;
};
+ divider_clk: core-clock@0064 {
+ compatible = "marvell,dove-divider-clock";
+ reg = <0x0064 0x8>;
+ #clock-cells = <1>;
+ };
+
pinctrl: pin-ctrl@0200 {
compatible = "marvell,dove-pinctrl";
reg = <0x0200 0x14>,
@@ -767,6 +780,24 @@
interrupts = <47>;
status = "disabled";
};
+
+ crypto_sram: sa-sram@ffffe000 {
+ compatible = "mmio-sram";
+ reg = <0xffffe000 0x800>;
+ clocks = <&gate_clk 15>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ gpu: gpu@840000 {
+ clocks = <&divider_clk 1>;
+ clock-names = "core";
+ compatible = "vivante,gc";
+ interrupts = <48>;
+ power-domains = <&gpu_domain>;
+ reg = <0x840000 0x4000>;
+ status = "disabled";
+ };
};
};
};
diff --git a/arch/arm/boot/dts/dra62x-clocks.dtsi b/arch/arm/boot/dts/dra62x-clocks.dtsi
new file mode 100644
index 0000000..6f98dc8
--- /dev/null
+++ b/arch/arm/boot/dts/dra62x-clocks.dtsi
@@ -0,0 +1,23 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "dm814x-clocks.dtsi"
+
+/*
+ * Compared to dm814x, dra62x has different shifts and more mux options.
+ * Please add the extra options for ysclk_14 and 16 if really needed.
+ */
+&timer1_fck {
+ clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+ &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+ ti,bit-shift = <4>;
+};
+
+&timer2_fck {
+ clocks = <&sysclk18_ck &aud_clkin0_ck &aud_clkin1_ck
+ &aud_clkin2_ck &devosc_ck &auxosc_ck &tclkin_ck>;
+ ti,bit-shift = <8>;
+};
diff --git a/arch/arm/boot/dts/dra62x-j5eco-evm.dts b/arch/arm/boot/dts/dra62x-j5eco-evm.dts
new file mode 100644
index 0000000..7900806
--- /dev/null
+++ b/arch/arm/boot/dts/dra62x-j5eco-evm.dts
@@ -0,0 +1,80 @@
+/*
+ * This program is free software; you can 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 "dra62x.dtsi"
+
+/ {
+ model = "DRA62x J5 Eco EVM";
+ compatible = "ti,dra62x-j5eco-evm", "ti,dra62x", "ti,dm8148";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+
+ /* MIC94060YC6 controlled by SD1_POW pin */
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_pins>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <4>;
+ cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+};
+
+&pincntl {
+ sd1_pins: pinmux_sd1_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0800, PIN_INPUT | 0x1) /* SD1_CLK */
+ DM814X_IOPAD(0x0804, PIN_INPUT_PULLUP | 0x1) /* SD1_CMD */
+ DM814X_IOPAD(0x0808, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[0] */
+ DM814X_IOPAD(0x080c, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[1] */
+ DM814X_IOPAD(0x0810, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[2] */
+ DM814X_IOPAD(0x0814, PIN_INPUT_PULLUP | 0x1) /* SD1_DAT[3] */
+ DM814X_IOPAD(0x0924, PIN_OUTPUT | 0x40) /* SD1_POW */
+ DM814X_IOPAD(0x093C, PIN_INPUT_PULLUP | 0x80) /* GP1[6] */
+ >;
+ };
+
+ usb0_pins: pinmux_usb0_pins {
+ pinctrl-single,pins = <
+ DM814X_IOPAD(0x0c34, PIN_OUTPUT | 0x1) /* USB0_DRVVBUS */
+ >;
+ };
+};
+
+/* USB0_ID pin state: SW10[1] = 0 cable detection, SW10[1] = 1 ID grounded */
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins>;
+ dr_mode = "otg";
+};
+
+&usb1_phy {
+ status = "disabled";
+};
+
+&usb1 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/dra62x.dtsi b/arch/arm/boot/dts/dra62x.dtsi
new file mode 100644
index 0000000..d3cbb4e
--- /dev/null
+++ b/arch/arm/boot/dts/dra62x.dtsi
@@ -0,0 +1,23 @@
+/*
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include "dm814x.dtsi"
+
+/ {
+ compatible = "ti,dra62x";
+};
+
+/* Compared to dm814x, dra62x has different offsets for Ethernet */
+&mac {
+ reg = <0x4a100000 0x800
+ 0x4a101200 0x100>;
+};
+
+&davinci_mdio {
+ reg = <0x4a101000 0x100>;
+};
+
+#include "dra62x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index a6c82e5..cfc24e5 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -9,6 +9,8 @@
#include "dra74x.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/ti-dra7-atl.h>
+#include <dt-bindings/input/input.h>
/ {
model = "TI DRA742";
@@ -28,13 +30,22 @@
gpio = <&pcf_gpio_21 5 GPIO_ACTIVE_HIGH>;
};
- mmc2_3v3: fixedregulator-mmc2 {
+ evm_3v3_sw: fixedregulator-evm_3v3_sw {
compatible = "regulator-fixed";
- regulator-name = "mmc2_3v3";
+ regulator-name = "evm_3v3_sw";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
+ aic_dvdd: fixedregulator-aic_dvdd {
+ /* TPS77018DBVT */
+ compatible = "regulator-fixed";
+ regulator-name = "aic_dvdd";
+ vin-supply = <&evm_3v3_sw>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
extcon_usb1: extcon_usb1 {
compatible = "linux,extcon-usb-gpio";
id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
@@ -55,6 +66,86 @@
enable-active-high;
gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
};
+
+ sound0: sound@0 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "DRA7xx-EVM";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line Out",
+ "Microphone", "Mic Jack",
+ "Line", "Line In";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT",
+ "MIC3L", "Mic Jack",
+ "MIC3R", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound0_master>;
+ simple-audio-card,frame-master = <&sound0_master>;
+ simple-audio-card,bitclock-inversion;
+
+ sound0_master: simple-audio-card,cpu {
+ sound-dai = <&mcasp3>;
+ system-clock-frequency = <5644800>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&atl_clkin2_ck>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led@0 {
+ label = "dra7:usr1";
+ gpios = <&pcf_lcd 4 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led@1 {
+ label = "dra7:usr2";
+ gpios = <&pcf_lcd 5 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led@2 {
+ label = "dra7:usr3";
+ gpios = <&pcf_lcd 6 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "dra7:usr4";
+ gpios = <&pcf_lcd 7 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+
+ USER1 {
+ label = "btnUser1";
+ linux,code = <BTN_0>;
+ gpios = <&pcf_lcd 2 GPIO_ACTIVE_LOW>;
+ };
+
+ USER2 {
+ label = "btnUser2";
+ linux,code = <BTN_1>;
+ gpios = <&pcf_lcd 3 GPIO_ACTIVE_LOW>;
+ };
+ };
};
&dra7_pmx_core {
@@ -63,100 +154,100 @@
vtt_pin: pinmux_vtt_pin {
pinctrl-single,pins = <
- 0x3b4 (PIN_OUTPUT | MUX_MODE14) /* spi1_cs1.gpio7_11 */
+ DRA7XX_CORE_IOPAD(0x37b4, 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 */
+ DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+ DRA7XX_CORE_IOPAD(0x3804, 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 */
+ DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE0) /* i2c2_sda */
+ DRA7XX_CORE_IOPAD(0x380c, 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 */
+ DRA7XX_CORE_IOPAD(0x3688, PIN_INPUT | MUX_MODE9) /* gpio6_14.i2c3_sda */
+ DRA7XX_CORE_IOPAD(0x368c, 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 */
+ DRA7XX_CORE_IOPAD(0x37a4, PIN_INPUT | MUX_MODE0) /* spi1_sclk */
+ DRA7XX_CORE_IOPAD(0x37a8, PIN_INPUT | MUX_MODE0) /* spi1_d1 */
+ DRA7XX_CORE_IOPAD(0x37ac, PIN_INPUT | MUX_MODE0) /* spi1_d0 */
+ DRA7XX_CORE_IOPAD(0x37b0, PIN_INPUT_SLEW | MUX_MODE0) /* spi1_cs0 */
+ DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_SLEW | MUX_MODE6) /* spi1_cs2.hdmi1_hpd */
+ DRA7XX_CORE_IOPAD(0x37bc, 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 */
+ DRA7XX_CORE_IOPAD(0x37c0, PIN_INPUT | MUX_MODE0) /* spi2_sclk */
+ DRA7XX_CORE_IOPAD(0x37c4, PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+ DRA7XX_CORE_IOPAD(0x37c8, PIN_INPUT_SLEW | MUX_MODE0) /* spi2_d1 */
+ DRA7XX_CORE_IOPAD(0x37cc, 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 */
+ DRA7XX_CORE_IOPAD(0x37e0, PIN_INPUT_SLEW | MUX_MODE0) /* uart1_rxd */
+ DRA7XX_CORE_IOPAD(0x37e4, PIN_INPUT_SLEW | MUX_MODE0) /* uart1_txd */
+ DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT | MUX_MODE3) /* uart1_ctsn */
+ DRA7XX_CORE_IOPAD(0x37ec, 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 */
+ DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT | MUX_MODE0) /* uart2_rxd */
+ DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT | MUX_MODE0) /* uart2_txd */
+ DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT | MUX_MODE0) /* uart2_ctsn */
+ DRA7XX_CORE_IOPAD(0x37fc, 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 */
+ DRA7XX_CORE_IOPAD(0x3648, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */
+ DRA7XX_CORE_IOPAD(0x364c, 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 */
+ DRA7XX_CORE_IOPAD(0x344c, PIN_INPUT | MUX_MODE1) /* gpmc_a3.qspi1_cs2 */
+ DRA7XX_CORE_IOPAD(0x3450, PIN_INPUT | MUX_MODE1) /* gpmc_a4.qspi1_cs3 */
+ DRA7XX_CORE_IOPAD(0x3474, PIN_INPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ DRA7XX_CORE_IOPAD(0x3478, PIN_INPUT | MUX_MODE1) /* gpmc_a14.qspi1_d3 */
+ DRA7XX_CORE_IOPAD(0x347c, PIN_INPUT | MUX_MODE1) /* gpmc_a15.qspi1_d2 */
+ DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+ DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d0 */
+ DRA7XX_CORE_IOPAD(0x3488, PIN_INPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ DRA7XX_CORE_IOPAD(0x34b8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+ DRA7XX_CORE_IOPAD(0x34bc, 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 */
+ DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
>;
};
usb2_pins: pinmux_usb2_pins {
pinctrl-single,pins = <
- 0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+ DRA7XX_CORE_IOPAD(0x3684, PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
>;
};
@@ -166,60 +257,60 @@
* 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 */
+ DRA7XX_CORE_IOPAD(0x3400, PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
+ DRA7XX_CORE_IOPAD(0x3404, PIN_INPUT | MUX_MODE0) /* gpmc_ad1 */
+ DRA7XX_CORE_IOPAD(0x3408, PIN_INPUT | MUX_MODE0) /* gpmc_ad2 */
+ DRA7XX_CORE_IOPAD(0x340c, PIN_INPUT | MUX_MODE0) /* gpmc_ad3 */
+ DRA7XX_CORE_IOPAD(0x3410, PIN_INPUT | MUX_MODE0) /* gpmc_ad4 */
+ DRA7XX_CORE_IOPAD(0x3414, PIN_INPUT | MUX_MODE0) /* gpmc_ad5 */
+ DRA7XX_CORE_IOPAD(0x3418, PIN_INPUT | MUX_MODE0) /* gpmc_ad6 */
+ DRA7XX_CORE_IOPAD(0x341c, PIN_INPUT | MUX_MODE0) /* gpmc_ad7 */
+ DRA7XX_CORE_IOPAD(0x3420, PIN_INPUT | MUX_MODE0) /* gpmc_ad8 */
+ DRA7XX_CORE_IOPAD(0x3424, PIN_INPUT | MUX_MODE0) /* gpmc_ad9 */
+ DRA7XX_CORE_IOPAD(0x3428, PIN_INPUT | MUX_MODE0) /* gpmc_ad10 */
+ DRA7XX_CORE_IOPAD(0x342c, PIN_INPUT | MUX_MODE0) /* gpmc_ad11 */
+ DRA7XX_CORE_IOPAD(0x3430, PIN_INPUT | MUX_MODE0) /* gpmc_ad12 */
+ DRA7XX_CORE_IOPAD(0x3434, PIN_INPUT | MUX_MODE0) /* gpmc_ad13 */
+ DRA7XX_CORE_IOPAD(0x3438, PIN_INPUT | MUX_MODE0) /* gpmc_ad14 */
+ DRA7XX_CORE_IOPAD(0x343c, PIN_INPUT | MUX_MODE0) /* gpmc_ad15 */
+ DRA7XX_CORE_IOPAD(0x34d8, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0 */
+ DRA7XX_CORE_IOPAD(0x34cc, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
+ DRA7XX_CORE_IOPAD(0x34b4, PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0 */
+ DRA7XX_CORE_IOPAD(0x34c4, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
+ DRA7XX_CORE_IOPAD(0x34c8, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
+ DRA7XX_CORE_IOPAD(0x34d0, 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 */
+ DRA7XX_CORE_IOPAD(0x3650, PIN_OUTPUT | MUX_MODE0) /* rgmii0_txc.rgmii0_txc */
+ DRA7XX_CORE_IOPAD(0x3654, PIN_OUTPUT | MUX_MODE0) /* rgmii0_txctl.rgmii0_txctl */
+ DRA7XX_CORE_IOPAD(0x3658, PIN_OUTPUT | MUX_MODE0) /* rgmii0_td3.rgmii0_txd3 */
+ DRA7XX_CORE_IOPAD(0x365c, PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd2.rgmii0_txd2 */
+ DRA7XX_CORE_IOPAD(0x3660, PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd1.rgmii0_txd1 */
+ DRA7XX_CORE_IOPAD(0x3664, PIN_OUTPUT | MUX_MODE0) /* rgmii0_txd0.rgmii0_txd0 */
+ DRA7XX_CORE_IOPAD(0x3668, PIN_INPUT | MUX_MODE0) /* rgmii0_rxc.rgmii0_rxc */
+ DRA7XX_CORE_IOPAD(0x366c, PIN_INPUT | MUX_MODE0) /* rgmii0_rxctl.rgmii0_rxctl */
+ DRA7XX_CORE_IOPAD(0x3670, PIN_INPUT | MUX_MODE0) /* rgmii0_rxd3.rgmii0_rxd3 */
+ DRA7XX_CORE_IOPAD(0x3674, PIN_INPUT | MUX_MODE0) /* rgmii0_rxd2.rgmii0_rxd2 */
+ DRA7XX_CORE_IOPAD(0x3678, PIN_INPUT | MUX_MODE0) /* rgmii0_rxd1.rgmii0_rxd1 */
+ DRA7XX_CORE_IOPAD(0x367c, 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 */
+ DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3) /* vin2a_d12.rgmii1_txc */
+ DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3) /* vin2a_d13.rgmii1_tctl */
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3) /* vin2a_d14.rgmii1_td3 */
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3) /* vin2a_d15.rgmii1_td2 */
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3) /* vin2a_d16.rgmii1_td1 */
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3) /* vin2a_d17.rgmii1_td0 */
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+ DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
>;
};
@@ -227,60 +318,85 @@
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)
+ DRA7XX_CORE_IOPAD(0x3650, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3654, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3658, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x365c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3660, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3664, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3668, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x366c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3670, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3674, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3678, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x367c, 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)
+ DRA7XX_CORE_IOPAD(0x3598, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x359c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a4, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a8, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35ac, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b4, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b8, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35bc, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c4, 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 */
+ DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_d.mdio_d */
+ DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
davinci_mdio_sleep: davinci_mdio_sleep {
pinctrl-single,pins = <
- 0x23c (MUX_MODE15)
- 0x240 (MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x363c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3640, 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 */
+ DRA7XX_CORE_IOPAD(0x37d0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+ DRA7XX_CORE_IOPAD(0x3818, 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 */
+ DRA7XX_CORE_IOPAD(0x37d0, MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+ DRA7XX_CORE_IOPAD(0x3818, MUX_MODE15 | PULL_UP) /* wakeup0.off */
+ >;
+ };
+
+ atl_pins: pinmux_atl_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3698, PIN_OUTPUT | MUX_MODE5) /* xref_clk1.atl_clk1 */
+ DRA7XX_CORE_IOPAD(0x369c, PIN_OUTPUT | MUX_MODE5) /* xref_clk2.atl_clk2 */
+ >;
+ };
+
+ mcasp3_pins: pinmux_mcasp3_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
+ DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
+ DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1 */
+ >;
+ };
+
+ mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3728, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x372c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3730, MUX_MODE15)
>;
};
};
@@ -388,6 +504,7 @@
regulator-max-microvolt = <1050000>;
regulator-always-on;
regulator-boot-on;
+ regulator-allow-bypass;
};
ldoln_reg: ldoln {
@@ -410,6 +527,17 @@
};
};
+ pcf_lcd: gpio@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
pcf_gpio_21: gpio@21 {
compatible = "ti,pcf8575";
reg = <0x21>;
@@ -422,6 +550,20 @@
#interrupt-cells = <2>;
};
+ tlv320aic3106: tlv320aic3106@19 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x19>;
+ adc-settle-ms = <40>;
+ ai3x-micbias-vg = <1>; /* 2.0V */
+ status = "okay";
+
+ /* Regulators */
+ AVDD-supply = <&evm_3v3_sw>;
+ IOVDD-supply = <&evm_3v3_sw>;
+ DRVDD-supply = <&evm_3v3_sw>;
+ DVDD-supply = <&aic_dvdd>;
+ };
};
&i2c2 {
@@ -429,6 +571,20 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins>;
clock-frequency = <400000>;
+
+ pcf_hdmi: gpio@26 {
+ compatible = "nxp,pcf8575";
+ reg = <0x26>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ p1 {
+ /* vin6_sel_s0: high: VIN6, low: audio */
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "vin6_sel_s0";
+ };
+ };
};
&i2c3 {
@@ -479,12 +635,12 @@
* SDCD signal is not being used here - using the fact that GPIO mode
* is always hardwired.
*/
- cd-gpios = <&gpio6 27 0>;
+ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>;
};
&mmc2 {
status = "okay";
- vmmc-supply = <&mmc2_3v3>;
+ vmmc-supply = <&evm_3v3_sw>;
bus-width = <8>;
};
@@ -707,3 +863,62 @@
pinctrl-1 = <&dcan1_pins_sleep>;
pinctrl-2 = <&dcan1_pins_default>;
};
+
+&atl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&atl_pins>;
+
+ assigned-clocks = <&abe_dpll_sys_clk_mux>,
+ <&atl_gfclk_mux>,
+ <&dpll_abe_ck>,
+ <&dpll_abe_m2x2_ck>,
+ <&atl_clkin2_ck>;
+ assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>;
+ assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>;
+
+ status = "okay";
+
+ atl2 {
+ bws = <DRA7_ATL_WS_MCASP2_FSX>;
+ aws = <DRA7_ATL_WS_MCASP3_FSX>;
+ };
+};
+
+&mcasp3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mcasp3_pins>;
+ pinctrl-1 = <&mcasp3_sleep_pins>;
+
+ assigned-clocks = <&mcasp3_ahclkx_mux>;
+ assigned-clock-parents = <&atl_clkin2_ck>;
+
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializer */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 2 0 0
+ >;
+};
+
+&mailbox5 {
+ status = "okay";
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ status = "okay";
+ };
+};
+
+&mailbox6 {
+ status = "okay";
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp2_ipc3x: mbox_dsp2_ipc3x {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index e289c70..f82aa44 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -41,6 +41,7 @@
ethernet1 = &cpsw_emac1;
d_can0 = &dcan1;
d_can1 = &dcan2;
+ spi0 = &qspi;
};
timer {
@@ -292,6 +293,11 @@
#thermal-sensor-cells = <1>;
};
+ dsp1_system: dsp_system@40d00000 {
+ compatible = "syscon";
+ reg = <0x40d00000 0x100>;
+ };
+
sdma: dma-controller@4a056000 {
compatible = "ti,omap4430-sdma";
reg = <0x4a056000 0x1000>;
@@ -911,6 +917,46 @@
status = "disabled";
};
+ mmu0_dsp1: mmu@40d01000 {
+ compatible = "ti,dra7-dsp-iommu";
+ reg = <0x40d01000 0x100>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu0_dsp1";
+ #iommu-cells = <0>;
+ ti,syscon-mmuconfig = <&dsp1_system 0x0>;
+ status = "disabled";
+ };
+
+ mmu1_dsp1: mmu@40d02000 {
+ compatible = "ti,dra7-dsp-iommu";
+ reg = <0x40d02000 0x100>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu1_dsp1";
+ #iommu-cells = <0>;
+ ti,syscon-mmuconfig = <&dsp1_system 0x1>;
+ status = "disabled";
+ };
+
+ mmu_ipu1: mmu@58882000 {
+ compatible = "ti,dra7-iommu";
+ reg = <0x58882000 0x100>;
+ interrupts = <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_ipu1";
+ #iommu-cells = <0>;
+ ti,iommu-bus-err-back;
+ status = "disabled";
+ };
+
+ mmu_ipu2: mmu@55082000 {
+ compatible = "ti,dra7-iommu";
+ reg = <0x55082000 0x100>;
+ interrupts = <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu_ipu2";
+ #iommu-cells = <0>;
+ ti,iommu-bus-err-back;
+ status = "disabled";
+ };
+
abb_mpu: regulator-abb-mpu {
compatible = "ti,abb-v3";
regulator-name = "abb_mpu";
@@ -1108,8 +1154,10 @@
qspi: qspi@4b300000 {
compatible = "ti,dra7xxx-qspi";
- reg = <0x4b300000 0x100>;
- reg-names = "qspi_base";
+ reg = <0x4b300000 0x100>,
+ <0x5c000000 0x4000000>;
+ reg-names = "qspi_base", "qspi_mmap";
+ syscon-chipselects = <&scm_conf 0x558>;
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "qspi";
@@ -1404,6 +1452,21 @@
status = "disabled";
};
+ mcasp3: mcasp@48468000 {
+ compatible = "ti,dra7-mcasp-audio";
+ ti,hwmods = "mcasp3";
+ reg = <0x48468000 0x2000>;
+ reg-names = "mpu";
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tx", "rx";
+ dmas = <&sdma_xbar 133>, <&sdma_xbar 132>;
+ dma-names = "tx", "rx";
+ clocks = <&mcasp3_aux_gfclk_mux>, <&mcasp3_ahclkx_mux>;
+ clock-names = "fck", "ahclkx";
+ status = "disabled";
+ };
+
crossbar_mpu: crossbar@4a002a48 {
compatible = "ti,irq-crossbar";
reg = <0x4a002a48 0x130>;
@@ -1437,6 +1500,16 @@
0x48485200 0x2E00>;
#address-cells = <1>;
#size-cells = <1>;
+
+ /*
+ * Do not allow gating of cpsw clock as workaround
+ * for errata i877. Keeping internal clock disabled
+ * causes the device switching characteristics
+ * to degrade over time and eventually fail to meet
+ * the data manual delay time/skew specs.
+ */
+ ti,no-idle;
+
/*
* rx_thresh_pend
* rx_pend
@@ -1448,6 +1521,7 @@
<GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>;
ranges;
+ syscon = <&scm_conf>;
status = "disabled";
davinci_mdio: mdio@48485000 {
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 6f6bd98..00b1200 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -9,6 +9,7 @@
#include "dra72x.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/ti-dra7-atl.h>
/ {
model = "TI DRA722";
@@ -30,6 +31,15 @@
regulator-max-microvolt = <3300000>;
};
+ aic_dvdd: fixedregulator-aic_dvdd {
+ /* TPS77018DBVT */
+ compatible = "regulator-fixed";
+ regulator-name = "aic_dvdd";
+ vin-supply = <&evm_3v3>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
evm_3v3_sd: fixedregulator-sd {
compatible = "regulator-fixed";
regulator-name = "evm_3v3_sd";
@@ -93,131 +103,197 @@
};
};
};
+
+ sound0: sound@0 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "DRA7xx-EVM";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Line", "Line Out",
+ "Microphone", "Mic Jack",
+ "Line", "Line In";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT",
+ "MIC3L", "Mic Jack",
+ "MIC3R", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "LINE1L", "Line In",
+ "LINE1R", "Line In";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&sound0_master>;
+ simple-audio-card,frame-master = <&sound0_master>;
+ simple-audio-card,bitclock-inversion;
+
+ sound0_master: simple-audio-card,cpu {
+ sound-dai = <&mcasp3>;
+ system-clock-frequency = <5644800>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ clocks = <&atl_clkin2_ck>;
+ };
+ };
};
&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 */
+ DRA7XX_CORE_IOPAD(0x3800, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ DRA7XX_CORE_IOPAD(0x3804, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
>;
};
i2c5_pins: pinmux_i2c5_pins {
pinctrl-single,pins = <
- 0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
- 0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+ DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+ DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+ >;
+ };
+
+ i2c5_pins: pinmux_i2c5_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x36b4, PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+ DRA7XX_CORE_IOPAD(0x36b8, PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_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 */
+ DRA7XX_CORE_IOPAD(0x3400, PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
+ DRA7XX_CORE_IOPAD(0x3404, PIN_INPUT | MUX_MODE0) /* gpmc_ad1 */
+ DRA7XX_CORE_IOPAD(0x3408, PIN_INPUT | MUX_MODE0) /* gpmc_ad2 */
+ DRA7XX_CORE_IOPAD(0x340c, PIN_INPUT | MUX_MODE0) /* gpmc_ad3 */
+ DRA7XX_CORE_IOPAD(0x3410, PIN_INPUT | MUX_MODE0) /* gpmc_ad4 */
+ DRA7XX_CORE_IOPAD(0x3414, PIN_INPUT | MUX_MODE0) /* gpmc_ad5 */
+ DRA7XX_CORE_IOPAD(0x3418, PIN_INPUT | MUX_MODE0) /* gpmc_ad6 */
+ DRA7XX_CORE_IOPAD(0x341c, PIN_INPUT | MUX_MODE0) /* gpmc_ad7 */
+ DRA7XX_CORE_IOPAD(0x3420, PIN_INPUT | MUX_MODE0) /* gpmc_ad8 */
+ DRA7XX_CORE_IOPAD(0x3424, PIN_INPUT | MUX_MODE0) /* gpmc_ad9 */
+ DRA7XX_CORE_IOPAD(0x3428, PIN_INPUT | MUX_MODE0) /* gpmc_ad10 */
+ DRA7XX_CORE_IOPAD(0x342c, PIN_INPUT | MUX_MODE0) /* gpmc_ad11 */
+ DRA7XX_CORE_IOPAD(0x3430, PIN_INPUT | MUX_MODE0) /* gpmc_ad12 */
+ DRA7XX_CORE_IOPAD(0x3434, PIN_INPUT | MUX_MODE0) /* gpmc_ad13 */
+ DRA7XX_CORE_IOPAD(0x3438, PIN_INPUT | MUX_MODE0) /* gpmc_ad14 */
+ DRA7XX_CORE_IOPAD(0x343c, PIN_INPUT | MUX_MODE0) /* gpmc_ad15 */
+ DRA7XX_CORE_IOPAD(0x34b4, PIN_OUTPUT | MUX_MODE0) /* gpmc_cs0 */
+ DRA7XX_CORE_IOPAD(0x34c4, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale */
+ DRA7XX_CORE_IOPAD(0x34cc, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen */
+ DRA7XX_CORE_IOPAD(0x34c8, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren */
+ DRA7XX_CORE_IOPAD(0x34d0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ben0 */
+ DRA7XX_CORE_IOPAD(0x34d8, PIN_INPUT | MUX_MODE0) /* gpmc_wait0 */
>;
};
usb1_pins: pinmux_usb1_pins {
pinctrl-single,pins = <
- 0x280 (PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
+ DRA7XX_CORE_IOPAD(0x3680, PIN_INPUT_SLEW | MUX_MODE0) /* usb1_drvvbus */
>;
};
usb2_pins: pinmux_usb2_pins {
pinctrl-single,pins = <
- 0x284 (PIN_INPUT_SLEW | MUX_MODE0) /* usb2_drvvbus */
+ DRA7XX_CORE_IOPAD(0x3684, 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 */
+ DRA7XX_CORE_IOPAD(0x3824, 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 */
+ DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */
+ DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
+ DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
+ DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
+ DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
+ DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
+ DRA7XX_CORE_IOPAD(0x3768, 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 */
+ DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */
+ DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */
+ DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */
+ DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */
+ DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */
+ DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */
+ DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */
+ DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */
+ DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */
+ DRA7XX_CORE_IOPAD(0x3498, 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 */
+ DRA7XX_CORE_IOPAD(0x37d0, PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+ DRA7XX_CORE_IOPAD(0x3818, 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 */
+ DRA7XX_CORE_IOPAD(0x37d0, MUX_MODE15 | PULL_UP) /* dcan1_tx.off */
+ DRA7XX_CORE_IOPAD(0x3818, 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 */
+ DRA7XX_CORE_IOPAD(0x3474, PIN_OUTPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ DRA7XX_CORE_IOPAD(0x3478, PIN_INPUT | MUX_MODE1) /* gpmc_a14.qspi1_d3 */
+ DRA7XX_CORE_IOPAD(0x347c, PIN_INPUT | MUX_MODE1) /* gpmc_a15.qspi1_d2 */
+ DRA7XX_CORE_IOPAD(0x3480, PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+ DRA7XX_CORE_IOPAD(0x3484, PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d0 */
+ DRA7XX_CORE_IOPAD(0x3488, PIN_OUTPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ DRA7XX_CORE_IOPAD(0x34b8, PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
>;
};
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
- 0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
- 0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
+ DRA7XX_CORE_IOPAD(0x3808, PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
+ DRA7XX_CORE_IOPAD(0x380c, PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
- 0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
+ DRA7XX_CORE_IOPAD(0x37b8, PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
+ >;
+ };
+
+ atl_pins: pinmux_atl_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3698, PIN_OUTPUT | MUX_MODE5) /* xref_clk1.atl_clk1 */
+ DRA7XX_CORE_IOPAD(0x369c, PIN_OUTPUT | MUX_MODE5) /* xref_clk2.atl_clk2 */
+ >;
+ };
+
+ mcasp3_pins: pinmux_mcasp3_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
+ DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
+ DRA7XX_CORE_IOPAD(0x372c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1 */
+ >;
+ };
+
+ mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+ pinctrl-single,pins = <
+ DRA7XX_CORE_IOPAD(0x3724, PIN_INPUT_PULLDOWN | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3728, PIN_INPUT_PULLDOWN | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x372c, PIN_INPUT_PULLDOWN | MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3730, PIN_INPUT_PULLDOWN | MUX_MODE15)
>;
};
};
@@ -297,6 +373,7 @@
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
+ regulator-allow-bypass;
};
ldo2_reg: ldo2 {
@@ -304,6 +381,7 @@
regulator-name = "ldo2";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
+ regulator-allow-bypass;
};
ldo3_reg: ldo3 {
@@ -353,12 +431,21 @@
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <2>;
+ };
- cpsw_sel_s0 {
- gpio-hog;
- gpios = <4 GPIO_ACTIVE_HIGH>;
- output-low;
- };
+ tlv320aic3106: tlv320aic3106@19 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x19>;
+ adc-settle-ms = <40>;
+ ai3x-micbias-vg = <1>; /* 2.0V */
+ status = "okay";
+
+ /* Regulators */
+ AVDD-supply = <&evm_3v3>;
+ IOVDD-supply = <&evm_3v3>;
+ DRVDD-supply = <&evm_3v3>;
+ DVDD-supply = <&aic_dvdd>;
};
};
@@ -380,11 +467,21 @@
* VIN6_SEL_S0 is low, thus selecting McASP3 over VIN6
*/
lines-initial-states = <0x0f2b>;
+
+ p1 {
+ /* vin6_sel_s0: high: VIN6, low: audio */
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "vin6_sel_s0";
+ };
};
};
&uart1 {
status = "okay";
+ interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <&dra7_pmx_core 0x3e0>;
};
&elm {
@@ -514,7 +611,7 @@
* SDCD signal is not being used here - using the fact that GPIO mode
* is a viable alternative
*/
- cd-gpios = <&gpio6 27 0>;
+ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>;
max-frequency = <192000000>;
};
@@ -534,18 +631,18 @@
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 */
+ DRA7XX_CORE_IOPAD(0x3598, PIN_OUTPUT | MUX_MODE3) /* vin2a_d12.rgmii1_txc */
+ DRA7XX_CORE_IOPAD(0x359c, PIN_OUTPUT | MUX_MODE3) /* vin2a_d13.rgmii1_tctl */
+ DRA7XX_CORE_IOPAD(0x35a0, PIN_OUTPUT | MUX_MODE3) /* vin2a_d14.rgmii1_td3 */
+ DRA7XX_CORE_IOPAD(0x35a4, PIN_OUTPUT | MUX_MODE3) /* vin2a_d15.rgmii1_td2 */
+ DRA7XX_CORE_IOPAD(0x35a8, PIN_OUTPUT | MUX_MODE3) /* vin2a_d16.rgmii1_td1 */
+ DRA7XX_CORE_IOPAD(0x35ac, PIN_OUTPUT | MUX_MODE3) /* vin2a_d17.rgmii1_td0 */
+ DRA7XX_CORE_IOPAD(0x35b0, PIN_INPUT | MUX_MODE3) /* vin2a_d18.rgmii1_rclk */
+ DRA7XX_CORE_IOPAD(0x35b4, PIN_INPUT | MUX_MODE3) /* vin2a_d19.rgmii1_rctl */
+ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */
+ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */
+ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */
+ DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */
>;
};
@@ -553,33 +650,33 @@
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)
+ DRA7XX_CORE_IOPAD(0x3598, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x359c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a4, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35a8, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35ac, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b4, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35b8, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35bc, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c0, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x35c4, 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 */
+ DRA7XX_CORE_IOPAD(0x363c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_d.mdio_d */
+ DRA7XX_CORE_IOPAD(0x3640, PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
davinci_mdio_sleep: davinci_mdio_sleep {
pinctrl-single,pins = <
- 0x23c (MUX_MODE15)
- 0x240 (MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x363c, MUX_MODE15)
+ DRA7XX_CORE_IOPAD(0x3640, MUX_MODE15)
>;
};
};
@@ -590,6 +687,7 @@
pinctrl-0 = <&cpsw_default>;
pinctrl-1 = <&cpsw_sleep>;
slaves = <1>;
+ mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_HIGH>;
};
&cpsw_emac0 {
@@ -695,3 +793,59 @@
};
};
};
+
+&atl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&atl_pins>;
+
+ assigned-clocks = <&abe_dpll_sys_clk_mux>,
+ <&atl_gfclk_mux>,
+ <&dpll_abe_ck>,
+ <&dpll_abe_m2x2_ck>,
+ <&atl_clkin2_ck>;
+ assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>;
+ assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>;
+
+ status = "okay";
+
+ atl2 {
+ bws = <DRA7_ATL_WS_MCASP2_FSX>;
+ aws = <DRA7_ATL_WS_MCASP3_FSX>;
+ };
+};
+
+&mcasp3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mcasp3_pins>;
+ pinctrl-1 = <&mcasp3_sleep_pins>;
+
+ assigned-clocks = <&mcasp3_ahclkx_mux>;
+ assigned-clock-parents = <&atl_clkin2_ck>;
+
+ status = "okay";
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializer */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 1 2 0 0
+ >;
+};
+
+&mailbox5 {
+ status = "okay";
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ status = "okay";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ status = "okay";
+ };
+};
+
+&mailbox6 {
+ status = "okay";
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi
index eaca143..70a2170 100644
--- a/arch/arm/boot/dts/dra72x.dtsi
+++ b/arch/arm/boot/dts/dra72x.dtsi
@@ -45,3 +45,24 @@
<&dss_video1_clk>;
clock-names = "fck", "video1_clk";
};
+
+&mailbox5 {
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ ti,mbox-tx = <6 2 2>;
+ ti,mbox-rx = <4 2 2>;
+ status = "disabled";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ ti,mbox-tx = <5 2 2>;
+ ti,mbox-rx = <1 2 2>;
+ status = "disabled";
+ };
+};
+
+&mailbox6 {
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ ti,mbox-tx = <6 2 2>;
+ ti,mbox-rx = <4 2 2>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi
index feea98e..8bcc47d 100644
--- a/arch/arm/boot/dts/dra74x.dtsi
+++ b/arch/arm/boot/dts/dra74x.dtsi
@@ -52,6 +52,11 @@
};
ocp {
+ dsp2_system: dsp_system@41500000 {
+ compatible = "syscon";
+ reg = <0x41500000 0x100>;
+ };
+
omap_dwc3_4: omap_dwc3_4@48940000 {
compatible = "ti,dwc3";
ti,hwmods = "usb_otg_ss4";
@@ -76,6 +81,26 @@
dr_mode = "otg";
};
};
+
+ mmu0_dsp2: mmu@41501000 {
+ compatible = "ti,dra7-dsp-iommu";
+ reg = <0x41501000 0x100>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu0_dsp2";
+ #iommu-cells = <0>;
+ ti,syscon-mmuconfig = <&dsp2_system 0x0>;
+ status = "disabled";
+ };
+
+ mmu1_dsp2: mmu@41502000 {
+ compatible = "ti,dra7-dsp-iommu";
+ reg = <0x41502000 0x100>;
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "mmu1_dsp2";
+ #iommu-cells = <0>;
+ ti,syscon-mmuconfig = <&dsp2_system 0x1>;
+ status = "disabled";
+ };
};
};
@@ -93,3 +118,29 @@
<&dss_video2_clk>;
clock-names = "fck", "video1_clk", "video2_clk";
};
+
+&mailbox5 {
+ mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
+ ti,mbox-tx = <6 2 2>;
+ ti,mbox-rx = <4 2 2>;
+ status = "disabled";
+ };
+ mbox_dsp1_ipc3x: mbox_dsp1_ipc3x {
+ ti,mbox-tx = <5 2 2>;
+ ti,mbox-rx = <1 2 2>;
+ status = "disabled";
+ };
+};
+
+&mailbox6 {
+ mbox_ipu2_ipc3x: mbox_ipu2_ipc3x {
+ ti,mbox-tx = <6 2 2>;
+ ti,mbox-rx = <4 2 2>;
+ status = "disabled";
+ };
+ mbox_dsp2_ipc3x: mbox_dsp2_ipc3x {
+ ti,mbox-tx = <5 2 2>;
+ ti,mbox-rx = <1 2 2>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/ea3250.dts b/arch/arm/boot/dts/ea3250.dts
index a4ba31b..a4a281f 100644
--- a/arch/arm/boot/dts/ea3250.dts
+++ b/arch/arm/boot/dts/ea3250.dts
@@ -12,7 +12,7 @@
*/
/dts-v1/;
-/include/ "lpc32xx.dtsi"
+#include "lpc32xx.dtsi"
/ {
model = "Embedded Artists LPC3250 board based on NXP LPC3250";
@@ -22,7 +22,7 @@
memory {
device_type = "memory";
- reg = <0 0x4000000>;
+ reg = <0x80000000 0x4000000>;
};
ahb {
@@ -31,19 +31,6 @@
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";
@@ -130,15 +117,6 @@
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>;
@@ -279,3 +257,18 @@
};
};
};
+
+/* Here, choose exactly one from: ohci, usbd */
+&ohci /* &usbd */ {
+ transceiver = <&isp1301>;
+ status = "okay";
+};
+
+&i2cusb {
+ clock-frequency = <100000>;
+
+ isp1301: usb-transceiver@2d {
+ compatible = "nxp,isp1301";
+ reg = <0x2d>;
+ };
+};
diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
index b4031fa4..504cf45 100644
--- a/arch/arm/boot/dts/efm32gg-dk3750.dts
+++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
@@ -26,7 +26,7 @@
};
i2c@4000a000 {
- efm32,location = <3>;
+ energymicro,location = <3>;
status = "ok";
temp@48 {
@@ -43,7 +43,7 @@
spi0: spi@4000c000 { /* USART0 */
cs-gpios = <&gpio 68 1>; // E4
- location = <1>;
+ energymicro,location = <1>;
status = "ok";
microsd@0 {
@@ -57,7 +57,7 @@
spi1: spi@4000c400 { /* USART1 */
cs-gpios = <&gpio 51 1>; // D3
- location = <1>;
+ energymicro,location = <1>;
status = "ok";
ks8851@0 {
@@ -70,7 +70,7 @@
};
uart4: uart@4000e400 { /* UART1 */
- location = <2>;
+ energymicro,location = <2>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/efm32gg.dtsi b/arch/arm/boot/dts/efm32gg.dtsi
index 106d505..c747983 100644
--- a/arch/arm/boot/dts/efm32gg.dtsi
+++ b/arch/arm/boot/dts/efm32gg.dtsi
@@ -23,7 +23,7 @@
soc {
adc: adc@40002000 {
- compatible = "efm32,adc";
+ compatible = "energymicro,efm32-adc";
reg = <0x40002000 0x400>;
interrupts = <7>;
clocks = <&cmu clk_HFPERCLKADC0>;
@@ -31,7 +31,7 @@
};
gpio: gpio@40006000 {
- compatible = "efm32,gpio";
+ compatible = "energymicro,efm32-gpio";
reg = <0x40006000 0x1000>;
interrupts = <1 11>;
gpio-controller;
@@ -45,7 +45,7 @@
i2c0: i2c@4000a000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "efm32,i2c";
+ compatible = "energymicro,efm32-i2c";
reg = <0x4000a000 0x400>;
interrupts = <9>;
clocks = <&cmu clk_HFPERCLKI2C0>;
@@ -56,7 +56,7 @@
i2c1: i2c@4000a400 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "efm32,i2c";
+ compatible = "energymicro,efm32-i2c";
reg = <0x4000a400 0x400>;
interrupts = <10>;
clocks = <&cmu clk_HFPERCLKI2C1>;
@@ -67,7 +67,7 @@
spi0: spi@4000c000 { /* USART0 */
#address-cells = <1>;
#size-cells = <0>;
- compatible = "efm32,spi";
+ compatible = "energymicro,efm32-spi";
reg = <0x4000c000 0x400>;
interrupts = <3 4>;
clocks = <&cmu clk_HFPERCLKUSART0>;
@@ -77,7 +77,7 @@
spi1: spi@4000c400 { /* USART1 */
#address-cells = <1>;
#size-cells = <0>;
- compatible = "efm32,spi";
+ compatible = "energymicro,efm32-spi";
reg = <0x4000c400 0x400>;
interrupts = <15 16>;
clocks = <&cmu clk_HFPERCLKUSART1>;
@@ -87,7 +87,7 @@
spi2: spi@4000c800 { /* USART2 */
#address-cells = <1>;
#size-cells = <0>;
- compatible = "efm32,spi";
+ compatible = "energymicro,efm32-spi";
reg = <0x4000c800 0x400>;
interrupts = <18 19>;
clocks = <&cmu clk_HFPERCLKUSART2>;
@@ -95,7 +95,7 @@
};
uart0: uart@4000c000 { /* USART0 */
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000c000 0x400>;
interrupts = <3 4>;
clocks = <&cmu clk_HFPERCLKUSART0>;
@@ -103,7 +103,7 @@
};
uart1: uart@4000c400 { /* USART1 */
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000c400 0x400>;
interrupts = <15 16>;
clocks = <&cmu clk_HFPERCLKUSART1>;
@@ -111,7 +111,7 @@
};
uart2: uart@4000c800 { /* USART2 */
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000c800 0x400>;
interrupts = <18 19>;
clocks = <&cmu clk_HFPERCLKUSART2>;
@@ -119,7 +119,7 @@
};
uart3: uart@4000e000 { /* UART0 */
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000e000 0x400>;
interrupts = <20 21>;
clocks = <&cmu clk_HFPERCLKUART0>;
@@ -127,7 +127,7 @@
};
uart4: uart@4000e400 { /* UART1 */
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000e400 0x400>;
interrupts = <22 23>;
clocks = <&cmu clk_HFPERCLKUART1>;
@@ -135,28 +135,28 @@
};
timer0: timer@40010000 {
- compatible = "efm32,timer";
+ compatible = "energymicro,efm32-timer";
reg = <0x40010000 0x400>;
interrupts = <2>;
clocks = <&cmu clk_HFPERCLKTIMER0>;
};
timer1: timer@40010400 {
- compatible = "efm32,timer";
+ compatible = "energymicro,efm32-timer";
reg = <0x40010400 0x400>;
interrupts = <12>;
clocks = <&cmu clk_HFPERCLKTIMER1>;
};
timer2: timer@40010800 {
- compatible = "efm32,timer";
+ compatible = "energymicro,efm32-timer";
reg = <0x40010800 0x400>;
interrupts = <13>;
clocks = <&cmu clk_HFPERCLKTIMER2>;
};
timer3: timer@40010c00 {
- compatible = "efm32,timer";
+ compatible = "energymicro,efm32-timer";
reg = <0x40010c00 0x400>;
interrupts = <14>;
clocks = <&cmu clk_HFPERCLKTIMER3>;
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi
index edad0c4..57795da 100644
--- a/arch/arm/boot/dts/emev2.dtsi
+++ b/arch/arm/boot/dts/emev2.dtsi
@@ -44,7 +44,7 @@
};
gic: interrupt-controller@e0020000 {
- compatible = "arm,cortex-a9-gic";
+ compatible = "arm,pl390";
interrupt-controller;
#interrupt-cells = <3>;
reg = <0xe0028000 0x1000>,
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 540a0ad..443a350 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -52,13 +52,13 @@
regulator-name = "V_EMMC_2.8V-fixed";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpk0 2 0>;
+ gpio = <&gpk0 2 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
i2c_max77836: i2c-gpio-0 {
compatible = "i2c-gpio";
- gpios = <&gpd0 2 0>, <&gpd0 3 0>;
+ gpios = <&gpd0 2 GPIO_ACTIVE_HIGH>, <&gpd0 3 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
@@ -161,6 +161,7 @@
};
&exynos_usbphy {
+ vbus-supply = <&safeout_reg>;
status = "okay";
};
@@ -266,14 +267,14 @@
regulator-name = "V_EMMC_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- samsung,ext-control-gpios = <&gpk0 2 0>;
+ samsung,ext-control-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
ldo12_reg: LDO12 {
regulator-name = "V_EMMC_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- samsung,ext-control-gpios = <&gpk0 2 0>;
+ samsung,ext-control-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
ldo13_reg: LDO13 {
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 41a5faf..3e64d5d 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -49,7 +49,7 @@
i2c_max77836: i2c-gpio-0 {
compatible = "i2c-gpio";
- gpios = <&gpd0 2 0>, <&gpd0 3 0>;
+ gpios = <&gpd0 2 GPIO_ACTIVE_HIGH>, <&gpd0 3 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
@@ -153,6 +153,7 @@
&exynos_usbphy {
status = "okay";
+ vbus-supply = <&safeout_reg>;
};
&hsotg {
@@ -188,8 +189,8 @@
reg = <0>;
vdd3-supply = <&ldo16_reg>;
vci-supply = <&ldo20_reg>;
- reset-gpios = <&gpe0 1 0>;
- te-gpios = <&gpx0 6 0>;
+ reset-gpios = <&gpe0 1 GPIO_ACTIVE_HIGH>;
+ te-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
power-on-delay= <30>;
power-off-delay= <120>;
reset-delay = <5>;
@@ -368,14 +369,14 @@
regulator-name = "V_EMMC_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- samsung,ext-control-gpios = <&gpk0 2 0>;
+ samsung,ext-control-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
ldo12_reg: LDO12 {
regulator-name = "V_EMMC_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- samsung,ext-control-gpios = <&gpk0 2 0>;
+ samsung,ext-control-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
ldo13_reg: LDO13 {
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 033def4..18e3def 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -152,6 +152,20 @@
interrupt-parent = <&gic>;
};
+ poweroff: syscon-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&pmu_system_controller>;
+ offset = <0x330C>; /* PS_HOLD_CONTROL */
+ mask = <0x5200>; /* Reset value */
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x0400>; /* SWRESET */
+ mask = <0x1>;
+ };
+
mipi_phy: video-phy@10020710 {
compatible = "samsung,s5pv210-mipi-video-phy";
#phy-cells = <1>;
@@ -333,7 +347,7 @@
};
mshc_0: mshc@12510000 {
- compatible = "samsung,exynos5250-dw-mshc";
+ compatible = "samsung,exynos5420-dw-mshc";
reg = <0x12510000 0x1000>;
interrupts = <0 142 0>;
clocks = <&cmu CLK_SDMMC0>, <&cmu CLK_SCLK_MMC0>;
@@ -345,7 +359,7 @@
};
mshc_1: mshc@12520000 {
- compatible = "samsung,exynos5250-dw-mshc";
+ compatible = "samsung,exynos5420-dw-mshc";
reg = <0x12520000 0x1000>;
interrupts = <0 143 0>;
clocks = <&cmu CLK_SDMMC1>, <&cmu CLK_SCLK_MMC1>;
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 98c0a36..045785c 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -158,6 +158,20 @@
interrupt-parent = <&gic>;
};
+ poweroff: syscon-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&pmu_system_controller>;
+ offset = <0x330C>; /* PS_HOLD_CONTROL */
+ mask = <0x5200>; /* reset value */
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x0400>; /* SWRESET */
+ mask = <0x1>;
+ };
+
dsi_0: dsi@11C80000 {
compatible = "samsung,exynos4210-mipi-dsi";
reg = <0x11C80000 0x10000>;
@@ -431,6 +445,8 @@
interrupts = <0 52 0>;
clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
+ dmas = <&pdma0 15>, <&pdma0 16>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -440,6 +456,8 @@
interrupts = <0 53 0>;
clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
+ dmas = <&pdma1 15>, <&pdma1 16>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -449,6 +467,8 @@
interrupts = <0 54 0>;
clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
+ dmas = <&pdma0 17>, <&pdma0 18>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -458,6 +478,8 @@
interrupts = <0 55 0>;
clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
clock-names = "uart", "clk_uart_baud0";
+ dmas = <&pdma1 17>, <&pdma1 18>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -705,6 +727,15 @@
iommus = <&sysmmu_jpeg>;
};
+ rotator: rotator@12810000 {
+ compatible = "samsung,exynos4210-rotator";
+ reg = <0x12810000 0x64>;
+ interrupts = <0 83 0>;
+ clocks = <&clock CLK_ROTATOR>;
+ clock-names = "rotator";
+ iommus = <&sysmmu_rotator>;
+ };
+
hdmi: hdmi@12D00000 {
compatible = "samsung,exynos4210-hdmi";
reg = <0x12D00000 0x70000>;
@@ -932,7 +963,6 @@
interrupts = <5 0>;
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
- power-domains = <&pd_lcd0>;
#iommu-cells = <0>;
};
@@ -946,4 +976,12 @@
power-domains = <&pd_lcd0>;
#iommu-cells = <0>;
};
+
+ prng: rng@10830400 {
+ compatible = "samsung,exynos4-rng";
+ reg = <0x10830400 0x200>;
+ clocks = <&clock CLK_SSS>;
+ clock-names = "secss";
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index e050d85..5821ad8 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -16,6 +16,7 @@
/dts-v1/;
#include "exynos4210.dtsi"
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
@@ -45,7 +46,7 @@
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpx1 1 0>;
+ gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
@@ -57,35 +58,35 @@
up {
label = "Up";
- gpios = <&gpx2 0 1>;
+ gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
linux,code = <KEY_UP>;
gpio-key,wakeup;
};
down {
label = "Down";
- gpios = <&gpx2 1 1>;
+ gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
linux,code = <KEY_DOWN>;
gpio-key,wakeup;
};
back {
label = "Back";
- gpios = <&gpx1 7 1>;
+ gpios = <&gpx1 7 GPIO_ACTIVE_LOW>;
linux,code = <KEY_BACK>;
gpio-key,wakeup;
};
home {
label = "Home";
- gpios = <&gpx1 6 1>;
+ gpios = <&gpx1 6 GPIO_ACTIVE_LOW>;
linux,code = <KEY_HOME>;
gpio-key,wakeup;
};
menu {
label = "Menu";
- gpios = <&gpx1 5 1>;
+ gpios = <&gpx1 5 GPIO_ACTIVE_LOW>;
linux,code = <KEY_MENU>;
gpio-key,wakeup;
};
@@ -94,7 +95,7 @@
leds {
compatible = "gpio-leds";
status {
- gpios = <&gpx1 3 1>;
+ gpios = <&gpx1 3 GPIO_ACTIVE_LOW>;
linux,default-trigger = "heartbeat";
};
};
@@ -137,10 +138,6 @@
status = "okay";
};
-&g2d {
- status = "okay";
-};
-
&i2c_0 {
status = "okay";
samsung,i2c-sda-delay = <100>;
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 043b03c..104cbb3 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -16,6 +16,7 @@
/dts-v1/;
#include "exynos4210.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung smdkv310 evaluation board based on Exynos4210";
@@ -43,10 +44,6 @@
};
};
-&g2d {
- status = "okay";
-};
-
&i2c_0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -182,7 +179,7 @@
};
&spi_2 {
- cs-gpios = <&gpc1 2 0>;
+ cs-gpios = <&gpc1 2 GPIO_ACTIVE_HIGH>;
status = "okay";
w25x80@0 {
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index ba34886..a50be64 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "exynos4210.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung Trats based on Exynos4210";
@@ -39,7 +40,7 @@
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpk0 2 0>;
+ gpio = <&gpk0 2 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -48,7 +49,7 @@
regulator-name = "TSP_FIXED_VOLTAGES";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpl0 3 0>;
+ gpio = <&gpl0 3 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -57,7 +58,7 @@
regulator-name = "8M_AF_2.8V_EN";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpk1 1 0>;
+ gpio = <&gpk1 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -66,7 +67,7 @@
regulator-name = "CAM_IO_EN";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpe2 1 0>;
+ gpio = <&gpe2 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -75,7 +76,7 @@
regulator-name = "8M_1.2V_EN";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- gpio = <&gpe2 5 0>;
+ gpio = <&gpe2 5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -84,7 +85,7 @@
regulator-name = "VT_CORE_1.5V";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
- gpio = <&gpe2 2 0>;
+ gpio = <&gpe2 2 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
@@ -93,21 +94,21 @@
compatible = "gpio-keys";
vol-down-key {
- gpios = <&gpx2 1 1>;
+ gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
linux,code = <114>;
label = "volume down";
debounce-interval = <10>;
};
vol-up-key {
- gpios = <&gpx2 0 1>;
+ gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
linux,code = <115>;
label = "volume up";
debounce-interval = <10>;
};
power-key {
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <116>;
label = "power";
debounce-interval = <10>;
@@ -115,7 +116,7 @@
};
ok-key {
- gpios = <&gpx3 5 1>;
+ gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
linux,code = <352>;
label = "ok";
debounce-interval = <10>;
@@ -218,7 +219,7 @@
compatible = "samsung,s6e8aa0";
vdd3-supply = <&vcclcd_reg>;
vci-supply = <&vlcd_reg>;
- reset-gpios = <&gpy4 5 0>;
+ reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
power-on-delay= <50>;
reset-delay = <100>;
init-delay = <100>;
@@ -251,6 +252,7 @@
&exynos_usbphy {
status = "okay";
+ vbus-supply = <&safe1_sreg>;
};
&fimd {
@@ -304,9 +306,9 @@
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-buck125-dvs-gpios = <&gpx0 5 GPIO_ACTIVE_HIGH>,
+ <&gpx0 6 GPIO_ACTIVE_HIGH>,
+ <&gpl0 0 GPIO_ACTIVE_HIGH>;
max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
<1250000>, <1200000>,
@@ -448,7 +450,6 @@
safe1_sreg: ESAFEOUT1 {
regulator-name = "SAFEOUT1";
- regulator-always-on;
};
safe2_sreg: ESAFEOUT2 {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index eb37952..4f5d379 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "exynos4210.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung Universal C210 based on Exynos4210 rev0";
@@ -65,7 +66,7 @@
regulator-name = "VMEM_VDD_2_8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpe1 3 0>;
+ gpio = <&gpe1 3 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -73,21 +74,21 @@
compatible = "gpio-keys";
vol-up-key {
- gpios = <&gpx2 0 1>;
+ gpios = <&gpx2 0 GPIO_ACTIVE_LOW>;
linux,code = <115>;
label = "volume up";
debounce-interval = <1>;
};
vol-down-key {
- gpios = <&gpx2 1 1>;
+ gpios = <&gpx2 1 GPIO_ACTIVE_LOW>;
linux,code = <114>;
label = "volume down";
debounce-interval = <1>;
};
config-key {
- gpios = <&gpx2 2 1>;
+ gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
linux,code = <171>;
label = "config";
debounce-interval = <1>;
@@ -95,14 +96,14 @@
};
camera-key {
- gpios = <&gpx2 3 1>;
+ gpios = <&gpx2 3 GPIO_ACTIVE_LOW>;
linux,code = <212>;
label = "camera";
debounce-interval = <1>;
};
power-key {
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <116>;
label = "power";
debounce-interval = <1>;
@@ -110,7 +111,7 @@
};
ok-key {
- gpios = <&gpx3 5 1>;
+ gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
linux,code = <352>;
label = "ok";
debounce-interval = <1>;
@@ -122,7 +123,7 @@
regulator-name = "TSP_2_8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpe2 3 0>;
+ gpio = <&gpe2 3 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -131,17 +132,17 @@
#address-cells = <1>;
#size-cells = <0>;
- gpio-sck = <&gpy3 1 0>;
- gpio-mosi = <&gpy3 3 0>;
+ gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>;
num-chipselects = <1>;
- cs-gpios = <&gpy4 3 0>;
+ cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>;
lcd@0 {
compatible = "samsung,ld9040";
reg = <0>;
vdd3-supply = <&ldo7_reg>;
vci-supply = <&ldo17_reg>;
- reset-gpios = <&gpy4 5 0>;
+ reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
spi-max-frequency = <1200000>;
spi-cpol;
spi-cpha;
@@ -218,13 +219,13 @@
regulator-name = "HDMI_5V";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpe0 1 0>;
+ gpio = <&gpe0 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
hdmi_ddc: i2c-ddc {
compatible = "i2c-gpio";
- gpios = <&gpe4 2 0 &gpe4 3 0>;
+ gpios = <&gpe4 2 GPIO_ACTIVE_HIGH &gpe4 3 GPIO_ACTIVE_HIGH>;
i2c-gpio,delay-us = <100>;
#address-cells = <1>;
#size-cells = <0>;
@@ -248,6 +249,7 @@
&exynos_usbphy {
status = "okay";
+ vbus-supply = <&safeout1_reg>;
};
&fimd {
@@ -267,7 +269,7 @@
};
&hdmi {
- hpd-gpio = <&gpx3 7 0>;
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
hdmi-en-supply = <&hdmi_en>;
@@ -311,7 +313,8 @@
compatible = "maxim,max8952";
reg = <0x60>;
- max8952,vid-gpios = <&gpx0 3 0>, <&gpx0 4 0>;
+ max8952,vid-gpios = <&gpx0 3 GPIO_ACTIVE_HIGH>,
+ <&gpx0 4 GPIO_ACTIVE_HIGH>;
max8952,default-mode = <0>;
max8952,dvs-mode-microvolt = <1250000>, <1200000>,
<1050000>, <950000>;
@@ -330,13 +333,13 @@
reg = <0x66>;
max8998,pmic-buck1-default-dvs-idx = <0>;
- max8998,pmic-buck1-dvs-gpios = <&gpx0 5 0>,
- <&gpx0 6 0>;
+ max8998,pmic-buck1-dvs-gpios = <&gpx0 5 GPIO_ACTIVE_HIGH>,
+ <&gpx0 6 GPIO_ACTIVE_HIGH>;
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-gpio = <&gpe2 0 GPIO_ACTIVE_HIGH>;
max8998,pmic-buck2-dvs-voltage = <1200000>, <1100000>;
regulators {
@@ -486,7 +489,6 @@
safeout1_reg: ESAFEOUT1 {
regulator-name = "SAFEOUT1";
- regulator-always-on;
};
safeout2_reg: ESAFEOUT2 {
@@ -551,23 +553,31 @@
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
pinctrl-names = "default";
vmmc-supply = <&ldo5_reg>;
- cd-gpios = <&gpx3 4 0>;
+ cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
cd-inverted;
status = "okay";
};
&serial_0 {
status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
};
&serial_1 {
status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
};
&serial_2 {
status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
};
&serial_3 {
status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 3e5ba66..c1cb8df 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -185,8 +185,8 @@
interrupts = <0 89 0>;
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
+ power-domains = <&pd_lcd0>;
iommus = <&sysmmu_g2d>;
- status = "disabled";
};
camera {
@@ -271,6 +271,10 @@
<0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
};
+&mdma1 {
+ power-domains = <&pd_lcd0>;
+};
+
&pmu_system_controller {
clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
"clkout4", "clkout8", "clkout9";
@@ -279,3 +283,11 @@
<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
#clock-cells = <1>;
};
+
+&rotator {
+ power-domains = <&pd_lcd0>;
+};
+
+&sysmmu_rotator {
+ power-domains = <&pd_lcd0>;
+};
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index db52841..395c3ca 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/clock/maxim,max77686.h>
#include "exynos4412.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
chosen {
@@ -30,7 +31,7 @@
power_key {
interrupt-parent = <&gpx1>;
interrupts = <3 0>;
- gpios = <&gpx1 3 1>;
+ gpios = <&gpx1 3 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "power key";
debounce-interval = <10>;
@@ -70,7 +71,7 @@
pinctrl-0 = <&sd1_cd>;
pinctrl-names = "default";
compatible = "mmc-pwrseq-emmc";
- reset-gpios = <&gpk1 2 1>;
+ reset-gpios = <&gpk1 2 GPIO_ACTIVE_LOW>;
};
camera {
@@ -176,12 +177,8 @@
assigned-clock-rates = <0>, <176000000>;
};
-&g2d {
- status = "okay";
-};
-
&hdmi {
- hpd-gpio = <&gpx3 7 0>;
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
vdd-supply = <&ldo8_reg>;
@@ -199,8 +196,6 @@
};
&i2c_0 {
- pinctrl-0 = <&i2c0_bus>;
- pinctrl-names = "default";
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <400000>;
status = "okay";
@@ -209,9 +204,9 @@
compatible = "smsc,usb3503";
reg = <0x08>;
- intn-gpios = <&gpx3 0 0>;
- connect-gpios = <&gpx3 4 0>;
- reset-gpios = <&gpx3 5 0>;
+ intn-gpios = <&gpx3 0 GPIO_ACTIVE_HIGH>;
+ connect-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
initial-mode = <1>;
};
@@ -276,15 +271,13 @@
regulator-always-on;
};
- ldo8_reg: ldo@8 {
- regulator-compatible = "LDO8";
+ ldo8_reg: LDO8 {
regulator-name = "VDD10_HDMI_1.0V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
};
- ldo10_reg: ldo@10 {
- regulator-compatible = "LDO10";
+ ldo10_reg: LDO10 {
regulator-name = "VDDQ_MIPIHSI_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -424,8 +417,6 @@
};
&i2c_1 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_bus>;
status = "okay";
max98090: max98090@10 {
compatible = "maxim,max98090";
@@ -440,8 +431,6 @@
&i2c_2 {
status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_bus>;
};
&i2c_8 {
@@ -490,7 +479,7 @@
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-gpios = <&gpk2 2 GPIO_ACTIVE_HIGH>;
cd-inverted;
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 8632f35..dd89f7b 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -13,7 +13,6 @@
/dts-v1/;
#include "exynos4412-odroid-common.dtsi"
-#include <dt-bindings/gpio/gpio.h>
/ {
model = "Hardkernel ODROID-U3 board based on Exynos4412";
@@ -27,11 +26,54 @@
compatible = "gpio-leds";
led1 {
label = "led1:heart";
- gpios = <&gpc1 0 1>;
+ gpios = <&gpc1 0 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "heartbeat";
};
};
+
+ fan0: pwm-fan {
+ compatible = "pwm-fan";
+ pwms = <&pwm 0 10000 0>;
+ cooling-min-state = <0>;
+ cooling-max-state = <3>;
+ #cooling-cells = <2>;
+ cooling-levels = <0 102 170 230>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert1>;
+ cooling-device = <&cpu0 7 7>;
+ };
+ map1 {
+ trip = <&cpu_alert2>;
+ cooling-device = <&cpu0 13 13>;
+ };
+ map2 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&fan0 0 1>;
+ };
+ map3 {
+ trip = <&cpu_alert1>;
+ cooling-device = <&fan0 1 2>;
+ };
+ map4 {
+ trip = <&cpu_alert2>;
+ cooling-device = <&fan0 2 3>;
+ };
+ };
+ };
+ };
+};
+
+&pwm {
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ samsung,pwm-outputs = <0>;
+ status = "okay";
};
&usb3503 {
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 679ac10..b44bb68 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -26,13 +26,13 @@
compatible = "gpio-leds";
led1 {
label = "led1:heart";
- gpios = <&gpc1 0 1>;
+ gpios = <&gpc1 0 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "heartbeat";
};
led2 {
label = "led2:mmc0";
- gpios = <&gpc1 2 1>;
+ gpios = <&gpc1 2 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "mmc0";
};
@@ -44,7 +44,7 @@
home_key {
interrupt-parent = <&gpx2>;
interrupts = <2 0>;
- gpios = <&gpx2 2 0>;
+ gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>;
linux,code = <KEY_HOME>;
label = "home key";
debounce-interval = <10>;
@@ -57,7 +57,7 @@
regulator-name = "p3v3_en";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&gpa1 1 1>;
+ gpio = <&gpa1 1 GPIO_ACTIVE_LOW>;
enable-active-high;
regulator-always-on;
};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index 9d528af..9e2e24c 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "exynos4412.dtsi"
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
@@ -45,7 +46,7 @@
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpx1 1 0>;
+ gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
@@ -88,10 +89,6 @@
status = "okay";
};
-&g2d {
- status = "okay";
-};
-
&i2c_0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -107,13 +104,13 @@
s5m8767,pmic-buck-default-dvs-idx = <3>;
- s5m8767,pmic-buck-dvs-gpios = <&gpx2 3 0>,
- <&gpx2 4 0>,
- <&gpx2 5 0>;
+ s5m8767,pmic-buck-dvs-gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>,
+ <&gpx2 4 GPIO_ACTIVE_HIGH>,
+ <&gpx2 5 GPIO_ACTIVE_HIGH>;
- s5m8767,pmic-buck-ds-gpios = <&gpm3 5 0>,
- <&gpm3 6 0>,
- <&gpm3 7 0>;
+ s5m8767,pmic-buck-ds-gpios = <&gpm3 5 GPIO_ACTIVE_HIGH>,
+ <&gpm3 6 GPIO_ACTIVE_HIGH>,
+ <&gpm3 7 GPIO_ACTIVE_HIGH>;
s5m8767,pmic-buck2-dvs-voltage = <1250000>, <1200000>,
<1200000>, <1200000>,
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index c2421df..a130ab3 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -41,10 +41,6 @@
};
};
-&g2d {
- status = "okay";
-};
-
&keypad {
samsung,keypad-num-rows = <3>;
samsung,keypad-num-columns = <8>;
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index 525684c..4840bbd 100644
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -13,6 +13,7 @@
/dts-v1/;
#include "exynos4412.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "FriendlyARM TINY4412 board based on Exynos4412";
@@ -31,26 +32,26 @@
led1 {
label = "led1";
- gpios = <&gpm4 0 1>;
+ gpios = <&gpm4 0 GPIO_ACTIVE_LOW>;
default-state = "off";
linux,default-trigger = "heartbeat";
};
led2 {
label = "led2";
- gpios = <&gpm4 1 1>;
+ gpios = <&gpm4 1 GPIO_ACTIVE_LOW>;
default-state = "off";
};
led3 {
label = "led3";
- gpios = <&gpm4 2 1>;
+ gpios = <&gpm4 2 GPIO_ACTIVE_LOW>;
default-state = "off";
};
led4 {
label = "led4";
- gpios = <&gpm4 3 1>;
+ gpios = <&gpm4 3 GPIO_ACTIVE_LOW>;
default-state = "off";
linux,default-trigger = "mmc0";
};
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 2a1ebb7..a6f78c3 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -65,7 +65,7 @@
regulator-name = "CAM_SENSOR_A";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpm0 2 0>;
+ gpio = <&gpm0 2 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -74,7 +74,7 @@
regulator-name = "LCD_VDD_2.2V";
regulator-min-microvolt = <2200000>;
regulator-max-microvolt = <2200000>;
- gpio = <&gpc0 1 0>;
+ gpio = <&gpc0 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -83,7 +83,7 @@
regulator-name = "CAM_AF";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpio = <&gpm0 4 0>;
+ gpio = <&gpm0 4 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
@@ -92,7 +92,7 @@
regulator-name = "LED_A_3.0V";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
- gpio = <&gpj0 5 0>;
+ gpio = <&gpj0 5 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};
@@ -101,21 +101,21 @@
compatible = "gpio-keys";
key-down {
- gpios = <&gpx3 3 1>;
+ gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
linux,code = <114>;
label = "volume down";
debounce-interval = <10>;
};
key-up {
- gpios = <&gpx2 2 1>;
+ gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
linux,code = <115>;
label = "volume up";
debounce-interval = <10>;
};
key-power {
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <116>;
label = "power";
debounce-interval = <10>;
@@ -123,7 +123,7 @@
};
key-ok {
- gpios = <&gpx0 1 1>;
+ gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
linux,code = <139>;
label = "ok";
debounce-inteval = <10>;
@@ -198,7 +198,7 @@
i2c_ak8975: i2c-gpio-0 {
compatible = "i2c-gpio";
- gpios = <&gpy2 4 0>, <&gpy2 5 0>;
+ gpios = <&gpy2 4 GPIO_ACTIVE_HIGH>, <&gpy2 5 GPIO_ACTIVE_HIGH>;
i2c-gpio,delay-us = <2>;
#address-cells = <1>;
#size-cells = <0>;
@@ -207,13 +207,13 @@
ak8975@0c {
compatible = "asahi-kasei,ak8975";
reg = <0x0c>;
- gpios = <&gpj0 7 0>;
+ gpios = <&gpj0 7 GPIO_ACTIVE_HIGH>;
};
};
i2c_cm36651: i2c-gpio-2 {
compatible = "i2c-gpio";
- gpios = <&gpf0 0 1>, <&gpf0 1 1>;
+ gpios = <&gpf0 0 GPIO_ACTIVE_LOW>, <&gpf0 1 GPIO_ACTIVE_LOW>;
i2c-gpio,delay-us = <2>;
#address-cells = <1>;
#size-cells = <0>;
@@ -359,7 +359,7 @@
reg = <0>;
vdd3-supply = <&lcd_vdd3_reg>;
vci-supply = <&ldo25_reg>;
- reset-gpios = <&gpy4 5 0>;
+ reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>;
power-on-delay= <50>;
reset-delay = <100>;
init-delay = <100>;
@@ -391,6 +391,7 @@
};
&exynos_usbphy {
+ vbus-supply = <&esafeout1_reg>;
status = "okay";
};
@@ -446,7 +447,7 @@
clocks = <&camera 1>;
clock-names = "extclk";
samsung,camclk-out = <1>;
- gpios = <&gpm1 6 0>;
+ gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>;
port {
is_s5k6a3_ep: endpoint {
@@ -488,8 +489,8 @@
s5c73m3@3c {
compatible = "samsung,s5c73m3";
reg = <0x3c>;
- standby-gpios = <&gpm0 1 1>; /* ISP_STANDBY */
- xshutdown-gpios = <&gpf1 3 1>; /* ISP_RESET */
+ standby-gpios = <&gpm0 1 GPIO_ACTIVE_LOW>; /* ISP_STANDBY */
+ xshutdown-gpios = <&gpf1 3 GPIO_ACTIVE_LOW>; /* ISP_RESET */
vdd-int-supply = <&buck9_reg>;
vddio-cis-supply = <&ldo9_reg>;
vdda-supply = <&ldo17_reg>;
@@ -564,16 +565,14 @@
#clock-cells = <1>;
voltage-regulators {
- ldo1_reg: ldo1 {
- regulator-compatible = "LDO1";
+ ldo1_reg: LDO1 {
regulator-name = "VALIVE_1.0V_AP";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
- ldo2_reg: ldo2 {
- regulator-compatible = "LDO2";
+ ldo2_reg: LDO2 {
regulator-name = "VM1M2_1.2V_AP";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
@@ -583,32 +582,28 @@
};
};
- ldo3_reg: ldo3 {
- regulator-compatible = "LDO3";
+ ldo3_reg: LDO3 {
regulator-name = "VCC_1.8V_AP";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
- ldo4_reg: ldo4 {
- regulator-compatible = "LDO4";
+ ldo4_reg: LDO4 {
regulator-name = "VCC_2.8V_AP";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
};
- ldo5_reg: ldo5 {
- regulator-compatible = "LDO5";
+ ldo5_reg: LDO5 {
regulator-name = "VCC_1.8V_IO";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
- ldo6_reg: ldo6 {
- regulator-compatible = "LDO6";
+ ldo6_reg: LDO6 {
regulator-name = "VMPLL_1.0V_AP";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
@@ -618,8 +613,7 @@
};
};
- ldo7_reg: ldo7 {
- regulator-compatible = "LDO7";
+ ldo7_reg: LDO7 {
regulator-name = "VPLL_1.0V_AP";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
@@ -629,8 +623,7 @@
};
};
- ldo8_reg: ldo8 {
- regulator-compatible = "LDO8";
+ ldo8_reg: LDO8 {
regulator-name = "VMIPI_1.0V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
@@ -639,15 +632,13 @@
};
};
- ldo9_reg: ldo9 {
- regulator-compatible = "LDO9";
+ ldo9_reg: LDO9 {
regulator-name = "CAM_ISP_MIPI_1.2V";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
- ldo10_reg: ldo10 {
- regulator-compatible = "LDO10";
+ ldo10_reg: LDO10 {
regulator-name = "VMIPI_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -656,8 +647,7 @@
};
};
- ldo11_reg: ldo11 {
- regulator-compatible = "LDO11";
+ ldo11_reg: LDO11 {
regulator-name = "VABB1_1.95V";
regulator-min-microvolt = <1950000>;
regulator-max-microvolt = <1950000>;
@@ -667,8 +657,7 @@
};
};
- ldo12_reg: ldo12 {
- regulator-compatible = "LDO12";
+ ldo12_reg: LDO12 {
regulator-name = "VUOTG_3.0V";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
@@ -677,15 +666,13 @@
};
};
- ldo13_reg: ldo13 {
- regulator-compatible = "LDO13";
+ ldo13_reg: LDO13 {
regulator-name = "NFC_AVDD_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- ldo14_reg: ldo14 {
- regulator-compatible = "LDO14";
+ ldo14_reg: LDO14 {
regulator-name = "VABB2_1.95V";
regulator-min-microvolt = <1950000>;
regulator-max-microvolt = <1950000>;
@@ -695,8 +682,7 @@
};
};
- ldo15_reg: ldo15 {
- regulator-compatible = "LDO15";
+ ldo15_reg: LDO15 {
regulator-name = "VHSIC_1.0V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
@@ -705,8 +691,7 @@
};
};
- ldo16_reg: ldo16 {
- regulator-compatible = "LDO16";
+ ldo16_reg: LDO16 {
regulator-name = "VHSIC_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -715,80 +700,69 @@
};
};
- ldo17_reg: ldo17 {
- regulator-compatible = "LDO17";
+ ldo17_reg: LDO17 {
regulator-name = "CAM_SENSOR_CORE_1.2V";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
- ldo18_reg: ldo18 {
- regulator-compatible = "LDO18";
+ ldo18_reg: LDO18 {
regulator-name = "CAM_ISP_SEN_IO_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- ldo19_reg: ldo19 {
- regulator-compatible = "LDO19";
+ ldo19_reg: LDO19 {
regulator-name = "VT_CAM_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- ldo20_reg: ldo20 {
- regulator-compatible = "LDO20";
+ ldo20_reg: LDO20 {
regulator-name = "VDDQ_PRE_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- ldo21_reg: ldo21 {
- regulator-compatible = "LDO21";
+ ldo21_reg: 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";
+ ldo22_reg: 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";
+ ldo23_reg: LDO23 {
regulator-name = "TSP_AVDD_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- ldo24_reg: ldo24 {
- regulator-compatible = "LDO24";
+ ldo24_reg: LDO24 {
regulator-name = "TSP_VDD_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- ldo25_reg: ldo25 {
- regulator-compatible = "LDO25";
+ ldo25_reg: LDO25 {
regulator-name = "LCD_VCC_3.3V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
};
- ldo26_reg: ldo26 {
- regulator-compatible = "LDO26";
+ ldo26_reg: LDO26 {
regulator-name = "MOTOR_VCC_3.0V";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
};
- buck1_reg: buck1 {
- regulator-compatible = "BUCK1";
+ buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1100000>;
@@ -799,8 +773,7 @@
};
};
- buck2_reg: buck2 {
- regulator-compatible = "BUCK2";
+ buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1500000>;
@@ -811,8 +784,7 @@
};
};
- buck3_reg: buck3 {
- regulator-compatible = "BUCK3";
+ buck3_reg: BUCK3 {
regulator-name = "vdd_int";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1150000>;
@@ -823,8 +795,7 @@
};
};
- buck4_reg: buck4 {
- regulator-compatible = "BUCK4";
+ buck4_reg: BUCK4 {
regulator-name = "vdd_g3d";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1150000>;
@@ -834,40 +805,35 @@
};
};
- buck5_reg: buck5 {
- regulator-compatible = "BUCK5";
+ buck5_reg: BUCK5 {
regulator-name = "VMEM_1.2V_AP";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
};
- buck6_reg: buck6 {
- regulator-compatible = "BUCK6";
+ buck6_reg: BUCK6 {
regulator-name = "VCC_SUB_1.35V";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
};
- buck7_reg: buck7 {
- regulator-compatible = "BUCK7";
+ buck7_reg: BUCK7 {
regulator-name = "VCC_SUB_2.0V";
regulator-min-microvolt = <2000000>;
regulator-max-microvolt = <2000000>;
regulator-always-on;
};
- buck8_reg: buck8 {
- regulator-compatible = "BUCK8";
+ buck8_reg: 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";
+ buck9_reg: BUCK9 {
regulator-name = "CAM_ISP_CORE_1.2V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1200000>;
@@ -1268,6 +1234,10 @@
status = "okay";
};
+&prng {
+ status = "okay";
+};
+
&rtc {
status = "okay";
clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
@@ -1276,7 +1246,7 @@
&sdhci_2 {
bus-width = <4>;
- cd-gpios = <&gpx3 4 0>;
+ cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
cd-inverted;
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
pinctrl-names = "default";
@@ -1303,7 +1273,7 @@
&spi_1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1_bus>;
- cs-gpios = <&gpb 5 0>;
+ cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>;
status = "okay";
s5c73m3_spi: s5c73m3 {
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 294cfe4..40beede 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -64,73 +64,73 @@
compatible = "operating-points-v2";
opp-shared;
- opp00 {
+ opp@200000000 {
opp-hz = /bits/ 64 <200000000>;
opp-microvolt = <900000>;
clock-latency-ns = <200000>;
};
- opp01 {
+ opp@300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <900000>;
clock-latency-ns = <200000>;
};
- opp02 {
+ opp@400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <925000>;
clock-latency-ns = <200000>;
};
- opp03 {
+ opp@500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <950000>;
clock-latency-ns = <200000>;
};
- opp04 {
+ opp@600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <975000>;
clock-latency-ns = <200000>;
};
- opp05 {
+ opp@700000000 {
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <987500>;
clock-latency-ns = <200000>;
};
- opp06 {
+ opp@800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1000000>;
clock-latency-ns = <200000>;
opp-suspend;
};
- opp07 {
+ opp@900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <1037500>;
clock-latency-ns = <200000>;
};
- opp08 {
+ opp@1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1087500>;
clock-latency-ns = <200000>;
};
- opp09 {
+ opp@1100000000 {
opp-hz = /bits/ 64 <1100000000>;
opp-microvolt = <1137500>;
clock-latency-ns = <200000>;
};
- opp10 {
+ opp@1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1187500>;
clock-latency-ns = <200000>;
};
- opp11 {
+ opp@1300000000 {
opp-hz = /bits/ 64 <1300000000>;
opp-microvolt = <1250000>;
clock-latency-ns = <200000>;
};
- opp12 {
+ opp@1400000000 {
opp-hz = /bits/ 64 <1400000000>;
opp-microvolt = <1287500>;
clock-latency-ns = <200000>;
};
- opp13 {
+ opp@1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1350000>;
clock-latency-ns = <200000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index b77dac61..84a23f9 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -116,7 +116,6 @@
clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
clock-names = "sclk_fimg2d", "fimg2d";
iommus = <&sysmmu_g2d>;
- status = "disabled";
};
camera {
@@ -339,6 +338,10 @@
compatible = "samsung,exynos4212-jpeg";
};
+&rotator {
+ compatible = "samsung,exynos4212-rotator";
+};
+
&mixer {
compatible = "samsung,exynos4212-mixer";
clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 110dbd4..e2439e8 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -88,6 +88,20 @@
status = "disabled";
};
+ poweroff: syscon-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&pmu_system_controller>;
+ offset = <0x330C>; /* PS_HOLD_CONTROL */
+ mask = <0x5200>; /* reset value */
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x0400>; /* SWRESET */
+ mask = <0x1>;
+ };
+
fimd: fimd@14400000 {
compatible = "samsung,exynos5250-fimd";
interrupt-parent = <&combiner>;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index db3f65f..c000532 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -129,10 +129,6 @@
samsung,color-depth = <1>;
samsung,link-rate = <0x0a>;
samsung,lane-count = <4>;
-};
-
-&fimd {
- status = "okay";
display-timings {
native-mode = <&timing0>;
@@ -152,6 +148,10 @@
};
};
+&fimd {
+ status = "okay";
+};
+
&hdmi {
hpd-gpio = <&gpx3 7 GPIO_ACTIVE_LOW>;
vdd_osc-supply = <&ldo10_reg>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index c625e71..0f5dcd4 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -89,14 +89,6 @@
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>;
@@ -116,6 +108,14 @@
};
};
+&ehci {
+ samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+};
+
+&fimd {
+ status = "okay";
+};
+
&hdmi {
hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
new file mode 100644
index 0000000..5cb33ba
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -0,0 +1,682 @@
+/*
+ * 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.
+ */
+
+#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"
+
+/ {
+ 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";
+ };
+ };
+ };
+ };
+
+ sound {
+ samsung,i2s-controller = <&i2s0>;
+ };
+
+ 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";
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&buck2_reg>;
+};
+
+&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>;
+
+ 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>;
+ };
+ };
+ };
+ };
+};
+
+&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>;
+ non-removable;
+ 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>;
+ non-removable;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ 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>;
+ };
+
+ 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>;
+ cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
+};
+
+&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-snow-rev5.dts b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
new file mode 100644
index 0000000..f811dc8
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
@@ -0,0 +1,47 @@
+/*
+ * Google Snow Rev 5+ board device tree source
+ *
+ * Copyright (c) 2012 Google, Inc
+ * Copyright (c) 2015 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 "exynos5250-snow-common.dtsi"
+
+/ {
+ model = "Google Snow Rev 5+";
+ compatible = "google,snow-rev5", "samsung,exynos5250",
+ "samsung,exynos5";
+
+ sound {
+ compatible = "google,snow-audio-max98090";
+
+ samsung,model = "Snow-I2S-MAX98090";
+ samsung,audio-codec = <&max98090>;
+ };
+};
+
+&i2c_7 {
+ max98090: codec@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupts = <4 IRQ_TYPE_NONE>;
+ interrupt-parent = <&gpx0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max98090_irq>;
+ };
+};
+
+&pinctrl_0 {
+ max98090_irq: max98090-irq {
+ samsung,pins = "gpx0-4";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index 0720caa..995c7ce 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -9,698 +9,35 @@
*/
/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"
+#include "exynos5250-snow-common.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";
- };
- };
- };
- };
+ compatible = "google,snow-rev4", "google,snow", "samsung,exynos5250",
+ "samsung,exynos5";
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";
- };
-};
-
-&cpu0 {
- cpu0-supply = <&buck2_reg>;
-};
-
-&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>;
-
- 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>;
- };
- };
- };
- };
-
max98095: codec@11 {
compatible = "maxim,max98095";
reg = <0x11>;
- pinctrl-0 = <&max98095_en>;
pinctrl-names = "default";
+ pinctrl-0 = <&max98095_en>;
};
};
-&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>;
- cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
-};
-
-&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.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index b24610e..33e2d5f 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -130,6 +130,10 @@
compatible = "samsung,exynos4210-pd";
reg = <0x100440A0 0x20>;
#power-domain-cells = <0>;
+ clocks = <&clock CLK_FIN_PLL>,
+ <&clock CLK_MOUT_ACLK200_DISP1_SUB>,
+ <&clock CLK_MOUT_ACLK300_DISP1_SUB>;
+ clock-names = "oscclk", "clk0", "clk1";
};
clock: clock-controller@10010000 {
@@ -265,6 +269,15 @@
iommu-names = "left", "right";
};
+ rotator: rotator@11C00000 {
+ compatible = "samsung,exynos5250-rotator";
+ reg = <0x11C00000 0x64>;
+ interrupts = <0 84 0>;
+ clocks = <&clock CLK_ROTATOR>;
+ clock-names = "rotator";
+ iommus = <&sysmmu_rotator>;
+ };
+
tmu: tmu@10060000 {
compatible = "samsung,exynos5250-tmu";
reg = <0x10060000 0x100>;
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
index 731eefd..fad0779 100644
--- a/arch/arm/boot/dts/exynos5410.dtsi
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -102,6 +102,20 @@
reg = <0x10040000 0x5000>;
};
+ poweroff: syscon-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&pmu_system_controller>;
+ offset = <0x330C>; /* PS_HOLD_CONTROL */
+ mask = <0x5200>; /* reset value */
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x0400>; /* SWRESET */
+ mask = <0x1>;
+ };
+
mct: mct@101C0000 {
compatible = "samsung,exynos4210-mct";
reg = <0x101C0000 0xB00>;
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index eeb4ac2..4ecef69 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "exynos5420.dtsi"
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/clock/samsung,s2mps11.h>
@@ -44,7 +45,7 @@
wakeup {
label = "SW-TACT1";
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WAKEUP>;
gpio-key,wakeup;
};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 1b95da7..35cfb07 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -94,7 +94,7 @@
regulator-name = "P5.0V_USB3CON0";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gph0 0 0>;
+ gpio = <&gph0 0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb300_vbus_en>;
enable-active-high;
@@ -105,7 +105,7 @@
regulator-name = "P5.0V_USB3CON1";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gph0 1 0>;
+ gpio = <&gph0 1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb301_vbus_en>;
enable-active-high;
@@ -153,7 +153,7 @@
samsung,color-depth = <1>;
samsung,link-rate = <0x06>;
samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx2 6 0>;
+ samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
ports {
port@0 {
@@ -690,11 +690,9 @@
&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>;
@@ -709,10 +707,9 @@
&mmc_1 {
status = "okay";
num-slots = <1>;
- broken-cd;
+ non-removable;
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>;
@@ -930,7 +927,7 @@
status = "okay";
num-cs = <1>;
samsung,spi-src-clk = <0>;
- cs-gpios = <&gpb1 2 0>;
+ cs-gpios = <&gpb1 2 GPIO_ACTIVE_HIGH>;
cros_ec: cros-ec@0 {
compatible = "google,cros-ec-spi";
@@ -940,6 +937,7 @@
pinctrl-0 = <&ec_spi_cs &ec_irq>;
reg = <0>;
spi-max-frequency = <3125000>;
+ google,has-vbc-nvram;
controller-data {
samsung,spi-feedback-delay = <1>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 98871f9..ac35aef 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "exynos5420.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung SMDK5420 board based on EXYNOS5420";
@@ -69,7 +70,7 @@
regulator-name = "VBUS0";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpg0 5 0>;
+ gpio = <&gpg0 5 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb300_vbus_en>;
enable-active-high;
@@ -80,7 +81,7 @@
regulator-name = "VBUS1";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpg1 4 0>;
+ gpio = <&gpg1 4 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb301_vbus_en>;
enable-active-high;
@@ -98,10 +99,7 @@
samsung,link-rate = <0x0a>;
samsung,lane-count = <4>;
status = "okay";
-};
-&fimd {
- status = "okay";
display-timings {
native-mode = <&timing0>;
timing0: timing@0 {
@@ -118,9 +116,13 @@
};
};
+&fimd {
+ status = "okay";
+};
+
&hdmi {
status = "okay";
- hpd-gpio = <&gpx3 7 0>;
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd_irq>;
};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 1b3d6c7..48a0a55 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -717,6 +717,15 @@
iommus = <&sysmmu_tv>;
};
+ rotator: rotator@11C00000 {
+ compatible = "samsung,exynos5250-rotator";
+ reg = <0x11C00000 0x64>;
+ interrupts = <0 84 0>;
+ clocks = <&clock CLK_ROTATOR>;
+ clock-names = "rotator";
+ iommus = <&sysmmu_rotator>;
+ };
+
gsc_0: video-scaler@13e00000 {
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
@@ -1059,6 +1068,16 @@
#iommu-cells = <0>;
};
+ sysmmu_rotator: sysmmu@0x11D40000 {
+ compatible = "samsung,exynos-sysmmu";
+ reg = <0x11D40000 0x1000>;
+ interrupt-parent = <&combiner>;
+ interrupts = <4 0>;
+ clock-names = "sysmmu", "master";
+ clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+ #iommu-cells = <0>;
+ };
+
sysmmu_jpeg0: sysmmu@0x11F10000 {
compatible = "samsung,exynos-sysmmu";
reg = <0x11F10000 0x1000>;
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
new file mode 100644
index 0000000..9493923
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
@@ -0,0 +1,61 @@
+/*
+ * Hardkernel Odroid XU3 Audio Codec device tree source
+ *
+ * Copyright (c) 2015 Krzysztof Kozlowski
+ * 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.
+*/
+
+/ {
+ sound: sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,name = "Odroid-XU3";
+ 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";
+
+ 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>;
+ };
+ };
+};
+
+&hsi2c_5 {
+ status = "okay";
+ max98090: max98090@10 {
+ compatible = "maxim,max98090";
+ reg = <0x10>;
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 0>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 3b43e57..9134217 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -43,71 +43,7 @@
pinctrl-0 = <&emmc_nrst_pin>;
pinctrl-names = "default";
compatible = "mmc-pwrseq-emmc";
- reset-gpios = <&gpd1 0 1>;
- };
-
- pwmleds {
- compatible = "pwm-leds";
-
- greenled {
- label = "green:mmc0";
- pwms = <&pwm 1 2000000 0>;
- pwm-names = "pwm1";
- /*
- * Green LED is much brighter than the others
- * so limit its max brightness
- */
- max_brightness = <127>;
- linux,default-trigger = "mmc0";
- };
-
- blueled {
- label = "blue:heartbeat";
- pwms = <&pwm 2 2000000 0>;
- pwm-names = "pwm2";
- max_brightness = <255>;
- linux,default-trigger = "heartbeat";
- };
- };
-
- gpioleds {
- compatible = "gpio-leds";
- redled {
- label = "red:microSD";
- gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- linux,default-trigger = "mmc1";
- };
- };
-
- sound: sound {
- compatible = "simple-audio-card";
-
- simple-audio-card,name = "Odroid-XU3";
- 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";
-
- 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>;
- };
+ reset-gpios = <&gpd1 0 GPIO_ACTIVE_LOW>;
};
fan0: pwm-fan {
@@ -131,14 +67,9 @@
<19200000>;
};
-&fimd {
- status = "okay";
-};
-
-
&hdmi {
status = "okay";
- hpd-gpio = <&gpx3 7 0>;
+ hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd_irq>;
@@ -160,6 +91,7 @@
s2mps11,buck2-ramp-enable = <1>;
s2mps11,buck3-ramp-enable = <1>;
s2mps11,buck4-ramp-enable = <1>;
+ samsung,s2mps11-acokb-ground;
interrupt-parent = <&gpx0>;
interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
@@ -375,19 +307,6 @@
};
};
-&hsi2c_5 {
- status = "okay";
- max98090: max98090@10 {
- compatible = "maxim,max98090";
- reg = <0x10>;
- interrupt-parent = <&gpx3>;
- interrupts = <2 0>;
- clocks = <&i2s0 CLK_I2S_CDCLK>;
- clock-names = "mclk";
- #sound-dai-cells = <0>;
- };
-};
-
&i2c_2 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <66000>;
@@ -399,10 +318,6 @@
};
};
-&i2s0 {
- status = "okay";
-};
-
&mfc {
samsung,mfc-r = <0x43000000 0x800000>;
samsung,mfc-l = <0x51000000 0x800000>;
@@ -463,18 +378,6 @@
};
};
-&pwm {
- /*
- * PWM 0 -- fan
- * PWM 1 -- Green LED
- * PWM 2 -- Blue LED
- * PWM 3 -- on MIPI connector for backlight
- */
- pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
- pinctrl-names = "default";
- status = "okay";
-};
-
&tmu_cpu0 {
vtmu-supply = <&ldo7_reg>;
status = "okay";
@@ -510,9 +413,7 @@
dr_mode = "host";
};
-&usbdrd_dwc3_1 {
- dr_mode = "otg";
-};
+/* usbdrd_dwc3_1 mode customized in each board */
&usbdrd3_0 {
vdd33-supply = <&ldo9_reg>;
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
index c06882b..2ae1cf4 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
@@ -13,8 +13,59 @@
/dts-v1/;
#include "exynos5422-odroidxu3-common.dtsi"
+#include "exynos5422-odroidxu3-audio.dtsi"
/ {
model = "Hardkernel Odroid XU3 Lite";
compatible = "hardkernel,odroid-xu3-lite", "samsung,exynos5800", "samsung,exynos5";
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ greenled {
+ label = "green:mmc0";
+ pwms = <&pwm 1 2000000 0>;
+ pwm-names = "pwm1";
+ /*
+ * Green LED is much brighter than the others
+ * so limit its max brightness
+ */
+ max_brightness = <127>;
+ linux,default-trigger = "mmc0";
+ };
+
+ blueled {
+ label = "blue:heartbeat";
+ pwms = <&pwm 2 2000000 0>;
+ pwm-names = "pwm2";
+ max_brightness = <255>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpioleds {
+ compatible = "gpio-leds";
+ redled {
+ label = "red:microSD";
+ gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "mmc1";
+ };
+ };
+};
+
+&pwm {
+ /*
+ * PWM 0 -- fan
+ * PWM 1 -- Green LED
+ * PWM 2 -- Blue LED
+ * PWM 3 -- on MIPI connector for backlight
+ */
+ pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "peripheral";
};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index 78e6a50..432406d 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -12,10 +12,45 @@
/dts-v1/;
#include "exynos5422-odroidxu3-common.dtsi"
+#include "exynos5422-odroidxu3-audio.dtsi"
/ {
model = "Hardkernel Odroid XU3";
compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5";
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ greenled {
+ label = "green:mmc0";
+ pwms = <&pwm 1 2000000 0>;
+ pwm-names = "pwm1";
+ /*
+ * Green LED is much brighter than the others
+ * so limit its max brightness
+ */
+ max_brightness = <127>;
+ linux,default-trigger = "mmc0";
+ };
+
+ blueled {
+ label = "blue:heartbeat";
+ pwms = <&pwm 2 2000000 0>;
+ pwm-names = "pwm2";
+ max_brightness = <255>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpioleds {
+ compatible = "gpio-leds";
+ redled {
+ label = "red:microSD";
+ gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "mmc1";
+ };
+ };
};
&i2c_0 {
@@ -49,3 +84,19 @@
shunt-resistor = <10000>;
};
};
+
+&pwm {
+ /*
+ * PWM 0 -- fan
+ * PWM 1 -- Green LED
+ * PWM 2 -- Blue LED
+ * PWM 3 -- on MIPI connector for backlight
+ */
+ pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
new file mode 100644
index 0000000..2faf886
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
@@ -0,0 +1,48 @@
+/*
+ * Hardkernel Odroid XU4 board device tree source
+ *
+ * Copyright (c) 2015 Krzysztof Kozlowski
+ * Copyright (c) 2014 Collabora Ltd.
+ * Copyright (c) 2013-2015 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 "exynos5422-odroidxu3-common.dtsi"
+
+/ {
+ model = "Hardkernel Odroid XU4";
+ compatible = "hardkernel,odroid-xu4", "samsung,exynos5800", \
+ "samsung,exynos5";
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ blueled {
+ label = "blue:heartbeat";
+ pwms = <&pwm 2 2000000 0>;
+ pwm-names = "pwm2";
+ max_brightness = <255>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+&pwm {
+ /*
+ * PWM 0 -- fan
+ * PWM 2 -- Blue LED
+ */
+ pinctrl-0 = <&pwm0_out &pwm2_out>;
+ pinctrl-names = "default";
+ samsung,pwm-outputs = <0>, <2>;
+ status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "host";
+};
diff --git a/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
index e4443f4..6a0d802 100644
--- a/arch/arm/boot/dts/exynos5440-ssdk5440.dts
+++ b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "exynos5440.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
@@ -29,12 +30,12 @@
};
&pcie_0 {
- reset-gpio = <&pin_ctrl 5 0>;
+ reset-gpio = <&pin_ctrl 5 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&pcie_1 {
- reset-gpio = <&pin_ctrl 22 0>;
+ reset-gpio = <&pin_ctrl 22 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 8f40c7e..064176f 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -94,7 +94,7 @@
regulator-name = "P5.0V_USB3CON0";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gph0 0 0>;
+ gpio = <&gph0 0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb300_vbus_en>;
enable-active-high;
@@ -105,7 +105,7 @@
regulator-name = "P5.0V_USB3CON1";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gph0 1 0>;
+ gpio = <&gph0 1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb301_vbus_en>;
enable-active-high;
@@ -122,6 +122,12 @@
compatible = "auo,b133htn01";
power-supply = <&tps65090_fet6>;
backlight = <&backlight>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dp_out>;
+ };
+ };
};
mmc1_pwrseq: mmc1_pwrseq {
@@ -147,8 +153,15 @@
samsung,color-depth = <1>;
samsung,link-rate = <0x0a>;
samsung,lane-count = <2>;
- samsung,hpd-gpio = <&gpx2 6 0>;
- panel = <&panel>;
+ samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ port {
+ dp_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
};
&fimd {
@@ -652,12 +665,10 @@
&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>;
@@ -672,10 +683,9 @@
&mmc_1 {
status = "okay";
num-slots = <1>;
- broken-cd;
+ non-removable;
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>;
@@ -893,7 +903,7 @@
status = "okay";
num-cs = <1>;
samsung,spi-src-clk = <0>;
- cs-gpios = <&gpb1 2 0>;
+ cs-gpios = <&gpb1 2 GPIO_ACTIVE_HIGH>;
cros_ec: cros-ec@0 {
compatible = "google,cros-ec-spi";
@@ -903,6 +913,7 @@
pinctrl-0 = <&ec_spi_cs &ec_irq>;
reg = <0>;
spi-max-frequency = <3125000>;
+ google,has-vbc-nvram;
controller-data {
samsung,spi-feedback-delay = <1>;
diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts
index fe62392..a579fbf 100644
--- a/arch/arm/boot/dts/hi3620-hi4511.dts
+++ b/arch/arm/boot/dts/hi3620-hi4511.dts
@@ -16,7 +16,8 @@
compatible = "hisilicon,hi3620-hi4511";
chosen {
- bootargs = "console=ttyAMA0,115200 root=/dev/ram0 earlyprintk";
+ bootargs = "root=/dev/ram0";
+ stdout-path = "serial0:115200n8";
};
memory {
diff --git a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts
index 721b092..d13af84 100644
--- a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts
+++ b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts
@@ -15,7 +15,7 @@
compatible = "hisilicon,hix5hd2";
chosen {
- bootargs = "console=ttyAMA0,115200 earlyprintk";
+ stdout-path = "serial0:115200n8";
};
cpus {
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index b995333..302d116 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -383,9 +383,11 @@
};
ocotp@8002c000 {
- compatible = "fsl,ocotp";
+ compatible = "fsl,imx23-ocotp", "fsl,ocotp";
+ #address-cells = <1>;
+ #size-cells = <1>;
reg = <0x8002c000 0x2000>;
- status = "disabled";
+ clocks = <&clks 15>;
};
axi-ahb@8002e000 {
@@ -567,7 +569,7 @@
};
};
- iio_hwmon {
+ iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&lradc 8>;
};
diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h
index 7c4b9f2..848ffa78 100644
--- a/arch/arm/boot/dts/imx25-pinfunc.h
+++ b/arch/arm/boot/dts/imx25-pinfunc.h
@@ -284,6 +284,7 @@
#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_CONTRAST__USBH2_PWR 0x118 0x310 0x000 0x16 0x000
#define MX25_PAD_PWM__PWM 0x11c 0x314 0x000 0x10 0x000
#define MX25_PAD_PWM__GPIO_1_26 0x11c 0x314 0x000 0x15 0x000
@@ -439,6 +440,7 @@
#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__UART1_DTR 0x1a8 0x3a0 0x000 0x14 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
@@ -446,6 +448,7 @@
#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__UART1_DCD 0x1b0 0x3a8 0x000 0x14 0x000
#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
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 677f81d..cde329e 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -24,6 +24,10 @@
i2c2 = &i2c3;
mmc0 = &esdhc1;
mmc1 = &esdhc2;
+ pwm0 = &pwm1;
+ pwm1 = &pwm2;
+ pwm2 = &pwm3;
+ pwm3 = &pwm4;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index feb9d34..f818ea4 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -486,7 +486,10 @@
compatible = "fsl,imx27-usb";
reg = <0x10024000 0x200>;
interrupts = <56>;
- clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+ <&clks IMX27_CLK_USB_AHB_GATE>,
+ <&clks IMX27_CLK_USB_DIV>;
+ clock-names = "ipg", "ahb", "per";
fsl,usbmisc = <&usbmisc 0>;
status = "disabled";
};
@@ -495,7 +498,10 @@
compatible = "fsl,imx27-usb";
reg = <0x10024200 0x200>;
interrupts = <54>;
- clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+ <&clks IMX27_CLK_USB_AHB_GATE>,
+ <&clks IMX27_CLK_USB_DIV>;
+ clock-names = "ipg", "ahb", "per";
fsl,usbmisc = <&usbmisc 1>;
dr_mode = "host";
status = "disabled";
@@ -505,7 +511,10 @@
compatible = "fsl,imx27-usb";
reg = <0x10024400 0x200>;
interrupts = <55>;
- clocks = <&clks IMX27_CLK_USB_IPG_GATE>;
+ clocks = <&clks IMX27_CLK_USB_IPG_GATE>,
+ <&clks IMX27_CLK_USB_AHB_GATE>,
+ <&clks IMX27_CLK_USB_DIV>;
+ clock-names = "ipg", "ahb", "per";
fsl,usbmisc = <&usbmisc 2>;
dr_mode = "host";
status = "disabled";
@@ -515,7 +524,6 @@
#index-cells = <1>;
compatible = "fsl,imx27-usbmisc";
reg = <0x10024600 0x200>;
- clocks = <&clks IMX27_CLK_USB_AHB_GATE>;
};
sahara2: sahara@10025000 {
diff --git a/arch/arm/boot/dts/imx28-cfa10057.dts b/arch/arm/boot/dts/imx28-cfa10057.dts
index 5df0b24..7a80bd6 100644
--- a/arch/arm/boot/dts/imx28-cfa10057.dts
+++ b/arch/arm/boot/dts/imx28-cfa10057.dts
@@ -115,7 +115,7 @@
pwm: pwm@80064000 {
pinctrl-names = "default";
- pinctrl-0 = <&pwm3_pins_b>;
+ pinctrl-0 = <&pwm4_pins_a>;
status = "okay";
};
@@ -170,7 +170,7 @@
backlight {
compatible = "pwm-backlight";
- pwms = <&pwm 3 5000000>;
+ pwms = <&pwm 4 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
};
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 279249b..e3ef94a 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -57,7 +57,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "sst,sst25vf016b";
+ compatible = "sst,sst25vf016b", "jedec,spi-nor";
spi-max-frequency = <40000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts
index e35cc6b..8d04e57 100644
--- a/arch/arm/boot/dts/imx28-m28evk.dts
+++ b/arch/arm/boot/dts/imx28-m28evk.dts
@@ -41,7 +41,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "m25p80";
+ compatible = "m25p80", "jedec,spi-nor";
spi-max-frequency = <40000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts
index a5b27c8..4ea8934 100644
--- a/arch/arm/boot/dts/imx28-tx28.dts
+++ b/arch/arm/boot/dts/imx28-tx28.dts
@@ -13,6 +13,7 @@
/dts-v1/;
#include "imx28.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "Ka-Ro electronics TX28 module";
@@ -324,7 +325,7 @@
pinctrl-names = "default";
pinctrl-0 = <&tx28_edt_ft5x06_pins>;
interrupt-parent = <&gpio2>;
- interrupts = <5 0>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
wake-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 4e073e8..f637ec9 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -405,6 +405,17 @@
fsl,pull-up = <MXS_PULL_DISABLE>;
};
+ auart4_2pins_b: auart4@1 {
+ reg = <1>;
+ fsl,pinmux-ids = <
+ MX28_PAD_AUART0_CTS__AUART4_RX
+ MX28_PAD_AUART0_RTS__AUART4_TX
+ >;
+ 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 = <
@@ -936,9 +947,11 @@
};
ocotp: ocotp@8002c000 {
- compatible = "fsl,ocotp";
+ compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+ #address-cells = <1>;
+ #size-cells = <1>;
reg = <0x8002c000 0x2000>;
- status = "disabled";
+ clocks = <&clks 25>;
};
axi-ahb@8002e000 {
@@ -1243,7 +1256,7 @@
};
};
- iio_hwmon {
+ iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&lradc 8>;
};
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
index c34f825..5fdb222 100644
--- a/arch/arm/boot/dts/imx31.dtsi
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -25,7 +25,7 @@
#size-cells = <0>;
cpu {
- compatible = "arm,arm1136";
+ compatible = "arm,arm1136jf-s";
device_type = "cpu";
};
};
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi
index e6540b5..ed3dc33 100644
--- a/arch/arm/boot/dts/imx35.dtsi
+++ b/arch/arm/boot/dts/imx35.dtsi
@@ -29,7 +29,7 @@
#size-cells = <0>;
cpu {
- compatible = "arm,arm1136";
+ compatible = "arm,arm1136jf-s";
device_type = "cpu";
};
};
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
index 1b22512..27d763c 100644
--- a/arch/arm/boot/dts/imx50-evk.dts
+++ b/arch/arm/boot/dts/imx50-evk.dts
@@ -33,7 +33,7 @@
flash: m25p32@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "m25p32", "m25p80";
+ compatible = "m25p32", "jedec,spi-nor";
spi-max-frequency = <25000000>;
reg = <1>;
diff --git a/arch/arm/boot/dts/imx51-ts4800.dts b/arch/arm/boot/dts/imx51-ts4800.dts
new file mode 100644
index 0000000..0ff76a1
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-ts4800.dts
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2015 Savoir-faire Linux
+ *
+ * This device tree is based on imx51-babbage.dts
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+/dts-v1/;
+#include "imx51.dtsi"
+
+/ {
+ model = "Technologic Systems TS-4800";
+ compatible = "technologic,imx51-ts4800", "fsl,imx51";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ memory {
+ reg = <0x90000000 0x10000000>;
+ };
+
+ clocks {
+ ckih1 {
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ clock-frequency = <24576000>;
+ };
+ };
+
+ backlight_reg: regulator-backlight {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_lcd>;
+ regulator-name = "enable_lcd_reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 9 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 78770>;
+ brightness-levels = <0 150 200 255>;
+ default-brightness-level = <1>;
+ power-supply = <&backlight_reg>;
+ };
+
+ display0: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+
+ display-timings {
+ 800x480p60 {
+ native-mode;
+ clock-frequency = <30066000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <50>;
+ hback-porch = <70>;
+ hsync-len = <50>;
+ vback-porch = <0>;
+ vfront-porch = <0>;
+ vsync-len = <50>;
+ };
+ };
+
+ port@0 {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ cd-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 1 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";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ rtc: m41t00@68 {
+ compatible = "stm,m41t00";
+ reg = <0x68>;
+ };
+};
+
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_backlight>;
+ 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";
+};
+
+&weim {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_weim>;
+ status = "okay";
+
+ fpga@0 {
+ compatible = "simple-bus";
+ fsl,weim-cs-timing = <0x0061008F 0x00000002 0x1c022000
+ 0x00000000 0x1c092480 0x00000000>;
+ reg = <0 0x0000000 0x1d000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x1d000>;
+
+ syscon: syscon@b0010000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x10000 0x3d>;
+ reg-io-width = <2>;
+
+ wdt@e {
+ compatible = "technologic,ts4800-wdt";
+ syscon = <&syscon 0xe>;
+ };
+ };
+
+ touchscreen {
+ compatible = "technologic,ts4800-ts";
+ reg = <0x12000 0x1000>;
+ syscon = <&syscon 0x10 6>;
+ };
+ };
+};
+
+&iomuxc {
+ 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_enable_lcd: enablelcdgrp {
+ fsl,pins = <
+ MX51_PAD_CSI2_D12__GPIO4_9 0x1c5
+ >;
+ };
+
+ 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_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_DISP2_DAT10__FEC_COL 0x00000180
+ MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x00000180
+ MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x00002180
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x00002004
+ MX51_PAD_NANDF_CS2__FEC_TX_ER 0x00002004
+ MX51_PAD_DI2_PIN2__FEC_MDC 0x00002004
+ MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x00002004
+ MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x00002004
+ MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x00002004
+ MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x00002004
+ MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x00002180
+ MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x000020a4
+ MX51_PAD_EIM_A20__GPIO2_14 0x00000085 /* Phy Reset */
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX51_PAD_KEY_COL4__I2C2_SCL 0x400001ed
+ MX51_PAD_KEY_COL5__I2C2_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_lcd: lcdgrp {
+ 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
+ MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x5
+ MX51_PAD_DI_GP4__DI2_PIN15 0x5
+ >;
+ };
+
+ pinctrl_pwm_backlight: backlightgrp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_2__PWM1_PWMO 0x80000000
+ >;
+ };
+
+ 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_EIM_D25__UART3_RXD 0x1c5
+ MX51_PAD_EIM_D26__UART3_TXD 0x1c5
+ >;
+ };
+
+ pinctrl_weim: weimgrp {
+ fsl,pins = <
+ MX51_PAD_EIM_DTACK__EIM_DTACK 0x85
+ MX51_PAD_EIM_CS0__EIM_CS0 0x0
+ MX51_PAD_EIM_CS1__EIM_CS1 0x0
+ MX51_PAD_EIM_EB0__EIM_EB0 0x85
+ MX51_PAD_EIM_EB1__EIM_EB1 0x85
+ MX51_PAD_EIM_OE__EIM_OE 0x85
+ MX51_PAD_EIM_LBA__EIM_LBA 0x85
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index fc89ce1..542ab9e 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -76,7 +76,7 @@
flash: m25p32@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p32", "st,m25p";
+ compatible = "st,m25p32", "st,m25p", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <1>;
diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts
index 3b73e81..13e842b 100644
--- a/arch/arm/boot/dts/imx53-tx53-x03x.dts
+++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts
@@ -12,6 +12,7 @@
/dts-v1/;
#include "imx53-tx53.dtsi"
#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>
/ {
@@ -216,7 +217,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_edt_ft5x06_1>;
interrupt-parent = <&gpio6>;
- interrupts = <15 0>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/imx6dl-nit6xlite.dts b/arch/arm/boot/dts/imx6dl-nit6xlite.dts
new file mode 100644
index 0000000..e0161e4
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-nit6xlite.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 Boundary Devices, 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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-nit6xlite.dtsi"
+
+/ {
+ model = "Boundary Devices i.MX6 Solo Nitrogen6_Lite Board";
+ compatible = "boundary,imx6dl-nit6xlite", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-nitrogen6x.dts b/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
index 5f4d33c..8398f97 100644
--- a/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
+++ b/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
@@ -3,12 +3,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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/;
@@ -16,6 +46,6 @@
#include "imx6qdl-nitrogen6x.dtsi"
/ {
- model = "Freescale i.MX6 DualLite Nitrogen6x Board";
- compatible = "fsl,imx6dl-nitrogen6x", "fsl,imx6dl";
+ model = "Boundary Devices i.MX6 DualLite Nitrogen6x Board";
+ compatible = "boundary,imx6dl-nitrogen6x", "fsl,imx6dl";
};
diff --git a/arch/arm/boot/dts/imx6dl-rex-basic.dts b/arch/arm/boot/dts/imx6dl-rex-basic.dts
index b13845c..c3a14a4 100644
--- a/arch/arm/boot/dts/imx6dl-rex-basic.dts
+++ b/arch/arm/boot/dts/imx6dl-rex-basic.dts
@@ -23,7 +23,7 @@
&ecspi3 {
flash: m25p80@0 {
- compatible = "sst,sst25vf016b";
+ compatible = "sst,sst25vf016b", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6dl-sabrelite.dts b/arch/arm/boot/dts/imx6dl-sabrelite.dts
index 2de0447..0f06ca5 100644
--- a/arch/arm/boot/dts/imx6dl-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6dl-sabrelite.dts
@@ -2,12 +2,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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/;
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 4b0ec07..c13a73a 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -104,10 +104,15 @@
compatible = "fsl,imx-display-subsystem";
ports = <&ipu1_di0>, <&ipu1_di1>;
};
+
+ gpu-subsystem {
+ compatible = "fsl,imx-gpu-subsystem";
+ cores = <&gpu_2d>, <&gpu_3d>;
+ };
};
&gpt {
- compatible = "fsl,imx6dl-gpt", "fsl,imx6q-gpt";
+ compatible = "fsl,imx6dl-gpt";
};
&hdmi {
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
index 4fa2543..364578d 100644
--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -109,7 +109,7 @@
status = "okay";
flash: m25p80@0 {
- compatible = "m25p80";
+ compatible = "m25p80", "jedec,spi-nor";
spi-max-frequency = <40000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
index 822ffb2..a51834e 100644
--- a/arch/arm/boot/dts/imx6q-gw5400-a.dts
+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts
@@ -145,7 +145,7 @@
status = "okay";
flash: m25p80@0 {
- compatible = "sst,w25q256";
+ compatible = "sst,w25q256", "jedec,spi-nor";
spi-max-frequency = <30000000>;
reg = <0>;
};
@@ -154,7 +154,7 @@
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6_max.dts b/arch/arm/boot/dts/imx6q-nitrogen6_max.dts
new file mode 100644
index 0000000..d417457
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-nitrogen6_max.dts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Boundary Devices, 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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-nitrogen6_max.dtsi"
+
+/ {
+ model = "Boundary Devices i.MX6 Quad Nitrogen6_MAX Board";
+ compatible = "boundary,imx6q-nitrogen6_max", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6x.dts b/arch/arm/boot/dts/imx6q-nitrogen6x.dts
index a57866b..d168633 100644
--- a/arch/arm/boot/dts/imx6q-nitrogen6x.dts
+++ b/arch/arm/boot/dts/imx6q-nitrogen6x.dts
@@ -3,12 +3,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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/;
@@ -16,8 +46,8 @@
#include "imx6qdl-nitrogen6x.dtsi"
/ {
- model = "Freescale i.MX6 Quad Nitrogen6x Board";
- compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
+ model = "Boundary Devices i.MX6 Quad Nitrogen6x Board";
+ compatible = "boundary,imx6q-nitrogen6x", "fsl,imx6q";
};
&sata {
diff --git a/arch/arm/boot/dts/imx6q-novena.dts b/arch/arm/boot/dts/imx6q-novena.dts
new file mode 100644
index 0000000..5acd0c6
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-novena.dts
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2015 Sutajio Ko-Usagi PTE 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.
+ *
+ * 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 = "Kosagi Novena Dual/Quad";
+ compatible = "kosagi,imx6q-novena", "fsl,imx6q";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 10000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight_novena>;
+ power-supply = <&reg_lvds_lcd>;
+ brightness-levels = <0 3 6 12 16 24 32 48 64 96 128 192 255>;
+ default-brightness-level = <12>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys_novena>;
+
+ user-button {
+ label = "User Button";
+ gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ };
+
+ lid {
+ label = "Lid";
+ gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds_novena>;
+
+ heartbeat {
+ label = "novena:white:panel";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ panel: panel {
+ compatible = "innolux,n133hse-ea1", "simple-panel";
+ backlight = <&backlight>;
+ };
+
+ reg_2p5v: regulator-2p5v {
+ compatible = "regulator-fixed";
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_audio_codec: regulator-audio-codec {
+ compatible = "regulator-fixed";
+ regulator-name = "es8328-power";
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <400000>;
+ gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_display: regulator-display {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd-display-power";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <200000>;
+ gpio = <&gpio5 28 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_lvds_lcd: regulator-lvds-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd-lvds-power";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_pcie: regulator-pcie {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie-bus-power";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_sata: regulator-sata {
+ compatible = "regulator-fixed";
+ regulator-name = "sata-power";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <10000>;
+ gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usb_otg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-es8328";
+ model = "imx-audio-es8328";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-amp-supply = <&reg_audio_codec>;
+ jack-gpio = <&gpio5 15 GPIO_ACTIVE_HIGH>;
+ audio-routing =
+ "Speaker", "LOUT2",
+ "Speaker", "ROUT2",
+ "Speaker", "audio-amp",
+ "Headphone", "ROUT1",
+ "Headphone", "LOUT1",
+ "LINPUT1", "Mic Jack",
+ "RINPUT1", "Mic Jack",
+ "Mic Jack", "Mic Bias";
+ mux-int-port = <0x1>;
+ mux-ext-port = <0x3>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_novena>;
+ status = "okay";
+};
+
+&ecspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3_novena>;
+ fsl,spi-num-chipselects = <3>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet_novena>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ rxc-skew-ps = <3000>;
+ rxdv-skew-ps = <0>;
+ txc-skew-ps = <3000>;
+ txen-skew-ps = <0>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txd0-skew-ps = <3000>;
+ txd1-skew-ps = <3000>;
+ txd2-skew-ps = <3000>;
+ txd3-skew-ps = <3000>;
+ status = "okay";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_novena>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_novena>;
+ status = "okay";
+
+ accel: mma8452@1c {
+ compatible = "fsl,mma8452";
+ reg = <0x1c>;
+ };
+
+ rtc: pcf8523@68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ };
+
+ sbs_battery: bq20z75@0b {
+ compatible = "sbs,sbs-battery";
+ reg = <0x0b>;
+ sbs,i2c-retry-count = <50>;
+ };
+
+ touch: stmpe811@44 {
+ compatible = "st,stmpe811";
+ reg = <0x44>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ irq-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>;
+ id = <0>;
+ blocks = <0x5>;
+ irq-trigger = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_stmpe_novena>;
+ vio-supply = <&reg_3p3v>;
+ vcc-supply = <&reg_3p3v>;
+
+ stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ st,sample-time = <4>;
+ st,mod-12b = <1>;
+ st,ref-sel = <0>;
+ st,adc-freq = <1>;
+ st,ave-ctrl = <1>;
+ st,touch-det-delay = <2>;
+ st,settling = <2>;
+ st,fraction-z = <7>;
+ st,i-drive = <1>;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_novena>;
+ status = "okay";
+
+ pmic: pfuze100@08 {
+ compatible = "fsl,pfuze100";
+ reg = <0x08>;
+
+ regulators {
+ reg_sw1a: sw1a {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ reg_sw1c: sw1c {
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1875000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_sw2: sw2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_sw3a: sw3a {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_sw3b: sw3b {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <1975000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_sw4: sw4 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_swbst: swbst {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ };
+
+ reg_snvs: vsnvs {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vref: vrefddr {
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vgen1: vgen1 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ reg_vgen2: vgen2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ reg_vgen3: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_vgen4: vgen4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vgen5: vgen5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_vgen6: vgen6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3_novena>;
+ status = "okay";
+
+ codec: es8328@11 {
+ compatible = "everest,es8328";
+ reg = <0x11>;
+ DVDD-supply = <&reg_audio_codec>;
+ AVDD-supply = <&reg_audio_codec>;
+ PVDD-supply = <&reg_audio_codec>;
+ HPVDD-supply = <&reg_audio_codec>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sound_novena>;
+ clocks = <&clks IMX6QDL_CLK_CKO1>;
+ assigned-clocks = <&clks IMX6QDL_CLK_CKO>,
+ <&clks IMX6QDL_CLK_CKO1_SEL>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO>,
+ <&clks IMX6QDL_CLK_CKO1>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_CKO1>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>,
+ <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_CLK_CKO1_PODF>;
+ assigned-clock-rates = <0 0 722534400 22579200>;
+ };
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp_novena>;
+ linux,keymap = <
+ MATRIX_KEY(1, 1, KEY_CONFIG)
+ >;
+ status = "okay";
+};
+
+&ldb {
+ fsl,dual-channel;
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "jeida";
+ fsl,data-width = <24>;
+ fsl,panel = <&panel>;
+ status = "okay";
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie_novena>;
+ reset-gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sata {
+ target-supply = <&reg_sata>;
+ fsl,transmit-level-mV = <1025>;
+ fsl,transmit-boost-mdB = <0>;
+ fsl,transmit-atten-16ths = <8>;
+ status = "okay";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_novena>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_novena>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4_novena>;
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ dr_mode = "otg";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_novena>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ vbus-supply = <&reg_swbst>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_novena>;
+ cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_novena>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_audmux_novena: audmuxgrp-novena {
+ 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_backlight_novena: backlightgrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0
+ MX6QDL_PAD_CSI0_DAT10__GPIO5_IO28 0x1b0b1
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b1
+ >;
+ };
+
+ pinctrl_ecspi3_novena: ecspi3grp-novena {
+ 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_novena: enetgrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b020
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b028
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b028
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b028
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b028
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b028
+ 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
+ /* Ethernet reset */
+ MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x1b0b1
+ >;
+ };
+
+ pinctrl_fpga_gpio: fpgagpiogrp-novena {
+ fsl,pins = <
+ /* FPGA power */
+ MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b1
+ /* Reset */
+ MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07 0x1b0b1
+ /* FPGA GPIOs */
+ MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x1b0b1
+ MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x1b0b1
+ MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x1b0b1
+ MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x1b0b1
+ MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x1b0b1
+ MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x1b0b1
+ MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x1b0b1
+ MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x1b0b1
+ MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x1b0b1
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x1b0b1
+ MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x1b0b1
+ MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x1b0b1
+ MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x1b0b1
+ MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b1
+ MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x1b0b1
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x1b0b1
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b1
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b1
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b1
+ MX6QDL_PAD_EIM_CS0__GPIO2_IO23 0x1b0b1
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x1b0b1
+ MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1b0b1
+ MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x1b0b1
+ MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x1b0b1
+ MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x1b0b1
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x1b0b1
+ >;
+ };
+
+ pinctrl_fpga_eim: fpgaeimgrp-novena {
+ fsl,pins = <
+ /* FPGA power */
+ MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b1
+ /* Reset */
+ MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07 0x1b0b1
+ /* FPGA GPIOs */
+ MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0f1
+ MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0f1
+ MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0f1
+ MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0f1
+ MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0f1
+ MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0f1
+ MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0f1
+ MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0f1
+ MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0f1
+ MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0f1
+ MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0f1
+ MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0f1
+ MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0f1
+ MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0f1
+ MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0f1
+ MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0f1
+ MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0f1
+ MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0f1
+ MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0f1
+ MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0f1
+ MX6QDL_PAD_EIM_CS1__EIM_CS1_B 0xb0f1
+ MX6QDL_PAD_EIM_LBA__EIM_LBA_B 0xb0f1
+ MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0f1
+ MX6QDL_PAD_EIM_RW__EIM_RW 0xb0f1
+ MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb0f1
+ MX6QDL_PAD_EIM_BCLK__EIM_BCLK 0xb0f1
+ >;
+ };
+
+ pinctrl_gpio_keys_novena: gpiokeysgrp-novena {
+ fsl,pins = <
+ /* User button */
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x1b0b0
+ /* PCIe Wakeup */
+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1f0e0
+ /* Lid switch */
+ MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0
+ >;
+ };
+
+ pinctrl_hdmi_novena: hdmigrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b0b1
+ >;
+ };
+
+ pinctrl_i2c1_novena: i2c1grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c2_novena: i2c2grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3_novena: i2c3grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_kpp_novena: kppgrp-novena {
+ fsl,pins = <
+ /* Front panel button */
+ MX6QDL_PAD_KEY_ROW1__KEY_ROW1 0x1b0b1
+ /* Fake column driver, not connected */
+ MX6QDL_PAD_KEY_COL1__KEY_COL1 0x1b0b1
+ >;
+ };
+
+ pinctrl_leds_novena: ledsgrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x1b0b1
+ >;
+ };
+
+ pinctrl_pcie_novena: pciegrp-novena {
+ fsl,pins = <
+ /* Reset */
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b1
+ /* Power On */
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b1
+ /* Wifi kill */
+ MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x1b0b1
+ >;
+ };
+
+ pinctrl_sata_novena: satagrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x1b0b1
+ >;
+ };
+
+ pinctrl_senoko_novena: senokogrp-novena {
+ fsl,pins = <
+ /* Senoko IRQ line */
+ MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x13048
+ /* Senoko reset line */
+ MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x1b0b1
+ >;
+ };
+
+ pinctrl_sound_novena: soundgrp-novena {
+ fsl,pins = <
+ /* Audio power regulator */
+ MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17 0x1b0b1
+ /* Headphone plug */
+ MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x1b0b1
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000b0
+ >;
+ };
+
+ pinctrl_stmpe_novena: stmpegrp-novena {
+ fsl,pins = <
+ /* Touchscreen interrupt */
+ MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2_novena: uart2grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3_novena: uart3grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart4_novena: uart4grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
+ MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbotg_novena: usbotggrp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usdhc2_novena: usdhc2grp-novena {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
+ /* Write protect */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b1
+ /* Card detect */
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3_novena: usdhc3grp-novena {
+ 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
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q-rex-pro.dts b/arch/arm/boot/dts/imx6q-rex-pro.dts
index 3c2852b..90ea61a 100644
--- a/arch/arm/boot/dts/imx6q-rex-pro.dts
+++ b/arch/arm/boot/dts/imx6q-rex-pro.dts
@@ -23,7 +23,7 @@
&ecspi3 {
flash: m25p80@0 {
- compatible = "sst,sst25vf032b";
+ compatible = "sst,sst25vf032b", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 96e4688..66d10d8 100644
--- a/arch/arm/boot/dts/imx6q-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -2,12 +2,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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/;
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 399103b..0d93c0e 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -14,6 +14,7 @@
/ {
aliases {
+ ipu1 = &ipu2;
spi4 = &ecspi5;
};
@@ -103,42 +104,6 @@
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
- >;
- };
- };
};
};
@@ -153,6 +118,16 @@
status = "disabled";
};
+ gpu_vg: gpu@02204000 {
+ compatible = "vivante,gc";
+ reg = <0x02204000 0x4000>;
+ interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_OPENVG_AXI>,
+ <&clks IMX6QDL_CLK_GPU2D_CORE>;
+ clock-names = "bus", "core";
+ power-domains = <&gpc 1>;
+ };
+
ipu2: ipu@02800000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -225,6 +200,11 @@
compatible = "fsl,imx-display-subsystem";
ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
};
+
+ gpu-subsystem {
+ compatible = "fsl,imx-gpu-subsystem";
+ cores = <&gpu_2d>, <&gpu_3d>, <&gpu_vg>;
+ };
};
&hdmi {
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
index f4d6ae5..ecbc6eb 100644
--- a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
@@ -109,7 +109,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q128a11";
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
index a47a039..7d81100 100644
--- a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
@@ -141,7 +141,7 @@
flash: m25p80@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q128a11";
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <1>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
index 45e7c39..da1341d 100644
--- a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
@@ -38,7 +38,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "sst,sst25vf040b", "m25p80";
+ compatible = "sst,sst25vf040b", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
index 7b31fdb..5cd16f2 100644
--- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
@@ -94,7 +94,7 @@
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -174,6 +174,24 @@
status = "okay";
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>; /* MX6_DIO3 */
+ status = "disabled";
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
@@ -294,6 +312,24 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm4: pwm4grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
index 1b66328..9fa8a10 100644
--- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -151,10 +151,25 @@
status = "okay";
};
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
+&ecspi3 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+};
+
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -275,6 +290,18 @@
status = "okay";
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
&pwm4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
@@ -338,6 +365,15 @@
>;
};
+ pinctrl_ecspi3: escpi3grp {
+ 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 0x100b1
+ >;
+ };
+
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
@@ -429,6 +465,18 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_pwm4: pwm4grp {
fsl,pins = <
MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
index 7c51839..e8375e1 100644
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -152,10 +152,17 @@
status = "okay";
};
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -247,7 +254,7 @@
&ldb {
status = "okay";
- lvds-channel@1 {
+ lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <18>;
status = "okay";
@@ -280,6 +287,18 @@
};
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
&pwm4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
@@ -435,6 +454,18 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_pwm4: pwm4grp {
fsl,pins = <
MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
index 929e0b3..66983dc 100644
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -142,10 +142,17 @@
status = "okay";
};
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -260,6 +267,8 @@
swbst_reg: swbst {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5150000>;
+ regulator-boot-on;
+ regulator-always-on;
};
snvs_reg: vsnvs {
@@ -336,7 +345,7 @@
&ldb {
status = "okay";
- lvds-channel@1 {
+ lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <18>;
status = "okay";
@@ -369,6 +378,24 @@
};
};
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>; /* MX6_DIO0 */
+ status = "disabled";
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
&pwm4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm4>;
@@ -528,6 +555,24 @@
>;
};
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_pwm4: pwm4grp {
fsl,pins = <
MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
index 741f3d5..118bea5 100644
--- a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi
@@ -198,6 +198,18 @@
status = "okay";
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
&ssi1 {
status = "okay";
};
@@ -290,6 +302,18 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
index d1e5048..cca39f1 100644
--- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi
@@ -164,6 +164,18 @@
status = "okay";
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+ status = "disabled";
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+ status = "disabled";
+};
+
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
@@ -242,6 +254,18 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__PWM2_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
new file mode 100644
index 0000000..24d7d3f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2015 Boundary Devices, 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x20000000>;
+ };
+
+ 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 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_wlan_vmmc: regulator@3 {
+ compatible = "regulator-fixed";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wlan_vmmc>;
+ regulator-name = "reg_wlan_vmmc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+ };
+
+ bt_rfkill {
+ compatible = "rfkill-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bt_rfkill>;
+ gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
+ name = "bt_rfkill";
+ type = <2>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ home {
+ label = "Home";
+ gpios = <&gpio7 13 IRQ_TYPE_LEVEL_LOW>;
+ linux,code = <102>;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio4 5 IRQ_TYPE_LEVEL_LOW>;
+ linux,code = <158>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>;
+
+ j14-pin1 {
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+
+ j14-pin3 {
+ gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+
+ j14-pins8-9 {
+ gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+
+ j46-pin2 {
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+
+ j46-pin3 {
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+ };
+
+ 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_lvds0: backlight_lvds0 {
+ 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";
+ };
+
+ panel_lvds0 {
+ compatible = "hannstar,hsd100pxn1";
+ backlight = <&backlight_lvds0>;
+
+ port {
+ panel_in_lvds0: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6dl-nit6xlite-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6dl-nit6xlite-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";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "microchip,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 27 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";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_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";
+
+ touchscreen@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ rtc@6f {
+ compatible = "isil,isl1208";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rtc>;
+ reg = <0x6f>;
+ interrupts-extended = <&gpio2 26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_j10>;
+ pinctrl-1 = <&pinctrl_j28>;
+
+ imx6dl-nit6xlite {
+ 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_bt_rfkill: bt_rfkillgrp {
+ fsl,pins = <
+ /* BT wake */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ /* BT reset */
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x0b0b0
+ /* BT reg en */
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0
+ /* BT host wake irq */
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x100b0
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ 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 0x0f0b0
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0
+ MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
+ >;
+ };
+
+ pinctrl_gpio_keys: gpio_keysgrp {
+ fsl,pins = <
+ /* Home Button: J14 pin 5 */
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
+ /* Back Button: J14 pin 7 */
+ 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
+ /* Touch IRQ: J7 pin 4 */
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
+ /* tcs2004 IRQ */
+ MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1b0b0
+ /* tsc2004 reset */
+ MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x0b0b0
+ >;
+ };
+
+ pinctrl_j10: j10grp {
+ fsl,pins = <
+ /* Broadcom WiFi module pins */
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
+ MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x0b0b0
+ MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0
+ MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x000b0
+ >;
+ };
+
+ pinctrl_j28: j28grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
+ >;
+ };
+
+ pinctrl_leds: ledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x0b0b0
+ MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x0b0b0
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x030b0
+ MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x0b0b0
+ MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x0b0b0
+ >;
+ };
+
+ 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_wlan_vmmc: wlan_vmmcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x030b0
+ >;
+ };
+
+ pinctrl_rtc: rtcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x1b0b0
+ >;
+ };
+
+ pinctrl_sgtl5000: sgtl5000grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000b0
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b0
+ >;
+ };
+
+ 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_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_D31__UART3_RTS_B 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_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
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in_lvds0>;
+ };
+ };
+ };
+};
+
+&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";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&usbh1 {
+ 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 = <4>;
+ non-removable;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_wlan_vmmc>;
+ vqmmc-1-8-v;
+ ocr-limit = <0x180>; /* 1.65v - 2.1v */
+ cap-power-off-card;
+ keep-power-in-suspend;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
new file mode 100644
index 0000000..a35d54f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
@@ -0,0 +1,873 @@
+/*
+ * Copyright 2015 Boundary Devices, 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0xF0000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_1p8v: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_2p5v: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "2P5V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ 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_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;
+ };
+
+ reg_usb_h1_vbus: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_wlan_vmmc: regulator@5 {
+ compatible = "regulator-fixed";
+ reg = <5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wlan_vmmc>;
+ regulator-name = "reg_wlan_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
+
+ reg_can_xcvr: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ regulator-name = "CAN XCVR";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can_xcvr>;
+ gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ 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 = <&gpio7 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+
+ i2cmux@2 {
+ compatible = "i2c-mux-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2mux>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mux-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH
+ &gpio4 15 GPIO_ACTIVE_HIGH>;
+ i2c-parent = <&i2c2>;
+ idle-state = <0>;
+
+ i2c2@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c2@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ i2cmux@3 {
+ compatible = "i2c-mux-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3mux>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mux-gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+ i2c-parent = <&i2c3>;
+ idle-state = <0>;
+
+ i2c3@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ speaker-enable {
+ gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+ retain-state-suspended;
+ default-state = "off";
+ };
+
+ ttymxc4-rs232 {
+ gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>;
+ retain-state-suspended;
+ default-state = "on";
+ };
+ };
+
+ backlight_lcd: 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_lvds0: backlight_lvds0 {
+ 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";
+ };
+
+ backlight_lvds1: backlight_lvds1 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm2 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_3p3v>;
+ status = "okay";
+ };
+
+ lcd_display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_j15>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lcd_display_out: endpoint {
+ remote-endpoint = <&lcd_panel_in>;
+ };
+ };
+ };
+
+ panel_lcd {
+ compatible = "okaya,rs800480t-7x0gp";
+ backlight = <&backlight_lcd>;
+
+ port {
+ lcd_panel_in: endpoint {
+ remote-endpoint = <&lcd_display_out>;
+ };
+ };
+ };
+
+ panel_lvds0 {
+ compatible = "hannstar,hsd100pxn1";
+ backlight = <&backlight_lvds0>;
+
+ port {
+ panel_in_lvds0: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+
+ panel_lvds1 {
+ compatible = "hannstar,hsd100pxn1";
+ backlight = <&backlight_lvds1>;
+
+ port {
+ panel_in_lvds1: endpoint {
+ remote-endpoint = <&lvds1_out>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx6q-nitrogen6_max-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6q-nitrogen6_max-sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_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";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ xceiver-supply = <&reg_can_xcvr>;
+ status = "okay";
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+ <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
+&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 = "microchip,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio1 27 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>;
+ };
+
+ rtc: rtc@68 {
+ compatible = "st,rv4162";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rv4162>;
+ reg = <0x68>;
+ interrupts-extended = <&gpio4 6 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&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";
+
+ touchscreen@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&iomuxc {
+ imx6q-nitrogen6_max {
+ 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_can1: can1grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x1b0b0
+ MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b0b0
+ >;
+ };
+
+ pinctrl_can_xcvr: can-xcvrgrp {
+ fsl,pins = <
+ /* Flexcan XCVR enable */
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ 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 0x0f0b0
+ MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0
+ 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_SD3_DAT4__GPIO7_IO01 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_i2c2mux: i2c2muxgrp {
+ fsl,pins = <
+ /* ov5642 camera i2c enable */
+ MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x000b0
+ /* ov5640_mipi camera i2c enable */
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x000b0
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
+ >;
+ };
+
+ pinctrl_i2c3mux: i2c3muxgrp {
+ fsl,pins = <
+ /* PCIe I2C enable */
+ MX6QDL_PAD_EIM_OE__GPIO2_IO25 0x000b0
+ >;
+ };
+
+ pinctrl_j15: j15grp {
+ 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_pcie: pciegrp {
+ fsl,pins = <
+ /* PCIe reset */
+ MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x000b0
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD1_DAT2__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_rv4162: rv4162grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x1b0b0
+ >;
+ };
+
+ pinctrl_sgtl5000: sgtl5000grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000b0
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x1b0b0
+ >;
+ };
+
+ 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_uart5: uart5grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x130b1
+ MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x030b1
+ /* RS485 RX Enable: pull up */
+ MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x1b0b1
+ /* RS485 DEN: pull down */
+ MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x030b1
+ /* RS485/!RS232 Select: pull down (rs232) */
+ MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x030b1
+ /* ON: pull down */
+ MX6QDL_PAD_NANDF_ALE__GPIO6_IO08 0x030b1
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x0b0b0
+ >;
+ };
+
+ 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_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
+ MX6QDL_PAD_NANDF_CS1__SD3_VSELECT 0x100b0
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
+ >;
+ };
+
+ 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_wlan_vmmc: wlan_vmmcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x100b0
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x000b0
+ MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x000b0
+ >;
+ };
+ };
+};
+
+&ipu1_di0_disp0 {
+ remote-endpoint = <&lcd_display_in>;
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in_lvds0>;
+ };
+ };
+ };
+
+ lvds-channel@1 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds1_out: endpoint {
+ remote-endpoint = <&panel_in_lvds1>;
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie>;
+ reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>;
+ 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";
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart5>;
+ 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 = <4>;
+ non-removable;
+ vmmc-supply = <&reg_wlan_vmmc>;
+ cap-power-off-card;
+ keep-power-in-suspend;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ vmmc-supply = <&reg_1p8v>;
+ keep-power-in-suspend;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index 340bc8e..caeed56 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -3,12 +3,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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 <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
@@ -65,6 +95,19 @@
pinctrl-0 = <&pinctrl_can_xcvr>;
gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
};
+
+ reg_wlan_vmmc: regulator@4 {
+ compatible = "regulator-fixed";
+ reg = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wlan_vmmc>;
+ regulator-name = "reg_wlan_vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <70000>;
+ enable-active-high;
+ };
};
gpio-keys {
@@ -124,7 +167,7 @@
mux-ext-port = <3>;
};
- backlight_lcd {
+ backlight_lcd: backlight_lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -142,6 +185,43 @@
status = "okay";
};
+ lcd_display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_j15>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lcd_display_out: endpoint {
+ remote-endpoint = <&lcd_panel_in>;
+ };
+ };
+ };
+
+ lcd_panel {
+ compatible = "okaya,rs800480t-7x0gp";
+ backlight = <&backlight_lcd>;
+
+ port {
+ lcd_panel_in: endpoint {
+ remote-endpoint = <&lcd_display_out>;
+ };
+ };
+ };
+
panel {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds>;
@@ -182,7 +262,7 @@
status = "okay";
flash: m25p80@0 {
- compatible = "sst,sst25vf016b";
+ compatible = "sst,sst25vf016b", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
@@ -247,6 +327,21 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
+
+ touchscreen@04 {
+ compatible = "eeti,egalax_ts";
+ reg = <0x04>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ };
+
+ touchscreen@38 {
+ compatible = "edt,edt-ft5x06";
+ reg = <0x38>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ };
};
&iomuxc {
@@ -258,6 +353,7 @@
fsl,pins = <
/* SGTL5000 sys_mclk */
MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
+ MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0
>;
};
@@ -354,6 +450,39 @@
>;
};
+ pinctrl_j15: j15grp {
+ 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_pwm1: pwm1grp {
fsl,pins = <
MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
@@ -395,6 +524,18 @@
>;
};
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17071
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10071
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
+ >;
+ };
+
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -418,9 +559,22 @@
MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
>;
};
+
+ pinctrl_wlan_vmmc: wlan_vmmcgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x100b0
+ MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x000b0
+ MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x000b0
+ >;
+ };
};
};
+&ipu1_di0_disp0 {
+ remote-endpoint = <&lcd_display_in>;
+};
+
&ldb {
status = "okay";
@@ -489,6 +643,27 @@
status = "okay";
};
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ bus-width = <4>;
+ non-removable;
+ vmmc-supply = <&reg_wlan_vmmc>;
+ cap-power-off-card;
+ keep-power-in-suspend;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+ ref-clock-frequency = <38400000>;
+ };
+};
+
&usdhc3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc3>;
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
index 9e6ecd9..d6d98d4 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/gpio/gpio.h>
/ {
- model = "Phytec phyFLEX-i.MX6 Ouad";
+ model = "Phytec phyFLEX-i.MX6 Quad";
compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
memory {
@@ -80,7 +80,7 @@
cs-gpios = <&gpio4 24 0>;
flash@0 {
- compatible = "m25p80";
+ compatible = "m25p80", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
@@ -373,7 +373,7 @@
};
&pcie {
- pinctrl-name = "default";
+ pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
reset-gpio = <&gpio4 17 0>;
status = "disabled";
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index c37bb9ff..d354d40 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -113,14 +113,14 @@
&clks {
assigned-clocks = <&clks IMX6QDL_PLL4_BYPASS_SRC>,
<&clks IMX6QDL_PLL4_BYPASS>,
- <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
<&clks IMX6QDL_CLK_LDB_DI0_SEL>,
- <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+ <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
+ <&clks IMX6QDL_CLK_PLL4_POST_DIV>;
assigned-clock-parents = <&clks IMX6QDL_CLK_LVDS2_IN>,
<&clks IMX6QDL_PLL4_BYPASS_SRC>,
<&clks IMX6QDL_CLK_PLL3_USB_OTG>,
<&clks IMX6QDL_CLK_PLL3_USB_OTG>;
- assigned-clock-rates = <0>, <0>, <24576000>;
+ assigned-clock-rates = <0>, <0>, <0>, <0>, <24576000>;
};
&ecspi1 {
@@ -133,7 +133,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p32";
+ compatible = "st,m25p32", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index ce4c731..1a69a34 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -2,12 +2,42 @@
* 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:
+ * 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.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT 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 <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
@@ -123,7 +153,7 @@
mux-ext-port = <4>;
};
- backlight_lcd {
+ backlight_lcd: backlight_lcd {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -141,6 +171,43 @@
status = "okay";
};
+ lcd_display: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "bgr666";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_j15>;
+ status = "okay";
+
+ port@0 {
+ reg = <0>;
+
+ lcd_display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lcd_display_out: endpoint {
+ remote-endpoint = <&lcd_panel_in>;
+ };
+ };
+ };
+
+ lcd_panel {
+ compatible = "okaya,rs800480t-7x0gp";
+ backlight = <&backlight_lcd>;
+
+ port {
+ lcd_panel_in: endpoint {
+ remote-endpoint = <&lcd_display_out>;
+ };
+ };
+ };
+
panel {
compatible = "hannstar,hsd100pxn1";
backlight = <&backlight_lvds>;
@@ -181,7 +248,7 @@
status = "okay";
flash: m25p80@0 {
- compatible = "sst,sst25vf016b";
+ compatible = "sst,sst25vf016b", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
@@ -348,6 +415,39 @@
>;
};
+ pinctrl_j15: j15grp {
+ 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_pwm1: pwm1grp {
fsl,pins = <
MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
@@ -416,6 +516,10 @@
};
};
+&ipu1_di0_disp0 {
+ remote-endpoint = <&lcd_display_in>;
+};
+
&ldb {
status = "okay";
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 2c07d3a..a6d445c 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -158,7 +158,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p32";
+ compatible = "st,m25p32", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
index da08de3..13cb7cc 100644
--- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
@@ -11,6 +11,7 @@
#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>
/ {
@@ -272,7 +273,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_edt_ft5x06>;
interrupt-parent = <&gpio6>;
- interrupts = <15 0>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
linux,wakeup;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e716e6f..f74d3db 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -30,6 +30,7 @@
i2c0 = &i2c1;
i2c1 = &i2c2;
i2c2 = &i2c3;
+ ipu0 = &ipu1;
mmc0 = &usdhc1;
mmc1 = &usdhc2;
mmc2 = &usdhc3;
@@ -47,15 +48,6 @@
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>;
@@ -147,6 +139,27 @@
};
};
+ gpu_3d: gpu@00130000 {
+ compatible = "vivante,gc";
+ reg = <0x00130000 0x4000>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_GPU3D_AXI>,
+ <&clks IMX6QDL_CLK_GPU3D_CORE>,
+ <&clks IMX6QDL_CLK_GPU3D_SHADER>;
+ clock-names = "bus", "core", "shader";
+ power-domains = <&gpc 1>;
+ };
+
+ gpu_2d: gpu@00134000 {
+ compatible = "vivante,gc";
+ reg = <0x00134000 0x4000>;
+ interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6QDL_CLK_GPU2D_AXI>,
+ <&clks IMX6QDL_CLK_GPU2D_CORE>;
+ clock-names = "bus", "core";
+ power-domains = <&gpc 1>;
+ };
+
timer@00a00600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x00a00600 0x20>;
@@ -155,6 +168,15 @@
clocks = <&clks IMX6QDL_CLK_TWD>;
};
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ interrupt-parent = <&intc>;
+ };
+
L2: l2-cache@00a02000 {
compatible = "arm,pl310-cache";
reg = <0x00a02000 0x1000>;
@@ -173,8 +195,7 @@
#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 */
+ ranges = <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>;
@@ -218,16 +239,16 @@
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>;
+ clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>,
+ <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>,
+ <&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>,
+ <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
"rxtx3", "rxtx4",
"rxtx5", "rxtx6",
- "rxtx7";
+ "rxtx7", "spba";
status = "disabled";
};
@@ -309,7 +330,7 @@
<&clks IMX6QDL_CLK_ESAI_EXTAL>,
<&clks IMX6QDL_CLK_ESAI_IPG>,
<&clks IMX6QDL_CLK_SPBA>;
- clock-names = "core", "mem", "extal", "fsys", "dma";
+ clock-names = "core", "mem", "extal", "fsys", "spba";
dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
dma-names = "rx", "tx";
status = "disabled";
@@ -378,7 +399,7 @@
"asrck_1", "asrck_2", "asrck_3", "asrck_4",
"asrck_5", "asrck_6", "asrck_7", "asrck_8",
"asrck_9", "asrck_a", "asrck_b", "asrck_c",
- "asrck_d", "asrck_e", "asrck_f", "dma";
+ "asrck_d", "asrck_e", "asrck_f", "spba";
dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
<&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
dma-names = "rxa", "rxb", "rxc",
@@ -875,7 +896,6 @@
#size-cells = <1>;
reg = <0x2100000 0x10000>;
ranges = <0 0x2100000 0x10000>;
- interrupt-parent = <&intc>;
clocks = <&clks IMX6QDL_CLK_CAAM_MEM>,
<&clks IMX6QDL_CLK_CAAM_ACLK>,
<&clks IMX6QDL_CLK_CAAM_IPG>,
@@ -906,6 +926,9 @@
clocks = <&clks IMX6QDL_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -917,6 +940,9 @@
fsl,usbphy = <&usbphy2>;
fsl,usbmisc = <&usbmisc 1>;
dr_mode = "host";
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -927,6 +953,9 @@
clocks = <&clks IMX6QDL_CLK_USBOH3>;
fsl,usbmisc = <&usbmisc 2>;
dr_mode = "host";
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -937,6 +966,9 @@
clocks = <&clks IMX6QDL_CLK_USBOH3>;
fsl,usbmisc = <&usbmisc 3>;
dr_mode = "host";
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
index b84dff2..be11882 100644
--- a/arch/arm/boot/dts/imx6sl-evk.dts
+++ b/arch/arm/boot/dts/imx6sl-evk.dts
@@ -126,7 +126,7 @@
flash: m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p32";
+ compatible = "st,m25p32", "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 320a27f..d12b250 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -135,8 +135,24 @@
ranges;
spdif: spdif@02004000 {
+ compatible = "fsl,imx6sl-spdif",
+ "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 IMX6SL_CLK_SPDIF_GCLK>, <&clks IMX6SL_CLK_OSC>,
+ <&clks IMX6SL_CLK_SPDIF>, <&clks IMX6SL_CLK_DUMMY>,
+ <&clks IMX6SL_CLK_DUMMY>, <&clks IMX6SL_CLK_DUMMY>,
+ <&clks IMX6SL_CLK_IPG>, <&clks IMX6SL_CLK_DUMMY>,
+ <&clks IMX6SL_CLK_DUMMY>, <&clks IMX6SL_CLK_SPBA>;
+ clock-names = "core", "rxtx0",
+ "rxtx1", "rxtx2",
+ "rxtx3", "rxtx4",
+ "rxtx5", "rxtx6",
+ "rxtx7", "spba";
+ status = "disabled";
};
ecspi1: ecspi@02008000 {
@@ -670,8 +686,11 @@
};
dcp: dcp@020fc000 {
+ compatible = "fsl,imx6sl-dcp", "fsl,imx28-dcp";
reg = <0x020fc000 0x4000>;
- interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>,
+ <0 100 IRQ_TYPE_LEVEL_HIGH>,
+ <0 101 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -689,6 +708,9 @@
clocks = <&clks IMX6SL_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -699,6 +721,9 @@
clocks = <&clks IMX6SL_CLK_USBOH3>;
fsl,usbphy = <&usbphy2>;
fsl,usbmisc = <&usbmisc 1>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -709,6 +734,9 @@
clocks = <&clks IMX6SL_CLK_USBOH3>;
fsl,usbmisc = <&usbmisc 2>;
dr_mode = "host";
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva.dts b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
index c76b87c..7100547 100644
--- a/arch/arm/boot/dts/imx6sx-sdb-reva.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
@@ -129,7 +129,7 @@
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spansion,s25fl128s";
+ compatible = "spansion,s25fl128s", "jedec,spi-nor";
spi-max-frequency = <66000000>;
};
@@ -137,7 +137,7 @@
reg = <1>;
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spansion,s25fl128s";
+ compatible = "spansion,s25fl128s", "jedec,spi-nor";
spi-max-frequency = <66000000>;
};
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index 0bfc4e7..0ad164a 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -130,7 +130,7 @@
flash0: n25q256a@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q256a";
+ compatible = "micron,n25q256a", "jedec,spi-nor";
spi-max-frequency = <29000000>;
reg = <0>;
};
@@ -138,7 +138,7 @@
flash1: n25q256a@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q256a";
+ compatible = "micron,n25q256a", "jedec,spi-nor";
spi-max-frequency = <29000000>;
reg = <1>;
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi
index ac88c34..94ac400 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dtsi
+++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi
@@ -114,7 +114,7 @@
regulator-name = "peri_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+ gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-always-on;
};
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index c94f2ea..a5f7602 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -211,7 +211,7 @@
dmas = <&sdma 14 18 0>,
<&sdma 15 18 0>;
dma-names = "rx", "tx";
- clocks = <&clks IMX6SX_CLK_SPDIF>,
+ clocks = <&clks IMX6SX_CLK_SPDIF_GCLK>,
<&clks IMX6SX_CLK_OSC>,
<&clks IMX6SX_CLK_SPDIF>,
<&clks 0>, <&clks 0>, <&clks 0>,
@@ -222,7 +222,7 @@
"rxtx1", "rxtx2",
"rxtx3", "rxtx4",
"rxtx5", "rxtx6",
- "rxtx7", "dma";
+ "rxtx7", "spba";
status = "disabled";
};
@@ -295,7 +295,7 @@
<&clks IMX6SX_CLK_ESAI_IPG>,
<&clks IMX6SX_CLK_SPBA>;
clock-names = "core", "mem", "extal",
- "fsys", "dma";
+ "fsys", "spba";
status = "disabled";
};
@@ -348,7 +348,7 @@
<&clks IMX6SX_CLK_ASRC_IPG>,
<&clks IMX6SX_CLK_SPDIF>,
<&clks IMX6SX_CLK_SPBA>;
- clock-names = "mem", "ipg", "asrck", "dma";
+ clock-names = "mem", "ipg", "asrck", "spba";
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>;
@@ -783,6 +783,9 @@
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
fsl,anatop = <&anatop>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -793,6 +796,9 @@
clocks = <&clks IMX6SX_CLK_USBOH3>;
fsl,usbphy = <&usbphy2>;
fsl,usbmisc = <&usbmisc 1>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -805,6 +811,9 @@
phy_type = "hsic";
fsl,anatop = <&anatop>;
dr_mode = "host";
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -1152,6 +1161,8 @@
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_IPG>;
clock-names = "adc";
+ fsl,adck-max-frequency = <30000000>, <40000000>,
+ <20000000>;
status = "disabled";
};
@@ -1161,6 +1172,8 @@
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_IPG>;
clock-names = "adc";
+ fsl,adck-max-frequency = <30000000>, <40000000>,
+ <20000000>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index 25746b1..6aaa5ec 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -87,6 +87,19 @@
};
};
+&snvs_poweroff {
+ status = "okay";
+};
+
+&tsc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc>;
+ xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ measure-delay-time = <0xffff>;
+ pre-charge-time = <0xfff>;
+ status = "okay";
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
@@ -277,6 +290,15 @@
>;
};
+ pinctrl_tsc: tscgrp {
+ fsl,pins = <
+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 09edbed..99b6465 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -135,6 +135,11 @@
status = "disabled";
};
+ ocram: sram@00900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
+ };
+
aips1: aips-bus@02000000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
@@ -424,6 +429,14 @@
<GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
};
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x60>;
+ status = "disabled";
+ };
+
snvs_pwrkey: snvs-powerkey {
compatible = "fsl,sec-v4.0-pwrkey";
regmap = <&snvs>;
@@ -535,6 +548,9 @@
fsl,usbphy = <&usbphy1>;
fsl,usbmisc = <&usbmisc 0>;
fsl,anatop = <&anatop>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -545,6 +561,9 @@
clocks = <&clks IMX6UL_CLK_USBOH3>;
fsl,usbphy = <&usbphy2>;
fsl,usbmisc = <&usbmisc 1>;
+ ahb-burst-config = <0x0>;
+ tx-burst-size-dword = <0x10>;
+ rx-burst-size-dword = <0x10>;
status = "disabled";
};
@@ -571,6 +590,17 @@
status = "disabled";
};
+ tsc: tsc@02040000 {
+ compatible = "fsl,imx6ul-tsc";
+ reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_IPG>,
+ <&clks IMX6UL_CLK_ADC2>;
+ clock-names = "tsc", "adc";
+ status = "disabled";
+ };
+
usdhc1: usdhc@02190000 {
compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
reg = <0x02190000 0x4000>;
@@ -595,6 +625,18 @@
status = "disabled";
};
+ adc1: adc@02198000 {
+ compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_ADC1>;
+ num-channels = <2>;
+ clock-names = "adc";
+ fsl,adck-max-frequency = <30000000>, <40000000>,
+ <20000000>;
+ status = "disabled";
+ };
+
i2c1: i2c@021a0000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -625,6 +667,11 @@
status = "disabled";
};
+ mmdc: mmdc@021b0000 {
+ compatible = "fsl,imx6ul-mmdc", "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
qspi: qspi@021e0000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
new file mode 100644
index 0000000..4863451
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -0,0 +1,286 @@
+/*
+ * Support for CompuLab CL-SOM-iMX7 System-on-Module
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Ilya Ledvich <ilya@compulab.co.il>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "imx7d.dtsi"
+
+/ {
+ model = "CompuLab CL-SOM-iMX7";
+ compatible = "compulab,cl-som-imx7", "fsl,imx7d";
+
+ memory {
+ reg = <0x80000000 0x10000000>; /* 256 MB - minimal configuration */
+ };
+
+ reg_usb_otg1_vbus: regulator-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&cpu0 {
+ arm-supply = <&sw1a_reg>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic: pmic@8 {
+ compatible = "fsl,pfuze3000";
+ reg = <0x08>;
+
+ regulators {
+ sw1a_reg: sw1a {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ /* use sw1c_reg to align with pfuze100/pfuze200 */
+ sw1c_reg: sw1b {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1475000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <6250>;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3a_reg: sw3 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1650000>;
+ 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: vldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen2_reg: vldo2 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1550000>;
+ };
+
+ vgen3_reg: vccsd {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen4_reg: v33 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen5_reg: vldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vgen6_reg: vldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ pca9555: pca9555@20 {
+ compatible = "nxp,pca9555";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ fsl,tuning-step = <2>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x3
+ MX7D_PAD_SD2_WP__ENET1_MDC 0x3
+ MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1
+ MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1
+ MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1
+ MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1
+ MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1
+ MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1
+ MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1
+ MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1
+ MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1
+ MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1
+ MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1
+ MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x1
+ MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x1
+ MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x1
+ MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x1
+ MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x1
+ MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x1
+ MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x1
+ MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x1
+ MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x1
+ MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x1
+ MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x1
+ MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX7D_PAD_I2C2_SDA__I2C2_SDA 0x4000007f
+ MX7D_PAD_I2C2_SCL__I2C2_SCL 0x4000007f
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
+ MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO05__GPIO1_IO5 0x14 /* OTG PWREN */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX7D_PAD_SD3_CMD__SD3_CMD 0x59
+ MX7D_PAD_SD3_CLK__SD3_CLK 0x19
+ MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59
+ MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59
+ MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59
+ MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59
+ MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59
+ MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59
+ MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59
+ MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59
+ MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index a8d8149..eeda783 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -15,6 +15,122 @@
* <mux_reg conf_reg input_reg mux_mode input_val>
*/
+#define MX7D_PAD_GPIO1_IO00__GPIO1_IO0 0x0000 0x0030 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO00__PWM4_OUT 0x0000 0x0030 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_ANY 0x0000 0x0030 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x0000 0x0030 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB 0x0000 0x0030 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__GPIO1_IO1 0x0004 0x0034 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO01__PWM1_OUT 0x0004 0x0034 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO01__CCM_ENET_REF_CLK3 0x0004 0x0034 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO01__SAI1_MCLK 0x0004 0x0034 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO01__ANATOP_24M_OUT 0x0004 0x0034 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__OBSERVE0_OUT 0x0004 0x0034 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__GPIO1_IO2 0x0008 0x0038 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO02__PWM2_OUT 0x0008 0x0038 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_ENET_REF_CLK1 0x0008 0x0038 0x0564 0x2 0x3
+#define MX7D_PAD_GPIO1_IO02__SAI2_MCLK 0x0008 0x0038 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_CLKO1 0x0008 0x0038 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO02__OBSERVE1_OUT 0x0008 0x0038 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__USB_OTG1_ID 0x0008 0x0038 0x0734 0x7 0x3
+#define MX7D_PAD_GPIO1_IO03__GPIO1_IO3 0x000C 0x003C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO03__PWM3_OUT 0x000C 0x003C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_ENET_REF_CLK2 0x000C 0x003C 0x0570 0x2 0x3
+#define MX7D_PAD_GPIO1_IO03__SAI3_MCLK 0x000C 0x003C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_CLKO2 0x000C 0x003C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO03__OBSERVE2_OUT 0x000C 0x003C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO03__USB_OTG2_ID 0x000C 0x003C 0x0730 0x7 0x3
+#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4 0x0010 0x0040 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC 0x0010 0x0040 0x072C 0x1 0x1
+#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4 0x0010 0x0040 0x0594 0x2 0x1
+#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B 0x0010 0x0040 0x0710 0x3 0x4
+#define MX7D_PAD_GPIO1_IO04__I2C1_SCL 0x0010 0x0040 0x05D4 0x4 0x2
+#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT 0x0010 0x0040 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5 0x0014 0x0044 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR 0x0014 0x0044 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5 0x0014 0x0044 0x0598 0x2 0x1
+#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B 0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__I2C1_SDA 0x0014 0x0044 0x05D8 0x4 0x2
+#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT 0x0014 0x0044 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6 0x0018 0x0048 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC 0x0018 0x0048 0x0728 0x1 0x1
+#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6 0x0018 0x0048 0x059C 0x2 0x1
+#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA 0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__I2C2_SCL 0x0018 0x0048 0x05DC 0x4 0x2
+#define MX7D_PAD_GPIO1_IO06__CCM_WAIT 0x0018 0x0048 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO06__KPP_ROW4 0x0018 0x0048 0x0624 0x6 0x1
+#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x001C 0x004C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR 0x001C 0x004C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7 0x001C 0x004C 0x05A0 0x2 0x1
+#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA 0x001C 0x004C 0x0714 0x3 0x5
+#define MX7D_PAD_GPIO1_IO07__I2C2_SDA 0x001C 0x004C 0x05E0 0x4 0x2
+#define MX7D_PAD_GPIO1_IO07__CCM_STOP 0x001C 0x004C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO07__KPP_COL4 0x001C 0x004C 0x0604 0x6 0x1
+#define MX7D_PAD_GPIO1_IO08__GPIO1_IO8 0x0014 0x026C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO08__SD1_VSELECT 0x0014 0x026C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x0014 0x026C 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DCE_RX 0x0014 0x026C 0x0704 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DTE_TX 0x0014 0x026C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__I2C3_SCL 0x0014 0x026C 0x05E4 0x4 0x0
+#define MX7D_PAD_GPIO1_IO08__KPP_COL5 0x0014 0x026C 0x0608 0x6 0x0
+#define MX7D_PAD_GPIO1_IO08__PWM1_OUT 0x0014 0x026C 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x0018 0x0270 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO09__SD1_LCTL 0x0018 0x0270 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_ENET_REF_CLK3 0x0018 0x0270 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DCE_TX 0x0018 0x0270 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DTE_RX 0x0018 0x0270 0x0704 0x3 0x1
+#define MX7D_PAD_GPIO1_IO09__I2C3_SDA 0x0018 0x0270 0x05E8 0x4 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_PMIC_READY 0x0018 0x0270 0x04F4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO09__KPP_ROW5 0x0018 0x0270 0x0628 0x6 0x0
+#define MX7D_PAD_GPIO1_IO09__PWM2_OUT 0x0018 0x0270 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x001C 0x0274 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO10__SD2_LCTL 0x001C 0x0274 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x001C 0x0274 0x0568 0x2 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DCE_RTS 0x001C 0x0274 0x0700 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DTE_CTS 0x001C 0x0274 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__I2C4_SCL 0x001C 0x0274 0x05EC 0x4 0x0
+#define MX7D_PAD_GPIO1_IO10__FLEXTIMER1_PHA 0x001C 0x0274 0x05A4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO10__KPP_COL6 0x001C 0x0274 0x060C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO10__PWM3_OUT 0x001C 0x0274 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO11__GPIO1_IO11 0x0020 0x0278 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO11__SD3_LCTL 0x0020 0x0278 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x0020 0x0278 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DCE_CTS 0x0020 0x0278 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DTE_RTS 0x0020 0x0278 0x0700 0x3 0x1
+#define MX7D_PAD_GPIO1_IO11__I2C4_SDA 0x0020 0x0278 0x05F0 0x4 0x0
+#define MX7D_PAD_GPIO1_IO11__FLEXTIMER1_PHB 0x0020 0x0278 0x05A8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO11__KPP_ROW6 0x0020 0x0278 0x062C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO11__PWM4_OUT 0x0020 0x0278 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x0024 0x027C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO12__SD2_VSELECT 0x0024 0x027C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1 0x0024 0x027C 0x0564 0x2 0x0
+#define MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX 0x0024 0x027C 0x04DC 0x3 0x0
+#define MX7D_PAD_GPIO1_IO12__CM4_NMI 0x0024 0x027C 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_EXT_CLK1 0x0024 0x027C 0x04E4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO12__SNVS_VIO_5 0x0024 0x027C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO12__USB_OTG1_ID 0x0024 0x027C 0x0734 0x7 0x0
+#define MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x0028 0x0280 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO13__SD3_VSELECT 0x0028 0x0280 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_ENET_REF_CLK2 0x0028 0x0280 0x0570 0x2 0x0
+#define MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX 0x0028 0x0280 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_PMIC_READY 0x0028 0x0280 0x04F4 0x4 0x1
+#define MX7D_PAD_GPIO1_IO13__CCM_EXT_CLK2 0x0028 0x0280 0x04E8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO13__SNVS_VIO_5_CTL 0x0028 0x0280 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO13__USB_OTG2_ID 0x0028 0x0280 0x0730 0x7 0x0
+#define MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x002C 0x0284 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO14__SD3_CD_B 0x002C 0x0284 0x0738 0x1 0x0
+#define MX7D_PAD_GPIO1_IO14__ENET2_MDIO 0x002C 0x0284 0x0574 0x2 0x0
+#define MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x002C 0x0284 0x04E0 0x3 0x0
+#define MX7D_PAD_GPIO1_IO14__WDOG3_WDOG_B 0x002C 0x0284 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO14__CCM_EXT_CLK3 0x002C 0x0284 0x04EC 0x5 0x0
+#define MX7D_PAD_GPIO1_IO14__SDMA_EXT_EVENT0 0x002C 0x0284 0x06D8 0x6 0x0
+#define MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x0030 0x0288 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO15__SD3_WP 0x0030 0x0288 0x073C 0x1 0x0
+#define MX7D_PAD_GPIO1_IO15__ENET2_MDC 0x0030 0x0288 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x0030 0x0288 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO15__WDOG4_WDOG_B 0x0030 0x0288 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO15__CCM_EXT_CLK4 0x0030 0x0288 0x04F0 0x5 0x0
+#define MX7D_PAD_GPIO1_IO15__SDMA_EXT_EVENT1 0x0030 0x0288 0x06DC 0x6 0x0
#define MX7D_PAD_EPDC_DATA00__EPDC_DATA0 0x0034 0x02A4 0x0000 0x0 0x0
#define MX7D_PAD_EPDC_DATA00__SIM1_PORT2_TRXD 0x0034 0x02A4 0x0000 0x1 0x0
#define MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 0x0034 0x02A4 0x0000 0x2 0x0
@@ -453,7 +569,7 @@
#define MX7D_PAD_LCD_DATA23__EIM_ADDR26 0x0124 0x0394 0x0000 0x4 0x0
#define MX7D_PAD_LCD_DATA23__GPIO3_IO28 0x0124 0x0394 0x0000 0x5 0x0
#define MX7D_PAD_LCD_DATA23__I2C4_SDA 0x0124 0x0394 0x05F0 0x6 0x1
-#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x0128 0x0398 0x0000 0x0 0x0
+#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x0128 0x0398 0x06F4 0x0 0x0
#define MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX 0x0128 0x0398 0x0000 0x0 0x0
#define MX7D_PAD_UART1_RX_DATA__I2C1_SCL 0x0128 0x0398 0x05D4 0x1 0x0
#define MX7D_PAD_UART1_RX_DATA__CCM_PMIC_READY 0x0128 0x0398 0x0000 0x2 0x0
@@ -469,7 +585,7 @@
#define MX7D_PAD_UART1_TX_DATA__ENET2_1588_EVENT0_OUT 0x012C 0x039C 0x0000 0x4 0x0
#define MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 0x012C 0x039C 0x0000 0x5 0x0
#define MX7D_PAD_UART1_TX_DATA__ENET1_MDC 0x012C 0x039C 0x0000 0x6 0x0
-#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0130 0x03A0 0x0000 0x0 0x0
+#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0130 0x03A0 0x06FC 0x0 0x2
#define MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX 0x0130 0x03A0 0x0000 0x0 0x0
#define MX7D_PAD_UART2_RX_DATA__I2C2_SCL 0x0130 0x03A0 0x05DC 0x1 0x0
#define MX7D_PAD_UART2_RX_DATA__SAI3_RX_BCLK 0x0130 0x03A0 0x0000 0x2 0x0
@@ -501,7 +617,7 @@
#define MX7D_PAD_UART3_TX_DATA__ENET1_1588_EVENT0_OUT 0x013C 0x03AC 0x0000 0x4 0x0
#define MX7D_PAD_UART3_TX_DATA__GPIO4_IO5 0x013C 0x03AC 0x0000 0x5 0x0
#define MX7D_PAD_UART3_TX_DATA__SD2_LCTL 0x013C 0x03AC 0x0000 0x6 0x0
-#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x0140 0x03B0 0x0000 0x0 0x0
+#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x0140 0x03B0 0x0700 0x0 0x2
#define MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS 0x0140 0x03B0 0x0000 0x0 0x0
#define MX7D_PAD_UART3_RTS_B__USB_OTG2_OC 0x0140 0x03B0 0x0728 0x1 0x0
#define MX7D_PAD_UART3_RTS_B__SAI3_TX_DATA0 0x0140 0x03B0 0x0000 0x2 0x0
diff --git a/arch/arm/boot/dts/imx7d-sbc-imx7.dts b/arch/arm/boot/dts/imx7d-sbc-imx7.dts
new file mode 100644
index 0000000..d63c597
--- /dev/null
+++ b/arch/arm/boot/dts/imx7d-sbc-imx7.dts
@@ -0,0 +1,42 @@
+/*
+ * Support for CompuLab SBC-iMX7 Single Board Computer
+ *
+ * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Author: Ilya Ledvich <ilya@compulab.co.il>
+ *
+ * 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.
+ */
+
+#include "imx7d-cl-som-imx7.dts"
+
+/ {
+ model = "CompuLab SBC-iMX7";
+ compatible = "compulab,sbc-imx7", "compulab,cl-som-imx7", "fsl,imx7d";
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ enable-sdio-wakeup;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX7D_PAD_SD1_CMD__SD1_CMD 0x59
+ MX7D_PAD_SD1_CLK__SD1_CLK 0x19
+ MX7D_PAD_SD1_DATA0__SD1_DATA0 0x59
+ MX7D_PAD_SD1_DATA1__SD1_DATA1 0x59
+ MX7D_PAD_SD1_DATA2__SD1_DATA2 0x59
+ MX7D_PAD_SD1_DATA3__SD1_DATA3 0x59
+ MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59 /* CD */
+ MX7D_PAD_SD1_WP__GPIO5_IO1 0x59 /* WP */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index fdd1d7c..b2c4536 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -97,10 +97,59 @@
};
};
+&adc1 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
+&adc2 {
+ vref-supply = <&reg_vref_1v8>;
+ status = "okay";
+};
+
&cpu0 {
arm-supply = <&sw1a_reg>;
};
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1>;
+ assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2>;
+ assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+ assigned-clock-rates = <0>, <100000000>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ fsl,magic-packet;
+ status = "okay";
+};
+
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
@@ -231,6 +280,17 @@
status = "okay";
};
+&usbotg1 {
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ dr_mode = "host";
+ status = "okay";
+};
+
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;
@@ -241,11 +301,60 @@
status = "okay";
};
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ fsl,tuning-step = <2>;
+ non-removable;
+ status = "okay";
+};
+
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
imx7d-sdb {
+ pinctrl_enet1: enet1grp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x3
+ MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x3
+ MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1
+ MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1
+ MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1
+ MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1
+ MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1
+ MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1
+ MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1
+ MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1
+ MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1
+ MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1
+ MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1
+ MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1
+ >;
+ };
+
+ pinctrl_enet2: enet2grp {
+ fsl,pins = <
+ MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x1
+ MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x1
+ MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x1
+ MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x1
+ MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x1
+ MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x1
+ MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x1
+ MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x1
+ MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x1
+ MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x1
+ MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x1
+ MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x1
+ >;
+ };
+
pinctrl_hog: hoggrp {
fsl,pins = <
MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14
@@ -281,7 +390,6 @@
>;
};
-
pinctrl_uart1: uart1grp {
fsl,pins = <
MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index 6e444bb..25ad309 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -85,9 +85,7 @@
792000 975000
>;
clock-latency = <61036>; /* two CLK32 periods */
- clocks = <&clks IMX7D_ARM_A7_ROOT_CLK>, <&clks IMX7D_ARM_A7_ROOT_SRC>,
- <&clks IMX7D_PLL_ARM_MAIN_CLK>, <&clks IMX7D_PLL_SYS_MAIN_CLK>;
- clock-names = "arm", "arm_root_src", "pll_arm", "pll_sys_main";
+ clocks = <&clks IMX7D_CLK_ARM>;
};
cpu1: cpu@1 {
@@ -446,6 +444,12 @@
status = "disabled";
};
+ iomuxc_lpsr: iomuxc-lpsr@302c0000 {
+ compatible = "fsl,imx7d-iomuxc-lpsr";
+ reg = <0x302c0000 0x10000>;
+ fsl,input-sel = <&iomuxc>;
+ };
+
gpt1: gpt@302d0000 {
compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
reg = <0x302d0000 0x10000>;
@@ -570,6 +574,76 @@
};
};
+ aips2: aips-bus@30400000 {
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x30400000 0x400000>;
+ ranges;
+
+ adc1: adc@30610000 {
+ compatible = "fsl,imx7d-adc";
+ reg = <0x30610000 0x10000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_ADC_ROOT_CLK>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ adc2: adc@30620000 {
+ compatible = "fsl,imx7d-adc";
+ reg = <0x30620000 0x10000>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_ADC_ROOT_CLK>;
+ clock-names = "adc";
+ status = "disabled";
+ };
+
+ pwm1: pwm@30660000 {
+ compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
+ reg = <0x30660000 0x10000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
+ <&clks IMX7D_PWM1_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@30670000 {
+ compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
+ reg = <0x30670000 0x10000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
+ <&clks IMX7D_PWM2_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@30680000 {
+ compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
+ reg = <0x30680000 0x10000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
+ <&clks IMX7D_PWM3_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+
+ pwm4: pwm@30690000 {
+ compatible = "fsl,imx7d-pwm", "fsl,imx27-pwm";
+ reg = <0x30690000 0x10000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
+ <&clks IMX7D_PWM4_ROOT_CLK>;
+ clock-names = "ipg", "per";
+ #pwm-cells = <2>;
+ status = "disabled";
+ };
+ };
+
aips3: aips-bus@30800000 {
compatible = "fsl,aips-bus", "simple-bus";
#address-cells = <1>;
@@ -694,6 +768,77 @@
status = "disabled";
};
+ usbotg1: usb@30b10000 {
+ compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x30b10000 0x200>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_USB_CTRL_CLK>;
+ fsl,usbphy = <&usbphynop1>;
+ fsl,usbmisc = <&usbmisc1 0>;
+ phy-clkgate-delay-us = <400>;
+ status = "disabled";
+ };
+
+ usbotg2: usb@30b20000 {
+ compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x30b20000 0x200>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_USB_CTRL_CLK>;
+ fsl,usbphy = <&usbphynop2>;
+ fsl,usbmisc = <&usbmisc2 0>;
+ phy-clkgate-delay-us = <400>;
+ status = "disabled";
+ };
+
+ usbh: usb@30b30000 {
+ compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
+ reg = <0x30b30000 0x200>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_USB_CTRL_CLK>;
+ fsl,usbphy = <&usbphynop3>;
+ fsl,usbmisc = <&usbmisc3 0>;
+ phy_type = "hsic";
+ dr_mode = "host";
+ phy-clkgate-delay-us = <400>;
+ status = "disabled";
+ };
+
+ usbmisc1: usbmisc@30b10200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x30b10200 0x200>;
+ };
+
+ usbmisc2: usbmisc@30b20200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x30b20200 0x200>;
+ };
+
+ usbmisc3: usbmisc@30b30200 {
+ #index-cells = <1>;
+ compatible = "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc";
+ reg = <0x30b30200 0x200>;
+ };
+
+ usbphynop1: usbphynop1 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX7D_USB_PHY1_CLK>;
+ clock-names = "main_clk";
+ };
+
+ usbphynop2: usbphynop2 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX7D_USB_PHY2_CLK>;
+ clock-names = "main_clk";
+ };
+
+ usbphynop3: usbphynop3 {
+ compatible = "usb-nop-xceiv";
+ clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>;
+ clock-names = "main_clk";
+ };
+
usdhc1: usdhc@30b40000 {
compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
reg = <0x30b40000 0x10000>;
@@ -729,6 +874,42 @@
bus-width = <4>;
status = "disabled";
};
+
+ fec1: ethernet@30be0000 {
+ compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+ reg = <0x30be0000 0x10000>;
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ <&clks IMX7D_ENET1_TIME_ROOT_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+ <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ status = "disabled";
+ };
+
+ fec2: ethernet@30bf0000 {
+ compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+ reg = <0x30bf0000 0x10000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ <&clks IMX7D_ENET2_TIME_ROOT_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+ <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+ clock-names = "ipg", "ahb", "ptp",
+ "enet_clk_ref", "enet_out";
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
+ status = "disabled";
+ };
};
};
};
diff --git a/arch/arm/boot/dts/k2e-evm.dts b/arch/arm/boot/dts/k2e-evm.dts
index 50c83c2..b7e9980 100644
--- a/arch/arm/boot/dts/k2e-evm.dts
+++ b/arch/arm/boot/dts/k2e-evm.dts
@@ -13,7 +13,7 @@
#include "k2e.dtsi"
/ {
- compatible = "ti,k2e-evm","ti,keystone";
+ compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone";
model = "Texas Instruments Keystone 2 Edison EVM";
soc {
diff --git a/arch/arm/boot/dts/k2e-netcp.dtsi b/arch/arm/boot/dts/k2e-netcp.dtsi
index b13b3c9..ac990f6 100644
--- a/arch/arm/boot/dts/k2e-netcp.dtsi
+++ b/arch/arm/boot/dts/k2e-netcp.dtsi
@@ -72,7 +72,17 @@ qmss: qmss@2a40000 {
qalloc-by-id;
};
};
+ accumulator {
+ acc-low-0 {
+ qrange = <480 32>;
+ accumulator = <0 47 16 2 50>;
+ interrupts = <0 226 0xf01>;
+ multi-queue;
+ qalloc-by-id;
+ };
+ };
};
+
descriptor-regions {
#address-cells = <1>;
#size-cells = <1>;
@@ -83,6 +93,19 @@ qmss: qmss@2a40000 {
link-index = <0x4000>;
};
};
+
+ pdsps {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ pdsp0@0x2a10000 {
+ reg = <0x2a10000 0x1000 /*iram */
+ 0x2a0f000 0x100 /*reg*/
+ 0x2a0c000 0x3c8 /*intd */
+ 0x2a20000 0x4000>; /*cmd*/
+ id = <0>;
+ };
+ };
}; /* qmss */
knav_dmas: knav_dmas@0 {
diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
index 675fb8e..1097dad 100644
--- a/arch/arm/boot/dts/k2e.dtsi
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -9,6 +9,9 @@
*/
/ {
+ compatible = "ti,k2e", "ti,keystone";
+ model = "Texas Instruments Keystone 2 Edison SoC";
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/k2hk-evm.dts b/arch/arm/boot/dts/k2hk-evm.dts
index 660ebf5..8161bf5 100644
--- a/arch/arm/boot/dts/k2hk-evm.dts
+++ b/arch/arm/boot/dts/k2hk-evm.dts
@@ -13,7 +13,7 @@
#include "k2hk.dtsi"
/ {
- compatible = "ti,k2hk-evm","ti,keystone";
+ compatible = "ti,k2hk-evm", "ti,k2hk", "ti,keystone";
model = "Texas Instruments Keystone 2 Kepler/Hawking EVM";
soc {
diff --git a/arch/arm/boot/dts/k2hk-netcp.dtsi b/arch/arm/boot/dts/k2hk-netcp.dtsi
index 77a32c3..f86d6dd 100644
--- a/arch/arm/boot/dts/k2hk-netcp.dtsi
+++ b/arch/arm/boot/dts/k2hk-netcp.dtsi
@@ -47,6 +47,7 @@ qmss: qmss@2a40000 {
"region", "push", "pop";
};
};
+
queue-pools {
qpend {
qpend-0 {
@@ -88,7 +89,17 @@ qmss: qmss@2a40000 {
qalloc-by-id;
};
};
+ accumulator {
+ acc-low-0 {
+ qrange = <480 32>;
+ accumulator = <0 47 16 2 50>;
+ interrupts = <0 226 0xf01>;
+ multi-queue;
+ qalloc-by-id;
+ };
+ };
};
+
descriptor-regions {
#address-cells = <1>;
#size-cells = <1>;
@@ -99,6 +110,19 @@ qmss: qmss@2a40000 {
link-index = <0x4000>;
};
};
+
+ pdsps {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ pdsp0@0x2a10000 {
+ reg = <0x2a10000 0x1000 /*iram */
+ 0x2a0f000 0x100 /*reg*/
+ 0x2a0c000 0x3c8 /*intd */
+ 0x2a20000 0x4000>; /*cmd*/
+ id = <0>;
+ };
+ };
}; /* qmss */
knav_dmas: knav_dmas@0 {
diff --git a/arch/arm/boot/dts/k2hk.dtsi b/arch/arm/boot/dts/k2hk.dtsi
index d0810a5..ada4c7a 100644
--- a/arch/arm/boot/dts/k2hk.dtsi
+++ b/arch/arm/boot/dts/k2hk.dtsi
@@ -9,6 +9,9 @@
*/
/ {
+ compatible = "ti,k2hk", "ti,keystone";
+ model = "Texas Instruments Keystone 2 Kepler/Hawking SoC";
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/k2l-evm.dts b/arch/arm/boot/dts/k2l-evm.dts
index 9a69a6b..0086124 100644
--- a/arch/arm/boot/dts/k2l-evm.dts
+++ b/arch/arm/boot/dts/k2l-evm.dts
@@ -13,7 +13,7 @@
#include "k2l.dtsi"
/ {
- compatible = "ti,k2l-evm","ti,keystone";
+ compatible = "ti,k2l-evm", "ti,k2l", "ti,keystone";
model = "Texas Instruments Keystone 2 Lamarr EVM";
soc {
diff --git a/arch/arm/boot/dts/k2l-netcp.dtsi b/arch/arm/boot/dts/k2l-netcp.dtsi
index 6b95284..5acbd0d 100644
--- a/arch/arm/boot/dts/k2l-netcp.dtsi
+++ b/arch/arm/boot/dts/k2l-netcp.dtsi
@@ -72,7 +72,16 @@ qmss: qmss@2a40000 {
qalloc-by-id;
};
};
+ accumulator {
+ acc-low-0 {
+ qrange = <480 32>;
+ accumulator = <0 47 16 2 50>;
+ interrupts = <0 226 0xf01>;
+ multi-queue;
+ };
+ };
};
+
descriptor-regions {
#address-cells = <1>;
#size-cells = <1>;
@@ -83,6 +92,20 @@ qmss: qmss@2a40000 {
link-index = <0x4000>;
};
};
+
+ pdsps {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ pdsp0@0x2a10000 {
+ reg = <0x2a10000 0x1000 /*iram */
+ 0x2a0f000 0x100 /*reg*/
+ 0x2a0c000 0x3c8 /*intd */
+ 0x2a20000 0x4000>; /*cmd*/
+ id = <0>;
+ };
+ };
+
}; /* qmss */
knav_dmas: knav_dmas@0 {
@@ -114,7 +137,7 @@ netcp: netcp@26000000 {
/* NetCP address range */
ranges = <0 0x26000000 0x1000000>;
- clocks = <&papllclk>, <&clkcpgmac>, <&chipclk12>;
+ clocks = <&clkosr>, <&papllclk>, <&clkcpgmac>, <&chipclk12>;
dma-coherent;
ti,navigator-dmas = <&dma_gbe 0>,
diff --git a/arch/arm/boot/dts/k2l.dtsi b/arch/arm/boot/dts/k2l.dtsi
index 49fd414..4446da7 100644
--- a/arch/arm/boot/dts/k2l.dtsi
+++ b/arch/arm/boot/dts/k2l.dtsi
@@ -9,6 +9,9 @@
*/
/ {
+ compatible = "ti,k2l", "ti,keystone";
+ model = "Texas Instruments Keystone 2 Lamarr SoC";
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 72816d6..3f27282 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -12,6 +12,7 @@
#include "skeleton.dtsi"
/ {
+ compatible = "ti,keystone";
model = "Texas Instruments Keystone 2 SoC";
#address-cells = <2>;
#size-cells = <2>;
@@ -136,7 +137,7 @@
};
spi0: spi@21000400 {
- compatible = "ti,dm6441-spi";
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
reg = <0x21000400 0x200>;
num-cs = <4>;
ti,davinci-spi-intr-line = <0>;
@@ -147,7 +148,7 @@
};
spi1: spi@21000600 {
- compatible = "ti,dm6441-spi";
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
reg = <0x21000600 0x200>;
num-cs = <4>;
ti,davinci-spi-intr-line = <0>;
@@ -158,7 +159,7 @@
};
spi2: spi@21000800 {
- compatible = "ti,dm6441-spi";
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
reg = <0x21000800 0x200>;
num-cs = <4>;
ti,davinci-spi-intr-line = <0>;
diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts
index bf4143c..b84af3d 100644
--- a/arch/arm/boot/dts/kirkwood-ds112.dts
+++ b/arch/arm/boot/dts/kirkwood-ds112.dts
@@ -14,7 +14,7 @@
#include "kirkwood-synology.dtsi"
/ {
- model = "Synology DS111";
+ model = "Synology DS112";
compatible = "synology,ds111", "marvell,kirkwood";
memory {
diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-lswvl.dts
index 09eed3c..36eec73 100644
--- a/arch/arm/boot/dts/kirkwood-lswvl.dts
+++ b/arch/arm/boot/dts/kirkwood-lswvl.dts
@@ -1,7 +1,8 @@
/*
* Device Tree file for Buffalo Linkstation LS-WVL/VL
*
- * Copyright (C) 2015, rogershimizu@gmail.com
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -156,21 +157,21 @@
button@1 {
label = "Function Button";
linux,code = <KEY_OPTION>;
- gpios = <&gpio0 45 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Power-on Switch";
linux,code = <KEY_RESERVED>;
linux,input-type = <5>;
- gpios = <&gpio0 46 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Power-auto Switch";
linux,code = <KEY_ESC>;
linux,input-type = <5>;
- gpios = <&gpio0 47 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
};
@@ -185,38 +186,38 @@
led@1 {
label = "lswvl:red:alarm";
- gpios = <&gpio0 36 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
led@2 {
label = "lswvl:red:func";
- gpios = <&gpio0 37 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
};
led@3 {
label = "lswvl:amber:info";
- gpios = <&gpio0 38 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
led@4 {
label = "lswvl:blue:func";
- gpios = <&gpio0 39 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
};
led@5 {
label = "lswvl:blue:power";
- gpios = <&gpio0 40 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
led@6 {
label = "lswvl:red:hdderr0";
- gpios = <&gpio0 34 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
};
led@7 {
label = "lswvl:red:hdderr1";
- gpios = <&gpio0 35 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
};
};
@@ -233,7 +234,7 @@
3250 1
5000 0>;
- alarm-gpios = <&gpio0 43 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
};
restart_poweroff {
diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-lswxl.dts
index f5db16a..b13ec20 100644
--- a/arch/arm/boot/dts/kirkwood-lswxl.dts
+++ b/arch/arm/boot/dts/kirkwood-lswxl.dts
@@ -1,7 +1,8 @@
/*
* Device Tree file for Buffalo Linkstation LS-WXL/WSXL
*
- * Copyright (C) 2015, rogershimizu@gmail.com
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -156,21 +157,21 @@
button@1 {
label = "Function Button";
linux,code = <KEY_OPTION>;
- gpios = <&gpio1 41 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Power-on Switch";
linux,code = <KEY_RESERVED>;
linux,input-type = <5>;
- gpios = <&gpio1 42 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
button@3 {
label = "Power-auto Switch";
linux,code = <KEY_ESC>;
linux,input-type = <5>;
- gpios = <&gpio1 43 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
};
@@ -185,12 +186,12 @@
led@1 {
label = "lswxl:blue:func";
- gpios = <&gpio1 36 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
led@2 {
label = "lswxl:red:alarm";
- gpios = <&gpio1 49 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
led@3 {
@@ -200,23 +201,23 @@
led@4 {
label = "lswxl:blue:power";
- gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ default-state = "keep";
};
led@5 {
label = "lswxl:red:func";
- gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
- default-state = "keep";
+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
};
led@6 {
label = "lswxl:red:hdderr0";
- gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
};
led@7 {
label = "lswxl:red:hdderr1";
- gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
};
@@ -225,15 +226,15 @@
pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
pinctrl-names = "default";
- gpios = <&gpio0 47 GPIO_ACTIVE_LOW
- &gpio0 48 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW
+ &gpio1 15 GPIO_ACTIVE_LOW>;
gpio-fan,speed-map = <0 3
1500 2
3250 1
5000 0>;
- alarm-gpios = <&gpio1 49 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
};
restart_poweroff {
@@ -256,7 +257,7 @@
enable-active-high;
regulator-always-on;
regulator-boot-on;
- gpio = <&gpio0 37 GPIO_ACTIVE_HIGH>;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
};
hdd_power0: regulator@2 {
compatible = "regulator-fixed";
diff --git a/arch/arm/boot/dts/kirkwood-net5big.dts b/arch/arm/boot/dts/kirkwood-net5big.dts
index 36155b7..d2d44df 100644
--- a/arch/arm/boot/dts/kirkwood-net5big.dts
+++ b/arch/arm/boot/dts/kirkwood-net5big.dts
@@ -86,6 +86,66 @@
clock-frequency = <32768>;
};
};
+
+ netxbig-leds {
+ blue-sata2 {
+ label = "netxbig:blue:sata2";
+ mode-addr = <5>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 7
+ NETXBIG_LED_SATA 1
+ NETXBIG_LED_TIMER1 3>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ red-sata2 {
+ label = "netxbig:red:sata2";
+ mode-addr = <5>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ blue-sata3 {
+ label = "netxbig:blue:sata3";
+ mode-addr = <6>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 7
+ NETXBIG_LED_SATA 1
+ NETXBIG_LED_TIMER1 3>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ red-sata3 {
+ label = "netxbig:red:sata3";
+ mode-addr = <6>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ blue-sata4 {
+ label = "netxbig:blue:sata4";
+ mode-addr = <7>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 7
+ NETXBIG_LED_SATA 1
+ NETXBIG_LED_TIMER1 3>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ red-sata4 {
+ label = "netxbig:red:sata4";
+ mode-addr = <7>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ };
};
&mdio {
diff --git a/arch/arm/boot/dts/kirkwood-netxbig.dtsi b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
index 1508b121..62515a8 100644
--- a/arch/arm/boot/dts/kirkwood-netxbig.dtsi
+++ b/arch/arm/boot/dts/kirkwood-netxbig.dtsi
@@ -13,6 +13,7 @@
* warranty of any kind, whether express or implied.
*/
+#include <dt-bindings/leds/leds-netxbig.h>
#include "kirkwood.dtsi"
#include "kirkwood-6281.dtsi"
@@ -105,6 +106,85 @@
gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
};
};
+
+ netxbig_gpio_ext: netxbig-gpio-ext {
+ compatible = "lacie,netxbig-gpio-ext";
+
+ addr-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH
+ &gpio1 16 GPIO_ACTIVE_HIGH
+ &gpio1 17 GPIO_ACTIVE_HIGH>;
+ data-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH
+ &gpio1 13 GPIO_ACTIVE_HIGH
+ &gpio1 14 GPIO_ACTIVE_HIGH>;
+ enable-gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+
+ netxbig-leds {
+ compatible = "lacie,netxbig-leds";
+
+ gpio-ext = <&netxbig_gpio_ext>;
+
+ timers = <NETXBIG_LED_TIMER1 500 500
+ NETXBIG_LED_TIMER2 500 1000>;
+
+ blue-power {
+ label = "netxbig:blue:power";
+ mode-addr = <0>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 1
+ NETXBIG_LED_TIMER1 3
+ NETXBIG_LED_TIMER2 7>;
+ bright-addr = <1>;
+ max-brightness = <7>;
+ };
+ red-power {
+ label = "netxbig:red:power";
+ mode-addr = <0>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <1>;
+ max-brightness = <7>;
+ };
+ blue-sata0 {
+ label = "netxbig:blue:sata0";
+ mode-addr = <3>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 7
+ NETXBIG_LED_SATA 1
+ NETXBIG_LED_TIMER1 3>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ red-sata0 {
+ label = "netxbig:red:sata0";
+ mode-addr = <3>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ blue-sata1 {
+ label = "netxbig:blue:sata1";
+ mode-addr = <4>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 7
+ NETXBIG_LED_SATA 1
+ NETXBIG_LED_TIMER1 3>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ red-sata1 {
+ label = "netxbig:red:sata1";
+ mode-addr = <4>;
+ mode-val = <NETXBIG_LED_OFF 0
+ NETXBIG_LED_ON 2
+ NETXBIG_LED_TIMER1 4>;
+ bright-addr = <2>;
+ max-brightness = <7>;
+ };
+ };
};
&mdio {
diff --git a/arch/arm/boot/dts/kirkwood-nsa325.dts b/arch/arm/boot/dts/kirkwood-nsa325.dts
new file mode 100644
index 0000000..bc4ec93
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-nsa325.dts
@@ -0,0 +1,238 @@
+/* Device tree file for the Zyxel NSA 325 NAS box.
+ *
+ * Copyright (c) 2015, Hans Ulli Kroll <ulli.kroll@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.
+ *
+ * Based upon the board setup file created by Peter Schildmann
+ */
+
+/dts-v1/;
+
+#include "kirkwood-nsa3x0-common.dtsi"
+
+/ {
+ model = "ZyXEL NSA325";
+ compatible = "zyxel,nsa325", "marvell,kirkwood-88f6282", "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";
+
+ 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";
+ };
+
+ pmx_pwr_sata1: pmx-pwr-sata1 {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+ };
+
+ /* This board uses the pcf8563 RTC instead of the SoC RTC */
+ rtc@10300 {
+ status = "disabled";
+ };
+
+ i2c@11000 {
+ status = "okay";
+
+ pcf8563: pcf8563@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_pwr_sata1>;
+ pinctrl-names = "default";
+
+ usb0_power: regulator@1 {
+ enable-active-high;
+ };
+
+ sata1_power: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&gpio1 15 GPIO_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 = "nsa325:green:sys";
+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+ };
+ orange-sys {
+ label = "nsa325:orange:sys";
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd1 {
+ label = "nsa325:green:hdd1";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd1 {
+ label = "nsa325:red:hdd1";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ };
+ green-hdd2 {
+ label = "nsa325:green:hdd2";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ };
+ red-hdd2 {
+ label = "nsa325:red:hdd2";
+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+ };
+ green-usb {
+ label = "nsa325:green:usb";
+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
+ };
+ green-copy {
+ label = "nsa325:green:copy";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+ red-copy {
+ label = "nsa325: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-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
new file mode 100644
index 0000000..8082d64
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
@@ -0,0 +1,179 @@
+/*
+ * kirkwood-pogoplug-series-4.dts - Device tree file for PogoPlug Series 4
+ * inspired by the board files made by Kevin Mihelich for ArchLinux,
+ * and their DTS file.
+ *
+ * Copyright (C) 2015 Linus Walleij <linus.walleij@linaro.org>
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+#include <dt-bindings/input/linux-event-codes.h>
+
+/ {
+ model = "Cloud Engines PogoPlug Series 4";
+ compatible = "cloudengines,pogoplugv4", "marvell,kirkwood-88f6192",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>;
+ };
+
+ chosen {
+ stdout-path = "uart0:115200n8";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_button_eject>;
+ pinctrl-names = "default";
+
+ button@1 {
+ debounce_interval = <50>;
+ wakeup-source;
+ linux,code = <KEY_EJECTCD>;
+ label = "Eject Button";
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_green &pmx_led_red>;
+ pinctrl-names = "default";
+
+ health {
+ label = "pogoplugv4:green:health";
+ gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+ fault {
+ label = "pogoplugv4:red:fault";
+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&pinctrl {
+ pmx_sata0: pmx-sata0 {
+ marvell,pins = "mpp21";
+ marvell,function = "sata0";
+ };
+
+ pmx_sata1: pmx-sata1 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata1";
+ };
+
+ pmx_sdio_cd: pmx-sdio-cd {
+ marvell,pins = "mpp27";
+ marvell,function = "gpio";
+ };
+
+ pmx_sdio_wp: pmx-sdio-wp {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_eject: pmx-button-eject {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_green: pmx-led-green {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_red: pmx-led-red {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+/*
+ * This PCIE controller has a USB 3.0 XHCI controller at 1,0
+ */
+&pciec {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+ pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+ pinctrl-names = "default";
+ nr-ports = <1>;
+};
+
+&sdio {
+ status = "okay";
+ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>;
+ pinctrl-names = "default";
+ cd-gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+};
+
+&nand {
+ /* 128 MiB of NAND flash */
+ chip-delay = <40>;
+ status = "okay";
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x200000>;
+ read-only;
+ };
+
+ partition@200000 {
+ label = "uImage";
+ reg = <0x00200000 0x300000>;
+ };
+
+ partition@500000 {
+ label = "uImage2";
+ reg = <0x00500000 0x300000>;
+ };
+
+ partition@800000 {
+ label = "failsafe";
+ reg = <0x00800000 0x800000>;
+ };
+
+ partition@1000000 {
+ label = "root";
+ reg = <0x01000000 0x7000000>;
+ };
+ };
+};
+
+&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.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi
index c56ab6b..0e46560 100644
--- a/arch/arm/boot/dts/kirkwood-ts219.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi
@@ -40,7 +40,7 @@
};
poweroff@12100 {
compatible = "qnap,power-off";
- reg = <0x12000 0x100>;
+ reg = <0x12100 0x100>;
clocks = <&gate_clk 7>;
};
spi@10600 {
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 464f09a..7b5a4a1 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -40,16 +40,6 @@
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>;
@@ -65,6 +55,14 @@
pinctrl-names = "default";
status = "disabled";
};
+
+ crypto_sram: sa-sram@0301 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x03, 0x01) 0x0 0x800>;
+ clocks = <&gate_clk 17>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
};
ocp@f1000000 {
@@ -252,6 +250,17 @@
status = "okay";
};
+ cesa: crypto@30000 {
+ compatible = "marvell,kirkwood-crypto";
+ reg = <0x30000 0x10000>;
+ reg-names = "regs";
+ interrupts = <22>;
+ clocks = <&gate_clk 17>;
+ marvell,crypto-srams = <&crypto_sram>;
+ marvell,crypto-sram-size = <0x800>;
+ status = "okay";
+ };
+
usb0: ehci@50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x1000>;
diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 5b04300..fb13f18 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -23,31 +23,37 @@
label = "sysboot2";
gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* gpio2 */
linux,code = <BTN_0>;
- gpio-key,wakeup;
+ wakeup-source;
};
sysboot5 {
label = "sysboot5";
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; /* gpio7 */
linux,code = <BTN_1>;
- gpio-key,wakeup;
+ wakeup-source;
};
gpio1 {
label = "gpio1";
gpios = <&gpio6 21 GPIO_ACTIVE_LOW>; /* gpio181 */
linux,code = <BTN_2>;
- gpio-key,wakeup;
+ wakeup-source;
};
gpio2 {
label = "gpio2";
gpios = <&gpio6 18 GPIO_ACTIVE_LOW>; /* gpio178 */
linux,code = <BTN_3>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3logic";
+ ti,mcbsp = <&mcbsp2>;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -67,6 +73,20 @@
};
};
+&vaux1 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+&vaux4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&mcbsp2 {
+ status = "okay";
+};
+
&charger {
ti,bb-uvolt = <3200000>;
ti,bb-uamp = <150>;
@@ -84,6 +104,70 @@
};
};
+&vpll2 {
+ regulator-always-on;
+};
+
+&dss {
+ status = "ok";
+ vdds_dsi-supply = <&vpll2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_dpi_pins1>;
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&lcd_in>;
+ data-lines = <16>;
+ };
+ };
+};
+
+/ {
+ aliases {
+ display0 = &lcd0;
+ };
+
+ lcd0: display@0 {
+ compatible = "panel-dpi";
+ label = "15";
+ status = "okay";
+ /* default-on; */
+ pinctrl-names = "default";
+ enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */
+
+ 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 = <3>;
+ vfront-porch = <4>;
+ vsync-len = <11>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ bl: backlight {
+ compatible = "gpio-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&backlight_pins>;
+
+ gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>, /* gpio_56 */
+ <&gpio5 26 GPIO_ACTIVE_HIGH>; /* gpio_154 */
+ default-on;
+ };
+};
+
&mmc1 {
interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
pinctrl-names = "default";
@@ -119,6 +203,48 @@
OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
>;
};
+
+ tsc2004_pins: pinmux_tsc2004_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE4) /* mcbsp4_dr.gpio_153 */
+ >;
+ };
+
+ backlight_pins: pinmux_backlight_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs5.gpio_56 */
+ OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE4) /* mcbsp4_dx.gpio_154 */
+ >;
+ };
+
+ dss_dpi_pins1: pinmux_dss_dpi_pins1 {
+ 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_wkup {
@@ -142,6 +268,27 @@
};
};
+&i2c3 {
+ touchscreen: tsc2004@48 {
+ compatible = "ti,tsc2004";
+ reg = <0x48>;
+ vio-supply = <&vaux1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsc2004_pins>;
+ interrupts-extended = <&gpio5 25 IRQ_TYPE_EDGE_RISING>; /* gpio 153 */
+
+ 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>;
+ };
+};
+
&uart1 {
interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
};
diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
index 36387b1..0080532 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
@@ -96,9 +96,22 @@
reg = <0x48>;
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
interrupt-parent = <&intc>;
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
};
};
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
/*
* Only found on the wireless SOM. For the SOM without wireless, the pins for
* MMC3 can be routed with jumpers to the second MMC slot on the devkit and
@@ -122,6 +135,7 @@
interrupt-parent = <&gpio5>;
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
ref-clock-frequency = <26000000>;
+ tcxo-clock-frequency = <26000000>;
};
};
@@ -136,6 +150,29 @@
OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_fsr.gpio_157 */
>;
};
+ 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 */
+ >;
+ };
+ 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_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* GPIO_162,BT_EN */
+ >;
+ };
+};
+
+&uart2 {
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
};
&omap3_pmx_core2 {
diff --git a/arch/arm/boot/dts/lpc18xx.dtsi b/arch/arm/boot/dts/lpc18xx.dtsi
index 2c569a6..053a1f5 100644
--- a/arch/arm/boot/dts/lpc18xx.dtsi
+++ b/arch/arm/boot/dts/lpc18xx.dtsi
@@ -68,6 +68,46 @@
};
soc {
+ sct_pwm: pwm@40000000 {
+ compatible = "nxp,lpc1850-sct-pwm";
+ reg = <0x40000000 0x1000>;
+ clocks =<&ccu1 CLK_CPU_SCT>;
+ clock-names = "pwm";
+ resets = <&rgu 37>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ dmac: dma-controller@40002000 {
+ compatible = "arm,pl080", "arm,primecell";
+ arm,primecell-periphid = <0x00041080>;
+ reg = <0x40002000 0x1000>;
+ interrupts = <2>;
+ clocks = <&ccu1 CLK_CPU_DMA>;
+ clock-names = "apb_pclk";
+ resets = <&rgu 19>;
+ #dma-cells = <2>;
+ dma-channels = <8>;
+ dma-requests = <16>;
+ lli-bus-interface-ahb1;
+ lli-bus-interface-ahb2;
+ mem-bus-interface-ahb1;
+ mem-bus-interface-ahb2;
+ memcpy-burst-size = <256>;
+ memcpy-bus-width = <32>;
+ };
+
+ spifi: flash-controller@40003000 {
+ compatible = "nxp,lpc1773-spifi";
+ reg = <0x40003000 0x1000>, <0x14000000 0x4000000>;
+ reg-names = "spifi", "flash";
+ interrupts = <30>;
+ clocks = <&ccu1 CLK_SPIFI>, <&ccu1 CLK_CPU_SPIFI>;
+ clock-names = "spifi", "reg";
+ resets = <&rgu 53>;
+ status = "disabled";
+ };
+
mmcsd: mmcsd@40004000 {
compatible = "snps,dw-mshc";
reg = <0x40004000 0x1000>;
@@ -75,6 +115,7 @@
num-slots = <1>;
clocks = <&ccu2 CLK_SDIO>, <&ccu1 CLK_CPU_SDIO>;
clock-names = "ciu", "biu";
+ resets = <&rgu 20>;
status = "disabled";
};
@@ -83,6 +124,7 @@
reg = <0x40006100 0x100>;
interrupts = <8>;
clocks = <&ccu1 CLK_CPU_USB0>;
+ resets = <&rgu 17>;
phys = <&usb0_otg_phy>;
phy-names = "usb";
has-transaction-translator;
@@ -94,6 +136,7 @@
reg = <0x40007100 0x100>;
interrupts = <9>;
clocks = <&ccu1 CLK_CPU_USB1>;
+ resets = <&rgu 18>;
status = "disabled";
};
@@ -102,6 +145,7 @@
reg = <0x40005000 0x1000>;
clocks = <&ccu1 CLK_CPU_EMCDIV>, <&ccu1 CLK_CPU_EMC>;
clock-names = "mpmcclk", "apb_pclk";
+ resets = <&rgu 21>;
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0x1c000000 0x1000000
@@ -118,6 +162,18 @@
interrupt-names = "combined";
clocks = <&cgu BASE_LCD_CLK>, <&ccu1 CLK_CPU_LCD>;
clock-names = "clcdclk", "apb_pclk";
+ resets = <&rgu 16>;
+ status = "disabled";
+ };
+
+ eeprom: eeprom@4000e000 {
+ compatible = "nxp,lpc1857-eeprom";
+ reg = <0x4000e000 0x1000>, <0x20040000 0x4000>;
+ reg-names = "reg", "mem";
+ clocks = <&ccu1 CLK_CPU_EEPROM>;
+ clock-names = "eeprom";
+ resets = <&rgu 27>;
+ interrupts = <4>;
status = "disabled";
};
@@ -128,6 +184,8 @@
interrupt-names = "macirq";
clocks = <&ccu1 CLK_CPU_ETHERNET>;
clock-names = "stmmaceth";
+ resets = <&rgu 22>;
+ reset-names = "stmmaceth";
status = "disabled";
};
@@ -135,12 +193,20 @@
compatible = "nxp,lpc1850-creg", "syscon", "simple-mfd";
reg = <0x40043000 0x1000>;
clocks = <&ccu1 CLK_CPU_CREG>;
+ resets = <&rgu 5>;
usb0_otg_phy: phy@004 {
compatible = "nxp,lpc1850-usb-otg-phy";
clocks = <&ccu1 CLK_USB0>;
#phy-cells = <0>;
};
+
+ dmamux: dma-mux@11c {
+ compatible = "nxp,lpc1850-dmamux";
+ #dma-cells = <3>;
+ dma-requests = <64>;
+ dma-masters = <&dmac>;
+ };
};
cgu: clock-controller@40050000 {
@@ -178,6 +244,22 @@
"base_ssp0_clk", "base_sdio_clk";
};
+ rgu: reset-controller@40053000 {
+ compatible = "nxp,lpc1850-rgu";
+ reg = <0x40053000 0x1000>;
+ clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>;
+ clock-names = "delay", "reg";
+ #reset-cells = <1>;
+ };
+
+ watchdog@40080000 {
+ compatible = "nxp,lpc1850-wwdt";
+ reg = <0x40080000 0x24>;
+ interrupts = <49>;
+ clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_WWDT>;
+ clock-names = "wdtclk", "reg";
+ };
+
uart0: serial@40081000 {
compatible = "nxp,lpc1850-uart", "ns16550a";
reg = <0x40081000 0x1000>;
@@ -185,6 +267,12 @@
interrupts = <24>;
clocks = <&ccu2 CLK_APB0_UART0>, <&ccu1 CLK_CPU_UART0>;
clock-names = "uartclk", "reg";
+ resets = <&rgu 44>;
+ dmas = <&dmamux 1 1 2
+ &dmamux 2 1 2
+ &dmamux 11 2 2
+ &dmamux 12 2 2>;
+ dma-names = "tx", "rx", "tx", "rx";
status = "disabled";
};
@@ -195,6 +283,10 @@
interrupts = <25>;
clocks = <&ccu2 CLK_APB0_UART1>, <&ccu1 CLK_CPU_UART1>;
clock-names = "uartclk", "reg";
+ resets = <&rgu 45>;
+ dmas = <&dmamux 3 1 2
+ &dmamux 4 1 2>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -204,6 +296,10 @@
interrupts = <22>;
clocks = <&ccu2 CLK_APB0_SSP0>, <&ccu1 CLK_CPU_SSP0>;
clock-names = "sspclk", "apb_pclk";
+ resets = <&rgu 50>;
+ dmas = <&dmamux 9 0 2
+ &dmamux 10 0 2>;
+ dma-names = "rx", "tx";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -215,6 +311,7 @@
interrupts = <12>;
clocks = <&ccu1 CLK_CPU_TIMER0>;
clock-names = "timerclk";
+ resets = <&rgu 32>;
};
timer1: timer@40085000 {
@@ -223,6 +320,7 @@
interrupts = <13>;
clocks = <&ccu1 CLK_CPU_TIMER1>;
clock-names = "timerclk";
+ resets = <&rgu 33>;
};
pinctrl: pinctrl@40086000 {
@@ -231,11 +329,23 @@
clocks = <&ccu1 CLK_CPU_SCU>;
};
+ i2c0: i2c@400a1000 {
+ compatible = "nxp,lpc1788-i2c";
+ reg = <0x400a1000 0x1000>;
+ interrupts = <18>;
+ clocks = <&ccu1 CLK_APB1_I2C0>;
+ resets = <&rgu 48>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
can1: can@400a4000 {
compatible = "bosch,c_can";
reg = <0x400a4000 0x1000>;
interrupts = <43>;
clocks = <&ccu1 CLK_APB1_CAN1>;
+ resets = <&rgu 54>;
status = "disabled";
};
@@ -246,6 +356,10 @@
interrupts = <26>;
clocks = <&ccu2 CLK_APB2_UART2>, <&ccu1 CLK_CPU_UART2>;
clock-names = "uartclk", "reg";
+ resets = <&rgu 46>;
+ dmas = <&dmamux 5 1 2
+ &dmamux 6 1 2>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -256,6 +370,12 @@
interrupts = <27>;
clocks = <&ccu2 CLK_APB2_UART3>, <&ccu1 CLK_CPU_UART3>;
clock-names = "uartclk", "reg";
+ resets = <&rgu 47>;
+ dmas = <&dmamux 7 1 2
+ &dmamux 8 1 2
+ &dmamux 13 3 2
+ &dmamux 14 3 2>;
+ dma-names = "tx", "rx", "rx", "tx";
status = "disabled";
};
@@ -265,6 +385,7 @@
interrupts = <14>;
clocks = <&ccu1 CLK_CPU_TIMER2>;
clock-names = "timerclk";
+ resets = <&rgu 34>;
};
timer3: timer@400c4000 {
@@ -273,6 +394,7 @@
interrupts = <15>;
clocks = <&ccu1 CLK_CPU_TIMER3>;
clock-names = "timerclk";
+ resets = <&rgu 35>;
};
ssp1: spi@400c5000 {
@@ -281,6 +403,28 @@
interrupts = <23>;
clocks = <&ccu2 CLK_APB2_SSP1>, <&ccu1 CLK_CPU_SSP1>;
clock-names = "sspclk", "apb_pclk";
+ resets = <&rgu 51>;
+ dmas = <&dmamux 11 2 2
+ &dmamux 12 2 2
+ &dmamux 3 3 2
+ &dmamux 4 3 2
+ &dmamux 5 2 2
+ &dmamux 6 2 2
+ &dmamux 13 2 2
+ &dmamux 14 2 2>;
+ dma-names = "rx", "tx", "tx", "rx",
+ "tx", "rx", "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@400e0000 {
+ compatible = "nxp,lpc1788-i2c";
+ reg = <0x400e0000 0x1000>;
+ interrupts = <19>;
+ clocks = <&ccu1 CLK_APB3_I2C1>;
+ resets = <&rgu 49>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -291,6 +435,7 @@
reg = <0x400e2000 0x1000>;
interrupts = <51>;
clocks = <&ccu1 CLK_APB3_CAN0>;
+ resets = <&rgu 55>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 3abebb7..c85cf97 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -11,19 +11,20 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
/ {
compatible = "nxp,lpc3220";
interrupt-parent = <&mic>;
cpus {
- #address-cells = <0>;
+ #address-cells = <1>;
#size-cells = <0>;
- cpu {
+ cpu@0 {
compatible = "arm,arm926ej-s";
device_type = "cpu";
+ reg = <0x0>;
};
};
@@ -31,7 +32,8 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
- ranges = <0x20000000 0x20000000 0x30000000>;
+ ranges = <0x20000000 0x20000000 0x30000000>,
+ <0xe0000000 0xe0000000 0x04000000>;
/*
* Enable either SLC or MLC
@@ -49,30 +51,46 @@
status = "disabled";
};
- dma@31000000 {
+ dma: 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";
- };
+ usb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x0 0x31020000 0x00001000>;
- usbd@31020000 {
- compatible = "nxp,lpc3220-udc";
- reg = <0x31020000 0x300>;
- interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
- status = "disabled";
+ /*
+ * Enable either ohci or usbd (gadget)!
+ */
+ ohci: ohci@0 {
+ compatible = "nxp,ohci-nxp", "usb-ohci";
+ reg = <0x0 0x300>;
+ interrupts = <0x3b 0>;
+ status = "disabled";
+ };
+
+ usbd: usbd@0 {
+ compatible = "nxp,lpc3220-udc";
+ reg = <0x0 0x300>;
+ interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+ status = "disabled";
+ };
+
+ i2cusb: i2c@300 {
+ compatible = "nxp,pnx-i2c";
+ reg = <0x300 0x100>;
+ interrupts = <0x3f 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pnx,timeout = <0x64>;
+ };
};
- clcd@31040000 {
+ clcd: clcd@31040000 {
compatible = "arm,pl110", "arm,primecell";
reg = <0x31040000 0x1000>;
interrupts = <0x0e 0>;
@@ -85,6 +103,19 @@
interrupts = <0x1d 0>;
};
+ emc: memory-controller@31080000 {
+ compatible = "arm,pl175", "arm,primecell";
+ reg = <0x31080000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0 0xe0000000 0x01000000>,
+ <1 0xe1000000 0x01000000>,
+ <2 0xe2000000 0x01000000>,
+ <3 0xe3000000 0x01000000>;
+ status = "disabled";
+ };
+
apb {
#address-cells = <1>;
#size-cells = <1>;
@@ -118,7 +149,7 @@
reg = <0x20094000 0x1000>;
};
- sd@20098000 {
+ sd: sd@20098000 {
compatible = "arm,pl18x", "arm,primecell";
reg = <0x20098000 0x1000>;
interrupts = <0x0f 0>, <0x0d 0>;
@@ -192,15 +223,6 @@
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 {
@@ -243,7 +265,7 @@
status = "disabled";
};
- rtc@40024000 {
+ rtc: rtc@40024000 {
compatible = "nxp,lpc3220-rtc";
reg = <0x40024000 0x1000>;
interrupts = <0x34 0>;
@@ -256,11 +278,31 @@
#gpio-cells = <3>; /* bank, pin, flags */
};
- watchdog@4003C000 {
+ timer4: timer@4002C000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x4002C000 0x1000>;
+ interrupts = <0x3 0>;
+ status = "disabled";
+ };
+
+ timer5: timer@40030000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x40030000 0x1000>;
+ interrupts = <0x4 0>;
+ status = "disabled";
+ };
+
+ watchdog: watchdog@4003C000 {
compatible = "nxp,pnx4008-wdt";
reg = <0x4003C000 0x1000>;
};
+ timer0: timer@40044000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x40044000 0x1000>;
+ interrupts = <0x10 0>;
+ };
+
/*
* TSC vs. ADC: Since those two share the same
* hardware, you need to choose from one of the
@@ -268,30 +310,56 @@
* them
*/
- adc@40048000 {
+ adc: adc@40048000 {
compatible = "nxp,lpc3220-adc";
reg = <0x40048000 0x1000>;
interrupts = <0x27 0>;
status = "disabled";
};
- tsc@40048000 {
+ tsc: tsc@40048000 {
compatible = "nxp,lpc3220-tsc";
reg = <0x40048000 0x1000>;
interrupts = <0x27 0>;
status = "disabled";
};
- key@40050000 {
+ timer1: timer@4004C000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x4004C000 0x1000>;
+ interrupts = <0x11 0>;
+ };
+
+ key: key@40050000 {
compatible = "nxp,lpc3220-key";
reg = <0x40050000 0x1000>;
interrupts = <54 0>;
status = "disabled";
};
- pwm: pwm@4005C000 {
+ timer2: timer@40058000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x40058000 0x1000>;
+ interrupts = <0x12 0>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@4005C000 {
compatible = "nxp,lpc3220-pwm";
- reg = <0x4005C000 0x8>;
+ reg = <0x4005C000 0x4>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@4005C004 {
+ compatible = "nxp,lpc3220-pwm";
+ reg = <0x4005C004 0x4>;
+ status = "disabled";
+ };
+
+ timer3: timer@40060000 {
+ compatible = "nxp,lpc3220-timer";
+ reg = <0x40060000 0x1000>;
+ interrupts = <0x13 0>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/lpc4337-ciaa.dts b/arch/arm/boot/dts/lpc4337-ciaa.dts
index 5f500c1..5cfadb0 100644
--- a/arch/arm/boot/dts/lpc4337-ciaa.dts
+++ b/arch/arm/boot/dts/lpc4337-ciaa.dts
@@ -99,6 +99,14 @@
};
};
+ i2c0_pins: i2c0-pins {
+ i2c0_pins_cfg {
+ pins = "i2c0_scl", "i2c0_sda";
+ function = "i2c0";
+ input-enable;
+ };
+ };
+
ssp_pins: ssp-pins {
ssp1_cs {
pins = "p6_7";
@@ -159,6 +167,28 @@
clock-frequency = <50000000>;
};
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+
+ eeprom@50 {
+ compatible = "microchip,24c512";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "microchip,24c02";
+ reg = <0x51>;
+ };
+
+ eeprom@54 {
+ compatible = "microchip,24c512";
+ reg = <0x54>;
+ };
+};
+
&mac {
status = "okay";
phy-mode = "rmii";
@@ -166,6 +196,10 @@
pinctrl-0 = <&enet_rmii_pins>;
};
+&sct_pwm {
+ status = "okay";
+};
+
&ssp1 {
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/lpc4350-hitex-eval.dts b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
index 32bc7ff..022d495 100644
--- a/arch/arm/boot/dts/lpc4350-hitex-eval.dts
+++ b/arch/arm/boot/dts/lpc4350-hitex-eval.dts
@@ -15,6 +15,9 @@
#include "lpc18xx.dtsi"
#include "lpc4350.dtsi"
+#include "dt-bindings/input/input.h"
+#include "dt-bindings/gpio/gpio.h"
+
/ {
model = "Hitex LPC4350 Evaluation Board";
compatible = "hitex,lpc4350-eval-board", "nxp,lpc4350";
@@ -34,6 +37,88 @@
device_type = "memory";
reg = <0x28000000 0x800000>; /* 8 MB */
};
+
+ pca_buttons {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <100>;
+ autorepeat;
+
+ button@0 {
+ label = "joy:right";
+ linux,code = <KEY_RIGHT>;
+ gpios = <&pca_gpio 8 GPIO_ACTIVE_LOW>;
+ };
+
+ button@1 {
+ label = "joy:up";
+ linux,code = <KEY_UP>;
+ gpios = <&pca_gpio 9 GPIO_ACTIVE_LOW>;
+ };
+
+
+ button@2 {
+ label = "joy:enter";
+ linux,code = <KEY_ENTER>;
+ gpios = <&pca_gpio 10 GPIO_ACTIVE_LOW>;
+ };
+
+ button@3 {
+ label = "joy:left";
+ linux,code = <KEY_LEFT>;
+ gpios = <&pca_gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ button@4 {
+ label = "joy:down";
+ linux,code = <KEY_DOWN>;
+ gpios = <&pca_gpio 12 GPIO_ACTIVE_LOW>;
+ };
+
+ button@5 {
+ label = "user:sw3";
+ linux,code = <KEY_F1>;
+ gpios = <&pca_gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ button@6 {
+ label = "user:sw4";
+ linux,code = <KEY_F2>;
+ gpios = <&pca_gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ button@7 {
+ label = "user:sw5";
+ linux,code = <KEY_F3>;
+ gpios = <&pca_gpio 15 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ pca_leds {
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "ext:led0";
+ gpios = <&pca_gpio 0 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led1 {
+ label = "ext:led1";
+ gpios = <&pca_gpio 1 GPIO_ACTIVE_LOW>;
+ };
+
+ led2 {
+ label = "ext:led2";
+ gpios = <&pca_gpio 2 GPIO_ACTIVE_LOW>;
+ };
+
+ led3 {
+ label = "ext:led3";
+ gpios = <&pca_gpio 3 GPIO_ACTIVE_LOW>;
+ };
+ };
};
&pinctrl {
@@ -186,6 +271,43 @@
};
};
+ i2c0_pins: i2c0-pins {
+ i2c0_pins_cfg {
+ pins = "i2c0_scl", "i2c0_sda";
+ function = "i2c0";
+ input-enable;
+ };
+ };
+
+ spifi_pins: spifi-pins {
+ spifi_clk_cfg {
+ pins = "p3_3";
+ function = "spifi";
+ slew-rate = <1>;
+ bias-disable;
+ input-enable;
+ input-schmitt-disable;
+ };
+
+ spifi_mosi_miso_sio2_3_cfg {
+ pins = "p3_7", "p3_6", "p3_5", "p3_4";
+ function = "spifi";
+ slew-rate = <1>;
+ bias-disable;
+ input-enable;
+ input-schmitt-disable;
+ };
+
+ spifi_cs_cfg {
+ pins = "p3_8";
+ function = "spifi";
+ slew-rate = <1>;
+ bias-disable;
+ input-enable;
+ input-schmitt-disable;
+ };
+ };
+
uart0_pins: uart0-pins {
uart0_rx_cfg {
pins = "pf_11";
@@ -271,6 +393,31 @@
clock-frequency = <25000000>;
};
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+
+ /* NXP SE97BTP with temperature sensor + eeprom */
+ sensor@18 {
+ compatible = "nxp,jc42";
+ reg = <0x18>;
+ };
+
+ eeprom@50 {
+ compatible = "nxp,24c02";
+ reg = <0x50>;
+ };
+
+ pca_gpio: gpio@24 {
+ compatible = "nxp,pca9673";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
&mac {
status = "okay";
phy-mode = "mii";
@@ -278,6 +425,34 @@
pinctrl-0 = <&enet_mii_pins>;
};
+&spifi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spifi_pins>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0x000000 0x040000>; /* 256 KiB */
+ };
+
+ partition@1 {
+ label = "kernel";
+ reg = <0x040000 0x2c0000>; /* 2.75 MiB */
+ };
+
+ partition@2 {
+ label = "rootfs";
+ reg = <0x300000 0x500000>; /* 5 MiB */
+ };
+ };
+};
+
&uart0 {
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
index 5f7bdad..079d3cf 100644
--- a/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
+++ b/arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
@@ -332,6 +332,14 @@
};
};
+ i2c0_pins: i2c0-pins {
+ i2c0_pins_cfg {
+ pins = "i2c0_scl", "i2c0_sda";
+ function = "i2c0";
+ input-enable;
+ };
+ };
+
sdmmc_pins: sdmmc-pins {
sdmmc_clk_cfg {
pins = "pc_0";
@@ -363,6 +371,49 @@
};
};
+ spifi_pins: spifi-pins {
+ spifi_clk_cfg {
+ pins = "p3_3";
+ function = "spifi";
+ slew-rate = <1>;
+ bias-disable;
+ input-enable;
+ input-schmitt-disable;
+ };
+
+ spifi_mosi_miso_sio2_3_cfg {
+ pins = "p3_7", "p3_6", "p3_5", "p3_4";
+ function = "spifi";
+ slew-rate = <0>;
+ bias-disable;
+ input-enable;
+ input-schmitt-disable;
+ };
+
+ spifi_cs_cfg {
+ pins = "p3_8";
+ function = "spifi";
+ bias-disable;
+ };
+ };
+
+ ssp0_pins: ssp0-pins {
+ ssp0_sck_miso_mosi {
+ pins = "pf_0", "pf_2", "pf_3";
+ function = "ssp0";
+ slew-rate = <1>;
+ bias-pull-down;
+ input-enable;
+ input-schmitt-disable;
+ };
+
+ ssp0_ssel {
+ pins = "pf_1";
+ function = "ssp0";
+ bias-pull-up;
+ };
+ };
+
uart0_pins: uart0-pins {
uart0_rx_cfg {
pins = "pf_11";
@@ -410,6 +461,28 @@
};
};
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <400000>;
+
+ mma7455@1d {
+ compatible = "fsl,mma7455";
+ reg = <0x1d>;
+ };
+
+ lm75@48 {
+ compatible = "nxp,lm75";
+ reg = <0x48>;
+ };
+
+ eeprom@57 {
+ compatible = "microchip,24c64";
+ reg = <0x57>;
+ };
+};
+
&emc {
status = "okay";
pinctrl-names = "default";
@@ -489,6 +562,33 @@
pinctrl-0 = <&sdmmc_pins>;
};
+&spifi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spifi_pins>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-cpol;
+ spi-cpha;
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "data";
+ reg = <0 0x200000>;
+ };
+ };
+};
+
+&ssp0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ssp0_pins>;
+ num-cs = <1>;
+};
+
&uart0 {
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/lpc4357.dtsi b/arch/arm/boot/dts/lpc4357.dtsi
index fb9ecc7..72f12db 100644
--- a/arch/arm/boot/dts/lpc4357.dtsi
+++ b/arch/arm/boot/dts/lpc4357.dtsi
@@ -37,3 +37,7 @@
};
};
};
+
+&eeprom {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts
index 0521e68..9408753 100644
--- a/arch/arm/boot/dts/ls1021a-qds.dts
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -320,6 +320,10 @@
status = "okay";
};
+&sata {
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index e008f93..75ecaed 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -105,6 +105,15 @@
bitclock-master;
};
};
+
+ panel: panel {
+ compatible = "nec,nl4827hc19-05b";
+ };
+};
+
+&dcu {
+ fsl,panel = <&panel>;
+ status = "okay";
};
&dspi1 {
@@ -144,6 +153,19 @@
&i2c0 {
status = "okay";
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+
};
&i2c1 {
@@ -199,6 +221,10 @@
status = "okay";
};
+&sata {
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 973a496..ecf12dc 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -53,6 +53,7 @@
interrupt-parent = <&gic>;
aliases {
+ crypto = &crypto;
ethernet0 = &enet0;
ethernet1 = &enet1;
ethernet2 = &enet2;
@@ -142,12 +143,62 @@
status = "disabled";
};
+ sata: sata@3200000 {
+ compatible = "fsl,ls1021a-ahci";
+ reg = <0x0 0x3200000 0x0 0x10000>,
+ <0x0 0x20220520 0x0 0x4>;
+ reg-names = "ahci", "sata-ecc";
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ dma-coherent;
+ status = "disabled";
+ };
+
scfg: scfg@1570000 {
compatible = "fsl,ls1021a-scfg", "syscon";
reg = <0x0 0x1570000 0x0 0x10000>;
big-endian;
};
+ crypto: crypto@1700000 {
+ compatible = "fsl,sec-v5.0", "fsl,sec-v4.0";
+ fsl,sec-era = <7>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x1700000 0x0 0x100000>;
+ ranges = <0x0 0x0 0x1700000 0x100000>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+
+ sec_jr0: jr@10000 {
+ compatible = "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x10000 0x10000>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr1: jr@20000 {
+ compatible = "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x20000 0x10000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr2: jr@30000 {
+ compatible = "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x30000 0x10000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ sec_jr3: jr@40000 {
+ compatible = "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x40000 0x10000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ };
+
clockgen: clocking@1ee1000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -388,6 +439,16 @@
<&platform_clk 1>;
};
+ dcu: dcu@2ce0000 {
+ compatible = "fsl,ls1021a-dcu";
+ reg = <0x0 0x2ce0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 0>;
+ clock-names = "dcu";
+ big-endian;
+ status = "disabled";
+ };
+
mdio0: mdio@2d24000 {
compatible = "gianfar";
device_type = "mdio";
@@ -396,6 +457,18 @@
reg = <0x0 0x2d24000 0x0 0x4000>;
};
+ ptp_clock@2d10e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0x0 0x2d10e00 0x0 0xb0>;
+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xaaaaaaab>;
+ fsl,tmr-fiper1 = <999999990>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <499999999>;
+ };
+
enet0: ethernet@2d10000 {
compatible = "fsl,etsec2";
device_type = "network";
@@ -405,6 +478,7 @@
model = "eTSEC";
fsl,magic-packet;
ranges;
+ dma-coherent;
queue-group@2d10000 {
#address-cells = <2>;
@@ -433,6 +507,7 @@
interrupt-parent = <&gic>;
model = "eTSEC";
ranges;
+ dma-coherent;
queue-group@2d50000 {
#address-cells = <2>;
@@ -461,6 +536,7 @@
interrupt-parent = <&gic>;
model = "eTSEC";
ranges;
+ dma-coherent;
queue-group@2d90000 {
#address-cells = <2>;
@@ -494,6 +570,7 @@
reg = <0x0 0x3100000 0x0 0x10000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
dr_mode = "host";
+ snps,quirk-frame-length-adjustment = <0x20>;
};
};
};
diff --git a/arch/arm/boot/dts/meson8b-mxq.dts b/arch/arm/boot/dts/meson8b-mxq.dts
new file mode 100644
index 0000000..c7fdaea
--- /dev/null
+++ b/arch/arm/boot/dts/meson8b-mxq.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+/dts-v1/;
+#include "meson8b.dtsi"
+
+/ {
+ model = "TRONFY MXQ S805";
+ compatible = "tronfy,mxq", "amlogic,meson8b";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
new file mode 100644
index 0000000..e50f1a1
--- /dev/null
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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.
+ */
+
+/dts-v1/;
+#include "meson8b.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Hardkernel ODROID-C1";
+ compatible = "hardkernel,odroid-c1", "amlogic,meson8b";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ blue {
+ label = "c1:blue:alive";
+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
new file mode 100644
index 0000000..8bad557
--- /dev/null
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.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 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/clock/meson8b-clkc.h>
+#include <dt-bindings/gpio/meson8b-gpio.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x201>;
+ };
+
+ cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x202>;
+ };
+
+ cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a5";
+ next-level-cache = <&L2>;
+ reg = <0x203>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ 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>;
+ };
+
+ wdt: watchdog@c1109900 {
+ compatible = "amlogic,meson8b-wdt";
+ reg = <0xc1109900 0x8>;
+ interrupts = <0 0 1>;
+ };
+
+ timer@c1109940 {
+ compatible = "amlogic,meson6-timer";
+ reg = <0xc1109940 0x18>;
+ interrupts = <0 10 1>;
+ };
+
+ uart_AO: serial@c81004c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc81004c0 0x18>;
+ interrupts = <0 90 1>;
+ clocks = <&clkc CLKID_CLK81>;
+ status = "disabled";
+ };
+
+ uart_A: serial@c11084c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc11084c0 0x18>;
+ interrupts = <0 26 1>;
+ clocks = <&clkc CLKID_CLK81>;
+ status = "disabled";
+ };
+
+ uart_B: serial@c11084dc {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc11084dc 0x18>;
+ interrupts = <0 75 1>;
+ clocks = <&clkc CLKID_CLK81>;
+ status = "disabled";
+ };
+
+ uart_C: serial@c1108700 {
+ compatible = "amlogic,meson-uart";
+ reg = <0xc1108700 0x18>;
+ interrupts = <0 93 1>;
+ clocks = <&clkc CLKID_CLK81>;
+ status = "disabled";
+ };
+
+ clkc: clock-controller@c1104000 {
+ #clock-cells = <1>;
+ compatible = "amlogic,meson8b-clkc";
+ reg = <0xc1108000 0x4>, <0xc1104000 0x460>;
+ };
+
+ pinctrl: pinctrl@c1109880 {
+ compatible = "amlogic,meson8b-pinctrl";
+ reg = <0xc1109880 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio: banks@c11080b0 {
+ reg = <0xc11080b0 0x28>,
+ <0xc11080e8 0x18>,
+ <0xc1108120 0x18>,
+ <0xc1108030 0x38>;
+ 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";
+ };
+ };
+ };
+ };
+}; /* end of / */
diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
new file mode 100644
index 0000000..082ca88
--- /dev/null
+++ b/arch/arm/boot/dts/mt2701-evb.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Erin Lo <erin.lo@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 "mt2701.dtsi"
+
+/ {
+ model = "MediaTek MT2701 evaluation board";
+ compatible = "mediatek,mt2701-evb", "mediatek,mt2701";
+
+ memory {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt2701-pinfunc.h b/arch/arm/boot/dts/mt2701-pinfunc.h
new file mode 100644
index 0000000..e24ebc8
--- /dev/null
+++ b/arch/arm/boot/dts/mt2701-pinfunc.h
@@ -0,0 +1,735 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Biao Huang <biao.huang@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.
+ */
+
+#ifndef __DTS_MT2701_PINFUNC_H
+#define __DTS_MT2701_PINFUNC_H
+
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
+#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1)
+#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2)
+
+#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
+#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1)
+#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2)
+
+#define MT2701_PIN_2_PWRAP_INT__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
+#define MT2701_PIN_2_PWRAP_INT__FUNC_PWRAP_INT (MTK_PIN_NO(2) | 1)
+
+#define MT2701_PIN_3_PWRAP_SPI0_CK__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
+#define MT2701_PIN_3_PWRAP_SPI0_CK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1)
+
+#define MT2701_PIN_4_PWRAP_SPI0_CSN__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
+#define MT2701_PIN_4_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1)
+
+#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
+#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1)
+#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_ANT_SEL1 (MTK_PIN_NO(5) | 5)
+
+#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
+#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1)
+#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_ANT_SEL0 (MTK_PIN_NO(6) | 5)
+#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_DBG_MON_A_0 (MTK_PIN_NO(6) | 7)
+
+#define MT2701_PIN_7_SPI1_CSN__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
+#define MT2701_PIN_7_SPI1_CSN__FUNC_SPI1_CS (MTK_PIN_NO(7) | 1)
+#define MT2701_PIN_7_SPI1_CSN__FUNC_KCOL0 (MTK_PIN_NO(7) | 4)
+#define MT2701_PIN_7_SPI1_CSN__FUNC_DBG_MON_B_12 (MTK_PIN_NO(7) | 7)
+
+#define MT2701_PIN_8_SPI1_MI__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
+#define MT2701_PIN_8_SPI1_MI__FUNC_SPI1_MI (MTK_PIN_NO(8) | 1)
+#define MT2701_PIN_8_SPI1_MI__FUNC_SPI1_MO (MTK_PIN_NO(8) | 2)
+#define MT2701_PIN_8_SPI1_MI__FUNC_KCOL1 (MTK_PIN_NO(8) | 4)
+#define MT2701_PIN_8_SPI1_MI__FUNC_DBG_MON_B_13 (MTK_PIN_NO(8) | 7)
+
+#define MT2701_PIN_9_SPI1_MO__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
+#define MT2701_PIN_9_SPI1_MO__FUNC_SPI1_MO (MTK_PIN_NO(9) | 1)
+#define MT2701_PIN_9_SPI1_MO__FUNC_SPI1_MI (MTK_PIN_NO(9) | 2)
+#define MT2701_PIN_9_SPI1_MO__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(9) | 3)
+#define MT2701_PIN_9_SPI1_MO__FUNC_KCOL2 (MTK_PIN_NO(9) | 4)
+#define MT2701_PIN_9_SPI1_MO__FUNC_DBG_MON_B_14 (MTK_PIN_NO(9) | 7)
+
+#define MT2701_PIN_10_RTC32K_CK__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
+#define MT2701_PIN_10_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1)
+
+#define MT2701_PIN_11_WATCHDOG__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
+#define MT2701_PIN_11_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(11) | 1)
+
+#define MT2701_PIN_12_SRCLKENA__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
+#define MT2701_PIN_12_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(12) | 1)
+
+#define MT2701_PIN_13_SRCLKENAI__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
+#define MT2701_PIN_13_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1)
+
+#define MT2701_PIN_14_URXD2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
+#define MT2701_PIN_14_URXD2__FUNC_URXD2 (MTK_PIN_NO(14) | 1)
+#define MT2701_PIN_14_URXD2__FUNC_UTXD2 (MTK_PIN_NO(14) | 2)
+#define MT2701_PIN_14_URXD2__FUNC_SRCCLKENAI2 (MTK_PIN_NO(14) | 5)
+#define MT2701_PIN_14_URXD2__FUNC_DBG_MON_B_30 (MTK_PIN_NO(14) | 7)
+
+#define MT2701_PIN_15_UTXD2__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
+#define MT2701_PIN_15_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(15) | 1)
+#define MT2701_PIN_15_UTXD2__FUNC_URXD2 (MTK_PIN_NO(15) | 2)
+#define MT2701_PIN_15_UTXD2__FUNC_DBG_MON_B_31 (MTK_PIN_NO(15) | 7)
+
+#define MT2701_PIN_18_PCM_CLK__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
+#define MT2701_PIN_18_PCM_CLK__FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1)
+#define MT2701_PIN_18_PCM_CLK__FUNC_MRG_CLK (MTK_PIN_NO(18) | 2)
+#define MT2701_PIN_18_PCM_CLK__FUNC_MM_TEST_CK (MTK_PIN_NO(18) | 4)
+#define MT2701_PIN_18_PCM_CLK__FUNC_CONN_DSP_JCK (MTK_PIN_NO(18) | 5)
+#define MT2701_PIN_18_PCM_CLK__FUNC_WCN_PCM_CLKO (MTK_PIN_NO(18) | 6)
+#define MT2701_PIN_18_PCM_CLK__FUNC_DBG_MON_A_3 (MTK_PIN_NO(18) | 7)
+
+#define MT2701_PIN_19_PCM_SYNC__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
+#define MT2701_PIN_19_PCM_SYNC__FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1)
+#define MT2701_PIN_19_PCM_SYNC__FUNC_MRG_SYNC (MTK_PIN_NO(19) | 2)
+#define MT2701_PIN_19_PCM_SYNC__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(19) | 5)
+#define MT2701_PIN_19_PCM_SYNC__FUNC_WCN_PCM_SYNC (MTK_PIN_NO(19) | 6)
+#define MT2701_PIN_19_PCM_SYNC__FUNC_DBG_MON_A_5 (MTK_PIN_NO(19) | 7)
+
+#define MT2701_PIN_20_PCM_RX__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
+#define MT2701_PIN_20_PCM_RX__FUNC_PCM_RX (MTK_PIN_NO(20) | 1)
+#define MT2701_PIN_20_PCM_RX__FUNC_MRG_RX (MTK_PIN_NO(20) | 2)
+#define MT2701_PIN_20_PCM_RX__FUNC_MRG_TX (MTK_PIN_NO(20) | 3)
+#define MT2701_PIN_20_PCM_RX__FUNC_PCM_TX (MTK_PIN_NO(20) | 4)
+#define MT2701_PIN_20_PCM_RX__FUNC_CONN_DSP_JDI (MTK_PIN_NO(20) | 5)
+#define MT2701_PIN_20_PCM_RX__FUNC_WCN_PCM_RX (MTK_PIN_NO(20) | 6)
+#define MT2701_PIN_20_PCM_RX__FUNC_DBG_MON_A_4 (MTK_PIN_NO(20) | 7)
+
+#define MT2701_PIN_21_PCM_TX__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
+#define MT2701_PIN_21_PCM_TX__FUNC_PCM_TX (MTK_PIN_NO(21) | 1)
+#define MT2701_PIN_21_PCM_TX__FUNC_MRG_TX (MTK_PIN_NO(21) | 2)
+#define MT2701_PIN_21_PCM_TX__FUNC_MRG_RX (MTK_PIN_NO(21) | 3)
+#define MT2701_PIN_21_PCM_TX__FUNC_PCM_RX (MTK_PIN_NO(21) | 4)
+#define MT2701_PIN_21_PCM_TX__FUNC_CONN_DSP_JMS (MTK_PIN_NO(21) | 5)
+#define MT2701_PIN_21_PCM_TX__FUNC_WCN_PCM_TX (MTK_PIN_NO(21) | 6)
+#define MT2701_PIN_21_PCM_TX__FUNC_DBG_MON_A_2 (MTK_PIN_NO(21) | 7)
+
+#define MT2701_PIN_22_EINT0__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
+#define MT2701_PIN_22_EINT0__FUNC_UCTS0 (MTK_PIN_NO(22) | 1)
+#define MT2701_PIN_22_EINT0__FUNC_KCOL3 (MTK_PIN_NO(22) | 3)
+#define MT2701_PIN_22_EINT0__FUNC_CONN_DSP_JDO (MTK_PIN_NO(22) | 4)
+#define MT2701_PIN_22_EINT0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(22) | 5)
+#define MT2701_PIN_22_EINT0__FUNC_DBG_MON_A_30 (MTK_PIN_NO(22) | 7)
+#define MT2701_PIN_22_EINT0__FUNC_PCIE0_PERST_N (MTK_PIN_NO(22) | 10)
+
+#define MT2701_PIN_23_EINT1__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
+#define MT2701_PIN_23_EINT1__FUNC_URTS0 (MTK_PIN_NO(23) | 1)
+#define MT2701_PIN_23_EINT1__FUNC_KCOL2 (MTK_PIN_NO(23) | 3)
+#define MT2701_PIN_23_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(23) | 4)
+#define MT2701_PIN_23_EINT1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(23) | 5)
+#define MT2701_PIN_23_EINT1__FUNC_DBG_MON_A_29 (MTK_PIN_NO(23) | 7)
+#define MT2701_PIN_23_EINT1__FUNC_PCIE1_PERST_N (MTK_PIN_NO(23) | 10)
+
+#define MT2701_PIN_24_EINT2__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
+#define MT2701_PIN_24_EINT2__FUNC_UCTS1 (MTK_PIN_NO(24) | 1)
+#define MT2701_PIN_24_EINT2__FUNC_KCOL1 (MTK_PIN_NO(24) | 3)
+#define MT2701_PIN_24_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(24) | 4)
+#define MT2701_PIN_24_EINT2__FUNC_DBG_MON_A_28 (MTK_PIN_NO(24) | 7)
+#define MT2701_PIN_24_EINT2__FUNC_PCIE2_PERST_N (MTK_PIN_NO(24) | 10)
+
+#define MT2701_PIN_25_EINT3__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
+#define MT2701_PIN_25_EINT3__FUNC_URTS1 (MTK_PIN_NO(25) | 1)
+#define MT2701_PIN_25_EINT3__FUNC_KCOL0 (MTK_PIN_NO(25) | 3)
+#define MT2701_PIN_25_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(25) | 4)
+#define MT2701_PIN_25_EINT3__FUNC_DBG_MON_A_27 (MTK_PIN_NO(25) | 7)
+
+#define MT2701_PIN_26_EINT4__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
+#define MT2701_PIN_26_EINT4__FUNC_UCTS3 (MTK_PIN_NO(26) | 1)
+#define MT2701_PIN_26_EINT4__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(26) | 2)
+#define MT2701_PIN_26_EINT4__FUNC_KROW3 (MTK_PIN_NO(26) | 3)
+#define MT2701_PIN_26_EINT4__FUNC_CONN_MCU_TCK0 (MTK_PIN_NO(26) | 4)
+#define MT2701_PIN_26_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(26) | 5)
+#define MT2701_PIN_26_EINT4__FUNC_PCIE2_WAKE_N (MTK_PIN_NO(26) | 6)
+#define MT2701_PIN_26_EINT4__FUNC_DBG_MON_A_26 (MTK_PIN_NO(26) | 7)
+
+#define MT2701_PIN_27_EINT5__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
+#define MT2701_PIN_27_EINT5__FUNC_URTS3 (MTK_PIN_NO(27) | 1)
+#define MT2701_PIN_27_EINT5__FUNC_IDDIG_P1 (MTK_PIN_NO(27) | 2)
+#define MT2701_PIN_27_EINT5__FUNC_KROW2 (MTK_PIN_NO(27) | 3)
+#define MT2701_PIN_27_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(27) | 4)
+#define MT2701_PIN_27_EINT5__FUNC_PCIE1_WAKE_N (MTK_PIN_NO(27) | 6)
+#define MT2701_PIN_27_EINT5__FUNC_DBG_MON_A_25 (MTK_PIN_NO(27) | 7)
+
+#define MT2701_PIN_28_EINT6__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
+#define MT2701_PIN_28_EINT6__FUNC_DRV_VBUS (MTK_PIN_NO(28) | 1)
+#define MT2701_PIN_28_EINT6__FUNC_KROW1 (MTK_PIN_NO(28) | 3)
+#define MT2701_PIN_28_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(28) | 4)
+#define MT2701_PIN_28_EINT6__FUNC_PCIE0_WAKE_N (MTK_PIN_NO(28) | 6)
+#define MT2701_PIN_28_EINT6__FUNC_DBG_MON_A_24 (MTK_PIN_NO(28) | 7)
+
+#define MT2701_PIN_29_EINT7__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
+#define MT2701_PIN_29_EINT7__FUNC_IDDIG (MTK_PIN_NO(29) | 1)
+#define MT2701_PIN_29_EINT7__FUNC_MSDC1_WP (MTK_PIN_NO(29) | 2)
+#define MT2701_PIN_29_EINT7__FUNC_KROW0 (MTK_PIN_NO(29) | 3)
+#define MT2701_PIN_29_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(29) | 4)
+#define MT2701_PIN_29_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(29) | 5)
+#define MT2701_PIN_29_EINT7__FUNC_DBG_MON_A_23 (MTK_PIN_NO(29) | 7)
+#define MT2701_PIN_29_EINT7__FUNC_PCIE2_PERST_N (MTK_PIN_NO(29) | 14)
+
+#define MT2701_PIN_33_I2S1_DATA__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_I2S1_DATA (MTK_PIN_NO(33) | 1)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_I2S1_DATA_BYPS (MTK_PIN_NO(33) | 2)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_PCM_TX (MTK_PIN_NO(33) | 3)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_IMG_TEST_CK (MTK_PIN_NO(33) | 4)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_G1_RXD0 (MTK_PIN_NO(33) | 5)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_WCN_PCM_TX (MTK_PIN_NO(33) | 6)
+#define MT2701_PIN_33_I2S1_DATA__FUNC_DBG_MON_B_8 (MTK_PIN_NO(33) | 7)
+
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_I2S1_DATA_IN (MTK_PIN_NO(34) | 1)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(34) | 3)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_VDEC_TEST_CK (MTK_PIN_NO(34) | 4)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_G1_RXD1 (MTK_PIN_NO(34) | 5)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_WCN_PCM_RX (MTK_PIN_NO(34) | 6)
+#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_DBG_MON_B_7 (MTK_PIN_NO(34) | 7)
+
+#define MT2701_PIN_35_I2S1_BCK__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
+#define MT2701_PIN_35_I2S1_BCK__FUNC_I2S1_BCK (MTK_PIN_NO(35) | 1)
+#define MT2701_PIN_35_I2S1_BCK__FUNC_PCM_CLK0 (MTK_PIN_NO(35) | 3)
+#define MT2701_PIN_35_I2S1_BCK__FUNC_G1_RXD2 (MTK_PIN_NO(35) | 5)
+#define MT2701_PIN_35_I2S1_BCK__FUNC_WCN_PCM_CLKO (MTK_PIN_NO(35) | 6)
+#define MT2701_PIN_35_I2S1_BCK__FUNC_DBG_MON_B_9 (MTK_PIN_NO(35) | 7)
+
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_I2S1_LRCK (MTK_PIN_NO(36) | 1)
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(36) | 3)
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_G1_RXD3 (MTK_PIN_NO(36) | 5)
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_WCN_PCM_SYNC (MTK_PIN_NO(36) | 6)
+#define MT2701_PIN_36_I2S1_LRCK__FUNC_DBG_MON_B_10 (MTK_PIN_NO(36) | 7)
+
+#define MT2701_PIN_37_I2S1_MCLK__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
+#define MT2701_PIN_37_I2S1_MCLK__FUNC_I2S1_MCLK (MTK_PIN_NO(37) | 1)
+#define MT2701_PIN_37_I2S1_MCLK__FUNC_G1_RXDV (MTK_PIN_NO(37) | 5)
+#define MT2701_PIN_37_I2S1_MCLK__FUNC_DBG_MON_B_11 (MTK_PIN_NO(37) | 7)
+
+#define MT2701_PIN_39_JTMS__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
+#define MT2701_PIN_39_JTMS__FUNC_JTMS (MTK_PIN_NO(39) | 1)
+#define MT2701_PIN_39_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(39) | 2)
+#define MT2701_PIN_39_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(39) | 3)
+#define MT2701_PIN_39_JTMS__FUNC_DFD_TMS_XI (MTK_PIN_NO(39) | 4)
+
+#define MT2701_PIN_40_JTCK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
+#define MT2701_PIN_40_JTCK__FUNC_JTCK (MTK_PIN_NO(40) | 1)
+#define MT2701_PIN_40_JTCK__FUNC_CONN_MCU_TCK1 (MTK_PIN_NO(40) | 2)
+#define MT2701_PIN_40_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(40) | 3)
+#define MT2701_PIN_40_JTCK__FUNC_DFD_TCK_XI (MTK_PIN_NO(40) | 4)
+
+#define MT2701_PIN_41_JTDI__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
+#define MT2701_PIN_41_JTDI__FUNC_JTDI (MTK_PIN_NO(41) | 1)
+#define MT2701_PIN_41_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(41) | 2)
+#define MT2701_PIN_41_JTDI__FUNC_DFD_TDI_XI (MTK_PIN_NO(41) | 4)
+
+#define MT2701_PIN_42_JTDO__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
+#define MT2701_PIN_42_JTDO__FUNC_JTDO (MTK_PIN_NO(42) | 1)
+#define MT2701_PIN_42_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(42) | 2)
+#define MT2701_PIN_42_JTDO__FUNC_DFD_TDO (MTK_PIN_NO(42) | 4)
+
+#define MT2701_PIN_43_NCLE__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
+#define MT2701_PIN_43_NCLE__FUNC_NCLE (MTK_PIN_NO(43) | 1)
+#define MT2701_PIN_43_NCLE__FUNC_EXT_XCS2 (MTK_PIN_NO(43) | 2)
+
+#define MT2701_PIN_44_NCEB1__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
+#define MT2701_PIN_44_NCEB1__FUNC_NCEB1 (MTK_PIN_NO(44) | 1)
+#define MT2701_PIN_44_NCEB1__FUNC_IDDIG (MTK_PIN_NO(44) | 2)
+
+#define MT2701_PIN_45_NCEB0__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
+#define MT2701_PIN_45_NCEB0__FUNC_NCEB0 (MTK_PIN_NO(45) | 1)
+#define MT2701_PIN_45_NCEB0__FUNC_DRV_VBUS (MTK_PIN_NO(45) | 2)
+
+#define MT2701_PIN_46_IR__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
+#define MT2701_PIN_46_IR__FUNC_IR (MTK_PIN_NO(46) | 1)
+
+#define MT2701_PIN_47_NREB__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
+#define MT2701_PIN_47_NREB__FUNC_NREB (MTK_PIN_NO(47) | 1)
+#define MT2701_PIN_47_NREB__FUNC_IDDIG_P1 (MTK_PIN_NO(47) | 2)
+
+#define MT2701_PIN_48_NRNB__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
+#define MT2701_PIN_48_NRNB__FUNC_NRNB (MTK_PIN_NO(48) | 1)
+#define MT2701_PIN_48_NRNB__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(48) | 2)
+
+#define MT2701_PIN_49_I2S0_DATA__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
+#define MT2701_PIN_49_I2S0_DATA__FUNC_I2S0_DATA (MTK_PIN_NO(49) | 1)
+#define MT2701_PIN_49_I2S0_DATA__FUNC_I2S0_DATA_BYPS (MTK_PIN_NO(49) | 2)
+#define MT2701_PIN_49_I2S0_DATA__FUNC_PCM_TX (MTK_PIN_NO(49) | 3)
+#define MT2701_PIN_49_I2S0_DATA__FUNC_WCN_I2S_DO (MTK_PIN_NO(49) | 6)
+#define MT2701_PIN_49_I2S0_DATA__FUNC_DBG_MON_B_3 (MTK_PIN_NO(49) | 7)
+
+#define MT2701_PIN_53_SPI0_CSN__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
+#define MT2701_PIN_53_SPI0_CSN__FUNC_SPI0_CS (MTK_PIN_NO(53) | 1)
+#define MT2701_PIN_53_SPI0_CSN__FUNC_SPDIF (MTK_PIN_NO(53) | 3)
+#define MT2701_PIN_53_SPI0_CSN__FUNC_ADC_CK (MTK_PIN_NO(53) | 4)
+#define MT2701_PIN_53_SPI0_CSN__FUNC_PWM1 (MTK_PIN_NO(53) | 5)
+#define MT2701_PIN_53_SPI0_CSN__FUNC_DBG_MON_A_7 (MTK_PIN_NO(53) | 7)
+
+#define MT2701_PIN_54_SPI0_CK__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
+#define MT2701_PIN_54_SPI0_CK__FUNC_SPI0_CK (MTK_PIN_NO(54) | 1)
+#define MT2701_PIN_54_SPI0_CK__FUNC_SPDIF_IN1 (MTK_PIN_NO(54) | 3)
+#define MT2701_PIN_54_SPI0_CK__FUNC_ADC_DAT_IN (MTK_PIN_NO(54) | 4)
+#define MT2701_PIN_54_SPI0_CK__FUNC_DBG_MON_A_10 (MTK_PIN_NO(54) | 7)
+
+#define MT2701_PIN_55_SPI0_MI__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
+#define MT2701_PIN_55_SPI0_MI__FUNC_SPI0_MI (MTK_PIN_NO(55) | 1)
+#define MT2701_PIN_55_SPI0_MI__FUNC_SPI0_MO (MTK_PIN_NO(55) | 2)
+#define MT2701_PIN_55_SPI0_MI__FUNC_MSDC1_WP (MTK_PIN_NO(55) | 3)
+#define MT2701_PIN_55_SPI0_MI__FUNC_ADC_WS (MTK_PIN_NO(55) | 4)
+#define MT2701_PIN_55_SPI0_MI__FUNC_PWM2 (MTK_PIN_NO(55) | 5)
+#define MT2701_PIN_55_SPI0_MI__FUNC_DBG_MON_A_8 (MTK_PIN_NO(55) | 7)
+
+#define MT2701_PIN_56_SPI0_MO__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
+#define MT2701_PIN_56_SPI0_MO__FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
+#define MT2701_PIN_56_SPI0_MO__FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
+#define MT2701_PIN_56_SPI0_MO__FUNC_SPDIF_IN0 (MTK_PIN_NO(56) | 3)
+#define MT2701_PIN_56_SPI0_MO__FUNC_DBG_MON_A_9 (MTK_PIN_NO(56) | 7)
+
+#define MT2701_PIN_57_SDA1__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
+#define MT2701_PIN_57_SDA1__FUNC_SDA1 (MTK_PIN_NO(57) | 1)
+
+#define MT2701_PIN_58_SCL1__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
+#define MT2701_PIN_58_SCL1__FUNC_SCL1 (MTK_PIN_NO(58) | 1)
+
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_I2S0_DATA_IN (MTK_PIN_NO(72) | 1)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(72) | 3)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_PWM0 (MTK_PIN_NO(72) | 4)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_DISP_PWM (MTK_PIN_NO(72) | 5)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_WCN_I2S_DI (MTK_PIN_NO(72) | 6)
+#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_DBG_MON_B_2 (MTK_PIN_NO(72) | 7)
+
+#define MT2701_PIN_73_I2S0_LRCK__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
+#define MT2701_PIN_73_I2S0_LRCK__FUNC_I2S0_LRCK (MTK_PIN_NO(73) | 1)
+#define MT2701_PIN_73_I2S0_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(73) | 3)
+#define MT2701_PIN_73_I2S0_LRCK__FUNC_WCN_I2S_LRCK (MTK_PIN_NO(73) | 6)
+#define MT2701_PIN_73_I2S0_LRCK__FUNC_DBG_MON_B_5 (MTK_PIN_NO(73) | 7)
+
+#define MT2701_PIN_74_I2S0_BCK__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
+#define MT2701_PIN_74_I2S0_BCK__FUNC_I2S0_BCK (MTK_PIN_NO(74) | 1)
+#define MT2701_PIN_74_I2S0_BCK__FUNC_PCM_CLK0 (MTK_PIN_NO(74) | 3)
+#define MT2701_PIN_74_I2S0_BCK__FUNC_WCN_I2S_BCK (MTK_PIN_NO(74) | 6)
+#define MT2701_PIN_74_I2S0_BCK__FUNC_DBG_MON_B_4 (MTK_PIN_NO(74) | 7)
+
+#define MT2701_PIN_75_SDA0__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
+#define MT2701_PIN_75_SDA0__FUNC_SDA0 (MTK_PIN_NO(75) | 1)
+
+#define MT2701_PIN_76_SCL0__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
+#define MT2701_PIN_76_SCL0__FUNC_SCL0 (MTK_PIN_NO(76) | 1)
+
+#define MT2701_PIN_77_SDA2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
+#define MT2701_PIN_77_SDA2__FUNC_SDA2 (MTK_PIN_NO(77) | 1)
+
+#define MT2701_PIN_78_SCL2__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
+#define MT2701_PIN_78_SCL2__FUNC_SCL2 (MTK_PIN_NO(78) | 1)
+
+#define MT2701_PIN_79_URXD0__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
+#define MT2701_PIN_79_URXD0__FUNC_URXD0 (MTK_PIN_NO(79) | 1)
+#define MT2701_PIN_79_URXD0__FUNC_UTXD0 (MTK_PIN_NO(79) | 2)
+#define MT2701_PIN_79_URXD0__FUNC_ (MTK_PIN_NO(79) | 5)
+
+#define MT2701_PIN_80_UTXD0__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
+#define MT2701_PIN_80_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(80) | 1)
+#define MT2701_PIN_80_UTXD0__FUNC_URXD0 (MTK_PIN_NO(80) | 2)
+
+#define MT2701_PIN_81_URXD1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
+#define MT2701_PIN_81_URXD1__FUNC_URXD1 (MTK_PIN_NO(81) | 1)
+#define MT2701_PIN_81_URXD1__FUNC_UTXD1 (MTK_PIN_NO(81) | 2)
+
+#define MT2701_PIN_82_UTXD1__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
+#define MT2701_PIN_82_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(82) | 1)
+#define MT2701_PIN_82_UTXD1__FUNC_URXD1 (MTK_PIN_NO(82) | 2)
+
+#define MT2701_PIN_83_LCM_RST__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
+#define MT2701_PIN_83_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
+#define MT2701_PIN_83_LCM_RST__FUNC_VDAC_CK_XI (MTK_PIN_NO(83) | 2)
+#define MT2701_PIN_83_LCM_RST__FUNC_DBG_MON_B_1 (MTK_PIN_NO(83) | 7)
+
+#define MT2701_PIN_84_DSI_TE__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
+#define MT2701_PIN_84_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(84) | 1)
+#define MT2701_PIN_84_DSI_TE__FUNC_DBG_MON_B_0 (MTK_PIN_NO(84) | 7)
+
+#define MT2701_PIN_91_TDN3__FUNC_GPI91 (MTK_PIN_NO(91) | 0)
+#define MT2701_PIN_91_TDN3__FUNC_TDN3 (MTK_PIN_NO(91) | 1)
+
+#define MT2701_PIN_92_TDP3__FUNC_GPI92 (MTK_PIN_NO(92) | 0)
+#define MT2701_PIN_92_TDP3__FUNC_TDP3 (MTK_PIN_NO(92) | 1)
+
+#define MT2701_PIN_93_TDN2__FUNC_GPI93 (MTK_PIN_NO(93) | 0)
+#define MT2701_PIN_93_TDN2__FUNC_TDN2 (MTK_PIN_NO(93) | 1)
+
+#define MT2701_PIN_94_TDP2__FUNC_GPI94 (MTK_PIN_NO(94) | 0)
+#define MT2701_PIN_94_TDP2__FUNC_TDP2 (MTK_PIN_NO(94) | 1)
+
+#define MT2701_PIN_95_TCN__FUNC_GPI95 (MTK_PIN_NO(95) | 0)
+#define MT2701_PIN_95_TCN__FUNC_TCN (MTK_PIN_NO(95) | 1)
+
+#define MT2701_PIN_96_TCP__FUNC_GPI96 (MTK_PIN_NO(96) | 0)
+#define MT2701_PIN_96_TCP__FUNC_TCP (MTK_PIN_NO(96) | 1)
+
+#define MT2701_PIN_97_TDN1__FUNC_GPI97 (MTK_PIN_NO(97) | 0)
+#define MT2701_PIN_97_TDN1__FUNC_TDN1 (MTK_PIN_NO(97) | 1)
+
+#define MT2701_PIN_98_TDP1__FUNC_GPI98 (MTK_PIN_NO(98) | 0)
+#define MT2701_PIN_98_TDP1__FUNC_TDP1 (MTK_PIN_NO(98) | 1)
+
+#define MT2701_PIN_99_TDN0__FUNC_GPI99 (MTK_PIN_NO(99) | 0)
+#define MT2701_PIN_99_TDN0__FUNC_TDN0 (MTK_PIN_NO(99) | 1)
+
+#define MT2701_PIN_100_TDP0__FUNC_GPI100 (MTK_PIN_NO(100) | 0)
+#define MT2701_PIN_100_TDP0__FUNC_TDP0 (MTK_PIN_NO(100) | 1)
+
+#define MT2701_PIN_101_SPI2_CSN__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
+#define MT2701_PIN_101_SPI2_CSN__FUNC_SPI2_CS (MTK_PIN_NO(101) | 1)
+#define MT2701_PIN_101_SPI2_CSN__FUNC_SCL3 (MTK_PIN_NO(101) | 3)
+#define MT2701_PIN_101_SPI2_CSN__FUNC_KROW0 (MTK_PIN_NO(101) | 4)
+
+#define MT2701_PIN_102_SPI2_MI__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
+#define MT2701_PIN_102_SPI2_MI__FUNC_SPI2_MI (MTK_PIN_NO(102) | 1)
+#define MT2701_PIN_102_SPI2_MI__FUNC_SPI2_MO (MTK_PIN_NO(102) | 2)
+#define MT2701_PIN_102_SPI2_MI__FUNC_SDA3 (MTK_PIN_NO(102) | 3)
+#define MT2701_PIN_102_SPI2_MI__FUNC_KROW1 (MTK_PIN_NO(102) | 4)
+
+#define MT2701_PIN_103_SPI2_MO__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
+#define MT2701_PIN_103_SPI2_MO__FUNC_SPI2_MO (MTK_PIN_NO(103) | 1)
+#define MT2701_PIN_103_SPI2_MO__FUNC_SPI2_MI (MTK_PIN_NO(103) | 2)
+#define MT2701_PIN_103_SPI2_MO__FUNC_SCL3 (MTK_PIN_NO(103) | 3)
+#define MT2701_PIN_103_SPI2_MO__FUNC_KROW2 (MTK_PIN_NO(103) | 4)
+
+#define MT2701_PIN_104_SPI2_CLK__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
+#define MT2701_PIN_104_SPI2_CLK__FUNC_SPI2_CK (MTK_PIN_NO(104) | 1)
+#define MT2701_PIN_104_SPI2_CLK__FUNC_SDA3 (MTK_PIN_NO(104) | 3)
+#define MT2701_PIN_104_SPI2_CLK__FUNC_KROW3 (MTK_PIN_NO(104) | 4)
+
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(105) | 1)
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_ANT_SEL0 (MTK_PIN_NO(105) | 2)
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_SDA1 (MTK_PIN_NO(105) | 3)
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_I2SOUT_BCK (MTK_PIN_NO(105) | 6)
+#define MT2701_PIN_105_MSDC1_CMD__FUNC_DBG_MON_B_27 (MTK_PIN_NO(105) | 7)
+
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(106) | 1)
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_ANT_SEL1 (MTK_PIN_NO(106) | 2)
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_SCL1 (MTK_PIN_NO(106) | 3)
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(106) | 6)
+#define MT2701_PIN_106_MSDC1_CLK__FUNC_DBG_MON_B_28 (MTK_PIN_NO(106) | 7)
+
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(107) | 1)
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(107) | 2)
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_UTXD0 (MTK_PIN_NO(107) | 5)
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(107) | 6)
+#define MT2701_PIN_107_MSDC1_DAT0__FUNC_DBG_MON_B_26 (MTK_PIN_NO(107) | 7)
+
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(108) | 1)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(108) | 2)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_PWM0 (MTK_PIN_NO(108) | 3)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_URXD0 (MTK_PIN_NO(108) | 5)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_PWM1 (MTK_PIN_NO(108) | 6)
+#define MT2701_PIN_108_MSDC1_DAT1__FUNC_DBG_MON_B_25 (MTK_PIN_NO(108) | 7)
+
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(109) | 1)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_ANT_SEL4 (MTK_PIN_NO(109) | 2)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_SDA2 (MTK_PIN_NO(109) | 3)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_UTXD1 (MTK_PIN_NO(109) | 5)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_PWM2 (MTK_PIN_NO(109) | 6)
+#define MT2701_PIN_109_MSDC1_DAT2__FUNC_DBG_MON_B_24 (MTK_PIN_NO(109) | 7)
+
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(110) | 1)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_ANT_SEL5 (MTK_PIN_NO(110) | 2)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_SCL2 (MTK_PIN_NO(110) | 3)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(110) | 4)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_URXD1 (MTK_PIN_NO(110) | 5)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_PWM3 (MTK_PIN_NO(110) | 6)
+#define MT2701_PIN_110_MSDC1_DAT3__FUNC_DBG_MON_B_23 (MTK_PIN_NO(110) | 7)
+
+#define MT2701_PIN_111_MSDC0_DAT7__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
+#define MT2701_PIN_111_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(111) | 1)
+#define MT2701_PIN_111_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(111) | 4)
+
+#define MT2701_PIN_112_MSDC0_DAT6__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
+#define MT2701_PIN_112_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(112) | 1)
+#define MT2701_PIN_112_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(112) | 4)
+
+#define MT2701_PIN_113_MSDC0_DAT5__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
+#define MT2701_PIN_113_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(113) | 1)
+#define MT2701_PIN_113_MSDC0_DAT5__FUNC_NLD5 (MTK_PIN_NO(113) | 4)
+
+#define MT2701_PIN_114_MSDC0_DAT4__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
+#define MT2701_PIN_114_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(114) | 1)
+#define MT2701_PIN_114_MSDC0_DAT4__FUNC_NLD4 (MTK_PIN_NO(114) | 4)
+
+#define MT2701_PIN_115_MSDC0_RSTB__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
+#define MT2701_PIN_115_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(115) | 1)
+#define MT2701_PIN_115_MSDC0_RSTB__FUNC_NLD8 (MTK_PIN_NO(115) | 4)
+
+#define MT2701_PIN_116_MSDC0_CMD__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
+#define MT2701_PIN_116_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(116) | 1)
+#define MT2701_PIN_116_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(116) | 4)
+
+#define MT2701_PIN_117_MSDC0_CLK__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
+#define MT2701_PIN_117_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(117) | 1)
+#define MT2701_PIN_117_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(117) | 4)
+
+#define MT2701_PIN_118_MSDC0_DAT3__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
+#define MT2701_PIN_118_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(118) | 1)
+#define MT2701_PIN_118_MSDC0_DAT3__FUNC_NLD3 (MTK_PIN_NO(118) | 4)
+
+#define MT2701_PIN_119_MSDC0_DAT2__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
+#define MT2701_PIN_119_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(119) | 1)
+#define MT2701_PIN_119_MSDC0_DAT2__FUNC_NLD2 (MTK_PIN_NO(119) | 4)
+
+#define MT2701_PIN_120_MSDC0_DAT1__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
+#define MT2701_PIN_120_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(120) | 1)
+#define MT2701_PIN_120_MSDC0_DAT1__FUNC_NLD1 (MTK_PIN_NO(120) | 4)
+
+#define MT2701_PIN_121_MSDC0_DAT0__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
+#define MT2701_PIN_121_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(121) | 1)
+#define MT2701_PIN_121_MSDC0_DAT0__FUNC_NLD0 (MTK_PIN_NO(121) | 4)
+#define MT2701_PIN_121_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(121) | 5)
+
+#define MT2701_PIN_122_CEC__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
+#define MT2701_PIN_122_CEC__FUNC_CEC (MTK_PIN_NO(122) | 1)
+#define MT2701_PIN_122_CEC__FUNC_SDA2 (MTK_PIN_NO(122) | 4)
+#define MT2701_PIN_122_CEC__FUNC_URXD0 (MTK_PIN_NO(122) | 5)
+
+#define MT2701_PIN_123_HTPLG__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
+#define MT2701_PIN_123_HTPLG__FUNC_HTPLG (MTK_PIN_NO(123) | 1)
+#define MT2701_PIN_123_HTPLG__FUNC_SCL2 (MTK_PIN_NO(123) | 4)
+#define MT2701_PIN_123_HTPLG__FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
+
+#define MT2701_PIN_124_HDMISCK__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
+#define MT2701_PIN_124_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(124) | 1)
+#define MT2701_PIN_124_HDMISCK__FUNC_SDA1 (MTK_PIN_NO(124) | 4)
+#define MT2701_PIN_124_HDMISCK__FUNC_PWM3 (MTK_PIN_NO(124) | 5)
+
+#define MT2701_PIN_125_HDMISD__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
+#define MT2701_PIN_125_HDMISD__FUNC_HDMISD (MTK_PIN_NO(125) | 1)
+#define MT2701_PIN_125_HDMISD__FUNC_SCL1 (MTK_PIN_NO(125) | 4)
+#define MT2701_PIN_125_HDMISD__FUNC_PWM4 (MTK_PIN_NO(125) | 5)
+
+#define MT2701_PIN_126_I2S0_MCLK__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
+#define MT2701_PIN_126_I2S0_MCLK__FUNC_I2S0_MCLK (MTK_PIN_NO(126) | 1)
+#define MT2701_PIN_126_I2S0_MCLK__FUNC_WCN_I2S_MCLK (MTK_PIN_NO(126) | 6)
+#define MT2701_PIN_126_I2S0_MCLK__FUNC_DBG_MON_B_6 (MTK_PIN_NO(126) | 7)
+
+#define MT2701_PIN_199_SPI1_CLK__FUNC_GPIO199 (MTK_PIN_NO(199) | 0)
+#define MT2701_PIN_199_SPI1_CLK__FUNC_SPI1_CK (MTK_PIN_NO(199) | 1)
+#define MT2701_PIN_199_SPI1_CLK__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(199) | 3)
+#define MT2701_PIN_199_SPI1_CLK__FUNC_KCOL3 (MTK_PIN_NO(199) | 4)
+#define MT2701_PIN_199_SPI1_CLK__FUNC_DBG_MON_B_15 (MTK_PIN_NO(199) | 7)
+
+#define MT2701_PIN_200_SPDIF_OUT__FUNC_GPIO200 (MTK_PIN_NO(200) | 0)
+#define MT2701_PIN_200_SPDIF_OUT__FUNC_SPDIF_OUT (MTK_PIN_NO(200) | 1)
+#define MT2701_PIN_200_SPDIF_OUT__FUNC_G1_TXD3 (MTK_PIN_NO(200) | 5)
+#define MT2701_PIN_200_SPDIF_OUT__FUNC_URXD2 (MTK_PIN_NO(200) | 6)
+#define MT2701_PIN_200_SPDIF_OUT__FUNC_DBG_MON_B_16 (MTK_PIN_NO(200) | 7)
+
+#define MT2701_PIN_201_SPDIF_IN0__FUNC_GPIO201 (MTK_PIN_NO(201) | 0)
+#define MT2701_PIN_201_SPDIF_IN0__FUNC_SPDIF_IN0 (MTK_PIN_NO(201) | 1)
+#define MT2701_PIN_201_SPDIF_IN0__FUNC_G1_TXEN (MTK_PIN_NO(201) | 5)
+#define MT2701_PIN_201_SPDIF_IN0__FUNC_UTXD2 (MTK_PIN_NO(201) | 6)
+#define MT2701_PIN_201_SPDIF_IN0__FUNC_DBG_MON_B_17 (MTK_PIN_NO(201) | 7)
+
+#define MT2701_PIN_202_SPDIF_IN1__FUNC_GPIO202 (MTK_PIN_NO(202) | 0)
+#define MT2701_PIN_202_SPDIF_IN1__FUNC_SPDIF_IN1 (MTK_PIN_NO(202) | 1)
+
+#define MT2701_PIN_203_PWM0__FUNC_GPIO203 (MTK_PIN_NO(203) | 0)
+#define MT2701_PIN_203_PWM0__FUNC_PWM0 (MTK_PIN_NO(203) | 1)
+#define MT2701_PIN_203_PWM0__FUNC_DISP_PWM (MTK_PIN_NO(203) | 2)
+#define MT2701_PIN_203_PWM0__FUNC_G1_TXD2 (MTK_PIN_NO(203) | 5)
+#define MT2701_PIN_203_PWM0__FUNC_DBG_MON_B_18 (MTK_PIN_NO(203) | 7)
+#define MT2701_PIN_203_PWM0__FUNC_I2S2_DATA (MTK_PIN_NO(203) | 9)
+
+#define MT2701_PIN_204_PWM1__FUNC_GPIO204 (MTK_PIN_NO(204) | 0)
+#define MT2701_PIN_204_PWM1__FUNC_PWM1 (MTK_PIN_NO(204) | 1)
+#define MT2701_PIN_204_PWM1__FUNC_CLKM3 (MTK_PIN_NO(204) | 2)
+#define MT2701_PIN_204_PWM1__FUNC_G1_TXD1 (MTK_PIN_NO(204) | 5)
+#define MT2701_PIN_204_PWM1__FUNC_DBG_MON_B_19 (MTK_PIN_NO(204) | 7)
+#define MT2701_PIN_204_PWM1__FUNC_I2S3_DATA (MTK_PIN_NO(204) | 9)
+
+#define MT2701_PIN_205_PWM2__FUNC_GPIO205 (MTK_PIN_NO(205) | 0)
+#define MT2701_PIN_205_PWM2__FUNC_PWM2 (MTK_PIN_NO(205) | 1)
+#define MT2701_PIN_205_PWM2__FUNC_CLKM2 (MTK_PIN_NO(205) | 2)
+#define MT2701_PIN_205_PWM2__FUNC_G1_TXD0 (MTK_PIN_NO(205) | 5)
+#define MT2701_PIN_205_PWM2__FUNC_DBG_MON_B_20 (MTK_PIN_NO(205) | 7)
+
+#define MT2701_PIN_206_PWM3__FUNC_GPIO206 (MTK_PIN_NO(206) | 0)
+#define MT2701_PIN_206_PWM3__FUNC_PWM3 (MTK_PIN_NO(206) | 1)
+#define MT2701_PIN_206_PWM3__FUNC_CLKM1 (MTK_PIN_NO(206) | 2)
+#define MT2701_PIN_206_PWM3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(206) | 3)
+#define MT2701_PIN_206_PWM3__FUNC_G1_TXC (MTK_PIN_NO(206) | 5)
+#define MT2701_PIN_206_PWM3__FUNC_DBG_MON_B_21 (MTK_PIN_NO(206) | 7)
+
+#define MT2701_PIN_207_PWM4__FUNC_GPIO207 (MTK_PIN_NO(207) | 0)
+#define MT2701_PIN_207_PWM4__FUNC_PWM4 (MTK_PIN_NO(207) | 1)
+#define MT2701_PIN_207_PWM4__FUNC_CLKM0 (MTK_PIN_NO(207) | 2)
+#define MT2701_PIN_207_PWM4__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(207) | 3)
+#define MT2701_PIN_207_PWM4__FUNC_G1_RXC (MTK_PIN_NO(207) | 5)
+#define MT2701_PIN_207_PWM4__FUNC_DBG_MON_B_22 (MTK_PIN_NO(207) | 7)
+
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_GPIO208 (MTK_PIN_NO(208) | 0)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_AUD_EXT_CK1 (MTK_PIN_NO(208) | 1)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_PWM0 (MTK_PIN_NO(208) | 2)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_ANT_SEL5 (MTK_PIN_NO(208) | 4)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_DISP_PWM (MTK_PIN_NO(208) | 5)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_DBG_MON_A_31 (MTK_PIN_NO(208) | 7)
+#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_PCIE0_PERST_N (MTK_PIN_NO(208) | 11)
+
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_GPIO209 (MTK_PIN_NO(209) | 0)
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_AUD_EXT_CK2 (MTK_PIN_NO(209) | 1)
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_MSDC1_WP (MTK_PIN_NO(209) | 2)
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_PWM1 (MTK_PIN_NO(209) | 5)
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_DBG_MON_A_32 (MTK_PIN_NO(209) | 7)
+#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_PCIE1_PERST_N (MTK_PIN_NO(209) | 11)
+
+#define MT2701_PIN_236_EXT_SDIO3__FUNC_GPIO236 (MTK_PIN_NO(236) | 0)
+#define MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3 (MTK_PIN_NO(236) | 1)
+#define MT2701_PIN_236_EXT_SDIO3__FUNC_IDDIG (MTK_PIN_NO(236) | 2)
+#define MT2701_PIN_236_EXT_SDIO3__FUNC_DBG_MON_A_1 (MTK_PIN_NO(236) | 7)
+
+#define MT2701_PIN_237_EXT_SDIO2__FUNC_GPIO237 (MTK_PIN_NO(237) | 0)
+#define MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2 (MTK_PIN_NO(237) | 1)
+#define MT2701_PIN_237_EXT_SDIO2__FUNC_DRV_VBUS (MTK_PIN_NO(237) | 2)
+
+#define MT2701_PIN_238_EXT_SDIO1__FUNC_GPIO238 (MTK_PIN_NO(238) | 0)
+#define MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1 (MTK_PIN_NO(238) | 1)
+#define MT2701_PIN_238_EXT_SDIO1__FUNC_IDDIG_P1 (MTK_PIN_NO(238) | 2)
+
+#define MT2701_PIN_239_EXT_SDIO0__FUNC_GPIO239 (MTK_PIN_NO(239) | 0)
+#define MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0 (MTK_PIN_NO(239) | 1)
+#define MT2701_PIN_239_EXT_SDIO0__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(239) | 2)
+
+#define MT2701_PIN_240_EXT_XCS__FUNC_GPIO240 (MTK_PIN_NO(240) | 0)
+#define MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS (MTK_PIN_NO(240) | 1)
+
+#define MT2701_PIN_241_EXT_SCK__FUNC_GPIO241 (MTK_PIN_NO(241) | 0)
+#define MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK (MTK_PIN_NO(241) | 1)
+
+#define MT2701_PIN_242_URTS2__FUNC_GPIO242 (MTK_PIN_NO(242) | 0)
+#define MT2701_PIN_242_URTS2__FUNC_URTS2 (MTK_PIN_NO(242) | 1)
+#define MT2701_PIN_242_URTS2__FUNC_UTXD3 (MTK_PIN_NO(242) | 2)
+#define MT2701_PIN_242_URTS2__FUNC_URXD3 (MTK_PIN_NO(242) | 3)
+#define MT2701_PIN_242_URTS2__FUNC_SCL1 (MTK_PIN_NO(242) | 4)
+#define MT2701_PIN_242_URTS2__FUNC_DBG_MON_B_32 (MTK_PIN_NO(242) | 7)
+
+#define MT2701_PIN_243_UCTS2__FUNC_GPIO243 (MTK_PIN_NO(243) | 0)
+#define MT2701_PIN_243_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(243) | 1)
+#define MT2701_PIN_243_UCTS2__FUNC_URXD3 (MTK_PIN_NO(243) | 2)
+#define MT2701_PIN_243_UCTS2__FUNC_UTXD3 (MTK_PIN_NO(243) | 3)
+#define MT2701_PIN_243_UCTS2__FUNC_SDA1 (MTK_PIN_NO(243) | 4)
+#define MT2701_PIN_243_UCTS2__FUNC_DBG_MON_A_6 (MTK_PIN_NO(243) | 7)
+
+#define MT2701_PIN_244_HDMI_SDA_RX__FUNC_GPIO244 (MTK_PIN_NO(244) | 0)
+#define MT2701_PIN_244_HDMI_SDA_RX__FUNC_HDMI_SDA_RX (MTK_PIN_NO(244) | 1)
+
+#define MT2701_PIN_245_HDMI_SCL_RX__FUNC_GPIO245 (MTK_PIN_NO(245) | 0)
+#define MT2701_PIN_245_HDMI_SCL_RX__FUNC_HDMI_SCL_RX (MTK_PIN_NO(245) | 1)
+
+#define MT2701_PIN_246_MHL_SENCE__FUNC_GPIO246 (MTK_PIN_NO(246) | 0)
+
+#define MT2701_PIN_247_HDMI_HPD_CBUS_RX__FUNC_GPIO247 (MTK_PIN_NO(247) | 0)
+#define MT2701_PIN_247_HDMI_HPD_CBUS_RX__FUNC_HDMI_HPD_RX (MTK_PIN_NO(247) | 1)
+
+#define MT2701_PIN_248_HDMI_TESTOUTP_RX__FUNC_GPIO248 (MTK_PIN_NO(248) | 0)
+#define MT2701_PIN_248_HDMI_TESTOUTP_RX__FUNC_HDMI_TESTOUTP_RX (MTK_PIN_NO(248) | 1)
+
+#define MT2701_PIN_249_MSDC0E_RSTB__FUNC_MSDC0E_RSTB (MTK_PIN_NO(249) | 9)
+
+#define MT2701_PIN_250_MSDC0E_DAT7__FUNC_MSDC3_DAT7 (MTK_PIN_NO(250) | 9)
+#define MT2701_PIN_250_MSDC0E_DAT7__FUNC_PCIE0_CLKREQ_N (MTK_PIN_NO(250) | 14)
+
+#define MT2701_PIN_251_MSDC0E_DAT6__FUNC_MSDC3_DAT6 (MTK_PIN_NO(251) | 9)
+#define MT2701_PIN_251_MSDC0E_DAT6__FUNC_PCIE0_WAKE_N (MTK_PIN_NO(251) | 14)
+
+#define MT2701_PIN_252_MSDC0E_DAT5__FUNC_MSDC3_DAT5 (MTK_PIN_NO(252) | 9)
+#define MT2701_PIN_252_MSDC0E_DAT5__FUNC_PCIE1_CLKREQ_N (MTK_PIN_NO(252) | 14)
+
+#define MT2701_PIN_253_MSDC0E_DAT4__FUNC_MSDC3_DAT4 (MTK_PIN_NO(253) | 9)
+#define MT2701_PIN_253_MSDC0E_DAT4__FUNC_PCIE1_WAKE_N (MTK_PIN_NO(253) | 14)
+
+#define MT2701_PIN_254_MSDC0E_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(254) | 9)
+#define MT2701_PIN_254_MSDC0E_DAT3__FUNC_PCIE2_CLKREQ_N (MTK_PIN_NO(254) | 14)
+
+#define MT2701_PIN_255_MSDC0E_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(255) | 9)
+#define MT2701_PIN_255_MSDC0E_DAT2__FUNC_PCIE2_WAKE_N (MTK_PIN_NO(255) | 14)
+
+#define MT2701_PIN_256_MSDC0E_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(256) | 9)
+
+#define MT2701_PIN_257_MSDC0E_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(257) | 9)
+
+#define MT2701_PIN_258_MSDC0E_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(258) | 9)
+
+#define MT2701_PIN_259_MSDC0E_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(259) | 9)
+
+#define MT2701_PIN_260_MSDC0E_DSL__FUNC_MSDC3_DSL (MTK_PIN_NO(260) | 9)
+
+#define MT2701_PIN_261_MSDC1_INS__FUNC_GPIO261 (MTK_PIN_NO(261) | 0)
+#define MT2701_PIN_261_MSDC1_INS__FUNC_MSDC1_INS (MTK_PIN_NO(261) | 1)
+#define MT2701_PIN_261_MSDC1_INS__FUNC_DBG_MON_B_29 (MTK_PIN_NO(261) | 7)
+
+#define MT2701_PIN_262_G2_TXEN__FUNC_GPIO262 (MTK_PIN_NO(262) | 0)
+#define MT2701_PIN_262_G2_TXEN__FUNC_G2_TXEN (MTK_PIN_NO(262) | 1)
+
+#define MT2701_PIN_263_G2_TXD3__FUNC_GPIO263 (MTK_PIN_NO(263) | 0)
+#define MT2701_PIN_263_G2_TXD3__FUNC_G2_TXD3 (MTK_PIN_NO(263) | 1)
+#define MT2701_PIN_263_G2_TXD3__FUNC_ANT_SEL5 (MTK_PIN_NO(263) | 6)
+
+#define MT2701_PIN_264_G2_TXD2__FUNC_GPIO264 (MTK_PIN_NO(264) | 0)
+#define MT2701_PIN_264_G2_TXD2__FUNC_G2_TXD2 (MTK_PIN_NO(264) | 1)
+#define MT2701_PIN_264_G2_TXD2__FUNC_ANT_SEL4 (MTK_PIN_NO(264) | 6)
+
+#define MT2701_PIN_265_G2_TXD1__FUNC_GPIO265 (MTK_PIN_NO(265) | 0)
+#define MT2701_PIN_265_G2_TXD1__FUNC_G2_TXD1 (MTK_PIN_NO(265) | 1)
+#define MT2701_PIN_265_G2_TXD1__FUNC_ANT_SEL3 (MTK_PIN_NO(265) | 6)
+
+#define MT2701_PIN_266_G2_TXD0__FUNC_GPIO266 (MTK_PIN_NO(266) | 0)
+#define MT2701_PIN_266_G2_TXD0__FUNC_G2_TXD0 (MTK_PIN_NO(266) | 1)
+#define MT2701_PIN_266_G2_TXD0__FUNC_ANT_SEL2 (MTK_PIN_NO(266) | 6)
+
+#define MT2701_PIN_267_G2_TXC__FUNC_GPIO267 (MTK_PIN_NO(267) | 0)
+#define MT2701_PIN_267_G2_TXC__FUNC_G2_TXC (MTK_PIN_NO(267) | 1)
+
+#define MT2701_PIN_268_G2_RXC__FUNC_GPIO268 (MTK_PIN_NO(268) | 0)
+#define MT2701_PIN_268_G2_RXC__FUNC_G2_RXC (MTK_PIN_NO(268) | 1)
+
+#define MT2701_PIN_269_G2_RXD0__FUNC_GPIO269 (MTK_PIN_NO(269) | 0)
+#define MT2701_PIN_269_G2_RXD0__FUNC_G2_RXD0 (MTK_PIN_NO(269) | 1)
+
+#define MT2701_PIN_270_G2_RXD1__FUNC_GPIO270 (MTK_PIN_NO(270) | 0)
+#define MT2701_PIN_270_G2_RXD1__FUNC_G2_RXD1 (MTK_PIN_NO(270) | 1)
+
+#define MT2701_PIN_271_G2_RXD2__FUNC_GPIO271 (MTK_PIN_NO(271) | 0)
+#define MT2701_PIN_271_G2_RXD2__FUNC_G2_RXD2 (MTK_PIN_NO(271) | 1)
+
+#define MT2701_PIN_272_G2_RXD3__FUNC_GPIO272 (MTK_PIN_NO(272) | 0)
+#define MT2701_PIN_272_G2_RXD3__FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1)
+
+#define MT2701_PIN_274_G2_RXDV__FUNC_GPIO274 (MTK_PIN_NO(274) | 0)
+#define MT2701_PIN_274_G2_RXDV__FUNC_G2_RXDV (MTK_PIN_NO(274) | 1)
+
+#define MT2701_PIN_275_MDC__FUNC_GPIO275 (MTK_PIN_NO(275) | 0)
+#define MT2701_PIN_275_MDC__FUNC_MDC (MTK_PIN_NO(275) | 1)
+#define MT2701_PIN_275_MDC__FUNC_ANT_SEL0 (MTK_PIN_NO(275) | 6)
+
+#define MT2701_PIN_276_MDIO__FUNC_GPIO276 (MTK_PIN_NO(276) | 0)
+#define MT2701_PIN_276_MDIO__FUNC_MDIO (MTK_PIN_NO(276) | 1)
+#define MT2701_PIN_276_MDIO__FUNC_ANT_SEL1 (MTK_PIN_NO(276) | 6)
+
+#define MT2701_PIN_278_JTAG_RESET__FUNC_GPIO278 (MTK_PIN_NO(278) | 0)
+#define MT2701_PIN_278_JTAG_RESET__FUNC_JTAG_RESET (MTK_PIN_NO(278) | 1)
+
+#endif /* __DTS_MT2701_PINFUNC_H */
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
new file mode 100644
index 0000000..3766904
--- /dev/null
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Erin.Lo <erin.lo@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,mt2701";
+ 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>;
+ };
+ };
+
+ 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 {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ 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)>;
+ };
+
+ watchdog: watchdog@10007000 {
+ compatible = "mediatek,mt2701-wdt",
+ "mediatek,mt6589-wdt";
+ reg = <0 0x10007000 0 0x100>;
+ };
+
+ timer: timer@10008000 {
+ compatible = "mediatek,mt2701-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,mt2701-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@11002000 {
+ compatible = "mediatek,mt2701-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11002000 0 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,mt2701-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11003000 0 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,mt2701-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11004000 0 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,mt2701-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/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
index ca3402e..52086c8 100644
--- a/arch/arm/boot/dts/mt8127.dtsi
+++ b/arch/arm/boot/dts/mt8127.dtsi
@@ -23,6 +23,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
+ enable-method = "mediatek,mt81xx-tz-smp";
cpu@0 {
device_type = "cpu";
@@ -47,6 +48,17 @@
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ trustzone-bootinfo@80002000 {
+ compatible = "mediatek,trustzone-bootinfo";
+ reg = <0 0x80002000 0 0x1000>;
+ };
+ };
+
clocks {
#address-cells = <2>;
#size-cells = <2>;
@@ -72,6 +84,21 @@
};
};
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ 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 = <13000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
soc {
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm/boot/dts/mt8135-evbp1.dts b/arch/arm/boot/dts/mt8135-evbp1.dts
index 357a91f..460db6d 100644
--- a/arch/arm/boot/dts/mt8135-evbp1.dts
+++ b/arch/arm/boot/dts/mt8135-evbp1.dts
@@ -32,7 +32,6 @@
compatible = "mediatek,mt6397-regulator";
mt6397_vpca15_reg: buck_vpca15 {
- regulator-compatible = "buck_vpca15";
regulator-name = "vpca15";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
@@ -41,7 +40,6 @@
};
mt6397_vpca7_reg: buck_vpca7 {
- regulator-compatible = "buck_vpca7";
regulator-name = "vpca7";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
@@ -50,7 +48,6 @@
};
mt6397_vsramca15_reg: buck_vsramca15 {
- regulator-compatible = "buck_vsramca15";
regulator-name = "vsramca15";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
@@ -59,7 +56,6 @@
};
mt6397_vsramca7_reg: buck_vsramca7 {
- regulator-compatible = "buck_vsramca7";
regulator-name = "vsramca7";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
@@ -68,7 +64,6 @@
};
mt6397_vcore_reg: buck_vcore {
- regulator-compatible = "buck_vcore";
regulator-name = "vcore";
regulator-min-microvolt = < 850000>;
regulator-max-microvolt = <1350000>;
@@ -77,7 +72,6 @@
};
mt6397_vgpu_reg: buck_vgpu {
- regulator-compatible = "buck_vgpu";
regulator-name = "vgpu";
regulator-min-microvolt = < 700000>;
regulator-max-microvolt = <1350000>;
@@ -86,7 +80,6 @@
};
mt6397_vdrm_reg: buck_vdrm {
- regulator-compatible = "buck_vdrm";
regulator-name = "vdrm";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1400000>;
@@ -95,7 +88,6 @@
};
mt6397_vio18_reg: buck_vio18 {
- regulator-compatible = "buck_vio18";
regulator-name = "vio18";
regulator-min-microvolt = <1620000>;
regulator-max-microvolt = <1980000>;
@@ -104,19 +96,16 @@
};
mt6397_vtcxo_reg: ldo_vtcxo {
- regulator-compatible = "ldo_vtcxo";
regulator-name = "vtcxo";
regulator-always-on;
};
mt6397_va28_reg: ldo_va28 {
- regulator-compatible = "ldo_va28";
regulator-name = "va28";
regulator-always-on;
};
mt6397_vcama_reg: ldo_vcama {
- regulator-compatible = "ldo_vcama";
regulator-name = "vcama";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2800000>;
@@ -124,18 +113,15 @@
};
mt6397_vio28_reg: ldo_vio28 {
- regulator-compatible = "ldo_vio28";
regulator-name = "vio28";
regulator-always-on;
};
mt6397_vusb_reg: ldo_vusb {
- regulator-compatible = "ldo_vusb";
regulator-name = "vusb";
};
mt6397_vmc_reg: ldo_vmc {
- regulator-compatible = "ldo_vmc";
regulator-name = "vmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
@@ -143,7 +129,6 @@
};
mt6397_vmch_reg: ldo_vmch {
- regulator-compatible = "ldo_vmch";
regulator-name = "vmch";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
@@ -151,7 +136,6 @@
};
mt6397_vemc_3v3_reg: ldo_vemc3v3 {
- regulator-compatible = "ldo_vemc3v3";
regulator-name = "vemc_3v3";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
@@ -159,7 +143,6 @@
};
mt6397_vgp1_reg: ldo_vgp1 {
- regulator-compatible = "ldo_vgp1";
regulator-name = "vcamd";
regulator-min-microvolt = <1220000>;
regulator-max-microvolt = <3300000>;
@@ -167,7 +150,6 @@
};
mt6397_vgp2_reg: ldo_vgp2 {
- regulator-compatible = "ldo_vgp2";
regulator-name = "vcamio";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
@@ -175,7 +157,6 @@
};
mt6397_vgp3_reg: ldo_vgp3 {
- regulator-compatible = "ldo_vgp3";
regulator-name = "vcamaf";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
@@ -183,7 +164,6 @@
};
mt6397_vgp4_reg: ldo_vgp4 {
- regulator-compatible = "ldo_vgp4";
regulator-name = "vgp4";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
@@ -191,7 +171,6 @@
};
mt6397_vgp5_reg: ldo_vgp5 {
- regulator-compatible = "ldo_vgp5";
regulator-name = "vgp5";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3000000>;
@@ -199,7 +178,6 @@
};
mt6397_vgp6_reg: ldo_vgp6 {
- regulator-compatible = "ldo_vgp6";
regulator-name = "vgp6";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
@@ -207,7 +185,6 @@
};
mt6397_vibr_reg: ldo_vibr {
- regulator-compatible = "ldo_vibr";
regulator-name = "vibr";
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
index 08371db..1d7f92b 100644
--- a/arch/arm/boot/dts/mt8135.dtsi
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -15,7 +15,7 @@
#include <dt-bindings/clock/mt8135-clk.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset-controller/mt8135-resets.h>
+#include <dt-bindings/reset/mt8135-resets.h>
#include "skeleton64.dtsi"
#include "mt8135-pinfunc.h"
@@ -46,6 +46,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
+ enable-method = "mediatek,mt81xx-tz-smp";
cpu0: cpu@0 {
device_type = "cpu";
@@ -72,6 +73,17 @@
};
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ trustzone-bootinfo@80002000 {
+ compatible = "mediatek,trustzone-bootinfo";
+ reg = <0 0x80002000 0 0x1000>;
+ };
+ };
+
clocks {
#address-cells = <2>;
#size-cells = <2>;
@@ -97,6 +109,21 @@
};
};
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ 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 = <13000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
soc {
#address-cells = <2>;
#size-cells = <2>;
diff --git a/arch/arm/boot/dts/nspire.dtsi b/arch/arm/boot/dts/nspire.dtsi
index 390c91a..ee5a0bb 100644
--- a/arch/arm/boot/dts/nspire.dtsi
+++ b/arch/arm/boot/dts/nspire.dtsi
@@ -16,7 +16,7 @@
cpus {
cpu@0 {
- compatible = "arm,arm926ejs";
+ compatible = "arm,arm926ej-s";
};
};
diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index c9f1e93..8491f46 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -9,9 +9,9 @@
ocp {
i2c@0 {
compatible = "i2c-cbus-gpio";
- gpios = <&gpio3 2 0 /* gpio66 clk */
- &gpio3 1 0 /* gpio65 dat */
- &gpio3 0 0 /* gpio64 sel */
+ gpios = <&gpio3 2 GPIO_ACTIVE_HIGH /* gpio66 clk */
+ &gpio3 1 GPIO_ACTIVE_HIGH /* gpio65 dat */
+ &gpio3 0 GPIO_ACTIVE_HIGH /* gpio64 sel */
>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts
index 7c4dca1..01e1e2d 100644
--- a/arch/arm/boot/dts/omap3-beagle-xm.dts
+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts
@@ -69,7 +69,7 @@
label = "user";
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
linux,code = <0x114>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -80,7 +80,7 @@
regulator-name = "hsusb2_vbus";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ gpio = <&twl_gpio 18 GPIO_ACTIVE_HIGH>; /* GPIO LEDA */
startup-delay-us = <70000>;
};
@@ -176,18 +176,18 @@
&omap3_pmx_wkup {
gpio1_pins: pinmux_gpio1_pins {
pinctrl-single,pins = <
- 0x0e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
+ OMAP3_WKUP_IOPAD(0x2a0e, 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_WKUP_IOPAD(0x2a0a, 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 */
>;
};
};
@@ -200,8 +200,8 @@
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 */
+ 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 OUTPUT | MODE0 */
>;
};
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 67659a0..8ba465d 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -55,7 +55,7 @@
regulator-name = "hsusb2_vbus";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ gpio = <&twl_gpio 18 GPIO_ACTIVE_HIGH>; /* GPIO LEDA */
startup-delay-us = <70000>;
};
@@ -80,7 +80,7 @@
label = "user";
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
linux,code = <0x114>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -171,7 +171,7 @@
&omap3_pmx_wkup {
gpio1_pins: pinmux_gpio1_pins {
pinctrl-single,pins = <
- 0x14 (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
+ OMAP3_WKUP_IOPAD(0x2a14, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
>;
};
};
@@ -195,47 +195,47 @@
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 */
+ 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 */
>;
};
tfp410_pins: pinmux_tfp410_pins {
pinctrl-single,pins = <
- 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ OMAP3_CORE1_IOPAD(0x21c6, 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_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 */
>;
};
};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
index 4d091ca..e5f7f5c 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -224,7 +224,7 @@
interrupt-parent = <&gpio2>;
interrupts = <25 0>; /* gpio_57 */
- pendown-gpio = <&gpio2 25 0>;
+ pendown-gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>;
ti,x-min = /bits/ 16 <0x0>;
ti,x-max = /bits/ 16 <0x0fff>;
@@ -238,7 +238,7 @@
ti,debounce-tol = /bits/ 16 <10>;
ti,debounce-rep = /bits/ 16 <1>;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 9ca2865a..86850bb 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -64,7 +64,7 @@
label = "user";
gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
linux,code = <BTN_EXTRA>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
index e84184d..738910d 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
@@ -54,7 +54,7 @@
interrupt-parent = <&gpio1>;
interrupts = <27 0>; /* gpio_27 */
- pendown-gpio = <&gpio1 27 0>;
+ pendown-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
ti,x-min = /bits/ 16 <0x0>;
ti,x-max = /bits/ 16 <0x0fff>;
@@ -68,6 +68,6 @@
ti,keep-vref-on = <1>;
ti,settle-delay-usec = /bits/ 16 <150>;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index bb339d1..ac18865 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -66,48 +66,48 @@
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 */
+ OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT_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 */
>;
};
/* 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 */
+ 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, WAKEUP_EN | 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 */
>;
};
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 */
+ OMAP3_CORE1_IOPAD(0x219e, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, 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 */
+ OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4) /* uart1_cts.gpio_150 */
+ OMAP3_CORE1_IOPAD(0x217e, 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_CORE1_IOPAD(0x21d2, PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */
>;
};
};
@@ -115,12 +115,12 @@
&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 */
+ OMAP3_WKUP_IOPAD(0x2a0a, 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 */
>;
};
};
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
index b2589f9..0904750 100644
--- a/arch/arm/boot/dts/omap3-evm-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -26,7 +26,7 @@
regulator-name = "vwl1271";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&gpio5 22 0>; /* gpio150 */
+ gpio = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* gpio150 */
startup-delay-us = <70000>;
enable-active-high;
vin-supply = <&vmmc2>;
@@ -91,7 +91,7 @@
tsc2046@0 {
interrupt-parent = <&gpio6>;
interrupts = <15 0>; /* gpio175 */
- pendown-gpio = <&gpio6 15 0>;
+ pendown-gpio = <&gpio6 15 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
index 7166d88..5e2d643 100644
--- a/arch/arm/boot/dts/omap3-gta04.dtsi
+++ b/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -37,7 +37,7 @@
label = "aux";
linux,code = <169>;
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -77,10 +77,10 @@
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>;
+ gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
num-chipselects = <1>;
/* lcd panel */
@@ -118,7 +118,7 @@
tv_amp: opa362 {
compatible = "ti,opa362";
- enable-gpios = <&gpio1 23 0>;
+ enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/omap3-gta04a5.dts b/arch/arm/boot/dts/omap3-gta04a5.dts
index 52b386f..600b6ca 100644
--- a/arch/arm/boot/dts/omap3-gta04a5.dts
+++ b/arch/arm/boot/dts/omap3-gta04a5.dts
@@ -12,6 +12,6 @@
model = "Goldelico GTA04A5";
sound {
- ti,jack-det-gpio = <&twl_gpio 2 0>; /* GTA04A5 only */
+ ti,jack-det-gpio = <&twl_gpio 2 GPIO_ACTIVE_HIGH>; /* GTA04A5 only */
};
};
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index 2230e1c..3caf062 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -1,7 +1,7 @@
/*
* Common device tree for IGEP boards based on AM/DM37x
*
- * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -35,60 +35,60 @@
&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 */
+ OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ OMAP3_CORE1_IOPAD(0x217c, 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 */
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx.uart3_rx */
+ OMAP3_CORE1_IOPAD(0x21a0, 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 */
+ OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx.mcbsp2_fsx */
+ OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx.mcbsp2_clkx */
+ OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr.mcbsp2.dr */
+ OMAP3_CORE1_IOPAD(0x2142, 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 */
+ 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 = <
- 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 */
+ 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 */
>;
};
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 */
+ OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc, 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 */
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
>;
};
};
@@ -155,7 +155,7 @@
twl_audio: audio {
compatible = "ti,twl4030-audio";
codec {
- };
+ };
};
};
};
@@ -175,11 +175,11 @@
};
&mmc1 {
- pinctrl-names = "default";
- pinctrl-0 = <&mmc1_pins>;
- vmmc-supply = <&vmmc1>;
- vmmc_aux-supply = <&vsim>;
- bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <4>;
};
&mmc3 {
@@ -187,13 +187,13 @@
};
&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
};
&uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart3_pins>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
};
&twl_gpio {
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index 5ad688c..d90f12c 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -1,7 +1,7 @@
/*
* Common Device Tree Source for IGEPv2
*
- * Copyright (C) 2014 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -111,40 +111,40 @@
tfp410_pins: pinmux_tfp410_pins {
pinctrl-single,pins = <
- 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ OMAP3_CORE1_IOPAD(0x21c6, 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_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 */
>;
};
diff --git a/arch/arm/boot/dts/omap3-igep0020-rev-f.dts b/arch/arm/boot/dts/omap3-igep0020-rev-f.dts
index 72f7cdc..321c2b7 100644
--- a/arch/arm/boot/dts/omap3-igep0020-rev-f.dts
+++ b/arch/arm/boot/dts/omap3-igep0020-rev-f.dts
@@ -1,7 +1,7 @@
/*
* Device Tree Source for IGEPv2 Rev. F (TI OMAP AM/DM37x)
*
- * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts
index fea7f7e..33d6b4e 100644
--- a/arch/arm/boot/dts/omap3-igep0020.dts
+++ b/arch/arm/boot/dts/omap3-igep0020.dts
@@ -1,7 +1,7 @@
/*
* Device Tree Source for IGEPv2 Rev. C (TI OMAP AM/DM37x)
*
- * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -15,25 +15,17 @@
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 {
+ vmmcsdio_fixed: fixedregulator-mmcsdio {
compatible = "regulator-fixed";
- regulator-name = "regulator-lbee1usjyc-pdn";
+ regulator-name = "vmmcsdio_fixed";
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;
+ mmc2_pwrseq: mmc2_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>, /* gpio_139 - RESET_N_W */
+ <&gpio5 10 GPIO_ACTIVE_LOW>; /* gpio_138 - WIFI_PDN */
};
};
@@ -45,23 +37,14 @@
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>;
+ vmmc-supply = <&vmmcsdio_fixed>;
+ mmc-pwrseq = <&mmc2_pwrseq>;
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
index 0cb1527..640f066 100644
--- a/arch/arm/boot/dts/omap3-igep0030-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0030-common.dtsi
@@ -1,7 +1,7 @@
/*
* Common Device Tree Source for IGEP COM MODULE
*
- * Copyright (C) 2014 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/boot/dts/omap3-igep0030-rev-g.dts b/arch/arm/boot/dts/omap3-igep0030-rev-g.dts
index b899e34..76dc088 100644
--- a/arch/arm/boot/dts/omap3-igep0030-rev-g.dts
+++ b/arch/arm/boot/dts/omap3-igep0030-rev-g.dts
@@ -1,7 +1,7 @@
/*
* 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 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts
index 8150f47..55b0cc4 100644
--- a/arch/arm/boot/dts/omap3-igep0030.dts
+++ b/arch/arm/boot/dts/omap3-igep0030.dts
@@ -1,7 +1,7 @@
/*
* 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 Javier Martinez Canillas <javier@osg.samsung.com>
* Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -15,25 +15,17 @@
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 {
+ vmmcsdio_fixed: fixedregulator-mmcsdio {
compatible = "regulator-fixed";
- regulator-name = "regulator-lbee1usjyc-pdn";
+ regulator-name = "vmmcsdio_fixed";
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;
+ mmc2_pwrseq: mmc2_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>, /* gpio_139 - RESET_N_W */
+ <&gpio5 10 GPIO_ACTIVE_LOW>; /* gpio_138 - WIFI_PDN */
};
};
@@ -62,8 +54,8 @@
&mmc2 {
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
- vmmc-supply = <&lbee1usjyc_pdn>;
- vmmc_aux-supply = <&lbee1usjyc_reset_n_w>;
+ vmmc-supply = <&vmmcsdio_fixed>;
+ mmc-pwrseq = <&mmc2_pwrseq>;
bus-width = <4>;
non-removable;
};
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index bd6e676..5401630 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -35,63 +35,63 @@
label = "enter";
gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* gpio101 */
linux,code = <KEY_ENTER>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_f1 {
label = "f1";
gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* gpio102 */
linux,code = <KEY_F1>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_f2 {
label = "f2";
gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* gpio103 */
linux,code = <KEY_F2>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_f3 {
label = "f3";
gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* gpio104 */
linux,code = <KEY_F3>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_f4 {
label = "f4";
gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* gpio105 */
linux,code = <KEY_F4>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_left {
label = "left";
gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */
linux,code = <KEY_LEFT>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_right {
label = "right";
gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* gpio107 */
linux,code = <KEY_RIGHT>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_up {
label = "up";
gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; /* gpio108 */
linux,code = <KEY_UP>;
- gpio-key,wakeup;
+ wakeup-source;
};
key_down {
label = "down";
gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* gpio109 */
linux,code = <KEY_DOWN>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
@@ -200,7 +200,7 @@
tsc2046@0 {
interrupt-parent = <&gpio2>;
interrupts = <22 0>; /* gpio54 */
- pendown-gpio = <&gpio2 22 0>;
+ pendown-gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>;
};
};
@@ -224,32 +224,32 @@
&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 */
+ OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE4) /* cam_d2.gpio_101 */
+ OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE4) /* cam_d3.gpio_102 */
+ OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE4) /* cam_d4.gpio_103 */
+ OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE4) /* cam_d5.gpio_104 */
+ OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE4) /* cam_d6.gpio_105 */
+ OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE4) /* cam_d7.gpio_106 */
+ OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT | MUX_MODE4) /* cam_d8.gpio_107 */
+ OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT | MUX_MODE4) /* cam_d9.gpio_108 */
+ OMAP3_CORE1_IOPAD(0x212a, 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 */
+ OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */
+ 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 */
+ 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(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */
>;
};
diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
index d0dd036..93f8dfe 100644
--- a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
+++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
@@ -284,7 +284,7 @@
};
&mmc1 {
- cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
+ cd-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>;
cd-inverted;
vmmc-supply = <&vmmc1>;
bus-width = <4>;
@@ -314,7 +314,7 @@
interrupt-parent = <&gpio1>;
interrupts = <8 0>; /* boot6 / gpio_8 */
spi-max-frequency = <1000000>;
- pendown-gpio = <&gpio1 8 0>;
+ pendown-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
vcc-supply = <&reg_vcc3>;
pinctrl-names = "default";
pinctrl-0 = <&tsc2048_pins>;
@@ -327,7 +327,7 @@
ti,pressure-max = /bits/ 16 <255>;
ti,swap-xy;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-lilly-dbb056.dts b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
index 834f7c6..0e3c981 100644
--- a/arch/arm/boot/dts/omap3-lilly-dbb056.dts
+++ b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
@@ -114,8 +114,8 @@
status = "okay";
bus-width = <4>;
vmmc-supply = <&vmmc1>;
- cd-gpios = <&gpio6 4 0>; /* gpio_164 */
- wp-gpios = <&gpio6 3 0>; /* gpio_163 */
+ cd-gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* gpio_164 */
+ wp-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* gpio_163 */
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins>;
ti,dual-volt;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 5f5e0f3..e3bdcf8 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -67,28 +67,28 @@
gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */
linux,input-type = <5>; /* EV_SW */
linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */
- gpio-key,wakeup;
+ wakeup-source;
};
camera_focus {
label = "Camera Focus";
gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */
linux,code = <0x210>; /* KEY_CAMERA_FOCUS */
- gpio-key,wakeup;
+ wakeup-source;
};
camera_capture {
label = "Camera Capture";
gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */
linux,code = <0xd4>; /* KEY_CAMERA */
- gpio-key,wakeup;
+ wakeup-source;
};
lock_button {
label = "Lock Button";
gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */
linux,code = <0x98>; /* KEY_SCREENLOCK */
- gpio-key,wakeup;
+ wakeup-source;
};
keypad_slide {
@@ -96,7 +96,7 @@
gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */
linux,input-type = <5>; /* EV_SW */
linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */
- gpio-key,wakeup;
+ wakeup-source;
};
proximity_sensor {
@@ -107,8 +107,8 @@
};
};
- isp1704: isp1704 {
- compatible = "nxp,isp1704";
+ isp1707: isp1707 {
+ compatible = "nxp,isp1707";
nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
usb-phy = <&usb2_phy>;
};
@@ -149,15 +149,15 @@
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
- 0x14a (PIN_INPUT | MUX_MODE0) /* uart2_rx */
- 0x148 (PIN_OUTPUT | MUX_MODE0) /* uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx */
+ OMAP3_CORE1_IOPAD(0x2178, 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 */
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx */
>;
};
@@ -198,22 +198,22 @@
i2c1_pins: pinmux_i2c1_pins {
pinctrl-single,pins = <
- 0x18a (PIN_INPUT | MUX_MODE0) /* i2c1_scl */
- 0x18c (PIN_INPUT | MUX_MODE0) /* i2c1_sda */
+ OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc, 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 */
+ OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0) /* i2c2_scl */
+ OMAP3_CORE1_IOPAD(0x21c0, 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 */
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda */
>;
};
@@ -225,85 +225,85 @@
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 */
+ OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */
+ OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */
+ OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */
+ OMAP3_CORE1_IOPAD(0x2196, 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 */
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, 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 */
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat4 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat5 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat6 */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat7 */
>;
};
acx565akm_pins: pinmux_acx565akm_pins {
pinctrl-single,pins = <
- 0x0d4 (PIN_OUTPUT | MUX_MODE4) /* RX51_LCD_RESET_GPIO */
+ OMAP3_CORE1_IOPAD(0x2104, 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 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE1) /* dss_data10.sdi_dat1n */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE1) /* dss_data11.sdi_dat1p */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE1) /* dss_data12.sdi_dat2n */
+ OMAP3_CORE1_IOPAD(0x20f6, 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 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE1) /* dss_data22.sdi_clkp */
+ OMAP3_CORE1_IOPAD(0x210a, 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 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE4) /* gpio 87 => wl1251 enable */
+ OMAP3_CORE1_IOPAD(0x208a, 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 */
+ OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT_PULLUP | MUX_MODE1) /* ssi1_rdy_tx */
+ OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE1) /* ssi1_flag_tx */
+ OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */
+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE1) /* ssi1_dat_tx */
+ OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT | MUX_MODE1) /* ssi1_dat_rx */
+ OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE1) /* ssi1_flag_rx */
+ OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE1) /* ssi1_rdy_rx */
+ OMAP3_CORE1_IOPAD(0x218a, 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 */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE4) /* gpio 70 => cmt_apeslpx */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* gpio 72 => ape_rst_rq */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE4) /* gpio 73 => cmt_rst_rq */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE4) /* gpio 74 => cmt_en */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE4) /* gpio 75 => cmt_rst */
+ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* gpio 157 => cmt_bsi */
>;
};
};
@@ -618,7 +618,7 @@
ti,termination-current = <100>;
ti,resistor-sense = <68>;
- ti,usb-charger-detection = <&isp1704>;
+ ti,usb-charger-detection = <&isp1707>;
};
};
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 800b379..a2c2b8d 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -27,7 +27,7 @@
regulator-name = "VEMMC";
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>;
- gpio = <&gpio5 29 0>; /* gpio line 157 */
+ gpio = <&gpio5 29 GPIO_ACTIVE_HIGH>; /* gpio line 157 */
startup-delay-us = <150>;
enable-active-high;
};
@@ -36,12 +36,12 @@
&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 */
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */
>;
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi b/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
index 7aae8fb..3b3a759 100644
--- a/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
@@ -48,7 +48,7 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* gpio_10 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi
index 28430f1..a29ad16 100644
--- a/arch/arm/boot/dts/omap3-overo-base.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-base.dtsi
@@ -35,7 +35,7 @@
regulator-name = "hsusb2_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpio6 8 0>; /* gpio_168: vbus enable */
+ gpio = <&gpio6 8 GPIO_ACTIVE_HIGH>; /* gpio_168: vbus enable */
startup-delay-us = <70000>;
enable-active-high;
};
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
index 17b82f8..7df2792 100644
--- a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -41,13 +41,13 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
- gpio-key,wakeup;
+ wakeup-source;
};
button1@14 {
label = "button1";
linux,code = <BTN_1>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
index 80d236a..6314da2 100644
--- a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
@@ -152,7 +152,7 @@
interrupt-parent = <&gpio4>;
interrupts = <18 0>; /* gpio_114 */
- pendown-gpio = <&gpio4 18 0>;
+ pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
ti,x-min = /bits/ 16 <0x0>;
ti,x-max = /bits/ 16 <0x0fff>;
@@ -161,6 +161,6 @@
ti,x-plate-ohms = /bits/ 16 <180>;
ti,pressure-max = /bits/ 16 <255>;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
index 048fd21..7e3fe85 100644
--- a/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
@@ -163,7 +163,7 @@
interrupt-parent = <&gpio4>;
interrupts = <18 0>; /* gpio_114 */
- pendown-gpio = <&gpio4 18 0>;
+ pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
ti,x-min = /bits/ 16 <0x0>;
ti,x-max = /bits/ 16 <0x0fff>;
@@ -172,7 +172,7 @@
ti,x-plate-ohms = /bits/ 16 <180>;
ti,pressure-max = /bits/ 16 <255>;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi b/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
index 49d2254..250cc7f 100644
--- a/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
@@ -41,13 +41,13 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
- gpio-key,wakeup;
+ wakeup-source;
};
button1@14 {
label = "button1";
linux,code = <BTN_1>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-palo35-common.dtsi b/arch/arm/boot/dts/omap3-overo-palo35-common.dtsi
index 680d726..8df7ec3 100644
--- a/arch/arm/boot/dts/omap3-overo-palo35-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-palo35-common.dtsi
@@ -41,13 +41,13 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
- gpio-key,wakeup;
+ wakeup-source;
};
button1@14 {
label = "button1";
linux,code = <BTN_1>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi b/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
index 087aedf..0ea2c45 100644
--- a/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
@@ -41,13 +41,13 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; /* gpio_23 */
- gpio-key,wakeup;
+ wakeup-source;
};
button1@14 {
label = "button1";
linux,code = <BTN_1>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; /* gpio_14 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi
index f2084e6..13e9d1f 100644
--- a/arch/arm/boot/dts/omap3-pandora-common.dtsi
+++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi
@@ -84,112 +84,112 @@
label = "up";
linux,code = <KEY_UP>;
gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* GPIO_110 */
- gpio-key,wakeup;
+ wakeup-source;
};
down-button {
label = "down";
linux,code = <KEY_DOWN>;
gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* GPIO_103 */
- gpio-key,wakeup;
+ wakeup-source;
};
left-button {
label = "left";
linux,code = <KEY_LEFT>;
gpios = <&gpio4 0 GPIO_ACTIVE_LOW>; /* GPIO_96 */
- gpio-key,wakeup;
+ wakeup-source;
};
right-button {
label = "right";
linux,code = <KEY_RIGHT>;
gpios = <&gpio4 2 GPIO_ACTIVE_LOW>; /* GPIO_98 */
- gpio-key,wakeup;
+ wakeup-source;
};
pageup-button {
label = "game 1";
linux,code = <KEY_PAGEUP>;
gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* GPIO_109 */
- gpio-key,wakeup;
+ wakeup-source;
};
pagedown-button {
label = "game 3";
linux,code = <KEY_PAGEDOWN>;
gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* GPIO_106 */
- gpio-key,wakeup;
+ wakeup-source;
};
home-button {
label = "game 4";
linux,code = <KEY_HOME>;
gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* GPIO_101 */
- gpio-key,wakeup;
+ wakeup-source;
};
end-button {
label = "game 2";
linux,code = <KEY_END>;
gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* GPIO_111 */
- gpio-key,wakeup;
+ wakeup-source;
};
right-shift {
label = "l";
linux,code = <KEY_RIGHTSHIFT>;
gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* GPIO_102 */
- gpio-key,wakeup;
+ wakeup-source;
};
kp-plus {
label = "l2";
linux,code = <KEY_KPPLUS>;
gpios = <&gpio4 1 GPIO_ACTIVE_LOW>; /* GPIO_97 */
- gpio-key,wakeup;
+ wakeup-source;
};
right-ctrl {
label = "r";
linux,code = <KEY_RIGHTCTRL>;
gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* GPIO_105 */
- gpio-key,wakeup;
+ wakeup-source;
};
kp-minus {
label = "r2";
linux,code = <KEY_KPMINUS>;
gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* GPIO_107 */
- gpio-key,wakeup;
+ wakeup-source;
};
left-ctrl {
label = "ctrl";
linux,code = <KEY_LEFTCTRL>;
gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* GPIO_104 */
- gpio-key,wakeup;
+ wakeup-source;
};
menu {
label = "menu";
linux,code = <KEY_MENU>;
gpios = <&gpio4 3 GPIO_ACTIVE_LOW>; /* GPIO_99 */
- gpio-key,wakeup;
+ wakeup-source;
};
hold {
label = "hold";
linux,code = <KEY_COFFEE>;
gpios = <&gpio6 16 GPIO_ACTIVE_LOW>; /* GPIO_176 */
- gpio-key,wakeup;
+ wakeup-source;
};
left-alt {
label = "alt";
linux,code = <KEY_LEFTALT>;
gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>; /* GPIO_100 */
- gpio-key,wakeup;
+ wakeup-source;
};
lid {
@@ -218,7 +218,7 @@
regulator-always-on;
regulator-boot-on;
enable-active-high;
- gpio = <&gpio6 4 0>; /* GPIO_164 */
+ gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* GPIO_164 */
};
/* wg7210 (wifi+bt module) 32k clock buffer */
@@ -607,7 +607,7 @@
pinctrl-0 = <&penirq_pins>;
interrupt-parent = <&gpio3>;
interrupts = <30 0>; /* GPIO_94 */
- pendown-gpio = <&gpio3 30 0>;
+ pendown-gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
vcc-supply = <&vaux4>;
ti,x-min = /bits/ 16 <0>;
@@ -617,7 +617,7 @@
ti,x-plate-ohms = /bits/ 16 <40>;
ti,pressure-max = /bits/ 16 <255>;
- linux,wakeup;
+ wakeup-source;
};
lcd: lcd@1 {
diff --git a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
index f4b1a61..157345b 100644
--- a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
+++ b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi
@@ -66,6 +66,6 @@
ti,x-plate-ohms = /bits/ 16 <40>;
ti,pressure-max = /bits/ 16 <255>;
ti,swap-xy;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi
index 7bd8d9a..ae5dbbd 100644
--- a/arch/arm/boot/dts/omap3-tao3530.dtsi
+++ b/arch/arm/boot/dts/omap3-tao3530.dtsi
@@ -37,7 +37,7 @@
regulator-name = "hsusb2_vbus";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&twl_gpio 18 0>; /* GPIO LEDA */
+ gpio = <&twl_gpio 18 GPIO_ACTIVE_HIGH>; /* GPIO LEDA */
startup-delay-us = <70000>;
};
@@ -225,7 +225,7 @@
pinctrl-0 = <&mmc1_pins>;
vmmc-supply = <&vmmc1>;
vmmc_aux-supply = <&vsim>;
- cd-gpios = <&twl_gpio 0 0>;
+ cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
bus-width = <8>;
};
diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts
index 131448d..f19170b 100644
--- a/arch/arm/boot/dts/omap3-zoom3.dts
+++ b/arch/arm/boot/dts/omap3-zoom3.dts
@@ -44,7 +44,7 @@
regulator-name = "vwl1271";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&gpio4 5 0>; /* gpio101 */
+ gpio = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */
startup-delay-us = <70000>;
enable-active-high;
};
@@ -54,27 +54,27 @@
/* 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 */
+ OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_OUTPUT_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 = <
- 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 */
+ 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 | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat4.sdmmc2_dat4 */
+ OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat5.sdmmc2_dat5 */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat6.sdmmc2_dat6 */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat7.sdmmc2_dat7 */
>;
};
@@ -87,35 +87,35 @@
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 */
+ OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */
+ OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */
+ OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | 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 = <
- 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 */
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */
+ OMAP3_CORE1_IOPAD(0x217a, WAKEUP_EN | 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 = <
- 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 */
+ OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */
+ OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */
+ OMAP3_CORE1_IOPAD(0x219e, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+ OMAP3_CORE1_IOPAD(0x21a0, 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_CORE1_IOPAD(0x211a, PIN_OUTPUT| MUX_MODE4) /* cam_d2.gpio_101 */
>;
};
};
@@ -135,7 +135,7 @@
&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 */
+ OMAP3_WKUP_IOPAD(0x2a1a, PIN_INPUT_PULLUP | MUX_MODE4) /* sys_clkout1.gpio_10 WLAN_HOST_WKUP */
>;
};
};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 8a2b253..d1ffabb 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -717,6 +717,8 @@
ti,hwmods = "gpmc";
reg = <0x6e000000 0x02d0>;
interrupts = <20>;
+ dmas = <&sdma 4>;
+ dma-names = "rxtx";
gpmc,num-cs = <8>;
gpmc,num-waitpins = <4>;
#address-cells = <2>;
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
index 1a78f01..06c5482 100644
--- a/arch/arm/boot/dts/omap4-duovero-parlor.dts
+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts
@@ -36,7 +36,7 @@
label = "button0";
linux,code = <BTN_0>;
gpios = <&gpio4 25 GPIO_ACTIVE_LOW>; /* gpio_121 */
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -189,3 +189,7 @@
};
};
+&uart3 {
+ interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
+ &omap4_pmx_core OMAP4_UART3_RX>;
+};
diff --git a/arch/arm/boot/dts/omap4-panda-a4.dts b/arch/arm/boot/dts/omap4-panda-a4.dts
index 133f1b7..78d3631 100644
--- a/arch/arm/boot/dts/omap4-panda-a4.dts
+++ b/arch/arm/boot/dts/omap4-panda-a4.dts
@@ -13,8 +13,8 @@
/* 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 */
+ OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ OMAP4_IOPAD(0x09e, 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
index f1507bc..df2e356 100644
--- a/arch/arm/boot/dts/omap4-panda-common.dtsi
+++ b/arch/arm/boot/dts/omap4-panda-common.dtsi
@@ -68,7 +68,7 @@
regulator-name = "hsusb1_vbus";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&gpio1 1 0>; /* gpio_1 */
+ gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>; /* gpio_1 */
startup-delay-us = <70000>;
enable-active-high;
/*
@@ -98,7 +98,7 @@
regulator-name = "vwl1271";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&gpio2 11 0>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
startup-delay-us = <70000>;
enable-active-high;
};
@@ -199,129 +199,129 @@
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 */
+ OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */
+ OMAP4_IOPAD(0x1a0, 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 */
+ 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 = <
- 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 */
+ 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 */
>;
};
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 */
+ 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 */
>;
};
tfp410_pins: pinmux_tfp410_pins {
pinctrl-single,pins = <
- 0x144 (PIN_OUTPUT | MUX_MODE3) /* gpio_0 */
+ OMAP4_IOPAD(0x184, 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 */
+ 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 */
>;
};
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 */
+ OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */
+ OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */
+ OMAP4_IOPAD(0x098, 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 */
+ 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 */
>;
};
i2c1_pins: pinmux_i2c1_pins {
pinctrl-single,pins = <
- 0xe2 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
- 0xe4 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP4_IOPAD(0x124, 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 */
+ 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 = <
- 0xea (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
- 0xec (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ OMAP4_IOPAD(0x12c, 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 */
+ OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */
>;
};
@@ -331,24 +331,24 @@
*/
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 */
+ OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */
+ OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 */
+ OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a24.gpio_48 */
+ OMAP4_IOPAD(0x072, 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_IOPAD(0x078, PIN_INPUT | MUX_MODE3) /* gpmc_ncs2.gpio_52 */
+ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
+ 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 */
>;
};
};
@@ -356,8 +356,8 @@
&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 */
+ OMAP4_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */
+ OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
>;
};
};
diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts
index 2f1dabc..119f8e6 100644
--- a/arch/arm/boot/dts/omap4-panda-es.dts
+++ b/arch/arm/boot/dts/omap4-panda-es.dts
@@ -34,23 +34,23 @@
/* 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_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ OMAP4_IOPAD(0x09e, 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 */
+ OMAP4_IOPAD(0x0f6, PIN_OUTPUT | MUX_MODE3) /* gpio_110 */
>;
};
};
&led_wkgpio_pins {
pinctrl-single,pins = <
- 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
+ OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */
>;
};
diff --git a/arch/arm/boot/dts/omap4-sdp-es23plus.dts b/arch/arm/boot/dts/omap4-sdp-es23plus.dts
index aad5dda..b4d19a7 100644
--- a/arch/arm/boot/dts/omap4-sdp-es23plus.dts
+++ b/arch/arm/boot/dts/omap4-sdp-es23plus.dts
@@ -10,8 +10,8 @@
/* 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 */
+ OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */
+ OMAP4_IOPAD(0x09e, 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
index dac86ed..aae5132 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -30,7 +30,7 @@
regulator-name = "VDD_ETH";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&gpio2 16 0>; /* gpio line 48 */
+ gpio = <&gpio2 16 GPIO_ACTIVE_HIGH>; /* gpio line 48 */
enable-active-high;
regulator-boot-on;
};
@@ -155,7 +155,7 @@
regulator-name = "vwl1271";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&gpio2 22 0>;
+ gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>;
startup-delay-us = <70000>;
enable-active-high;
};
@@ -212,143 +212,143 @@
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 */
+ 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 */
>;
};
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 */
+ 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 */
>;
};
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 */
+ OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx.uart4_rx */
+ OMAP4_IOPAD(0x15e, 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 */
+ OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */
+ OMAP4_IOPAD(0x1a0, 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 */
+ 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 */
>;
};
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 */
+ OMAP4_IOPAD(0x110, PIN_OUTPUT | MUX_MODE0) /* abe_dmic_clk1.abe_dmic_clk1 */
+ OMAP4_IOPAD(0x112, PIN_INPUT | MUX_MODE0) /* abe_dmic_din1.abe_dmic_din1 */
+ OMAP4_IOPAD(0x114, PIN_INPUT | MUX_MODE0) /* abe_dmic_din2.abe_dmic_din2 */
+ OMAP4_IOPAD(0x116, 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 */
+ 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 */
>;
};
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 */
+ OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */
+ OMAP4_IOPAD(0x0f8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dr.abe_mcbsp2_dr */
+ OMAP4_IOPAD(0x0fa, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dx.abe_mcbsp2_dx */
+ OMAP4_IOPAD(0x0fc, 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 */
+ 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 */
>;
};
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 */
+ 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 */
>;
};
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 */
+ OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */
+ OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */
+ OMAP4_IOPAD(0x098, 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 */
+ OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP4_IOPAD(0x124, 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 */
+ 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 = <
- 0xea (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
- 0xec (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */
+ OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */
+ OMAP4_IOPAD(0x12c, 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 */
+ OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */
+ OMAP4_IOPAD(0x130, 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 */
+ OMAP4_IOPAD(0x07c, 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 */
+ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */
+ 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 */
>;
};
};
@@ -374,7 +374,7 @@
/* 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 */
+ ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio line 127 */
vio-supply = <&v1v8>;
v2v1-supply = <&v2v1>;
diff --git a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi
index f2d2fdb..6e278d7 100644
--- a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi
+++ b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi
@@ -41,7 +41,7 @@
label = "user";
gpios = <&gpio6 24 GPIO_ACTIVE_HIGH>; /* gpio 184 */
linux,code = <BTN_EXTRA>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
index 9bceeb7..1c5f6f3 100644
--- a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
+++ b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
@@ -15,7 +15,7 @@
regulator-name = "vwl1271";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&gpio2 11 0>; /* gpio 43 */
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>; /* gpio 43 */
startup-delay-us = <70000>;
enable-active-high;
};
diff --git a/arch/arm/boot/dts/omap4-var-som-om44.dtsi b/arch/arm/boot/dts/omap4-var-som-om44.dtsi
index a4f1ba2..49d032b 100644
--- a/arch/arm/boot/dts/omap4-var-som-om44.dtsi
+++ b/arch/arm/boot/dts/omap4-var-som-om44.dtsi
@@ -196,7 +196,7 @@
/* 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 */
+ ti,audpwron-gpio = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* gpio 182 */
vio-supply = <&v1v8>;
v2v1-supply = <&v2v1>;
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 5a206c1..2bd9c83 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -348,12 +348,22 @@
#interrupt-cells = <2>;
};
+ elm: elm@48078000 {
+ compatible = "ti,am3352-elm";
+ reg = <0x48078000 0x2000>;
+ interrupts = <4>;
+ ti,hwmods = "elm";
+ status = "disabled";
+ };
+
gpmc: gpmc@50000000 {
compatible = "ti,omap4430-gpmc";
reg = <0x50000000 0x1000>;
#address-cells = <2>;
#size-cells = <1>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 4>;
+ dma-names = "rxtx";
gpmc,num-cs = <8>;
gpmc,num-waitpins = <4>;
ti,hwmods = "gpmc";
diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi
index 194f9ef..5fa68f19 100644
--- a/arch/arm/boot/dts/omap4460.dtsi
+++ b/arch/arm/boot/dts/omap4460.dtsi
@@ -46,7 +46,7 @@
0x4a002378 0x18>;
compatible = "ti,omap4460-bandgap";
interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */
- gpios = <&gpio3 22 0>; /* tshut */
+ gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; /* tshut */
#thermal-sensor-cells = <0>;
};
diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi
new file mode 100644
index 0000000..902657d
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-board-common.dtsi
@@ -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.
+ */
+#include "omap5.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ aliases {
+ display0 = &hdmi0;
+ };
+
+ vmmcsd_fixed: fixedregulator-mmcsd {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ mmc3_pwrseq: sdhci0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&clk32kgaudio>;
+ clock-names = "ext_clock";
+ };
+
+ vmmcsdio_fixed: fixedregulator-mmcsdio {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsdio_fixed";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio5 12 GPIO_ACTIVE_HIGH>; /* gpio140 WLAN_EN */
+ enable-active-high;
+ startup-delay-us = <70000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_pins>;
+ };
+
+ /* 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 defined in the board specific dts */
+
+ 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";
+ };
+};
+
+&gpio8 {
+ /* TI trees use GPIO instead of msecure, see also muxing */
+ p234 {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "gpio8_234/msecure";
+ };
+};
+
+&omap5_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &usbhost_pins
+ &led_gpio_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1be, PIN_OUTPUT | MUX_MODE6) /* mcspi1_somi.gpio5_141 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x182, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_clks.abe_clks */
+ OMAP5_IOPAD(0x19c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_ul_data.abemcpdm_ul_data */
+ OMAP5_IOPAD(0x19e, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_dl_data.abemcpdm_dl_data */
+ OMAP5_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE0) /* abemcpdm_frame.abemcpdm_frame */
+ OMAP5_IOPAD(0x1a2, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcpdm_lb_clk.abemcpdm_lb_clk */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x18c, PIN_INPUT | MUX_MODE1) /* abedmic_clk2.abemcbsp1_fsx */
+ OMAP5_IOPAD(0x18e, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* abedmic_clk3.abemcbsp1_dx */
+ OMAP5_IOPAD(0x190, PIN_INPUT | MUX_MODE1) /* abeslimbus1_clock.abemcbsp1_clkx */
+ OMAP5_IOPAD(0x192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* abeslimbus1_data.abemcbsp1_dr */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x194, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abemcbsp2_dr.abemcbsp2_dr */
+ OMAP5_IOPAD(0x196, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* abemcbsp2_dx.abemcbsp2_dx */
+ OMAP5_IOPAD(0x198, PIN_INPUT | MUX_MODE0) /* abemcbsp2_fsx.abemcbsp2_fsx */
+ OMAP5_IOPAD(0x19a, PIN_INPUT | MUX_MODE0) /* abemcbsp2_clkx.abemcbsp2_clkx */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1f2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */
+ OMAP5_IOPAD(0x1f4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */
+ >;
+ };
+
+ mcspi2_pins: pinmux_mcspi2_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0fc, PIN_INPUT | MUX_MODE0) /* mcspi2_clk */
+ OMAP5_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* mcspi2_simo */
+ OMAP5_IOPAD(0x100, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi2_somi */
+ OMAP5_IOPAD(0x102, PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs0 */
+ >;
+ };
+
+ mcspi3_pins: pinmux_mcspi3_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0b8, PIN_INPUT | MUX_MODE1) /* mcspi3_somi */
+ OMAP5_IOPAD(0x0ba, PIN_INPUT | MUX_MODE1) /* mcspi3_cs0 */
+ OMAP5_IOPAD(0x0bc, PIN_INPUT | MUX_MODE1) /* mcspi3_simo */
+ OMAP5_IOPAD(0x0be, PIN_INPUT | MUX_MODE1) /* mcspi3_clk */
+ >;
+ };
+
+ 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_pins: pinmux_wlan_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1bc, PIN_OUTPUT | MUX_MODE6) /* mcspi1_clk.gpio5_140 */
+ >;
+ };
+
+ /* TI trees use GPIO mode; msecure mode does not work reliably? */
+ palmas_msecure_pins: palmas_msecure_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x180, PIN_OUTPUT | MUX_MODE6) /* gpio8_234 */
+ >;
+ };
+
+ usbhost_pins: pinmux_usbhost_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0c4, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
+ OMAP5_IOPAD(0x0c6, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
+
+ OMAP5_IOPAD(0x1de, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
+ OMAP5_IOPAD(0x1e0, PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
+
+ OMAP5_IOPAD(0x0b0, PIN_OUTPUT | MUX_MODE6) /* gpio3_80 HUB_NRESET */
+ OMAP5_IOPAD(0x0ae, PIN_OUTPUT | MUX_MODE6) /* gpio3_79 ETH_NRESET */
+ >;
+ };
+
+ led_gpio_pins: pinmux_led_gpio_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1d6, PIN_OUTPUT | MUX_MODE6) /* uart3_cts_rctx.gpio5_153 */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0a0, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_cts */
+ OMAP5_IOPAD(0x0a2, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_tx.uart1_cts */
+ OMAP5_IOPAD(0x0a4, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rx.uart1_rts */
+ OMAP5_IOPAD(0x0a6, PIN_OUTPUT | MUX_MODE0) /* uart1_rx.uart1_rts */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1da, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_irsd.uart3_tx_irtx */
+ OMAP5_IOPAD(0x1dc, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_rx_irrx.uart3_usbb3_hsic */
+ >;
+ };
+
+ uart5_pins: pinmux_uart5_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1b0, PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_rx.uart5_rx */
+ OMAP5_IOPAD(0x1b2, PIN_OUTPUT | MUX_MODE0) /* uart5_tx.uart5_tx */
+ OMAP5_IOPAD(0x1b4, PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_cts.uart5_rts */
+ OMAP5_IOPAD(0x1b6, PIN_OUTPUT | MUX_MODE0) /* uart5_cts.uart5_rts */
+ >;
+ };
+
+ dss_hdmi_pins: pinmux_dss_hdmi_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */
+ OMAP5_IOPAD(0x140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */
+ OMAP5_IOPAD(0x142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */
+ >;
+ };
+
+ tpd12s015_pins: pinmux_tpd12s015_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x13e, PIN_INPUT_PULLDOWN | MUX_MODE6) /* hdmi_hpd.gpio7_193 */
+ >;
+ };
+};
+
+&omap5_pmx_wkup {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &usbhost_wkup_pins
+ >;
+
+ palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */
+ >;
+ };
+
+ usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
+ >;
+ };
+
+ wlcore_irq_pin: pinmux_wlcore_irq_pin {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x40, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE6) /* llia_wakereqin.gpio1_wk14 */
+ >;
+ };
+};
+
+&mmc1 {
+ vmmc-supply = <&ldo9_reg>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+};
+
+&mmc3 {
+ vmmc-supply = <&vmmcsdio_fixed>;
+ mmc-pwrseq = <&mmc3_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ cap-power-off-card;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins &wlcore_irq_pin>;
+ interrupts-extended = <&gic GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH
+ &omap5_pmx_core 0x168>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wlcore: wlcore@2 {
+ compatible = "ti,wl1271";
+ reg = <2>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; /* gpio 14 */
+ ref-clock-frequency = <26000000>;
+ };
+};
+
+&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;
+ pinctrl-names = "default";
+ pinctrl-0 = <&palmas_sys_nirq_pins &palmas_msecure_pins>;
+
+ 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>;
+ };
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupt-parent = <&palmas>;
+ interrupts = <8 IRQ_TYPE_NONE>;
+ ti,backup-battery-chargeable;
+ ti,backup-battery-charge-high-current;
+ };
+
+ 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;
+ };
+ };
+ };
+
+ palmas_power_button: palmas_power_button {
+ compatible = "ti,palmas-pwrbutton";
+ interrupt-parent = <&palmas>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ };
+ };
+
+ 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 GPIO_ACTIVE_HIGH>; /* gpio line 141 */
+
+ vio-supply = <&smps7_reg>;
+ v2v1-supply = <&smps9_reg>;
+ enable-active-high;
+
+ clocks = <&clk32kgaudio>;
+ clock-names = "clk32k";
+ };
+};
+
+&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>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <&omap5_pmx_core 0x19c>;
+};
+
+&uart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5_pins>;
+};
+
+&cpu0 {
+ cpu0-supply = <&smps123_reg>;
+};
+
+&dss {
+ status = "ok";
+};
+
+&hdmi {
+ status = "ok";
+
+ /* vdda-supply populated in board specific dts file */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_hdmi_pins>;
+
+ port {
+ hdmi_out: endpoint {
+ remote-endpoint = <&tpd12s015_in>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts
index 61ad2ea..ecc591d 100644
--- a/arch/arm/boot/dts/omap5-cm-t54.dts
+++ b/arch/arm/boot/dts/omap5-cm-t54.dts
@@ -175,7 +175,7 @@
ads7846_pins: pinmux_ads7846_pins {
pinctrl-single,pins = <
- 0x02 (PIN_INPUT_PULLDOWN | MUX_MODE6) /* llib_wakereqin.gpio1_wk15 */
+ OMAP5_IOPAD(0x0042, PIN_INPUT_PULLDOWN | MUX_MODE6) /* llib_wakereqin.gpio1_wk15 */
>;
};
};
@@ -344,7 +344,7 @@
interrupt-parent = <&gpio1>;
interrupts = <15 0>; /* gpio1_wk15 */
- pendown-gpio = <&gpio1 15 0>;
+ pendown-gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>;
ti,x-min = /bits/ 16 <0x0>;
@@ -359,7 +359,7 @@
ti,debounce-tol = /bits/ 16 <10>;
ti,debounce-rep = /bits/ 16 <1>;
- linux,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/omap5-igep0050.dts b/arch/arm/boot/dts/omap5-igep0050.dts
new file mode 100644
index 0000000..46ecb1d
--- /dev/null
+++ b/arch/arm/boot/dts/omap5-igep0050.dts
@@ -0,0 +1,54 @@
+/*
+ * 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 "omap5-board-common.dtsi"
+
+/ {
+ model = "IGEPv5";
+ compatible = "isee,omap5-igep0050", "ti,omap5";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x7f000000>; /* 2032 MB */
+ };
+};
+
+&hdmi {
+ vdda-supply = <&ldo7_reg>;
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+
+ tca6416: tca6416@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&omap5_pmx_core {
+ i2c4_pins: pinmux_i2c4_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0) /* i2c4_scl */
+ OMAP5_IOPAD(0x0fa, PIN_INPUT | MUX_MODE0) /* i2c4_sda */
+ >;
+ };
+};
+
+&tpd12s015 {
+ gpios = <&tca6416 11 0>, /* TCA6416 P01, CT_CP_HDP */
+ <&tca6416 12 0>, /* TCA6416 P00, LS_OE*/
+ <&gpio7 1 0>, /* 193, HPD */
+ <&gpio7 2 0>, /* 194, SCL */
+ <&gpio7 3 0>; /* 195, SDA */
+};
+
diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
index 3cb030f..60b3fbb 100644
--- a/arch/arm/boot/dts/omap5-uevm.dts
+++ b/arch/arm/boot/dts/omap5-uevm.dts
@@ -7,9 +7,7 @@
*/
/dts-v1/;
-#include "omap5.dtsi"
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "omap5-board-common.dtsi"
/ {
model = "TI OMAP5 uEVM board";
@@ -19,523 +17,10 @@
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 = <
- 0x186 (PIN_INPUT | MUX_MODE0) /* i2c5_scl */
- 0x188 (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;
- };
- };
- };
-
- palmas_power_button: palmas_power_button {
- compatible = "ti,palmas-pwrbutton";
- interrupt-parent = <&palmas>;
- interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
- wakeup-source;
- };
- };
-
- 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";
- };
+&hdmi {
+ vdda-supply = <&ldo4_reg>;
};
&i2c5 {
@@ -552,92 +37,17 @@
};
};
-&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>;
- interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
- <&omap5_pmx_core 0x19c>;
-};
-
-&uart5 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart5_pins>;
-};
-
-&cpu0 {
- cpu0-supply = <&smps123_reg>;
-};
-
-&dss {
- status = "ok";
+&omap5_pmx_core {
+ i2c5_pins: pinmux_i2c5_pins {
+ pinctrl-single,pins = <
+ OMAP5_IOPAD(0x1c6, PIN_INPUT | MUX_MODE0) /* i2c5_scl */
+ OMAP5_IOPAD(0x1c8, PIN_INPUT | MUX_MODE0) /* i2c5_sda */
+ >;
+ };
};
-&hdmi {
- status = "ok";
- vdda-supply = <&ldo4_reg>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&dss_hdmi_pins>;
-
- port {
- hdmi_out: endpoint {
- remote-endpoint = <&tpd12s015_in>;
- };
- };
+&tpd12s015 {
+ 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 */
};
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 4c04389..ca3c17f 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -391,6 +391,8 @@
#address-cells = <2>;
#size-cells = <1>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&sdma 4>;
+ dma-names = "rxtx";
gpmc,num-cs = <8>;
gpmc,num-waitpins = <4>;
ti,hwmods = "gpmc";
diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
index 3daec91..aae8a7a 100644
--- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
+++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
@@ -1,7 +1,8 @@
/*
* Device Tree file for Buffalo Linkstation LS-WTGL
*
- * Copyright (C) 2015, Roger Shimizu <rogershimizu@gmail.com>
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@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
@@ -69,8 +70,6 @@
internal-regs {
pinctrl: pinctrl@10000 {
- pinctrl-0 = <&pmx_usb_power &pmx_power_hdd
- &pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
pinctrl-names = "default";
pmx_led_power: pmx-leds {
@@ -162,6 +161,7 @@
led@1 {
label = "lswtgl:blue:power";
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
};
led@2 {
@@ -188,7 +188,7 @@
3250 1
5000 0>;
- alarm-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+ alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
};
restart_poweroff {
@@ -228,6 +228,37 @@
};
};
+&devbus_bootcs {
+ status = "okay";
+ devbus,keep-config;
+
+ flash@0 {
+ compatible = "jedec-flash";
+ reg = <0 0x40000>;
+ bank-width = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ header@0 {
+ reg = <0 0x30000>;
+ read-only;
+ };
+
+ uboot@30000 {
+ reg = <0x30000 0xF000>;
+ read-only;
+ };
+
+ uboot_env@3F000 {
+ reg = <0x3F000 0x1000>;
+ };
+ };
+ };
+};
+
&mdio {
status = "okay";
diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi
index 75cd01b..e1b6d2a 100644
--- a/arch/arm/boot/dts/orion5x.dtsi
+++ b/arch/arm/boot/dts/orion5x.dtsi
@@ -212,6 +212,16 @@
status = "disabled";
};
+ cesa: crypto@90000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <28>;
+ marvell,crypto-srams = <&crypto_sram>;
+ marvell,crypto-sram-size = <0x800>;
+ status = "okay";
+ };
+
ehci1: ehci@a0000 {
compatible = "marvell,orion-ehci";
reg = <0xa0000 0x1000>;
@@ -220,13 +230,11 @@
};
};
- 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";
+ crypto_sram: sa-sram {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x00) 0x0 0x800>;
+ #address-cells = <1>;
+ #size-cells = <1>;
};
};
};
diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts
index 90fdbd7..7d253bb 100644
--- a/arch/arm/boot/dts/phy3250.dts
+++ b/arch/arm/boot/dts/phy3250.dts
@@ -12,7 +12,7 @@
*/
/dts-v1/;
-/include/ "lpc32xx.dtsi"
+#include "lpc32xx.dtsi"
/ {
model = "PHYTEC phyCORE-LPC3250 board based on NXP LPC3250";
@@ -22,7 +22,7 @@
memory {
device_type = "memory";
- reg = <0 0x4000000>;
+ reg = <0x80000000 0x4000000>;
};
ahb {
@@ -31,19 +31,6 @@
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";
};
@@ -123,15 +110,6 @@
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>;
@@ -200,3 +178,18 @@
};
};
};
+
+/* Here, choose exactly one from: ohci, usbd */
+&ohci /* &usbd */ {
+ transceiver = <&isp1301>;
+ status = "okay";
+};
+
+&i2cusb {
+ clock-frequency = <100000>;
+
+ isp1301: usb-transceiver@2c {
+ compatible = "nxp,isp1301";
+ reg = <0x2c>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index 47c0282..21095da 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -1,4 +1,6 @@
#include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
model = "CompuLab CM-QS600";
@@ -12,12 +14,27 @@
stdout-path = "serial0:115200n8";
};
+ pwrseq {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ compatible = "simple-bus";
+
+ sdcc4_pwrseq: sdcc4_pwrseq {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_default_gpios>;
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;
+ };
+ };
+
soc {
pinctrl@800000 {
- i2c1_pins: i2c1 {
+ card_detect: card_detect {
mux {
- pins = "gpio20", "gpio21";
- function = "gsbi1";
+ pins = "gpio26";
+ function = "gpio";
+ bias-disable;
};
};
};
@@ -37,7 +54,7 @@
/* Buck SMPS */
- pm8921_s1: s1 {
+ s1 {
regulator-always-on;
regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
@@ -45,43 +62,43 @@
bias-pull-down;
};
- pm8921_s3: s3 {
+ s3 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
qcom,switch-mode-frequency = <4800000>;
};
- pm8921_s4: s4 {
+ s4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
qcom,switch-mode-frequency = <3200000>;
};
- pm8921_s7: s7 {
+ s7 {
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1300000>;
qcom,switch-mode-frequency = <3200000>;
};
- pm8921_l3: l3 {
+ l3 {
regulator-min-microvolt = <3050000>;
regulator-max-microvolt = <3300000>;
bias-pull-down;
};
- pm8921_l4: l4 {
+ l4 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1800000>;
bias-pull-down;
};
- pm8921_l5: l5 {
+ l5 {
regulator-min-microvolt = <2750000>;
regulator-max-microvolt = <3000000>;
bias-pull-down;
};
- pm8921_l23: l23 {
+ l23 {
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
bias-pull-down;
@@ -96,10 +113,8 @@
i2c@12460000 {
status = "okay";
clock-frequency = <200000>;
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-names = "default";
- eeprom: eeprom@50 {
+ eeprom@50 {
compatible = "24c02";
reg = <0x50>;
pagesize = <32>;
@@ -112,6 +127,8 @@
qcom,mode = <GSBI_PROT_I2C_UART>;
serial@16640000 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsbi7_uart_2pins>;
};
};
@@ -163,6 +180,21 @@
regulator-always-on;
};
+ qcom,ssbi@500000 {
+ pmic@0 {
+ gpio@150 {
+ wlan_default_gpios: wlan-gpios {
+ pios {
+ pins = "gpio43";
+ function = "normal";
+ bias-disable;
+ power-source = <PM8921_GPIO_S4>;
+ };
+ };
+ };
+ };
+ };
+
amba {
/* eMMC */
sdcc1: sdcc@12400000 {
@@ -175,12 +207,16 @@
sdcc3: sdcc@12180000 {
status = "okay";
vmmc-supply = <&v3p3_fixed>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&card_detect>;
+ cd-gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
};
/* WLAN */
sdcc4: sdcc@121c0000 {
status = "okay";
vmmc-supply = <&v3p3_fixed>;
vqmmc-supply = <&v3p3_fixed>;
+ mmc-pwrseq = <&sdcc4_pwrseq>;
};
};
};
diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index f3100da..fd4d49e 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -1,5 +1,6 @@
#include "qcom-apq8064-v2.0.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
model = "Qualcomm APQ8064/IFC6410";
@@ -14,6 +15,29 @@
stdout-path = "serial0:115200n8";
};
+ pwrseq {
+ compatible = "simple-bus";
+
+ sdcc4_pwrseq: sdcc4_pwrseq {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_default_gpios>;
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&notify_led>;
+
+ led@1 {
+ label = "apq8064:green:user1";
+ gpios = <&pm8921_gpio 18 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
soc {
pinctrl@800000 {
card_detect: card_detect {
@@ -23,6 +47,18 @@
bias-disable;
};
};
+
+ pcie_pins: pcie_pinmux {
+ mux {
+ pins = "gpio27";
+ function = "gpio";
+ };
+ conf {
+ pins = "gpio27";
+ drive-strength = <12>;
+ bias-disable;
+ };
+ };
};
rpm@108000 {
@@ -40,7 +76,7 @@
/* Buck SMPS */
- pm8921_s1: s1 {
+ s1 {
regulator-always-on;
regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
@@ -48,55 +84,59 @@
bias-pull-down;
};
- pm8921_s3: s3 {
+ s3 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
qcom,switch-mode-frequency = <4800000>;
};
- pm8921_s4: s4 {
+ s4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
qcom,switch-mode-frequency = <3200000>;
};
- pm8921_s7: s7 {
+ s7 {
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1300000>;
qcom,switch-mode-frequency = <3200000>;
};
- pm8921_l3: l3 {
+ l3 {
regulator-min-microvolt = <3050000>;
regulator-max-microvolt = <3300000>;
bias-pull-down;
};
- pm8921_l4: l4 {
+ l4 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1800000>;
bias-pull-down;
};
- pm8921_l5: l5 {
+ l5 {
regulator-min-microvolt = <2750000>;
regulator-max-microvolt = <3000000>;
bias-pull-down;
};
- pm8921_l6: l6 {
+ l6 {
regulator-min-microvolt = <2950000>;
regulator-max-microvolt = <2950000>;
bias-pull-down;
};
- pm8921_l23: l23 {
+ l23 {
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <1900000>;
bias-pull-down;
};
- pm8921_lvs1: lvs1 {
+ lvs1 {
+ bias-pull-down;
+ };
+
+ lvs6 {
bias-pull-down;
};
};
@@ -119,8 +159,6 @@
qcom,mode = <GSBI_PROT_I2C>;
i2c3: i2c@16280000 {
status = "okay";
- pinctrl-0 = <&i2c3_pins>;
- pinctrl-names = "default";
};
};
@@ -131,10 +169,8 @@
i2c@12460000 {
status = "okay";
clock-frequency = <200000>;
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-names = "default";
- eeprom: eeprom@52 {
+ eeprom@52 {
compatible = "atmel,24c128";
reg = <0x52>;
pagesize = <32>;
@@ -144,13 +180,12 @@
gsbi@16500000 {
status = "ok";
- qcom,mode = <GSBI_PROT_I2C_UART>;
+ qcom,mode = <GSBI_PROT_UART_W_FC>;
serial@16540000 {
status = "ok";
-
pinctrl-names = "default";
- pinctrl-0 = <&uart_pins>;
+ pinctrl-0 = <&gsbi6_uart_4pins>;
};
};
@@ -159,6 +194,8 @@
qcom,mode = <GSBI_PROT_I2C_UART>;
serial@16640000 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsbi7_uart_2pins>;
};
};
@@ -210,6 +247,40 @@
status = "okay";
};
+ pci@1b500000 {
+ status = "ok";
+ vdda-supply = <&pm8921_s3>;
+ vdda_phy-supply = <&pm8921_lvs6>;
+ vdda_refclk-supply = <&ext_3p3v>;
+ pinctrl-0 = <&pcie_pins>;
+ pinctrl-names = "default";
+ perst-gpio = <&tlmm_pinmux 27 GPIO_ACTIVE_LOW>;
+ };
+
+ qcom,ssbi@500000 {
+ pmic@0 {
+ gpio@150 {
+ wlan_default_gpios: wlan-gpios {
+ pios {
+ pins = "gpio43";
+ function = "normal";
+ bias-disable;
+ power-source = <PM8921_GPIO_S4>;
+ };
+ };
+
+ notify_led: nled {
+ pios {
+ pins = "gpio18";
+ function = "normal";
+ bias-disable;
+ power-source = <PM8921_GPIO_S4>;
+ };
+ };
+ };
+ };
+ };
+
amba {
/* eMMC */
sdcc1: sdcc@12400000 {
@@ -231,6 +302,7 @@
status = "okay";
vmmc-supply = <&ext_3p3v>;
vqmmc-supply = <&pm8921_lvs1>;
+ mmc-pwrseq = <&sdcc4_pwrseq>;
};
};
};
diff --git a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts
new file mode 100644
index 0000000..06b3c76
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts
@@ -0,0 +1,436 @@
+#include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mfd/qcom-rpm.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+ model = "Sony Xperia Z";
+ compatible = "sony,xperia-yuga", "qcom,apq8064";
+
+ aliases {
+ serial0 = &gsbi5_serial;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pin_a>;
+
+ camera-focus {
+ label = "camera_focus";
+ gpios = <&pm8921_gpio 3 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ };
+
+ camera-snapshot {
+ label = "camera_snapshot";
+ gpios = <&pm8921_gpio 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_CAMERA>;
+ };
+
+ volume-down {
+ label = "volume_down";
+ gpios = <&pm8921_gpio 29 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ volume-up {
+ label = "volume_up";
+ gpios = <&pm8921_gpio 35 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ soc {
+ pinctrl@800000 {
+ gsbi5_uart_pin_a: gsbi5-uart-pin-active {
+ rx {
+ pins = "gpio52";
+ function = "gsbi5";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ tx {
+ pins = "gpio51";
+ function = "gsbi5";
+ drive-strength = <4>;
+ bias-disable;
+ };
+ };
+
+ sdcc1_pin_a: sdcc1-pin-active {
+ clk {
+ pins = "sdc1_clk";
+ drive-strengh = <16>;
+ bias-disable;
+ };
+
+ cmd {
+ pins = "sdc1_cmd";
+ drive-strengh = <10>;
+ bias-pull-up;
+ };
+
+ data {
+ pins = "sdc1_data";
+ drive-strengh = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdcc3_pin_a: sdcc3-pin-active {
+ clk {
+ pins = "sdc3_clk";
+ drive-strengh = <8>;
+ bias-disable;
+ };
+
+ cmd {
+ pins = "sdc3_cmd";
+ drive-strengh = <8>;
+ bias-pull-up;
+ };
+
+ data {
+ pins = "sdc3_data";
+ drive-strengh = <8>;
+ bias-pull-up;
+ };
+ };
+
+ sdcc3_cd_pin_a: sdcc3-cd-pin-active {
+ pins = "gpio26";
+ function = "gpio";
+
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+
+ rpm@108000 {
+ regulators {
+ vin_l1_l2_l12_l18-supply = <&pm8921_s4>;
+ vin_lvs_1_3_6-supply = <&pm8921_s4>;
+ vin_lvs_4_5_7-supply = <&pm8921_s4>;
+ vin_ncp-supply = <&pm8921_l6>;
+ vin_lvs2-supply = <&pm8921_s4>;
+ vin_l24-supply = <&pm8921_s1>;
+ vin_l25-supply = <&pm8921_s1>;
+ vin_l27-supply = <&pm8921_s7>;
+ vin_l28-supply = <&pm8921_s7>;
+
+ /* Buck SMPS */
+ s1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,switch-mode-frequency = <3200000>;
+ bias-pull-down;
+ };
+
+ s2 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ };
+
+ s3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1150000>;
+ qcom,switch-mode-frequency = <4800000>;
+ bias-pull-down;
+ };
+
+ s4 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,switch-mode-frequency = <1600000>;
+ bias-pull-down;
+ qcom,force-mode = <QCOM_RPM_FORCE_MODE_AUTO>;
+ };
+
+ s7 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ qcom,switch-mode-frequency = <3200000>;
+ };
+
+ s8 {
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ qcom,switch-mode-frequency = <1600000>;
+ };
+
+ /* PMOS LDO */
+ l1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ bias-pull-down;
+ };
+
+ l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ bias-pull-down;
+ };
+
+ l3 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ bias-pull-down;
+ };
+
+ l4 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ bias-pull-down;
+ };
+
+ l5 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ bias-pull-down;
+ };
+
+ l6 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ bias-pull-down;
+ };
+
+ l7 {
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <2950000>;
+ bias-pull-down;
+ };
+
+ l8 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ bias-pull-down;
+ };
+
+ l9 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ bias-pull-down;
+ };
+
+ l10 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ bias-pull-down;
+ };
+
+ l11 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ bias-pull-down;
+ };
+
+ l12 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ bias-pull-down;
+ };
+
+ l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ bias-pull-down;
+ };
+
+ l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ bias-pull-down;
+ };
+
+ l16 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ bias-pull-down;
+ };
+
+ l17 {
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ bias-pull-down;
+ };
+
+ l18 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ bias-pull-down;
+ };
+
+ l21 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ bias-pull-down;
+ };
+
+ l22 {
+ regulator-min-microvolt = <2600000>;
+ regulator-max-microvolt = <2600000>;
+ bias-pull-down;
+ };
+
+ l23 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ bias-pull-down;
+ };
+
+ l24 {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1150000>;
+ bias-pull-down;
+ };
+
+ l25 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ bias-pull-down;
+ };
+
+ l27 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ l28 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ bias-pull-down;
+ };
+
+ l29 {
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ bias-pull-down;
+ };
+
+ /* Low Voltage Switch */
+ lvs1 {
+ bias-pull-down;
+ };
+
+ lvs2 {
+ bias-pull-down;
+ };
+
+ lvs3 {
+ bias-pull-down;
+ };
+
+ lvs4 {
+ bias-pull-down;
+ };
+
+ lvs5 {
+ bias-pull-down;
+ };
+
+ lvs6 {
+ bias-pull-down;
+ };
+
+ lvs7 {
+ bias-pull-down;
+ };
+
+ usb-switch {};
+
+ hdmi-switch {};
+
+ ncp {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,switch-mode-frequency = <1600000>;
+ };
+ };
+ };
+
+ qcom,ssbi@500000 {
+ pmic@0 {
+ gpio@150 {
+ gpio_keys_pin_a: gpio-keys-pin-active {
+ pins = "gpio3", "gpio4", "gpio29", "gpio35";
+ function = "normal";
+
+ bias-pull-up;
+ drive-push-pull;
+ input-enable;
+ power-source = <2>;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+ qcom,pull-up-strength = <0>;
+ };
+ };
+ };
+ };
+
+ phy@12500000 {
+ status = "okay";
+ vddcx-supply = <&pm8921_s3>;
+ v3p3-supply = <&pm8921_l3>;
+ v1p8-supply = <&pm8921_l4>;
+ };
+
+ gadget@12500000 {
+ status = "okay";
+ };
+
+ gsbi@1a200000 {
+ status = "ok";
+ qcom,mode = <GSBI_PROT_I2C_UART>;
+
+ serial@1a240000 {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsbi5_uart_pin_a>;
+ };
+ };
+
+ amba {
+ sdcc1: sdcc@12400000 {
+ status = "okay";
+
+ vmmc-supply = <&pm8921_l5>;
+ vqmmc-supply = <&pm8921_s4>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdcc1_pin_a>;
+ };
+
+ sdcc3: sdcc@12180000 {
+ status = "okay";
+
+ vmmc-supply = <&pm8921_l6>;
+ cd-gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdcc3_pin_a>, <&sdcc3_cd_pin_a>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index d2e94d6..ed521e8 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -11,6 +11,17 @@
compatible = "qcom,apq8064";
interrupt-parent = <&intc>;
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ smem_region: smem@80000000 {
+ reg = <0x80000000 0x200000>;
+ no-map;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -80,6 +91,39 @@
interrupts = <1 10 0x304>;
};
+ clocks {
+ cxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ };
+
+ pxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+
+ sleep_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ sfpb_mutex: hwmutex {
+ compatible = "qcom,sfpb-mutex";
+ syscon = <&sfpb_wrapper_mutex 0x604 0x4>;
+ #hwlock-cells = <1>;
+ };
+
+ smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_region>;
+
+ hwlocks = <&sfpb_mutex 3>;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -127,12 +171,38 @@
};
};
- uart_pins: uart_pins {
+ gsbi6_uart_2pins: gsbi6_uart_2pins {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "gsbi6";
+ };
+ };
+
+ gsbi6_uart_4pins: gsbi6_uart_4pins {
mux {
pins = "gpio14", "gpio15", "gpio16", "gpio17";
function = "gsbi6";
};
};
+
+ gsbi7_uart_2pins: gsbi7_uart_2pins {
+ mux {
+ pins = "gpio82", "gpio83";
+ function = "gsbi7";
+ };
+ };
+
+ gsbi7_uart_4pins: gsbi7_uart_4pins {
+ mux {
+ pins = "gpio82", "gpio83", "gpio84", "gpio85";
+ function = "gsbi7";
+ };
+ };
+ };
+
+ sfpb_wrapper_mutex: syscon@1200000 {
+ compatible = "syscon";
+ reg = <0x01200000 0x8000>;
};
intc: interrupt-controller@2000000 {
@@ -213,6 +283,8 @@
i2c1: i2c@12460000 {
compatible = "qcom,i2c-qup-v1.1.1";
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
reg = <0x12460000 0x1000>;
interrupts = <0 194 IRQ_TYPE_NONE>;
clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>;
@@ -258,6 +330,8 @@
ranges;
i2c3: i2c@16280000 {
compatible = "qcom,i2c-qup-v1.1.1";
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-names = "default";
reg = <0x16280000 0x1000>;
interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
clocks = <&gcc GSBI3_QUP_CLK>,
@@ -266,6 +340,28 @@
};
};
+ gsbi5: gsbi@1a200000 {
+ status = "disabled";
+ compatible = "qcom,gsbi-v1.0.0";
+ cell-index = <5>;
+ reg = <0x1a200000 0x03>;
+ clocks = <&gcc GSBI5_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gsbi5_serial: serial@1a240000 {
+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+ reg = <0x1a240000 0x100>,
+ <0x1a200000 0x03>;
+ interrupts = <0 154 0x0>;
+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ };
+ };
+
gsbi6: gsbi@16500000 {
status = "disabled";
compatible = "qcom,gsbi-v1.0.0";
@@ -311,6 +407,13 @@
};
};
+ rng@1a500000 {
+ compatible = "qcom,prng";
+ reg = <0x1a500000 0x200>;
+ clocks = <&gcc PRNG_CLK>;
+ clock-names = "core";
+ };
+
qcom,ssbi@500000 {
compatible = "qcom,ssbi";
reg = <0x00500000 0x1000>;
@@ -327,7 +430,8 @@
pm8921_gpio: gpio@150 {
- compatible = "qcom,pm8921-gpio";
+ compatible = "qcom,pm8921-gpio",
+ "qcom,ssbi-gpio";
reg = <0x150>;
interrupts = <192 1>, <193 1>, <194 1>,
<195 1>, <196 1>, <197 1>,
@@ -351,7 +455,8 @@
};
pm8921_mpps: mpps@50 {
- compatible = "qcom,pm8921-mpp";
+ compatible = "qcom,pm8921-mpp",
+ "qcom,ssbi-mpp";
reg = <0x50>;
gpio-controller;
#gpio-cells = <2>;
@@ -361,6 +466,22 @@
<136 1>, <137 1>, <138 1>, <139 1>;
};
+ rtc@11d {
+ compatible = "qcom,pm8921-rtc";
+ interrupt-parent = <&pmicintc>;
+ interrupts = <39 1>;
+ reg = <0x11d>;
+ allow-set-time;
+ };
+
+ pwrkey@1c {
+ compatible = "qcom,pm8921-pwrkey";
+ reg = <0x1c>;
+ interrupt-parent = <&pmicintc>;
+ interrupts = <50 1>, <51 1>;
+ debounce = <15625>;
+ pull-up;
+ };
};
};
@@ -403,9 +524,55 @@
regulators {
compatible = "qcom,rpm-pm8921-regulators";
+ pm8921_s1: s1 {};
+ pm8921_s2: s2 {};
+ pm8921_s3: s3 {};
+ pm8921_s4: s4 {};
+ pm8921_s7: s7 {};
+ pm8921_s8: s8 {};
+
+ pm8921_l1: l1 {};
+ pm8921_l2: l2 {};
+ pm8921_l3: l3 {};
+ pm8921_l4: l4 {};
+ pm8921_l5: l5 {};
+ pm8921_l6: l6 {};
+ pm8921_l7: l7 {};
+ pm8921_l8: l8 {};
+ pm8921_l9: l9 {};
+ pm8921_l10: l10 {};
+ pm8921_l11: l11 {};
+ pm8921_l12: l12 {};
+ pm8921_l14: l14 {};
+ pm8921_l15: l15 {};
+ pm8921_l16: l16 {};
+ pm8921_l17: l17 {};
+ pm8921_l18: l18 {};
+ pm8921_l21: l21 {};
+ pm8921_l22: l22 {};
+ pm8921_l23: l23 {};
+ pm8921_l24: l24 {};
+ pm8921_l25: l25 {};
+ pm8921_l26: l26 {};
+ pm8921_l27: l27 {};
+ pm8921_l28: l28 {};
+ pm8921_l29: l29 {};
+
+ pm8921_lvs1: lvs1 {};
+ pm8921_lvs2: lvs2 {};
+ pm8921_lvs3: lvs3 {};
+ pm8921_lvs4: lvs4 {};
+ pm8921_lvs5: lvs5 {};
+ pm8921_lvs6: lvs6 {};
+ pm8921_lvs7: lvs7 {};
+
+ pm8921_usb_switch: usb-switch {};
+
pm8921_hdmi_switch: hdmi-switch {
bias-pull-down;
};
+
+ pm8921_ncp: ncp {};
};
};
@@ -618,5 +785,41 @@
compatible = "qcom,tcsr-apq8064", "syscon";
reg = <0x1a400000 0x100>;
};
+
+ pcie: pci@1b500000 {
+ compatible = "qcom,pcie-apq8064", "snps,dw-pcie";
+ reg = <0x1b500000 0x1000
+ 0x1b502000 0x80
+ 0x1b600000 0x100
+ 0x0ff00000 0x100000>;
+ reg-names = "dbi", "elbi", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000 /* I/O */
+ 0x82000000 0 0 0x08000000 0 0x07e00000>; /* memory */
+ interrupts = <GIC_SPI 238 IRQ_TYPE_NONE>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+ <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+ <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+ <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+ clocks = <&gcc PCIE_A_CLK>,
+ <&gcc PCIE_H_CLK>,
+ <&gcc PCIE_PHY_REF_CLK>;
+ clock-names = "core", "iface", "phy";
+ resets = <&gcc PCIE_ACLK_RESET>,
+ <&gcc PCIE_HCLK_RESET>,
+ <&gcc PCIE_POR_RESET>,
+ <&gcc PCIE_PCI_RESET>,
+ <&gcc PCIE_PHY_RESET>;
+ reset-names = "axi", "ahb", "por", "pci", "phy";
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
index 835bdc7..c0e2053 100644
--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -8,6 +8,8 @@
aliases {
serial0 = &blsp1_uart2;
+ usid0 = &pm8941_0;
+ usid4 = &pm8841_0;
};
chosen {
diff --git a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
index c9c2b76..2052b84 100644
--- a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
+++ b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts
@@ -3,10 +3,11 @@
/ {
model = "Qualcomm APQ8084/IFC6540";
- compatible = "qcom,apq8084-ifc6540", "qcom,apq8084";
+ compatible = "qcom,apq8084-sbc", "qcom,apq8084";
aliases {
serial0 = &blsp2_uart2;
+ usid0 = &pma8084_0;
};
chosen {
diff --git a/arch/arm/boot/dts/qcom-apq8084-mtp.dts b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
index 3016c70..d174d15 100644
--- a/arch/arm/boot/dts/qcom-apq8084-mtp.dts
+++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
@@ -7,6 +7,7 @@
aliases {
serial0 = &blsp2_uart2;
+ usid0 = &pma8084_0;
};
chosen {
diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 0554fbd..08214cb 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -10,6 +10,17 @@
compatible = "qcom,apq8084";
interrupt-parent = <&intc>;
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ smem_mem: smem_region@fa00000 {
+ reg = <0xfa00000 0x200000>;
+ no-map;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -89,6 +100,15 @@
clock-frequency = <19200000>;
};
+ smem {
+ compatible = "qcom,smem";
+
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ memory-region = <&smem_mem>;
+
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -103,6 +123,11 @@
<0xf9002000 0x1000>;
};
+ apcs: syscon@f9011000 {
+ compatible = "syscon";
+ reg = <0xf9011000 0x1000>;
+ };
+
timer@f9020000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -221,9 +246,26 @@
compatible = "qcom,gcc-apq8084";
#clock-cells = <1>;
#reset-cells = <1>;
+ #power-domain-cells = <1>;
reg = <0xfc400000 0x4000>;
};
+ tcsr_mutex_regs: syscon@fd484000 {
+ compatible = "syscon";
+ reg = <0xfd484000 0x2000>;
+ };
+
+ tcsr_mutex: hwlock {
+ compatible = "qcom,tcsr-mutex";
+ syscon = <&tcsr_mutex_regs 0 0x80>;
+ #hwlock-cells = <1>;
+ };
+
+ rpm_msg_ram: memory@fc428000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0xfc428000 0x4000>;
+ };
+
tlmm: pinctrl@fd510000 {
compatible = "qcom,apq8084-pinctrl";
reg = <0xfd510000 0x4000>;
@@ -281,4 +323,71 @@
#interrupt-cells = <4>;
};
};
+
+ smd {
+ compatible = "qcom,smd";
+
+ rpm {
+ interrupts = <0 168 1>;
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+ rpm_requests {
+ compatible = "qcom,rpm-apq8084";
+ qcom,smd-channels = "rpm_requests";
+
+ pma8084-regulators {
+ compatible = "qcom,rpm-pma8084-regulators";
+
+ pma8084_s1: s1 {};
+ pma8084_s2: s2 {};
+ pma8084_s3: s3 {};
+ pma8084_s4: s4 {};
+ pma8084_s5: s5 {};
+ pma8084_s6: s6 {};
+ pma8084_s7: s7 {};
+ pma8084_s8: s8 {};
+ pma8084_s9: s9 {};
+ pma8084_s10: s10 {};
+ pma8084_s11: s11 {};
+ pma8084_s12: s12 {};
+
+ pma8084_l1: l1 {};
+ pma8084_l2: l2 {};
+ pma8084_l3: l3 {};
+ pma8084_l4: l4 {};
+ pma8084_l5: l5 {};
+ pma8084_l6: l6 {};
+ pma8084_l7: l7 {};
+ pma8084_l8: l8 {};
+ pma8084_l9: l9 {};
+ pma8084_l10: l10 {};
+ pma8084_l11: l11 {};
+ pma8084_l12: l12 {};
+ pma8084_l13: l13 {};
+ pma8084_l14: l14 {};
+ pma8084_l15: l15 {};
+ pma8084_l16: l16 {};
+ pma8084_l17: l17 {};
+ pma8084_l18: l18 {};
+ pma8084_l19: l19 {};
+ pma8084_l20: l20 {};
+ pma8084_l21: l21 {};
+ pma8084_l22: l22 {};
+ pma8084_l23: l23 {};
+ pma8084_l24: l24 {};
+ pma8084_l25: l25 {};
+ pma8084_l26: l26 {};
+ pma8084_l27: l27 {};
+
+ pma8084_lvs1: lvs1 {};
+ pma8084_lvs2: lvs2 {};
+ pma8084_lvs3: lvs3 {};
+ pma8084_lvs4: lvs4 {};
+
+ pma8084_5vs1: 5vs1 {};
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
index 134cd91..51a40d8 100644
--- a/arch/arm/boot/dts/qcom-msm8960.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
@@ -49,6 +49,29 @@
qcom,no-pc-write;
};
+ clocks {
+ cxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ clock-output-names = "cxo_board";
+ };
+
+ pxo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "pxo_board";
+ };
+
+ sleep_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "sleep_clk";
+ };
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
index 016f9ad..a0398b6 100644
--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
@@ -1,6 +1,9 @@
#include "qcom-msm8974.dtsi"
#include "qcom-pm8841.dtsi"
#include "qcom-pm8941.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
model = "Sony Xperia Z1";
@@ -14,24 +17,403 @@
stdout-path = "serial0:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pin_a>;
+
+ volume-down {
+ label = "volume_down";
+ gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ camera-snapshot {
+ label = "camera_snapshot";
+ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_CAMERA>;
+ };
+
+ camera-focus {
+ label = "camera_focus";
+ gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_CAMERA_FOCUS>;
+ };
+
+ volume-up {
+ label = "volume_up";
+ gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
memory@0 {
reg = <0 0x40000000>, <0x40000000 0x40000000>;
device_type = "memory";
};
+
+ smd {
+ rpm {
+ rpm_requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ s2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ s3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ s4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ };
+ };
+
+ pm8941-regulators {
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+ vdd_l5_l7-supply = <&pm8941_s2>;
+ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+ vdd_l21-supply = <&vreg_boost>;
+ vin_5vs-supply = <&pm8941_5v>;
+
+ s1 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ s2 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ regulator-boot-on;
+ };
+
+ s3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ s4 {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ l1 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ l2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ l3 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ l4 {
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ };
+
+ l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-boot-on;
+ };
+
+ l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-boot-on;
+ };
+
+ l8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+
+ l11 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1350000>;
+ };
+
+ l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+
+ regulator-boot-on;
+ };
+
+ l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ l15 {
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ };
+
+ l16 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ l17 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ l18 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+
+ l19 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ l20 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ regulator-allow-set-load;
+ regulator-boot-on;
+ regulator-system-load = <200000>;
+ };
+
+ l21 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ regulator-boot-on;
+ };
+
+ l22 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ l23 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ l24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+ };
+
+ vreg_boost: vreg-boost {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vreg-boost";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&boost_bypass_n_pin>;
+ };
};
&soc {
+ sdhci@f9824900 {
+ status = "ok";
+
+ vmmc-supply = <&pm8941_l20>;
+ vqmmc-supply = <&pm8941_s3>;
+
+ bus-width = <8>;
+ non-removable;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc1_pin_a>;
+ };
+
+ sdhci@f98a4900 {
+ status = "ok";
+
+ bus-width = <4>;
+
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l13>;
+
+ cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+ };
+
serial@f991e000 {
status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&blsp1_uart2_pin_a>;
+ };
+
+ pinctrl@fd510000 {
+ blsp1_uart2_pin_a: blsp1-uart2-pin-active {
+ rx {
+ pins = "gpio5";
+ function = "blsp_uart2";
+
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ tx {
+ pins = "gpio4";
+ function = "blsp_uart2";
+
+ drive-strength = <4>;
+ bias-disable;
+ };
+ };
+
+ sdhc1_pin_a: sdhc1-pin-active {
+ clk {
+ pins = "sdc1_clk";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ cmd-data {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+ pins = "gpio62";
+ function = "gpio";
+
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdhc2_pin_a: sdhc2-pin-active {
+ clk {
+ pins = "sdc2_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
+ cmd-data {
+ pins = "sdc2_cmd", "sdc2_data";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
};
};
&spmi_bus {
pm8941@0 {
+ charger@1000 {
+ qcom,fast-charge-safe-current = <1500000>;
+ qcom,fast-charge-current-limit = <1500000>;
+ qcom,dc-current-limit = <1800000>;
+ qcom,fast-charge-safe-voltage = <4400000>;
+ qcom,fast-charge-high-threshold-voltage = <4350000>;
+ qcom,fast-charge-low-threshold-voltage = <3400000>;
+ qcom,auto-recharge-threshold-voltage = <4200000>;
+ qcom,minimum-input-voltage = <4300000>;
+ };
+
+ gpios@c000 {
+ boost_bypass_n_pin: boost-bypass {
+ pins = "gpio21";
+ function = "normal";
+ };
+
+ gpio_keys_pin_a: gpio-keys-active {
+ pins = "gpio2", "gpio3", "gpio4", "gpio5";
+ function = "normal";
+
+ bias-pull-up;
+ power-source = <PM8941_GPIO_S3>;
+ };
+ };
+
coincell@2800 {
status = "ok";
qcom,rset-ohms = <2100>;
qcom,vset-millivolts = <3000>;
};
};
+
+ pm8941@1 {
+ wled@d800 {
+ status = "ok";
+
+ qcom,cs-out;
+ qcom,current-limit = <20>;
+ qcom,current-boost-limit = <805>;
+ qcom,switching-freq = <1600>;
+ qcom,ovp = <29>;
+ qcom,num-strings = <2>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index ab8e572..dfdafdc 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -100,6 +100,15 @@
clock-frequency = <19200000>;
};
+ smem {
+ compatible = "qcom,smem";
+
+ memory-region = <&smem_region>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -114,6 +123,11 @@
<0xf9002000 0x1000>;
};
+ apcs: syscon@f9011000 {
+ compatible = "syscon";
+ reg = <0xf9011000 0x1000>;
+ };
+
timer@f9020000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -228,6 +242,7 @@
compatible = "qcom,gcc-msm8974";
#clock-cells = <1>;
#reset-cells = <1>;
+ #power-domain-cells = <1>;
reg = <0xfc400000 0x4000>;
};
@@ -240,6 +255,7 @@
compatible = "qcom,mmcc-msm8974";
#clock-cells = <1>;
#reset-cells = <1>;
+ #power-domain-cells = <1>;
reg = <0xfd8c0000 0x6000>;
};
@@ -250,13 +266,9 @@
#hwlock-cells = <1>;
};
- smem@fa00000 {
- compatible = "qcom,smem";
-
- memory-region = <&smem_region>;
+ rpm_msg_ram: memory@fc428000 {
+ compatible = "qcom,rpm-msg-ram";
reg = <0xfc428000 0x4000>;
-
- hwlocks = <&tcsr_mutex 3>;
};
blsp1_uart2: serial@f991e000 {
@@ -307,8 +319,19 @@
interrupts = <0 208 0>;
};
+ blsp_i2c8: i2c@f9964000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9964000 0x1000>;
+ interrupts = <0 102 IRQ_TYPE_NONE>;
+ clocks = <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
blsp_i2c11: i2c@f9967000 {
- status = "disable";
+ status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9967000 0x1000>;
interrupts = <0 105 IRQ_TYPE_NONE>;
@@ -334,4 +357,73 @@
#interrupt-cells = <4>;
};
};
+
+ smd {
+ compatible = "qcom,smd";
+
+ rpm {
+ interrupts = <0 168 1>;
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+ rpm_requests {
+ compatible = "qcom,rpm-msm8974";
+ qcom,smd-channels = "rpm_requests";
+
+ pm8841-regulators {
+ compatible = "qcom,rpm-pm8841-regulators";
+
+ pm8841_s1: s1 {};
+ pm8841_s2: s2 {};
+ pm8841_s3: s3 {};
+ pm8841_s4: s4 {};
+ pm8841_s5: s5 {};
+ pm8841_s6: s6 {};
+ pm8841_s7: s7 {};
+ pm8841_s8: s8 {};
+ };
+
+ pm8941-regulators {
+ compatible = "qcom,rpm-pm8941-regulators";
+
+ pm8941_s1: s1 {};
+ pm8941_s2: s2 {};
+ pm8941_s3: s3 {};
+ pm8941_5v: s4 {};
+
+ pm8941_l1: l1 {};
+ pm8941_l2: l2 {};
+ pm8941_l3: l3 {};
+ pm8941_l4: l4 {};
+ pm8941_l5: l5 {};
+ pm8941_l6: l6 {};
+ pm8941_l7: l7 {};
+ pm8941_l8: l8 {};
+ pm8941_l9: l9 {};
+ pm8941_l10: l10 {};
+ pm8941_l11: l11 {};
+ pm8941_l12: l12 {};
+ pm8941_l13: l13 {};
+ pm8941_l14: l14 {};
+ pm8941_l15: l15 {};
+ pm8941_l16: l16 {};
+ pm8941_l17: l17 {};
+ pm8941_l18: l18 {};
+ pm8941_l19: l19 {};
+ pm8941_l20: l20 {};
+ pm8941_l21: l21 {};
+ pm8941_l22: l22 {};
+ pm8941_l23: l23 {};
+ pm8941_l24: l24 {};
+
+ pm8941_lvs1: lvs1 {};
+ pm8941_lvs2: lvs2 {};
+ pm8941_lvs3: lvs3 {};
+
+ pm8941_5vs1: 5vs1 {};
+ pm8941_5vs2: 5vs2 {};
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi
index 8f1a0b1..9f357f6 100644
--- a/arch/arm/boot/dts/qcom-pm8841.dtsi
+++ b/arch/arm/boot/dts/qcom-pm8841.dtsi
@@ -3,14 +3,14 @@
&spmi_bus {
- usid4: pm8841@4 {
- compatible = "qcom,spmi-pmic";
+ pm8841_0: pm8841@4 {
+ compatible = "qcom,pm8841", "qcom,spmi-pmic";
reg = <0x4 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pm8841_mpps: mpps@a000 {
- compatible = "qcom,pm8841-mpp";
+ compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000 0x400>;
gpio-controller;
#gpio-cells = <2>;
@@ -27,8 +27,8 @@
};
};
- usid5: pm8841@5 {
- compatible = "qcom,spmi-pmic";
+ pm8841_1: pm8841@5 {
+ compatible = "qcom,pm8841", "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
index 968f104..ca53a59 100644
--- a/arch/arm/boot/dts/qcom-pm8941.dtsi
+++ b/arch/arm/boot/dts/qcom-pm8941.dtsi
@@ -4,8 +4,8 @@
&spmi_bus {
- usid0: pm8941@0 {
- compatible ="qcom,spmi-pmic";
+ pm8941_0: pm8941@0 {
+ compatible = "qcom,pm8941", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
@@ -26,8 +26,29 @@
bias-pull-up;
};
+ charger@1000 {
+ compatible = "qcom,pm8941-charger";
+ reg = <0x1000 0x700>;
+ interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "chg-done",
+ "chg-fast",
+ "chg-trkl",
+ "bat-temp-ok",
+ "bat-present",
+ "chg-gone",
+ "usb-valid",
+ "dc-valid";
+ };
+
pm8941_gpios: gpios@c000 {
- compatible = "qcom,pm8941-gpio";
+ compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio";
reg = <0xc000 0x2400>;
gpio-controller;
#gpio-cells = <2>;
@@ -70,7 +91,7 @@
};
pm8941_mpps: mpps@a000 {
- compatible = "qcom,pm8941-mpp";
+ compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp";
reg = <0xa000 0x800>;
gpio-controller;
#gpio-cells = <2>;
@@ -120,8 +141,7 @@
pm8941_iadc: iadc@3600 {
compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc";
- reg = <0x3600 0x100>,
- <0x12f1 0x1>;
+ reg = <0x3600 0x100>;
interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>;
qcom,external-resistor-micro-ohms = <10000>;
};
@@ -133,23 +153,18 @@
};
};
- usid1: pm8941@1 {
- compatible = "qcom,spmi-pmic";
+ pm8941_1: pm8941@1 {
+ compatible = "qcom,pm8941", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
- wled@d800 {
+ pm8941_wled: wled@d800 {
compatible = "qcom,pm8941-wled";
reg = <0xd800 0x100>;
label = "backlight";
- qcom,cs-out;
- qcom,current-limit = <20>;
- qcom,current-boost-limit = <805>;
- qcom,switching-freq = <1600>;
- qcom,ovp = <29>;
- qcom,num-strings = <2>;
+ status = "disabled";
};
};
};
diff --git a/arch/arm/boot/dts/qcom-pma8084.dtsi b/arch/arm/boot/dts/qcom-pma8084.dtsi
index 5e240cc..4e9bd3f 100644
--- a/arch/arm/boot/dts/qcom-pma8084.dtsi
+++ b/arch/arm/boot/dts/qcom-pma8084.dtsi
@@ -4,8 +4,8 @@
&spmi_bus {
- usid0: pma8084@0 {
- compatible = "qcom,spmi-pmic";
+ pma8084_0: pma8084@0 {
+ compatible = "qcom,pma8084", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
@@ -19,7 +19,7 @@
};
pma8084_gpios: gpios@c000 {
- compatible = "qcom,pma8084-gpio";
+ compatible = "qcom,pma8084-gpio", "qcom,spmi-gpio";
reg = <0xc000 0x1600>;
gpio-controller;
#gpio-cells = <2>;
@@ -48,7 +48,7 @@
};
pma8084_mpps: mpps@a000 {
- compatible = "qcom,pma8084-mpp";
+ compatible = "qcom,pma8084-mpp", "qcom,spmi-mpp";
reg = <0xa000 0x800>;
gpio-controller;
#gpio-cells = <2>;
@@ -101,8 +101,8 @@
};
};
- usid1: pma8084@1 {
- compatible = "qcom,spmi-pmic";
+ pma8084_1: pma8084@1 {
+ compatible = "qcom,pma8084", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index 060c32c..4657d7f 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -329,7 +329,7 @@
};
gic: interrupt-controller@e8201000 {
- compatible = "arm,cortex-a9-gic";
+ compatible = "arm,pl390";
#interrupt-cells = <3>;
#address-cells = <0>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
index a4c4259..5902570 100644
--- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts
+++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
@@ -23,7 +23,7 @@
chosen {
bootargs = "ignore_loglevel root=/dev/nfs ip=dhcp rw";
- stdout-path = &scifa0;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -110,7 +110,7 @@
gpios = <&pfc 324 GPIO_ACTIVE_LOW>;
linux,code = <KEY_0>;
label = "S16";
- gpio-key,wakeup;
+ wakeup-source;
};
menu-key {
diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
index 105d9c9..c548cab 100644
--- a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
@@ -85,7 +85,7 @@
gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "SW3";
- gpio-key,wakeup;
+ wakeup-source;
};
back-key {
@@ -180,7 +180,7 @@
};
&extal1_clk {
- clock-frequency = <25000000>;
+ clock-frequency = <24000000>;
};
&extal2_clk {
clock-frequency = <48000000>;
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index e14cb14..6ef9547 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -26,17 +26,30 @@
reg = <0x0>;
clock-frequency = <800000000>;
power-domains = <&pd_a3sm>;
+ next-level-cache = <&L2>;
};
};
gic: interrupt-controller@c2800000 {
- compatible = "arm,cortex-a9-gic";
+ compatible = "arm,pl390";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0xc2800000 0x1000>,
<0xc2000000 0x1000>;
};
+ L2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0xf0100000 0x1000>;
+ interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_a3sm>;
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ arm,shared-override;
+ cache-unified;
+ cache-level = <2>;
+ };
+
dbsc3: memory-controller@fe400000 {
compatible = "renesas,dbsc3-r8a7740";
reg = <0xfe400000 0x400>;
diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts
deleted file mode 100644
index dffa6ff..0000000
--- a/arch/arm/boot/dts/r8a7778-bockw-reference.dts
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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", "jedec,spi-nor";
- 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
index 90543b1..a52b359 100644
--- a/arch/arm/boot/dts/r8a7778-bockw.dts
+++ b/arch/arm/boot/dts/r8a7778-bockw.dts
@@ -28,8 +28,8 @@
};
chosen {
- bootargs = "console=ttySC0,115200 ignore_loglevel ip=dhcp root=/dev/nfs rw";
- stdout-path = &scif0;
+ bootargs = "ignore_loglevel ip=dhcp root=/dev/nfs rw";
+ stdout-path = "serial0:115200n8";
};
memory {
@@ -137,10 +137,14 @@
};
sdhi0_pins: sd0 {
- renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
- "sdhi0_cd";
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
renesas,function = "sdhi0";
};
+ sdhi0_pup_pins: sd0_pup {
+ renesas,groups = "sdhi0_cd", "sdhi0_wp";
+ renesas,function = "sdhi0";
+ bias-pull-up;
+ };
hspi0_pins: hspi0 {
renesas,groups = "hspi0_a";
@@ -168,8 +172,13 @@
};
};
+&rcar_sound {
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+};
+
&sdhi0 {
- pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-0 = <&sdhi0_pins>, <&sdhi0_pup_pins>;
pinctrl-names = "default";
vmmc-supply = <&fixedregulator3v3>;
@@ -184,16 +193,20 @@
status = "okay";
flash: flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "spansion,s25fl008k", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <104000000>;
m25p,fast-read;
- partition@0 {
- label = "data(spi)";
- reg = <0x00000000 0x00100000>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "data(spi)";
+ reg = <0x00000000 0x00100000>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
index 4b1fa9f..791aafd 100644
--- a/arch/arm/boot/dts/r8a7778.dtsi
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -61,7 +61,7 @@
};
gic: interrupt-controller@fe438000 {
- compatible = "arm,cortex-a9-gic";
+ compatible = "arm,pl390";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0xfe438000 0x1000>,
@@ -236,10 +236,15 @@
};
rcar_sound: sound@ffd90000 {
- #sound-dai-cells = <1>;
+ /*
+ * #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-r8a7778", "renesas,rcar_sound-gen1";
reg = <0xffd90000 0x1000>, /* SRU */
- <0xffd91000 0x1240>, /* SSI */
+ <0xffd91000 0x240>, /* SSI */
<0xfffe0000 0x24>; /* ADG */
clocks = <&mstp3_clks R8A7778_CLK_SSI8>,
<&mstp3_clks R8A7778_CLK_SSI7>,
diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts
index 20afea6..fe396c8 100644
--- a/arch/arm/boot/dts/r8a7779-marzen.dts
+++ b/arch/arm/boot/dts/r8a7779-marzen.dts
@@ -19,12 +19,12 @@
compatible = "renesas,marzen", "renesas,r8a7779";
aliases {
- serial2 = &scif2;
- serial4 = &scif4;
+ serial0 = &scif2;
+ serial1 = &scif4;
};
chosen {
- bootargs = "console=ttySC2,115200 ignore_loglevel root=/dev/nfs ip=on";
+ bootargs = "ignore_loglevel root=/dev/nfs ip=on";
stdout-path = &scif2;
};
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 37dec52..052dcee 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -47,13 +47,13 @@
compatible = "renesas,lager", "renesas,r8a7790";
aliases {
- serial0 = &scifa0;
+ serial0 = &scif0;
serial1 = &scifa1;
};
chosen {
bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
- stdout-path = &scifa0;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -77,28 +77,28 @@
button@1 {
linux,code = <KEY_1>;
label = "SW2-1";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
button@2 {
linux,code = <KEY_2>;
label = "SW2-2";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
};
button@3 {
linux,code = <KEY_3>;
label = "SW2-3";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
};
button@4 {
linux,code = <KEY_4>;
label = "SW2-4";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
};
@@ -174,6 +174,13 @@
1800000 0>;
};
+ audio_clock: clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <11289600>;
+ clock-output-names = "audio_clock";
+ };
+
rsnd_ak4643: sound {
compatible = "simple-audio-card";
@@ -187,7 +194,7 @@
sndcodec: simple-audio-card,codec {
sound-dai = <&ak4643>;
- system-clock-frequency = <11289600>;
+ clocks = <&audio_clock>;
};
};
@@ -289,9 +296,9 @@
renesas,function = "du";
};
- scifa0_pins: serial0 {
- renesas,groups = "scifa0_data";
- renesas,function = "scifa0";
+ scif0_pins: serial0 {
+ renesas,groups = "scif0_data";
+ renesas,function = "scif0";
};
ether_pins: ether {
@@ -335,6 +342,11 @@
renesas,function = "msiof1";
};
+ iic0_pins: iic0 {
+ renesas,groups = "iic0";
+ renesas,function = "iic0";
+ };
+
iic1_pins: iic1 {
renesas,groups = "iic1";
renesas,function = "iic1";
@@ -427,8 +439,6 @@
status = "okay";
flash: flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "spansion,s25fl512s", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <30000000>;
@@ -438,25 +448,31 @@
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>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 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>;
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
pinctrl-names = "default";
status = "okay";
@@ -510,6 +526,8 @@
&iic0 {
status = "okay";
+ pinctrl-0 = <&iic0_pins>;
+ pinctrl-names = "default";
};
&iic1 {
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 4624d0f..7dfd393 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -143,7 +143,7 @@
interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
- gpio-ranges = <&pfc 0 32 32>;
+ gpio-ranges = <&pfc 0 32 30>;
#interrupt-cells = <2>;
interrupt-controller;
clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
@@ -156,7 +156,7 @@
interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
- gpio-ranges = <&pfc 0 64 32>;
+ gpio-ranges = <&pfc 0 64 30>;
#interrupt-cells = <2>;
interrupt-controller;
clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
@@ -266,7 +266,7 @@
};
dmac0: dma-controller@e6700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
reg = <0 0xe6700000 0 0x20000>;
interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
0 200 IRQ_TYPE_LEVEL_HIGH
@@ -297,7 +297,7 @@
};
dmac1: dma-controller@e6720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
reg = <0 0xe6720000 0 0x20000>;
interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
0 216 IRQ_TYPE_LEVEL_HIGH
@@ -328,7 +328,7 @@
};
audma0: dma-controller@ec700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
reg = <0 0xec700000 0 0x10000>;
interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH
0 320 IRQ_TYPE_LEVEL_HIGH
@@ -357,7 +357,7 @@
};
audma1: dma-controller@ec720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac";
reg = <0 0xec720000 0 0x10000>;
interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH
0 333 IRQ_TYPE_LEVEL_HIGH
@@ -386,7 +386,7 @@
};
usb_dmac0: dma-controller@e65a0000 {
- compatible = "renesas,usb-dmac";
+ compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
reg = <0 0xe65a0000 0 0x100>;
interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH
0 109 IRQ_TYPE_LEVEL_HIGH>;
@@ -398,7 +398,7 @@
};
usb_dmac1: dma-controller@e65b0000 {
- compatible = "renesas,usb-dmac";
+ compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac";
reg = <0 0xe65b0000 0 0x100>;
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH
0 110 IRQ_TYPE_LEVEL_HIGH>;
@@ -417,6 +417,7 @@
interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <110>;
status = "disabled";
};
@@ -428,6 +429,7 @@
interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -439,6 +441,7 @@
interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -450,6 +453,7 @@
interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <110>;
status = "disabled";
};
@@ -1599,7 +1603,7 @@
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x1280>, /* SSI */
+ <0 0xec541000 0 0x280>, /* SSI */
<0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
@@ -1766,7 +1770,7 @@
};
ipmmu_sy0: mmu@e6280000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xe6280000 0 0x1000>;
interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
<0 224 IRQ_TYPE_LEVEL_HIGH>;
@@ -1775,7 +1779,7 @@
};
ipmmu_sy1: mmu@e6290000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xe6290000 0 0x1000>;
interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -1783,7 +1787,7 @@
};
ipmmu_ds: mmu@e6740000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xe6740000 0 0x1000>;
interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
<0 199 IRQ_TYPE_LEVEL_HIGH>;
@@ -1792,7 +1796,7 @@
};
ipmmu_mp: mmu@ec680000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xec680000 0 0x1000>;
interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -1800,7 +1804,7 @@
};
ipmmu_mx: mmu@fe951000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xfe951000 0 0x1000>;
interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
<0 221 IRQ_TYPE_LEVEL_HIGH>;
@@ -1809,7 +1813,7 @@
};
ipmmu_rt: mmu@ffc80000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa";
reg = <0 0xffc80000 0 0x1000>;
interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
diff --git a/arch/arm/boot/dts/r8a7791-henninger.dts b/arch/arm/boot/dts/r8a7791-henninger.dts
deleted file mode 100644
index 655d180..0000000
--- a/arch/arm/boot/dts/r8a7791-henninger.dts
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * 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", "jedec,spi-nor";
- 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
index dc15884..45256f3 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -54,7 +54,7 @@
chosen {
bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
- stdout-path = &scif0;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -79,77 +79,77 @@
gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
linux,code = <KEY_1>;
label = "SW2-1";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-2 {
gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
linux,code = <KEY_2>;
label = "SW2-2";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-3 {
gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
linux,code = <KEY_3>;
label = "SW2-3";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-4 {
gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
linux,code = <KEY_4>;
label = "SW2-4";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-a {
gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
linux,code = <KEY_A>;
label = "SW30";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-b {
gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
linux,code = <KEY_B>;
label = "SW31";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-c {
gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
linux,code = <KEY_C>;
label = "SW32";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-d {
gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
linux,code = <KEY_D>;
label = "SW33";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-e {
gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
linux,code = <KEY_E>;
label = "SW34";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-f {
gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
linux,code = <KEY_F>;
label = "SW35";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
key-g {
gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
linux,code = <KEY_G>;
label = "SW36";
- gpio-key,wakeup;
+ wakeup-source;
debounce-interval = <20>;
};
};
@@ -242,6 +242,13 @@
1800000 0>;
};
+ audio_clock: clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <11289600>;
+ clock-output-names = "audio_clock";
+ };
+
rsnd_ak4643: sound {
compatible = "simple-audio-card";
@@ -255,7 +262,7 @@
sndcodec: simple-audio-card,codec {
sound-dai = <&ak4643>;
- system-clock-frequency = <11289600>;
+ clocks = <&audio_clock>;
};
};
@@ -319,7 +326,7 @@
};
du_pins: du {
- renesas,groups = "du_rgb666", "du_sync", "du_disp", "du_clk_out_0";
+ renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
renesas,function = "du";
};
@@ -472,8 +479,6 @@
status = "okay";
flash: flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "spansion,s25fl512s", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <30000000>;
@@ -483,19 +488,25 @@
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>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 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>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts
new file mode 100644
index 0000000..01d239c
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7791-porter.dts
@@ -0,0 +1,305 @@
+/*
+ * Device Tree Source for the Porter board
+ *
+ * Copyright (C) 2015 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 = "Porter";
+ compatible = "renesas,porter", "renesas,r8a7791";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = "serial0:115200n8";
+ };
+
+ 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";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+
+ i2c2_pins: i2c2 {
+ renesas,groups = "i2c2";
+ renesas,function = "i2c2";
+ };
+
+ 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 = "ok";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&irqc0>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <1>;
+ };
+};
+
+&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";
+};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "spansion,s25fl512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ m25p,fast-read;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 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>;
+ };
+ };
+ };
+};
+
+&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>;
+ };
+ };
+ };
+};
+
+&sata0 {
+ status = "okay";
+};
+
+/* composite video input */
+&vin0 {
+ status = "ok";
+ pinctrl-0 = <&vin0_pins>;
+ pinctrl-names = "default";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vin0ep: endpoint {
+ remote-endpoint = <&adv7180>;
+ bus-width = <8>;
+ };
+ };
+};
+
+&pci0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pci1 {
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&hsusb {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&pcie_bus_clk {
+ status = "okay";
+};
+
+&pciec {
+ status = "okay";
+};
+
+&can0 {
+ pinctrl-0 = <&can0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1666c8a..2a369dd 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -100,7 +100,7 @@
interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
- gpio-ranges = <&pfc 0 32 32>;
+ gpio-ranges = <&pfc 0 32 26>;
#interrupt-cells = <2>;
interrupt-controller;
clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
@@ -255,7 +255,7 @@
};
dmac0: dma-controller@e6700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
reg = <0 0xe6700000 0 0x20000>;
interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
0 200 IRQ_TYPE_LEVEL_HIGH
@@ -286,7 +286,7 @@
};
dmac1: dma-controller@e6720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
reg = <0 0xe6720000 0 0x20000>;
interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
0 216 IRQ_TYPE_LEVEL_HIGH
@@ -317,7 +317,7 @@
};
audma0: dma-controller@ec700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
reg = <0 0xec700000 0 0x10000>;
interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH
0 320 IRQ_TYPE_LEVEL_HIGH
@@ -346,7 +346,7 @@
};
audma1: dma-controller@ec720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac";
reg = <0 0xec720000 0 0x10000>;
interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH
0 333 IRQ_TYPE_LEVEL_HIGH
@@ -375,7 +375,7 @@
};
usb_dmac0: dma-controller@e65a0000 {
- compatible = "renesas,usb-dmac";
+ compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
reg = <0 0xe65a0000 0 0x100>;
interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH
0 109 IRQ_TYPE_LEVEL_HIGH>;
@@ -387,7 +387,7 @@
};
usb_dmac1: dma-controller@e65b0000 {
- compatible = "renesas,usb-dmac";
+ compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac";
reg = <0 0xe65b0000 0 0x100>;
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH
0 110 IRQ_TYPE_LEVEL_HIGH>;
@@ -407,6 +407,7 @@
interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -418,6 +419,7 @@
interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -429,6 +431,7 @@
interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -440,6 +443,7 @@
interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -451,6 +455,7 @@
interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <6>;
status = "disabled";
};
@@ -463,6 +468,7 @@
interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
power-domains = <&cpg_clocks>;
+ i2c-scl-internal-delay-ns = <110>;
status = "disabled";
};
@@ -509,7 +515,6 @@
pfc: pfc@e6060000 {
compatible = "renesas,pfc-r8a7791";
reg = <0 0xe6060000 0 0x250>;
- #gpio-range-cells = <3>;
};
mmcif0: mmc@ee200000 {
@@ -786,6 +791,18 @@
status = "disabled";
};
+ avb: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a7791",
+ "renesas,etheravb-rcar-gen2";
+ reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
+ interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7791_CLK_ETHERAVB>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
sata0: sata@ee300000 {
compatible = "renesas,sata-r8a7791";
reg = <0 0xee300000 0 0x2000>;
@@ -1163,14 +1180,6 @@
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>;
@@ -1338,16 +1347,18 @@
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>;
+ <&zg_clk>, <&hp_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
+ R8A7791_CLK_ETHERAVB R8A7791_CLK_ETHER
+ R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
>;
clock-output-names =
- "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0", "ether",
- "sata1", "sata0";
+ "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0",
+ "etheravb", "ether", "sata1", "sata0";
};
mstp9_clks: mstp9_clks@e6150994 {
compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -1579,7 +1590,7 @@
};
ipmmu_sy0: mmu@e6280000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xe6280000 0 0x1000>;
interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
<0 224 IRQ_TYPE_LEVEL_HIGH>;
@@ -1588,7 +1599,7 @@
};
ipmmu_sy1: mmu@e6290000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xe6290000 0 0x1000>;
interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -1596,7 +1607,7 @@
};
ipmmu_ds: mmu@e6740000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xe6740000 0 0x1000>;
interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
<0 199 IRQ_TYPE_LEVEL_HIGH>;
@@ -1605,7 +1616,7 @@
};
ipmmu_mp: mmu@ec680000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xec680000 0 0x1000>;
interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -1613,7 +1624,7 @@
};
ipmmu_mx: mmu@fe951000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xfe951000 0 0x1000>;
interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
<0 221 IRQ_TYPE_LEVEL_HIGH>;
@@ -1622,7 +1633,7 @@
};
ipmmu_rt: mmu@ffc80000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xffc80000 0 0x1000>;
interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -1630,7 +1641,7 @@
};
ipmmu_gp: mmu@e62a0000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa";
reg = <0 0xe62a0000 0 0x1000>;
interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
<0 261 IRQ_TYPE_LEVEL_HIGH>;
@@ -1649,7 +1660,7 @@
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x1280>, /* SSI */
+ <0 0xec541000 0 0x280>, /* SSI */
<0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts
index 96443ec..baa59fe 100644
--- a/arch/arm/boot/dts/r8a7793-gose.dts
+++ b/arch/arm/boot/dts/r8a7793-gose.dts
@@ -24,7 +24,7 @@
chosen {
bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
- stdout-path = &scif0;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -37,7 +37,37 @@
clock-frequency = <20000000>;
};
+&pfc {
+ 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";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+};
+
&ether {
+ pinctrl-0 = <&ether_pins &phy1_pins>;
+ pinctrl-names = "default";
+
phy-handle = <&phy1>;
renesas,ether-link-active-low;
status = "okay";
@@ -55,9 +85,54 @@
};
&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+
status = "okay";
};
&scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+
status = "okay";
};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "spansion,s25fl512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-cpol;
+ spi-cpha;
+ m25p,fast-read;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 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>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index c465404..aef9e69 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -18,6 +18,10 @@
#address-cells = <2>;
#size-cells = <2>;
+ aliases {
+ spi0 = &qspi;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -53,6 +57,118 @@
interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO0>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7793", "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 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7793_CLK_GPIO1>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO2>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO3>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO4>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO5>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO6>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio7: gpio@e6055800 {
+ compatible = "renesas,gpio-r8a7793", "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 R8A7793_CLK_GPIO7>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ thermal@e61f0000 {
+ compatible = "renesas,thermal-r8a7793", "renesas,rcar-thermal";
+ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+ interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp5_clks R8A7793_CLK_THERMAL>;
+ power-domains = <&cpg_clocks>;
+ };
+
timer {
compatible = "arm,armv7-timer";
interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
@@ -114,12 +230,189 @@
power-domains = <&cpg_clocks>;
};
+ pfc: pfc@e6060000 {
+ compatible = "renesas,pfc-r8a7793";
+ reg = <0 0xe6060000 0 0x250>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ compatible = "renesas,dmac-r8a7793", "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 R8A7793_CLK_SYS_DMAC0>;
+ clock-names = "fck";
+ power-domains = <&cpg_clocks>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ dmac1: dma-controller@e6720000 {
+ compatible = "renesas,dmac-r8a7793", "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 R8A7793_CLK_SYS_DMAC1>;
+ clock-names = "fck";
+ power-domains = <&cpg_clocks>;
+ #dma-cells = <1>;
+ dma-channels = <15>;
+ };
+
+ scifa0: serial@e6c40000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x21>, <&dmac0 0x22>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifa1: serial@e6c50000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x25>, <&dmac0 0x26>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifa2: serial@e6c60000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c60000 0 64>;
+ interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x27>, <&dmac0 0x28>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifa3: serial@e6c70000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c70000 0 64>;
+ interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifa4: serial@e6c78000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c78000 0 64>;
+ interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifa5: serial@e6c80000 {
+ compatible = "renesas,scifa-r8a7793", "renesas,scifa";
+ reg = <0 0xe6c80000 0 64>;
+ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x23>, <&dmac0 0x24>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifb0: serial@e6c20000 {
+ compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+ reg = <0 0xe6c20000 0 64>;
+ interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifb1: serial@e6c30000 {
+ compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+ reg = <0 0xe6c30000 0 64>;
+ interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scifb2: serial@e6ce0000 {
+ compatible = "renesas,scifb-r8a7793", "renesas,scifb";
+ reg = <0 0xe6ce0000 0 64>;
+ interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
scif0: serial@e6e60000 {
compatible = "renesas,scif-r8a7793", "renesas,scif";
reg = <0 0xe6e60000 0 64>;
interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp7_clks R8A7793_CLK_SCIF0>;
clock-names = "sci_ick";
+ dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
+ dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
status = "disabled";
};
@@ -130,6 +423,92 @@
interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp7_clks R8A7793_CLK_SCIF1>;
clock-names = "sci_ick";
+ dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scif2: serial@e6e58000 {
+ compatible = "renesas,scif-r8a7793", "renesas,scif";
+ reg = <0 0xe6e58000 0 64>;
+ interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_SCIF2>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scif3: serial@e6ea8000 {
+ compatible = "renesas,scif-r8a7793", "renesas,scif";
+ reg = <0 0xe6ea8000 0 64>;
+ interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_SCIF3>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scif4: serial@e6ee0000 {
+ compatible = "renesas,scif-r8a7793", "renesas,scif";
+ reg = <0 0xe6ee0000 0 64>;
+ interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_SCIF4>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ scif5: serial@e6ee8000 {
+ compatible = "renesas,scif-r8a7793", "renesas,scif";
+ reg = <0 0xe6ee8000 0 64>;
+ interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_SCIF5>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ hscif0: serial@e62c0000 {
+ compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+ reg = <0 0xe62c0000 0 96>;
+ interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ hscif1: serial@e62c8000 {
+ compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+ reg = <0 0xe62c8000 0 96>;
+ interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ hscif2: serial@e62d0000 {
+ compatible = "renesas,hscif-r8a7793", "renesas,hscif";
+ reg = <0 0xe62d0000 0 96>;
+ interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
+ dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
status = "disabled";
};
@@ -146,6 +525,50 @@
status = "disabled";
};
+ qspi: spi@e6b10000 {
+ compatible = "renesas,qspi-r8a7793", "renesas,qspi";
+ reg = <0 0xe6b10000 0 0x2c>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7793_CLK_QSPI_MOD>;
+ dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a7793";
+ 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 R8A7793_CLK_DU0>,
+ <&mstp7_clks R8A7793_CLK_DU1>,
+ <&mstp7_clks R8A7793_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 {
+ };
+ };
+ };
+ };
+
clocks {
#address-cells = <2>;
#size-cells = <2>;
@@ -299,6 +722,21 @@
"tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
"vsp1-du0", "vsps";
};
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,r8a7793-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>, <&zs_clk>, <&zs_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7793_CLK_SCIFA2 R8A7793_CLK_SCIFA1 R8A7793_CLK_SCIFA0
+ R8A7793_CLK_SCIFB0 R8A7793_CLK_SCIFB1 R8A7793_CLK_SCIFB2
+ R8A7793_CLK_SYS_DMAC1 R8A7793_CLK_SYS_DMAC0
+ >;
+ clock-output-names =
+ "scifa2", "scifa1", "scifa0", "scifb0",
+ "scifb1", "scifb2", "sys-dmac1", "sys-dmac0";
+ };
mstp3_clks: mstp3_clks@e615013c {
compatible = "renesas,r8a7793-mstp-clocks",
"renesas,cpg-mstp-clocks";
@@ -329,6 +767,14 @@
clock-indices = <R8A7793_CLK_IRQC>;
clock-output-names = "irqc";
};
+ mstp5_clks: mstp5_clks@e6150144 {
+ compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+ clocks = <&extal_clk>;
+ #clock-cells = <1>;
+ clock-indices = <R8A7793_CLK_THERMAL>;
+ clock-output-names = "thermal";
+ };
mstp7_clks: mstp7_clks@e615014c {
compatible = "renesas,r8a7793-mstp-clocks",
"renesas,cpg-mstp-clocks";
@@ -369,6 +815,94 @@
"ipmmu_sgx", "vin2", "vin1", "vin0", "ether",
"sata1", "sata0";
};
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7793-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>,
+ <&cpg_clocks R8A7793_CLK_QSPI>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7793_CLK_GPIO7 R8A7793_CLK_GPIO6
+ R8A7793_CLK_GPIO5 R8A7793_CLK_GPIO4
+ R8A7793_CLK_GPIO3 R8A7793_CLK_GPIO2
+ R8A7793_CLK_GPIO1 R8A7793_CLK_GPIO0
+ R8A7793_CLK_QSPI_MOD
+ >;
+ clock-output-names =
+ "gpio7", "gpio6", "gpio5", "gpio4",
+ "gpio3", "gpio2", "gpio1", "gpio0",
+ "qspi_mod";
+ };
+ mstp11_clks: mstp11_clks@e615099c {
+ compatible = "renesas,r8a7793-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 = <
+ R8A7793_CLK_SCIFA3 R8A7793_CLK_SCIFA4 R8A7793_CLK_SCIFA5
+ >;
+ clock-output-names = "scifa3", "scifa4", "scifa5";
+ };
+ };
+
+ ipmmu_sy0: mmu@e6280000 {
+ compatible = "renesas,ipmmu-r8a7793", "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-r8a7793", "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-r8a7793", "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-r8a7793", "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-r8a7793", "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-r8a7793", "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-r8a7793", "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/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index 928cfa6..2394e48 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -21,7 +21,7 @@
chosen {
bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
- stdout-path = &scif2;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -33,17 +33,115 @@
#address-cells = <1>;
#size-cells = <1>;
};
+
+ vga-encoder {
+ compatible = "adi,adv7123";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7123_in: endpoint {
+ remote-endpoint = <&du_out_rgb1>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ adv7123_out: endpoint {
+ remote-endpoint = <&vga_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_in: endpoint {
+ remote-endpoint = <&adv7123_out>;
+ };
+ };
+ };
+
+ x2_clk: x2-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <74250000>;
+ };
+
+ 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 R8A7794_CLK_DU0>,
+ <&mstp7_clks R8A7794_CLK_DU0>,
+ <&x13_clk>, <&x2_clk>;
+ clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1";
+
+ ports {
+ port@1 {
+ endpoint {
+ remote-endpoint = <&adv7123_in>;
+ };
+ };
+ };
};
&extal_clk {
clock-frequency = <20000000>;
};
+&pfc {
+ du_pins: du {
+ renesas,groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0";
+ renesas,function = "du";
+ };
+
+ scif2_pins: serial2 {
+ renesas,groups = "scif2_data";
+ renesas,function = "scif2";
+ };
+
+ ether_pins: ether {
+ renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+ renesas,function = "eth";
+ };
+
+ phy1_pins: phy1 {
+ renesas,groups = "intc_irq8";
+ renesas,function = "intc";
+ };
+
+ i2c1_pins: i2c1 {
+ renesas,groups = "i2c1";
+ renesas,function = "i2c1";
+ };
+
+ vin0_pins: vin0 {
+ renesas,groups = "vin0_data8", "vin0_clk";
+ renesas,function = "vin0";
+ };
+};
+
&cmt0 {
status = "okay";
};
&ether {
+ pinctrl-0 = <&ether_pins &phy1_pins>;
+ pinctrl-names = "default";
+
phy-handle = <&phy1>;
renesas,ether-link-active-low;
status = "okay";
@@ -56,6 +154,46 @@
};
};
+&i2c1 {
+ pinctrl-0 = <&i2c1_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>;
+ };
+ };
+ };
+};
+
+&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>;
+ };
+ };
+};
+
&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
status = "okay";
};
diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
index d4dd5a3..5153e3a 100644
--- a/arch/arm/boot/dts/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -12,6 +12,7 @@
/dts-v1/;
#include "r8a7794.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "SILK";
@@ -23,7 +24,7 @@
chosen {
bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
- stdout-path = &scif2;
+ stdout-path = "serial0:115200n8";
};
memory@40000000 {
@@ -39,6 +40,30 @@
regulator-boot-on;
regulator-always-on;
};
+
+ vcc_sdhi1: regulator@3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI1 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi1: regulator@4 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI1 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
};
&extal_clk {
@@ -61,10 +86,40 @@
renesas,function = "intc";
};
+ i2c1_pins: i2c1 {
+ renesas,groups = "i2c1";
+ renesas,function = "i2c1";
+ };
+
mmcif0_pins: mmcif0 {
renesas,groups = "mmc_data8", "mmc_ctrl";
renesas,function = "mmc";
};
+
+ sdhi1_pins: sd1 {
+ renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+ renesas,function = "sdhi1";
+ };
+
+ qspi_pins: spi0 {
+ renesas,groups = "qspi_ctrl", "qspi_data4";
+ renesas,function = "qspi";
+ };
+
+ vin0_pins: vin0 {
+ renesas,groups = "vin0_data8", "vin0_clk";
+ renesas,function = "vin0";
+ };
+
+ usb0_pins: usb0 {
+ renesas,groups = "usb0";
+ renesas,function = "usb0";
+ };
+
+ usb1_pins: usb1 {
+ renesas,groups = "usb1";
+ renesas,function = "usb1";
+ };
};
&scif2 {
@@ -90,6 +145,27 @@
};
};
+&i2c1 {
+ pinctrl-0 = <&i2c1_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>;
+ };
+ };
+ };
+};
+
&mmcif0 {
pinctrl-0 = <&mmcif0_pins>;
pinctrl-names = "default";
@@ -100,3 +176,85 @@
non-removable;
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>;
+ status = "okay";
+};
+
+&qspi {
+ pinctrl-0 = <&qspi_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "spansion,s25fl512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-cpol;
+ spi-cpha;
+ m25p,fast-read;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 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>;
+ };
+ };
+ };
+};
+
+/* 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>;
+ };
+ };
+};
+
+&pci0 {
+ status = "okay";
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+};
+
+&pci1 {
+ status = "okay";
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 97c8e9a..6c78f1f 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -19,6 +19,18 @@
#address-cells = <2>;
#size-cells = <2>;
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ spi0 = &qspi;
+ vin0 = &vin0;
+ vin1 = &vin1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -50,6 +62,97 @@
interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7794", "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 R8A7794_CLK_GPIO0>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7794", "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 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7794_CLK_GPIO1>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7794", "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 R8A7794_CLK_GPIO2>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7794", "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 R8A7794_CLK_GPIO3>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7794", "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 R8A7794_CLK_GPIO4>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7794", "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 28>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7794_CLK_GPIO5>;
+ power-domains = <&cpg_clocks>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7794", "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 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&mstp9_clks R8A7794_CLK_GPIO6>;
+ power-domains = <&cpg_clocks>;
+ };
+
cmt0: timer@ffca0000 {
compatible = "renesas,cmt-48-gen2";
reg = <0 0xffca0000 0 0x1004>;
@@ -114,11 +217,10 @@
pfc: pin-controller@e6060000 {
compatible = "renesas,pfc-r8a7794";
reg = <0 0xe6060000 0 0x11c>;
- #gpio-range-cells = <3>;
};
dmac0: dma-controller@e6700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
reg = <0 0xe6700000 0 0x20000>;
interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
0 200 IRQ_TYPE_LEVEL_HIGH
@@ -149,7 +251,7 @@
};
dmac1: dma-controller@e6720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac";
reg = <0 0xe6720000 0 0x20000>;
interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
0 216 IRQ_TYPE_LEVEL_HIGH
@@ -407,6 +509,79 @@
status = "disabled";
};
+ /* The memory map in the User's Manual maps the cores to bus numbers */
+ i2c0: i2c@e6508000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C0>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6518000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6518000 0 0x40>;
+ interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C1>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6530000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6530000 0 0x40>;
+ interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C2>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e6540000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6540000 0 0x40>;
+ interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C3>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e6520000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6520000 0 0x40>;
+ interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C4>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@e6528000 {
+ compatible = "renesas,i2c-r8a7794";
+ reg = <0 0xe6528000 0 0x40>;
+ interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_I2C5>;
+ power-domains = <&cpg_clocks>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
mmcif0: mmc@ee200000 {
compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif";
reg = <0 0xee200000 0 0x80>;
@@ -446,6 +621,168 @@
status = "disabled";
};
+ qspi: spi@e6b10000 {
+ compatible = "renesas,qspi-r8a7794", "renesas,qspi";
+ reg = <0 0xe6b10000 0 0x2c>;
+ interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>;
+ dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg_clocks>;
+ num-cs = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a7794";
+ reg = <0 0xe6ef0000 0 0x1000>;
+ interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7794_CLK_VIN0>;
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ vin1: video@e6ef1000 {
+ compatible = "renesas,vin-r8a7794";
+ reg = <0 0xe6ef1000 0 0x1000>;
+ interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp8_clks R8A7794_CLK_VIN1>;
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+ };
+
+ pci0: pci@ee090000 {
+ compatible = "renesas,pci-r8a7794";
+ device_type = "pci";
+ reg = <0 0xee090000 0 0xc00>,
+ <0 0xee080000 0 0x1100>;
+ interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_EHCI>;
+ power-domains = <&cpg_clocks>;
+ 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-r8a7794";
+ device_type = "pci";
+ reg = <0 0xee0d0000 0 0xc00>,
+ <0 0xee0c0000 0 0x1100>;
+ interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_EHCI>;
+ power-domains = <&cpg_clocks>;
+ 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";
+ };
+ };
+
+ hsusb: usb@e6590000 {
+ compatible = "renesas,usbhs-r8a7794";
+ reg = <0 0xe6590000 0 0x100>;
+ interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_HSUSB>;
+ power-domains = <&cpg_clocks>;
+ renesas,buswait = <4>;
+ phys = <&usb0 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usbphy: usb-phy@e6590100 {
+ compatible = "renesas,usb-phy-r8a7794";
+ reg = <0 0xe6590100 0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&mstp7_clks R8A7794_CLK_HSUSB>;
+ clock-names = "usbhs";
+ power-domains = <&cpg_clocks>;
+ status = "disabled";
+
+ usb0: usb-channel@0 {
+ reg = <0>;
+ #phy-cells = <1>;
+ };
+ usb2: usb-channel@2 {
+ reg = <2>;
+ #phy-cells = <1>;
+ };
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a7794";
+ reg = <0 0xfeb00000 0 0x40000>;
+ reg-names = "du";
+ interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+ <0 268 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp7_clks R8A7794_CLK_DU0>,
+ <&mstp7_clks R8A7794_CLK_DU0>;
+ clock-names = "du.0", "du.1";
+ 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 = <2>;
#size-cells = <2>;
@@ -575,14 +912,6 @@
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>;
@@ -721,19 +1050,20 @@
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>;
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+ <&zx_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
+ R8A7794_CLK_SCIF0 R8A7794_CLK_DU0
>;
clock-output-names =
"ehci", "hsusb",
"hscif2", "scif5", "scif4", "hscif1", "hscif0",
- "scif3", "scif2", "scif1", "scif0";
+ "scif3", "scif2", "scif1", "scif0", "du0";
};
mstp8_clks: mstp8_clks@e6150990 {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -749,16 +1079,22 @@
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>;
+ clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&cp_clk>, <&cp_clk>, <&cp_clk>,
+ <&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-indices = <R8A7794_CLK_GPIO6 R8A7794_CLK_GPIO5
+ R8A7794_CLK_GPIO4 R8A7794_CLK_GPIO3
+ R8A7794_CLK_GPIO2 R8A7794_CLK_GPIO1
+ R8A7794_CLK_GPIO0 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";
+ "gpio6", "gpio5", "gpio4", "gpio3", "gpio2",
+ "gpio1", "gpio0", "qspi_mod",
+ "i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
};
mstp11_clks: mstp11_clks@e615099c {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -773,7 +1109,7 @@
};
ipmmu_sy0: mmu@e6280000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
reg = <0 0xe6280000 0 0x1000>;
interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>,
<0 224 IRQ_TYPE_LEVEL_HIGH>;
@@ -782,7 +1118,7 @@
};
ipmmu_sy1: mmu@e6290000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
reg = <0 0xe6290000 0 0x1000>;
interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -790,15 +1126,16 @@
};
ipmmu_ds: mmu@e6740000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7794", "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";
+ compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
reg = <0 0xec680000 0 0x1000>;
interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>;
#iommu-cells = <1>;
@@ -806,15 +1143,16 @@
};
ipmmu_mx: mmu@fe951000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7794", "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_gp: mmu@e62a0000 {
- compatible = "renesas,ipmmu-vmsa";
+ compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa";
reg = <0 0xe62a0000 0 0x1000>;
interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>,
<0 261 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi b/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi
new file mode 100644
index 0000000..a07ebf8
--- /dev/null
+++ b/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Common file for the AA121TD01 panel connected to Renesas R-Car boards
+ *
+ * Copyright (C) 2015 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,aa121td01", "panel-dpi";
+
+ width-mm = <261>;
+ height-mm = <163>;
+
+ panel-timing {
+ /* 1280x800 @60Hz */
+ clock-frequency = <71000000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hsync-len = <70>;
+ hfront-porch = <20>;
+ hback-porch = <70>;
+ vsync-len = <5>;
+ vfront-porch = <3>;
+ vback-porch = <15>;
+ };
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&lvds_connector>;
+ };
+ };
+ };
+};
+
+&lvds_connector {
+ remote-endpoint = <&panel_in>;
+};
diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
new file mode 100644
index 0000000..b3d6ec8
--- /dev/null
+++ b/arch/arm/boot/dts/rk3036-evb.dts
@@ -0,0 +1,78 @@
+/*
+ * 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 "rk3036.dtsi"
+
+/ {
+ model = "Rockchip RK3036 Evaluation board";
+ compatible = "rockchip,rk3036-evb", "rockchip,rk3036";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>;
+ phy = <&phy0>;
+ phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */
+ phy-reset-duration = <10>; /* millisecond */
+
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts
new file mode 100644
index 0000000..6b4ffc3
--- /dev/null
+++ b/arch/arm/boot/dts/rk3036-kylin.dts
@@ -0,0 +1,314 @@
+/*
+ * 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 "rk3036.dtsi"
+
+/ {
+ model = "Rockchip RK3036 KylinBoard";
+ compatible = "rockchip,rk3036-kylin", "rockchip,rk3036";
+
+ 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;
+ };
+};
+
+&acodec {
+ status = "okay";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>;
+ phy = <&phy0>;
+ phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */
+ phy-reset-duration = <10>; /* millisecond */
+
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&emmc {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <2 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>;
+ };
+ };
+
+ vout5: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-name = "vout5";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ 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 = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca_codec";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ 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;
+ };
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&sdio {
+ status = "okay";
+
+ broken-cd;
+ bus-width = <4>;
+ cap-sdio-irq;
+ default-sample-phase = <90>;
+ keep-power-in-suspend;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>;
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&pinctrl {
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ sleep {
+ global_pwroff: global-pwroff {
+ rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
new file mode 100644
index 0000000..609319c
--- /dev/null
+++ b/arch/arm/boot/dts/rk3036.dtsi
@@ -0,0 +1,661 @@
+/*
+ * 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 <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/rk3036-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "rockchip,rk3036";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ mshc0 = &emmc;
+ mshc1 = &sdmmc;
+ mshc2 = &sdio;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3036-smp";
+
+ cpu0: cpu@f00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ resets = <&cru SRST_CORE0>;
+ operating-points = <
+ /* KHz uV */
+ 816000 1000000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu1: cpu@f01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf01>;
+ resets = <&cru SRST_CORE1>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma@20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ arm,cpu-registers-not-fw-configured;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ bus_intmem@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x2000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x00 0x10>;
+ };
+ };
+
+ gic: interrupt-controller@10139000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0x10139000 0x1000>,
+ <0x1013a000 0x1000>,
+ <0x1013c000 0x2000>,
+ <0x1013e000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ usb_otg: usb@10180000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ dr_mode = "otg";
+ g-np-tx-fifo-size = <16>;
+ g-rx-fifo-size = <275>;
+ g-tx-fifo-size = <256 128 128 64 64 32>;
+ g-use-dma;
+ status = "disabled";
+ };
+
+ usb_host: usb@101c0000 {
+ compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb",
+ "snps,dwc2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG1>;
+ clock-names = "otg";
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ emac: ethernet@10200000 {
+ compatible = "rockchip,rk3036-emac", "snps,arc-emac";
+ reg = <0x10200000 0x4000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rockchip,grf = <&grf>;
+ clocks = <&cru HCLK_MAC>, <&cru SCLK_MACREF>, <&cru SCLK_MAC>;
+ clock-names = "hclk", "macref", "macclk";
+ /*
+ * Fix the emac parent clock is DPLL instead of APLL.
+ * since that will cause some unstable things if the cpufreq
+ * is working. (e.g: the accurate 50MHz what mac_ref need)
+ */
+ assigned-clocks = <&cru SCLK_MACPLL>;
+ assigned-clock-parents = <&cru PLL_DPLL>;
+ max-speed = <100>;
+ phy-mode = "rmii";
+ status = "disabled";
+ };
+
+ sdmmc: dwmmc@10214000 {
+ compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x10214000 0x4000>;
+ clock-frequency = <37500000>;
+ clock-freq-min-max = <400000 37500000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdio: dwmmc@10218000 {
+ compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x10218000 0x4000>;
+ clock-freq-min-max = <400000 37500000>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc@1021c000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ reg = <0x1021c000 0x4000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ clock-frequency = <37500000>;
+ clock-freq-min-max = <400000 37500000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ default-sample-phase = <158>;
+ disable-wp;
+ dmas = <&pdma 12>;
+ dma-names = "rx-tx";
+ fifo-depth = <0x100>;
+ mmc-ddr-1_8v;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ status = "disabled";
+ };
+
+ i2s: i2s@10220000 {
+ compatible = "rockchip,rk3036-i2s", "rockchip,rk3066-i2s";
+ reg = <0x10220000 0x4000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S>, <&cru SCLK_I2S>;
+ dmas = <&pdma 0>, <&pdma 1>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s_bus>;
+ status = "disabled";
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rk3036-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_GPLL>;
+ assigned-clock-rates = <594000000>;
+ };
+
+ grf: syscon@20008000 {
+ compatible = "rockchip,rk3036-grf", "syscon";
+ reg = <0x20008000 0x1000>;
+ };
+
+ acodec: acodec-ana@20030000 {
+ compatible = "rk3036-codec";
+ reg = <0x20030000 0x4000>;
+ rockchip,grf = <&grf>;
+ clock-names = "acodec_pclk";
+ clocks = <&cru PCLK_ACODEC>;
+ status = "disabled";
+ };
+
+ timer: timer@20044000 {
+ compatible = "rockchip,rk3036-timer", "rockchip,rk3288-timer";
+ reg = <0x20044000 0x20>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>, <&cru PCLK_TIMER>;
+ clock-names = "timer", "pclk";
+ };
+
+ pwm0: pwm@20050000 {
+ compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+ reg = <0x20050000 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@20050010 {
+ compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+ reg = <0x20050010 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@20050020 {
+ compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@20050030 {
+ compatible = "rockchip,rk3036-pwm", "rockchip,rk2928-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@20056000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 25 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";
+ };
+
+ i2c2: i2c@2005a000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0x2005a000 0x1000>;
+ interrupts = <GIC_SPI 26 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";
+ };
+
+ uart0: serial@20060000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20060000 0x100>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ status = "disabled";
+ };
+
+ uart1: serial@20064000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20064000 0x100>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ status = "disabled";
+ };
+
+ uart2: serial@20068000 {
+ compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+ reg = <0x20068000 0x100>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@20072000 {
+ compatible = "rockchip,rk3288-i2c";
+ reg = <0x20072000 0x1000>;
+ interrupts = <GIC_SPI 24 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";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3036-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@2007c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2007c000 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@20084000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20084000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ 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;
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins = <0 1 2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <0 27 1 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <1 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdmmc_cd: sdmcc-cd {
+ rockchip,pins = <1 17 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdmmc_bus1: sdmmc-bus1 {
+ rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <1 18 RK_FUNC_1 &pcfg_pull_default>,
+ <1 19 RK_FUNC_1 &pcfg_pull_default>,
+ <1 20 RK_FUNC_1 &pcfg_pull_default>,
+ <1 21 RK_FUNC_1 &pcfg_pull_default>;
+ };
+ };
+
+ sdio {
+ sdio_bus1: sdio-bus1 {
+ rockchip,pins = <0 11 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdio_bus4: sdio-bus4 {
+ rockchip,pins = <0 11 RK_FUNC_1 &pcfg_pull_default>,
+ <0 12 RK_FUNC_1 &pcfg_pull_default>,
+ <0 13 RK_FUNC_1 &pcfg_pull_default>,
+ <0 14 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdio_cmd: sdio-cmd {
+ rockchip,pins = <0 8 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ sdio_clk: sdio-clk {
+ rockchip,pins = <0 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ emmc {
+ /*
+ * We run eMMC at max speed; bump up drive strength.
+ * We also have external pulls, so disable the internal ones.
+ */
+ emmc_clk: emmc-clk {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <2 1 RK_FUNC_2 &pcfg_pull_default>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_default>,
+ <1 25 RK_FUNC_2 &pcfg_pull_default>,
+ <1 26 RK_FUNC_2 &pcfg_pull_default>,
+ <1 27 RK_FUNC_2 &pcfg_pull_default>,
+ <1 28 RK_FUNC_2 &pcfg_pull_default>,
+ <1 29 RK_FUNC_2 &pcfg_pull_default>,
+ <1 30 RK_FUNC_2 &pcfg_pull_default>,
+ <1 31 RK_FUNC_2 &pcfg_pull_default>;
+ };
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_default>, /* crs_dvalid */
+ <2 13 RK_FUNC_1 &pcfg_pull_default>, /* tx_en */
+ <2 14 RK_FUNC_1 &pcfg_pull_default>, /* mac_clk */
+ <2 15 RK_FUNC_1 &pcfg_pull_default>, /* rx_err */
+ <2 16 RK_FUNC_1 &pcfg_pull_default>, /* rxd1 */
+ <2 17 RK_FUNC_1 &pcfg_pull_default>, /* rxd0 */
+ <2 18 RK_FUNC_1 &pcfg_pull_default>, /* txd1 */
+ <2 19 RK_FUNC_1 &pcfg_pull_default>; /* txd0 */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <2 12 RK_FUNC_1 &pcfg_pull_default>, /* mac_md */
+ <2 25 RK_FUNC_1 &pcfg_pull_default>; /* mac_mdclk */
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>,
+ <0 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_none>,
+ <0 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <2 20 RK_FUNC_1 &pcfg_pull_none>,
+ <2 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s {
+ i2s_bus: i2s-bus {
+ rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_none>,
+ <1 1 RK_FUNC_1 &pcfg_pull_none>,
+ <1 2 RK_FUNC_1 &pcfg_pull_none>,
+ <1 3 RK_FUNC_1 &pcfg_pull_none>,
+ <1 4 RK_FUNC_1 &pcfg_pull_none>,
+ <1 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_default>,
+ <0 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_default>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_default>,
+ <2 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart1 */
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_default>,
+ <1 19 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
index c027375..38c91a8 100644
--- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts
+++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
@@ -186,6 +186,8 @@
pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
vmmc-supply = <&vcc_sd0>;
bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
disable-wp;
};
diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
index bae965c..7cdc308 100644
--- a/arch/arm/boot/dts/rk3066a-marsboard.dts
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -178,6 +178,14 @@
};
};
+&mmc0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd0>;
+};
+
&pinctrl {
lan8720a {
phy_int: phy-int {
diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts
index e36383c..341c1f8 100644
--- a/arch/arm/boot/dts/rk3066a-rayeager.dts
+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts
@@ -330,6 +330,8 @@
pinctrl-names = "default";
pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
vmmc-supply = <&vcc_sd>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
status = "okay";
};
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index 946f187..58bac50 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -103,6 +103,8 @@
dma-names = "tx", "rx";
clock-names = "i2s_hclk", "i2s_clk";
clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ rockchip,playback-channels = <8>;
+ rockchip,capture-channels = <2>;
status = "disabled";
};
@@ -118,6 +120,8 @@
dma-names = "tx", "rx";
clock-names = "i2s_hclk", "i2s_clk";
clocks = <&cru HCLK_I2S1>, <&cru SCLK_I2S1>;
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
status = "disabled";
};
@@ -133,6 +137,8 @@
dma-names = "tx", "rx";
clock-names = "i2s_hclk", "i2s_clk";
clocks = <&cru HCLK_I2S2>, <&cru SCLK_I2S2>;
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
status = "disabled";
};
@@ -153,6 +159,19 @@
clock-names = "timer", "pclk";
};
+ efuse: efuse@20010000 {
+ compatible = "rockchip,rockchip-efuse";
+ reg = <0x20010000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage {
+ reg = <0x17 0x1>;
+ };
+ };
+
timer@20038000 {
compatible = "snps,dw-apb-timer-osc";
reg = <0x20038000 0x100>;
diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
index d2180e5..66fa87d 100644
--- a/arch/arm/boot/dts/rk3188-radxarock.dts
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -90,6 +90,21 @@
};
};
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SPDIF";
+
+ simple-audio-card,dai-link@1 { /* S/PDIF - S/PDIF */
+ cpu { sound-dai = <&spdif>; };
+ codec { sound-dai = <&spdif_out>; };
+ };
+ };
+
+ spdif_out: spdif-out {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
ir_recv: gpio-ir-receiver {
compatible = "gpio-ir-receiver";
gpios = <&gpio0 10 1>;
@@ -289,6 +304,8 @@
vmmc-supply = <&vcc_sd0>;
bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
disable-wp;
};
@@ -343,6 +360,10 @@
};
};
+&spdif {
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 3163042..348d46b 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -118,6 +118,22 @@
dma-names = "tx", "rx";
clock-names = "i2s_hclk", "i2s_clk";
clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ status = "disabled";
+ };
+
+ spdif: sound@1011e000 {
+ compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+ reg = <0x1011e000 0x2000>;
+ #sound-dai-cells = <0>;
+ clock-names = "hclk", "mclk";
+ clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+ dmas = <&dmac1_s 8>;
+ dma-names = "tx";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx>;
status = "disabled";
};
@@ -130,6 +146,19 @@
#reset-cells = <1>;
};
+ efuse: efuse@20010000 {
+ compatible = "rockchip,rockchip-efuse";
+ reg = <0x20010000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage {
+ reg = <0x17 0x1>;
+ };
+ };
+
usbphy: phy {
compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
rockchip,grf = <&grf>;
@@ -484,6 +513,12 @@
<RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
};
};
+
+ spdif {
+ spdif_tx: spdif-tx {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
new file mode 100644
index 0000000..e3898b8
--- /dev/null
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -0,0 +1,66 @@
+/*
+ * 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 "rk3228.dtsi"
+
+/ {
+ model = "Rockchip RK3228 Evaluation board";
+ compatible = "rockchip,rk3228-evb", "rockchip,rk3228";
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+};
+
+&emmc {
+ broken-cd;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ disable-wp;
+ non-removable;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3228.dtsi b/arch/arm/boot/dts/rk3228.dtsi
new file mode 100644
index 0000000..119ff12
--- /dev/null
+++ b/arch/arm/boot/dts/rk3228.dtsi
@@ -0,0 +1,442 @@
+/*
+ * 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 <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/rk3228-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "rockchip,rk3228";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@f00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ resets = <&cru SRST_CORE0>;
+ operating-points = <
+ /* KHz uV */
+ 816000 1000000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu1: cpu@f01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf01>;
+ resets = <&cru SRST_CORE1>;
+ };
+
+ cpu2: cpu@f02 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf02>;
+ resets = <&cru SRST_CORE2>;
+ };
+
+ cpu3: cpu@f03 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf03>;
+ resets = <&cru SRST_CORE3>;
+ };
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pdma: pdma@110f0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x110f0000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ 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>;
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ grf: syscon@11000000 {
+ compatible = "syscon";
+ reg = <0x11000000 0x1000>;
+ };
+
+ uart0: serial@11010000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x11010000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: serial@11020000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x11020000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart2: serial@11030000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x11030000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ pwm0: pwm@110b0000 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0x110b0000 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ status = "disabled";
+ };
+
+ pwm1: pwm@110b0010 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0x110b0010 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ status = "disabled";
+ };
+
+ pwm2: pwm@110b0020 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0x110b0020 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ status = "disabled";
+ };
+
+ pwm3: pwm@110b0030 {
+ compatible = "rockchip,rk3288-pwm";
+ reg = <0x110b0030 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ status = "disabled";
+ };
+
+ timer: timer@110c0000 {
+ compatible = "rockchip,rk3288-timer";
+ reg = <0x110c0000 0x20>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>, <&cru PCLK_TIMER>;
+ clock-names = "timer", "pclk";
+ };
+
+ cru: clock-controller@110e0000 {
+ compatible = "rockchip,rk3228-cru";
+ reg = <0x110e0000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_GPLL>;
+ assigned-clock-rates = <594000000>;
+ };
+
+ emmc: dwmmc@30020000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ reg = <0x30020000 0x4000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <37500000>;
+ clock-freq-min-max = <400000 37500000>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ bus-width = <8>;
+ default-sample-phase = <158>;
+ num-slots = <1>;
+ fifo-depth = <0x100>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@32010000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0x32011000 0x1000>,
+ <0x32012000 0x1000>,
+ <0x32014000 0x2000>,
+ <0x32016000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3228-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@11110000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x11110000 0x100>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@11120000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x11120000 0x100>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@11130000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x11130000 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3@11140000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x11140000 0x100>;
+ interrupts = <GIC_SPI 54 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 = <2 7 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <1 22 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_none>,
+ <1 25 RK_FUNC_2 &pcfg_pull_none>,
+ <1 26 RK_FUNC_2 &pcfg_pull_none>,
+ <1 27 RK_FUNC_2 &pcfg_pull_none>,
+ <1 28 RK_FUNC_2 &pcfg_pull_none>,
+ <1 29 RK_FUNC_2 &pcfg_pull_none>,
+ <1 30 RK_FUNC_2 &pcfg_pull_none>,
+ <1 31 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <3 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <0 30 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins = <1 12 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <1 11 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <2 26 RK_FUNC_1 &pcfg_pull_none>,
+ <2 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <2 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <0 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <1 9 RK_FUNC_1 &pcfg_pull_none>,
+ <1 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <1 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
+ <1 19 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ uart2_cts: uart2-cts {
+ rockchip,pins = <0 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart2_rts: uart2-rts {
+ rockchip,pins = <0 24 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
index 43949a6..452ca24 100644
--- a/arch/arm/boot/dts/rk3288-evb-act8846.dts
+++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
@@ -43,10 +43,26 @@
/ {
compatible = "rockchip,rk3288-evb-act8846", "rockchip,rk3288";
-};
-&cpu0 {
- cpu0-supply = <&vdd_cpu>;
+ vcc_lcd: vcc-lcd {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio7 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_en>;
+ regulator-name = "vcc_lcd";
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_wl: vcc-wl {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_pwr>;
+ regulator-name = "vcc_wl";
+ vin-supply = <&vcc_18>;
+ };
};
&i2c0 {
@@ -119,8 +135,8 @@
vdd_log: REG3 {
regulator-name = "VDD_LOG";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1500000>;
regulator-always-on;
};
@@ -133,7 +149,7 @@
vccio_sd: REG5 {
regulator-name = "VCCIO_SD";
- regulator-min-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
@@ -152,7 +168,7 @@
regulator-always-on;
};
- vcca_tp: REG8 {
+ vcc_tp: REG8 {
regulator-name = "VCCA_TP";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -189,3 +205,17 @@
};
};
};
+
+&pinctrl {
+ lcd {
+ lcd_en: lcd-en {
+ rockchip,pins = <7 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_pwr: wifi-pwr {
+ rockchip,pins = <7 9 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts
index 18eb6cb..736b08b 100644
--- a/arch/arm/boot/dts/rk3288-evb-rk808.dts
+++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts
@@ -43,17 +43,6 @@
/ {
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 {
@@ -244,19 +233,3 @@
};
};
};
-
-&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
index f6d2e78..4faabdb 100644
--- a/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -89,6 +89,13 @@
pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
};
+ 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>;
@@ -160,6 +167,10 @@
};
};
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
&emmc {
broken-cd;
bus-width = <8>;
@@ -172,11 +183,6 @@
status = "okay";
};
-&hdmi {
- ddc-i2c-bus = <&i2c5>;
- status = "okay";
-};
-
&sdmmc {
bus-width = <4>;
cap-mmc-highspeed;
@@ -191,6 +197,27 @@
vqmmc-supply = <&vccio_sd>;
};
+&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";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
index 20fa0ef..4e3fd9a 100644
--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
@@ -48,6 +48,14 @@
reg = <0 0x80000000>;
};
+ dovdd_1v8: dovdd-1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "dovdd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc28_dvp>;
+ };
+
ext_gmac: external-gmac-clock {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -55,6 +63,22 @@
clock-output-names = "ext_gmac";
};
+ io_domains: io-domains {
+ compatible = "rockchip,rk3288-io-voltage-domain";
+ rockchip,grf = <&grf>;
+
+ audio-supply = <&vcca_33>;
+ bb-supply = <&vcc_io>;
+ dvp-supply = <&dovdd_1v8>;
+ flash0-supply = <&vcc_flash>;
+ flash1-supply = <&vcc_lan>;
+ gpio30-supply = <&vcc_io>;
+ gpio1830-supply = <&vcc_io>;
+ lcdc-supply = <&vcc_io>;
+ sdcard-supply = <&vccio_sd>;
+ wifi-supply = <&vccio_wl>;
+ };
+
ir: ir-receiver {
compatible = "gpio-ir-receiver";
pinctrl-names = "default";
@@ -96,7 +120,7 @@
};
};
- vcc_sys: vsys-regulator {
+ vbat_wl: vcc_sys: vsys-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_sys";
regulator-min-microvolt = <5000000>;
@@ -160,6 +184,23 @@
regulator-always-on;
vin-supply = <&vcc_5v>;
};
+
+ /*
+ * A TT8142 creates both dovdd_1v8 and vcc28_dvp, controlled
+ * by the dvp_pwr pin.
+ */
+ vcc28_dvp: vcc28-dvp-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dvp_pwr>;
+ regulator-name = "vcc28_dvp";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ vin-supply = <&vcc_io>;
+ };
};
&cpu0 {
@@ -325,7 +366,7 @@
regulator-always-on;
};
- vcc_18: REG11 {
+ vccio_wl: vcc_18: REG11 {
regulator-name = "vcc_18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -373,6 +414,12 @@
};
};
+ dvp {
+ dvp_pwr: dvp-pwr {
+ rockchip,pins = <0 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
gmac {
phy_int: phy-int {
rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -445,7 +492,8 @@
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
- vmmc-supply = <&vcc_18>;
+ vmmc-supply = <&vbat_wl>;
+ vqmmc-supply = <&vccio_wl>;
status = "okay";
};
@@ -459,6 +507,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts
index f82b956..65c4756 100644
--- a/arch/arm/boot/dts/rk3288-popmetal.dts
+++ b/arch/arm/boot/dts/rk3288-popmetal.dts
@@ -79,6 +79,22 @@
};
};
+ io_domains: io-domains {
+ compatible = "rockchip,rk3288-io-voltage-domain";
+ rockchip,grf = <&grf>;
+
+ audio-supply = <&vcca_33>;
+ bb-supply = <&vcc_io>;
+ dvp-supply = <&vcc18_dvp>;
+ flash0-supply = <&vcc_flash>;
+ flash1-supply = <&vcc_lan>;
+ gpio30-supply = <&vcc_io>;
+ gpio1830-supply = <&vcc_io>;
+ lcdc-supply = <&vcc_io>;
+ sdcard-supply = <&vccio_sd>;
+ wifi-supply = <&vccio_wl>;
+ };
+
ir: ir-receiver {
compatible = "gpio-ir-receiver";
gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
@@ -86,6 +102,26 @@
pinctrl-0 = <&ir_int>;
};
+ vcc_flash: flash-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_flash";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ 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_sys: vsys-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_sys";
@@ -94,6 +130,31 @@
regulator-always-on;
regulator-boot-on;
};
+
+ /*
+ * A PT5128 creates both dovdd_1v8 and vcc28_dvp, controlled
+ * by the dvp_pwr pin.
+ */
+ vcc18_dvp: vcc18-dvp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc18-dvp";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc28_dvp>;
+ };
+
+ vcc28_dvp: vcc28-dvp-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dvp_pwr>;
+ regulator-name = "vcc28_dvp";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ vin-supply = <&vcc_io>;
+ };
};
&cpu0 {
@@ -109,6 +170,8 @@
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";
};
@@ -121,6 +184,8 @@
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
status = "okay";
};
@@ -297,22 +362,22 @@
};
};
- vcca_codec: LDO_REG8 {
+ vcca_33: LDO_REG8 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-name = "vcca_codec";
+ regulator-name = "vcca_33";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
- vcc_wl: SWITCH_REG1 {
+ vccio_wl: SWITCH_REG1 {
regulator-always-on;
regulator-boot-on;
- regulator-name = "vcc_wl";
+ regulator-name = "vccio_wl";
regulator-state-mem {
regulator-on-in-suspend;
};
@@ -388,6 +453,12 @@
};
};
+ dvp {
+ dvp_pwr: dvp-pwr {
+ rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
ir {
ir_int: ir-int {
rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -405,6 +476,12 @@
rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&tsadc {
diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts
index 14b9fc7..17f13c7 100644
--- a/arch/arm/boot/dts/rk3288-r89.dts
+++ b/arch/arm/boot/dts/rk3288-r89.dts
@@ -78,6 +78,13 @@
};
};
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
vcc_host: vcc-host-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -310,6 +317,12 @@
};
};
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
pmic {
pmic_int: pmic-int {
rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
new file mode 100644
index 0000000..1ece66f
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
@@ -0,0 +1,278 @@
+/*
+ * 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 <dt-bindings/pwm/pwm.h>
+#include "rk3288.dtsi"
+
+/ {
+ memory {
+ reg = <0x0 0x80000000>;
+ device_type = "memory";
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
+ };
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ };
+
+ 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 {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ vmmc-supply = <&vcc_io>;
+ status = "okay";
+};
+
+&gmac {
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ clock_in_out = "input";
+ phy-mode = "rgmii";
+ phy-supply = <&vccio_pmu>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins &phy_rst>;
+ snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 30000>;
+ rx_delay = <0x10>;
+ tx_delay = <0x30>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ system-power-controller;
+ inl1-supply = <&vcc_io>;
+ inl2-supply = <&vcc_sys>;
+ inl3-supply = <&vcc_20>;
+ vp1-supply = <&vcc_sys>;
+ vp2-supply = <&vcc_sys>;
+ vp3-supply = <&vcc_sys>;
+ vp4-supply = <&vcc_sys>;
+
+ 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;
+ };
+ };
+ };
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <300>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <8000>;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ reg = <0x41>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <300>;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-name = "vdd_gpu";
+ regulator-ramp-delay = <8000>;
+ vin-supply = <&vcc_sys>;
+ };
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ emmc {
+ emmc_reset: emmc-reset {
+ rockchip,pins = <3 9 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gmac {
+ phy_rst: phy-rst {
+ rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+};
+
+&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";
+};
+
+&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-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
new file mode 100644
index 0000000..c5453a0
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
@@ -0,0 +1,180 @@
+/*
+ * 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-rock2-som.dtsi"
+
+/ {
+ model = "Radxa Rock 2 Square";
+ compatible = "radxa,rock2-square", "rockchip,rk3288";
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SPDIF";
+ simple-audio-card,dai-link@1 { /* S/PDIF - S/PDIF */
+ cpu { sound-dai = <&spdif>; };
+ codec { sound-dai = <&spdif_out>; };
+ };
+ };
+
+ spdif_out: spdif-out {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ vcc_usb_host: vcc-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ /* Always on as the rockchip usb phy doesn't have a vbus-supply
+ * property
+ */
+ regulator-always-on;
+ regulator-name = "vcc_host";
+ };
+
+ 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>;
+ vin-supply = <&vcc_io>;
+ };
+};
+
+&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>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&gmac {
+ status = "ok";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&i2c0 {
+ hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio0>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>;
+
+ };
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&pinctrl {
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&spdif {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-thermal.dtsi b/arch/arm/boot/dts/rk3288-thermal.dtsi
index 3404066..651b962 100644
--- a/arch/arm/boot/dts/rk3288-thermal.dtsi
+++ b/arch/arm/boot/dts/rk3288-thermal.dtsi
@@ -52,7 +52,7 @@ reserve_thermal: reserve_thermal {
};
cpu_thermal: cpu_thermal {
- polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay-passive = <100>; /* milliseconds */
polling-delay = <5000>; /* milliseconds */
thermal-sensors = <&tsadc 1>;
@@ -63,6 +63,11 @@ cpu_thermal: cpu_thermal {
hysteresis = <2000>; /* millicelsius */
type = "passive";
};
+ cpu_alert1: cpu_alert1 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
cpu_crit: cpu_crit {
temperature = <90000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
@@ -74,13 +79,18 @@ cpu_thermal: cpu_thermal {
map0 {
trip = <&cpu_alert0>;
cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT 6>;
+ };
+ map1 {
+ trip = <&cpu_alert1>;
+ cooling-device =
<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
gpu_thermal: gpu_thermal {
- polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay-passive = <100>; /* milliseconds */
polling-delay = <5000>; /* milliseconds */
thermal-sensors = <&tsadc 2>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-brain.dts b/arch/arm/boot/dts/rk3288-veyron-brain.dts
new file mode 100644
index 0000000..cf5311d
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-brain.dts
@@ -0,0 +1,139 @@
+/*
+ * Google Veyron Brain Rev 0 board device tree source
+ *
+ * Copyright 2014 Google, 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.
+ *
+ * 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-veyron.dtsi"
+
+/ {
+ model = "Google Brain";
+ compatible = "google,veyron-brain-rev0", "google,veyron-brain",
+ "google,veyron", "rockchip,rk3288";
+
+ vcc33_sys: vcc33-sys {
+ vin-supply = <&vcc_5v>;
+ };
+
+ vcc33_io: vcc33_io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc33_io";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc33_sys>;
+ /* This is gated by vcc_18 too */
+ };
+
+ /* This turns on vbus for host2 and otg (dwc2) */
+ vcc5_host2: vcc5-host2-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_pwr_en>;
+ regulator-name = "vcc5_host2";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&pinctrl {
+ hdmi {
+ vcc50_hdmi_en: vcc50-hdmi-en {
+ rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ dvs_1: dvs-1 {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ dvs_2: dvs-2 {
+ rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ usb-host {
+ usb2_pwr_en: usb2-pwr-en {
+ rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&rk808 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+ dvs-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>,
+ <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+ /delete-property/ vcc6-supply;
+
+ regulators {
+ /* vcc33_io is sourced directly from vcc33_sys */
+ /delete-node/ LDO_REG1;
+
+ /* This is not a pwren anymore, but the real power supply */
+ vdd10_lcd: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd10_lcd";
+ regulator-suspend-mem-disabled;
+ };
+
+ vcc18_hdmi: SWITCH_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc18_hdmi";
+ regulator-suspend-mem-disabled;
+ };
+ };
+};
+
+&vcc50_hdmi {
+ enable-active-high;
+ gpio = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc50_hdmi_en>;
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
new file mode 100644
index 0000000..c2f52cf
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
@@ -0,0 +1,176 @@
+/*
+ * Google Veyron Jaq Rev 1+ board device tree source
+ *
+ * Copyright 2015 Google, 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.
+ *
+ * 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-veyron-chromebook.dtsi"
+#include "cros-ec-sbs.dtsi"
+
+/ {
+ model = "Google Jaq";
+ compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+ "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+ "google,veyron-jaq-rev1", "google,veyron-jaq",
+ "google,veyron", "rockchip,rk3288";
+
+ panel_regulator: panel-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_enable_h>;
+ regulator-name = "panel_regulator";
+ vin-supply = <&vcc33_sys>;
+ };
+
+ vcc18_lcd: vcc18-lcd {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&avdd_1v8_disp_en>;
+ regulator-name = "vcc18_lcd";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc18_wl>;
+ };
+
+ backlight_regulator: backlight-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_pwr_en>;
+ regulator-name = "backlight_regulator";
+ vin-supply = <&vcc33_sys>;
+ startup-delay-us = <15000>;
+ };
+};
+
+&rk808 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+ dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+ <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+ regulators {
+ mic_vcc: LDO_REG2 {
+ regulator-name = "mic_vcc";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+};
+
+&sdmmc {
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+ &sdmmc_bus4>;
+};
+
+&vcc_5v {
+ enable-active-high;
+ gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+ enable-active-high;
+ gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+ backlight {
+ bl_pwr_en: bl_pwr_en {
+ rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ buck-5v {
+ drv_5v: drv-5v {
+ rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ edp {
+ edp_hpd: edp_hpd {
+ rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
+ };
+ };
+
+ hdmi {
+ vcc50_hdmi_en: vcc50-hdmi-en {
+ rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ lcd {
+ lcd_enable_h: lcd-en {
+ rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ avdd_1v8_disp_en: avdd-1v8-disp-en {
+ rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ dvs_1: dvs-1 {
+ rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ dvs_2: dvs-2 {
+ rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-mickey.dts b/arch/arm/boot/dts/rk3288-veyron-mickey.dts
new file mode 100644
index 0000000..f36f6f4
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-mickey.dts
@@ -0,0 +1,250 @@
+/*
+ * Google Veyron Mickey Rev 0 board device tree source
+ *
+ * Copyright 2015 Google, 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.
+ *
+ * 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-veyron.dtsi"
+
+/ {
+ model = "Google Mickey";
+ compatible = "google,veyron-mickey-rev8", "google,veyron-mickey-rev7",
+ "google,veyron-mickey-rev6", "google,veyron-mickey-rev5",
+ "google,veyron-mickey-rev4", "google,veyron-mickey-rev3",
+ "google,veyron-mickey-rev2", "google,veyron-mickey-rev1",
+ "google,veyron-mickey-rev0", "google,veyron-mickey",
+ "google,veyron", "rockchip,rk3288";
+
+ vcc_5v: vcc-5v {
+ vin-supply = <&vcc33_sys>;
+ };
+
+ vcc33_io: vcc33_io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc33_io";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc33_sys>;
+ };
+};
+
+&cpu_thermal {
+ /delete-node/ trips;
+ /delete-node/ cooling-maps;
+
+ trips {
+ cpu_alert_almost_warm: cpu_alert_almost_warm {
+ temperature = <63000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert_warm: cpu_alert_warm {
+ temperature = <65000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert_almost_hot: cpu_alert_almost_hot {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert_hot: cpu_alert_hot {
+ temperature = <82000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert_hotter: cpu_alert_hotter {
+ temperature = <84000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert_very_hot: cpu_alert_very_hot {
+ temperature = <85000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_crit: cpu_crit {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /*
+ * After 1st level, throttle the CPU down to as low as 1.4 GHz
+ * and don't let the GPU go faster than 400 MHz. Note that we
+ * won't throttle the GPU lower than 400 MHz due to CPU
+ * heat--we'll let the GPU do the rest itself.
+ */
+ cpu_warm_limit_cpu {
+ trip = <&cpu_alert_warm>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT 4>;
+ };
+
+ /*
+ * Add some discrete steps to help throttling system deal
+ * with the fact that there are two passive cooling devices:
+ * the CPU and the GPU.
+ *
+ * - 1.2 GHz - 1.0 GHz (almost hot)
+ * - 800 MHz (hot)
+ * - 800 MHz - 696 MHz (hotter)
+ * - 696 MHz - min (very hot)
+ *
+ * Note:
+ * - 800 MHz appears to be a "sweet spot" for me. I can run
+ * some pretty serious workload here and be happy.
+ * - After 696 MHz we stop lowering voltage, so throttling
+ * past there is less effective.
+ */
+ cpu_almost_hot_limit_cpu {
+ trip = <&cpu_alert_almost_hot>;
+ cooling-device =
+ <&cpu0 5 6>;
+ };
+ cpu_hot_limit_cpu {
+ trip = <&cpu_alert_hot>;
+ cooling-device =
+ <&cpu0 7 7>;
+ };
+ cpu_hotter_limit_cpu {
+ trip = <&cpu_alert_hotter>;
+ cooling-device =
+ <&cpu0 7 8>;
+ };
+ cpu_very_hot_limit_cpu {
+ trip = <&cpu_alert_very_hot>;
+ cooling-device =
+ <&cpu0 8 THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+&emmc {
+ /delete-property/mmc-hs200-1_8v;
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c4 {
+ status = "disabled";
+};
+
+&i2s {
+ status = "okay";
+ clock-names = "i2s_hclk", "i2s_clk", "i2s_clk_out";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>, <&cru SCLK_I2S0_OUT>;
+};
+
+&rk808 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+ dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+ <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+ /delete-property/ vcc6-supply;
+ /delete-property/ vcc12-supply;
+
+ vcc11-supply = <&vcc33_sys>;
+
+ regulators {
+ /* vcc33_io is sourced directly from vcc33_sys */
+ /delete-node/ LDO_REG1;
+ /delete-node/ LDO_REG7;
+
+ /* This is not a pwren anymore, but the real power supply */
+ vdd10_lcd: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd10_lcd";
+ regulator-suspend-mem-disabled;
+ };
+
+ vcc18_lcd: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_lcd";
+ regulator-suspend-mem-disabled;
+ };
+ };
+};
+
+&pinctrl {
+ hdmi {
+ power_hdmi_on: power-hdmi-on {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ dvs_1: dvs-1 {
+ rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ dvs_2: dvs-2 {
+ rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
+
+&usb_host0_ehci {
+ status = "disabled";
+};
+
+&usb_host1 {
+ status = "disabled";
+};
+
+&vcc50_hdmi {
+ enable-active-high;
+ gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_hdmi_on>;
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
index 8fd8ef2..699beb0 100644
--- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -86,6 +86,10 @@
};
};
+&emmc {
+ /delete-property/mmc-hs200-1_8v;
+};
+
&gpio_keys {
pinctrl-0 = <&pwr_key_l &ap_lid_int_l &volum_down_l &volum_up_l>;
@@ -117,6 +121,18 @@
clock-frequency = <400000>;
i2c-scl-falling-time-ns = <50>;
i2c-scl-rising-time-ns = <300>;
+
+ touchscreen@10 {
+ compatible = "elan,ekth3500";
+ reg = <0x10>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_int &touch_rst>;
+ reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+ vcc33-supply = <&vcc33_touch>;
+ vccio-supply = <&vcc33_touch>;
+ };
};
&rk808 {
diff --git a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
index b5334ec..fec076e 100644
--- a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
@@ -90,7 +90,7 @@
regulators {
vccio_sd: LDO_REG4 {
regulator-name = "vccio_sd";
- regulator-min-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-state-mem {
regulator-off-in-suspend;
@@ -116,7 +116,12 @@
cap-sd-highspeed;
card-detect-delay = <200>;
cd-gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+ rockchip,default-sample-phase = <90>;
num-slots = <1>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
vmmc-supply = <&vcc33_sd>;
vqmmc-supply = <&vccio_sd>;
};
diff --git a/arch/arm/boot/dts/rk3288-veyron-speedy.dts b/arch/arm/boot/dts/rk3288-veyron-speedy.dts
index a7ea7d0..b34a7b5 100644
--- a/arch/arm/boot/dts/rk3288-veyron-speedy.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-speedy.dts
@@ -88,6 +88,14 @@
};
};
+&cpu_alert0 {
+ temperature = <65000>;
+};
+
+&cpu_alert1 {
+ temperature = <70000>;
+};
+
&rk808 {
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
index 275c78c..9fce91f 100644
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
@@ -149,7 +149,9 @@
broken-cd;
bus-width = <8>;
cap-mmc-highspeed;
+ rockchip,default-sample-phase = <158>;
disable-wp;
+ mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
non-removable;
num-slots = <1>;
@@ -338,6 +340,11 @@
i2c-scl-rising-time-ns = <1000>;
};
+&power {
+ assigned-clocks = <&cru SCLK_EDP_24M>;
+ assigned-clock-parents = <&xin24m>;
+};
+
&pwm1 {
status = "okay";
};
@@ -355,6 +362,10 @@
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
vmmc-supply = <&vcc33_sys>;
vqmmc-supply = <&vcc18_wl>;
};
@@ -544,18 +555,6 @@
};
};
- /*
- * On Marvell-based hardware this is a no-connect. Make sure we enable
- * the pullup so that the line doesn't float. The pullup shouldn't
- * hurt on Broadcom-based hardware since the other side is actively
- * driving this signal. As proof: we've already got a pullup on RX.
- */
- uart0 {
- uart0_cts: uart0-cts {
- rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_up>;
- };
- };
-
write-protect {
fw_wp_ap: fw-wp-ap {
rockchip,pins = <7 6 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 906e938..8ac49f3 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -44,6 +44,7 @@
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/power/rk3288-power.h>
#include "skeleton.dtsi"
/ {
@@ -52,6 +53,7 @@
interrupt-parent = <&gic>;
aliases {
+ ethernet0 = &gmac;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
@@ -222,8 +224,9 @@
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";
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xff0c0000 0x4000>;
@@ -233,8 +236,9 @@
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";
+ clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
+ <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xff0d0000 0x4000>;
@@ -244,8 +248,9 @@
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";
+ clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
+ <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xff0e0000 0x4000>;
@@ -255,8 +260,9 @@
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";
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xff0f0000 0x4000>;
@@ -447,8 +453,10 @@
clock-names = "tsadc", "apb_pclk";
resets = <&cru SRST_TSADC>;
reset-names = "tsadc-apb";
- pinctrl-names = "default";
- pinctrl-0 = <&otp_out>;
+ pinctrl-names = "init", "default", "sleep";
+ pinctrl-0 = <&otp_gpio>;
+ pinctrl-1 = <&otp_out>;
+ pinctrl-2 = <&otp_gpio>;
#thermal-sensor-cells = <1>;
rockchip,hw-tshut-temp = <95000>;
status = "disabled";
@@ -613,8 +621,98 @@
};
pmu: power-management@ff730000 {
- compatible = "rockchip,rk3288-pmu", "syscon";
+ compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd";
reg = <0xff730000 0x100>;
+
+ power: power-controller {
+ compatible = "rockchip,rk3288-power-controller";
+ #power-domain-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * Note: Although SCLK_* are the working clocks
+ * of device without including on the NOC, needed for
+ * synchronous reset.
+ *
+ * The clocks on the which NOC:
+ * ACLK_IEP/ACLK_VIP/ACLK_VOP0 are on ACLK_VIO0_NIU.
+ * ACLK_ISP/ACLK_VOP1 are on ACLK_VIO1_NIU.
+ * ACLK_RGA is on ACLK_RGA_NIU.
+ * The others (HCLK_*,PLCK_*) are on HCLK_VIO_NIU.
+ *
+ * Which clock are device clocks:
+ * clocks devices
+ * *_IEP IEP:Image Enhancement Processor
+ * *_ISP ISP:Image Signal Processing
+ * *_VIP VIP:Video Input Processor
+ * *_VOP* VOP:Visual Output Processor
+ * *_RGA RGA
+ * *_EDP* EDP
+ * *_LVDS_* LVDS
+ * *_HDMI HDMI
+ * *_MIPI_* MIPI
+ */
+ pd_vio {
+ reg = <RK3288_PD_VIO>;
+ clocks = <&cru ACLK_IEP>,
+ <&cru ACLK_ISP>,
+ <&cru ACLK_RGA>,
+ <&cru ACLK_VIP>,
+ <&cru ACLK_VOP0>,
+ <&cru ACLK_VOP1>,
+ <&cru DCLK_VOP0>,
+ <&cru DCLK_VOP1>,
+ <&cru HCLK_IEP>,
+ <&cru HCLK_ISP>,
+ <&cru HCLK_RGA>,
+ <&cru HCLK_VIP>,
+ <&cru HCLK_VOP0>,
+ <&cru HCLK_VOP1>,
+ <&cru PCLK_EDP_CTRL>,
+ <&cru PCLK_HDMI_CTRL>,
+ <&cru PCLK_LVDS_PHY>,
+ <&cru PCLK_MIPI_CSI>,
+ <&cru PCLK_MIPI_DSI0>,
+ <&cru PCLK_MIPI_DSI1>,
+ <&cru SCLK_EDP_24M>,
+ <&cru SCLK_EDP>,
+ <&cru SCLK_ISP_JPE>,
+ <&cru SCLK_ISP>,
+ <&cru SCLK_RGA>;
+ };
+
+ /*
+ * Note: The following 3 are HEVC(H.265) clocks,
+ * and on the ACLK_HEVC_NIU (NOC).
+ */
+ pd_hevc {
+ reg = <RK3288_PD_HEVC>;
+ clocks = <&cru ACLK_HEVC>,
+ <&cru SCLK_HEVC_CABAC>,
+ <&cru SCLK_HEVC_CORE>;
+ };
+
+ /*
+ * Note: ACLK_VCODEC/HCLK_VCODEC are VCODEC
+ * (video endecoder & decoder) clocks that on the
+ * ACLK_VCODEC_NIU and HCLK_VCODEC_NIU (NOC).
+ */
+ pd_video {
+ reg = <RK3288_PD_VIDEO>;
+ clocks = <&cru ACLK_VCODEC>,
+ <&cru HCLK_VCODEC>;
+ };
+
+ /*
+ * Note: ACLK_GPU is the GPU clock,
+ * and on the ACLK_GPU_NIU (NOC).
+ */
+ pd_gpu {
+ reg = <RK3288_PD_GPU>;
+ clocks = <&cru ACLK_GPU>;
+ };
+ };
};
sgrf: syscon@ff740000 {
@@ -653,6 +751,21 @@
status = "disabled";
};
+ spdif: sound@ff88b0000 {
+ compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif";
+ reg = <0xff8b0000 0x10000>;
+ #sound-dai-cells = <0>;
+ clock-names = "hclk", "mclk";
+ clocks = <&cru HCLK_SPDIF8CH>, <&cru SCLK_SPDIF8CH>;
+ dmas = <&dmac_bus_s 3>;
+ dma-names = "tx";
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx>;
+ rockchip,grf = <&grf>;
+ status = "disabled";
+ };
+
i2s: i2s@ff890000 {
compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
reg = <0xff890000 0x10000>;
@@ -665,15 +778,30 @@
clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
+ rockchip,playback-channels = <8>;
+ rockchip,capture-channels = <2>;
status = "disabled";
};
+ crypto: cypto-controller@ff8a0000 {
+ compatible = "rockchip,rk3288-crypto";
+ reg = <0xff8a0000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
+ <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
+ clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ status = "okay";
+ };
+
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";
+ power-domains = <&power RK3288_PD_VIO>;
resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
reset-names = "axi", "ahb", "dclk";
iommus = <&vopb_mmu>;
@@ -695,6 +823,7 @@
reg = <0xff930300 0x100>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vopb_mmu";
+ power-domains = <&power RK3288_PD_VIO>;
#iommu-cells = <0>;
status = "disabled";
};
@@ -705,6 +834,7 @@
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";
+ power-domains = <&power RK3288_PD_VIO>;
resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
reset-names = "axi", "ahb", "dclk";
iommus = <&vopl_mmu>;
@@ -726,6 +856,7 @@
reg = <0xff940300 0x100>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "vopl_mmu";
+ power-domains = <&power RK3288_PD_VIO>;
#iommu-cells = <0>;
status = "disabled";
};
@@ -738,6 +869,7 @@
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
clock-names = "iahb", "isfr";
+ power-domains = <&power RK3288_PD_VIO>;
status = "disabled";
ports {
@@ -769,6 +901,19 @@
interrupts = <GIC_PPI 9 0xf04>;
};
+ efuse: efuse@ffb40000 {
+ compatible = "rockchip,rockchip-efuse";
+ reg = <0xffb40000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE256>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage@17 {
+ reg = <0x17 0x1>;
+ };
+ };
+
usbphy: phy {
compatible = "rockchip,rk3288-usb-phy";
rockchip,grf = <&grf>;
@@ -923,6 +1068,13 @@
#interrupt-cells = <2>;
};
+ hdmi {
+ hdmi_ddc: hdmi-ddc {
+ rockchip,pins = <7 19 RK_FUNC_2 &pcfg_pull_none>,
+ <7 20 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
pcfg_pull_up: pcfg-pull-up {
bias-pull-up;
};
@@ -1020,7 +1172,7 @@
rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up>;
};
- sdmmc_cd: sdmcc-cd {
+ sdmmc_cd: sdmmc-cd {
rockchip,pins = <6 22 RK_FUNC_1 &pcfg_pull_up>;
};
@@ -1211,7 +1363,7 @@
};
uart0_cts: uart0-cts {
- rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_none>;
+ rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_up>;
};
uart0_rts: uart0-rts {
@@ -1226,7 +1378,7 @@
};
uart1_cts: uart1-cts {
- rockchip,pins = <5 10 RK_FUNC_1 &pcfg_pull_none>;
+ rockchip,pins = <5 10 RK_FUNC_1 &pcfg_pull_up>;
};
uart1_rts: uart1-rts {
@@ -1249,7 +1401,7 @@
};
uart3_cts: uart3-cts {
- rockchip,pins = <7 9 RK_FUNC_1 &pcfg_pull_none>;
+ rockchip,pins = <7 9 RK_FUNC_1 &pcfg_pull_up>;
};
uart3_rts: uart3-rts {
@@ -1264,7 +1416,7 @@
};
uart4_cts: uart4-cts {
- rockchip,pins = <5 14 3 &pcfg_pull_none>;
+ rockchip,pins = <5 14 3 &pcfg_pull_up>;
};
uart4_rts: uart4-rts {
@@ -1273,6 +1425,10 @@
};
tsadc {
+ otp_gpio: otp-gpio {
+ rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
otp_out: otp-out {
rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
};
@@ -1334,5 +1490,11 @@
<4 3 3 &pcfg_pull_none>;
};
};
+
+ spdif {
+ spdif_tx: spdif-tx {
+ rockchip,pins = <RK_GPIO6 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 4497d28..99eeea7 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -49,6 +49,7 @@
interrupt-parent = <&gic>;
aliases {
+ ethernet0 = &emac;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
diff --git a/arch/arm/boot/dts/s3c2416.dtsi b/arch/arm/boot/dts/s3c2416.dtsi
index a5184ff..80f0075 100644
--- a/arch/arm/boot/dts/s3c2416.dtsi
+++ b/arch/arm/boot/dts/s3c2416.dtsi
@@ -25,7 +25,7 @@
#size-cells = <0>;
cpu {
- compatible = "arm,arm926ejs";
+ compatible = "arm,arm926ej-s";
};
};
diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts
index f00cea7..aa64faa 100644
--- a/arch/arm/boot/dts/s5pv210-aquila.dts
+++ b/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -46,7 +46,7 @@
regulator-name = "V_TF_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- gpios = <&mp05 4 0>;
+ gpio = <&mp05 4 0>;
enable-active-high;
};
diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts
index a3d4643..3b76eeeb 100644
--- a/arch/arm/boot/dts/s5pv210-goni.dts
+++ b/arch/arm/boot/dts/s5pv210-goni.dts
@@ -47,7 +47,7 @@
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
reg = <0>;
- gpios = <&mp05 4 0>;
+ gpio = <&mp05 4 0>;
enable-active-high;
};
@@ -73,7 +73,7 @@
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
reg = <3>;
- gpios = <&gpj1 3 0>;
+ gpio = <&gpj1 3 0>;
enable-active-high;
};
};
diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h
new file mode 100644
index 0000000..b0c912fe
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
@@ -0,0 +1,880 @@
+#define PINMUX_PIN(no, func, ioset) \
+(((no) & 0xffff) | (((func) & 0xf) << 16) | (((ioset) & 0xff) << 20))
+
+#define PIN_PA0 0
+#define PIN_PA0__GPIO PINMUX_PIN(PIN_PA0, 0, 0)
+#define PIN_PA0__SDMMC0_CK PINMUX_PIN(PIN_PA0, 1, 1)
+#define PIN_PA0__QSPI0_SCK PINMUX_PIN(PIN_PA0, 2, 1)
+#define PIN_PA0__D0 PINMUX_PIN(PIN_PA0, 6, 2)
+#define PIN_PA1 1
+#define PIN_PA1__GPIO PINMUX_PIN(PIN_PA1, 0, 0)
+#define PIN_PA1__SDMMC0_CMD PINMUX_PIN(PIN_PA1, 1, 1)
+#define PIN_PA1__QSPI0_CS PINMUX_PIN(PIN_PA1, 2, 1)
+#define PIN_PA1__D1 PINMUX_PIN(PIN_PA1, 6, 2)
+#define PIN_PA2 2
+#define PIN_PA2__GPIO PINMUX_PIN(PIN_PA2, 0, 0)
+#define PIN_PA2__SDMMC0_DAT0 PINMUX_PIN(PIN_PA2, 1, 1)
+#define PIN_PA2__QSPI0_IO0 PINMUX_PIN(PIN_PA2, 2, 1)
+#define PIN_PA2__D2 PINMUX_PIN(PIN_PA2, 6, 2)
+#define PIN_PA3 3
+#define PIN_PA3__GPIO PINMUX_PIN(PIN_PA3, 0, 0)
+#define PIN_PA3__SDMMC0_DAT1 PINMUX_PIN(PIN_PA3, 1, 1)
+#define PIN_PA3__QSPI0_IO1 PINMUX_PIN(PIN_PA3, 2, 1)
+#define PIN_PA3__D3 PINMUX_PIN(PIN_PA3, 6, 2)
+#define PIN_PA4 4
+#define PIN_PA4__GPIO PINMUX_PIN(PIN_PA4, 0, 0)
+#define PIN_PA4__SDMMC0_DAT2 PINMUX_PIN(PIN_PA4, 1, 1)
+#define PIN_PA4__QSPI0_IO2 PINMUX_PIN(PIN_PA4, 2, 1)
+#define PIN_PA4__D4 PINMUX_PIN(PIN_PA4, 6, 2)
+#define PIN_PA5 5
+#define PIN_PA5__GPIO PINMUX_PIN(PIN_PA5, 0, 0)
+#define PIN_PA5__SDMMC0_DAT3 PINMUX_PIN(PIN_PA5, 1, 1)
+#define PIN_PA5__QSPI0_IO3 PINMUX_PIN(PIN_PA5, 2, 1)
+#define PIN_PA5__D5 PINMUX_PIN(PIN_PA5, 6, 2)
+#define PIN_PA6 6
+#define PIN_PA6__GPIO PINMUX_PIN(PIN_PA6, 0, 0)
+#define PIN_PA6__SDMMC0_DAT4 PINMUX_PIN(PIN_PA6, 1, 1)
+#define PIN_PA6__QSPI1_SCK PINMUX_PIN(PIN_PA6, 2, 1)
+#define PIN_PA6__TIOA5 PINMUX_PIN(PIN_PA6, 4, 1)
+#define PIN_PA6__FLEXCOM2_IO0 PINMUX_PIN(PIN_PA6, 5, 1)
+#define PIN_PA6__D6 PINMUX_PIN(PIN_PA6, 6, 2)
+#define PIN_PA7 7
+#define PIN_PA7__GPIO PINMUX_PIN(PIN_PA7, 0, 0)
+#define PIN_PA7__SDMMC0_DAT5 PINMUX_PIN(PIN_PA7, 1, 1)
+#define PIN_PA7__QSPI1_IO0 PINMUX_PIN(PIN_PA7, 2, 1)
+#define PIN_PA7__TIOB5 PINMUX_PIN(PIN_PA7, 4, 1)
+#define PIN_PA7__FLEXCOM2_IO1 PINMUX_PIN(PIN_PA7, 5, 1)
+#define PIN_PA7__D7 PINMUX_PIN(PIN_PA7, 6, 2)
+#define PIN_PA8 8
+#define PIN_PA8__GPIO PINMUX_PIN(PIN_PA8, 0, 0)
+#define PIN_PA8__SDMMC0_DAT6 PINMUX_PIN(PIN_PA8, 1, 1)
+#define PIN_PA8__QSPI1_IO1 PINMUX_PIN(PIN_PA8, 2, 1)
+#define PIN_PA8__TCLK5 PINMUX_PIN(PIN_PA8, 4, 1)
+#define PIN_PA8__FLEXCOM2_IO2 PINMUX_PIN(PIN_PA8, 5, 1)
+#define PIN_PA8__NWE_NANDWE PINMUX_PIN(PIN_PA8, 6, 2)
+#define PIN_PA9 9
+#define PIN_PA9__GPIO PINMUX_PIN(PIN_PA9, 0, 0)
+#define PIN_PA9__SDMMC0_DAT7 PINMUX_PIN(PIN_PA9, 1, 1)
+#define PIN_PA9__QSPI1_IO2 PINMUX_PIN(PIN_PA9, 2, 1)
+#define PIN_PA9__TIOA4 PINMUX_PIN(PIN_PA9, 4, 1)
+#define PIN_PA9__FLEXCOM2_IO3 PINMUX_PIN(PIN_PA9, 5, 1)
+#define PIN_PA9__NCS3 PINMUX_PIN(PIN_PA9, 6, 2)
+#define PIN_PA10 10
+#define PIN_PA10__GPIO PINMUX_PIN(PIN_PA10, 0, 0)
+#define PIN_PA10__SDMMC0_RSTN PINMUX_PIN(PIN_PA10, 1, 1)
+#define PIN_PA10__QSPI1_IO3 PINMUX_PIN(PIN_PA10, 2, 1)
+#define PIN_PA10__TIOB4 PINMUX_PIN(PIN_PA10, 4, 1)
+#define PIN_PA10__FLEXCOM2_IO4 PINMUX_PIN(PIN_PA10, 5, 1)
+#define PIN_PA10__A21_NANDALE PINMUX_PIN(PIN_PA10, 6, 2)
+#define PIN_PA11 11
+#define PIN_PA11__GPIO PINMUX_PIN(PIN_PA11, 0, 0)
+#define PIN_PA11__SDMMC0_VDDSEL PINMUX_PIN(PIN_PA11, 1, 1)
+#define PIN_PA11__QSPI1_CS PINMUX_PIN(PIN_PA11, 2, 1)
+#define PIN_PA11__TCLK4 PINMUX_PIN(PIN_PA11, 4, 1)
+#define PIN_PA11__A22_NANDCLE PINMUX_PIN(PIN_PA11, 6, 2)
+#define PIN_PA12 12
+#define PIN_PA12__GPIO PINMUX_PIN(PIN_PA12, 0, 0)
+#define PIN_PA12__SDMMC0_WP PINMUX_PIN(PIN_PA12, 1, 1)
+#define PIN_PA12__IRQ PINMUX_PIN(PIN_PA12, 2, 1)
+#define PIN_PA12__NRD_NANDOE PINMUX_PIN(PIN_PA12, 6, 2)
+#define PIN_PA13 13
+#define PIN_PA13__GPIO PINMUX_PIN(PIN_PA13, 0, 0)
+#define PIN_PA13__SDMMC0_CD PINMUX_PIN(PIN_PA13, 1, 1)
+#define PIN_PA13__FLEXCOM3_IO1 PINMUX_PIN(PIN_PA13, 5, 1)
+#define PIN_PA13__D8 PINMUX_PIN(PIN_PA13, 6, 2)
+#define PIN_PA14 14
+#define PIN_PA14__GPIO PINMUX_PIN(PIN_PA14, 0, 0)
+#define PIN_PA14__SPI0_SPCK PINMUX_PIN(PIN_PA14, 1, 1)
+#define PIN_PA14__TK1 PINMUX_PIN(PIN_PA14, 2, 1)
+#define PIN_PA14__QSPI0_SCK PINMUX_PIN(PIN_PA14, 3, 2)
+#define PIN_PA14__I2SC1_MCK PINMUX_PIN(PIN_PA14, 4, 2)
+#define PIN_PA14__FLEXCOM3_IO2 PINMUX_PIN(PIN_PA14, 5, 1)
+#define PIN_PA14__D9 PINMUX_PIN(PIN_PA14, 6, 2)
+#define PIN_PA15 15
+#define PIN_PA15__GPIO PINMUX_PIN(PIN_PA15, 0, 0)
+#define PIN_PA15__SPI0_MOSI PINMUX_PIN(PIN_PA15, 1, 1)
+#define PIN_PA15__TF1 PINMUX_PIN(PIN_PA15, 2, 1)
+#define PIN_PA15__QSPI0_CS PINMUX_PIN(PIN_PA15, 3, 2)
+#define PIN_PA15__I2SC1_CK PINMUX_PIN(PIN_PA15, 4, 2)
+#define PIN_PA15__FLEXCOM3_IO0 PINMUX_PIN(PIN_PA15, 5, 1)
+#define PIN_PA15__D10 PINMUX_PIN(PIN_PA15, 6, 2)
+#define PIN_PA16 16
+#define PIN_PA16__GPIO PINMUX_PIN(PIN_PA16, 0, 0)
+#define PIN_PA16__SPI0_MISO PINMUX_PIN(PIN_PA16, 1, 1)
+#define PIN_PA16__TD1 PINMUX_PIN(PIN_PA16, 2, 1)
+#define PIN_PA16__QSPI0_IO0 PINMUX_PIN(PIN_PA16, 3, 2)
+#define PIN_PA16__I2SC1_WS PINMUX_PIN(PIN_PA16, 4, 2)
+#define PIN_PA16__FLEXCOM3_IO3 PINMUX_PIN(PIN_PA16, 5, 1)
+#define PIN_PA16__D11 PINMUX_PIN(PIN_PA16, 6, 2)
+#define PIN_PA17 17
+#define PIN_PA17__GPIO PINMUX_PIN(PIN_PA17, 0, 0)
+#define PIN_PA17__SPI0_NPCS0 PINMUX_PIN(PIN_PA17, 1, 1)
+#define PIN_PA17__RD1 PINMUX_PIN(PIN_PA17, 2, 1)
+#define PIN_PA17__QSPI0_IO1 PINMUX_PIN(PIN_PA17, 3, 2)
+#define PIN_PA17__I2SC1_DI0 PINMUX_PIN(PIN_PA17, 4, 2)
+#define PIN_PA17__FLEXCOM3_IO4 PINMUX_PIN(PIN_PA17, 5, 1)
+#define PIN_PA17__D12 PINMUX_PIN(PIN_PA17, 6, 2)
+#define PIN_PA18 18
+#define PIN_PA18__GPIO PINMUX_PIN(PIN_PA18, 0, 0)
+#define PIN_PA18__SPI0_NPCS1 PINMUX_PIN(PIN_PA18, 1, 1)
+#define PIN_PA18__RK1 PINMUX_PIN(PIN_PA18, 2, 1)
+#define PIN_PA18__QSPI0_IO2 PINMUX_PIN(PIN_PA18, 3, 2)
+#define PIN_PA18__I2SC1_DO0 PINMUX_PIN(PIN_PA18, 4, 2)
+#define PIN_PA18__SDMMC1_DAT0 PINMUX_PIN(PIN_PA18, 5, 1)
+#define PIN_PA18__D13 PINMUX_PIN(PIN_PA18, 6, 2)
+#define PIN_PA19 19
+#define PIN_PA19__GPIO PINMUX_PIN(PIN_PA19, 0, 0)
+#define PIN_PA19__SPI0_NPCS2 PINMUX_PIN(PIN_PA19, 1, 1)
+#define PIN_PA19__RF1 PINMUX_PIN(PIN_PA19, 2, 1)
+#define PIN_PA19__QSPI0_IO3 PINMUX_PIN(PIN_PA19, 3, 2)
+#define PIN_PA19__TIOA0 PINMUX_PIN(PIN_PA19, 4, 1)
+#define PIN_PA19__SDMMC1_DAT1 PINMUX_PIN(PIN_PA19, 5, 1)
+#define PIN_PA19__D14 PINMUX_PIN(PIN_PA19, 6, 2)
+#define PIN_PA20 20
+#define PIN_PA20__GPIO PINMUX_PIN(PIN_PA20, 0, 0)
+#define PIN_PA20__SPI0_NPCS3 PINMUX_PIN(PIN_PA20, 1, 1)
+#define PIN_PA20__TIOB0 PINMUX_PIN(PIN_PA20, 4, 1)
+#define PIN_PA20__SDMMC1_DAT2 PINMUX_PIN(PIN_PA20, 5, 1)
+#define PIN_PA20__D15 PINMUX_PIN(PIN_PA20, 6, 2)
+#define PIN_PA21 21
+#define PIN_PA21__GPIO PINMUX_PIN(PIN_PA21, 0, 0)
+#define PIN_PA21__IRQ PINMUX_PIN(PIN_PA21, 1, 2)
+#define PIN_PA21__PCK2 PINMUX_PIN(PIN_PA21, 2, 3)
+#define PIN_PA21__TCLK0 PINMUX_PIN(PIN_PA21, 4, 1)
+#define PIN_PA21__SDMMC1_DAT3 PINMUX_PIN(PIN_PA21, 5, 1)
+#define PIN_PA21__NANDRDY PINMUX_PIN(PIN_PA21, 6, 2)
+#define PIN_PA22 22
+#define PIN_PA22__GPIO PINMUX_PIN(PIN_PA22, 0, 0)
+#define PIN_PA22__FLEXCOM1_IO2 PINMUX_PIN(PIN_PA22, 1, 1)
+#define PIN_PA22__D0 PINMUX_PIN(PIN_PA22, 2, 1)
+#define PIN_PA22__TCK PINMUX_PIN(PIN_PA22, 3, 4)
+#define PIN_PA22__SPI1_SPCK PINMUX_PIN(PIN_PA22, 4, 2)
+#define PIN_PA22__SDMMC1_CK PINMUX_PIN(PIN_PA22, 5, 1)
+#define PIN_PA22__QSPI0_SCK PINMUX_PIN(PIN_PA22, 6, 3)
+#define PIN_PA23 23
+#define PIN_PA23__GPIO PINMUX_PIN(PIN_PA23, 0, 0)
+#define PIN_PA23__FLEXCOM1_IO1 PINMUX_PIN(PIN_PA23, 1, 1)
+#define PIN_PA23__D1 PINMUX_PIN(PIN_PA23, 2, 1)
+#define PIN_PA23__TDI PINMUX_PIN(PIN_PA23, 3, 4)
+#define PIN_PA23__SPI1_MOSI PINMUX_PIN(PIN_PA23, 4, 2)
+#define PIN_PA23__QSPI0_CS PINMUX_PIN(PIN_PA23, 6, 3)
+#define PIN_PA24 24
+#define PIN_PA24__GPIO PINMUX_PIN(PIN_PA24, 0, 0)
+#define PIN_PA24__FLEXCOM1_IO0 PINMUX_PIN(PIN_PA24, 1, 1)
+#define PIN_PA24__D2 PINMUX_PIN(PIN_PA24, 2, 1)
+#define PIN_PA24__TDO PINMUX_PIN(PIN_PA24, 3, 4)
+#define PIN_PA24__SPI1_MISO PINMUX_PIN(PIN_PA24, 4, 2)
+#define PIN_PA24__QSPI0_IO0 PINMUX_PIN(PIN_PA24, 6, 3)
+#define PIN_PA25 25
+#define PIN_PA25__GPIO PINMUX_PIN(PIN_PA25, 0, 0)
+#define PIN_PA25__FLEXCOM1_IO3 PINMUX_PIN(PIN_PA25, 1, 1)
+#define PIN_PA25__D3 PINMUX_PIN(PIN_PA25, 2, 1)
+#define PIN_PA25__TMS PINMUX_PIN(PIN_PA25, 3, 4)
+#define PIN_PA25__SPI1_NPCS0 PINMUX_PIN(PIN_PA25, 4, 2)
+#define PIN_PA25__QSPI0_IO1 PINMUX_PIN(PIN_PA25, 6, 3)
+#define PIN_PA26 26
+#define PIN_PA26__GPIO PINMUX_PIN(PIN_PA26, 0, 0)
+#define PIN_PA26__FLEXCOM1_IO4 PINMUX_PIN(PIN_PA26, 1, 1)
+#define PIN_PA26__D4 PINMUX_PIN(PIN_PA26, 2, 1)
+#define PIN_PA26__NTRST PINMUX_PIN(PIN_PA26, 3, 4)
+#define PIN_PA26__SPI1_NPCS1 PINMUX_PIN(PIN_PA26, 4, 2)
+#define PIN_PA26__QSPI0_IO2 PINMUX_PIN(PIN_PA26, 6, 3)
+#define PIN_PA27 27
+#define PIN_PA27__GPIO PINMUX_PIN(PIN_PA27, 0, 0)
+#define PIN_PA27__TIOA1 PINMUX_PIN(PIN_PA27, 1, 2)
+#define PIN_PA27__D5 PINMUX_PIN(PIN_PA27, 2, 1)
+#define PIN_PA27__SPI0_NPCS2 PINMUX_PIN(PIN_PA27, 3, 2)
+#define PIN_PA27__SPI1_NPCS2 PINMUX_PIN(PIN_PA27, 4, 2)
+#define PIN_PA27__SDMMC1_RSTN PINMUX_PIN(PIN_PA27, 5, 1)
+#define PIN_PA27__QSPI0_IO3 PINMUX_PIN(PIN_PA27, 6, 3)
+#define PIN_PA28 28
+#define PIN_PA28__GPIO PINMUX_PIN(PIN_PA28, 0, 0)
+#define PIN_PA28__TIOB1 PINMUX_PIN(PIN_PA28, 1, 2)
+#define PIN_PA28__D6 PINMUX_PIN(PIN_PA28, 2, 1)
+#define PIN_PA28__SPI0_NPCS3 PINMUX_PIN(PIN_PA28, 3, 2)
+#define PIN_PA28__SPI1_NPCS3 PINMUX_PIN(PIN_PA28, 4, 2)
+#define PIN_PA28__SDMMC1_CMD PINMUX_PIN(PIN_PA28, 5, 1)
+#define PIN_PA28__CLASSD_L0 PINMUX_PIN(PIN_PA28, 6, 1)
+#define PIN_PA29 29
+#define PIN_PA29__GPIO PINMUX_PIN(PIN_PA29, 0, 0)
+#define PIN_PA29__TCLK1 PINMUX_PIN(PIN_PA29, 1, 2)
+#define PIN_PA29__D7 PINMUX_PIN(PIN_PA29, 2, 1)
+#define PIN_PA29__SPI0_NPCS1 PINMUX_PIN(PIN_PA29, 3, 2)
+#define PIN_PA29__SDMMC1_WP PINMUX_PIN(PIN_PA29, 5, 1)
+#define PIN_PA29__CLASSD_L1 PINMUX_PIN(PIN_PA29, 6, 1)
+#define PIN_PA30 30
+#define PIN_PA30__GPIO PINMUX_PIN(PIN_PA30, 0, 0)
+#define PIN_PA30__NWE_NANDWE PINMUX_PIN(PIN_PA30, 2, 1)
+#define PIN_PA30__SPI0_NPCS0 PINMUX_PIN(PIN_PA30, 3, 2)
+#define PIN_PA30__PWMH0 PINMUX_PIN(PIN_PA30, 4, 1)
+#define PIN_PA30__SDMMC1_CD PINMUX_PIN(PIN_PA30, 5, 1)
+#define PIN_PA30__CLASSD_L2 PINMUX_PIN(PIN_PA30, 6, 1)
+#define PIN_PA31 31
+#define PIN_PA31__GPIO PINMUX_PIN(PIN_PA31, 0, 0)
+#define PIN_PA31__NCS3 PINMUX_PIN(PIN_PA31, 2, 1)
+#define PIN_PA31__SPI0_MISO PINMUX_PIN(PIN_PA31, 3, 2)
+#define PIN_PA31__PWML0 PINMUX_PIN(PIN_PA31, 4, 1)
+#define PIN_PA31__CLASSD_L3 PINMUX_PIN(PIN_PA31, 6, 1)
+#define PIN_PB0 32
+#define PIN_PB0__GPIO PINMUX_PIN(PIN_PB0, 0, 0)
+#define PIN_PB0__A21_NANDALE PINMUX_PIN(PIN_PB0, 2, 1)
+#define PIN_PB0__SPI0_MOSI PINMUX_PIN(PIN_PB0, 3, 2)
+#define PIN_PB0__PWMH1 PINMUX_PIN(PIN_PB0, 4, 1)
+#define PIN_PB1 33
+#define PIN_PB1__GPIO PINMUX_PIN(PIN_PB1, 0, 0)
+#define PIN_PB1__A22_NANDCLE PINMUX_PIN(PIN_PB1, 2, 1)
+#define PIN_PB1__SPI0_SPCK PINMUX_PIN(PIN_PB1, 3, 2)
+#define PIN_PB1__PWML1 PINMUX_PIN(PIN_PB1, 4, 1)
+#define PIN_PB1__CLASSD_R0 PINMUX_PIN(PIN_PB1, 6, 1)
+#define PIN_PB2 34
+#define PIN_PB2__GPIO PINMUX_PIN(PIN_PB2, 0, 0)
+#define PIN_PB2__NRD_NANDOE PINMUX_PIN(PIN_PB2, 2, 1)
+#define PIN_PB2__PWMFI0 PINMUX_PIN(PIN_PB2, 4, 1)
+#define PIN_PB2__CLASSD_R1 PINMUX_PIN(PIN_PB2, 6, 1)
+#define PIN_PB3 35
+#define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0)
+#define PIN_PB3__URXD4 PINMUX_PIN(PIN_PB3, 1, 1)
+#define PIN_PB3__D8 PINMUX_PIN(PIN_PB3, 2, 1)
+#define PIN_PB3__IRQ PINMUX_PIN(PIN_PB3, 3, 3)
+#define PIN_PB3__PWMEXTRG0 PINMUX_PIN(PIN_PB3, 4, 1)
+#define PIN_PB3__CLASSD_R2 PINMUX_PIN(PIN_PB3, 6, 1)
+#define PIN_PB4 36
+#define PIN_PB4__GPIO PINMUX_PIN(PIN_PB4, 0, 0)
+#define PIN_PB4__UTXD4 PINMUX_PIN(PIN_PB4, 1, 1)
+#define PIN_PB4__D9 PINMUX_PIN(PIN_PB4, 2, 1)
+#define PIN_PB4__FIQ PINMUX_PIN(PIN_PB4, 3, 4)
+#define PIN_PB4__CLASSD_R3 PINMUX_PIN(PIN_PB4, 6, 1)
+#define PIN_PB5 37
+#define PIN_PB5__GPIO PINMUX_PIN(PIN_PB5, 0, 0)
+#define PIN_PB5__TCLK2 PINMUX_PIN(PIN_PB5, 1, 1)
+#define PIN_PB5__D10 PINMUX_PIN(PIN_PB5, 2, 1)
+#define PIN_PB5__PWMH2 PINMUX_PIN(PIN_PB5, 3, 1)
+#define PIN_PB5__QSPI1_SCK PINMUX_PIN(PIN_PB5, 4, 2)
+#define PIN_PB5__GTSUCOMP PINMUX_PIN(PIN_PB5, 6, 3)
+#define PIN_PB6 38
+#define PIN_PB6__GPIO PINMUX_PIN(PIN_PB6, 0, 0)
+#define PIN_PB6__TIOA2 PINMUX_PIN(PIN_PB6, 1, 1)
+#define PIN_PB6__D11 PINMUX_PIN(PIN_PB6, 2, 1)
+#define PIN_PB6__PWML2 PINMUX_PIN(PIN_PB6, 3, 1)
+#define PIN_PB6__QSPI1_CS PINMUX_PIN(PIN_PB6, 4, 2)
+#define PIN_PB6__GTXER PINMUX_PIN(PIN_PB6, 6, 3)
+#define PIN_PB7 39
+#define PIN_PB7__GPIO PINMUX_PIN(PIN_PB7, 0, 0)
+#define PIN_PB7__TIOB2 PINMUX_PIN(PIN_PB7, 1, 1)
+#define PIN_PB7__D12 PINMUX_PIN(PIN_PB7, 2, 1)
+#define PIN_PB7__PWMH3 PINMUX_PIN(PIN_PB7, 3, 1)
+#define PIN_PB7__QSPI1_IO0 PINMUX_PIN(PIN_PB7, 4, 2)
+#define PIN_PB7__GRXCK PINMUX_PIN(PIN_PB7, 6, 3)
+#define PIN_PB8 40
+#define PIN_PB8__GPIO PINMUX_PIN(PIN_PB8, 0, 0)
+#define PIN_PB8__TCLK3 PINMUX_PIN(PIN_PB8, 1, 1)
+#define PIN_PB8__D13 PINMUX_PIN(PIN_PB8, 2, 1)
+#define PIN_PB8__PWML3 PINMUX_PIN(PIN_PB8, 3, 1)
+#define PIN_PB8__QSPI1_IO1 PINMUX_PIN(PIN_PB8, 4, 2)
+#define PIN_PB8__GCRS PINMUX_PIN(PIN_PB8, 6, 3)
+#define PIN_PB9 41
+#define PIN_PB9__GPIO PINMUX_PIN(PIN_PB9, 0, 0)
+#define PIN_PB9__TIOA3 PINMUX_PIN(PIN_PB9, 1, 1)
+#define PIN_PB9__D14 PINMUX_PIN(PIN_PB9, 2, 1)
+#define PIN_PB9__PWMFI1 PINMUX_PIN(PIN_PB9, 3, 1)
+#define PIN_PB9__QSPI1_IO2 PINMUX_PIN(PIN_PB9, 4, 2)
+#define PIN_PB9__GCOL PINMUX_PIN(PIN_PB9, 6, 3)
+#define PIN_PB10 42
+#define PIN_PB10__GPIO PINMUX_PIN(PIN_PB10, 0, 0)
+#define PIN_PB10__TIOB3 PINMUX_PIN(PIN_PB10, 1, 1)
+#define PIN_PB10__D15 PINMUX_PIN(PIN_PB10, 2, 1)
+#define PIN_PB10__PWMEXTRG1 PINMUX_PIN(PIN_PB10, 3, 1)
+#define PIN_PB10__QSPI1_IO3 PINMUX_PIN(PIN_PB10, 4, 2)
+#define PIN_PB10__GRX2 PINMUX_PIN(PIN_PB10, 6, 3)
+#define PIN_PB11 43
+#define PIN_PB11__GPIO PINMUX_PIN(PIN_PB11, 0, 0)
+#define PIN_PB11__LCDDAT0 PINMUX_PIN(PIN_PB11, 1, 1)
+#define PIN_PB11__A0_NBS0 PINMUX_PIN(PIN_PB11, 2, 1)
+#define PIN_PB11__URXD3 PINMUX_PIN(PIN_PB11, 3, 3)
+#define PIN_PB11__PDMIC_DAT PINMUX_PIN(PIN_PB11, 4, 2)
+#define PIN_PB11__GRX3 PINMUX_PIN(PIN_PB11, 6, 3)
+#define PIN_PB12 44
+#define PIN_PB12__GPIO PINMUX_PIN(PIN_PB12, 0, 0)
+#define PIN_PB12__LCDDAT1 PINMUX_PIN(PIN_PB12, 1, 1)
+#define PIN_PB12__A1 PINMUX_PIN(PIN_PB12, 2, 1)
+#define PIN_PB12__UTXD3 PINMUX_PIN(PIN_PB12, 3, 3)
+#define PIN_PB12__PDMIC_CLK PINMUX_PIN(PIN_PB12, 4, 2)
+#define PIN_PB12__GTX2 PINMUX_PIN(PIN_PB12, 6, 3)
+#define PIN_PB13 45
+#define PIN_PB13__GPIO PINMUX_PIN(PIN_PB13, 0, 0)
+#define PIN_PB13__LCDDAT2 PINMUX_PIN(PIN_PB13, 1, 1)
+#define PIN_PB13__A2 PINMUX_PIN(PIN_PB13, 2, 1)
+#define PIN_PB13__PCK1 PINMUX_PIN(PIN_PB13, 3, 3)
+#define PIN_PB13__GTX3 PINMUX_PIN(PIN_PB13, 6, 3)
+#define PIN_PB14 46
+#define PIN_PB14__GPIO PINMUX_PIN(PIN_PB14, 0, 0)
+#define PIN_PB14__LCDDAT3 PINMUX_PIN(PIN_PB14, 1, 1)
+#define PIN_PB14__A3 PINMUX_PIN(PIN_PB14, 2, 1)
+#define PIN_PB14__TK1 PINMUX_PIN(PIN_PB14, 3, 2)
+#define PIN_PB14__I2SC1_MCK PINMUX_PIN(PIN_PB14, 4, 1)
+#define PIN_PB14__QSPI1_SCK PINMUX_PIN(PIN_PB14, 5, 3)
+#define PIN_PB14__GTXCK PINMUX_PIN(PIN_PB14, 6, 3)
+#define PIN_PB15 47
+#define PIN_PB15__GPIO PINMUX_PIN(PIN_PB15, 0, 0)
+#define PIN_PB15__LCDDAT4 PINMUX_PIN(PIN_PB15, 1, 1)
+#define PIN_PB15__A4 PINMUX_PIN(PIN_PB15, 2, 1)
+#define PIN_PB15__TF1 PINMUX_PIN(PIN_PB15, 3, 2)
+#define PIN_PB15__I2SC1_CK PINMUX_PIN(PIN_PB15, 4, 1)
+#define PIN_PB15__QSPI1_CS PINMUX_PIN(PIN_PB15, 5, 3)
+#define PIN_PB15__GTXEN PINMUX_PIN(PIN_PB15, 6, 3)
+#define PIN_PB16 48
+#define PIN_PB16__GPIO PINMUX_PIN(PIN_PB16, 0, 0)
+#define PIN_PB16__LCDDAT5 PINMUX_PIN(PIN_PB16, 1, 1)
+#define PIN_PB16__A5 PINMUX_PIN(PIN_PB16, 2, 1)
+#define PIN_PB16__TD1 PINMUX_PIN(PIN_PB16, 3, 2)
+#define PIN_PB16__I2SC1_WS PINMUX_PIN(PIN_PB16, 4, 1)
+#define PIN_PB16__QSPI1_IO0 PINMUX_PIN(PIN_PB16, 5, 3)
+#define PIN_PB16__GRXDV PINMUX_PIN(PIN_PB16, 6, 3)
+#define PIN_PB17 49
+#define PIN_PB17__GPIO PINMUX_PIN(PIN_PB17, 0, 0)
+#define PIN_PB17__LCDDAT6 PINMUX_PIN(PIN_PB17, 1, 1)
+#define PIN_PB17__A6 PINMUX_PIN(PIN_PB17, 2, 1)
+#define PIN_PB17__RD1 PINMUX_PIN(PIN_PB17, 3, 2)
+#define PIN_PB17__I2SC1_DI0 PINMUX_PIN(PIN_PB17, 4, 1)
+#define PIN_PB17__QSPI1_IO1 PINMUX_PIN(PIN_PB17, 5, 3)
+#define PIN_PB17__GRXER PINMUX_PIN(PIN_PB17, 6, 3)
+#define PIN_PB18 50
+#define PIN_PB18__GPIO PINMUX_PIN(PIN_PB18, 0, 0)
+#define PIN_PB18__LCDDAT7 PINMUX_PIN(PIN_PB18, 1, 1)
+#define PIN_PB18__A7 PINMUX_PIN(PIN_PB18, 2, 1)
+#define PIN_PB18__RK1 PINMUX_PIN(PIN_PB18, 3, 2)
+#define PIN_PB18__I2SC1_DO0 PINMUX_PIN(PIN_PB18, 4, 1)
+#define PIN_PB18__QSPI1_IO2 PINMUX_PIN(PIN_PB18, 5, 3)
+#define PIN_PB18__GRX0 PINMUX_PIN(PIN_PB18, 6, 3)
+#define PIN_PB19 51
+#define PIN_PB19__GPIO PINMUX_PIN(PIN_PB19, 0, 0)
+#define PIN_PB19__LCDDAT8 PINMUX_PIN(PIN_PB19, 1, 1)
+#define PIN_PB19__A8 PINMUX_PIN(PIN_PB19, 2, 1)
+#define PIN_PB19__RF1 PINMUX_PIN(PIN_PB19, 3, 2)
+#define PIN_PB19__TIOA3 PINMUX_PIN(PIN_PB19, 4, 2)
+#define PIN_PB19__QSPI1_IO3 PINMUX_PIN(PIN_PB19, 5, 3)
+#define PIN_PB19__GRX1 PINMUX_PIN(PIN_PB19, 6, 3)
+#define PIN_PB20 52
+#define PIN_PB20__GPIO PINMUX_PIN(PIN_PB20, 0, 0)
+#define PIN_PB20__LCDDAT9 PINMUX_PIN(PIN_PB20, 1, 1)
+#define PIN_PB20__A9 PINMUX_PIN(PIN_PB20, 2, 1)
+#define PIN_PB20__TK0 PINMUX_PIN(PIN_PB20, 3, 1)
+#define PIN_PB20__TIOB3 PINMUX_PIN(PIN_PB20, 4, 2)
+#define PIN_PB20__PCK1 PINMUX_PIN(PIN_PB20, 5, 4)
+#define PIN_PB20__GTX0 PINMUX_PIN(PIN_PB20, 6, 3)
+#define PIN_PB21 53
+#define PIN_PB21__GPIO PINMUX_PIN(PIN_PB21, 0, 0)
+#define PIN_PB21__LCDDAT10 PINMUX_PIN(PIN_PB21, 1, 1)
+#define PIN_PB21__A10 PINMUX_PIN(PIN_PB21, 2, 1)
+#define PIN_PB21__TF0 PINMUX_PIN(PIN_PB21, 3, 1)
+#define PIN_PB21__TCLK3 PINMUX_PIN(PIN_PB21, 4, 2)
+#define PIN_PB21__FLEXCOM3_IO2 PINMUX_PIN(PIN_PB21, 5, 3)
+#define PIN_PB21__GTX1 PINMUX_PIN(PIN_PB21, 6, 3)
+#define PIN_PB22 54
+#define PIN_PB22__GPIO PINMUX_PIN(PIN_PB22, 0, 0)
+#define PIN_PB22__LCDDAT11 PINMUX_PIN(PIN_PB22, 1, 1)
+#define PIN_PB22__A11 PINMUX_PIN(PIN_PB22, 2, 1)
+#define PIN_PB22__TDO PINMUX_PIN(PIN_PB22, 3, 1)
+#define PIN_PB22__TIOA2 PINMUX_PIN(PIN_PB22, 4, 2)
+#define PIN_PB22__FLEXCOM3_IO1 PINMUX_PIN(PIN_PB22, 5, 3)
+#define PIN_PB22__GMDC PINMUX_PIN(PIN_PB22, 6, 3)
+#define PIN_PB23 55
+#define PIN_PB23__GPIO PINMUX_PIN(PIN_PB23, 0, 0)
+#define PIN_PB23__LCDDAT12 PINMUX_PIN(PIN_PB23, 1, 1)
+#define PIN_PB23__A12 PINMUX_PIN(PIN_PB23, 2, 1)
+#define PIN_PB23__RD0 PINMUX_PIN(PIN_PB23, 3, 1)
+#define PIN_PB23__TIOB2 PINMUX_PIN(PIN_PB23, 4, 2)
+#define PIN_PB23__FLEXCOM3_IO0 PINMUX_PIN(PIN_PB23, 5, 3)
+#define PIN_PB23__GMDIO PINMUX_PIN(PIN_PB23, 6, 3)
+#define PIN_PB24 56
+#define PIN_PB24__GPIO PINMUX_PIN(PIN_PB24, 0, 0)
+#define PIN_PB24__LCDDAT13 PINMUX_PIN(PIN_PB24, 1, 1)
+#define PIN_PB24__A13 PINMUX_PIN(PIN_PB24, 2, 1)
+#define PIN_PB24__RK0 PINMUX_PIN(PIN_PB24, 3, 1)
+#define PIN_PB24__TCLK2 PINMUX_PIN(PIN_PB24, 4, 2)
+#define PIN_PB24__FLEXCOM3_IO3 PINMUX_PIN(PIN_PB24, 5, 3)
+#define PIN_PB24__ISC_D10 PINMUX_PIN(PIN_PB24, 6, 3)
+#define PIN_PB25 57
+#define PIN_PB25__GPIO PINMUX_PIN(PIN_PB25, 0, 0)
+#define PIN_PB25__LCDDAT14 PINMUX_PIN(PIN_PB25, 1, 1)
+#define PIN_PB25__A14 PINMUX_PIN(PIN_PB25, 2, 1)
+#define PIN_PB25__RF0 PINMUX_PIN(PIN_PB25, 3, 1)
+#define PIN_PB25__FLEXCOM3_IO4 PINMUX_PIN(PIN_PB25, 5, 3)
+#define PIN_PB25__ISC_D11 PINMUX_PIN(PIN_PB25, 6, 3)
+#define PIN_PB26 58
+#define PIN_PB26__GPIO PINMUX_PIN(PIN_PB26, 0, 0)
+#define PIN_PB26__LCDDAT15 PINMUX_PIN(PIN_PB26, 1, 1)
+#define PIN_PB26__A15 PINMUX_PIN(PIN_PB26, 2, 1)
+#define PIN_PB26__URXD0 PINMUX_PIN(PIN_PB26, 3, 1)
+#define PIN_PB26__PDMIC_DAT PINMUX_PIN(PIN_PB26, 4, 1)
+#define PIN_PB26__ISC_D0 PINMUX_PIN(PIN_PB26, 6, 3)
+#define PIN_PB27 59
+#define PIN_PB27__GPIO PINMUX_PIN(PIN_PB27, 0, 0)
+#define PIN_PB27__LCDDAT16 PINMUX_PIN(PIN_PB27, 1, 1)
+#define PIN_PB27__A16 PINMUX_PIN(PIN_PB27, 2, 1)
+#define PIN_PB27__UTXD0 PINMUX_PIN(PIN_PB27, 3, 1)
+#define PIN_PB27__PDMIC_CLK PINMUX_PIN(PIN_PB27, 4, 1)
+#define PIN_PB27__ISC_D1 PINMUX_PIN(PIN_PB27, 6, 3)
+#define PIN_PB28 60
+#define PIN_PB28__GPIO PINMUX_PIN(PIN_PB28, 0, 0)
+#define PIN_PB28__LCDDAT17 PINMUX_PIN(PIN_PB28, 1, 1)
+#define PIN_PB28__A17 PINMUX_PIN(PIN_PB28, 2, 1)
+#define PIN_PB28__FLEXCOM0_IO0 PINMUX_PIN(PIN_PB28, 3, 1)
+#define PIN_PB28__TIOA5 PINMUX_PIN(PIN_PB28, 4, 2)
+#define PIN_PB28__ISC_D2 PINMUX_PIN(PIN_PB28, 6, 3)
+#define PIN_PB29 61
+#define PIN_PB29__GPIO PINMUX_PIN(PIN_PB29, 0, 0)
+#define PIN_PB29__LCDDAT18 PINMUX_PIN(PIN_PB29, 1, 1)
+#define PIN_PB29__A18 PINMUX_PIN(PIN_PB29, 2, 1)
+#define PIN_PB29__FLEXCOM0_IO1 PINMUX_PIN(PIN_PB29, 3, 1)
+#define PIN_PB29__TIOB5 PINMUX_PIN(PIN_PB29, 4, 2)
+#define PIN_PB29__ISC_D3 PINMUX_PIN(PIN_PB29, 7, 3)
+#define PIN_PB30 62
+#define PIN_PB30__GPIO PINMUX_PIN(PIN_PB30, 0, 0)
+#define PIN_PB30__LCDDAT19 PINMUX_PIN(PIN_PB30, 1, 1)
+#define PIN_PB30__A19 PINMUX_PIN(PIN_PB30, 2, 1)
+#define PIN_PB30__FLEXCOM0_IO2 PINMUX_PIN(PIN_PB30, 3, 1)
+#define PIN_PB30__TCLK5 PINMUX_PIN(PIN_PB30, 4, 2)
+#define PIN_PB30__ISC_D4 PINMUX_PIN(PIN_PB30, 6, 3)
+#define PIN_PB31 63
+#define PIN_PB31__GPIO PINMUX_PIN(PIN_PB31, 0, 0)
+#define PIN_PB31__LCDDAT20 PINMUX_PIN(PIN_PB31, 1, 1)
+#define PIN_PB31__A20 PINMUX_PIN(PIN_PB31, 2, 1)
+#define PIN_PB31__FLEXCOM0_IO3 PINMUX_PIN(PIN_PB31, 3, 1)
+#define PIN_PB31__TWD0 PINMUX_PIN(PIN_PB31, 4, 1)
+#define PIN_PB31__ISC_D5 PINMUX_PIN(PIN_PB31, 6, 3)
+#define PIN_PC0 64
+#define PIN_PC0__GPIO PINMUX_PIN(PIN_PC0, 0, 0)
+#define PIN_PC0__LCDDAT21 PINMUX_PIN(PIN_PC0, 1, 1)
+#define PIN_PC0__A23 PINMUX_PIN(PIN_PC0, 2, 1)
+#define PIN_PC0__FLEXCOM0_IO4 PINMUX_PIN(PIN_PC0, 3, 1)
+#define PIN_PC0__TWCK0 PINMUX_PIN(PIN_PC0, 4, 1)
+#define PIN_PC0__ISC_D6 PINMUX_PIN(PIN_PC0, 6, 3)
+#define PIN_PC1 65
+#define PIN_PC1__GPIO PINMUX_PIN(PIN_PC1, 0, 0)
+#define PIN_PC1__LCDDAT22 PINMUX_PIN(PIN_PC1, 1, 1)
+#define PIN_PC1__A24 PINMUX_PIN(PIN_PC1, 2, 1)
+#define PIN_PC1__CANTX0 PINMUX_PIN(PIN_PC1, 3, 1)
+#define PIN_PC1__SPI1_SPCK PINMUX_PIN(PIN_PC1, 4, 1)
+#define PIN_PC1__I2SC0_CK PINMUX_PIN(PIN_PC1, 5, 1)
+#define PIN_PC1__ISC_D7 PINMUX_PIN(PIN_PC1, 6, 3)
+#define PIN_PC2 66
+#define PIN_PC2__GPIO PINMUX_PIN(PIN_PC2, 0, 0)
+#define PIN_PC2__LCDDAT23 PINMUX_PIN(PIN_PC2, 1, 1)
+#define PIN_PC2__A25 PINMUX_PIN(PIN_PC2, 2, 1)
+#define PIN_PC2__CANRX0 PINMUX_PIN(PIN_PC2, 3, 1)
+#define PIN_PC2__SPI1_MOSI PINMUX_PIN(PIN_PC2, 4, 1)
+#define PIN_PC2__I2SC0_MCK PINMUX_PIN(PIN_PC2, 5, 1)
+#define PIN_PC2__ISC_D8 PINMUX_PIN(PIN_PC2, 6, 3)
+#define PIN_PC3 67
+#define PIN_PC3__GPIO PINMUX_PIN(PIN_PC3, 0, 0)
+#define PIN_PC3__LCDPWM PINMUX_PIN(PIN_PC3, 1, 1)
+#define PIN_PC3__NWAIT PINMUX_PIN(PIN_PC3, 2, 1)
+#define PIN_PC3__TIOA1 PINMUX_PIN(PIN_PC3, 3, 1)
+#define PIN_PC3__SPI1_MISO PINMUX_PIN(PIN_PC3, 4, 1)
+#define PIN_PC3__I2SC0_WS PINMUX_PIN(PIN_PC3, 5, 1)
+#define PIN_PC3__ISC_D9 PINMUX_PIN(PIN_PC3, 6, 3)
+#define PIN_PC4 68
+#define PIN_PC4__GPIO PINMUX_PIN(PIN_PC4, 0, 0)
+#define PIN_PC4__LCDDISP PINMUX_PIN(PIN_PC4, 1, 1)
+#define PIN_PC4__NWR1_NBS1 PINMUX_PIN(PIN_PC4, 2, 1)
+#define PIN_PC4__TIOB1 PINMUX_PIN(PIN_PC4, 3, 1)
+#define PIN_PC4__SPI1_NPCS0 PINMUX_PIN(PIN_PC4, 4, 1)
+#define PIN_PC4__I2SC0_DI0 PINMUX_PIN(PIN_PC4, 5, 1)
+#define PIN_PC4__ISC_PCK PINMUX_PIN(PIN_PC4, 6, 3)
+#define PIN_PC5 69
+#define PIN_PC5__GPIO PINMUX_PIN(PIN_PC5, 0, 0)
+#define PIN_PC5__LCDVSYNC PINMUX_PIN(PIN_PC5, 1, 1)
+#define PIN_PC5__NCS0 PINMUX_PIN(PIN_PC5, 2, 1)
+#define PIN_PC5__TCLK1 PINMUX_PIN(PIN_PC5, 3, 1)
+#define PIN_PC5__SPI1_NPCS1 PINMUX_PIN(PIN_PC5, 4, 1)
+#define PIN_PC5__I2SC0_DO0 PINMUX_PIN(PIN_PC5, 5, 1)
+#define PIN_PC5__ISC_VSYNC PINMUX_PIN(PIN_PC5, 6, 3)
+#define PIN_PC6 70
+#define PIN_PC6__GPIO PINMUX_PIN(PIN_PC6, 0, 0)
+#define PIN_PC6__LCDHSYNC PINMUX_PIN(PIN_PC6, 1, 1)
+#define PIN_PC6__NCS1 PINMUX_PIN(PIN_PC6, 2, 1)
+#define PIN_PC6__TWD1 PINMUX_PIN(PIN_PC6, 3, 1)
+#define PIN_PC6__SPI1_NPCS2 PINMUX_PIN(PIN_PC6, 4, 1)
+#define PIN_PC6__ISC_HSYNC PINMUX_PIN(PIN_PC6, 6, 3)
+#define PIN_PC7 71
+#define PIN_PC7__GPIO PINMUX_PIN(PIN_PC7, 0, 0)
+#define PIN_PC7__LCDPCK PINMUX_PIN(PIN_PC7, 1, 1)
+#define PIN_PC7__NCS2 PINMUX_PIN(PIN_PC7, 2, 1)
+#define PIN_PC7__TWCK1 PINMUX_PIN(PIN_PC7, 3, 1)
+#define PIN_PC7__SPI1_NPCS3 PINMUX_PIN(PIN_PC7, 4, 1)
+#define PIN_PC7__URXD1 PINMUX_PIN(PIN_PC7, 5, 2)
+#define PIN_PC7__ISC_MCK PINMUX_PIN(PIN_PC7, 6, 3)
+#define PIN_PC8 72
+#define PIN_PC8__GPIO PINMUX_PIN(PIN_PC8, 0, 0)
+#define PIN_PC8__LCDDEN PINMUX_PIN(PIN_PC8, 1, 1)
+#define PIN_PC8__NANDRDY PINMUX_PIN(PIN_PC8, 2, 1)
+#define PIN_PC8__FIQ PINMUX_PIN(PIN_PC8, 3, 1)
+#define PIN_PC8__PCK0 PINMUX_PIN(PIN_PC8, 4, 3)
+#define PIN_PC8__UTXD1 PINMUX_PIN(PIN_PC8, 5, 2)
+#define PIN_PC8__ISC_FIELD PINMUX_PIN(PIN_PC8, 6, 3)
+#define PIN_PC9 73
+#define PIN_PC9__GPIO PINMUX_PIN(PIN_PC9, 0, 0)
+#define PIN_PC9__FIQ PINMUX_PIN(PIN_PC9, 1, 3)
+#define PIN_PC9__GTSUCOMP PINMUX_PIN(PIN_PC9, 2, 1)
+#define PIN_PC9__ISC_D0 PINMUX_PIN(PIN_PC9, 2, 1)
+#define PIN_PC9__TIOA4 PINMUX_PIN(PIN_PC9, 4, 2)
+#define PIN_PC10 74
+#define PIN_PC10__GPIO PINMUX_PIN(PIN_PC10, 0, 0)
+#define PIN_PC10__LCDDAT2 PINMUX_PIN(PIN_PC10, 1, 2)
+#define PIN_PC10__GTXCK PINMUX_PIN(PIN_PC10, 2, 1)
+#define PIN_PC10__ISC_D1 PINMUX_PIN(PIN_PC10, 3, 1)
+#define PIN_PC10__TIOB4 PINMUX_PIN(PIN_PC10, 4, 2)
+#define PIN_PC10__CANTX0 PINMUX_PIN(PIN_PC10, 5, 2)
+#define PIN_PC11 75
+#define PIN_PC11__GPIO PINMUX_PIN(PIN_PC11, 0, 0)
+#define PIN_PC11__LCDDAT3 PINMUX_PIN(PIN_PC11, 1, 2)
+#define PIN_PC11__GTXEN PINMUX_PIN(PIN_PC11, 2, 1)
+#define PIN_PC11__ISC_D2 PINMUX_PIN(PIN_PC11, 3, 1)
+#define PIN_PC11__TCLK4 PINMUX_PIN(PIN_PC11, 4, 2)
+#define PIN_PC11__CANRX0 PINMUX_PIN(PIN_PC11, 5, 2)
+#define PIN_PC11__A0_NBS0 PINMUX_PIN(PIN_PC11, 6, 2)
+#define PIN_PC12 76
+#define PIN_PC12__GPIO PINMUX_PIN(PIN_PC12, 0, 0)
+#define PIN_PC12__LCDDAT4 PINMUX_PIN(PIN_PC12, 1, 2)
+#define PIN_PC12__GRXDV PINMUX_PIN(PIN_PC12, 2, 1)
+#define PIN_PC12__ISC_D3 PINMUX_PIN(PIN_PC12, 3, 1)
+#define PIN_PC12__URXD3 PINMUX_PIN(PIN_PC12, 4, 1)
+#define PIN_PC12__TK0 PINMUX_PIN(PIN_PC12, 5, 2)
+#define PIN_PC12__A1 PINMUX_PIN(PIN_PC12, 6, 2)
+#define PIN_PC13 77
+#define PIN_PC13__GPIO PINMUX_PIN(PIN_PC13, 0, 0)
+#define PIN_PC13__LCDDAT5 PINMUX_PIN(PIN_PC13, 1, 2)
+#define PIN_PC13__GRXER PINMUX_PIN(PIN_PC13, 2, 1)
+#define PIN_PC13__ISC_D4 PINMUX_PIN(PIN_PC13, 3, 1)
+#define PIN_PC13__UTXD3 PINMUX_PIN(PIN_PC13, 4, 1)
+#define PIN_PC13__TF0 PINMUX_PIN(PIN_PC13, 5, 2)
+#define PIN_PC13__A2 PINMUX_PIN(PIN_PC13, 6, 2)
+#define PIN_PC14 78
+#define PIN_PC14__GPIO PINMUX_PIN(PIN_PC14, 0, 0)
+#define PIN_PC14__LCDDAT6 PINMUX_PIN(PIN_PC14, 1, 2)
+#define PIN_PC14__GRX0 PINMUX_PIN(PIN_PC14, 2, 1)
+#define PIN_PC14__ISC_D5 PINMUX_PIN(PIN_PC14, 3, 1)
+#define PIN_PC14__TDO PINMUX_PIN(PIN_PC14, 5, 2)
+#define PIN_PC14__A3 PINMUX_PIN(PIN_PC14, 6, 2)
+#define PIN_PC15 79
+#define PIN_PC15__GPIO PINMUX_PIN(PIN_PC15, 0, 0)
+#define PIN_PC15__LCDDAT7 PINMUX_PIN(PIN_PC15, 1, 2)
+#define PIN_PC15__GRX1 PINMUX_PIN(PIN_PC15, 2, 1)
+#define PIN_PC15__ISC_D6 PINMUX_PIN(PIN_PC15, 3, 1)
+#define PIN_PC15__RD0 PINMUX_PIN(PIN_PC15, 5, 2)
+#define PIN_PC15__A4 PINMUX_PIN(PIN_PC15, 6, 2)
+#define PIN_PC16 80
+#define PIN_PC16__GPIO PINMUX_PIN(PIN_PC16, 0, 0)
+#define PIN_PC16__LCDDAT10 PINMUX_PIN(PIN_PC16, 1, 2)
+#define PIN_PC16__GTX0 PINMUX_PIN(PIN_PC16, 2, 1)
+#define PIN_PC16__ISC_D7 PINMUX_PIN(PIN_PC16, 3, 1)
+#define PIN_PC16__RK0 PINMUX_PIN(PIN_PC16, 5, 2)
+#define PIN_PC16__A5 PINMUX_PIN(PIN_PC16, 6, 2)
+#define PIN_PC17 81
+#define PIN_PC17__GPIO PINMUX_PIN(PIN_PC17, 0, 0)
+#define PIN_PC17__LCDDAT11 PINMUX_PIN(PIN_PC17, 1, 2)
+#define PIN_PC17__GTX1 PINMUX_PIN(PIN_PC17, 2, 1)
+#define PIN_PC17__ISC_D8 PINMUX_PIN(PIN_PC17, 3, 1)
+#define PIN_PC17__RF0 PINMUX_PIN(PIN_PC17, 5, 2)
+#define PIN_PC17__A6 PINMUX_PIN(PIN_PC17, 6, 2)
+#define PIN_PC18 82
+#define PIN_PC18__GPIO PINMUX_PIN(PIN_PC18, 0, 0)
+#define PIN_PC18__LCDDAT12 PINMUX_PIN(PIN_PC18, 1, 2)
+#define PIN_PC18__GMDC PINMUX_PIN(PIN_PC18, 2, 1)
+#define PIN_PC18__ISC_D9 PINMUX_PIN(PIN_PC18, 3, 1)
+#define PIN_PC18__FLEXCOM3_IO2 PINMUX_PIN(PIN_PC18, 5, 2)
+#define PIN_PC18__A7 PINMUX_PIN(PIN_PC18, 6, 2)
+#define PIN_PC19 83
+#define PIN_PC19__GPIO PINMUX_PIN(PIN_PC19, 0, 0)
+#define PIN_PC19__LCDDAT13 PINMUX_PIN(PIN_PC19, 1, 2)
+#define PIN_PC19__GMDIO PINMUX_PIN(PIN_PC19, 2, 1)
+#define PIN_PC19__ISC_D10 PINMUX_PIN(PIN_PC19, 3, 1)
+#define PIN_PC19__FLEXCOM3_IO1 PINMUX_PIN(PIN_PC19, 5, 2)
+#define PIN_PC19__A8 PINMUX_PIN(PIN_PC19, 6, 2)
+#define PIN_PC20 84
+#define PIN_PC20__GPIO PINMUX_PIN(PIN_PC20, 0, 0)
+#define PIN_PC20__LCDDAT14 PINMUX_PIN(PIN_PC20, 1, 2)
+#define PIN_PC20__GRXCK PINMUX_PIN(PIN_PC20, 2, 1)
+#define PIN_PC20__ISC_D11 PINMUX_PIN(PIN_PC20, 3, 1)
+#define PIN_PC20__FLEXCOM3_IO0 PINMUX_PIN(PIN_PC20, 5, 2)
+#define PIN_PC20__A9 PINMUX_PIN(PIN_PC20, 6, 2)
+#define PIN_PC21 85
+#define PIN_PC21__GPIO PINMUX_PIN(PIN_PC21, 0, 0)
+#define PIN_PC21__LCDDAT15 PINMUX_PIN(PIN_PC21, 1, 2)
+#define PIN_PC21__GTXER PINMUX_PIN(PIN_PC21, 2, 1)
+#define PIN_PC21__ISC_PCK PINMUX_PIN(PIN_PC21, 3, 1)
+#define PIN_PC21__FLEXCOM3_IO3 PINMUX_PIN(PIN_PC21, 5, 2)
+#define PIN_PC21__A10 PINMUX_PIN(PIN_PC21, 6, 2)
+#define PIN_PC22 86
+#define PIN_PC22__GPIO PINMUX_PIN(PIN_PC22, 0, 0)
+#define PIN_PC22__LCDDAT18 PINMUX_PIN(PIN_PC22, 1, 2)
+#define PIN_PC22__GCRS PINMUX_PIN(PIN_PC22, 2, 1)
+#define PIN_PC22__ISC_VSYNC PINMUX_PIN(PIN_PC22, 3, 1)
+#define PIN_PC22__FLEXCOM3_IO4 PINMUX_PIN(PIN_PC22, 5, 2)
+#define PIN_PC22__A11 PINMUX_PIN(PIN_PC22, 6, 2)
+#define PIN_PC23 87
+#define PIN_PC23__GPIO PINMUX_PIN(PIN_PC23, 0, 0)
+#define PIN_PC23__LCDDAT19 PINMUX_PIN(PIN_PC23, 1, 2)
+#define PIN_PC23__GCOL PINMUX_PIN(PIN_PC23, 2, 1)
+#define PIN_PC23__ISC_HSYNC PINMUX_PIN(PIN_PC23, 3, 1)
+#define PIN_PC23__A12 PINMUX_PIN(PIN_PC23, 6, 2)
+#define PIN_PC24 88
+#define PIN_PC24__GPIO PINMUX_PIN(PIN_PC24, 0, 0)
+#define PIN_PC24__LCDDAT20 PINMUX_PIN(PIN_PC24, 1, 2)
+#define PIN_PC24__GRX2 PINMUX_PIN(PIN_PC24, 2, 1)
+#define PIN_PC24__ISC_MCK PINMUX_PIN(PIN_PC24, 3, 1)
+#define PIN_PC24__A13 PINMUX_PIN(PIN_PC24, 6, 2)
+#define PIN_PC25 89
+#define PIN_PC25__GPIO PINMUX_PIN(PIN_PC25, 0, 0)
+#define PIN_PC25__LCDDAT21 PINMUX_PIN(PIN_PC25, 1, 2)
+#define PIN_PC25__GRX3 PINMUX_PIN(PIN_PC25, 2, 1)
+#define PIN_PC25__ISC_FIELD PINMUX_PIN(PIN_PC25, 3, 1)
+#define PIN_PC25__A14 PINMUX_PIN(PIN_PC25, 6, 2)
+#define PIN_PC26 90
+#define PIN_PC26__GPIO PINMUX_PIN(PIN_PC26, 0, 0)
+#define PIN_PC26__LCDDAT22 PINMUX_PIN(PIN_PC26, 1, 2)
+#define PIN_PC26__GTX2 PINMUX_PIN(PIN_PC26, 2, 1)
+#define PIN_PC26__CANTX1 PINMUX_PIN(PIN_PC26, 4, 1)
+#define PIN_PC26__A15 PINMUX_PIN(PIN_PC26, 6, 2)
+#define PIN_PC27 91
+#define PIN_PC27__GPIO PINMUX_PIN(PIN_PC27, 0, 0)
+#define PIN_PC27__LCDDAT23 PINMUX_PIN(PIN_PC27, 1, 2)
+#define PIN_PC27__GTX3 PINMUX_PIN(PIN_PC27, 2, 1)
+#define PIN_PC27__PCK1 PINMUX_PIN(PIN_PC27, 3, 2)
+#define PIN_PC27__CANRX1 PINMUX_PIN(PIN_PC27, 4, 1)
+#define PIN_PC27__TWD0 PINMUX_PIN(PIN_PC27, 5, 2)
+#define PIN_PC27__A16 PINMUX_PIN(PIN_PC27, 6, 2)
+#define PIN_PC28 92
+#define PIN_PC28__GPIO PINMUX_PIN(PIN_PC28, 0, 0)
+#define PIN_PC28__LCDPWM PINMUX_PIN(PIN_PC28, 1, 2)
+#define PIN_PC28__FLEXCOM4_IO0 PINMUX_PIN(PIN_PC28, 2, 1)
+#define PIN_PC28__PCK2 PINMUX_PIN(PIN_PC28, 3, 2)
+#define PIN_PC28__TWCK0 PINMUX_PIN(PIN_PC28, 5, 2)
+#define PIN_PC28__A17 PINMUX_PIN(PIN_PC28, 6, 2)
+#define PIN_PC29 93
+#define PIN_PC29__GPIO PINMUX_PIN(PIN_PC29, 0, 0)
+#define PIN_PC29__LCDDISP PINMUX_PIN(PIN_PC29, 1, 2)
+#define PIN_PC29__FLEXCOM4_IO1 PINMUX_PIN(PIN_PC29, 2, 1)
+#define PIN_PC29__A18 PINMUX_PIN(PIN_PC29, 6, 2)
+#define PIN_PC30 94
+#define PIN_PC30__GPIO PINMUX_PIN(PIN_PC30, 0, 0)
+#define PIN_PC30__LCDVSYNC PINMUX_PIN(PIN_PC30, 1, 2)
+#define PIN_PC30__FLEXCOM4_IO2 PINMUX_PIN(PIN_PC30, 2, 1)
+#define PIN_PC30__A19 PINMUX_PIN(PIN_PC30, 6, 2)
+#define PIN_PC31 95
+#define PIN_PC31__GPIO PINMUX_PIN(PIN_PC31, 0, 0)
+#define PIN_PC31__LCDHSYNC PINMUX_PIN(PIN_PC31, 1, 2)
+#define PIN_PC31__FLEXCOM4_IO3 PINMUX_PIN(PIN_PC31, 2, 1)
+#define PIN_PC31__URXD3 PINMUX_PIN(PIN_PC31, 3, 2)
+#define PIN_PC31__A20 PINMUX_PIN(PIN_PC31, 6, 2)
+#define PIN_PD0 96
+#define PIN_PD0__GPIO PINMUX_PIN(PIN_PD0, 0, 0)
+#define PIN_PD0__LCDPCK PINMUX_PIN(PIN_PD0, 1, 2)
+#define PIN_PD0__FLEXCOM4_IO4 PINMUX_PIN(PIN_PD0, 2, 1)
+#define PIN_PD0__UTXD3 PINMUX_PIN(PIN_PD0, 3, 2)
+#define PIN_PD0__GTSUCOMP PINMUX_PIN(PIN_PD0, 4, 2)
+#define PIN_PD0__A23 PINMUX_PIN(PIN_PD0, 6, 2)
+#define PIN_PD1 97
+#define PIN_PD1__GPIO PINMUX_PIN(PIN_PD1, 0, 0)
+#define PIN_PD1__LCDDEN PINMUX_PIN(PIN_PD1, 1, 2)
+#define PIN_PD1__GRXCK PINMUX_PIN(PIN_PD1, 4, 2)
+#define PIN_PD1__A24 PINMUX_PIN(PIN_PD1, 6, 2)
+#define PIN_PD2 98
+#define PIN_PD2__GPIO PINMUX_PIN(PIN_PD2, 0, 0)
+#define PIN_PD2__URXD1 PINMUX_PIN(PIN_PD2, 1, 1)
+#define PIN_PD2__GTXER PINMUX_PIN(PIN_PD2, 4, 2)
+#define PIN_PD2__ISC_MCK PINMUX_PIN(PIN_PD2, 5, 2)
+#define PIN_PD2__A25 PINMUX_PIN(PIN_PD2, 6, 2)
+#define PIN_PD3 99
+#define PIN_PD3__GPIO PINMUX_PIN(PIN_PD3, 0, 0)
+#define PIN_PD3__UTXD1 PINMUX_PIN(PIN_PD3, 1, 1)
+#define PIN_PD3__FIQ PINMUX_PIN(PIN_PD3, 2, 2)
+#define PIN_PD3__GCRS PINMUX_PIN(PIN_PD3, 4, 2)
+#define PIN_PD3__ISC_D11 PINMUX_PIN(PIN_PD3, 5, 2)
+#define PIN_PD3__NWAIT PINMUX_PIN(PIN_PD3, 6, 2)
+#define PIN_PD4 100
+#define PIN_PD4__GPIO PINMUX_PIN(PIN_PD4, 0, 0)
+#define PIN_PD4__TWD1 PINMUX_PIN(PIN_PD4, 1, 2)
+#define PIN_PD4__URXD2 PINMUX_PIN(PIN_PD4, 2, 1)
+#define PIN_PD4__GCOL PINMUX_PIN(PIN_PD4, 4, 2)
+#define PIN_PD4__ISC_D10 PINMUX_PIN(PIN_PD4, 5, 2)
+#define PIN_PD4__NCS0 PINMUX_PIN(PIN_PD4, 6, 2)
+#define PIN_PD5 101
+#define PIN_PD5__GPIO PINMUX_PIN(PIN_PD5, 0, 0)
+#define PIN_PD5__TWCK1 PINMUX_PIN(PIN_PD5, 1, 2)
+#define PIN_PD5__UTXD2 PINMUX_PIN(PIN_PD5, 2, 1)
+#define PIN_PD5__GRX2 PINMUX_PIN(PIN_PD5, 4, 2)
+#define PIN_PD5__ISC_D9 PINMUX_PIN(PIN_PD5, 5, 2)
+#define PIN_PD5__NCS1 PINMUX_PIN(PIN_PD5, 6, 2)
+#define PIN_PD6 102
+#define PIN_PD6__GPIO PINMUX_PIN(PIN_PD6, 0, 0)
+#define PIN_PD6__TCK PINMUX_PIN(PIN_PD6, 1, 2)
+#define PIN_PD6__PCK1 PINMUX_PIN(PIN_PD6, 2, 1)
+#define PIN_PD6__GRX3 PINMUX_PIN(PIN_PD6, 4, 2)
+#define PIN_PD6__ISC_D8 PINMUX_PIN(PIN_PD6, 5, 2)
+#define PIN_PD6__NCS2 PINMUX_PIN(PIN_PD6, 6, 2)
+#define PIN_PD7 103
+#define PIN_PD7__GPIO PINMUX_PIN(PIN_PD7, 0, 0)
+#define PIN_PD7__TDI PINMUX_PIN(PIN_PD7, 1, 2)
+#define PIN_PD7__UTMI_RXVAL PINMUX_PIN(PIN_PD7, 3, 1)
+#define PIN_PD7__GTX2 PINMUX_PIN(PIN_PD7, 4, 2)
+#define PIN_PD7__ISC_D0 PINMUX_PIN(PIN_PD7, 5, 2)
+#define PIN_PD7__NWR1_NBS1 PINMUX_PIN(PIN_PD7, 6, 2)
+#define PIN_PD8 104
+#define PIN_PD8__GPIO PINMUX_PIN(PIN_PD8, 0, 0)
+#define PIN_PD8__TDO PINMUX_PIN(PIN_PD8, 1, 2)
+#define PIN_PD8__UTMI_RXERR PINMUX_PIN(PIN_PD8, 3, 1)
+#define PIN_PD8__GTX3 PINMUX_PIN(PIN_PD8, 4, 2)
+#define PIN_PD8__ISC_D1 PINMUX_PIN(PIN_PD8, 5, 2)
+#define PIN_PD8__NANDRDY PINMUX_PIN(PIN_PD8, 6, 2)
+#define PIN_PD9 105
+#define PIN_PD9__GPIO PINMUX_PIN(PIN_PD9, 0, 0)
+#define PIN_PD9__TMS PINMUX_PIN(PIN_PD9, 1, 2)
+#define PIN_PD9__UTMI_RXACT PINMUX_PIN(PIN_PD9, 3, 1)
+#define PIN_PD9__GTXCK PINMUX_PIN(PIN_PD9, 4, 2)
+#define PIN_PD9__ISC_D2 PINMUX_PIN(PIN_PD9, 5, 2)
+#define PIN_PD10 106
+#define PIN_PD10__GPIO PINMUX_PIN(PIN_PD10, 0, 0)
+#define PIN_PD10__NTRST PINMUX_PIN(PIN_PD10, 1, 2)
+#define PIN_PD10__UTMI_HDIS PINMUX_PIN(PIN_PD10, 3, 1)
+#define PIN_PD10__GTXEN PINMUX_PIN(PIN_PD10, 4, 2)
+#define PIN_PD10__ISC_D3 PINMUX_PIN(PIN_PD10, 5, 2)
+#define PIN_PD11 107
+#define PIN_PD11__GPIO PINMUX_PIN(PIN_PD11, 0, 0)
+#define PIN_PD11__TIOA1 PINMUX_PIN(PIN_PD11, 1, 3)
+#define PIN_PD11__PCK2 PINMUX_PIN(PIN_PD11, 2, 2)
+#define PIN_PD11__UTMI_LS0 PINMUX_PIN(PIN_PD11, 3, 1)
+#define PIN_PD11__GRXDV PINMUX_PIN(PIN_PD11, 4, 2)
+#define PIN_PD11__ISC_D4 PINMUX_PIN(PIN_PD11, 5, 2)
+#define PIN_PD11__ISC_MCK PINMUX_PIN(PIN_PD11, 7, 4)
+#define PIN_PD12 108
+#define PIN_PD12__GPIO PINMUX_PIN(PIN_PD12, 0, 0)
+#define PIN_PD12__TIOB1 PINMUX_PIN(PIN_PD12, 1, 3)
+#define PIN_PD12__FLEXCOM4_IO0 PINMUX_PIN(PIN_PD12, 2, 2)
+#define PIN_PD12__UTMI_LS1 PINMUX_PIN(PIN_PD12, 3, 1)
+#define PIN_PD12__GRXER PINMUX_PIN(PIN_PD12, 4, 2)
+#define PIN_PD12__ISC_D5 PINMUX_PIN(PIN_PD12, 5, 2)
+#define PIN_PD12__ISC_D4 PINMUX_PIN(PIN_PD12, 6, 4)
+#define PIN_PD13 109
+#define PIN_PD13__GPIO PINMUX_PIN(PIN_PD13, 0, 0)
+#define PIN_PD13__TCLK1 PINMUX_PIN(PIN_PD13, 1, 3)
+#define PIN_PD13__FLEXCOM4_IO1 PINMUX_PIN(PIN_PD13, 2, 2)
+#define PIN_PD13__UTMI_CDRPCSEL0 PINMUX_PIN(PIN_PD13, 3, 1)
+#define PIN_PD13__GRX0 PINMUX_PIN(PIN_PD13, 4, 2)
+#define PIN_PD13__ISC_D6 PINMUX_PIN(PIN_PD13, 5, 2)
+#define PIN_PD13__ISC_D5 PINMUX_PIN(PIN_PD13, 6, 4)
+#define PIN_PD14 110
+#define PIN_PD14__GPIO PINMUX_PIN(PIN_PD14, 0, 0)
+#define PIN_PD14__TCK PINMUX_PIN(PIN_PD14, 1, 1)
+#define PIN_PD14__FLEXCOM4_IO2 PINMUX_PIN(PIN_PD14, 2, 2)
+#define PIN_PD14__UTMI_CDRPCSEL1 PINMUX_PIN(PIN_PD14, 3, 1)
+#define PIN_PD14__GRX1 PINMUX_PIN(PIN_PD14, 4, 2)
+#define PIN_PD14__ISC_D7 PINMUX_PIN(PIN_PD14, 5, 2)
+#define PIN_PD14__ISC_D6 PINMUX_PIN(PIN_PD14, 6, 4)
+#define PIN_PD15 111
+#define PIN_PD15__GPIO PINMUX_PIN(PIN_PD15, 0, 0)
+#define PIN_PD15__TDI PINMUX_PIN(PIN_PD15, 1, 1)
+#define PIN_PD15__FLEXCOM4_IO3 PINMUX_PIN(PIN_PD15, 2, 2)
+#define PIN_PD15__UTMI_CDRCPDIVEN PINMUX_PIN(PIN_PD15, 3, 1)
+#define PIN_PD15__GTX0 PINMUX_PIN(PIN_PD15, 4, 2)
+#define PIN_PD15__ISC_PCK PINMUX_PIN(PIN_PD15, 5, 2)
+#define PIN_PD15__ISC_D7 PINMUX_PIN(PIN_PD15, 6, 4)
+#define PIN_PD16 112
+#define PIN_PD16__GPIO PINMUX_PIN(PIN_PD16, 0, 0)
+#define PIN_PD16__TDO PINMUX_PIN(PIN_PD16, 1, 1)
+#define PIN_PD16__FLEXCOM4_IO4 PINMUX_PIN(PIN_PD16, 2, 2)
+#define PIN_PD16__UTMI_CDRBISTEN PINMUX_PIN(PIN_PD16, 3, 1)
+#define PIN_PD16__GTX1 PINMUX_PIN(PIN_PD16, 4, 2)
+#define PIN_PD16__ISC_VSYNC PINMUX_PIN(PIN_PD16, 5, 2)
+#define PIN_PD16__ISC_D8 PINMUX_PIN(PIN_PD16, 6, 4)
+#define PIN_PD17 113
+#define PIN_PD17__GPIO PINMUX_PIN(PIN_PD17, 0, 0)
+#define PIN_PD17__TMS PINMUX_PIN(PIN_PD17, 1, 1)
+#define PIN_PD17__UTMI_CDRCPSELDIV PINMUX_PIN(PIN_PD17, 3, 1)
+#define PIN_PD17__GMDC PINMUX_PIN(PIN_PD17, 4, 2)
+#define PIN_PD17__ISC_HSYNC PINMUX_PIN(PIN_PD17, 5, 2)
+#define PIN_PD17__ISC_D9 PINMUX_PIN(PIN_PD17, 6, 4)
+#define PIN_PD18 114
+#define PIN_PD18__GPIO PINMUX_PIN(PIN_PD18, 0, 0)
+#define PIN_PD18__NTRST PINMUX_PIN(PIN_PD18, 1, 1)
+#define PIN_PD18__GMDIO PINMUX_PIN(PIN_PD18, 4, 2)
+#define PIN_PD18__ISC_FIELD PINMUX_PIN(PIN_PD18, 5, 2)
+#define PIN_PD18__ISC_D10 PINMUX_PIN(PIN_PD18, 6, 4)
+#define PIN_PD19 115
+#define PIN_PD19__GPIO PINMUX_PIN(PIN_PD19, 0, 0)
+#define PIN_PD19__PCK0 PINMUX_PIN(PIN_PD19, 1, 1)
+#define PIN_PD19__TWD1 PINMUX_PIN(PIN_PD19, 2, 3)
+#define PIN_PD19__URXD2 PINMUX_PIN(PIN_PD19, 3, 3)
+#define PIN_PD19__I2SC0_CK PINMUX_PIN(PIN_PD19, 5, 2)
+#define PIN_PD19__ISC_D11 PINMUX_PIN(PIN_PD19, 6, 4)
+#define PIN_PD20 116
+#define PIN_PD20__GPIO PINMUX_PIN(PIN_PD20, 0, 0)
+#define PIN_PD20__TIOA2 PINMUX_PIN(PIN_PD20, 1, 3)
+#define PIN_PD20__TWCK1 PINMUX_PIN(PIN_PD20, 2, 3)
+#define PIN_PD20__UTXD2 PINMUX_PIN(PIN_PD20, 3, 3)
+#define PIN_PD20__I2SC0_MCK PINMUX_PIN(PIN_PD20, 5, 2)
+#define PIN_PD20__ISC_PCK PINMUX_PIN(PIN_PD20, 6, 4)
+#define PIN_PD21 117
+#define PIN_PD21__GPIO PINMUX_PIN(PIN_PD21, 0, 0)
+#define PIN_PD21__TIOB2 PINMUX_PIN(PIN_PD21, 1, 3)
+#define PIN_PD21__TWD0 PINMUX_PIN(PIN_PD21, 2, 4)
+#define PIN_PD21__FLEXCOM4_IO0 PINMUX_PIN(PIN_PD21, 3, 3)
+#define PIN_PD21__I2SC0_WS PINMUX_PIN(PIN_PD21, 5, 2)
+#define PIN_PD21__ISC_VSYNC PINMUX_PIN(PIN_PD21, 6, 4)
+#define PIN_PD22 118
+#define PIN_PD22__GPIO PINMUX_PIN(PIN_PD22, 0, 0)
+#define PIN_PD22__TCLK2 PINMUX_PIN(PIN_PD22, 1, 3)
+#define PIN_PD22__TWCK0 PINMUX_PIN(PIN_PD22, 2, 4)
+#define PIN_PD22__FLEXCOM4_IO1 PINMUX_PIN(PIN_PD22, 3, 3)
+#define PIN_PD22__I2SC0_DI0 PINMUX_PIN(PIN_PD22, 5, 2)
+#define PIN_PD22__ISC_HSYNC PINMUX_PIN(PIN_PD22, 6, 4)
+#define PIN_PD23 119
+#define PIN_PD23__GPIO PINMUX_PIN(PIN_PD23, 0, 0)
+#define PIN_PD23__URXD2 PINMUX_PIN(PIN_PD23, 1, 2)
+#define PIN_PD23__FLEXCOM4_IO2 PINMUX_PIN(PIN_PD23, 3, 3)
+#define PIN_PD23__I2SC0_DO0 PINMUX_PIN(PIN_PD23, 5, 2)
+#define PIN_PD23__ISC_FIELD PINMUX_PIN(PIN_PD23, 6, 4)
+#define PIN_PD24 120
+#define PIN_PD24__GPIO PINMUX_PIN(PIN_PD24, 0, 0)
+#define PIN_PD24__UTXD2 PINMUX_PIN(PIN_PD23, 1, 2)
+#define PIN_PD24__FLEXCOM4_IO3 PINMUX_PIN(PIN_PD23, 3, 3)
+#define PIN_PD25 121
+#define PIN_PD25__GPIO PINMUX_PIN(PIN_PD25, 0, 0)
+#define PIN_PD25__SPI1_SPCK PINMUX_PIN(PIN_PD25, 1, 3)
+#define PIN_PD25__FLEXCOM4_IO4 PINMUX_PIN(PIN_PD25, 3, 3)
+#define PIN_PD26 122
+#define PIN_PD26__GPIO PINMUX_PIN(PIN_PD26, 0, 0)
+#define PIN_PD26__SPI1_MOSI PINMUX_PIN(PIN_PD26, 1, 3)
+#define PIN_PD26__FLEXCOM2_IO0 PINMUX_PIN(PIN_PD26, 3, 2)
+#define PIN_PD27 123
+#define PIN_PD27__GPIO PINMUX_PIN(PIN_PD27, 0, 0)
+#define PIN_PD27__SPI1_MISO PINMUX_PIN(PIN_PD27, 1, 3)
+#define PIN_PD27__TCK PINMUX_PIN(PIN_PD27, 2, 3)
+#define PIN_PD27__FLEXCOM2_IO1 PINMUX_PIN(PIN_PD27, 3, 2)
+#define PIN_PD28 124
+#define PIN_PD28__GPIO PINMUX_PIN(PIN_PD28, 0, 0)
+#define PIN_PD28__SPI1_NPCS0 PINMUX_PIN(PIN_PD28, 1, 3)
+#define PIN_PD28__TCI PINMUX_PIN(PIN_PD28, 2, 3)
+#define PIN_PD28__FLEXCOM2_IO2 PINMUX_PIN(PIN_PD28, 3, 2)
+#define PIN_PD29 125
+#define PIN_PD29__GPIO PINMUX_PIN(PIN_PD29, 0, 0)
+#define PIN_PD29__SPI1_NPCS1 PINMUX_PIN(PIN_PD29, 1, 3)
+#define PIN_PD29__TDO PINMUX_PIN(PIN_PD29, 2, 3)
+#define PIN_PD29__FLEXCOM2_IO3 PINMUX_PIN(PIN_PD29, 3, 2)
+#define PIN_PD29__TIOA3 PINMUX_PIN(PIN_PD29, 4, 3)
+#define PIN_PD29__TWD0 PINMUX_PIN(PIN_PD29, 5, 3)
+#define PIN_PD30 126
+#define PIN_PD30__GPIO PINMUX_PIN(PIN_PD30, 0, 0)
+#define PIN_PD30__SPI1_NPCS2 PINMUX_PIN(PIN_PD30, 1, 3)
+#define PIN_PD30__TMS PINMUX_PIN(PIN_PD30, 2, 3)
+#define PIN_PD30__FLEXCOM2_IO4 PINMUX_PIN(PIN_PD30, 3, 2)
+#define PIN_PD30__TIOB3 PINMUX_PIN(PIN_PD30, 4, 3)
+#define PIN_PD30__TWCK0 PINMUX_PIN(PIN_PD30, 5, 3)
+#define PIN_PD31 127
+#define PIN_PD31__GPIO PINMUX_PIN(PIN_PD31, 0, 0)
+#define PIN_PD31__ADTRG PINMUX_PIN(PIN_PD31, 1, 1)
+#define PIN_PD31__NTRST PINMUX_PIN(PIN_PD31, 2, 3)
+#define PIN_PD31__IRQ PINMUX_PIN(PIN_PD31, 3, 4)
+#define PIN_PD31__TCLK3 PINMUX_PIN(PIN_PD31, 4, 3)
+#define PIN_PD31__PCK0 PINMUX_PIN(PIN_PD31, 5, 2)
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 034cd48..3f750f6 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -263,6 +263,24 @@
cache-level = <2>;
};
+ sdmmc0: sdio-host@a0000000 {
+ compatible = "atmel,sama5d2-sdhci";
+ reg = <0xa0000000 0x300>;
+ interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&sdmmc0_hclk>, <&sdmmc0_gclk>, <&main>;
+ clock-names = "hclock", "multclk", "baseclk";
+ status = "disabled";
+ };
+
+ sdmmc1: sdio-host@b0000000 {
+ compatible = "atmel,sama5d2-sdhci";
+ reg = <0xb0000000 0x300>;
+ interrupts = <32 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&sdmmc1_hclk>, <&sdmmc1_gclk>, <&main>;
+ clock-names = "hclock", "multclk", "baseclk";
+ status = "disabled";
+ };
+
apb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -286,7 +304,7 @@
};
pmc: pmc@f0014000 {
- compatible = "atmel,sama5d2-pmc";
+ compatible = "atmel,sama5d2-pmc", "syscon";
reg = <0xf0014000 0x160>;
interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
@@ -619,6 +637,24 @@
atmel,clk-output-range = <0 83000000>;
};
+ pdmic_clk: pdmic_clk {
+ #clock-cells = <0>;
+ reg = <48>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ i2s0_clk: i2s0_clk {
+ #clock-cells = <0>;
+ reg = <54>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ i2s1_clk: i2s1_clk {
+ #clock-cells = <0>;
+ reg = <55>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
classd_clk: classd_clk {
#clock-cells = <0>;
reg = <59>;
@@ -697,6 +733,57 @@
reg = <53>;
};
};
+
+ gck {
+ compatible = "atmel,sama5d2-clk-generated";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&pmc>;
+ clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
+
+ sdmmc0_gclk: sdmmc0_gclk {
+ #clock-cells = <0>;
+ reg = <31>;
+ };
+
+ sdmmc1_gclk: sdmmc1_gclk {
+ #clock-cells = <0>;
+ reg = <32>;
+ };
+
+ tcb0_gclk: tcb0_gclk {
+ #clock-cells = <0>;
+ reg = <35>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ tcb1_gclk: tcb1_gclk {
+ #clock-cells = <0>;
+ reg = <36>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ pwm_gclk: pwm_gclk {
+ #clock-cells = <0>;
+ reg = <38>;
+ atmel,clk-output-range = <0 83000000>;
+ };
+
+ pdmic_gclk: pdmic_gclk {
+ #clock-cells = <0>;
+ reg = <48>;
+ };
+
+ i2s0_gclk: i2s0_gclk {
+ #clock-cells = <0>;
+ reg = <54>;
+ };
+
+ i2s1_gclk: i2s1_gclk {
+ #clock-cells = <0>;
+ reg = <55>;
+ };
+ };
};
sha@f0028000 {
@@ -709,7 +796,7 @@
dma-names = "tx";
clocks = <&sha_clk>;
clock-names = "sha_clk";
- status = "disabled";
+ status = "okay";
};
aes@f002c000 {
@@ -725,7 +812,7 @@
dma-names = "tx", "rx";
clocks = <&aes_clk>;
clock-names = "aes_clk";
- status = "disabled";
+ status = "okay";
};
spi0: spi@f8000000 {
@@ -776,6 +863,19 @@
clock-names = "t0_clk", "slow_clk";
};
+ pdmic: pdmic@f8018000 {
+ compatible = "atmel,sama5d2-pdmic";
+ reg = <0xf8018000 0x124>;
+ interrupts = <48 IRQ_TYPE_LEVEL_HIGH 7>;
+ dmas = <&dma0
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+ | AT91_XDMAC_DT_PERID(50))>;
+ dma-names = "rx";
+ clocks = <&pdmic_clk>, <&pdmic_gclk>;
+ clock-names = "pclk", "gclk";
+ status = "disabled";
+ };
+
uart0: serial@f801c000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xf801c000 0x100>;
@@ -820,6 +920,32 @@
status = "disabled";
};
+ flx0: flexcom@f8034000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xf8034000 0x200>;
+ clocks = <&flx0_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xf8034000 0x800>;
+ status = "disabled";
+ };
+
+ flx1: flexcom@f8038000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xf8038000 0x200>;
+ clocks = <&flx1_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xf8038000 0x800>;
+ status = "disabled";
+ };
+
+ rstc@f8048000 {
+ compatible = "atmel,sama5d3-rstc";
+ reg = <0xf8048000 0x10>;
+ clocks = <&clk32k>;
+ };
+
pit: timer@f8048030 {
compatible = "atmel,at91sam9260-pit";
reg = <0xf8048030 0x10>;
@@ -827,6 +953,13 @@
clocks = <&h32ck>;
};
+ watchdog@f8048040 {
+ compatible = "atmel,sama5d4-wdt";
+ reg = <0xf8048040 0x10>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
sckc@f8048050 {
compatible = "atmel,at91sam9x5-sckc";
reg = <0xf8048050 0x4>;
@@ -897,6 +1030,36 @@
status = "disabled";
};
+ flx2: flexcom@fc010000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xfc010000 0x200>;
+ clocks = <&flx2_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xfc010000 0x800>;
+ status = "disabled";
+ };
+
+ flx3: flexcom@fc014000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xfc014000 0x200>;
+ clocks = <&flx3_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xfc014000 0x800>;
+ status = "disabled";
+ };
+
+ flx4: flexcom@fc018000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xfc018000 0x200>;
+ clocks = <&flx4_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xfc018000 0x800>;
+ status = "disabled";
+ };
+
aic: interrupt-controller@fc020000 {
#interrupt-cells = <3>;
compatible = "atmel,sama5d2-aic";
@@ -921,6 +1084,36 @@
clocks = <&twi1_clk>;
status = "disabled";
};
+
+ pioA: pinctrl@fc038000 {
+ compatible = "atmel,sama5d2-pinctrl";
+ reg = <0xfc038000 0x600>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 7>,
+ <68 IRQ_TYPE_LEVEL_HIGH 7>,
+ <69 IRQ_TYPE_LEVEL_HIGH 7>,
+ <70 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&pioA_clk>;
+ };
+
+ tdes@fc044000 {
+ compatible = "atmel,at91sam9g46-tdes";
+ reg = <0xfc044000 0x100>;
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
+ dmas = <&dma0
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+ AT91_XDMAC_DT_PERID(28))>,
+ <&dma0
+ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+ AT91_XDMAC_DT_PERID(29))>;
+ dma-names = "tx", "rx";
+ clocks = <&tdes_clk>;
+ clock-names = "tdes_clk";
+ status = "okay";
+ };
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 7fa2765..a532791 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -75,7 +75,7 @@
adc_op_clk: adc_op_clk{
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <20000000>;
+ clock-frequency = <1000000>;
};
};
@@ -322,6 +322,7 @@
atmel,adc-use-external-triggers;
atmel,adc-vref = <3000>;
atmel,adc-res = <10 12>;
+ atmel,adc-sample-hold-time = <11>;
atmel,adc-res-names = "lowres", "highres";
status = "disabled";
@@ -906,7 +907,7 @@
};
pmc: pmc@fffffc00 {
- compatible = "atmel,sama5d3-pmc";
+ compatible = "atmel,sama5d3-pmc", "syscon";
reg = <0xfffffc00 0x120>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/sama5d35ek.dts b/arch/arm/boot/dts/sama5d35ek.dts
index d9a9aca..e812f5c 100644
--- a/arch/arm/boot/dts/sama5d35ek.dts
+++ b/arch/arm/boot/dts/sama5d35ek.dts
@@ -49,7 +49,7 @@
label = "pb_user1";
gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
linux,code = <0x100>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi
index 026b252..e21099a 100644
--- a/arch/arm/boot/dts/sama5d3_mci2.dtsi
+++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi
@@ -24,9 +24,9 @@
};
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 */
+ <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
+ AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP /* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
+ AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>; /* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi
index 83bee7a..8901042 100644
--- a/arch/arm/boot/dts/sama5d3xmb.dtsi
+++ b/arch/arm/boot/dts/sama5d3xmb.dtsi
@@ -87,6 +87,8 @@
isi_0: endpoint {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
+ vsync-active = <1>;
+ hsync-active = <1>;
};
};
};
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 8d1de29..db1151c 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -386,7 +386,7 @@
};
pmc: pmc@f0018000 {
- compatible = "atmel,sama5d3-pmc";
+ compatible = "atmel,sama5d3-pmc", "syscon";
reg = <0xf0018000 0x120>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
interrupt-controller;
@@ -451,7 +451,7 @@
interrupt-parent = <&pmc>;
interrupts = <AT91_PMC_MCKRDY>;
clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>;
- atmel,clk-output-range = <125000000 177000000>;
+ atmel,clk-output-range = <125000000 200000000>;
atmel,clk-divisors = <1 2 4 3>;
};
@@ -916,7 +916,7 @@
};
i2c0: i2c@f8014000 {
- compatible = "atmel,at91sam9x5-i2c";
+ compatible = "atmel,sama5d4-i2c";
reg = <0xf8014000 0x4000>;
interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>;
dmas = <&dma1
@@ -935,15 +935,15 @@
};
i2c1: i2c@f8018000 {
- compatible = "atmel,at91sam9x5-i2c";
+ compatible = "atmel,sama5d4-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)>,
+ (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)>;
+ (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>;
@@ -975,7 +975,7 @@
};
i2c2: i2c@f8024000 {
- compatible = "atmel,at91sam9x5-i2c";
+ compatible = "atmel,sama5d4-i2c";
reg = <0xf8024000 0x4000>;
interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>;
dmas = <&dma1
@@ -1189,6 +1189,19 @@
clock-names = "t0_clk", "slow_clk";
};
+ macb1: ethernet@fc028000 {
+ compatible = "atmel,sama5d4-gem";
+ reg = <0xfc028000 0x100>;
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb1_rmii>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&macb1_clk>, <&macb1_clk>;
+ clock-names = "hclk", "pclk";
+ status = "disabled";
+ };
+
adc0: adc@fc034000 {
compatible = "atmel,at91sam9x5-adc";
reg = <0xfc034000 0x100>;
@@ -1238,7 +1251,7 @@
dma-names = "tx", "rx";
clocks = <&aes_clk>;
clock-names = "aes_clk";
- status = "disabled";
+ status = "okay";
};
tdes@fc04c000 {
@@ -1252,7 +1265,7 @@
dma-names = "tx", "rx";
clocks = <&tdes_clk>;
clock-names = "tdes_clk";
- status = "disabled";
+ status = "okay";
};
sha@fc050000 {
@@ -1264,7 +1277,7 @@
dma-names = "tx";
clocks = <&sha_clk>;
clock-names = "sha_clk";
- status = "disabled";
+ status = "okay";
};
rstc@fc068600 {
@@ -1287,7 +1300,7 @@
};
watchdog@fc068640 {
- compatible = "atmel,at91sam9260-wdt";
+ compatible = "atmel,sama5d4-wdt";
reg = <0xfc068640 0x10>;
clocks = <&clk32k>;
status = "disabled";
@@ -1329,7 +1342,7 @@
dbgu: serial@fc069000 {
compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
reg = <0xfc069000 0x200>;
- interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
+ interrupts = <45 IRQ_TYPE_LEVEL_HIGH 7>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dbgu>;
clocks = <&dbgu_clk>;
@@ -1350,7 +1363,7 @@
0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */
0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */
0xffffffff 0x3ff83fff 0xff00ffff /* pioC */
- 0x00000000 0x00000000 0x00000000 /* pioD */
+ 0x0003ff00 0x8002a800 0x00000000 /* pioD */
0xffffffff 0x7fffffff 0x76fff1bf /* pioE */
>;
@@ -1396,7 +1409,6 @@
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&pioD_clk>;
- status = "disabled";
};
pioE: gpio@fc06d000 {
@@ -1636,19 +1648,44 @@
};
};
+ macb1 {
+ pinctrl_macb1_rmii: macb1_rmii-0 {
+ atmel,pins =
+ <AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_TX0 */
+ AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_TX1 */
+ AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_RX0 */
+ AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_RX1 */
+ AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_RXDV */
+ AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_RXER */
+ AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_TXEN */
+ AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_TXCK */
+ AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_MDC */
+ AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE /* G1_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 */
+ AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_CDA, conflict with NAND_D0 */
+ AT91_PIOC 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA0, 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 */
+ <AT91_PIOC 7 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA1, conflict with NAND_D2 */
+ AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA2, conflict with NAND_D3 */
+ AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA3, conflict with NAND_D4 */
+ >;
+ };
+ pinctrl_mmc0_dat4_7: mmc0_dat4_7 {
+ atmel,pins =
+ <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA4, conflict with NAND_D5 */
+ AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA5, conflict with NAND_D6 */
+ AT91_PIOC 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA6, conflict with NAND_D7 */
+ AT91_PIOC 13 AT91_PERIPH_B AT91_PINCTRL_PULL_UP /* MCI0_DA7, conflict with NAND_OE */
>;
};
};
diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts
index 24b4cd2..aa8bae3 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts
@@ -147,7 +147,7 @@
gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>;
linux,code = <KEY_HOME>;
label = "SW1";
- gpio-key,wakeup;
+ wakeup-source;
};
};
@@ -206,7 +206,7 @@
};
accelerometer@1d {
- compatible = "adi,adxl34x";
+ compatible = "adi,adxl345";
reg = <0x1d>;
interrupt-parent = <&irqpin3>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index ff7c8f2..3a6056f 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -28,6 +28,7 @@
reg = <0>;
clock-frequency = <1196000000>;
power-domains = <&pd_a2sl>;
+ next-level-cache = <&L2>;
};
cpu@1 {
device_type = "cpu";
@@ -35,6 +36,7 @@
reg = <1>;
clock-frequency = <1196000000>;
power-domains = <&pd_a2sl>;
+ next-level-cache = <&L2>;
};
};
@@ -53,6 +55,18 @@
<0xf0000100 0x100>;
};
+ L2: cache-controller {
+ compatible = "arm,pl310-cache";
+ reg = <0xf0100000 0x1000>;
+ interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_a3sm>;
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ arm,shared-override;
+ cache-unified;
+ cache-level = <2>;
+ };
+
sbsc2: memory-controller@fb400000 {
compatible = "renesas,sbsc-sh73a0";
reg = <0xfb400000 0x400>;
@@ -259,6 +273,50 @@
status = "disabled";
};
+ msiof0: spi@e6e20000 {
+ compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+ reg = <0xe6e20000 0x0064>;
+ interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks SH73A0_CLK_MSIOF0>;
+ power-domains = <&pd_a3sp>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof1: spi@e6e10000 {
+ compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+ reg = <0xe6e10000 0x0064>;
+ interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_MSIOF1>;
+ power-domains = <&pd_a3sp>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof2: spi@e6e00000 {
+ compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+ reg = <0xe6e00000 0x0064>;
+ interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_MSIOF2>;
+ power-domains = <&pd_a3sp>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ msiof3: spi@e6c90000 {
+ compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof";
+ reg = <0xe6c90000 0x0064>;
+ interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_MSIOF3>;
+ power-domains = <&pd_a3sp>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
sdhi0: sd@ee100000 {
compatible = "renesas,sdhi-sh73a0";
reg = <0xee100000 0x100>;
@@ -798,13 +856,13 @@
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>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>;
#clock-cells = <1>;
clock-indices = <
- SH73A0_CLK_IIC2
+ SH73A0_CLK_IIC2 SH73A0_CLK_MSIOF0
>;
clock-output-names =
- "iic2";
+ "iic2", "msiof0";
};
mstp1_clks: mstp1_clks@e6150134 {
compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -834,20 +892,24 @@
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>;
+ <&sub_clk>, <&sub_clk>, <&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
+ SH73A0_CLK_MP_DMAC SH73A0_CLK_MSIOF3
+ SH73A0_CLK_MSIOF1 SH73A0_CLK_SCIFA5
+ SH73A0_CLK_SCIFB SH73A0_CLK_MSIOF2
+ 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";
+ "scifa7", "sy_dmac", "mp_dmac", "msiof3",
+ "msiof1", "scifa5", "scifb", "msiof2",
+ "scifa0", "scifa1", "scifa2", "scifa3",
+ "scifa4";
};
mstp3_clks: mstp3_clks@e615013c {
compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 314e589..15cbc74 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -513,6 +513,13 @@
};
};
+ fpgamgr0: fpgamgr@ff706000 {
+ compatible = "altr,socfpga-fpga-mgr";
+ reg = <0xff706000 0x1000
+ 0xffb90000 0x1000>;
+ interrupts = <0 175 4>;
+ };
+
gmac0: ethernet@ff700000 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
altr,sysmgr-syscon = <&sysmgr 0x60 0>;
@@ -549,46 +556,6 @@
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>;
@@ -649,15 +616,64 @@
};
};
- sdr: sdr@ffc25000 {
- compatible = "syscon";
- reg = <0xffc25000 0x1000>;
+ 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";
};
- sdramedac {
- compatible = "altr,sdram-edac";
- altr,sdr-syscon = <&sdr>;
- interrupts = <0 39 4>;
+ 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";
+ };
+
+ eccmgr: eccmgr@ffd08140 {
+ compatible = "altr,socfpga-ecc-manager";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ l2-ecc@ffd08140 {
+ compatible = "altr,socfpga-l2-ecc";
+ reg = <0xffd08140 0x4>;
+ interrupts = <0 36 1>, <0 37 1>;
+ };
+
+ ocram-ecc@ffd08144 {
+ compatible = "altr,socfpga-ocram-ecc";
+ reg = <0xffd08144 0x4>;
+ iram = <&ocram>;
+ interrupts = <0 178 1>, <0 179 1>;
+ };
};
L2: l2-cache@fffef000 {
@@ -681,6 +697,7 @@
#size-cells = <0>;
clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>;
clock-names = "biu", "ciu";
+ status = "disabled";
};
ocram: sram@ffff0000 {
@@ -688,6 +705,29 @@
reg = <0xffff0000 0x10000>;
};
+ rst: rstmgr@ffd05000 {
+ #reset-cells = <1>;
+ compatible = "altr,rst-mgr";
+ reg = <0xffd05000 0x1000>;
+ altr,modrst-offset = <0x10>;
+ };
+
+ scu: snoop-control-unit@fffec000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0xfffec000 0x100>;
+ };
+
+ sdr: sdr@ffc25000 {
+ compatible = "syscon";
+ reg = <0xffc25000 0x1000>;
+ };
+
+ sdramedac {
+ compatible = "altr,sdram-edac";
+ altr,sdr-syscon = <&sdr>;
+ interrupts = <0 39 4>;
+ };
+
spi0: spi@fff00000 {
compatible = "snps,dw-apb-ssi";
#address-cells = <1>;
@@ -699,11 +739,6 @@
status = "disabled";
};
- scu: snoop-control-unit@fffec000 {
- compatible = "arm,cortex-a9-scu";
- reg = <0xfffec000 0x100>;
- };
-
spi1: spi@fff01000 {
compatible = "snps,dw-apb-ssi";
#address-cells = <1>;
@@ -715,6 +750,11 @@
status = "disabled";
};
+ sysmgr: sysmgr@ffd08000 {
+ compatible = "altr,sys-mgr", "syscon";
+ reg = <0xffd08000 0x4000>;
+ };
+
/* Local timer */
timer@fffec600 {
compatible = "arm,cortex-a9-twd-timer";
@@ -779,13 +819,6 @@
dma-names = "tx", "rx";
};
- rst: rstmgr@ffd05000 {
- #reset-cells = <1>;
- compatible = "altr,rst-mgr";
- reg = <0xffd05000 0x1000>;
- altr,modrst-offset = <0x10>;
- };
-
usbphy0: usbphy@0 {
#phy-cells = <0>;
compatible = "usb-nop-xceiv";
@@ -829,10 +862,5 @@
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
index 2340fcb..cce9e50 100644
--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
@@ -519,6 +519,7 @@
compatible = "snps,designware-i2c";
reg = <0xffc02200 0x100>;
interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -528,6 +529,7 @@
compatible = "snps,designware-i2c";
reg = <0xffc02300 0x100>;
interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -537,6 +539,7 @@
compatible = "snps,designware-i2c";
reg = <0xffc02400 0x100>;
interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -546,6 +549,7 @@
compatible = "snps,designware-i2c";
reg = <0xffc02500 0x100>;
interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -555,6 +559,7 @@
compatible = "snps,designware-i2c";
reg = <0xffc02600 0x100>;
interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -658,6 +663,7 @@
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
+ clocks = <&l4_sp_clk>;
status = "disabled";
};
@@ -692,6 +698,8 @@
compatible = "snps,dwc2";
reg = <0xffb40000 0xffff>;
interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&usb_clk>;
+ clock-names = "otg";
phys = <&usbphy0>;
phy-names = "usb2-phy";
status = "disabled";
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
index 99aa9a1..567df98 100644
--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
@@ -70,6 +70,33 @@
status = "okay";
};
+&i2c1 {
+ speed-mode = <0>;
+ status = "okay";
+
+ /*
+ * adjust the falling times to decrease the i2c frequency to 50Khz
+ * because the LCD module does not work at the standard 100Khz
+ */
+ i2c-sda-falling-time-ns = <6000>;
+ i2c-scl-falling-time-ns = <6000>;
+
+ eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+};
+
&uart1 {
status = "okay";
};
+
+&usb0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
index a75a666..3c88678 100644
--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
@@ -79,6 +79,7 @@
&mmc0 {
vmmc-supply = <&regulator_3_3v>;
vqmmc-supply = <&regulator_3_3v>;
+ status = "okay";
};
&usb1 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
index 555e9ca..afea364 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
@@ -100,6 +100,7 @@
&mmc0 {
vmmc-supply = <&regulator_3_3v>;
vqmmc-supply = <&regulator_3_3v>;
+ status = "okay";
};
&uart0 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
new file mode 100644
index 0000000..f86f9c0
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 = "DENX MCV";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1 GiB */
+ };
+};
+
+&mmc0 { /* On-SoM eMMC */
+ bus-width = <8>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
new file mode 100644
index 0000000..7186a29
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 Marek Vasut <marex@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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_mcv.dtsi"
+
+/ {
+ model = "DENX MCV EVK";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+ aliases {
+ ethernet0 = &gmac0;
+ stmpe-i2c0 = &stmpe1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&can0 {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&gmac0 {
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&gpio0 { /* GPIO 0 ... 28 */
+ status = "okay";
+};
+
+&gpio1 { /* GPIO 29 ... 57 */
+ status = "okay";
+};
+
+&gpio2 { /* GPIO 58..66 (HLGPI 0..13 at offset 13) */
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ speed-mode = <0>;
+
+ stmpe1: stmpe811@41 {
+ compatible = "st,stmpe811";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x41>;
+ id = <0>;
+ blocks = <0x5>;
+ irq-gpio = <&portb 28 0x4>; /* GPIO 57, trig. level HI */
+
+ stmpe_touchscreen {
+ compatible = "st,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>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
index d4d0a28..15e43f4 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
@@ -84,6 +84,7 @@
cd-gpios = <&portb 18 0>;
vmmc-supply = <&regulator_3_3v>;
vqmmc-supply = <&regulator_3_3v>;
+ status = "okay";
};
&usb1 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
index 48bf651..b61f22f 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
@@ -80,6 +80,7 @@
&mmc0 {
vmmc-supply = <&regulator_3_3v>;
vqmmc-supply = <&regulator_3_3v>;
+ status = "okay";
};
&usb1 {
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index 50f5e9d..341f5b7 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -512,63 +512,51 @@
// 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
@@ -577,39 +565,32 @@
// 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";
};
};
@@ -721,7 +702,6 @@
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;
@@ -729,7 +709,6 @@
};
ab8500_ext2_reg: ab8500_ext2 {
- regulator-compatible = "ab8500_ext2";
regulator-min-microvolt = <1360000>;
regulator-max-microvolt = <1360000>;
regulator-boot-on;
@@ -737,7 +716,6 @@
};
ab8500_ext3_reg: ab8500_ext3 {
- regulator-compatible = "ab8500_ext3";
regulator-min-microvolt = <3400000>;
regulator-max-microvolt = <3400000>;
regulator-boot-on;
@@ -750,7 +728,6 @@
// 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;
@@ -760,56 +737,46 @@
// 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";
};
};
};
diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi
index 78b7525..c3987ad 100644
--- a/arch/arm/boot/dts/ste-href-stuib.dtsi
+++ b/arch/arm/boot/dts/ste-href-stuib.dtsi
@@ -114,6 +114,8 @@
rohm,touch-max-x = <384>;
rohm,touch-max-y = <704>;
rohm,flip-y;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_rohm_mode>;
};
bu21013_tp@5d {
@@ -124,6 +126,8 @@
rohm,touch-max-x = <384>;
rohm,touch-max-y = <704>;
rohm,flip-y;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_rohm_mode>;
};
};
@@ -166,6 +170,25 @@
};
};
};
+ touch {
+ touch_rohm_mode: touch_rohm {
+ /*
+ * ROHM 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.
+ */
+ stuib_cfg1 {
+ pins = "GPIO143_D12", "GPIO146_D13";
+ ste,config = <&gpio_out_lo>;
+ };
+ stuib_cfg2 {
+ pins = "GPIO67_G2";
+ 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
index 0e1c969..b7b4211 100644
--- a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi
+++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi
@@ -66,7 +66,7 @@
keypad,num-columns = <8>;
keypad,num-rows = <8>;
linux,no-autorepeat;
- linux,wakeup;
+ wakeup-source;
linux,keymap = <0x0301006b
0x04010066
0x06040072
@@ -104,13 +104,40 @@
<19 IRQ_TYPE_EDGE_RISING>;
};
lsm303dlh@1e {
- /* Magnetometer */
+ /*
+ * This magnetometer is packaged with
+ * the accelerometer, and has a DRDY line,
+ * however it is not connected on this
+ * board so it can not generate interrupts.
+ */
compatible = "st,lsm303dlh-magn";
reg = <0x1e>;
vdd-supply = <&ab8500_ldo_aux1_reg>;
vddio-supply = <&db8500_vsmps2_reg>;
+ };
+ lis331dl@1c {
+ /* Accelerometer */
+ compatible = "st,lis331dl-accel";
+ st,drdy-int-pin = <1>;
+ reg = <0x1c>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&accel_tvk_mode>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <18 IRQ_TYPE_EDGE_RISING>,
+ <19 IRQ_TYPE_EDGE_RISING>;
+ };
+ ak8974@0f {
+ /* Magnetometer */
+ compatible = "asahi-kasei,ak8974";
+ reg = <0x0f>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>;
+ vddio-supply = <&db8500_vsmps2_reg>;
pinctrl-names = "default";
- pinctrl-0 = <&magneto_tvk_mode>;
+ pinctrl-0 = <&gyro_magn_tvk_mode>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
};
l3g4200d@68 {
/* Gyroscope */
@@ -119,6 +146,10 @@
reg = <0x68>;
vdd-supply = <&ab8500_ldo_aux1_reg>;
vddio-supply = <&db8500_vsmps2_reg>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gyro_magn_tvk_mode>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
};
lsp001wm@5c {
/* Barometer/pressure sensor */
@@ -159,17 +190,22 @@
/* Accelerometer interrupt lines 1 & 2 */
tvk_cfg {
pins = "GPIO82_C1", "GPIO83_D3";
- ste,config = <&gpio_in_pu>;
+ ste,config = <&gpio_in_pd>;
};
};
};
- magnetometer {
- magneto_tvk_mode: magneto_tvk {
- /* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */
+ gyroscope {
+ /*
+ * These lines are shared between Gyroscope l3g400dh
+ * and AK8974 magnetometer.
+ */
+ gyro_magn_tvk_mode: gyro_magn_tvk {
+ /* GPIO 31 used for INT pull down the line */
tvk_cfg1 {
pins = "GPIO31_V3";
- ste,config = <&gpio_in_pu>;
+ ste,config = <&gpio_in_pd>;
};
+ /* GPIO 32 used for DRDY, pull this down */
tvk_cfg2 {
pins = "GPIO32_V2";
ste,config = <&gpio_in_pd>;
diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi
index 9c2387b..149a72e 100644
--- a/arch/arm/boot/dts/ste-hrefv60plus.dtsi
+++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi
@@ -43,7 +43,6 @@
<&vaudio_hf_hrefv60_mode>,
<&gbf_hrefv60_mode>,
<&hdtv_hrefv60_mode>,
- <&touch_hrefv60_mode>,
<&gpios_hrefv60_mode>;
sdi0 {
@@ -190,23 +189,6 @@
};
};
};
- 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 {
/*
diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts
index 35282c0..7893290 100644
--- a/arch/arm/boot/dts/ste-nomadik-s8815.dts
+++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts
@@ -163,7 +163,7 @@
label = "user_button";
gpios = <&gpio0 3 0x1>;
linux,code = <1>; /* KEY_ESC */
- gpio-key,wakeup;
+ wakeup-source;
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
index 314f59c..27a333e 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -25,9 +25,9 @@
cache-sets = <512>;
cache-line-size = <32>;
/* At full speed latency must be >=2 */
- arm,tag-latency = <2>;
- arm,data-latency = <2 2>;
- arm,dirty-latency = <2>;
+ arm,tag-latency = <8>;
+ arm,data-latency = <8 8>;
+ arm,dirty-latency = <8>;
};
mtu0: mtu@101e2000 {
@@ -127,22 +127,14 @@
};
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>;
+ /*
+ * MCCLK, MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2
+ * MCCMD, MCDAT3-0, MCMSFBCLK
+ */
+ pins = "GPIO8_B10", "GPIO9_A10", "GPIO10_C11", "GPIO11_B11",
+ "GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO15_A12",
+ "GPIO16_C13", "GPIO23_D15", "GPIO24_C15";
+ ste,output = <2>;
};
};
};
@@ -802,10 +794,21 @@
clock-names = "mclk", "apb_pclk";
interrupt-parent = <&vica>;
interrupts = <22>;
- max-frequency = <48000000>;
+ max-frequency = <400000>;
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ full-pwr-cycle;
+ /*
+ * The STw4811 circuit used with the Nomadik strictly
+ * requires that all of these signal direction pins be
+ * routed and used for its 4-bit levelshifter.
+ */
+ st,sig-dir-dat0;
+ st,sig-dir-dat2;
+ st,sig-dir-dat31;
+ st,sig-dir-cmd;
+ st,sig-pin-fbclk;
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
index e80e421..08f8207 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -281,7 +281,8 @@
vddio-supply = <&db8500_vsmps2_reg>;
pinctrl-names = "default";
pinctrl-0 = <&magneto_snowball_mode>;
- gpios = <&gpio5 5 0x4>; /* DRDY line */
+ interrupt-parent = <&gpio5>;
+ interrupts = <5 IRQ_TYPE_EDGE_RISING>; /* DRDY line */
};
l3g4200d@68 {
/* Gyroscope */
@@ -292,9 +293,9 @@
vddio-supply = <&db8500_vsmps2_reg>;
pinctrl-names = "default";
pinctrl-0 = <&gyro_snowball_mode>;
- gpios = <&gpio5 6 0x4>; /* DRDY line */
interrupt-parent = <&gpio5>;
- interrupts = <9 IRQ_TYPE_EDGE_RISING>; /* INT1 */
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>, /* DRDY line */
+ <9 IRQ_TYPE_EDGE_RISING>; /* INT1 */
};
lsp001wm@5c {
/* Barometer/pressure sensor */
diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts
index 82a6616..9c73ac2 100644
--- a/arch/arm/boot/dts/ste-u300.dts
+++ b/arch/arm/boot/dts/ste-u300.dts
@@ -315,21 +315,17 @@
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>;
@@ -337,7 +333,6 @@
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>;
@@ -345,28 +340,23 @@
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>;
diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
index 6d93475..c8ad905 100644
--- a/arch/arm/boot/dts/stih407-b2120.dts
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -25,6 +25,7 @@
aliases {
ttyAS0 = &sbc_serial0;
+ ethernet0 = &ethernet0;
};
};
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index ae05277..81f8121 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -152,6 +152,19 @@
<ST_IRQ_SYSCFG_DISABLED>;
};
+ /* 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>;
+ };
+
serial@9830000 {
compatible = "st,asc";
reg = <0x9830000 0x2c>;
@@ -396,6 +409,8 @@
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1_default>;
status = "disabled";
};
@@ -406,6 +421,8 @@
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default>;
status = "disabled";
};
@@ -416,6 +433,8 @@
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi3_default>;
status = "disabled";
};
@@ -426,6 +445,8 @@
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi4_default>;
status = "disabled";
};
@@ -437,6 +458,8 @@
interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_sysin>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi10_default>;
status = "disabled";
};
@@ -447,6 +470,8 @@
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_sysin>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi11_default>;
status = "disabled";
};
@@ -457,6 +482,8 @@
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_sysin>;
clock-names = "ssc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi12_default>;
status = "disabled";
};
@@ -585,7 +612,6 @@
/* COMMS PWM Module */
pwm0: pwm@9810000 {
compatible = "st,sti-pwm";
- status = "okay";
#pwm-cells = <2>;
reg = <0x9810000 0x68>;
pinctrl-names = "default";
@@ -593,12 +619,13 @@
clock-names = "pwm";
clocks = <&clk_sysin>;
st,pwm-num-chan = <1>;
+
+ status = "disabled";
};
/* SBC PWM Module */
pwm1: pwm@9510000 {
compatible = "st,sti-pwm";
- status = "okay";
#pwm-cells = <2>;
reg = <0x9510000 0x68>;
pinctrl-names = "default";
@@ -609,6 +636,63 @@
clock-names = "pwm";
clocks = <&clk_sysin>;
st,pwm-num-chan = <4>;
+
+ status = "disabled";
+ };
+
+ rng10: rng@08a89000 {
+ compatible = "st,rng";
+ reg = <0x08a89000 0x1000>;
+ clocks = <&clk_sysin>;
+ status = "okay";
+ };
+
+ rng11: rng@08a8a000 {
+ compatible = "st,rng";
+ reg = <0x08a8a000 0x1000>;
+ clocks = <&clk_sysin>;
+ status = "okay";
+ };
+
+ ethernet0: dwmac@9630000 {
+ device_type = "network";
+ status = "disabled";
+ compatible = "st,stih407-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+ reg = <0x9630000 0x8000>, <0x80 0x4>;
+ reg-names = "stmmaceth", "sti-ethconf";
+
+ st,syscon = <&syscfg_sbc_reg 0x80>;
+ st,gmac_en;
+ resets = <&softreset STIH407_ETH1_SOFTRESET>;
+ reset-names = "stmmaceth";
+
+ interrupts = <GIC_SPI 98 IRQ_TYPE_NONE>,
+ <GIC_SPI 99 IRQ_TYPE_NONE>;
+ interrupt-names = "macirq", "eth_wake_irq";
+
+ /* DMA Bus Mode */
+ snps,pbl = <8>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1>;
+
+ clock-names = "stmmaceth", "sti-ethclk";
+ clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>,
+ <&clk_s_c0_flexgen CLK_ETH_PHY>;
+ };
+
+ rng10: rng@08a89000 {
+ compatible = "st,rng";
+ reg = <0x08a89000 0x1000>;
+ clocks = <&clk_sysin>;
+ status = "okay";
+ };
+
+ rng11: rng@08a8a000 {
+ compatible = "st,rng";
+ reg = <0x08a8a000 0x1000>;
+ clocks = <&clk_sysin>;
+ status = "okay";
};
};
};
diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi
index 1683deb..a538ae5 100644
--- a/arch/arm/boot/dts/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi
@@ -53,7 +53,7 @@
reg = <0x0961f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 188 IRQ_TYPE_NONE>;
- interrupts-names = "irqmux";
+ interrupt-names = "irqmux";
ranges = <0 0x09610000 0x6000>;
pio0: gpio@09610000 {
@@ -107,12 +107,38 @@
st,retime-pin-mask = <0x3f>;
};
+ cec0 {
+ pinctrl_cec0_default: cec0-default {
+ st,pins {
+ hdmi_cec = <&pio2 4 ALT1 BIDIR>;
+ };
+ };
+ };
+
rc {
pinctrl_ir: ir0 {
st,pins {
ir = <&pio4 0 ALT2 IN>;
};
};
+
+ pinctrl_uhf: uhf0 {
+ st,pins {
+ ir = <&pio4 1 ALT2 IN>;
+ };
+ };
+
+ pinctrl_tx: tx0 {
+ st,pins {
+ tx = <&pio4 2 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_tx_od: tx_od0 {
+ st,pins {
+ tx_od = <&pio4 3 ALT2 OUT>;
+ };
+ };
};
/* SBC_ASC0 - UART10 */
@@ -190,9 +216,9 @@
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>;
+ rxclk = <&pio2 2 ALT1 IN NICLK 0 CLK_A>;
clk125 = <&pio3 7 ALT4 IN NICLK 0 CLK_A>;
- phyclk = <&pio2 3 ALT4 OUT NICLK 1750 CLK_B>;
+ phyclk = <&pio2 3 ALT4 OUT NICLK 1250 CLK_B>;
};
};
@@ -230,6 +256,33 @@
phyclk = <&pio2 3 ALT1 OUT NICLK 0 CLK_A>;
};
};
+
+ pinctrl_rmii1: rmii1-0 {
+ st,pins {
+ txd0 = <&pio0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txd1 = <&pio0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ txen = <&pio0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+ mdio = <&pio1 0 ALT1 OUT BYPASS 0>;
+ mdc = <&pio1 1 ALT1 OUT NICLK 0 CLK_A>;
+ mdint = <&pio1 3 ALT1 IN BYPASS 0>;
+ rxd0 = <&pio1 4 ALT1 IN SE_NICLK_IO 0 CLK_B>;
+ rxd1 = <&pio1 5 ALT1 IN SE_NICLK_IO 0 CLK_B>;
+ rxdv = <&pio2 0 ALT1 IN SE_NICLK_IO 0 CLK_B>;
+ rx_er = <&pio2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+ };
+ };
+
+ pinctrl_rmii1_phyclk: rmii1_phyclk {
+ st,pins {
+ phyclk = <&pio2 3 ALT1 OUT NICLK 0 CLK_A>;
+ };
+ };
+
+ pinctrl_rmii1_phyclk_ext: rmii1_phyclk_ext {
+ st,pins {
+ phyclk = <&pio2 3 ALT2 IN NICLK 0 CLK_A>;
+ };
+ };
};
pwm1 {
@@ -254,6 +307,57 @@
};
};
};
+
+ spi10 {
+ pinctrl_spi10_default: spi10-4w-alt1-0 {
+ st,pins {
+ mtsr = <&pio4 6 ALT1 OUT>;
+ mrst = <&pio4 7 ALT1 IN>;
+ scl = <&pio4 5 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi10_3w_alt1_0: spi10-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio4 6 ALT1 BIDIR_PU>;
+ scl = <&pio4 5 ALT1 OUT>;
+ };
+ };
+ };
+
+ spi11 {
+ pinctrl_spi11_default: spi11-4w-alt2-0 {
+ st,pins {
+ mtsr = <&pio3 1 ALT2 OUT>;
+ mrst = <&pio3 0 ALT2 IN>;
+ scl = <&pio3 2 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi11_3w_alt2_0: spi11-3w-alt2-0 {
+ st,pins {
+ mtsr = <&pio3 1 ALT2 BIDIR_PU>;
+ scl = <&pio3 2 ALT2 OUT>;
+ };
+ };
+ };
+
+ spi12 {
+ pinctrl_spi12_default: spi12-4w-alt2-0 {
+ st,pins {
+ mtsr = <&pio3 6 ALT2 OUT>;
+ mrst = <&pio3 4 ALT2 IN>;
+ scl = <&pio3 7 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi12_3w_alt2_0: spi12-3w-alt2-0 {
+ st,pins {
+ mtsr = <&pio3 6 ALT2 BIDIR_PU>;
+ scl = <&pio3 7 ALT2 OUT>;
+ };
+ };
+ };
};
pin-controller-front0 {
@@ -264,7 +368,7 @@
reg = <0x0920f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 189 IRQ_TYPE_NONE>;
- interrupts-names = "irqmux";
+ interrupt-names = "irqmux";
ranges = <0 0x09200000 0x10000>;
pio10: pio@09200000 {
@@ -422,20 +526,180 @@
};
i2c3 {
- pinctrl_i2c3_default: i2c3-default {
+ pinctrl_i2c3_default: i2c3-alt1-0 {
st,pins {
sda = <&pio18 6 ALT1 BIDIR>;
scl = <&pio18 5 ALT1 BIDIR>;
};
};
+ pinctrl_i2c3_alt1_1: i2c3-alt1-1 {
+ st,pins {
+ sda = <&pio17 7 ALT1 BIDIR>;
+ scl = <&pio17 6 ALT1 BIDIR>;
+ };
+ };
+ pinctrl_i2c3_alt3_0: i2c3-alt3-0 {
+ st,pins {
+ sda = <&pio13 6 ALT3 BIDIR>;
+ scl = <&pio13 5 ALT3 BIDIR>;
+ };
+ };
};
spi0 {
- pinctrl_spi0_default: spi0-default {
+ pinctrl_spi0_default: spi0-4w-alt2-0 {
+ st,pins {
+ mtsr = <&pio10 6 ALT2 OUT>;
+ mrst = <&pio10 7 ALT2 IN>;
+ scl = <&pio10 5 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi0_3w_alt2_0: spi0-3w-alt2-0 {
+ st,pins {
+ mtsr = <&pio10 6 ALT2 BIDIR_PU>;
+ scl = <&pio10 5 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi0_4w_alt1_0: spi0-4w-alt1-0 {
+ st,pins {
+ mtsr = <&pio19 7 ALT1 OUT>;
+ mrst = <&pio19 5 ALT1 IN>;
+ scl = <&pio19 6 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi0_3w_alt1_0: spi0-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio19 7 ALT1 BIDIR_PU>;
+ scl = <&pio19 6 ALT1 OUT>;
+ };
+ };
+ };
+
+ spi1 {
+ pinctrl_spi1_default: spi1-4w-alt2-0 {
+ st,pins {
+ mtsr = <&pio11 1 ALT2 OUT>;
+ mrst = <&pio11 2 ALT2 IN>;
+ scl = <&pio11 0 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi1_3w_alt2_0: spi1-3w-alt2-0 {
+ st,pins {
+ mtsr = <&pio11 1 ALT2 BIDIR_PU>;
+ scl = <&pio11 0 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi1_4w_alt1_0: spi1-4w-alt1-0 {
st,pins {
- mtsr = <&pio12 6 ALT2 BIDIR>;
- mrst = <&pio12 7 ALT2 BIDIR>;
- scl = <&pio12 5 ALT2 BIDIR>;
+ mtsr = <&pio14 3 ALT1 OUT>;
+ mrst = <&pio14 4 ALT1 IN>;
+ scl = <&pio14 2 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi1_3w_alt1_0: spi1-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio14 3 ALT1 BIDIR_PU>;
+ scl = <&pio14 2 ALT1 OUT>;
+ };
+ };
+ };
+
+ spi2 {
+ pinctrl_spi2_default: spi2-4w-alt2-0 {
+ st,pins {
+ mtsr = <&pio12 6 ALT2 OUT>;
+ mrst = <&pio12 7 ALT2 IN>;
+ scl = <&pio12 5 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi2_3w_alt2_0: spi2-3w-alt2-0 {
+ st,pins {
+ mtsr = <&pio12 6 ALT2 BIDIR_PU>;
+ scl = <&pio12 5 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi2_4w_alt1_0: spi2-4w-alt1-0 {
+ st,pins {
+ mtsr = <&pio14 6 ALT1 OUT>;
+ mrst = <&pio14 7 ALT1 IN>;
+ scl = <&pio14 5 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi2_3w_alt1_0: spi2-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio14 6 ALT1 BIDIR_PU>;
+ scl = <&pio14 5 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi2_4w_alt2_1: spi2-4w-alt2-1 {
+ st,pins {
+ mtsr = <&pio15 6 ALT2 OUT>;
+ mrst = <&pio15 7 ALT2 IN>;
+ scl = <&pio15 5 ALT2 OUT>;
+ };
+ };
+
+ pinctrl_spi2_3w_alt2_1: spi2-3w-alt2-1 {
+ st,pins {
+ mtsr = <&pio15 6 ALT2 BIDIR_PU>;
+ scl = <&pio15 5 ALT2 OUT>;
+ };
+ };
+ };
+
+ spi3 {
+ pinctrl_spi3_default: spi3-4w-alt3-0 {
+ st,pins {
+ mtsr = <&pio13 6 ALT3 OUT>;
+ mrst = <&pio13 7 ALT3 IN>;
+ scl = <&pio13 5 ALT3 OUT>;
+ };
+ };
+
+ pinctrl_spi3_3w_alt3_0: spi3-3w-alt3-0 {
+ st,pins {
+ mtsr = <&pio13 6 ALT3 BIDIR_PU>;
+ scl = <&pio13 5 ALT3 OUT>;
+ };
+ };
+
+ pinctrl_spi3_4w_alt1_0: spi3-4w-alt1-0 {
+ st,pins {
+ mtsr = <&pio17 7 ALT1 OUT>;
+ mrst = <&pio17 5 ALT1 IN>;
+ scl = <&pio17 6 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi3_3w_alt1_0: spi3-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio17 7 ALT1 BIDIR_PU>;
+ scl = <&pio17 6 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi3_4w_alt1_1: spi3-4w-alt1-1 {
+ st,pins {
+ mtsr = <&pio18 6 ALT1 OUT>;
+ mrst = <&pio18 7 ALT1 IN>;
+ scl = <&pio18 5 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi3_3w_alt1_1: spi3-3w-alt1-1 {
+ st,pins {
+ mtsr = <&pio18 6 ALT1 BIDIR_PU>;
+ scl = <&pio18 5 ALT1 OUT>;
};
};
};
@@ -627,6 +891,18 @@
};
};
};
+
+ systrace {
+ pinctrl_systrace_default: systrace-default {
+ st,pins {
+ trc_data0 = <&pio11 3 ALT5 OUT>;
+ trc_data1 = <&pio11 4 ALT5 OUT>;
+ trc_data2 = <&pio11 5 ALT5 OUT>;
+ trc_data3 = <&pio11 6 ALT5 OUT>;
+ trc_clk = <&pio11 7 ALT5 OUT>;
+ };
+ };
+ };
};
pin-controller-front1 {
@@ -637,7 +913,7 @@
reg = <0x0921f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 190 IRQ_TYPE_NONE>;
- interrupts-names = "irqmux";
+ interrupt-names = "irqmux";
ranges = <0 0x09210000 0x10000>;
tsin4 {
@@ -670,7 +946,7 @@
reg = <0x0922f080 0x4>;
reg-names = "irqmux";
interrupts = <GIC_SPI 191 IRQ_TYPE_NONE>;
- interrupts-names = "irqmux";
+ interrupt-names = "irqmux";
ranges = <0 0x09220000 0x6000>;
pio30: gpio@09220000 {
@@ -758,6 +1034,47 @@
};
};
};
+
+ spi4 {
+ pinctrl_spi4_default: spi4-4w-alt1-0 {
+ st,pins {
+ mtsr = <&pio30 1 ALT1 OUT>;
+ mrst = <&pio30 2 ALT1 IN>;
+ scl = <&pio30 0 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi4_3w_alt1_0: spi4-3w-alt1-0 {
+ st,pins {
+ mtsr = <&pio30 1 ALT1 BIDIR_PU>;
+ scl = <&pio30 0 ALT1 OUT>;
+ };
+ };
+
+ pinctrl_spi4_4w_alt3_0: spi4-4w-alt3-0 {
+ st,pins {
+ mtsr = <&pio34 1 ALT3 OUT>;
+ mrst = <&pio34 2 ALT3 IN>;
+ scl = <&pio34 0 ALT3 OUT>;
+ };
+ };
+
+ pinctrl_spi4_3w_alt3_0: spi4-3w-alt3-0 {
+ st,pins {
+ mtsr = <&pio34 1 ALT3 BIDIR_PU>;
+ scl = <&pio34 0 ALT3 OUT>;
+ };
+ };
+ };
+
+ serial3 {
+ pinctrl_serial3: serial3-0 {
+ st,pins {
+ tx = <&pio31 3 ALT1 OUT>;
+ rx = <&pio31 4 ALT1 IN>;
+ };
+ };
+ };
};
pin-controller-flash {
@@ -811,6 +1128,57 @@
emmc_d7 = <&pio41 7 ALT1 BIDIR_PU>;
};
};
+ pinctrl_sd0: sd0-0 {
+ st,pins {
+ sd_clk = <&pio40 6 ALT1 BIDIR>;
+ sd_cmd = <&pio40 7 ALT1 BIDIR_PU>;
+ sd_dat0 = <&pio41 0 ALT1 BIDIR_PU>;
+ sd_dat1 = <&pio41 1 ALT1 BIDIR_PU>;
+ sd_dat2 = <&pio41 2 ALT1 BIDIR_PU>;
+ sd_dat3 = <&pio41 3 ALT1 BIDIR_PU>;
+ sd_led = <&pio42 0 ALT2 OUT>;
+ sd_pwren = <&pio42 2 ALT2 OUT>;
+ sd_vsel = <&pio42 3 ALT2 OUT>;
+ sd_cd = <&pio42 4 ALT2 IN>;
+ sd_wp = <&pio42 5 ALT2 IN>;
+ };
+ };
+ };
+
+ fsm {
+ pinctrl_fsm: fsm {
+ st,pins {
+ spi-fsm-clk = <&pio40 1 ALT1 OUT>;
+ spi-fsm-cs = <&pio40 0 ALT1 OUT>;
+ spi-fsm-mosi = <&pio40 2 ALT1 OUT>;
+ spi-fsm-miso = <&pio40 3 ALT1 IN>;
+ spi-fsm-hol = <&pio40 5 ALT1 OUT>;
+ spi-fsm-wp = <&pio40 4 ALT1 OUT>;
+ };
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand {
+ st,pins {
+ nand_cs1 = <&pio40 6 ALT3 OUT>;
+ nand_cs0 = <&pio40 7 ALT3 OUT>;
+ nand_d0 = <&pio41 0 ALT3 BIDIR>;
+ nand_d1 = <&pio41 1 ALT3 BIDIR>;
+ nand_d2 = <&pio41 2 ALT3 BIDIR>;
+ nand_d3 = <&pio41 3 ALT3 BIDIR>;
+ nand_d4 = <&pio41 4 ALT3 BIDIR>;
+ nand_d5 = <&pio41 5 ALT3 BIDIR>;
+ nand_d6 = <&pio41 6 ALT3 BIDIR>;
+ nand_d7 = <&pio41 7 ALT3 BIDIR>;
+ nand_we = <&pio42 0 ALT3 OUT>;
+ nand_dqs = <&pio42 1 ALT3 OUT>;
+ nand_ale = <&pio42 2 ALT3 OUT>;
+ nand_cle = <&pio42 3 ALT3 OUT>;
+ nand_rnb = <&pio42 4 ALT3 IN>;
+ nand_oe = <&pio42 5 ALT3 OUT>;
+ };
+ };
};
};
};
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
index 6b914e4..d60f0d8 100644
--- a/arch/arm/boot/dts/stih407.dtsi
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -10,19 +10,6 @@
#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>;
diff --git a/arch/arm/boot/dts/stih410-b2120.dts b/arch/arm/boot/dts/stih410-b2120.dts
index 16f02c5..118ac28 100644
--- a/arch/arm/boot/dts/stih410-b2120.dts
+++ b/arch/arm/boot/dts/stih410-b2120.dts
@@ -25,6 +25,7 @@
aliases {
ttyAS0 = &sbc_serial0;
+ ethernet0 = &ethernet0;
};
soc {
@@ -35,5 +36,29 @@
sd-uhs-sdr104;
sd-uhs-ddr50;
};
+
+ usb2_picophy1: phy2 {
+ status = "okay";
+ };
+
+ usb2_picophy2: phy3 {
+ status = "okay";
+ };
+
+ ohci0: usb@9a03c00 {
+ status = "okay";
+ };
+
+ ehci0: usb@9a03e00 {
+ status = "okay";
+ };
+
+ ohci1: usb@9a83c00 {
+ status = "okay";
+ };
+
+ ehci1: usb@9a83e00 {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 8c6e61a..18ed1ad 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -22,6 +22,8 @@
resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
<&picophyreset STIH407_PICOPHY0_RESET>;
reset-names = "global", "port";
+
+ status = "disabled";
};
usb2_picophy2: phy3 {
@@ -31,6 +33,8 @@
resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
<&picophyreset STIH407_PICOPHY1_RESET>;
reset-names = "global", "port";
+
+ status = "disabled";
};
ohci0: usb@9a03c00 {
@@ -43,6 +47,8 @@
reset-names = "power", "softreset";
phys = <&usb2_picophy1>;
phy-names = "usb";
+
+ status = "disabled";
};
ehci0: usb@9a03e00 {
@@ -57,6 +63,8 @@
reset-names = "power", "softreset";
phys = <&usb2_picophy1>;
phy-names = "usb";
+
+ status = "disabled";
};
ohci1: usb@9a83c00 {
@@ -69,6 +77,8 @@
reset-names = "power", "softreset";
phys = <&usb2_picophy2>;
phy-names = "usb";
+
+ status = "disabled";
};
ehci1: usb@9a83e00 {
@@ -83,19 +93,8 @@
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>;
+ status = "disabled";
};
sti-display-subsystem {
diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
index 82eee39..772d2bb 100644
--- a/arch/arm/boot/dts/stih418-b2199.dts
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -24,6 +24,7 @@
aliases {
ttyAS0 = &sbc_serial0;
+ ethernet0 = &ethernet0;
};
soc {
@@ -101,5 +102,12 @@
st_dwc3: dwc3@8f94000 {
status = "okay";
};
+
+ ethernet0: dwmac@9630000 {
+ st,tx-retime-src = "clkgen";
+ status = "okay";
+ phy-mode = "rgmii";
+ fixed-link = <0 1 1000 0 0>;
+ };
};
};
diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
index 148e177..ae6d997 100644
--- a/arch/arm/boot/dts/stih418-clock.dtsi
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -44,7 +44,7 @@
clockgen_a9_pll: clockgen-a9-pll {
#clock-cells = <1>;
- compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+ compatible = "st,stih418-plls-c28-a9", "st,clkgen-plls-c32";
clocks = <&clk_sysin>;
diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
index 8160a75..965f881 100644
--- a/arch/arm/boot/dts/stih418.dtsi
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -99,5 +99,11 @@
phys = <&usb2_picophy2>;
phy-names = "usb";
};
+
+ mmc0: sdhci@09060000 {
+ assigned-clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
+ assigned-clock-parents = <&clk_s_c0_pll1 0>;
+ assigned-clock-rates = <200000000>;
+ };
};
};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index f589fe4..133375b 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,6 +6,9 @@
* 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>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/media/c8sectpfe.h>
/ {
soc {
sbc_serial0: serial@9530000 {
@@ -27,14 +30,28 @@
};
};
- i2c@9842000 {
+ pwm0: pwm@9810000 {
status = "okay";
};
- i2c@9843000 {
+ pwm1: pwm@9510000 {
status = "okay";
};
+ ssc2: i2c@9842000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ st,i2c-min-scl-pulse-width-us = <0>;
+ st,i2c-min-sda-pulse-width-us = <5>;
+ };
+
+ ssc3: i2c@9843000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ st,i2c-min-scl-pulse-width-us = <0>;
+ st,i2c-min-sda-pulse-width-us = <5>;
+ };
+
i2c@9844000 {
status = "okay";
};
@@ -79,5 +96,44 @@
status = "okay";
};
+ ethernet0: dwmac@9630000 {
+ st,tx-retime-src = "clkgen";
+ status = "okay";
+ phy-mode = "rgmii";
+ fixed-link = <0 1 1000 0 0>;
+ };
+
+ demux@08a20000 {
+ compatible = "st,stih407-c8sectpfe";
+ status = "okay";
+ reg = <0x08a20000 0x10000>,
+ <0x08a00000 0x4000>;
+ reg-names = "c8sectpfe", "c8sectpfe-ram";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_NONE>,
+ <GIC_SPI 35 IRQ_TYPE_NONE>;
+ interrupt-names = "c8sectpfe-error-irq",
+ "c8sectpfe-idle-irq";
+ pinctrl-0 = <&pinctrl_tsin0_serial>;
+ pinctrl-1 = <&pinctrl_tsin0_parallel>;
+ pinctrl-2 = <&pinctrl_tsin3_serial>;
+ pinctrl-3 = <&pinctrl_tsin4_serial_alt3>;
+ pinctrl-4 = <&pinctrl_tsin5_serial_alt1>;
+ pinctrl-names = "tsin0-serial",
+ "tsin0-parallel",
+ "tsin3-serial",
+ "tsin4-serial",
+ "tsin5-serial";
+ clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
+ clock-names = "c8sectpfe";
+
+ /* tsin0 is TSA on NIMA */
+ tsin0: port@0 {
+ tsin-num = <0>;
+ serial-not-parallel;
+ i2c-bus = <&ssc2>;
+ reset-gpios = <&pio15 4 GPIO_ACTIVE_HIGH>;
+ dvb-card = <STV0367_TDA18212_NIMA_1>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index d78a481..5e1e234 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -174,6 +174,13 @@
reg = <0x40023800 0x400>;
clocks = <&clk_hse>;
};
+
+ rng: rng@50060800 {
+ compatible = "st,stm32-rng";
+ reg = <0x50060800 0x400>;
+ interrupts = <80>;
+ clocks = <&rcc 0 38>;
+ };
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index 2630d78..97570cb 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -93,6 +93,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
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
index 1430568..5366089 100644
--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -78,6 +78,18 @@
};
};
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
&lradc {
vref-supply = <&reg_vcc3v0>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 046a84d..710e2ef 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -83,6 +83,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
diff --git a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
index 570754d..ac64781 100644
--- a/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
+++ b/arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
@@ -47,6 +47,7 @@
#include "sunxi-common-regulators.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "Gemei G9 Tablet";
@@ -64,12 +65,22 @@
/*
* TODO:
* 2x cameras via CSI
- * bma250 IRQs
* AXP battery management
* NAND
* OTG
* Touchscreen - gt801_2plus1 @ i2c adapter 2 @ 0x48
*/
+&codec {
+ /* PH15 controls power to external amplifier (ft2012q) */
+ pinctrl-names = "default";
+ pinctrl-0 = <&codec_pa_pin>;
+ allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
&ehci0 {
status = "okay";
@@ -85,15 +96,13 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupts = <0>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
};
};
+#include "axp209.dtsi"
+
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
@@ -103,17 +112,13 @@
bma250@18 {
compatible = "bosch,bma250";
reg = <0x18>;
-
- /*
- * TODO: interrupt pins:
- * int1 - PH00
- * int2 - PI10
- */
+ interrupt-parent = <&pio>;
+ interrupts = <7 0 IRQ_TYPE_EDGE_RISING>; /* PH00 / EINT0 */
};
};
&lradc {
- vref-supply = <&reg_vcc3v0>;
+ vref-supply = <&reg_ldo2>;
status = "okay";
@@ -149,6 +154,40 @@
status = "okay";
};
+&pio {
+ codec_pa_pin: codec_pa_pin@0 {
+ allwinner,pins = "PH15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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_usb1_vbus {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-inet1.dts b/arch/arm/boot/dts/sun4i-a10-inet1.dts
new file mode 100644
index 0000000..e09053b
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-inet1.dts
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "iNet-1";
+ compatible = "inet-tek,inet1", "allwinner,sun4i-a10";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_en_pin_inet>;
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&codec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ /* Accelerometer */
+ bma250@18 {
+ compatible = "bosch,bma250";
+ reg = <0x18>;
+ interrupt-parent = <&pio>;
+ interrupts = <7 0 IRQ_TYPE_EDGE_RISING>; /* PH0 / EINT0 */
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ ft5x: touchscreen@38 {
+ compatible = "edt,edt-ft5406";
+ reg = <0x38>;
+ interrupt-parent = <&pio>;
+ interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_wake_pin>;
+ wake-gpios = <&pio 1 13 GPIO_ACTIVE_HIGH>; /* PB13 */
+ touchscreen-size-x = <600>;
+ touchscreen-size-y = <1024>;
+ touchscreen-swapped-x-y;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ status = "okay";
+
+ button@200 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <200000>;
+ };
+
+ button@1000 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <1000000>;
+ };
+
+ button@1200 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <1200000>;
+ };
+};
+
+&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";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ bl_en_pin_inet: bl_en_pin@0 {
+ allwinner,pins = "PH7";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ touchscreen_wake_pin: touchscreen_wake_pin@0 {
+ allwinner,pins = "PB13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PH5";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>;
+ status = "okay";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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_usb0_vbus {
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ 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
index 6c927a8..77c31da 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -47,6 +47,7 @@
#include "sunxi-common-regulators.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
/ {
model = "INet-97F Rev 02";
@@ -61,8 +62,8 @@
};
};
-&ehci0 {
- status = "okay";
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
};
&ehci1 {
@@ -75,12 +76,62 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ status = "okay";
+
+ button@200 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <200000>;
+ };
+
+ button@600 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <600000>;
+ };
+
+ button@800 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <800000>;
+ };
+
+ button@1000 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <1000000>;
+ };
- interrupt-controller;
- #interrupt-cells = <1>;
+ button@1200 {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ channel = <0>;
+ voltage = <1200000>;
};
};
@@ -94,15 +145,52 @@
status = "okay";
};
-&ohci0 {
+&otg_sram {
status = "okay";
};
-&ohci1 {
- status = "okay";
+&pio {
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PH5";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
};
-&reg_usb1_vbus {
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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_usb0_vbus {
status = "okay";
};
@@ -116,8 +204,17 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
- usb1_vbus-supply = <&reg_usb1_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
new file mode 100644
index 0000000..ca49b0d
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts
@@ -0,0 +1,391 @@
+/*
+ * 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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "iNet-9F Rev 03";
+ compatible = "inet-tek,inet9f-rev03", "allwinner,sun4i-a10";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys-polled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_pins_inet9f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <20>;
+
+ button@0 {
+ label = "Left Joystick Left";
+ linux,code = <ABS_X>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
+ };
+
+ button@1 {
+ label = "Left Joystick Right";
+ linux,code = <ABS_X>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
+ };
+
+ button@2 {
+ label = "Left Joystick Up";
+ linux,code = <ABS_Y>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
+ };
+
+ button@3 {
+ label = "Left Joystick Down";
+ linux,code = <ABS_Y>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
+ };
+
+ button@4 {
+ label = "Right Joystick Left";
+ linux,code = <ABS_Z>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
+ };
+
+ button@5 {
+ label = "Right Joystick Right";
+ linux,code = <ABS_Z>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
+ };
+
+ button@6 {
+ label = "Right Joystick Up";
+ linux,code = <ABS_RZ>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
+ };
+
+ button@7 {
+ label = "Right Joystick Down";
+ linux,code = <ABS_RZ>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
+ };
+
+ button@8 {
+ label = "DPad Left";
+ linux,code = <ABS_HAT0X>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 7 23 GPIO_ACTIVE_LOW>; /* PH23 */
+ };
+
+ button@9 {
+ label = "DPad Right";
+ linux,code = <ABS_HAT0X>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 7 24 GPIO_ACTIVE_LOW>; /* PH24 */
+ };
+
+ button@10 {
+ label = "DPad Up";
+ linux,code = <ABS_HAT0Y>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <0xffffffff>; /* -1 */
+ gpios = <&pio 7 25 GPIO_ACTIVE_LOW>; /* PH25 */
+ };
+
+ button@11 {
+ label = "DPad Down";
+ linux,code = <ABS_HAT0Y>;
+ linux,input-type = <EV_ABS>;
+ linux,input-value = <1>;
+ gpios = <&pio 7 26 GPIO_ACTIVE_LOW>; /* PH26 */
+ };
+
+ button@12 {
+ label = "Button X";
+ linux,code = <BTN_X>;
+ gpios = <&pio 0 16 GPIO_ACTIVE_LOW>; /* PA16 */
+ };
+
+ button@13 {
+ label = "Button Y";
+ linux,code = <BTN_Y>;
+ gpios = <&pio 0 14 GPIO_ACTIVE_LOW>; /* PA14 */
+ };
+
+ button@14 {
+ label = "Button A";
+ linux,code = <BTN_A>;
+ gpios = <&pio 0 17 GPIO_ACTIVE_LOW>; /* PA17 */
+ };
+
+ button@15 {
+ label = "Button B";
+ linux,code = <BTN_B>;
+ gpios = <&pio 0 15 GPIO_ACTIVE_LOW>; /* PA15 */
+ };
+
+ button@16 {
+ label = "Select Button";
+ linux,code = <BTN_SELECT>;
+ gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
+ };
+
+ button@17 {
+ label = "Start Button";
+ linux,code = <BTN_START>;
+ gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
+ };
+
+ button@18 {
+ label = "Top Left Button";
+ linux,code = <BTN_TL>;
+ gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 */
+ };
+
+ button@19 {
+ label = "Top Right Button";
+ linux,code = <BTN_TR>;
+ gpios = <&pio 0 13 GPIO_ACTIVE_LOW>; /* PA13 */
+ };
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ /* Accelerometer */
+ bma250@18 {
+ compatible = "bosch,bma250";
+ reg = <0x18>;
+ interrupt-parent = <&pio>;
+ interrupts = <7 0 IRQ_TYPE_EDGE_RISING>; /* PH0 / EINT0 */
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ status = "okay";
+
+ button@200 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <200000>;
+ };
+
+ button@600 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <600000>;
+ };
+
+ button@800 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <800000>;
+ };
+
+ button@1000 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <1000000>;
+ };
+
+ button@1200 {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ channel = <0>;
+ voltage = <1200000>;
+ };
+};
+
+&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";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ key_pins_inet9f: key_pins@0 {
+ allwinner,pins = "PA0", "PA1", "PA3", "PA4",
+ "PA5", "PA6", "PA8", "PA9",
+ "PA11", "PA12", "PA13",
+ "PA14", "PA15", "PA16", "PA17",
+ "PH22", "PH23", "PH24", "PH25", "PH26";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PH5";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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_usb0_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
index dc2f2ae..7afc7a6 100644
--- a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
+++ b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
@@ -156,6 +156,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
emac_power_pin_q5: emac_power_pin@0 {
allwinner,pins = "PH19";
@@ -172,6 +176,11 @@
};
};
+&reg_usb0_vbus {
+ regulator-boot-on;
+ status = "okay";
+};
+
&reg_usb1_vbus {
status = "okay";
};
@@ -186,7 +195,13 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
&usbphy {
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun4i-a10-marsboard.dts b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
index 02158bc..8e50723 100644
--- a/arch/arm/boot/dts/sun4i-a10-marsboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
@@ -91,6 +91,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
@@ -154,6 +158,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
led_pins_marsboard: led_pins@0 {
allwinner,pins = "PB5", "PB6", "PB7", "PB8";
@@ -161,6 +169,13 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
&reg_usb1_vbus {
@@ -184,7 +199,15 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts
index 3c7eebe..ddf0683 100644
--- a/arch/arm/boot/dts/sun4i-a10-mk802.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts
@@ -58,6 +58,10 @@
};
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
index 28e32ad..b350448 100644
--- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -124,6 +124,18 @@
};
};
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
&mdio {
status = "okay";
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
index 4e3e1b9..39034aa 100644
--- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -104,6 +104,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
@@ -129,12 +133,8 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupts = <0>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
};
};
@@ -164,6 +164,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
led_pins_pcduino: led_pins@0 {
allwinner,pins = "PH15", "PH16";
@@ -178,14 +182,40 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
-&reg_usb1_vbus {
- status = "okay";
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
};
-&reg_usb2_vbus {
- status = "okay";
+&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";
};
&uart0 {
@@ -194,8 +224,16 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
- usb1_vbus-supply = <&reg_usb1_vbus>;
- usb2_vbus-supply = <&reg_usb2_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb1_vbus-supply = <&reg_vcc5v0>; /* USB1 VBUS is always on */
+ usb2_vbus-supply = <&reg_vcc5v0>; /* USB2 VBUS is always on */
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino2.dts b/arch/arm/boot/dts/sun4i-a10-pcduino2.dts
new file mode 100644
index 0000000..de483a1
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino2.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Siarhei Siamashka <siarhei.siamashka@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.
+ */
+
+/*
+ * The LinkSprite pcDuino2 board is almost identical to the older
+ * LinkSprite pcDuino1 board. The only software visible difference
+ * is that the pcDuino2 board got a USB VBUS voltage regulator, which
+ * is controlled by the PD2 pin (pulled-up by default). Also one of
+ * the USB host ports has been replaced with a USB WIFI chip.
+ */
+
+#include "sun4i-a10-pcduino.dts"
+
+/ {
+ model = "LinkSprite pcDuino2";
+ compatible = "linksprite,a10-pcduino2", "allwinner,sun4i-a10";
+};
+
+&pio {
+ usb2_vbus_pin_pcduino2: usb2_vbus_pin@0 {
+ allwinner,pins = "PD2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb2_vbus {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin_pcduino2>;
+ gpio = <&pio 3 2 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_vcc3v3>; /* USB WIFI is always on */
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
new file mode 100644
index 0000000..918f972
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts
@@ -0,0 +1,260 @@
+/*
+ * 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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Point of View Protab2-IPS9";
+ compatible = "pov,protab2-ips9", "allwinner,sun4i-a10";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_en_pin_protab>;
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&codec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&codec_pa_pin>;
+ allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ /* pull-ups and devices require AXP209 LDO3 */
+ status = "failed";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ pixcir_ts@5c {
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ compatible = "pixcir,pixcir_tangoc";
+ reg = <0x5c>;
+ interrupt-parent = <&pio>;
+ interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; /* EINT21 (PH21) */
+ attb-gpio = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* PH21 */
+ enable-gpios = <&pio 0 5 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&pio 1 13 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <1024>;
+ touchscreen-size-y = <768>;
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ status = "okay";
+
+ button@400 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <400000>;
+ };
+
+ button@800 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <800000>;
+ };
+};
+
+&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";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ bl_en_pin_protab: bl_en_pin@0 {
+ allwinner,pins = "PH7";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ codec_pa_pin: codec_pa_pin@0 {
+ allwinner,pins = "PH15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ touchscreen_pins: touchscreen_pins@0 {
+ allwinner,pins = "PA5", "PB13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PH5";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>;
+ status = "okay";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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_usb0_vbus {
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 1f3c51a..2c8f5e6 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -45,6 +45,7 @@
#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
#include <dt-bindings/dma/sun4i-a10.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
@@ -65,7 +66,7 @@
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
- <&ahb_gates 44>;
+ <&ahb_gates 44>, <&dram_gates 26>;
status = "disabled";
};
@@ -74,7 +75,8 @@
"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>;
+ <&ahb_gates 44>, <&ahb_gates 46>,
+ <&dram_gates 25>, <&dram_gates 26>;
status = "disabled";
};
@@ -83,7 +85,8 @@
"simple-framebuffer";
allwinner,pipeline = "de_fe0-de_be0-lcd0";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
- <&ahb_gates 46>;
+ <&ahb_gates 46>, <&dram_gates 25>,
+ <&dram_gates 26>;
status = "disabled";
};
@@ -92,7 +95,8 @@
"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>;
+ <&ahb_gates 44>, <&ahb_gates 46>,
+ <&dram_gates 25>, <&dram_gates 26>;
status = "disabled";
};
};
@@ -195,6 +199,15 @@
clock-output-names = "pll1";
};
+ pll2: clk@01c20008 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll2-clk";
+ reg = <0x01c20008 0x8>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll2-1x", "pll2-2x",
+ "pll2-4x", "pll2-8x";
+ };
+
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
@@ -481,6 +494,48 @@
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi3";
};
+
+ dram_gates: clk@01c20100 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-dram-gates-clk";
+ reg = <0x01c20100 0x4>;
+ clocks = <&pll5 0>;
+ clock-indices = <0>,
+ <1>, <2>,
+ <3>,
+ <4>,
+ <5>, <6>,
+ <15>,
+ <24>, <25>,
+ <26>, <27>,
+ <28>, <29>;
+ clock-output-names = "dram_ve",
+ "dram_csi0", "dram_csi1",
+ "dram_ts",
+ "dram_tvd",
+ "dram_tve0", "dram_tve1",
+ "dram_output",
+ "dram_de_fe1", "dram_de_fe0",
+ "dram_de_be0", "dram_de_be1",
+ "dram_de_mp", "dram_ace";
+ };
+
+ ve_clk: clk@01c2013c {
+ #clock-cells = <0>;
+ #reset-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ve-clk";
+ reg = <0x01c2013c 0x4>;
+ clocks = <&pll4>;
+ clock-output-names = "ve";
+ };
+
+ codec_clk: clk@01c20140 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-codec-clk";
+ reg = <0x01c20140 0x4>;
+ clocks = <&pll2 SUN4I_A10_PLL2_1X>;
+ clock-output-names = "codec";
+ };
};
soc@01c00000 {
@@ -1004,6 +1059,19 @@
status = "disabled";
};
+ codec: codec@01c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun4i-a10-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <30>;
+ clocks = <&apb0_gates 0>, <&codec_clk>;
+ clock-names = "apb", "codec";
+ dmas = <&dma SUN4I_DMA_NORMAL 19>,
+ <&dma SUN4I_DMA_NORMAL 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>;
diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
new file mode 100644
index 0000000..d4ad021
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ *
+ * 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 = "Auxtek t003 A10s hdmi tv-stick";
+ compatible = "allwinner,auxtek-t003", "allwinner,sun5i-a10s";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_t003>;
+
+ red {
+ label = "t003-tv-dongle:red:usr";
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+ default-state = "on";
+ };
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp152: pmic@30 {
+ compatible = "x-powers,axp152";
+ reg = <0x30>;
+ interrupts = <0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t003>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_t003: 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_t003: led_pins@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb0_vbus {
+ gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>; /* PB10 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb0_vbus_pin_a {
+ allwinner,pins = "PG13";
+};
+
+&usb1_vbus_pin_a {
+ allwinner,pins = "PB10";
+};
+
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
index 2b3511e..a790ec8 100644
--- a/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts
@@ -86,6 +86,20 @@
status = "okay";
};
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp152: pmic@30 {
+ compatible = "x-powers,axp152";
+ reg = <0x30>;
+ interrupts = <0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t004>;
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index 5a422c1..86d046a 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -111,7 +111,7 @@
status = "okay";
at24@50 {
- compatible = "at,24c16";
+ compatible = "atmel,24c16";
pagesize = <16>;
reg = <0x50>;
read-only;
diff --git a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
new file mode 100644
index 0000000..9fea918
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2015 Jelle van der Waa <jelle@vdwaa.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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "A10s-Wobo i5";
+ compatible = "wobo,a10s-wobo-i5", "allwinner,sun5i-a10s";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_wobo_i5>;
+
+ blue {
+ label = "a10s-wobo-i5:blue:usr";
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ reg_emac_3v3: emac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_power_pin_wobo>;
+ regulator-name = "emac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 0 2 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_b>;
+ phy = <&phy1>;
+ status = "okay";
+};
+
+&emac_sram {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&mdio {
+ phy-supply = <&reg_emac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_wobo_i5>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ led_pins_wobo_i5: 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_wobo_i5: mmc0_cd_pin@0 {
+ allwinner,pins = "PB3";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ emac_power_pin_wobo: emac_power_pin@0 {
+ allwinner,pins = "PA02";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ 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-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+&reg_usb1_vbus {
+ gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb1_vbus_pin_a {
+ allwinner,pins = "PG12";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index a513b41..bddd0de 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -77,6 +77,15 @@
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";
+ };
};
clocks {
@@ -156,6 +165,14 @@
#size-cells = <0>;
};
+ pwm: pwm@01c20e00 {
+ compatible = "allwinner,sun5i-a10s-pwm";
+ reg = <0x01c20e00 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
@@ -195,13 +212,6 @@
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",
@@ -213,6 +223,17 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ emac_pins_b: emac0@1 {
+ allwinner,pins = "PD6", "PD7", "PD10",
+ "PD11", "PD12", "PD13", "PD14",
+ "PD15", "PD18", "PD19", "PD20",
+ "PD21", "PD22", "PD23", "PD24",
+ "PD25", "PD26", "PD27";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
mmc1_pins_a: mmc1@0 {
allwinner,pins = "PG3", "PG4", "PG5",
"PG6", "PG7", "PG8";
diff --git a/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
new file mode 100644
index 0000000..7fbb0b0
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-empire-electronix-d709.dts
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ model = "Empire Electronix D709 tablet";
+ compatible = "empire-electronix,d709", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ /* TODO: backlight uses axp gpio1 as enable pin */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ 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>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+
+ mmccard: mmccard@0 {
+ reg = <0>;
+ compatible = "mmc-card";
+ broken-hpi;
+ };
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_inet98fv2: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PG2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins>;
+ status = "okay";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-name = "vdd-int-pll";
+};
+
+&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";
+};
+
+&reg_usb0_vbus {
+ gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb0_vbus_pin_a {
+ allwinner,pins = "PG12";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_ldo3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
new file mode 100644
index 0000000..6fa54b6
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ *
+ * 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/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "INet-98V Rev 02";
+ compatible = "primux,inet98v-rev2", "allwinner,sun5i-a13";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_ldo2>;
+ 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>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+
+ mmccard: mmccard@0 {
+ reg = <0>;
+ compatible = "mmc-card";
+ broken-hpi;
+ };
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_inet98fv2: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PG2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-name = "vdd-int-pll";
+};
+
+&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";
+};
+
+&reg_usb0_vbus {
+ gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb0_vbus_pin_a {
+ allwinner,pins = "PG12";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_ldo3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-q8-tablet.dts b/arch/arm/boot/dts/sun5i-a13-q8-tablet.dts
new file mode 100644
index 0000000..72e93ac
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-q8-tablet.dts
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * 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 "sun5i-q8-common.dtsi"
+
+/ {
+ model = "Q8 A13 Tablet";
+ compatible = "allwinner,q8-a13", "allwinner,sun5i-a13";
+};
+
+&reg_ldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_ldo3>;
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
index eb793d5..fa9ddfd 100644
--- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
+++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
@@ -47,11 +47,21 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/pwm/pwm.h>
/ {
model = "Utoo P66";
compatible = "utoo,p66", "allwinner,sun5i-a13";
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ /* Note levels of 10 / 20% result in backlight off */
+ brightness-levels = <0 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <6>;
+ /* TODO: backlight uses axp gpio1 as enable pin */
+ };
+
i2c_lcd: i2c@0 {
/* The lcd panel i2c interface is hooked up via gpios */
compatible = "i2c-gpio";
@@ -63,6 +73,13 @@
};
};
+&codec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&codec_pa_pin>;
+ allwinner,pa-gpios = <&pio 6 3 GPIO_ACTIVE_HIGH>; /* PG3 */
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
@@ -158,6 +175,13 @@
};
&pio {
+ codec_pa_pin: codec_pa_pin@0 {
+ allwinner,pins = "PG3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
mmc0_cd_pin_p66: mmc0_cd_pin@0 {
allwinner,pins = "PG0";
allwinner,function = "gpio_in";
@@ -201,6 +225,12 @@
};
};
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins>;
+ status = "okay";
+};
+
&reg_dcdc2 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index f3631c9..d910d3a 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -150,6 +150,16 @@
"apb1_uart3";
};
};
+
+ soc@01c00000 {
+ pwm: pwm@01c20e00 {
+ compatible = "allwinner,sun5i-a13-pwm";
+ reg = <0x01c20e00 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+ };
};
&cpu0 {
diff --git a/arch/arm/boot/dts/sun5i-q8-common.dtsi b/arch/arm/boot/dts/sun5i-q8-common.dtsi
new file mode 100644
index 0000000..a78e189
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-q8-common.dtsi
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ *
+ * 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 "sunxi-q8-common.dtsi"
+
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ /* TODO: backlight uses axp gpio1 as enable pin */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupts = <0>;
+ };
+};
+
+&i2c1 {
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+ cd-inverted;
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_q8: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PG2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_pin_a: usb0_vbus_pin@0 {
+ allwinner,pins = "PG12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&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-pll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+ gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
new file mode 100644
index 0000000..530ab28
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2015 Free Electrons
+ * Copyright 2015 NextThing Co
+ *
+ * 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.
+ *
+ * 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-r8.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "NextThing C.H.I.P.";
+ compatible = "nextthing,chip", "allwinner,sun5i-r8";
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c2 = &i2c2;
+ serial0 = &uart1;
+ serial1 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&codec {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+
+ /*
+ * The interrupt is routed through the "External Fast
+ * Interrupt Request" pin (ball G13 of the module)
+ * directly to the main interrupt controller, without
+ * any other controller interfering.
+ */
+ interrupts = <0>;
+ };
+};
+
+#include "axp209.dtsi"
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ xio: gpio@38 {
+ compatible = "nxp,pcf8574a";
+ reg = <0x38>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-parent = <&pio>;
+ interrupts = <6 0 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ chip_vbus_pin: chip_vbus_pin@0 {
+ allwinner,pins = "PB10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ chip_id_det_pin: chip_id_det_pin@0 {
+ allwinner,pins = "PG2";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "cpuvdd";
+ regulator-always-on;
+};
+
+&reg_dcdc3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "corevdd";
+ regulator-always-on;
+};
+
+&reg_ldo1 {
+ regulator-name = "rtcvdd";
+};
+
+&reg_ldo2 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+ regulator-always-on;
+};
+
+&reg_ldo5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-1v8";
+};
+
+&reg_usb0_vbus {
+ pinctrl-0 = <&chip_vbus_pin>;
+ vin-supply = <&reg_vcc5v0>;
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>; /* PB10 */
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins_a>,
+ <&uart3_pins_cts_rts_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&chip_id_det_pin>;
+ status = "okay";
+
+ usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_vcc5v0>;
+};
diff --git a/arch/arm/boot/dts/sun5i-r8.dtsi b/arch/arm/boot/dts/sun5i-r8.dtsi
new file mode 100644
index 0000000..0ef8656
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-r8.dtsi
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Free Electrons
+ * Copyright 2015 NextThing Co
+ *
+ * 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.
+ *
+ * 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 "sun5i-a13.dtsi"
+
+/ {
+ chosen {
+ framebuffer@1 {
+ 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";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 78b993a..59a9426 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -44,6 +44,7 @@
#include "skeleton.dtsi"
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
#include <dt-bindings/dma/sun4i-a10.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
@@ -102,6 +103,15 @@
clock-output-names = "pll1";
};
+ pll2: clk@01c20008 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-a13-pll2-clk";
+ reg = <0x01c20008 0x8>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll2-1x", "pll2-2x",
+ "pll2-4x", "pll2-8x";
+ };
+
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
@@ -285,6 +295,14 @@
clock-output-names = "usb_ohci0", "usb_phy";
};
+ codec_clk: clk@01c20140 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-codec-clk";
+ reg = <0x01c20140 0x4>;
+ clocks = <&pll2 SUN4I_A10_PLL2_1X>;
+ clock-output-names = "codec";
+ };
+
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-mbus-clk";
@@ -529,6 +547,27 @@
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
+
+ uart3_pins_a: uart3@0 {
+ allwinner,pins = "PG9", "PG10";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ uart3_pins_cts_rts_a: uart3-cts-rts@0 {
+ allwinner,pins = "PG11", "PG12";
+ allwinner,function = "uart3";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ pwm0_pins: pwm0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "pwm";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
timer@01c20c00 {
@@ -550,6 +589,19 @@
status = "disabled";
};
+ codec: codec@01c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun4i-a10-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <30>;
+ clocks = <&apb0_gates 0>, <&codec_clk>;
+ clock-names = "apb", "codec";
+ dmas = <&dma SUN4I_DMA_NORMAL 19>,
+ <&dma SUN4I_DMA_NORMAL 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>;
diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
index 0cf9926..f9cf368 100644
--- a/arch/arm/boot/dts/sun6i-a31-colombus.dts
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -60,12 +60,34 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ i2c_lcd: i2c@0 {
+ /* The lcd panel i2c interface is hooked up via gpios */
+ compatible = "i2c-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_lcd_pins>;
+ gpios = <&pio 0 23 GPIO_ACTIVE_HIGH>, /* PA23, sda */
+ <&pio 0 24 GPIO_ACTIVE_HIGH>; /* PA24, scl */
+ i2c-gpio,delay-us = <5>;
+ };
};
&ehci1 {
status = "okay";
};
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
@@ -82,6 +104,13 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins_a>;
status = "okay";
+
+ mma8452: mma8452@1d {
+ compatible = "fsl,mma8452";
+ reg = <0x1d>;
+ interrupt-parent = <&pio>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PA9 */
+ };
};
&mmc0 {
@@ -112,6 +141,13 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ i2c_lcd_pins: i2c_lcd_pin@0 {
+ allwinner,pins = "PA23", "PA24";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
&reg_usb2_vbus {
diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index d0cfada..9a74637 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -54,6 +54,8 @@
compatible = "merrii,a31-hummingbird", "allwinner,sun6i-a31";
aliases {
+ rtc0 = &pcf8563;
+ rtc1 = &rtc;
serial0 = &uart0;
};
@@ -67,13 +69,17 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc3>;
+};
+
&ehci0 {
status = "okay";
};
&gmac {
pinctrl-names = "default";
- pinctrl-0 = <&gmac_pins_rgmii_a>;
+ pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_hummingbird>;
phy = <&phy1>;
phy-mode = "rgmii";
snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>;
@@ -119,7 +125,7 @@
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
- vmmc-supply = <&vcc_3v0>;
+ vmmc-supply = <&reg_dcdc1>;
bus-width = <4>;
cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
cd-inverted;
@@ -134,7 +140,7 @@
&mmc1 {
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins_a>, <&wifi_reset_pin_hummingbird>;
- vmmc-supply = <&vcc_wifi>;
+ vmmc-supply = <&reg_aldo1>;
mmc-pwrseq = <&wifi_pwrseq>;
bus-width = <4>;
non-removable;
@@ -146,6 +152,13 @@
};
&pio {
+ gmac_phy_reset_pin_hummingbird: gmac_phy_reset_pin@0 {
+ allwinner,pins = "PA21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
mmc0_cd_pin_hummingbird: mmc0_cd_pin@0 {
allwinner,pins = "PA8";
allwinner,function = "gpio_in";
@@ -164,70 +177,69 @@
&p2wi {
status = "okay";
- axp221: pmic@68 {
+ axp22x: pmic@68 {
compatible = "x-powers,axp221";
reg = <0x68>;
interrupt-parent = <&nmi_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
- interrupt-controller;
- #interrupt-cells = <1>;
- dcdc1-supply = <&vcc_3v0>;
- dcdc5-supply = <&vcc_dram>;
-
- regulators {
- x-powers,dcdc-freq = <3000>;
-
- vcc_3v0: dcdc1 {
- regulator-always-on;
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- regulator-name = "vcc-3v0";
- };
-
- vdd_cpu: dcdc2 {
- regulator-always-on;
- regulator-min-microvolt = <700000>;
- regulator-max-microvolt = <1320000>;
- regulator-name = "vdd-cpu";
- };
-
- vdd_gpu: dcdc3 {
- regulator-always-on;
- regulator-min-microvolt = <700000>;
- regulator-max-microvolt = <1320000>;
- regulator-name = "vdd-gpu";
- };
-
- vdd_sys_dll: dcdc4 {
- regulator-always-on;
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1100000>;
- regulator-name = "vdd-sys-dll";
- };
-
- vcc_dram: dcdc5 {
- regulator-always-on;
- regulator-min-microvolt = <1500000>;
- regulator-max-microvolt = <1500000>;
- regulator-name = "vcc-dram";
- };
-
- vcc_wifi: aldo1 {
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-name = "vcc_wifi";
- };
-
- avcc: aldo3 {
- regulator-always-on;
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- regulator-name = "avcc";
- };
- };
};
};
+#include "axp22x.dtsi"
+
+&reg_aldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+};
+
+&reg_dc5ldo {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpus";
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
&reg_usb1_vbus {
gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>; /* PH24 */
status = "okay";
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 54bb83b..b6ad785 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -61,7 +61,7 @@
#size-cells = <1>;
ranges;
- framebuffer@0 {
+ simplefb_hdmi: framebuffer@0 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
@@ -69,7 +69,7 @@
status = "disabled";
};
- framebuffer@1 {
+ simplefb_lcd: framebuffer@1 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
@@ -691,6 +691,24 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ 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>;
+ };
+
+ mmc2_8bit_emmc_pins: mmc2@1 {
+ allwinner,pins = "PC6", "PC7", "PC8", "PC9",
+ "PC10", "PC11", "PC12",
+ "PC13", "PC14", "PC15",
+ "PC24";
+ allwinner,function = "mmc2";
+ 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",
@@ -768,6 +786,13 @@
reg = <0x01c20ca0 0x20>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
rtp: rtp@01c25000 {
compatible = "allwinner,sun6i-a31-ts";
reg = <0x01c25000 0x100>;
@@ -1085,7 +1110,7 @@
resets = <&apb0_rst 0>;
gpio-controller;
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
#size-cells = <0>;
#gpio-cells = <3>;
diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
new file mode 100644
index 0000000..68b479b
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2014 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ * Copyright 2015 Karsten Merker <merker@debian.org>
+ * Copyright 2015 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.
+ *
+ * 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 "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "MSI Primo81 tablet";
+ compatible = "msi,primo81", "allwinner,sun6i-a31s";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc3>;
+};
+
+&ehci0 {
+ /* rtl8188etv wifi is connected here */
+ status = "okay";
+};
+
+&i2c0 {
+ /* pull-ups and device VDDIO use AXP221 DLDO3 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "failed";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ ctp@5d {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gt911_int_primo81>;
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ interrupt-parent = <&pio>;
+ interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
+ touchscreen-swapped-x-y;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ accelerometer@1c {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mma8452_int_primo81>;
+ compatible = "fsl,mma8452";
+ reg = <0x1c>;
+ interrupt-parent = <&pio>;
+ interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; /* PA9 */
+ #io-channel-cells = <1>;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_aldo3>;
+ status = "okay";
+
+ button@158 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <158730>;
+ };
+
+ button@349 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <349206>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_primo81>;
+ vmmc-supply = <&reg_dcdc1>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&pio {
+ gt911_int_primo81: gt911_int_pin@0 {
+ allwinner,pins = "PA3";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mma8452_int_primo81: mma8452_int_pin@0 {
+ allwinner,pins = "PA9";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ mmc0_cd_pin_primo81: mmc0_cd_pin@0 {
+ allwinner,pins = "PA8";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&p2wi {
+ status = "okay";
+
+ axp22x: pmic@68 {
+ compatible = "x-powers,axp221";
+ reg = <0x68>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+#include "axp22x.dtsi"
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+};
+
+&reg_dc1sw {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-lcd";
+};
+
+&reg_dc5ldo {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpus"; /* This is an educated guess */
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
+&reg_dldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+&reg_dldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "vddio-csi";
+};
+
+&reg_eldo3 {
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-mipi-bridge";
+};
+
+&simplefb_lcd {
+ vcc-lcd-supply = <&reg_dc1sw>;
+ vdd-mipi-bridge-supply = <&reg_eldo3>;
+};
+
+&usb_otg {
+ /* otg support requires support for AXP221 usb-power-supply and GPIO */
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_dldo1>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
new file mode 100644
index 0000000..ea69fb8
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2015 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.
+ *
+ * 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 "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Sinlinx SinA31s Core Board";
+ compatible = "sinlinx,sina31s", "allwinner,sun6i-a31s";
+
+ aliases {
+ serial0 = &uart0;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc3>;
+};
+
+/* eMMC on core board */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_emmc_pins>;
+ vmmc-supply = <&reg_dcdc1>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+/* AXP221s PMIC on core board */
+&p2wi {
+ status = "okay";
+
+ axp22x: pmic@68 {
+ compatible = "x-powers,axp221";
+ reg = <0x68>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+#include "axp22x.dtsi"
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+};
+
+&reg_dc5ldo {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpus";
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
+/* UART0 pads available on core board */
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
new file mode 100644
index 0000000..6ead2f5
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2015 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.
+ *
+ * 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 SinA31s development board has the SinA31s core board soldered on */
+#include "sun6i-a31s-sina31s-core.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Sinlinx SinA31s Development Board";
+ compatible = "sinlinx,sina31s-sdk", "allwinner,sun6i-a31s";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin_sina31s>;
+
+ status {
+ label = "sina31s:status:usr";
+ gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; /* PH13 */
+ };
+ };
+};
+
+&ehci0 {
+ /* USB 2.0 4 port hub IC */
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ phy-supply = <&reg_dldo1>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
+
+&lradc {
+ vref-supply = <&reg_aldo3>;
+ status = "okay";
+
+ button@158 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <158730>;
+ };
+
+ button@349 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <349206>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina31s>;
+ vmmc-supply = <&reg_dcdc1>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ led_pin_sina31s: led_pin@0 {
+ allwinner,pins = "PH13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_sina31s: mmc0_cd_pin@0 {
+ allwinner,pins = "PA4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&reg_dldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-gmac-phy";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
new file mode 100644
index 0000000..db7fa13
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
@@ -0,0 +1,194 @@
+/*
+ * 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 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 "sun6i-a31s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Sinovoip BPI-M2";
+ compatible = "sinovoip,bpi-m2", "allwinner,sun6i-a31s";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_bpi_m2>;
+
+ blue {
+ label = "bpi-m2:blue:usr";
+ gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
+ };
+
+ green {
+ label = "bpi-m2:green:usr";
+ gpios = <&pio 6 10 GPIO_ACTIVE_HIGH>; /* PG10 */
+ };
+
+ red {
+ label = "bpi-m2:red:usr";
+ gpios = <&pio 6 5 GPIO_ACTIVE_HIGH>; /* PG5 */
+ };
+ };
+
+ mmc2_pwrseq: mmc2_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pwrseq_pin_bpi_m2>;
+ reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 WIFI_EN */
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_bpi_m2>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 30000>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc0_pins_a {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins_a>;
+ vmmc-supply = <&reg_vcc3v0>;
+ mmc-pwrseq = <&mmc2_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ interrupt-parent = <&r_pio>;
+ interrupts = <0 5 IRQ_TYPE_LEVEL_LOW>; /* PL5 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&mmc2_pins_a {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ gmac_phy_reset_pin_bpi_m2: gmac_phy_reset_pin@0 {
+ allwinner,pins = "PA21";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_bpi_m2: led_pins@0 {
+ allwinner,pins = "PG5", "PG10", "PG11";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_bpi_m2: mmc0_cd_pin@0 {
+ allwinner,pins = "PA4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&r_pio {
+ mmc2_pwrseq_pin_bpi_m2: mmc2_pwrseq_pin@0 {
+ allwinner,pins = "PL8";
+ 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";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
new file mode 100644
index 0000000..360adfb
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2015 Lawrence Yu <lyu@micile.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 "sun6i-a31s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Yones TopTech BS1078 v2 Tablet";
+ compatible = "yones-toptech,bs1078-v2", "allwinner,sun6i-a31s";
+
+ aliases {
+ serial0 = &uart0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_bs1078v2: mmc0_cd_pin@0 {
+ allwinner,pins = "PA8";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bs1078v2>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc0_pins_a {
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&p2wi {
+ status = "okay";
+
+ axp22x: pmic@68 {
+ compatible = "x-powers,axp221";
+ reg = <0x68>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+#include "axp22x.dtsi"
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avcc";
+};
+
+&reg_dc1sw {
+ regulator-name = "vcc-lcd-usb2";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+};
+
+&reg_dc5ldo {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpus";
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc4 {
+ regulator-always-on;
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
+&reg_dldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+/* Voltage source for I2C pullup resistors for I2C Bus 0 */
+&reg_dldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "vddio-csi";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_dldo1>;
+ usb2_vbus-supply = <&reg_dc1sw>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index 9f7b472..67c8a76 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -92,6 +92,24 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+ operating-points = <
+ /* kHz uV */
+ 960000 1400000
+ 912000 1400000
+ 864000 1350000
+ 720000 1250000
+ 528000 1150000
+ 312000 1100000
+ 144000 1050000
+ >;
+};
+
&ehci0 {
status = "okay";
};
@@ -119,13 +137,9 @@
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>;
};
};
@@ -159,7 +173,18 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
mmc0_cd_pin_bananapi: mmc0_cd_pin@0 {
allwinner,pins = "PH10";
allwinner,function = "gpio_in";
@@ -182,6 +207,37 @@
};
};
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ 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_usb0_vbus {
+ status = "okay";
+};
+
&reg_usb1_vbus {
status = "okay";
};
@@ -216,7 +272,21 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
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
index 39a51d5..1fa832d 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -84,6 +84,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
@@ -150,6 +154,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
led_pins_cubieboard2: led_pins@0 {
allwinner,pins = "PH20", "PH21";
@@ -157,12 +165,24 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
&reg_ahci_5v {
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
#include "axp209.dtsi"
&reg_dcdc2 {
@@ -205,6 +225,9 @@
};
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index e6b0192..8da939a 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -101,6 +101,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
diff --git a/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
new file mode 100644
index 0000000..f5b5325
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2015 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.
+ *
+ * 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 = "ICnova-A20 SWAC";
+ compatible = "swac,icnova-a20-swac", "incircuit,icnova-a20", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ 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>;
+ };
+};
+
+&i2c0 {
+ 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 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ 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 8 5 GPIO_ACTIVE_HIGH>; /* PI5 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ 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_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/sun7i-a20-mk808c.dts b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
index 4f432f8..c9e648d 100644
--- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts
+++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts
@@ -68,6 +68,10 @@
};
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
new file mode 100644
index 0000000..c3c626b
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2015 - Marcus Cooper <codekipper@gmail.com>
+ * Copyright 2015 - Karsten Merker <merker@debian.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 "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 = "Olimex A20-Olimex-SOM-EVB";
+ compatible = "olimex,a20-olimex-som-evb", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olimex_som_evb>;
+
+ green {
+ label = "a20-olimex-som-evb:green:usr";
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+};
+
+&ahci {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&codec {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&i2c0 {
+ 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>;
+ };
+};
+
+&lradc {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@190 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <190000>;
+ };
+
+ button@390 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <390000>;
+ };
+
+ button@600 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <600000>;
+ };
+
+ button@800 {
+ label = "Search";
+ linux,code = <KEY_SEARCH>;
+ channel = <0>;
+ voltage = <800000>;
+ };
+
+ button@980 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <980000>;
+ };
+
+ button@1180 {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ channel = <0>;
+ voltage = <1180000>;
+ };
+
+ button@1400 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <1400000>;
+ };
+};
+
+&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";
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olimex_som_evb>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 0 GPIO_ACTIVE_HIGH>; /* PH0 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ ahci_pwr_pin_olimex_som_evb: 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_olimex_som_evb: led_pins@0 {
+ allwinner,pins = "PH2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc3_cd_pin_olimex_som_evb: mmc3_cd_pin@0 {
+ allwinner,pins = "PH0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&reg_ahci_5v {
+ pinctrl-0 = <&ahci_pwr_pin_olimex_som_evb>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ 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_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/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
index 0423708..35ad700 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -117,6 +117,18 @@
};
};
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
index 8acff78..d5c796c 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -170,6 +170,12 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
};
&mmc0 {
@@ -190,6 +196,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
allwinner,pins = "PC3";
@@ -204,6 +214,27 @@
allwinner,drive = <SUN4I_PINCTRL_20_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+ allwinner,pins = "PH5";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+ };
+
+ usb0_vbus_pin_lime2: usb0_vbus_pin@0 {
+ allwinner,pins = "PC17";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
&reg_ahci_5v {
@@ -212,6 +243,12 @@
status = "okay";
};
+&reg_usb0_vbus {
+ pinctrl-0 = <&usb0_vbus_pin_lime2>;
+ gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
&reg_usb1_vbus {
status = "okay";
};
@@ -226,7 +263,17 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index c5d70ca..7e3006f 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -125,6 +125,12 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c16";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
};
&i2c2 {
diff --git a/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts b/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
index 73cd81ee..2be04c43 100644
--- a/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
+++ b/arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
@@ -95,6 +95,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
@@ -156,7 +160,18 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
mmc0_cd_pin_orangepi: mmc0_cd_pin@0 {
allwinner,pins = "PH10";
allwinner,function = "gpio_in";
@@ -225,6 +240,10 @@
regulator-name = "avcc";
};
+&reg_usb0_vbus {
+ status = "okay";
+};
+
&reg_usb1_vbus {
pinctrl-0 = <&usb1_vbus_pin_bananapro>;
gpio = <&pio 7 26 GPIO_ACTIVE_HIGH>; /* PH26 */
@@ -243,7 +262,21 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-orangepi.dts b/arch/arm/boot/dts/sun7i-a20-orangepi.dts
index 55a06ce..71125bf 100644
--- a/arch/arm/boot/dts/sun7i-a20-orangepi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-orangepi.dts
@@ -141,7 +141,18 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
mmc0_cd_pin_orangepi: mmc0_cd_pin@0 {
allwinner,pins = "PH10";
allwinner,function = "gpio_in";
@@ -203,6 +214,10 @@
regulator-name = "avcc";
};
+&reg_usb0_vbus {
+ status = "okay";
+};
+
&reg_usb1_vbus {
pinctrl-0 = <&usb1_vbus_pin_bananapro>;
gpio = <&pio 7 26 GPIO_ACTIVE_HIGH>; /* PH26 */
@@ -221,7 +236,21 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
index 5361fce..ddac732 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
@@ -82,6 +82,14 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
@@ -108,13 +116,9 @@
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>;
};
};
@@ -142,6 +146,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
ahci_pwr_pin_pcduino3_nano: ahci_pwr_pin@0 {
allwinner,pins = "PH2";
@@ -157,8 +165,15 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
usb1_vbus_pin_pcduino3_nano: usb1_vbus_pin@0 {
- allwinner,pins = "PH11";
+ allwinner,pins = "PD2";
allwinner,function = "gpio_out";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
@@ -171,13 +186,37 @@
status = "okay";
};
-&reg_usb1_vbus {
- pinctrl-0 = <&usb1_vbus_pin_pcduino3_nano>;
- gpio = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
- status = "okay";
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
};
-&reg_usb2_vbus {
+/* A single regulator (U24) powers both USB host ports. */
+&reg_usb1_vbus {
+ pinctrl-0 = <&usb1_vbus_pin_pcduino3_nano>;
+ gpio = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
status = "okay";
};
@@ -187,8 +226,16 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
usb1_vbus-supply = <&reg_usb1_vbus>;
- usb2_vbus-supply = <&reg_usb2_vbus>;
+ usb2_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
index afc9ece..1a8b39b 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -111,6 +111,14 @@
allwinner,pins = "PH2";
};
+&codec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
@@ -137,16 +145,14 @@
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>;
};
};
+#include "axp209.dtsi"
+
&ir0 {
pinctrl-names = "default";
pinctrl-0 = <&ir0_rx_pins_a>;
@@ -171,6 +177,10 @@
status = "okay";
};
+&otg_sram {
+ status = "okay";
+};
+
&pio {
led_pins_pcduino3: led_pins@0 {
allwinner,pins = "PH15", "PH16";
@@ -185,6 +195,13 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
};
&reg_ahci_5v {
@@ -192,6 +209,31 @@
status = "okay";
};
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
&reg_usb1_vbus {
status = "okay";
};
@@ -206,7 +248,15 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
index 83c6d3f..2f6b21a 100644
--- a/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
+++ b/arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
@@ -48,6 +48,7 @@
#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 = "Wexler TAB7200";
@@ -57,11 +58,28 @@
serial0 = &uart0;
};
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_enable_pin>;
+ enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
};
+&codec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&codec_pa_pin>;
+ allwinner,pa-gpios = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&reg_dcdc2>;
};
@@ -86,6 +104,8 @@
};
};
+#include "axp209.dtsi"
+
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
@@ -96,6 +116,18 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins_a>;
status = "okay";
+
+ gt911: touchscreen@5d {
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ interrupt-parent = <&pio>;
+ interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; /* EINT21 (PH21) */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_reset_pin>;
+ irq-gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* INT (PH21) */
+ reset-gpios = <&pio 1 13 GPIO_ACTIVE_HIGH>; /* RST (PB13) */
+ touchscreen-swapped-x-y;
+ };
};
&lradc {
@@ -135,7 +167,45 @@
status = "okay";
};
-#include "axp209.dtsi"
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ bl_enable_pin: bl_enable_pin@0 {
+ allwinner,pins = "PH7";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ codec_pa_pin: codec_pa_pin@0 {
+ allwinner,pins = "PH15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ts_reset_pin: ts_reset_pin@0 {
+ allwinner,pins = "PB13";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins_a>;
+ status = "okay";
+};
&reg_dcdc2 {
regulator-always-on;
@@ -162,6 +232,10 @@
regulator-name = "avcc";
};
+&reg_usb0_vbus {
+ status = "okay";
+};
+
&reg_usb1_vbus {
status = "okay";
};
@@ -176,7 +250,21 @@
status = "okay";
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
diff --git a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
new file mode 100644
index 0000000..dc31d47
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2015 Jelle de Jong <jelledejong@powercraft.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.
+ *
+ * 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>
+
+/ {
+ model = "Wits Pro A20 DKT";
+ compatible = "wits,pro-a20-dkt", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ mmc3_pwrseq: mmc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_ap6xxx_wl_regon>;
+ reset-gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&i2c0 {
+ 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 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&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";
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ mmc-pwrseq = <&mmc3_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ brcmf: bcrmf@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ interrupt-parent = <&pio>;
+ interrupts = <7 10 IRQ_TYPE_LEVEL_LOW>; /* PH10 / EINT10 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ vmmc3_pin_ap6xxx_wl_regon: vmmc3_pin@0 {
+ allwinner,pins = "PH9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb0_id_detect_pin: usb0_id_detect_pin@0 {
+ allwinner,pins = "PH4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&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";
+};
+
+&reg_usb0_vbus {
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
+&usbphy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_id_detect_pin>;
+ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <&reg_usb0_vbus>;
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 391230c..0940a78 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -47,6 +47,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
#include <dt-bindings/dma/sun4i-a10.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
@@ -67,7 +68,7 @@
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
- <&ahb_gates 44>;
+ <&ahb_gates 44>, <&dram_gates 26>;
status = "disabled";
};
@@ -75,7 +76,8 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
- clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
+ <&dram_gates 26>;
status = "disabled";
};
@@ -84,7 +86,7 @@
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-tve0";
clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
- <&ahb_gates 44>;
+ <&ahb_gates 44>, <&dram_gates 26>;
status = "disabled";
};
};
@@ -199,6 +201,15 @@
clock-output-names = "pll1";
};
+ pll2: clk@01c20008 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-pll2-clk";
+ reg = <0x01c20008 0x8>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll2-1x", "pll2-2x",
+ "pll2-4x", "pll2-8x";
+ };
+
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun7i-a20-pll4-clk";
@@ -465,6 +476,14 @@
clock-output-names = "ir1";
};
+ keypad_clk: clk@01c200c4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c200c4 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "keypad";
+ };
+
usb_clk: clk@01c200cc {
#clock-cells = <1>;
#reset-cells = <1>;
@@ -483,6 +502,48 @@
clock-output-names = "spi3";
};
+ dram_gates: clk@01c20100 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-dram-gates-clk";
+ reg = <0x01c20100 0x4>;
+ clocks = <&pll5 0>;
+ clock-indices = <0>,
+ <1>, <2>,
+ <3>,
+ <4>,
+ <5>, <6>,
+ <15>,
+ <24>, <25>,
+ <26>, <27>,
+ <28>, <29>;
+ clock-output-names = "dram_ve",
+ "dram_csi0", "dram_csi1",
+ "dram_ts",
+ "dram_tvd",
+ "dram_tve0", "dram_tve1",
+ "dram_output",
+ "dram_de_fe1", "dram_de_fe0",
+ "dram_de_be0", "dram_de_be1",
+ "dram_de_mp", "dram_ace";
+ };
+
+ ve_clk: clk@01c2013c {
+ #clock-cells = <0>;
+ #reset-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ve-clk";
+ reg = <0x01c2013c 0x4>;
+ clocks = <&pll4>;
+ clock-output-names = "ve";
+ };
+
+ codec_clk: clk@01c20140 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-codec-clk";
+ reg = <0x01c20140 0x4>;
+ clocks = <&pll2 SUN4I_A10_PLL2_1X>;
+ clock-output-names = "codec";
+ };
+
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-mbus-clk";
@@ -1190,6 +1251,19 @@
status = "disabled";
};
+ codec: codec@01c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun7i-a20-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 0>, <&codec_clk>;
+ clock-names = "apb", "codec";
+ dmas = <&dma SUN4I_DMA_NORMAL 19>,
+ <&dma SUN4I_DMA_NORMAL 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 27a925e..6f88fb0 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -56,7 +56,7 @@
#size-cells = <1>;
ranges;
- framebuffer@0 {
+ simplefb_lcd: framebuffer@0 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
@@ -175,31 +175,6 @@
clock-output-names = "apb1";
};
- ahb1_gates: clk@01c20060 {
- #clock-cells = <1>;
- compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
- reg = <0x01c20060 0x8>;
- clocks = <&ahb1>;
- clock-indices = <1>, <6>,
- <8>, <9>, <10>,
- <13>, <14>,
- <19>, <20>,
- <21>, <24>, <26>,
- <29>, <32>, <36>,
- <40>, <44>, <46>,
- <52>, <54>,
- <57>;
- 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";
@@ -412,6 +387,13 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ pwm0_pins: pwm0 {
+ allwinner,pins = "PH0";
+ allwinner,function = "pwm0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PH2", "PH3";
allwinner,function = "i2c0";
@@ -466,6 +448,14 @@
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
};
+ pwm: pwm@01c21400 {
+ compatible = "allwinner,sun7i-a20-pwm";
+ reg = <0x01c21400 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
lradc: lradc@01c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
@@ -589,6 +579,14 @@
<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,sun8i-a23-prcm";
reg = <0x01f01400 0x200>;
@@ -657,10 +655,18 @@
resets = <&apb0_rst 0>;
gpio-controller;
interrupt-controller;
+ #interrupt-cells = <3>;
#address-cells = <1>;
#size-cells = <0>;
#gpio-cells = <3>;
+ r_rsb_pins: r_rsb {
+ allwinner,pins = "PL0", "PL1";
+ allwinner,function = "s_rsb";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
r_uart_pins_a: r_uart@0 {
allwinner,pins = "PL2", "PL3";
allwinner,function = "s_uart";
@@ -668,5 +674,19 @@
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
+
+ r_rsb: rsb@01f03400 {
+ compatible = "allwinner,sun8i-a23-rsb";
+ reg = <0x01f03400 0x400>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb0_gates 3>;
+ clock-frequency = <3000000>;
+ resets = <&apb0_rst 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_rsb_pins>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
};
diff --git a/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts b/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts
new file mode 100644
index 0000000..1aeb06c
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ *
+ * 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 = "Allwinner GT90H Quad Core Tablet (v4)";
+ compatible = "allwinner,gt90h-v4", "allwinner,sun8i-a33";
+
+ aliases {
+ serial0 = &r_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&lradc {
+ 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>;
+ };
+
+ button@600 {
+ label = "Back";
+ linux,code = <KEY_BACK>;
+ channel = <0>;
+ voltage = <600000>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gt90h>;
+ /* FIXME this really is aldo1, correct once we've pmic support */
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+ cd-inverted;
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_gt90h: mmc0_cd_pin@0 {
+ allwinner,pins = "PB4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&r_uart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_uart_pins_a>;
+ status = "okay";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
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
index 382d64c..c2f22fc 100644..120000
--- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
@@ -1,54 +1 @@
-/*
- * 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.
- *
- * 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";
-};
+sun8i-a23-q8-tablet.dts \ No newline at end of file
diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
index 8d9da68..c2f22fc 100644..120000
--- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
@@ -1,136 +1 @@
-/*
- * 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.
- *
- * 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 {
- stdout-path = "serial0:115200n8";
- };
-};
-
-&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>;
- /* pull-ups and devices require PMIC regulator */
- status = "failed";
-};
-
-&lradc {
- 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>;
- };
-};
-
-&mmc0 {
- 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";
-};
-
-&pio {
- 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>;
- };
-};
-
-&r_uart {
- pinctrl-names = "default";
- pinctrl-0 = <&r_uart_pins_a>;
- status = "okay";
-};
-
-&usb_otg {
- dr_mode = "host";
- status = "okay";
-};
-
-&usbphy {
- status = "okay";
-};
+sun8i-a23-q8-tablet.dts \ No newline at end of file
diff --git a/arch/arm/boot/dts/sun8i-a23-q8-tablet.dts b/arch/arm/boot/dts/sun8i-a23-q8-tablet.dts
new file mode 100644
index 0000000..6062ea7
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-q8-tablet.dts
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ * 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 "sun8i-q8-common.dtsi"
+
+/ {
+ model = "Q8 A23 Tablet";
+ compatible = "allwinner,q8-a23", "allwinner,sun8i-a23";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi
index 2cc27c7..92e6616 100644
--- a/arch/arm/boot/dts/sun8i-a23.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23.dtsi
@@ -50,6 +50,31 @@
};
clocks {
+ ahb1_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb1>;
+ clock-indices = <1>, <6>,
+ <8>, <9>, <10>,
+ <13>, <14>,
+ <19>, <20>,
+ <21>, <24>, <26>,
+ <29>, <32>, <36>,
+ <40>, <44>, <46>,
+ <52>, <53>,
+ <54>, <57>;
+ 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_msgbox",
+ "ahb1_spinlock", "ahb1_drc";
+ };
+
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun8i-a23-mbus-clk";
diff --git a/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts b/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
index 19db844..4519fd7 100644..120000
--- a/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
+++ b/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
@@ -1,88 +1 @@
-/*
- * Copyright 2015 Vishnu Patekar
- * Vishnu Patekar <vishnupatekar0510@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 "sun8i-a33.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 = "ET Q8 Quad Core Tablet (v1.6)";
- compatible = "et,q8-v1.6", "allwinner,sun8i-a33";
-
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-};
-
-&lradc {
- 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>;
- };
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
-};
+sun8i-a33-q8-tablet.dts \ No newline at end of file
diff --git a/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts b/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
index a438975..4519fd7 100644..120000
--- a/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
+++ b/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
@@ -1,133 +1 @@
-/*
- * 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.
- *
- * 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-a33.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 Quad Core Tablet (v1.2)";
- compatible = "ippo,a33-q8h-v1.2", "allwinner,sun8i-a33";
-
- aliases {
- serial0 = &r_uart;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins_a>;
- status = "okay";
-};
-
-&i2c1 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_pins_a>;
- status = "okay";
-};
-
-&lradc {
- 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>;
- };
-};
-
-&mmc0 {
- 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";
-};
-
-&pio {
- 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>;
- };
-};
-
-&r_uart {
- pinctrl-names = "default";
- pinctrl-0 = <&r_uart_pins_a>;
- status = "okay";
-};
-
-/*
- * FIXME for now we only support host mode and rely on u-boot to have
- * turned on Vbus which is controlled by the axp223 pmic on the board.
- *
- * Once we have axp223 support we should switch to fully supporting otg.
- */
-&usb_otg {
- dr_mode = "host";
- status = "okay";
-};
-
-&usbphy {
- status = "okay";
-};
+sun8i-a33-q8-tablet.dts \ No newline at end of file
diff --git a/arch/arm/boot/dts/sun8i-a33-q8-tablet.dts b/arch/arm/boot/dts/sun8i-a33-q8-tablet.dts
new file mode 100644
index 0000000..44b3229
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a33-q8-tablet.dts
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ * 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-a33.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+ model = "Q8 A33 Tablet";
+ compatible = "allwinner,q8-a33", "allwinner,sun8i-a33";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index 1d5390d..13ce68f 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -130,6 +130,10 @@
};
};
+&r_rsb {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_b>;
diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index faa7d3c..001d840 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -72,6 +72,41 @@
clock-output-names = "pll11";
};
+ ahb1_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a33-ahb1-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb1>;
+ clock-indices = <1>, <5>,
+ <6>, <8>, <9>,
+ <10>, <13>, <14>,
+ <19>, <20>,
+ <21>, <24>, <26>,
+ <29>, <32>, <36>,
+ <40>, <44>, <46>,
+ <52>, <53>,
+ <54>, <57>,
+ <58>;
+ clock-output-names = "ahb1_mipidsi", "ahb1_ss",
+ "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_msgbox",
+ "ahb1_spinlock", "ahb1_drc",
+ "ahb1_sat";
+ };
+
+ ss_clk: clk@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 0>;
+ clock-output-names = "ss";
+ };
+
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun8i-a23-mbus-clk";
@@ -82,6 +117,16 @@
};
soc@01c00000 {
+ crypto: crypto-engine@01c15000 {
+ compatible = "allwinner,sun4i-a10-crypto";
+ reg = <0x01c15000 0x1000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 5>, <&ss_clk>;
+ clock-names = "ahb", "mod";
+ resets = <&ahb1_rst 5>;
+ reset-names = "ahb";
+ };
+
usb_otg: usb@01c19000 {
compatible = "allwinner,sun8i-a33-musb";
reg = <0x01c19000 0x0400>;
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
new file mode 100644
index 0000000..e67df59
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jenskuske@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 "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Xunlong Orange Pi Plus";
+ compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ cd-inverted;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
new file mode 100644
index 0000000..1524130e
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2015 Jens Kuske <jenskuske@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 "skeleton.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>;
+
+ 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>;
+ };
+ };
+
+ 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)>;
+ };
+
+ 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";
+ };
+
+ pll6d2: pll6d2_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clock-div = <2>;
+ clock-mult = <1>;
+ clocks = <&pll6 0>;
+ clock-output-names = "pll6d2";
+ };
+
+ /* dummy clock until pll6 can be reused */
+ pll8: pll8_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <1>;
+ clock-output-names = "pll8";
+ };
+
+ cpu: cpu_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-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";
+ };
+
+ ahb2: ahb2_clk@01c2005c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-h3-ahb2-clk";
+ reg = <0x01c2005c 0x4>;
+ clocks = <&ahb1>, <&pll6d2>;
+ clock-output-names = "ahb2";
+ };
+
+ apb1: apb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ apb2: 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";
+ };
+
+ bus_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-h3-bus-gates-clk";
+ reg = <0x01c20060 0x14>;
+ clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>;
+ clock-names = "ahb1", "ahb2", "apb1", "apb2";
+ clock-indices = <5>, <6>, <8>,
+ <9>, <10>, <13>,
+ <14>, <17>, <18>,
+ <19>, <20>,
+ <21>, <23>,
+ <24>, <25>,
+ <26>, <27>,
+ <28>, <29>,
+ <30>, <31>, <32>,
+ <35>, <36>, <37>,
+ <40>, <41>, <43>,
+ <44>, <52>, <53>,
+ <54>, <64>,
+ <65>, <69>, <72>,
+ <76>, <77>, <78>,
+ <96>, <97>, <98>,
+ <112>, <113>,
+ <114>, <115>,
+ <116>, <128>, <135>;
+ clock-output-names = "bus_ce", "bus_dma", "bus_mmc0",
+ "bus_mmc1", "bus_mmc2", "bus_nand",
+ "bus_sdram", "bus_gmac", "bus_ts",
+ "bus_hstimer", "bus_spi0",
+ "bus_spi1", "bus_otg",
+ "bus_otg_ehci0", "bus_ehci1",
+ "bus_ehci2", "bus_ehci3",
+ "bus_otg_ohci0", "bus_ohci1",
+ "bus_ohci2", "bus_ohci3", "bus_ve",
+ "bus_lcd0", "bus_lcd1", "bus_deint",
+ "bus_csi", "bus_tve", "bus_hdmi",
+ "bus_de", "bus_gpu", "bus_msgbox",
+ "bus_spinlock", "bus_codec",
+ "bus_spdif", "bus_pio", "bus_ths",
+ "bus_i2s0", "bus_i2s1", "bus_i2s2",
+ "bus_i2c0", "bus_i2c1", "bus_i2c2",
+ "bus_uart0", "bus_uart1",
+ "bus_uart2", "bus_uart3",
+ "bus_scr", "bus_ephy", "bus_dbg";
+ };
+
+ mmc0_clk: clk@01c20088 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-a10-mmc-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 0>, <&pll8>;
+ 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>, <&pll8>;
+ 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>, <&pll8>;
+ 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 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma: dma-controller@01c02000 {
+ compatible = "allwinner,sun8i-h3-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bus_gates 6>;
+ resets = <&ahb_rst 6>;
+ #dma-cells = <1>;
+ };
+
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&bus_gates 8>,
+ <&mmc0_clk 0>,
+ <&mmc0_clk 1>,
+ <&mmc0_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb_rst 8>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&bus_gates 9>,
+ <&mmc1_clk 0>,
+ <&mmc1_clk 1>,
+ <&mmc1_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb_rst 9>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&bus_gates 10>,
+ <&mmc2_clk 0>,
+ <&mmc2_clk 1>,
+ <&mmc2_clk 2>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ahb_rst 10>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ pio: pinctrl@01c20800 {
+ compatible = "allwinner,sun8i-h3-pinctrl";
+ reg = <0x01c20800 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bus_gates 69>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart0_pins_a: uart0@0 {
+ allwinner,pins = "PA4", "PA5";
+ 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>;
+ };
+
+ mmc0_cd_pin: mmc0_cd_pin@0 {
+ allwinner,pins = "PF6";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ 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>;
+ };
+ };
+
+ ahb_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>;
+ clocks = <&osc24M>;
+ };
+
+ wdt0: watchdog@01c20ca0 {
+ compatible = "allwinner,sun6i-a31-wdt";
+ reg = <0x01c20ca0 0x20>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ 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 = <&bus_gates 112>;
+ 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 = <&bus_gates 113>;
+ 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 = <&bus_gates 114>;
+ 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 = <&bus_gates 115>;
+ resets = <&apb2_rst 19>;
+ dmas = <&dma 9>, <&dma 9>;
+ dma-names = "rx", "tx";
+ 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>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sun8i-q8-common.dtsi b/arch/arm/boot/dts/sun8i-q8-common.dtsi
new file mode 100644
index 0000000..1a69231
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-q8-common.dtsi
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ *
+ * 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 "sunxi-q8-common.dtsi"
+
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+ aliases {
+ serial0 = &r_uart;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_en_pin_q8>;
+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+ default-brightness-level = <8>;
+ enable-gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+ /* backlight is powered by AXP223 DC1SW */
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+ cd-inverted;
+ status = "okay";
+};
+
+&pio {
+ bl_en_pin_q8: bl_en_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_q8: mmc0_cd_pin@0 {
+ allwinner,pins = "PB4";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&r_rsb {
+ status = "okay";
+};
+
+&r_uart {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_uart_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
index 6484dcf..382bd9f 100644
--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
@@ -62,9 +62,31 @@
stdout-path = "serial0:115200n8";
};
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_cubieboard4>;
+
+ green {
+ label = "cubieboard4:green:usr";
+ gpios = <&pio 7 17 GPIO_ACTIVE_HIGH>; /* PH17 */
+ };
+
+ red {
+ label = "cubieboard4:red:usr";
+ gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+ };
+ };
};
&pio {
+ led_pins_cubieboard4: led-pins@0 {
+ allwinner,pins = "PH6", "PH17";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
mmc0_cd_pin_cubieboard4: mmc0_cd_pin@0 {
allwinner,pins = "PH18";
allwinner,function = "gpio_in";
@@ -92,6 +114,14 @@
status = "okay";
};
+&r_ir {
+ status = "okay";
+};
+
+&r_rsb {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index 6ce4b5e..c0060e4 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -65,7 +65,7 @@
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
- pinctrl-0 = <&led_pins_optimus>;
+ pinctrl-0 = <&led_pins_optimus>, <&led_r_pins_optimus>;
/* The LED names match those found on the board */
@@ -74,7 +74,10 @@
gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
};
- /* led3 is on PM15, in R_PIO */
+ led3 {
+ label = "optimus:led3:usr";
+ gpios = <&r_pio 1 15 GPIO_ACTIVE_HIGH>; /* PM15 */
+ };
led4 {
label = "optimus:led4:usr";
@@ -180,6 +183,23 @@
status = "okay";
};
+&r_ir {
+ status = "okay";
+};
+
+&r_pio {
+ led_r_pins_optimus: led-pins@1 {
+ allwinner,pins = "PM15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&r_rsb {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 5908e3d..e838f20 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -128,6 +128,17 @@
*/
ranges = <0 0 0 0x20000000>;
+ /*
+ * This clock is actually configurable from the PRCM address
+ * space. The external 24M oscillator can be turned off, and
+ * the clock switched to an internal 16M RC oscillator. Under
+ * normal operation there's no reason to do this, and the
+ * default is to use the external good one, so just model this
+ * as a fixed clock. Also it is not entirely clear if the
+ * osc24M mux in the PRCM affects the entire clock tree, which
+ * would also throw all the PLL clock rates off, or just the
+ * downstream clocks in the PRCM.
+ */
osc24M: osc24M_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
@@ -135,6 +146,13 @@
clock-output-names = "osc24M";
};
+ /*
+ * The 32k clock is from an external source, normally the
+ * AC100 codec/RTC chip. This clock is by default enabled
+ * and clocked at 32768 Hz, from the oscillator connected
+ * to the AC100. It is configurable, but no such driver or
+ * bindings exist yet.
+ */
osc32k: osc32k_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
@@ -164,6 +182,14 @@
"usb_phy2", "usb_hsic_12M";
};
+ pll3: clk@06000008 {
+ /* placeholder until implemented */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-rate = <0>;
+ clock-output-names = "pll3";
+ };
+
pll4: clk@0600000c {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-pll4-clk";
@@ -350,6 +376,68 @@
"apb1_uart2", "apb1_uart3",
"apb1_uart4", "apb1_uart5";
};
+
+ cpus_clk: clk@08001410 {
+ compatible = "allwinner,sun9i-a80-cpus-clk";
+ reg = <0x08001410 0x4>;
+ #clock-cells = <0>;
+ clocks = <&osc32k>, <&osc24M>, <&pll4>, <&pll3>;
+ clock-output-names = "cpus";
+ };
+
+ ahbs: ahbs_clk {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clocks = <&cpus_clk>;
+ clock-output-names = "ahbs";
+ };
+
+ apbs: clk@0800141c {
+ compatible = "allwinner,sun8i-a23-apb0-clk";
+ reg = <0x0800141c 0x4>;
+ #clock-cells = <0>;
+ clocks = <&ahbs>;
+ clock-output-names = "apbs";
+ };
+
+ apbs_gates: clk@08001428 {
+ compatible = "allwinner,sun9i-a80-apbs-gates-clk";
+ reg = <0x08001428 0x4>;
+ #clock-cells = <1>;
+ clocks = <&apbs>;
+ clock-indices = <0>, <1>,
+ <2>, <3>,
+ <4>, <5>,
+ <6>, <7>,
+ <12>, <13>,
+ <16>, <17>,
+ <18>, <20>;
+ clock-output-names = "apbs_pio", "apbs_ir",
+ "apbs_timer", "apbs_rsb",
+ "apbs_uart", "apbs_1wire",
+ "apbs_i2c0", "apbs_i2c1",
+ "apbs_ps2_0", "apbs_ps2_1",
+ "apbs_dma", "apbs_i2s0",
+ "apbs_i2s1", "apbs_twd";
+ };
+
+ r_1wire_clk: clk@08001450 {
+ reg = <0x08001450 0x4>;
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ clocks = <&osc32k>, <&osc24M>;
+ clock-output-names = "r_1wire";
+ };
+
+ r_ir_clk: clk@08001454 {
+ reg = <0x08001454 0x4>;
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ clocks = <&osc32k>, <&osc24M>;
+ clock-output-names = "r_ir";
+ };
};
soc {
@@ -594,7 +682,7 @@
clocks = <&apb0_gates 5>;
gpio-controller;
interrupt-controller;
- #interrupt-cells = <2>;
+ #interrupt-cells = <3>;
#size-cells = <0>;
#gpio-cells = <3>;
@@ -764,14 +852,83 @@
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
};
+ apbs_rst: reset@080014b0 {
+ reg = <0x080014b0 0x4>;
+ compatible = "allwinner,sun6i-a31-clock-reset";
+ #reset-cells = <1>;
+ };
+
+ nmi_intc: interrupt-controller@080015a0 {
+ compatible = "allwinner,sun9i-a80-nmi";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x080015a0 0xc>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ r_ir: ir@08002000 {
+ compatible = "allwinner,sun5i-a13-ir";
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_ir_pins>;
+ clocks = <&apbs_gates 1>, <&r_ir_clk>;
+ clock-names = "apb", "ir";
+ resets = <&apbs_rst 1>;
+ reg = <0x08002000 0x40>;
+ status = "disabled";
+ };
+
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>;
+ clocks = <&apbs_gates 4>;
+ resets = <&apbs_rst 4>;
+ status = "disabled";
+ };
+
+ r_pio: pinctrl@08002c00 {
+ compatible = "allwinner,sun9i-a80-r-pinctrl";
+ reg = <0x08002c00 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apbs_gates 0>;
+ resets = <&apbs_rst 0>;
+ gpio-controller;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #gpio-cells = <3>;
+
+ r_ir_pins: r_ir {
+ allwinner,pins = "PL6";
+ allwinner,function = "s_cir_rx";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ r_rsb_pins: r_rsb {
+ allwinner,pins = "PN0", "PN1";
+ allwinner,function = "s_rsb";
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+ };
+
+ r_rsb: i2c@08003400 {
+ compatible = "allwinner,sun8i-a23-rsb";
+ reg = <0x08003400 0x400>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apbs_gates 3>;
+ clock-frequency = <3000000>;
+ resets = <&apbs_rst 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_rsb_pins>;
status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
};
diff --git a/arch/arm/boot/dts/sunxi-q8-common.dtsi b/arch/arm/boot/dts/sunxi-q8-common.dtsi
new file mode 100644
index 0000000..b824146
--- /dev/null
+++ b/arch/arm/boot/dts/sunxi-q8-common.dtsi
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ *
+ * 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/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+#include "sunxi-common-regulators.dtsi"
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&lradc {
+ 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>;
+ };
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/tango4-common.dtsi b/arch/arm/boot/dts/tango4-common.dtsi
new file mode 100644
index 0000000..ef665d2
--- /dev/null
+++ b/arch/arm/boot/dts/tango4-common.dtsi
@@ -0,0 +1,130 @@
+/*
+ * Based on Mans Rullgard's Tango3 DT
+ * https://github.com/mansr/linux-tangox
+ */
+
+#define CPU_CLK 0
+#define SYS_CLK 1
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ periph_clk: periph_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&clkgen CPU_CLK>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ #clock-cells = <0>;
+ };
+
+ mpcore {
+ compatible = "simple-bus";
+ ranges = <0x00000000 0x20000000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ scu@0 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x0 0x100>;
+ };
+
+ twd@600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x600 0x10>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&periph_clk>;
+ always-on;
+ };
+
+ gic: interrupt-controller@1000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x1000 0x1000>, <0x100 0x100>;
+ };
+ };
+
+ l2cc: l2-cache-controller@20100000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x20100000 0x1000>;
+ cache-level = <2>;
+ cache-unified;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&irq0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ xtal: xtal {
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ #clock-cells = <0>;
+ };
+
+ clkgen: clkgen@10000 {
+ compatible = "sigma,tango4-clkgen";
+ reg = <0x10000 0x40>;
+ clocks = <&xtal>;
+ #clock-cells = <1>;
+ };
+
+ tick-counter@10048 {
+ compatible = "sigma,tick-counter";
+ reg = <0x10048 0x4>;
+ clocks = <&xtal>;
+ };
+
+ uart: serial@10700 {
+ compatible = "ralink,rt2880-uart";
+ reg = <0x10700 0x30>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+ reg-shift = <2>;
+ };
+
+ eth0: ethernet@26000 {
+ compatible = "sigma,smp8734-ethernet";
+ reg = <0x26000 0x800>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkgen SYS_CLK>;
+ };
+
+ intc: interrupt-controller@6e000 {
+ compatible = "sigma,smp8642-intc";
+ reg = <0x6e000 0x400>;
+ ranges = <0 0x6e000 0x400>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ irq0: irq0@000 {
+ reg = <0x000 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ irq1: irq1@100 {
+ reg = <0x100 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ irq2: irq2@300 {
+ reg = <0x300 0x100>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tango4-smp8758.dtsi b/arch/arm/boot/dts/tango4-smp8758.dtsi
new file mode 100644
index 0000000..7ed88ee
--- /dev/null
+++ b/arch/arm/boot/dts/tango4-smp8758.dtsi
@@ -0,0 +1,31 @@
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "sigma,tango4-smp";
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&l2cc>;
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&l2cc>;
+ device_type = "cpu";
+ reg = <1>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupt-affinity = <&cpu0>, <&cpu1>;
+ interrupts =
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/tango4-vantage-1172.dts b/arch/arm/boot/dts/tango4-vantage-1172.dts
new file mode 100644
index 0000000..3e5b9c8
--- /dev/null
+++ b/arch/arm/boot/dts/tango4-vantage-1172.dts
@@ -0,0 +1,37 @@
+/dts-v1/;
+
+#include "tango4-smp8758.dtsi"
+#include "tango4-common.dtsi"
+
+/ {
+ model = "Sigma Designs SMP8758 Vantage-1172 Rev E1";
+ compatible = "sigma,vantage-1172", "sigma,smp8758", "sigma,tango4";
+
+ aliases {
+ serial = &uart;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>; /* 2 GB */
+ };
+
+ chosen {
+ stdout-path = "serial:115200n8";
+ };
+};
+
+&eth0 {
+ phy-connection-type = "rgmii";
+ phy-handle = <&eth0_phy>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Atheros AR8035 */
+ eth0_phy: ethernet-phy@4 {
+ compatible = "ethernet-phy-id004d.d072",
+ "ethernet-phy-ieee802.3-c22";
+ interrupts = <37 IRQ_TYPE_EDGE_RISING>;
+ reg = <4>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi
index a9aec23..ec1aa64 100644
--- a/arch/arm/boot/dts/tegra124-nyan.dtsi
+++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
@@ -159,7 +159,7 @@
vin-ldo9-10-supply = <&vdd_5v0_sys>;
vin-ldo11-supply = <&vdd_3v3_run>;
- sd0 {
+ vdd_cpu: sd0 {
regulator-name = "+VDD_CPU_AP";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1350000>;
@@ -397,6 +397,13 @@
non-removable;
};
+ /* CPU DFLL clock */
+ clock@0,70110000 {
+ status = "disabled";
+ vdd-cpu-supply = <&vdd_cpu>;
+ nvidia,i2c-fs-rate = <400000>;
+ };
+
ahub@0,70300000 {
i2s@0,70301100 {
status = "okay";
@@ -487,6 +494,12 @@
};
};
+ cpus {
+ cpu@0 {
+ vdd-cpu-supply = <&vdd_cpu>;
+ };
+ };
+
gpio-keys {
compatible = "gpio-keys";
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 819e2ae..68669f7 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -610,26 +610,20 @@
sata@0,70020000 {
compatible = "nvidia,tegra124-ahci";
-
reg = <0x0 0x70027000 0x0 0x2000>, /* AHCI */
- <0x0 0x70020000 0x0 0x7000>; /* SATA */
-
+ <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>;
+ <&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>;
+ <&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";
};
@@ -638,7 +632,7 @@
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_HDA2HDMI>,
<&tegra_car TEGRA124_CLK_HDA2CODEC_2X>;
clock-names = "hda", "hda2hdmi", "hda2codec_2x";
resets = <&tegra_car 125>, /* hda */
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 969b828..33173e1 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -603,8 +603,8 @@
<&tegra_car TEGRA20_CLK_PLL_E>;
clock-names = "pex", "afi", "pll_e";
resets = <&tegra_car 70>,
- <&tegra_car 72>,
- <&tegra_car 74>;
+ <&tegra_car 72>,
+ <&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled";
diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index 6236bde..f2879cf 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -126,6 +126,10 @@
};
};
+ hda@70030000 {
+ status = "okay";
+ };
+
sd1: sdhci@78000000 {
status = "okay";
bus-width = <4>;
@@ -149,6 +153,7 @@
usb-phy@7d000000 {
status = "okay";
+ dr_mode = "otg";
vbus-supply = <&usbo1_vbus_reg>;
};
@@ -175,7 +180,7 @@
backlight: backlight {
compatible = "pwm-backlight";
- /* PWM0 */
+ /* PWM_BKL1 */
pwms = <&pwm 0 5000000>;
brightness-levels = <255 231 223 207 191 159 127 0>;
default-brightness-level = <6>;
@@ -186,10 +191,10 @@
gpio-keys {
compatible = "gpio-keys";
- power {
- label = "Power";
+ wakeup {
+ label = "WAKE1_MICO";
gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>;
- linux,code = <KEY_POWER>;
+ linux,code = <KEY_WAKEUP>;
debounce-interval = <10>;
gpio-key,wakeup;
};
diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index a5446cb..bf36127 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -1,8 +1,9 @@
#include "tegra30.dtsi"
/*
- * Toradex Apalis T30 Device Tree
- * Compatible for Revisions 1GB: V1.0A; 2GB: V1.0B, V1.0C
+ * Toradex Apalis T30 Module Device Tree
+ * Compatible for Revisions 1GB: V1.0A, V1.1A; 1GB IT: V1.1A;
+ * 2GB: V1.0B, V1.0C, V1.0E, V1.1A
*/
/ {
model = "Toradex Apalis T30";
@@ -33,8 +34,8 @@
host1x@50000000 {
hdmi@54280000 {
- vdd-supply = <&sys_3v3_reg>;
- pll-supply = <&vio_reg>;
+ vdd-supply = <&avdd_hdmi_3v3_reg>;
+ pll-supply = <&avdd_hdmi_pll_1v8_reg>;
nvidia,hpd-gpio =
<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
@@ -57,25 +58,25 @@
/* Apalis BKL1_PWM */
uart3_rts_n_pc0 {
- nvidia,pins = "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,pins = "uart3_cts_n_pa1";
+ nvidia,function = "rsvd2";
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,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>;
@@ -91,10 +92,10 @@
/* Apalis CAN2 on SPI4 */
gmi_a16_pj7 {
- nvidia,pins = "gmi_a16_pj7",
- "gmi_a17_pb0",
- "gmi_a18_pb1",
- "gmi_a19_pk7";
+ 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>;
@@ -108,6 +109,30 @@
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
+ /* Apalis Digital Audio */
+ clk1_req_pee2 {
+ nvidia,pins = "clk1_req_pee2";
+ nvidia,function = "hda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <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>;
+ };
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0",
+ "dap1_din_pn1",
+ "dap1_dout_pn2",
+ "dap1_sclk_pn3";
+ nvidia,function = "hda";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
/* Apalis I2C3 */
cam_i2c_scl_pbb1 {
nvidia,pins = "cam_i2c_scl_pbb1",
@@ -122,21 +147,21 @@
/* Apalis MMC1 */
sdmmc3_clk_pa6 {
- nvidia,pins = "sdmmc3_clk_pa6",
- "sdmmc3_cmd_pa7";
+ 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,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>;
@@ -151,32 +176,32 @@
};
/* Apalis PWM1 */
- gpio_pu6 {
- nvidia,pins = "gpio_pu6";
+ pu6 {
+ nvidia,pins = "pu6";
nvidia,function = "pwm3";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
/* Apalis PWM2 */
- gpio_pu5 {
- nvidia,pins = "gpio_pu5";
+ pu5 {
+ nvidia,pins = "pu5";
nvidia,function = "pwm2";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
/* Apalis PWM3 */
- gpio_pu4 {
- nvidia,pins = "gpio_pu4";
+ pu4 {
+ nvidia,pins = "pu4";
nvidia,function = "pwm1";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
/* Apalis PWM4 */
- gpio_pu3 {
- nvidia,pins = "gpio_pu3";
+ pu3 {
+ nvidia,pins = "pu3";
nvidia,function = "pwm0";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -198,11 +223,11 @@
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,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>;
@@ -218,10 +243,10 @@
/* Apalis SPI1 */
spi1_sck_px5 {
- nvidia,pins = "spi1_sck_px5",
- "spi1_mosi_px4",
- "spi1_miso_px7",
- "spi1_cs0_n_px6";
+ 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>;
@@ -229,10 +254,10 @@
/* Apalis SPI2 */
lcd_sck_pz4 {
- nvidia,pins = "lcd_sck_pz4",
- "lcd_sdout_pn5",
- "lcd_sdin_pz2",
- "lcd_cs0_n_pn4";
+ 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>;
@@ -240,14 +265,14 @@
/* 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,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>;
@@ -255,10 +280,10 @@
/* Apalis UART2 */
ulpi_clk_py0 {
- nvidia,pins = "ulpi_clk_py0",
- "ulpi_dir_py1",
- "ulpi_nxt_py2",
- "ulpi_stp_py3";
+ 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>;
@@ -266,8 +291,8 @@
/* Apalis UART3 */
uart2_rxd_pc3 {
- nvidia,pins = "uart2_rxd_pc3",
- "uart2_txd_pc2";
+ nvidia,pins = "uart2_rxd_pc3",
+ "uart2_txd_pc2";
nvidia,function = "uartb";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -275,8 +300,8 @@
/* Apalis UART4 */
uart3_rxd_pw7 {
- nvidia,pins = "uart3_rxd_pw7",
- "uart3_txd_pw6";
+ nvidia,pins = "uart3_rxd_pw7",
+ "uart3_txd_pw6";
nvidia,function = "uartc";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -312,21 +337,21 @@
/* eMMC (On-module) */
sdmmc4_clk_pcc4 {
- nvidia,pins = "sdmmc4_clk_pcc4",
- "sdmmc4_rst_n_pcc3";
+ 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,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>;
@@ -334,10 +359,10 @@
/* LVDS Transceiver Configuration */
pbb0 {
- nvidia,pins = "pbb0",
- "pbb7",
- "pcc1",
- "pcc2";
+ nvidia,pins = "pbb0",
+ "pbb7",
+ "pcc1",
+ "pcc2";
nvidia,function = "rsvd2";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -345,10 +370,10 @@
nvidia,lock = <TEGRA_PIN_DISABLE>;
};
pbb3 {
- nvidia,pins = "pbb3",
- "pbb4",
- "pbb5",
- "pbb6";
+ nvidia,pins = "pbb3",
+ "pbb4",
+ "pbb5",
+ "pbb6";
nvidia,function = "displayb";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -635,6 +660,7 @@
nvidia,sys-clock-req-active-high;
};
+ /* eMMC */
sdhci@78000600 {
status = "okay";
bus-width = <8>;
@@ -666,18 +692,40 @@
#address-cells = <1>;
#size-cells = <0>;
- sys_3v3_reg: regulator@100 {
+ avdd_hdmi_pll_1v8_reg: regulator@100 {
compatible = "regulator-fixed";
reg = <100>;
+ regulator-name = "+V1.8_AVDD_HDMI_PLL";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vio_reg>;
+ };
+
+ sys_3v3_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
regulator-name = "3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
- charge_pump_5v0_reg: regulator@101 {
+ avdd_hdmi_3v3_reg: regulator@102 {
compatible = "regulator-fixed";
- reg = <101>;
+ reg = <102>;
+ regulator-name = "+V3.3_AVDD_HDMI";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ charge_pump_5v0_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
regulator-name = "5v0";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index 4d3ddc5..3ff019f 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -55,7 +55,7 @@
/* M41T0M6 real time clock on carrier board */
rtc@68 {
- compatible = "stm,m41t00";
+ compatible = "st,m41t00";
reg = <0x68>;
};
};
@@ -84,6 +84,7 @@
};
};
+ /* SD/MMC */
sdhci@78000200 {
status = "okay";
bus-width = <4>;
@@ -136,10 +137,10 @@
gpio-keys {
compatible = "gpio-keys";
- power {
- label = "Power";
+ wakeup {
+ label = "SODIMM pin 45 wakeup";
gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
- linux,code = <KEY_POWER>;
+ linux,code = <KEY_WAKEUP>;
debounce-interval = <10>;
gpio-key,wakeup;
};
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index c4ed1be..2d8c58f 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -2,8 +2,8 @@
#include "tegra30.dtsi"
/*
- * Toradex Colibri T30 Device Tree
- * Compatible for Revisions 1.1B/1.1C/1.1D
+ * Toradex Colibri T30 Module Device Tree
+ * Compatible for Revisions V1.1B, V1.1C, V1.1D, V1.1E; IT: V1.1A
*/
/ {
model = "Toradex Colibri T30";
@@ -15,8 +15,8 @@
host1x@50000000 {
hdmi@54280000 {
- vdd-supply = <&sys_3v3_reg>;
- pll-supply = <&vio_reg>;
+ vdd-supply = <&avdd_hdmi_3v3_reg>;
+ pll-supply = <&avdd_hdmi_pll_1v8_reg>;
nvidia,hpd-gpio =
<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
@@ -39,7 +39,7 @@
/* Colibri Backlight PWM<A> */
sdmmc3_dat3_pb4 {
- nvidia,pins = "sdmmc3_dat3_pb4";
+ nvidia,pins = "sdmmc3_dat3_pb4";
nvidia,function = "pwm0";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -66,15 +66,6 @@
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";
@@ -83,11 +74,11 @@
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,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>;
@@ -95,17 +86,17 @@
/* Colibri SSP */
ulpi_clk_py0 {
- nvidia,pins = "ulpi_clk_py0",
- "ulpi_dir_py1",
- "ulpi_nxt_py2",
- "ulpi_stp_py3";
+ 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,pins = "sdmmc3_dat6_pd3",
+ "sdmmc3_dat7_pd4";
nvidia,function = "spdif";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
@@ -113,14 +104,14 @@
/* 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,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>;
@@ -128,10 +119,10 @@
/* Colibri UART_B */
gmi_a16_pj7 {
- nvidia,pins = "gmi_a16_pj7",
- "gmi_a17_pb0",
- "gmi_a18_pb1",
- "gmi_a19_pk7";
+ 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>;
@@ -139,8 +130,8 @@
/* Colibri UART_C */
uart2_rxd {
- nvidia,pins = "uart2_rxd_pc3",
- "uart2_txd_pc2";
+ nvidia,pins = "uart2_rxd_pc3",
+ "uart2_txd_pc2";
nvidia,function = "uartb";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
@@ -148,25 +139,59 @@
/* eMMC */
sdmmc4_clk_pcc4 {
- nvidia,pins = "sdmmc4_clk_pcc4",
- "sdmmc4_rst_n_pcc3";
+ 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,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>;
};
+
+ /* 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>;
+ };
};
};
@@ -236,7 +261,7 @@
/*
* EN_+V3.3 switching via FET:
* +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
- * see also v3_3 fixed supply
+ * see also 3v3 fixed supply
*/
ldo2_reg: ldo2 {
regulator-name = "en_3v3";
@@ -295,6 +320,46 @@
};
};
+ /* 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
@@ -331,7 +396,8 @@
nvidia,sys-clock-req-active-high;
};
- emmc: sdhci@78000600 {
+ /* eMMC */
+ sdhci@78000600 {
status = "okay";
bus-width = <8>;
non-removable;
@@ -365,18 +431,40 @@
#address-cells = <1>;
#size-cells = <0>;
- sys_3v3_reg: regulator@100 {
+ avdd_hdmi_pll_1v8_reg: regulator@100 {
compatible = "regulator-fixed";
reg = <100>;
+ regulator-name = "+V1.8_AVDD_HDMI_PLL";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vio_reg>;
+ };
+
+ sys_3v3_reg: regulator@101 {
+ compatible = "regulator-fixed";
+ reg = <101>;
regulator-name = "3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
- charge_pump_5v0_reg: regulator@101 {
+ avdd_hdmi_3v3_reg: regulator@102 {
compatible = "regulator-fixed";
- reg = <101>;
+ reg = <102>;
+ regulator-name = "+V3.3_AVDD_HDMI";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&sys_3v3_reg>;
+ };
+
+ charge_pump_5v0_reg: regulator@103 {
+ compatible = "regulator-fixed";
+ reg = <103>;
regulator-name = "5v0";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index c6938ad..313e260 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -42,8 +42,8 @@
<&tegra_car TEGRA30_CLK_CML0>;
clock-names = "pex", "afi", "pll_e", "cml";
resets = <&tegra_car 70>,
- <&tegra_car 72>,
- <&tegra_car 74>;
+ <&tegra_car 72>,
+ <&tegra_car 74>;
reset-names = "pex", "afi", "pcie_x";
status = "disabled";
@@ -153,7 +153,7 @@
&tegra_car TEGRA30_CLK_GR3D2>;
clock-names = "3d", "3d2";
resets = <&tegra_car 24>,
- <&tegra_car 98>;
+ <&tegra_car 98>;
reset-names = "3d", "3d2";
};
@@ -457,7 +457,7 @@
};
i2c@7000c000 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000c000 0x100>;
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
@@ -662,7 +662,7 @@
reg = <0x70030000 0x10000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA30_CLK_HDA>,
- <&tegra_car TEGRA30_CLK_HDA2HDMI>,
+ <&tegra_car TEGRA30_CLK_HDA2HDMI>,
<&tegra_car TEGRA30_CLK_HDA2CODEC_2X>;
clock-names = "hda", "hda2hdmi", "hda2codec_2x";
resets = <&tegra_car 125>, /* hda */
diff --git a/arch/arm/boot/dts/twl4030_omap3.dtsi b/arch/arm/boot/dts/twl4030_omap3.dtsi
index 3537ae5..5288e6d 100644
--- a/arch/arm/boot/dts/twl4030_omap3.dtsi
+++ b/arch/arm/boot/dts/twl4030_omap3.dtsi
@@ -19,7 +19,7 @@
*/
twl4030_pins: pinmux_twl4030_pins {
pinctrl-single,pins = <
- 0x1b0 (PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+ OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
>;
};
};
diff --git a/arch/arm/boot/dts/twl6030_omap4.dtsi b/arch/arm/boot/dts/twl6030_omap4.dtsi
index a4fa570..e373f59 100644
--- a/arch/arm/boot/dts/twl6030_omap4.dtsi
+++ b/arch/arm/boot/dts/twl6030_omap4.dtsi
@@ -24,7 +24,7 @@
&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_IOPAD(0x054, PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */
>;
};
};
@@ -32,7 +32,7 @@
&omap4_pmx_core {
twl6030_pins: pinmux_twl6030_pins {
pinctrl-single,pins = <
- 0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */
+ OMAP4_IOPAD(0x19e, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */
>;
};
};
diff --git a/arch/arm/boot/dts/uniphier-common32.dtsi b/arch/arm/boot/dts/uniphier-common32.dtsi
new file mode 100644
index 0000000..ea9301a
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-common32.dtsi
@@ -0,0 +1,135 @@
+/*
+ * Device Tree Source commonly used by UniPhier ARM SoCs
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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"
+
+/ {
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&intc>;
+
+ extbus: extbus {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart_clk>;
+ };
+
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart_clk>;
+ };
+
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&uart_clk>;
+ };
+
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&uart_clk>;
+ };
+
+ system-bus-controller@58c00000 {
+ compatible = "socionext,uniphier-system-bus-controller";
+ reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
+ };
+
+ timer@60000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x60000200 0x20>;
+ interrupts = <1 11 0x104>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ timer@60000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x60000600 0x20>;
+ interrupts = <1 13 0x104>;
+ clocks = <&arm_timer_clk>;
+ };
+
+ intc: interrupt-controller@60001000 {
+ compatible = "arm,cortex-a9-gic";
+ reg = <0x60001000 0x1000>,
+ <0x60000100 0x100>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ };
+
+ pinctrl: pinctrl@5f801000 {
+ /* specify compatible in each SoC DTSI */
+ reg = <0x5f801000 0xe00>;
+ };
+ };
+};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
index bfd3bb8..f1e9d40 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
@@ -57,8 +57,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &serial0;
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -74,12 +73,11 @@
};
&extbus {
- ranges = <0 0x00000000 0x0f000000 0x01000000
- 1 0x00000000 0x00000000 0x08000000>;
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
};
&support_card {
- ranges = <0x00000000 1 0x03f00000 0x00100000>;
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
};
&ethsc {
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
index a6a185f..34f0d8d 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
@@ -42,7 +42,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
/ {
compatible = "socionext,ph1-ld4";
@@ -55,6 +55,7 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
};
@@ -77,177 +78,105 @@
clock-frequency = <100000000>;
};
};
+};
- soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- extbus: extbus {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- };
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- interrupts = <0 33 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- interrupts = <0 35 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- interrupts = <0 37 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- interrupts = <0 29 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- i2c0: i2c@58400000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58400000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- interrupts = <0 41 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
-
- i2c1: i2c@58480000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58480000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- interrupts = <0 42 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
-
- /* chip-internal connection for DMD */
- i2c2: i2c@58500000 {
- compatible = "socionext,uniphier-i2c";
- reg = <0x58500000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- interrupts = <0 43 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <400000>;
- };
+&soc {
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>;
+ cache-unified;
+ cache-size = <(512 * 1024)>;
+ cache-sets = <256>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ };
- i2c3: i2c@58580000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58580000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- interrupts = <0 44 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
+ i2c0: i2c@58400000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58400000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
- };
+ i2c1: i2c@58480000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58480000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- usb0: usb@5a800100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a800100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0>;
- interrupts = <0 80 4>;
- };
+ /* chip-internal connection for DMD */
+ i2c2: i2c@58500000 {
+ compatible = "socionext,uniphier-i2c";
+ reg = <0x58500000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <400000>;
+ };
- usb1: usb@5a810100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a810100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb1>;
- interrupts = <0 81 4>;
- };
+ i2c3: i2c@58580000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58580000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- usb2: usb@5a820100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a820100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb2>;
- interrupts = <0 82 4>;
- };
+ usb0: usb@5a800100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a800100 0x100>;
+ interrupts = <0 80 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ };
- pinctrl: pinctrl@5f801000 {
- compatible = "socionext,ph1-ld4-pinctrl",
- "syscon";
- reg = <0x5f801000 0xe00>;
- };
+ usb1: usb@5a810100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a810100 0x100>;
+ interrupts = <0 81 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ };
- timer@60000200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x60000200 0x20>;
- interrupts = <1 11 0x104>;
- clocks = <&arm_timer_clk>;
- };
+ usb2: usb@5a820100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a820100 0x100>;
+ interrupts = <0 82 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ };
- timer@60000600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x60000600 0x20>;
- interrupts = <1 13 0x104>;
- clocks = <&arm_timer_clk>;
- };
+};
- intc: interrupt-controller@60001000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x60001000 0x1000>,
- <0x60000100 0x100>;
- };
- };
+&serial3 {
+ interrupts = <0 29 4>;
};
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+ compatible = "socionext,ph1-ld4-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
index f80f772..5baa9fc 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
@@ -57,8 +57,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &serial0;
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -76,12 +75,11 @@
};
&extbus {
- ranges = <0 0x00000000 0x0f000000 0x01000000
- 1 0x00000000 0x00000000 0x08000000>;
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
};
&support_card {
- ranges = <0x00000000 1 0x03f00000 0x00100000>;
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
};
&ethsc {
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
index c6499ee..5321152 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
@@ -53,7 +53,7 @@
compatible = "socionext,ph1-ld6b";
};
-/* UART3 unavilable: the pads are not wired to the package balls */
+/* UART3 unavailable: the pads are not wired to the package balls */
&serial3 {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
index 69a5b7d..2462668 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
@@ -57,8 +57,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &serial0;
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -76,12 +75,11 @@
};
&extbus {
- ranges = <0 0x00000000 0x0f000000 0x01000000
- 1 0x00000000 0x00000000 0x08000000>;
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
};
&support_card {
- ranges = <0x00000000 1 0x03f00000 0x00100000>;
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
};
&ethsc {
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
index e8bbc45..d78142f 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
@@ -42,7 +42,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
/ {
compatible = "socionext,ph1-pro4";
@@ -56,12 +56,14 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ next-level-cache = <&l2>;
};
};
@@ -84,192 +86,115 @@
clock-frequency = <50000000>;
};
};
+};
- soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- extbus: extbus {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- };
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- interrupts = <0 33 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- interrupts = <0 35 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- interrupts = <0 37 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- interrupts = <0 29 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- i2c0: i2c@58780000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58780000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- interrupts = <0 41 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c1: i2c@58781000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58781000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- interrupts = <0 42 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c2: i2c@58782000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58782000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- interrupts = <0 43 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c3: i2c@58783000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58783000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- interrupts = <0 44 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- /* i2c4 does not exist */
+&soc {
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>;
+ cache-unified;
+ cache-size = <(768 * 1024)>;
+ cache-sets = <256>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ };
- /* chip-internal connection for DMD */
- i2c5: i2c@58785000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58785000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 25 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c0: i2c@58780000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58780000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- /* chip-internal connection for HDMI */
- i2c6: i2c@58786000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58786000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 26 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c1: i2c@58781000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58781000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
- };
+ i2c2: i2c@58782000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58782000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- usb2: usb@5a800100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a800100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb2>;
- interrupts = <0 80 4>;
- };
+ i2c3: i2c@58783000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58783000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- usb3: usb@5a810100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a810100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb3>;
- interrupts = <0 81 4>;
- };
+ /* i2c4 does not exist */
- pinctrl: pinctrl@5f801000 {
- compatible = "socionext,ph1-pro4-pinctrl",
- "syscon";
- reg = <0x5f801000 0xe00>;
- };
+ /* chip-internal connection for DMD */
+ i2c5: i2c@58785000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58785000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 25 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
- timer@60000200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x60000200 0x20>;
- interrupts = <1 11 0x304>;
- clocks = <&arm_timer_clk>;
- };
+ /* chip-internal connection for HDMI */
+ i2c6: i2c@58786000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58786000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 26 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
- timer@60000600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x60000600 0x20>;
- interrupts = <1 13 0x304>;
- clocks = <&arm_timer_clk>;
- };
+ usb2: usb@5a800100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a800100 0x100>;
+ interrupts = <0 80 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ };
- intc: interrupt-controller@60001000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x60001000 0x1000>,
- <0x60000100 0x100>;
- };
+ usb3: usb@5a810100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a810100 0x100>;
+ interrupts = <0 81 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
};
};
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+ compatible = "socionext,ph1-pro4-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
index 59c2b12..2f389ea 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
@@ -42,7 +42,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
/ {
compatible = "socionext,ph1-pro5";
@@ -56,12 +56,14 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ next-level-cache = <&l2>;
};
};
@@ -84,169 +86,109 @@
clock-frequency = <50000000>;
};
};
+};
- soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- extbus: extbus {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- };
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- interrupts = <0 33 4>;
- clocks = <&uart_clk>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- interrupts = <0 35 4>;
- clocks = <&uart_clk>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- interrupts = <0 37 4>;
- clocks = <&uart_clk>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- interrupts = <0 177 4>;
- clocks = <&uart_clk>;
- };
-
- i2c0: i2c@58780000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58780000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- interrupts = <0 41 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c1: i2c@58781000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58781000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- interrupts = <0 42 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c2: i2c@58782000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58782000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- interrupts = <0 43 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
+&soc {
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x8>, <0x506c0000 0x400>;
+ interrupts = <0 190 4>, <0 191 4>;
+ cache-unified;
+ cache-size = <(2 * 1024 * 1024)>;
+ cache-sets = <512>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ next-level-cache = <&l3>;
+ };
- i2c3: i2c@58783000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58783000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- interrupts = <0 44 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
+ l3: l3-cache@500c8000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c8000 0x2000>, <0x503c8100 0x8>, <0x506c8000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>;
+ cache-unified;
+ cache-size = <(2 * 1024 * 1024)>;
+ cache-sets = <512>;
+ cache-line-size = <256>;
+ cache-level = <3>;
+ };
- /* i2c4 does not exist */
-
- /* chip-internal connection for DMD */
- i2c5: i2c@58785000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58785000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 25 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c0: i2c@58780000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58780000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- /* chip-internal connection for HDMI */
- i2c6: i2c@58786000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58786000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 26 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c1: i2c@58781000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58781000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
- };
+ i2c2: i2c@58782000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58782000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- pinctrl: pinctrl@5f801000 {
- compatible = "socionext,ph1-pro5-pinctrl", "syscon";
- reg = <0x5f801000 0xe00>;
- };
+ i2c3: i2c@58783000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58783000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- timer@60000200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x60000200 0x20>;
- interrupts = <1 11 0x304>;
- clocks = <&arm_timer_clk>;
- };
+ /* i2c4 does not exist */
- timer@60000600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x60000600 0x20>;
- interrupts = <1 13 0x304>;
- clocks = <&arm_timer_clk>;
- };
+ /* chip-internal connection for DMD */
+ i2c5: i2c@58785000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58785000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 25 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
- intc: interrupt-controller@60001000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x60001000 0x1000>,
- <0x60000100 0x100>;
- };
+ /* chip-internal connection for HDMI */
+ i2c6: i2c@58786000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58786000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 26 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
};
};
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+ compatible = "socionext,ph1-pro5-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
index 1a440f8..b7a03215 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
@@ -58,8 +58,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &serial0;
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -75,12 +74,11 @@
};
&extbus {
- ranges = <0 0x00000000 0x0f000000 0x01000000
- 1 0x00000000 0x00000000 0x08000000>;
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
};
&support_card {
- ranges = <0x00000000 1 0x03f00000 0x00100000>;
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
};
&ethsc {
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
index 3cc90cd..691a17d 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
@@ -56,12 +56,14 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ next-level-cache = <&l2>;
};
};
@@ -120,6 +122,18 @@
<0x20000100 0x100>;
};
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+ <0x506c0000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>;
+ cache-unified;
+ cache-size = <(512 * 1024)>;
+ cache-sets = <256>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ };
+
serial0: serial@54006800 {
compatible = "socionext,uniphier-uart";
status = "disabled";
@@ -202,10 +216,9 @@
clock-frequency = <400000>;
};
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
+ system-bus-controller@58c00000 {
+ compatible = "socionext,uniphier-system-bus-controller";
+ reg = <0x58c00000 0x400>, <0x59800000 0x2000>;
};
usb0: usb@5a800100 {
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
index 955d417..fc7250c 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
@@ -57,8 +57,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &serial0;
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -74,12 +73,11 @@
};
&extbus {
- ranges = <0 0x00000000 0x0f000000 0x01000000
- 1 0x00000000 0x00000000 0x08000000>;
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
};
&support_card {
- ranges = <0x00000000 1 0x03f00000 0x00100000>;
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
};
&ethsc {
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
index 58067df..7d06a1c 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
@@ -42,7 +42,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
/ {
compatible = "socionext,ph1-sld8";
@@ -55,6 +55,7 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
};
@@ -77,177 +78,104 @@
clock-frequency = <100000000>;
};
};
+};
- soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- extbus: extbus {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- };
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- interrupts = <0 33 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- interrupts = <0 35 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- interrupts = <0 37 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- interrupts = <0 29 4>;
- clocks = <&uart_clk>;
- fifo-size = <64>;
- };
-
- i2c0: i2c@58400000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58400000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- interrupts = <0 41 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
-
- i2c1: i2c@58480000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58480000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- interrupts = <0 42 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
-
- /* chip-internal connection for DMD */
- i2c2: i2c@58500000 {
- compatible = "socionext,uniphier-i2c";
- reg = <0x58500000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- interrupts = <0 43 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <400000>;
- };
-
- i2c3: i2c@58580000 {
- compatible = "socionext,uniphier-i2c";
- status = "disabled";
- reg = <0x58580000 0x40>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- interrupts = <0 44 1>;
- clocks = <&iobus_clk>;
- clock-frequency = <100000>;
- };
-
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
- };
+&soc {
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>;
+ cache-unified;
+ cache-size = <(256 * 1024)>;
+ cache-sets = <256>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ };
- usb0: usb@5a800100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a800100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0>;
- interrupts = <0 80 4>;
- };
+ i2c0: i2c@58400000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58400000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- usb1: usb@5a810100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a810100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb1>;
- interrupts = <0 81 4>;
- };
+ i2c1: i2c@58480000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58480000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- usb2: usb@5a820100 {
- compatible = "socionext,uniphier-ehci", "generic-ehci";
- status = "disabled";
- reg = <0x5a820100 0x100>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb2>;
- interrupts = <0 82 4>;
- };
+ /* chip-internal connection for DMD */
+ i2c2: i2c@58500000 {
+ compatible = "socionext,uniphier-i2c";
+ reg = <0x58500000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <400000>;
+ };
- pinctrl: pinctrl@5f801000 {
- compatible = "socionext,ph1-sld8-pinctrl",
- "syscon";
- reg = <0x5f801000 0xe00>;
- };
+ i2c3: i2c@58580000 {
+ compatible = "socionext,uniphier-i2c";
+ status = "disabled";
+ reg = <0x58580000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&iobus_clk>;
+ clock-frequency = <100000>;
+ };
- timer@60000200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x60000200 0x20>;
- interrupts = <1 11 0x104>;
- clocks = <&arm_timer_clk>;
- };
+ usb0: usb@5a800100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a800100 0x100>;
+ interrupts = <0 80 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ };
- timer@60000600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x60000600 0x20>;
- interrupts = <1 13 0x104>;
- clocks = <&arm_timer_clk>;
- };
+ usb1: usb@5a810100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a810100 0x100>;
+ interrupts = <0 81 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ };
- intc: interrupt-controller@60001000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x60001000 0x1000>,
- <0x60000100 0x100>;
- };
+ usb2: usb@5a820100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a820100 0x100>;
+ interrupts = <0 82 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
};
};
-/include/ "uniphier-pinctrl.dtsi"
+&serial3 {
+ interrupts = <0 29 4>;
+};
+
+&pinctrl {
+ compatible = "socionext,ph1-sld8-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts b/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts
new file mode 100644
index 0000000..9d7ec5c
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts
@@ -0,0 +1,78 @@
+/*
+ * Device Tree Source for UniPhier ProXstream2 Gentil Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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/ "uniphier-proxstream2.dtsi"
+
+/ {
+ model = "UniPhier ProXstream2 Gentil Board";
+ compatible = "socionext,proxstream2-gentil", "socionext,proxstream2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ i2c0 = &i2c0;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ };
+};
+
+&serial2 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/uniphier-proxstream2-vodka.dts b/arch/arm/boot/dts/uniphier-proxstream2-vodka.dts
new file mode 100644
index 0000000..498acac
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-proxstream2-vodka.dts
@@ -0,0 +1,78 @@
+/*
+ * Device Tree Source for UniPhier ProXstream2 Vodka Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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/ "uniphier-proxstream2.dtsi"
+
+/ {
+ model = "UniPhier ProXstream2 Vodka Board";
+ compatible = "socionext,proxstream2-vodka", "socionext,proxstream2";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ i2c0 = &i2c0;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ };
+};
+
+&serial2 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
index 4c7b246..6bd353f 100644
--- a/arch/arm/boot/dts/uniphier-proxstream2.dtsi
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -42,7 +42,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+/include/ "uniphier-common32.dtsi"
/ {
compatible = "socionext,proxstream2";
@@ -56,24 +56,28 @@
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
+ next-level-cache = <&l2>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
+ next-level-cache = <&l2>;
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <2>;
+ next-level-cache = <&l2>;
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <3>;
+ next-level-cache = <&l2>;
};
};
@@ -96,178 +100,106 @@
clock-frequency = <50000000>;
};
};
+};
- soc {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- interrupt-parent = <&intc>;
-
- extbus: extbus {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- };
-
- serial0: serial@54006800 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006800 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- interrupts = <0 33 4>;
- clocks = <&uart_clk>;
- };
-
- serial1: serial@54006900 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006900 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- interrupts = <0 35 4>;
- clocks = <&uart_clk>;
- };
-
- serial2: serial@54006a00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006a00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- interrupts = <0 37 4>;
- clocks = <&uart_clk>;
- };
-
- serial3: serial@54006b00 {
- compatible = "socionext,uniphier-uart";
- status = "disabled";
- reg = <0x54006b00 0x40>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- interrupts = <0 177 4>;
- clocks = <&uart_clk>;
- };
-
- i2c0: i2c@58780000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58780000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- interrupts = <0 41 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c1: i2c@58781000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58781000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- interrupts = <0 42 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c2: i2c@58782000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58782000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- interrupts = <0 43 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- i2c3: i2c@58783000 {
- compatible = "socionext,uniphier-fi2c";
- status = "disabled";
- reg = <0x58783000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- interrupts = <0 44 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <100000>;
- };
-
- /* chip-internal connection for DMD */
- i2c4: i2c@58784000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58784000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 45 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+&soc {
+ l2: l2-cache@500c0000 {
+ compatible = "socionext,uniphier-system-cache";
+ reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, <0x506c0000 0x400>;
+ interrupts = <0 174 4>, <0 175 4>, <0 190 4>, <0 191 4>;
+ cache-unified;
+ cache-size = <(1280 * 1024)>;
+ cache-sets = <512>;
+ cache-line-size = <128>;
+ cache-level = <2>;
+ };
- /* chip-internal connection for STM */
- i2c5: i2c@58785000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58785000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 25 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c0: i2c@58780000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58780000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- /* chip-internal connection for HDMI */
- i2c6: i2c@58786000 {
- compatible = "socionext,uniphier-fi2c";
- reg = <0x58786000 0x80>;
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <0 26 4>;
- clocks = <&i2c_clk>;
- clock-frequency = <400000>;
- };
+ i2c1: i2c@58781000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58781000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- system-bus-controller-misc@59800000 {
- compatible = "socionext,uniphier-system-bus-controller-misc",
- "syscon";
- reg = <0x59800000 0x2000>;
- };
+ i2c2: i2c@58782000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58782000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ interrupts = <0 43 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- pinctrl: pinctrl@5f801000 {
- compatible = "socionext,proxstream2-pinctrl", "syscon";
- reg = <0x5f801000 0xe00>;
- };
+ i2c3: i2c@58783000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58783000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
- timer@60000200 {
- compatible = "arm,cortex-a9-global-timer";
- reg = <0x60000200 0x20>;
- interrupts = <1 11 0xf04>;
- clocks = <&arm_timer_clk>;
- };
+ /* chip-internal connection for DMD */
+ i2c4: i2c@58784000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58784000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 45 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
- timer@60000600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x60000600 0x20>;
- interrupts = <1 13 0xf04>;
- clocks = <&arm_timer_clk>;
- };
+ /* chip-internal connection for STM */
+ i2c5: i2c@58785000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58785000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 25 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
- intc: interrupt-controller@60001000 {
- compatible = "arm,cortex-a9-gic";
- #interrupt-cells = <3>;
- interrupt-controller;
- reg = <0x60001000 0x1000>,
- <0x60000100 0x100>;
- };
+ /* chip-internal connection for HDMI */
+ i2c6: i2c@58786000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58786000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 26 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
};
};
-/include/ "uniphier-pinctrl.dtsi"
+&pinctrl {
+ compatible = "socionext,proxstream2-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/usb_a9260_common.dtsi b/arch/arm/boot/dts/usb_a9260_common.dtsi
index 12edafe..9beea89 100644
--- a/arch/arm/boot/dts/usb_a9260_common.dtsi
+++ b/arch/arm/boot/dts/usb_a9260_common.dtsi
@@ -115,7 +115,7 @@
label = "user_pb";
gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
linux,code = <28>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/usb_a9263.dts b/arch/arm/boot/dts/usb_a9263.dts
index 68c0de3..8cc6edb 100644
--- a/arch/arm/boot/dts/usb_a9263.dts
+++ b/arch/arm/boot/dts/usb_a9263.dts
@@ -143,7 +143,7 @@
label = "user_pb";
gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
linux,code = <28>;
- gpio-key,wakeup;
+ wakeup-source;
};
};
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index 01f4019..6fd7efb 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -30,9 +30,69 @@
};
core-module@10000000 {
- compatible = "arm,core-module-versatile", "syscon";
+ compatible = "arm,core-module-versatile", "syscon", "simple-mfd";
reg = <0x10000000 0x200>;
+ 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";
+ };
+
/* OSC1 on AB, OSC4 on PB */
osc1: cm_aux_osc@24M {
#clock-cells = <0>;
@@ -110,7 +170,11 @@
interrupt-parent = <&vic>;
interrupts = <31>; /* Cascaded to vic */
clear-mask = <0xffffffff>;
- valid-mask = <0xffc203f8>;
+ /*
+ * Valid interrupt lines mask according to
+ * table 4-36 page 4-50 of ARM DUI 0225D
+ */
+ valid-mask = <0x0760031b>;
};
dma@10130000 {
@@ -266,8 +330,8 @@
};
mmc@5000 {
compatible = "arm,pl180", "arm,primecell";
- reg = < 0x5000 0x1000>;
- interrupts-extended = <&vic 22 &sic 2>;
+ reg = <0x5000 0x1000>;
+ interrupts-extended = <&vic 22 &sic 1>;
clocks = <&xtal24mhz>, <&pclk>;
clock-names = "mclk", "apb_pclk";
};
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
index b83137f..33a8eb2 100644
--- a/arch/arm/boot/dts/versatile-pb.dts
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -5,6 +5,16 @@
compatible = "arm,versatile-pb";
amba {
+ /* The Versatile PB is using more SIC IRQ lines than the AB */
+ sic: intc@10003000 {
+ clear-mask = <0xffffffff>;
+ /*
+ * Valid interrupt lines mask according to
+ * figure 3-30 page 3-74 of ARM DUI 0224B
+ */
+ valid-mask = <0x7fe003ff>;
+ };
+
gpio2: gpio@101e6000 {
compatible = "arm,pl061", "arm,primecell";
reg = <0x101e6000 0x1000>;
@@ -67,6 +77,13 @@
};
fpga {
+ mmc@5000 {
+ /*
+ * Overrides the interrupt assignment from
+ * the Versatile AB board file.
+ */
+ interrupts-extended = <&sic 22 &sic 23>;
+ };
uart@9000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x9000 0x1000>;
@@ -86,7 +103,8 @@
mmc@b000 {
compatible = "arm,pl180", "arm,primecell";
reg = <0xb000 0x1000>;
- interrupts-extended = <&vic 23 &sic 2>;
+ interrupt-parent = <&sic>;
+ interrupts = <1>, <2>;
clocks = <&xtal24mhz>, <&pclk>;
clock-names = "mclk", "apb_pclk";
};
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index 68ca125..6e556be 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -23,6 +23,18 @@
status = "okay";
};
+&can0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan0>;
+ status = "disabled";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
&dspi1 {
bus-num = <1>;
pinctrl-names = "default";
@@ -52,6 +64,26 @@
pinctrl-0 = <&pinctrl_i2c0>;
};
+&nfc {
+ assigned-clocks = <&clks VF610_CLK_NFC>;
+ assigned-clock-rates = <33000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ status = "okay";
+
+ nand@0 {
+ compatible = "fsl,vf610-nfc-nandcs";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <32>;
+ nand-ecc-step-size = <2048>;
+ nand-on-flash-bbt;
+ };
+};
+
&pwm0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0>;
@@ -105,6 +137,20 @@
&iomuxc {
vf610-colibri {
+ pinctrl_flexcan0: can0grp {
+ fsl,pins = <
+ VF610_PAD_PTB14__CAN0_RX 0x31F1
+ VF610_PAD_PTB15__CAN0_TX 0x31F2
+ >;
+ };
+
+ pinctrl_flexcan1: can1grp {
+ fsl,pins = <
+ VF610_PAD_PTB16__CAN1_RX 0x31F1
+ VF610_PAD_PTB17__CAN1_TX 0x31F2
+ >;
+ };
+
pinctrl_gpio_ext: gpio_ext {
fsl,pins = <
VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */
@@ -156,6 +202,25 @@
>;
};
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ VF610_PAD_PTD23__NF_IO7 0x28df
+ VF610_PAD_PTD22__NF_IO6 0x28df
+ VF610_PAD_PTD21__NF_IO5 0x28df
+ VF610_PAD_PTD20__NF_IO4 0x28df
+ VF610_PAD_PTD19__NF_IO3 0x28df
+ VF610_PAD_PTD18__NF_IO2 0x28df
+ VF610_PAD_PTD17__NF_IO1 0x28df
+ VF610_PAD_PTD16__NF_IO0 0x28df
+ VF610_PAD_PTB24__NF_WE_B 0x28c2
+ VF610_PAD_PTB25__NF_CE0_B 0x28c2
+ VF610_PAD_PTB27__NF_RE_B 0x28c2
+ VF610_PAD_PTC26__NF_RB_B 0x283d
+ VF610_PAD_PTC27__NF_ALE 0x28c2
+ VF610_PAD_PTC28__NF_CLE 0x28c2
+ >;
+ };
+
pinctrl_pwm0: pwm0grp {
fsl,pins = <
VF610_PAD_PTB0__FTM0_CH0 0x1182
diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
index 7fc782c..c3173fc 100644
--- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
@@ -15,3 +15,8 @@
model = "Toradex Colibri VF50 on Colibri Evaluation Board";
compatible = "toradex,vf500-colibri_vf50-on-eval", "toradex,vf500-colibri_vf50", "fsl,vf500";
};
+
+&touchscreen {
+ vf50-ts-min-pressure = <200>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
index cee34a3..84f091d 100644
--- a/arch/arm/boot/dts/vf500-colibri.dtsi
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -17,4 +17,51 @@
memory {
reg = <0x80000000 0x8000000>;
};
+
+ touchscreen: vf50-touchscreen {
+ compatible = "toradex,vf50-touchscreen";
+ io-channels = <&adc1 0>,<&adc0 0>,
+ <&adc0 1>,<&adc1 2>;
+ xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+ yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "idle","default","gpios";
+ pinctrl-0 = <&pinctrl_touchctrl_idle>;
+ pinctrl-1 = <&pinctrl_touchctrl_default>;
+ pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+ vf50-ts-min-pressure = <200>;
+ status = "disabled";
+ };
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_touchctrl_idle: touchctrl_idle {
+ fsl,pins = <
+ VF610_PAD_PTA18__GPIO_8 0x006d
+ VF610_PAD_PTA19__GPIO_9 0x006c
+ >;
+ };
+
+ pinctrl_touchctrl_default: touchctrl_default {
+ fsl,pins = <
+ VF610_PAD_PTA18__ADC0_SE0 0x0040
+ VF610_PAD_PTA19__ADC0_SE1 0x0040
+ VF610_PAD_PTA16__ADC1_SE0 0x0040
+ VF610_PAD_PTB2__ADC1_SE2 0x0040
+ >;
+ };
+
+ pinctrl_touchctrl_gpios: touchctrl_gpios {
+ fsl,pins = <
+ VF610_PAD_PTA23__GPIO_13 0x22e9
+ VF610_PAD_PTB23__GPIO_93 0x22e9
+ VF610_PAD_PTA22__GPIO_12 0x22e9
+ VF610_PAD_PTA11__GPIO_4 0x22e9
+ >;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi
index 19fe045..2d7eab7 100644
--- a/arch/arm/boot/dts/vf610-colibri.dtsi
+++ b/arch/arm/boot/dts/vf610-colibri.dtsi
@@ -18,8 +18,3 @@
reg = <0x80000000 0x10000000>;
};
};
-
-&L2 {
- arm,data-latency = <2 1 2>;
- arm,tag-latency = <3 2 3>;
-};
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 375ab23..5438ee4 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -237,6 +237,33 @@
>;
};
+ pinctrl_nfc: nfcgrp {
+ fsl,pins = <
+ VF610_PAD_PTD31__NF_IO15 0x28df
+ VF610_PAD_PTD30__NF_IO14 0x28df
+ VF610_PAD_PTD29__NF_IO13 0x28df
+ VF610_PAD_PTD28__NF_IO12 0x28df
+ VF610_PAD_PTD27__NF_IO11 0x28df
+ VF610_PAD_PTD26__NF_IO10 0x28df
+ VF610_PAD_PTD25__NF_IO9 0x28df
+ VF610_PAD_PTD24__NF_IO8 0x28df
+ VF610_PAD_PTD23__NF_IO7 0x28df
+ VF610_PAD_PTD22__NF_IO6 0x28df
+ VF610_PAD_PTD21__NF_IO5 0x28df
+ VF610_PAD_PTD20__NF_IO4 0x28df
+ VF610_PAD_PTD19__NF_IO3 0x28df
+ VF610_PAD_PTD18__NF_IO2 0x28df
+ VF610_PAD_PTD17__NF_IO1 0x28df
+ VF610_PAD_PTD16__NF_IO0 0x28df
+ VF610_PAD_PTB24__NF_WE_B 0x28c2
+ VF610_PAD_PTB25__NF_CE0_B 0x28c2
+ VF610_PAD_PTB27__NF_RE_B 0x28c2
+ VF610_PAD_PTC26__NF_RB_B 0x283d
+ VF610_PAD_PTC27__NF_ALE 0x28c2
+ VF610_PAD_PTC28__NF_CLE 0x28c2
+ >;
+ };
+
pinctrl_pwm0: pwm0grp {
fsl,pins = <
VF610_PAD_PTB0__FTM0_CH0 0x1582
@@ -274,6 +301,26 @@
};
};
+&nfc {
+ assigned-clocks = <&clks VF610_CLK_NFC>;
+ assigned-clock-rates = <33000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nfc>;
+ status = "okay";
+
+ nand@0 {
+ compatible = "fsl,vf610-nfc-nandcs";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ nand-bus-width = <16>;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <24>;
+ nand-ecc-step-size = <2048>;
+ nand-on-flash-bbt;
+ };
+};
+
&pwm0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0>;
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 5f8eb1b..58bc6e4 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -19,7 +19,7 @@
reg = <0x40006000 0x1000>;
cache-unified;
cache-level = <2>;
- arm,data-latency = <1 1 1>;
+ arm,data-latency = <3 3 3>;
arm,tag-latency = <2 2 2>;
};
};
diff --git a/arch/arm/boot/dts/vf610m4-cosmic.dts b/arch/arm/boot/dts/vf610m4-cosmic.dts
new file mode 100644
index 0000000..8944a2d
--- /dev/null
+++ b/arch/arm/boot/dts/vf610m4-cosmic.dts
@@ -0,0 +1,90 @@
+/*
+ * Device tree for Cosmic+ VF6xx Cortex-M4 support
+ *
+ * Copyright (C) 2015
+ *
+ * Based on vf610m4 Colibri
+ *
+ * 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 "vf610m4.dtsi"
+
+/ {
+ model = "VF610 Cortex-M4";
+ compatible = "fsl,vf610m4";
+};
+
+&gpio0 {
+ status = "disabled";
+};
+
+&gpio1 {
+ status = "disabled";
+};
+
+&gpio2 {
+ status = "disabled";
+};
+
+&gpio3 {
+ status = "disabled";
+};
+
+&gpio4 {
+ status = "disabled";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&iomuxc {
+ vf610-cosmic {
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ VF610_PAD_PTA20__UART3_TX 0x21a2
+ VF610_PAD_PTA21__UART3_RX 0x21a1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 6865137..4539f8d 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -158,7 +158,7 @@
interrupts = <67 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_DSPI0>;
clock-names = "dspi";
- spi-num-chipselects = <5>;
+ spi-num-chipselects = <6>;
status = "disabled";
};
@@ -170,7 +170,7 @@
interrupts = <68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_DSPI1>;
clock-names = "dspi";
- spi-num-chipselects = <5>;
+ spi-num-chipselects = <4>;
status = "disabled";
};
@@ -178,8 +178,10 @@
compatible = "fsl,vf610-sai";
reg = <0x40031000 0x1000>;
interrupts = <86 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks VF610_CLK_SAI2>;
- clock-names = "sai";
+ clocks = <&clks VF610_CLK_SAI2>,
+ <&clks VF610_CLK_SAI2_DIV>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
dma-names = "tx", "rx";
dmas = <&edma0 0 21>,
<&edma0 0 20>;
@@ -453,6 +455,30 @@
status = "disabled";
};
+ dspi2: dspi2@400ac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x400ac000 0x1000>;
+ interrupts = <69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI2>;
+ clock-names = "dspi";
+ spi-num-chipselects = <2>;
+ status = "disabled";
+ };
+
+ dspi3: dspi3@400ad000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x400ad000 0x1000>;
+ interrupts = <70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI3>;
+ clock-names = "dspi";
+ spi-num-chipselects = <2>;
+ status = "disabled";
+ };
+
adc1: adc@400bb000 {
compatible = "fsl,vf610-adc";
reg = <0x400bb000 0x1000>;
@@ -461,6 +487,8 @@
clock-names = "adc";
#io-channel-cells = <1>;
status = "disabled";
+ fsl,adck-max-frequency = <30000000>, <40000000>,
+ <20000000>;
};
esdhc0: esdhc@400b1000 {
@@ -472,8 +500,6 @@
<&clks VF610_CLK_ESDHC0>;
clock-names = "ipg", "ahb", "per";
status = "disabled";
- fsl,adck-max-frequency = <30000000>, <40000000>,
- <20000000>;
};
esdhc1: esdhc@400b2000 {
@@ -564,6 +590,17 @@
status = "disabled";
};
+ nfc: nand@400e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-nfc";
+ reg = <0x400e0000 0x4000>;
+ interrupts = <83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_NFC>;
+ clock-names = "nfc";
+ status = "disabled";
+ };
+
i2c2: i2c@400e6000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -592,5 +629,10 @@
status = "disabled";
};
};
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 16>, <&adc1 16>;
+ };
};
};
diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi
index a1a854b..e9ef539 100644
--- a/arch/arm/boot/dts/wm8505.dtsi
+++ b/arch/arm/boot/dts/wm8505.dtsi
@@ -281,8 +281,8 @@
sdhc@d800a000 {
compatible = "wm,wm8505-sdhc";
- reg = <0xd800a000 0x1000>;
- interrupts = <20 21>;
+ reg = <0xd800a000 0x400>;
+ interrupts = <20>, <21>;
clocks = <&clksdhc>;
bus-width = <4>;
};
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
index b1c59a7..e12213d 100644
--- a/arch/arm/boot/dts/wm8650.dtsi
+++ b/arch/arm/boot/dts/wm8650.dtsi
@@ -187,6 +187,15 @@
interrupts = <43>;
};
+ sdhc@d800a000 {
+ compatible = "wm,wm8505-sdhc";
+ reg = <0xd800a000 0x400>;
+ interrupts = <20>, <21>;
+ clocks = <&clksdhc>;
+ bus-width = <4>;
+ sdon-inverted;
+ };
+
fb: fb@d8050800 {
compatible = "wm,wm8505-fb";
reg = <0xd8050800 0x200>;
diff --git a/arch/arm/boot/dts/wm8750.dtsi b/arch/arm/boot/dts/wm8750.dtsi
index 557a9c2a..46d076d 100644
--- a/arch/arm/boot/dts/wm8750.dtsi
+++ b/arch/arm/boot/dts/wm8750.dtsi
@@ -17,7 +17,7 @@
cpu {
device_type = "cpu";
- compatible = "arm,arm1176ej-s";
+ compatible = "arm,arm1176jzf";
};
};
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index dc0457e..f283ff0 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -19,7 +19,7 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0>;
@@ -33,7 +33,7 @@
>;
};
- cpu@1 {
+ cpu1: cpu@1 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <1>;
@@ -101,6 +101,8 @@
#gpio-cells = <2>;
clocks = <&clkc 42>;
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
reg = <0xe000a000 0x1000>;
@@ -238,7 +240,7 @@
slcr: slcr@f8000000 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
+ compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
reg = <0xF8000000 0x1000>;
ranges;
clkc: clkc@100 {
@@ -294,6 +296,11 @@
devcfg: devcfg@f8007000 {
compatible = "xlnx,zynq-devcfg-1.0";
reg = <0xf8007000 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 8 4>;
+ clocks = <&clkc 12>;
+ clock-names = "ref_clk";
+ syscon = <&slcr>;
};
global_timer: timer@f8f00200 {
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 5df8f81..cb64209 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -43,14 +43,14 @@
label = "sw14";
gpios = <&gpio0 12 0>;
linux,code = <108>; /* down */
- gpio-key,wakeup;
+ wakeup-source;
autorepeat;
};
sw13 {
label = "sw13";
gpios = <&gpio0 14 0>;
linux,code = <103>; /* up */
- gpio-key,wakeup;
+ wakeup-source;
autorepeat;
};
};
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index c3a4e9c..9353184 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -17,6 +17,3 @@ config SHARP_PARAM
config SHARP_SCOOP
bool
-
-config TI_PRIV_EDMA
- bool
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 6ee5959..27f23b1 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -15,6 +15,5 @@ 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/edma.c b/arch/arm/common/edma.c
deleted file mode 100644
index 873dbfc..0000000
--- a/arch/arm/common/edma.c
+++ /dev/null
@@ -1,1876 +0,0 @@
-/*
- * 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);
-
- /* clear possibly pending completion interrupt */
- edma_shadow0_write_array(ctlr, SH_ICR, 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/icst.c b/arch/arm/common/icst.c
index 2dc6da70..d7ed252 100644
--- a/arch/arm/common/icst.c
+++ b/arch/arm/common/icst.c
@@ -16,7 +16,7 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
-
+#include <asm/div64.h>
#include <asm/hardware/icst.h>
/*
@@ -29,7 +29,11 @@ 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]);
+ u64 dividend = p->ref * 2 * (u64)(vco.v + 8);
+ u32 divisor = (vco.r + 2) * p->s2div[vco.s];
+
+ do_div(dividend, divisor);
+ return (unsigned long)dividend;
}
EXPORT_SYMBOL(icst_hz);
@@ -58,6 +62,7 @@ icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
if (f > p->vco_min && f <= p->vco_max)
break;
+ i++;
} while (i < 8);
if (i >= 8)
diff --git a/arch/arm/common/mcpm_platsmp.c b/arch/arm/common/mcpm_platsmp.c
index 2b25b60..c773157 100644
--- a/arch/arm/common/mcpm_platsmp.c
+++ b/arch/arm/common/mcpm_platsmp.c
@@ -83,7 +83,7 @@ static void mcpm_cpu_die(unsigned int cpu)
#endif
-static struct smp_operations __initdata mcpm_smp_ops = {
+static const struct smp_operations mcpm_smp_ops __initconst = {
.smp_boot_secondary = mcpm_boot_secondary,
.smp_secondary_init = mcpm_secondary_init,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 3d22494..fb0a0a4 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1290,7 +1290,7 @@ 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;
+ return !!(dev->devid & drv->devid);
}
static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 45f4c21..9ba45ad 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -69,7 +69,7 @@ static void __scoop_gpio_set(struct scoop_dev *sdev,
static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
- struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+ struct scoop_dev *sdev = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&sdev->scoop_lock, flags);
@@ -81,16 +81,16 @@ static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+ struct scoop_dev *sdev = gpiochip_get_data(chip);
/* XXX: I'm unsure, but it seems so */
- return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
+ 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);
+ struct scoop_dev *sdev = gpiochip_get_data(chip);
unsigned long flags;
unsigned short gpcr;
@@ -108,7 +108,7 @@ static int scoop_gpio_direction_input(struct gpio_chip *chip,
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);
+ struct scoop_dev *sdev = gpiochip_get_data(chip);
unsigned long flags;
unsigned short gpcr;
@@ -224,7 +224,7 @@ static int scoop_probe(struct platform_device *pdev)
devptr->gpio.direction_input = scoop_gpio_direction_input;
devptr->gpio.direction_output = scoop_gpio_direction_output;
- ret = gpiochip_add(&devptr->gpio);
+ ret = gpiochip_add_data(&devptr->gpio, devptr);
if (ret)
goto err_gpio;
}
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 090c5b2..e4b1be6 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -17,7 +17,6 @@ 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
@@ -28,7 +27,6 @@ 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
@@ -43,7 +41,6 @@ CONFIG_IP_PNP_RARP=y
# 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
@@ -119,7 +116,6 @@ 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
@@ -129,7 +125,6 @@ CONFIG_POWER_RESET=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_SSB=m
CONFIG_MFD_ATMEL_HLCDC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -142,16 +137,12 @@ CONFIG_SOC_CAMERA_OV2640=m
CONFIG_DRM=y
CONFIG_DRM_ATMEL_HLCDC=y
CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_FB=y
CONFIG_FB_ATMEL=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_ATMEL_LCDC=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PWM=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
@@ -216,18 +207,11 @@ CONFIG_DEBUG_FS=y
# 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
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 31cb073..72def20 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -10,7 +10,6 @@ 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
@@ -18,10 +17,6 @@ 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
@@ -29,6 +24,7 @@ CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_JUMP_LABEL=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
CONFIG_ARCH_MULTI_V6=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_BCM=y
@@ -38,7 +34,6 @@ 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
@@ -57,7 +52,6 @@ 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
@@ -75,19 +69,30 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_BCM2835=y
CONFIG_SPI=y
CONFIG_SPI_BCM2835=y
+CONFIG_SPI_BCM2835AUX=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_BCM2835_WDT=y
CONFIG_FB=y
CONFIG_FB_SIMPLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC2=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_BCM2835=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
@@ -96,17 +101,19 @@ CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BCM2835=y
CONFIG_STAGING=y
-CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_HOST=y
+CONFIG_MAILBOX=y
+CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_BCM2835=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_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig
deleted file mode 100644
index 3125e00..0000000
--- a/arch/arm/configs/bockw_defconfig
+++ /dev/null
@@ -1,133 +0,0 @@
-# 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/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
index 18c311a..0b9211b 100644
--- a/arch/arm/configs/colibri_pxa270_defconfig
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -166,7 +166,6 @@ 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
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index a7846d6..158dde8 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -132,6 +132,5 @@ 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/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 1ff2bfa..24dcd2b 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -7,7 +7,6 @@ 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
@@ -44,7 +43,6 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_CFG80211=y
CONFIG_RFKILL_REGULATOR=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
@@ -61,11 +59,12 @@ CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=m
CONFIG_NETDEVICES=y
CONFIG_SMSC911X=y
+CONFIG_USB_RTL8152=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
-CONFIG_MWIFIEX=y
-CONFIG_MWIFIEX_SDIO=y
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_CROS_EC=y
@@ -73,6 +72,9 @@ CONFIG_KEYBOARD_CROS_EC=y
CONFIG_MOUSE_CYAPA=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MAX77693_HAPTIC=y
+CONFIG_INPUT_MAX8997_HAPTIC=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_SAMSUNG=y
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
@@ -86,6 +88,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
CONFIG_SPI_S3C64XX=y
CONFIG_DEBUG_GPIO=y
CONFIG_POWER_SUPPLY=y
@@ -94,6 +97,7 @@ CONFIG_BATTERY_MAX17040=y
CONFIG_BATTERY_MAX17042=y
CONFIG_CHARGER_MAX14577=y
CONFIG_CHARGER_MAX77693=y
+CONFIG_CHARGER_MAX8997=y
CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_NTC_THERMISTOR=y
@@ -112,6 +116,7 @@ CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
CONFIG_MFD_MAX8997=y
+CONFIG_MFD_MAX8998=y
CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_TPS65090=y
CONFIG_REGULATOR=y
@@ -119,6 +124,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_MAX14577=y
CONFIG_REGULATOR_MAX8997=y
+CONFIG_REGULATOR_MAX8998=y
CONFIG_REGULATOR_MAX77686=y
CONFIG_REGULATOR_MAX77693=y
CONFIG_REGULATOR_MAX77802=y
@@ -126,16 +132,22 @@ CONFIG_REGULATOR_S2MPA01=y
CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS65090=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
CONFIG_DRM=y
CONFIG_DRM_NXP_PTN3460=y
CONFIG_DRM_PARADE_PS8622=y
CONFIG_DRM_EXYNOS=y
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS_DSI=y
+CONFIG_DRM_EXYNOS_MIXER=y
+CONFIG_DRM_EXYNOS_DPI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
-CONFIG_FB_SIMPLE=y
CONFIG_EXYNOS_VIDEO=y
CONFIG_EXYNOS_MIPI_DSI=y
CONFIG_LCD_CLASS_DEVICE=y
@@ -158,17 +170,28 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_EXYNOS=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
CONFIG_USB_HSIC_USB3503=y
CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=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_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_MAX77693=y
+CONFIG_LEDS_MAX8997=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MAX8997=y
CONFIG_RTC_DRV_MAX77686=y
CONFIG_RTC_DRV_MAX77802=y
CONFIG_RTC_DRV_S5M=y
@@ -183,6 +206,7 @@ CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_EXTCON=y
CONFIG_EXTCON_MAX14577=y
CONFIG_EXTCON_MAX77693=y
+CONFIG_EXTCON_MAX8997=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
CONFIG_PWM=y
@@ -191,6 +215,7 @@ CONFIG_PHY_EXYNOS5250_SATA=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
+CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
@@ -198,6 +223,7 @@ CONFIG_TMPFS_POSIX_ACL=y
CONFIG_CRAMFS=y
CONFIG_ROMFS_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
index 5997dbc..b2e340b 100644
--- a/arch/arm/configs/hisi_defconfig
+++ b/arch/arm/configs/hisi_defconfig
@@ -69,7 +69,6 @@ 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
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 79194c6..2d5253d 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -42,12 +42,11 @@ CONFIG_SOC_IMX6SL=y
CONFIG_SOC_IMX6SX=y
CONFIG_SOC_IMX6UL=y
CONFIG_SOC_IMX7D=y
-CONFIG_SOC_LS1021A=y
CONFIG_SOC_VF610=y
CONFIG_PCI=y
+CONFIG_PCI_MSI=y
CONFIG_PCI_IMX6=y
CONFIG_SMP=y
-CONFIG_VMSPLIT_2G=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
@@ -159,6 +158,7 @@ CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
CONFIG_TOUCHSCREEN_MC13783=y
CONFIG_TOUCHSCREEN_TSC2007=y
CONFIG_TOUCHSCREEN_STMPE=y
@@ -224,6 +224,7 @@ CONFIG_SOC_CAMERA_OV2640=y
CONFIG_IMX_IPUV3_CORE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_IMX=y
CONFIG_DRM_IMX_FB_HELPER=y
CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
@@ -315,6 +316,8 @@ CONFIG_MXS_DMA=y
CONFIG_FSL_EDMA=y
CONFIG_STAGING=y
# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_VF610_ADC=y
CONFIG_PWM=y
CONFIG_PWM_IMX=y
CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index 4fa94a1..652b7bd 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -95,7 +95,6 @@ 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
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index c3058da..aa3af0a 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -108,7 +108,6 @@ 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
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 95ce128..5bcc9cf 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -4,6 +4,12 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
@@ -27,6 +33,7 @@ CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
+CONFIG_CMA=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_SUSPEND is not set
@@ -57,7 +64,6 @@ 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
@@ -93,7 +99,6 @@ 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
@@ -106,7 +111,8 @@ CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP_SCTP=y
CONFIG_VLAN_8021Q=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CMA=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
@@ -117,7 +123,6 @@ 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
@@ -125,7 +130,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
CONFIG_TI_KEYSTONE_NETCP=y
CONFIG_TI_KEYSTONE_NETCP_ETHSS=y
-CONFIG_PHYLIB=y
+CONFIG_MARVELL_PHY=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
@@ -137,12 +142,15 @@ CONFIG_I2C_DAVINCI=y
CONFIG_SPI=y
CONFIG_SPI_DAVINCI=y
CONFIG_SPI_SPIDEV=y
-# CONFIG_HWMON is not set
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DAVINCI=y
+CONFIG_GPIO_SYSCON=y
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_KEYSTONE=y
+# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
CONFIG_DAVINCI_WATCHDOG=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -150,9 +158,15 @@ 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_NEW_LEDS=y
+CONFIG_LEDS_CLASS=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_DMADEVICES=y
CONFIG_TI_EDMA=y
CONFIG_SOC_TI=y
@@ -160,8 +174,11 @@ CONFIG_KEYSTONE_NAVIGATOR_QMSS=y
CONFIG_KEYSTONE_NAVIGATOR_DMA=y
CONFIG_MEMORY=y
CONFIG_TI_AEMIF=y
+CONFIG_KEYSTONE_IRQ=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_FANOTIFY=y
+CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
@@ -179,11 +196,10 @@ 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_SHIRQ=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
@@ -192,19 +208,3 @@ 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/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
index 1c47f86..2ae00b0 100644
--- a/arch/arm/configs/lpc18xx_defconfig
+++ b/arch/arm/configs/lpc18xx_defconfig
@@ -52,15 +52,22 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FW_LOADER is not set
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=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_SPI_NXP_SPIFI=y
CONFIG_BLK_DEV_RAM=y
CONFIG_SRAM=y
CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ARC is not set
# CONFIG_NET_CADENCE is not set
@@ -102,14 +109,17 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
+CONFIG_I2C_LPC2K=y
CONFIG_SPI=y
CONFIG_SPI_PL022=y
+CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_74XX_MMIO=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_SENSORS_JC42=y
CONFIG_SENSORS_LM75=y
CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_MFD_SYSCON=y
+CONFIG_LPC18XX_WATCHDOG=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_FB=y
@@ -117,9 +127,10 @@ CONFIG_FB_ARMCLCD=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_PCA9532=y
@@ -128,12 +139,25 @@ CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_LPC24XX=y
CONFIG_DMADEVICES=y
CONFIG_AMBA_PL08X=y
+CONFIG_LPC18XX_DMAMUX=y
+CONFIG_MEMORY=y
+CONFIG_ARM_PL172_MPMC=y
+CONFIG_PWM=y
+CONFIG_PWM_LPC18XX_SCT=y
+CONFIG_IIO=y
+CONFIG_MMA7455_I2C=y
+CONFIG_IIO_SYSFS_TRIGGER=y
+CONFIG_PHY_LPC18XX_USB_OTG=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LPC18XX_EEPROM=y
CONFIG_EXT2_FS=y
# CONFIG_FILE_LOCKING is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
+CONFIG_JFFS2_FS=y
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
@@ -143,8 +167,6 @@ CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_RCU_CPU_STALL_INFO is not set
-# CONFIG_FTRACE is not set
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
CONFIG_CRC_ITU_T=y
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
index c100b7d..9f56ca3 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -204,7 +204,6 @@ 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
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index f69a459..afb1f62 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -11,10 +11,32 @@ CONFIG_MODULE_UNLOAD=y
# 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_SOC_IMX25=y
+CONFIG_ARCH_ORION5X=y
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_RD88F5182_DT=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_LSCHL=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_D2NET_DT=y
+CONFIG_MACH_NET2BIG=y
+CONFIG_MACH_MSS2_DT=y
+CONFIG_MACH_WNR854T=y
+CONFIG_MACH_RD88F5181L_GE=y
+CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=y
CONFIG_ARCH_U300=y
CONFIG_PCI_MVEBU=y
CONFIG_PREEMPT=y
@@ -38,6 +60,8 @@ 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_SWITCHDEV=y
CONFIG_NET_PKTGEN=m
CONFIG_CFG80211=y
CONFIG_MAC80211=y
@@ -53,7 +77,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
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
@@ -66,8 +89,11 @@ CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123=y
CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6352=y
CONFIG_MV643XX_ETH=y
CONFIG_R8169=y
CONFIG_MARVELL_PHY=y
@@ -92,7 +118,6 @@ 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
@@ -105,17 +130,16 @@ CONFIG_THERMAL=y
CONFIG_KIRKWOOD_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
+# CONFIG_ABX500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=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
@@ -162,8 +186,6 @@ 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
@@ -189,7 +211,6 @@ CONFIG_DEBUG_KERNEL=y
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
index 03deb7f..8e8b2ac 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -11,6 +11,9 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_MULTI_V7=y
+# CONFIG_ARCH_MULTI_V5 is not set
+# CONFIG_ARCH_MULTI_V4 is not set
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_ALPINE=y
CONFIG_ARCH_MVEBU=y
@@ -21,10 +24,12 @@ CONFIG_MACH_ARMADA_39X=y
CONFIG_MACH_ARMADA_XP=y
CONFIG_MACH_DOVE=y
CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAMA5D2=y
CONFIG_SOC_SAMA5D3=y
CONFIG_SOC_SAMA5D4=y
CONFIG_ARCH_BCM=y
CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARCH_BCM_NSP=y
CONFIG_ARCH_BCM_21664=y
CONFIG_ARCH_BCM_281XX=y
CONFIG_ARCH_BCM_5301X=y
@@ -73,7 +78,7 @@ CONFIG_MACH_SPEAR1340=y
CONFIG_ARCH_STI=y
CONFIG_ARCH_EXYNOS=y
CONFIG_EXYNOS5420_MCPM=y
-CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_RENESAS=y
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R7S72100=y
CONFIG_ARCH_R8A73A4=y
@@ -85,7 +90,6 @@ CONFIG_ARCH_R8A7791=y
CONFIG_ARCH_R8A7793=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
@@ -124,6 +128,7 @@ CONFIG_KEXEC=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_QORIQ_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
CONFIG_NEON=y
@@ -151,8 +156,10 @@ CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_DEV=y
CONFIG_CAN_AT91=m
+CONFIG_CAN_RCAR=m
CONFIG_CAN_XILINXCAN=y
CONFIG_CAN_MCP251X=y
+CONFIG_CAN_SUN4I=y
CONFIG_BT=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
@@ -167,6 +174,7 @@ CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=64
CONFIG_OMAP_OCP2SCP=y
CONFIG_SIMPLE_PM_BUS=y
+CONFIG_SUNXI_RSB=m
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
@@ -176,17 +184,21 @@ CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_BRCMNAND=y
CONFIG_MTD_NAND_DAVINCI=y
CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_FSL_QUADSPI=m
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=y
CONFIG_AD525X_DPOT=y
CONFIG_AD525X_DPOT_I2C=y
CONFIG_ATMEL_TCLIB=y
CONFIG_ICS932S401=y
CONFIG_ATMEL_SSC=m
+CONFIG_QCOM_COINCELL=m
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
@@ -200,13 +212,16 @@ CONFIG_SATA_HIGHBANK=y
CONFIG_SATA_MV=y
CONFIG_SATA_RCAR=y
CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
CONFIG_HIX5HD2_GMAC=y
CONFIG_SUN4I_EMAC=y
CONFIG_MACB=y
CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_GIANFAR=y
CONFIG_IGB=y
CONFIG_MV643XX_ETH=y
CONFIG_MVNETA=y
+CONFIG_PXA168_ETH=m
CONFIG_KS8851=y
CONFIG_R8169=y
CONFIG_SH_ETH=y
@@ -219,8 +234,11 @@ CONFIG_MARVELL_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_BROADCOM_PHY=y
CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
CONFIG_MICREL_PHY=y
+CONFIG_FIXED_PHY=y
CONFIG_USB_PEGASUS=y
+CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
@@ -236,7 +254,7 @@ CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_TEGRA=y
CONFIG_KEYBOARD_SPEAR=y
CONFIG_KEYBOARD_ST_KEYSCAN=y
-CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_KEYBOARD_CROS_EC=m
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_CYAPA=m
CONFIG_MOUSE_ELAN_I2C=y
@@ -245,9 +263,12 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_STMPE=y
CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_TOUCHSCREEN_WM97XX=m
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MAX77693_HAPTIC=m
+CONFIG_INPUT_MAX8997_HAPTIC=m
CONFIG_INPUT_MPU3050=y
-CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_AXP20X_PEK=m
CONFIG_INPUT_ADXL34X=m
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIAL_8250=y
@@ -288,6 +309,8 @@ CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DAVINCI=y
CONFIG_I2C_MUX=y
@@ -298,16 +321,21 @@ CONFIG_I2C_AT91=m
CONFIG_I2C_CADENCE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_DIGICOLOR=m
+CONFIG_I2C_EMEV2=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_EXYNOS5=y
+CONFIG_I2C_IMX=m
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_RIIC=y
+CONFIG_I2C_RK3X=y
CONFIG_I2C_S3C2410=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_I2C_SIRF=y
CONFIG_I2C_ST=y
CONFIG_I2C_SUN6I_P2WI=y
CONFIG_I2C_TEGRA=y
+CONFIG_I2C_UNIPHIER=y
+CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_XILINX=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=m
@@ -315,9 +343,11 @@ CONFIG_SPI=y
CONFIG_SPI_ATMEL=m
CONFIG_SPI_CADENCE=y
CONFIG_SPI_DAVINCI=y
+CONFIG_SPI_FSL_DSPI=m
CONFIG_SPI_OMAP24XX=y
CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
+CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_RSPI=y
CONFIG_SPI_S3C64XX=m
CONFIG_SPI_SH_MSIOF=m
@@ -330,9 +360,18 @@ CONFIG_SPI_TEGRA20_SFLASH=y
CONFIG_SPI_TEGRA20_SLINK=y
CONFIG_SPI_XILINX=y
CONFIG_SPI_SPIDEV=y
+CONFIG_SPMI=y
CONFIG_PINCTRL_AS3722=y
CONFIG_PINCTRL_PALMAS=y
+CONFIG_PINCTRL_APQ8064=y
CONFIG_PINCTRL_APQ8084=y
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM8660=y
+CONFIG_PINCTRL_MSM8960=y
+CONFIG_PINCTRL_MSM8X74=y
+CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_DAVINCI=y
@@ -354,17 +393,23 @@ CONFIG_BATTERY_MAX17040=m
CONFIG_BATTERY_MAX17042=m
CONFIG_CHARGER_MAX14577=m
CONFIG_CHARGER_MAX77693=m
+CONFIG_CHARGER_MAX8997=m
CONFIG_CHARGER_TPS65090=y
+CONFIG_AXP20X_POWER=m
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_RMOBILE=y
+CONFIG_POWER_AVS=y
+CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_LM95245=y
CONFIG_SENSORS_NTC_THERMISTOR=m
-CONFIG_THERMAL=y
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_INA2XX=m
CONFIG_CPU_THERMAL=y
+CONFIG_ROCKCHIP_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_DAVINCI_WATCHDOG=m
@@ -372,54 +417,77 @@ CONFIG_EXYNOS_THERMAL=m
CONFIG_ST_THERMAL_SYSCFG=y
CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_WATCHDOG=y
+CONFIG_DA9063_WATCHDOG=m
CONFIG_XILINX_WATCHDOG=y
CONFIG_ARM_SP805_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
CONFIG_ST_LPC_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
+CONFIG_IMX2_WDT=y
CONFIG_TEGRA_WATCHDOG=m
CONFIG_MESON_WATCHDOG=y
+CONFIG_DW_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_MFD_AS3711=y
CONFIG_MFD_AS3722=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
CONFIG_MFD_BCM590XX=y
CONFIG_MFD_AXP20X=y
-CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_AXP20X_I2C=m
+CONFIG_MFD_AXP20X_RSB=m
+CONFIG_MFD_CROS_EC=m
CONFIG_MFD_CROS_EC_I2C=m
-CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_CROS_EC_SPI=m
+CONFIG_MFD_DA9063=m
CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
CONFIG_MFD_MAX8907=y
+CONFIG_MFD_MAX8997=y
+CONFIG_MFD_RK808=y
+CONFIG_MFD_PM8921_CORE=y
+CONFIG_MFD_QCOM_RPM=y
+CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_SEC_CORE=y
CONFIG_MFD_STMPE=y
CONFIG_MFD_PALMAS=y
CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_ACT8865=y
CONFIG_REGULATOR_AS3711=y
CONFIG_REGULATOR_AS3722=y
-CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_AXP20X=m
CONFIG_REGULATOR_BCM590XX=y
CONFIG_REGULATOR_DA9210=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MFD_SYSCON=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_REGULATOR_MAX14577=m
CONFIG_REGULATOR_MAX8907=y
CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_MAX8997=m
CONFIG_REGULATOR_MAX77686=y
CONFIG_REGULATOR_MAX77693=m
CONFIG_REGULATOR_MAX77802=m
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_PWM=m
+CONFIG_REGULATOR_QCOM_RPM=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
+CONFIG_REGULATOR_TI_ABB=y
CONFIG_REGULATOR_TPS51632=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS65090=y
+CONFIG_REGULATOR_TPS65217=y
+CONFIG_REGULATOR_TPS65218=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TWL4030=y
@@ -436,11 +504,13 @@ CONFIG_SOC_CAMERA=m
CONFIG_SOC_CAMERA_PLATFORM=m
CONFIG_VIDEO_RCAR_VIN=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_JPU=m
CONFIG_VIDEO_RENESAS_VSP1=m
# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
CONFIG_VIDEO_ADV7180=m
CONFIG_VIDEO_ML86V7667=m
CONFIG_DRM=y
+CONFIG_DRM_I2C_ADV7511=m
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_NXP_PTN3460=m
@@ -450,7 +520,11 @@ CONFIG_DRM_EXYNOS=m
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS_HDMI=y
+CONFIG_DRM_ROCKCHIP=m
+CONFIG_ROCKCHIP_DW_HDMI=m
CONFIG_DRM_RCAR_DU=m
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=y
CONFIG_DRM_TEGRA=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_PANEL_SIMPLE=y
@@ -474,26 +548,38 @@ CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_CODEC_REALTEK=m
CONFIG_SND_HDA_CODEC_HDMI=m
-CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO=m
CONFIG_SND_SOC=m
CONFIG_SND_ATMEL_SOC=m
CONFIG_SND_ATMEL_SOC_WM8904=m
+CONFIG_SND_SOC_FSL_SAI=m
+CONFIG_SND_SOC_ROCKCHIP=m
+CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
+CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
+CONFIG_SND_SOC_ROCKCHIP_RT5645=m
CONFIG_SND_SOC_SH4_FSI=m
CONFIG_SND_SOC_RCAR=m
CONFIG_SND_SOC_RSRC_CARD=m
+CONFIG_SND_SOC_SAMSUNG=m
+CONFIG_SND_SOC_SNOW=m
+CONFIG_SND_SOC_ODROIDX2=m
CONFIG_SND_SOC_TEGRA=m
CONFIG_SND_SOC_TEGRA_RT5640=m
CONFIG_SND_SOC_TEGRA_WM8753=m
CONFIG_SND_SOC_TEGRA_WM8903=m
+CONFIG_SND_SOC_TEGRA_WM9712=m
CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
CONFIG_SND_SOC_TEGRA_ALC5632=m
CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_SGTL5000=m
+CONFIG_SND_SOC_SPDIF=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_MSM=m
CONFIG_USB_EHCI_EXYNOS=y
CONFIG_USB_EHCI_TEGRA=y
CONFIG_USB_EHCI_HCD_STI=y
@@ -507,6 +593,7 @@ CONFIG_USB_R8A66597_HCD=m
CONFIG_USB_RENESAS_USBHS=m
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=m
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_AB8500_USB=y
@@ -514,16 +601,19 @@ CONFIG_KEYSTONE_USB_PHY=y
CONFIG_OMAP_USB3=y
CONFIG_USB_GPIO_VBUS=y
CONFIG_USB_ISP1301=y
+CONFIG_USB_MSM_OTG=m
CONFIG_USB_MXS_PHY=y
-CONFIG_USB_RCAR_PHY=m
CONFIG_USB_GADGET=y
CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_ETH=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_OF_AT91=y
+CONFIG_MMC_SDHCI_OF_ESDHC=m
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_DOVE=y
CONFIG_MMC_SDHCI_TEGRA=y
@@ -536,6 +626,7 @@ CONFIG_MMC_SDHCI_ST=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_MVSDIO=y
CONFIG_MMC_SDHI=y
CONFIG_MMC_DW=y
@@ -547,8 +638,11 @@ CONFIG_MMC_SH_MMCIF=y
CONFIG_MMC_SUNXI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_PWM=y
+CONFIG_LEDS_MAX77693=m
+CONFIG_LEDS_MAX8997=m
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
@@ -566,8 +660,11 @@ CONFIG_EDAC_HIGHBANK_L2=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AS3722=y
CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_HYM8563=m
CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_MAX8997=m
CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_RK808=m
CONFIG_RTC_DRV_MAX77802=m
CONFIG_RTC_DRV_RS5C372=m
CONFIG_RTC_DRV_PALMAS=y
@@ -578,6 +675,7 @@ CONFIG_RTC_DRV_TPS65910=y
CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_RX8581=m
CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_DA9063=m
CONFIG_RTC_DRV_DIGICOLOR=m
CONFIG_RTC_DRV_S5M=m
CONFIG_RTC_DRV_S3C=m
@@ -593,10 +691,12 @@ CONFIG_DMADEVICES=y
CONFIG_DW_DMAC=y
CONFIG_AT_HDMAC=y
CONFIG_AT_XDMAC=y
+CONFIG_FSL_EDMA=m
CONFIG_MV_XOR=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_SH_DMAE=y
CONFIG_RCAR_DMAC=y
+CONFIG_RENESAS_USB_DMAC=m
CONFIG_STE_DMA40=y
CONFIG_SIRF_DMA=y
CONFIG_TI_EDMA=y
@@ -605,6 +705,7 @@ CONFIG_IMX_SDMA=y
CONFIG_IMX_DMA=y
CONFIG_MXS_DMA=y
CONFIG_DMA_OMAP=y
+CONFIG_QCOM_BAM_DMA=y
CONFIG_XILINX_VDMA=y
CONFIG_DMA_SUN6I=y
CONFIG_STAGING=y
@@ -617,16 +718,27 @@ CONFIG_NVEC_POWER=y
CONFIG_NVEC_PAZ00=y
CONFIG_QCOM_GSBI=y
CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_WCNSS_CTRL=m
+CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_CHROME_PLATFORMS=y
+CONFIG_STAGING_BOARD=y
CONFIG_CROS_EC_CHARDEV=m
CONFIG_COMMON_CLK_MAX77686=y
CONFIG_COMMON_CLK_MAX77802=m
+CONFIG_COMMON_CLK_RK808=m
CONFIG_COMMON_CLK_S2MPS11=m
CONFIG_APQ_MMCC_8084=y
CONFIG_MSM_GCC_8660=y
CONFIG_MSM_MMCC_8960=y
CONFIG_MSM_MMCC_8974=y
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ROCKCHIP_IOMMU=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_PM_DEVFREQ=y
@@ -636,13 +748,16 @@ CONFIG_EXTCON=y
CONFIG_TI_AEMIF=y
CONFIG_IIO=y
CONFIG_AT91_ADC=m
+CONFIG_BERLIN2_ADC=m
CONFIG_EXYNOS_ADC=m
CONFIG_XILINX_XADC=y
CONFIG_AK8975=y
CONFIG_PWM=y
CONFIG_PWM_ATMEL=m
CONFIG_PWM_ATMEL_TCB=m
+CONFIG_PWM_FSL_FTM=m
CONFIG_PWM_RENESAS_TPU=y
+CONFIG_PWM_ROCKCHIP=m
CONFIG_PWM_SAMSUNG=m
CONFIG_PWM_SUN4I=y
CONFIG_PWM_TEGRA=y
@@ -651,6 +766,10 @@ CONFIG_PHY_HIX5HD2_SATA=y
CONFIG_PWM_STI=m
CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
+CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_BERLIN_SATA=y
+CONFIG_PHY_ROCKCHIP_USB=m
+CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_MIPHY365X=y
CONFIG_PHY_RCAR_GEN2=m
@@ -659,6 +778,8 @@ CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SUNXI_SID=y
CONFIG_EXT4_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
@@ -685,6 +806,7 @@ CONFIG_CRYPTO_DEV_TEGRA_AES=y
CONFIG_CPUFREQ_DT=y
CONFIG_KEYSTONE_IRQ=y
CONFIG_CRYPTO_DEV_SUN4I_SS=m
+CONFIG_CRYPTO_DEV_ROCKCHIP=m
CONFIG_ARM_CRYPTO=y
CONFIG_CRYPTO_SHA1_ARM=m
CONFIG_CRYPTO_SHA1_ARM_NEON=m
@@ -699,3 +821,7 @@ CONFIG_CRYPTO_GHASH_ARM_CE=m
CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+CONFIG_VIRTIO_MMIO=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 85d10d2..a0345e1 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -11,6 +11,9 @@ CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_MV78XX0=y
CONFIG_MACH_DB78X00_BP=y
CONFIG_MACH_RD78X00_MASA=y
@@ -132,7 +135,6 @@ 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
diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
index 824de49..6c4c540 100644
--- a/arch/arm/configs/mvebu_v5_defconfig
+++ b/arch/arm/configs/mvebu_v5_defconfig
@@ -12,8 +12,29 @@ CONFIG_MODULE_UNLOAD=y
# 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_ARCH_ORION5X=y
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_RD88F5182_DT=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_LSCHL=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_D2NET_DT=y
+CONFIG_MACH_NET2BIG=y
+CONFIG_MACH_MSS2_DT=y
+CONFIG_MACH_WNR854T=y
+CONFIG_MACH_RD88F5181L_GE=y
+CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=y
CONFIG_PCI_MVEBU=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
@@ -26,6 +47,7 @@ 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
@@ -35,6 +57,8 @@ 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_SWITCHDEV=y
CONFIG_NET_PKTGEN=m
CONFIG_CFG80211=y
CONFIG_MAC80211=y
@@ -66,8 +90,11 @@ CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123=y
CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6352=y
CONFIG_MV643XX_ETH=y
CONFIG_R8169=y
CONFIG_MARVELL_PHY=y
@@ -91,7 +118,6 @@ 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
@@ -103,16 +129,15 @@ CONFIG_SENSORS_LM85=y
CONFIG_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=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
@@ -159,8 +184,6 @@ 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
@@ -186,7 +209,6 @@ CONFIG_DEBUG_KERNEL=y
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
index 13fcd02..c6729bf 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -61,6 +61,7 @@ CONFIG_MTD_SPI_NOR=y
CONFIG_EEPROM_AT24=y
CONFIG_BLK_DEV_SD=y
CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
CONFIG_AHCI_MVEBU=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
@@ -85,6 +86,9 @@ CONFIG_SPI=y
CONFIG_SPI_ORION=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_PCA953X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_THERMAL=y
CONFIG_ARMADA_THERMAL=y
@@ -111,12 +115,15 @@ CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_DOVE=y
CONFIG_MMC_SDHCI_PXAV3=y
CONFIG_MMC_MVSDIO=y
-CONFIG_LEDS_GPIO=y
+CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_MV=y
CONFIG_RTC_DRV_ARMADA38X=y
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 25ed772..4f3dfb2 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -5,6 +5,7 @@ CONFIG_ARCH_FOOTBRIDGE=y
CONFIG_ARCH_NETWINDER=y
CONFIG_LEDS=y
CONFIG_LEDS_CPU=y
+CONFIG_DEPRECATED_PARAM_STRUCT=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="root=0x301"
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 3f15a5c..d18d6b4 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -50,6 +50,7 @@ CONFIG_SOC_AM33XX=y
CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_ARM_ERRATA_411920=y
CONFIG_ARM_ERRATA_430973=y
CONFIG_SMP=y
@@ -177,6 +178,7 @@ CONFIG_TI_CPTS=y
CONFIG_AT803X_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_USB_USBNET=m
+CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
@@ -246,7 +248,7 @@ CONFIG_GPIO_TWL4030=y
CONFIG_GPIO_PALMAS=y
CONFIG_W1=m
CONFIG_HDQ_MASTER_OMAP=m
-CONFIG_BATTERY_BQ27x00=m
+CONFIG_BATTERY_BQ27XXX=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_TWL4030=m
CONFIG_CHARGER_BQ2415X=m
@@ -290,24 +292,23 @@ 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_OMAP5_DSS_HDMI=y
+CONFIG_FB_OMAP2_DSS_SDI=y
+CONFIG_FB_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_FB_OMAP2_ENCODER_TFP410=m
+CONFIG_FB_OMAP2_ENCODER_TPD12S015=m
+CONFIG_FB_OMAP2_CONNECTOR_DVI=m
+CONFIG_FB_OMAP2_CONNECTOR_HDMI=m
+CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV=m
+CONFIG_FB_OMAP2_PANEL_DPI=m
+CONFIG_FB_OMAP2_PANEL_DSI_CM=m
+CONFIG_FB_OMAP2_PANEL_SONY_ACX565AKM=m
+CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02=m
+CONFIG_FB_OMAP2_PANEL_SHARP_LS037V7DW01=m
+CONFIG_FB_OMAP2_PANEL_TPO_TD028TTEC1=m
+CONFIG_FB_OMAP2_PANEL_TPO_TD043MTEA1=m
+CONFIG_FB_OMAP2_PANEL_NEC_NL8048HL11=m
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=y
@@ -354,6 +355,11 @@ CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_INVENTRA_DMA=y
CONFIG_USB_TI_CPPI41_DMA=y
CONFIG_USB_DWC3=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_SIMPLE=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_TEST=m
CONFIG_AM335X_PHY_USB=y
CONFIG_USB_GADGET=m
@@ -387,6 +393,7 @@ CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_PWM=m
+CONFIG_LEDS_PCA963X=m
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
@@ -449,6 +456,8 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_SPLIT=y
+CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 8099417..6a5bc27 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -13,6 +13,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_BSD_DISKLABEL=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_ORION5X=y
CONFIG_ARCH_ORION5X_DT=y
CONFIG_MACH_DB88F5281=y
@@ -83,7 +86,7 @@ CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
CONFIG_MII=y
CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6123=y
CONFIG_MV643XX_ETH=y
CONFIG_MARVELL_PHY=y
# CONFIG_INPUT_MOUSEDEV is not set
@@ -159,7 +162,6 @@ 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
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
new file mode 100644
index 0000000..0cb724b
--- /dev/null
+++ b/arch/arm/configs/pxa_defconfig
@@ -0,0 +1,783 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=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=13
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLOB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+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_PARTITION_ADVANCED=y
+CONFIG_LDM_PARTITION=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_PXA27X_DT=y
+CONFIG_MACH_PXA3XX_DT=y
+CONFIG_ARCH_LUBBOCK=y
+CONFIG_MACH_MAINSTONE=y
+CONFIG_MACH_ZYLONITE300=y
+CONFIG_MACH_ZYLONITE320=y
+CONFIG_MACH_LITTLETON=y
+CONFIG_MACH_TAVOREVB=y
+CONFIG_MACH_SAAR=y
+CONFIG_ARCH_PXA_IDP=y
+CONFIG_ARCH_VIPER=y
+CONFIG_MACH_ARCOM_ZEUS=y
+CONFIG_MACH_BALLOON3=y
+CONFIG_MACH_CSB726=y
+CONFIG_CSB726_CSB701=y
+CONFIG_MACH_ARMCORE=y
+CONFIG_MACH_EM_X270=y
+CONFIG_MACH_EXEDA=y
+CONFIG_MACH_CM_X300=y
+CONFIG_MACH_CAPC7117=y
+CONFIG_ARCH_GUMSTIX=y
+CONFIG_MACH_INTELMOTE2=y
+CONFIG_MACH_STARGATE2=y
+CONFIG_MACH_XCEP=y
+CONFIG_TRIZEPS_PXA=y
+CONFIG_MACH_TRIZEPS4WL=y
+CONFIG_MACH_LOGICPD_PXA270=y
+CONFIG_MACH_PCM027=y
+CONFIG_MACH_PCM990_BASEBOARD=y
+CONFIG_MACH_COLIBRI=y
+CONFIG_MACH_COLIBRI_PXA270_INCOME=y
+CONFIG_MACH_COLIBRI300=y
+CONFIG_MACH_COLIBRI320=y
+CONFIG_MACH_COLIBRI_EVALBOARD=y
+CONFIG_MACH_VPAC270=y
+CONFIG_MACH_H4700=y
+CONFIG_MACH_H5000=y
+CONFIG_MACH_HIMALAYA=y
+CONFIG_MACH_MAGICIAN=y
+CONFIG_MACH_MIOA701=y
+CONFIG_PXA_EZX=y
+CONFIG_MACH_MP900C=y
+CONFIG_ARCH_PXA_PALM=y
+CONFIG_MACH_RAUMFELD_RC=y
+CONFIG_MACH_RAUMFELD_CONNECTOR=y
+CONFIG_MACH_RAUMFELD_SPEAKER=y
+CONFIG_PXA_SHARPSL=y
+CONFIG_MACH_POODLE=y
+CONFIG_MACH_CORGI=y
+CONFIG_MACH_SHEPHERD=y
+CONFIG_MACH_HUSKY=y
+CONFIG_MACH_AKITA=y
+CONFIG_MACH_BORZOI=y
+CONFIG_MACH_TOSA=y
+CONFIG_TOSA_BT=m
+CONFIG_TOSA_USE_EXT_KEYCODES=y
+CONFIG_MACH_ICONTROL=y
+CONFIG_ARCH_PXA_ESERIES=y
+CONFIG_MACH_ZIPIT2=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 ro"
+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=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPUFREQ_DT=m
+CONFIG_ARM_PXA2xx_CPUFREQ=m
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_BINFMT_MISC=y
+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_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IEEE802154=y
+CONFIG_DNS_RESOLVER=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_IRTTY_SIR=m
+CONFIG_PXA_FICP=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_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_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=0
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CMDLINE_PARTS=m
+CONFIG_MTD_AFS_PARTS=m
+CONFIG_MTD_OF_PARTS=m
+CONFIG_MTD_AR7_PARTS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_OTP=y
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PXA2XX=m
+CONFIG_MTD_M25P80=m
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_DOCG3=m
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_ECC_BCH=y
+CONFIG_MTD_NAND_GPIO=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+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_NAND_SHARPSL=m
+CONFIG_MTD_NAND_PXA3xx=m
+CONFIG_MTD_NAND_CM_X270=m
+CONFIG_MTD_NAND_TMIO=m
+CONFIG_MTD_NAND_BRCMNAND=m
+CONFIG_MTD_NAND_PLATFORM=m
+CONFIG_MTD_ONENAND=m
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_GENERIC=m
+CONFIG_MTD_SPI_NOR=m
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+CONFIG_AD525X_DPOT=m
+CONFIG_AD525X_DPOT_I2C=m
+CONFIG_ICS932S401=m
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_TI_DAC7512=m
+CONFIG_EEPROM_AT24=m
+CONFIG_SENSORS_LIS3_SPI=m
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=m
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_SATA_MV=m
+CONFIG_PATA_PXA=m
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PLATFORM=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_MACB=m
+CONFIG_DM9000=m
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+CONFIG_IGB=m
+CONFIG_KS8851=y
+CONFIG_AX88796=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_8139TOO=m
+CONFIG_R8169=m
+CONFIG_SMC91X=m
+CONFIG_SMSC911X=m
+CONFIG_STMMAC_ETH=m
+CONFIG_PHYLIB=y
+CONFIG_AT803X_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=m
+CONFIG_MICREL_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_MDIO_BITBANG=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_BRCMFMAC=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_RT2X00=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_APMPOWER=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_QT1070=m
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_PXA27x=m
+CONFIG_KEYBOARD_PXA930_ROTARY=m
+CONFIG_KEYBOARD_CROS_EC=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_CYAPA=m
+CONFIG_MOUSE_ELAN_I2C=m
+CONFIG_MOUSE_PXA930_TRKBALL=m
+CONFIG_MOUSE_NAVPOINT_PXA27x=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_DA9034=m
+CONFIG_TOUCHSCREEN_EETI=m
+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_UCB1400=m
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_PCAP=m
+CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=m
+CONFIG_INPUT_AXP20X_PEK=m
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+CONFIG_INPUT_PCAP=m
+CONFIG_INPUT_ADXL34X=m
+CONFIG_SERIO=m
+CONFIG_SERIO_SA1111=m
+CONFIG_LEGACY_PTY_COUNT=8
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=7
+CONFIG_SERIAL_8250_RUNTIME_UARTS=7
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX_PCA954x=m
+CONFIG_I2C_MUX_PINCTRL=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+CONFIG_I2C_PXA_SLAVE=y
+CONFIG_I2C_XILINX=m
+CONFIG_I2C_CROS_EC_TUNNEL=m
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_CADENCE=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_PXA2XX=m
+CONFIG_SPI_ROCKCHIP=m
+CONFIG_SPI_XILINX=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_PPS=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_DWAPB=m
+CONFIG_GPIO_GENERIC_PLATFORM=m
+CONFIG_GPIO_MAX732X=m
+CONFIG_GPIO_PCA953X=m
+CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_MAX7301=m
+CONFIG_POWER_SUPPLY_DEBUG=y
+CONFIG_PDA_POWER=m
+CONFIG_BATTERY_SBS=m
+CONFIG_BATTERY_DA9030=m
+CONFIG_BATTERY_MAX17040=m
+CONFIG_BATTERY_MAX17042=m
+CONFIG_CHARGER_MAX14577=m
+CONFIG_CHARGER_MAX77693=m
+CONFIG_CHARGER_TPS65090=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM95245=m
+CONFIG_SENSORS_NTC_THERMISTOR=m
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_XILINX_WATCHDOG=m
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_MFD_AS3711=y
+CONFIG_MFD_BCM590XX=m
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_CROS_EC=m
+CONFIG_MFD_CROS_EC_I2C=m
+CONFIG_MFD_CROS_EC_SPI=m
+CONFIG_MFD_ASIC3=y
+CONFIG_PMIC_DA903X=y
+CONFIG_HTC_EGPIO=y
+CONFIG_HTC_PASIC3=m
+CONFIG_MFD_MAX14577=y
+CONFIG_MFD_MAX77693=y
+CONFIG_MFD_MAX8907=m
+CONFIG_EZX_PCAP=y
+CONFIG_UCB1400_CORE=m
+CONFIG_MFD_PM8921_CORE=m
+CONFIG_MFD_SEC_CORE=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_MFD_T7L66XB=y
+CONFIG_MFD_TC6387XB=y
+CONFIG_MFD_TC6393XB=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=m
+CONFIG_REGULATOR_USERSPACE_CONSUMER=m
+CONFIG_REGULATOR_ACT8865=m
+CONFIG_REGULATOR_AS3711=m
+CONFIG_REGULATOR_AXP20X=m
+CONFIG_REGULATOR_BCM590XX=m
+CONFIG_REGULATOR_DA903X=m
+CONFIG_REGULATOR_DA9210=m
+CONFIG_REGULATOR_FAN53555=m
+CONFIG_REGULATOR_GPIO=m
+CONFIG_REGULATOR_MAX14577=m
+CONFIG_REGULATOR_MAX8660=m
+CONFIG_REGULATOR_MAX8907=m
+CONFIG_REGULATOR_MAX8973=m
+CONFIG_REGULATOR_MAX77693=m
+CONFIG_REGULATOR_PALMAS=m
+CONFIG_REGULATOR_PCAP=m
+CONFIG_REGULATOR_PWM=m
+CONFIG_REGULATOR_S2MPS11=m
+CONFIG_REGULATOR_S5M8767=m
+CONFIG_REGULATOR_TPS51632=m
+CONFIG_REGULATOR_TPS62360=m
+CONFIG_REGULATOR_TPS65090=m
+CONFIG_REGULATOR_TPS6586X=m
+CONFIG_REGULATOR_TPS65910=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=m
+CONFIG_SOC_CAMERA_PLATFORM=m
+CONFIG_VIDEO_PXA27x=m
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_SOC_CAMERA_MT9M111=m
+CONFIG_DRM=m
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_PXA_OVERLAY=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_PXA3XX_GCU=m
+CONFIG_FB_MBX=m
+CONFIG_FB_VIRTUAL=m
+CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CORGI=m
+CONFIG_LCD_PLATFORM=m
+CONFIG_LCD_TOSA=m
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_BACKLIGHT_TOSA=m
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_PXA2XX_AC97=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=m
+CONFIG_SND_ATMEL_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_CORGI=m
+CONFIG_SND_PXA2XX_SOC_SPITZ=m
+CONFIG_SND_PXA2XX_SOC_Z2=m
+CONFIG_SND_PXA2XX_SOC_POODLE=m
+CONFIG_SND_PXA2XX_SOC_TOSA=m
+CONFIG_SND_PXA2XX_SOC_E740=m
+CONFIG_SND_PXA2XX_SOC_E750=m
+CONFIG_SND_PXA2XX_SOC_E800=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
+CONFIG_SND_PXA2XX_SOC_PALM27X=y
+CONFIG_SND_SOC_ZYLONITE=m
+CONFIG_SND_SOC_RAUMFELD=m
+CONFIG_SND_PXA2XX_SOC_HX4700=m
+CONFIG_SND_PXA2XX_SOC_MAGICIAN=m
+CONFIG_SND_PXA2XX_SOC_MIOA701=m
+CONFIG_SND_PXA2XX_SOC_IMOTE2=m
+CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_WM8978=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SOUND_PRIME=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_DRAGONRISE=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_HID_ZEROPLUS=m
+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_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=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_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_DWC3=m
+CONFIG_USB_DWC2=m
+CONFIG_USB_CHIPIDEA=m
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_ISP1760=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_GPIO_VBUS=y
+CONFIG_USB_ISP1301=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_PXA25X=m
+CONFIG_USB_PXA27X=m
+CONFIG_USB_ZERO=m
+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_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=m
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_SDIO_UART=m
+CONFIG_MMC_PXA=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SDHCI_PLTFM=m
+CONFIG_MMC_TMIO=m
+CONFIG_MMC_DW=m
+CONFIG_MMC_DW_EXYNOS=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_DA903X=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_LT3593=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_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DEBUG=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_MAX8907=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_PALMAS=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_TPS6586X=m
+CONFIG_RTC_DRV_TPS65910=m
+CONFIG_RTC_DRV_S35390A=m
+CONFIG_RTC_DRV_RX8581=m
+CONFIG_RTC_DRV_EM3027=m
+CONFIG_RTC_DRV_S5M=m
+CONFIG_RTC_DRV_V3020=m
+CONFIG_RTC_DRV_PXA=m
+CONFIG_RTC_DRV_PCAP=m
+CONFIG_DMADEVICES=y
+CONFIG_PXA_DMA=y
+CONFIG_DW_DMAC=m
+CONFIG_UIO=y
+CONFIG_CROS_EC_CHARDEV=m
+CONFIG_COMMON_CLK_S2MPS11=m
+CONFIG_PM_DEVFREQ=y
+CONFIG_EXTCON=y
+CONFIG_MEMORY=y
+CONFIG_PWM=y
+CONFIG_PWM_PXA=m
+CONFIG_PHY_SAMSUNG_USB2=m
+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_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=1
+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_UBIFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=0
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_TIMER_STATS=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_DEBUG_USER=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=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_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM=m
+CONFIG_CRYPTO_SHA256_ARM=m
+CONFIG_CRYPTO_SHA512_ARM=m
+CONFIG_CRYPTO_AES_ARM=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_MINI_4x6=y
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index ff7985b..7bff7bf 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -1,8 +1,10 @@
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_BLK_DEV_INITRD=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
@@ -22,10 +24,10 @@ CONFIG_ARCH_MSM8X60=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8974=y
CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=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
@@ -78,10 +80,14 @@ CONFIG_USB_USBNET=y
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PMIC8XXX=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8XXX_VIBRATOR=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
@@ -99,16 +105,22 @@ CONFIG_PINCTRL_APQ8084=y
CONFIG_PINCTRL_IPQ8064=y
CONFIG_PINCTRL_MSM8960=y
CONFIG_PINCTRL_MSM8X74=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_GPIOLIB=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
+CONFIG_CHARGER_QCOM_SMBB=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_MSM=y
CONFIG_THERMAL=y
+CONFIG_MFD_PM8921_CORE=y
CONFIG_MFD_QCOM_RPM=y
+CONFIG_MFD_SPMI_PMIC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_QCOM_RPM=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_FB=y
CONFIG_SOUND=y
@@ -135,6 +147,7 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PM8XXX=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_STAGING=y
@@ -145,16 +158,17 @@ 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_HWSPINLOCK_QCOM=y
CONFIG_QCOM_GSBI=y
CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=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
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index 1da5d9e..93efdcf 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -1,19 +1,29 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_FULL=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_PERF_EVENTS=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_MULTI_V6=y
CONFIG_ARCH_REALVIEW=y
+CONFIG_REALVIEW_DT=y
CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM1136=y
+CONFIG_REALVIEW_EB_ARM1176=y
+CONFIG_REALVIEW_EB_A9MP=y
CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_REALVIEW_EB_ARM11MP_REVB=y
CONFIG_MACH_REALVIEW_PB11MP=y
+CONFIG_MACH_REALVIEW_PB1176=y
+CONFIG_MACH_REALVIEW_PBA8=y
+CONFIG_MACH_REALVIEW_PBX=y
CONFIG_SMP=y
-CONFIG_HOTPLUG_CPU=y
CONFIG_AEABI=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
@@ -30,28 +40,24 @@ CONFIG_IP_PNP_BOOTP=y
# 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_AFS_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=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_SMSC_PHY=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_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_VERSATILE=y
@@ -70,8 +76,8 @@ 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_USB=y
+CONFIG_USB_ISP1760=y
CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
CONFIG_NEW_LEDS=y
@@ -87,17 +93,13 @@ 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_MAGIC_SYSRQ=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
index d02e9d9..8f56fb3 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -1,18 +1,26 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_PERF_EVENTS=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_MULTI_V6=y
CONFIG_ARCH_REALVIEW=y
+CONFIG_REALVIEW_DT=y
CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM1136=y
+CONFIG_REALVIEW_EB_ARM1176=y
+CONFIG_REALVIEW_EB_A9MP=y
CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_REALVIEW_EB_ARM11MP_REVB=y
CONFIG_MACH_REALVIEW_PB11MP=y
CONFIG_MACH_REALVIEW_PB1176=y
+CONFIG_MACH_REALVIEW_PBA8=y
+CONFIG_MACH_REALVIEW_PBX=y
CONFIG_AEABI=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
@@ -29,28 +37,24 @@ CONFIG_IP_PNP_BOOTP=y
# 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_AFS_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=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_SMSC_PHY=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_LEGACY_PTY_COUNT=16
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_VERSATILE=y
@@ -69,8 +73,8 @@ 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_USB=y
+CONFIG_USB_ISP1760=y
CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
CONFIG_NEW_LEDS=y
@@ -86,17 +90,13 @@ 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_MAGIC_SYSRQ=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/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig
index e2f9fa5..e0f6693 100644
--- a/arch/arm/configs/s3c6400_defconfig
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -5,6 +5,8 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MULTI_V6=y
+# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_S3C64XX=y
CONFIG_S3C_BOOT_ERROR_RESET=y
CONFIG_MACH_SMDK6400=y
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig
index 31eb951..c11bab7 100644
--- a/arch/arm/configs/sama5_defconfig
+++ b/arch/arm/configs/sama5_defconfig
@@ -10,12 +10,11 @@ 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_SAMA5D2=y
CONFIG_SOC_SAMA5D3=y
CONFIG_SOC_SAMA5D4=y
CONFIG_AEABI=y
@@ -25,12 +24,10 @@ 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
@@ -47,7 +44,6 @@ CONFIG_IP_PNP_RARP=y
# 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
@@ -123,7 +119,6 @@ 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
@@ -134,7 +129,10 @@ CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_RESET=y
# CONFIG_HWMON is not set
-CONFIG_SSB=m
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_SAMA5D4_WATCHDOG=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_ACT8865=y
@@ -142,8 +140,8 @@ 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_SOC_CAMERA_OV2640=y
CONFIG_FB=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
@@ -171,6 +169,9 @@ CONFIG_USB_ATMEL_USBA=y
CONFIG_USB_G_SERIAL=y
CONFIG_MMC=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_AT91=y
CONFIG_MMC_ATMELMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -207,11 +208,8 @@ 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/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 89bf31c..9697383 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -2,14 +2,13 @@ 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_RENESAS=y
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R7S72100=y
CONFIG_ARCH_R8A73A4=y
@@ -21,7 +20,6 @@ CONFIG_ARCH_R8A7791=y
CONFIG_ARCH_R8A7793=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
@@ -54,6 +52,8 @@ CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
+CONFIG_CAN=y
+CONFIG_CAN_RCAR=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
@@ -100,6 +100,7 @@ CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=20
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_EMEV2=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_RIIC=y
CONFIG_I2C_SH_MOBILE=y
@@ -136,18 +137,23 @@ CONFIG_SOC_CAMERA=y
CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_VIDEO_RCAR_VIN=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_JPU=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_I2C_ADV7511=y
CONFIG_DRM_RCAR_DU=y
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=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_FRAMEBUFFER_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
@@ -161,7 +167,6 @@ 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_GADGET=y
CONFIG_USB_RENESAS_USBHS_UDC=y
CONFIG_USB_ETH=y
@@ -175,9 +180,13 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_RS5C372=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_RX8581=y
+CONFIG_RTC_DRV_DA9063=y
CONFIG_DMADEVICES=y
CONFIG_SH_DMAE=y
CONFIG_RCAR_DMAC=y
+CONFIG_RENESAS_USB_DMAC=y
+CONFIG_STAGING=y
+CONFIG_STAGING_BOARD=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_IIO=y
CONFIG_AK8975=y
@@ -197,6 +206,7 @@ CONFIG_NFS_V4_1=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=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/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index a2956c3..f7f4e2e 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -36,7 +36,6 @@ 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
@@ -57,7 +56,6 @@ 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
@@ -83,14 +81,16 @@ CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_HOST=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GADGET=y
CONFIG_MMC=y
CONFIG_MMC_DW=y
+CONFIG_FPGA=y
+CONFIG_FPGA_MGR_SOCFPGA=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
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 4725fab..ec52505 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -54,6 +54,8 @@ CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_DMADEVICES=y
+CONFIG_STM32_DMA=y
# CONFIG_FILE_LOCKING is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 51eea22..a9a81a7 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -5,19 +5,18 @@ CONFIG_CGROUPS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PERF_EVENTS=y
CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=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
@@ -31,10 +30,11 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
+CONFIG_CAN=y
+CONFIG_CAN_SUN4I=y
# 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
@@ -58,12 +58,12 @@ CONFIG_STMMAC_ETH=y
# 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_KEYBOARD_SUN4I_LRADC=y
# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_AXP20X_PEK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=8
@@ -80,11 +80,14 @@ CONFIG_SPI_SUN4I=y
CONFIG_SPI_SUN6I=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
+CONFIG_AXP20X_POWER=y
CONFIG_THERMAL=y
CONFIG_CPU_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+CONFIG_MFD_AXP20X_RSB=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_AXP20X=y
@@ -119,6 +122,8 @@ CONFIG_PWM=y
CONFIG_PWM_SUN4I=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SUNXI_SID=y
CONFIG_EXT4_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 9808581..3a36244 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -1,5 +1,6 @@
CONFIG_SYSVIPC=y
CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
@@ -60,7 +61,6 @@ CONFIG_INET_ESP=y
# 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
@@ -121,6 +121,9 @@ CONFIG_KEYBOARD_CROS_EC=y
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
CONFIG_TOUCHSCREEN_STMPE=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_MPU3050=y
@@ -142,6 +145,7 @@ CONFIG_SPI_TEGRA20_SFLASH=y
CONFIG_SPI_TEGRA20_SLINK=y
CONFIG_PINCTRL_AS3722=y
CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PALMAS=y
@@ -208,6 +212,7 @@ 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_WM9712=y
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
CONFIG_SND_SOC_TEGRA_ALC5632=y
CONFIG_SND_SOC_TEGRA_MAX98090=y
@@ -266,10 +271,8 @@ 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
@@ -278,6 +281,7 @@ CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
index 4bc8700..0ada29d 100644
--- a/arch/arm/configs/trizeps4_defconfig
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -214,7 +214,6 @@ 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
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index ea49d37..295408e 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -1,13 +1,15 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=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_MULTI_V7 is not set
CONFIG_ARCH_VERSATILE=y
-CONFIG_MACH_VERSATILE_AB=y
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -47,9 +49,12 @@ CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_PL061=y
# CONFIG_HWMON is not set
+CONFIG_MFD_SYSCON=y
CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -59,13 +64,15 @@ CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_ARMAACI=m
CONFIG_MMC=y
-CONFIG_MMC_ARMMMCI=m
+CONFIG_MMC_ARMMMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_VERSATILE=y
+CONFIG_LEDS_SYSCON=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_EXT2_FS=y
CONFIG_VFAT_FS=m
CONFIG_JFFS2_FS=y
@@ -82,6 +89,5 @@ 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/zx_defconfig b/arch/arm/configs/zx_defconfig
index b200bb0..ab683fb 100644
--- a/arch/arm/configs/zx_defconfig
+++ b/arch/arm/configs/zx_defconfig
@@ -83,7 +83,6 @@ CONFIG_MMC=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
CONFIG_EXT2_FS=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c
index b445a5d..da3c042 100644
--- a/arch/arm/crypto/aes-ce-glue.c
+++ b/arch/arm/crypto/aes-ce-glue.c
@@ -15,6 +15,7 @@
#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <linux/module.h>
+#include <crypto/xts.h>
MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
@@ -152,6 +153,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
int ret;
+ ret = xts_check_key(tfm, in_key, key_len);
+ if (ret)
+ return 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],
@@ -364,7 +369,7 @@ static struct crypto_alg aes_algs[] = { {
.cra_blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
- .ivsize = AES_BLOCK_SIZE,
+ .ivsize = 0,
.setkey = ce_aes_setkey,
.encrypt = ecb_encrypt,
.decrypt = ecb_decrypt,
@@ -441,7 +446,7 @@ static struct crypto_alg aes_algs[] = { {
.cra_ablkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
- .ivsize = AES_BLOCK_SIZE,
+ .ivsize = 0,
.setkey = ablk_set_key,
.encrypt = ablk_encrypt,
.decrypt = ablk_decrypt,
diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
index 6d68529..0511a6c 100644
--- a/arch/arm/crypto/aesbs-glue.c
+++ b/arch/arm/crypto/aesbs-glue.c
@@ -13,6 +13,7 @@
#include <crypto/ablk_helper.h>
#include <crypto/algapi.h>
#include <linux/module.h>
+#include <crypto/xts.h>
#include "aes_glue.h"
@@ -89,6 +90,11 @@ static int aesbs_xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
{
struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm);
int bits = key_len * 4;
+ int err;
+
+ err = xts_check_key(tfm, in_key, key_len);
+ if (err)
+ return err;
if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index be648eb..3f6616b 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -3,6 +3,7 @@
generic-y += bitsperlong.h
generic-y += cputime.h
generic-y += current.h
+generic-y += early_ioremap.h
generic-y += emergency-restart.h
generic-y += errno.h
generic-y += exec.h
@@ -14,6 +15,7 @@ generic-y += local.h
generic-y += local64.h
generic-y += mm-arch-hooks.h
generic-y += msgbuf.h
+generic-y += msi.h
generic-y += param.h
generic-y += parport.h
generic-y += poll.h
@@ -21,7 +23,6 @@ generic-y += preempt.h
generic-y += resource.h
generic-y += rwsem.h
generic-y += seccomp.h
-generic-y += sections.h
generic-y += segment.h
generic-y += sembuf.h
generic-y += serial.h
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
new file mode 100644
index 0000000..e08d151
--- /dev/null
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -0,0 +1,190 @@
+/*
+ * arch/arm/include/asm/arch_gicv3.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_ARCH_GICV3_H
+#define __ASM_ARCH_GICV3_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/io.h>
+#include <asm/barrier.h>
+
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2) p15, Op1, %0, CRn, CRm, Op2
+#define __ACCESS_CP15_64(Op1, CRm) p15, Op1, %Q0, %R0, CRm
+
+#define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
+#define ICC_DIR __ACCESS_CP15(c12, 0, c11, 1)
+#define ICC_IAR1 __ACCESS_CP15(c12, 0, c12, 0)
+#define ICC_SGI1R __ACCESS_CP15_64(0, c12)
+#define ICC_PMR __ACCESS_CP15(c4, 0, c6, 0)
+#define ICC_CTLR __ACCESS_CP15(c12, 0, c12, 4)
+#define ICC_SRE __ACCESS_CP15(c12, 0, c12, 5)
+#define ICC_IGRPEN1 __ACCESS_CP15(c12, 0, c12, 7)
+
+#define ICC_HSRE __ACCESS_CP15(c12, 4, c9, 5)
+
+#define ICH_VSEIR __ACCESS_CP15(c12, 4, c9, 4)
+#define ICH_HCR __ACCESS_CP15(c12, 4, c11, 0)
+#define ICH_VTR __ACCESS_CP15(c12, 4, c11, 1)
+#define ICH_MISR __ACCESS_CP15(c12, 4, c11, 2)
+#define ICH_EISR __ACCESS_CP15(c12, 4, c11, 3)
+#define ICH_ELSR __ACCESS_CP15(c12, 4, c11, 5)
+#define ICH_VMCR __ACCESS_CP15(c12, 4, c11, 7)
+
+#define __LR0(x) __ACCESS_CP15(c12, 4, c12, x)
+#define __LR8(x) __ACCESS_CP15(c12, 4, c13, x)
+
+#define ICH_LR0 __LR0(0)
+#define ICH_LR1 __LR0(1)
+#define ICH_LR2 __LR0(2)
+#define ICH_LR3 __LR0(3)
+#define ICH_LR4 __LR0(4)
+#define ICH_LR5 __LR0(5)
+#define ICH_LR6 __LR0(6)
+#define ICH_LR7 __LR0(7)
+#define ICH_LR8 __LR8(0)
+#define ICH_LR9 __LR8(1)
+#define ICH_LR10 __LR8(2)
+#define ICH_LR11 __LR8(3)
+#define ICH_LR12 __LR8(4)
+#define ICH_LR13 __LR8(5)
+#define ICH_LR14 __LR8(6)
+#define ICH_LR15 __LR8(7)
+
+/* LR top half */
+#define __LRC0(x) __ACCESS_CP15(c12, 4, c14, x)
+#define __LRC8(x) __ACCESS_CP15(c12, 4, c15, x)
+
+#define ICH_LRC0 __LRC0(0)
+#define ICH_LRC1 __LRC0(1)
+#define ICH_LRC2 __LRC0(2)
+#define ICH_LRC3 __LRC0(3)
+#define ICH_LRC4 __LRC0(4)
+#define ICH_LRC5 __LRC0(5)
+#define ICH_LRC6 __LRC0(6)
+#define ICH_LRC7 __LRC0(7)
+#define ICH_LRC8 __LRC8(0)
+#define ICH_LRC9 __LRC8(1)
+#define ICH_LRC10 __LRC8(2)
+#define ICH_LRC11 __LRC8(3)
+#define ICH_LRC12 __LRC8(4)
+#define ICH_LRC13 __LRC8(5)
+#define ICH_LRC14 __LRC8(6)
+#define ICH_LRC15 __LRC8(7)
+
+#define __AP0Rx(x) __ACCESS_CP15(c12, 4, c8, x)
+#define ICH_AP0R0 __AP0Rx(0)
+#define ICH_AP0R1 __AP0Rx(1)
+#define ICH_AP0R2 __AP0Rx(2)
+#define ICH_AP0R3 __AP0Rx(3)
+
+#define __AP1Rx(x) __ACCESS_CP15(c12, 4, c9, x)
+#define ICH_AP1R0 __AP1Rx(0)
+#define ICH_AP1R1 __AP1Rx(1)
+#define ICH_AP1R2 __AP1Rx(2)
+#define ICH_AP1R3 __AP1Rx(3)
+
+/* Low-level accessors */
+
+static inline void gic_write_eoir(u32 irq)
+{
+ asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
+ isb();
+}
+
+static inline void gic_write_dir(u32 val)
+{
+ asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
+ isb();
+}
+
+static inline u32 gic_read_iar(void)
+{
+ u32 irqstat;
+
+ asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
+ dsb(sy);
+ return irqstat;
+}
+
+static inline void gic_write_pmr(u32 val)
+{
+ asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+}
+
+static inline void gic_write_ctlr(u32 val)
+{
+ asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
+ isb();
+}
+
+static inline void gic_write_grpen1(u32 val)
+{
+ asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+ isb();
+}
+
+static inline void gic_write_sgi1r(u64 val)
+{
+ asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
+}
+
+static inline u32 gic_read_sre(void)
+{
+ u32 val;
+
+ asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
+ return val;
+}
+
+static inline void gic_write_sre(u32 val)
+{
+ asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
+ isb();
+}
+
+/*
+ * Even in 32bit systems that use LPAE, there is no guarantee that the I/O
+ * interface provides true 64bit atomic accesses, so using strd/ldrd doesn't
+ * make much sense.
+ * Moreover, 64bit I/O emulation is extremely difficult to implement on
+ * AArch32, since the syndrome register doesn't provide any information for
+ * them.
+ * Consequently, the following IO helpers use 32bit accesses.
+ *
+ * There are only two registers that need 64bit accesses in this driver:
+ * - GICD_IROUTERn, contain the affinity values associated to each interrupt.
+ * The upper-word (aff3) will always be 0, so there is no need for a lock.
+ * - GICR_TYPER is an ID register and doesn't need atomicity.
+ */
+static inline void gic_write_irouter(u64 val, volatile void __iomem *addr)
+{
+ writel_relaxed((u32)val, addr);
+ writel_relaxed((u32)(val >> 32), addr + 4);
+}
+
+static inline u64 gic_read_typer(const volatile void __iomem *addr)
+{
+ u64 val;
+
+ val = readl_relaxed(addr);
+ val |= (u64)readl_relaxed(addr + 4) << 32;
+ return val;
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif /* !__ASM_ARCH_GICV3_H */
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index fe3ef39..9e10c45 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -27,8 +27,8 @@
* 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))
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
#if __LINUX_ARM_ARCH__ >= 6
@@ -210,8 +210,8 @@ ATOMIC_OP(xor, ^=, eor)
#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_inc_return_relaxed(v) (atomic_add_return_relaxed(1, v))
+#define atomic_dec_return_relaxed(v) (atomic_sub_return_relaxed(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)
@@ -442,11 +442,11 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
#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_return_relaxed(v) atomic64_add_return_relaxed(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_return_relaxed(v) atomic64_sub_return_relaxed(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)
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 3ff5642..112cc1a 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -60,38 +60,11 @@ extern void arm_heavy_mb(void);
#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(); \
- WRITE_ONCE(*p, v); \
-} while (0)
-
-#define smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_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 smp_store_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
+#define __smp_mb() dmb(ish)
+#define __smp_rmb() __smp_mb()
+#define __smp_wmb() dmb(ishst)
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() smp_mb()
+#include <asm-generic/barrier.h>
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_BARRIER_H */
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index e7335a9..4e6e88a 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -5,8 +5,6 @@
#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
@@ -47,7 +45,7 @@ do { \
unreachable(); \
} while (0)
-#else /* not CONFIG_DEBUG_BUGVERBOSE */
+#else
#define __BUG(__file, __line, __value) \
do { \
@@ -57,7 +55,6 @@ do { \
#endif /* CONFIG_DEBUG_BUGVERBOSE */
#define HAVE_ARCH_BUG
-#endif /* CONFIG_BUG */
#include <asm-generic/bug.h>
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index d5525bf..9156fc3 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -491,7 +491,6 @@ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
#endif
#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void);
void set_kernel_text_rw(void);
void set_kernel_text_ro(void);
#else
diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h
index 5233151..524692f 100644
--- a/arch/arm/include/asm/checksum.h
+++ b/arch/arm/include/asm/checksum.h
@@ -84,10 +84,10 @@ ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
- u32 lenprot = len | proto << 16;
+ u32 lenprot = len + proto;
if (__builtin_constant_p(sum) && sum == 0) {
__asm__(
"adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t"
@@ -121,8 +121,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* 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)
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
@@ -144,8 +144,8 @@ __csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __
__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)
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+ __u32 len, __u8 proto, __wsum sum)
{
return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
htonl(proto), sum));
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index 916a274..97882f9 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -39,6 +39,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
switch (size) {
#if __LINUX_ARM_ARCH__ >= 6
+#ifndef CONFIG_CPU_V6 /* MIN ARCH >= V6K */
case 1:
asm volatile("@ __xchg1\n"
"1: ldrexb %0, [%3]\n"
@@ -49,6 +50,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
+ case 2:
+ asm volatile("@ __xchg2\n"
+ "1: ldrexh %0, [%3]\n"
+ " strexh %1, %2, [%3]\n"
+ " teq %1, #0\n"
+ " bne 1b"
+ : "=&r" (ret), "=&r" (tmp)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+#endif
case 4:
asm volatile("@ __xchg4\n"
"1: ldrex %0, [%3]\n"
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
index 0f84249..3848259 100644
--- a/arch/arm/include/asm/cpuidle.h
+++ b/arch/arm/include/asm/cpuidle.h
@@ -30,7 +30,7 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
struct device_node;
struct cpuidle_ops {
- int (*suspend)(int cpu, unsigned long arg);
+ int (*suspend)(unsigned long arg);
int (*init)(struct device_node *, int cpu);
};
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 85e374f..b23c6c8 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -228,10 +228,26 @@ static inline int cpu_is_xsc3(void)
}
#endif
-#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
-#define cpu_is_xscale() 0
+#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) && \
+ !defined(CONFIG_CPU_MOHAWK)
+#define cpu_is_xscale_family() 0
#else
-#define cpu_is_xscale() 1
+static inline int cpu_is_xscale_family(void)
+{
+ unsigned int id;
+ id = read_cpuid_id() & 0xffffe000;
+
+ switch (id) {
+ case 0x69052000: /* Intel XScale 1 */
+ case 0x69054000: /* Intel XScale 2 */
+ case 0x69056000: /* Intel XScale 3 */
+ case 0x56056000: /* Marvell XScale 3 */
+ case 0x56158000: /* Marvell Mohawk */
+ return 1;
+ }
+
+ return 0;
+}
#endif
/*
diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
index 662c7bd..7d919a9 100644
--- a/arch/arm/include/asm/div64.h
+++ b/arch/arm/include/asm/div64.h
@@ -5,9 +5,9 @@
#include <asm/compiler.h>
/*
- * The semantics of do_div() are:
+ * The semantics of __div64_32() are:
*
- * uint32_t do_div(uint64_t *n, uint32_t base)
+ * uint32_t __div64_32(uint64_t *n, uint32_t base)
* {
* uint32_t remainder = *n % base;
* *n = *n / base;
@@ -16,8 +16,9 @@
*
* 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).
+ * we override the generic version in lib/div64.c to call our __do_div64
+ * assembly implementation with completely non standard calling convention
+ * for arguments and results (beware).
*/
#ifdef __ARMEB__
@@ -28,199 +29,101 @@
#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)
+static inline uint32_t __div64_32(uint64_t *n, uint32_t 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;
+ return __rem;
+}
+#define __div64_32 __div64_32
+
+#if !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.
+ * In OABI configurations, some uses of the do_div function
+ * cause gcc to run out of registers. To work around that,
+ * we can force the use of the out-of-line version for
+ * configurations that build a OABI kernel.
*/
-#define do_div(n, base) __do_div_asm(n, base)
-
-#elif __GNUC__ >= 4
+#define do_div(n, base) __div64_32(&(n), base)
-#include <asm/bug.h>
+#else
/*
- * 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.)
+ * gcc versions earlier than 4.0 are simply too problematic for the
+ * __div64_const32() code in asm-generic/div64.h. 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) \
-({ \
- 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; \
-})
+
+#define __div64_const32_is_OK (__GNUC__ >= 4)
+
+static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias)
+{
+ unsigned long long res;
+ register unsigned int tmp asm("ip") = 0;
+
+ if (!bias) {
+ 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, %Q2, %Q3\n\t"
+ "cmn %Q0, %Q2\n\t"
+ "adcs %R0, %R0, %R2\n\t"
+ "adc %Q0, %1, #0"
+ : "=&r" (res), "+&r" (tmp)
+ : "r" (m), "r" (n)
+ : "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" (tmp)
+ : "r" (m), "r" (n)
+ : "cc");
+ }
+
+ return res;
+}
+#define __arch_xprod_64 __arch_xprod_64
+
+#include <asm-generic/div64.h>
#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index ccb3aa6..6ad1ced 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -41,13 +41,6 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
#define HAVE_ARCH_DMA_SUPPORTED 1
extern int dma_supported(struct device *dev, u64 mask);
-/*
- * Note that while the generic code provides dummy dma_{alloc,free}_noncoherent
- * implementations, we don't provide a dma_cache_sync function so drivers using
- * this API are highlighted with build warnings.
- */
-#include <asm-generic/dma-mapping-common.h>
-
#ifdef __arch_page_to_dma
#error Please update to __arch_pfn_to_dma
#endif
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
new file mode 100644
index 0000000..e0eea72
--- /dev/null
+++ b/arch/arm/include/asm/efi.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef __ASM_ARM_EFI_H
+#define __ASM_ARM_EFI_H
+
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/early_ioremap.h>
+#include <asm/fixmap.h>
+#include <asm/highmem.h>
+#include <asm/mach/map.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_EFI
+void efi_init(void);
+
+int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
+
+#define efi_call_virt(f, ...) \
+({ \
+ efi_##f##_t *__f; \
+ efi_status_t __s; \
+ \
+ efi_virtmap_load(); \
+ __f = efi.systab->runtime->f; \
+ __s = __f(__VA_ARGS__); \
+ efi_virtmap_unload(); \
+ __s; \
+})
+
+#define __efi_call_virt(f, ...) \
+({ \
+ efi_##f##_t *__f; \
+ \
+ efi_virtmap_load(); \
+ __f = efi.systab->runtime->f; \
+ __f(__VA_ARGS__); \
+ efi_virtmap_unload(); \
+})
+
+static inline void efi_set_pgd(struct mm_struct *mm)
+{
+ check_and_switch_context(mm, NULL);
+}
+
+void efi_virtmap_load(void);
+void efi_virtmap_unload(void);
+
+#else
+#define efi_init()
+#endif /* CONFIG_EFI */
+
+/* arch specific definitions used by the stub code */
+
+#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
+
+/*
+ * A reasonable upper bound for the uncompressed kernel size is 32 MBytes,
+ * so we will reserve that amount of memory. We have no easy way to tell what
+ * the actuall size of code + data the uncompressed kernel will use.
+ * If this is insufficient, the decompressor will relocate itself out of the
+ * way before performing the decompression.
+ */
+#define MAX_UNCOMP_KERNEL_SIZE SZ_32M
+
+/*
+ * The kernel zImage should preferably be located between 32 MB and 128 MB
+ * from the base of DRAM. The min address leaves space for a maximal size
+ * uncompressed image, and the max address is due to how the zImage decompressor
+ * picks a destination address.
+ */
+#define ZIMAGE_OFFSET_LIMIT SZ_128M
+#define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE
+#define MAX_FDT_OFFSET ZIMAGE_OFFSET_LIMIT
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 58cfe9f..5c17d2d 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -19,20 +19,47 @@ enum fixed_addresses {
FIX_TEXT_POKE0,
FIX_TEXT_POKE1,
- __end_of_fixed_addresses
+ __end_of_fixmap_region,
+
+ /*
+ * Share the kmap() region with early_ioremap(): this is guaranteed
+ * not to clash since early_ioremap() is only available before
+ * paging_init(), and kmap() only after.
+ */
+#define NR_FIX_BTMAPS 32
+#define FIX_BTMAPS_SLOTS 7
+#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+
+ FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+ FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
+ __end_of_early_ioremap_region
};
+static const enum fixed_addresses __end_of_fixed_addresses =
+ __end_of_fixmap_region > __end_of_early_ioremap_region ?
+ __end_of_fixmap_region : __end_of_early_ioremap_region;
+
#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY)
#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
+#define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY)
/* Used by set_fixmap_(io|nocache), both meant for mapping a device */
#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED)
#define FIXMAP_PAGE_NOCACHE FIXMAP_PAGE_IO
+#define __early_set_fixmap __set_fixmap
+
+#ifdef CONFIG_MMU
+
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
void __init early_fixmap_init(void);
#include <asm-generic/fixmap.h>
+#else
+
+static inline void early_fixmap_init(void) { }
+
+#endif
#endif
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index fe3ea77..3d7351c 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
#include <linux/threads.h>
#include <asm/irq.h>
-#define NR_IPI 8
+#define NR_IPI 7
typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm/include/asm/hardware/cache-uniphier.h b/arch/arm/include/asm/hardware/cache-uniphier.h
new file mode 100644
index 0000000..102e3fb
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-uniphier.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __CACHE_UNIPHIER_H
+#define __CACHE_UNIPHIER_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_CACHE_UNIPHIER
+int uniphier_cache_init(void);
+int uniphier_cache_l2_is_enabled(void);
+void uniphier_cache_l2_touch_range(unsigned long start, unsigned long end);
+void uniphier_cache_l2_set_locked_ways(u32 way_mask);
+#else
+static inline int uniphier_cache_init(void)
+{
+ return -ENODEV;
+}
+
+static inline int uniphier_cache_l2_is_enabled(void)
+{
+ return 0;
+}
+
+static inline void uniphier_cache_l2_touch_range(unsigned long start,
+ unsigned long end)
+{
+}
+
+static inline void uniphier_cache_l2_set_locked_ways(u32 way_mask)
+{
+}
+#endif
+
+#endif /* __CACHE_UNIPHIER_H */
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 5355795..0a0e2d1 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -68,7 +68,6 @@ 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/irq.h b/arch/arm/include/asm/irq.h
index be1d07d..1bd9510de 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -40,6 +40,11 @@ extern void arch_trigger_all_cpu_backtrace(bool);
#define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x)
#endif
+static inline int nr_legacy_irqs(void)
+{
+ return NR_IRQS_LEGACY;
+}
+
#endif
#endif
diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
index 4390814..e6b70d9 100644
--- a/arch/arm/include/asm/irqflags.h
+++ b/arch/arm/include/asm/irqflags.h
@@ -54,6 +54,14 @@ static inline void arch_local_irq_disable(void)
#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
+
+#ifndef CONFIG_CPU_V7M
+#define local_abt_enable() __asm__("cpsie a @ __sta" : : : "memory", "cc")
+#define local_abt_disable() __asm__("cpsid a @ __cla" : : : "memory", "cc")
+#else
+#define local_abt_enable() do { } while (0)
+#define local_abt_disable() do { } while (0)
+#endif
#else
/*
@@ -136,6 +144,8 @@ static inline void arch_local_irq_disable(void)
: "memory", "cc"); \
})
+#define local_abt_enable() do { } while (0)
+#define local_abt_disable() do { } while (0)
#endif
/*
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index d995821..e22089f 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -19,6 +19,7 @@
#ifndef __ARM_KVM_ARM_H__
#define __ARM_KVM_ARM_H__
+#include <linux/const.h>
#include <linux/types.h>
/* Hyp Configuration Register (HCR) bits */
@@ -132,10 +133,9 @@
* 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))
+#define KVM_PHYS_SIZE (_AC(1, ULL) << KVM_PHYS_SHIFT)
+#define KVM_PHYS_MASK (KVM_PHYS_SIZE - _AC(1, ULL))
+#define PTRS_PER_S2_PGD (_AC(1, ULL) << (KVM_PHYS_SHIFT - 30))
/* Virtualization Translation Control Register (VTCR) bits */
#define VTCR_SH0 (3 << 12)
@@ -162,17 +162,17 @@
#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)
+#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_VMID_SHIFT _AC(48, ULL)
+#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << 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_EC (_AC(0x3f, UL) << HSR_EC_SHIFT)
+#define HSR_IL (_AC(1, UL) << 25)
#define HSR_ISS (HSR_IL - 1)
#define HSR_ISV_SHIFT (24)
-#define HSR_ISV (1U << HSR_ISV_SHIFT)
+#define HSR_ISV (_AC(1, UL) << HSR_ISV_SHIFT)
#define HSR_SRT_SHIFT (16)
#define HSR_SRT_MASK (0xf << HSR_SRT_SHIFT)
#define HSR_FSC (0x3f)
@@ -180,9 +180,9 @@
#define HSR_SSE (1 << 21)
#define HSR_WNR (1 << 6)
#define HSR_CV_SHIFT (24)
-#define HSR_CV (1U << HSR_CV_SHIFT)
+#define HSR_CV (_AC(1, UL) << HSR_CV_SHIFT)
#define HSR_COND_SHIFT (20)
-#define HSR_COND (0xfU << HSR_COND_SHIFT)
+#define HSR_COND (_AC(0xf, UL) << HSR_COND_SHIFT)
#define FSC_FAULT (0x04)
#define FSC_ACCESS (0x08)
@@ -210,12 +210,32 @@
#define HSR_EC_DABT (0x24)
#define HSR_EC_DABT_HYP (0x25)
-#define HSR_WFI_IS_WFE (1U << 0)
+#define HSR_WFI_IS_WFE (_AC(1, UL) << 0)
-#define HSR_HVC_IMM_MASK ((1UL << 16) - 1)
+#define HSR_HVC_IMM_MASK ((_AC(1, UL) << 16) - 1)
+
+#define HSR_DABT_S1PTW (_AC(1, UL) << 7)
+#define HSR_DABT_CM (_AC(1, UL) << 8)
+#define HSR_DABT_EA (_AC(1, UL) << 9)
+
+#define kvm_arm_exception_type \
+ {0, "RESET" }, \
+ {1, "UNDEFINED" }, \
+ {2, "SOFTWARE" }, \
+ {3, "PREF_ABORT" }, \
+ {4, "DATA_ABORT" }, \
+ {5, "IRQ" }, \
+ {6, "FIQ" }, \
+ {7, "HVC" }
+
+#define HSRECN(x) { HSR_EC_##x, #x }
+
+#define kvm_arm_exception_class \
+ HSRECN(UNKNOWN), HSRECN(WFI), HSRECN(CP15_32), HSRECN(CP15_64), \
+ HSRECN(CP14_MR), HSRECN(CP14_LS), HSRECN(CP_0_13), HSRECN(CP10_ID), \
+ HSRECN(JAZELLE), HSRECN(BXJ), HSRECN(CP14_64), HSRECN(SVC_HYP), \
+ HSRECN(HVC), HSRECN(SMC), HSRECN(IABT), HSRECN(IABT_HYP), \
+ HSRECN(DABT), HSRECN(DABT_HYP)
-#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
index 194c91b..3d5a5cd 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -19,38 +19,7 @@
#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 /* Auxiliary 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) */
+#include <asm/virt.h>
#define ARM_EXCEPTION_RESET 0
#define ARM_EXCEPTION_UNDEFINED 1
@@ -79,6 +48,8 @@
#define rr_lo_hi(a1, a2) a1, a2
#endif
+#define kvm_ksym_ref(kva) (kva)
+
#ifndef __ASSEMBLY__
struct kvm;
struct kvm_vcpu;
@@ -86,19 +57,15 @@ 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);
+
+extern void __init_stage2_translation(void);
#endif
#endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index a9c80a2..ee5328f 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -28,6 +28,18 @@
unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
+static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
+ u8 reg_num)
+{
+ return *vcpu_reg(vcpu, reg_num);
+}
+
+static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
+ unsigned long val)
+{
+ *vcpu_reg(vcpu, reg_num) = val;
+}
+
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);
@@ -56,12 +68,12 @@ static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
{
- return &vcpu->arch.regs.usr_regs.ARM_pc;
+ return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_pc;
}
static inline unsigned long *vcpu_cpsr(struct kvm_vcpu *vcpu)
{
- return &vcpu->arch.regs.usr_regs.ARM_cpsr;
+ return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_cpsr;
}
static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
@@ -71,13 +83,13 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
static inline bool mode_has_spsr(struct kvm_vcpu *vcpu)
{
- unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
+ unsigned long cpsr_mode = vcpu->arch.ctxt.gp_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;
+ unsigned long cpsr_mode = vcpu->arch.ctxt.gp_regs.usr_regs.ARM_cpsr & MODE_MASK;
return cpsr_mode > USR_MODE;;
}
@@ -96,11 +108,6 @@ 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;
@@ -131,6 +138,11 @@ static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW;
}
+static inline bool kvm_vcpu_dabt_is_cm(struct kvm_vcpu *vcpu)
+{
+ return !!(kvm_vcpu_get_hsr(vcpu) & HSR_DABT_CM);
+}
+
/* Get Access Size from a data abort */
static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
{
@@ -180,7 +192,7 @@ static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.cp15[c0_MPIDR] & MPIDR_HWID_BITMASK;
+ return vcpu_cp15(vcpu, c0_MPIDR) & MPIDR_HWID_BITMASK;
}
static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c4072d9..3850701 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -85,20 +85,61 @@ 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;
+/*
+ * 0 is reserved as an invalid value.
+ * Order should be kept in sync with the save/restore code.
+ */
+enum vcpu_sysreg {
+ __INVALID_SYSREG__,
+ c0_MPIDR, /* MultiProcessor ID Register */
+ c0_CSSELR, /* Cache Size Selection Register */
+ c1_SCTLR, /* System Control Register */
+ c1_ACTLR, /* Auxiliary Control Register */
+ c1_CPACR, /* Coprocessor Access Control */
+ c2_TTBR0, /* Translation Table Base Register 0 */
+ c2_TTBR0_high, /* TTBR0 top 32 bits */
+ c2_TTBR1, /* Translation Table Base Register 1 */
+ c2_TTBR1_high, /* TTBR1 top 32 bits */
+ c2_TTBCR, /* Translation Table Base Control R. */
+ c3_DACR, /* Domain Access Control Register */
+ c5_DFSR, /* Data Fault Status Register */
+ c5_IFSR, /* Instruction Fault Status Register */
+ c5_ADFSR, /* Auxilary Data Fault Status R */
+ c5_AIFSR, /* Auxilary Instrunction Fault Status R */
+ c6_DFAR, /* Data Fault Address Register */
+ c6_IFAR, /* Instruction Fault Address Register */
+ c7_PAR, /* Physical Address Register */
+ c7_PAR_high, /* PAR top 32 bits */
+ c9_L2CTLR, /* Cortex A15/A7 L2 Control Register */
+ c10_PRRR, /* Primary Region Remap Register */
+ c10_NMRR, /* Normal Memory Remap Register */
+ c12_VBAR, /* Vector Base Address Register */
+ c13_CID, /* Context ID Register */
+ c13_TID_URW, /* Thread ID, User R/W */
+ c13_TID_URO, /* Thread ID, User R/O */
+ c13_TID_PRIV, /* Thread ID, Privileged */
+ c14_CNTKCTL, /* Timer Control Register (PL1) */
+ c10_AMAIR0, /* Auxilary Memory Attribute Indirection Reg0 */
+ c10_AMAIR1, /* Auxilary Memory Attribute Indirection Reg1 */
+ NR_CP15_REGS /* Number of regs (incl. invalid) */
+};
+
+struct kvm_cpu_context {
+ struct kvm_regs gp_regs;
+ struct vfp_hard_struct vfp;
+ u32 cp15[NR_CP15_REGS];
+};
+
+typedef struct kvm_cpu_context kvm_cpu_context_t;
struct kvm_vcpu_arch {
- struct kvm_regs regs;
+ struct kvm_cpu_context ctxt;
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;
@@ -111,9 +152,6 @@ struct kvm_vcpu_arch {
/* 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;
@@ -126,7 +164,10 @@ struct kvm_vcpu_arch {
* here.
*/
- /* Don't run the guest on this vcpu */
+ /* vcpu power-off state */
+ bool power_off;
+
+ /* Don't run the guest (internal implementation need) */
bool pause;
/* IO related fields */
@@ -147,14 +188,22 @@ struct kvm_vcpu_stat {
u32 halt_successful_poll;
u32 halt_attempted_poll;
u32 halt_wakeup;
+ u32 hvc_exit_stat;
+ u64 wfe_exit_stat;
+ u64 wfi_exit_stat;
+ u64 mmio_exit_user;
+ u64 mmio_exit_kernel;
+ u64 exits;
};
+#define vcpu_cp15(v,r) (v)->arch.ctxt.cp15[r]
+
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, ...);
+unsigned long kvm_call_hyp(void *hypfn, ...);
void force_vm_exit(const cpumask_t *mask);
#define KVM_ARCH_WANT_MMU_NOTIFIER
@@ -211,6 +260,11 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
}
+static inline void __cpu_init_stage2(void)
+{
+ kvm_call_hyp(__init_stage2_translation);
+}
+
static inline int kvm_arch_dev_ioctl_check_extension(long ext)
{
return 0;
@@ -233,5 +287,20 @@ static inline void kvm_arm_init_debug(void) {}
static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
+static inline int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ return -ENXIO;
+}
+static inline int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ return -ENXIO;
+}
+static inline int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ return -ENXIO;
+}
#endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
new file mode 100644
index 0000000..f0e8607
--- /dev/null
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 - 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_HYP_H__
+#define __ARM_KVM_HYP_H__
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
+#include <asm/vfp.h>
+
+#define __hyp_text __section(.hyp.text) notrace
+
+#define kern_hyp_va(v) (v)
+#define hyp_kern_va(v) (v)
+
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
+ "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
+#define __ACCESS_CP15_64(Op1, CRm) \
+ "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
+#define __ACCESS_VFP(CRn) \
+ "mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
+
+#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
+#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
+
+#define __read_sysreg(r, w, c, t) ({ \
+ t __val; \
+ asm volatile(r " " c : "=r" (__val)); \
+ __val; \
+})
+#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
+
+#define write_special(v, r) \
+ asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
+#define read_special(r) ({ \
+ u32 __val; \
+ asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
+ __val; \
+})
+
+#define TTBR0 __ACCESS_CP15_64(0, c2)
+#define TTBR1 __ACCESS_CP15_64(1, c2)
+#define VTTBR __ACCESS_CP15_64(6, c2)
+#define PAR __ACCESS_CP15_64(0, c7)
+#define CNTV_CVAL __ACCESS_CP15_64(3, c14)
+#define CNTVOFF __ACCESS_CP15_64(4, c14)
+
+#define MIDR __ACCESS_CP15(c0, 0, c0, 0)
+#define CSSELR __ACCESS_CP15(c0, 2, c0, 0)
+#define VPIDR __ACCESS_CP15(c0, 4, c0, 0)
+#define VMPIDR __ACCESS_CP15(c0, 4, c0, 5)
+#define SCTLR __ACCESS_CP15(c1, 0, c0, 0)
+#define CPACR __ACCESS_CP15(c1, 0, c0, 2)
+#define HCR __ACCESS_CP15(c1, 4, c1, 0)
+#define HDCR __ACCESS_CP15(c1, 4, c1, 1)
+#define HCPTR __ACCESS_CP15(c1, 4, c1, 2)
+#define HSTR __ACCESS_CP15(c1, 4, c1, 3)
+#define TTBCR __ACCESS_CP15(c2, 0, c0, 2)
+#define HTCR __ACCESS_CP15(c2, 4, c0, 2)
+#define VTCR __ACCESS_CP15(c2, 4, c1, 2)
+#define DACR __ACCESS_CP15(c3, 0, c0, 0)
+#define DFSR __ACCESS_CP15(c5, 0, c0, 0)
+#define IFSR __ACCESS_CP15(c5, 0, c0, 1)
+#define ADFSR __ACCESS_CP15(c5, 0, c1, 0)
+#define AIFSR __ACCESS_CP15(c5, 0, c1, 1)
+#define HSR __ACCESS_CP15(c5, 4, c2, 0)
+#define DFAR __ACCESS_CP15(c6, 0, c0, 0)
+#define IFAR __ACCESS_CP15(c6, 0, c0, 2)
+#define HDFAR __ACCESS_CP15(c6, 4, c0, 0)
+#define HIFAR __ACCESS_CP15(c6, 4, c0, 2)
+#define HPFAR __ACCESS_CP15(c6, 4, c0, 4)
+#define ICIALLUIS __ACCESS_CP15(c7, 0, c1, 0)
+#define ATS1CPR __ACCESS_CP15(c7, 0, c8, 0)
+#define TLBIALLIS __ACCESS_CP15(c8, 0, c3, 0)
+#define TLBIALLNSNHIS __ACCESS_CP15(c8, 4, c3, 4)
+#define PRRR __ACCESS_CP15(c10, 0, c2, 0)
+#define NMRR __ACCESS_CP15(c10, 0, c2, 1)
+#define AMAIR0 __ACCESS_CP15(c10, 0, c3, 0)
+#define AMAIR1 __ACCESS_CP15(c10, 0, c3, 1)
+#define VBAR __ACCESS_CP15(c12, 0, c0, 0)
+#define CID __ACCESS_CP15(c13, 0, c0, 1)
+#define TID_URW __ACCESS_CP15(c13, 0, c0, 2)
+#define TID_URO __ACCESS_CP15(c13, 0, c0, 3)
+#define TID_PRIV __ACCESS_CP15(c13, 0, c0, 4)
+#define HTPIDR __ACCESS_CP15(c13, 4, c0, 2)
+#define CNTKCTL __ACCESS_CP15(c14, 0, c1, 0)
+#define CNTV_CTL __ACCESS_CP15(c14, 0, c3, 1)
+#define CNTHCTL __ACCESS_CP15(c14, 4, c1, 0)
+
+#define VFP_FPEXC __ACCESS_VFP(FPEXC)
+
+/* AArch64 compatibility macros, only for the timer so far */
+#define read_sysreg_el0(r) read_sysreg(r##_el0)
+#define write_sysreg_el0(v, r) write_sysreg(v, r##_el0)
+
+#define cntv_ctl_el0 CNTV_CTL
+#define cntv_cval_el0 CNTV_CVAL
+#define cntvoff_el2 CNTVOFF
+#define cnthctl_el2 CNTHCTL
+
+void __timer_save_state(struct kvm_vcpu *vcpu);
+void __timer_restore_state(struct kvm_vcpu *vcpu);
+
+void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
+
+void __sysreg_save_state(struct kvm_cpu_context *ctxt);
+void __sysreg_restore_state(struct kvm_cpu_context *ctxt);
+
+void asmlinkage __vfp_save_state(struct vfp_hard_struct *vfp);
+void asmlinkage __vfp_restore_state(struct vfp_hard_struct *vfp);
+static inline bool __vfp_enabled(void)
+{
+ return !(read_sysreg(HCPTR) & (HCPTR_TCP(11) | HCPTR_TCP(10)));
+}
+
+void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt);
+void __hyp_text __banked_restore_state(struct kvm_cpu_context *ctxt);
+
+int asmlinkage __guest_enter(struct kvm_vcpu *vcpu,
+ struct kvm_cpu_context *host);
+int asmlinkage __hyp_do_panic(const char *, int, u32);
+
+#endif /* __ARM_KVM_HYP_H__ */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 405aa18..da44be9 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -179,10 +179,11 @@ struct kvm;
static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
{
- return (vcpu->arch.cp15[c1_SCTLR] & 0b101) == 0b101;
+ return (vcpu_cp15(vcpu, c1_SCTLR) & 0b101) == 0b101;
}
-static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
+ kvm_pfn_t pfn,
unsigned long size,
bool ipa_uncached)
{
@@ -246,7 +247,7 @@ static inline void __kvm_flush_dcache_pte(pte_t pte)
static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
{
unsigned long size = PMD_SIZE;
- pfn_t pfn = pmd_pfn(pmd);
+ kvm_pfn_t pfn = pmd_pfn(pmd);
while (size) {
void *va = kmap_atomic_pfn(pfn);
@@ -279,6 +280,11 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
pgd_t *merged_hyp_pgd,
unsigned long hyp_idmap_start) { }
+static inline unsigned int kvm_get_vmid_bits(void)
+{
+ return 8;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* __ARM_KVM_MMU_H__ */
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index cb3a407..5c1ad11 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -47,7 +47,7 @@ struct machine_desc {
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 */
+ const struct smp_operations *smp; /* SMP operations */
bool (*smp_init)(void);
void (*fixup)(struct tag *, char **);
void (*dt_fixup)(void);
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index f98c7f3..9b7c328 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -42,6 +42,8 @@ enum {
extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller);
+extern void create_mapping_late(struct mm_struct *mm, struct map_desc *md,
+ bool ng);
#ifdef CONFIG_DEBUG_LL
extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 8857d28..0070e85 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -52,12 +52,6 @@ struct pci_sys_data {
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 */
};
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 98d58bb..9427fd6 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -76,10 +76,12 @@
*/
#define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff))
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
/*
* Allow 16MB-aligned ioremap pages
*/
#define IOREMAP_MAX_ORDER 24
+#endif
#else /* CONFIG_MMU */
@@ -132,6 +134,21 @@
*/
#define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
+#ifdef CONFIG_XIP_KERNEL
+/*
+ * When referencing data in RAM from the XIP region in a relative manner
+ * with the MMU off, we need the relative offset between the two physical
+ * addresses. The macro below achieves this, which is:
+ * __pa(v_data) - __xip_pa(v_text)
+ */
+#define PHYS_RELATIVE(v_data, v_text) \
+ (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \
+ ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \
+ CONFIG_XIP_PHYS_ADDR))
+#else
+#define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text))
+#endif
+
#ifndef __ASSEMBLY__
/*
@@ -271,14 +288,14 @@ static inline void *phys_to_virt(phys_addr_t x)
#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
#define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT)
-extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x);
+extern unsigned long (*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.
+ * untouched. Note: this can only return addresses less than 4GiB.
*/
-static inline phys_addr_t __virt_to_idmap(unsigned long x)
+static inline unsigned long __virt_to_idmap(unsigned long x)
{
if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap)
return arch_virt_to_idmap(x);
@@ -301,20 +318,6 @@ static inline phys_addr_t __virt_to_idmap(unsigned long 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.
*
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 9b32f76..fa5b42d 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -26,7 +26,12 @@ 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; })
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ atomic64_set(&mm->context.id, 0);
+ return 0;
+}
#ifdef CONFIG_ARM_ERRATA_798181
void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
@@ -85,7 +90,12 @@ static inline void finish_arch_post_lock_switch(void)
#endif /* CONFIG_MMU */
-#define init_new_context(tsk,mm) 0
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
#endif /* CONFIG_CPU_HAS_ASID */
diff --git a/arch/arm/include/asm/paravirt.h b/arch/arm/include/asm/paravirt.h
new file mode 100644
index 0000000..8435ff5
--- /dev/null
+++ b/arch/arm/include/asm/paravirt.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_ARM_PARAVIRT_H
+#define _ASM_ARM_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT
+struct static_key;
+extern struct static_key paravirt_steal_enabled;
+extern struct static_key paravirt_steal_rq_enabled;
+
+struct pv_time_ops {
+ unsigned long long (*steal_clock)(int cpu);
+};
+extern struct pv_time_ops pv_time_ops;
+
+static inline u64 paravirt_steal_clock(int cpu)
+{
+ return pv_time_ops.steal_clock(cpu);
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index a563544..057d381 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -2,9 +2,6 @@
#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;
@@ -41,5 +38,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
}
#endif /* __KERNEL__ */
-
#endif
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index a745a2a..dc46398 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -88,7 +88,6 @@
#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)
@@ -232,13 +231,6 @@ static inline pte_t pte_mkspecial(pte_t pte)
#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) \
@@ -246,9 +238,9 @@ 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(mkclean, &= ~L_PMD_SECT_DIRTY);
PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index f403541..348caab 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -43,7 +43,7 @@
*/
#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-#define VMALLOC_END 0xff000000UL
+#define VMALLOC_END 0xff800000UL
#define LIBRARY_TEXT_START 0x0c000000
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index 68ee3ce..e1b825d 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -14,9 +14,9 @@
#ifndef __ASM_ARM_PSCI_H
#define __ASM_ARM_PSCI_H
-extern struct smp_operations psci_smp_ops;
+extern const struct smp_operations psci_smp_ops;
-#ifdef CONFIG_ARM_PSCI
+#if defined(CONFIG_SMP) && defined(CONFIG_ARM_PSCI)
bool psci_smp_available(void);
#else
static inline bool psci_smp_available(void) { return false; }
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
new file mode 100644
index 0000000..803bbf2
--- /dev/null
+++ b/arch/arm/include/asm/sections.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_ARM_SECTIONS_H
+#define _ASM_ARM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _exiprom[];
+
+#endif /* _ASM_ARM_SECTIONS_H */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index e0adb9f..3613d7e 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -25,4 +25,10 @@ extern int arm_add_memory(u64 start, u64 size);
extern void early_print(const char *str, ...);
extern void dump_machine_table(void);
+#ifdef CONFIG_ATAGS_PROC
+extern void save_atags(const struct tag *tags);
+#else
+static inline void save_atags(const struct tag *tags) { }
+#endif
+
#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index ef35665..3d6dc8b 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -112,7 +112,7 @@ struct smp_operations {
struct of_cpu_method {
const char *method;
- struct smp_operations *ops;
+ const struct smp_operations *ops;
};
#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
@@ -122,6 +122,6 @@ struct of_cpu_method {
/*
* set platform specific SMP operations
*/
-extern void smp_set_ops(struct smp_operations *);
+extern void smp_set_ops(const struct smp_operations *);
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h
index 0009861..73e5e85 100644
--- a/arch/arm/include/asm/sparsemem.h
+++ b/arch/arm/include/asm/sparsemem.h
@@ -15,10 +15,11 @@
* 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.
+ * These can be overridden in your mach/memory.h.
*/
-#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS)
-#error Sparsemem is not supported on this platform
+#if !defined(MAX_PHYSMEM_BITS) || !defined(SECTION_SIZE_BITS)
+#define MAX_PHYSMEM_BITS 36
+#define SECTION_SIZE_BITS 28
#endif
#endif
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 8cc85a4..35c9db8 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -510,10 +510,14 @@ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
static inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
+#ifndef CONFIG_UACCESS_WITH_MEMCPY
unsigned int __ua_flags = uaccess_save_and_enable();
n = arm_copy_to_user(to, from, n);
uaccess_restore(__ua_flags);
return n;
+#else
+ return arm_copy_to_user(to, from, n);
+#endif
}
extern unsigned long __must_check
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 7cba573..7b84657 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -21,13 +21,6 @@
*/
#define __NR_syscalls (392)
-/*
- * *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
diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 4371f45..d4ceaf5 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -74,6 +74,15 @@ static inline bool is_hyp_mode_mismatched(void)
{
return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
}
+
+static inline bool is_kernel_in_hyp_mode(void)
+{
+ return false;
+}
+
+/* The section containing the hypervisor text */
+extern char __hyp_text_start[];
+extern char __hyp_text_end[];
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
index 712b50e..d769972 100644
--- a/arch/arm/include/asm/xen/hypercall.h
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -35,6 +35,7 @@
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
+#include <xen/interface/platform.h>
long privcmd_call(unsigned call, unsigned long a1,
unsigned long a2, unsigned long a3,
@@ -49,6 +50,12 @@ 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_platform_op_raw(void *arg);
+static inline int HYPERVISOR_platform_op(struct xen_platform_op *op)
+{
+ op->interface_version = XENPF_INTERFACE_VERSION;
+ return HYPERVISOR_platform_op_raw(op);
+}
int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);
static inline int
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
index 04ff8e7..9525151 100644
--- a/arch/arm/include/asm/xen/hypervisor.h
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -26,4 +26,14 @@ void __init xen_early_init(void);
static inline void xen_early_init(void) { return; }
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+static inline void xen_arch_register_cpu(int num)
+{
+}
+
+static inline void xen_arch_unregister_cpu(int num)
+{
+}
+#endif
+
#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
index 5006600..75d5968 100644
--- a/arch/arm/include/asm/xen/interface.h
+++ b/arch/arm/include/asm/xen/interface.h
@@ -27,6 +27,8 @@
(hnd).p = val; \
} while (0)
+#define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op
+
#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.
@@ -76,6 +78,7 @@ struct pvclock_wall_clock {
u32 version;
u32 sec;
u32 nsec;
+ u32 sec_hi;
} __attribute__((__packed__));
#endif
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index efd5624..9408a99 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -35,11 +35,22 @@ 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. */
+ unsigned long page_pfn = page_to_xen_pfn(page);
+ unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
+ unsigned long compound_pages =
+ (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
+ bool local = (page_pfn <= dev_pfn) &&
+ (dev_pfn - page_pfn < compound_pages);
+
+ /*
+ * Dom0 is mapped 1:1, while the Linux page can span across
+ * multiple Xen pages, it's not possible for it to contain a
+ * mix of local and foreign Xen pages. So if the first xen_pfn
+ * == mfn the page is local otherwise it's 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
@@ -51,10 +62,14 @@ static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
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. */
+ /*
+ * Dom0 is mapped 1:1, while the Linux page can be spanned accross
+ * multiple Xen page, it's not possible to have a mix of local and
+ * foreign Xen page. 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);
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1279563..415dbc6 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -13,9 +13,6 @@
#define phys_to_machine_mapping_valid(pfn) (1)
-#define pte_mfn pte_pfn
-#define mfn_pte pfn_pte
-
/* Xen machine address */
typedef struct xmaddr {
phys_addr_t maddr;
@@ -31,6 +28,17 @@ typedef struct xpaddr {
#define INVALID_P2M_ENTRY (~0UL)
+/*
+ * The pseudo-physical frame (pfn) used in all the helpers is always based
+ * on Xen page granularity (i.e 4KB).
+ *
+ * A Linux page may be split across multiple non-contiguous Xen page so we
+ * have to keep track with frame based on 4KB page granularity.
+ *
+ * PV drivers should never make a direct usage of those helpers (particularly
+ * pfn_to_gfn and gfn_to_pfn).
+ */
+
unsigned long __pfn_to_mfn(unsigned long pfn);
extern struct rb_root phys_to_mach;
@@ -67,8 +75,8 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
#define bfn_to_local_pfn(bfn) bfn_to_pfn(bfn)
/* VIRT <-> GUEST conversion */
-#define virt_to_gfn(v) (pfn_to_gfn(virt_to_pfn(v)))
-#define gfn_to_virt(m) (__va(gfn_to_pfn(m) << PAGE_SHIFT))
+#define virt_to_gfn(v) (pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT))
+#define gfn_to_virt(m) (__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
/* Only used in PV code. But ARM guests are always HVM. */
static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
@@ -107,8 +115,8 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
#define xen_unmap(cookie) iounmap((cookie))
bool xen_arch_need_swiotlb(struct device *dev,
- unsigned long pfn,
- unsigned long bfn);
+ phys_addr_t phys,
+ dma_addr_t dev_addr);
unsigned long xen_get_swiotlb_free_pages(unsigned int order);
#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S
index 2556a88..43243be 100644
--- a/arch/arm/include/debug/at91.S
+++ b/arch/arm/include/debug/at91.S
@@ -9,32 +9,22 @@
*
*/
-#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 */
-#elif defined(CONFIG_AT91_DEBUG_LL_DBGU2)
-/* On sama5d4, use USART3 as low level serial console */
-#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
-#else
-/* On sama5d2, use UART1 as low level serial console */
-#define AT91_DBGU 0xf8020000
-#endif
-
#ifdef CONFIG_MMU
#define AT91_IO_P2V(x) ((x) - 0x01000000)
#else
#define AT91_IO_P2V(x) (x)
#endif
+#define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS)
+
#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)
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS @ System peripherals (phys address)
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT @ System peripherals (virt address)
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/include/debug/dc21285.S
index 02247f3..02247f3 100644
--- a/arch/arm/mach-footbridge/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/dc21285.S
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index 7a2a32a1..5dd2528 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -416,6 +416,8 @@
#define __NR_execveat (__NR_SYSCALL_BASE+387)
#define __NR_userfaultfd (__NR_SYSCALL_BASE+388)
#define __NR_membarrier (__NR_SYSCALL_BASE+389)
+#define __NR_mlock2 (__NR_SYSCALL_BASE+390)
+#define __NR_copy_file_range (__NR_SYSCALL_BASE+391)
/*
* The following SWIs are ARM private.
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index af9e59b..ad325a8 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -73,23 +73,26 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
perf_event_v7.o
-CFLAGS_pj4-cp0.o := -marm
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_VDSO) += vdso.o
+obj-$(CONFIG_EFI) += efi.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
endif
+obj-$(CONFIG_PARAVIRT) += paravirt.o
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
+AFLAGS_hyp-stub.o :=-Wa,-march=armv7-a
ifeq ($(CONFIG_ARM_PSCI),y)
-obj-y += psci-call.o
obj-$(CONFIG_SMP) += psci_smp.o
endif
+obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
+
extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index f89811f..7e45f69 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -16,6 +16,7 @@
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/arm-smccc.h>
#include <asm/checksum.h>
#include <asm/ftrace.h>
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
EXPORT_SYMBOL(__pv_phys_pfn_offset);
EXPORT_SYMBOL(__pv_offset);
#endif
+
+#ifdef CONFIG_HAVE_ARM_SMCCC
+EXPORT_SYMBOL(arm_smccc_smc);
+EXPORT_SYMBOL(arm_smccc_hvc);
+#endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 871b826..27d0581 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -170,41 +170,11 @@ int main(void)
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));
+ DEFINE(VCPU_GUEST_CTXT, offsetof(struct kvm_vcpu, arch.ctxt));
+ DEFINE(VCPU_HOST_CTXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
+ DEFINE(CPU_CTXT_VFP, offsetof(struct kvm_cpu_context, vfp));
+ DEFINE(CPU_CTXT_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
+ DEFINE(GP_REGS_USR, offsetof(struct kvm_regs, usr_regs));
#endif
BLANK();
#ifdef CONFIG_VDSO
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
index ec4164d..edfa226 100644
--- a/arch/arm/kernel/atags.h
+++ b/arch/arm/kernel/atags.h
@@ -1,9 +1,3 @@
-#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
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 874e182..066f7f9 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -456,7 +456,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
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)
@@ -465,6 +464,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
ret = hw->setup(nr, sys);
if (ret > 0) {
+ struct pci_host_bridge *host_bridge;
+
ret = pcibios_init_resources(nr, sys);
if (ret) {
kfree(sys);
@@ -486,6 +487,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
busnr = sys->bus->busn_res.end + 1;
list_add(&sys->node, head);
+
+ host_bridge = pci_find_host_bridge(sys->bus);
+ host_bridge->align_resource = hw->align_resource;
} else {
kfree(sys);
if (ret < 0)
@@ -572,16 +576,19 @@ 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;
+ struct pci_host_bridge *host_bridge;
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);
+ host_bridge = pci_find_host_bridge(dev->bus);
+
+ if (host_bridge->align_resource)
+ return host_bridge->align_resource(dev, res,
+ start, size, align);
return start;
}
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index fde6c88..dfc7cd6 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -399,6 +399,8 @@
CALL(sys_execveat)
CALL(sys_userfaultfd)
CALL(sys_membarrier)
+ CALL(sys_mlock2)
+ CALL(sys_copy_file_range)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
index 318da33..703926e 100644
--- a/arch/arm/kernel/cpuidle.c
+++ b/arch/arm/kernel/cpuidle.c
@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
int cpu = smp_processor_id();
if (cpuidle_ops[cpu].suspend)
- ret = cpuidle_ops[cpu].suspend(cpu, index);
+ ret = cpuidle_ops[cpu].suspend(index);
return ret;
}
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 11c54de..2e26016 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -101,6 +101,7 @@ void __init arm_dt_init_cpu_maps(void)
if (of_property_read_u32(cpu, "reg", &hwid)) {
pr_debug(" * %s missing reg property\n",
cpu->full_name);
+ of_node_put(cpu);
return;
}
@@ -108,8 +109,10 @@ void __init arm_dt_init_cpu_maps(void)
* 8 MSBs must be set to 0 in the DT since the reg property
* defines the MPIDR[23:0].
*/
- if (hwid & ~MPIDR_HWID_BITMASK)
+ if (hwid & ~MPIDR_HWID_BITMASK) {
+ of_node_put(cpu);
return;
+ }
/*
* Duplicate MPIDRs are a recipe for disaster.
@@ -119,9 +122,11 @@ void __init arm_dt_init_cpu_maps(void)
* 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"))
+ if (WARN(tmp_map[j] == hwid,
+ "Duplicate /cpu reg properties in the DT\n")) {
+ of_node_put(cpu);
return;
+ }
/*
* Build a stashed array of MPIDR values. Numbering scheme
@@ -143,6 +148,7 @@ void __init arm_dt_init_cpu_maps(void)
"max cores %u, capping them\n",
cpuidx, nr_cpu_ids)) {
cpuidx = nr_cpu_ids;
+ of_node_put(cpu);
break;
}
@@ -205,7 +211,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
{
const struct machine_desc *mdesc, *mdesc_best = NULL;
-#ifdef CONFIG_ARCH_MULTIPLATFORM
+#if defined(CONFIG_ARCH_MULTIPLATFORM) || defined(CONFIG_ARM_SINGLE_ARMV7M)
DT_MACHINE_START(GENERIC_DT, "Generic DT based system")
MACHINE_END
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
new file mode 100644
index 0000000..ff8a9d8
--- /dev/null
+++ b/arch/arm/kernel/efi.c
@@ -0,0 +1,38 @@
+/*
+ * 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/efi.h>
+#include <asm/efi.h>
+#include <asm/mach/map.h>
+#include <asm/mmu_context.h>
+
+int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
+{
+ struct map_desc desc = {
+ .virtual = md->virt_addr,
+ .pfn = __phys_to_pfn(md->phys_addr),
+ .length = md->num_pages * EFI_PAGE_SIZE,
+ };
+
+ /*
+ * Order is important here: memory regions may have all of the
+ * bits below set (and usually do), so we check them in order of
+ * preference.
+ */
+ if (md->attribute & EFI_MEMORY_WB)
+ desc.type = MT_MEMORY_RWX;
+ else if (md->attribute & EFI_MEMORY_WT)
+ desc.type = MT_MEMORY_RWX_NONCACHED;
+ else if (md->attribute & EFI_MEMORY_WC)
+ desc.type = MT_DEVICE_WC;
+ else
+ desc.type = MT_DEVICE;
+
+ create_mapping_late(mm, &desc, true);
+ return 0;
+}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 3e1c26e..e255050 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -427,8 +427,7 @@ ENDPROC(__fiq_abt)
.endm
.macro kuser_cmpxchg_check
-#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
- !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS)
#ifndef CONFIG_MMU
#warning "NPTL on non MMU needs fixing"
#else
@@ -859,20 +858,7 @@ __kuser_helper_start:
__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)
+#if defined(CONFIG_CPU_32v6K)
stmfd sp!, {r4, r5, r6, r7}
ldrd r4, r5, [r0] @ load old val
@@ -948,20 +934,7 @@ __kuser_memory_barrier: @ 0xffff0fa0
__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
+#if __LINUX_ARM_ARCH__ < 6
#ifdef CONFIG_MMU
@@ -1091,7 +1064,6 @@ ENDPROC(vector_\name)
.endm
.section .stubs, "ax", %progbits
-__stubs_start:
@ This must be the first word
.word vector_swi
@@ -1229,14 +1201,13 @@ vector_addrexcptn:
.long __fiq_svc @ e
.long __fiq_svc @ f
- .globl vector_fiq_offset
- .equ vector_fiq_offset, vector_fiq
+ .globl vector_fiq
.section .vectors, "ax", %progbits
-__vectors_start:
+.L__vectors_start:
W(b) vector_rst
W(b) vector_und
- W(ldr) pc, __vectors_start + 0x1000
+ W(ldr) pc, .L__vectors_start + 0x1000
W(b) vector_pabt
W(b) vector_dabt
W(b) vector_addrexcptn
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index b6c8bb9..907534f 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -88,7 +88,7 @@ __pendsv_entry:
@ execute the pending work, including reschedule
get_thread_info tsk
mov why, #0
- b ret_to_user
+ b ret_to_user_from_irq
ENDPROC(__pendsv_entry)
/*
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
index a71501f..b09561a 100644
--- a/arch/arm/kernel/hibernate.c
+++ b/arch/arm/kernel/hibernate.c
@@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused)
ret = swsusp_save();
if (ret == 0)
- _soft_restart(virt_to_phys(cpu_resume), false);
+ _soft_restart(virt_to_idmap(cpu_resume), false);
return ret;
}
@@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused)
for (pbe = restore_pblist; pbe; pbe = pbe->next)
copy_page(pbe->orig_address, pbe->address);
- _soft_restart(virt_to_phys(cpu_resume), false);
+ _soft_restart(virt_to_idmap(cpu_resume), false);
}
static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata;
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index dc7d0a9..6284779 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -35,7 +35,6 @@
#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. */
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 2a55373..0b1e4a9 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -17,6 +17,7 @@
*/
#include <linux/init.h>
+#include <linux/irqchip/arm-gic-v3.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/virt.h>
@@ -161,6 +162,29 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE
1:
#endif
+#ifdef CONFIG_ARM_GIC_V3
+ @ Check whether GICv3 system registers are available
+ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1
+ ubfx r7, r7, #28, #4
+ cmp r7, #1
+ bne 2f
+
+ @ Enable system register accesses
+ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE
+ orr r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE)
+ mcr p15, 4, r7, c12, c9, 5 @ ICC_HSRE
+ isb
+
+ @ SRE bit could be forced to 0 by firmware.
+ @ Check whether it sticks before accessing any other sysreg
+ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE
+ tst r7, #ICC_SRE_EL2_SRE
+ beq 2f
+ mov r7, #0
+ mcr p15, 4, r7, c12, c11, 0 @ ICH_HCR
+2:
+#endif
+
bx lr @ The boot CPU mode is left in r4.
ENDPROC(__hyp_stub_install_secondary)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 2766183..ece04a4 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -39,6 +39,7 @@
#include <linux/export.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/cache-uniphier.h>
#include <asm/outercache.h>
#include <asm/exception.h>
#include <asm/mach/arch.h>
@@ -94,9 +95,11 @@ void __init init_IRQ(void)
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)
+ if (ret && ret != -ENODEV)
pr_err("L2C: failed to init: %d\n", ret);
}
+
+ uniphier_cache_init();
}
#ifdef CONFIG_MULTI_IRQ_HANDLER
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index fd9eefc..9232cae 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -74,7 +74,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
void
sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
{
- struct pt_regs *thread_regs;
+ struct thread_info *ti;
int regno;
/* Just making sure... */
@@ -86,24 +86,17 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
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;
+ ti = task_thread_info(task);
+ gdb_regs[_R4] = ti->cpu_context.r4;
+ gdb_regs[_R5] = ti->cpu_context.r5;
+ gdb_regs[_R6] = ti->cpu_context.r6;
+ gdb_regs[_R7] = ti->cpu_context.r7;
+ gdb_regs[_R8] = ti->cpu_context.r8;
+ gdb_regs[_R9] = ti->cpu_context.r9;
+ gdb_regs[_R10] = ti->cpu_context.sl;
+ gdb_regs[_FP] = ti->cpu_context.fp;
+ gdb_regs[_SPT] = ti->cpu_context.sp;
+ gdb_regs[_PC] = ti->cpu_context.pc;
}
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8bf3b7c..59fd0e2 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -143,10 +143,8 @@ 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;
+ unsigned long page_list, reboot_entry_phys;
+ void (*reboot_entry)(void);
void *reboot_code_buffer;
/*
@@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image)
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*/
@@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image)
/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
- reboot_entry,
+ &relocate_new_kernel,
relocate_new_kernel_size);
- reboot_entry_phys = (unsigned long)reboot_entry +
- (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
+
+ /* get the identity mapping physical address for the reboot code */
+ reboot_entry_phys = virt_to_idmap(reboot_entry);
pr_info("Bye!\n");
diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
index 097e2e2..0c7efc3 100644
--- a/arch/arm/kernel/module-plts.c
+++ b/arch/arm/kernel/module-plts.c
@@ -32,7 +32,7 @@ struct plt_entries {
static bool in_init(const struct module *mod, u32 addr)
{
- return addr - (u32)mod->module_init < mod->init_size;
+ return addr - (u32)mod->init_layout.base < mod->init_layout.size;
}
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index efdddcb..4f14b5c 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -34,7 +34,7 @@
* 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)
+#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
#endif
#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/paravirt.c b/arch/arm/kernel/paravirt.c
new file mode 100644
index 0000000..53f371e
--- /dev/null
+++ b/arch/arm/kernel/paravirt.c
@@ -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) 2013 Citrix Systems
+ *
+ * Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+ */
+
+#include <linux/export.h>
+#include <linux/jump_label.h>
+#include <linux/types.h>
+#include <asm/paravirt.h>
+
+struct static_key paravirt_steal_enabled;
+struct static_key paravirt_steal_rq_enabled;
+
+struct pv_time_ops pv_time_ops;
+EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 126dc67..4152158 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -35,133 +35,117 @@
* 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,
+#define ARMV7_PERFCTR_PMNC_SW_INCR 0x00
+#define ARMV7_PERFCTR_L1_ICACHE_REFILL 0x01
+#define ARMV7_PERFCTR_ITLB_REFILL 0x02
+#define ARMV7_PERFCTR_L1_DCACHE_REFILL 0x03
+#define ARMV7_PERFCTR_L1_DCACHE_ACCESS 0x04
+#define ARMV7_PERFCTR_DTLB_REFILL 0x05
+#define ARMV7_PERFCTR_MEM_READ 0x06
+#define ARMV7_PERFCTR_MEM_WRITE 0x07
+#define ARMV7_PERFCTR_INSTR_EXECUTED 0x08
+#define ARMV7_PERFCTR_EXC_TAKEN 0x09
+#define ARMV7_PERFCTR_EXC_EXECUTED 0x0A
+#define 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_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+ * It counts:
+ * - all (taken) branch instructions,
+ * - instructions that explicitly write the PC,
+ * - exception generating instructions.
+ */
+#define ARMV7_PERFCTR_PC_WRITE 0x0C
+#define ARMV7_PERFCTR_PC_IMM_BRANCH 0x0D
+#define ARMV7_PERFCTR_PC_PROC_RETURN 0x0E
+#define ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS 0x0F
+#define ARMV7_PERFCTR_PC_BRANCH_MIS_PRED 0x10
+#define ARMV7_PERFCTR_CLOCK_CYCLES 0x11
+#define ARMV7_PERFCTR_PC_BRANCH_PRED 0x12
+
+/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
+#define ARMV7_PERFCTR_MEM_ACCESS 0x13
+#define ARMV7_PERFCTR_L1_ICACHE_ACCESS 0x14
+#define ARMV7_PERFCTR_L1_DCACHE_WB 0x15
+#define ARMV7_PERFCTR_L2_CACHE_ACCESS 0x16
+#define ARMV7_PERFCTR_L2_CACHE_REFILL 0x17
+#define ARMV7_PERFCTR_L2_CACHE_WB 0x18
+#define ARMV7_PERFCTR_BUS_ACCESS 0x19
+#define ARMV7_PERFCTR_MEM_ERROR 0x1A
+#define ARMV7_PERFCTR_INSTR_SPEC 0x1B
+#define ARMV7_PERFCTR_TTBR_WRITE 0x1C
+#define ARMV7_PERFCTR_BUS_CYCLES 0x1D
+
+#define 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,
-};
+#define ARMV7_A8_PERFCTR_L2_CACHE_ACCESS 0x43
+#define ARMV7_A8_PERFCTR_L2_CACHE_REFILL 0x44
+#define ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS 0x50
+#define 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,
-};
+#define ARMV7_A9_PERFCTR_INSTR_CORE_RENAME 0x68
+#define ARMV7_A9_PERFCTR_STALL_ICACHE 0x60
+#define 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,
-};
+#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL 0xc2
+#define 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,
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ 0x40
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE 0x41
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ 0x42
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE 0x43
- ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
- ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
+#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ 0x4C
+#define 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,
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ 0x50
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE 0x51
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ 0x52
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE 0x53
- ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
-};
+#define 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,
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ 0x40
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE 0x41
- ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
- ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ 0x50
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE 0x51
- ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
+#define ARMV7_A12_PERFCTR_PC_WRITE_SPEC 0x76
- ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
-};
+#define 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,
+#define KRAIT_PMRESR0_GROUP0 0xcc
+#define KRAIT_PMRESR1_GROUP0 0xd0
+#define KRAIT_PMRESR2_GROUP0 0xd4
+#define KRAIT_VPMRESR0_GROUP0 0xd8
- KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
- KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
+#define KRAIT_PERFCTR_L1_ICACHE_ACCESS 0x10011
+#define KRAIT_PERFCTR_L1_ICACHE_MISS 0x10010
- KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
- KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
-};
+#define KRAIT_PERFCTR_L1_ITLB_ACCESS 0x12222
+#define 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,
+#define SCORPION_LPM0_GROUP0 0x4c
+#define SCORPION_LPM1_GROUP0 0x50
+#define SCORPION_LPM2_GROUP0 0x54
+#define SCORPION_L2LPM_GROUP0 0x58
+#define SCORPION_VLPM_GROUP0 0x5c
- SCORPION_ICACHE_ACCESS = 0x10053,
- SCORPION_ICACHE_MISS = 0x10052,
+#define SCORPION_ICACHE_ACCESS 0x10053
+#define SCORPION_ICACHE_MISS 0x10052
- SCORPION_DTLB_ACCESS = 0x12013,
- SCORPION_DTLB_MISS = 0x12012,
+#define SCORPION_DTLB_ACCESS 0x12013
+#define SCORPION_DTLB_MISS 0x12012
- SCORPION_ITLB_MISS = 0x12021,
-};
+#define SCORPION_ITLB_MISS 0x12021
/*
* Cortex-A8 HW events mapping
@@ -547,6 +531,134 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
};
+PMU_FORMAT_ATTR(event, "config:0-7");
+
+static struct attribute *armv7_pmu_format_attrs[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group armv7_pmu_format_attr_group = {
+ .name = "format",
+ .attrs = armv7_pmu_format_attrs,
+};
+
+#define ARMV7_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV7_EVENT_ATTR(name, config) \
+ PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, \
+ "event=" ARMV7_EVENT_ATTR_RESOLVE(config))
+
+ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
+ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
+ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
+ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
+ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
+ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
+ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
+ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
+ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
+ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
+ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
+ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
+
+static struct attribute *armv7_pmuv1_event_attrs[] = {
+ &armv7_event_attr_sw_incr.attr.attr,
+ &armv7_event_attr_l1i_cache_refill.attr.attr,
+ &armv7_event_attr_l1i_tlb_refill.attr.attr,
+ &armv7_event_attr_l1d_cache_refill.attr.attr,
+ &armv7_event_attr_l1d_cache.attr.attr,
+ &armv7_event_attr_l1d_tlb_refill.attr.attr,
+ &armv7_event_attr_ld_retired.attr.attr,
+ &armv7_event_attr_st_retired.attr.attr,
+ &armv7_event_attr_inst_retired.attr.attr,
+ &armv7_event_attr_exc_taken.attr.attr,
+ &armv7_event_attr_exc_return.attr.attr,
+ &armv7_event_attr_cid_write_retired.attr.attr,
+ &armv7_event_attr_pc_write_retired.attr.attr,
+ &armv7_event_attr_br_immed_retired.attr.attr,
+ &armv7_event_attr_br_return_retired.attr.attr,
+ &armv7_event_attr_unaligned_ldst_retired.attr.attr,
+ &armv7_event_attr_br_mis_pred.attr.attr,
+ &armv7_event_attr_cpu_cycles.attr.attr,
+ &armv7_event_attr_br_pred.attr.attr,
+ NULL,
+};
+
+static struct attribute_group armv7_pmuv1_events_attr_group = {
+ .name = "events",
+ .attrs = armv7_pmuv1_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv1_attr_groups[] = {
+ &armv7_pmuv1_events_attr_group,
+ &armv7_pmu_format_attr_group,
+ NULL,
+};
+
+ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
+ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
+ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
+ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
+ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
+ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
+ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
+ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
+ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
+ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+ &armv7_event_attr_sw_incr.attr.attr,
+ &armv7_event_attr_l1i_cache_refill.attr.attr,
+ &armv7_event_attr_l1i_tlb_refill.attr.attr,
+ &armv7_event_attr_l1d_cache_refill.attr.attr,
+ &armv7_event_attr_l1d_cache.attr.attr,
+ &armv7_event_attr_l1d_tlb_refill.attr.attr,
+ &armv7_event_attr_ld_retired.attr.attr,
+ &armv7_event_attr_st_retired.attr.attr,
+ &armv7_event_attr_inst_retired.attr.attr,
+ &armv7_event_attr_exc_taken.attr.attr,
+ &armv7_event_attr_exc_return.attr.attr,
+ &armv7_event_attr_cid_write_retired.attr.attr,
+ &armv7_event_attr_pc_write_retired.attr.attr,
+ &armv7_event_attr_br_immed_retired.attr.attr,
+ &armv7_event_attr_br_return_retired.attr.attr,
+ &armv7_event_attr_unaligned_ldst_retired.attr.attr,
+ &armv7_event_attr_br_mis_pred.attr.attr,
+ &armv7_event_attr_cpu_cycles.attr.attr,
+ &armv7_event_attr_br_pred.attr.attr,
+ &armv7_event_attr_mem_access.attr.attr,
+ &armv7_event_attr_l1i_cache.attr.attr,
+ &armv7_event_attr_l1d_cache_wb.attr.attr,
+ &armv7_event_attr_l2d_cache.attr.attr,
+ &armv7_event_attr_l2d_cache_refill.attr.attr,
+ &armv7_event_attr_l2d_cache_wb.attr.attr,
+ &armv7_event_attr_bus_access.attr.attr,
+ &armv7_event_attr_memory_error.attr.attr,
+ &armv7_event_attr_inst_spec.attr.attr,
+ &armv7_event_attr_ttbr_write_retired.attr.attr,
+ &armv7_event_attr_bus_cycles.attr.attr,
+ NULL,
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+ .name = "events",
+ .attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+ &armv7_pmuv2_events_attr_group,
+ &armv7_pmu_format_attr_group,
+ NULL,
+};
+
/*
* Perf Events' indices
*/
@@ -1085,6 +1197,7 @@ 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->pmu.attr_groups = armv7_pmuv1_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1093,6 +1206,7 @@ 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->pmu.attr_groups = armv7_pmuv1_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1101,6 +1215,7 @@ 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->pmu.attr_groups = armv7_pmuv1_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1110,6 +1225,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
cpu_pmu->name = "armv7_cortex_a15";
cpu_pmu->map_event = armv7_a15_map_event;
cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1119,6 +1235,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
cpu_pmu->name = "armv7_cortex_a7";
cpu_pmu->map_event = armv7_a7_map_event;
cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1128,6 +1245,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
cpu_pmu->name = "armv7_cortex_a12";
cpu_pmu->map_event = armv7_a12_map_event;
cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
return armv7_probe_num_events(cpu_pmu);
}
@@ -1135,6 +1253,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
{
int ret = armv7_a12_pmu_init(cpu_pmu);
cpu_pmu->name = "armv7_cortex_a17";
+ cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
return ret;
}
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
index 8153e36..7c9248b 100644
--- a/arch/arm/kernel/pj4-cp0.c
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
__asm__ __volatile__ (
"mcr p15, 0, %1, c1, c0, 2\n\t"
+#ifdef CONFIG_THUMB2_KERNEL
+ "isb\n\t"
+#else
"mrc p15, 0, %0, c1, c0, 2\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4\n\t"
+#endif
: "=r" (temp) : "r" (value));
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 7a7c4ce..4adfb46 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -95,6 +95,22 @@ void __show_regs(struct pt_regs *regs)
{
unsigned long flags;
char buf[64];
+#ifndef CONFIG_CPU_V7M
+ unsigned int domain;
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+ /*
+ * Get the domain register for the parent context. In user
+ * mode, we don't save the DACR, so lets use what it should
+ * be. For other modes, we place it after the pt_regs struct.
+ */
+ if (user_mode(regs))
+ domain = DACR_UACCESS_ENABLE;
+ else
+ domain = *(unsigned int *)(regs + 1);
+#else
+ domain = get_domain();
+#endif
+#endif
show_regs_print_info(KERN_DEFAULT);
@@ -123,21 +139,8 @@ void __show_regs(struct pt_regs *regs)
#ifndef CONFIG_CPU_V7M
{
- unsigned int domain = get_domain();
const char *segment;
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
- /*
- * Get the domain register for the parent context. In user
- * mode, we don't save the DACR, so lets use what it should
- * be. For other modes, we place it after the pt_regs struct.
- */
- if (user_mode(regs))
- domain = DACR_UACCESS_ENABLE;
- else
- domain = *(unsigned int *)(regs + 1);
-#endif
-
if ((domain & domain_mask(DOMAIN_USER)) ==
domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
segment = "none";
@@ -163,11 +166,11 @@ void __show_regs(struct pt_regs *regs)
buf[0] = '\0';
#ifdef CONFIG_CPU_CP15_MMU
{
- unsigned int transbase, dac = get_domain();
+ unsigned int transbase;
asm("mrc p15, 0, %0, c2, c0\n\t"
: "=r" (transbase));
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
- transbase, dac);
+ transbase, domain);
}
#endif
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
diff --git a/arch/arm/kernel/psci-call.S b/arch/arm/kernel/psci-call.S
deleted file mode 100644
index a78e9e1..0000000
--- a/arch/arm/kernel/psci-call.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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_smp.c b/arch/arm/kernel/psci_smp.c
index 61c04b0..cb3fcae 100644
--- a/arch/arm/kernel/psci_smp.c
+++ b/arch/arm/kernel/psci_smp.c
@@ -71,7 +71,7 @@ int psci_cpu_disable(unsigned int cpu)
return 0;
}
-void __ref psci_cpu_die(unsigned int cpu)
+void psci_cpu_die(unsigned int cpu)
{
u32 state = PSCI_POWER_STATE_TYPE_POWER_DOWN <<
PSCI_0_2_POWER_STATE_TYPE_SHIFT;
@@ -83,7 +83,7 @@ void __ref psci_cpu_die(unsigned int cpu)
panic("psci: cpu %d failed to shutdown\n", cpu);
}
-int __ref psci_cpu_kill(unsigned int cpu)
+int psci_cpu_kill(unsigned int cpu)
{
int err, i;
@@ -120,7 +120,7 @@ bool __init psci_smp_available(void)
return (psci_ops.cpu_on != NULL);
}
-struct smp_operations __initdata psci_smp_ops = {
+const struct smp_operations psci_smp_ops __initconst = {
.smp_boot_secondary = psci_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = psci_cpu_disable,
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3826935..71a2ff9 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -50,7 +50,7 @@ static void __soft_restart(void *addr)
flush_cache_all();
/* Switch to the identity mapping. */
- phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset);
+ phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
phys_reset((unsigned long)addr);
/* Should never get here. */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 20edd34..139791e 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/efi.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
@@ -37,7 +38,9 @@
#include <asm/cp15.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
+#include <asm/efi.h>
#include <asm/elf.h>
+#include <asm/early_ioremap.h>
#include <asm/fixmap.h>
#include <asm/procinfo.h>
#include <asm/psci.h>
@@ -173,13 +176,13 @@ static struct resource mem_res[] = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
},
{
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
}
};
@@ -375,6 +378,72 @@ void __init early_print(const char *str, ...)
printk("%s", buf);
}
+#ifdef CONFIG_ARM_PATCH_IDIV
+
+static inline u32 __attribute_const__ sdiv_instruction(void)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ /* "sdiv r0, r0, r1" */
+ u32 insn = __opcode_thumb32_compose(0xfb90, 0xf0f1);
+ return __opcode_to_mem_thumb32(insn);
+ }
+
+ /* "sdiv r0, r0, r1" */
+ return __opcode_to_mem_arm(0xe710f110);
+}
+
+static inline u32 __attribute_const__ udiv_instruction(void)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ /* "udiv r0, r0, r1" */
+ u32 insn = __opcode_thumb32_compose(0xfbb0, 0xf0f1);
+ return __opcode_to_mem_thumb32(insn);
+ }
+
+ /* "udiv r0, r0, r1" */
+ return __opcode_to_mem_arm(0xe730f110);
+}
+
+static inline u32 __attribute_const__ bx_lr_instruction(void)
+{
+ if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+ /* "bx lr; nop" */
+ u32 insn = __opcode_thumb32_compose(0x4770, 0x46c0);
+ return __opcode_to_mem_thumb32(insn);
+ }
+
+ /* "bx lr" */
+ return __opcode_to_mem_arm(0xe12fff1e);
+}
+
+static void __init patch_aeabi_idiv(void)
+{
+ extern void __aeabi_uidiv(void);
+ extern void __aeabi_idiv(void);
+ uintptr_t fn_addr;
+ unsigned int mask;
+
+ mask = IS_ENABLED(CONFIG_THUMB2_KERNEL) ? HWCAP_IDIVT : HWCAP_IDIVA;
+ if (!(elf_hwcap & mask))
+ return;
+
+ pr_info("CPU: div instructions available: patching division code\n");
+
+ fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
+ ((u32 *)fn_addr)[0] = udiv_instruction();
+ ((u32 *)fn_addr)[1] = bx_lr_instruction();
+ flush_icache_range(fn_addr, fn_addr + 8);
+
+ fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
+ ((u32 *)fn_addr)[0] = sdiv_instruction();
+ ((u32 *)fn_addr)[1] = bx_lr_instruction();
+ flush_icache_range(fn_addr, fn_addr + 8);
+}
+
+#else
+static inline void patch_aeabi_idiv(void) { }
+#endif
+
static void __init cpuid_init_hwcaps(void)
{
int block;
@@ -642,6 +711,7 @@ static void __init setup_processor(void)
elf_hwcap = list->elf_hwcap;
cpuid_init_hwcaps();
+ patch_aeabi_idiv();
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
@@ -781,7 +851,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc)
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;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
@@ -956,8 +1026,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
- if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM))
- early_fixmap_init();
+ early_fixmap_init();
+ early_ioremap_init();
parse_early_param();
@@ -965,9 +1035,12 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
#endif
setup_dma_zone(mdesc);
+ efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
+ early_ioremap_reset();
+
paging_init(mdesc);
request_standard_resources(mdesc);
diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S
new file mode 100644
index 0000000..2e48b67
--- /dev/null
+++ b/arch/arm/kernel/smccc-call.S
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+#include <asm/unwind.h>
+
+ /*
+ * Wrap c macros in asm macros to delay expansion until after the
+ * SMCCC asm macro is expanded.
+ */
+ .macro SMCCC_SMC
+ __SMC(0)
+ .endm
+
+ .macro SMCCC_HVC
+ __HVC(0)
+ .endm
+
+ .macro SMCCC instr
+UNWIND( .fnstart)
+ mov r12, sp
+ push {r4-r7}
+UNWIND( .save {r4-r7})
+ ldm r12, {r4-r7}
+ \instr
+ pop {r4-r7}
+ ldr r12, [sp, #(4 * 4)]
+ stm r12, {r0-r3}
+ bx lr
+UNWIND( .fnend)
+ .endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_smc)
+ SMCCC SMCCC_SMC
+ENDPROC(arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_hvc)
+ SMCCC SMCCC_HVC
+ENDPROC(arm_smccc_hvc)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 48185a7..baee702 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -69,18 +69,22 @@ enum ipi_msg_type {
IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
- IPI_CALL_FUNC_SINGLE,
IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_COMPLETION,
- IPI_CPU_BACKTRACE = 15,
+ IPI_CPU_BACKTRACE,
+ /*
+ * SGI8-15 can be reserved by secure firmware, and thus may
+ * not be usable by the kernel. Please keep the above limited
+ * to at most 8 entries.
+ */
};
static DECLARE_COMPLETION(cpu_running);
static struct smp_operations smp_ops;
-void __init smp_set_ops(struct smp_operations *ops)
+void __init smp_set_ops(const struct smp_operations *ops)
{
if (ops)
smp_ops = *ops;
@@ -400,11 +404,12 @@ asmlinkage void secondary_start_kernel(void)
local_irq_enable();
local_fiq_enable();
+ local_abt_enable();
/*
* OK, it's off to the idle thread for us
*/
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
void __init smp_cpus_done(unsigned int max_cpus)
@@ -474,7 +479,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
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"),
@@ -524,7 +528,7 @@ void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
void arch_send_call_function_single_ipi(int cpu)
{
- smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
}
#ifdef CONFIG_IRQ_WORK
@@ -619,12 +623,6 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
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);
@@ -748,6 +746,15 @@ core_initcall(register_cpufreq_notifier);
static void raise_nmi(cpumask_t *mask)
{
+ /*
+ * Generate the backtrace directly if we are running in a calling
+ * context that is not preemptible by the backtrace IPI. Note
+ * that nmi_cpu_backtrace() automatically removes the current cpu
+ * from mask.
+ */
+ if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled())
+ nmi_cpu_backtrace(NULL);
+
smp_cross_call(mask, IPI_CPU_BACKTRACE);
}
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index e9035cd..1bfa7a7 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -23,7 +23,6 @@
#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 */
@@ -34,6 +33,8 @@ static unsigned long twd_timer_rate;
static DEFINE_PER_CPU(bool, percpu_setup_called);
static struct clock_event_device __percpu *twd_evt;
+static unsigned int twd_features =
+ CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
static int twd_ppi;
static int twd_shutdown(struct clock_event_device *clk)
@@ -294,8 +295,7 @@ static void twd_timer_setup(void)
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->features = twd_features;
clk->rating = 350;
clk->set_state_shutdown = twd_shutdown;
clk->set_state_periodic = twd_set_periodic;
@@ -350,6 +350,8 @@ static int __init twd_local_timer_common_register(struct device_node *np)
goto out_irq;
twd_get_clock(np);
+ if (!of_property_read_bool(np, "always-on"))
+ twd_features |= CLOCK_EVT_FEAT_C3STOP;
/*
* Immediately configure the timer on the boot CPU, unless we need
@@ -392,9 +394,6 @@ 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;
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 5b26e7e..c3fe769d 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -36,10 +36,10 @@
*/
#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" \
+ "0: ldrex"B" %2, [%3]\n" \
+ "1: strex"B" %0, %1, [%3]\n" \
" cmp %0, #0\n" \
+ " moveq %1, %2\n" \
" movne %0, %4\n" \
"2:\n" \
" .section .text.fixup,\"ax\"\n" \
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index b83f3b7..087acb5 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -193,15 +193,44 @@ struct oabi_flock64 {
pid_t l_pid;
} __attribute__ ((packed,aligned(4)));
-asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+static long do_locks(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;
+ struct oabi_flock64 user;
+ mm_segment_t fs;
+ long ret;
+
+ 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;
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel);
+ set_fs(fs);
+
+ if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) {
+ 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;
+ }
+ return ret;
+}
+asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
switch (cmd) {
case F_OFD_GETLK:
case F_OFD_SETLK:
@@ -209,39 +238,11 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
- if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
- sizeof(user)))
- return -EFAULT;
- kernel.l_type = user.l_type;
- kernel.l_whence = user.l_whence;
- kernel.l_start = user.l_start;
- kernel.l_len = user.l_len;
- kernel.l_pid = user.l_pid;
- local_arg = (unsigned long)&kernel;
- fs = get_fs();
- set_fs(KERNEL_DS);
- }
-
- ret = sys_fcntl64(fd, cmd, local_arg);
+ return do_locks(fd, cmd, 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);
+ default:
+ return sys_fcntl64(fd, cmd, arg);
}
-
- return ret;
}
struct oabi_epoll_event {
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index a66e37e..97b22fa 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -120,6 +120,6 @@ void __init time_init(void)
#ifdef CONFIG_COMMON_CLK
of_clk_init(NULL);
#endif
- clocksource_of_init();
+ clocksource_probe();
}
}
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 08b7847..ec279d1 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -40,7 +40,7 @@
* 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);
+static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
{
@@ -306,8 +306,6 @@ void __init init_cpu_topology(void)
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();
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 969f9d9..bc69838 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -625,58 +625,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
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
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 54a5aea..994e971 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -224,7 +224,7 @@ static int install_vvar(struct mm_struct *mm, unsigned long addr)
VM_READ | VM_MAYREAD,
&vdso_data_mapping);
- return IS_ERR(vma) ? PTR_ERR(vma) : 0;
+ return PTR_ERR_OR_ZERO(vma);
}
/* assumes mmap_sem is write-locked */
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S
new file mode 100644
index 0000000..cba1ec8
--- /dev/null
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -0,0 +1,316 @@
+/* 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>
+
+#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.*)
+ }
+
+ . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+ _xiprom = .; /* XIP ROM area to be mapped */
+
+ .head.text : {
+ _text = .;
+ HEAD_TEXT
+ }
+
+ .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)
+ }
+
+ 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 */
+
+ /*
+ * The vectors and stubs are relocatable code, and the
+ * only thing that matters is their relative offsets
+ */
+ __vectors_start = .;
+ .vectors 0xffff0000 : AT(__vectors_start) {
+ *(.vectors)
+ }
+ . = __vectors_start + SIZEOF(.vectors);
+ __vectors_end = .;
+
+ __stubs_start = .;
+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {
+ *(.stubs)
+ }
+ . = __stubs_start + SIZEOF(.stubs);
+ __stubs_end = .;
+
+ PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
+
+ 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 : {
+ INIT_SETUP(16)
+ INIT_CALLS
+ CON_INITCALL
+ SECURITY_INITCALL
+ INIT_RAM_FS
+ }
+
+#ifdef CONFIG_SMP
+ PERCPU_SECTION(L1_CACHE_BYTES)
+#endif
+
+ _exiprom = .; /* End of XIP ROM area */
+ __data_loc = ALIGN(4); /* location in binary */
+ . = PAGE_OFFSET + TEXT_OFFSET;
+
+ .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)
+
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ INIT_DATA
+ ARM_EXIT_KEEP(EXIT_DATA)
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+
+ 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/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8b60fde..1fab979 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -3,14 +3,16 @@
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
+#ifdef CONFIG_XIP_KERNEL
+#include "vmlinux-xip.lds.S"
+#else
+
#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); \
@@ -18,6 +20,11 @@
*(.proc.info.init) \
VMLINUX_SYMBOL(__proc_info_end) = .;
+#define HYPERVISOR_TEXT \
+ VMLINUX_SYMBOL(__hyp_text_start) = .; \
+ *(.hyp.text) \
+ VMLINUX_SYMBOL(__hyp_text_end) = .;
+
#define IDMAP_TEXT \
ALIGN_FUNCTION(); \
VMLINUX_SYMBOL(__idmap_text_start) = .; \
@@ -84,17 +91,13 @@ SECTIONS
*(.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
+#ifdef CONFIG_DEBUG_RODATA
. = ALIGN(1<<SECTION_SHIFT);
#endif
@@ -108,6 +111,7 @@ SECTIONS
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
+ HYPERVISOR_TEXT
KPROBES_TEXT
*(.gnu.warning)
*(.glue_7)
@@ -117,7 +121,7 @@ SECTIONS
ARM_CPU_KEEP(PROC_INFO)
}
-#ifdef CONFIG_DEBUG_RODATA
+#ifdef CONFIG_DEBUG_ALIGN_RODATA
. = ALIGN(1<<SECTION_SHIFT);
#endif
RO_DATA(PAGE_SIZE)
@@ -152,32 +156,33 @@ SECTIONS
_etext = .; /* End of text and rodata section */
-#ifndef CONFIG_XIP_KERNEL
-# ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
. = ALIGN(1<<SECTION_SHIFT);
-# else
+#else
. = ALIGN(PAGE_SIZE);
-# endif
- __init_begin = .;
#endif
+ __init_begin = .;
+
/*
* 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 0xffff0000 : AT(__vectors_start) {
*(.vectors)
}
. = __vectors_start + SIZEOF(.vectors);
__vectors_end = .;
__stubs_start = .;
- .stubs 0x1000 : AT(__stubs_start) {
+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {
*(.stubs)
}
. = __stubs_start + SIZEOF(.stubs);
__stubs_end = .;
+ PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
+
INIT_TEXT_SECTION(8)
.exit.text : {
ARM_EXIT_KEEP(EXIT_TEXT)
@@ -208,37 +213,28 @@ SECTIONS
__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
+#ifdef CONFIG_DEBUG_RODATA
. = ALIGN(1<<SECTION_SHIFT);
#else
. = ALIGN(THREAD_SIZE);
#endif
__init_end = .;
__data_loc = .;
-#endif
.data : AT(__data_loc) {
_data = .; /* address in memory */
@@ -250,15 +246,6 @@ SECTIONS
*/
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)
@@ -336,6 +323,15 @@ SECTIONS
STABS_DEBUG
}
+#ifdef CONFIG_DEBUG_RODATA
+/*
+ * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will
+ * be the first section-aligned location after __start_rodata. Otherwise,
+ * it will be equal to __start_rodata.
+ */
+__start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT);
+#endif
+
/*
* These must never be empty
* If you have to comment these two assert statements out, your
@@ -351,3 +347,5 @@ ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
*/
ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
"HYP init code too big or misaligned")
+
+#endif /* CONFIG_XIP_KERNEL */
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
index bdbb8853..77a2eef 100644
--- a/arch/arm/kernel/xscale-cp0.c
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -15,6 +15,9 @@
#include <linux/init.h>
#include <linux/io.h>
#include <asm/thread_notify.h>
+#include <asm/cputype.h>
+
+asm(" .arch armv5te\n");
static inline void dsp_save_state(u32 *state)
{
@@ -152,6 +155,10 @@ static int __init xscale_cp0_init(void)
{
u32 cp_access;
+ /* do not attempt to probe iwmmxt on non-xscale family CPUs */
+ if (!cpu_is_xscale_family())
+ return 0;
+
cp_access = xscale_cp_access_read() & ~3;
xscale_cp_access_write(cp_access | 1);
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 356970f..95a0005 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -46,4 +46,6 @@ config KVM_ARM_HOST
---help---
Provides host support for ARM processors.
+source drivers/vhost/Kconfig
+
endif # VIRTUALIZATION
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index c5eef02c..eb1bf43 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -17,6 +17,7 @@ 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 $(KVM)/vfio.o
+obj-$(CONFIG_KVM_ARM_HOST) += hyp/
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
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 78b2869..3e0fb66 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -28,6 +28,7 @@
#include <linux/sched.h>
#include <linux/kvm.h>
#include <trace/events/kvm.h>
+#include <kvm/arm_pmu.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
@@ -44,6 +45,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_psci.h>
+#include <asm/sections.h>
#ifdef REQUIRES_VIRT
__asm__(".arch_extension virt");
@@ -58,9 +60,12 @@ 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 u32 kvm_next_vmid;
+static unsigned int kvm_vmid_bits __read_mostly;
static DEFINE_SPINLOCK(kvm_vmid_lock);
+static bool vgic_present;
+
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
{
BUG_ON(preemptible());
@@ -132,7 +137,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
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();
+ kvm->arch.max_vcpus = vgic_present ?
+ kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
return ret;
out_free_stage2_pgd:
@@ -172,6 +178,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int r;
switch (ext) {
case KVM_CAP_IRQCHIP:
+ r = vgic_present;
+ break;
case KVM_CAP_IOEVENTFD:
case KVM_CAP_DEVICE_CTRL:
case KVM_CAP_USER_MEMORY:
@@ -258,6 +266,7 @@ 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);
+ kvm_pmu_vcpu_destroy(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu);
}
@@ -271,6 +280,16 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
return kvm_timer_should_fire(vcpu);
}
+void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
+{
+ kvm_timer_schedule(vcpu);
+}
+
+void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
+{
+ kvm_timer_unschedule(vcpu);
+}
+
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
/* Force users to call KVM_ARM_VCPU_INIT */
@@ -303,12 +322,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
vcpu->cpu = -1;
kvm_arm_set_running_vcpu(NULL);
+ kvm_timer_vcpu_put(vcpu);
}
int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
- if (vcpu->arch.pause)
+ if (vcpu->arch.power_off)
mp_state->mp_state = KVM_MP_STATE_STOPPED;
else
mp_state->mp_state = KVM_MP_STATE_RUNNABLE;
@@ -321,10 +341,10 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
{
switch (mp_state->mp_state) {
case KVM_MP_STATE_RUNNABLE:
- vcpu->arch.pause = false;
+ vcpu->arch.power_off = false;
break;
case KVM_MP_STATE_STOPPED:
- vcpu->arch.pause = true;
+ vcpu->arch.power_off = true;
break;
default:
return -EINVAL;
@@ -342,7 +362,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
*/
int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
{
- return !!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v);
+ return ((!!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v))
+ && !v->arch.power_off && !v->arch.pause);
}
/* Just ensure a guest exit from a particular CPU */
@@ -422,11 +443,12 @@ static void update_vttbr(struct kvm *kvm)
kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
kvm->arch.vmid = kvm_next_vmid;
kvm_next_vmid++;
+ kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
/* 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;
+ vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
kvm->arch.vttbr = pgd_phys | vmid;
spin_unlock(&kvm_vmid_lock);
@@ -468,11 +490,38 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
return vgic_initialized(kvm);
}
-static void vcpu_pause(struct kvm_vcpu *vcpu)
+static void kvm_arm_halt_guest(struct kvm *kvm) __maybe_unused;
+static void kvm_arm_resume_guest(struct kvm *kvm) __maybe_unused;
+
+static void kvm_arm_halt_guest(struct kvm *kvm)
+{
+ int i;
+ struct kvm_vcpu *vcpu;
+
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ vcpu->arch.pause = true;
+ force_vm_exit(cpu_all_mask);
+}
+
+static void kvm_arm_resume_guest(struct kvm *kvm)
+{
+ int i;
+ struct kvm_vcpu *vcpu;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ struct swait_queue_head *wq = kvm_arch_vcpu_wq(vcpu);
+
+ vcpu->arch.pause = false;
+ swake_up(wq);
+ }
+}
+
+static void vcpu_sleep(struct kvm_vcpu *vcpu)
{
- wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
+ struct swait_queue_head *wq = kvm_arch_vcpu_wq(vcpu);
- wait_event_interruptible(*wq, !vcpu->arch.pause);
+ swait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
+ (!vcpu->arch.pause)));
}
static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
@@ -522,14 +571,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
update_vttbr(vcpu->kvm);
- if (vcpu->arch.pause)
- vcpu_pause(vcpu);
-
- /*
- * Disarming the background timer must be done in a
- * preemptible context, as this call may sleep.
- */
- kvm_timer_flush_hwstate(vcpu);
+ if (vcpu->arch.power_off || vcpu->arch.pause)
+ vcpu_sleep(vcpu);
/*
* Preparing the interrupts to be injected also
@@ -537,6 +580,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
* non-preemptible context.
*/
preempt_disable();
+ kvm_pmu_flush_hwstate(vcpu);
+ kvm_timer_flush_hwstate(vcpu);
kvm_vgic_flush_hwstate(vcpu);
local_irq_disable();
@@ -549,11 +594,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->exit_reason = KVM_EXIT_INTR;
}
- if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
+ if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
+ vcpu->arch.power_off || vcpu->arch.pause) {
local_irq_enable();
+ kvm_pmu_sync_hwstate(vcpu);
+ kvm_timer_sync_hwstate(vcpu);
kvm_vgic_sync_hwstate(vcpu);
preempt_enable();
- kvm_timer_sync_hwstate(vcpu);
continue;
}
@@ -569,6 +616,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
+ vcpu->stat.exits++;
/*
* Back from guest
*************************************************************/
@@ -596,14 +644,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
* guest time.
*/
kvm_guest_exit();
- trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
+ trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
+
+ /*
+ * We must sync the PMU and timer state before the vgic state so
+ * that the vgic can properly sample the updated state of the
+ * interrupt line.
+ */
+ kvm_pmu_sync_hwstate(vcpu);
+ kvm_timer_sync_hwstate(vcpu);
kvm_vgic_sync_hwstate(vcpu);
preempt_enable();
- kvm_timer_sync_hwstate(vcpu);
-
ret = handle_exit(vcpu, run, ret);
}
@@ -765,21 +819,64 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
vcpu_reset_hcr(vcpu);
/*
- * Handle the "start in power-off" case by marking the VCPU as paused.
+ * Handle the "start in power-off" case.
*/
if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
- vcpu->arch.pause = true;
+ vcpu->arch.power_off = true;
else
- vcpu->arch.pause = false;
+ vcpu->arch.power_off = false;
return 0;
}
+static int kvm_arm_vcpu_set_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret = -ENXIO;
+
+ switch (attr->group) {
+ default:
+ ret = kvm_arm_vcpu_arch_set_attr(vcpu, attr);
+ break;
+ }
+
+ return ret;
+}
+
+static int kvm_arm_vcpu_get_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret = -ENXIO;
+
+ switch (attr->group) {
+ default:
+ ret = kvm_arm_vcpu_arch_get_attr(vcpu, attr);
+ break;
+ }
+
+ return ret;
+}
+
+static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret = -ENXIO;
+
+ switch (attr->group) {
+ default:
+ ret = kvm_arm_vcpu_arch_has_attr(vcpu, attr);
+ break;
+ }
+
+ return ret;
+}
+
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;
+ struct kvm_device_attr attr;
switch (ioctl) {
case KVM_ARM_VCPU_INIT: {
@@ -822,6 +919,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
return -E2BIG;
return kvm_arm_copy_reg_indices(vcpu, user_list->reg);
}
+ case KVM_SET_DEVICE_ATTR: {
+ if (copy_from_user(&attr, argp, sizeof(attr)))
+ return -EFAULT;
+ return kvm_arm_vcpu_set_attr(vcpu, &attr);
+ }
+ case KVM_GET_DEVICE_ATTR: {
+ if (copy_from_user(&attr, argp, sizeof(attr)))
+ return -EFAULT;
+ return kvm_arm_vcpu_get_attr(vcpu, &attr);
+ }
+ case KVM_HAS_DEVICE_ATTR: {
+ if (copy_from_user(&attr, argp, sizeof(attr)))
+ return -EFAULT;
+ return kvm_arm_vcpu_has_attr(vcpu, &attr);
+ }
default:
return -EINVAL;
}
@@ -874,6 +986,8 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
switch (dev_id) {
case KVM_ARM_DEVICE_VGIC_V2:
+ if (!vgic_present)
+ return -ENXIO;
return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
default:
return -ENODEV;
@@ -888,6 +1002,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
switch (ioctl) {
case KVM_CREATE_IRQCHIP: {
+ if (!vgic_present)
+ return -ENXIO;
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
}
case KVM_ARM_SET_DEVICE_ADDR: {
@@ -915,6 +1031,11 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
}
+static void cpu_init_stage2(void *dummy)
+{
+ __cpu_init_stage2();
+}
+
static void cpu_init_hyp_mode(void *dummy)
{
phys_addr_t boot_pgd_ptr;
@@ -930,9 +1051,10 @@ static void cpu_init_hyp_mode(void *dummy)
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;
+ vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+ __cpu_init_stage2();
kvm_arm_init_debug();
}
@@ -983,6 +1105,82 @@ static inline void hyp_cpu_pm_init(void)
}
#endif
+static void teardown_common_resources(void)
+{
+ free_percpu(kvm_host_cpu_state);
+}
+
+static int init_common_resources(void)
+{
+ kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
+ if (!kvm_host_cpu_state) {
+ kvm_err("Cannot allocate host CPU state\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int init_subsystems(void)
+{
+ int err;
+
+ /*
+ * Init HYP view of VGIC
+ */
+ err = kvm_vgic_hyp_init();
+ switch (err) {
+ case 0:
+ vgic_present = true;
+ break;
+ case -ENODEV:
+ case -ENXIO:
+ vgic_present = false;
+ break;
+ default:
+ return err;
+ }
+
+ /*
+ * Init HYP architected timer support
+ */
+ err = kvm_timer_hyp_init();
+ if (err)
+ return err;
+
+ kvm_perf_init();
+ kvm_coproc_table_init();
+
+ return 0;
+}
+
+static void teardown_hyp_mode(void)
+{
+ int cpu;
+
+ if (is_kernel_in_hyp_mode())
+ return;
+
+ free_hyp_pgds();
+ for_each_possible_cpu(cpu)
+ free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
+}
+
+static int init_vhe_mode(void)
+{
+ /*
+ * Execute the init code on each CPU.
+ */
+ on_each_cpu(cpu_init_stage2, NULL, 1);
+
+ /* set size of VMID supported by CPU */
+ kvm_vmid_bits = kvm_get_vmid_bits();
+ kvm_info("%d-bit VMID\n", kvm_vmid_bits);
+
+ kvm_info("VHE mode initialized successfully\n");
+ return 0;
+}
+
/**
* Inits Hyp-mode on all online CPUs
*/
@@ -1013,7 +1211,7 @@ static int init_hyp_mode(void)
stack_page = __get_free_page(GFP_KERNEL);
if (!stack_page) {
err = -ENOMEM;
- goto out_free_stack_pages;
+ goto out_err;
}
per_cpu(kvm_arm_hyp_stack_page, cpu) = stack_page;
@@ -1022,10 +1220,18 @@ static int init_hyp_mode(void)
/*
* Map the Hyp-code called directly from the host
*/
- err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
+ err = create_hyp_mappings(kvm_ksym_ref(__hyp_text_start),
+ kvm_ksym_ref(__hyp_text_end));
if (err) {
kvm_err("Cannot map world-switch code\n");
- goto out_free_mappings;
+ goto out_err;
+ }
+
+ err = create_hyp_mappings(kvm_ksym_ref(__start_rodata),
+ kvm_ksym_ref(__end_rodata));
+ if (err) {
+ kvm_err("Cannot map rodata section\n");
+ goto out_err;
}
/*
@@ -1037,20 +1243,10 @@ static int init_hyp_mode(void)
if (err) {
kvm_err("Cannot map hyp stack\n");
- goto out_free_mappings;
+ goto out_err;
}
}
- /*
- * 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;
@@ -1059,7 +1255,7 @@ static int init_hyp_mode(void)
if (err) {
kvm_err("Cannot map host CPU state: %d\n", err);
- goto out_free_context;
+ goto out_err;
}
}
@@ -1068,37 +1264,33 @@ static int init_hyp_mode(void)
*/
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_context;
-
#ifndef CONFIG_HOTPLUG_CPU
free_boot_hyp_pgd();
#endif
- kvm_perf_init();
+ cpu_notifier_register_begin();
+
+ err = __register_cpu_notifier(&hyp_init_cpu_nb);
+
+ cpu_notifier_register_done();
+
+ if (err) {
+ kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
+ goto out_err;
+ }
+
+ hyp_cpu_pm_init();
+
+ /* set size of VMID supported by CPU */
+ kvm_vmid_bits = kvm_get_vmid_bits();
+ kvm_info("%d-bit VMID\n", kvm_vmid_bits);
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:
+ teardown_hyp_mode();
kvm_err("error initializing Hyp mode: %d\n", err);
return err;
}
@@ -1142,26 +1334,27 @@ int kvm_arch_init(void *opaque)
}
}
- cpu_notifier_register_begin();
-
- err = init_hyp_mode();
+ err = init_common_resources();
if (err)
- goto out_err;
+ return err;
- err = __register_cpu_notifier(&hyp_init_cpu_nb);
- if (err) {
- kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
+ if (is_kernel_in_hyp_mode())
+ err = init_vhe_mode();
+ else
+ err = init_hyp_mode();
+ if (err)
goto out_err;
- }
-
- cpu_notifier_register_done();
- hyp_cpu_pm_init();
+ err = init_subsystems();
+ if (err)
+ goto out_hyp;
- kvm_coproc_table_init();
return 0;
+
+out_hyp:
+ teardown_hyp_mode();
out_err:
- cpu_notifier_register_done();
+ teardown_common_resources();
return err;
}
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index f3d88dc..1bb2b79 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -16,6 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
+#include <linux/bsearch.h>
#include <linux/mm.h>
#include <linux/kvm_host.h>
#include <linux/uaccess.h>
@@ -54,8 +56,8 @@ 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;
+ vcpu_cp15(vcpu, r->reg) = val & 0xffffffff;
+ vcpu_cp15(vcpu, r->reg + 1) = val >> 32;
}
static inline u64 vcpu_cp15_reg64_get(struct kvm_vcpu *vcpu,
@@ -63,9 +65,9 @@ static inline u64 vcpu_cp15_reg64_get(struct kvm_vcpu *vcpu,
{
u64 val;
- val = vcpu->arch.cp15[r->reg + 1];
+ val = vcpu_cp15(vcpu, r->reg + 1);
val = val << 32;
- val = val | vcpu->arch.cp15[r->reg];
+ val = val | vcpu_cp15(vcpu, r->reg);
return val;
}
@@ -104,7 +106,7 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
* 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_cp15(vcpu, c0_MPIDR) = ((read_cpuid_mpidr() & MPIDR_SMP_BITMASK) |
((vcpu->vcpu_id >> 2) << MPIDR_LEVEL_BITS) |
(vcpu->vcpu_id & 3));
}
@@ -117,7 +119,7 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
if (p->is_write)
return ignore_write(vcpu, p);
- *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR];
+ *vcpu_reg(vcpu, p->Rt1) = vcpu_cp15(vcpu, c1_ACTLR);
return true;
}
@@ -139,7 +141,7 @@ static bool access_l2ctlr(struct kvm_vcpu *vcpu,
if (p->is_write)
return ignore_write(vcpu, p);
- *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR];
+ *vcpu_reg(vcpu, p->Rt1) = vcpu_cp15(vcpu, c9_L2CTLR);
return true;
}
@@ -156,7 +158,7 @@ static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
ncores = min(ncores, 3U);
l2ctlr |= (ncores & 3) << 24;
- vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
+ vcpu_cp15(vcpu, c9_L2CTLR) = l2ctlr;
}
static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
@@ -171,7 +173,7 @@ static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
else
actlr &= ~(1U << 6);
- vcpu->arch.cp15[c1_ACTLR] = actlr;
+ vcpu_cp15(vcpu, c1_ACTLR) = actlr;
}
/*
@@ -218,9 +220,9 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
BUG_ON(!p->is_write);
- vcpu->arch.cp15[r->reg] = *vcpu_reg(vcpu, p->Rt1);
+ vcpu_cp15(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt1);
if (p->is_64bit)
- vcpu->arch.cp15[r->reg + 1] = *vcpu_reg(vcpu, p->Rt2);
+ vcpu_cp15(vcpu, r->reg + 1) = *vcpu_reg(vcpu, p->Rt2);
kvm_toggle_cache(vcpu, was_enabled);
return true;
@@ -381,17 +383,26 @@ static const struct coproc_reg cp15_regs[] = {
{ CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
};
+static int check_reg_table(const struct coproc_reg *table, unsigned int n)
+{
+ unsigned int i;
+
+ for (i = 1; i < n; i++) {
+ if (cmp_reg(&table[i-1], &table[i]) >= 0) {
+ kvm_err("reg table %p out of order (%d)\n", table, i - 1);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* 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);
-
+ BUG_ON(check_reg_table(table->table, table->num));
target_tables[table->target] = table;
}
@@ -405,29 +416,32 @@ static const struct coproc_reg *get_target_table(unsigned target, size_t *num)
return table->table;
}
+#define reg_to_match_value(x) \
+ ({ \
+ unsigned long val; \
+ val = (x)->CRn << 11; \
+ val |= (x)->CRm << 7; \
+ val |= (x)->Op1 << 4; \
+ val |= (x)->Op2 << 1; \
+ val |= !(x)->is_64bit; \
+ val; \
+ })
+
+static int match_reg(const void *key, const void *elt)
+{
+ const unsigned long pval = (unsigned long)key;
+ const struct coproc_reg *r = elt;
+
+ return pval - reg_to_match_value(r);
+}
+
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;
+ unsigned long pval = reg_to_match_value(params);
- return r;
- }
- return NULL;
+ return bsearch((void *)pval, table, num, sizeof(table[0]), match_reg);
}
static int emulate_cp15(struct kvm_vcpu *vcpu,
@@ -645,6 +659,9 @@ static struct coproc_reg invariant_cp15[] = {
{ 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( 0), Op1( 1), Op2( 1), is32, NULL, get_CLIDR },
+ { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR },
+
{ 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 },
@@ -660,9 +677,6 @@ static struct coproc_reg invariant_cp15[] = {
{ 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 },
};
/*
@@ -901,7 +915,7 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
if (vfpid < num_fp_regs()) {
if (KVM_REG_SIZE(id) != 8)
return -ENOENT;
- return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpregs[vfpid],
+ return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpregs[vfpid],
id);
}
@@ -911,13 +925,13 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
switch (vfpid) {
case KVM_REG_ARM_VFP_FPEXC:
- return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpexc, id);
+ return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpexc, id);
case KVM_REG_ARM_VFP_FPSCR:
- return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpscr, id);
+ return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpscr, id);
case KVM_REG_ARM_VFP_FPINST:
- return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst, id);
+ return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpinst, id);
case KVM_REG_ARM_VFP_FPINST2:
- return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst2, id);
+ return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpinst2, id);
case KVM_REG_ARM_VFP_MVFR0:
val = fmrx(MVFR0);
return reg_to_user(uaddr, &val, id);
@@ -945,7 +959,7 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
if (vfpid < num_fp_regs()) {
if (KVM_REG_SIZE(id) != 8)
return -ENOENT;
- return reg_from_user(&vcpu->arch.vfp_guest.fpregs[vfpid],
+ return reg_from_user(&vcpu->arch.ctxt.vfp.fpregs[vfpid],
uaddr, id);
}
@@ -955,13 +969,13 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
switch (vfpid) {
case KVM_REG_ARM_VFP_FPEXC:
- return reg_from_user(&vcpu->arch.vfp_guest.fpexc, uaddr, id);
+ return reg_from_user(&vcpu->arch.ctxt.vfp.fpexc, uaddr, id);
case KVM_REG_ARM_VFP_FPSCR:
- return reg_from_user(&vcpu->arch.vfp_guest.fpscr, uaddr, id);
+ return reg_from_user(&vcpu->arch.ctxt.vfp.fpscr, uaddr, id);
case KVM_REG_ARM_VFP_FPINST:
- return reg_from_user(&vcpu->arch.vfp_guest.fpinst, uaddr, id);
+ return reg_from_user(&vcpu->arch.ctxt.vfp.fpinst, uaddr, id);
case KVM_REG_ARM_VFP_FPINST2:
- return reg_from_user(&vcpu->arch.vfp_guest.fpinst2, uaddr, id);
+ return reg_from_user(&vcpu->arch.ctxt.vfp.fpinst2, uaddr, id);
/* These are invariant. */
case KVM_REG_ARM_VFP_MVFR0:
if (reg_from_user(&val, uaddr, id))
@@ -1030,7 +1044,7 @@ int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
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);
+ ret = reg_to_user(uaddr, &vcpu_cp15(vcpu, r->reg), reg->id);
}
return ret;
@@ -1060,7 +1074,7 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
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);
+ ret = reg_from_user(&vcpu_cp15(vcpu, r->reg), uaddr, reg->id);
}
return ret;
@@ -1096,7 +1110,7 @@ static int write_demux_regids(u64 __user *uindices)
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) {
+ if (reg->is_64bit) {
val |= KVM_REG_SIZE_U64;
val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
/*
@@ -1210,8 +1224,8 @@ 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);
+ BUG_ON(check_reg_table(cp15_regs, ARRAY_SIZE(cp15_regs)));
+ BUG_ON(check_reg_table(invariant_cp15, ARRAY_SIZE(invariant_cp15)));
/* We abuse the reset function to overwrite the table itself. */
for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++)
@@ -1248,7 +1262,7 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu)
const struct coproc_reg *table;
/* Catch someone adding a register without putting in reset entry. */
- memset(vcpu->arch.cp15, 0x42, sizeof(vcpu->arch.cp15));
+ memset(vcpu->arch.ctxt.cp15, 0x42, sizeof(vcpu->arch.ctxt.cp15));
/* Generic chip reset first (so target could override). */
reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs));
@@ -1257,6 +1271,6 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu)
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);
+ if (vcpu_cp15(vcpu, num) == 0x42424242)
+ panic("Didn't reset vcpu_cp15(vcpu, %zi)", num);
}
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h
index 88d24a3..eef1759 100644
--- a/arch/arm/kvm/coproc.h
+++ b/arch/arm/kvm/coproc.h
@@ -37,7 +37,7 @@ struct coproc_reg {
unsigned long Op1;
unsigned long Op2;
- bool is_64;
+ bool is_64bit;
/* Trapped access from guest, if non-NULL. */
bool (*access)(struct kvm_vcpu *,
@@ -47,7 +47,7 @@ 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. */
+ /* Index into vcpu_cp15(vcpu, ...), or 0 if we don't need to save it. */
unsigned long reg;
/* Value (usually reset value) */
@@ -104,25 +104,25 @@ 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;
+ BUG_ON(r->reg >= ARRAY_SIZE(vcpu->arch.ctxt.cp15));
+ vcpu_cp15(vcpu, 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;
+ BUG_ON(r->reg >= ARRAY_SIZE(vcpu->arch.ctxt.cp15));
+ vcpu_cp15(vcpu, 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));
+ BUG_ON(r->reg + 1 >= ARRAY_SIZE(vcpu->arch.ctxt.cp15));
- vcpu->arch.cp15[r->reg] = 0xdecafbad;
- vcpu->arch.cp15[r->reg+1] = 0xd0c0ffee;
+ vcpu_cp15(vcpu, r->reg) = 0xdecafbad;
+ vcpu_cp15(vcpu, r->reg+1) = 0xd0c0ffee;
}
static inline int cmp_reg(const struct coproc_reg *i1,
@@ -141,7 +141,7 @@ static inline int cmp_reg(const struct coproc_reg *i1,
return i1->Op1 - i2->Op1;
if (i1->Op2 != i2->Op2)
return i1->Op2 - i2->Op2;
- return i2->is_64 - i1->is_64;
+ return i2->is_64bit - i1->is_64bit;
}
@@ -150,8 +150,8 @@ static inline int cmp_reg(const struct coproc_reg *i1,
#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
+#define is64 .is_64bit = true
+#define is32 .is_64bit = false
bool access_vm_reg(struct kvm_vcpu *vcpu,
const struct coproc_params *p,
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index d6c0052..a494def 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -112,7 +112,7 @@ static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][15] = {
*/
unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num)
{
- unsigned long *reg_array = (unsigned long *)&vcpu->arch.regs;
+ unsigned long *reg_array = (unsigned long *)&vcpu->arch.ctxt.gp_regs;
unsigned long mode = *vcpu_cpsr(vcpu) & MODE_MASK;
switch (mode) {
@@ -147,15 +147,15 @@ 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;
+ return &vcpu->arch.ctxt.gp_regs.KVM_ARM_SVC_spsr;
case ABT_MODE:
- return &vcpu->arch.regs.KVM_ARM_ABT_spsr;
+ return &vcpu->arch.ctxt.gp_regs.KVM_ARM_ABT_spsr;
case UND_MODE:
- return &vcpu->arch.regs.KVM_ARM_UND_spsr;
+ return &vcpu->arch.ctxt.gp_regs.KVM_ARM_UND_spsr;
case IRQ_MODE:
- return &vcpu->arch.regs.KVM_ARM_IRQ_spsr;
+ return &vcpu->arch.ctxt.gp_regs.KVM_ARM_IRQ_spsr;
case FIQ_MODE:
- return &vcpu->arch.regs.KVM_ARM_FIQ_spsr;
+ return &vcpu->arch.ctxt.gp_regs.KVM_ARM_FIQ_spsr;
default:
BUG();
}
@@ -266,8 +266,8 @@ void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr)
static u32 exc_vector_base(struct kvm_vcpu *vcpu)
{
- u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
- u32 vbar = vcpu->arch.cp15[c12_VBAR];
+ u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
+ u32 vbar = vcpu_cp15(vcpu, c12_VBAR);
if (sctlr & SCTLR_V)
return 0xffff0000;
@@ -275,6 +275,40 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
return vbar;
}
+/*
+ * Switch to an exception mode, updating both CPSR and SPSR. Follow
+ * the logic described in AArch32.EnterMode() from the ARMv8 ARM.
+ */
+static void kvm_update_psr(struct kvm_vcpu *vcpu, unsigned long mode)
+{
+ unsigned long cpsr = *vcpu_cpsr(vcpu);
+ u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
+
+ *vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | mode;
+
+ switch (mode) {
+ case FIQ_MODE:
+ *vcpu_cpsr(vcpu) |= PSR_F_BIT;
+ /* Fall through */
+ case ABT_MODE:
+ case IRQ_MODE:
+ *vcpu_cpsr(vcpu) |= PSR_A_BIT;
+ /* Fall through */
+ default:
+ *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 the mode banked copies */
+ *vcpu_spsr(vcpu) = cpsr;
+}
+
/**
* kvm_inject_undefined - inject an undefined exception into the guest
* @vcpu: The VCPU to receive the undefined exception
@@ -286,29 +320,13 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
*/
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;
+ kvm_update_psr(vcpu, UND_MODE);
+ *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) - return_offset;
/* Branch to exception vector */
*vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
@@ -320,30 +338,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
*/
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;
+ kvm_update_psr(vcpu, ABT_MODE);
+ *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
if (is_pabt)
vect_offset = 12;
@@ -355,22 +357,22 @@ static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr)
if (is_pabt) {
/* Set IFAR and IFSR */
- vcpu->arch.cp15[c6_IFAR] = addr;
- is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31);
+ vcpu_cp15(vcpu, c6_IFAR) = addr;
+ is_lpae = (vcpu_cp15(vcpu, 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;
+ vcpu_cp15(vcpu, c5_IFSR) = 1 << 9 | 0x22;
else
- vcpu->arch.cp15[c5_IFSR] = 2;
+ vcpu_cp15(vcpu, c5_IFSR) = 2;
} else { /* !iabt */
/* Set DFAR and DFSR */
- vcpu->arch.cp15[c6_DFAR] = addr;
- is_lpae = (vcpu->arch.cp15[c2_TTBCR] >> 31);
+ vcpu_cp15(vcpu, c6_DFAR) = addr;
+ is_lpae = (vcpu_cp15(vcpu, 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;
+ vcpu_cp15(vcpu, c5_DFSR) = 1 << 9 | 0x22;
else
- vcpu->arch.cp15[c5_DFSR] = 2;
+ vcpu_cp15(vcpu, c5_DFSR) = 2;
}
}
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 96e935b..9093ed0 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -25,7 +25,6 @@
#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>
@@ -33,6 +32,12 @@
#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
struct kvm_stats_debugfs_item debugfs_entries[] = {
+ VCPU_STAT(hvc_exit_stat),
+ VCPU_STAT(wfe_exit_stat),
+ VCPU_STAT(wfi_exit_stat),
+ VCPU_STAT(mmio_exit_user),
+ VCPU_STAT(mmio_exit_kernel),
+ VCPU_STAT(exits),
{ NULL }
};
@@ -49,7 +54,7 @@ static u64 core_reg_offset_from_id(u64 id)
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;
+ struct kvm_regs *regs = &vcpu->arch.ctxt.gp_regs;
u64 off;
if (KVM_REG_SIZE(reg->id) != 4)
@@ -66,7 +71,7 @@ static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
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;
+ struct kvm_regs *regs = &vcpu->arch.ctxt.gp_regs;
u64 off, val;
if (KVM_REG_SIZE(reg->id) != 4)
@@ -155,7 +160,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
u64 val;
val = kvm_arm_timer_get_reg(vcpu, reg->id);
- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
+ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
}
static unsigned long num_core_regs(void)
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 95f12b2..3f1ef0d 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -42,6 +42,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
kvm_vcpu_hvc_get_imm(vcpu));
+ vcpu->stat.hvc_exit_stat++;
ret = kvm_psci_call(vcpu);
if (ret < 0) {
@@ -89,9 +90,11 @@ 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);
+ vcpu->stat.wfe_exit_stat++;
kvm_vcpu_on_spin(vcpu);
} else {
trace_kvm_wfx(*vcpu_pc(vcpu), false);
+ vcpu->stat.wfi_exit_stat++;
kvm_vcpu_block(vcpu);
}
@@ -144,13 +147,6 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
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
diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile
new file mode 100644
index 0000000..8dfa5f7
--- /dev/null
+++ b/arch/arm/kvm/hyp/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for Kernel-based Virtual Machine module, HYP part
+#
+
+KVM=../../../../virt/kvm
+
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
+
+obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
+obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
+obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += entry.o
+obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
+obj-$(CONFIG_KVM_ARM_HOST) += switch.o
+obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o
diff --git a/arch/arm/kvm/hyp/banked-sr.c b/arch/arm/kvm/hyp/banked-sr.c
new file mode 100644
index 0000000..111bda8
--- /dev/null
+++ b/arch/arm/kvm/hyp/banked-sr.c
@@ -0,0 +1,77 @@
+/*
+ * Original code:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * Mostly rewritten in C by 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 <asm/kvm_hyp.h>
+
+__asm__(".arch_extension virt");
+
+void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt)
+{
+ ctxt->gp_regs.usr_regs.ARM_sp = read_special(SP_usr);
+ ctxt->gp_regs.usr_regs.ARM_pc = read_special(ELR_hyp);
+ ctxt->gp_regs.usr_regs.ARM_cpsr = read_special(SPSR);
+ ctxt->gp_regs.KVM_ARM_SVC_sp = read_special(SP_svc);
+ ctxt->gp_regs.KVM_ARM_SVC_lr = read_special(LR_svc);
+ ctxt->gp_regs.KVM_ARM_SVC_spsr = read_special(SPSR_svc);
+ ctxt->gp_regs.KVM_ARM_ABT_sp = read_special(SP_abt);
+ ctxt->gp_regs.KVM_ARM_ABT_lr = read_special(LR_abt);
+ ctxt->gp_regs.KVM_ARM_ABT_spsr = read_special(SPSR_abt);
+ ctxt->gp_regs.KVM_ARM_UND_sp = read_special(SP_und);
+ ctxt->gp_regs.KVM_ARM_UND_lr = read_special(LR_und);
+ ctxt->gp_regs.KVM_ARM_UND_spsr = read_special(SPSR_und);
+ ctxt->gp_regs.KVM_ARM_IRQ_sp = read_special(SP_irq);
+ ctxt->gp_regs.KVM_ARM_IRQ_lr = read_special(LR_irq);
+ ctxt->gp_regs.KVM_ARM_IRQ_spsr = read_special(SPSR_irq);
+ ctxt->gp_regs.KVM_ARM_FIQ_r8 = read_special(R8_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_r9 = read_special(R9_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_r10 = read_special(R10_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_fp = read_special(R11_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_ip = read_special(R12_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_sp = read_special(SP_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_lr = read_special(LR_fiq);
+ ctxt->gp_regs.KVM_ARM_FIQ_spsr = read_special(SPSR_fiq);
+}
+
+void __hyp_text __banked_restore_state(struct kvm_cpu_context *ctxt)
+{
+ write_special(ctxt->gp_regs.usr_regs.ARM_sp, SP_usr);
+ write_special(ctxt->gp_regs.usr_regs.ARM_pc, ELR_hyp);
+ write_special(ctxt->gp_regs.usr_regs.ARM_cpsr, SPSR_cxsf);
+ write_special(ctxt->gp_regs.KVM_ARM_SVC_sp, SP_svc);
+ write_special(ctxt->gp_regs.KVM_ARM_SVC_lr, LR_svc);
+ write_special(ctxt->gp_regs.KVM_ARM_SVC_spsr, SPSR_svc);
+ write_special(ctxt->gp_regs.KVM_ARM_ABT_sp, SP_abt);
+ write_special(ctxt->gp_regs.KVM_ARM_ABT_lr, LR_abt);
+ write_special(ctxt->gp_regs.KVM_ARM_ABT_spsr, SPSR_abt);
+ write_special(ctxt->gp_regs.KVM_ARM_UND_sp, SP_und);
+ write_special(ctxt->gp_regs.KVM_ARM_UND_lr, LR_und);
+ write_special(ctxt->gp_regs.KVM_ARM_UND_spsr, SPSR_und);
+ write_special(ctxt->gp_regs.KVM_ARM_IRQ_sp, SP_irq);
+ write_special(ctxt->gp_regs.KVM_ARM_IRQ_lr, LR_irq);
+ write_special(ctxt->gp_regs.KVM_ARM_IRQ_spsr, SPSR_irq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_r8, R8_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_r9, R9_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_r10, R10_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_fp, R11_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_ip, R12_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_sp, SP_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_lr, LR_fiq);
+ write_special(ctxt->gp_regs.KVM_ARM_FIQ_spsr, SPSR_fiq);
+}
diff --git a/arch/arm/kvm/hyp/cp15-sr.c b/arch/arm/kvm/hyp/cp15-sr.c
new file mode 100644
index 0000000..c478281
--- /dev/null
+++ b/arch/arm/kvm/hyp/cp15-sr.c
@@ -0,0 +1,84 @@
+/*
+ * Original code:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * Mostly rewritten in C by 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 <asm/kvm_hyp.h>
+
+static u64 *cp15_64(struct kvm_cpu_context *ctxt, int idx)
+{
+ return (u64 *)(ctxt->cp15 + idx);
+}
+
+void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
+{
+ ctxt->cp15[c0_MPIDR] = read_sysreg(VMPIDR);
+ ctxt->cp15[c0_CSSELR] = read_sysreg(CSSELR);
+ ctxt->cp15[c1_SCTLR] = read_sysreg(SCTLR);
+ ctxt->cp15[c1_CPACR] = read_sysreg(CPACR);
+ *cp15_64(ctxt, c2_TTBR0) = read_sysreg(TTBR0);
+ *cp15_64(ctxt, c2_TTBR1) = read_sysreg(TTBR1);
+ ctxt->cp15[c2_TTBCR] = read_sysreg(TTBCR);
+ ctxt->cp15[c3_DACR] = read_sysreg(DACR);
+ ctxt->cp15[c5_DFSR] = read_sysreg(DFSR);
+ ctxt->cp15[c5_IFSR] = read_sysreg(IFSR);
+ ctxt->cp15[c5_ADFSR] = read_sysreg(ADFSR);
+ ctxt->cp15[c5_AIFSR] = read_sysreg(AIFSR);
+ ctxt->cp15[c6_DFAR] = read_sysreg(DFAR);
+ ctxt->cp15[c6_IFAR] = read_sysreg(IFAR);
+ *cp15_64(ctxt, c7_PAR) = read_sysreg(PAR);
+ ctxt->cp15[c10_PRRR] = read_sysreg(PRRR);
+ ctxt->cp15[c10_NMRR] = read_sysreg(NMRR);
+ ctxt->cp15[c10_AMAIR0] = read_sysreg(AMAIR0);
+ ctxt->cp15[c10_AMAIR1] = read_sysreg(AMAIR1);
+ ctxt->cp15[c12_VBAR] = read_sysreg(VBAR);
+ ctxt->cp15[c13_CID] = read_sysreg(CID);
+ ctxt->cp15[c13_TID_URW] = read_sysreg(TID_URW);
+ ctxt->cp15[c13_TID_URO] = read_sysreg(TID_URO);
+ ctxt->cp15[c13_TID_PRIV] = read_sysreg(TID_PRIV);
+ ctxt->cp15[c14_CNTKCTL] = read_sysreg(CNTKCTL);
+}
+
+void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
+{
+ write_sysreg(ctxt->cp15[c0_MPIDR], VMPIDR);
+ write_sysreg(ctxt->cp15[c0_CSSELR], CSSELR);
+ write_sysreg(ctxt->cp15[c1_SCTLR], SCTLR);
+ write_sysreg(ctxt->cp15[c1_CPACR], CPACR);
+ write_sysreg(*cp15_64(ctxt, c2_TTBR0), TTBR0);
+ write_sysreg(*cp15_64(ctxt, c2_TTBR1), TTBR1);
+ write_sysreg(ctxt->cp15[c2_TTBCR], TTBCR);
+ write_sysreg(ctxt->cp15[c3_DACR], DACR);
+ write_sysreg(ctxt->cp15[c5_DFSR], DFSR);
+ write_sysreg(ctxt->cp15[c5_IFSR], IFSR);
+ write_sysreg(ctxt->cp15[c5_ADFSR], ADFSR);
+ write_sysreg(ctxt->cp15[c5_AIFSR], AIFSR);
+ write_sysreg(ctxt->cp15[c6_DFAR], DFAR);
+ write_sysreg(ctxt->cp15[c6_IFAR], IFAR);
+ write_sysreg(*cp15_64(ctxt, c7_PAR), PAR);
+ write_sysreg(ctxt->cp15[c10_PRRR], PRRR);
+ write_sysreg(ctxt->cp15[c10_NMRR], NMRR);
+ write_sysreg(ctxt->cp15[c10_AMAIR0], AMAIR0);
+ write_sysreg(ctxt->cp15[c10_AMAIR1], AMAIR1);
+ write_sysreg(ctxt->cp15[c12_VBAR], VBAR);
+ write_sysreg(ctxt->cp15[c13_CID], CID);
+ write_sysreg(ctxt->cp15[c13_TID_URW], TID_URW);
+ write_sysreg(ctxt->cp15[c13_TID_URO], TID_URO);
+ write_sysreg(ctxt->cp15[c13_TID_PRIV], TID_PRIV);
+ write_sysreg(ctxt->cp15[c14_CNTKCTL], CNTKCTL);
+}
diff --git a/arch/arm/kvm/hyp/entry.S b/arch/arm/kvm/hyp/entry.S
new file mode 100644
index 0000000..21c2388
--- /dev/null
+++ b/arch/arm/kvm/hyp/entry.S
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 - 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/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/kvm_arm.h>
+
+ .arch_extension virt
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+#define USR_REGS_OFFSET (CPU_CTXT_GP_REGS + GP_REGS_USR)
+
+/* int __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host) */
+ENTRY(__guest_enter)
+ @ Save host registers
+ add r1, r1, #(USR_REGS_OFFSET + S_R4)
+ stm r1!, {r4-r12}
+ str lr, [r1, #4] @ Skip SP_usr (already saved)
+
+ @ Restore guest registers
+ add r0, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
+ ldr lr, [r0, #S_LR]
+ ldm r0, {r0-r12}
+
+ clrex
+ eret
+ENDPROC(__guest_enter)
+
+ENTRY(__guest_exit)
+ /*
+ * return convention:
+ * guest r0, r1, r2 saved on the stack
+ * r0: vcpu pointer
+ * r1: exception code
+ */
+
+ add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R3)
+ stm r2!, {r3-r12}
+ str lr, [r2, #4]
+ add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
+ pop {r3, r4, r5} @ r0, r1, r2
+ stm r2, {r3-r5}
+
+ ldr r0, [r0, #VCPU_HOST_CTXT]
+ add r0, r0, #(USR_REGS_OFFSET + S_R4)
+ ldm r0!, {r4-r12}
+ ldr lr, [r0, #4]
+
+ mov r0, r1
+ bx lr
+ENDPROC(__guest_exit)
+
+/*
+ * 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
+ENTRY(__vfp_guest_restore)
+ push {r3, r4, lr}
+
+ @ NEON/VFP used. Turn on VFP access.
+ mrc p15, 4, r1, c1, c1, 2 @ HCPTR
+ bic r1, r1, #(HCPTR_TCP(10) | HCPTR_TCP(11))
+ mcr p15, 4, r1, c1, c1, 2 @ HCPTR
+ isb
+
+ @ Switch VFP/NEON hardware state to the guest's
+ mov r4, r0
+ ldr r0, [r0, #VCPU_HOST_CTXT]
+ add r0, r0, #CPU_CTXT_VFP
+ bl __vfp_save_state
+ add r0, r4, #(VCPU_GUEST_CTXT + CPU_CTXT_VFP)
+ bl __vfp_restore_state
+
+ pop {r3, r4, lr}
+ pop {r0, r1, r2}
+ clrex
+ eret
+ENDPROC(__vfp_guest_restore)
+#endif
+
+ .popsection
+
diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
new file mode 100644
index 0000000..7809138
--- /dev/null
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -0,0 +1,169 @@
+/*
+ * 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/kvm_arm.h>
+#include <asm/kvm_asm.h>
+
+ .arch_extension virt
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+.macro load_vcpu reg
+ mrc p15, 4, \reg, c13, c0, 2 @ HTPIDR
+.endm
+
+/********************************************************************
+ * 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.
+ * - 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).
+ */
+
+ .align 5
+__kvm_hyp_vector:
+ .global __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
+
+.macro invalid_vector label, cause
+ .align
+\label: mov r0, #\cause
+ b __hyp_panic
+.endm
+
+ invalid_vector hyp_reset ARM_EXCEPTION_RESET
+ invalid_vector hyp_undef ARM_EXCEPTION_UNDEFINED
+ invalid_vector hyp_svc ARM_EXCEPTION_SOFTWARE
+ invalid_vector hyp_pabt ARM_EXCEPTION_PREF_ABORT
+ invalid_vector hyp_dabt ARM_EXCEPTION_DATA_ABORT
+ invalid_vector hyp_fiq ARM_EXCEPTION_FIQ
+
+ENTRY(__hyp_do_panic)
+ mrs lr, cpsr
+ bic lr, lr, #MODE_MASK
+ orr lr, lr, #SVC_MODE
+THUMB( orr lr, lr, #PSR_T_BIT )
+ msr spsr_cxsf, lr
+ ldr lr, =panic
+ msr ELR_hyp, lr
+ ldr lr, =kvm_call_hyp
+ clrex
+ eret
+ENDPROC(__hyp_do_panic)
+
+hyp_hvc:
+ /*
+ * Getting here is either because of a trap from a guest,
+ * or from executing HVC from the host kernel, which means
+ * "do something in Hyp mode".
+ */
+ push {r0, r1, r2}
+
+ @ Check syndrome register
+ mrc p15, 4, r1, c5, c2, 0 @ HSR
+ lsr r0, r1, #HSR_EC_SHIFT
+ 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
+
+ /*
+ * Getting here means host called HVC, we shift parameters and branch
+ * to Hyp function.
+ */
+ 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}
+
+ mov lr, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+
+THUMB( orr lr, #1)
+ blx lr @ Call the HYP function
+
+ pop {lr}
+1: eret
+
+guest_trap:
+ load_vcpu r0 @ Load VCPU pointer to r0
+
+#ifdef CONFIG_VFPv3
+ @ Check for a VFP access
+ lsr r1, r1, #HSR_EC_SHIFT
+ cmp r1, #HSR_EC_CP_0_13
+ beq __vfp_guest_restore
+#endif
+
+ mov r1, #ARM_EXCEPTION_HVC
+ b __guest_exit
+
+hyp_irq:
+ push {r0, r1, r2}
+ mov r1, #ARM_EXCEPTION_IRQ
+ load_vcpu r0 @ Load VCPU pointer to r0
+ b __guest_exit
+
+ .ltorg
+
+ .popsection
diff --git a/arch/arm/kvm/hyp/s2-setup.c b/arch/arm/kvm/hyp/s2-setup.c
new file mode 100644
index 0000000..7be39af
--- /dev/null
+++ b/arch/arm/kvm/hyp/s2-setup.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 - 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/types.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+void __hyp_text __init_stage2_translation(void)
+{
+ u64 val;
+
+ val = read_sysreg(VTCR) & ~VTCR_MASK;
+
+ val |= read_sysreg(HTCR) & VTCR_HTCR_SH;
+ val |= KVM_VTCR_SL0 | KVM_VTCR_T0SZ | KVM_VTCR_S;
+
+ write_sysreg(val, VTCR);
+}
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
new file mode 100644
index 0000000..b13caa9
--- /dev/null
+++ b/arch/arm/kvm/hyp/switch.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2015 - 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 <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+__asm__(".arch_extension virt");
+
+/*
+ * Activate the traps, saving the host's fpexc register before
+ * overwriting it. We'll restore it on VM exit.
+ */
+static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu, u32 *fpexc_host)
+{
+ u32 val;
+
+ /*
+ * We are about to set HCPTR.TCP10/11 to trap all floating point
+ * register accesses to HYP, however, the ARM ARM clearly states that
+ * traps are only taken to HYP if the operation would not otherwise
+ * trap to SVC. Therefore, always make sure that for 32-bit guests,
+ * we set FPEXC.EN to prevent traps to SVC, when setting the TCP bits.
+ */
+ val = read_sysreg(VFP_FPEXC);
+ *fpexc_host = val;
+ if (!(val & FPEXC_EN)) {
+ write_sysreg(val | FPEXC_EN, VFP_FPEXC);
+ isb();
+ }
+
+ write_sysreg(vcpu->arch.hcr | vcpu->arch.irq_lines, HCR);
+ /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
+ write_sysreg(HSTR_T(15), HSTR);
+ write_sysreg(HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11), HCPTR);
+ val = read_sysreg(HDCR);
+ write_sysreg(val | HDCR_TPM | HDCR_TPMCR, HDCR);
+}
+
+static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
+{
+ u32 val;
+
+ write_sysreg(0, HCR);
+ write_sysreg(0, HSTR);
+ val = read_sysreg(HDCR);
+ write_sysreg(val & ~(HDCR_TPM | HDCR_TPMCR), HDCR);
+ write_sysreg(0, HCPTR);
+}
+
+static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = kern_hyp_va(vcpu->kvm);
+ write_sysreg(kvm->arch.vttbr, VTTBR);
+ write_sysreg(vcpu->arch.midr, VPIDR);
+}
+
+static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
+{
+ write_sysreg(0, VTTBR);
+ write_sysreg(read_sysreg(MIDR), VPIDR);
+}
+
+static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
+{
+ __vgic_v2_save_state(vcpu);
+}
+
+static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
+{
+ __vgic_v2_restore_state(vcpu);
+}
+
+static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
+{
+ u32 hsr = read_sysreg(HSR);
+ u8 ec = hsr >> HSR_EC_SHIFT;
+ u32 hpfar, far;
+
+ vcpu->arch.fault.hsr = hsr;
+
+ if (ec == HSR_EC_IABT)
+ far = read_sysreg(HIFAR);
+ else if (ec == HSR_EC_DABT)
+ far = read_sysreg(HDFAR);
+ else
+ return true;
+
+ /*
+ * 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.
+ */
+ if (!(hsr & HSR_DABT_S1PTW) && (hsr & HSR_FSC_TYPE) == FSC_PERM) {
+ u64 par, tmp;
+
+ par = read_sysreg(PAR);
+ write_sysreg(far, ATS1CPR);
+ isb();
+
+ tmp = read_sysreg(PAR);
+ write_sysreg(par, PAR);
+
+ if (unlikely(tmp & 1))
+ return false; /* Translation failed, back to guest */
+
+ hpfar = ((tmp >> 12) & ((1UL << 28) - 1)) << 4;
+ } else {
+ hpfar = read_sysreg(HPFAR);
+ }
+
+ vcpu->arch.fault.hxfar = far;
+ vcpu->arch.fault.hpfar = hpfar;
+ return true;
+}
+
+static int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ bool fp_enabled;
+ u64 exit_code;
+ u32 fpexc;
+
+ vcpu = kern_hyp_va(vcpu);
+ write_sysreg(vcpu, HTPIDR);
+
+ host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ guest_ctxt = &vcpu->arch.ctxt;
+
+ __sysreg_save_state(host_ctxt);
+ __banked_save_state(host_ctxt);
+
+ __activate_traps(vcpu, &fpexc);
+ __activate_vm(vcpu);
+
+ __vgic_restore_state(vcpu);
+ __timer_restore_state(vcpu);
+
+ __sysreg_restore_state(guest_ctxt);
+ __banked_restore_state(guest_ctxt);
+
+ /* Jump in the fire! */
+again:
+ exit_code = __guest_enter(vcpu, host_ctxt);
+ /* And we're baaack! */
+
+ if (exit_code == ARM_EXCEPTION_HVC && !__populate_fault_info(vcpu))
+ goto again;
+
+ fp_enabled = __vfp_enabled();
+
+ __banked_save_state(guest_ctxt);
+ __sysreg_save_state(guest_ctxt);
+ __timer_save_state(vcpu);
+ __vgic_save_state(vcpu);
+
+ __deactivate_traps(vcpu);
+ __deactivate_vm(vcpu);
+
+ __banked_restore_state(host_ctxt);
+ __sysreg_restore_state(host_ctxt);
+
+ if (fp_enabled) {
+ __vfp_save_state(&guest_ctxt->vfp);
+ __vfp_restore_state(&host_ctxt->vfp);
+ }
+
+ write_sysreg(fpexc, VFP_FPEXC);
+
+ return exit_code;
+}
+
+__alias(__guest_run) int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+
+static const char * const __hyp_panic_string[] = {
+ [ARM_EXCEPTION_RESET] = "\nHYP panic: RST PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_UNDEFINED] = "\nHYP panic: UNDEF PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_SOFTWARE] = "\nHYP panic: SVC PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_PREF_ABORT] = "\nHYP panic: PABRT PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_DATA_ABORT] = "\nHYP panic: DABRT PC:%08x ADDR:%08x",
+ [ARM_EXCEPTION_IRQ] = "\nHYP panic: IRQ PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_FIQ] = "\nHYP panic: FIQ PC:%08x CPSR:%08x",
+ [ARM_EXCEPTION_HVC] = "\nHYP panic: HVC PC:%08x CPSR:%08x",
+};
+
+void __hyp_text __noreturn __hyp_panic(int cause)
+{
+ u32 elr = read_special(ELR_hyp);
+ u32 val;
+
+ if (cause == ARM_EXCEPTION_DATA_ABORT)
+ val = read_sysreg(HDFAR);
+ else
+ val = read_special(SPSR);
+
+ if (read_sysreg(VTTBR)) {
+ struct kvm_vcpu *vcpu;
+ struct kvm_cpu_context *host_ctxt;
+
+ vcpu = (struct kvm_vcpu *)read_sysreg(HTPIDR);
+ host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ __deactivate_traps(vcpu);
+ __deactivate_vm(vcpu);
+ __sysreg_restore_state(host_ctxt);
+ }
+
+ /* Call panic for real */
+ __hyp_do_panic(__hyp_panic_string[cause], elr, val);
+
+ unreachable();
+}
diff --git a/arch/arm/kvm/hyp/tlb.c b/arch/arm/kvm/hyp/tlb.c
new file mode 100644
index 0000000..a263600
--- /dev/null
+++ b/arch/arm/kvm/hyp/tlb.c
@@ -0,0 +1,70 @@
+/*
+ * Original code:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * Mostly rewritten in C by 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 <asm/kvm_hyp.h>
+
+/**
+ * Flush per-VMID TLBs
+ *
+ * __kvm_tlb_flush_vmid(struct kvm *kvm);
+ *
+ * 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.
+ */
+static void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
+{
+ dsb(ishst);
+
+ /* Switch to requested VMID */
+ kvm = kern_hyp_va(kvm);
+ write_sysreg(kvm->arch.vttbr, VTTBR);
+ isb();
+
+ write_sysreg(0, TLBIALLIS);
+ dsb(ish);
+ isb();
+
+ write_sysreg(0, VTTBR);
+}
+
+__alias(__tlb_flush_vmid) void __kvm_tlb_flush_vmid(struct kvm *kvm);
+
+static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
+{
+ __tlb_flush_vmid(kvm);
+}
+
+__alias(__tlb_flush_vmid_ipa) void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm,
+ phys_addr_t ipa);
+
+static void __hyp_text __tlb_flush_vm_context(void)
+{
+ write_sysreg(0, TLBIALLNSNHIS);
+ write_sysreg(0, ICIALLUIS);
+ dsb(ish);
+}
+
+__alias(__tlb_flush_vm_context) void __kvm_flush_vm_context(void);
diff --git a/arch/arm/kvm/hyp/vfp.S b/arch/arm/kvm/hyp/vfp.S
new file mode 100644
index 0000000..7c297e8
--- /dev/null
+++ b/arch/arm/kvm/hyp/vfp.S
@@ -0,0 +1,68 @@
+/*
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/vfpmacros.h>
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+/* void __vfp_save_state(struct vfp_hard_struct *vfp); */
+ENTRY(__vfp_save_state)
+ push {r4, r5}
+ VFPFMRX r1, FPEXC
+
+ @ Make sure *really* VFP is enabled so we can touch the registers.
+ orr r5, r1, #FPEXC_EN
+ tst r5, #FPEXC_EX @ Check for VFP Subarchitecture
+ bic r5, r5, #FPEXC_EX @ FPEXC_EX disable
+ VFPFMXR FPEXC, r5
+ isb
+
+ VFPFMRX r2, FPSCR
+ 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 r3, FPINST
+ tst r5, #FPEXC_FP2V
+ VFPFMRX r4, FPINST2, ne @ vmrsne
+1:
+ VFPFSTMIA r0, r5 @ Save VFP registers
+ stm r0, {r1-r4} @ Save FPEXC, FPSCR, FPINST, FPINST2
+ pop {r4, r5}
+ bx lr
+ENDPROC(__vfp_save_state)
+
+/* void __vfp_restore_state(struct vfp_hard_struct *vfp);
+ * Assume FPEXC_EN is on and FPEXC_EX is off */
+ENTRY(__vfp_restore_state)
+ VFPFLDMIA r0, r1 @ Load VFP registers
+ ldm r0, {r0-r3} @ Load FPEXC, FPSCR, FPINST, FPINST2
+
+ VFPFMXR FPSCR, r1
+ tst r0, #FPEXC_EX @ Check for VFP Subarchitecture
+ beq 1f
+ VFPFMXR FPINST, r2
+ tst r0, #FPEXC_FP2V
+ VFPFMXR FPINST2, r3, ne
+1:
+ VFPFMXR FPEXC, r0 @ FPEXC (last, in case !EN)
+ bx lr
+ENDPROC(__vfp_restore_state)
+
+ .popsection
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 3988e72..1f9ae17 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -84,14 +84,6 @@ __do_hyp_init:
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
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 900ef6d..b1bd316 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -17,211 +17,14 @@
*/
#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, ...);
+ * unsigned long 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
@@ -232,7 +35,7 @@ after_vfp_restore:
* 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.
+ * passed in r0 (strictly 32bit).
*
* 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
@@ -246,281 +49,4 @@ after_vfp_restore:
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, =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
- 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
-
- /*
- * Getting here means host called HVC, we shift parameters and branch
- * to Hyp function.
- */
- 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
-#ifdef CONFIG_VFPv3
- cmp r1, #HSR_EC_CP_0_13
- beq switch_to_guest_vfp
-#endif
- 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:
- 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"
+ENDPROC(kvm_call_hyp)
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
deleted file mode 100644
index 51a5950..0000000
--- a/arch/arm/kvm/interrupts_head.S
+++ /dev/null
@@ -1,648 +0,0 @@
-#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 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 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 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]
-
- 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:
- mov r2, #0 @ Clear ENABLE
- mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
-
- @ 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
index 974b1c6..0f6600f 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -115,7 +115,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
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;
+ vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data);
}
return 0;
@@ -186,7 +186,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
rt = vcpu->arch.mmio_decode.rt;
if (is_write) {
- data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len);
+ data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
+ len);
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data);
mmio_write_buf(data_buf, len, data);
@@ -205,12 +206,16 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
run->mmio.is_write = is_write;
run->mmio.phys_addr = fault_ipa;
run->mmio.len = len;
- memcpy(run->mmio.data, data_buf, len);
+ if (is_write)
+ memcpy(run->mmio.data, data_buf, len);
if (!ret) {
/* We handled the access successfully in the kernel. */
+ vcpu->stat.mmio_exit_kernel++;
kvm_handle_mmio_return(vcpu, run);
return 1;
+ } else {
+ vcpu->stat.mmio_exit_user++;
}
run->exit_reason = KVM_EXIT_MMIO;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 6984342..58dbd5c 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -28,6 +28,7 @@
#include <asm/kvm_mmio.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_emulate.h>
+#include <asm/virt.h>
#include "trace.h"
@@ -98,6 +99,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
__kvm_flush_dcache_pud(pud);
}
+static bool kvm_is_device_pfn(unsigned long pfn)
+{
+ return !pfn_valid(pfn);
+}
+
/**
* stage2_dissolve_pmd() - clear and flush huge PMD entry
* @kvm: pointer to kvm structure.
@@ -213,7 +219,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
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)
+ if (!kvm_is_device_pfn(pte_pfn(old_pte)))
kvm_flush_dcache_pte(old_pte);
put_page(virt_to_page(pte));
@@ -305,8 +311,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
pte = pte_offset_kernel(pmd, addr);
do {
- if (!pte_none(*pte) &&
- (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+ if (!pte_none(*pte) && !kvm_is_device_pfn(pte_pfn(*pte)))
kvm_flush_dcache_pte(*pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
}
@@ -594,6 +599,9 @@ int create_hyp_mappings(void *from, void *to)
unsigned long start = KERN_TO_HYP((unsigned long)from);
unsigned long end = KERN_TO_HYP((unsigned long)to);
+ if (is_kernel_in_hyp_mode())
+ return 0;
+
start = start & PAGE_MASK;
end = PAGE_ALIGN(end);
@@ -626,6 +634,9 @@ 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);
+ if (is_kernel_in_hyp_mode())
+ return 0;
+
/* Check for a valid kernel IO mapping */
if (!is_vmalloc_addr(from) || !is_vmalloc_addr(to - 1))
return -EINVAL;
@@ -652,9 +663,9 @@ static void *kvm_alloc_hwpgd(void)
* 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.
+ * Allocates only the stage-2 HW PGD level table(s) (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.
@@ -988,9 +999,9 @@ out:
return ret;
}
-static bool transparent_hugepage_adjust(pfn_t *pfnp, phys_addr_t *ipap)
+static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
{
- pfn_t pfn = *pfnp;
+ kvm_pfn_t pfn = *pfnp;
gfn_t gfn = *ipap >> PAGE_SHIFT;
if (PageTransCompound(pfn_to_page(pfn))) {
@@ -1037,11 +1048,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
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
@@ -1202,7 +1208,7 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
}
-static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, kvm_pfn_t pfn,
unsigned long size, bool uncached)
{
__coherent_cache_guest_page(vcpu, pfn, size, uncached);
@@ -1219,7 +1225,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
struct vm_area_struct *vma;
- pfn_t pfn;
+ kvm_pfn_t pfn;
pgprot_t mem_type = PAGE_S2;
bool fault_ipa_uncached;
bool logging_active = memslot_is_logging(memslot);
@@ -1347,7 +1353,7 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
{
pmd_t *pmd;
pte_t *pte;
- pfn_t pfn;
+ kvm_pfn_t pfn;
bool pfn_valid = false;
trace_kvm_access_fault(fault_ipa);
@@ -1432,6 +1438,22 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
}
/*
+ * Check for a cache maintenance operation. Since we
+ * ended-up here, we know it is outside of any memory
+ * slot. But we can't find out if that is for a device,
+ * or if the guest is just being stupid. The only thing
+ * we know for sure is that this range cannot be cached.
+ *
+ * So let's assume that the guest is just being
+ * cautious, and skip the instruction.
+ */
+ if (kvm_vcpu_dabt_is_cm(vcpu)) {
+ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(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
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index ad6f642..c2b1315 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -63,19 +63,19 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
{
- vcpu->arch.pause = true;
+ vcpu->arch.power_off = 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;
+ struct swait_queue_head *wq;
unsigned long cpu_id;
unsigned long context_id;
phys_addr_t target_pc;
- cpu_id = *vcpu_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
+ cpu_id = vcpu_get_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
if (vcpu_mode_is_32bit(source_vcpu))
cpu_id &= ~((u32) 0);
@@ -87,15 +87,15 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
*/
if (!vcpu)
return PSCI_RET_INVALID_PARAMS;
- if (!vcpu->arch.pause) {
+ if (!vcpu->arch.power_off) {
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);
+ target_pc = vcpu_get_reg(source_vcpu, 2);
+ context_id = vcpu_get_reg(source_vcpu, 3);
kvm_reset_vcpu(vcpu);
@@ -114,12 +114,12 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
* 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;
+ vcpu_set_reg(vcpu, 0, context_id);
+ vcpu->arch.power_off = false;
smp_mb(); /* Make sure the above is visible */
wq = kvm_arch_vcpu_wq(vcpu);
- wake_up_interruptible(wq);
+ swake_up(wq);
return PSCI_RET_SUCCESS;
}
@@ -134,8 +134,8 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
struct kvm *kvm = vcpu->kvm;
struct kvm_vcpu *tmp;
- target_affinity = *vcpu_reg(vcpu, 1);
- lowest_affinity_level = *vcpu_reg(vcpu, 2);
+ target_affinity = vcpu_get_reg(vcpu, 1);
+ lowest_affinity_level = vcpu_get_reg(vcpu, 2);
/* Determine target affinity mask */
target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
@@ -153,7 +153,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
mpidr = kvm_vcpu_get_mpidr_aff(tmp);
if ((mpidr & target_affinity_mask) == target_affinity) {
matching_cpus++;
- if (!tmp->arch.pause)
+ if (!tmp->arch.power_off)
return PSCI_0_2_AFFINITY_LEVEL_ON;
}
}
@@ -179,7 +179,7 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
* re-initialized.
*/
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
- tmp->arch.pause = true;
+ tmp->arch.power_off = true;
kvm_vcpu_kick(tmp);
}
@@ -209,7 +209,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
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 psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
switch (psci_fn) {
@@ -273,13 +273,13 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
break;
}
- *vcpu_reg(vcpu, 0) = val;
+ vcpu_set_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 psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
switch (psci_fn) {
@@ -295,7 +295,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
break;
}
- *vcpu_reg(vcpu, 0) = val;
+ vcpu_set_reg(vcpu, 0, val);
return 1;
}
diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
index eeb8585..0048b5a 100644
--- a/arch/arm/kvm/reset.c
+++ b/arch/arm/kvm/reset.c
@@ -71,7 +71,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
}
/* Reset core registers */
- memcpy(&vcpu->arch.regs, reset_regs, sizeof(vcpu->arch.regs));
+ memcpy(&vcpu->arch.ctxt.gp_regs, reset_regs, sizeof(vcpu->arch.ctxt.gp_regs));
/* Reset CP15 registers */
kvm_reset_coprocs(vcpu);
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index 0ec3539..c25a885 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -25,21 +25,25 @@ TRACE_EVENT(kvm_entry,
);
TRACE_EVENT(kvm_exit,
- TP_PROTO(unsigned int exit_reason, unsigned long vcpu_pc),
- TP_ARGS(exit_reason, vcpu_pc),
+ TP_PROTO(int idx, unsigned int exit_reason, unsigned long vcpu_pc),
+ TP_ARGS(idx, exit_reason, vcpu_pc),
TP_STRUCT__entry(
+ __field( int, idx )
__field( unsigned int, exit_reason )
__field( unsigned long, vcpu_pc )
),
TP_fast_assign(
+ __entry->idx = idx;
__entry->exit_reason = exit_reason;
__entry->vcpu_pc = vcpu_pc;
),
- TP_printk("HSR_EC: 0x%04x, PC: 0x%08lx",
+ TP_printk("%s: HSR_EC: 0x%04x (%s), PC: 0x%08lx",
+ __print_symbolic(__entry->idx, kvm_arm_exception_type),
__entry->exit_reason,
+ __print_symbolic(__entry->exit_reason, kvm_arm_exception_class),
__entry->vcpu_pc)
);
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 970d6c0..e936352 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -9,6 +9,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/unwind.h>
.text
@@ -20,6 +21,8 @@
*/
ENTRY(__clear_user_std)
WEAK(arm_clear_user)
+UNWIND(.fnstart)
+UNWIND(.save {r1, lr})
stmfd sp!, {r1, lr}
mov r2, #0
cmp r1, #4
@@ -44,6 +47,7 @@ WEAK(arm_clear_user)
USER( strnebt r2, [r0])
mov r0, #0
ldmfd sp!, {r1, pc}
+UNWIND(.fnend)
ENDPROC(arm_clear_user)
ENDPROC(__clear_user_std)
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index af2267f..9397b2e 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -205,6 +205,10 @@ Boston, MA 02111-1307, USA. */
.endm
+#ifdef CONFIG_ARM_PATCH_IDIV
+ .align 3
+#endif
+
ENTRY(__udivsi3)
ENTRY(__aeabi_uidiv)
UNWIND(.fnstart)
@@ -253,6 +257,10 @@ UNWIND(.fnstart)
UNWIND(.fnend)
ENDPROC(__umodsi3)
+#ifdef CONFIG_ARM_PATCH_IDIV
+ .align 3
+#endif
+
ENTRY(__divsi3)
ENTRY(__aeabi_idiv)
UNWIND(.fnstart)
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index d72b909..6bd1089 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -52,14 +52,13 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
*
* 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.
+ * need to fault on write.
*/
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))) {
+ || pmd_hugewillfault(*pmd))) {
spin_unlock(ptl);
return 0;
}
@@ -88,6 +87,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
static unsigned long noinline
__copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
{
+ unsigned long ua_flags;
int atomic;
if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
@@ -118,7 +118,9 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
if (tocopy > n)
tocopy = n;
+ ua_flags = uaccess_save_and_enable();
memcpy((void *)to, from, tocopy);
+ uaccess_restore(ua_flags);
to += tocopy;
from += tocopy;
n -= tocopy;
@@ -145,14 +147,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
* 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);
+ if (n < 64) {
+ unsigned long ua_flags = uaccess_save_and_enable();
+ n = __copy_to_user_std(to, from, n);
+ uaccess_restore(ua_flags);
+ } else {
+ n = __copy_to_user_memcpy(to, from, n);
+ }
+ return n;
}
static unsigned long noinline
__clear_user_memset(void __user *addr, unsigned long n)
{
+ unsigned long ua_flags;
+
if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
memset((void *)addr, 0, n);
return 0;
@@ -175,7 +184,9 @@ __clear_user_memset(void __user *addr, unsigned long n)
if (tocopy > n)
tocopy = n;
+ ua_flags = uaccess_save_and_enable();
memset((void *)addr, 0, tocopy);
+ uaccess_restore(ua_flags);
addr += tocopy;
n -= tocopy;
@@ -193,9 +204,14 @@ out:
unsigned long arm_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 (n < 64) {
+ unsigned long ua_flags = uaccess_save_and_enable();
+ n = __clear_user_std(addr, n);
+ uaccess_restore(ua_flags);
+ } else {
+ n = __clear_user_memset(addr, n);
+ }
+ return n;
}
#if 0
diff --git a/arch/arm/mach-alpine/Kconfig b/arch/arm/mach-alpine/Kconfig
index 2c44b93..5c2d54f 100644
--- a/arch/arm/mach-alpine/Kconfig
+++ b/arch/arm/mach-alpine/Kconfig
@@ -1,5 +1,6 @@
config ARCH_ALPINE
- bool "Annapurna Labs Alpine platform" if ARCH_MULTI_V7
+ bool "Annapurna Labs Alpine platform"
+ depends on ARCH_MULTI_V7
select ARM_AMBA
select ARM_GIC
select GENERIC_IRQ_CHIP
diff --git a/arch/arm/mach-alpine/platsmp.c b/arch/arm/mach-alpine/platsmp.c
index f78429f..dd77ea2 100644
--- a/arch/arm/mach-alpine/platsmp.c
+++ b/arch/arm/mach-alpine/platsmp.c
@@ -42,7 +42,7 @@ static void __init alpine_smp_prepare_cpus(unsigned int max_cpus)
alpine_cpu_pm_init();
}
-static struct smp_operations alpine_smp_ops __initdata = {
+static const struct smp_operations alpine_smp_ops __initconst = {
.smp_prepare_cpus = alpine_smp_prepare_cpus,
.smp_boot_secondary = alpine_boot_secondary,
};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 89a755b..23be2e4 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -4,12 +4,12 @@ menuconfig ARCH_AT91
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLK_AT91
select PINCTRL
- select PINCTRL_AT91
select SOC_BUS
if ARCH_AT91
config SOC_SAMA5D2
- bool "SAMA5D2 family" if ARCH_MULTI_V7
+ bool "SAMA5D2 family"
+ depends on ARCH_MULTI_V7
select SOC_SAMA5
select CACHE_L2X0
select HAVE_FB_ATMEL
@@ -17,22 +17,26 @@ config SOC_SAMA5D2
select HAVE_AT91_USB_CLK
select HAVE_AT91_H32MX
select HAVE_AT91_GENERATED_CLK
+ select PINCTRL_AT91PIO4
help
Select this if ou are using one of Atmel's SAMA5D2 family SoC.
config SOC_SAMA5D3
- bool "SAMA5D3 family" if ARCH_MULTI_V7
+ bool "SAMA5D3 family"
+ depends on ARCH_MULTI_V7
select SOC_SAMA5
select HAVE_FB_ATMEL
select HAVE_AT91_UTMI
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
+ select PINCTRL_AT91
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
+ bool "SAMA5D4 family"
+ depends on ARCH_MULTI_V7
select SOC_SAMA5
select CACHE_L2X0
select HAVE_FB_ATMEL
@@ -40,23 +44,27 @@ config SOC_SAMA5D4
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
select HAVE_AT91_H32MX
+ select PINCTRL_AT91
help
Select this if you are using one of Atmel's SAMA5D4 family SoC.
config SOC_AT91RM9200
- bool "AT91RM9200" if ARCH_MULTI_V4T
+ bool "AT91RM9200"
+ depends on ARCH_MULTI_V4T
select ATMEL_AIC_IRQ
select ATMEL_ST
select CPU_ARM920T
select HAVE_AT91_USB_CLK
select MIGHT_HAVE_PCI
+ select PINCTRL_AT91
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
+ bool "AT91SAM9"
+ depends on ARCH_MULTI_V5
select ATMEL_AIC_IRQ
select ATMEL_SDRAMC
select CPU_ARM926T
@@ -65,6 +73,7 @@ config SOC_AT91SAM9
select HAVE_AT91_UTMI
select HAVE_FB_ATMEL
select MEMORY
+ select PINCTRL_AT91
select SOC_SAM_V4_V5
select SRAM if PM
help
@@ -102,6 +111,9 @@ config HAVE_AT91_SMD
config HAVE_AT91_H32MX
bool
+config HAVE_AT91_GENERATED_CLK
+ bool
+
config SOC_SAM_V4_V5
bool
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 80e277c..23726fb 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -41,8 +41,10 @@
* implementation should be moved down into the pinctrl driver and get
* called as part of the generic suspend/resume path.
*/
+#ifdef CONFIG_PINCTRL_AT91
extern void at91_pinctrl_gpio_suspend(void);
extern void at91_pinctrl_gpio_resume(void);
+#endif
static struct {
unsigned long uhp_udp_mask;
@@ -151,8 +153,9 @@ static void at91_pm_suspend(suspend_state_t state)
static int at91_pm_enter(suspend_state_t state)
{
+#ifdef CONFIG_PINCTRL_AT91
at91_pinctrl_gpio_suspend();
-
+#endif
switch (state) {
/*
* Suspend-to-RAM is like STANDBY plus slow clock mode, so
@@ -192,7 +195,9 @@ static int at91_pm_enter(suspend_state_t state)
error:
target_state = PM_SUSPEND_ON;
+#ifdef CONFIG_PINCTRL_AT91
at91_pinctrl_gpio_resume();
+#endif
return 0;
}
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 0d95f48..a25defd 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -80,6 +80,8 @@ tmp2 .req r5
* @r2: base address of second SDRAM Controller or 0 if not present
* @r3: pm information
*/
+/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
+ .align 3
ENTRY(at91_pm_suspend_in_sram)
/* Save registers on stack */
stmfd sp!, {r4 - r12, lr}
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
index 8be7e0a..6c6d5e7 100644
--- a/arch/arm/mach-axxia/Kconfig
+++ b/arch/arm/mach-axxia/Kconfig
@@ -1,5 +1,6 @@
config ARCH_AXXIA
- bool "LSI Axxia platforms" if (ARCH_MULTI_V7 && ARM_LPAE)
+ bool "LSI Axxia platforms"
+ depends on ARCH_MULTI_V7 && ARM_LPAE
select ARCH_DMA_ADDR_T_64BIT
select ARM_AMBA
select ARM_GIC
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index 959d4df..ffbd71d 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -82,7 +82,7 @@ static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
}
}
-static struct smp_operations axxia_smp_ops __initdata = {
+static const struct smp_operations axxia_smp_ops __initconst = {
.smp_prepare_cpus = axxia_smp_prepare_cpus,
.smp_boot_secondary = axxia_boot_secondary,
};
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 1319c3c..7ef1214 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_BCM
- bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7
+ bool "Broadcom SoC Support"
+ depends on ARCH_MULTI_V6_V7
help
This enables support for Broadcom ARM based SoC chips
@@ -14,7 +15,7 @@ config ARCH_BCM_IPROC
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GLOBAL_TIMER
-
+ select COMMON_CLK_IPROC
select CLKSRC_MMIO
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
@@ -27,7 +28,8 @@ config ARCH_BCM_IPROC
Currently supported SoCs are Cygnus.
config ARCH_BCM_CYGNUS
- bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
+ bool "Broadcom Cygnus Support"
+ depends on ARCH_MULTI_V7
select ARCH_BCM_IPROC
help
Enable support for the Cygnus family,
@@ -35,9 +37,32 @@ config ARCH_BCM_CYGNUS
BCM11300, BCM11320, BCM11350, BCM11360,
BCM58300, BCM58302, BCM58303, BCM58305.
+config ARCH_BCM_NSP
+ bool "Broadcom Northstar Plus SoC Support"
+ depends on ARCH_MULTI_V7
+ select ARCH_BCM_IPROC
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+ select ARM_ERRATA_764369 if SMP
+ select HAVE_SMP
+ help
+ Support for Broadcom Northstar Plus SoC.
+ Broadcom Northstar Plus family of SoCs are used for switching control
+ and management applications as well as residential router/gateway
+ applications. The SoC features dual core Cortex A9 ARM CPUs,
+ integrating several peripheral interfaces including multiple Gigabit
+ Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and
+ NAND flash, SATA and several other IO controllers.
+
config ARCH_BCM_5301X
- bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
+ bool "Broadcom BCM470X / BCM5301X ARM SoC"
+ depends on ARCH_MULTI_V7
select ARCH_BCM_IPROC
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+ select ARM_ERRATA_764369 if SMP
+ select HAVE_SMP
+
help
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
@@ -68,7 +93,8 @@ config ARCH_BCM_MOBILE
This enables support for systems based on Broadcom mobile SoCs.
config ARCH_BCM_281XX
- bool "Broadcom BCM281XX SoC family" if ARCH_MULTI_V7
+ bool "Broadcom BCM281XX SoC family"
+ depends on ARCH_MULTI_V7
select ARCH_BCM_MOBILE
select HAVE_SMP
help
@@ -77,7 +103,8 @@ config ARCH_BCM_281XX
variants.
config ARCH_BCM_21664
- bool "Broadcom BCM21664 SoC family" if ARCH_MULTI_V7
+ bool "Broadcom BCM21664 SoC family"
+ depends on ARCH_MULTI_V7
select ARCH_BCM_MOBILE
select HAVE_SMP
help
@@ -108,20 +135,23 @@ config ARCH_BCM_MOBILE_SMP
comment "Other Architectures"
config ARCH_BCM2835
- bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
+ bool "Broadcom BCM2835 family"
+ depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
- select ARM_ERRATA_411920
+ select ARM_ERRATA_411920 if ARCH_MULTI_V6
select ARM_TIMER_SP804
+ select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
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.
+ This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
+ 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
+ bool "Broadcom BCM63xx DSL SoC"
+ depends on ARCH_MULTI_V7
depends on MMU
select ARM_ERRATA_754322
select ARM_ERRATA_764369 if SMP
@@ -138,7 +168,8 @@ config ARCH_BCM_63XX
the BCM63138 variant.
config ARCH_BRCMSTB
- bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
+ bool "Broadcom BCM7XXX based boards"
+ depends on ARCH_MULTI_V7
select ARM_GIC
select ARM_ERRATA_798181 if SMP
select HAVE_ARM_ARCH_TIMER
@@ -147,6 +178,7 @@ config ARCH_BRCMSTB
select BCM7120_L2_IRQ
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select SOC_BRCMSTB
help
Say Y if you intend to run the kernel on a Broadcom ARM-based STB
chipset.
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 1780a3f..7d66515 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2012-2014 Broadcom Corporation
+# Copyright (C) 2012-2015 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
@@ -13,6 +13,13 @@
# Cygnus
obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
+# Northstar Plus
+obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+
+ifeq ($(CONFIG_ARCH_BCM_NSP),y)
+obj-$(CONFIG_SMP) += platsmp.o
+endif
+
# BCM281XX
obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
@@ -20,7 +27,7 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
# BCM281XX and BCM21664 SMP support
-obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o
# BCM281XX and BCM21664 L2 cache control
obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
@@ -36,6 +43,9 @@ obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
# BCM5301X
obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
+obj-$(CONFIG_SMP) += platsmp.o
+endif
# BCM63XXx
ifeq ($(CONFIG_ARCH_BCM_63XX),y)
diff --git a/arch/arm/mach-bcm/bcm63xx_smp.c b/arch/arm/mach-bcm/bcm63xx_smp.c
index 19be904..9b6727e 100644
--- a/arch/arm/mach-bcm/bcm63xx_smp.c
+++ b/arch/arm/mach-bcm/bcm63xx_smp.c
@@ -161,7 +161,7 @@ static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
}
}
-struct smp_operations bcm63138_smp_ops __initdata = {
+static const struct smp_operations bcm63138_smp_ops __initconst = {
.smp_prepare_cpus = bcm63138_smp_prepare_cpus,
.smp_boot_secondary = bcm63138_smp_boot_secondary,
};
diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c
index 5478fe6..c8830a2 100644
--- a/arch/arm/mach-bcm/bcm_5301x.c
+++ b/arch/arm/mach-bcm/bcm_5301x.c
@@ -9,40 +9,6 @@
#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 == 0x1406 || fsr == 0x1c06) && first_fault) {
- first_fault = false;
-
- /*
- * These faults with codes 0x1406 (BCM4709) or 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 *const bcm5301x_dt_compat[] __initconst = {
"brcm,bcm4708",
@@ -52,6 +18,5 @@ static const char *const bcm5301x_dt_compat[] __initconst = {
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_nsp.c b/arch/arm/mach-bcm/bcm_nsp.c
new file mode 100644
index 0000000..a1101a3
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_nsp.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 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_nsp_dt_compat[] __initconst = {
+ "brcm,nsp",
+ NULL,
+};
+
+DT_MACHINE_START(NSP_DT, "Broadcom Northstar Plus SoC")
+ .l2c_aux_val = 0,
+ .l2c_aux_mask = ~0,
+ .dt_compat = bcm_nsp_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
index 0f7b9ea..834d676 100644
--- a/arch/arm/mach-bcm/board_bcm2835.c
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -36,7 +36,12 @@ static void __init bcm2835_init(void)
}
static const char * const bcm2835_compat[] = {
+#ifdef CONFIG_ARCH_MULTI_V6
"brcm,bcm2835",
+#endif
+#ifdef CONFIG_ARCH_MULTI_V7
+ "brcm,bcm2836",
+#endif
NULL
};
diff --git a/arch/arm/mach-bcm/brcmstb.c b/arch/arm/mach-bcm/brcmstb.c
index 3a60f7e..99a67cf 100644
--- a/arch/arm/mach-bcm/brcmstb.c
+++ b/arch/arm/mach-bcm/brcmstb.c
@@ -12,11 +12,19 @@
*/
#include <linux/init.h>
+#include <linux/irqchip.h>
#include <linux/of_platform.h>
+#include <linux/soc/brcmstb/brcmstb.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+static void __init brcmstb_init_irq(void)
+{
+ irqchip_init();
+ brcmstb_biuctrl_init();
+}
+
static const char *const brcmstb_match[] __initconst = {
"brcm,bcm7445",
"brcm,brcmstb",
@@ -25,4 +33,5 @@ static const char *const brcmstb_match[] __initconst = {
DT_MACHINE_START(BRCMSTB, "Broadcom STB (Flattened Device Tree)")
.dt_compat = brcmstb_match,
+ .init_irq = brcmstb_init_irq,
MACHINE_END
diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
deleted file mode 100644
index 66a0465..0000000
--- a/arch/arm/mach-bcm/kona_smp.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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
index 44d6bddf..40dc844 100644
--- a/arch/arm/mach-bcm/platsmp-brcmstb.c
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -356,7 +356,7 @@ static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
-static struct smp_operations brcmstb_smp_ops __initdata = {
+static const struct smp_operations brcmstb_smp_ops __initconst = {
.smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
.smp_boot_secondary = brcmstb_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
new file mode 100644
index 0000000..575defc
--- /dev/null
+++ b/arch/arm/mach-bcm/platsmp.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2014-2015 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/cpumask.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.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"
+#define MPIDR_CPUID_BITMASK 0x3
+
+/* I/O address of register used to coordinate secondary core startup */
+static u32 secondary_boot_addr;
+
+/*
+ * 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 int nsp_write_lut(void)
+{
+ void __iomem *sku_rom_lut;
+ phys_addr_t secondary_startup_phy;
+
+ if (!secondary_boot_addr) {
+ pr_warn("required secondary boot register not specified\n");
+ return -EINVAL;
+ }
+
+ sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
+ sizeof(secondary_boot_addr));
+ if (!sku_rom_lut) {
+ pr_warn("unable to ioremap SKU-ROM LUT register\n");
+ return -ENOMEM;
+ }
+
+ secondary_startup_phy = virt_to_phys(secondary_startup);
+ BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX);
+
+ writel_relaxed(secondary_startup_phy, sku_rom_lut);
+
+ /* Ensure the write is visible to the secondary core */
+ smp_wmb();
+
+ iounmap(sku_rom_lut);
+
+ 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 *cpus_node = NULL;
+ struct device_node *cpu_node = NULL;
+ int ret;
+
+ /*
+ * 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.
+ */
+ cpus_node = of_find_node_by_path("/cpus");
+ if (!cpus_node)
+ return;
+
+ for_each_child_of_node(cpus_node, cpu_node) {
+ u32 cpuid;
+
+ if (of_node_cmp(cpu_node->type, "cpu"))
+ continue;
+
+ if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
+ pr_debug("%s: missing reg property\n",
+ cpu_node->full_name);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ /*
+ * "secondary-boot-reg" property should be defined only
+ * for secondary cpu
+ */
+ if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
+ /*
+ * Our secondary enable method requires a
+ * "secondary-boot-reg" property to specify a register
+ * address used to request the ROM code boot a secondary
+ * core. If we have any trouble getting this we fall
+ * back to uniprocessor mode.
+ */
+ if (of_property_read_u32(cpu_node,
+ OF_SECONDARY_BOOT,
+ &secondary_boot_addr)) {
+ pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
+ cpu_node->name);
+ ret = -ENOENT;
+ 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(cpu_node);
+ of_node_put(cpus_node);
+
+ if (ret) {
+ /* Update the CPU present map to reflect uniprocessor mode */
+ 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 kona_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_addr) {
+ pr_err("required secondary boot register not specified\n");
+ return -EINVAL;
+ }
+
+ boot_reg = ioremap_nocache(
+ (phys_addr_t)secondary_boot_addr, sizeof(u32));
+ if (!boot_reg) {
+ pr_err("unable to map boot register for cpu %u\n", cpu_id);
+ return -ENOMEM;
+ }
+
+ /*
+ * 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 -ENXIO;
+}
+
+static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ int ret;
+
+ /*
+ * After wake up, secondary core branches to the startup
+ * address programmed at SKU ROM LUT location.
+ */
+ ret = nsp_write_lut();
+ if (ret) {
+ pr_err("unable to write startup addr to SKU ROM LUT\n");
+ goto out;
+ }
+
+ /* Send a CPU wakeup interrupt to the secondary core */
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+out:
+ return ret;
+}
+
+static const struct smp_operations bcm_smp_ops __initconst = {
+ .smp_prepare_cpus = bcm_smp_prepare_cpus,
+ .smp_boot_secondary = kona_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
+ &bcm_smp_ops);
+
+struct smp_operations nsp_smp_ops __initdata = {
+ .smp_prepare_cpus = bcm_smp_prepare_cpus,
+ .smp_boot_secondary = nsp_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
index 742d53a..ffbfa0b 100644
--- a/arch/arm/mach-berlin/Kconfig
+++ b/arch/arm/mach-berlin/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_BERLIN
- bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
+ bool "Marvell Berlin SoCs"
+ depends on ARCH_MULTI_V7
select ARCH_HAS_RESET_CONTROLLER
select ARCH_REQUIRE_GPIOLIB
select ARM_GIC
diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
index ac181c6..25d7387 100644
--- a/arch/arm/mach-berlin/berlin.c
+++ b/arch/arm/mach-berlin/berlin.c
@@ -18,6 +18,11 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
+static void __init berlin_init_late(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
static const char * const berlin_dt_compat[] = {
"marvell,berlin",
NULL,
@@ -25,6 +30,7 @@ static const char * const berlin_dt_compat[] = {
DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
.dt_compat = berlin_dt_compat,
+ .init_late = berlin_init_late,
/*
* with DT probing for L2CCs, berlin_init_machine can be removed.
* Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
diff --git a/arch/arm/mach-berlin/platsmp.c b/arch/arm/mach-berlin/platsmp.c
index 34a3753..93f9068 100644
--- a/arch/arm/mach-berlin/platsmp.c
+++ b/arch/arm/mach-berlin/platsmp.c
@@ -14,10 +14,16 @@
#include <linux/of_address.h>
#include <asm/cacheflush.h>
+#include <asm/cp15.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
-#define CPU_RESET 0x00
+/*
+ * There are two reset registers, one with self-clearing (SC)
+ * reset and one with non-self-clearing reset (NON_SC).
+ */
+#define CPU_RESET_SC 0x00
+#define CPU_RESET_NON_SC 0x20
#define RESET_VECT 0x00
#define SW_RESET_ADDR 0x94
@@ -30,9 +36,11 @@ static inline void berlin_perform_reset_cpu(unsigned int cpu)
{
u32 val;
- val = readl(cpu_ctrl + CPU_RESET);
+ val = readl(cpu_ctrl + CPU_RESET_NON_SC);
+ val &= ~BIT(cpu_logical_map(cpu));
+ writel(val, cpu_ctrl + CPU_RESET_NON_SC);
val |= BIT(cpu_logical_map(cpu));
- writel(val, cpu_ctrl + CPU_RESET);
+ writel(val, cpu_ctrl + CPU_RESET_NON_SC);
}
static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -91,8 +99,32 @@ unmap_scu:
iounmap(scu_base);
}
-static struct smp_operations berlin_smp_ops __initdata = {
+#ifdef CONFIG_HOTPLUG_CPU
+static void berlin_cpu_die(unsigned int cpu)
+{
+ v7_exit_coherency_flush(louis);
+ while (1)
+ cpu_do_idle();
+}
+
+static int berlin_cpu_kill(unsigned int cpu)
+{
+ u32 val;
+
+ val = readl(cpu_ctrl + CPU_RESET_NON_SC);
+ val &= ~BIT(cpu_logical_map(cpu));
+ writel(val, cpu_ctrl + CPU_RESET_NON_SC);
+
+ return 1;
+}
+#endif
+
+static const struct smp_operations berlin_smp_ops __initconst = {
.smp_prepare_cpus = berlin_smp_prepare_cpus,
.smp_boot_secondary = berlin_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = berlin_cpu_die,
+ .cpu_kill = berlin_cpu_kill,
+#endif
};
CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);
diff --git a/arch/arm/mach-clps711x/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c
index c3d9642..ba3d7d1 100644
--- a/arch/arm/mach-clps711x/board-autcpu12.c
+++ b/arch/arm/mach-clps711x/board-autcpu12.c
@@ -31,7 +31,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand-gpio.h>
#include <linux/platform_device.h>
-#include <linux/basic_mmio_gpio.h>
+#include <linux/gpio/driver.h>
#include <mach/hardware.h>
#include <asm/sizes.h>
diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c
index e68dd62..80a16a8 100644
--- a/arch/arm/mach-clps711x/board-p720t.c
+++ b/arch/arm/mach-clps711x/board-p720t.c
@@ -28,7 +28,7 @@
#include <linux/leds.h>
#include <linux/sizes.h>
#include <linux/backlight.h>
-#include <linux/basic_mmio_gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand-gpio.h>
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
index 3c22a19..eb14a0f 100644
--- a/arch/arm/mach-cns3xxx/Kconfig
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_CNS3XXX
- bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
+ bool "Cavium Networks CNS3XXX family"
+ depends on ARCH_MULTI_V6
select ARM_GIC
select PCI_DOMAINS if PCI
help
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
index c622c30..47905a5 100644
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -65,8 +65,9 @@ static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
/*
* 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.
+ * we still want to access it.
+ * We place the host bridge on bus 0, and the directly connected
+ * device on bus 1, slot 0.
*/
if (busno == 0) { /* internal PCIe bus, host bridge device */
if (devfn == 0) /* device# and function# are ignored by hw */
@@ -211,58 +212,46 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
}
}
+static void cns3xxx_write_config(struct cns3xxx_pcie *cnspci,
+ int where, int size, u32 val)
+{
+ void __iomem *base = cnspci->host_regs + (where & 0xffc);
+ u32 v;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ v = readl_relaxed(base + (where & 0xffc));
+
+ v &= ~(mask << shift);
+ v |= (val & mask) << shift;
+
+ writel_relaxed(v, base + (where & 0xffc));
+ readl_relaxed(base + (where & 0xffc));
+}
+
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);
+ cns3xxx_write_config(cnspci, PCI_PRIMARY_BUS, 1, 0);
+ cns3xxx_write_config(cnspci, PCI_SECONDARY_BUS, 1, 1);
+ cns3xxx_write_config(cnspci, PCI_SUBORDINATE_BUS, 1, 1);
+ cns3xxx_write_config(cnspci, PCI_MEMORY_BASE, 2, mem_base);
+ cns3xxx_write_config(cnspci, PCI_MEMORY_LIMIT, 2, mem_limit);
+ cns3xxx_write_config(cnspci, PCI_IO_BASE_UPPER16, 2, io_base);
+ cns3xxx_write_config(cnspci, PCI_IO_LIMIT_UPPER16, 2, 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");
- }
+ pcie_bus_config = PCIE_BUS_PEER2PEER;
+
/* Disable PCIe0 Interrupt Mask INTA to INTD */
- __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
+ __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(cnspci->port));
}
static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index dd8f531..bcaf1d0 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -34,7 +34,8 @@ 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
+ # needed on silicon revs 1.0, 1.1:
+ select CPU_DCACHE_WRITETHROUGH if !CPU_DCACHE_DISABLE
select CP_INTC
config ARCH_DAVINCI_DA850
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index f8f62fb..3d8cf8c 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -32,7 +32,7 @@
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
#include <mach/mux.h>
#include <mach/da8xx.h>
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 1ed545c..8e4539f 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -40,17 +40,17 @@
#include <linux/spi/flash.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
#include <mach/da8xx.h>
#include <mach/mux.h>
-#include <mach/sram.h>
+#include "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>
+#include <media/i2c/tvp514x.h>
+#include <media/i2c/adv7343.h>
#define DA850_EVM_PHY_ID "davinci_mdio-0:00"
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index b46b4d2..1844076 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -19,7 +19,7 @@
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/videodev2.h>
-#include <media/tvp514x.h>
+#include <media/i2c/tvp514x.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/platform_data/gpio-davinci.h>
@@ -384,9 +384,7 @@ static __init void dm355_evm_init(void)
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
+ if (!WARN(IS_ERR(aemif), "unable to get AEMIF clock\n"))
clk_prepare_enable(aemif);
platform_add_devices(davinci_evm_devices,
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 680a7a2..284ff27 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -242,9 +242,7 @@ static __init void dm355_leopard_init(void)
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
+ if (!WARN(IS_ERR(aemif), "unable to get AEMIF clock\n"))
clk_prepare_enable(aemif);
platform_add_devices(davinci_leopard_devices,
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index a756003..f073518 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -40,8 +40,8 @@
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
-#include <media/ths7303.h>
-#include <media/tvp514x.h>
+#include <media/i2c/ths7303.h>
+#include <media/i2c/tvp514x.h>
#include "davinci.h"
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 1a0898c..7a20507 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -26,7 +26,7 @@
#include <linux/v4l2-dv-timings.h>
#include <linux/export.h>
-#include <media/tvp514x.h>
+#include <media/i2c/tvp514x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -546,9 +546,7 @@ static int dm6444evm_msp430_get_pins(void)
if (status < 0)
return status;
- dev_dbg(&dm6446evm_msp->dev,
- "PINS: %02x %02x %02x %02x\n",
- buf[0], buf[1], buf[2], buf[3]);
+ dev_dbg(&dm6446evm_msp->dev, "PINS: %4ph\n", buf);
return (buf[3] << 8) | buf[2];
}
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 846a84d..ee6ab7e 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -25,8 +25,8 @@
#include <linux/platform_data/at24.h>
#include <linux/i2c/pcf857x.h>
-#include <media/tvp514x.h>
-#include <media/adv7343.h>
+#include <media/i2c/tvp514x.h>
+#include <media/i2c/adv7343.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 8cfbfe0..62ebac5 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -26,7 +26,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
#include <mach/da8xx.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
@@ -115,13 +115,14 @@ static void mityomapl138_cpufreq_init(const char *partnum)
static void mityomapl138_cpufreq_init(const char *partnum) { }
#endif
-static void read_factory_config(struct memory_accessor *a, void *context)
+static void read_factory_config(struct nvmem_device *nvmem, 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));
+ ret = nvmem_device_read(nvmem, 0, sizeof(factory_config),
+ &factory_config);
if (ret != sizeof(struct factory_config)) {
pr_warn("Read Factory Config Failed: %d\n", ret);
goto bad_config;
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 2aac51d..ee62486 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -19,7 +19,7 @@
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
#include <mach/da8xx.h>
#include <mach/mux.h>
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index c70bb0a..3424eac6 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -23,7 +23,7 @@
#include <mach/hardware.h>
#include <mach/clock.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/cputype.h>
#include "clock.h"
@@ -97,7 +97,9 @@ int clk_enable(struct clk *clk)
{
unsigned long flags;
- if (clk == NULL || IS_ERR(clk))
+ if (!clk)
+ return 0;
+ else if (IS_ERR(clk))
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
@@ -124,7 +126,7 @@ EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
+ return 0;
return clk->rate;
}
@@ -159,8 +161,10 @@ 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)
+ return 0;
+ else if (IS_ERR(clk))
+ return -EINVAL;
if (clk->set_rate)
ret = clk->set_rate(clk, rate);
@@ -181,7 +185,9 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
{
unsigned long flags;
- if (clk == NULL || IS_ERR(clk))
+ if (!clk)
+ return 0;
+ else if (IS_ERR(clk))
return -EINVAL;
/* Cannot change parent on enabled clock */
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index a794f6d..f55ef2e 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -28,13 +28,13 @@ 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)
+void davinci_get_mac_addr(struct nvmem_device *nvmem, 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)
+ if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN)
pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
}
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 507aad4..1a68d24 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -19,7 +19,7 @@
#include <linux/of_irq.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
static inline unsigned int cp_intc_read(unsigned offset)
{
diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/cp_intc.h
index 827bbe9..827bbe9 100644
--- a/arch/arm/mach-davinci/include/mach/cp_intc.h
+++ b/arch/arm/mach-davinci/cp_intc.h
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index 306ebc5..1b8f085 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -19,8 +19,8 @@
#include <linux/export.h>
#include <asm/cpuidle.h>
-#include <mach/cpuidle.h>
-#include <mach/ddr2.h>
+#include "cpuidle.h"
+#include "ddr2.h"
#define DAVINCI_CPUIDLE_MAX_STATES 2
diff --git a/arch/arm/mach-davinci/include/mach/cpuidle.h b/arch/arm/mach-davinci/cpuidle.h
index 74f088b..74f088b 100644
--- a/arch/arm/mach-davinci/include/mach/cpuidle.h
+++ b/arch/arm/mach-davinci/cpuidle.h
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 115d573..7187e7f 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -15,7 +15,7 @@
#include <asm/mach/map.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/common.h>
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 6769978..97d8779 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -22,7 +22,7 @@
#include <asm/mach/map.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/common.h>
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 06b6451..c4b5808 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -15,7 +15,7 @@
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/cp_intc.h>
+#include "cp_intc.h"
#include <mach/da8xx.h>
#define DA8XX_NUM_UARTS 3
diff --git a/arch/arm/mach-davinci/include/mach/ddr2.h b/arch/arm/mach-davinci/ddr2.h
index c19e047..c19e047 100644
--- a/arch/arm/mach-davinci/include/mach/ddr2.h
+++ b/arch/arm/mach-davinci/ddr2.h
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 29e08aa..e88b7a5 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -22,8 +22,8 @@
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
-#include <mach/cpuidle.h>
-#include <mach/sram.h>
+#include "cpuidle.h"
+#include "sram.h"
#include "clock.h"
#include "asp.h"
@@ -147,150 +147,118 @@ static s8 da850_queue_priority_mapping[][2] = {
{-1, -1}
};
-static struct edma_soc_info da830_edma_cc0_info = {
+static struct edma_soc_info da8xx_edma0_pdata = {
.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_edma1_pdata = {
+ .queue_priority_mapping = da850_queue_priority_mapping,
+ .default_queue = EVENTQ_0,
};
-static struct edma_soc_info da850_edma_cc_info[] = {
+static struct resource da8xx_edma0_resources[] = {
{
- .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",
+ .name = "edma3_cc",
.start = DA8XX_TPCC_BASE,
.end = DA8XX_TPCC_BASE + SZ_32K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc0",
+ .name = "edma3_tc0",
.start = DA8XX_TPTC0_BASE,
.end = DA8XX_TPTC0_BASE + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc1",
+ .name = "edma3_tc1",
.start = DA8XX_TPTC1_BASE,
.end = DA8XX_TPTC1_BASE + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma0",
+ .name = "edma3_ccint",
.start = IRQ_DA8XX_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma0_err",
+ .name = "edma3_ccerrint",
.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,
- },
+static struct resource da850_edma1_resources[] = {
{
- .name = "edma_cc1",
+ .name = "edma3_cc",
.start = DA850_TPCC1_BASE,
.end = DA850_TPCC1_BASE + SZ_32K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc2",
+ .name = "edma3_tc0",
.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",
+ .name = "edma3_ccint",
.start = IRQ_DA850_CCINT1,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma1_err",
+ .name = "edma3_ccerrint",
.start = IRQ_DA850_CCERRINT1,
.flags = IORESOURCE_IRQ,
},
};
-static struct platform_device da830_edma_device = {
+static const struct platform_device_info da8xx_edma0_device __initconst = {
.name = "edma",
- .id = -1,
- .dev = {
- .platform_data = da830_edma_info,
- },
- .num_resources = ARRAY_SIZE(da830_edma_resources),
- .resource = da830_edma_resources,
+ .id = 0,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = da8xx_edma0_resources,
+ .num_res = ARRAY_SIZE(da8xx_edma0_resources),
+ .data = &da8xx_edma0_pdata,
+ .size_data = sizeof(da8xx_edma0_pdata),
};
-static struct platform_device da850_edma_device = {
+static const struct platform_device_info da850_edma1_device __initconst = {
.name = "edma",
- .id = -1,
- .dev = {
- .platform_data = da850_edma_info,
- },
- .num_resources = ARRAY_SIZE(da850_edma_resources),
- .resource = da850_edma_resources,
+ .id = 1,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = da850_edma1_resources,
+ .num_res = ARRAY_SIZE(da850_edma1_resources),
+ .data = &da850_edma1_pdata,
+ .size_data = sizeof(da850_edma1_pdata),
};
int __init da830_register_edma(struct edma_rsv_info *rsv)
{
- da830_edma_cc0_info.rsv = rsv;
+ struct platform_device *edma_pdev;
+
+ da8xx_edma0_pdata.rsv = rsv;
- return platform_device_register(&da830_edma_device);
+ edma_pdev = platform_device_register_full(&da8xx_edma0_device);
+ return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
}
int __init da850_register_edma(struct edma_rsv_info *rsv[2])
{
+ struct platform_device *edma_pdev;
+
if (rsv) {
- da850_edma_cc_info[0].rsv = rsv[0];
- da850_edma_cc_info[1].rsv = rsv[1];
+ da8xx_edma0_pdata.rsv = rsv[0];
+ da850_edma1_pdata.rsv = rsv[1];
}
- return platform_device_register(&da850_edma_device);
+ edma_pdev = platform_device_register_full(&da8xx_edma0_device);
+ if (IS_ERR(edma_pdev)) {
+ pr_warn("%s: Failed to register eDMA0\n", __func__);
+ return PTR_ERR(edma_pdev);
+ }
+ edma_pdev = platform_device_register_full(&da850_edma1_device);
+ return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
}
static struct resource da8xx_i2c_resources0[] = {
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 567dc56..c7c1458 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -21,7 +21,7 @@
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/mux.h>
#include <mach/irqs.h>
#include <mach/time.h>
@@ -569,61 +569,58 @@ static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
/*----------------------------------------------------------------------*/
-static s8
-queue_priority_mapping[][2] = {
+static s8 queue_priority_mapping[][2] = {
/* {event queue no, Priority} */
{0, 3},
{1, 7},
{-1, -1},
};
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm355_edma_pdata = {
.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",
+ .name = "edma3_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc0",
+ .name = "edma3_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc1",
+ .name = "edma3_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma0",
+ .name = "edma3_ccint",
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma0_err",
+ .name = "edma3_ccerrint",
.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 const struct platform_device_info dm355_edma_device __initconst = {
+ .name = "edma",
+ .id = 0,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = edma_resources,
+ .num_res = ARRAY_SIZE(edma_resources),
+ .data = &dm355_edma_pdata,
+ .size_data = sizeof(dm355_edma_pdata),
};
static struct resource dm355_asp1_resources[] = {
@@ -1062,13 +1059,18 @@ int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
static int __init dm355_init_devices(void)
{
+ struct platform_device *edma_pdev;
int ret = 0;
if (!cpu_is_davinci_dm355())
return 0;
davinci_cfg_reg(DM355_INT_EDMA_CC);
- platform_device_register(&dm355_edma_device);
+ edma_pdev = platform_device_register_full(&dm355_edma_device);
+ if (IS_ERR(edma_pdev)) {
+ pr_warn("%s: Failed to register eDMA\n", __func__);
+ return PTR_ERR(edma_pdev);
+ }
ret = davinci_init_wdt();
if (ret)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 6a890a8..01843fb 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -26,7 +26,7 @@
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/mux.h>
#include <mach/irqs.h>
#include <mach/time.h>
@@ -853,8 +853,7 @@ static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
};
/* Four Transfer Controllers on DM365 */
-static s8
-dm365_queue_priority_mapping[][2] = {
+static s8 dm365_queue_priority_mapping[][2] = {
/* {event queue no, Priority} */
{0, 7},
{1, 7},
@@ -863,53 +862,49 @@ dm365_queue_priority_mapping[][2] = {
{-1, -1},
};
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm365_edma_pdata = {
.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",
+ .name = "edma3_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc0",
+ .name = "edma3_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc1",
+ .name = "edma3_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc2",
+ .name = "edma3_tc2",
.start = 0x01c10800,
.end = 0x01c10800 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc3",
+ .name = "edma3_tc3",
.start = 0x01c10c00,
.end = 0x01c10c00 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma0",
+ .name = "edma3_ccint",
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma0_err",
+ .name = "edma3_ccerrint",
.start = IRQ_CCERRINT,
.flags = IORESOURCE_IRQ,
},
@@ -919,7 +914,7 @@ static struct resource edma_resources[] = {
static struct platform_device dm365_edma_device = {
.name = "edma",
.id = 0,
- .dev.platform_data = dm365_edma_info,
+ .dev.platform_data = &dm365_edma_pdata,
.num_resources = ARRAY_SIZE(edma_resources),
.resource = edma_resources,
};
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index dc52657..b28071a 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -19,7 +19,7 @@
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/mux.h>
#include <mach/time.h>
#include <mach/serial.h>
@@ -498,61 +498,58 @@ static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
/*----------------------------------------------------------------------*/
-static s8
-queue_priority_mapping[][2] = {
+static s8 queue_priority_mapping[][2] = {
/* {event queue no, Priority} */
{0, 3},
{1, 7},
{-1, -1},
};
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm644x_edma_pdata = {
.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",
+ .name = "edma3_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc0",
+ .name = "edma3_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc1",
+ .name = "edma3_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma0",
+ .name = "edma3_ccint",
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma0_err",
+ .name = "edma3_ccerrint",
.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,
+static const struct platform_device_info dm644x_edma_device __initconst = {
+ .name = "edma",
+ .id = 0,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = edma_resources,
+ .num_res = ARRAY_SIZE(edma_resources),
+ .data = &dm644x_edma_pdata,
+ .size_data = sizeof(dm644x_edma_pdata),
};
/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
@@ -950,12 +947,17 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
static int __init dm644x_init_devices(void)
{
+ struct platform_device *edma_pdev;
int ret = 0;
if (!cpu_is_davinci_dm644x())
return 0;
- platform_device_register(&dm644x_edma_device);
+ edma_pdev = platform_device_register_full(&dm644x_edma_device);
+ if (IS_ERR(edma_pdev)) {
+ pr_warn("%s: Failed to register eDMA\n", __func__);
+ return PTR_ERR(edma_pdev);
+ }
platform_device_register(&dm644x_mdio_device);
platform_device_register(&dm644x_emac_device);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 3f842bb..cf80786 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -20,7 +20,7 @@
#include <mach/cputype.h>
#include <mach/irqs.h>
-#include <mach/psc.h>
+#include "psc.h"
#include <mach/mux.h>
#include <mach/time.h>
#include <mach/serial.h>
@@ -531,8 +531,7 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
/*----------------------------------------------------------------------*/
/* Four Transfer Controllers on DM646x */
-static s8
-dm646x_queue_priority_mapping[][2] = {
+static s8 dm646x_queue_priority_mapping[][2] = {
/* {event queue no, Priority} */
{0, 4},
{1, 0},
@@ -541,65 +540,63 @@ dm646x_queue_priority_mapping[][2] = {
{-1, -1},
};
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm646x_edma_pdata = {
.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",
+ .name = "edma3_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc0",
+ .name = "edma3_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc1",
+ .name = "edma3_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc2",
+ .name = "edma3_tc2",
.start = 0x01c10800,
.end = 0x01c10800 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma_tc3",
+ .name = "edma3_tc3",
.start = 0x01c10c00,
.end = 0x01c10c00 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "edma0",
+ .name = "edma3_ccint",
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
- .name = "edma0_err",
+ .name = "edma3_ccerrint",
.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 const struct platform_device_info dm646x_edma_device __initconst = {
+ .name = "edma",
+ .id = 0,
+ .dma_mask = DMA_BIT_MASK(32),
+ .res = edma_resources,
+ .num_res = ARRAY_SIZE(edma_resources),
+ .data = &dm646x_edma_pdata,
+ .size_data = sizeof(dm646x_edma_pdata),
};
static struct resource dm646x_mcasp0_resources[] = {
@@ -936,9 +933,12 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config,
int __init dm646x_init_edma(struct edma_rsv_info *rsv)
{
- edma_cc0_info.rsv = rsv;
+ struct platform_device *edma_pdev;
+
+ dm646x_edma_pdata.rsv = rsv;
- return platform_device_register(&dm646x_edma_device);
+ edma_pdev = platform_device_register_full(&dm646x_edma_device);
+ return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0;
}
void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index 8fb97b9..53b456a5 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -30,7 +30,7 @@
u32 *uart;
/* PORT_16C550A, in polled non-fifo mode */
-static void putc(char c)
+static inline void putc(char c)
{
if (!uart)
return;
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 07e23ba..8929569 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -21,7 +21,7 @@
#include <mach/common.h>
#include <mach/da8xx.h>
-#include <mach/sram.h>
+#include "sram.h"
#include <mach/pm.h>
#include "clock.h"
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index 82fdc69..e5dc6bf 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -23,7 +23,7 @@
#include <linux/io.h>
#include <mach/cputype.h>
-#include <mach/psc.h>
+#include "psc.h"
#include "clock.h"
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/psc.h
index 99d47cf..99d47cf 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/psc.h
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
index a5336a5..cd350de 100644
--- a/arch/arm/mach-davinci/sleep.S
+++ b/arch/arm/mach-davinci/sleep.S
@@ -21,8 +21,8 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <mach/psc.h>
-#include <mach/ddr2.h>
+#include "psc.h"
+#include "ddr2.h"
#include "clock.h"
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
index 8540ddd..668b6e7 100644
--- a/arch/arm/mach-davinci/sram.c
+++ b/arch/arm/mach-davinci/sram.c
@@ -14,7 +14,7 @@
#include <linux/genalloc.h>
#include <mach/common.h>
-#include <mach/sram.h>
+#include "sram.h"
static struct gen_pool *sram_pool;
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/sram.h
index 4e5db56..4e5db56 100644
--- a/arch/arm/mach-davinci/include/mach/sram.h
+++ b/arch/arm/mach-davinci/sram.h
diff --git a/arch/arm/mach-digicolor/Kconfig b/arch/arm/mach-digicolor/Kconfig
index 4f36d8d..fc65b0f 100644
--- a/arch/arm/mach-digicolor/Kconfig
+++ b/arch/arm/mach-digicolor/Kconfig
@@ -1,7 +1,10 @@
config ARCH_DIGICOLOR
bool "Conexant Digicolor SoC Support"
depends on ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
select CLKSRC_MMIO
select DIGICOLOR_TIMER
select GENERIC_IRQ_CHIP
select MFD_SYSCON
+ select PINCTRL
+ select PINCTRL_DIGICOLOR
diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c
index 0dc39cf..b9a7c33 100644
--- a/arch/arm/mach-dove/cm-a510.c
+++ b/arch/arm/mach-dove/cm-a510.c
@@ -88,6 +88,7 @@ static void __init cm_a510_init(void)
MACHINE_START(CM_A510, "Compulab CM-A510 Board")
.atag_offset = 0x100,
+ .nr_irqs = DOVE_NR_IRQS,
.init_machine = cm_a510_init,
.map_io = dove_map_io,
.init_early = dove_init_early,
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 0d1a892..0cdaa38 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -16,6 +16,7 @@
#include <linux/platform_data/dma-mv_xor.h>
#include <linux/platform_data/usb-ehci-orion.h>
#include <linux/platform_device.h>
+#include <linux/soc/dove/pmu.h>
#include <asm/hardware/cache-tauros2.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -375,6 +376,47 @@ void __init dove_setup_cpu_wins(void)
DOVE_SCRATCHPAD_SIZE);
}
+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,
+};
+
+static void __init __maybe_unused orion_wdt_init(void)
+{
+ platform_device_register(&orion_wdt_device);
+}
+
+static const struct dove_pmu_domain_initdata pmu_domains[] __initconst = {
+ {
+ .pwr_mask = PMU_PWR_VPU_PWR_DWN_MASK,
+ .rst_mask = PMU_SW_RST_VIDEO_MASK,
+ .iso_mask = PMU_ISO_VIDEO_MASK,
+ .name = "vpu-domain",
+ }, {
+ .pwr_mask = PMU_PWR_GPU_PWR_DWN_MASK,
+ .rst_mask = PMU_SW_RST_GPU_MASK,
+ .iso_mask = PMU_ISO_GPU_MASK,
+ .name = "gpu-domain",
+ }, {
+ /* sentinel */
+ },
+};
+
+static const struct dove_pmu_initdata pmu_data __initconst = {
+ .pmc_base = DOVE_PMU_VIRT_BASE,
+ .pmu_base = DOVE_PMU_VIRT_BASE + 0x8000,
+ .irq = IRQ_DOVE_PMU,
+ .irq_domain_start = IRQ_DOVE_PMU_START,
+ .domains = pmu_domains,
+};
+
void __init dove_init(void)
{
pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
@@ -389,6 +431,7 @@ void __init dove_init(void)
dove_clk_init();
/* internal devices that every board has */
+ dove_init_pmu_legacy(&pmu_data);
dove_rtc_init();
dove_xor0_init();
dove_xor1_init();
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
index 76e26f9..bcb678f 100644
--- a/arch/arm/mach-dove/dove-db-setup.c
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -94,6 +94,7 @@ static void __init dove_db_init(void)
MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
.atag_offset = 0x100,
+ .nr_irqs = DOVE_NR_IRQS,
.init_machine = dove_db_init,
.map_io = dove_map_io,
.init_early = dove_init_early,
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
index 0c4b35f..00f4545 100644
--- a/arch/arm/mach-dove/include/mach/dove.h
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARCH_DOVE_H
#define __ASM_ARCH_DOVE_H
+#include <mach/irqs.h>
+
/*
* Marvell Dove address maps.
*
diff --git a/arch/arm/mach-dove/include/mach/entry-macro.S b/arch/arm/mach-dove/include/mach/entry-macro.S
deleted file mode 100644
index 72d622ba..0000000
--- a/arch/arm/mach-dove/include/mach/entry-macro.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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/irqs.h b/arch/arm/mach-dove/include/mach/irqs.h
index 3f29e6bc..8ff0fa8 100644
--- a/arch/arm/mach-dove/include/mach/irqs.h
+++ b/arch/arm/mach-dove/include/mach/irqs.h
@@ -90,7 +90,7 @@
#define NR_PMU_IRQS 7
#define IRQ_DOVE_RTC (IRQ_DOVE_PMU_START + 5)
-#define NR_IRQS (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+#define DOVE_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
index b47f750..d22b9b1 100644
--- a/arch/arm/mach-dove/include/mach/pm.h
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -51,22 +51,14 @@
#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;
+#define PMU_SW_RST_VIDEO_MASK BIT(16)
+#define PMU_SW_RST_GPU_MASK BIT(18)
- return -EINVAL;
-}
+#define PMU_PWR_GPU_PWR_DWN_MASK BIT(2)
+#define PMU_PWR_VPU_PWR_DWN_MASK BIT(3)
-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;
-}
+#define PMU_ISO_VIDEO_MASK BIT(0)
+#define PMU_ISO_GPU_MASK BIT(1)
#endif
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index bfb3703..d6627c1 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -7,87 +7,15 @@
* 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 <asm/exception.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(struct irq_desc *desc)
-{
- unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
- unsigned int irq;
-
- cause &= readl(PMU_INTERRUPT_MASK);
- if (cause == 0) {
- do_bad_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,
@@ -109,14 +37,6 @@ static int __initdata gpio2_irqs[4] = {
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
@@ -139,18 +59,13 @@ __exception_irq_entry dove_legacy_handle_irq(struct pt_regs *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.
@@ -163,17 +78,4 @@ void __init dove_init_irq(void)
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);
- irq_clear_status_flags(i, IRQ_NOREQUEST);
- }
- irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
}
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index c490426..b2db791 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -49,7 +49,7 @@
static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
static u16 nand_state = SNAPPERCL15_NAND_WPN;
u16 set;
@@ -76,7 +76,7 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
}
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 61f4b5d..45b81a2 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -74,7 +74,7 @@ static void __init ts72xx_map_io(void)
static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
int cmd, unsigned int ctrl)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
if (ctrl & NAND_CTRL_CHANGE) {
void __iomem *addr = chip->IO_ADDR_R;
@@ -96,7 +96,7 @@ static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
static int ts72xx_nand_device_ready(struct mtd_info *mtd)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *addr = chip->IO_ADDR_R;
addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 3a10f1a..652a0bb 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -8,7 +8,8 @@
# Configuration options for the EXYNOS4
menuconfig ARCH_EXYNOS
- bool "Samsung EXYNOS" if ARCH_MULTI_V7
+ bool "Samsung EXYNOS"
+ depends on ARCH_MULTI_V7
select ARCH_HAS_BANDGAP
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_REQUIRE_GPIOLIB
@@ -27,6 +28,10 @@ menuconfig ARCH_EXYNOS
select SRAM
select THERMAL
select MFD_SYSCON
+ select CLKSRC_EXYNOS_MCT
+ select POWER_RESET
+ select POWER_RESET_SYSCON
+ select POWER_RESET_SYSCON_POWEROFF
help
Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 1534925..e349a0389 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -149,7 +149,7 @@ static inline void exynos_pm_init(void) {}
extern void exynos_cpu_resume(void);
extern void exynos_cpu_resume_ns(void);
-extern struct smp_operations exynos_smp_ops;
+extern const struct smp_operations exynos_smp_ops;
extern void exynos_cpu_power_down(int cpu);
extern void exynos_cpu_power_up(int cpu);
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 98a2c0c..5bd9559 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -479,7 +479,7 @@ static void exynos_cpu_die(unsigned int cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-struct smp_operations exynos_smp_ops __initdata = {
+const struct smp_operations exynos_smp_ops __initconst = {
.smp_init_cpus = exynos_smp_init_cpus,
.smp_prepare_cpus = exynos_smp_prepare_cpus,
.smp_secondary_init = exynos_secondary_init,
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index de68938..dbf9fe9 100644
--- a/arch/arm/mach-exynos/pmu.c
+++ b/arch/arm/mach-exynos/pmu.c
@@ -14,9 +14,8 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
+#include <asm/cputype.h>
#include "exynos-pmu.h"
#include "regs-pmu.h"
@@ -681,23 +680,6 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = {
EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
};
-static void exynos_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)
- ;
-}
-
static void exynos5420_powerdown_conf(enum sys_powerdown mode)
{
u32 this_cluster;
@@ -748,8 +730,12 @@ static void exynos5_powerdown_conf(enum sys_powerdown mode)
void exynos_sys_powerdown_conf(enum sys_powerdown mode)
{
unsigned int i;
+ const struct exynos_pmu_data *pmu_data;
+
+ if (!pmu_context)
+ return;
- const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
+ pmu_data = pmu_context->pmu_data;
if (pmu_data->powerdown_conf)
pmu_data->powerdown_conf(mode);
@@ -875,14 +861,6 @@ static void exynos5420_pmu_init(void)
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,
@@ -908,7 +886,7 @@ static const struct exynos_pmu_data exynos5250_pmu_data = {
.powerdown_conf = exynos5_powerdown_conf,
};
-static struct exynos_pmu_data exynos5420_pmu_data = {
+static const struct exynos_pmu_data exynos5420_pmu_data = {
.pmu_config = exynos5420_pmu_config,
.pmu_init = exynos5420_pmu_init,
.powerdown_conf = exynos5420_powerdown_conf,
@@ -940,20 +918,11 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = {
{ /*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);
@@ -978,12 +947,6 @@ static int exynos_pmu_probe(struct platform_device *pdev)
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);
-
- pm_power_off = exynos_power_off;
-
dev_dbg(dev, "Exynos PMU Driver probe done\n");
return 0;
}
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index fba9068..5e4f4c2 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -484,15 +484,6 @@
#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)
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index e00eb39..c169cc3 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -19,6 +19,7 @@
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/err.h>
@@ -177,54 +178,57 @@ static struct irq_chip exynos_pmu_chip = {
#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)
+static int exynos_pmu_domain_translate(struct irq_domain *d,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *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 */
+ if (is_of_node(fwspec->fwnode)) {
+ if (fwspec->param_count != 3)
+ return -EINVAL;
- *out_hwirq = intspec[1];
- *out_type = intspec[2];
- return 0;
+ /* No PPI should point to this domain */
+ if (fwspec->param[0] != 0)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2];
+ return 0;
+ }
+
+ return -EINVAL;
}
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;
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
irq_hw_number_t hwirq;
int i;
- if (args->args_count != 3)
+ if (fwspec->param_count != 3)
return -EINVAL; /* Not GIC compliant */
- if (args->args[0] != 0)
+ if (fwspec->param[0] != 0)
return -EINVAL; /* No PPI should point to this domain */
- hwirq = args->args[1];
+ hwirq = fwspec->param[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);
+ parent_fwspec = *fwspec;
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
+ &parent_fwspec);
}
static const struct irq_domain_ops exynos_pmu_domain_ops = {
- .xlate = exynos_pmu_domain_xlate,
- .alloc = exynos_pmu_domain_alloc,
- .free = irq_domain_free_irqs_common,
+ .translate = exynos_pmu_domain_translate,
+ .alloc = exynos_pmu_domain_alloc,
+ .free = irq_domain_free_irqs_common,
};
static int __init exynos_pmu_irq_init(struct device_node *node,
@@ -262,7 +266,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
return 0;
}
-#define EXYNOS_PMU_IRQ(symbol, name) OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init)
+#define EXYNOS_PMU_IRQ(symbol, name) IRQCHIP_DECLARE(symbol, name, exynos_pmu_irq_init)
EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 07152d0..cbbdd84 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -68,7 +68,6 @@ config ARCH_NETWINDER
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:
diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c
index ca8a25b..18b1279 100644
--- a/arch/arm/mach-gemini/board-nas4220b.c
+++ b/arch/arm/mach-gemini/board-nas4220b.c
@@ -18,7 +18,6 @@
#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>
diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c
index 418188c..14c56f3 100644
--- a/arch/arm/mach-gemini/board-wbd111.c
+++ b/arch/arm/mach-gemini/board-wbd111.c
@@ -15,7 +15,6 @@
#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>
diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c
index 266b265..6070282 100644
--- a/arch/arm/mach-gemini/board-wbd222.c
+++ b/arch/arm/mach-gemini/board-wbd222.c
@@ -15,7 +15,6 @@
#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>
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index 2478d9f..469a76e 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -17,7 +17,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -227,5 +227,5 @@ void __init gemini_gpio_init(void)
(void *)i);
}
- BUG_ON(gpiochip_add(&gemini_gpio_chip));
+ BUG_ON(gpiochip_add_data(&gemini_gpio_chip, NULL));
}
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 31aa866..81110ec 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -1,5 +1,6 @@
config ARCH_HIGHBANK
- bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+ bool "Calxeda ECX-1000/2000 (Highbank/Midway)"
+ depends on ARCH_MULTI_V7
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_SUPPORTS_BIG_ENDIAN
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index 83061ad..a3b091a 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -13,7 +13,8 @@ if ARCH_HISI
menu "Hisilicon platform type"
config ARCH_HI3xxx
- bool "Hisilicon Hi36xx family" if ARCH_MULTI_V7
+ bool "Hisilicon Hi36xx family"
+ depends on ARCH_MULTI_V7
select CACHE_L2X0
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
@@ -23,7 +24,8 @@ config ARCH_HI3xxx
Support for Hisilicon Hi36xx SoC family
config ARCH_HIP01
- bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
+ bool "Hisilicon HIP01 family"
+ depends on ARCH_MULTI_V7
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GLOBAL_TIMER
@@ -31,7 +33,8 @@ config ARCH_HIP01
Support for Hisilicon HIP01 SoC family
config ARCH_HIP04
- bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
+ bool "Hisilicon HiP04 Cortex A15 family"
+ depends on ARCH_MULTI_V7
select ARM_ERRATA_798181 if SMP
select HAVE_ARM_ARCH_TIMER
select MCPM if SMP
@@ -40,7 +43,8 @@ config ARCH_HIP04
Support for Hisilicon HiP04 SoC family
config ARCH_HIX5HD2
- bool "Hisilicon X5HD2 family" if ARCH_MULTI_V7
+ bool "Hisilicon X5HD2 family"
+ depends on ARCH_MULTI_V7
select CACHE_L2X0
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
index c7648ef..e883583 100644
--- a/arch/arm/mach-hisi/core.h
+++ b/arch/arm/mach-hisi/core.h
@@ -6,17 +6,14 @@
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 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/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c
index b5f8f5f..4b653a8 100644
--- a/arch/arm/mach-hisi/platmcpm.c
+++ b/arch/arm/mach-hisi/platmcpm.c
@@ -239,7 +239,7 @@ err:
}
#endif
-static struct smp_operations __initdata hip04_smp_ops = {
+static const struct smp_operations hip04_smp_ops __initconst = {
.smp_boot_secondary = hip04_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = hip04_cpu_die,
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
index 5174412..47ed32c 100644
--- a/arch/arm/mach-hisi/platsmp.c
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -89,7 +89,7 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
-struct smp_operations hi3xxx_smp_ops __initdata = {
+static const struct smp_operations hi3xxx_smp_ops __initconst = {
.smp_prepare_cpus = hi3xxx_smp_prepare_cpus,
.smp_boot_secondary = hi3xxx_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
}
-struct smp_operations hix5hd2_smp_ops __initdata = {
+static const struct smp_operations hix5hd2_smp_ops __initconst = {
.smp_prepare_cpus = hisi_common_smp_prepare_cpus,
.smp_boot_secondary = hix5hd2_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
@@ -176,7 +176,7 @@ static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
-struct smp_operations hip01_smp_ops __initdata = {
+static const struct smp_operations hip01_smp_ops __initconst = {
.smp_prepare_cpus = hisi_common_smp_prepare_cpus,
.smp_boot_secondary = hip01_boot_secondary,
};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8ceda28..15df34fb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_MXC
- bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
+ bool "Freescale i.MX family"
+ depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
select ARCH_REQUIRE_GPIOLIB
select ARM_CPU_SUSPEND if PM
select CLKSRC_IMX_GPT
@@ -562,6 +563,7 @@ config SOC_IMX7D
select ARM_GIC
select HAVE_IMX_ANATOP
select HAVE_IMX_MMDC
+ select HAVE_IMX_SRC
help
This enables support for Freescale i.MX7 Dual processor.
@@ -596,7 +598,8 @@ choice
default VF_USE_ARM_GLOBAL_TIMER
config VF_USE_ARM_GLOBAL_TIMER
- bool "Use ARM Global Timer" if ARCH_MULTI_V7
+ bool "Use ARM Global Timer"
+ depends on ARCH_MULTI_V7
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 21e4e86..32b83f0 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -131,6 +131,7 @@ void imx6q_pm_init(void);
void imx6dl_pm_init(void);
void imx6sl_pm_init(void);
void imx6sx_pm_init(void);
+void imx6ul_pm_init(void);
#ifdef CONFIG_PM
void imx51_pm_init(void);
@@ -152,7 +153,7 @@ void imx_init_l2cache(void);
static inline void imx_init_l2cache(void) {}
#endif
-extern struct smp_operations imx_smp_ops;
-extern struct smp_operations ls1021a_smp_ops;
+extern const struct smp_operations imx_smp_ops;
+extern const struct smp_operations ls1021a_smp_ops;
#endif
diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
index 67f7fb1..09cebd8 100644
--- a/arch/arm/mach-imx/devices/devices-common.h
+++ b/arch/arm/mach-imx/devices/devices-common.h
@@ -177,7 +177,7 @@ struct platform_device *__init imx_add_imx_uart_1irq(
const struct imxuart_platform_data *pdata);
#include <linux/platform_data/video-mx3fb.h>
-#include <linux/platform_data/camera-mx3.h>
+#include <linux/platform_data/media/camera-mx3.h>
struct imx_ipu_core_data {
resource_size_t iobase;
resource_size_t synirq;
@@ -192,7 +192,7 @@ 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>
+#include <linux/platform_data/media/camera-mx2.h>
struct imx_mx2_camera_data {
const char *devid;
resource_size_t iobasecsi;
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 8c4467f..fd87205 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -14,6 +14,7 @@
#include <linux/delay.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>
@@ -176,45 +177,48 @@ static struct irq_chip imx_gpc_chip = {
.irq_unmask = imx_gpc_irq_unmask,
.irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_set_wake = imx_gpc_irq_set_wake,
+ .irq_set_type = irq_chip_set_type_parent,
#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)
+static int imx_gpc_domain_translate(struct irq_domain *d,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *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 */
+ if (is_of_node(fwspec->fwnode)) {
+ if (fwspec->param_count != 3)
+ return -EINVAL;
- *out_hwirq = intspec[1];
- *out_type = intspec[2];
- return 0;
+ /* No PPI should point to this domain */
+ if (fwspec->param[0] != 0)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2];
+ return 0;
+ }
+
+ return -EINVAL;
}
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;
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
irq_hw_number_t hwirq;
int i;
- if (args->args_count != 3)
+ if (fwspec->param_count != 3)
return -EINVAL; /* Not GIC compliant */
- if (args->args[0] != 0)
+ if (fwspec->param[0] != 0)
return -EINVAL; /* No PPI should point to this domain */
- hwirq = args->args[1];
+ hwirq = fwspec->param[1];
if (hwirq >= GPC_MAX_IRQS)
return -EINVAL; /* Can't deal with this */
@@ -222,15 +226,16 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain,
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);
+ parent_fwspec = *fwspec;
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
+ &parent_fwspec);
}
static const struct irq_domain_ops imx_gpc_domain_ops = {
- .xlate = imx_gpc_domain_xlate,
- .alloc = imx_gpc_domain_alloc,
- .free = irq_domain_free_irqs_common,
+ .translate = imx_gpc_domain_translate,
+ .alloc = imx_gpc_domain_alloc,
+ .free = irq_domain_free_irqs_common,
};
static int __init imx_gpc_init(struct device_node *node,
@@ -268,12 +273,7 @@ static int __init imx_gpc_init(struct device_node *node,
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);
+IRQCHIP_DECLARE(imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
void __init imx_gpc_check_dt(void)
{
@@ -374,8 +374,13 @@ static struct pu_domain imx6q_pu_domain = {
.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,
+ .states = {
+ [0] = {
+ .power_off_latency_ns = 25000,
+ .power_on_latency_ns = 2000000,
+ },
+ },
+ .state_count = 1,
},
};
diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c
index 6dd22ca..0b5ba4b 100644
--- a/arch/arm/mach-imx/iomux-imx31.c
+++ b/arch/arm/mach-imx/iomux-imx31.c
@@ -100,7 +100,7 @@ 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",
+ printk(KERN_ERR "mxc_iomux: Attempt to request nonexistent pin %u for \"%s\"\n",
pad, label ? label : "?");
return -EINVAL;
}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 9602cc1..3878494b 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -350,7 +350,7 @@ static void __init imx6q_opp_init(void)
return;
}
- if (of_init_opp_table(cpu_dev)) {
+ if (dev_pm_opp_of_add_table(cpu_dev)) {
pr_warn("failed to init OPP table\n");
goto put_node;
}
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index 1b97fe1..a38b16b 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -67,6 +67,7 @@ static void __init imx6ul_init_machine(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
imx6ul_enet_init();
imx_anatop_init();
+ imx6ul_pm_init();
}
static void __init imx6ul_init_irq(void)
@@ -74,9 +75,16 @@ static void __init imx6ul_init_irq(void)
imx_init_revision_from_anatop();
imx_src_init();
irqchip_init();
+ imx6_pm_ccm_init("fsl,imx6ul-ccm");
}
-static const char *imx6ul_dt_compat[] __initconst = {
+static void __init imx6ul_init_late(void)
+{
+ if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+ platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+}
+
+static const char * const imx6ul_dt_compat[] __initconst = {
"fsl,imx6ul",
NULL,
};
@@ -84,5 +92,6 @@ static const char *imx6ul_dt_compat[] __initconst = {
DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
.init_irq = imx6ul_init_irq,
.init_machine = imx6ul_init_machine,
+ .init_late = imx6ul_init_late,
.dt_compat = imx6ul_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 62f3437..5a27f20 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -6,12 +6,85 @@
* published by the Free Software Foundation.
*/
#include <linux/irqchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include "common.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);
+
+ /* disable phy AR8031 SmartEEE function. */
+ phy_write(dev, 0xd, 0x3);
+ phy_write(dev, 0xe, 0x805d);
+ phy_write(dev, 0xd, 0x4003);
+ val = phy_read(dev, 0xe);
+ val &= ~(0x1 << 8);
+ 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;
+}
+
+static int bcm54220_phy_fixup(struct phy_device *dev)
+{
+ /* enable RXC skew select RGMII copper mode */
+ phy_write(dev, 0x1e, 0x21);
+ phy_write(dev, 0x1f, 0x7ea8);
+ phy_write(dev, 0x1e, 0x2f);
+ phy_write(dev, 0x1f, 0x71b7);
+
+ return 0;
+}
+
+#define PHY_ID_AR8031 0x004dd074
+#define PHY_ID_BCM54220 0x600d8589
+
+static void __init imx7d_enet_phy_init(void)
+{
+ if (IS_BUILTIN(CONFIG_PHYLIB)) {
+ phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+ ar8031_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
+ bcm54220_phy_fixup);
+ }
+}
+
+static void __init imx7d_enet_clk_sel(void)
+{
+ struct regmap *gpr;
+
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+ if (!IS_ERR(gpr)) {
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
+ } else {
+ pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+ }
+}
+
+static inline void imx7d_enet_init(void)
+{
+ imx7d_enet_phy_init();
+ imx7d_enet_clk_sel();
+}
+
static void __init imx7d_init_machine(void)
{
struct device *parent;
@@ -22,6 +95,7 @@ static void __init imx7d_init_machine(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
imx_anatop_init();
+ imx7d_enet_init();
}
static void __init imx7d_init_irq(void)
@@ -31,6 +105,11 @@ static void __init imx7d_init_irq(void)
irqchip_init();
}
+static void __init imx7d_init_late(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
static const char *const imx7d_dt_compat[] __initconst = {
"fsl,imx7d",
NULL,
@@ -38,6 +117,7 @@ static const char *const imx7d_dt_compat[] __initconst = {
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
.init_irq = imx7d_init_irq,
+ .init_late = imx7d_init_late,
.init_machine = imx7d_init_machine,
.dt_compat = imx7d_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 703ce31..9986f9a 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
-#include <linux/basic_mmio_gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index eb1c347..f510c43 100644
--- a/arch/arm/mach-imx/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -13,6 +13,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+#include <linux/gpio/driver.h>
+/* Needed for gpio_to_irq() */
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
@@ -243,7 +245,7 @@ static void __init mx27ads_regulator_init(void)
vchip->ngpio = 1;
vchip->direction_output = vgpio_dir_out;
vchip->set = vgpio_set;
- gpiochip_add(vchip);
+ gpiochip_add_data(vchip, NULL);
platform_device_register_data(NULL, "reg-fixed-voltage",
PLATFORM_DEVID_AUTO,
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c
index a213e7b..5c27646 100644
--- a/arch/arm/mach-imx/mach-qong.c
+++ b/arch/arm/mach-imx/mach-qong.c
@@ -131,7 +131,7 @@ static void qong_init_nor_mtd(void)
*/
static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
- struct nand_chip *nand_chip = mtd->priv;
+ struct nand_chip *nand_chip = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 7f27001..711dbbd 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -88,7 +88,7 @@ static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
sync_cache_w(&g_diag_reg);
}
-struct smp_operations imx_smp_ops __initdata = {
+const struct smp_operations imx_smp_ops __initconst = {
.smp_init_cpus = imx_smp_init_cpus,
.smp_prepare_cpus = imx_smp_prepare_cpus,
.smp_boot_secondary = imx_boot_secondary,
@@ -123,7 +123,7 @@ static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
iounmap(dcfg_base);
}
-struct smp_operations ls1021a_smp_ops __initdata = {
+const struct smp_operations ls1021a_smp_ops __initconst = {
.smp_prepare_cpus = ls1021a_smp_prepare_cpus,
.smp_boot_secondary = ls1021a_boot_secondary,
};
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 8ff8fc0..4470376 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -93,6 +93,7 @@ struct imx6_pm_socdata {
const char *src_compat;
const char *iomuxc_compat;
const char *gpc_compat;
+ const char *pl310_compat;
const u32 mmdc_io_num;
const u32 *mmdc_io_offset;
};
@@ -137,11 +138,19 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
};
+static const u32 imx6ul_mmdc_io_offset[] __initconst = {
+ 0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
+ 0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
+ 0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */
+ 0x494, 0x4b0, /* MODE_CTL, MODE, */
+};
+
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",
+ .pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
.mmdc_io_offset = imx6q_mmdc_io_offset,
};
@@ -151,6 +160,7 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
.src_compat = "fsl,imx6q-src",
.iomuxc_compat = "fsl,imx6dl-iomuxc",
.gpc_compat = "fsl,imx6q-gpc",
+ .pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
.mmdc_io_offset = imx6dl_mmdc_io_offset,
};
@@ -160,6 +170,7 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
.src_compat = "fsl,imx6sl-src",
.iomuxc_compat = "fsl,imx6sl-iomuxc",
.gpc_compat = "fsl,imx6sl-gpc",
+ .pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
.mmdc_io_offset = imx6sl_mmdc_io_offset,
};
@@ -169,10 +180,21 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
.src_compat = "fsl,imx6sx-src",
.iomuxc_compat = "fsl,imx6sx-iomuxc",
.gpc_compat = "fsl,imx6sx-gpc",
+ .pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
.mmdc_io_offset = imx6sx_mmdc_io_offset,
};
+static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6ul-mmdc",
+ .src_compat = "fsl,imx6ul-src",
+ .iomuxc_compat = "fsl,imx6ul-iomuxc",
+ .gpc_compat = "fsl,imx6ul-gpc",
+ .pl310_compat = NULL,
+ .mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
+ .mmdc_io_offset = imx6ul_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
@@ -290,7 +312,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= BM_CLPCR_SBYOS;
if (cpu_is_imx6sl())
val |= BM_CLPCR_BYPASS_PMIC_READY;
- if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -330,6 +352,10 @@ static int imx6q_suspend_finish(unsigned long val)
* as we need to float DDR IO.
*/
local_flush_tlb_all();
+ /* check if need to flush internal L2 cache */
+ if (!((struct imx6_cpu_pm_info *)
+ suspend_ocram_base)->l2_base.vbase)
+ flush_cache_all();
imx6_suspend_in_ocram_fn(suspend_ocram_base);
}
@@ -470,6 +496,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
MX6Q_SUSPEND_OCRAM_SIZE, false);
+ memset(suspend_ocram_base, 0, sizeof(*pm_info));
pm_info = suspend_ocram_base;
pm_info->pbase = ocram_pbase;
pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
@@ -505,11 +532,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
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;
+ if (socdata->pl310_compat) {
+ ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat);
+ 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();
@@ -610,3 +639,8 @@ void __init imx6sx_pm_init(void)
{
imx6_pm_common_init(&imx6sx_pm_data);
}
+
+void __init imx6ul_pm_init(void)
+{
+ imx6_pm_common_init(&imx6ul_pm_data);
+}
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index b99987b..76ee2ce 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -79,12 +79,15 @@
/* sync L2 cache to drain L2's buffers to DRAM. */
#ifdef CONFIG_CACHE_L2X0
ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+ teq r11, #0
+ beq 6f
mov r6, #0x0
str r6, [r11, #L2X0_CACHE_SYNC]
1:
ldr r6, [r11, #L2X0_CACHE_SYNC]
ands r6, r6, #0x1
bne 1b
+6:
#endif
.endm
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 02d0834..b01bdc9 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -1,5 +1,6 @@
-config ARCH_INTEGRATOR
- bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+menuconfig ARCH_INTEGRATOR
+ bool "ARM Ltd. Integrator family"
+ depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6
select ARM_AMBA
select ARM_PATCH_PHYS_VIRT if MMU
select AUTO_ZRELADDR
@@ -23,8 +24,6 @@ config ARCH_INTEGRATOR
if ARCH_INTEGRATOR
-menu "Integrator Options"
-
config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms"
select CLKSRC_MMIO
@@ -36,19 +35,6 @@ config ARCH_INTEGRATOR_AP
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
@@ -63,6 +49,119 @@ config INTEGRATOR_IMPD1
To compile this driver as a module, choose M here: the
module will be called impd1.
-endmenu
+config INTEGRATOR_CM7TDMI
+ bool "Integrator/CM7TDMI core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V4 && !MMU
+ select CPU_ARM7TDMI
+
+config INTEGRATOR_CM720T
+ bool "Integrator/CM720T core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V4T
+ select CPU_ARM720T
+
+config INTEGRATOR_CM740T
+ bool "Integrator/CM740T core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V4T && !MMU
+ select CPU_ARM740T
+
+config INTEGRATOR_CM920T
+ bool "Integrator/CM920T core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V4T
+ select CPU_ARM920T
+
+config INTEGRATOR_CM922T_XA10
+ bool "Integrator/CM922T-XA10 core module"
+ depends on ARCH_MULTI_V4T
+ depends on ARCH_INTEGRATOR_AP
+ select CPU_ARM922T
+
+config INTEGRATOR_CM926EJS
+ bool "Integrator/CM926EJ-S core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V5
+ select CPU_ARM926T
+
+config INTEGRATOR_CM940T
+ bool "Integrator/CM940T core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V4T && !MMU
+ select CPU_ARM940T
+
+config INTEGRATOR_CM946ES
+ bool "Integrator/CM946E-S core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V5 && !MMU
+ select CPU_ARM946E
+
+config INTEGRATOR_CM966ES
+ bool "Integrator/CM966E-S core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on BROKEN # no kernel support
+
+config INTEGRATOR_CM10200E_REV0
+ bool "Integrator/CM10200E rev.0 core module"
+ depends on ARCH_INTEGRATOR_AP && n
+ depends on ARCH_MULTI_V5
+ select CPU_ARM1020
+
+config INTEGRATOR_CM10200E
+ bool "Integrator/CM10200E core module"
+ depends on ARCH_INTEGRATOR_AP && n
+ depends on ARCH_MULTI_V5
+ select CPU_ARM1020E
+
+config INTEGRATOR_CM10220E
+ bool "Integrator/CM10220E core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V5
+ select CPU_ARM1022
+
+config INTEGRATOR_CM1026EJS
+ bool "Integrator/CM1026EJ-S core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V5
+ select CPU_ARM1026
+
+config INTEGRATOR_CM1136JFS
+ bool "Integrator/CM1136JF-S core module"
+ depends on ARCH_INTEGRATOR_AP
+ depends on ARCH_MULTI_V6
+ select CPU_V6
+
+config ARCH_INTEGRATOR_CP
+ bool "Support Integrator/CP platform"
+ depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+ 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 INTEGRATOR_CT7T
+ bool "Integrator/CT7TD (ARM7TDMI) core tile"
+ depends on ARCH_INTEGRATOR_CP
+ depends on ARCH_MULTI_V4T && !MMU
+ select CPU_ARM7TDMI
+
+config INTEGRATOR_CT926
+ bool "Integrator/CT926 (ARM926EJ-S) core tile"
+ depends on ARCH_INTEGRATOR_CP
+ depends on ARCH_MULTI_V5
+ select CPU_ARM926T
+
+config INTEGRATOR_CTB36
+ bool "Integrator/CTB36 (ARM1136JF-S) core tile"
+ depends on ARCH_INTEGRATOR_CP
+ depends on ARCH_MULTI_V6
+ select CPU_V6
+
+config ARCH_CINTEGRATOR
+ depends on ARCH_INTEGRATOR_CP
+ def_bool y
endif
diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
deleted file mode 100644
index 59f42b5..0000000
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#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/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..d255ab5 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -23,7 +23,7 @@
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pci.h>
+#include "pci.h"
#include <asm/mach/time.h>
#include <mach/time.h>
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..33eeaf1 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -23,7 +23,7 @@
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pci.h>
+#include "pci.h"
#include <asm/mach/time.h>
#include <mach/time.h>
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index 623d85a..c702cc4 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -25,7 +25,7 @@
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/msi.h>
+#include "msi.h"
/* INTCTL0 CP6 R0 Page 4
*/
diff --git a/arch/arm/mach-iop13xx/include/mach/msi.h b/arch/arm/mach-iop13xx/msi.h
index b80c5ae..b80c5ae 100644
--- a/arch/arm/mach-iop13xx/include/mach/msi.h
+++ b/arch/arm/mach-iop13xx/msi.h
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..204eb44 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -27,7 +27,7 @@
#include <asm/sizes.h>
#include <asm/signal.h>
#include <asm/mach/pci.h>
-#include <mach/pci.h>
+#include "pci.h"
#define IOP13XX_PCI_DEBUG 0
#define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x)))
diff --git a/arch/arm/mach-iop13xx/pci.h b/arch/arm/mach-iop13xx/pci.h
index d45a80b..71b9c57 100644
--- a/arch/arm/mach-iop13xx/pci.h
+++ b/arch/arm/mach-iop13xx/pci.h
@@ -1,6 +1,64 @@
+#ifndef _IOP13XX_PCI_H_
+#define _IOP13XX_PCI_H_
+#include <linux/io.h>
+#include <mach/irqs.h>
+
#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;
+
+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-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 1cb6f2f..26874f6 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -27,7 +27,7 @@
#include <linux/clockchips.h>
#include <linux/io.h>
#include <linux/export.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/cpu.h>
#include <linux/pci.h>
#include <linux/sched_clock.h>
@@ -461,7 +461,7 @@ void __init ixp4xx_sys_init(void)
platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
- gpiochip_add(&ixp4xx_gpio_chip);
+ gpiochip_add_data(&ixp4xx_gpio_chip, NULL);
if (cpu_is_ixp46x()) {
int region;
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
index b024390..7a0c13b 100644
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -143,7 +143,7 @@ static inline void __indirect_writesl(volatile void __iomem *bus_addr,
writel(*vaddr++, bus_addr);
}
-static inline unsigned char __indirect_readb(const volatile void __iomem *p)
+static inline u8 __indirect_readb(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
@@ -166,7 +166,7 @@ static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
*vaddr++ = readb(bus_addr);
}
-static inline unsigned short __indirect_readw(const volatile void __iomem *p)
+static inline u16 __indirect_readw(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
@@ -189,7 +189,7 @@ static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
*vaddr++ = readw(bus_addr);
}
-static inline unsigned long __indirect_readl(const volatile void __iomem *p)
+static inline u32 __indirect_readl(const volatile void __iomem *p)
{
u32 addr = (__force u32)p;
u32 data;
@@ -350,7 +350,7 @@ static inline void insl(u32 io_addr, void *p, u32 count)
((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
#define ioread8(p) ioread8(p)
-static inline unsigned int ioread8(const void __iomem *addr)
+static inline u8 ioread8(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -378,7 +378,7 @@ static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
}
#define ioread16(p) ioread16(p)
-static inline unsigned int ioread16(const void __iomem *addr)
+static inline u16 ioread16(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
@@ -407,7 +407,7 @@ static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
}
#define ioread32(p) ioread32(p)
-static inline unsigned int ioread32(const void __iomem *addr)
+static inline u32 ioread32(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index c5bae9c..b7ddd27 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -395,204 +395,6 @@
#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 */
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index e7b8bef..508c2d7 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -76,8 +76,8 @@ static struct mtd_partition ixdp425_partitions[] = {
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;
+ struct nand_chip *this = mtd_to_nand(mtd);
+ int offset = (int)nand_get_controller_data(this);
if (ctrl & NAND_CTRL_CHANGE) {
if (ctrl & NAND_NCE) {
@@ -88,7 +88,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
- this->priv = (void *)offset;
+ nand_set_controller_data(this, (void *)offset);
}
if (cmd != NAND_CMD_NONE)
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index e288010..d80879c 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -63,7 +63,7 @@ static void __init keystone_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
-static phys_addr_t keystone_virt_to_idmap(unsigned long x)
+static unsigned long keystone_virt_to_idmap(unsigned long x)
{
return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START;
}
@@ -97,6 +97,9 @@ static long long __init keystone_pv_fixup(void)
}
static const char *const keystone_match[] __initconst = {
+ "ti,k2hk",
+ "ti,k2e",
+ "ti,k2l",
"ti,keystone",
NULL,
};
diff --git a/arch/arm/mach-keystone/keystone.h b/arch/arm/mach-keystone/keystone.h
index cd04a1c..33eaa03 100644
--- a/arch/arm/mach-keystone/keystone.h
+++ b/arch/arm/mach-keystone/keystone.h
@@ -15,7 +15,7 @@
#ifndef __ASSEMBLER__
-extern struct smp_operations keystone_smp_ops;
+extern const 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);
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
index 4bbb184..5665276 100644
--- a/arch/arm/mach-keystone/platsmp.c
+++ b/arch/arm/mach-keystone/platsmp.c
@@ -39,6 +39,6 @@ static int keystone_smp_boot_secondary(unsigned int cpu,
return error;
}
-struct smp_operations keystone_smp_ops __initdata = {
+const struct smp_operations keystone_smp_ops __initconst = {
.smp_boot_secondary = keystone_smp_boot_secondary,
};
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
index 9f9c044..e4d709c 100644
--- a/arch/arm/mach-ks8695/board-acs5k.c
+++ b/arch/arm/mach-ks8695/board-acs5k.c
@@ -33,7 +33,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/devices.h>
+#include "devices.h"
#include <mach/gpio-ks8695.h>
#include "generic.h"
diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c
index d37c218..13537e9 100644
--- a/arch/arm/mach-ks8695/board-dsm320.c
+++ b/arch/arm/mach-ks8695/board-dsm320.c
@@ -28,7 +28,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/devices.h>
+#include "devices.h"
#include <mach/gpio-ks8695.h>
#include "generic.h"
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
index 3acbdfd..69cfb99 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -19,7 +19,7 @@
#include <asm/mach/irq.h>
#include <mach/gpio-ks8695.h>
-#include <mach/devices.h>
+#include "devices.h"
#include "generic.h"
diff --git a/arch/arm/mach-ks8695/board-og.c b/arch/arm/mach-ks8695/board-og.c
index f265816..1f4f2f4 100644
--- a/arch/arm/mach-ks8695/board-og.c
+++ b/arch/arm/mach-ks8695/board-og.c
@@ -18,7 +18,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/devices.h>
+#include "devices.h"
#include <mach/regs-gpio.h>
#include <mach/gpio-ks8695.h>
#include "generic.h"
diff --git a/arch/arm/mach-ks8695/board-sg.c b/arch/arm/mach-ks8695/board-sg.c
index fdf2352..46e455c 100644
--- a/arch/arm/mach-ks8695/board-sg.c
+++ b/arch/arm/mach-ks8695/board-sg.c
@@ -16,7 +16,7 @@
#include <linux/mtd/partitions.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/devices.h>
+#include "devices.h"
#include "generic.h"
/*
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
index ddb2422..474a050 100644
--- a/arch/arm/mach-ks8695/cpu.c
+++ b/arch/arm/mach-ks8695/cpu.c
@@ -30,7 +30,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/regs-sys.h>
+#include "regs-sys.h"
#include <mach/regs-misc.h>
diff --git a/arch/arm/mach-ks8695/devices.c b/arch/arm/mach-ks8695/devices.c
index 47399bc..61cf20b 100644
--- a/arch/arm/mach-ks8695/devices.c
+++ b/arch/arm/mach-ks8695/devices.c
@@ -24,9 +24,9 @@
#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 "regs-wan.h"
+#include "regs-lan.h"
+#include "regs-hpna.h"
#include <mach/regs-switch.h>
#include <mach/regs-misc.h>
diff --git a/arch/arm/mach-ks8695/include/mach/devices.h b/arch/arm/mach-ks8695/devices.h
index 1e6594a..1e6594a 100644
--- a/arch/arm/mach-ks8695/include/mach/devices.h
+++ b/arch/arm/mach-ks8695/devices.h
diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h
index c089a1a..a001c7c 100644
--- a/arch/arm/mach-ks8695/include/mach/uncompress.h
+++ b/arch/arm/mach-ks8695/include/mach/uncompress.h
@@ -17,7 +17,7 @@
#include <linux/io.h>
#include <mach/regs-uart.h>
-static void putc(char c)
+static inline void putc(char c)
{
while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE))
barrier();
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index c1bc4c3..577a35f 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -33,8 +33,8 @@
#include <asm/mach/pci.h>
#include <mach/hardware.h>
-#include <mach/devices.h>
-#include <mach/regs-pci.h>
+#include "devices.h"
+#include "regs-pci.h"
static int pci_dbg;
diff --git a/arch/arm/mach-ks8695/include/mach/regs-hpna.h b/arch/arm/mach-ks8695/regs-hpna.h
index 815ce5c..815ce5c 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-hpna.h
+++ b/arch/arm/mach-ks8695/regs-hpna.h
diff --git a/arch/arm/mach-ks8695/include/mach/regs-lan.h b/arch/arm/mach-ks8695/regs-lan.h
index 82c5f37..82c5f37 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-lan.h
+++ b/arch/arm/mach-ks8695/regs-lan.h
diff --git a/arch/arm/mach-ks8695/include/mach/regs-mem.h b/arch/arm/mach-ks8695/regs-mem.h
index 55806bc..55806bc 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-mem.h
+++ b/arch/arm/mach-ks8695/regs-mem.h
diff --git a/arch/arm/mach-ks8695/include/mach/regs-pci.h b/arch/arm/mach-ks8695/regs-pci.h
index 75a9db6..75a9db6 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-pci.h
+++ b/arch/arm/mach-ks8695/regs-pci.h
diff --git a/arch/arm/mach-ks8695/include/mach/regs-sys.h b/arch/arm/mach-ks8695/regs-sys.h
index 57c20be..57c20be 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-sys.h
+++ b/arch/arm/mach-ks8695/regs-sys.h
diff --git a/arch/arm/mach-ks8695/include/mach/regs-wan.h b/arch/arm/mach-ks8695/regs-wan.h
index c475bed..c475bed 100644
--- a/arch/arm/mach-ks8695/include/mach/regs-wan.h
+++ b/arch/arm/mach-ks8695/regs-wan.h
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 77d6b1b..ee06fab 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -86,8 +86,8 @@ 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);
+ fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, PANEL_SIZE, &dma,
+ GFP_KERNEL);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
@@ -116,15 +116,14 @@ static int lpc32xx_clcd_setup(struct clcd_fb *fb)
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);
+ return dma_mmap_wc(&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);
+ dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
+ fb->fb.fix.smem_start);
}
/*
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index aeece17..0abcc51 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_MEDIATEK
- bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
+ bool "Mediatek MT65xx & MT81xx SoC"
+ depends on ARCH_MULTI_V7
select ARM_GIC
select PINCTRL
select MTK_TIMER
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 43e619f..2116460 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1 +1,4 @@
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+endif
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index a954900..2f9f09a 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -16,8 +16,35 @@
*/
#include <linux/init.h>
#include <asm/mach/arch.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+
+#define GPT6_CON_MT65xx 0x10008060
+#define GPT_ENABLE 0x31
+
+static void __init mediatek_timer_init(void)
+{
+ void __iomem *gpt_base;
+
+ if (of_machine_is_compatible("mediatek,mt6589") ||
+ of_machine_is_compatible("mediatek,mt8135") ||
+ of_machine_is_compatible("mediatek,mt8127")) {
+ /* turn on GPT6 which ungates arch timer clocks */
+ gpt_base = ioremap(GPT6_CON_MT65xx, 0x04);
+
+ /* enable clock and set to free-run */
+ writel(GPT_ENABLE, gpt_base);
+ iounmap(gpt_base);
+ }
+
+ of_clk_init(NULL);
+ clocksource_probe();
+};
static const char * const mediatek_board_dt_compat[] = {
+ "mediatek,mt2701",
"mediatek,mt6589",
"mediatek,mt6592",
"mediatek,mt8127",
@@ -27,4 +54,5 @@ static const char * const mediatek_board_dt_compat[] = {
DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
.dt_compat = mediatek_board_dt_compat,
+ .init_time = mediatek_timer_init,
MACHINE_END
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
new file mode 100644
index 0000000..a1b07ee
--- /dev/null
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -0,0 +1,141 @@
+/*
+ * arch/arm/mach-mediatek/platsmp.c
+ *
+ * Copyright (c) 2014 Mediatek Inc.
+ * Author: Shunli Wang <shunli.wang@mediatek.com>
+ * Yingjoe Chen <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 <linux/io.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/string.h>
+#include <linux/threads.h>
+
+#define MTK_MAX_CPU 8
+#define MTK_SMP_REG_SIZE 0x1000
+
+struct mtk_smp_boot_info {
+ unsigned long smp_base;
+ unsigned int jump_reg;
+ unsigned int core_keys[MTK_MAX_CPU - 1];
+ unsigned int core_regs[MTK_MAX_CPU - 1];
+};
+
+static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = {
+ 0x80002000, 0x3fc,
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
+ { 0x3f8, 0x3f8, 0x3f8 },
+};
+
+static const struct mtk_smp_boot_info mtk_mt6589_boot = {
+ 0x10002000, 0x34,
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
+ { 0x38, 0x3c, 0x40 },
+};
+
+static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
+ { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
+ { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
+};
+
+static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
+ { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot },
+};
+
+static void __iomem *mtk_smp_base;
+static const struct mtk_smp_boot_info *mtk_smp_info;
+
+static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ if (!mtk_smp_base)
+ return -EINVAL;
+
+ if (!mtk_smp_info->core_keys[cpu-1])
+ return -EINVAL;
+
+ writel_relaxed(mtk_smp_info->core_keys[cpu-1],
+ mtk_smp_base + mtk_smp_info->core_regs[cpu-1]);
+
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ return 0;
+}
+
+static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
+{
+ int i, num;
+ const struct of_device_id *infos;
+
+ if (trustzone) {
+ num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
+ infos = mtk_tz_smp_boot_infos;
+ } else {
+ num = ARRAY_SIZE(mtk_smp_boot_infos);
+ infos = mtk_smp_boot_infos;
+ }
+
+ /* Find smp boot info for this SoC */
+ for (i = 0; i < num; i++) {
+ if (of_machine_is_compatible(infos[i].compatible)) {
+ mtk_smp_info = infos[i].data;
+ break;
+ }
+ }
+
+ if (!mtk_smp_info) {
+ pr_err("%s: Device is not supported\n", __func__);
+ return;
+ }
+
+ if (trustzone) {
+ /* smp_base(trustzone-bootinfo) is reserved by device tree */
+ mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base);
+ } else {
+ mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE);
+ if (!mtk_smp_base) {
+ pr_err("%s: Can't remap %lx\n", __func__,
+ mtk_smp_info->smp_base);
+ return;
+ }
+ }
+
+ /*
+ * write the address of slave startup address into the system-wide
+ * jump register
+ */
+ writel_relaxed(virt_to_phys(secondary_startup_arm),
+ mtk_smp_base + mtk_smp_info->jump_reg);
+}
+
+static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus)
+{
+ __mtk_smp_prepare_cpus(max_cpus, 1);
+}
+
+static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
+{
+ __mtk_smp_prepare_cpus(max_cpus, 0);
+}
+
+static const struct smp_operations mt81xx_tz_smp_ops __initconst = {
+ .smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
+ .smp_boot_secondary = mtk_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);
+
+static const struct smp_operations mt6589_smp_ops __initconst = {
+ .smp_prepare_cpus = mtk_smp_prepare_cpus,
+ .smp_boot_secondary = mtk_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 0743e20..31bdd91 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_MESON
- bool "Amlogic Meson SoCs" if ARCH_MULTI_V7
+ bool "Amlogic Meson SoCs"
+ depends on ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
select GENERIC_IRQ_CHIP
select ARM_GIC
@@ -19,4 +20,9 @@ config MACH_MESON8
default ARCH_MESON
select MESON6_TIMER
+config MACH_MESON8B
+ bool "Amlogic Meson8b SoCs support"
+ default ARCH_MESON
+ select MESON6_TIMER
+
endif
diff --git a/arch/arm/mach-meson/meson.c b/arch/arm/mach-meson/meson.c
index 5d6affe..4e23571 100644
--- a/arch/arm/mach-meson/meson.c
+++ b/arch/arm/mach-meson/meson.c
@@ -19,6 +19,7 @@
static const char * const meson_common_board_compat[] = {
"amlogic,meson6",
"amlogic,meson8",
+ "amlogic,meson8b",
NULL,
};
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index fdbfadf..01c57d3 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -1,9 +1,22 @@
+menuconfig ARCH_MMP
+ bool "Marvell PXA168/910/MMP2"
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_PXA
+ select PINCTRL
+ select PLAT_PXA
+ help
+ Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+
if ARCH_MMP
-menu "Marvell PXA168/910/MMP2 Implmentations"
+menu "Marvell PXA168/910/MMP2 Implementations"
+
+if ATAGS
config MACH_ASPENITE
bool "Marvell's PXA168 Aspenite Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
@@ -11,6 +24,7 @@ config MACH_ASPENITE
config MACH_ZYLONITE2
bool "Marvell's PXA168 Zylonite2 Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
@@ -18,6 +32,7 @@ config MACH_ZYLONITE2
config MACH_AVENGERS_LITE
bool "Marvell's PXA168 Avengers Lite Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
@@ -25,6 +40,7 @@ config MACH_AVENGERS_LITE
config MACH_TAVOREVB
bool "Marvell's PXA910 TavorEVB Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA910
help
Say 'Y' here if you want to support the Marvell PXA910-based
@@ -32,6 +48,7 @@ config MACH_TAVOREVB
config MACH_TTC_DKB
bool "Marvell's PXA910 TavorEVB Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA910
help
Say 'Y' here if you want to support the Marvell PXA910-based
@@ -39,7 +56,7 @@ config MACH_TTC_DKB
config MACH_BROWNSTONE
bool "Marvell's Brownstone Development Platform"
- depends on !CPU_MOHAWK
+ depends on ARCH_MULTI_V7
select CPU_MMP2
help
Say 'Y' here if you want to support the Marvell MMP2-based
@@ -50,7 +67,7 @@ config MACH_BROWNSTONE
config MACH_FLINT
bool "Marvell's Flint Development Platform"
- depends on !CPU_MOHAWK
+ depends on ARCH_MULTI_V7
select CPU_MMP2
help
Say 'Y' here if you want to support the Marvell MMP2-based
@@ -61,7 +78,7 @@ config MACH_FLINT
config MACH_MARVELL_JASPER
bool "Marvell's Jasper Development Platform"
- depends on !CPU_MOHAWK
+ depends on ARCH_MULTI_V7
select CPU_MMP2
help
Say 'Y' here if you want to support the Marvell MMP2-base
@@ -72,6 +89,7 @@ config MACH_MARVELL_JASPER
config MACH_TETON_BGA
bool "Marvell's PXA168 Teton BGA Development Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
@@ -79,14 +97,16 @@ config MACH_TETON_BGA
config MACH_GPLUGD
bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
+ depends on ARCH_MULTI_V5
select CPU_PXA168
help
Say 'Y' here if you want to support the Marvell PXA168-based
GuruPlug Display (gplugD) Board
+endif
config MACH_MMP_DT
bool "Support MMP (ARMv5) platforms from device tree"
- select USE_OF
+ depends on ARCH_MULTI_V5
select PINCTRL
select PINCTRL_SINGLE
select COMMON_CLK
@@ -99,11 +119,9 @@ config MACH_MMP_DT
config MACH_MMP2_DT
bool "Support MMP2 (ARMv7) platforms from device tree"
- depends on !CPU_MOHAWK
- select USE_OF
+ depends on ARCH_MULTI_V7
select PINCTRL
select PINCTRL_SINGLE
- select COMMON_CLK
select ARCH_HAS_RESET_CONTROLLER
select CPU_PJ4
help
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 98f0f63..7677ad5 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -1,6 +1,7 @@
#
# Makefile for Marvell's PXA168 processors line
#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-pxa/include
obj-y += common.o devices.o time.o
diff --git a/arch/arm/mach-mmp/addr-map.h b/arch/arm/mach-mmp/addr-map.h
new file mode 100644
index 0000000..2739d27
--- /dev/null
+++ b/arch/arm/mach-mmp/addr-map.h
@@ -0,0 +1,44 @@
+/*
+ * 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/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 7e02485..5db0edf 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -22,14 +22,14 @@
#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 "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "irqs.h"
#include "common.h"
static unsigned long common_pin_config[] __initdata = {
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index a451a0f..3d2aea8 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -17,10 +17,10 @@
#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 "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "irqs.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index ac25544..d1613b9 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -22,10 +22,10 @@
#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 "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
+#include "irqs.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/clock-mmp2.c b/arch/arm/mach-mmp/clock-mmp2.c
index 53d77cb..835c3e7 100644
--- a/arch/arm/mach-mmp/clock-mmp2.c
+++ b/arch/arm/mach-mmp/clock-mmp2.c
@@ -4,8 +4,9 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/clk/mmp.h>
-#include <mach/addr-map.h>
+#include "addr-map.h"
#include "common.h"
#include "clock.h"
@@ -105,7 +106,8 @@ static struct clk_lookup mmp2_clkregs[] = {
INIT_CLKREG(&clk_sdh3, "sdhci-pxav3.3", "PXA-SDHCLK"),
};
-void __init mmp2_clk_init(void)
+void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+ phys_addr_t apbc_phys)
{
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
index c572f21..f726a36 100644
--- a/arch/arm/mach-mmp/clock-pxa168.c
+++ b/arch/arm/mach-mmp/clock-pxa168.c
@@ -4,8 +4,9 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/clk/mmp.h>
-#include <mach/addr-map.h>
+#include "addr-map.h"
#include "common.h"
#include "clock.h"
@@ -85,7 +86,8 @@ static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
};
-void __init pxa168_clk_init(void)
+void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+ phys_addr_t apbc_phys)
{
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
index 379e1df..bca60a2 100644
--- a/arch/arm/mach-mmp/clock-pxa910.c
+++ b/arch/arm/mach-mmp/clock-pxa910.c
@@ -4,8 +4,9 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/clk/mmp.h>
-#include <mach/addr-map.h>
+#include "addr-map.h"
#include "common.h"
#include "clock.h"
@@ -61,7 +62,8 @@ static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
};
-void __init pxa910_clk_init(void)
+void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
+ phys_addr_t apbc_phys, phys_addr_t apbcp_phys)
{
clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
}
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
index 7c6f95f..ac6633d 100644
--- a/arch/arm/mach-mmp/clock.c
+++ b/arch/arm/mach-mmp/clock.c
@@ -13,7 +13,7 @@
#include <linux/clk.h>
#include <linux/io.h>
-#include <mach/regs-apbc.h>
+#include "regs-apbc.h"
#include "clock.h"
static void apbc_clk_enable(struct clk *clk)
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 149b30c..8194445 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -1,6 +1,4 @@
/*
- * 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.
diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c
index c03b4ab..685a099 100644
--- a/arch/arm/mach-mmp/common.c
+++ b/arch/arm/mach-mmp/common.c
@@ -15,8 +15,8 @@
#include <asm/page.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
-#include <mach/addr-map.h>
-#include <mach/cputype.h>
+#include "addr-map.h"
+#include "cputype.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index cf445ba..7453a90 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -5,6 +5,3 @@ 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/include/mach/cputype.h b/arch/arm/mach-mmp/cputype.h
index 8a3b56d..8a3b56d 100644
--- a/arch/arm/mach-mmp/include/mach/cputype.h
+++ b/arch/arm/mach-mmp/cputype.h
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
index 2bcb766..3330ac7 100644
--- a/arch/arm/mach-mmp/devices.c
+++ b/arch/arm/mach-mmp/devices.c
@@ -12,10 +12,10 @@
#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>
+#include "irqs.h"
+#include "devices.h"
+#include "cputype.h"
+#include "regs-usb.h"
int __init pxa_register_device(struct pxa_device_desc *desc,
void *data, size_t size)
@@ -73,6 +73,8 @@ int __init pxa_register_device(struct pxa_device_desc *desc,
}
#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
+#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
/*****************************************************************************
* The registers read/write routines
@@ -112,9 +114,6 @@ static void u2o_write(void __iomem *base, unsigned int 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;
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/devices.h
index 21217ef..21217ef 100644
--- a/arch/arm/mach-mmp/include/mach/devices.h
+++ b/arch/arm/mach-mmp/devices.h
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 6291c33..078b980 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -21,10 +21,10 @@
#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 "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
+#include "irqs.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 22762a1..c224119 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -16,9 +16,9 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/irqs.h>
-#include <mach/pxa168.h>
-#include <mach/mfp-pxa168.h>
+#include "irqs.h"
+#include "pxa168.h"
+#include "mfp-pxa168.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h
deleted file mode 100644
index f88a44c..0000000
--- a/arch/arm/mach-mmp/include/mach/addr-map.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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/dma.h b/arch/arm/mach-mmp/include/mach/dma.h
deleted file mode 100644
index 1d69145..0000000
--- a/arch/arm/mach-mmp/include/mach/dma.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 99264a5..0000000
--- a/arch/arm/mach-mmp/include/mach/hardware.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __ASM_MACH_HARDWARE_H
-#define __ASM_MACH_HARDWARE_H
-
-#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
deleted file mode 100644
index 4ad3862..0000000
--- a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
+++ /dev/null
@@ -1,395 +0,0 @@
-#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
deleted file mode 100644
index 92aaa3c..0000000
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ /dev/null
@@ -1,354 +0,0 @@
-#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
deleted file mode 100644
index 8c78f2b1..0000000
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
+++ /dev/null
@@ -1,169 +0,0 @@
-#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/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
deleted file mode 100644
index 0764f4e..0000000
--- a/arch/arm/mach-mmp/include/mach/mmp2.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#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
deleted file mode 100644
index 98bd66c..0000000
--- a/arch/arm/mach-mmp/include/mach/pm-mmp2.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
deleted file mode 100644
index a83ba7c..0000000
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#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
deleted file mode 100644
index 9225320..0000000
--- a/arch/arm/mach-mmp/include/mach/pxa910.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#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
deleted file mode 100644
index ddc812f..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-apbc.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 93c8d0e..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f882d91..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-icu.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/regs-icu.h
- *
- * Interrupt Control Unit
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_MACH_ICU_H
-#define __ASM_MACH_ICU_H
-
-#include <mach/addr-map.h>
-
-#define ICU_VIRT_BASE (AXI_VIRT_BASE + 0x82000)
-#define ICU_REG(x) (ICU_VIRT_BASE + (x))
-
-#define ICU_INT_CONF(n) ICU_REG((n) << 2)
-#define ICU_INT_CONF_MASK (0xf)
-
-/************ PXA168/PXA910 (MMP) *********************/
-#define ICU_INT_CONF_AP_INT (1 << 6)
-#define ICU_INT_CONF_CP_INT (1 << 5)
-#define ICU_INT_CONF_IRQ (1 << 4)
-
-#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108) /* AP FIQ Selected Interrupt */
-#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C) /* AP IRQ Selected Interrupt */
-#define ICU_AP_GBL_IRQ_MSK ICU_REG(0x114) /* AP Global Interrupt Mask */
-#define ICU_INT_STATUS_0 ICU_REG(0x128) /* Interrupt Stuats 0 */
-#define ICU_INT_STATUS_1 ICU_REG(0x12C) /* Interrupt Status 1 */
-
-/************************** MMP2 ***********************/
-
-/*
- * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
- * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
- */
-#define ICU_INT_ROUTE_SP_IRQ (1 << 4)
-#define ICU_INT_ROUTE_PJ4_IRQ (1 << 5)
-#define ICU_INT_ROUTE_PJ4_FIQ (1 << 6)
-
-#define MMP2_ICU_PJ4_IRQ_STATUS0 ICU_REG(0x138)
-#define MMP2_ICU_PJ4_IRQ_STATUS1 ICU_REG(0x13c)
-#define MMP2_ICU_PJ4_FIQ_STATUS0 ICU_REG(0x140)
-#define MMP2_ICU_PJ4_FIQ_STATUS1 ICU_REG(0x144)
-
-#define MMP2_ICU_INT4_STATUS ICU_REG(0x150)
-#define MMP2_ICU_INT5_STATUS ICU_REG(0x154)
-#define MMP2_ICU_INT17_STATUS ICU_REG(0x158)
-#define MMP2_ICU_INT35_STATUS ICU_REG(0x15c)
-#define MMP2_ICU_INT51_STATUS ICU_REG(0x160)
-
-#define MMP2_ICU_INT4_MASK ICU_REG(0x168)
-#define MMP2_ICU_INT5_MASK ICU_REG(0x16C)
-#define MMP2_ICU_INT17_MASK ICU_REG(0x170)
-#define MMP2_ICU_INT35_MASK ICU_REG(0x174)
-#define MMP2_ICU_INT51_MASK ICU_REG(0x178)
-
-#define MMP2_ICU_SP_IRQ_SEL ICU_REG(0x100)
-#define MMP2_ICU_PJ4_IRQ_SEL ICU_REG(0x104)
-#define MMP2_ICU_PJ4_FIQ_SEL ICU_REG(0x108)
-
-#define MMP2_ICU_INVERT ICU_REG(0x164)
-
-#define MMP2_ICU_INV_PMIC (1 << 0)
-#define MMP2_ICU_INV_PERF (1 << 1)
-#define MMP2_ICU_INV_COMMTX (1 << 2)
-#define MMP2_ICU_INV_COMMRX (1 << 3)
-
-#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
deleted file mode 100644
index e484d40..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-smc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 45589fe..0000000
--- a/arch/arm/mach-mmp/include/mach/regs-timers.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h
deleted file mode 100644
index 61a539b..0000000
--- a/arch/arm/mach-mmp/include/mach/teton_bga.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8890fa8..0000000
--- a/arch/arm/mach-mmp/include/mach/uncompress.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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/include/mach/irqs.h b/arch/arm/mach-mmp/irqs.h
index fb492a5..fb492a5 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/irqs.h
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index 0e9e5c05..5dbb753 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -20,12 +20,12 @@
#include <linux/mfd/max8925.h>
#include <linux/interrupt.h>
-#include <mach/irqs.h>
+#include "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 "addr-map.h"
+#include "mfp-mmp2.h"
+#include "mmp2.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/mfp-mmp2.h b/arch/arm/mach-mmp/mfp-mmp2.h
new file mode 100644
index 0000000..b274434
--- /dev/null
+++ b/arch/arm/mach-mmp/mfp-mmp2.h
@@ -0,0 +1,395 @@
+#ifndef __ASM_MACH_MFP_MMP2_H
+#define __ASM_MACH_MFP_MMP2_H
+
+#include "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/mfp-pxa168.h b/arch/arm/mach-mmp/mfp-pxa168.h
new file mode 100644
index 0000000..9050d03
--- /dev/null
+++ b/arch/arm/mach-mmp/mfp-pxa168.h
@@ -0,0 +1,354 @@
+#ifndef __ASM_MACH_MFP_PXA168_H
+#define __ASM_MACH_MFP_PXA168_H
+
+#include "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/mfp-pxa910.h b/arch/arm/mach-mmp/mfp-pxa910.h
new file mode 100644
index 0000000..f06db5c
--- /dev/null
+++ b/arch/arm/mach-mmp/mfp-pxa910.h
@@ -0,0 +1,169 @@
+#ifndef __ASM_MACH_MFP_PXA910_H
+#define __ASM_MACH_MFP_PXA910_H
+
+#include "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/mfp.h
index 62e510e..62e510e 100644
--- a/arch/arm/mach-mmp/include/mach/mfp.h
+++ b/arch/arm/mach-mmp/mfp.h
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index a70b553..afba546 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -9,6 +9,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/clk/mmp.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -20,15 +21,14 @@
#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 "addr-map.h"
+#include "regs-apbc.h"
+#include "cputype.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "devices.h"
+#include "mmp2.h"
+#include "pm-mmp2.h"
#include "common.h"
@@ -110,8 +110,9 @@ static int __init mmp2_init(void)
#endif
mfp_init_base(MFPR_VIRT_BASE);
mfp_init_addr(mmp2_addr_map);
- pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
- mmp2_clk_init();
+ mmp2_clk_init(APB_PHYS_BASE + 0x50000,
+ AXI_PHYS_BASE + 0x82800,
+ APB_PHYS_BASE + 0x15000);
}
return 0;
diff --git a/arch/arm/mach-mmp/mmp2.h b/arch/arm/mach-mmp/mmp2.h
new file mode 100644
index 0000000..9b5e75e
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2.h
@@ -0,0 +1,103 @@
+#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 <linux/platform_data/dma-mmp_tdma.h>
+
+#include "devices.h"
+
+extern struct pxa_device_desc mmp2_device_uart1;
+extern struct pxa_device_desc mmp2_device_uart2;
+extern struct pxa_device_desc mmp2_device_uart3;
+extern struct pxa_device_desc mmp2_device_uart4;
+extern struct pxa_device_desc mmp2_device_twsi1;
+extern struct pxa_device_desc mmp2_device_twsi2;
+extern struct pxa_device_desc mmp2_device_twsi3;
+extern struct pxa_device_desc mmp2_device_twsi4;
+extern struct pxa_device_desc mmp2_device_twsi5;
+extern struct pxa_device_desc mmp2_device_twsi6;
+extern struct pxa_device_desc mmp2_device_sdh0;
+extern struct pxa_device_desc mmp2_device_sdh1;
+extern struct pxa_device_desc mmp2_device_sdh2;
+extern struct pxa_device_desc mmp2_device_sdh3;
+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/pm-mmp2.c b/arch/arm/mach-mmp/pm-mmp2.c
index 43b1a51..17699be 100644
--- a/arch/arm/mach-mmp/pm-mmp2.c
+++ b/arch/arm/mach-mmp/pm-mmp2.c
@@ -18,12 +18,12 @@
#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>
+
+#include "cputype.h"
+#include "addr-map.h"
+#include "pm-mmp2.h"
+#include "regs-icu.h"
+#include "irqs.h"
int mmp2_set_wake(struct irq_data *d, unsigned int on)
{
diff --git a/arch/arm/mach-mmp/pm-mmp2.h b/arch/arm/mach-mmp/pm-mmp2.h
new file mode 100644
index 0000000..486e059
--- /dev/null
+++ b/arch/arm/mach-mmp/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 "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/pm-pxa910.c b/arch/arm/mach-mmp/pm-pxa910.c
index 7db5870..8b47600 100644
--- a/arch/arm/mach-mmp/pm-pxa910.c
+++ b/arch/arm/mach-mmp/pm-pxa910.c
@@ -19,12 +19,12 @@
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <asm/outercache.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>
+
+#include "cputype.h"
+#include "addr-map.h"
+#include "pm-pxa910.h"
+#include "regs-icu.h"
+#include "irqs.h"
int pxa910_set_wake(struct irq_data *data, unsigned int on)
{
diff --git a/arch/arm/mach-mmp/include/mach/pm-pxa910.h b/arch/arm/mach-mmp/pm-pxa910.h
index 8cac8ab..8cac8ab 100644
--- a/arch/arm/mach-mmp/include/mach/pm-pxa910.h
+++ b/arch/arm/mach-mmp/pm-pxa910.h
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 144e997..0f5f16f 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -13,25 +13,25 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/clk/mmp.h>
#include <linux/platform_device.h>
#include <linux/platform_data/mv_usb.h>
+#include <linux/dma-mapping.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 "addr-map.h"
#include "clock.h"
+#include "common.h"
+#include "cputype.h"
+#include "devices.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "pxa168.h"
+#include "regs-apbc.h"
+#include "regs-apmu.h"
+#include "regs-usb.h"
#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
@@ -55,8 +55,9 @@ 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();
+ pxa168_clk_init(APB_PHYS_BASE + 0x50000,
+ AXI_PHYS_BASE + 0x82800,
+ APB_PHYS_BASE + 0x15000);
}
return 0;
diff --git a/arch/arm/mach-mmp/pxa168.h b/arch/arm/mach-mmp/pxa168.h
new file mode 100644
index 0000000..75841e9
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa168.h
@@ -0,0 +1,138 @@
+#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 <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/pxa168fb.h>
+#include <linux/platform_data/keypad-pxa27x.h>
+#include <linux/pxa168_eth.h>
+#include <linux/platform_data/mv_usb.h>
+
+#include "devices.h"
+#include "cputype.h"
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_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/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index eb57ee1..1ccbba9 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/clk/mmp.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -18,15 +19,14 @@
#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 "addr-map.h"
+#include "regs-apbc.h"
+#include "cputype.h"
+#include "irqs.h"
+#include "mfp.h"
+#include "devices.h"
+#include "pm-pxa910.h"
+#include "pxa910.h"
#include "common.h"
@@ -96,8 +96,10 @@ static int __init pxa910_init(void)
#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();
+ pxa910_clk_init(APB_PHYS_BASE + 0x50000,
+ AXI_PHYS_BASE + 0x82800,
+ APB_PHYS_BASE + 0x15000,
+ APB_PHYS_BASE + 0x3b000);
}
return 0;
diff --git a/arch/arm/mach-mmp/pxa910.h b/arch/arm/mach-mmp/pxa910.h
new file mode 100644
index 0000000..a211e81e
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa910.h
@@ -0,0 +1,88 @@
+#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 <linux/platform_data/mtd-nand-pxa3xx.h>
+#include <video/mmp_disp.h>
+
+#include "devices.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/regs-apbc.h b/arch/arm/mach-mmp/regs-apbc.h
new file mode 100644
index 0000000..704bcae
--- /dev/null
+++ b/arch/arm/mach-mmp/regs-apbc.h
@@ -0,0 +1,22 @@
+/*
+ * 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 "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/regs-apmu.h b/arch/arm/mach-mmp/regs-apmu.h
new file mode 100644
index 0000000..23f6209
--- /dev/null
+++ b/arch/arm/mach-mmp/regs-apmu.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "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/regs-icu.h b/arch/arm/mach-mmp/regs-icu.h
new file mode 100644
index 0000000..0328abe
--- /dev/null
+++ b/arch/arm/mach-mmp/regs-icu.h
@@ -0,0 +1,69 @@
+/*
+ * 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 "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/regs-timers.h b/arch/arm/mach-mmp/regs-timers.h
new file mode 100644
index 0000000..d3611c0
--- /dev/null
+++ b/arch/arm/mach-mmp/regs-timers.h
@@ -0,0 +1,42 @@
+/*
+ * 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 "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/regs-usb.h
index b047bf4..b047bf4 100644
--- a/arch/arm/mach-mmp/include/mach/regs-usb.h
+++ b/arch/arm/mach-mmp/regs-usb.h
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index cdfc9bf..efe35fa 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -16,10 +16,10 @@
#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 "addr-map.h"
+#include "mfp-pxa910.h"
+#include "pxa910.h"
+#include "irqs.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 6aa53fb..cf038eb 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -23,11 +23,11 @@
#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 "addr-map.h"
+#include "mfp-pxa168.h"
+#include "pxa168.h"
+#include "teton_bga.h"
+#include "irqs.h"
#include "common.h"
diff --git a/arch/arm/mach-mmp/teton_bga.h b/arch/arm/mach-mmp/teton_bga.h
new file mode 100644
index 0000000..019730f
--- /dev/null
+++ b/arch/arm/mach-mmp/teton_bga.h
@@ -0,0 +1,25 @@
+/*
+ * 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/time.c b/arch/arm/mach-mmp/time.c
index dbc697b..3c2c92a 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -29,14 +29,13 @@
#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 "addr-map.h"
+#include "regs-timers.h"
+#include "regs-apbc.h"
+#include "irqs.h"
+#include "cputype.h"
#include "clock.h"
#ifdef CONFIG_CPU_MMP2
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index ac4af81..d90c74f 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -26,11 +26,11 @@
#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 "addr-map.h"
+#include "mfp-pxa910.h"
+#include "pxa910.h"
+#include "irqs.h"
+#include "regs-usb.h"
#include "common.h"
diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
index f49328c..180d9d2 100644
--- a/arch/arm/mach-moxart/Kconfig
+++ b/arch/arm/mach-moxart/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_MOXART
- bool "MOXA ART SoC" if ARCH_MULTI_V4
+ bool "MOXA ART SoC"
+ depends on ARCH_MULTI_V4
select CPU_FA526
select ARM_DMA_MEM_BUFFERABLE
select CLKSRC_MMIO
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
index f2d309d..a32575f 100644
--- a/arch/arm/mach-mv78xx0/Kconfig
+++ b/arch/arm/mach-mv78xx0/Kconfig
@@ -1,6 +1,15 @@
-if ARCH_MV78XX0
+menuconfig ARCH_MV78XX0
+ bool "Marvell MV78xx0" if ARCH_MULTI_V5
+ select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
+ select MVEBU_MBUS
+ select PCI
+ select PLAT_ORION_LEGACY
+ help
+ Support for the following Marvell MV78xx0 series SoCs:
+ MV781x0, MV782x0.
-menu "Marvell MV78xx0 Implementations"
+if ARCH_MV78XX0
config MACH_DB78X00_BP
bool "Marvell DB-78x00-BP Development Board"
@@ -20,6 +29,4 @@ config MACH_TERASTATION_WXL
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
index 7cd0463..ddb3aa9 100644
--- a/arch/arm/mach-mv78xx0/Makefile
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include
+
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
diff --git a/arch/arm/mach-mv78xx0/bridge-regs.h b/arch/arm/mach-mv78xx0/bridge-regs.h
new file mode 100644
index 0000000..2f54e17
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/bridge-regs.h
@@ -0,0 +1,35 @@
+/*
+ * This file is licensed under the terms 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 "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/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
index 1f2ef98..e112f2e 100644
--- a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -17,9 +17,9 @@
#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 "mv78xx0.h"
#include "common.h"
#include "mpp.h"
@@ -146,6 +146,7 @@ subsys_initcall(wxl_pci_init);
MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
/* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
.atag_offset = 0x100,
+ .nr_irqs = MV78XX0_NR_IRQS,
.init_machine = wxl_init,
.map_io = mv78xx0_map_io,
.init_early = mv78xx0_init_early,
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index e6ac679..a1a04df 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -18,13 +18,13 @@
#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 "mv78xx0.h"
+#include "bridge-regs.h"
#include "common.h"
static int get_tclk(void);
diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
index 4e0f22b..cf16e08 100644
--- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
+++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
@@ -15,9 +15,9 @@
#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 "mv78xx0.h"
#include "common.h"
static struct mv643xx_eth_platform_data db78x00_ge00_data = {
@@ -94,6 +94,7 @@ subsys_initcall(db78x00_pci_init);
MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = MV78XX0_NR_IRQS,
.init_machine = db78x00_init,
.map_io = mv78xx0_map_io,
.init_early = mv78xx0_init_early,
diff --git a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
deleted file mode 100644
index e20d6da..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6b1f088..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 67cab0a..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/hardware.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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
deleted file mode 100644
index fa1d422..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/irqs.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 723748d..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6a761c4..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/uncompress.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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
index 3207344..788569e 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -11,9 +11,10 @@
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <mach/bridge-regs.h>
+#include <asm/exception.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
+#include "bridge-regs.h"
#include "common.h"
static int __initdata gpio0_irqs[4] = {
@@ -23,12 +24,44 @@ static int __initdata gpio0_irqs[4] = {
IRQ_MV78XX0_GPIO_24_31,
};
+static void __iomem *mv78xx0_irq_base = IRQ_VIRT_BASE;
+
+static asmlinkage void
+__exception_irq_entry mv78xx0_legacy_handle_irq(struct pt_regs *regs)
+{
+ u32 stat;
+
+ stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_LOW_OFF);
+ stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_LOW_OFF);
+ if (stat) {
+ unsigned int hwirq = __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+ stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_HIGH_OFF);
+ stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_HIGH_OFF);
+ if (stat) {
+ unsigned int hwirq = 32 + __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+ stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_ERR_OFF);
+ stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_ERR_OFF);
+ if (stat) {
+ unsigned int hwirq = 64 + __fls(stat);
+ handle_IRQ(hwirq, regs);
+ return;
+ }
+}
+
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);
+ set_handle_irq(mv78xx0_legacy_handle_irq);
+
/*
* Initialize gpiolib for GPIOs 0-31. (The GPIO interrupt mask
* registers for core #1 are at an offset of 0x18 from those of
diff --git a/arch/arm/mach-mv78xx0/irqs.h b/arch/arm/mach-mv78xx0/irqs.h
new file mode 100644
index 0000000..67e0fe7
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/irqs.h
@@ -0,0 +1,92 @@
+/*
+ * 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 MV78XX0_NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
index df50342..72843c0 100644
--- a/arch/arm/mach-mv78xx0/mpp.c
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <plat/mpp.h>
-#include <mach/hardware.h>
+#include "mv78xx0.h"
#include "common.h"
#include "mpp.h"
diff --git a/arch/arm/mach-mv78xx0/mv78xx0.h b/arch/arm/mach-mv78xx0/mv78xx0.h
new file mode 100644
index 0000000..2db1265
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mv78xx0.h
@@ -0,0 +1,127 @@
+/*
+ * 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
+
+#include "irqs.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/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index 097ea4c..13a7d72 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -15,7 +15,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
-#include <mach/mv78xx0.h>
+#include "mv78xx0.h"
#include "common.h"
#define MV78XX0_MBUS_PCIE_MEM_TARGET(port, lane) ((port) ? 8 : 4)
diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
index d2d06f3..308ab71e 100644
--- a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
+++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
@@ -14,9 +14,9 @@
#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 "mv78xx0.h"
#include "common.h"
static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
@@ -79,6 +79,7 @@ subsys_initcall(rd78x00_pci_init);
MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = MV78XX0_NR_IRQS,
.init_machine = rd78x00_masa_init,
.map_io = mv78xx0_map_io,
.init_early = mv78xx0_init_early,
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index c86a5a0..b003e3a 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -1,8 +1,8 @@
menuconfig ARCH_MVEBU
- bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5)
+ bool "Marvell Engineering Business Unit (MVEBU) SoCs"
+ depends on 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
@@ -25,8 +25,10 @@ config MACH_MVEBU_V7
select MACH_MVEBU_ANY
config MACH_ARMADA_370
- bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
+ bool "Marvell Armada 370 boards"
+ depends on ARCH_MULTI_V7
select ARMADA_370_CLK
+ select ARMADA_370_XP_IRQ
select CPU_PJ4B
select MACH_MVEBU_V7
select PINCTRL_ARMADA_370
@@ -35,7 +37,9 @@ config MACH_ARMADA_370
on the Marvell Armada 370 SoC with device tree.
config MACH_ARMADA_375
- bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
+ bool "Marvell Armada 375 boards"
+ depends on ARCH_MULTI_V7
+ select ARMADA_370_XP_IRQ
select ARM_ERRATA_720789
select ARM_ERRATA_753970
select ARM_GIC
@@ -50,10 +54,12 @@ config MACH_ARMADA_375
on the Marvell Armada 375 SoC with device tree.
config MACH_ARMADA_38X
- bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
+ bool "Marvell Armada 380/385 boards"
+ depends on ARCH_MULTI_V7
select ARM_ERRATA_720789
select ARM_ERRATA_753970
select ARM_GIC
+ select ARMADA_370_XP_IRQ
select ARMADA_38X_CLK
select HAVE_ARM_SCU
select HAVE_ARM_TWD if SMP
@@ -65,8 +71,10 @@ config MACH_ARMADA_38X
on the Marvell Armada 380/385 SoC with device tree.
config MACH_ARMADA_39X
- bool "Marvell Armada 39x boards" if ARCH_MULTI_V7
+ bool "Marvell Armada 39x boards"
+ depends on ARCH_MULTI_V7
select ARM_GIC
+ select ARMADA_370_XP_IRQ
select ARMADA_39X_CLK
select CACHE_L2X0
select HAVE_ARM_SCU
@@ -79,7 +87,9 @@ config MACH_ARMADA_39X
on the Marvell Armada 39x SoC with device tree.
config MACH_ARMADA_XP
- bool "Marvell Armada XP boards" if ARCH_MULTI_V7
+ bool "Marvell Armada XP boards"
+ depends on ARCH_MULTI_V7
+ select ARMADA_370_XP_IRQ
select ARMADA_XP_CLK
select CPU_PJ4B
select MACH_MVEBU_V7
@@ -89,7 +99,8 @@ config MACH_ARMADA_XP
on the Marvell Armada XP SoC with device tree.
config MACH_DOVE
- bool "Marvell Dove boards" if ARCH_MULTI_V7
+ bool "Marvell Dove boards"
+ depends on ARCH_MULTI_V7
select CACHE_L2X0
select CPU_PJ4
select DOVE_CLK
@@ -103,7 +114,8 @@ config MACH_DOVE
Marvell Dove using flattened device tree.
config MACH_KIRKWOOD
- bool "Marvell Kirkwood boards" if ARCH_MULTI_V5
+ bool "Marvell Kirkwood boards"
+ depends on ARCH_MULTI_V5
select ARCH_REQUIRE_GPIOLIB
select CPU_FEROCEON
select KIRKWOOD_CLK
@@ -117,11 +129,4 @@ config MACH_KIRKWOOD
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
index b4f0149..ecf9e0c 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -13,4 +13,3 @@ 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
index c55bbf8..09413b6 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -17,7 +17,7 @@
#ifdef CONFIG_SMP
void armada_xp_secondary_startup(void);
-extern struct smp_operations armada_xp_smp_ops;
+extern const 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
index 9f739f3..1648edd 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -22,7 +22,6 @@
#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>
@@ -105,27 +104,6 @@ static void __init mvebu_memblock_reserve(void)
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();
@@ -134,17 +112,6 @@ static void __init mvebu_init_irq(void)
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;
@@ -177,8 +144,6 @@ 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);
}
diff --git a/arch/arm/mach-mvebu/board.h b/arch/arm/mach-mvebu/board.h
deleted file mode 100644
index 98e32cc..0000000
--- a/arch/arm/mach-mvebu/board.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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
index 44eedf3..55348ee 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -40,6 +40,7 @@
unsigned long coherency_phys_base;
void __iomem *coherency_base;
static void __iomem *coherency_cpu_base;
+static void __iomem *cpu_config_base;
/* Coherency fabric registers */
#define IO_SYNC_BARRIER_CTL_OFFSET 0x0
@@ -65,6 +66,31 @@ static const struct of_device_id of_coherency_table[] = {
int ll_enable_coherency(void);
void ll_add_cpu_to_smp_group(void);
+#define CPU_CONFIG_SHARED_L2 BIT(16)
+
+/*
+ * Disable the "Shared L2 Present" bit in CPU Configuration register
+ * on Armada XP.
+ *
+ * The "Shared L2 Present" bit affects the "level of coherence" value
+ * in the clidr CP15 register. Cache operation functions such as
+ * "flush all" and "invalidate all" operate on all the cache levels
+ * that included in the defined level of coherence. When HW I/O
+ * coherency is used, this bit causes unnecessary flushes of the L2
+ * cache.
+ */
+static void armada_xp_clear_shared_l2(void)
+{
+ u32 reg;
+
+ if (!cpu_config_base)
+ return;
+
+ reg = readl(cpu_config_base);
+ reg &= ~CPU_CONFIG_SHARED_L2;
+ writel(reg, cpu_config_base);
+}
+
static int mvebu_hwcc_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
@@ -85,9 +111,24 @@ static struct notifier_block mvebu_hwcc_pci_nb = {
.notifier_call = mvebu_hwcc_notifier,
};
+static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+ armada_xp_clear_shared_l2();
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block armada_xp_clear_shared_l2_notifier = {
+ .notifier_call = armada_xp_clear_shared_l2_notifier_func,
+ .priority = 100,
+};
+
static void __init armada_370_coherency_init(struct device_node *np)
{
struct resource res;
+ struct device_node *cpu_config_np;
of_address_to_resource(np, 0, &res);
coherency_phys_base = res.start;
@@ -100,6 +141,23 @@ static void __init armada_370_coherency_init(struct device_node *np)
sync_cache_w(&coherency_phys_base);
coherency_base = of_iomap(np, 0);
coherency_cpu_base = of_iomap(np, 1);
+
+ cpu_config_np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-xp-cpu-config");
+ if (!cpu_config_np)
+ goto exit;
+
+ cpu_config_base = of_iomap(cpu_config_np, 0);
+ if (!cpu_config_base) {
+ of_node_put(cpu_config_np);
+ goto exit;
+ }
+
+ of_node_put(cpu_config_np);
+
+ register_cpu_notifier(&armada_xp_clear_shared_l2_notifier);
+
+exit:
set_cpu_coherent();
}
@@ -204,6 +262,8 @@ int set_cpu_coherent(void)
pr_warn("Coherency fabric is not initialized\n");
return 1;
}
+
+ armada_xp_clear_shared_l2();
ll_add_cpu_to_smp_group();
return ll_enable_coherency();
}
diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h
deleted file mode 100644
index 40a8c17..0000000
--- a/arch/arm/mach-mvebu/include/mach/gpio.h
+++ /dev/null
@@ -1 +0,0 @@
-/* empty */
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
index 925f75f..f9d8e1e 100644
--- a/arch/arm/mach-mvebu/kirkwood.c
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -25,7 +25,6 @@
#include "kirkwood.h"
#include "kirkwood-pm.h"
#include "common.h"
-#include "board.h"
static struct resource kirkwood_cpufreq_resources[] = {
[0] = {
@@ -180,9 +179,6 @@ static void __init kirkwood_dt_init(void)
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);
}
diff --git a/arch/arm/mach-mvebu/netxbig.c b/arch/arm/mach-mvebu/netxbig.c
deleted file mode 100644
index 94b11b6..0000000
--- a/arch/arm/mach-mvebu/netxbig.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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
index 3d50004..d715dec 100644
--- a/arch/arm/mach-mvebu/platsmp-a9.c
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -93,11 +93,11 @@ static int armada_38x_cpu_kill(unsigned int cpu)
}
#endif
-static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
+static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
.smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
};
-static struct smp_operations armada_38x_smp_ops __initdata = {
+static const struct smp_operations armada_38x_smp_ops __initconst = {
.smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
.smp_secondary_init = armada_38x_secondary_init,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index 58cc8c1..f9597b7 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -170,7 +170,7 @@ static int armada_xp_cpu_kill(unsigned int cpu)
}
#endif
-struct smp_operations armada_xp_smp_ops __initdata = {
+const struct smp_operations armada_xp_smp_ops __initconst = {
.smp_init_cpus = armada_xp_smp_init_cpus,
.smp_prepare_cpus = armada_xp_smp_prepare_cpus,
.smp_boot_secondary = armada_xp_boot_secondary,
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index e8fdb9c..ed8fda4 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -296,11 +296,11 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
/* 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"
+ "tst r0, %0 \n\t"
"orreq r0, r0, #(1 << 2) \n\t"
"mcreq p15, 0, r0, c1, c0, 0 \n\t"
"isb "
- : : : "r0");
+ : : "Ir" (CR_C) : "r0");
pr_debug("Failed to suspend the system\n");
@@ -379,6 +379,16 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
static struct platform_device mvebu_v7_cpuidle_device;
+static int broken_idle(struct device_node *np)
+{
+ if (of_property_read_bool(np, "broken-idle")) {
+ pr_warn("CPU idle is currently broken: disabling\n");
+ return 1;
+ }
+
+ return 0;
+}
+
static __init int armada_370_cpuidle_init(void)
{
struct device_node *np;
@@ -387,7 +397,9 @@ static __init int armada_370_cpuidle_init(void)
np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
if (!np)
return -ENODEV;
- of_node_put(np);
+
+ if (broken_idle(np))
+ goto end;
/*
* On Armada 370, there is "a slow exit process from the deep
@@ -406,6 +418,8 @@ static __init int armada_370_cpuidle_init(void)
mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
mvebu_v7_cpuidle_device.name = "cpuidle-armada-370";
+end:
+ of_node_put(np);
return 0;
}
@@ -422,6 +436,10 @@ static __init int armada_38x_cpuidle_init(void)
"marvell,armada-380-coherency-fabric");
if (!np)
return -ENODEV;
+
+ if (broken_idle(np))
+ goto end;
+
of_node_put(np);
np = of_find_compatible_node(NULL, NULL,
@@ -430,7 +448,6 @@ static __init int armada_38x_cpuidle_init(void)
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);
@@ -450,6 +467,8 @@ static __init int armada_38x_cpuidle_init(void)
mvebu_v7_cpuidle_device.dev.platform_data = armada_38x_cpu_suspend;
mvebu_v7_cpuidle_device.name = "cpuidle-armada-38x";
+end:
+ of_node_put(np);
return 0;
}
@@ -460,12 +479,16 @@ static __init int armada_xp_cpuidle_init(void)
np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
if (!np)
return -ENODEV;
- of_node_put(np);
+
+ if (broken_idle(np))
+ goto end;
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";
+end:
+ of_node_put(np);
return 0;
}
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
index d122ee6..8814ee5 100644
--- a/arch/arm/mach-netx/fb.c
+++ b/arch/arm/mach-netx/fb.c
@@ -42,8 +42,8 @@ int netx_clcd_setup(struct clcd_fb *fb)
fb->panel = netx_panel;
- fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, 1024*1024,
- &dma, GFP_KERNEL);
+ fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, 1024 * 1024, &dma,
+ GFP_KERNEL);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
@@ -57,16 +57,14 @@ int netx_clcd_setup(struct clcd_fb *fb)
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);
+ return dma_mmap_wc(&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);
+ dma_free_wc(&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);
diff --git a/arch/arm/mach-netx/include/mach/param.h b/arch/arm/mach-netx/include/mach/param.h
deleted file mode 100644
index a771459..0000000
--- a/arch/arm/mach-netx/include/mach/param.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 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/uncompress.h b/arch/arm/mach-netx/include/mach/uncompress.h
index 5cb1051b..033875d 100644
--- a/arch/arm/mach-netx/include/mach/uncompress.h
+++ b/arch/arm/mach-netx/include/mach/uncompress.h
@@ -40,7 +40,7 @@
#define FR_BUSY (1<<3)
#define FR_TXFF (1<<5)
-static void putc(char c)
+static inline void putc(char c)
{
unsigned long base;
diff --git a/arch/arm/mach-nspire/clcd.c b/arch/arm/mach-nspire/clcd.c
index abea126..ea0e5b2 100644
--- a/arch/arm/mach-nspire/clcd.c
+++ b/arch/arm/mach-nspire/clcd.c
@@ -90,8 +90,8 @@ int nspire_clcd_setup(struct clcd_fb *fb)
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);
+ fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, panel_size, &dma,
+ GFP_KERNEL);
if (!fb->fb.screen_base) {
pr_err("CLCD: unable to map framebuffer\n");
@@ -107,13 +107,12 @@ int nspire_clcd_setup(struct clcd_fb *fb)
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);
+ return dma_mmap_wc(&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);
+ dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
+ fb->fb.fix.smem_start);
}
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index cdd05f2..afb80950 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -90,13 +90,6 @@ config MACH_OMAP_FSAMPLE
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
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 3889b6c..0e8ea95 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -37,7 +37,6 @@ 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
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index a95499e..6613a6f 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -11,7 +11,7 @@
* 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/driver.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -41,7 +41,7 @@
#include <mach/hardware.h>
#include <mach/ams-delta-fiq.h>
-#include <mach/camera.h>
+#include "camera.h"
#include <mach/usb.h>
#include "iomap.h"
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 0fb51d2..fad95b7 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -29,7 +29,7 @@
#include <mach/tc.h>
#include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <linux/platform_data/keypad-omap.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 8340d68..cd146ed 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -42,7 +42,7 @@
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <linux/platform_data/keypad-omap.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/hardware.h>
#include <mach/usb.h>
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 086ff34..f7c8c63 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -44,7 +44,7 @@
#include <mach/tc.h>
#include <linux/platform_data/keypad-omap.h>
#include <linux/omap-dma.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/hardware.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index ed4e045..ae90bd0 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -32,7 +32,7 @@
#include <asm/mach/map.h>
#include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/tc.h>
#include <linux/platform_data/keypad-omap.h>
diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c
index 4d08353..7684f92 100644
--- a/arch/arm/mach-omap1/board-nand.c
+++ b/arch/arm/mach-omap1/board-nand.c
@@ -22,7 +22,7 @@
void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long mask;
if (cmd == NAND_CMD_NONE)
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 0efd165..209aecb 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -46,7 +46,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/mux.h>
#include <mach/tc.h>
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 1142ae4..e5288cd 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -34,7 +34,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/mux.h>
#include <mach/tc.h>
#include <linux/omap-dma.h>
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 54a547a..d672495 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -34,7 +34,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/mux.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 87ec04a..aaf741b 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -36,7 +36,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/mux.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 3d76f05..150b57b 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -30,7 +30,7 @@
#include <mach/tc.h>
#include <mach/mux.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/hardware.h>
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 4fcf19c..a937357 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -16,7 +16,7 @@
#include <linux/platform_device.h>
#include <mach/hardware.h>
-#include <mach/board-sx1.h>
+#include "board-sx1.h"
#include "mmc.h"
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 939991e..6c48225 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -34,11 +34,11 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/mux.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
-#include <mach/board-sx1.h>
+#include "board-sx1.h"
#include <mach/hardware.h>
#include <mach/usb.h>
diff --git a/arch/arm/mach-omap1/include/mach/board-sx1.h b/arch/arm/mach-omap1/board-sx1.h
index 355adbd..355adbd 100644
--- a/arch/arm/mach-omap1/include/mach/board-sx1.h
+++ b/arch/arm/mach-omap1/board-sx1.h
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
deleted file mode 100644
index e960687..0000000
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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,
- .handle_irq = omap1_handle_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/camera.h b/arch/arm/mach-omap1/camera.h
new file mode 100644
index 0000000..caa6c0d
--- /dev/null
+++ b/arch/arm/mach-omap1/camera.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#include <linux/platform_data/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/devices.c b/arch/arm/mach-omap1/devices.c
index 325e603..8c8be86 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -25,7 +25,7 @@
#include <mach/mux.h>
#include <mach/omap7xx.h>
-#include <mach/camera.h>
+#include "camera.h"
#include <mach/hardware.h>
#include "common.h"
@@ -33,24 +33,6 @@
#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
@@ -425,7 +407,6 @@ static int __init omap1_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
- omap_init_audio();
omap_init_mbox();
omap_init_rtc();
omap_init_spi100k();
diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c
index b3fb531..99cda40 100644
--- a/arch/arm/mach-omap1/flash.c
+++ b/arch/arm/mach-omap1/flash.c
@@ -11,7 +11,7 @@
#include <linux/mtd/map.h>
#include <mach/tc.h>
-#include <mach/flash.h>
+#include "flash.h"
#include <mach/hardware.h>
diff --git a/arch/arm/mach-omap1/include/mach/flash.h b/arch/arm/mach-omap1/flash.h
index 0d88499..0d88499 100644
--- a/arch/arm/mach-omap1/include/mach/flash.h
+++ b/arch/arm/mach-omap1/flash.h
diff --git a/arch/arm/mach-omap1/include/mach/board-voiceblue.h b/arch/arm/mach-omap1/include/mach/board-voiceblue.h
deleted file mode 100644
index 27916b2..0000000
--- a/arch/arm/mach-omap1/include/mach/board-voiceblue.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 847d00f..0000000
--- a/arch/arm/mach-omap1/include/mach/camera.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#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/uncompress.h b/arch/arm/mach-omap1/include/mach/uncompress.h
index 4869633..9cca6a5 100644
--- a/arch/arm/mach-omap1/include/mach/uncompress.h
+++ b/arch/arm/mach-omap1/include/mach/uncompress.h
@@ -45,7 +45,7 @@ static void set_omap_uart_info(unsigned char port)
*uart_info = port;
}
-static void putc(int c)
+static inline void putc(int c)
{
if (!uart_base)
return;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 33d1460..0517f0c 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -65,6 +65,8 @@ config SOC_AM43XX
select MACH_OMAP_GENERIC
select MIGHT_HAVE_CACHE_L2X0
select HAVE_ARM_SCU
+ select GENERIC_CLOCKEVENTS_BROADCAST
+ select HAVE_ARM_TWD
config SOC_DRA7XX
bool "TI DRA7XX"
@@ -96,8 +98,8 @@ config ARCH_OMAP2PLUS
select OMAP_GPMC
select PINCTRL
select SOC_BUS
- select TI_PRIV_EDMA
select OMAP_IRQCHIP
+ select CLKSRC_TI_32K
help
Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
@@ -121,6 +123,7 @@ config ARCH_OMAP2PLUS_TYPICAL
select NEON if CPU_V7
select PM
select REGULATOR
+ select REGULATOR_FIXED_VOLTAGE
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
select VFP
@@ -201,7 +204,6 @@ config MACH_OMAP3_PANDORA
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_NOKIA_N810
bool
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 9358696..0ba6a0e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -48,11 +48,9 @@ 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
@@ -186,7 +184,6 @@ obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common)
-obj-$(CONFIG_ARCH_OMAP3) += clkt34xx_dpll3m2.o
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common)
obj-$(CONFIG_SOC_AM33XX) += $(clock-common)
obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
@@ -226,8 +223,6 @@ obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o
# EMU peripherals
obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
-obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
-
# OMAP2420 MSDI controller integration support ("MMC")
obj-$(CONFIG_SOC_OMAP2420) += msdi.o
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fb219a3..bab814d 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -16,7 +16,9 @@
#include <linux/of_platform.h>
#include <linux/irqdomain.h>
+#include <asm/setup.h>
#include <asm/mach/arch.h>
+#include <asm/system_info.h>
#include "common.h"
@@ -46,7 +48,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
.map_io = omap242x_map_io,
.init_early = omap2420_init_early,
.init_machine = omap_generic_init,
- .init_time = omap2_sync32k_timer_init,
+ .init_time = omap_init_time,
.dt_compat = omap242x_boards_compat,
.restart = omap2xxx_restart,
MACHINE_END
@@ -63,7 +65,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
.map_io = omap243x_map_io,
.init_early = omap2430_init_early,
.init_machine = omap_generic_init,
- .init_time = omap2_sync32k_timer_init,
+ .init_time = omap_init_time,
.dt_compat = omap243x_boards_compat,
.restart = omap2xxx_restart,
MACHINE_END
@@ -76,13 +78,41 @@ static const char *const n900_boards_compat[] __initconst = {
NULL,
};
+/* Set system_rev from atags */
+static void __init rx51_set_system_rev(const struct tag *tags)
+{
+ const struct tag *tag;
+
+ if (tags->hdr.tag != ATAG_CORE)
+ return;
+
+ for_each_tag(tag, tags) {
+ if (tag->hdr.tag == ATAG_REVISION) {
+ system_rev = tag->u.revision.rev;
+ break;
+ }
+ }
+}
+
+/* Legacy userspace on Nokia N900 needs ATAGS exported in /proc/atags,
+ * save them while the data is still not overwritten
+ */
+static void __init rx51_reserve(void)
+{
+ const struct tag *tags = (const struct tag *)(PAGE_OFFSET + 0x100);
+
+ save_atags(tags);
+ rx51_set_system_rev(tags);
+ omap_reserve();
+}
+
DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
- .reserve = omap_reserve,
+ .reserve = rx51_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,
+ .init_time = omap_init_time,
.dt_compat = n900_boards_compat,
.restart = omap3xxx_restart,
MACHINE_END
@@ -100,7 +130,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
.init_early = omap3430_init_early,
.init_machine = omap_generic_init,
.init_late = omap3_init_late,
- .init_time = omap3_sync32k_timer_init,
+ .init_time = omap_init_time,
.dt_compat = omap3_boards_compat,
.restart = omap3xxx_restart,
MACHINE_END
@@ -117,7 +147,7 @@ DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)")
.init_early = omap3630_init_early,
.init_machine = omap_generic_init,
.init_late = omap3_init_late,
- .init_time = omap3_sync32k_timer_init,
+ .init_time = omap_init_time,
.dt_compat = omap36xx_boards_compat,
.restart = omap3xxx_restart,
MACHINE_END
@@ -276,7 +306,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
.init_late = am43xx_init_late,
.init_irq = omap_gic_of_init,
.init_machine = omap_generic_init,
- .init_time = omap3_gptimer_timer_init,
+ .init_time = omap4_local_timer_init,
.dt_compat = am43_boards_compat,
.restart = omap44xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index c2975af..d9c3ffc 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -424,6 +424,6 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
.init_irq = omap3_init_irq,
.init_machine = omap_ldp_init,
.init_late = omap3430_init_late,
- .init_time = omap3_sync32k_timer_init,
+ .init_time = omap_init_time,
.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
index 14edcd7..da174c0 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -39,7 +39,7 @@
#include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h>
-#include <media/si4713.h>
+#include <linux/platform_data/media/si4713.h>
#include <linux/platform_data/leds-lp55xx.h>
#include <linux/platform_data/tsl2563.h>
@@ -48,7 +48,7 @@
#include <video/omap-panel-data.h>
#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
-#include <media/ir-rx51.h>
+#include <linux/platform_data/media/ir-rx51.h>
#endif
#include "mux.h"
@@ -1257,7 +1257,7 @@ static struct platform_device omap3_rom_rng_device = {
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");
+ pr_info("RX-51: Registering OMAP3 HWRNG device\n");
platform_device_register(&omap3_rom_rng_device);
}
}
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 2d1e5a6..41161ca9 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -136,6 +136,6 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
.init_irq = omap3_init_irq,
.init_machine = rx51_init,
.init_late = omap3430_init_late,
- .init_time = omap3_sync32k_timer_init,
+ .init_time = omap_init_time,
.restart = omap3xxx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
deleted file mode 100644
index 3f65213..0000000
--- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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 "sdrc.h"
-#include "sram.h"
-
-#define CYCLES_PER_MHZ 1000000
-
-struct clk *sdrc_ick_p, *arm_fck_p;
-
-/*
- * 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;
-
- new_div = DIV_ROUND_UP(parent_rate, rate);
- validrate = parent_rate / new_div;
-
- if (validrate != rate)
- return -EINVAL;
-
- sdrcrate = clk_get_rate(sdrc_ick_p);
- clkrate = clk_hw_get_rate(hw);
- 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/clock.c b/arch/arm/mach-omap2/clock.c
index acb60ed..d058125 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -225,5 +225,9 @@ void __init ti_clk_init_features(void)
if (omap_rev() == OMAP3430_REV_ES1_0)
features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
+ /* Errata I810 for omap5 / dra7 */
+ if (soc_is_omap54xx() || soc_is_dra7xx())
+ features.flags |= TI_CLK_ERRATA_I810;
+
ti_clk_setup_features(&features);
}
diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c
index 53442c8..3b5fb05 100644
--- a/arch/arm/mach-omap2/clockdomains81xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains81xx_data.c
@@ -83,6 +83,14 @@ static struct clockdomain mmu_cfg_81xx_clkdm = {
.flags = CLKDM_CAN_SWSUP,
};
+static struct clockdomain default_l3_slow_81xx_clkdm = {
+ .name = "default_l3_slow_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI81XX_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
/* 816x only */
static struct clockdomain alwon_mpu_816x_clkdm = {
@@ -96,7 +104,7 @@ static struct clockdomain alwon_mpu_816x_clkdm = {
static struct clockdomain active_gem_816x_clkdm = {
.name = "active_gem_clkdm",
.pwrdm = { .name = "active_pwrdm" },
- .cm_inst = TI816X_CM_ACTIVE_MOD,
+ .cm_inst = TI81XX_CM_ACTIVE_MOD,
.clkdm_offs = TI816X_CM_ACTIVE_GEM_CLKDM,
.flags = CLKDM_CAN_SWSUP,
};
@@ -128,7 +136,7 @@ static struct clockdomain ivahd2_816x_clkdm = {
static struct clockdomain sgx_816x_clkdm = {
.name = "sgx_clkdm",
.pwrdm = { .name = "sgx_pwrdm" },
- .cm_inst = TI816X_CM_SGX_MOD,
+ .cm_inst = TI81XX_CM_SGX_MOD,
.clkdm_offs = TI816X_CM_SGX_CLKDM,
.flags = CLKDM_CAN_SWSUP,
};
@@ -136,7 +144,7 @@ static struct clockdomain sgx_816x_clkdm = {
static struct clockdomain default_l3_med_816x_clkdm = {
.name = "default_l3_med_clkdm",
.pwrdm = { .name = "default_pwrdm" },
- .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .cm_inst = TI81XX_CM_DEFAULT_MOD,
.clkdm_offs = TI816X_CM_DEFAULT_L3_MED_CLKDM,
.flags = CLKDM_CAN_SWSUP,
};
@@ -144,7 +152,7 @@ static struct clockdomain default_l3_med_816x_clkdm = {
static struct clockdomain default_ducati_816x_clkdm = {
.name = "default_ducati_clkdm",
.pwrdm = { .name = "default_pwrdm" },
- .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .cm_inst = TI81XX_CM_DEFAULT_MOD,
.clkdm_offs = TI816X_CM_DEFAULT_DUCATI_CLKDM,
.flags = CLKDM_CAN_SWSUP,
};
@@ -152,19 +160,11 @@ static struct clockdomain default_ducati_816x_clkdm = {
static struct clockdomain default_pci_816x_clkdm = {
.name = "default_pci_clkdm",
.pwrdm = { .name = "default_pwrdm" },
- .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .cm_inst = TI81XX_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_ti814x[] __initdata = {
&alwon_l3_slow_81xx_clkdm,
&alwon_l3_med_81xx_clkdm,
@@ -172,6 +172,7 @@ static struct clockdomain *clockdomains_ti814x[] __initdata = {
&alwon_ethernet_81xx_clkdm,
&mmu_81xx_clkdm,
&mmu_cfg_81xx_clkdm,
+ &default_l3_slow_81xx_clkdm,
NULL,
};
@@ -198,7 +199,7 @@ static struct clockdomain *clockdomains_ti816x[] __initdata = {
&default_l3_med_816x_clkdm,
&default_ducati_816x_clkdm,
&default_pci_816x_clkdm,
- &default_l3_slow_816x_clkdm,
+ &default_l3_slow_81xx_clkdm,
NULL,
};
diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h
index 45cb407..3a0ccf0 100644
--- a/arch/arm/mach-omap2/cm81xx.h
+++ b/arch/arm/mach-omap2/cm81xx.h
@@ -18,15 +18,15 @@
#define __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
/* TI81XX common CM module offsets */
+#define TI81XX_CM_ACTIVE_MOD 0x0400 /* 256B */
+#define TI81XX_CM_DEFAULT_MOD 0x0500 /* 256B */
#define TI81XX_CM_ALWON_MOD 0x1400 /* 1KB */
+#define TI81XX_CM_SGX_MOD 0x0900 /* 256B */
/* 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
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 92e92cf..f7666b9 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -88,8 +88,7 @@ static inline int omap_mux_late_init(void)
extern void omap2_init_common_infrastructure(void);
-extern void omap2_sync32k_timer_init(void);
-extern void omap3_sync32k_timer_init(void);
+extern void omap_init_time(void);
extern void omap3_secure_sync32k_timer_init(void);
extern void omap3_gptimer_timer_init(void);
extern void omap4_local_timer_init(void);
@@ -271,7 +270,7 @@ extern u32 omap_read_auxcoreboot0(void);
extern void omap4_cpu_die(unsigned int cpu);
-extern struct smp_operations omap4_smp_ops;
+extern const struct smp_operations omap4_smp_ops;
extern void omap5_secondary_startup(void);
extern void omap5_secondary_hyp_startup(void);
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index a69bd67..d7f1d69 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -18,7 +18,6 @@
#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>
@@ -33,7 +32,6 @@
#include "common.h"
#include "mux.h"
#include "control.h"
-#include "devices.h"
#include "display.h"
#define L3_MODULES_MAX_LEN 12
@@ -67,102 +65,8 @@ static int __init omap3_l3_init(void)
}
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>
@@ -292,14 +196,12 @@ static int __init omap2_init_devices(void)
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();
+ /*
+ * please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
omap_init_mcspi();
omap_init_sham();
omap_init_aes();
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
deleted file mode 100644
index f61eb6e..0000000
--- a/arch/arm/mach-omap2/devices.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 17a6f75..8633c70 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -101,10 +101,8 @@ static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
static void set_onenand_cfg(void __iomem *onenand_base)
{
- u32 reg;
+ u32 reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
- 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)
@@ -123,6 +121,7 @@ static void set_onenand_cfg(void __iomem *onenand_base)
reg |= ONENAND_SYS_CFG1_VHF;
else
reg &= ~ONENAND_SYS_CFG1_VHF;
+
writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
}
@@ -149,8 +148,8 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
freq = 104;
break;
default:
- freq = 54;
- break;
+ pr_err("onenand rate not detected, bad GPMC async timings?\n");
+ freq = 0;
}
return freq;
@@ -271,6 +270,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
struct gpmc_timings t;
int ret;
+ /*
+ * Note that we need to keep sync_write set for the call to
+ * omap2_onenand_set_async_mode() to work to detect the onenand
+ * supported clock rate for the sync timings.
+ */
if (gpmc_onenand_data->of_node) {
gpmc_read_settings_dt(gpmc_onenand_data->of_node,
&onenand_async);
@@ -281,12 +285,10 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
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);
-
+ onenand_async.sync_write = true;
omap2_onenand_calc_async_timings(&t);
ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
@@ -310,6 +312,8 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
if (!freq) {
/* Very first call freq is not known */
freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
+ if (!freq)
+ return -ENODEV;
set_onenand_cfg(onenand_base);
}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 54a5ba5..d85c249 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -57,15 +57,15 @@ int omap_type(void)
if (val < OMAP2_DEVICETYPE_MASK)
return val;
- if (cpu_is_omap24xx()) {
+ if (soc_is_omap24xx()) {
val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
- } else if (cpu_is_ti81xx()) {
+ } else if (soc_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()) {
+ } else if (soc_is_omap34xx()) {
val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
- } else if (cpu_is_omap44xx()) {
+ } else if (soc_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);
@@ -122,7 +122,7 @@ 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()) {
+ if (soc_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);
@@ -218,17 +218,17 @@ static void __init omap3_cpuinfo(void)
* on available features. Upon detection, update the CPU id
* and CPU class bits.
*/
- if (cpu_is_omap3630()) {
+ if (soc_is_omap3630()) {
cpu_name = "OMAP3630";
} else if (soc_is_am35xx()) {
cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
- } else if (cpu_is_ti816x()) {
+ } else if (soc_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()) {
+ } else if (soc_is_ti814x()) {
cpu_name = "TI814X";
} else if (omap3_has_iva() && omap3_has_sgx()) {
/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
@@ -275,11 +275,11 @@ void __init omap3xxx_check_features(void)
OMAP3_CHECK_FEATURE(status, SGX);
OMAP3_CHECK_FEATURE(status, NEON);
OMAP3_CHECK_FEATURE(status, ISP);
- if (cpu_is_omap3630())
+ if (soc_is_omap3630())
omap_features |= OMAP3_HAS_192MHZ_CLK;
- if (cpu_is_omap3430() || cpu_is_omap3630())
+ if (soc_is_omap3430() || soc_is_omap3630())
omap_features |= OMAP3_HAS_IO_WAKEUP;
- if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
+ if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
omap_rev() == OMAP3430_REV_ES3_1_2)
omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
@@ -488,6 +488,7 @@ void __init omap3xxx_check_revision(void)
}
break;
case 0xb8f2:
+ case 0xb968:
switch (rev) {
case 0:
/* FALLTHROUGH */
@@ -511,7 +512,8 @@ void __init omap3xxx_check_revision(void)
/* 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");
+ pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
+ hawkeye);
}
sprintf(soc_rev, "ES%s", cpu_rev);
}
@@ -701,7 +703,7 @@ void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
tap_base = tap;
/* XXX What is this intended to do? */
- if (cpu_is_omap34xx())
+ if (soc_is_omap34xx())
tap_prod_id = 0x0210;
else
tap_prod_id = 0x0208;
@@ -719,11 +721,11 @@ static const char * const omap_types[] = {
static const char * __init omap_get_family(void)
{
- if (cpu_is_omap24xx())
+ if (soc_is_omap24xx())
return kasprintf(GFP_KERNEL, "OMAP2");
- else if (cpu_is_omap34xx())
+ else if (soc_is_omap34xx())
return kasprintf(GFP_KERNEL, "OMAP3");
- else if (cpu_is_omap44xx())
+ else if (soc_is_omap44xx())
return kasprintf(GFP_KERNEL, "OMAP4");
else if (soc_is_omap54xx())
return kasprintf(GFP_KERNEL, "OMAP5");
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 3eaeaca..3c87e40 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -612,8 +612,7 @@ void __init ti814x_init_early(void)
ti814x_clockdomains_init();
dm814x_hwmod_init();
omap_hwmod_init_postsetup();
- if (of_have_populated_dt())
- omap_clk_soc_init = dm814x_dt_clk_init;
+ omap_clk_soc_init = dm814x_dt_clk_init;
}
void __init ti816x_init_early(void)
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 971791f..593fec7 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -27,7 +27,7 @@
* platform-specific code to shutdown a CPU
* Called with IRQs disabled
*/
-void __ref omap4_cpu_die(unsigned int cpu)
+void omap4_cpu_die(unsigned int cpu)
{
unsigned int boot_cpu = 0;
void __iomem *base = omap_get_wakeupgen_base();
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
deleted file mode 100644
index 8867eb4..0000000
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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/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);
-}
-omap_subsys_initcall(omap_iommu_init);
-/* must be ready before omap3isp is probed */
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 5305ec7..c625cc1 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -143,9 +143,9 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
* 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);
+ clkdm_wakeup_nolock(cpu1_clkdm);
+ pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
+ clkdm_allow_idle_nolock(cpu1_clkdm);
if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
while (gic_dist_disabled()) {
@@ -241,7 +241,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
}
-struct smp_operations omap4_smp_ops __initdata = {
+const struct smp_operations omap4_smp_ops __initconst = {
.smp_init_cpus = omap4_smp_init_cpus,
.smp_prepare_cpus = omap4_smp_prepare_cpus,
.smp_secondary_init = omap4_secondary_init,
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index e1d2e99..f397bd6 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -330,7 +331,7 @@ static int irq_cpu_hotplug_notify(struct notifier_block *self,
return NOTIFY_OK;
}
-static struct notifier_block __refdata irq_hotplug_notifier = {
+static struct notifier_block irq_hotplug_notifier = {
.notifier_call = irq_cpu_hotplug_notify,
};
@@ -399,40 +400,42 @@ static struct irq_chip wakeupgen_chip = {
#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)
+static int wakeupgen_domain_translate(struct irq_domain *d,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *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 */
+ if (is_of_node(fwspec->fwnode)) {
+ if (fwspec->param_count != 3)
+ return -EINVAL;
- *out_hwirq = intspec[1];
- *out_type = intspec[2];
- return 0;
+ /* No PPI should point to this domain */
+ if (fwspec->param[0] != 0)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[1];
+ *type = fwspec->param[2];
+ return 0;
+ }
+
+ return -EINVAL;
}
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;
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
irq_hw_number_t hwirq;
int i;
- if (args->args_count != 3)
+ if (fwspec->param_count != 3)
return -EINVAL; /* Not GIC compliant */
- if (args->args[0] != 0)
+ if (fwspec->param[0] != 0)
return -EINVAL; /* No PPI should point to this domain */
- hwirq = args->args[1];
+ hwirq = fwspec->param[1];
if (hwirq >= MAX_IRQS)
return -EINVAL; /* Can't deal with this */
@@ -440,15 +443,16 @@ static int wakeupgen_domain_alloc(struct irq_domain *domain,
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);
+ parent_fwspec = *fwspec;
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
+ &parent_fwspec);
}
static const struct irq_domain_ops wakeupgen_domain_ops = {
- .xlate = wakeupgen_domain_xlate,
- .alloc = wakeupgen_domain_alloc,
- .free = irq_domain_free_irqs_common,
+ .translate = wakeupgen_domain_translate,
+ .alloc = wakeupgen_domain_alloc,
+ .free = irq_domain_free_irqs_common,
};
/*
@@ -537,9 +541,4 @@ static int __init wakeupgen_init(struct device_node *node,
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);
+IRQCHIP_DECLARE(ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init);
diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c
index d937b2e..497269d 100644
--- a/arch/arm/mach-omap2/omap2-restart.c
+++ b/arch/arm/mach-omap2/omap2-restart.c
@@ -62,4 +62,4 @@ static int __init omap2xxx_common_look_up_clks_for_reset(void)
return 0;
}
-omap_core_initcall(omap2xxx_common_look_up_clks_for_reset);
+omap_postcore_initcall(omap2xxx_common_look_up_clks_for_reset);
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 72ebc4c..f7ff3b9 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -32,6 +32,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/notifier.h>
@@ -168,7 +169,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
r->name = dev_name(&pdev->dev);
}
- pdev->dev.pm_domain = &omap_device_pm_domain;
+ dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
if (device_active) {
omap_device_enable(pdev);
@@ -180,7 +181,7 @@ odbfd_exit1:
odbfd_exit:
/* if data/we are at fault.. load up a fail handler */
if (ret)
- pdev->dev.pm_domain = &omap_device_fail_pm_domain;
+ dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain);
return ret;
}
@@ -190,12 +191,22 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_device *od;
+ int err;
switch (event) {
case BUS_NOTIFY_DEL_DEVICE:
if (pdev->archdata.od)
omap_device_delete(pdev->archdata.od);
break;
+ case BUS_NOTIFY_UNBOUND_DRIVER:
+ od = to_omap_device(pdev);
+ if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) {
+ dev_info(dev, "enabled after unload, idling\n");
+ err = omap_device_idle(pdev);
+ if (err)
+ dev_err(dev, "failed to idle\n");
+ }
+ break;
case BUS_NOTIFY_ADD_DEVICE:
if (pdev->dev.of_node)
omap_device_build_from_dt(pdev);
@@ -601,8 +612,10 @@ static int _od_runtime_resume(struct device *dev)
int ret;
ret = omap_device_enable(pdev);
- if (ret)
+ if (ret) {
+ dev_err(dev, "use pm_runtime_put_sync_suspend() in driver?\n");
return ret;
+ }
return pm_generic_runtime_resume(dev);
}
@@ -701,7 +714,7 @@ 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;
+ dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
return platform_device_add(pdev);
}
@@ -869,7 +882,7 @@ static int __init omap_device_init(void)
bus_register_notifier(&platform_bus_type, &platform_nb);
return 0;
}
-omap_core_initcall(omap_device_init);
+omap_postcore_initcall(omap_device_init);
/**
* omap_device_late_idle - idle devices without drivers
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index cc8a987..b6d62e4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -890,6 +890,36 @@ static int _init_opt_clks(struct omap_hwmod *oh)
return ret;
}
+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);
+ }
+}
+
/**
* _enable_clocks - enable hwmod main clock and interface clocks
* @oh: struct omap_hwmod *
@@ -917,6 +947,9 @@ static int _enable_clocks(struct omap_hwmod *oh)
clk_enable(os->_clk);
}
+ if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
+ _enable_optional_clocks(oh);
+
/* The opt clocks are controlled by the device driver. */
return 0;
@@ -948,41 +981,14 @@ static int _disable_clocks(struct omap_hwmod *oh)
clk_disable(os->_clk);
}
+ if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
+ _disable_optional_clocks(oh);
+
/* 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 *
@@ -2194,6 +2200,11 @@ static int _enable(struct omap_hwmod *oh)
*/
static int _idle(struct omap_hwmod *oh)
{
+ if (oh->flags & HWMOD_NO_IDLE) {
+ oh->_int_flags |= _HWMOD_SKIP_ENABLE;
+ return 0;
+ }
+
pr_debug("omap_hwmod: %s: idling\n", oh->name);
if (oh->_state != _HWMOD_STATE_ENABLED) {
@@ -2498,6 +2509,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
oh->flags |= HWMOD_INIT_NO_RESET;
if (of_find_property(np, "ti,no-idle-on-init", NULL))
oh->flags |= HWMOD_INIT_NO_IDLE;
+ if (of_find_property(np, "ti,no-idle", NULL))
+ oh->flags |= HWMOD_NO_IDLE;
}
oh->_state = _HWMOD_STATE_INITIALIZED;
@@ -2624,7 +2637,7 @@ static void __init _setup_postsetup(struct omap_hwmod *oh)
* 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) &&
+ if ((oh->flags & (HWMOD_INIT_NO_IDLE | HWMOD_NO_IDLE)) &&
(postsetup_state == _HWMOD_STATE_IDLE)) {
oh->_int_flags |= _HWMOD_SKIP_ENABLE;
postsetup_state = _HWMOD_STATE_ENABLED;
@@ -3307,7 +3320,7 @@ static int __init omap_hwmod_setup_all(void)
return 0;
}
-omap_core_initcall(omap_hwmod_setup_all);
+omap_postcore_initcall(omap_hwmod_setup_all);
/**
* omap_hwmod_enable - enable an omap_hwmod
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index ca6df1a..7c7a311 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -523,6 +523,10 @@ struct omap_hwmod_omap4_prcm {
* 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.
+ * HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to
+ * operate and they need to be handled at the same time as the main_clk.
+ * HWMOD_NO_IDLE: Do not idle the hwmod at all. Useful to handle certain
+ * IPs like CPSW on DRA7, where clocks to this module cannot be disabled.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -538,6 +542,8 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_FORCE_MSTANDBY (1 << 11)
#define HWMOD_SWSUP_SIDLE_ACT (1 << 12)
#define HWMOD_RECONFIG_IO_CHAIN (1 << 13)
+#define HWMOD_OPT_CLKS_NEEDED (1 << 14)
+#define HWMOD_NO_IDLE (1 << 15)
/*
* omap_hwmod._int_flags definitions
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
index 8f5989d..1c210cb 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
@@ -152,20 +152,10 @@ struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
.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,
};
@@ -285,20 +275,10 @@ struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
};
/* 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,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index dc55f8d..0a98532 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -25,8 +25,6 @@
#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"
@@ -1506,26 +1504,9 @@ static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = {
.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 = {
@@ -1536,7 +1517,6 @@ static struct omap_hwmod omap3xxx_mailbox_hwmod = {
.idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT,
},
},
- .dev_attr = &omap3xxx_mailbox_attrs,
};
/*
@@ -2976,80 +2956,40 @@ static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = {
};
/* 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),
@@ -3062,7 +3002,6 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
.idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
},
},
- .dev_attr = &mmu_iva_dev_attr,
.flags = HWMOD_NO_IDLEST,
};
@@ -3276,20 +3215,10 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = {
.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,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 43eebf2..dad871a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,7 +30,6 @@
#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"
@@ -2088,30 +2087,16 @@ static struct omap_hwmod_class omap44xx_mmu_hwmod_class = {
/* 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,
};
@@ -2130,35 +2115,20 @@ static struct omap_hwmod omap44xx_mmu_ipu_hwmod = {
.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,
};
@@ -2177,7 +2147,6 @@ static struct omap_hwmod omap44xx_mmu_dsp_hwmod = {
.modulemode = MODULEMODE_HWCTRL,
},
},
- .dev_attr = &mmu_dsp_dev_attr,
};
/*
@@ -3915,21 +3884,11 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
.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,
};
@@ -4471,21 +4430,11 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
.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,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 7c3fac0..8cdfd9b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -1844,8 +1844,7 @@ 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),
+ 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),
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 562247b..848356e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -1298,6 +1298,44 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
};
/*
+ * 'mcasp' class
+ *
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
+ .sysc_offs = 0x0004,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
+ .name = "mcasp",
+ .sysc = &dra7xx_mcasp_sysc,
+};
+
+/* mcasp3 */
+static struct omap_hwmod_opt_clk mcasp3_opt_clks[] = {
+ { .role = "ahclkx", .clk = "mcasp3_ahclkx_mux" },
+};
+
+static struct omap_hwmod dra7xx_mcasp3_hwmod = {
+ .name = "mcasp3",
+ .class = &dra7xx_mcasp_hwmod_class,
+ .clkdm_name = "l4per2_clkdm",
+ .main_clk = "mcasp3_aux_gfclk_mux",
+ .flags = HWMOD_OPT_CLKS_NEEDED,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
+ .context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = mcasp3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(mcasp3_opt_clks),
+};
+
+/*
* 'mmc' class
*
*/
@@ -2065,7 +2103,7 @@ static struct omap_hwmod dra7xx_uart4_hwmod = {
.class = &dra7xx_uart_hwmod_class,
.clkdm_name = "l4per_clkdm",
.main_clk = "uart4_gfclk_mux",
- .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP4UART4_FLAGS,
.prcm = {
.omap4 = {
.clkctrl_offs = DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET,
@@ -2566,13 +2604,20 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
.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_per2 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
+ .master = &dra7xx_l4_per2_hwmod,
+ .slave = &dra7xx_mcasp3_hwmod,
+ .clk = "l4_root_clk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__mcasp3 = {
+ .master = &dra7xx_l3_main_1_hwmod,
+ .slave = &dra7xx_mcasp3_hwmod,
+ .clk = "l3_iclk_div",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* l4_per1 -> elm */
@@ -2580,7 +2625,6 @@ 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,
};
@@ -2648,21 +2692,11 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio8 = {
.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,
};
@@ -3029,21 +3063,11 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_mpu = {
.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,
};
@@ -3338,6 +3362,8 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l4_wkup__dcan1,
&dra7xx_l4_per2__dcan2,
&dra7xx_l4_per2__cpgmac0,
+ &dra7xx_l4_per2__mcasp3,
+ &dra7xx_l3_main_1__mcasp3,
&dra7xx_gmac__mdio,
&dra7xx_l4_cfg__dma_system,
&dra7xx_l3_main_1__dss,
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index b1288f5..e493ae3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -104,8 +104,8 @@
* 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)
+#define DM81XX_CM_DEFAULT_OFFSET 0x500
+#define DM81XX_CM_DEFAULT_USB_CLKCTRL (0x558 - DM81XX_CM_DEFAULT_OFFSET)
/* L3 Interconnect entries clocked at 125, 250 and 500MHz */
static struct omap_hwmod dm81xx_alwon_l3_slow_hwmod = {
@@ -144,6 +144,7 @@ static struct omap_hwmod dm81xx_l4_ls_hwmod = {
.name = "l4_ls",
.clkdm_name = "alwon_l3s_clkdm",
.class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
};
/*
@@ -155,6 +156,7 @@ static struct omap_hwmod dm81xx_l4_hs_hwmod = {
.name = "l4_hs",
.clkdm_name = "alwon_l3_med_clkdm",
.class = &l4_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
};
/* L3 slow -> L4 ls peripheral interface running at 125MHz */
@@ -555,22 +557,42 @@ static struct omap_hwmod_class dm81xx_usbotg_class = {
.sysc = &dm81xx_usbhsotg_sysc,
};
-static struct omap_hwmod dm81xx_usbss_hwmod = {
+static struct omap_hwmod dm814x_usbss_hwmod = {
+ .name = "usb_otg_hs",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .main_clk = "pll260dcoclkldo", /* 481c5260.adpll.dcoclkldo */
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM81XX_CM_DEFAULT_USB_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm81xx_usbotg_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_default_l3_slow__usbss = {
+ .master = &dm81xx_default_l3_slow_hwmod,
+ .slave = &dm814x_usbss_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_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,
+ .clkctrl_offs = DM81XX_CM_DEFAULT_USB_CLKCTRL,
.modulemode = MODULEMODE_SWCTRL,
},
},
.class = &dm81xx_usbotg_class,
};
-static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
+static struct omap_hwmod_ocp_if dm816x_default_l3_slow__usbss = {
.master = &dm81xx_default_l3_slow_hwmod,
- .slave = &dm81xx_usbss_hwmod,
+ .slave = &dm816x_usbss_hwmod,
.clk = "sysclk6_ck",
.user = OCP_USER_MPU,
};
@@ -597,7 +619,7 @@ static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
static struct omap_hwmod dm814x_timer1_hwmod = {
.name = "timer1",
.clkdm_name = "alwon_l3s_clkdm",
- .main_clk = "timer_sys_ck",
+ .main_clk = "timer1_fck",
.dev_attr = &capability_alwon_dev_attr,
.class = &dm816x_timer_hwmod_class,
.flags = HWMOD_NO_IDLEST,
@@ -606,7 +628,7 @@ static struct omap_hwmod dm814x_timer1_hwmod = {
static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = {
.master = &dm81xx_l4_ls_hwmod,
.slave = &dm814x_timer1_hwmod,
- .clk = "timer_sys_ck",
+ .clk = "timer1_fck",
.user = OCP_USER_MPU,
};
@@ -634,7 +656,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
static struct omap_hwmod dm814x_timer2_hwmod = {
.name = "timer2",
.clkdm_name = "alwon_l3s_clkdm",
- .main_clk = "timer_sys_ck",
+ .main_clk = "timer2_fck",
.dev_attr = &capability_alwon_dev_attr,
.class = &dm816x_timer_hwmod_class,
.flags = HWMOD_NO_IDLEST,
@@ -643,7 +665,7 @@ static struct omap_hwmod dm814x_timer2_hwmod = {
static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = {
.master = &dm81xx_l4_ls_hwmod,
.slave = &dm814x_timer2_hwmod,
- .clk = "timer_sys_ck",
+ .clk = "timer2_fck",
.user = OCP_USER_MPU,
};
@@ -850,6 +872,7 @@ static struct omap_hwmod dm816x_emac0_hwmod = {
.name = "emac0",
.clkdm_name = "alwon_ethernet_clkdm",
.class = &dm816x_emac_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
};
static struct omap_hwmod_ocp_if dm81xx_l4_hs__emac0 = {
@@ -909,7 +932,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
+static struct omap_hwmod_class_sysconfig dm81xx_mmc_sysc = {
.rev_offs = 0x0,
.sysc_offs = 0x110,
.syss_offs = 0x114,
@@ -920,24 +943,94 @@ static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
.sysc_fields = &omap_hwmod_sysc_type1,
};
-static struct omap_hwmod_class dm816x_mmc_class = {
+static struct omap_hwmod_class dm81xx_mmc_class = {
.name = "mmc",
- .sysc = &dm816x_mmc_sysc,
+ .sysc = &dm81xx_mmc_sysc,
};
-static struct omap_hwmod_opt_clk dm816x_mmc1_opt_clks[] = {
+static struct omap_hwmod_opt_clk dm81xx_mmc_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_hsmmc_dev_attr mmc_dev_attr = {
+};
+
+static struct omap_hwmod dm814x_mmc1_hwmod = {
+ .name = "mmc1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .opt_clks = dm81xx_mmc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+ .main_clk = "sysclk8_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM814X_CM_ALWON_MMCHS_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc_dev_attr,
+ .class = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__mmc1 = {
+ .master = &dm81xx_l4_ls_hwmod,
+ .slave = &dm814x_mmc1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod dm814x_mmc2_hwmod = {
+ .name = "mmc2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .opt_clks = dm81xx_mmc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+ .main_clk = "sysclk8_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM814X_CM_ALWON_MMCHS_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc_dev_attr,
+ .class = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__mmc2 = {
+ .master = &dm81xx_l4_ls_hwmod,
+ .slave = &dm814x_mmc2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod dm814x_mmc3_hwmod = {
+ .name = "mmc3",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .opt_clks = dm81xx_mmc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm81xx_mmc_opt_clks),
+ .main_clk = "sysclk8_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM814X_CM_ALWON_MMCHS_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc_dev_attr,
+ .class = &dm81xx_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm814x_alwon_l3_med__mmc3 = {
+ .master = &dm81xx_alwon_l3_med_hwmod,
+ .slave = &dm814x_mmc3_hwmod,
+ .clk = "sysclk4_ck",
+ .user = OCP_USER_MPU,
};
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),
+ .opt_clks = dm81xx_mmc_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm81xx_mmc_opt_clks),
.main_clk = "sysclk10_ck",
.prcm = {
.omap4 = {
@@ -945,8 +1038,8 @@ static struct omap_hwmod dm816x_mmc1_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
- .dev_attr = &mmc1_dev_attr,
- .class = &dm816x_mmc_class,
+ .dev_attr = &mmc_dev_attr,
+ .class = &dm81xx_mmc_class,
};
static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
@@ -1033,6 +1126,40 @@ static struct omap_hwmod_ocp_if dm81xx_l4_ls__mailbox = {
.user = OCP_USER_MPU,
};
+static struct omap_hwmod_class_sysconfig dm81xx_spinbox_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 dm81xx_spinbox_hwmod_class = {
+ .name = "spinbox",
+ .sysc = &dm81xx_spinbox_sysc,
+};
+
+static struct omap_hwmod dm81xx_spinbox_hwmod = {
+ .name = "spinbox",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_spinbox_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM81XX_CM_ALWON_SPINBOX_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__spinbox = {
+ .master = &dm81xx_l4_ls_hwmod,
+ .slave = &dm81xx_spinbox_hwmod,
+ .user = OCP_USER_MPU,
+};
+
static struct omap_hwmod_class dm81xx_tpcc_hwmod_class = {
.name = "tpcc",
};
@@ -1227,11 +1354,7 @@ static struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = {
/*
* REVISIT: Test and enable the following once clocks work:
- * dm81xx_l4_ls__gpio1
- * dm81xx_l4_ls__gpio2
* dm81xx_l4_ls__mailbox
- * dm81xx_alwon_l3_slow__gpmc
- * dm81xx_default_l3_slow__usbss
*
* Also note that some devices share a single clkctrl_offs..
* For example, i2c1 and 3 share one, and i2c2 and 4 share one.
@@ -1247,8 +1370,12 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = {
&dm81xx_l4_ls__wd_timer1,
&dm81xx_l4_ls__i2c1,
&dm81xx_l4_ls__i2c2,
+ &dm81xx_l4_ls__gpio1,
+ &dm81xx_l4_ls__gpio2,
&dm81xx_l4_ls__elm,
&dm81xx_l4_ls__mcspi1,
+ &dm814x_l4_ls__mmc1,
+ &dm814x_l4_ls__mmc2,
&dm81xx_alwon_l3_fast__tpcc,
&dm81xx_alwon_l3_fast__tptc0,
&dm81xx_alwon_l3_fast__tptc1,
@@ -1262,6 +1389,9 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = {
&dm814x_l4_ls__timer2,
&dm814x_l4_hs__cpgmac0,
&dm814x_cpgmac0__mdio,
+ &dm81xx_alwon_l3_slow__gpmc,
+ &dm814x_default_l3_slow__usbss,
+ &dm814x_alwon_l3_med__mmc3,
NULL,
};
@@ -1295,6 +1425,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
&dm816x_l4_ls__timer7,
&dm81xx_l4_ls__mcspi1,
&dm81xx_l4_ls__mailbox,
+ &dm81xx_l4_ls__spinbox,
&dm81xx_l4_hs__emac0,
&dm81xx_emac0__mdio,
&dm816x_l4_hs__emac1,
@@ -1308,7 +1439,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
&dm81xx_tptc2__alwon_l3_fast,
&dm81xx_tptc3__alwon_l3_fast,
&dm81xx_alwon_l3_slow__gpmc,
- &dm81xx_default_l3_slow__usbss,
+ &dm816x_default_l3_slow__usbss,
NULL,
};
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 1dfe346..a935d28 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -23,9 +23,8 @@
#include <linux/platform_data/pinctrl-single.h>
#include <linux/platform_data/iommu-omap.h>
#include <linux/platform_data/wkup_m3.h>
-
-#include <asm/siginfo.h>
-#include <asm/signal.h>
+#include <linux/platform_data/pwm_omap_dmtimer.h>
+#include <plat/dmtimer.h>
#include "common.h"
#include "common-board-devices.h"
@@ -153,6 +152,21 @@ static struct platform_device wl18xx_device = {
}
};
+static struct ti_st_plat_data wilink7_pdata = {
+ .nshutdown_gpio = 162,
+ .dev_name = "/dev/ttyO1",
+ .flow_cntrl = 1,
+ .baud_rate = 300000,
+};
+
+static struct platform_device wl128x_device = {
+ .name = "kim",
+ .id = -1,
+ .dev = {
+ .platform_data = &wilink7_pdata,
+ }
+};
+
static struct platform_device btwilink_device = {
.name = "btwilink",
.id = -1,
@@ -268,7 +282,7 @@ static void __init nokia_n900_legacy_init(void)
pr_warn("Thumb binaries may crash randomly without this workaround\n");
}
- pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+ pr_info("RX-51: Registering OMAP3 HWRNG device\n");
platform_device_register(&omap3_rom_rng_device);
}
@@ -279,6 +293,13 @@ static void __init omap3_tao3530_legacy_init(void)
hsmmc2_internal_input_clk();
}
+static void __init omap3_logicpd_torpedo_init(void)
+{
+ omap3_gpio126_127_129();
+ platform_device_register(&wl128x_device);
+ platform_device_register(&btwilink_device);
+}
+
/* omap3pandora legacy devices */
#define PANDORA_WIFI_IRQ_GPIO 21
#define PANDORA_WIFI_NRESET_GPIO 23
@@ -385,29 +406,6 @@ static void __init omap3_pandora_legacy_init(void)
}
#endif /* CONFIG_ARCH_OMAP3 */
-#ifdef CONFIG_SOC_TI81XX
-static int fault_fixed_up;
-
-static int t410_abort_handler(unsigned long addr, unsigned int fsr,
- struct pt_regs *regs)
-{
- if ((fsr == 0x406 || fsr == 0xc06) && !fault_fixed_up) {
- pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
- addr, fsr);
- fault_fixed_up = 1;
- return 0;
- }
-
- return 1;
-}
-
-static void __init t410_abort_init(void)
-{
- hook_fault_code(16 + 6, t410_abort_handler, SIGBUS, BUS_OBJERR,
- "imprecise external abort");
-}
-#endif
-
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
static struct iommu_platform_data omap4_iommu_pdata = {
.reset_name = "mmu_cache",
@@ -453,6 +451,24 @@ void omap_auxdata_legacy_init(struct device *dev)
dev->platform_data = &twl_gpio_auxdata;
}
+/* Dual mode timer PWM callbacks platdata */
+#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
+struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
+ .request_by_node = omap_dm_timer_request_by_node,
+ .free = omap_dm_timer_free,
+ .enable = omap_dm_timer_enable,
+ .disable = omap_dm_timer_disable,
+ .get_fclk = omap_dm_timer_get_fclk,
+ .start = omap_dm_timer_start,
+ .stop = omap_dm_timer_stop,
+ .set_load = omap_dm_timer_set_load,
+ .set_match = omap_dm_timer_set_match,
+ .set_pwm = omap_dm_timer_set_pwm,
+ .set_prescaler = omap_dm_timer_set_prescaler,
+ .write_counter = omap_dm_timer_write_counter,
+};
+#endif
+
/*
* Few boards still need auxdata populated before we populate
* the dev entries in of_platform_populate().
@@ -506,6 +522,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
&wkup_m3_data),
#endif
+#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
+ OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata),
+#endif
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
&omap4_iommu_pdata),
@@ -529,16 +548,13 @@ static struct pdata_init pdata_quirks[] __initdata = {
{ "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, },
- { "logicpd,dm3730-torpedo-devkit", omap3_gpio126_127_129, },
+ { "logicpd,dm3730-torpedo-devkit", omap3_logicpd_torpedo_init, },
{ "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
{ "ti,am3517-evm", am3517_evm_legacy_init, },
{ "technexion,omap3-tao3530", omap3_tao3530_legacy_init, },
{ "openpandora,omap3-pandora-600mhz", omap3_pandora_legacy_init, },
{ "openpandora,omap3-pandora-1ghz", omap3_pandora_legacy_init, },
#endif
-#ifdef CONFIG_SOC_TI81XX
- { "hp,t410", t410_abort_init, },
-#endif
#ifdef CONFIG_SOC_OMAP5
{ "ti,omap5-uevm", omap5_uevm_legacy_init, },
#endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 87b98bf9..2dbd378 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -301,11 +301,11 @@ static void omap3_pm_idle(void)
if (omap_irq_pending())
return;
- trace_cpu_idle(1, smp_processor_id());
+ trace_cpu_idle_rcuidle(1, smp_processor_id());
omap_sram_idle();
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+ trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_SUSPEND
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index d697cec..178e22c 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -210,7 +210,7 @@ static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
}
map++;
- };
+ }
return 0;
}
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index d31c495..eb27ae0 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -384,14 +384,14 @@ static struct powerdomain isp_814x_pwrdm = {
.voltdm = { .name = "core" },
};
-static struct powerdomain active_816x_pwrdm = {
+static struct powerdomain active_81xx_pwrdm = {
.name = "active_pwrdm",
.prcm_offs = TI816X_PRM_ACTIVE_MOD,
.pwrsts = PWRSTS_OFF_ON,
.voltdm = { .name = "core" },
};
-static struct powerdomain default_816x_pwrdm = {
+static struct powerdomain default_81xx_pwrdm = {
.name = "default_pwrdm",
.prcm_offs = TI81XX_PRM_DEFAULT_MOD,
.pwrsts = PWRSTS_OFF_ON,
@@ -486,6 +486,8 @@ static struct powerdomain *powerdomains_am35x[] __initdata = {
static struct powerdomain *powerdomains_ti814x[] __initdata = {
&alwon_81xx_pwrdm,
&device_81xx_pwrdm,
+ &active_81xx_pwrdm,
+ &default_81xx_pwrdm,
&gem_814x_pwrdm,
&ivahd_814x_pwrdm,
&hdvpss_814x_pwrdm,
@@ -497,8 +499,8 @@ static struct powerdomain *powerdomains_ti814x[] __initdata = {
static struct powerdomain *powerdomains_ti816x[] __initdata = {
&alwon_81xx_pwrdm,
&device_81xx_pwrdm,
- &active_816x_pwrdm,
- &default_816x_pwrdm,
+ &active_81xx_pwrdm,
+ &default_81xx_pwrdm,
&ivahd0_816x_pwrdm,
&ivahd1_816x_pwrdm,
&ivahd2_816x_pwrdm,
@@ -582,7 +584,7 @@ void __init omap3xxx_powerdomains_init(void)
/* Only 81xx needs custom pwrdm_operations */
if (!cpu_is_ti81xx())
- pwrdm_register_platform_funcs(&omap3_pwrdm_operations);;
+ pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
rev = omap_rev();
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 3fc2cbe..5b2f513 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -664,6 +664,13 @@ static struct omap_prcm_init_data am3_prm_data __initdata = {
};
#endif
+#ifdef CONFIG_SOC_TI81XX
+static struct omap_prcm_init_data dm814_pllss_data __initdata = {
+ .index = TI_CLKM_PLLSS,
+ .init = am33xx_prm_init,
+};
+#endif
+
#ifdef CONFIG_ARCH_OMAP4
static struct omap_prcm_init_data omap4_prm_data __initdata = {
.index = TI_CLKM_PRM,
@@ -715,6 +722,7 @@ static const struct of_device_id const omap_prcm_dt_match_table[] __initconst =
#endif
#ifdef CONFIG_SOC_TI81XX
{ .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
+ { .compatible = "ti,dm814-pllss", .data = &dm814_pllss_data },
{ .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
#endif
#ifdef CONFIG_ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 5fb50fe..8e072de 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -213,7 +213,7 @@ static int __init omap_serial_early_init(void)
return 0;
}
-omap_core_initcall(omap_serial_early_init);
+omap_postcore_initcall(omap_serial_early_init);
/**
* omap_serial_init_port() - initialize single serial port
@@ -252,7 +252,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
info = omap_serial_default_info;
oh = uart->oh;
- name = DRIVER_NAME;
+ name = OMAP_SERIAL_DRIVER_NAME;
omap_up.dma_enabled = info->dma_enabled;
omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index eafd120..1b9f052 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -86,13 +86,18 @@ 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]
+ adrl r3, l2dis_3630_offset @ may be too distant for plain adr
+ ldr r2, [r3] @ value for offset
+ str r1, [r2, r3] @ write to l2dis_3630
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 */
+/*
+ * Function to call rom code to save secure ram context. This gets
+ * relocated to SRAM, so it can be all in .data section. Otherwise
+ * we need to initialize api_params separately.
+ */
+ .data
.align 3
ENTRY(save_secure_ram_context)
stmfd sp!, {r4 - r11, lr} @ save registers on stack
@@ -126,6 +131,8 @@ ENDPROC(save_secure_ram_context)
ENTRY(save_secure_ram_context_sz)
.word . - save_secure_ram_context
+ .text
+
/*
* ======================
* == Idle entry point ==
@@ -289,12 +296,6 @@ wait_sdrc_ready:
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
@@ -302,11 +303,7 @@ is_dll_in_lock_mode:
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
@@ -330,9 +327,6 @@ kick_dll:
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:
@@ -360,15 +354,6 @@ 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
@@ -437,7 +422,9 @@ ENTRY(omap3_restore)
cmp r2, #0x0 @ Check if target power state was OFF or RET
bne logic_l1_restore
- ldr r0, l2dis_3630
+ adr r1, l2dis_3630_offset @ address for offset
+ ldr r0, [r1] @ value for offset
+ ldr r0, [r1, r0] @ value at l2dis_3630
cmp r0, #0x1 @ should we disable L2 on 3630?
bne skipl2dis
mrc p15, 0, r0, c1, c0, 1
@@ -449,12 +436,14 @@ skipl2dis:
and r1, #0x700
cmp r1, #0x300
beq l2_inv_gp
+ adr r0, l2_inv_api_params_offset
+ ldr r3, [r0]
+ add r3, r3, r0 @ r3 points to dummy parameters
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)
@@ -488,8 +477,8 @@ skipl2dis:
b logic_l1_restore
.align
-l2_inv_api_params:
- .word 0x1, 0x00
+l2_inv_api_params_offset:
+ .long l2_inv_api_params - .
l2_inv_gp:
/* Execute smi to invalidate L2 cache */
mov r12, #0x1 @ set up to invalidate L2
@@ -506,7 +495,9 @@ l2_inv_gp:
mov r12, #0x2
smc #0 @ Call SMI monitor (smieq)
logic_l1_restore:
- ldr r1, l2dis_3630
+ adr r0, l2dis_3630_offset @ adress for offset
+ ldr r1, [r0] @ value for offset
+ ldr r1, [r0, r1] @ value at l2dis_3630
cmp r1, #0x1 @ Test if L2 re-enable needed on 3630
bne skipl2reen
mrc p15, 0, r1, c1, c0, 1
@@ -535,9 +526,17 @@ control_stat:
.word CONTROL_STAT
control_mem_rta:
.word CONTROL_MEM_RTA_CTRL
+l2dis_3630_offset:
+ .long l2dis_3630 - .
+
+ .data
l2dis_3630:
.word 0
+ .data
+l2_inv_api_params:
+ .word 0x1, 0x00
+
/*
* Internal functions
*/
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
index 9b09d85..c7a3b4a 100644
--- a/arch/arm/mach-omap2/sleep44xx.S
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -29,12 +29,6 @@
dsb
.endm
-ppa_zero_params:
- .word 0x0
-
-ppa_por_params:
- .word 1, 0
-
#ifdef CONFIG_ARCH_OMAP4
/*
@@ -266,7 +260,9 @@ ENTRY(omap4_cpu_resume)
beq skip_ns_smp_enable
ppa_actrl_retry:
mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
- adr r3, ppa_zero_params @ Pointer to parameters
+ adr r1, ppa_zero_params_offset
+ ldr r3, [r1]
+ add r3, r3, r1 @ Pointer to ppa_zero_params
mov r1, #0x0 @ Process ID
mov r2, #0x4 @ Flag
mov r6, #0xff
@@ -303,7 +299,9 @@ skip_ns_smp_enable:
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
+ adr r1, ppa_por_params_offset
+ ldr r3, [r1]
+ add r3, r3, r1 @ Pointer to ppa_por_params
str r4, [r3, #0x04]
mov r1, #0x0 @ Process ID
mov r2, #0x4 @ Flag
@@ -328,6 +326,8 @@ skip_l2en:
#endif
b cpu_resume @ Jump to generic resume
+ppa_por_params_offset:
+ .long ppa_por_params - .
ENDPROC(omap4_cpu_resume)
#endif /* CONFIG_ARCH_OMAP4 */
@@ -380,4 +380,13 @@ ENTRY(omap_do_wfi)
nop
ldmfd sp!, {pc}
+ppa_zero_params_offset:
+ .long ppa_zero_params - .
ENDPROC(omap_do_wfi)
+
+ .data
+ppa_zero_params:
+ .word 0
+
+ppa_por_params:
+ .word 1, 0
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
index 2d1d384..79ca3c3 100644
--- a/arch/arm/mach-omap2/soc.h
+++ b/arch/arm/mach-omap2/soc.h
@@ -129,9 +129,9 @@ 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]
+ * SoC id bits (0730, 1510, 1710, 2422...) [31:16]
+ * SoC revision (See _REV_ defined in cpu.h) [15:08]
+ * SoC class bits (15xx, 16xx, 24xx, 34xx...) [07:00]
*/
unsigned int omap_rev(void);
@@ -141,20 +141,20 @@ static inline int soc_is_omap(void)
}
/*
- * Get the CPU revision for OMAP devices
+ * Get the SoC 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_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
+ * soc_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423
+ * soc_is_omap243x(): True for OMAP2430
+ * soc_is_omap343x(): True for OMAP3430
+ * soc_is_omap443x(): True for OMAP4430
+ * soc_is_omap446x(): True for OMAP4460
+ * soc_is_omap447x(): True for OMAP4470
* soc_is_omap543x(): True for OMAP5430, OMAP5432
*/
#define GET_OMAP_CLASS (omap_rev() & 0xff)
@@ -225,23 +225,23 @@ 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_omap24xx() 0
+#define soc_is_omap242x() 0
+#define soc_is_omap243x() 0
+#define soc_is_omap34xx() 0
+#define soc_is_omap343x() 0
+#define soc_is_ti81xx() 0
+#define soc_is_ti816x() 0
+#define soc_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_omap44xx() 0
+#define soc_is_omap443x() 0
+#define soc_is_omap446x() 0
+#define soc_is_omap447x() 0
#define soc_is_omap54xx() 0
#define soc_is_omap543x() 0
#define soc_is_dra7xx() 0
@@ -250,54 +250,54 @@ IS_AM_SUBCLASS(437x, 0x437)
#if defined(MULTI_OMAP2)
# if defined(CONFIG_ARCH_OMAP2)
-# undef cpu_is_omap24xx
-# define cpu_is_omap24xx() is_omap24xx()
+# undef soc_is_omap24xx
+# define soc_is_omap24xx() is_omap24xx()
# endif
# if defined (CONFIG_SOC_OMAP2420)
-# undef cpu_is_omap242x
-# define cpu_is_omap242x() is_omap242x()
+# undef soc_is_omap242x
+# define soc_is_omap242x() is_omap242x()
# endif
# if defined (CONFIG_SOC_OMAP2430)
-# undef cpu_is_omap243x
-# define cpu_is_omap243x() is_omap243x()
+# undef soc_is_omap243x
+# define soc_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()
+# undef soc_is_omap34xx
+# undef soc_is_omap343x
+# define soc_is_omap34xx() is_omap34xx()
+# define soc_is_omap343x() is_omap343x()
# endif
#else
# if defined(CONFIG_ARCH_OMAP2)
-# undef cpu_is_omap24xx
-# define cpu_is_omap24xx() 1
+# undef soc_is_omap24xx
+# define soc_is_omap24xx() 1
# endif
# if defined(CONFIG_SOC_OMAP2420)
-# undef cpu_is_omap242x
-# define cpu_is_omap242x() 1
+# undef soc_is_omap242x
+# define soc_is_omap242x() 1
# endif
# if defined(CONFIG_SOC_OMAP2430)
-# undef cpu_is_omap243x
-# define cpu_is_omap243x() 1
+# undef soc_is_omap243x
+# define soc_is_omap243x() 1
# endif
# if defined(CONFIG_ARCH_OMAP3)
-# undef cpu_is_omap34xx
-# define cpu_is_omap34xx() 1
+# undef soc_is_omap34xx
+# define soc_is_omap34xx() 1
# endif
# if defined(CONFIG_SOC_OMAP3430)
-# undef cpu_is_omap343x
-# define cpu_is_omap343x() 1
+# undef soc_is_omap343x
+# define soc_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
+ * soc_is_omap2420(): True for OMAP2420
+ * soc_is_omap2422(): True for OMAP2422
+ * soc_is_omap2423(): True for OMAP2423
+ * soc_is_omap2430(): True for OMAP2430
+ * soc_is_omap3430(): True for OMAP3430
*/
#define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff)
@@ -313,51 +313,51 @@ 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_omap2420() 0
+#define soc_is_omap2422() 0
+#define soc_is_omap2423() 0
+#define soc_is_omap2430() 0
+#define soc_is_omap3430() 0
+#define soc_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 soc_is_omap7xx() 0
+#define soc_is_omap15xx() 0
+#define soc_is_omap16xx() 0
+#define soc_is_omap1510() 0
+#define soc_is_omap1610() 0
+#define soc_is_omap1611() 0
+#define soc_is_omap1621() 0
+#define soc_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()
+# undef soc_is_omap2420
+# undef soc_is_omap2422
+# undef soc_is_omap2423
+# undef soc_is_omap2430
+# define soc_is_omap2420() is_omap2420()
+# define soc_is_omap2422() is_omap2422()
+# define soc_is_omap2423() is_omap2423()
+# define soc_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_omap3430
+# undef soc_is_ti81xx
+# undef soc_is_ti816x
+# undef soc_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_omap3430() is_omap3430()
+# undef soc_is_omap3630
+# define soc_is_omap3630() is_omap363x()
+# define soc_is_ti81xx() is_ti81xx()
+# define soc_is_ti816x() is_ti816x()
+# define soc_is_ti814x() is_ti814x()
# define soc_is_am35xx() is_am35xx()
#endif
@@ -376,14 +376,14 @@ IS_OMAP_TYPE(3430, 0x3430)
#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()
+# undef soc_is_omap44xx
+# undef soc_is_omap443x
+# undef soc_is_omap446x
+# undef soc_is_omap447x
+# define soc_is_omap44xx() is_omap44xx()
+# define soc_is_omap443x() is_omap443x()
+# define soc_is_omap446x() is_omap446x()
+# define soc_is_omap447x() is_omap447x()
# endif
# if defined(CONFIG_SOC_OMAP5)
@@ -556,5 +556,22 @@ level(__##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__ */
+/* Legacy defines, these can be removed when users are removed */
+#define cpu_is_omap2420() soc_is_omap2420()
+#define cpu_is_omap2422() soc_is_omap2422()
+#define cpu_is_omap242x() soc_is_omap242x()
+#define cpu_is_omap2430() soc_is_omap2430()
+#define cpu_is_omap243x() soc_is_omap243x()
+#define cpu_is_omap24xx() soc_is_omap24xx()
+#define cpu_is_omap3430() soc_is_omap3430()
+#define cpu_is_omap343x() soc_is_omap343x()
+#define cpu_is_omap34xx() soc_is_omap34xx()
+#define cpu_is_omap3630() soc_is_omap3630()
+#define cpu_is_omap443x() soc_is_omap443x()
+#define cpu_is_omap446x() soc_is_omap446x()
+#define cpu_is_omap44xx() soc_is_omap44xx()
+#define cpu_is_ti814x() soc_is_ti814x()
+#define cpu_is_ti816x() soc_is_ti816x()
+#define cpu_is_ti81xx() soc_is_ti81xx()
+#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/mach-omap2/sram.c b/arch/arm/mach-omap2/sram.c
index cd488b8..83d0e61 100644
--- a/arch/arm/mach-omap2/sram.c
+++ b/arch/arm/mach-omap2/sram.c
@@ -211,35 +211,10 @@ static inline int omap243x_sram_init(void)
#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();
}
diff --git a/arch/arm/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h
index 948d3ed..18dc884 100644
--- a/arch/arm/mach-omap2/sram.h
+++ b/arch/arm/mach-omap2/sram.h
@@ -15,12 +15,6 @@ 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 */
@@ -52,14 +46,6 @@ 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
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
deleted file mode 100644
index 1446331..0000000
--- a/arch/arm/mach-omap2/sram34xx.S
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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/timer.c b/arch/arm/mach-omap2/timer.c
index a556551..5b385bb 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -183,7 +183,8 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
of_get_property(np, "ti,timer-secure", NULL)))
continue;
- of_add_property(np, &device_disabled);
+ if (!of_device_is_compatible(np, "ti,omap-counter32k"))
+ of_add_property(np, &device_disabled);
return np;
}
@@ -193,8 +194,8 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
/**
* 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
+ * For secure OMAP3/DRA7xx 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.
*/
@@ -202,7 +203,7 @@ static void __init omap_dmtimer_init(void)
{
struct device_node *np;
- if (!cpu_is_omap34xx())
+ if (!cpu_is_omap34xx() && !soc_is_dra7xx())
return;
/* If we are a secure device, remove any secure timer nodes */
@@ -319,6 +320,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
return r;
}
+#if !defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+void tick_broadcast(const struct cpumask *mask)
+{
+}
+#endif
+
static void __init omap2_gp_clockevent_init(int gptimer_id,
const char *fck_source,
const char *property)
@@ -394,7 +401,6 @@ 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";
/*
@@ -420,18 +426,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
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",
@@ -439,13 +433,18 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
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);
- }
+ if (!of_have_populated_dt()) {
+ void __iomem *vbase;
+
+ vbase = omap_hwmod_get_mpu_rt_va(oh);
+ 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;
}
@@ -476,7 +475,64 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
clocksource_gpt.name, clksrc.rate);
}
-#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
+static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src,
+ const char *clkev_prop, int clksrc_nr, const char *clksrc_src,
+ const char *clksrc_prop, bool gptimer)
+{
+ 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 || gptimer)
+ omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src,
+ clksrc_prop);
+ else
+ omap2_sync32k_clocksource_init();
+}
+
+void __init omap_init_time(void)
+{
+ __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
+ 2, "timer_sys_ck", NULL, false);
+
+ if (of_have_populated_dt())
+ clocksource_probe();
+}
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
+void __init omap3_secure_sync32k_timer_init(void)
+{
+ __omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure",
+ 2, "timer_sys_ck", NULL, false);
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
+void __init omap3_gptimer_timer_init(void)
+{
+ __omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
+ 1, "timer_sys_ck", "ti,timer-alwon", true);
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
+ defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
+static void __init omap4_sync32k_timer_init(void)
+{
+ __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
+ 2, "sys_clkin_ck", NULL, false);
+}
+
+void __init omap4_local_timer_init(void)
+{
+ omap4_sync32k_timer_init();
+ clocksource_probe();
+}
+#endif
+
+#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+
/*
* The realtime counter also called master counter, is a free-running
* counter, which is related to real time. It produces the count used
@@ -488,6 +544,7 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
*/
static void __init realtime_counter_init(void)
{
+#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void __iomem *base;
static struct clk *sys_clk;
unsigned long rate;
@@ -586,84 +643,15 @@ sysclk1_based:
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
-void __init omap4_local_timer_init(void)
-{
- omap4_sync32k_timer_init();
- clocksource_of_init();
}
-#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();
+ clocksource_probe();
}
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index d44d311..2028167f 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -280,10 +280,6 @@ void omap3_vc_set_pmic_signaling(int core_next_state)
}
}
-#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
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 08d2be2..a9ad95f 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -1,6 +1,18 @@
-if ARCH_ORION5X
+menuconfig ARCH_ORION5X
+ bool "Marvell Orion"
+ depends on MMU && ARCH_MULTI_V5
+ 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).
-menu "Orion Implementations"
+if ARCH_ORION5X
config ARCH_ORION5X_DT
bool "Marvell Orion5x Flattened Device Tree"
@@ -45,6 +57,7 @@ config MACH_KUROBOX_PRO
config MACH_DNS323
bool "D-Link DNS-323"
+ select GENERIC_NET_UTILS
select I2C_BOARDINFO
help
Say 'Y' here if you want your kernel to support the
@@ -52,6 +65,7 @@ config MACH_DNS323
config MACH_TS209
bool "QNAP TS-109/TS-209"
+ select GENERIC_NET_UTILS
help
Say 'Y' here if you want your kernel to support the
QNAP TS-109/TS-209 platform.
@@ -93,6 +107,7 @@ config MACH_LINKSTATION_LS_HGL
config MACH_TS409
bool "QNAP TS-409"
+ select GENERIC_NET_UTILS
help
Say 'Y' here if you want your kernel to support the
QNAP TS-409 platform.
@@ -160,6 +175,4 @@ config MACH_RD88F6183AP_GE
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
index a1e0fbe..4b2502b 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -1,3 +1,5 @@
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include
+
obj-y += common.o pci.o irq.o mpp.o
obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
diff --git a/arch/arm/mach-orion5x/board-d2net.c b/arch/arm/mach-orion5x/board-d2net.c
index 8a72841..a89376a 100644
--- a/arch/arm/mach-orion5x/board-d2net.c
+++ b/arch/arm/mach-orion5x/board-d2net.c
@@ -20,9 +20,9 @@
#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"
+#include "orion5x.h"
/*****************************************************************************
* LaCie d2 Network Info
diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c
index d087178..6f4c2c4 100644
--- a/arch/arm/mach-orion5x/board-dt.c
+++ b/arch/arm/mach-orion5x/board-dt.c
@@ -20,10 +20,10 @@
#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 "orion5x.h"
+#include "bridge-regs.h"
#include "common.h"
static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
diff --git a/arch/arm/mach-orion5x/board-mss2.c b/arch/arm/mach-orion5x/board-mss2.c
index 66f9c3b..79202fd 100644
--- a/arch/arm/mach-orion5x/board-mss2.c
+++ b/arch/arm/mach-orion5x/board-mss2.c
@@ -17,8 +17,8 @@
#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 "orion5x.h"
+#include "bridge-regs.h"
#include "common.h"
/*****************************************************************************
diff --git a/arch/arm/mach-orion5x/board-rd88f5182.c b/arch/arm/mach-orion5x/board-rd88f5182.c
index 270824b..b7b0f52 100644
--- a/arch/arm/mach-orion5x/board-rd88f5182.c
+++ b/arch/arm/mach-orion5x/board-rd88f5182.c
@@ -18,8 +18,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <mach/orion5x.h>
#include "common.h"
+#include "orion5x.h"
/*****************************************************************************
* RD-88F5182 Info
diff --git a/arch/arm/mach-orion5x/bridge-regs.h b/arch/arm/mach-orion5x/bridge-regs.h
new file mode 100644
index 0000000..305598e
--- /dev/null
+++ b/arch/arm/mach-orion5x/bridge-regs.h
@@ -0,0 +1,35 @@
+/*
+ * 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 "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/common.c b/arch/arm/mach-orion5x/common.c
index 6bbb7b5..70c3366 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -27,14 +27,14 @@
#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 "bridge-regs.h"
#include "common.h"
+#include "orion5x.h"
/*****************************************************************************
* I/O Address Mapping
@@ -184,9 +184,21 @@ static void __init orion5x_crypto_init(void)
/*****************************************************************************
* 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,
+};
+
static void __init orion5x_wdt_init(void)
{
- orion_wdt_init();
+ platform_device_register(&orion_wdt_device);
}
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index dc01c4f..12f74b4 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -23,10 +23,10 @@
#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"
+#include "orion5x.h"
/*****************************************************************************
* DB-88F5281 on board devices
@@ -369,6 +369,7 @@ static void __init db88f5281_init(void)
MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = db88f5281_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index f267e58..cd483bf 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -33,8 +33,8 @@
#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 "orion5x.h"
#include "common.h"
#include "mpp.h"
@@ -173,42 +173,10 @@ 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;
+ void __iomem *mac_page;
/* MAC address is stored as a regular ol' string in /dev/mtdblock4
* (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
@@ -217,23 +185,8 @@ static int __init dns323_read_mac_addr(void)
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;
- }
+ if (!mac_pton((__force const char *) mac_page, addr))
+ goto error_fail;
iounmap(mac_page);
printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
@@ -713,6 +666,7 @@ static void __init dns323_init(void)
MACHINE_START(DNS323, "D-Link DNS-323")
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = dns323_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
deleted file mode 100644
index 5766e3f..0000000
--- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 79eb502..0000000
--- a/arch/arm/mach-orion5x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3957354..0000000
--- a/arch/arm/mach-orion5x/include/mach/hardware.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2431d99..0000000
--- a/arch/arm/mach-orion5x/include/mach/irqs.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 (1 + 0)
-#define IRQ_ORION5X_DOORBELL_H2C (1 + 1)
-#define IRQ_ORION5X_DOORBELL_C2H (1 + 2)
-#define IRQ_ORION5X_UART0 (1 + 3)
-#define IRQ_ORION5X_UART1 (1 + 4)
-#define IRQ_ORION5X_I2C (1 + 5)
-#define IRQ_ORION5X_GPIO_0_7 (1 + 6)
-#define IRQ_ORION5X_GPIO_8_15 (1 + 7)
-#define IRQ_ORION5X_GPIO_16_23 (1 + 8)
-#define IRQ_ORION5X_GPIO_24_31 (1 + 9)
-#define IRQ_ORION5X_PCIE0_ERR (1 + 10)
-#define IRQ_ORION5X_PCIE0_INT (1 + 11)
-#define IRQ_ORION5X_USB1_CTRL (1 + 12)
-#define IRQ_ORION5X_DEV_BUS_ERR (1 + 14)
-#define IRQ_ORION5X_PCI_ERR (1 + 15)
-#define IRQ_ORION5X_USB_BR_ERR (1 + 16)
-#define IRQ_ORION5X_USB0_CTRL (1 + 17)
-#define IRQ_ORION5X_ETH_RX (1 + 18)
-#define IRQ_ORION5X_ETH_TX (1 + 19)
-#define IRQ_ORION5X_ETH_MISC (1 + 20)
-#define IRQ_ORION5X_ETH_SUM (1 + 21)
-#define IRQ_ORION5X_ETH_ERR (1 + 22)
-#define IRQ_ORION5X_IDMA_ERR (1 + 23)
-#define IRQ_ORION5X_IDMA_0 (1 + 24)
-#define IRQ_ORION5X_IDMA_1 (1 + 25)
-#define IRQ_ORION5X_IDMA_2 (1 + 26)
-#define IRQ_ORION5X_IDMA_3 (1 + 27)
-#define IRQ_ORION5X_CESA (1 + 28)
-#define IRQ_ORION5X_SATA (1 + 29)
-#define IRQ_ORION5X_XOR0 (1 + 30)
-#define IRQ_ORION5X_XOR1 (1 + 31)
-
-/*
- * Orion General Purpose Pins
- */
-#define IRQ_ORION5X_GPIO_START 33
-#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
deleted file mode 100644
index b78ff32..0000000
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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
deleted file mode 100644
index abd26b5..0000000
--- a/arch/arm/mach-orion5x/include/mach/uncompress.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
index 086ecb8..de980ef 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -13,10 +13,10 @@
#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 "bridge-regs.h"
#include "common.h"
static int __initdata gpio0_irqs[4] = {
@@ -26,14 +26,6 @@ static int __initdata gpio0_irqs[4] = {
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)
{
@@ -47,15 +39,12 @@ __exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
return;
}
}
-#endif
void __init orion5x_init_irq(void)
{
orion_irq_init(1, MAIN_IRQ_MASK);
-#ifdef CONFIG_MULTI_IRQ_HANDLER
set_handle_irq(orion5x_legacy_handle_irq);
-#endif
/*
* Initialize gpiolib for GPIOs 0-31.
diff --git a/arch/arm/mach-orion5x/irqs.h b/arch/arm/mach-orion5x/irqs.h
new file mode 100644
index 0000000..506c8e0
--- /dev/null
+++ b/arch/arm/mach-orion5x/irqs.h
@@ -0,0 +1,58 @@
+/*
+ * 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 (1 + 0)
+#define IRQ_ORION5X_DOORBELL_H2C (1 + 1)
+#define IRQ_ORION5X_DOORBELL_C2H (1 + 2)
+#define IRQ_ORION5X_UART0 (1 + 3)
+#define IRQ_ORION5X_UART1 (1 + 4)
+#define IRQ_ORION5X_I2C (1 + 5)
+#define IRQ_ORION5X_GPIO_0_7 (1 + 6)
+#define IRQ_ORION5X_GPIO_8_15 (1 + 7)
+#define IRQ_ORION5X_GPIO_16_23 (1 + 8)
+#define IRQ_ORION5X_GPIO_24_31 (1 + 9)
+#define IRQ_ORION5X_PCIE0_ERR (1 + 10)
+#define IRQ_ORION5X_PCIE0_INT (1 + 11)
+#define IRQ_ORION5X_USB1_CTRL (1 + 12)
+#define IRQ_ORION5X_DEV_BUS_ERR (1 + 14)
+#define IRQ_ORION5X_PCI_ERR (1 + 15)
+#define IRQ_ORION5X_USB_BR_ERR (1 + 16)
+#define IRQ_ORION5X_USB0_CTRL (1 + 17)
+#define IRQ_ORION5X_ETH_RX (1 + 18)
+#define IRQ_ORION5X_ETH_TX (1 + 19)
+#define IRQ_ORION5X_ETH_MISC (1 + 20)
+#define IRQ_ORION5X_ETH_SUM (1 + 21)
+#define IRQ_ORION5X_ETH_ERR (1 + 22)
+#define IRQ_ORION5X_IDMA_ERR (1 + 23)
+#define IRQ_ORION5X_IDMA_0 (1 + 24)
+#define IRQ_ORION5X_IDMA_1 (1 + 25)
+#define IRQ_ORION5X_IDMA_2 (1 + 26)
+#define IRQ_ORION5X_IDMA_3 (1 + 27)
+#define IRQ_ORION5X_CESA (1 + 28)
+#define IRQ_ORION5X_SATA (1 + 29)
+#define IRQ_ORION5X_XOR0 (1 + 30)
+#define IRQ_ORION5X_XOR1 (1 + 31)
+
+/*
+ * Orion General Purpose Pins
+ */
+#define IRQ_ORION5X_GPIO_START 33
+#define NR_GPIO_IRQS 32
+
+#define ORION5X_NR_IRQS (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index fe6a48a..9dc3f59 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -23,10 +23,10 @@
#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"
+#include "orion5x.h"
/*****************************************************************************
* KUROBOX-PRO Info
@@ -383,6 +383,7 @@ static void __init kurobox_pro_init(void)
MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = kurobox_pro_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
@@ -397,6 +398,7 @@ MACHINE_END
MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = kurobox_pro_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
index 028ea03..dfdaa8a 100644
--- a/arch/arm/mach-orion5x/ls-chl-setup.c
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -22,9 +22,9 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
+#include "orion5x.h"
/*****************************************************************************
* Linkstation LS-CHL Info
@@ -320,6 +320,7 @@ static void __init lschl_init(void)
MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")
/* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = lschl_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
index 32b7129..47ba6e0 100644
--- a/arch/arm/mach-orion5x/ls_hgl-setup.c
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -21,9 +21,9 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
+#include "orion5x.h"
/*****************************************************************************
* Linkstation LS-HGL Info
@@ -267,6 +267,7 @@ static void __init ls_hgl_init(void)
MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
/* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = ls_hgl_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
index 5b70026..19ef185 100644
--- a/arch/arm/mach-orion5x/mpp.c
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -11,8 +11,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
-#include <mach/hardware.h>
#include <plat/mpp.h>
+#include "orion5x.h"
#include "mpp.h"
#include "common.h"
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index e032f01..2bf8ec7 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -21,9 +21,9 @@
#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"
+#include "orion5x.h"
#define MV2120_NOR_BOOT_BASE 0xf4000000
#define MV2120_NOR_BOOT_SIZE SZ_512K
@@ -232,6 +232,7 @@ static void __init mv2120_init(void)
MACHINE_START(MV2120, "HP Media Vault mv2120")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = mv2120_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index ba73dc7..bf6be4c 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -24,10 +24,10 @@
#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"
+#include "orion5x.h"
/*****************************************************************************
* LaCie 2Big Network Info
@@ -423,6 +423,7 @@ static void __init net2big_init(void)
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
MACHINE_START(NET2BIG, "LaCie 2Big Network")
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = net2big_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/orion5x.h b/arch/arm/mach-orion5x/orion5x.h
new file mode 100644
index 0000000..3364df3
--- /dev/null
+++ b/arch/arm/mach-orion5x/orion5x.h
@@ -0,0 +1,146 @@
+/*
+ * 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
+
+#include "irqs.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/pci.c b/arch/arm/mach-orion5x/pci.c
index b02f394..ecb998e 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -19,8 +19,8 @@
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <plat/addr-map.h>
-#include <mach/orion5x.h>
#include "common.h"
+#include "orion5x.h"
/*****************************************************************************
* Orion has one PCIe controller and one PCI controller.
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index 213b3e1..c742e7b 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -20,9 +20,9 @@
#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 "orion5x.h"
/*****************************************************************************
* RD-88F5181L FXO Info
@@ -169,6 +169,7 @@ 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,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = rd88f5181l_fxo_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index 594800e..7e977b7 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -21,9 +21,9 @@
#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 "orion5x.h"
/*****************************************************************************
* RD-88F5181L GE Info
@@ -181,6 +181,7 @@ 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,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = rd88f5181l_ge_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index b576ef5..fe3e67c 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -23,9 +23,9 @@
#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 "orion5x.h"
/*****************************************************************************
* RD-88F5182 Info
@@ -281,6 +281,7 @@ static void __init rd88f5182_init(void)
MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = rd88f5182_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
index 78a1e6a..4bf80dd 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -22,8 +22,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <mach/orion5x.h>
#include "common.h"
+#include "orion5x.h"
static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
.phy_addr = -1,
@@ -119,6 +119,7 @@ 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,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = rd88f6183ap_ge_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index 1208674..deb5e29 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -22,9 +22,9 @@
#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 "orion5x.h"
/*****************************************************************************
* Terastation Pro 2/Live Info
@@ -359,6 +359,7 @@ static void __init tsp2_init(void)
MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
/* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = tsp2_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index c725b7c..7bd671b 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -25,9 +25,9 @@
#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 "orion5x.h"
#include "tsx09-common.h"
#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
@@ -324,6 +324,7 @@ static void __init qnap_ts209_init(void)
MACHINE_START(TS209, "QNAP TS-109/TS-209")
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = qnap_ts209_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index cf2ab53..a77613b 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -27,9 +27,9 @@
#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 "orion5x.h"
#include "tsx09-common.h"
/*****************************************************************************
@@ -313,6 +313,7 @@ static void __init qnap_ts409_init(void)
MACHINE_START(TS409, "QNAP TS-409")
/* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = qnap_ts409_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 1b704d3..3a58a5d 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -23,9 +23,9 @@
#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 "orion5x.h"
#include "ts78xx-fpga.h"
/*****************************************************************************
@@ -176,7 +176,7 @@ static void ts78xx_ts_rtc_unload(void)
static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
if (ctrl & NAND_CTRL_CHANGE) {
unsigned char bits;
@@ -200,7 +200,7 @@ static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
const uint8_t *buf, int len)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *io_base = chip->IO_ADDR_W;
unsigned long off = ((unsigned long)buf & 3);
int sz;
@@ -227,7 +227,7 @@ static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd,
uint8_t *buf, int len)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *io_base = chip->IO_ADDR_R;
unsigned long off = ((unsigned long)buf & 3);
int sz;
@@ -615,6 +615,7 @@ static void __init ts78xx_init(void)
MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
/* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = ts78xx_init,
.map_io = ts78xx_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c
index 24b2959..8977498 100644
--- a/arch/arm/mach-orion5x/tsx09-common.c
+++ b/arch/arm/mach-orion5x/tsx09-common.c
@@ -15,7 +15,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/timex.h>
#include <linux/serial_reg.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
#include "tsx09-common.h"
#include "common.h"
@@ -53,53 +53,12 @@ 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;
- }
+ if (!mac_pton(addr_str, addr))
+ return -1;
printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr);
@@ -118,12 +77,12 @@ 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;
+ void __iomem *nor_page;
int ret = 0;
nor_page = ioremap(addr, 1024);
if (nor_page != NULL) {
- ret = qnap_tsx09_check_mac_addr(nor_page);
+ ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page);
iounmap(nor_page);
}
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 80a56ee..4e1e5c8 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -19,7 +19,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
#include "common.h"
#include "mpp.h"
@@ -174,6 +174,7 @@ subsys_initcall(wnr854t_pci_init);
MACHINE_START(WNR854T, "Netgear WNR854T")
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = wnr854t_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index 670e30d..61e9027 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -22,7 +22,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <mach/orion5x.h>
+#include "orion5x.h"
#include "common.h"
#include "mpp.h"
@@ -262,6 +262,7 @@ subsys_initcall(wrt350n_v2_pci_init);
MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
.atag_offset = 0x100,
+ .nr_irqs = ORION5X_NR_IRQS,
.init_machine = wrt350n_v2_init,
.map_io = orion5x_map_io,
.init_early = orion5x_init_early,
diff --git a/arch/arm/mach-picoxcell/Kconfig b/arch/arm/mach-picoxcell/Kconfig
index 62240f6..aef92ba 100644
--- a/arch/arm/mach-picoxcell/Kconfig
+++ b/arch/arm/mach-picoxcell/Kconfig
@@ -1,5 +1,6 @@
config ARCH_PICOXCELL
- bool "Picochip PicoXcell" if ARCH_MULTI_V6
+ bool "Picochip PicoXcell"
+ depends on ARCH_MULTI_V6
select ARCH_REQUIRE_GPIOLIB
select ARM_VIC
select DW_APB_TIMER_OF
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
index 9ab8932..f998eb1 100644
--- a/arch/arm/mach-prima2/Kconfig
+++ b/arch/arm/mach-prima2/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_SIRF
- bool "CSR SiRF" if ARCH_MULTI_V7
+ bool "CSR SiRF"
+ depends on ARCH_MULTI_V7
select ARCH_HAS_RESET_CONTROLLER
select ARCH_REQUIRE_GPIOLIB
select GENERIC_IRQ_CHIP
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index 3916a66..6d77b62 100644
--- a/arch/arm/mach-prima2/common.h
+++ b/arch/arm/mach-prima2/common.h
@@ -15,7 +15,7 @@
#include <asm/mach/time.h>
#include <asm/exception.h>
-extern struct smp_operations sirfsoc_smp_ops;
+extern const struct smp_operations sirfsoc_smp_ops;
extern void sirfsoc_secondary_startup(void);
extern void sirfsoc_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c
index 0ab2f8b..a728c78 100644
--- a/arch/arm/mach-prima2/hotplug.c
+++ b/arch/arm/mach-prima2/hotplug.c
@@ -32,7 +32,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void __ref sirfsoc_cpu_die(unsigned int cpu)
+void 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
index e46c910..0875b99 100644
--- a/arch/arm/mach-prima2/platsmp.c
+++ b/arch/arm/mach-prima2/platsmp.c
@@ -112,7 +112,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0;
}
-struct smp_operations sirfsoc_smp_ops __initdata = {
+const struct smp_operations sirfsoc_smp_ops __initconst = {
.smp_secondary_init = sirfsoc_secondary_init,
.smp_boot_secondary = sirfsoc_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index 12fb0f4..50e18ed 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -30,8 +30,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <mach/pxa25x.h>
-#include <mach/gumstix.h>
+#include "pxa25x.h"
+#include "gumstix.h"
#include <linux/platform_data/video-pxafb.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
index 8b90c4f..17d08ab 100644
--- a/arch/arm/mach-pxa/am300epd.c
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -28,8 +28,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <mach/gumstix.h>
-#include <mach/mfp-pxa25x.h>
+#include "gumstix.h"
+#include "mfp-pxa25x.h"
#include <mach/irqs.h>
#include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index a727282..8a3c409 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -42,13 +42,13 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa27x.h>
+#include "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 "udc.h"
+#include "pxa27x-udc.h"
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
@@ -572,7 +572,7 @@ static inline void balloon3_i2c_init(void) {}
#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;
+ struct nand_chip *this = mtd_to_nand(mtd);
uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
if (ctrl & NAND_CTRL_CHANGE) {
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index bf366b3..1c3cbfc 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -29,8 +29,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa320.h>
-#include <mach/mxm8x10.h>
+#include "pxa320.h"
+#include "mxm8x10.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c
index be75147..b592f79 100644
--- a/arch/arm/mach-pxa/cm-x255.c
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -22,7 +22,7 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 2503db9..fa5f51d 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -21,7 +21,7 @@
#include <linux/spi/pxa2xx_spi.h>
#include <linux/spi/libertas_spi.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/mmc-pxamci.h>
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index a17a91e..7202022 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -22,9 +22,18 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#undef GPIO24_SSP1_SFRM
-#include <mach/pxa27x.h>
+#undef GPIO86_GPIO
+#undef GPIO87_GPIO
+#undef GPIO88_GPIO
+#undef GPIO89_GPIO
+#include "pxa27x.h"
+#undef GPIO24_SSP1_SFRM
+#undef GPIO86_GPIO
+#undef GPIO87_GPIO
+#undef GPIO88_GPIO
+#undef GPIO89_GPIO
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
#include <mach/smemc.h>
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 5851f4c..5f5ac7c 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -26,6 +26,7 @@
#include <linux/dm9000.h>
#include <linux/leds.h>
#include <linux/rtc-v3020.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/i2c.h>
@@ -46,8 +47,8 @@
#include <asm/setup.h>
#include <asm/system_info.h>
-#include <mach/pxa300.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa300.h"
+#include "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>
@@ -305,11 +306,14 @@ static inline void cm_x300_init_lcd(void) {}
#endif
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup cm_x300_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.0", NULL, 10000,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -323,6 +327,7 @@ static struct platform_device cm_x300_backlight_device = {
static void cm_x300_init_bl(void)
{
+ pwm_add_table(cm_x300_pwm_lookup, ARRAY_SIZE(cm_x300_pwm_lookup));
platform_device_register(&cm_x300_backlight_device);
}
#else
diff --git a/arch/arm/mach-pxa/colibri-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c
index 638b0bb..dc44fbb 100644
--- a/arch/arm/mach-pxa/colibri-evalboard.c
+++ b/arch/arm/mach-pxa/colibri-evalboard.c
@@ -22,11 +22,11 @@
#include <linux/i2c/pxa-i2c.h>
#include <asm/io.h>
-#include <mach/pxa27x.h>
-#include <mach/colibri.h>
+#include "pxa27x.h"
+#include "colibri.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x-udc.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c
index 3aa2646..8cff770 100644
--- a/arch/arm/mach-pxa/colibri-pxa270-income.c
+++ b/arch/arm/mach-pxa/colibri-pxa270-income.c
@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/i2c/pxa-i2c.h>
@@ -29,8 +30,8 @@
#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 "pxa27x.h"
+#include "pxa27x-udc.h"
#include <linux/platform_data/video-pxafb.h>
#include "devices.h"
@@ -184,11 +185,14 @@ static inline void income_lcd_init(void) {}
* Backlight
******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup income_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 1000000,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -202,6 +206,7 @@ static struct platform_device income_backlight = {
static void __init income_pwm_init(void)
{
+ pwm_add_table(income_pwm_lookup, ARRAY_SIZE(income_pwm_lookup));
platform_device_register(&income_backlight);
}
#else
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index 3503826..e68acdd 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -27,8 +27,8 @@
#include <asm/sizes.h>
#include <mach/audio.h>
-#include <mach/colibri.h>
-#include <mach/pxa27x.h>
+#include "colibri.h"
+#include "pxa27x.h"
#include "devices.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index f1a1ac1..6a5558d 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -22,8 +22,8 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
-#include <mach/pxa300.h>
-#include <mach/colibri.h>
+#include "pxa300.h"
+#include "colibri.h"
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/video-pxafb.h>
#include <mach/audio.h>
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index f6cc8b0..17067a3 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -23,13 +23,13 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
-#include <mach/pxa320.h>
-#include <mach/colibri.h>
+#include "pxa320.h"
+#include "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 "pxa27x-udc.h"
+#include "udc.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 8240291..b04431b 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -22,8 +22,8 @@
#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 "mfp-pxa300.h"
+#include "colibri.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mtd-nand-pxa3xx.h>
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/colibri.h
index cb4236e..cb4236e 100644
--- a/arch/arm/mach-pxa/include/mach/colibri.h
+++ b/arch/arm/mach-pxa/colibri.h
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 89f790d..dc109dc3 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -48,12 +48,12 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <linux/platform_data/irda-pxaficp.h>
#include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
+#include "udc.h"
#include <mach/corgi.h>
-#include <mach/sharpsl_pm.h>
+#include "sharpsl_pm.h"
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 7a39efc..d920681 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -27,7 +27,7 @@
#include <mach/corgi.h>
#include <mach/pxa2xx-regs.h>
-#include <mach/sharpsl_pm.h>
+#include "sharpsl_pm.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index fadfff8..bf19b84 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -21,8 +21,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/csb726.h>
-#include <mach/pxa27x.h>
+#include "csb726.h"
+#include "pxa27x.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <mach/audio.h>
diff --git a/arch/arm/mach-pxa/csb726.h b/arch/arm/mach-pxa/csb726.h
new file mode 100644
index 0000000..f1f2a78
--- /dev/null
+++ b/arch/arm/mach-pxa/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 <mach/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/devices.c b/arch/arm/mach-pxa/devices.c
index c624732..37d8d85 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -6,7 +6,7 @@
#include <linux/spi/pxa2xx_spi.h>
#include <linux/i2c/pxa-i2c.h>
-#include <mach/udc.h>
+#include "udc.h"
#include <linux/platform_data/usb-pxa3xx-ulpi.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
@@ -14,7 +14,7 @@
#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 <linux/platform_data/media/camera-pxa.h>
#include <mach/audio.h>
#include <mach/hardware.h>
#include <linux/platform_data/mmp_dma.h>
@@ -395,6 +395,26 @@ static struct resource pxa_ir_resources[] = {
.end = IRQ_ICP,
.flags = IORESOURCE_IRQ,
},
+ [3] = {
+ .start = 0x40800000,
+ .end = 0x4080001b,
+ .flags = IORESOURCE_MEM,
+ },
+ [4] = {
+ .start = 0x40700000,
+ .end = 0x40700023,
+ .flags = IORESOURCE_MEM,
+ },
+ [5] = {
+ .start = 17,
+ .end = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ [6] = {
+ .start = 18,
+ .end = 18,
+ .flags = IORESOURCE_DMA,
+ },
};
struct platform_device pxa_device_ficp = {
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 9d7072b..6e0268d 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -39,14 +39,14 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "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 <linux/platform_data/media/camera-pxa.h>
#include "generic.h"
#include "devices.h"
@@ -289,7 +289,7 @@ static void nand_cs_off(void)
static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
dsb();
diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/eseries-irq.h
index de292b2..de292b2 100644
--- a/arch/arm/mach-pxa/include/mach/eseries-irq.h
+++ b/arch/arm/mach-pxa/eseries-irq.h
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 16dc95f..0b00b22 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -31,12 +31,12 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <mach/eseries-gpio.h>
-#include <mach/eseries-irq.h>
+#include "eseries-irq.h"
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
-#include <mach/udc.h>
+#include "udc.h"
#include <linux/platform_data/irda-pxaficp.h>
#include "devices.h"
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index ab93441..34ad0a8 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/input.h>
#include <linux/gpio.h>
@@ -28,12 +29,12 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
+#include "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 <linux/platform_data/media/camera-pxa.h>
#include "devices.h"
#include "generic.h"
@@ -49,11 +50,14 @@
#define GPIO19_GEN1_CAM_RST 19
#define GPIO28_GEN2_CAM_RST 28
+static struct pwm_lookup ezx_pwm_lookup[] __maybe_unused = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78700,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -79,7 +83,7 @@ static struct pxafb_mode_info mode_ezx_old = {
.sync = 0,
};
-static struct pxafb_mach_info ezx_fb_info_1 = {
+static struct pxafb_mach_info ezx_fb_info_1 __maybe_unused = {
.modes = &mode_ezx_old,
.num_modes = 1,
.lcd_conn = LCD_COLOR_TFT_16BPP,
@@ -100,17 +104,17 @@ static struct pxafb_mode_info mode_72r89803y01 = {
.sync = 0,
};
-static struct pxafb_mach_info ezx_fb_info_2 = {
+static struct pxafb_mach_info ezx_fb_info_2 __maybe_unused = {
.modes = &mode_72r89803y01,
.num_modes = 1,
.lcd_conn = LCD_COLOR_TFT_18BPP,
};
-static struct platform_device *ezx_devices[] __initdata = {
+static struct platform_device *ezx_devices[] __initdata __maybe_unused = {
&ezx_backlight_device,
};
-static unsigned long ezx_pin_config[] __initdata = {
+static unsigned long ezx_pin_config[] __initdata __maybe_unused = {
/* PWM backlight */
GPIO16_PWM0_OUT,
@@ -817,6 +821,7 @@ static void __init a780_init(void)
platform_device_register(&a780_camera);
}
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a780_devices));
}
@@ -884,6 +889,7 @@ static void __init e680_init(void)
pxa_set_keypad_info(&e680_keypad_platform_data);
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e680_devices));
}
@@ -951,6 +957,7 @@ static void __init a1200_init(void)
pxa_set_keypad_info(&a1200_keypad_platform_data);
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
}
@@ -1143,6 +1150,7 @@ static void __init a910_init(void)
platform_device_register(&a910_camera);
}
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a910_devices));
}
@@ -1210,6 +1218,7 @@ static void __init e6_init(void)
pxa_set_keypad_info(&e6_keypad_platform_data);
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e6_devices));
}
@@ -1251,6 +1260,7 @@ static void __init e2_init(void)
pxa_set_keypad_info(&e2_keypad_platform_data);
+ pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e2_devices));
}
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index f6c76a3..6815a93 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -40,10 +40,10 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/gumstix.h>
+#include "udc.h"
+#include "gumstix.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/gumstix.h b/arch/arm/mach-pxa/gumstix.h
new file mode 100644
index 0000000..825f2d1
--- /dev/null
+++ b/arch/arm/mach-pxa/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 <mach/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/h5000.c b/arch/arm/mach-pxa/h5000.c
index 875ec33..be2a9c3 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -30,9 +30,9 @@
#include <asm/mach/map.h>
#include <asm/irq.h>
-#include <mach/pxa25x.h>
-#include <mach/h5000.h>
-#include <mach/udc.h>
+#include "pxa25x.h"
+#include "h5000.h"
+#include "udc.h"
#include <mach/smemc.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/h5000.h b/arch/arm/mach-pxa/h5000.h
new file mode 100644
index 0000000..252461f
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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/himalaya.c b/arch/arm/mach-pxa/himalaya.c
index 7a8d749..70e9c06 100644
--- a/arch/arm/mach-pxa/himalaya.c
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -24,7 +24,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 5fb41ad..4a2f9ab 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -44,7 +44,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/hx4700.h>
#include <linux/platform_data/irda-pxaficp.h>
@@ -557,10 +557,8 @@ static struct platform_device hx4700_lcd = {
*/
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,
};
@@ -630,7 +628,6 @@ static struct spi_board_info tsc2046_board_info[] __initdata = {
static struct pxa2xx_spi_master pxa_ssp2_master_info = {
.num_chipselect = 1,
- .clock_enable = CKEN_SSP2,
.enable_dma = 1,
};
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 9b0eb02..cbaf4f6 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -20,8 +20,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa320.h>
-#include <mach/mxm8x10.h>
+#include "pxa320.h"
+#include "mxm8x10.h"
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
@@ -116,13 +116,11 @@ static struct spi_board_info mcp251x_board_info[] = {
};
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
};
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index f6d02e4..c410d84 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -31,8 +31,8 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa25x.h>
-#include <mach/idp.h>
+#include "pxa25x.h"
+#include "idp.h"
#include <linux/platform_data/video-pxafb.h>
#include <mach/bitfield.h>
#include <linux/platform_data/mmc-pxamci.h>
diff --git a/arch/arm/mach-pxa/idp.h b/arch/arm/mach-pxa/idp.h
new file mode 100644
index 0000000..7182ff92
--- /dev/null
+++ b/arch/arm/mach-pxa/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 <mach/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/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h
deleted file mode 100644
index 00cfbbb..0000000
--- a/arch/arm/mach-pxa/include/mach/csb726.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h
deleted file mode 100644
index f7df27b..0000000
--- a/arch/arm/mach-pxa/include/mach/gumstix.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2a5ae38..0000000
--- a/arch/arm/mach-pxa/include/mach/h5000.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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/idp.h b/arch/arm/mach-pxa/include/mach/idp.h
deleted file mode 100644
index 7e63f46..0000000
--- a/arch/arm/mach-pxa/include/mach/idp.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index ba6a6e1..5f6b850 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -52,9 +52,9 @@
#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 GPIO104_MAGICIAN_LCD_VOFF_EN 104
+#define GPIO105_MAGICIAN_LCD_VON_EN 105
+#define GPIO106_MAGICIAN_LCD_DCDC_NRESET 106
#define GPIO107_MAGICIAN_DS1WM_IRQ 107
#define GPIO108_MAGICIAN_GSM_READY 108
#define GPIO114_MAGICIAN_UNKNOWN 114
@@ -78,43 +78,51 @@
* CPLD EGPIOs
*/
-#define MAGICIAN_EGPIO_BASE PXA_NR_BUILTIN_GPIO
+#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)
+#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_IR_RX_SHUTDOWN 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_NICD_CHARGE MAGICIAN_EGPIO(2, 6)
+#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)
+/* USB or AC charger type */
+#define EGPIO_MAGICIAN_CABLE_TYPE MAGICIAN_EGPIO(4, 0)
+/*
+ * Vbus is detected
+ * FIXME behaves like (6,3), may differ for host/device
+ */
+#define EGPIO_MAGICIAN_CABLE_VBUS 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_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)
+#define EGPIO_MAGICIAN_EP_INSERT MAGICIAN_EGPIO(6, 1)
+/* FIXME behaves like (4,1), may differ for host/device */
+#define EGPIO_MAGICIAN_CABLE_INSERTED MAGICIAN_EGPIO(6, 3)
#endif /* _MAGICIAN_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
deleted file mode 100644
index cafadc3..0000000
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ /dev/null
@@ -1,225 +0,0 @@
-#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
deleted file mode 100644
index b6132aa..0000000
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
+++ /dev/null
@@ -1,471 +0,0 @@
-#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-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
deleted file mode 100644
index 4e12870..0000000
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3ce4682..0000000
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * 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-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
deleted file mode 100644
index 04f7c97..0000000
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
deleted file mode 100644
index e342c59..0000000
--- a/arch/arm/mach-pxa/include/mach/palmt5.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
deleted file mode 100644
index 86ebd7b..0000000
--- a/arch/arm/mach-pxa/include/mach/pcm027.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7e544c1..0000000
--- a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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/pxa25x-udc.h b/arch/arm/mach-pxa/include/mach/pxa25x-udc.h
index 1b80a48..e69de29 100644
--- a/arch/arm/mach-pxa/include/mach/pxa25x-udc.h
+++ b/arch/arm/mach-pxa/include/mach/pxa25x-udc.h
@@ -1,163 +0,0 @@
-#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
deleted file mode 100644
index 5a34175..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa25x.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#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.h b/arch/arm/mach-pxa/include/mach/pxa27x.h
deleted file mode 100644
index 599b925..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa27x.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#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/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h
deleted file mode 100644
index 733b641..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa300.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index b6204e4..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa320.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#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/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h
deleted file mode 100644
index 190363b..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa930.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#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/littleton.c b/arch/arm/mach-pxa/littleton.c
index 5d66558..051c554 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -41,11 +41,11 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa300.h>
+#include "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 "littleton.h"
#include <linux/platform_data/mtd-nand-pxa3xx.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/littleton.h
index 8066be54..8066be54 100644
--- a/arch/arm/mach-pxa/include/mach/littleton.h
+++ b/arch/arm/mach-pxa/littleton.h
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 4823d97..e9f401b 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -23,6 +23,7 @@
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/smc91x.h>
@@ -39,8 +40,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa27x.h>
-#include <mach/lpd270.h>
+#include "pxa27x.h"
+#include "lpd270.h"
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
@@ -271,11 +272,14 @@ static struct platform_device lpd270_flash_device[2] = {
},
};
+static struct pwm_lookup lpd270_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -474,6 +478,7 @@ static void __init lpd270_init(void)
*/
ARB_CNTRL = ARB_CORE_PARK | 0x234;
+ pwm_add_table(lpd270_pwm_lookup, ARRAY_SIZE(lpd270_pwm_lookup));
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
pxa_set_ac97_info(NULL);
diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/lpd270.h
index 4edc712..4edc712 100644
--- a/arch/arm/mach-pxa/include/mach/lpd270.h
+++ b/arch/arm/mach-pxa/lpd270.h
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6de32fa..7245f33 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -47,14 +47,14 @@
#include <asm/hardware/sa1111.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <mach/audio.h>
#include <mach/lubbock.h>
-#include <mach/udc.h>
+#include "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 "pm.h"
#include <mach/smemc.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index a9761c2..abc9181 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -24,8 +24,10 @@
#include <linux/mfd/htc-pasic3.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/fixed.h>
#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/usb/gpio_vbus.h>
@@ -36,13 +38,19 @@
#include <asm/mach/arch.h>
#include <asm/system_info.h>
-#include <mach/pxa27x.h>
+#include "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 <linux/regulator/max1586.h>
+
+#include <linux/platform_data/pxa2xx_udc.h>
+
+#include "udc.h"
+#include "pxa27x-udc.h"
#include "devices.h"
#include "generic.h"
@@ -52,36 +60,36 @@ static unsigned long magician_pin_config[] __initdata = {
GPIO20_nSDCS_2,
GPIO21_nSDCS_3,
GPIO15_nCS_1,
- GPIO78_nCS_2, /* PASIC3 */
- GPIO79_nCS_3, /* EGPIO CPLD */
+ GPIO78_nCS_2, /* PASIC3 */
+ GPIO79_nCS_3, /* EGPIO CPLD */
GPIO80_nCS_4,
GPIO33_nCS_5,
- /* I2C */
+ /* I2C UDA1380 + OV9640 */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
- /* PWM 0 */
+ /* PWM 0 - LCD backlight */
GPIO16_PWM0_OUT,
- /* I2S */
+ /* I2S UDA1380 capture */
GPIO28_I2S_BITCLK_OUT,
GPIO29_I2S_SDATA_IN,
GPIO31_I2S_SYNC,
GPIO113_I2S_SYSCLK,
- /* SSP 1 */
+ /* SSP 1 UDA1380 playback */
GPIO23_SSP1_SCLK,
GPIO24_SSP1_SFRM,
GPIO25_SSP1_TXD,
- /* SSP 2 */
+ /* SSP 2 TSC2046 touchscreen */
GPIO19_SSP2_SCLK,
GPIO14_SSP2_SFRM,
GPIO89_SSP2_TXD,
GPIO88_SSP2_RXD,
- /* MMC */
+ /* MMC/SD/SDHC slot */
GPIO32_MMC_CLK,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
@@ -92,7 +100,7 @@ static unsigned long magician_pin_config[] __initdata = {
/* LCD */
GPIOxx_LCD_TFT_16BPP,
- /* QCI */
+ /* QCI camera interface */
GPIO12_CIF_DD_7,
GPIO17_CIF_DD_6,
GPIO50_CIF_DD_3,
@@ -120,12 +128,13 @@ static unsigned long magician_pin_config[] __initdata = {
};
/*
- * IRDA
+ * IrDA
*/
static struct pxaficp_platform_data magician_ficp_info = {
.gpio_pwdown = GPIO83_MAGICIAN_nIR_EN,
.transceiver_cap = IR_SIRMODE | IR_OFF,
+ .gpio_pwdown_inverted = 0,
};
/*
@@ -134,11 +143,11 @@ static struct pxaficp_platform_data magician_ficp_info = {
#define INIT_KEY(_code, _gpio, _desc) \
{ \
- .code = KEY_##_code, \
- .gpio = _gpio, \
- .desc = _desc, \
- .type = EV_KEY, \
- .wakeup = 1, \
+ .code = KEY_##_code, \
+ .gpio = _gpio, \
+ .desc = _desc, \
+ .type = EV_KEY, \
+ .wakeup = 1, \
}
static struct gpio_keys_button magician_button_table[] = {
@@ -160,164 +169,162 @@ static struct gpio_keys_button magician_button_table[] = {
};
static struct gpio_keys_platform_data gpio_keys_data = {
- .buttons = magician_button_table,
- .nbuttons = ARRAY_SIZE(magician_button_table),
+ .buttons = magician_button_table,
+ .nbuttons = ARRAY_SIZE(magician_button_table),
};
static struct platform_device gpio_keys = {
- .name = "gpio-keys",
- .dev = {
+ .name = "gpio-keys",
+ .dev = {
.platform_data = &gpio_keys_data,
},
- .id = -1,
+ .id = -1,
};
-
/*
* EGPIO (Xilinx CPLD)
*
- * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
+ * 32-bit aligned 8-bit registers
+ * 16 possible registers (reg windows size), only 7 used:
+ * 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,
+ .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,
+ .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 */
+ .reg_start = 0,
+ .gpio_base = MAGICIAN_EGPIO(0, 0),
+ .num_gpios = 24,
+ .direction = HTC_EGPIO_OUTPUT,
+ /*
+ * Depends on modules configuration
+ */
+ .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
},
[1] = {
- .reg_start = 4,
- .gpio_base = MAGICIAN_EGPIO(4, 0),
- .num_gpios = 24,
- .direction = HTC_EGPIO_INPUT,
+ .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),
+ .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),
+ .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
+ * PXAFB 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,
+ .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,
+ .pixclock = 226469,
+ .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");
+ pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");
if (on) {
- pr_debug("on\n");
gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
- gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 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);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
udelay(2000);
- gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
} else {
- pr_debug("off\n");
msleep(15);
- gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
udelay(500);
- gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
udelay(1000);
- gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 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");
+ pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");
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);
+ mdelay(6);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
+ mdelay(6); /* Avdd -> Voff >5ms */
+ gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
+ mdelay(16); /* Voff -> Von >(5+10)ms */
+ gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
} 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);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
+ mdelay(16);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
+ mdelay(6);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
+ mdelay(6);
if (system_rev < 3)
gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
else
@@ -326,29 +333,43 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
}
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,
+ .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,
+ .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 pwm_lookup magician_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 30923,
+ PWM_POLARITY_NORMAL),
+};
+
+ /*
+ * fixed regulator for pwm_backlight
+ */
+
+static struct regulator_consumer_supply pwm_backlight_supply[] = {
+ REGULATOR_SUPPLY("power", "pwm_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" },
+ { 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)
@@ -358,6 +379,7 @@ static int magician_backlight_init(struct device *dev)
static int magician_backlight_notify(struct device *dev, int brightness)
{
+ pr_debug("Brightness = %i\n", brightness);
gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
if (brightness >= 200) {
gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
@@ -373,28 +395,33 @@ static void magician_backlight_exit(struct device *dev)
gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
}
+/*
+ * LCD PWM backlight (main)
+ *
+ * MP1521 frequency should be:
+ * 100-400 Hz = 2 .5*10^6 - 10 *10^6 ns
+ */
+
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,
+ .max_brightness = 272,
+ .dft_brightness = 100,
+ .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,
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &backlight_data,
},
};
/*
- * LEDs
+ * GPIO LEDs, Phone keys backlight, vibra
*/
static struct gpio_led gpio_leds[] = {
@@ -416,69 +443,32 @@ static struct gpio_led_platform_data gpio_led_info = {
};
static struct platform_device leds_gpio = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
+ .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,
+ .start = PXA_CS2_PHYS,
.end = PXA_CS2_PHYS + 0x1b,
- .flags = IORESOURCE_MEM,
+ .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,
+ .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,
};
@@ -493,25 +483,42 @@ static struct platform_device pasic3 = {
};
/*
- * USB "Transceiver"
+ * PXA UDC
+ */
+
+static void magician_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 | UP2OCR_DPPUBE);
+}
+
+static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
+ .udc_command = magician_udc_command,
+ .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+};
+
+/*
+ * USB device VBus detection
*/
static struct resource gpio_vbus_resource = {
- .flags = IORESOURCE_IRQ,
- .start = IRQ_MAGICIAN_VBUS,
- .end = IRQ_MAGICIAN_VBUS,
+ .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,
+ .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+ .gpio_vbus = EGPIO_MAGICIAN_CABLE_VBUS,
};
static struct platform_device gpio_vbus = {
- .name = "gpio-vbus",
- .id = -1,
- .num_resources = 1,
- .resource = &gpio_vbus_resource,
+ .name = "gpio-vbus",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &gpio_vbus_resource,
.dev = {
.platform_data = &gpio_vbus_info,
},
@@ -521,19 +528,60 @@ static struct platform_device gpio_vbus = {
* External power
*/
-static int power_supply_init(struct device *dev)
+static int magician_supply_init(struct device *dev)
+{
+ int ret = -1;
+
+ ret = gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "Cable is AC charger");
+ if (ret) {
+ pr_err("Cannot request AC/USB charger GPIO (%i)\n", ret);
+ goto err_ac;
+ }
+
+ ret = gpio_request(EGPIO_MAGICIAN_CABLE_INSERTED, "Cable inserted");
+ if (ret) {
+ pr_err("Cannot request cable detection GPIO (%i)\n", ret);
+ goto err_usb;
+ }
+
+ return 0;
+
+err_usb:
+ gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
+err_ac:
+ return ret;
+}
+
+static void magician_set_charge(int flags)
{
- return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+ if (flags & PDA_POWER_CHARGE_AC) {
+ pr_debug("Charging from AC\n");
+ gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+ } else if (flags & PDA_POWER_CHARGE_USB) {
+ pr_debug("Charging from USB\n");
+ gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+ } else {
+ pr_debug("Charging disabled\n");
+ gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 0);
+ }
}
static int magician_is_ac_online(void)
{
- return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+ return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
+ gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE); /* AC=1 */
}
-static void power_supply_exit(struct device *dev)
+static int magician_is_usb_online(void)
{
- gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+ return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
+ (!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
+}
+
+static void magician_supply_exit(struct device *dev)
+{
+ gpio_free(EGPIO_MAGICIAN_CABLE_INSERTED);
+ gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
}
static char *magician_supplicants[] = {
@@ -541,38 +589,40 @@ static char *magician_supplicants[] = {
};
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),
+ .init = magician_supply_init,
+ .exit = magician_supply_exit,
+ .is_ac_online = magician_is_ac_online,
+ .is_usb_online = magician_is_usb_online,
+ .set_charge = magician_set_charge,
+ .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,
+ .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,
+ .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 = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
.platform_data = &power_supply_info,
},
- .resource = power_supply_resources,
- .num_resources = ARRAY_SIZE(power_supply_resources),
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
};
/*
@@ -586,11 +636,12 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
static struct regulator_init_data bq24022_init_data = {
.constraints = {
- .max_uA = 500000,
- .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+ .max_uA = 500000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
- .consumer_supplies = bq24022_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+ .consumer_supplies = bq24022_consumers,
};
static struct gpio bq24022_gpios[] = {
@@ -603,39 +654,85 @@ static struct gpio_regulator_state bq24022_states[] = {
};
static struct gpio_regulator_config bq24022_info = {
- .supply_name = "bq24022",
+ .supply_name = "bq24022",
- .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
- .enable_high = 0,
- .enabled_at_boot = 0,
+ .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+ .enable_high = 0,
+ .enabled_at_boot = 1,
- .gpios = bq24022_gpios,
- .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+ .gpios = bq24022_gpios,
+ .nr_gpios = ARRAY_SIZE(bq24022_gpios),
- .states = bq24022_states,
- .nr_states = ARRAY_SIZE(bq24022_states),
+ .states = bq24022_states,
+ .nr_states = ARRAY_SIZE(bq24022_states),
- .type = REGULATOR_CURRENT,
- .init_data = &bq24022_init_data,
+ .type = REGULATOR_CURRENT,
+ .init_data = &bq24022_init_data,
};
static struct platform_device bq24022 = {
- .name = "gpio-regulator",
- .id = -1,
- .dev = {
+ .name = "gpio-regulator",
+ .id = -1,
+ .dev = {
.platform_data = &bq24022_info,
},
};
/*
+ * Vcore regulator MAX1587A
+ */
+
+static struct regulator_consumer_supply magician_max1587a_consumers[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data magician_max1587a_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 700000,
+ .max_uV = 1475000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = magician_max1587a_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(magician_max1587a_consumers),
+};
+
+static struct max1586_subdev_data magician_max1587a_subdevs[] = {
+ {
+ .name = "vcc_core",
+ .id = MAX1586_V3,
+ .platform_data = &magician_max1587a_v3_info,
+ }
+};
+
+static struct max1586_platform_data magician_max1587a_info = {
+ .subdevs = magician_max1587a_subdevs,
+ .num_subdevs = ARRAY_SIZE(magician_max1587a_subdevs),
+ /*
+ * NOTICE measured directly on the PCB (board_id == 0x3a), but
+ * if R24 is present, it will boost the voltage
+ * (write 1.475V, get 1.645V and smoke)
+ */
+ .v3_gain = MAX1586_GAIN_NO_R24,
+};
+
+static struct i2c_board_info magician_pwr_i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &magician_max1587a_info,
+ },
+};
+
+/*
* MMC/SD
*/
static int magician_mci_init(struct device *dev,
- irq_handler_t detect_irq, void *data)
+ irq_handler_t detect_irq, void *data)
{
return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0,
- "mmc card detect", data);
+ "mmc card detect", data);
}
static void magician_mci_exit(struct device *dev, void *data)
@@ -644,9 +741,9 @@ static void magician_mci_exit(struct device *dev, void *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,
+ .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,
@@ -660,47 +757,102 @@ static struct pxamci_platform_data magician_mci_info = {
static struct pxaohci_platform_data magician_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
- .flags = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+ /* port1: CSR Bluetooth, port2: OTG with UDC */
+ .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
.power_budget = 0,
+ .power_on_delay = 100,
};
-
/*
* StrataFlash
*/
+static int magician_flash_init(struct platform_device *pdev)
+{
+ int ret = gpio_request(EGPIO_MAGICIAN_FLASH_VPP, "flash Vpp enable");
+
+ if (ret) {
+ pr_err("Cannot request flash enable GPIO (%i)\n", ret);
+ return ret;
+ }
+
+ ret = gpio_direction_output(EGPIO_MAGICIAN_FLASH_VPP, 1);
+ if (ret) {
+ pr_err("Cannot set direction for flash enable (%i)\n", ret);
+ gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+ }
+
+ return ret;
+}
+
static void magician_set_vpp(struct platform_device *pdev, int vpp)
{
gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
}
+static void magician_flash_exit(struct platform_device *pdev)
+{
+ gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+}
+
static struct resource strataflash_resource = {
- .start = PXA_CS0_PHYS,
- .end = PXA_CS0_PHYS + SZ_64M - 1,
- .flags = IORESOURCE_MEM,
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
};
+static struct mtd_partition magician_flash_parts[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x0,
+ .size = 0x40000,
+ .mask_flags = MTD_WRITEABLE, /* EXPERIMENTAL */
+ },
+ {
+ .name = "Linux Kernel",
+ .offset = 0x40000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+/*
+ * physmap-flash driver
+ */
+
static struct physmap_flash_data strataflash_data = {
- .width = 4,
- .set_vpp = magician_set_vpp,
+ .width = 4,
+ .init = magician_flash_init,
+ .set_vpp = magician_set_vpp,
+ .exit = magician_flash_exit,
+ .parts = magician_flash_parts,
+ .nr_parts = ARRAY_SIZE(magician_flash_parts),
};
static struct platform_device strataflash = {
- .name = "physmap-flash",
- .id = -1,
- .resource = &strataflash_resource,
- .num_resources = 1,
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &strataflash_resource,
+ .num_resources = 1,
.dev = {
.platform_data = &strataflash_data,
},
};
/*
- * I2C
+ * PXA I2C main controller
*/
static struct i2c_pxa_platform_data i2c_info = {
- .fast_mode = 1,
+ /* OV9640 I2C device doesn't support fast mode */
+ .fast_mode = 0,
+};
+
+/*
+ * PXA I2C power controller
+ */
+
+static struct i2c_pxa_platform_data magician_i2c_power_info = {
+ .fast_mode = 1,
};
/*
@@ -720,12 +872,13 @@ static struct platform_device *devices[] __initdata = {
};
static struct gpio magician_global_gpios[] = {
- { GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
+ { 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" },
+
+ /* NOTICE valid LCD init sequence */
+ { GPIO106_MAGICIAN_LCD_DCDC_NRESET, GPIOF_OUT_INIT_LOW, "LCD DCDC nreset" },
+ { GPIO104_MAGICIAN_LCD_VOFF_EN, GPIOF_OUT_INIT_LOW, "LCD VOFF enable" },
+ { GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_LOW, "LCD VON enable" },
};
static void __init magician_init(void)
@@ -737,44 +890,55 @@ static void __init magician_init(void)
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);
+ pr_err("magician: Failed to request global 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));
+ pwm_add_table(magician_pwm_lookup, ARRAY_SIZE(magician_pwm_lookup));
pxa_set_ficp_info(&magician_ficp_info);
- pxa27x_set_i2c_power_info(NULL);
+ pxa27x_set_i2c_power_info(&magician_i2c_power_info);
pxa_set_i2c_info(&i2c_info);
+
+ i2c_register_board_info(1,
+ ARRAY_AND_SIZE(magician_pwr_i2c_board_info));
+
pxa_set_mci_info(&magician_mci_info);
pxa_set_ohci_info(&magician_ohci_info);
+ pxa_set_udc_info(&magician_udc_info);
/* Check LCD type we have */
cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
if (cpld) {
- u8 board_id = __raw_readb(cpld+0x14);
+ 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))
+ /* NOTICE valid LCD init sequence */
gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
- GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
- pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
+ GPIOF_OUT_INIT_LOW, "Samsung LCD Power");
+ pxa_set_fb_info(NULL,
+ lcd_select ? &samsung_info : &toppoly_info);
} else
pr_err("LCD detection: CPLD mapping failed\n");
-}
+ regulator_register_always_on(0, "power", pwm_backlight_supply,
+ ARRAY_SIZE(pwm_backlight_supply), 5000000);
+
+ platform_add_devices(ARRAY_AND_SIZE(devices));
+}
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,
+ .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
index 2c0658c..4096406 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -26,6 +26,7 @@
#include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/smc91x.h>
#include <linux/i2c/pxa-i2c.h>
@@ -45,7 +46,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/mainstone.h>
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
@@ -248,11 +249,14 @@ static struct platform_device mst_flash_device[2] = {
};
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pwm_lookup mainstone_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -266,9 +270,16 @@ static struct platform_device mainstone_backlight_device = {
static void __init mainstone_backlight_register(void)
{
- int ret = platform_device_register(&mainstone_backlight_device);
- if (ret)
+ int ret;
+
+ pwm_add_table(mainstone_pwm_lookup, ARRAY_SIZE(mainstone_pwm_lookup));
+
+ ret = platform_device_register(&mainstone_backlight_device);
+ if (ret) {
printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
+ pwm_remove_table(mainstone_pwm_lookup,
+ ARRAY_SIZE(mainstone_pwm_lookup));
+ }
}
#else
#define mainstone_backlight_register() do { } while (0)
diff --git a/arch/arm/mach-pxa/mfp-pxa25x.h b/arch/arm/mach-pxa/mfp-pxa25x.h
new file mode 100644
index 0000000..1c59d4b
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp-pxa25x.h
@@ -0,0 +1,225 @@
+#ifndef __ASM_ARCH_MFP_PXA25X_H
+#define __ASM_ARCH_MFP_PXA25X_H
+
+#include "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/mfp-pxa27x.h b/arch/arm/mach-pxa/mfp-pxa27x.h
new file mode 100644
index 0000000..9fe5601
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 666b789..3732aec 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -21,7 +21,7 @@
#include <linux/syscore_ops.h>
#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa2xx.h>
+#include "mfp-pxa2xx.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/mfp-pxa2xx.h
index cbf51ae..cbf51ae 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.h
diff --git a/arch/arm/mach-pxa/mfp-pxa300.h b/arch/arm/mach-pxa/mfp-pxa300.h
new file mode 100644
index 0000000..5ee51e2
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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/mfp-pxa320.h b/arch/arm/mach-pxa/mfp-pxa320.h
new file mode 100644
index 0000000..e8797cf
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c
index 89863a0..994edc0 100644
--- a/arch/arm/mach-pxa/mfp-pxa3xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa3xx.c
@@ -20,7 +20,7 @@
#include <linux/syscore_ops.h>
#include <mach/hardware.h>
-#include <mach/mfp-pxa3xx.h>
+#include "mfp-pxa3xx.h"
#include <mach/pxa3xx-regs.h>
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h b/arch/arm/mach-pxa/mfp-pxa3xx.h
index d375195..d375195 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
+++ b/arch/arm/mach-pxa/mfp-pxa3xx.h
diff --git a/arch/arm/mach-pxa/mfp-pxa930.h b/arch/arm/mach-pxa/mfp-pxa930.h
new file mode 100644
index 0000000..113967b
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 29997bd..38a96a1 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -26,6 +26,7 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/gpio_keys.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/rtc.h>
#include <linux/leds.h>
@@ -46,19 +47,19 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
-#include <mach/regs-rtc.h>
+#include "pxa27x.h"
+#include "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 "udc.h"
+#include "pxa27x-udc.h"
+#include <linux/platform_data/media/camera-pxa.h>
#include <mach/audio.h>
#include <mach/smemc.h>
#include <media/soc_camera.h>
-#include <mach/mioa701.h>
+#include "mioa701.h"
#include "generic.h"
#include "devices.h"
@@ -181,12 +182,15 @@ static unsigned long mioa701_pin_config[] = {
MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
};
+static struct pwm_lookup mioa701_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 4000 * 1024,
+ PWM_POLARITY_NORMAL),
+};
+
/* 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,
};
@@ -678,6 +682,7 @@ 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(wm9713_acodec, "wm9713-codec", NULL);
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
MIO_SIMPLE_DEV(mioa701_camera, "soc-camera-pdrv",&iclink);
@@ -685,6 +690,7 @@ static struct platform_device *devices[] __initdata = {
&mioa701_gpio_keys,
&mioa701_backlight,
&mioa701_led,
+ &wm9713_acodec,
&pxa2xx_pcm,
&mioa701_sound,
&power_dev,
@@ -751,6 +757,7 @@ static void __init mioa701_machine_init(void)
pxa_set_udc_info(&mioa701_udc_info);
pxa_set_ac97_info(&mioa701_ac97_info);
pm_power_off = mioa701_poweroff;
+ pwm_add_table(mioa701_pwm_lookup, ARRAY_SIZE(mioa701_pwm_lookup));
platform_add_devices(devices, ARRAY_SIZE(devices));
gsm_init();
diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/mioa701.h
index e57f5c7..e57f5c7 100644
--- a/arch/arm/mach-pxa/include/mach/mioa701.h
+++ b/arch/arm/mach-pxa/mioa701.h
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 14f6aaf..4d89029 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -22,7 +22,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include "generic.h"
static void isp116x_pfm_delay(struct device *dev, int delay)
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index d04ed49..9a22ae0 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -29,9 +29,9 @@
#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 "pxa320.h"
-#include <mach/mxm8x10.h>
+#include "mxm8x10.h"
#include "devices.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/include/mach/mxm8x10.h b/arch/arm/mach-pxa/mxm8x10.h
index ffa1566..ffa1566 100644
--- a/arch/arm/mach-pxa/include/mach/mxm8x10.h
+++ b/arch/arm/mach-pxa/mxm8x10.h
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c
index e54a296..e5ae99d 100644
--- a/arch/arm/mach-pxa/palm27x.c
+++ b/arch/arm/mach-pxa/palm27x.c
@@ -15,6 +15,7 @@
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
@@ -27,14 +28,14 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "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 "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
#include "generic.h"
#include "devices.h"
@@ -270,6 +271,11 @@ void __init palm27x_ac97_init(int minv, int maxv, int jack, int reset)
* Backlight
******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup palm27x_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 3500 * 1024,
+ PWM_POLARITY_NORMAL),
+};
+
static int palm_bl_power;
static int palm_lcd_power;
@@ -318,10 +324,8 @@ static void palm27x_backlight_exit(struct device *dev)
}
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,
@@ -340,6 +344,7 @@ void __init palm27x_pwm_init(int bl, int lcd)
{
palm_bl_power = bl;
palm_lcd_power = lcd;
+ pwm_add_table(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
platform_device_register(&palm27x_backlight);
}
#endif
diff --git a/arch/arm/mach-pxa/include/mach/palm27x.h b/arch/arm/mach-pxa/palm27x.h
index d4eac3d..d4eac3d 100644
--- a/arch/arm/mach-pxa/include/mach/palm27x.h
+++ b/arch/arm/mach-pxa/palm27x.h
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index cf210b1..980f284 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -32,7 +32,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/audio.h>
#include <mach/palmld.h>
#include <linux/platform_data/mmc-pxamci.h>
@@ -40,7 +40,7 @@
#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 "palm27x.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 3ed9b02..876144a 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -33,16 +33,16 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/audio.h>
-#include <mach/palmt5.h>
+#include "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 "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/palmt5.h b/arch/arm/mach-pxa/palmt5.h
new file mode 100644
index 0000000..f850cc9
--- /dev/null
+++ b/arch/arm/mach-pxa/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 <mach/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/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 7691c97..1894659 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/input.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/input/matrix_keypad.h>
@@ -31,13 +32,13 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa25x.h>
+#include "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 "udc.h"
#include "generic.h"
#include "devices.h"
@@ -166,11 +167,14 @@ static inline void palmtc_keys_init(void) {}
* Backlight
******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup palmtc_pwm_lookup[] = {
+ PWM_LOOKUP("pxa25x-pwm.1", 0, "pwm-backlight.0", NULL, PALMTC_PERIOD_NS,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -184,6 +188,7 @@ static struct platform_device palmtc_backlight = {
static void __init palmtc_pwm_init(void)
{
+ pwm_add_table(palmtc_pwm_lookup, ARRAY_SIZE(palmtc_pwm_lookup));
platform_device_register(&palmtc_backlight);
}
#else
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 956fd24..36b4614 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -21,6 +21,7 @@
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
@@ -31,13 +32,13 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <mach/audio.h>
-#include <mach/palmte2.h>
+#include "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 "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
#include "generic.h"
@@ -138,6 +139,11 @@ static struct platform_device palmte2_pxa_keys = {
/******************************************************************************
* Backlight
******************************************************************************/
+static struct pwm_lookup palmte2_pwm_lookup[] = {
+ PWM_LOOKUP("pxa25x-pwm.0", 0, "pwm-backlight.0", NULL,
+ PALMTE2_PERIOD_NS, PWM_POLARITY_NORMAL),
+};
+
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" },
@@ -161,10 +167,8 @@ static void palmte2_backlight_exit(struct device *dev)
}
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,
@@ -355,6 +359,7 @@ static void __init palmte2_init(void)
pxa_set_ac97_info(&palmte2_ac97_pdata);
pxa_set_ficp_info(&palmte2_ficp_platform_data);
+ pwm_add_table(palmte2_pwm_lookup, ARRAY_SIZE(palmte2_pwm_lookup));
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/palmte2.h
index f89e989..f89e989 100644
--- a/arch/arm/mach-pxa/include/mach/palmte2.h
+++ b/arch/arm/mach-pxa/palmte2.h
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b937c..4cc05ec 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -31,20 +31,20 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "pxa27x-udc.h"
#include <mach/audio.h>
-#include <mach/palmtreo.h>
+#include "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 "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 <linux/platform_data/media/camera-pxa.h>
+#include "palm27x.h"
#include <sound/pxa2xx-lib.h>
diff --git a/arch/arm/mach-pxa/include/mach/palmtreo.h b/arch/arm/mach-pxa/palmtreo.h
index 714b657..714b657 100644
--- a/arch/arm/mach-pxa/include/mach/palmtreo.h
+++ b/arch/arm/mach-pxa/palmtreo.h
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 83f830d..3664697 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -37,16 +37,16 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "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 "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
#include "generic.h"
#include "devices.h"
@@ -250,7 +250,7 @@ static inline void palmtx_keys_init(void) {}
static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
char __iomem *nandaddr = this->IO_ADDR_W;
if (cmd == NAND_CMD_NONE)
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 1a35ddf..9c308de 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -37,19 +37,19 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/audio.h>
-#include <mach/palmz72.h>
+#include "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 "udc.h"
#include <linux/platform_data/asoc-palm27x.h>
-#include <mach/palm27x.h>
+#include "palm27x.h"
-#include <mach/pm.h>
-#include <linux/platform_data/camera-pxa.h>
+#include "pm.h"
+#include <linux/platform_data/media/camera-pxa.h>
#include <media/soc_camera.h>
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/palmz72.h
index 0d4700a..0d4700a 100644
--- a/arch/arm/mach-pxa/include/mach/palmz72.h
+++ b/arch/arm/mach-pxa/palmz72.h
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index 69918c7..ccca9f7 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -30,8 +30,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
-#include <mach/pcm027.h>
+#include "pxa27x.h"
+#include "pcm027.h"
#include "generic.h"
/*
diff --git a/arch/arm/mach-pxa/pcm027.h b/arch/arm/mach-pxa/pcm027.h
new file mode 100644
index 0000000..047cdf2
--- /dev/null
+++ b/arch/arm/mach-pxa/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 <mach/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/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index d8319b5..0bd5959 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -24,18 +24,19 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
-#include <media/mt9v022.h>
+#include <media/i2c/mt9v022.h>
#include <media/soc_camera.h>
-#include <linux/platform_data/camera-pxa.h>
+#include <linux/platform_data/media/camera-pxa.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "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 "pcm990_baseboard.h"
#include <linux/platform_data/video-pxafb.h>
#include "devices.h"
@@ -148,11 +149,14 @@ static struct pxafb_mach_info pcm990_fbinfo __initdata = {
};
#endif
+static struct pwm_lookup pcm990_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -542,6 +546,7 @@ void __init pcm990_baseboard_init(void)
#ifndef CONFIG_PCM990_DISPLAY_NONE
pxa_set_fb_info(NULL, &pcm990_fbinfo);
#endif
+ pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
platform_device_register(&pcm990_backlight_device);
/* MMC */
diff --git a/arch/arm/mach-pxa/pcm990_baseboard.h b/arch/arm/mach-pxa/pcm990_baseboard.h
new file mode 100644
index 0000000..79d35ad
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "pcm027.h"
+#include <mach/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/pm.c b/arch/arm/mach-pxa/pm.c
index 37178a8..388463b 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -16,7 +16,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
-#include <mach/pm.h>
+#include "pm.h"
struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
static unsigned long *sleep_save;
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/pm.h
index 51558bc..51558bc 100644
--- a/arch/arm/mach-pxa/include/mach/pm.h
+++ b/arch/arm/mach-pxa/pm.h
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 195b112..62a1191 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -41,9 +41,9 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
+#include "udc.h"
#include <linux/platform_data/irda-pxaficp.h>
#include <mach/poodle.h>
#include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 1dc85ff..a177bf4 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -30,9 +30,9 @@
#include <asm/suspend.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <mach/reset.h>
-#include <mach/pm.h>
+#include "pm.h"
#include <mach/dma.h>
#include <mach/smemc.h>
diff --git a/arch/arm/mach-pxa/pxa25x.h b/arch/arm/mach-pxa/pxa25x.h
new file mode 100644
index 0000000..2011e8d
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa25x.h
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include "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/pxa27x-udc.h
index 4cf28f6..4cf28f6 100644
--- a/arch/arm/mach-pxa/include/mach/pxa27x-udc.h
+++ b/arch/arm/mach-pxa/pxa27x-udc.h
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 221260d..8dfd175 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -28,10 +28,10 @@
#include <asm/irq.h>
#include <asm/suspend.h>
#include <mach/irqs.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/reset.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pm.h>
+#include "pm.h"
#include <mach/dma.h>
#include <mach/smemc.h>
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset);
*/
static unsigned int pwrmode = PWRMODE_SLEEP;
-int __init pxa27x_set_pwrmode(unsigned int mode)
+int pxa27x_set_pwrmode(unsigned int mode)
{
switch (mode) {
case PWRMODE_SLEEP:
diff --git a/arch/arm/mach-pxa/pxa27x.h b/arch/arm/mach-pxa/pxa27x.h
new file mode 100644
index 0000000..075131d
--- /dev/null
+++ b/arch/arm/mach-pxa/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 "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 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/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
index 447dcbb..6b5e566 100644
--- a/arch/arm/mach-pxa/pxa2xx.c
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -17,7 +17,7 @@
#include <mach/hardware.h>
#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include "mfp-pxa25x.h"
#include <mach/reset.h>
#include <linux/platform_data/irda-pxaficp.h>
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 28c5b56..df83b1b 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <mach/pxa300.h>
+#include "pxa300.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa300.h b/arch/arm/mach-pxa/pxa300.h
new file mode 100644
index 0000000..59fa410
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa300.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa300.h"
+
+#endif /* __MACH_PXA300_H */
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 2f55bb4..a26eec5 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <mach/pxa320.h>
+#include "pxa320.h"
#include "generic.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa320.h b/arch/arm/mach-pxa/pxa320.h
new file mode 100644
index 0000000..b9e5115
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa320.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa320.h"
+
+#endif /* __MACH_PXA320_H */
+
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
index 1c85275..eba595f 100644
--- a/arch/arm/mach-pxa/pxa3xx-ulpi.c
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -26,7 +26,7 @@
#include <linux/usb/otg.h>
#include <mach/hardware.h>
-#include <mach/regs-u2d.h>
+#include "regs-u2d.h"
#include <linux/platform_data/usb-pxa3xx-ulpi.h>
struct pxa3xx_u2d_ulpi {
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 20ce2d3..a1c4c88 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -30,7 +30,7 @@
#include <mach/pxa3xx-regs.h>
#include <mach/reset.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
-#include <mach/pm.h>
+#include "pm.h"
#include <mach/dma.h>
#include <mach/smemc.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/pxa3xx.h
index b4143fb..b4143fb 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx.h
+++ b/arch/arm/mach-pxa/pxa3xx.h
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
index ab62448..da912be 100644
--- a/arch/arm/mach-pxa/pxa930.c
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -17,7 +17,7 @@
#include <linux/gpio-pxa.h>
#include <linux/platform_device.h>
-#include <mach/pxa930.h>
+#include "pxa930.h"
#include "devices.h"
diff --git a/arch/arm/mach-pxa/pxa930.h b/arch/arm/mach-pxa/pxa930.h
new file mode 100644
index 0000000..4eceb02
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa930.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include "pxa3xx.h"
+#include "mfp-pxa930.h"
+
+#endif /* __MACH_PXA930_H */
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 88f70c3..5a941bd 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -18,17 +18,19 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.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.h>
#include <linux/pwm_backlight.h>
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
@@ -48,7 +50,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa300.h>
+#include "pxa300.h"
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/mmc-pxamci.h>
@@ -365,22 +367,31 @@ static struct pxaohci_platform_data raumfeld_ohci_info = {
* 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 gpiod_lookup_table raumfeld_rotary_gpios_table = {
+ .dev_id = "rotary-encoder.0",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-0",
+ GPIO_VOLENC_A, NULL, 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-0",
+ GPIO_VOLENC_B, NULL, 1, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct property_entry raumfeld_rotary_properties[] = {
+ PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24),
+ PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X),
+ PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1),
+ { },
+};
+
+static struct property_set raumfeld_rotary_property_set = {
+ .properties = raumfeld_rotary_properties,
};
static struct platform_device rotary_encoder_device = {
.name = "rotary-encoder",
.id = 0,
- .dev = {
- .platform_data = &raumfeld_rotary_encoder_info,
- }
};
/**
@@ -507,7 +518,7 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = {
.ext_pullup_enable_pin = -EINVAL,
};
-struct platform_device raumfeld_w1_gpio_device = {
+static struct platform_device raumfeld_w1_gpio_device = {
.name = "w1-gpio",
.dev = {
.platform_data = &w1_gpio_platform_data
@@ -531,13 +542,15 @@ static void __init raumfeld_w1_init(void)
* Framebuffer device
*/
+static struct pwm_lookup raumfeld_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 10000,
+ PWM_POLARITY_NORMAL),
+};
+
/* 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,
};
@@ -618,6 +631,8 @@ static void __init raumfeld_lcd_init(void)
} else {
mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+ pwm_add_table(raumfeld_pwm_lookup,
+ ARRAY_SIZE(raumfeld_pwm_lookup));
platform_device_register(&raumfeld_pwm_backlight_device);
}
@@ -629,7 +644,7 @@ static void __init raumfeld_lcd_init(void)
* SPI devices
*/
-struct spi_gpio_platform_data raumfeld_spi_platform_data = {
+static struct spi_gpio_platform_data raumfeld_spi_platform_data = {
.sck = GPIO_SPI_CLK,
.mosi = GPIO_SPI_MOSI,
.miso = GPIO_SPI_MISO,
@@ -848,7 +863,7 @@ static void __init raumfeld_power_init(void)
static struct regulator_consumer_supply audio_va_consumer_supply =
REGULATOR_SUPPLY("va", "0-0048");
-struct regulator_init_data audio_va_initdata = {
+static struct regulator_init_data audio_va_initdata = {
.consumer_supplies = &audio_va_consumer_supply,
.num_consumer_supplies = 1,
.constraints = {
@@ -880,7 +895,7 @@ static struct regulator_consumer_supply audio_dummy_supplies[] = {
REGULATOR_SUPPLY("vlc", "0-0048"),
};
-struct regulator_init_data audio_dummy_initdata = {
+static struct regulator_init_data audio_dummy_initdata = {
.consumer_supplies = audio_dummy_supplies,
.num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies),
.constraints = {
@@ -928,7 +943,7 @@ static struct regulator_init_data vcc_mmc_init_data = {
.num_consumer_supplies = 1,
};
-struct max8660_subdev_data max8660_v6_subdev_data = {
+static struct max8660_subdev_data max8660_v6_subdev_data = {
.id = MAX8660_V6,
.name = "vmmc",
.platform_data = &vcc_mmc_init_data,
@@ -1041,12 +1056,17 @@ static void __init raumfeld_common_init(void)
i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
}
-static void __init raumfeld_controller_init(void)
+static void __init __maybe_unused raumfeld_controller_init(void)
{
int ret;
pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config));
+
+ gpiod_add_lookup_table(&raumfeld_rotary_gpios_table);
+ device_add_property_set(&rotary_encoder_device.dev,
+ &raumfeld_rotary_property_set);
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);
@@ -1062,7 +1082,7 @@ static void __init raumfeld_controller_init(void)
raumfeld_w1_init();
}
-static void __init raumfeld_connector_init(void)
+static void __init __maybe_unused raumfeld_connector_init(void)
{
pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config));
spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
@@ -1074,13 +1094,17 @@ static void __init raumfeld_connector_init(void)
raumfeld_common_init();
}
-static void __init raumfeld_speaker_init(void)
+static void __init __maybe_unused 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);
+
+ gpiod_add_lookup_table(&raumfeld_rotary_gpios_table);
+ device_add_property_set(&rotary_encoder_device.dev,
+ &raumfeld_rotary_property_set);
platform_device_register(&rotary_encoder_device);
raumfeld_audio_init();
diff --git a/arch/arm/mach-pxa/include/mach/regs-rtc.h b/arch/arm/mach-pxa/regs-rtc.h
index f0e4a58..f0e4a58 100644
--- a/arch/arm/mach-pxa/include/mach/regs-rtc.h
+++ b/arch/arm/mach-pxa/regs-rtc.h
diff --git a/arch/arm/mach-pxa/include/mach/regs-u2d.h b/arch/arm/mach-pxa/regs-u2d.h
index c15c0c5..c15c0c5 100644
--- a/arch/arm/mach-pxa/include/mach/regs-u2d.h
+++ b/arch/arm/mach-pxa/regs-u2d.h
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 710c493..1414b5f 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -31,7 +31,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
-#include <mach/pxa930.h>
+#include "pxa930.h"
#include <linux/platform_data/video-pxafb.h>
#include "devices.h"
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index bdc0c41..b80eab9 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -27,10 +27,10 @@
#include <linux/io.h>
#include <asm/mach-types.h>
-#include <mach/pm.h>
+#include "pm.h"
#include <mach/pxa2xx-regs.h>
-#include <mach/regs-rtc.h>
-#include <mach/sharpsl_pm.h>
+#include "regs-rtc.h"
+#include "sharpsl_pm.h"
/*
* Constants
diff --git a/arch/arm/mach-pxa/include/mach/sharpsl_pm.h b/arch/arm/mach-pxa/sharpsl_pm.h
index 905be67..905be67 100644
--- a/arch/arm/mach-pxa/include/mach/sharpsl_pm.h
+++ b/arch/arm/mach-pxa/sharpsl_pm.h
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index f4e2e27..825f903 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -40,15 +40,15 @@
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
+#include "pxa27x.h"
+#include "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 "sharpsl_pm.h"
#include <mach/smemc.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index e191f99..ea9f903 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -25,8 +25,8 @@
#include <mach/hardware.h>
#include <mach/spitz.h>
-#include <mach/pxa27x.h>
-#include <mach/sharpsl_pm.h>
+#include "pxa27x.h"
+#include "sharpsl_pm.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 01de542..702f4f1 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -43,10 +43,10 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <linux/platform_data/mmc-pxamci.h>
-#include <mach/udc.h>
-#include <mach/pxa27x-udc.h>
+#include "udc.h"
+#include "pxa27x-udc.h"
#include <mach/smemc.h>
#include <linux/spi/spi.h>
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index a71da84..4b38e82 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -18,12 +18,13 @@
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/smc91x.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa930.h>
+#include "pxa930.h"
#include <linux/platform_data/video-pxafb.h>
#include <linux/platform_data/keypad-pxa27x.h>
@@ -168,21 +169,24 @@ 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 pwm_lookup tavorevb_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.0", NULL, 100000,
+ PWM_POLARITY_NORMAL),
+ PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.1", NULL, 100000,
+ PWM_POLARITY_NORMAL),
+};
+
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,
},
};
@@ -470,6 +474,7 @@ static struct pxafb_mach_info tavorevb_lcd_info = {
static void __init tavorevb_init_lcd(void)
{
+ pwm_add_table(tavorevb_pwm_lookup, ARRAY_SIZE(tavorevb_pwm_lookup));
platform_device_register(&tavorevb_backlight_devices[0]);
platform_device_register(&tavorevb_backlight_devices[1]);
pxa_set_fb_info(NULL, &tavorevb_lcd_info);
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
index e0a5320..107f372 100644
--- a/arch/arm/mach-pxa/tosa-bt.c
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/rfkill.h>
-#include <mach/tosa_bt.h>
+#include "tosa_bt.h"
static void tosa_bt_on(struct tosa_bt_data *data)
{
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index e6e27c0..13de6602 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -43,12 +43,12 @@
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include <mach/pxa25x.h>
+#include "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 "udc.h"
+#include "tosa_bt.h"
#include <mach/audio.h>
#include <mach/smemc.h>
diff --git a/arch/arm/mach-pxa/include/mach/tosa_bt.h b/arch/arm/mach-pxa/tosa_bt.h
index efc3c3d..efc3c3d 100644
--- a/arch/arm/mach-pxa/include/mach/tosa_bt.h
+++ b/arch/arm/mach-pxa/tosa_bt.h
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 066e3a2..ea78bc5 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -41,7 +41,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa27x.h>
+#include "pxa27x.h"
#include <mach/trizeps4.h>
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/include/mach/udc.h b/arch/arm/mach-pxa/udc.h
index 9a827e3..9a827e3 100644
--- a/arch/arm/mach-pxa/include/mach/udc.h
+++ b/arch/arm/mach-pxa/udc.h
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 8ab2637..8e89d91 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -39,6 +39,7 @@
#include <linux/i2c/pxa-i2c.h>
#include <linux/serial_8250.h>
#include <linux/smc91x.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/usb/isp116x.h>
#include <linux/mtd/mtd.h>
@@ -46,12 +47,12 @@
#include <linux/mtd/physmap.h>
#include <linux/syscore_ops.h>
-#include <mach/pxa25x.h>
+#include "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 "viper.h"
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -350,6 +351,11 @@ static struct pxafb_mach_info fb_info = {
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};
+static struct pwm_lookup viper_pwm_lookup[] = {
+ PWM_LOOKUP("pxa25x-pwm.0", 0, "pwm-backlight.0", NULL, 1000000,
+ PWM_POLARITY_NORMAL),
+};
+
static int viper_backlight_init(struct device *dev)
{
int ret;
@@ -398,10 +404,8 @@ static void viper_backlight_exit(struct device *dev)
}
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,
@@ -939,6 +943,7 @@ static void __init viper_init(void)
smc91x_device.num_resources--;
pxa_set_i2c_info(NULL);
+ pwm_add_table(viper_pwm_lookup, ARRAY_SIZE(viper_pwm_lookup));
platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs));
viper_init_vcore_gpios();
diff --git a/arch/arm/mach-pxa/include/mach/viper.h b/arch/arm/mach-pxa/viper.h
index 5f5fbf1..5f5fbf1 100644
--- a/arch/arm/mach-pxa/include/mach/viper.h
+++ b/arch/arm/mach-pxa/viper.h
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index 54122a9..c006ee9 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -31,14 +31,14 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
+#include "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 "pxa27x-udc.h"
+#include "udc.h"
#include <linux/platform_data/ata-pxa.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
index 13b1d45..3f06cd9 100644
--- a/arch/arm/mach-pxa/xcep.c
+++ b/arch/arm/mach-pxa/xcep.c
@@ -28,7 +28,7 @@
#include <asm/mach/map.h>
#include <mach/hardware.h>
-#include <mach/pxa25x.h>
+#include "pxa25x.h"
#include <mach/smemc.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index e1a121b..510e533 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/z2_battery.h>
#include <linux/dma-mapping.h>
@@ -34,13 +35,13 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/pxa27x.h>
-#include <mach/mfp-pxa27x.h>
+#include "pxa27x.h"
+#include "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 "pm.h"
#include "generic.h"
#include "devices.h"
@@ -199,21 +200,24 @@ static inline void z2_nor_init(void) {}
* Backlight
******************************************************************************/
#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup z2_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight.0", NULL, 1260320,
+ PWM_POLARITY_NORMAL),
+ PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.1", NULL, 1260320,
+ PWM_POLARITY_NORMAL),
+};
+
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,
},
};
@@ -236,6 +240,7 @@ static struct platform_device z2_backlight_devices[2] = {
};
static void __init z2_pwm_init(void)
{
+ pwm_add_table(z2_pwm_lookup, ARRAY_SIZE(z2_pwm_lookup));
platform_device_register(&z2_backlight_devices[0]);
platform_device_register(&z2_backlight_devices[1]);
}
@@ -595,13 +600,11 @@ static struct spi_board_info spi_board_info[] __initdata = {
};
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,
};
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 30e62a3..515b7dd 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -38,17 +38,17 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa27x.h>
+#include "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 "pxa27x-udc.h"
+#include "udc.h"
#include <linux/platform_data/video-pxafb.h>
-#include <mach/pm.h>
+#include "pm.h"
#include <mach/audio.h>
#include <linux/platform_data/pcmcia-pxa2xx_viper.h>
-#include <mach/zeus.h>
+#include "zeus.h"
#include <mach/smemc.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/zeus.h
index 56024f8..56024f8 100644
--- a/arch/arm/mach-pxa/include/mach/zeus.h
+++ b/arch/arm/mach-pxa/zeus.h
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 77daea4..3642389 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -19,15 +19,16 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/pwm.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 "pxa3xx.h"
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
-#include <mach/zylonite.h>
+#include "zylonite.h"
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/keypad-pxa27x.h>
@@ -120,11 +121,14 @@ static inline void zylonite_init_leds(void) {}
#endif
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pwm_lookup zylonite_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.1", 1, "pwm-backlight.0", NULL, 10000,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -206,6 +210,7 @@ static struct pxafb_mach_info zylonite_sharp_lcd_info = {
static void __init zylonite_init_lcd(void)
{
+ pwm_add_table(zylonite_pwm_lookup, ARRAY_SIZE(zylonite_pwm_lookup));
platform_device_register(&zylonite_backlight_device);
if (lcd_id & 0x20) {
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/zylonite.h
index ecca976..ecca976 100644
--- a/arch/arm/mach-pxa/include/mach/zylonite.h
+++ b/arch/arm/mach-pxa/zylonite.h
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 869bce7..e247acf 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -21,8 +21,8 @@
#include <linux/platform_data/pca953x.h>
#include <linux/gpio.h>
-#include <mach/pxa300.h>
-#include <mach/zylonite.h>
+#include "pxa300.h"
+#include "zylonite.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 9942bac..47961ae 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -18,8 +18,8 @@
#include <linux/init.h>
#include <linux/gpio.h>
-#include <mach/pxa320.h>
-#include <mach/zylonite.h>
+#include "pxa320.h"
+#include "zylonite.h"
#include "generic.h"
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 2256cd1..7349450 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_QCOM
- bool "Qualcomm Support" if ARCH_MULTI_V7
+ bool "Qualcomm Support"
+ depends on ARCH_MULTI_V7
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_GIC
select ARM_AMBA
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index 5cde63a..5494c9e 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -49,7 +49,7 @@ extern void secondary_startup_arm(void);
static DEFINE_SPINLOCK(boot_lock);
#ifdef CONFIG_HOTPLUG_CPU
-static void __ref qcom_cpu_die(unsigned int cpu)
+static void qcom_cpu_die(unsigned int cpu)
{
wfi();
}
@@ -332,7 +332,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
}
}
-static struct smp_operations smp_msm8660_ops __initdata = {
+static const struct smp_operations smp_msm8660_ops __initconst = {
.smp_prepare_cpus = qcom_smp_prepare_cpus,
.smp_secondary_init = qcom_secondary_init,
.smp_boot_secondary = msm8660_boot_secondary,
@@ -342,7 +342,7 @@ static struct smp_operations smp_msm8660_ops __initdata = {
};
CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
-static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv1_ops __initconst = {
.smp_prepare_cpus = qcom_smp_prepare_cpus,
.smp_secondary_init = qcom_secondary_init,
.smp_boot_secondary = kpssv1_boot_secondary,
@@ -352,7 +352,7 @@ static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
};
CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
-static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv2_ops __initconst = {
.smp_prepare_cpus = qcom_smp_prepare_cpus,
.smp_secondary_init = qcom_secondary_init,
.smp_boot_secondary = kpssv2_boot_secondary,
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 565925f..70ab4a2 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -1,13 +1,30 @@
-menu "RealView platform type"
- depends on ARCH_REALVIEW
+menuconfig ARCH_REALVIEW
+ bool "ARM Ltd. RealView family"
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select COMMON_CLK_VERSATILE
+ select GPIO_PL061 if GPIOLIB
+ select ICST
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_SCHED_CLOCK
+ help
+ This enables support for ARM Ltd RealView boards.
+
+if ARCH_REALVIEW
config REALVIEW_DT
bool "Support RealView(R) Device Tree based boot"
select ARM_GIC
+ select CLK_SP810
+ select HAVE_SMP
+ select ICST
+ select MACH_REALVIEW_EB if ARCH_MULTI_V5
select MFD_SYSCON
select POWER_RESET
select POWER_RESET_VERSATILE
select POWER_SUPPLY
+ select SMP_ON_UP if SMP
select SOC_REALVIEW
select USE_OF
help
@@ -17,14 +34,32 @@ config REALVIEW_DT
config MACH_REALVIEW_EB
bool "Support RealView(R) Emulation Baseboard"
select ARM_GIC
+ select CPU_ARM926T if ARCH_MULTI_V5
help
Include support for the ARM(R) RealView(R) Emulation Baseboard
- platform.
+ platform. On an ARMv5 kernel, this will include support for
+ the ARM926EJ-S core tile, while on an ARMv6/v7 kernel, at least
+ one of the ARM1136, ARM1176, ARM11MPCore or Cortex-A9MPCore
+ core tile options should be enabled.
+
+config REALVIEW_EB_ARM1136
+ bool "Support ARM1136J(F)-S Tile"
+ depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+ select CPU_V6
+ help
+ Enable support for the ARM1136 tile fitted to the
+ Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM1176
+ bool "Support ARM1176JZ(F)-S Tile"
+ depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+ help
+ Enable support for the ARM1176 tile fitted to the
+ Realview(R) Emulation Baseboard platform.
config REALVIEW_EB_A9MP
bool "Support Multicore Cortex-A9 Tile"
- depends on MACH_REALVIEW_EB
- select CPU_V7
+ depends on MACH_REALVIEW_EB && ARCH_MULTI_V7
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select HAVE_SMP
@@ -35,9 +70,7 @@ config REALVIEW_EB_A9MP
config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore Tile"
- depends on MACH_REALVIEW_EB
- select ARCH_HAS_BARRIERS if SMP
- select CPU_V6K
+ depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select HAVE_SMP
@@ -48,7 +81,7 @@ config REALVIEW_EB_ARM11MP
config REALVIEW_EB_ARM11MP_REVB
bool "Support ARM11MPCore RevB Tile"
- depends on REALVIEW_EB_ARM11MP
+ depends on REALVIEW_EB_ARM11MP && ARCH_MULTI_V6
help
Enable support for the ARM11MPCore Revision B tile on the
Realview(R) Emulation Baseboard platform. Since there are device
@@ -57,9 +90,8 @@ config REALVIEW_EB_ARM11MP_REVB
config MACH_REALVIEW_PB11MP
bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
- select ARCH_HAS_BARRIERS if SMP
+ depends on ARCH_MULTI_V6
select ARM_GIC
- select CPU_V6K
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select HAVE_PATA_PLATFORM
@@ -73,6 +105,7 @@ config MACH_REALVIEW_PB11MP
# 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"
+ depends on ARCH_MULTI_V6
select ARM_GIC
select CPU_V6
select HAVE_TCM
@@ -92,8 +125,8 @@ config REALVIEW_PB1176_SECURE_FLASH
config MACH_REALVIEW_PBA8
bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
+ depends on ARCH_MULTI_V7
select ARM_GIC
- select CPU_V7
select HAVE_PATA_PLATFORM
help
Include support for the ARM(R) RealView Platform Baseboard for
@@ -101,15 +134,15 @@ config MACH_REALVIEW_PBA8
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
+ bool "Support RealView(R) Platform Baseboard Explore for Cortex-A9"
+ depends on ARCH_MULTI_V7
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
+ select ZONE_DMA
help
Include support for the ARM(R) RealView(R) Platform Baseboard
Explore.
@@ -124,6 +157,6 @@ config REALVIEW_HIGH_PHYS_OFFSET
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.
+ RAM to be used with HIGHMEM.
-endmenu
+endif
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index e07fdf7..dae8d86 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -1,13 +1,19 @@
#
# Makefile for the linux kernel.
#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+ -I$(srctree)/arch/arm/plat-versatile/include
obj-y := core.o
obj-$(CONFIG_REALVIEW_DT) += realview-dt.o
+obj-$(CONFIG_SMP) += platsmp-dt.o
+
+ifdef CONFIG_ATAGS
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
+endif
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-realview/board-eb.h b/arch/arm/mach-realview/board-eb.h
new file mode 100644
index 0000000..a850ae6
--- /dev/null
+++ b/arch/arm/mach-realview/board-eb.h
@@ -0,0 +1,94 @@
+/*
+ * 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 "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/board-pb1176.h b/arch/arm/mach-realview/board-pb1176.h
new file mode 100644
index 0000000..29c04a9
--- /dev/null
+++ b/arch/arm/mach-realview/board-pb1176.h
@@ -0,0 +1,81 @@
+/*
+ * 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 "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/board-pb11mp.h b/arch/arm/mach-realview/board-pb11mp.h
new file mode 100644
index 0000000..b16e6e85
--- /dev/null
+++ b/arch/arm/mach-realview/board-pb11mp.h
@@ -0,0 +1,96 @@
+/*
+ * 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 "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/board-pba8.h b/arch/arm/mach-realview/board-pba8.h
new file mode 100644
index 0000000..6a1391f
--- /dev/null
+++ b/arch/arm/mach-realview/board-pba8.h
@@ -0,0 +1,71 @@
+/*
+ * 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 "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/board-pbx.h b/arch/arm/mach-realview/board-pbx.h
new file mode 100644
index 0000000..5cda480
--- /dev/null
+++ b/arch/arm/mach-realview/board-pbx.h
@@ -0,0 +1,106 @@
+/*
+ * 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 "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/core.c b/arch/arm/mach-realview/core.c
index 44575ed..baf1745 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -36,8 +36,7 @@
#include <linux/memblock.h>
#include <clocksource/timer-sp804.h>
-
-#include <mach/hardware.h>
+#include "hardware.h"
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware/icst.h>
@@ -46,8 +45,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
-#include <mach/platform.h>
-#include <mach/irqs.h>
+#include "platform.h"
#include <plat/sched_clock.h>
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 868ece2..05a995e 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -1,6 +1,4 @@
/*
- * linux/arch/arm/mach-realview/core.h
- *
* Copyright (C) 2004 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
@@ -54,7 +52,7 @@ 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 const struct smp_operations realview_smp_ops;
extern void realview_cpu_die(unsigned int cpu);
#endif
diff --git a/arch/arm/mach-realview/hardware.h b/arch/arm/mach-realview/hardware.h
new file mode 100644
index 0000000..957a230
--- /dev/null
+++ b/arch/arm/mach-realview/hardware.h
@@ -0,0 +1,40 @@
+/*
+ * 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/hotplug.c b/arch/arm/mach-realview/hotplug.c
index ac22dd4..968e2d1 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -90,7 +90,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
*
* Called with IRQs disabled
*/
-void __ref realview_cpu_die(unsigned int cpu)
+void realview_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mach-realview/include/mach/barriers.h b/arch/arm/mach-realview/include/mach/barriers.h
deleted file mode 100644
index 9a73219..0000000
--- a/arch/arm/mach-realview/include/mach/barriers.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a301e61..0000000
--- a/arch/arm/mach-realview/include/mach/board-eb.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2a15fef..0000000
--- a/arch/arm/mach-realview/include/mach/board-pb1176.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
deleted file mode 100644
index aa2d4e0..0000000
--- a/arch/arm/mach-realview/include/mach/board-pb11mp.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4dfc67a..0000000
--- a/arch/arm/mach-realview/include/mach/board-pba8.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 848bfff..0000000
--- a/arch/arm/mach-realview/include/mach/board-pbx.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 281e71c..0000000
--- a/arch/arm/mach-realview/include/mach/hardware.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4475423..0000000
--- a/arch/arm/mach-realview/include/mach/irqs-eb.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 708f841..0000000
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 34e255a..0000000
--- a/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 4a88a4e..0000000
--- a/arch/arm/mach-realview/include/mach/irqs-pba8.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 206a300..0000000
--- a/arch/arm/mach-realview/include/mach/irqs-pbx.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 78854f2..0000000
--- a/arch/arm/mach-realview/include/mach/irqs.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 23e7a31..0000000
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1b77a27..0000000
--- a/arch/arm/mach-realview/include/mach/platform.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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
deleted file mode 100644
index cfa30d2..0000000
--- a/arch/arm/mach-realview/include/mach/uncompress.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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/irqs-eb.h b/arch/arm/mach-realview/irqs-eb.h
new file mode 100644
index 0000000..61e3168
--- /dev/null
+++ b/arch/arm/mach-realview/irqs-eb.h
@@ -0,0 +1,114 @@
+/*
+ * 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_LOCALTIMER 29
+#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
+
+#endif /* __MACH_IRQS_EB_H */
diff --git a/arch/arm/mach-realview/irqs-pb1176.h b/arch/arm/mach-realview/irqs-pb1176.h
new file mode 100644
index 0000000..778edfd
--- /dev/null
+++ b/arch/arm/mach-realview/irqs-pb1176.h
@@ -0,0 +1,77 @@
+/*
+ * 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
+
+#endif /* __MACH_IRQS_PB1176_H */
diff --git a/arch/arm/mach-realview/irqs-pb11mp.h b/arch/arm/mach-realview/irqs-pb11mp.h
new file mode 100644
index 0000000..938898a
--- /dev/null
+++ b/arch/arm/mach-realview/irqs-pb11mp.h
@@ -0,0 +1,97 @@
+/*
+ * 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_LOCALTIMER 29
+#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 */
+
+#endif /* __MACH_IRQS_PB11MP_H */
diff --git a/arch/arm/mach-realview/irqs-pba8.h b/arch/arm/mach-realview/irqs-pba8.h
new file mode 100644
index 0000000..262e321
--- /dev/null
+++ b/arch/arm/mach-realview/irqs-pba8.h
@@ -0,0 +1,71 @@
+/*
+ * 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
+
+#endif /* __MACH_IRQS_PBA8_H */
diff --git a/arch/arm/mach-realview/irqs-pbx.h b/arch/arm/mach-realview/irqs-pbx.h
new file mode 100644
index 0000000..4ef0567
--- /dev/null
+++ b/arch/arm/mach-realview/irqs-pbx.h
@@ -0,0 +1,87 @@
+/*
+ * 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_LOCALTIMER 29
+#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
+
+#endif /* __MACH_IRQS_PBX_H */
diff --git a/arch/arm/mach-realview/platform.h b/arch/arm/mach-realview/platform.h
new file mode 100644
index 0000000..1112173
--- /dev/null
+++ b/arch/arm/mach-realview/platform.h
@@ -0,0 +1,247 @@
+/*
+ * 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/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c
new file mode 100644
index 0000000..6964e88
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp-dt.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 Linus Walleij
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms 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.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include <plat/platsmp.h>
+
+#include "core.h"
+
+#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30
+
+static const struct of_device_id realview_scu_match[] = {
+ { .compatible = "arm,arm11mp-scu", },
+ { .compatible = "arm,cortex-a9-scu", },
+ { .compatible = "arm,cortex-a5-scu", },
+ { }
+};
+
+static const struct of_device_id realview_syscon_match[] = {
+ { .compatible = "arm,core-module-integrator", },
+ { .compatible = "arm,realview-eb-syscon", },
+ { .compatible = "arm,realview-pb11mp-syscon", },
+ { .compatible = "arm,realview-pbx-syscon", },
+ { },
+};
+
+static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *np;
+ void __iomem *scu_base;
+ struct regmap *map;
+ unsigned int ncores;
+ int i;
+
+ np = of_find_matching_node(NULL, realview_scu_match);
+ if (!np) {
+ pr_err("PLATSMP: No SCU base address\n");
+ return;
+ }
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!scu_base) {
+ pr_err("PLATSMP: No SCU remap\n");
+ return;
+ }
+
+ scu_enable(scu_base);
+ ncores = scu_get_core_count(scu_base);
+ pr_info("SCU: %d cores detected\n", ncores);
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+ iounmap(scu_base);
+
+ /* The syscon contains the magic SMP start address registers */
+ np = of_find_matching_node(NULL, realview_syscon_match);
+ if (!np) {
+ pr_err("PLATSMP: No syscon match\n");
+ return;
+ }
+ map = syscon_node_to_regmap(np);
+ if (IS_ERR(map)) {
+ pr_err("PLATSMP: No syscon regmap\n");
+ return;
+ }
+ /* Put the boot address in this magic register */
+ regmap_write(map, REALVIEW_SYS_FLAGSSET_OFFSET,
+ virt_to_phys(versatile_secondary_startup));
+}
+
+static const struct smp_operations realview_dt_smp_ops __initconst = {
+ .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
+};
+CPU_METHOD_OF_DECLARE(realview_smp, "arm,realview-smp", &realview_dt_smp_ops);
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 98e3052..e8ab69c 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -13,13 +13,13 @@
#include <linux/smp.h>
#include <linux/io.h>
-#include <mach/hardware.h>
+#include "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 "board-eb.h"
+#include "board-pb11mp.h"
+#include "board-pbx.h"
#include <plat/platsmp.h>
@@ -75,7 +75,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
__io_address(REALVIEW_SYS_FLAGSSET));
}
-struct smp_operations realview_smp_ops __initdata = {
+const struct smp_operations realview_smp_ops __initconst = {
.smp_init_cpus = realview_smp_init_cpus,
.smp_prepare_cpus = realview_smp_prepare_cpus,
.smp_secondary_init = versatile_secondary_init,
diff --git a/arch/arm/mach-realview/realview-dt.c b/arch/arm/mach-realview/realview-dt.c
index 382cc1b..88b6724 100644
--- a/arch/arm/mach-realview/realview-dt.c
+++ b/arch/arm/mach-realview/realview-dt.c
@@ -11,7 +11,6 @@
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include <asm/hardware/cache-l2x0.h>
-#include "core.h"
static const char *const realview_dt_platform_compat[] __initconst = {
"arm,realview-eb",
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index b3869cb..b442fa6 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -31,20 +31,21 @@
#include <linux/platform_data/clk-realview.h>
#include <linux/reboot.h>
-#include <mach/hardware.h>
+#include "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/outercache.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 "board-eb.h"
+#include "irqs-eb.h"
#include "core.h"
@@ -450,6 +451,12 @@ static void __init realview_eb_init(void)
* Bits: .... ...0 0111 1001 0000 .... .... ....
*/
l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
+
+ /*
+ * due to a bug in the l220 cache controller, we must not call
+ * the sync function. stub it out here instead!
+ */
+ outer_cache.sync = NULL;
#endif
pmu_device.name = core_tile_a9mp() ? "armv7-pmu" : "armv6-pmu";
platform_device_register(&pmu_device);
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index ce92c18..537f387 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -34,7 +34,7 @@
#include <linux/reboot.h>
#include <linux/memblock.h>
-#include <mach/hardware.h>
+#include "hardware.h"
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/pgtable.h>
@@ -45,8 +45,8 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <mach/board-pb1176.h>
-#include <mach/irqs.h>
+#include "board-pb1176.h"
+#include "irqs-pb1176.h"
#include "core.h"
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 15c45e2..a90a075 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -31,7 +31,7 @@
#include <linux/platform_data/clk-realview.h>
#include <linux/reboot.h>
-#include <mach/hardware.h>
+#include "hardware.h"
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/pgtable.h>
@@ -42,9 +42,10 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
+#include <asm/outercache.h>
-#include <mach/board-pb11mp.h>
-#include <mach/irqs.h>
+#include "board-pb11mp.h"
+#include "irqs-pb11mp.h"
#include "core.h"
@@ -345,6 +346,11 @@ static void __init realview_pb11mp_init(void)
* Bits: .... ...0 0111 1001 0000 .... .... ....
*/
l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
+ /*
+ * due to a bug in the l220 cache controller, we must not call
+ * the sync function. stub it out here instead!
+ */
+ outer_cache.sync = NULL;
#endif
realview_flash_register(realview_pb11mp_flash_resource,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 4c64662..ddafb67 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -39,9 +39,9 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/board-pba8.h>
-#include <mach/irqs.h>
+#include "hardware.h"
+#include "board-pba8.h"
+#include "irqs-pba8.h"
#include "core.h"
@@ -77,14 +77,6 @@ static struct map_desc realview_pba8_io_desc[] __initdata = {
.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),
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 9a22b86..b9f0757 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -41,9 +41,9 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/board-pbx.h>
-#include <mach/irqs.h>
+#include "hardware.h"
+#include "board-pbx.h"
+#include "irqs-pbx.h"
#include "core.h"
@@ -79,14 +79,6 @@ static struct map_desc realview_pbx_io_desc[] __initdata = {
.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),
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index ae4eb7c..cef42fd 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -1,5 +1,6 @@
config ARCH_ROCKCHIP
- bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7
+ bool "Rockchip RK2928 and RK3xxx SOCs"
+ depends on ARCH_MULTI_V7
select PINCTRL
select PINCTRL_ROCKCHIP
select ARCH_HAS_RESET_CONTROLLER
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index 3e7a4b7..d42a07e 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -42,6 +42,7 @@ static int ncores;
#define PMU_PWRDN_SCU 4
static struct regmap *pmu;
+static int has_pmu = true;
static int pmu_power_domain_is_on(int pd)
{
@@ -89,20 +90,23 @@ static int pmu_set_power_domain(int pd, bool on)
if (!IS_ERR(rstc) && !on)
reset_control_assert(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 (has_pmu) {
+ ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
if (ret < 0) {
- pr_err("%s: could not read power domain state\n",
+ 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;
+ }
+ }
}
if (!IS_ERR(rstc)) {
@@ -122,7 +126,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
int ret;
- if (!sram_base_addr || !pmu) {
+ if (!sram_base_addr || (has_pmu && !pmu)) {
pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
return -ENXIO;
}
@@ -275,7 +279,7 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
return;
}
- if (rockchip_smp_prepare_pmu())
+ if (has_pmu && rockchip_smp_prepare_pmu())
return;
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
@@ -318,6 +322,13 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
pmu_set_power_domain(0 + i, false);
}
+static void __init rk3036_smp_prepare_cpus(unsigned int max_cpus)
+{
+ has_pmu = false;
+
+ rockchip_smp_prepare_cpus(max_cpus);
+}
+
#ifdef CONFIG_HOTPLUG_CPU
static int rockchip_cpu_kill(unsigned int cpu)
{
@@ -340,7 +351,16 @@ static void rockchip_cpu_die(unsigned int cpu)
}
#endif
-static struct smp_operations rockchip_smp_ops __initdata = {
+static const struct smp_operations rk3036_smp_ops __initconst = {
+ .smp_prepare_cpus = rk3036_smp_prepare_cpus,
+ .smp_boot_secondary = rockchip_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_kill = rockchip_cpu_kill,
+ .cpu_die = rockchip_cpu_die,
+#endif
+};
+
+static const struct smp_operations rockchip_smp_ops __initconst = {
.smp_prepare_cpus = rockchip_smp_prepare_cpus,
.smp_boot_secondary = rockchip_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
@@ -349,4 +369,5 @@ static struct smp_operations rockchip_smp_ops __initdata = {
#endif
};
+CPU_METHOD_OF_DECLARE(rk3036_smp, "rockchip,rk3036-smp", &rk3036_smp_ops);
CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops);
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index b6cf3b4..3f07cc5 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -67,7 +67,7 @@ static void __init rockchip_timer_init(void)
}
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
}
static void __init rockchip_dt_init(void)
@@ -82,6 +82,7 @@ static const char * const rockchip_board_dt_compat[] = {
"rockchip,rk3066a",
"rockchip,rk3066b",
"rockchip,rk3188",
+ "rockchip,rk3228",
"rockchip,rk3288",
NULL,
};
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h
index 0fd4b0b..654a6f3 100644
--- a/arch/arm/mach-rpc/include/mach/uncompress.h
+++ b/arch/arm/mach-rpc/include/mach/uncompress.h
@@ -76,7 +76,7 @@ int white;
/*
* This does not append a newline
*/
-static void putc(int c)
+static inline void putc(int c)
{
extern void ll_write_char(char *, char c, char white);
int x,y;
diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
index 69459dbb..712333f 100644
--- a/arch/arm/mach-s3c24xx/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
@@ -85,3 +85,17 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
static inline void s3c_pm_restored_gpios(void) { }
static inline void samsung_pm_saved_gpios(void) { }
+
+/* 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
+*/
+#ifdef CONFIG_PM_SLEEP
+#define s3c_irqwake_intallow (1L << 30 | 0xfL)
+#define s3c_irqwake_eintallow (0x0000fff0L)
+#else
+#define s3c_irqwake_eintallow 0
+#define s3c_irqwake_intallow 0
+#endif
diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
index b91341e..417b7a2 100644
--- a/arch/arm/mach-s3c24xx/irq-pm.c
+++ b/arch/arm/mach-s3c24xx/irq-pm.c
@@ -25,19 +25,10 @@
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
+#include <mach/pm-core.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;
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index d40d4f5..7ed7861 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/i2c.h>
#include <linux/leds.h>
@@ -469,6 +470,11 @@ static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
.ocr_avail = MMC_VDD_32_33,
};
+static struct pwm_lookup h1940_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296,
+ PWM_POLARITY_NORMAL),
+};
+
static int h1940_backlight_init(struct device *dev)
{
gpio_request(S3C2410_GPB(0), "Backlight");
@@ -503,11 +509,8 @@ static void h1940_backlight_exit(struct device *dev)
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,
@@ -661,7 +664,7 @@ static void __init h1940_map_io(void)
/* Add latch gpio chip, set latch initial value */
h1940_latch_control(0, 0);
- WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
+ WARN_ON(gpiochip_add_data(&h1940_latch_gpiochip, NULL));
}
static void __init h1940_init_time(void)
@@ -725,6 +728,7 @@ static void __init h1940_init(void)
gpio_request(H1940_LATCH_SD_POWER, "SD power");
gpio_direction_output(H1940_LATCH_SD_POWER, 0);
+ pwm_add_table(h1940_pwm_lookup, ARRAY_SIZE(h1940_pwm_lookup));
platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
gpio_request(S3C2410_GPA(1), "Red LED blink");
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 1d35ff3..774c982 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -375,6 +375,11 @@ static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
};
+static struct pwm_lookup rx1950_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight.0", NULL, 48000,
+ PWM_POLARITY_NORMAL),
+};
+
static struct pwm_device *lcd_pwm;
static void rx1950_lcd_power(int enable)
@@ -520,10 +525,8 @@ static int rx1950_backlight_notify(struct device *dev, int 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,
@@ -792,6 +795,7 @@ static void __init rx1950_init_machine(void)
gpio_direction_output(S3C2410_GPA(4), 0);
gpio_direction_output(S3C2410_GPJ(6), 0);
+ pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup));
platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
i2c_register_board_info(0, rx1950_i2c_devices,
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
index a19460e..b355fca 100644
--- a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
@@ -20,7 +20,7 @@
#include <plat/cpu.h>
#include <plat/cpu-freq-core.h>
-static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_12[] = {
{ .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 */
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
index 1191b29..be9a248 100644
--- a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
@@ -20,7 +20,7 @@
#include <plat/cpu.h>
#include <plat/cpu-freq-core.h>
-static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+static struct cpufreq_frequency_table s3c2440_plls_169344[] = {
{ .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 */
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 28c7097..7c0c420 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -2,6 +2,26 @@
# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
#
# Licensed under GPLv2
+menuconfig ARCH_S3C64XX
+ bool "Samsung S3C64XX" if ARCH_MULTI_V6
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKSRC_SAMSUNG_PWM
+ select COMMON_CLK_SAMSUNG
+ select GPIO_SAMSUNG if ATAGS
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_TCM
+ select PLAT_SAMSUNG
+ select PM_GENERIC_DOMAINS if PM
+ select S3C_DEV_NAND if ATAGS
+ select S3C_GPIO_TRACK if ATAGS
+ select SAMSUNG_ATAGS if ATAGS
+ select SAMSUNG_WAKEMASK if PM
+ select SAMSUNG_WDT_RESET
+ help
+ Samsung S3C64XX series based systems
if ARCH_S3C64XX
@@ -90,6 +110,7 @@ config S3C64XX_SETUP_USB_PHY
config MACH_SMDK6400
bool "SMDK6400"
+ depends on ATAGS
select CPU_S3C6400
select S3C64XX_SETUP_SDHCI
select S3C_DEV_HSMMC1
@@ -100,6 +121,7 @@ config MACH_SMDK6400
config MACH_ANW6410
bool "A&W6410"
+ depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_FB
@@ -108,6 +130,7 @@ config MACH_ANW6410
config MACH_MINI6410
bool "MINI6410"
+ depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_SDHCI
@@ -123,6 +146,7 @@ config MACH_MINI6410
config MACH_REAL6410
bool "REAL6410"
+ depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_SDHCI
@@ -138,6 +162,7 @@ config MACH_REAL6410
config MACH_SMDK6410
bool "SMDK6410"
+ depends on ATAGS
select CPU_S3C6410
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select S3C64XX_SETUP_FB_24BPP
@@ -225,6 +250,7 @@ config SMDK6410_WM1192_EV1
config MACH_NCP
bool "NCP"
+ depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_I2C1
select S3C_DEV_HSMMC1
@@ -234,6 +260,7 @@ config MACH_NCP
config MACH_HMT
bool "Airgoo HMT"
+ depends on ATAGS
select CPU_S3C6410
select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_FB
@@ -265,18 +292,21 @@ config MACH_SMARTQ
config MACH_SMARTQ5
bool "SmartQ 5"
+ depends on ATAGS
select MACH_SMARTQ
help
Machine support for the SmartQ 5
config MACH_SMARTQ7
bool "SmartQ 7"
+ depends on ATAGS
select MACH_SMARTQ
help
Machine support for the SmartQ 7
config MACH_WLF_CRAGG_6410
bool "Wolfson Cragganmore 6410"
+ depends on ATAGS
depends on I2C=y
select CPU_S3C6410
select LEDS_GPIO_REGISTER
@@ -310,7 +340,6 @@ config MACH_S3C64XX_DT
select CPU_S3C6410
select PINCTRL
select PINCTRL_S3C64XX
- select USE_OF
help
Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
enabled.
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index bb233f3..256cd5b 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -5,21 +5,25 @@
#
# Licensed under GPLv2
-# Core
-
-obj-y += common.o
-
-# Core support
-
-obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
-obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
+asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include
# PM
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
+obj-$(CONFIG_PM_SLEEP) += sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+ifdef CONFIG_SAMSUNG_ATAGS
+
+obj-$(CONFIG_PM_SLEEP) += irq-pm.o
+
+# Core
+
+obj-y += common.o
+obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+
# DMA support
obj-$(CONFIG_S3C64XX_PL080) += pl080.o
@@ -55,4 +59,6 @@ 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
+endif
+
obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index ddb30b8..7c66ce1a 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -39,6 +39,7 @@
#include <asm/system_misc.h>
#include <mach/map.h>
+#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
@@ -208,7 +209,7 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
static __init int s3c64xx_dev_init(void)
{
/* Not applicable when using DT. */
- if (of_have_populated_dt())
+ if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
subsys_system_register(&s3c64xx_subsys, NULL);
@@ -413,7 +414,7 @@ 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())
+ if (of_have_populated_dt() || !soc_is_s3c64xx())
return -ENODEV;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
index 93aa8cb..5322db5 100644
--- a/arch/arm/mach-s3c64xx/cpuidle.c
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -18,6 +18,7 @@
#include <asm/cpuidle.h>
+#include <plat/cpu.h>
#include <mach/map.h>
#include "regs-sys.h"
@@ -57,6 +58,8 @@ static struct cpuidle_driver s3c64xx_cpuidle_driver = {
static int __init s3c64xx_init_cpuidle(void)
{
- return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+ if (soc_is_s3c64xx())
+ return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+ return 0;
}
device_initcall(s3c64xx_init_cpuidle);
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index ff780a8..b577833 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -54,12 +54,13 @@ static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
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 = {
+static struct s3c_audio_pdata i2s0_pdata = {
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .dma_filter = pl08x_filter_id,
+ .dma_playback = DMACH_I2S0_OUT,
+ .dma_capture = DMACH_I2S0_IN,
};
struct platform_device s3c64xx_device_iis0 = {
@@ -68,15 +69,20 @@ struct platform_device s3c64xx_device_iis0 = {
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
.resource = s3c64xx_iis0_resource,
.dev = {
- .platform_data = &i2sv3_pdata,
+ .platform_data = &i2s0_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),
+};
+
+static struct s3c_audio_pdata i2s1_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .dma_filter = pl08x_filter_id,
+ .dma_playback = DMACH_I2S1_OUT,
+ .dma_capture = DMACH_I2S1_IN,
};
struct platform_device s3c64xx_device_iis1 = {
@@ -85,19 +91,20 @@ struct platform_device s3c64xx_device_iis1 = {
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
.resource = s3c64xx_iis1_resource,
.dev = {
- .platform_data = &i2sv3_pdata,
+ .platform_data = &i2s1_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,
+ .dma_filter = pl08x_filter_id,
+ .dma_playback = DMACH_HSI_I2SV40_TX,
+ .dma_capture = DMACH_HSI_I2SV40_RX,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN,
@@ -142,12 +149,13 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
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,
+ .dma_filter = pl08x_filter_id,
+ .dma_capture = DMACH_PCM0_RX,
+ .dma_playback = DMACH_PCM0_TX,
};
struct platform_device s3c64xx_device_pcm0 = {
@@ -163,12 +171,13 @@ 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,
+ .dma_filter = pl08x_filter_id,
+ .dma_playback = DMACH_PCM1_TX,
+ .dma_capture = DMACH_PCM1_RX,
};
struct platform_device s3c64xx_device_pcm1 = {
@@ -196,13 +205,15 @@ static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
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),
+ [1] = DEFINE_RES_IRQ(IRQ_AC97),
};
-static struct s3c_audio_pdata s3c_ac97_pdata;
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+ .dma_playback = DMACH_AC97_PCMOUT,
+ .dma_filter = pl08x_filter_id,
+ .dma_capture = DMACH_AC97_PCMIN,
+ .dma_capture_mic = DMACH_AC97_MICIN,
+};
static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-s3c64xx/dev-backlight.c b/arch/arm/mach-s3c64xx/dev-backlight.c
index 38c323e..e62e789 100644
--- a/arch/arm/mach-s3c64xx/dev-backlight.c
+++ b/arch/arm/mach-s3c64xx/dev-backlight.c
@@ -69,7 +69,6 @@ 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,
@@ -111,7 +110,6 @@ void __init samsung_bl_set(struct samsung_bl_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)
@@ -120,8 +118,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
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)
diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c
index 46e18d7..a0b4f03 100644
--- a/arch/arm/mach-s3c64xx/dev-uart.c
+++ b/arch/arm/mach-s3c64xx/dev-uart.c
@@ -23,6 +23,7 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
+#include <mach/irqs.h>
#include <plat/devs.h>
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
deleted file mode 100644
index c9b9532..0000000
--- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/* 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
index 096e140..9c739ea 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -14,38 +14,38 @@
#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_UART0 "uart0_tx"
+#define DMACH_UART0_SRC2 "uart0_rx"
+#define DMACH_UART1 "uart1_tx"
+#define DMACH_UART1_SRC2 "uart1_rx"
+#define DMACH_UART2 "uart2_tx"
+#define DMACH_UART2_SRC2 "uart2_rx"
+#define DMACH_UART3 "uart3_tx"
+#define DMACH_UART3_SRC2 "uart3_rx"
+#define DMACH_PCM0_TX "pcm0_tx"
+#define DMACH_PCM0_RX "pcm0_rx"
+#define DMACH_I2S0_OUT "i2s0_tx"
+#define DMACH_I2S0_IN "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")
+#define DMACH_HSI_I2SV40_TX "i2s2_tx"
+#define DMACH_HSI_I2SV40_RX "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_PCM1_TX "pcm1_tx"
+#define DMACH_PCM1_RX "pcm1_rx"
+#define DMACH_I2S1_OUT "i2s1_tx"
+#define DMACH_I2S1_IN "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")
+#define DMACH_AC97_PCMOUT "ac97_out"
+#define DMACH_AC97_PCMIN "ac97_in"
+#define DMACH_AC97_MICIN "ac97_mic"
+#define DMACH_PWM "pwm"
+#define DMACH_IRDA "irda"
+#define DMACH_EXTERNAL "external"
+#define DMACH_SECURITY_RX "sec_rx"
+#define DMACH_SECURITY_TX "sec_tx"
enum dma_ch {
DMACH_MAX = 32
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
index 9c81fac..1d36365 100644
--- a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
@@ -14,6 +14,8 @@
#ifndef GPIO_SAMSUNG_S3C64XX_H
#define GPIO_SAMSUNG_S3C64XX_H
+#ifdef CONFIG_GPIO_SAMSUNG
+
/* GPIO bank sizes */
#define S3C64XX_GPIO_A_NR (8)
#define S3C64XX_GPIO_B_NR (7)
@@ -90,5 +92,6 @@ enum s3c_gpio_number {
/* 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 */
#endif /* GPIO_SAMSUNG_S3C64XX_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
index 67bbd1d..3ceb00b 100644
--- a/arch/arm/mach-s3c64xx/include/mach/irqs.h
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -156,25 +156,11 @@
#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). */
+/* Some boards have their own IRQs behind this */
#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)
+/* Set the default nr_irqs, boards can override if necessary */
+#define S3C64XX_NR_IRQS IRQ_BOARD_START
/* Compatibility */
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
index a30a1e3f..4a285e9 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -16,8 +16,11 @@
#define __MACH_S3C64XX_PM_CORE_H __FILE__
#include <linux/serial_s3c.h>
+#include <linux/delay.h>
#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/map.h>
static inline void s3c_pm_debug_init_uart(void)
{
@@ -56,9 +59,13 @@ 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 */
-
+#ifdef CONFIG_PM_SLEEP
#define s3c_irqwake_eintallow ((1 << 28) - 1)
#define s3c_irqwake_intallow (~0)
+#else
+#define s3c_irqwake_eintallow 0
+#define s3c_irqwake_intallow 0
+#endif
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
index ae4ea76..0bbf1fa 100644
--- a/arch/arm/mach-s3c64xx/irq-pm.c
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -113,7 +113,7 @@ static struct syscore_ops s3c64xx_irq_syscore_ops = {
static __init int s3c64xx_syscore_init(void)
{
/* Appropriate drivers (pinctrl, uart) handle this when using DT. */
- if (of_have_populated_dt())
+ if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
register_syscore_ops(&s3c64xx_irq_syscore_ops);
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index 6224c67..347ce60 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -47,6 +47,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <mach/irqs.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/samsung-time.h>
@@ -229,7 +230,7 @@ static void __init anw6410_machine_init(void)
MACHINE_START(ANW6410, "A&W6410")
/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
.atag_offset = 0x100,
-
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = anw6410_map_io,
.init_machine = anw6410_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index 9c00d83..571f95c 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -29,6 +29,9 @@
#include <linux/platform_data/spi-s3c64xx.h>
+#include <plat/cpu.h>
+#include <mach/irqs.h>
+
#include "crag6410.h"
static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
@@ -399,6 +402,9 @@ static struct i2c_driver wlf_gf_module_driver = {
static int __init wlf_gf_module_register(void)
{
+ if (!soc_is_s3c64xx())
+ return 0;
+
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
index 65c426b..d9d0440 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -25,10 +25,11 @@
#include <linux/mmc/host.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/dm9000.h>
#include <linux/gpio_keys.h>
-#include <linux/basic_mmio_gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/pca953x.h>
@@ -51,6 +52,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
+#include <mach/irqs.h>
#include <plat/fb.h>
#include <plat/sdhci.h>
@@ -108,11 +110,14 @@ static struct s3c2410_uartcfg crag6410_uartcfgs[] __initdata = {
},
};
+static struct pwm_lookup crag6410_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 100000,
+ PWM_POLARITY_NORMAL),
+};
+
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,
};
@@ -809,7 +814,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
-static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+static struct dwc2_hsotg_plat crag6410_hsotg_pdata;
static void __init crag6410_machine_init(void)
{
@@ -835,7 +840,7 @@ static void __init crag6410_machine_init(void)
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);
+ dwc2_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));
@@ -843,6 +848,7 @@ static void __init crag6410_machine_init(void)
samsung_keypad_set_platdata(&crag6410_keypad_data);
s3c64xx_spi0_set_platdata(NULL, 0, 2);
+ pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup));
platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
gpio_led_register_device(-1, &gpio_leds_pdata);
@@ -855,6 +861,7 @@ static void __init crag6410_machine_init(void)
MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
/* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = crag6410_map_io,
.init_machine = crag6410_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index e4b087c..bc7dc1f 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -19,6 +19,7 @@
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/leds.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -30,6 +31,7 @@
#include <video/samsung_fimd.h>
#include <mach/hardware.h>
#include <mach/map.h>
+#include <mach/irqs.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
@@ -73,6 +75,11 @@ static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
},
};
+static struct pwm_lookup hmt_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
+ 1000000000 / (100 * 256 * 20), PWM_POLARITY_NORMAL),
+};
+
static int hmt_bl_init(struct device *dev)
{
int ret;
@@ -110,10 +117,8 @@ static void hmt_bl_exit(struct device *dev)
}
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,
@@ -268,12 +273,14 @@ static void __init hmt_machine_init(void)
gpio_request(S3C64XX_GPF(13), "usb power");
gpio_direction_output(S3C64XX_GPF(13), 1);
+ pwm_add_table(hmt_pwm_lookup, ARRAY_SIZE(hmt_pwm_lookup));
platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
}
MACHINE_START(HMT, "Airgoo-HMT")
/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = hmt_map_io,
.init_machine = hmt_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index ab61af5..ae999fb 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -41,6 +41,7 @@
#include <linux/platform_data/mmc-sdhci-s3c.h>
#include <plat/sdhci.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <mach/irqs.h>
#include <video/platform_lcd.h>
#include <video/samsung_fimd.h>
@@ -233,7 +234,6 @@ static struct platform_device *mini6410_devices[] __initdata = {
&s3c_device_fb,
&mini6410_lcd_powerdev,
&s3c_device_adc,
- &s3c_device_ts,
};
static void __init mini6410_map_io(void)
@@ -332,7 +332,7 @@ static void __init mini6410_machine_init(void)
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);
+ s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
@@ -363,6 +363,7 @@ static void __init mini6410_machine_init(void)
MACHINE_START(MINI6410, "MINI6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = mini6410_map_io,
.init_machine = mini6410_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 80cb144..23baaa0 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -31,6 +31,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/map.h>
@@ -100,6 +101,7 @@ static void __init ncp_machine_init(void)
MACHINE_START(NCP, "NCP")
/* Maintainer: Samsung Electronics */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = ncp_map_io,
.init_machine = ncp_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 85fa959..4e240ff 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -33,6 +33,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
+#include <mach/irqs.h>
#include <plat/adc.h>
#include <plat/cpu.h>
@@ -202,7 +203,6 @@ static struct platform_device *real6410_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_nand,
&s3c_device_adc,
- &s3c_device_ts,
&s3c_device_ohci,
};
@@ -301,7 +301,7 @@ static void __init real6410_machine_init(void)
s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
s3c_nand_set_platdata(&real6410_nand_info);
- s3c24xx_ts_set_platdata(NULL);
+ s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
@@ -331,7 +331,7 @@ static void __init real6410_machine_init(void)
MACHINE_START(REAL6410, "REAL6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
.atag_offset = 0x100,
-
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = real6410_map_io,
.init_machine = real6410_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index b3d1353..936a63f 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -12,8 +12,10 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
@@ -139,6 +141,11 @@ static struct platform_device smartq_usb_otg_vbus_dev = {
.dev.platform_data = &smartq_usb_otg_vbus_pdata,
};
+static struct pwm_lookup smartq_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
+ 1000000000 / (1000 * 20), PWM_POLARITY_NORMAL),
+};
+
static int smartq_bl_init(struct device *dev)
{
s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
@@ -147,10 +154,8 @@ static int smartq_bl_init(struct device *dev)
}
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,
};
@@ -189,7 +194,7 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
},
};
-static struct s3c_hsotg_plat smartq_hsotg_pdata;
+static struct dwc2_hsotg_plat smartq_hsotg_pdata;
static int __init smartq_lcd_setup_gpio(void)
{
@@ -248,7 +253,6 @@ static struct platform_device *smartq_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_rtc,
&samsung_device_pwm,
- &s3c_device_ts,
&s3c_device_usb_hsotg,
&s3c64xx_device_iis0,
&smartq_backlight_device,
@@ -379,14 +383,23 @@ void __init smartq_map_io(void)
smartq_lcd_mode_set();
}
+static struct gpiod_lookup_table smartq_audio_gpios = {
+ .dev_id = "smartq-audio",
+ .table = {
+ GPIO_LOOKUP("GPL", 12, "headphone detect", 0),
+ GPIO_LOOKUP("GPK", 12, "amplifiers shutdown", 0),
+ { },
+ },
+};
+
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
- s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
+ dwc2_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);
+ s3c64xx_ts_set_platdata(&smartq_touchscreen_pdata);
i2c_register_board_info(0, smartq_i2c_devs,
ARRAY_SIZE(smartq_i2c_devs));
@@ -396,5 +409,9 @@ void __init smartq_machine_init(void)
WARN_ON(smartq_usb_host_init());
WARN_ON(smartq_wifi_init());
+ pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
+
+ gpiod_add_lookup_table(&smartq_audio_gpios);
+ platform_device_register_simple("smartq-audio", -1, NULL, 0);
}
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index 33224ab..0972b6c 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -21,6 +21,7 @@
#include <asm/mach/arch.h>
#include <video/samsung_fimd.h>
+#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
@@ -153,6 +154,7 @@ static void __init smartq5_machine_init(void)
MACHINE_START(SMARTQ5, "SmartQ 5")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
.init_machine = smartq5_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index fc7fece..51ac1c6 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -21,6 +21,7 @@
#include <asm/mach/arch.h>
#include <video/samsung_fimd.h>
+#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
@@ -169,6 +170,7 @@ static void __init smartq7_machine_init(void)
MACHINE_START(SMARTQ7, "SmartQ 7")
/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
.atag_offset = 0x100,
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smartq_map_io,
.init_machine = smartq7_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index 6f42512..7d8a74f 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -27,6 +27,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/map.h>
@@ -88,7 +89,7 @@ static void __init smdk6400_machine_init(void)
MACHINE_START(SMDK6400, "SMDK6400")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
.atag_offset = 0x100,
-
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6400_init_irq,
.map_io = smdk6400_map_io,
.init_machine = smdk6400_machine_init,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d590b88..8a894ee 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,6 +30,7 @@
#include <linux/smsc911x.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/platform_data/s3c-hsotg.h>
@@ -51,6 +52,7 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
+#include <mach/irqs.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -288,7 +290,6 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
&s3c_device_rtc,
- &s3c_device_ts,
&s3c_device_wdt,
};
@@ -623,12 +624,16 @@ static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
.func = S3C_GPIO_SFN(2),
};
+static struct pwm_lookup smdk6410_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 78770,
+ PWM_POLARITY_NORMAL),
+};
+
static struct platform_pwm_backlight_data smdk6410_bl_data = {
- .pwm_id = 1,
.enable_gpio = -1,
};
-static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+static struct dwc2_hsotg_plat smdk6410_hsotg_pdata;
static void __init smdk6410_map_io(void)
{
@@ -659,11 +664,11 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
- s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
+ dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
- s3c24xx_ts_set_platdata(NULL);
+ s3c64xx_ts_set_platdata(NULL);
/* configure nCS1 width to 16 bits */
@@ -695,13 +700,14 @@ static void __init smdk6410_machine_init(void)
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+ pwm_add_table(smdk6410_pwm_lookup, ARRAY_SIZE(smdk6410_pwm_lookup));
samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
}
MACHINE_START(SMDK6410, "SMDK6410")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
.atag_offset = 0x100,
-
+ .nr_irqs = S3C64XX_NR_IRQS,
.init_irq = s3c6410_init_irq,
.map_io = smdk6410_map_io,
.init_machine = smdk6410_machine_init,
diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c
index 901a984..89c5a62 100644
--- a/arch/arm/mach-s3c64xx/pl080.c
+++ b/arch/arm/mach-s3c64xx/pl080.c
@@ -14,6 +14,7 @@
#include <linux/amba/pl08x.h>
#include <linux/of.h>
+#include <plat/cpu.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -230,6 +231,9 @@ static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
static int __init s3c64xx_pl080_init(void)
{
+ if (!soc_is_s3c64xx())
+ return 0;
+
/* Set all DMA configuration to be DMA, not SDMA */
writel(0xffffff, S3C64XX_SDMA_SEL);
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 75b14e7..59d91b8 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -22,6 +22,7 @@
#include <mach/map.h>
#include <mach/irqs.h>
+#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/wakeup-mask.h>
@@ -332,6 +333,9 @@ int __init s3c64xx_pm_init(void)
static __init int s3c64xx_pm_initcall(void)
{
+ if (!soc_is_s3c64xx())
+ return 0;
+
pm_cpu_prep = s3c64xx_pm_prepare;
pm_cpu_sleep = s3c64xx_cpu_suspend;
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
index 33273ab..5ea82acc 100644
--- a/arch/arm/mach-s3c64xx/s3c6400.c
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -81,7 +81,7 @@ static struct device s3c6400_dev = {
static int __init s3c6400_core_init(void)
{
/* Not applicable when using DT. */
- if (of_have_populated_dt())
+ if (of_have_populated_dt() || soc_is_s3c64xx())
return 0;
return subsys_system_register(&s3c6400_subsys, NULL);
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
index eadc48d..92bb927 100644
--- a/arch/arm/mach-s3c64xx/s3c6410.c
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -84,7 +84,7 @@ static struct device s3c6410_dev = {
static int __init s3c6410_core_init(void)
{
/* Not applicable when using DT. */
- if (of_have_populated_dt())
+ if (of_have_populated_dt() || !soc_is_s3c64xx())
return 0;
return subsys_system_register(&s3c6410_subsys, NULL);
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 330bfc8..13bc982 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -8,7 +8,8 @@
# Configuration options for the S5PV210/S5PC110
config ARCH_S5PV210
- bool "Samsung S5PV210/S5PC110" if ARCH_MULTI_V7
+ bool "Samsung S5PV210/S5PC110"
+ depends on ARCH_MULTI_V7
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_REQUIRE_GPIOLIB
select ARM_VIC
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h
index 73093dc..a1a041b 100644
--- a/arch/arm/mach-sa1100/include/mach/uncompress.h
+++ b/arch/arm/mach-sa1100/include/mach/uncompress.h
@@ -19,7 +19,7 @@
#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
-static void putc(int c)
+static inline void putc(int c)
{
unsigned long serial_port;
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 41e476e..bb3ca9c 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -15,7 +15,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <mach/hardware.h>
#include <asm/setup.h>
@@ -98,8 +98,8 @@ static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
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);
+ 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)
@@ -369,7 +369,7 @@ static int __init simpad_init(void)
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);
+ ret = gpiochip_add_data(&cs3_gpio, NULL);
if (ret)
printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 926e336..cd5f171 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -1,6 +1,8 @@
config ARCH_SHMOBILE
bool
- select ZONE_DMA if ARM_LPAE
+
+config ARCH_SHMOBILE_MULTI
+ bool
config PM_RCAR
bool
@@ -29,10 +31,11 @@ config ARCH_RMOBILE
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
+menuconfig ARCH_RENESAS
+ bool "Renesas ARM SoCs"
+ depends on ARCH_MULTI_V7 && MMU
select ARCH_SHMOBILE
+ select ARCH_SHMOBILE_MULTI
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select ARM_GIC
@@ -40,8 +43,9 @@ menuconfig ARCH_SHMOBILE_MULTI
select NO_IOPORT_MAP
select PINCTRL
select ARCH_REQUIRE_GPIOLIB
+ select ZONE_DMA if ARM_LPAE
-if ARCH_SHMOBILE_MULTI
+if ARCH_RENESAS
#comment "Renesas ARM SoCs System Type"
@@ -98,76 +102,3 @@ config ARCH_SH73A0
comment "Renesas ARM SoCs System Configuration"
endif
-
-if ARCH_SHMOBILE_LEGACY
-
-comment "Renesas ARM SoCs System Type"
-
-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_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 && I2C
- 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
-
-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
index 476de30..a65c80ac 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
#
# Common objects
-obj-y := timer.o console.o
+obj-y := timer.o
# CPU objects
obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o
@@ -18,12 +18,6 @@ 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_R8A7778) += clock-r8a7778.o
-endif
-
# CPU reset vector handling objects
cpu-y := platsmp.o headsmp.o
@@ -49,11 +43,5 @@ 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
-ifndef CONFIG_ARCH_SHMOBILE_MULTI
-obj-$(CONFIG_MACH_BOCKW) += board-bockw.o
-obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.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
deleted file mode 100644
index a489fe9..0000000
--- a/arch/arm/mach-shmobile/Makefile.boot
+++ /dev/null
@@ -1,12 +0,0 @@
-# per-board load address for uImage
-loadaddr-y :=
-loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
-loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 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-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c
deleted file mode 100644
index 4f78296..0000000
--- a/arch/arm/mach-shmobile/board-bockw-reference.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 *const bockw_boards_compat_dt[] __initconst = {
- "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
deleted file mode 100644
index 25a0e72..0000000
--- a/arch/arm/mach-shmobile/board-bockw.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * 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 *const bockw_boards_compat_dt[] __initconst = {
- "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/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c
deleted file mode 100644
index e8510c3..0000000
--- a/arch/arm/mach-shmobile/clock-r8a7778.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * 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.c b/arch/arm/mach-shmobile/clock.c
deleted file mode 100644
index 68c2d06..0000000
--- a/arch/arm/mach-shmobile/clock.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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
deleted file mode 100644
index cf3552e..0000000
--- a/arch/arm/mach-shmobile/clock.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#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
index 8d27ec5..b3a4ed528 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -1,13 +1,9 @@
#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);
@@ -18,8 +14,6 @@ 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
diff --git a/arch/arm/mach-shmobile/console.c b/arch/arm/mach-shmobile/console.c
deleted file mode 100644
index e329ccb..0000000
--- a/arch/arm/mach-shmobile/console.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S
index fa5248c..5e503d9 100644
--- a/arch/arm/mach-shmobile/headsmp-scu.S
+++ b/arch/arm/mach-shmobile/headsmp-scu.S
@@ -38,9 +38,3 @@ ENTRY(shmobile_boot_scu)
b secondary_startup
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
index 330c1fc..32e0bf6 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -24,7 +24,6 @@
.arm
.align 12
ENTRY(shmobile_boot_vector)
- ldr r0, 2f
ldr r1, 1f
bx r1
@@ -34,9 +33,6 @@ ENDPROC(shmobile_boot_vector)
.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
@@ -46,13 +42,15 @@ shmobile_boot_size:
*/
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
+ and r0, r1, #0xffffff @ MPIDR_HWID_BITMASK
+ @ 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
+ adr r2, 1f
+ ldmia r2, {r5, r6, r7}
+ add r5, r5, r2 @ array of per-cpu mpidr values
+ add r6, r6, r2 @ array of per-cpu functions
+ add r7, r7, r2 @ array of per-cpu arguments
shmobile_smp_boot_find_mpidr:
ldr r8, [r5, r1, lsl #2]
@@ -80,12 +78,18 @@ ENTRY(shmobile_smp_sleep)
b shmobile_smp_boot
ENDPROC(shmobile_smp_sleep)
+ .align 2
+1: .long shmobile_smp_mpidr - .
+ .long shmobile_smp_fn - 1b
+ .long shmobile_smp_arg - 1b
+
+ .bss
.globl shmobile_smp_mpidr
shmobile_smp_mpidr:
-1: .space NR_CPUS * 4
+ .space NR_CPUS * 4
.globl shmobile_smp_fn
shmobile_smp_fn:
-2: .space NR_CPUS * 4
+ .space NR_CPUS * 4
.globl shmobile_smp_arg
shmobile_smp_arg:
-3: .space NR_CPUS * 4
+ .space NR_CPUS * 4
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
deleted file mode 100644
index 5aee83f..0000000
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#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/intc.h b/arch/arm/mach-shmobile/intc.h
deleted file mode 100644
index 40b2ad4..0000000
--- a/arch/arm/mach-shmobile/intc.h
+++ /dev/null
@@ -1,295 +0,0 @@
-#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
deleted file mode 100644
index 3070f6d..0000000
--- a/arch/arm/mach-shmobile/irqs.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
index 4e54512..aba75c8 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -88,7 +88,7 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
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 id;
int k;
int bit, index;
bool is_allowed;
@@ -123,7 +123,6 @@ void __init shmobile_smp_apmu_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;
/* perform per-cpu setup */
apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
@@ -170,7 +169,7 @@ static inline void cpu_enter_lowpower_a15(void)
dsb();
}
-void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
+static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
{
/* Select next sleep mode using the APMU */
diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c
index 6466311..081a097 100644
--- a/arch/arm/mach-shmobile/platsmp-scu.c
+++ b/arch/arm/mach-shmobile/platsmp-scu.c
@@ -17,6 +17,9 @@
#include <asm/smp_scu.h>
#include "common.h"
+
+void __iomem *shmobile_scu_base;
+
static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
@@ -41,7 +44,6 @@ 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);
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index 47a862e..14c42a1b 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -9,20 +9,8 @@
* 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"
@@ -30,17 +18,6 @@
#define SYSCIER 0x0c
#define SYSCIMR 0x10
-struct r8a7779_pm_domain {
- struct generic_pm_domain genpd;
- struct rcar_sysc_ch ch;
-};
-
-static inline
-const 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)
@@ -58,82 +35,6 @@ 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;
-
- 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;
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index a5b96b9..46d0a1d 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -12,6 +12,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
+#include <linux/clk/shmobile.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/of.h>
@@ -124,36 +125,6 @@ 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;
@@ -164,8 +135,8 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
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;
+ genpd->attach_dev = cpg_mstp_attach_dev;
+ genpd->detach_dev = cpg_mstp_detach_dev;
__rmobile_pd_power_up(rmobile_pd, false);
}
@@ -342,8 +313,10 @@ static int __init rmobile_add_pm_domains(void __iomem *base,
}
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
- if (!pd)
+ if (!pd) {
+ of_node_put(np);
return -ENOMEM;
+ }
pd->genpd.name = np->name;
pd->base = base;
diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h
index 30a4a42..8146bb6 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/pm-rmobile.h
@@ -12,10 +12,6 @@
#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;
@@ -26,9 +22,4 @@ struct rmobile_pm_domain {
bool no_debug;
};
-struct pm_domain_device {
- const char *domain_name;
- struct platform_device *pdev;
-};
-
#endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/r8a7778.h b/arch/arm/mach-shmobile/r8a7778.h
deleted file mode 100644
index f64fedb..0000000
--- a/arch/arm/mach-shmobile/r8a7778.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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
index db303f7..2a5f773 100644
--- a/arch/arm/mach-shmobile/r8a7779.h
+++ b/arch/arm/mach-shmobile/r8a7779.h
@@ -1,16 +1,8 @@
#ifndef __ASM_R8A7779_H__
#define __ASM_R8A7779_H__
-#include <linux/sh_clk.h>
-
extern void r8a7779_pm_init(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;
+extern const 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
index 1a46d02..136f345 100644
--- a/arch/arm/mach-shmobile/r8a7790.h
+++ b/arch/arm/mach-shmobile/r8a7790.h
@@ -1,6 +1,6 @@
#ifndef __ASM_R8A7790_H__
#define __ASM_R8A7790_H__
-extern struct smp_operations r8a7790_smp_ops;
+extern const 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
index 7ca0b7d..cf7a840 100644
--- a/arch/arm/mach-shmobile/r8a7791.h
+++ b/arch/arm/mach-shmobile/r8a7791.h
@@ -1,6 +1,6 @@
#ifndef __ASM_R8A7791_H__
#define __ASM_R8A7791_H__
-extern struct smp_operations r8a7791_smp_ops;
+extern const struct smp_operations r8a7791_smp_ops;
#endif /* __ASM_R8A7791_H__ */
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
index 37f7b15..10b7cb5 100644
--- a/arch/arm/mach-shmobile/setup-emev2.c
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -42,7 +42,7 @@ static const char *const emev2_boards_compat_dt[] __initconst = {
NULL,
};
-extern struct smp_operations emev2_smp_ops;
+extern const struct smp_operations emev2_smp_ops;
DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
.smp = smp_ops(emev2_smp_ops),
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c
index b9116c8..fab95d1 100644
--- a/arch/arm/mach-shmobile/setup-r8a7778.c
+++ b/arch/arm/mach-shmobile/setup-r8a7778.c
@@ -16,35 +16,15 @@
*/
#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;
@@ -55,555 +35,21 @@ static void __init r8a7778_timer_init(void)
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)
+
+static 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);
@@ -624,10 +70,6 @@ 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
index 6bfa640..1e572a9 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -97,7 +97,7 @@ static u32 __init r8a7779_read_mode_pins(void)
static void __init r8a7779_init_time(void)
{
r8a7779_clocks_init(r8a7779_read_mode_pins());
- clocksource_of_init();
+ clocksource_probe();
}
static const char *const r8a7779_compat_dt[] __initconst = {
diff --git a/arch/arm/mach-shmobile/setup-r8a7793.c b/arch/arm/mach-shmobile/setup-r8a7793.c
index 1d2825c..5fce87f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7793.c
+++ b/arch/arm/mach-shmobile/setup-r8a7793.c
@@ -19,7 +19,7 @@
#include "common.h"
#include "rcar-gen2.h"
-static const char *r8a7793_boards_compat_dt[] __initconst = {
+static const char * const r8a7793_boards_compat_dt[] __initconst = {
"renesas,r8a7793",
NULL,
};
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index aa33392..9eccde3 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -128,7 +128,7 @@ void __init rcar_gen2_timer_init(void)
#endif /* CONFIG_ARM_ARCH_TIMER */
rcar_gen2_clocks_init(mode);
- clocksource_of_init();
+ clocksource_probe();
}
struct memory_reserve_config {
diff --git a/arch/arm/mach-shmobile/sh-gpio.h b/arch/arm/mach-shmobile/sh-gpio.h
deleted file mode 100644
index 2c41414..0000000
--- a/arch/arm/mach-shmobile/sh-gpio.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
index 3964680..50ef24f 100644
--- a/arch/arm/mach-shmobile/sh73a0.h
+++ b/arch/arm/mach-shmobile/sh73a0.h
@@ -1,6 +1,6 @@
#ifndef __ASM_SH73A0_H__
#define __ASM_SH73A0_H__
-extern struct smp_operations sh73a0_smp_ops;
+extern const 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
index baff3b5..adbac696 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -49,7 +49,7 @@ static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
shmobile_smp_scu_prepare_cpus(max_cpus);
}
-struct smp_operations emev2_smp_ops __initdata = {
+const struct smp_operations emev2_smp_ops __initconst = {
.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
index 353562b8..0b024a9 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -92,8 +92,6 @@ 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);
@@ -117,7 +115,7 @@ static int r8a7779_cpu_kill(unsigned int cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-struct smp_operations r8a7779_smp_ops __initdata = {
+const struct smp_operations r8a7779_smp_ops __initconst = {
.smp_prepare_cpus = r8a7779_smp_prepare_cpus,
.smp_boot_secondary = r8a7779_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c
index 4b33d43..f6426c6 100644
--- a/arch/arm/mach-shmobile/smp-r8a7790.c
+++ b/arch/arm/mach-shmobile/smp-r8a7790.c
@@ -60,7 +60,7 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
rcar_sysc_power_up(&r8a7790_ca7_scu);
}
-struct smp_operations r8a7790_smp_ops __initdata = {
+const struct smp_operations r8a7790_smp_ops __initconst = {
.smp_prepare_cpus = r8a7790_smp_prepare_cpus,
.smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c
index b2508c0..2d6417a 100644
--- a/arch/arm/mach-shmobile/smp-r8a7791.c
+++ b/arch/arm/mach-shmobile/smp-r8a7791.c
@@ -54,7 +54,7 @@ static int r8a7791_smp_boot_secondary(unsigned int cpu,
return shmobile_smp_apmu_boot_secondary(cpu, idle);
}
-struct smp_operations r8a7791_smp_ops __initdata = {
+const struct smp_operations r8a7791_smp_ops __initconst = {
.smp_prepare_cpus = r8a7791_smp_prepare_cpus,
.smp_boot_secondary = r8a7791_smp_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index bc2824a..ee1a4b7 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -56,7 +56,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
shmobile_smp_scu_prepare_cpus(max_cpus);
}
-struct smp_operations sh73a0_smp_ops __initdata = {
+const struct smp_operations sh73a0_smp_ops __initconst = {
.smp_prepare_cpus = sh73a0_smp_prepare_cpus,
.smp_boot_secondary = sh73a0_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index f1d027a..c17d4d3 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -77,24 +77,3 @@ void __init shmobile_init_delay(void)
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
index 90efdeb..d0f62ea 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_SOCFPGA
- bool "Altera SOCFPGA family" if ARCH_MULTI_V7
+ bool "Altera SOCFPGA family"
+ depends on ARCH_MULTI_V7
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
select ARM_GIC
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index b8f9e23..ed15db1 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -5,3 +5,5 @@
obj-y := socfpga.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
obj-$(CONFIG_SOCFPGA_SUSPEND) += pm.o self-refresh.o
+obj-$(CONFIG_EDAC_ALTERA_L2C) += l2_cache.o
+obj-$(CONFIG_EDAC_ALTERA_OCRAM) += ocram.o
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 5bc6ea8..575195b 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -36,6 +36,8 @@
extern void socfpga_init_clocks(void);
extern void socfpga_sysmgr_init(void);
+void socfpga_init_l2_ecc(void);
+void socfpga_init_ocram_ecc(void);
extern void __iomem *sys_manager_base_addr;
extern void __iomem *rst_manager_base_addr;
diff --git a/arch/arm/mach-socfpga/l2_cache.c b/arch/arm/mach-socfpga/l2_cache.c
new file mode 100644
index 0000000..e3907ab
--- /dev/null
+++ b/arch/arm/mach-socfpga/l2_cache.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright Altera Corporation (C) 2016. 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/io.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+void socfpga_init_l2_ecc(void)
+{
+ struct device_node *np;
+ void __iomem *mapped_l2_edac_addr;
+
+ np = of_find_compatible_node(NULL, NULL, "altr,socfpga-l2-ecc");
+ if (!np) {
+ pr_err("Unable to find socfpga-l2-ecc in dtb\n");
+ return;
+ }
+
+ mapped_l2_edac_addr = of_iomap(np, 0);
+ of_node_put(np);
+ if (!mapped_l2_edac_addr) {
+ pr_err("Unable to find L2 ECC mapping in dtb\n");
+ return;
+ }
+
+ /* Enable ECC */
+ writel(0x01, mapped_l2_edac_addr);
+ iounmap(mapped_l2_edac_addr);
+}
diff --git a/arch/arm/mach-socfpga/ocram.c b/arch/arm/mach-socfpga/ocram.c
new file mode 100644
index 0000000..60ec643
--- /dev/null
+++ b/arch/arm/mach-socfpga/ocram.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright Altera Corporation (C) 2016. 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/io.h>
+#include <linux/genalloc.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#define ALTR_OCRAM_CLEAR_ECC 0x00000018
+#define ALTR_OCRAM_ECC_EN 0x00000019
+
+void socfpga_init_ocram_ecc(void)
+{
+ struct device_node *np;
+ void __iomem *mapped_ocr_edac_addr;
+
+ /* Find the OCRAM EDAC device tree node */
+ np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc");
+ if (!np) {
+ pr_err("Unable to find socfpga-ocram-ecc\n");
+ return;
+ }
+
+ mapped_ocr_edac_addr = of_iomap(np, 0);
+ of_node_put(np);
+ if (!mapped_ocr_edac_addr) {
+ pr_err("Unable to map OCRAM ecc regs.\n");
+ return;
+ }
+
+ /* Clear any pending OCRAM ECC interrupts, then enable ECC */
+ writel(ALTR_OCRAM_CLEAR_ECC, mapped_ocr_edac_addr);
+ writel(ALTR_OCRAM_ECC_EN, mapped_ocr_edac_addr);
+
+ iounmap(mapped_ocr_edac_addr);
+}
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 15c8ce8..cbb0a54 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -117,7 +117,7 @@ static int socfpga_cpu_kill(unsigned int cpu)
return 1;
}
-static struct smp_operations socfpga_smp_ops __initdata = {
+static const struct smp_operations socfpga_smp_ops __initconst = {
.smp_prepare_cpus = socfpga_smp_prepare_cpus,
.smp_boot_secondary = socfpga_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static struct smp_operations socfpga_smp_ops __initdata = {
#endif
};
-static struct smp_operations socfpga_a10_smp_ops __initdata = {
+static const struct smp_operations socfpga_a10_smp_ops __initconst = {
.smp_prepare_cpus = socfpga_smp_prepare_cpus,
.smp_boot_secondary = socfpga_a10_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index a1c0efa..7e0aad2 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -59,6 +59,11 @@ static void __init socfpga_init_irq(void)
{
irqchip_init();
socfpga_sysmgr_init();
+ if (IS_ENABLED(CONFIG_EDAC_ALTERA_L2C))
+ socfpga_init_l2_ecc();
+
+ if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
+ socfpga_init_ocram_ecc();
}
static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
index b6f4bda2..ea9ea95 100644
--- a/arch/arm/mach-spear/Kconfig
+++ b/arch/arm/mach-spear/Kconfig
@@ -3,7 +3,8 @@
#
menuconfig PLAT_SPEAR
- bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5
+ bool "ST SPEAr Family"
+ depends on ARCH_MULTI_V7 || ARCH_MULTI_V5
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select CLKSRC_MMIO
diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h
index 0664091..909b97c0 100644
--- a/arch/arm/mach-spear/generic.h
+++ b/arch/arm/mach-spear/generic.h
@@ -39,7 +39,7 @@ 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;
+extern const struct smp_operations spear13xx_smp_ops;
#ifdef CONFIG_MACH_SPEAR1310
void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base);
diff --git a/arch/arm/mach-spear/hotplug.c b/arch/arm/mach-spear/hotplug.c
index d97749c..12edd1c 100644
--- a/arch/arm/mach-spear/hotplug.c
+++ b/arch/arm/mach-spear/hotplug.c
@@ -80,7 +80,7 @@ static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)
*
* Called with IRQs disabled
*/
-void __ref spear13xx_cpu_die(unsigned int cpu)
+void spear13xx_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
index fd42977..8d1e2d5 100644
--- a/arch/arm/mach-spear/platsmp.c
+++ b/arch/arm/mach-spear/platsmp.c
@@ -120,7 +120,7 @@ static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
__raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
}
-struct smp_operations spear13xx_smp_ops __initdata = {
+const struct smp_operations spear13xx_smp_ops __initconst = {
.smp_init_cpus = spear13xx_smp_init_cpus,
.smp_prepare_cpus = spear13xx_smp_prepare_cpus,
.smp_secondary_init = spear13xx_secondary_init,
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index b7afce6..ca2f6a8 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -124,5 +124,5 @@ void __init spear13xx_timer_init(void)
clk_put(pclk);
spear_setup_of_timer();
- clocksource_of_init();
+ clocksource_probe();
}
diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig
index 125865d..a196d14 100644
--- a/arch/arm/mach-sti/Kconfig
+++ b/arch/arm/mach-sti/Kconfig
@@ -1,8 +1,10 @@
menuconfig ARCH_STI
- bool "STMicroelectronics Consumer Electronics SOCs" if ARCH_MULTI_V7
+ bool "STMicroelectronics Consumer Electronics SOCs"
+ depends on ARCH_MULTI_V7
select ARM_GIC
select ST_IRQCHIP
select ARM_GLOBAL_TIMER
+ select CLKSRC_ST_LPC
select PINCTRL
select PINCTRL_ST
select MFD_SYSCON
diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c
index c4ad6ea..ea5a227 100644
--- a/arch/arm/mach-sti/platsmp.c
+++ b/arch/arm/mach-sti/platsmp.c
@@ -156,7 +156,7 @@ static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
}
}
-struct smp_operations __initdata sti_smp_ops = {
+const struct smp_operations sti_smp_ops __initconst = {
.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
index ae22707..d8a2f87 100644
--- a/arch/arm/mach-sti/smp.h
+++ b/arch/arm/mach-sti/smp.h
@@ -12,7 +12,7 @@
#ifndef __MACH_STI_SMP_H
#define __MACH_STI_SMP_H
-extern struct smp_operations sti_smp_ops;
+extern const struct smp_operations sti_smp_ops;
void sti_secondary_startup(void);
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 4efe2d4..c124d65 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_SUNXI
- bool "Allwinner SoCs" if ARCH_MULTI_V7
+ bool "Allwinner SoCs"
+ depends on ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_RESET_CONTROLLER
select CLKSRC_MMIO
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index e8483ec..6642267 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -116,7 +116,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
return 0;
}
-static struct smp_operations sun6i_smp_ops __initdata = {
+static const struct smp_operations sun6i_smp_ops __initconst = {
.smp_prepare_cpus = sun6i_smp_prepare_cpus,
.smp_boot_secondary = sun6i_smp_boot_secondary,
};
@@ -185,7 +185,7 @@ static int sun8i_smp_boot_secondary(unsigned int cpu,
return 0;
}
-struct smp_operations sun8i_smp_ops __initdata = {
+static const struct smp_operations sun8i_smp_ops __initconst = {
.smp_prepare_cpus = sun8i_smp_prepare_cpus,
.smp_boot_secondary = sun8i_smp_boot_secondary,
};
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 65bab28..c2be98f 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -26,10 +26,11 @@ static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
"allwinner,sun5i-a10s",
"allwinner,sun5i-a13",
+ "allwinner,sun5i-r8",
NULL,
};
-DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+DT_MACHINE_START(SUNXI_DT, "Allwinner sun4i/sun5i Families")
.dt_compat = sunxi_board_dt_compat,
.init_late = sunxi_dt_cpufreq_init,
MACHINE_END
@@ -46,7 +47,7 @@ static void __init sun6i_timer_init(void)
of_clk_init(NULL);
if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
sun6i_reset_init();
- clocksource_of_init();
+ clocksource_probe();
}
DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
diff --git a/arch/arm/mach-tango/Kconfig b/arch/arm/mach-tango/Kconfig
new file mode 100644
index 0000000..ebe15b9
--- /dev/null
+++ b/arch/arm/mach-tango/Kconfig
@@ -0,0 +1,13 @@
+config ARCH_TANGO
+ bool "Sigma Designs Tango4 (SMP87xx)"
+ depends on ARCH_MULTI_V7
+ # Cortex-A9 MPCore r3p0, PL310 r3p2
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_ERRATA_775420
+ select ARM_GIC
+ select CLKSRC_TANGO_XTAL
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD
+ select TANGO_IRQ
diff --git a/arch/arm/mach-tango/Makefile b/arch/arm/mach-tango/Makefile
new file mode 100644
index 0000000..f33935e
--- /dev/null
+++ b/arch/arm/mach-tango/Makefile
@@ -0,0 +1,5 @@
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_smc.o := -Wa,-march=armv7-a$(plus_sec)
+
+obj-y += setup.o smc.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c
new file mode 100644
index 0000000..a21f55e
--- /dev/null
+++ b/arch/arm/mach-tango/platsmp.c
@@ -0,0 +1,16 @@
+#include <linux/init.h>
+#include <linux/smp.h>
+#include "smc.h"
+
+static int tango_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ tango_set_aux_boot_addr(virt_to_phys(secondary_startup));
+ tango_start_aux_core(cpu);
+ return 0;
+}
+
+static const struct smp_operations tango_smp_ops __initconst = {
+ .smp_boot_secondary = tango_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango_smp_ops);
diff --git a/arch/arm/mach-tango/setup.c b/arch/arm/mach-tango/setup.c
new file mode 100644
index 0000000..f14b6c7
--- /dev/null
+++ b/arch/arm/mach-tango/setup.c
@@ -0,0 +1,17 @@
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "smc.h"
+
+static void tango_l2c_write(unsigned long val, unsigned int reg)
+{
+ if (reg == L2X0_CTRL)
+ tango_set_l2_control(val);
+}
+
+static const char *const tango_dt_compat[] = { "sigma,tango4", NULL };
+
+DT_MACHINE_START(TANGO_DT, "Sigma Tango DT")
+ .dt_compat = tango_dt_compat,
+ .l2c_aux_mask = ~0,
+ .l2c_write_sec = tango_l2c_write,
+MACHINE_END
diff --git a/arch/arm/mach-tango/smc.S b/arch/arm/mach-tango/smc.S
new file mode 100644
index 0000000..5d932ce
--- /dev/null
+++ b/arch/arm/mach-tango/smc.S
@@ -0,0 +1,9 @@
+#include <linux/linkage.h>
+
+ENTRY(tango_smc)
+ push {lr}
+ mov ip, r1
+ dsb /* This barrier is probably unnecessary */
+ smc #0
+ pop {pc}
+ENDPROC(tango_smc)
diff --git a/arch/arm/mach-tango/smc.h b/arch/arm/mach-tango/smc.h
new file mode 100644
index 0000000..7a4af35
--- /dev/null
+++ b/arch/arm/mach-tango/smc.h
@@ -0,0 +1,5 @@
+extern int tango_smc(unsigned int val, unsigned int service);
+
+#define tango_set_l2_control(val) tango_smc(val, 0x102)
+#define tango_start_aux_core(val) tango_smc(val, 0x104)
+#define tango_set_aux_boot_addr(val) tango_smc((unsigned int)val, 0x105)
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 0fa4c5f..0fa8b84 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_TEGRA
- bool "NVIDIA Tegra" if ARCH_MULTI_V7
+ bool "NVIDIA Tegra"
+ depends on ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
select ARM_AMBA
@@ -12,57 +13,5 @@ menuconfig ARCH_TEGRA
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/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index fbe74c6..52db8bf 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -17,36 +17,39 @@
*
*/
+#include <linux/property.h>
#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 property_entry __initdata wifi_rfkill_prop[] = {
+ PROPERTY_ENTRY_STRING("name", "wifi_rfkill"),
+ PROPERTY_ENTRY_STRING("type", "wlan"),
+ { },
+};
+
+static struct property_set __initdata wifi_rfkill_pset = {
+ .properties = wifi_rfkill_prop,
};
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),
+ GPIO_LOOKUP("tegra-gpio", 25, "reset", 0),
+ GPIO_LOOKUP("tegra-gpio", 85, "shutdown", 0),
{ },
},
};
void __init tegra_paz00_wifikill_init(void)
{
+ platform_device_add_properties(&wifi_rfkill_device, &wifi_rfkill_pset);
gpiod_add_lookup_table(&wifi_gpio_lookup);
platform_device_register(&wifi_rfkill_device);
}
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
index 5900cc4..1f6fb80 100644
--- a/arch/arm/mach-tegra/common.h
+++ b/arch/arm/mach-tegra/common.h
@@ -1,4 +1,4 @@
-extern struct smp_operations tegra_smp_ops;
+extern const 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/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 6fc71f1..1b12989 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -37,7 +37,7 @@ int tegra_cpu_kill(unsigned cpu)
*
* Called with IRQs disabled
*/
-void __ref tegra_cpu_die(unsigned int cpu)
+void tegra_cpu_die(unsigned int cpu)
{
if (!tegra_hotplug_shutdown) {
WARN(1, "hotplug is not yet initialized\n");
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index b450866..f3f61db 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -192,7 +192,7 @@ static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
scu_enable(IO_ADDRESS(scu_a9_get_base()));
}
-struct smp_operations tegra_smp_ops __initdata = {
+const struct smp_operations tegra_smp_ops __initconst = {
.smp_prepare_cpus = tegra_smp_prepare_cpus,
.smp_secondary_init = tegra_secondary_init,
.smp_boot_secondary = tegra_boot_secondary,
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index e6b684e..f5d1966 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -231,8 +231,11 @@ ENDPROC(tegra20_cpu_is_resettable_soon)
* tegra20_tear_down_core in IRAM
*/
ENTRY(tegra20_sleep_core_finish)
+ mov r4, r0
/* Flush, disable the L1 data cache and exit SMP */
+ mov r0, #TEGRA_FLUSH_CACHE_ALL
bl tegra_disable_clean_inv_dcache
+ mov r0, r4
mov32 r3, tegra_shut_off_mmu
add r3, r3, r0
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index 9a2f0b0..16e5ff0 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -242,8 +242,11 @@ ENDPROC(tegra30_cpu_shutdown)
* tegra30_tear_down_core in IRAM
*/
ENTRY(tegra30_sleep_core_finish)
+ mov r4, r0
/* Flush, disable the L1 data cache and exit SMP */
+ mov r0, #TEGRA_FLUSH_CACHE_ALL
bl tegra_disable_clean_inv_dcache
+ mov r0, r4
/*
* Preload all the address literals that are needed for the
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
index bc51a71..301a984 100644
--- a/arch/arm/mach-u300/Kconfig
+++ b/arch/arm/mach-u300/Kconfig
@@ -1,6 +1,6 @@
menuconfig ARCH_U300
- bool "ST-Ericsson U300 Series" if ARCH_MULTI_V5
- depends on MMU
+ bool "ST-Ericsson U300 Series"
+ depends on ARCH_MULTI_V5 && MMU
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 35670b1..546338b 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -408,7 +408,7 @@ static const char * u300_board_compat[] = {
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_time = clocksource_probe,
.init_machine = u300_init_machine_dt,
.restart = u300_restart,
.dt_compat = u300_board_compat,
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
index 1319968..68fe986 100644
--- a/arch/arm/mach-u300/dummyspichip.c
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -264,7 +264,6 @@ static const struct of_device_id pl022_dummy_dt_match[] = {
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,
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
index b640458..82dddee 100644
--- a/arch/arm/mach-uniphier/Kconfig
+++ b/arch/arm/mach-uniphier/Kconfig
@@ -6,6 +6,7 @@ config ARCH_UNIPHIER
select ARM_GIC
select HAVE_ARM_SCU
select HAVE_ARM_TWD if SMP
+ select PINCTRL
help
Support for UniPhier SoC family developed by Socionext Inc.
(formerly, System LSI Business Division of Panasonic Corporation)
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
index 60bd226..1233f9b 100644
--- a/arch/arm/mach-uniphier/Makefile
+++ b/arch/arm/mach-uniphier/Makefile
@@ -1,2 +1,2 @@
obj-y := uniphier.o
-obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-uniphier/headsmp.S b/arch/arm/mach-uniphier/headsmp.S
new file mode 100644
index 0000000..c819dff
--- /dev/null
+++ b/arch/arm/mach-uniphier/headsmp.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/cp15.h>
+
+ENTRY(uniphier_smp_trampoline)
+ARM_BE8(setend be) @ ensure we are in BE8 mode
+ mrc p15, 0, r0, c0, c0, 5 @ MPIDR (Multiprocessor Affinity Reg)
+ and r2, r0, #0x3 @ CPU ID
+ ldr r1, uniphier_smp_trampoline_jump
+ ldr r3, uniphier_smp_trampoline_poll_addr
+ mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register)
+ orr r0, r0, #CR_I @ Enable ICache
+ bic r0, r0, #(CR_C | CR_M) @ Disable MMU and Dcache
+ mcr p15, 0, r0, c1, c0, 0
+ b 1f @ cache the following 5 instructions
+0: wfe
+1: ldr r0, [r3]
+ cmp r0, r2
+ bxeq r1 @ branch to secondary_startup
+ b 0b
+ .globl uniphier_smp_trampoline_jump
+uniphier_smp_trampoline_jump:
+ .word 0 @ set virt_to_phys(secondary_startup)
+ .globl uniphier_smp_trampoline_poll_addr
+uniphier_smp_trampoline_poll_addr:
+ .word 0 @ set CPU ID to be kicked to this reg
+ .globl uniphier_smp_trampoline_end
+uniphier_smp_trampoline_end:
+ENDPROC(uniphier_smp_trampoline)
diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
index 4b784f7..e1cfc1d 100644
--- a/arch/arm/mach-uniphier/platsmp.c
+++ b/arch/arm/mach-uniphier/platsmp.c
@@ -12,73 +12,198 @@
* GNU General Public License for more details.
*/
-#include <linux/sizes.h>
-#include <linux/compiler.h>
+#define pr_fmt(fmt) "uniphier: " fmt
+
#include <linux/init.h>
#include <linux/io.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/sizes.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-uniphier.h>
+#include <asm/pgtable.h>
#include <asm/smp.h>
#include <asm/smp_scu.h>
-static struct regmap *sbcm_regmap;
+/*
+ * The secondary CPUs check this register from the boot ROM for the jump
+ * destination. After that, it can be reused as a scratch register.
+ */
+#define UNIPHIER_SBC_ROM_BOOT_RSV2 0x1208
-static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+static void __iomem *uniphier_smp_rom_boot_rsv2;
+static unsigned int uniphier_smp_max_cpus;
+
+extern char uniphier_smp_trampoline;
+extern char uniphier_smp_trampoline_jump;
+extern char uniphier_smp_trampoline_poll_addr;
+extern char uniphier_smp_trampoline_end;
+
+/*
+ * Copy trampoline code to the tail of the 1st section of the page table used
+ * in the boot ROM. This area is directly accessible by the secondary CPUs
+ * for all the UniPhier SoCs.
+ */
+static const phys_addr_t uniphier_smp_trampoline_dest_end = SECTION_SIZE;
+static phys_addr_t uniphier_smp_trampoline_dest;
+
+static int __init uniphier_smp_copy_trampoline(phys_addr_t poll_addr)
{
- static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
- unsigned long scu_base_phys = 0;
- void __iomem *scu_base;
+ size_t trmp_size;
+ static void __iomem *trmp_base;
- sbcm_regmap = syscon_regmap_lookup_by_compatible(
- "socionext,uniphier-system-bus-controller-misc");
- if (IS_ERR(sbcm_regmap)) {
- pr_err("failed to regmap system-bus-controller-misc\n");
- goto err;
+ if (!uniphier_cache_l2_is_enabled()) {
+ pr_warn("outer cache is needed for SMP, but not enabled\n");
+ return -ENODEV;
}
+ uniphier_cache_l2_set_locked_ways(1);
+
+ outer_flush_all();
+
+ trmp_size = &uniphier_smp_trampoline_end - &uniphier_smp_trampoline;
+ uniphier_smp_trampoline_dest = uniphier_smp_trampoline_dest_end -
+ trmp_size;
+
+ uniphier_cache_l2_touch_range(uniphier_smp_trampoline_dest,
+ uniphier_smp_trampoline_dest_end);
+
+ trmp_base = ioremap_cache(uniphier_smp_trampoline_dest, trmp_size);
+ if (!trmp_base) {
+ pr_err("failed to map trampoline destination area\n");
+ return -ENOMEM;
+ }
+
+ memcpy(trmp_base, &uniphier_smp_trampoline, trmp_size);
+
+ writel(virt_to_phys(secondary_startup),
+ trmp_base + (&uniphier_smp_trampoline_jump -
+ &uniphier_smp_trampoline));
+
+ writel(poll_addr, trmp_base + (&uniphier_smp_trampoline_poll_addr -
+ &uniphier_smp_trampoline));
+
+ flush_cache_all(); /* flush out trampoline code to outer cache */
+
+ iounmap(trmp_base);
+
+ return 0;
+}
+
+static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus)
+{
+ struct device_node *np;
+ struct resource res;
+ phys_addr_t rom_rsv2_phys;
+ int ret;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "socionext,uniphier-system-bus-controller");
+ ret = of_address_to_resource(np, 1, &res);
+ if (ret) {
+ pr_err("failed to get resource of system-bus-controller\n");
+ return ret;
+ }
+
+ rom_rsv2_phys = res.start + UNIPHIER_SBC_ROM_BOOT_RSV2;
+
+ ret = uniphier_smp_copy_trampoline(rom_rsv2_phys);
+ if (ret)
+ return ret;
+
+ uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, sizeof(SZ_4));
+ if (!uniphier_smp_rom_boot_rsv2) {
+ pr_err("failed to map ROM_BOOT_RSV2 register\n");
+ return -ENOMEM;
+ }
+
+ writel(uniphier_smp_trampoline_dest, uniphier_smp_rom_boot_rsv2);
+ asm("sev"); /* Bring up all secondary CPUs to the trampoline code */
+
+ uniphier_smp_max_cpus = max_cpus; /* save for later use */
+
+ return 0;
+}
+
+static void __init uniphier_smp_unprepare_trampoline(void)
+{
+ iounmap(uniphier_smp_rom_boot_rsv2);
+
+ if (uniphier_smp_trampoline_dest)
+ outer_inv_range(uniphier_smp_trampoline_dest,
+ uniphier_smp_trampoline_dest_end);
+
+ uniphier_cache_l2_set_locked_ways(0);
+}
+
+static int __init uniphier_smp_enable_scu(void)
+{
+ unsigned long scu_base_phys = 0;
+ void __iomem *scu_base;
+
if (scu_a9_has_base())
scu_base_phys = scu_a9_get_base();
if (!scu_base_phys) {
pr_err("failed to get scu base\n");
- goto err;
+ return -ENODEV;
}
scu_base = ioremap(scu_base_phys, SZ_128);
if (!scu_base) {
- pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys);
- goto err;
+ pr_err("failed to map scu base\n");
+ return -ENOMEM;
}
scu_enable(scu_base);
iounmap(scu_base);
+ return 0;
+}
+
+static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+{
+ static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+ int ret;
+
+ ret = uniphier_smp_prepare_trampoline(max_cpus);
+ if (ret)
+ goto err;
+
+ ret = uniphier_smp_enable_scu();
+ if (ret)
+ goto err;
+
return;
err:
pr_warn("disabling SMP\n");
init_cpu_present(&only_cpu_0);
- sbcm_regmap = NULL;
+ uniphier_smp_unprepare_trampoline();
}
-static int uniphier_boot_secondary(unsigned int cpu,
- struct task_struct *idle)
+static int __init uniphier_smp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
{
- int ret;
+ if (WARN_ON_ONCE(!uniphier_smp_rom_boot_rsv2))
+ return -EFAULT;
- if (!sbcm_regmap)
- return -ENODEV;
+ writel(cpu, uniphier_smp_rom_boot_rsv2);
+ readl(uniphier_smp_rom_boot_rsv2); /* relax */
- ret = regmap_write(sbcm_regmap, 0x1208,
- virt_to_phys(secondary_startup));
- if (!ret)
- asm("sev"); /* wake up secondary CPU */
+ asm("sev"); /* wake up secondary CPUs sleeping in the trampoline */
+
+ if (cpu == uniphier_smp_max_cpus - 1) {
+ /* clean up resources if this is the last CPU */
+ uniphier_smp_unprepare_trampoline();
+ }
- return ret;
+ return 0;
}
-struct smp_operations uniphier_smp_ops __initdata = {
+static const struct smp_operations uniphier_smp_ops __initconst = {
.smp_prepare_cpus = uniphier_smp_prepare_cpus,
- .smp_boot_secondary = uniphier_boot_secondary,
+ .smp_boot_secondary = uniphier_smp_boot_secondary,
};
CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp",
&uniphier_smp_ops);
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index c9ac19b..3185081 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -1,6 +1,6 @@
menuconfig ARCH_U8500
- bool "ST-Ericsson U8500 Series" if ARCH_MULTI_V7
- depends on MMU
+ bool "ST-Ericsson U8500 Series"
+ depends on ARCH_MULTI_V7 && MMU
select AB8500_CORE
select ABX500_CORE
select ARCH_REQUIRE_GPIOLIB
@@ -32,6 +32,7 @@ config UX500_SOC_DB8500
select PINCTRL_AB8540
select REGULATOR
select REGULATOR_DB8500_PRCMU
+ select CLKSRC_DBX500_PRCMU
select PM_GENERIC_DOMAINS if PM
config MACH_MOP500
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index c8643ac..edfff1a 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel, U8500 machine.
#
-obj-y := cpu.o id.o timer.o pm.o
+obj-y := cpu.o id.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 \
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index f805603..a0ffaad 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -156,8 +156,6 @@ static const char * stericsson_dt_platform_compat[] = {
DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
.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,
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 41b81c4..82156cb 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -9,7 +9,6 @@
#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>
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index 2bc00b0..1cbed03 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -21,7 +21,7 @@
*
* Called with IRQs disabled
*/
-void __ref ux500_cpu_die(unsigned int cpu)
+void ux500_cpu_die(unsigned int cpu)
{
/* directly enter low power state, skipping secure registers */
for (;;) {
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 70766b96..88b8ab4 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -98,7 +98,7 @@ static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
-struct smp_operations ux500_smp_ops __initdata = {
+static const struct smp_operations ux500_smp_ops __initconst = {
.smp_prepare_cpus = ux500_smp_prepare_cpus,
.smp_boot_secondary = ux500_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h
index 65876ea..c704254 100644
--- a/arch/arm/mach-ux500/setup.h
+++ b/arch/arm/mach-ux500/setup.h
@@ -12,7 +12,6 @@
#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>
@@ -24,8 +23,6 @@ extern void __init ux500_init_irq(void);
extern struct device *ux500_soc_device_init(const char *soc_id);
-extern void ux500_timer_init(void);
-
extern void ux500_cpu_die(unsigned int cpu);
#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
deleted file mode 100644
index ff28d8a..0000000
--- a/arch/arm/mach-ux500/timer.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
index 1dba368..e40f777 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -1,33 +1,16 @@
-menu "Versatile platform type"
- depends on ARCH_VERSATILE
-
-config ARCH_VERSATILE_PB
- bool "Support Versatile Platform Baseboard for ARM926EJ-S"
- default y
+config ARCH_VERSATILE
+ bool "ARM Ltd. Versatile family"
+ depends on ARCH_MULTI_V5
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select ARM_VIC
+ select CLKSRC_VERSATILE
+ select COMMON_CLK_VERSATILE
select CPU_ARM926T
+ select ICST
select MIGHT_HAVE_PCI
+ select PLAT_VERSATILE
+ select VERSATILE_FPGA_IRQ
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
+ This enables support for ARM Ltd Versatile board.
-endmenu
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
index 81fa3fe..41b124b 100644
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -2,8 +2,4 @@
# 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
+obj-y := versatile_dt.o
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
deleted file mode 100644
index ff0a4b5..0000000
--- a/arch/arm/mach-versatile/Makefile.boot
+++ /dev/null
@@ -1,4 +0,0 @@
- 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
deleted file mode 100644
index 23a04fe..0000000
--- a/arch/arm/mach-versatile/core.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * 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 <clocksource/timer-sp804.h>
-
-#include <asm/irq.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 <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)
- */
- sp804_timer_disable(TIMER0_VA_BASE);
- sp804_timer_disable(TIMER1_VA_BASE);
- sp804_timer_disable(TIMER2_VA_BASE);
- sp804_timer_disable(TIMER3_VA_BASE);
-
- 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
deleted file mode 100644
index f06d576..0000000
--- a/arch/arm/mach-versatile/core.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e58d077..0000000
--- a/arch/arm/mach-versatile/include/mach/clkdev.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#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
deleted file mode 100644
index 3e5d425..0000000
--- a/arch/arm/mach-versatile/include/mach/hardware.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0fd771c..0000000
--- a/arch/arm/mach-versatile/include/mach/irqs.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6f938cc..0000000
--- a/arch/arm/mach-versatile/include/mach/platform.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 986e3d3..0000000
--- a/arch/arm/mach-versatile/include/mach/uncompress.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c97be4e..0000000
--- a/arch/arm/mach-versatile/pci.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1caef10..0000000
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
index 7de3e92..c448718 100644
--- a/arch/arm/mach-versatile/versatile_dt.c
+++ b/arch/arm/mach-versatile/versatile_dt.c
@@ -22,15 +22,389 @@
*/
#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/platform_data/video-clcd-versatile.h>
+#include <linux/amba/mmci.h>
+#include <linux/mtd/physmap.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
-#include "core.h"
+/* 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))
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_FLASH_BASE 0x34000000
+#define VERSATILE_FLASH_SIZE SZ_64M
+
+/*
+ * ------------------------------------------------------------------------
+ * Versatile Registers
+ * ------------------------------------------------------------------------
+ */
+#define VERSATILE_SYS_LOCK_OFFSET 0x20
+#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
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_MMCI0_BASE 0x10005000 /* MMC interface */
+#define VERSATILE_MMCI1_BASE 0x1000B000 /* MMC Interface */
+#define VERSATILE_CLCD_BASE 0x10120000 /* CLCD */
+#define VERSATILE_SCTL_BASE 0x101E0000 /* System controller */
+#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */
+#define VERSATILE_IB2_CTL_BASE (VERSATILE_IB2_BASE + 0x03000000)
+
+/*
+ * 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
+
+static void __iomem *versatile_sys_base;
+static void __iomem *versatile_ib2_ctrl;
+
+static void versatile_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ u32 val;
+
+ val = readl(versatile_sys_base + VERSATILE_SYS_FLASH_OFFSET);
+ if (on)
+ val |= VERSATILE_FLASHPROG_FLVPPEN;
+ else
+ val &= ~VERSATILE_FLASHPROG_FLVPPEN;
+ writel(val, versatile_sys_base + VERSATILE_SYS_FLASH_OFFSET);
+}
+
+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,
+};
+
+struct platform_device versatile_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &versatile_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &versatile_flash_resource,
+};
+
+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_sys_base + VERSATILE_SYS_MCI_OFFSET) & 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 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,
+};
+
+/*
+ * 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 = versatile_sys_base + VERSATILE_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+
+ /*
+ * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
+ */
+ if (of_machine_is_compatible("arm,versatile-ab") && is_sanyo_2_5_lcd) {
+ unsigned long ctrl;
+
+ ctrl = readl(versatile_ib2_ctrl);
+ ctrl &= ~0x01;
+ writel(ctrl, versatile_ib2_ctrl);
+ }
+}
+
+/*
+ * 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 = 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);
+
+ /*
+ * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
+ */
+ if (of_machine_is_compatible("arm,versatile-ab") && is_sanyo_2_5_lcd) {
+ unsigned long ctrl;
+
+ ctrl = readl(versatile_ib2_ctrl);
+ ctrl |= 0x01;
+ writel(ctrl, versatile_ib2_ctrl);
+ }
+}
+
+/*
+ * 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 = 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,
+};
+
+/*
+ * 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_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
+ OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data),
+ {}
+};
+
+static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
+ {
+ .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE),
+ .length = SZ_4K * 9,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init versatile_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
+}
+
+static void __init versatile_init_early(void)
+{
+ u32 val;
+
+ /*
+ * set clock frequency:
+ * VERSATILE_REFCLK is 32KHz
+ * VERSATILE_TIMCLK is 1MHz
+ */
+ val = readl(__io_address(VERSATILE_SCTL_BASE));
+ writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+ __io_address(VERSATILE_SCTL_BASE));
+}
+
+static void versatile_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 val;
+
+ val = readl(versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET);
+ val |= 0x105;
+
+ writel(0xa05f, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET);
+ writel(val, versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET);
+ writel(0, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET);
+}
+
+static void __init versatile_dt_pci_init(void)
+{
+ u32 val;
+ struct device_node *np;
+ struct property *newprop;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
+ if (!np)
+ return;
+
+ /* Check if PCI backplane is detected */
+ val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+ if (val & 1) {
+ /*
+ * Enable PCI accesses. Note that the documentaton is
+ * inconsistent whether or not this is needed, but the old
+ * driver had it so we will keep it.
+ */
+ writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+ return;
+ }
+
+ newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
+ if (!newprop)
+ return;
+
+ newprop->name = kstrdup("status", GFP_KERNEL);
+ newprop->value = kstrdup("disabled", GFP_KERNEL);
+ newprop->length = sizeof("disabled");
+ of_update_property(np, newprop);
+
+ pr_info("Not plugged into PCI backplane!\n");
+}
static void __init versatile_dt_init(void)
{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
+ if (np)
+ versatile_sys_base = of_iomap(np, 0);
+ WARN_ON(!versatile_sys_base);
+
+ versatile_ib2_ctrl = ioremap(VERSATILE_IB2_CTL_BASE, SZ_4K);
+
+ versatile_dt_pci_init();
+
+ platform_device_register(&versatile_flash_device);
of_platform_populate(NULL, of_default_bus_match_table,
versatile_auxdata_lookup, NULL);
}
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
deleted file mode 100644
index 9a53d0bd..0000000
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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
index 10f9389..398a297 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_VEXPRESS
- bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
+ bool "ARM Ltd. Versatile Express family"
+ depends on ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 2a11d3a..a162ab4 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -1,5 +1,5 @@
bool vexpress_smp_init_ops(void);
-extern struct smp_operations vexpress_smp_dt_ops;
+extern const struct smp_operations vexpress_smp_dt_ops;
extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index f0ce6b8..f2fafc1 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -85,7 +85,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
*
* Called with IRQs disabled
*/
-void __ref vexpress_cpu_die(unsigned int cpu)
+void vexpress_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 83188cf..8b8d072 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -64,7 +64,7 @@ static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
}
-struct smp_operations __initdata vexpress_smp_dt_ops = {
+const struct smp_operations vexpress_smp_dt_ops __initconst = {
.smp_prepare_cpus = vexpress_smp_dt_prepare_cpus,
.smp_secondary_init = versatile_secondary_init,
.smp_boot_secondary = versatile_boot_secondary,
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c
index 213230ee..ca76325 100644
--- a/arch/arm/mach-w90x900/cpu.c
+++ b/arch/arm/mach-w90x900/cpu.c
@@ -33,8 +33,8 @@
#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 "regs-ebi.h"
+#include "regs-timer.h"
#include "cpu.h"
#include "clock.h"
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
index ba05aec..55d1a00 100644
--- a/arch/arm/mach-w90x900/gpio.c
+++ b/arch/arm/mach-w90x900/gpio.c
@@ -20,7 +20,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <mach/hardware.h>
@@ -30,7 +30,6 @@
#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) \
{ \
@@ -53,7 +52,7 @@ struct nuc900_gpio_chip {
static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
unsigned int regval;
@@ -65,7 +64,7 @@ static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
{
- struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
unsigned int regval;
unsigned long flags;
@@ -86,7 +85,7 @@ static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
{
- struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
unsigned int regval;
unsigned long flags;
@@ -104,7 +103,7 @@ static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
{
- struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
unsigned int regval;
@@ -149,6 +148,6 @@ void __init nuc900_init_gpio(int nr_group)
gpio_chip = &nuc900_gpio[i];
spin_lock_init(&gpio_chip->gpio_lock);
gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
- gpiochip_add(&gpio_chip->chip);
+ gpiochip_add_data(&gpio_chip->chip, gpio_chip);
}
}
diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h
index 4b7c324..3855ece 100644
--- a/arch/arm/mach-w90x900/include/mach/uncompress.h
+++ b/arch/arm/mach-w90x900/include/mach/uncompress.h
@@ -27,7 +27,7 @@
#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
static volatile u32 * const uart_base = (u32 *)UART0_PA;
-static void putc(int ch)
+static inline void putc(int ch)
{
/* Check THRE and TEMT bits before we transmit the character.
*/
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/regs-ebi.h
index b68455e..b68455e 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-ebi.h
+++ b/arch/arm/mach-w90x900/regs-ebi.h
diff --git a/arch/arm/mach-w90x900/include/mach/regs-gcr.h b/arch/arm/mach-w90x900/regs-gcr.h
index 6087abd..6087abd 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-gcr.h
+++ b/arch/arm/mach-w90x900/regs-gcr.h
diff --git a/arch/arm/mach-w90x900/include/mach/regs-timer.h b/arch/arm/mach-w90x900/regs-timer.h
index 8f39062..8f39062 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-timer.h
+++ b/arch/arm/mach-w90x900/regs-timer.h
diff --git a/arch/arm/mach-w90x900/include/mach/regs-usb.h b/arch/arm/mach-w90x900/regs-usb.h
index ab74b0c..ab74b0c 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-usb.h
+++ b/arch/arm/mach-w90x900/regs-usb.h
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index cd1966e..cda0852 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -31,7 +31,7 @@
#include <asm/mach/time.h>
#include <mach/map.h>
-#include <mach/regs-timer.h>
+#include "regs-timer.h"
#include "nuc9xx.h"
diff --git a/arch/arm/mach-zx/Kconfig b/arch/arm/mach-zx/Kconfig
index 7fdc5bf..209c979 100644
--- a/arch/arm/mach-zx/Kconfig
+++ b/arch/arm/mach-zx/Kconfig
@@ -1,5 +1,6 @@
menuconfig ARCH_ZX
- bool "ZTE ZX family" if ARCH_MULTI_V7
+ bool "ZTE ZX family"
+ depends on ARCH_MULTI_V7
help
Support for ZTE ZX-based family of processors. TV
set-top-box processor is supported. More will be
@@ -13,7 +14,7 @@ config SOC_ZX296702
select ARM_GLOBAL_TIMER
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
- select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS if PM
help
Support for ZTE ZX296702 SoC which is a dual core CortexA9MP
endif
diff --git a/arch/arm/mach-zx/platsmp.c b/arch/arm/mach-zx/platsmp.c
index a369398..0297f92 100644
--- a/arch/arm/mach-zx/platsmp.c
+++ b/arch/arm/mach-zx/platsmp.c
@@ -176,7 +176,7 @@ static void zx_secondary_init(unsigned int cpu)
scu_power_mode(scu_base, SCU_PM_NORMAL);
}
-struct smp_operations zx_smp_ops __initdata = {
+static const struct smp_operations zx_smp_ops __initconst = {
.smp_prepare_cpus = zx_smp_prepare_cpus,
.smp_secondary_init = zx_secondary_init,
.smp_boot_secondary = zx_boot_secondary,
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index 78e5e00..fd0aeeb 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -1,5 +1,7 @@
config ARCH_ZYNQ
- bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
+ bool "Xilinx Zynq ARM Cortex A9 Platform"
+ depends on ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
select ARM_GIC
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 5a6e4e2..6f39d03 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -154,7 +154,7 @@ static void __init zynq_timer_init(void)
zynq_clock_init();
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
}
static struct map_desc zynq_cortex_a9_scu_map __initdata = {
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
index 79cda2e..e771933 100644
--- a/arch/arm/mach-zynq/common.h
+++ b/arch/arm/mach-zynq/common.h
@@ -30,7 +30,7 @@ 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;
+extern const struct smp_operations zynq_smp_ops;
#endif
extern void __iomem *zynq_scu_base;
diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
index f66816c..7cd9865 100644
--- a/arch/arm/mach-zynq/platsmp.c
+++ b/arch/arm/mach-zynq/platsmp.c
@@ -157,7 +157,7 @@ static void zynq_cpu_die(unsigned int cpu)
}
#endif
-struct smp_operations zynq_smp_ops __initdata = {
+const struct smp_operations zynq_smp_ops __initconst = {
.smp_init_cpus = zynq_smp_init_cpus,
.smp_prepare_cpus = zynq_smp_prepare_cpus,
.smp_boot_secondary = zynq_boot_secondary,
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index df7537f..5534766 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -21,7 +21,7 @@ config CPU_ARM7TDMI
# ARM720T
config CPU_ARM720T
- bool "Support ARM720T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ bool
select CPU_32v4T
select CPU_ABRT_LV4T
select CPU_CACHE_V4
@@ -39,7 +39,7 @@ config CPU_ARM720T
# ARM740T
config CPU_ARM740T
- bool "Support ARM740T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ bool
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
@@ -71,7 +71,7 @@ config CPU_ARM9TDMI
# ARM920T
config CPU_ARM920T
- bool "Support ARM920T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ bool
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
@@ -89,7 +89,7 @@ config CPU_ARM920T
# ARM922T
config CPU_ARM922T
- bool "Support ARM922T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ bool
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
@@ -108,7 +108,7 @@ config CPU_ARM922T
# ARM925T
config CPU_ARM925T
- bool "Support ARM925T processor" if ARCH_OMAP1
+ bool
select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
@@ -127,7 +127,7 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
- bool "Support ARM926T processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V5) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB)
+ bool
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
@@ -163,7 +163,7 @@ config CPU_FA526
# ARM940T
config CPU_ARM940T
- bool "Support ARM940T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
+ bool
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
@@ -181,7 +181,7 @@ config CPU_ARM940T
# ARM946E-S
config CPU_ARM946E
- bool "Support ARM946E-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ bool
depends on !MMU
select CPU_32v5
select CPU_ABRT_NOMMU
@@ -198,7 +198,7 @@ config CPU_ARM946E
# ARM1020 - needs validating
config CPU_ARM1020
- bool "Support ARM1020T (rev 0) processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ bool
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
@@ -216,7 +216,7 @@ config CPU_ARM1020
# ARM1020E - needs validating
config CPU_ARM1020E
- bool "Support ARM1020E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ bool
depends on n
select CPU_32v5
select CPU_ABRT_EV4T
@@ -229,7 +229,7 @@ config CPU_ARM1020E
# ARM1022E
config CPU_ARM1022
- bool "Support ARM1022E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ bool
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_CACHE_VIVT
@@ -247,7 +247,7 @@ config CPU_ARM1022
# ARM1026EJ-S
config CPU_ARM1026
- bool "Support ARM1026EJ-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
+ bool
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
select CPU_CACHE_VIVT
@@ -358,7 +358,7 @@ config CPU_PJ4B
# ARMv6
config CPU_V6
- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ bool
select CPU_32v6
select CPU_ABRT_EV6
select CPU_CACHE_V6
@@ -371,7 +371,7 @@ config CPU_V6
# ARMv6k
config CPU_V6K
- bool "Support ARM V6K processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ bool
select CPU_32v6
select CPU_32v6K
select CPU_ABRT_EV6
@@ -385,7 +385,7 @@ config CPU_V6K
# ARMv7
config CPU_V7
- bool "Support ARM V7 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V7) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
+ bool
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
@@ -419,28 +419,24 @@ config CPU_THUMBONLY
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
@@ -805,14 +801,6 @@ config TLS_REG_EMUL
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
@@ -986,6 +974,16 @@ config CACHE_TAUROS2
This option enables the Tauros2 L2 cache controller (as
found on PJ1/PJ4).
+config CACHE_UNIPHIER
+ bool "Enable the UniPhier outer cache controller"
+ depends on ARCH_UNIPHIER
+ default y
+ select OUTER_CACHE
+ select OUTER_CACHE_SYNC
+ help
+ This option enables the UniPhier outer cache (system cache)
+ controller.
+
config CACHE_XSC3L2
bool "Enable the L2 cache on XScale3"
depends on CPU_XSC3
@@ -1007,8 +1005,6 @@ config ARM_L1_CACHE_SHIFT
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
@@ -1041,24 +1037,26 @@ config ARCH_SUPPORTS_BIG_ENDIAN
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
+ depends on MMU && !XIP_KERNEL
+ default y if CPU_V7
+ help
+ If this is set, kernel text and rodata memory will be made
+ read-only, and non-text kernel memory 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), which
+ can waste memory.
+
+config DEBUG_ALIGN_RODATA
+ bool "Make rodata strictly non-executable"
+ depends on DEBUG_RODATA
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.
+ If this is set, rodata will be made explicitly non-executable. This
+ provides protection on the rare chance that attackers might find and
+ use ROP gadgets that exist in the rodata section. This adds an
+ additional section-aligned split of rodata from kernel text so it
+ can be made explicitly non-executable. This padding may waste memory
+ space to gain the additional protection.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 57c8df5..7f76d96 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -103,3 +103,4 @@ 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
+obj-$(CONFIG_CACHE_UNIPHIER) += cache-uniphier.o
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 00b7f7d..7d5f4c7 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -803,7 +803,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
}
}
} else {
- fault = probe_kernel_address(instrptr, instr);
+ fault = probe_kernel_address((void *)instrptr, instr);
instr = __mem_to_opcode_arm(instr);
}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 493692d..9f9d542 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -790,7 +790,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
};
static int __init __l2c_init(const struct l2c_init_data *data,
- u32 aux_val, u32 aux_mask, u32 cache_id)
+ u32 aux_val, u32 aux_mask, u32 cache_id, bool nosync)
{
struct outer_cache_fns fns;
unsigned way_size_bits, ways;
@@ -866,6 +866,10 @@ static int __init __l2c_init(const struct l2c_init_data *data,
fns.configure = outer_cache.configure;
if (data->fixup)
data->fixup(l2x0_base, cache_id, &fns);
+ if (nosync) {
+ pr_info("L2C: disabling outer sync\n");
+ fns.sync = NULL;
+ }
/*
* Check if l2x0 controller is already enabled. If we are booting
@@ -925,7 +929,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
if (data->save)
data->save(l2x0_base);
- __l2c_init(data, aux_val, aux_mask, cache_id);
+ __l2c_init(data, aux_val, aux_mask, cache_id, false);
}
#ifdef CONFIG_OF
@@ -1060,6 +1064,18 @@ static void __init l2x0_of_parse(const struct device_node *np,
val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
}
+ if (of_property_read_bool(np, "arm,parity-enable")) {
+ mask &= ~L2C_AUX_CTRL_PARITY_ENABLE;
+ val |= L2C_AUX_CTRL_PARITY_ENABLE;
+ } else if (of_property_read_bool(np, "arm,parity-disable")) {
+ mask &= ~L2C_AUX_CTRL_PARITY_ENABLE;
+ }
+
+ if (of_property_read_bool(np, "arm,shared-override")) {
+ mask &= ~L2C_AUX_CTRL_SHARED_OVERRIDE;
+ val |= L2C_AUX_CTRL_SHARED_OVERRIDE;
+ }
+
ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_256K);
if (ret)
return;
@@ -1176,6 +1192,14 @@ static void __init l2c310_of_parse(const struct device_node *np,
*aux_mask &= ~L2C_AUX_CTRL_SHARED_OVERRIDE;
}
+ if (of_property_read_bool(np, "arm,parity-enable")) {
+ *aux_val |= L2C_AUX_CTRL_PARITY_ENABLE;
+ *aux_mask &= ~L2C_AUX_CTRL_PARITY_ENABLE;
+ } else if (of_property_read_bool(np, "arm,parity-disable")) {
+ *aux_val &= ~L2C_AUX_CTRL_PARITY_ENABLE;
+ *aux_mask &= ~L2C_AUX_CTRL_PARITY_ENABLE;
+ }
+
prefetch = l2x0_saved_regs.prefetch_ctrl;
ret = of_property_read_u32(np, "arm,double-linefill", &val);
@@ -1704,6 +1728,7 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
struct resource res;
u32 cache_id, old_aux;
u32 cache_level = 2;
+ bool nosync = false;
np = of_find_matching_node(NULL, l2x0_ids);
if (!np)
@@ -1742,6 +1767,8 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
if (cache_level != 2)
pr_err("L2C: device tree specifies invalid cache level\n");
+ nosync = of_property_read_bool(np, "arm,outer-sync-disable");
+
/* Read back current (default) hardware configuration */
if (data->save)
data->save(l2x0_base);
@@ -1756,6 +1783,6 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
else
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
- return __l2c_init(data, aux_val, aux_mask, cache_id);
+ return __l2c_init(data, aux_val, aux_mask, cache_id, nosync);
}
#endif
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
index 1e373d2..88255be 100644
--- a/arch/arm/mm/cache-tauros2.c
+++ b/arch/arm/mm/cache-tauros2.c
@@ -22,6 +22,11 @@
#include <asm/cputype.h>
#include <asm/hardware/cache-tauros2.h>
+/* CP15 PJ4 Control configuration register */
+#define CCR_L2C_PREFETCH_DISABLE BIT(24)
+#define CCR_L2C_ECC_ENABLE BIT(23)
+#define CCR_L2C_WAY7_4_DISABLE BIT(21)
+#define CCR_L2C_BURST8_ENABLE BIT(20)
/*
* When Tauros2 is used on a CPU that supports the v7 hierarchical
@@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features)
u = read_extra_features();
if (features & CACHE_TAUROS2_PREFETCH_ON)
- u &= ~0x01000000;
+ u &= ~CCR_L2C_PREFETCH_DISABLE;
else
- u |= 0x01000000;
+ u |= CCR_L2C_PREFETCH_DISABLE;
pr_info("Tauros2: %s L2 prefetch.\n",
(features & CACHE_TAUROS2_PREFETCH_ON)
? "Enabling" : "Disabling");
if (features & CACHE_TAUROS2_LINEFILL_BURST8)
- u |= 0x00100000;
+ u |= CCR_L2C_BURST8_ENABLE;
else
- u &= ~0x00100000;
- pr_info("Tauros2: %s line fill burt8.\n",
+ u &= ~CCR_L2C_BURST8_ENABLE;
+ pr_info("Tauros2: %s burst8 line fill.\n",
(features & CACHE_TAUROS2_LINEFILL_BURST8)
? "Enabling" : "Disabling");
@@ -287,16 +292,15 @@ void __init tauros2_init(unsigned int features)
node = of_find_matching_node(NULL, tauros2_ids);
if (!node) {
pr_info("Not found marvell,tauros2-cache, disable it\n");
- return;
+ } else {
+ 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;
}
-
- 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-uniphier.c b/arch/arm/mm/cache-uniphier.c
new file mode 100644
index 0000000..a6fa7b7
--- /dev/null
+++ b/arch/arm/mm/cache-uniphier.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "uniphier: " fmt
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <asm/hardware/cache-uniphier.h>
+#include <asm/outercache.h>
+
+/* control registers */
+#define UNIPHIER_SSCC 0x0 /* Control Register */
+#define UNIPHIER_SSCC_BST BIT(20) /* UCWG burst read */
+#define UNIPHIER_SSCC_ACT BIT(19) /* Inst-Data separate */
+#define UNIPHIER_SSCC_WTG BIT(18) /* WT gathering on */
+#define UNIPHIER_SSCC_PRD BIT(17) /* enable pre-fetch */
+#define UNIPHIER_SSCC_ON BIT(0) /* enable cache */
+#define UNIPHIER_SSCLPDAWCR 0x30 /* Unified/Data Active Way Control */
+#define UNIPHIER_SSCLPIAWCR 0x34 /* Instruction Active Way Control */
+
+/* revision registers */
+#define UNIPHIER_SSCID 0x0 /* ID Register */
+
+/* operation registers */
+#define UNIPHIER_SSCOPE 0x244 /* Cache Operation Primitive Entry */
+#define UNIPHIER_SSCOPE_CM_INV 0x0 /* invalidate */
+#define UNIPHIER_SSCOPE_CM_CLEAN 0x1 /* clean */
+#define UNIPHIER_SSCOPE_CM_FLUSH 0x2 /* flush */
+#define UNIPHIER_SSCOPE_CM_SYNC 0x8 /* sync (drain bufs) */
+#define UNIPHIER_SSCOPE_CM_FLUSH_PREFETCH 0x9 /* flush p-fetch buf */
+#define UNIPHIER_SSCOQM 0x248 /* Cache Operation Queue Mode */
+#define UNIPHIER_SSCOQM_TID_MASK (0x3 << 21)
+#define UNIPHIER_SSCOQM_TID_LRU_DATA (0x0 << 21)
+#define UNIPHIER_SSCOQM_TID_LRU_INST (0x1 << 21)
+#define UNIPHIER_SSCOQM_TID_WAY (0x2 << 21)
+#define UNIPHIER_SSCOQM_S_MASK (0x3 << 17)
+#define UNIPHIER_SSCOQM_S_RANGE (0x0 << 17)
+#define UNIPHIER_SSCOQM_S_ALL (0x1 << 17)
+#define UNIPHIER_SSCOQM_S_WAY (0x2 << 17)
+#define UNIPHIER_SSCOQM_CE BIT(15) /* notify completion */
+#define UNIPHIER_SSCOQM_CM_INV 0x0 /* invalidate */
+#define UNIPHIER_SSCOQM_CM_CLEAN 0x1 /* clean */
+#define UNIPHIER_SSCOQM_CM_FLUSH 0x2 /* flush */
+#define UNIPHIER_SSCOQM_CM_PREFETCH 0x3 /* prefetch to cache */
+#define UNIPHIER_SSCOQM_CM_PREFETCH_BUF 0x4 /* prefetch to pf-buf */
+#define UNIPHIER_SSCOQM_CM_TOUCH 0x5 /* touch */
+#define UNIPHIER_SSCOQM_CM_TOUCH_ZERO 0x6 /* touch to zero */
+#define UNIPHIER_SSCOQM_CM_TOUCH_DIRTY 0x7 /* touch with dirty */
+#define UNIPHIER_SSCOQAD 0x24c /* Cache Operation Queue Address */
+#define UNIPHIER_SSCOQSZ 0x250 /* Cache Operation Queue Size */
+#define UNIPHIER_SSCOQMASK 0x254 /* Cache Operation Queue Address Mask */
+#define UNIPHIER_SSCOQWN 0x258 /* Cache Operation Queue Way Number */
+#define UNIPHIER_SSCOPPQSEF 0x25c /* Cache Operation Queue Set Complete*/
+#define UNIPHIER_SSCOPPQSEF_FE BIT(1)
+#define UNIPHIER_SSCOPPQSEF_OE BIT(0)
+#define UNIPHIER_SSCOLPQS 0x260 /* Cache Operation Queue Status */
+#define UNIPHIER_SSCOLPQS_EF BIT(2)
+#define UNIPHIER_SSCOLPQS_EST BIT(1)
+#define UNIPHIER_SSCOLPQS_QST BIT(0)
+
+/* Is the touch/pre-fetch destination specified by ways? */
+#define UNIPHIER_SSCOQM_TID_IS_WAY(op) \
+ ((op & UNIPHIER_SSCOQM_TID_MASK) == UNIPHIER_SSCOQM_TID_WAY)
+/* Is the operation region specified by address range? */
+#define UNIPHIER_SSCOQM_S_IS_RANGE(op) \
+ ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE)
+
+/**
+ * uniphier_cache_data - UniPhier outer cache specific data
+ *
+ * @ctrl_base: virtual base address of control registers
+ * @rev_base: virtual base address of revision registers
+ * @op_base: virtual base address of operation registers
+ * @way_present_mask: each bit specifies if the way is present
+ * @way_locked_mask: each bit specifies if the way is locked
+ * @nsets: number of associativity sets
+ * @line_size: line size in bytes
+ * @range_op_max_size: max size that can be handled by a single range operation
+ * @list: list node to include this level in the whole cache hierarchy
+ */
+struct uniphier_cache_data {
+ void __iomem *ctrl_base;
+ void __iomem *rev_base;
+ void __iomem *op_base;
+ u32 way_present_mask;
+ u32 way_locked_mask;
+ u32 nsets;
+ u32 line_size;
+ u32 range_op_max_size;
+ struct list_head list;
+};
+
+/*
+ * List of the whole outer cache hierarchy. This list is only modified during
+ * the early boot stage, so no mutex is taken for the access to the list.
+ */
+static LIST_HEAD(uniphier_cache_list);
+
+/**
+ * __uniphier_cache_sync - perform a sync point for a particular cache level
+ *
+ * @data: cache controller specific data
+ */
+static void __uniphier_cache_sync(struct uniphier_cache_data *data)
+{
+ /* This sequence need not be atomic. Do not disable IRQ. */
+ writel_relaxed(UNIPHIER_SSCOPE_CM_SYNC,
+ data->op_base + UNIPHIER_SSCOPE);
+ /* need a read back to confirm */
+ readl_relaxed(data->op_base + UNIPHIER_SSCOPE);
+}
+
+/**
+ * __uniphier_cache_maint_common - run a queue operation for a particular level
+ *
+ * @data: cache controller specific data
+ * @start: start address of range operation (don't care for "all" operation)
+ * @size: data size of range operation (don't care for "all" operation)
+ * @operation: flags to specify the desired cache operation
+ */
+static void __uniphier_cache_maint_common(struct uniphier_cache_data *data,
+ unsigned long start,
+ unsigned long size,
+ u32 operation)
+{
+ unsigned long flags;
+
+ /*
+ * No spin lock is necessary here because:
+ *
+ * [1] This outer cache controller is able to accept maintenance
+ * operations from multiple CPUs at a time in an SMP system; if a
+ * maintenance operation is under way and another operation is issued,
+ * the new one is stored in the queue. The controller performs one
+ * operation after another. If the queue is full, the status register,
+ * UNIPHIER_SSCOPPQSEF, indicates that the queue registration has
+ * failed. The status registers, UNIPHIER_{SSCOPPQSEF, SSCOLPQS}, have
+ * different instances for each CPU, i.e. each CPU can track the status
+ * of the maintenance operations triggered by itself.
+ *
+ * [2] The cache command registers, UNIPHIER_{SSCOQM, SSCOQAD, SSCOQSZ,
+ * SSCOQWN}, are shared between multiple CPUs, but the hardware still
+ * guarantees the registration sequence is atomic; the write access to
+ * them are arbitrated by the hardware. The first accessor to the
+ * register, UNIPHIER_SSCOQM, holds the access right and it is released
+ * by reading the status register, UNIPHIER_SSCOPPQSEF. While one CPU
+ * is holding the access right, other CPUs fail to register operations.
+ * One CPU should not hold the access right for a long time, so local
+ * IRQs should be disabled while the following sequence.
+ */
+ local_irq_save(flags);
+
+ /* clear the complete notification flag */
+ writel_relaxed(UNIPHIER_SSCOLPQS_EF, data->op_base + UNIPHIER_SSCOLPQS);
+
+ do {
+ /* set cache operation */
+ writel_relaxed(UNIPHIER_SSCOQM_CE | operation,
+ data->op_base + UNIPHIER_SSCOQM);
+
+ /* set address range if needed */
+ if (likely(UNIPHIER_SSCOQM_S_IS_RANGE(operation))) {
+ writel_relaxed(start, data->op_base + UNIPHIER_SSCOQAD);
+ writel_relaxed(size, data->op_base + UNIPHIER_SSCOQSZ);
+ }
+
+ /* set target ways if needed */
+ if (unlikely(UNIPHIER_SSCOQM_TID_IS_WAY(operation)))
+ writel_relaxed(data->way_locked_mask,
+ data->op_base + UNIPHIER_SSCOQWN);
+ } while (unlikely(readl_relaxed(data->op_base + UNIPHIER_SSCOPPQSEF) &
+ (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE)));
+
+ /* wait until the operation is completed */
+ while (likely(readl_relaxed(data->op_base + UNIPHIER_SSCOLPQS) !=
+ UNIPHIER_SSCOLPQS_EF))
+ cpu_relax();
+
+ local_irq_restore(flags);
+}
+
+static void __uniphier_cache_maint_all(struct uniphier_cache_data *data,
+ u32 operation)
+{
+ __uniphier_cache_maint_common(data, 0, 0,
+ UNIPHIER_SSCOQM_S_ALL | operation);
+
+ __uniphier_cache_sync(data);
+}
+
+static void __uniphier_cache_maint_range(struct uniphier_cache_data *data,
+ unsigned long start, unsigned long end,
+ u32 operation)
+{
+ unsigned long size;
+
+ /*
+ * If the start address is not aligned,
+ * perform a cache operation for the first cache-line
+ */
+ start = start & ~(data->line_size - 1);
+
+ size = end - start;
+
+ if (unlikely(size >= (unsigned long)(-data->line_size))) {
+ /* this means cache operation for all range */
+ __uniphier_cache_maint_all(data, operation);
+ return;
+ }
+
+ /*
+ * If the end address is not aligned,
+ * perform a cache operation for the last cache-line
+ */
+ size = ALIGN(size, data->line_size);
+
+ while (size) {
+ unsigned long chunk_size = min_t(unsigned long, size,
+ data->range_op_max_size);
+
+ __uniphier_cache_maint_common(data, start, chunk_size,
+ UNIPHIER_SSCOQM_S_RANGE | operation);
+
+ start += chunk_size;
+ size -= chunk_size;
+ }
+
+ __uniphier_cache_sync(data);
+}
+
+static void __uniphier_cache_enable(struct uniphier_cache_data *data, bool on)
+{
+ u32 val = 0;
+
+ if (on)
+ val = UNIPHIER_SSCC_WTG | UNIPHIER_SSCC_PRD | UNIPHIER_SSCC_ON;
+
+ writel_relaxed(val, data->ctrl_base + UNIPHIER_SSCC);
+}
+
+static void __init __uniphier_cache_set_locked_ways(
+ struct uniphier_cache_data *data,
+ u32 way_mask)
+{
+ data->way_locked_mask = way_mask & data->way_present_mask;
+
+ writel_relaxed(~data->way_locked_mask & data->way_present_mask,
+ data->ctrl_base + UNIPHIER_SSCLPDAWCR);
+}
+
+static void uniphier_cache_maint_range(unsigned long start, unsigned long end,
+ u32 operation)
+{
+ struct uniphier_cache_data *data;
+
+ list_for_each_entry(data, &uniphier_cache_list, list)
+ __uniphier_cache_maint_range(data, start, end, operation);
+}
+
+static void uniphier_cache_maint_all(u32 operation)
+{
+ struct uniphier_cache_data *data;
+
+ list_for_each_entry(data, &uniphier_cache_list, list)
+ __uniphier_cache_maint_all(data, operation);
+}
+
+static void uniphier_cache_inv_range(unsigned long start, unsigned long end)
+{
+ uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void uniphier_cache_clean_range(unsigned long start, unsigned long end)
+{
+ uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_CLEAN);
+}
+
+static void uniphier_cache_flush_range(unsigned long start, unsigned long end)
+{
+ uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+static void __init uniphier_cache_inv_all(void)
+{
+ uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void uniphier_cache_flush_all(void)
+{
+ uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+static void uniphier_cache_disable(void)
+{
+ struct uniphier_cache_data *data;
+
+ list_for_each_entry_reverse(data, &uniphier_cache_list, list)
+ __uniphier_cache_enable(data, false);
+
+ uniphier_cache_flush_all();
+}
+
+static void __init uniphier_cache_enable(void)
+{
+ struct uniphier_cache_data *data;
+
+ uniphier_cache_inv_all();
+
+ list_for_each_entry(data, &uniphier_cache_list, list) {
+ __uniphier_cache_enable(data, true);
+ __uniphier_cache_set_locked_ways(data, 0);
+ }
+}
+
+static void uniphier_cache_sync(void)
+{
+ struct uniphier_cache_data *data;
+
+ list_for_each_entry(data, &uniphier_cache_list, list)
+ __uniphier_cache_sync(data);
+}
+
+int __init uniphier_cache_l2_is_enabled(void)
+{
+ struct uniphier_cache_data *data;
+
+ data = list_first_entry_or_null(&uniphier_cache_list,
+ struct uniphier_cache_data, list);
+ if (!data)
+ return 0;
+
+ return !!(readl_relaxed(data->ctrl_base + UNIPHIER_SSCC) &
+ UNIPHIER_SSCC_ON);
+}
+
+void __init uniphier_cache_l2_touch_range(unsigned long start,
+ unsigned long end)
+{
+ struct uniphier_cache_data *data;
+
+ data = list_first_entry_or_null(&uniphier_cache_list,
+ struct uniphier_cache_data, list);
+ if (data)
+ __uniphier_cache_maint_range(data, start, end,
+ UNIPHIER_SSCOQM_TID_WAY |
+ UNIPHIER_SSCOQM_CM_TOUCH);
+}
+
+void __init uniphier_cache_l2_set_locked_ways(u32 way_mask)
+{
+ struct uniphier_cache_data *data;
+
+ data = list_first_entry_or_null(&uniphier_cache_list,
+ struct uniphier_cache_data, list);
+ if (data)
+ __uniphier_cache_set_locked_ways(data, way_mask);
+}
+
+static const struct of_device_id uniphier_cache_match[] __initconst = {
+ {
+ .compatible = "socionext,uniphier-system-cache",
+ },
+ { /* sentinel */ }
+};
+
+static int __init __uniphier_cache_init(struct device_node *np,
+ unsigned int *cache_level)
+{
+ struct uniphier_cache_data *data;
+ u32 level, cache_size;
+ struct device_node *next_np;
+ int ret = 0;
+
+ if (!of_match_node(uniphier_cache_match, np)) {
+ pr_err("L%d: not compatible with uniphier cache\n",
+ *cache_level);
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(np, "cache-level", &level)) {
+ pr_err("L%d: cache-level is not specified\n", *cache_level);
+ return -EINVAL;
+ }
+
+ if (level != *cache_level) {
+ pr_err("L%d: cache-level is unexpected value %d\n",
+ *cache_level, level);
+ return -EINVAL;
+ }
+
+ if (!of_property_read_bool(np, "cache-unified")) {
+ pr_err("L%d: cache-unified is not specified\n", *cache_level);
+ return -EINVAL;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (of_property_read_u32(np, "cache-line-size", &data->line_size) ||
+ !is_power_of_2(data->line_size)) {
+ pr_err("L%d: cache-line-size is unspecified or invalid\n",
+ *cache_level);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (of_property_read_u32(np, "cache-sets", &data->nsets) ||
+ !is_power_of_2(data->nsets)) {
+ pr_err("L%d: cache-sets is unspecified or invalid\n",
+ *cache_level);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (of_property_read_u32(np, "cache-size", &cache_size) ||
+ cache_size == 0 || cache_size % (data->nsets * data->line_size)) {
+ pr_err("L%d: cache-size is unspecified or invalid\n",
+ *cache_level);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ data->way_present_mask =
+ ((u32)1 << cache_size / data->nsets / data->line_size) - 1;
+
+ data->ctrl_base = of_iomap(np, 0);
+ if (!data->ctrl_base) {
+ pr_err("L%d: failed to map control register\n", *cache_level);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ data->rev_base = of_iomap(np, 1);
+ if (!data->rev_base) {
+ pr_err("L%d: failed to map revision register\n", *cache_level);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ data->op_base = of_iomap(np, 2);
+ if (!data->op_base) {
+ pr_err("L%d: failed to map operation register\n", *cache_level);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (*cache_level == 2) {
+ u32 revision = readl(data->rev_base + UNIPHIER_SSCID);
+ /*
+ * The size of range operation is limited to (1 << 22) or less
+ * for PH-sLD8 or older SoCs.
+ */
+ if (revision <= 0x16)
+ data->range_op_max_size = (u32)1 << 22;
+ }
+
+ data->range_op_max_size -= data->line_size;
+
+ INIT_LIST_HEAD(&data->list);
+ list_add_tail(&data->list, &uniphier_cache_list); /* no mutex */
+
+ /*
+ * OK, this level has been successfully initialized. Look for the next
+ * level cache. Do not roll back even if the initialization of the
+ * next level cache fails because we want to continue with available
+ * cache levels.
+ */
+ next_np = of_find_next_cache_node(np);
+ if (next_np) {
+ (*cache_level)++;
+ ret = __uniphier_cache_init(next_np, cache_level);
+ }
+ of_node_put(next_np);
+
+ return ret;
+err:
+ iounmap(data->op_base);
+ iounmap(data->rev_base);
+ iounmap(data->ctrl_base);
+ kfree(data);
+
+ return ret;
+}
+
+int __init uniphier_cache_init(void)
+{
+ struct device_node *np = NULL;
+ unsigned int cache_level;
+ int ret = 0;
+
+ /* look for level 2 cache */
+ while ((np = of_find_matching_node(np, uniphier_cache_match)))
+ if (!of_property_read_u32(np, "cache-level", &cache_level) &&
+ cache_level == 2)
+ break;
+
+ if (!np)
+ return -ENODEV;
+
+ ret = __uniphier_cache_init(np, &cache_level);
+ of_node_put(np);
+
+ if (ret) {
+ /*
+ * Error out iif L2 initialization fails. Continue with any
+ * error on L3 or outer because they are optional.
+ */
+ if (cache_level == 2) {
+ pr_err("failed to initialize L2 cache\n");
+ return ret;
+ }
+
+ cache_level--;
+ ret = 0;
+ }
+
+ outer_cache.inv_range = uniphier_cache_inv_range;
+ outer_cache.clean_range = uniphier_cache_clean_range;
+ outer_cache.flush_range = uniphier_cache_flush_range;
+ outer_cache.flush_all = uniphier_cache_flush_all;
+ outer_cache.disable = uniphier_cache_disable;
+ outer_cache.sync = uniphier_cache_sync;
+
+ uniphier_cache_enable();
+
+ pr_info("enabled outer cache (cache level: %d)\n", cache_level);
+
+ return ret;
+}
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 845769e..c8c8b9e 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -165,13 +165,28 @@ static void flush_context(unsigned int cpu)
__flush_icache_all();
}
-static int is_reserved_asid(u64 asid)
+static bool check_update_reserved_asid(u64 asid, u64 newasid)
{
int cpu;
- for_each_possible_cpu(cpu)
- if (per_cpu(reserved_asids, cpu) == asid)
- return 1;
- return 0;
+ bool hit = false;
+
+ /*
+ * Iterate over the set of reserved ASIDs looking for a match.
+ * If we find one, then we can update our mm to use newasid
+ * (i.e. the same ASID in the current generation) but we can't
+ * exit the loop early, since we need to ensure that all copies
+ * of the old ASID are updated to reflect the mm. Failure to do
+ * so could result in us missing the reserved ASID in a future
+ * generation.
+ */
+ for_each_possible_cpu(cpu) {
+ if (per_cpu(reserved_asids, cpu) == asid) {
+ hit = true;
+ per_cpu(reserved_asids, cpu) = newasid;
+ }
+ }
+
+ return hit;
}
static u64 new_context(struct mm_struct *mm, unsigned int cpu)
@@ -181,12 +196,14 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
u64 generation = atomic64_read(&asid_generation);
if (asid != 0) {
+ u64 newasid = generation | (asid & ~ASID_MASK);
+
/*
* 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);
+ if (check_update_reserved_asid(asid, newasid))
+ return newasid;
/*
* We had a valid ASID in a previous life, so try to re-use
@@ -194,7 +211,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
*/
asid &= ~ASID_MASK;
if (!__test_and_set_bit(asid, asid_map))
- goto bump_gen;
+ return newasid;
}
/*
@@ -216,11 +233,8 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
__set_bit(asid, asid_map);
cur_idx = asid;
-
-bump_gen:
- asid |= generation;
cpumask_clear(mm_cpumask(mm));
- return asid;
+ return asid | generation;
}
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1a7815e..deac58d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -42,6 +42,55 @@
#include "dma.h"
#include "mm.h"
+struct arm_dma_alloc_args {
+ struct device *dev;
+ size_t size;
+ gfp_t gfp;
+ pgprot_t prot;
+ const void *caller;
+ bool want_vaddr;
+};
+
+struct arm_dma_free_args {
+ struct device *dev;
+ size_t size;
+ void *cpu_addr;
+ struct page *page;
+ bool want_vaddr;
+};
+
+struct arm_dma_allocator {
+ void *(*alloc)(struct arm_dma_alloc_args *args,
+ struct page **ret_page);
+ void (*free)(struct arm_dma_free_args *args);
+};
+
+struct arm_dma_buffer {
+ struct list_head list;
+ void *virt;
+ struct arm_dma_allocator *allocator;
+};
+
+static LIST_HEAD(arm_dma_bufs);
+static DEFINE_SPINLOCK(arm_dma_bufs_lock);
+
+static struct arm_dma_buffer *arm_dma_buffer_find(void *virt)
+{
+ struct arm_dma_buffer *buf, *found = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&arm_dma_bufs_lock, flags);
+ list_for_each_entry(buf, &arm_dma_bufs, list) {
+ if (buf->virt == virt) {
+ list_del(&buf->list);
+ found = buf;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&arm_dma_bufs_lock, flags);
+ return found;
+}
+
/*
* 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
@@ -592,7 +641,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
#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_pool(cpu_addr, size) do { } while (0)
#define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0)
#define __dma_free_remap(cpu_addr, size) do { } while (0)
@@ -610,7 +659,78 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
return page_address(page);
}
+static void *simple_allocator_alloc(struct arm_dma_alloc_args *args,
+ struct page **ret_page)
+{
+ return __alloc_simple_buffer(args->dev, args->size, args->gfp,
+ ret_page);
+}
+
+static void simple_allocator_free(struct arm_dma_free_args *args)
+{
+ __dma_free_buffer(args->page, args->size);
+}
+static struct arm_dma_allocator simple_allocator = {
+ .alloc = simple_allocator_alloc,
+ .free = simple_allocator_free,
+};
+
+static void *cma_allocator_alloc(struct arm_dma_alloc_args *args,
+ struct page **ret_page)
+{
+ return __alloc_from_contiguous(args->dev, args->size, args->prot,
+ ret_page, args->caller,
+ args->want_vaddr);
+}
+
+static void cma_allocator_free(struct arm_dma_free_args *args)
+{
+ __free_from_contiguous(args->dev, args->page, args->cpu_addr,
+ args->size, args->want_vaddr);
+}
+
+static struct arm_dma_allocator cma_allocator = {
+ .alloc = cma_allocator_alloc,
+ .free = cma_allocator_free,
+};
+
+static void *pool_allocator_alloc(struct arm_dma_alloc_args *args,
+ struct page **ret_page)
+{
+ return __alloc_from_pool(args->size, ret_page);
+}
+
+static void pool_allocator_free(struct arm_dma_free_args *args)
+{
+ __free_from_pool(args->cpu_addr, args->size);
+}
+
+static struct arm_dma_allocator pool_allocator = {
+ .alloc = pool_allocator_alloc,
+ .free = pool_allocator_free,
+};
+
+static void *remap_allocator_alloc(struct arm_dma_alloc_args *args,
+ struct page **ret_page)
+{
+ return __alloc_remap_buffer(args->dev, args->size, args->gfp,
+ args->prot, ret_page, args->caller,
+ args->want_vaddr);
+}
+
+static void remap_allocator_free(struct arm_dma_free_args *args)
+{
+ if (args->want_vaddr)
+ __dma_free_remap(args->cpu_addr, args->size);
+
+ __dma_free_buffer(args->page, args->size);
+}
+
+static struct arm_dma_allocator remap_allocator = {
+ .alloc = remap_allocator_alloc,
+ .free = remap_allocator_free,
+};
static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp, pgprot_t prot, bool is_coherent,
@@ -619,7 +739,16 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
u64 mask = get_coherent_dma_mask(dev);
struct page *page = NULL;
void *addr;
- bool want_vaddr;
+ bool allowblock, cma;
+ struct arm_dma_buffer *buf;
+ struct arm_dma_alloc_args args = {
+ .dev = dev,
+ .size = PAGE_ALIGN(size),
+ .gfp = gfp,
+ .prot = prot,
+ .caller = caller,
+ .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs),
+ };
#ifdef CONFIG_DMA_API_DEBUG
u64 limit = (mask + 1) & ~mask;
@@ -633,6 +762,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
if (!mask)
return NULL;
+ buf = kzalloc(sizeof(*buf), gfp);
+ if (!buf)
+ return NULL;
+
if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
@@ -644,28 +777,37 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
* platform; see CONFIG_HUGETLBFS.
*/
gfp &= ~(__GFP_COMP);
+ args.gfp = gfp;
*handle = DMA_ERROR_CODE;
- size = PAGE_ALIGN(size);
- want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
-
- if (nommu())
- addr = __alloc_simple_buffer(dev, size, gfp, &page);
- else if (dev_get_cma_area(dev) && (gfp & __GFP_WAIT))
- addr = __alloc_from_contiguous(dev, size, prot, &page,
- caller, want_vaddr);
- else if (is_coherent)
- addr = __alloc_simple_buffer(dev, size, gfp, &page);
- else if (!(gfp & __GFP_WAIT))
- addr = __alloc_from_pool(size, &page);
+ allowblock = gfpflags_allow_blocking(gfp);
+ cma = allowblock ? dev_get_cma_area(dev) : false;
+
+ if (cma)
+ buf->allocator = &cma_allocator;
+ else if (nommu() || is_coherent)
+ buf->allocator = &simple_allocator;
+ else if (allowblock)
+ buf->allocator = &remap_allocator;
else
- addr = __alloc_remap_buffer(dev, size, gfp, prot, &page,
- caller, want_vaddr);
+ buf->allocator = &pool_allocator;
+
+ addr = buf->allocator->alloc(&args, &page);
+
+ if (page) {
+ unsigned long flags;
- if (page)
*handle = pfn_to_dma(dev, page_to_pfn(page));
+ buf->virt = args.want_vaddr ? addr : page;
- return want_vaddr ? addr : page;
+ spin_lock_irqsave(&arm_dma_bufs_lock, flags);
+ list_add(&buf->list, &arm_dma_bufs);
+ spin_unlock_irqrestore(&arm_dma_bufs_lock, flags);
+ } else {
+ kfree(buf);
+ }
+
+ return args.want_vaddr ? addr : page;
}
/*
@@ -741,25 +883,21 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
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);
-
- size = PAGE_ALIGN(size);
-
- if (nommu()) {
- __dma_free_buffer(page, size);
- } else if (!is_coherent && __free_from_pool(cpu_addr, size)) {
+ struct arm_dma_buffer *buf;
+ struct arm_dma_free_args args = {
+ .dev = dev,
+ .size = PAGE_ALIGN(size),
+ .cpu_addr = cpu_addr,
+ .page = page,
+ .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs),
+ };
+
+ buf = arm_dma_buffer_find(cpu_addr);
+ if (WARN(!buf, "Freeing invalid buffer %p\n", cpu_addr))
return;
- } else if (!dev_get_cma_area(dev)) {
- if (want_vaddr && !is_coherent)
- __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);
- }
+
+ buf->allocator->free(&args);
+ kfree(buf);
}
void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
@@ -1122,6 +1260,9 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
spin_unlock_irqrestore(&mapping->lock, flags);
}
+/* We'll try 2M, 1M, 64K, and finally 4K; array must end with 0! */
+static const int iommu_order_array[] = { 9, 8, 4, 0 };
+
static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
gfp_t gfp, struct dma_attrs *attrs)
{
@@ -1129,6 +1270,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
int count = size >> PAGE_SHIFT;
int array_size = count * sizeof(struct page *);
int i = 0;
+ int order_idx = 0;
if (array_size <= PAGE_SIZE)
pages = kzalloc(array_size, GFP_KERNEL);
@@ -1154,6 +1296,10 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
return pages;
}
+ /* Go straight to 4K chunks if caller says it's OK. */
+ if (dma_get_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, attrs))
+ order_idx = ARRAY_SIZE(iommu_order_array) - 1;
+
/*
* IOMMU can map any pages, so himem can also be used here
*/
@@ -1162,22 +1308,24 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
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;
+ order = iommu_order_array[order_idx];
+
+ /* Drop down when we get small */
+ if (__fls(count) < order) {
+ order_idx++;
+ continue;
}
- if (!pages[i]) {
- /*
- * Fall back to single page allocation.
- * Might invoke OOM killer as last resort.
- */
+ if (order) {
+ /* See if it's easy to allocate a high-order chunk */
+ pages[i] = alloc_pages(gfp | __GFP_NORETRY, order);
+
+ /* Go down a notch at first sign of pressure */
+ if (!pages[i]) {
+ order_idx++;
+ continue;
+ }
+ } else {
pages[i] = alloc_pages(gfp, 0);
if (!pages[i])
goto error;
@@ -1200,10 +1348,7 @@ error:
while (i--)
if (pages[i])
__free_pages(pages[i], 0);
- if (array_size <= PAGE_SIZE)
- kfree(pages);
- else
- vfree(pages);
+ kvfree(pages);
return NULL;
}
@@ -1211,7 +1356,6 @@ 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)) {
@@ -1222,10 +1366,7 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages,
__free_pages(pages[i], 0);
}
- if (array_size <= PAGE_SIZE)
- kfree(pages);
- else
- vfree(pages);
+ kvfree(pages);
return 0;
}
@@ -1363,7 +1504,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
- if (!(gfp & __GFP_WAIT))
+ if (!gfpflags_allow_blocking(gfp))
return __iommu_alloc_atomic(dev, size, handle);
/*
@@ -1407,12 +1548,19 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
unsigned long uaddr = vma->vm_start;
unsigned long usize = vma->vm_end - vma->vm_start;
struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+ unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned long off = vma->vm_pgoff;
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
if (!pages)
return -ENXIO;
+ if (off >= nr_pages || (usize >> PAGE_SHIFT) > nr_pages - off)
+ return -ENXIO;
+
+ pages += off;
+
do {
int ret = vm_insert_page(vma, uaddr, *pages++);
if (ret) {
@@ -1514,7 +1662,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
return -ENOMEM;
for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
- phys_addr_t phys = sg_phys(s) & PAGE_MASK;
+ phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length);
if (!is_coherent &&
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 0d629b8..ad58418 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -346,7 +346,7 @@ retry:
up_read(&mm->mmap_sem);
/*
- * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
+ * Handle the "normal" case first - VM_FAULT_MAJOR
*/
if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
return 0;
@@ -593,6 +593,28 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
arm_notify_die("", regs, &info, ifsr, 0);
}
+/*
+ * Abort handler to be used only during first unmasking of asynchronous aborts
+ * on the boot CPU. This makes sure that the machine will not die if the
+ * firmware/bootloader left an imprecise abort pending for us to trip over.
+ */
+static int __init early_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ pr_warn("Hit pending asynchronous external abort (FSR=0x%08x) during "
+ "first unmask, this is most likely caused by a "
+ "firmware/bootloader bug.\n", fsr);
+
+ return 0;
+}
+
+void __init early_abt_enable(void)
+{
+ fsr_info[22].fn = early_abort_handler;
+ local_abt_enable();
+ fsr_info[22].fn = do_bad;
+}
+
#ifndef CONFIG_ARM_LPAE
static int __init exceptions_init(void)
{
diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
index cf08bdf..05ec5e0 100644
--- a/arch/arm/mm/fault.h
+++ b/arch/arm/mm/fault.h
@@ -24,5 +24,6 @@ static inline int fsr_fs(unsigned int fsr)
void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
unsigned long search_exception_table(unsigned long addr);
+void early_abt_enable(void);
#endif /* __ARCH_ARM_FAULT_H */
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 1ec8e75..d0ba3551 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -330,7 +330,7 @@ void flush_dcache_page(struct page *page)
mapping = page_mapping(page);
if (!cache_ops_need_broadcast() &&
- mapping && !page_mapped(page))
+ mapping && !page_mapcount(page))
clear_bit(PG_dcache_clean, &page->flags);
else {
__flush_dcache_page(mapping, page);
@@ -415,18 +415,3 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l
*/
__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/highmem.c b/arch/arm/mm/highmem.c
index 9df5f09..d02f818 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -147,13 +147,3 @@ void *kmap_atomic_pfn(unsigned long pfn)
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/idmap.c b/arch/arm/mm/idmap.c
index e7a81ceb..bd274a0 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -15,7 +15,7 @@
* page tables.
*/
pgd_t *idmap_pgd;
-phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
+unsigned long (*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,
@@ -86,7 +86,7 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
- if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+ if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale_family())
prot |= PMD_BIT4;
pgd += pgd_index(addr);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8a63b4c..370581a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -22,6 +22,7 @@
#include <linux/memblock.h>
#include <linux/dma-contiguous.h>
#include <linux/sizes.h>
+#include <linux/stop_machine.h>
#include <asm/cp15.h>
#include <asm/mach-types.h>
@@ -191,7 +192,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low,
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
int pfn_valid(unsigned long pfn)
{
- return memblock_is_memory(__pfn_to_phys(pfn));
+ return memblock_is_map_memory(__pfn_to_phys(pfn));
}
EXPORT_SYMBOL(pfn_valid);
#endif
@@ -432,6 +433,9 @@ static void __init free_highpages(void)
if (end <= max_low)
continue;
+ if (memblock_is_nomap(mem))
+ continue;
+
/* Truncate partial highmem entries */
if (start < max_low)
start = max_low;
@@ -568,8 +572,9 @@ void __init mem_init(void)
}
}
-#ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
struct section_perm {
+ const char *name;
unsigned long start;
unsigned long end;
pmdval_t mask;
@@ -577,9 +582,13 @@ struct section_perm {
pmdval_t clear;
};
+/* First section-aligned location at or after __start_rodata. */
+extern char __start_rodata_section_aligned[];
+
static struct section_perm nx_perms[] = {
/* Make pages tables, etc before _stext RW (set NX). */
{
+ .name = "pre-text NX",
.start = PAGE_OFFSET,
.end = (unsigned long)_stext,
.mask = ~PMD_SECT_XN,
@@ -587,26 +596,26 @@ static struct section_perm nx_perms[] = {
},
/* Make init RW (set NX). */
{
+ .name = "init 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,
+ .name = "rodata NX",
+ .start = (unsigned long)__start_rodata_section_aligned,
.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). */
{
+ .name = "text/rodata RO",
.start = (unsigned long)_stext,
.end = (unsigned long)__init_begin,
#ifdef CONFIG_ARM_LPAE
@@ -619,7 +628,6 @@ static struct section_perm ro_perms[] = {
#endif
},
};
-#endif
/*
* Updates section permissions only for the current mm (sections are
@@ -627,12 +635,10 @@ static struct section_perm ro_perms[] = {
* 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)
+ pmdval_t prot, struct mm_struct *mm)
{
- 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
@@ -656,55 +662,86 @@ static inline bool arch_has_strict_perms(void)
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); \
- } \
+void set_section_perms(struct section_perm *perms, int n, bool set,
+ struct mm_struct *mm)
+{
+ size_t i;
+ unsigned long addr;
+
+ if (!arch_has_strict_perms())
+ return;
+
+ for (i = 0; i < n; i++) {
+ if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) ||
+ !IS_ALIGNED(perms[i].end, SECTION_SIZE)) {
+ pr_err("BUG: %s section %lx-%lx not aligned to %lx\n",
+ perms[i].name, 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,
+ set ? perms[i].prot : perms[i].clear, mm);
+ }
+
+}
+
+static void update_sections_early(struct section_perm perms[], int n)
+{
+ struct task_struct *t, *s;
+
+ read_lock(&tasklist_lock);
+ for_each_process(t) {
+ if (t->flags & PF_KTHREAD)
+ continue;
+ for_each_thread(t, s)
+ set_section_perms(perms, n, true, s->mm);
+ }
+ read_unlock(&tasklist_lock);
+ set_section_perms(perms, n, true, current->active_mm);
+ set_section_perms(perms, n, true, &init_mm);
}
-static inline void fix_kernmem_perms(void)
+int __fix_kernmem_perms(void *unused)
{
- set_section_perms(nx_perms, prot);
+ update_sections_early(nx_perms, ARRAY_SIZE(nx_perms));
+ return 0;
+}
+
+void fix_kernmem_perms(void)
+{
+ stop_machine(__fix_kernmem_perms, NULL, NULL);
+}
+
+int __mark_rodata_ro(void *unused)
+{
+ update_sections_early(ro_perms, ARRAY_SIZE(ro_perms));
+ return 0;
}
-#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void)
{
- set_section_perms(ro_perms, prot);
+ stop_machine(__mark_rodata_ro, NULL, NULL);
}
void set_kernel_text_rw(void)
{
- set_section_perms(ro_perms, clear);
+ set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false,
+ current->active_mm);
}
void set_kernel_text_ro(void)
{
- set_section_perms(ro_perms, prot);
+ set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
+ current->active_mm);
}
-#endif /* CONFIG_DEBUG_RODATA */
#else
static inline void fix_kernmem_perms(void) { }
-#endif /* CONFIG_ARM_KERNMEM_PERMS */
+#endif /* CONFIG_DEBUG_RODATA */
void free_tcmmem(void)
{
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0c81056..66a978d 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -30,6 +30,7 @@
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/cacheflush.h>
+#include <asm/early_ioremap.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
@@ -469,3 +470,11 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
#endif
+
+/*
+ * Must be called after early_fixmap_init
+ */
+void __init early_ioremap_init(void)
+{
+ early_ioremap_setup();
+}
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 407dc78..66353ca 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -173,8 +173,7 @@ 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);
+ rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
return rnd << PAGE_SHIFT;
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7cd1514..62f4d01 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -38,6 +38,7 @@
#include <asm/mach/pci.h>
#include <asm/fixmap.h>
+#include "fault.h"
#include "mm.h"
#include "tcm.h"
@@ -389,7 +390,7 @@ void __init early_fixmap_init(void)
* The early fixmap range spans multiple pmds, for which
* we are not prepared:
*/
- BUILD_BUG_ON((__fix_to_virt(__end_of_permanent_fixed_addresses) >> PMD_SHIFT)
+ BUILD_BUG_ON((__fix_to_virt(__end_of_early_ioremap_region) >> PMD_SHIFT)
!= FIXADDR_TOP >> PMD_SHIFT);
pmd = fixmap_pmd(FIXADDR_TOP);
@@ -476,7 +477,7 @@ static void __init build_mem_type_table(void)
* "update-able on write" bit on ARM610). However, Xscale and
* Xscale3 require this bit to be cleared.
*/
- if (cpu_is_xscale() || cpu_is_xsc3()) {
+ if (cpu_is_xscale_family()) {
for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
mem_types[i].prot_sect &= ~PMD_BIT4;
mem_types[i].prot_l1 &= ~PMD_BIT4;
@@ -571,7 +572,7 @@ static void __init build_mem_type_table(void)
* in the Short-descriptor translation table format descriptors.
*/
if (cpu_arch == CPU_ARCH_ARMv7 &&
- (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) == 4) {
+ (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) >= 4) {
user_pmd_table |= PMD_PXNTABLE;
}
#endif
@@ -723,30 +724,49 @@ 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)
+static void *__init late_alloc(unsigned long sz)
+{
+ void *ptr = (void *)__get_free_pages(PGALLOC_GFP, get_order(sz));
+
+ BUG_ON(!ptr);
+ return ptr;
+}
+
+static pte_t * __init arm_pte_alloc(pmd_t *pmd, unsigned long addr,
+ unsigned long prot,
+ void *(*alloc)(unsigned long sz))
{
if (pmd_none(*pmd)) {
- pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
+ pte_t *pte = 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 pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr,
+ unsigned long prot)
+{
+ return arm_pte_alloc(pmd, addr, prot, early_alloc);
+}
+
static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
- const struct mem_type *type)
+ const struct mem_type *type,
+ void *(*alloc)(unsigned long sz),
+ bool ng)
{
- pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
+ pte_t *pte = arm_pte_alloc(pmd, addr, type->prot_l1, alloc);
do {
- set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
+ set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)),
+ ng ? PTE_EXT_NG : 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)
+ const struct mem_type *type, bool ng)
{
pmd_t *p = pmd;
@@ -764,7 +784,7 @@ static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
pmd++;
#endif
do {
- *pmd = __pmd(phys | type->prot_sect);
+ *pmd = __pmd(phys | type->prot_sect | (ng ? PMD_SECT_nG : 0));
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
@@ -773,7 +793,8 @@ static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
unsigned long end, phys_addr_t phys,
- const struct mem_type *type)
+ const struct mem_type *type,
+ void *(*alloc)(unsigned long sz), bool ng)
{
pmd_t *pmd = pmd_offset(pud, addr);
unsigned long next;
@@ -791,10 +812,10 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
*/
if (type->prot_sect &&
((addr | next | phys) & ~SECTION_MASK) == 0) {
- __map_init_section(pmd, addr, next, phys, type);
+ __map_init_section(pmd, addr, next, phys, type, ng);
} else {
alloc_init_pte(pmd, addr, next,
- __phys_to_pfn(phys), type);
+ __phys_to_pfn(phys), type, alloc, ng);
}
phys += next - addr;
@@ -804,21 +825,24 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
unsigned long end, phys_addr_t phys,
- const struct mem_type *type)
+ const struct mem_type *type,
+ void *(*alloc)(unsigned long sz), bool ng)
{
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);
+ alloc_init_pmd(pud, addr, next, phys, type, alloc, ng);
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)
+static void __init create_36bit_mapping(struct mm_struct *mm,
+ struct map_desc *md,
+ const struct mem_type *type,
+ bool ng)
{
unsigned long addr, length, end;
phys_addr_t phys;
@@ -858,7 +882,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
*/
phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
- pgd = pgd_offset_k(addr);
+ pgd = pgd_offset(mm, addr);
end = addr + length;
do {
pud_t *pud = pud_offset(pgd, addr);
@@ -866,7 +890,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
int i;
for (i = 0; i < 16; i++)
- *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER);
+ *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER |
+ (ng ? PMD_SECT_nG : 0));
addr += SUPERSECTION_SIZE;
phys += SUPERSECTION_SIZE;
@@ -875,33 +900,15 @@ static void __init create_36bit_mapping(struct map_desc *md,
}
#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)
+static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
+ void *(*alloc)(unsigned long sz),
+ bool ng)
{
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 < FIXADDR_START &&
- (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
@@ -909,7 +916,7 @@ static void __init create_mapping(struct map_desc *md)
* Catch 36-bit addresses
*/
if (md->pfn >= 0x100000) {
- create_36bit_mapping(md, type);
+ create_36bit_mapping(mm, md, type, ng);
return;
}
#endif
@@ -924,12 +931,12 @@ static void __init create_mapping(struct map_desc *md)
return;
}
- pgd = pgd_offset_k(addr);
+ pgd = pgd_offset(mm, addr);
end = addr + length;
do {
unsigned long next = pgd_addr_end(addr, end);
- alloc_init_pud(pgd, addr, next, phys, type);
+ alloc_init_pud(pgd, addr, next, phys, type, alloc, ng);
phys += next - addr;
addr = next;
@@ -937,6 +944,43 @@ static void __init create_mapping(struct map_desc *md)
}
/*
+ * 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)
+{
+ 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 < FIXADDR_START &&
+ (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);
+ }
+
+ __create_mapping(&init_mm, md, early_alloc, false);
+}
+
+void __init create_mapping_late(struct mm_struct *mm, struct map_desc *md,
+ bool ng)
+{
+#ifdef CONFIG_ARM_LPAE
+ pud_t *pud = pud_alloc(mm, pgd_offset(mm, md->virtual), md->virtual);
+ if (WARN_ON(!pud))
+ return;
+ pmd_alloc(mm, pud, 0);
+#endif
+ __create_mapping(mm, md, late_alloc, ng);
+}
+
+/*
* Create the architecture specific mappings
*/
void __init iotable_init(struct map_desc *io_desc, int nr)
@@ -1209,7 +1253,7 @@ static inline void prepare_page_table(void)
#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;
+ addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
#endif
for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -1291,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
#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.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
map.type = MT_ROM;
create_mapping(&map);
#endif
@@ -1363,6 +1407,9 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
*/
local_flush_tlb_all();
flush_cache_all();
+
+ /* Enable asynchronous aborts */
+ early_abt_enable();
}
static void __init kmap_init(void)
@@ -1379,7 +1426,11 @@ static void __init kmap_init(void)
static void __init map_lowmem(void)
{
struct memblock_region *reg;
+#ifdef CONFIG_XIP_KERNEL
+ phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
+#else
phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+#endif
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
/* Map all the lowmem memory banks. */
@@ -1388,6 +1439,9 @@ static void __init map_lowmem(void)
phys_addr_t end = start + reg->size;
struct map_desc map;
+ if (memblock_is_nomap(reg))
+ continue;
+
if (end > arm_lowmem_limit)
end = arm_lowmem_limit;
if (start >= end)
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
index cf30daf..d19b1ad 100644
--- a/arch/arm/mm/pageattr.c
+++ b/arch/arm/mm/pageattr.c
@@ -49,6 +49,9 @@ static int change_memory_common(unsigned long addr, int numpages,
WARN_ON_ONCE(1);
}
+ if (!numpages)
+ return 0;
+
if (start < MODULES_VADDR || start >= MODULES_END)
return -EINVAL;
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index e683db1..b8d4773 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -80,7 +80,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
if (!new_pmd)
goto no_pmd;
- new_pte = pte_alloc_map(mm, NULL, new_pmd, 0);
+ new_pte = pte_alloc_map(mm, new_pmd, 0);
if (!new_pte)
goto no_pte;
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index d65edf7..6f07d2e 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -342,11 +342,13 @@ ENTRY(cpu_mohawk_switch_mm)
*/
.align 5
ENTRY(cpu_mohawk_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
ret lr
+#endif
.globl cpu_mohawk_suspend_size
.equ cpu_mohawk_suspend_size, 4 * 6
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index de2b246..0f8963a 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -95,7 +95,7 @@ ENDPROC(cpu_v7_dcache_clean_area)
.equ cpu_v7_suspend_size, 4 * 9
#ifdef CONFIG_ARM_CPU_SUSPEND
ENTRY(cpu_v7_do_suspend)
- stmfd sp!, {r4 - r10, lr}
+ stmfd sp!, {r4 - r11, 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}
@@ -112,7 +112,7 @@ ENTRY(cpu_v7_do_suspend)
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}
+ ldmfd sp!, {r4 - r11, pc}
ENDPROC(cpu_v7_do_suspend)
ENTRY(cpu_v7_do_resume)
@@ -274,10 +274,12 @@ __v7_ca15mp_setup:
__v7_b15mp_setup:
__v7_ca17mp_setup:
mov r10, #0
-1: adr r12, __v7_setup_stack @ the local stack
- stmia r12, {r0-r5, lr} @ v7_invalidate_l1 touches r0-r6
+1: adr r0, __v7_setup_stack_ptr
+ ldr r12, [r0]
+ add r12, r12, r0 @ the local stack
+ stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6
bl v7_invalidate_l1
- ldmia r12, {r0-r5, lr}
+ ldmia r12, {r1-r6, lr}
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
@@ -415,10 +417,12 @@ __v7_pj4b_setup:
#endif /* CONFIG_CPU_PJ4B */
__v7_setup:
- adr r12, __v7_setup_stack @ the local stack
- stmia r12, {r0-r5, lr} @ v7_invalidate_l1 touches r0-r6
+ adr r0, __v7_setup_stack_ptr
+ ldr r12, [r0]
+ add r12, r12, r0 @ the local stack
+ stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6
bl v7_invalidate_l1
- ldmia r12, {r0-r5, lr}
+ ldmia r12, {r1-r6, lr}
__v7_setup_cont:
and r0, r9, #0xff000000 @ ARM?
@@ -480,11 +484,16 @@ __errata_finish:
orr r0, r0, r6 @ set them
THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions
ret lr @ return to head.S:__ret
+
+ .align 2
+__v7_setup_stack_ptr:
+ .word PHYS_RELATIVE(__v7_setup_stack, .)
ENDPROC(__v7_setup)
+ .bss
.align 2
__v7_setup_stack:
- .space 4 * 7 @ 12 registers
+ .space 4 * 7 @ 7 registers
__INITDATA
diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
index 67d9209..7229d8d 100644
--- a/arch/arm/mm/proc-v7m.S
+++ b/arch/arm/mm/proc-v7m.S
@@ -12,6 +12,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/memory.h>
#include <asm/v7m.h>
#include "proc-macros.S"
@@ -97,19 +98,19 @@ __v7m_setup:
mov r5, #0x00800000
str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority
- @ SVC to run the kernel in this mode
+ @ SVC to switch to handler mode. Notice that this requires sp to
+ @ point to writeable memory because the processor saves
+ @ some registers to the stack.
badr r1, 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
+ ldr sp, =init_thread_union + THREAD_START_SP
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
@@ -123,11 +124,6 @@ __v7m_setup:
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"
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index b8efb8c..93d0b6d 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -125,7 +125,7 @@ static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
}
/*
- * Wrapper that handles both OABI and EABI and assures Thumb2 interworking
+ * Wrappers which handle 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)
@@ -133,6 +133,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor)
return dividend / divisor;
}
+static u32 jit_mod(u32 dividend, u32 divisor)
+{
+ return dividend % divisor;
+}
+
static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
{
inst |= (cond << 28);
@@ -182,19 +187,6 @@ static inline int mem_words_used(struct jit_ctx *ctx)
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;
@@ -206,7 +198,6 @@ static void jit_fill_hole(void *area, unsigned int size)
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
@@ -236,7 +227,7 @@ static void build_prologue(struct jit_ctx *ctx)
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)))
+ if (bpf_needs_clear_a(&ctx->skf->insns[0]))
emit(ARM_MOV_I(r_A, 0), ctx);
/* stack space for the BPF_MEM words */
@@ -471,11 +462,17 @@ static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
#endif
}
-static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
+static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx,
+ int bpf_op)
{
#if __LINUX_ARM_ARCH__ == 7
if (elf_hwcap & HWCAP_IDIVA) {
- emit(ARM_UDIV(rd, rm, rn), ctx);
+ if (bpf_op == BPF_DIV)
+ emit(ARM_UDIV(rd, rm, rn), ctx);
+ else {
+ emit(ARM_UDIV(ARM_R3, rm, rn), ctx);
+ emit(ARM_MLS(rd, rn, ARM_R3, rm), ctx);
+ }
return;
}
#endif
@@ -496,7 +493,8 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
emit(ARM_MOV_R(ARM_R0, rm), ctx);
ctx->seen |= SEEN_CALL;
- emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
+ emit_mov_i(ARM_R3, bpf_op == BPF_DIV ? (u32)jit_udiv : (u32)jit_mod,
+ ctx);
emit_blx_r(ARM_R3, ctx);
if (rd != ARM_R0)
@@ -698,13 +696,27 @@ load_ind:
if (k == 1)
break;
emit_mov_i(r_scratch, k, ctx);
- emit_udiv(r_A, r_A, r_scratch, ctx);
+ emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_DIV);
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);
+ emit_udivmod(r_A, r_A, r_X, ctx, BPF_DIV);
+ break;
+ case BPF_ALU | BPF_MOD | BPF_K:
+ if (k == 1) {
+ emit_mov_i(r_A, 0, ctx);
+ break;
+ }
+ emit_mov_i(r_scratch, k, ctx);
+ emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_MOD);
+ break;
+ case BPF_ALU | BPF_MOD | BPF_X:
+ update_on_xread(ctx);
+ emit(ARM_CMP_I(r_X, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+ emit_udivmod(r_A, r_A, r_X, ctx, BPF_MOD);
break;
case BPF_ALU | BPF_OR | BPF_K:
/* A |= K */
@@ -744,7 +756,8 @@ load_ind:
case BPF_ALU | BPF_RSH | BPF_K:
if (unlikely(k > 31))
return -1;
- emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ if (k)
+ emit(ARM_LSR_I(r_A, r_A, k), ctx);
break;
case BPF_ALU | BPF_RSH | BPF_X:
update_on_xread(ctx);
@@ -1035,7 +1048,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
}
build_epilogue(&ctx);
- flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
+ flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));
#if __LINUX_ARM_ARCH__ < 7
if (ctx.imm_count)
@@ -1048,7 +1061,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
set_memory_ro((unsigned long)header, header->pages);
fp->bpf_func = (void *)ctx.target;
- fp->jited = true;
+ fp->jited = 1;
out:
kfree(ctx.offsets);
return;
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
index 4b17d5ab..c46fca2 100644
--- a/arch/arm/net/bpf_jit_32.h
+++ b/arch/arm/net/bpf_jit_32.h
@@ -115,6 +115,8 @@
#define ARM_INST_UMULL 0x00800090
+#define ARM_INST_MLS 0x00600090
+
/*
* 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
@@ -210,4 +212,7 @@
#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \
| (rd_lo) << 12 | (rm) << 8 | rn)
+#define ARM_MLS(rd, rn, rm, ra) (ARM_INST_MLS | (rd) << 16 | (rn) | (rm) << 8 \
+ | (ra) << 12)
+
#endif /* PFILTER_OPCODES_ARM_H */
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 8ca94d3..7a327bd 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -36,6 +36,7 @@
*/
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/device.h>
@@ -137,6 +138,31 @@ static int omap_dm_timer_reset(struct omap_dm_timer *timer)
return 0;
}
+static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
+{
+ int ret;
+ struct clk *parent;
+
+ /*
+ * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
+ * do not call clk_get() for these devices.
+ */
+ if (!timer->fclk)
+ return -ENODEV;
+
+ parent = clk_get(&timer->pdev->dev, NULL);
+ if (IS_ERR(parent))
+ return -ENODEV;
+
+ ret = clk_set_parent(timer->fclk, parent);
+ if (ret < 0)
+ pr_err("%s: failed to set parent\n", __func__);
+
+ clk_put(parent);
+
+ return ret;
+}
+
static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
int rc;
@@ -166,7 +192,11 @@ static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
__omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
- return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+ rc = omap_dm_timer_of_set_source(timer);
+ if (rc == -ENODEV)
+ return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+
+ return rc;
}
static inline u32 omap_dm_timer_reserved_systimer(int id)
@@ -504,6 +534,12 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
if (IS_ERR(timer->fclk))
return -EINVAL;
+#if defined(CONFIG_COMMON_CLK)
+ /* Check if the clock has configurable parents */
+ if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
+ return 0;
+#endif
+
switch (source) {
case OMAP_TIMER_SRC_SYS_CLK:
parent_name = "timer_sys_ck";
@@ -943,6 +979,10 @@ static const struct of_device_id omap_timer_match[] = {
.compatible = "ti,am335x-timer-1ms",
.data = &omap3plus_pdata,
},
+ {
+ .compatible = "ti,dm816-timer",
+ .data = &omap3plus_pdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, omap_timer_match);
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 8861c36..78c8bf4 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -21,7 +21,6 @@
#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 */
@@ -589,26 +588,6 @@ void __init orion_spi_1_init(unsigned long mapbase)
}
/*****************************************************************************
- * 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);
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 7bd22d8..f740693 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -154,8 +154,7 @@ err_out:
*/
static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
{
- struct orion_gpio_chip *ochip =
- container_of(chip, struct orion_gpio_chip, chip);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
if (orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK) ||
orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
@@ -166,8 +165,7 @@ static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
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);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
unsigned long flags;
if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK))
@@ -182,8 +180,7 @@ static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
static int orion_gpio_get(struct gpio_chip *chip, unsigned pin)
{
- struct orion_gpio_chip *ochip =
- container_of(chip, struct orion_gpio_chip, chip);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
int val;
if (readl(GPIO_IO_CONF(ochip)) & (1 << pin)) {
@@ -198,8 +195,7 @@ static int orion_gpio_get(struct gpio_chip *chip, unsigned pin)
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);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
unsigned long flags;
if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
@@ -216,8 +212,7 @@ orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value)
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);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&ochip->lock, flags);
@@ -227,8 +222,7 @@ static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
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);
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
return irq_create_mapping(ochip->domain,
ochip->secondary_irq_base + pin);
@@ -445,8 +439,8 @@ static void gpio_irq_handler(struct irq_desc *desc)
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);
+
+ struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
int i;
@@ -567,7 +561,7 @@ void __init orion_gpio_init(struct device_node *np,
ochip->mask_offset = mask_offset;
ochip->secondary_irq_base = secondary_irq_base;
- gpiochip_add(&ochip->chip);
+ gpiochip_add_data(&ochip->chip, ochip);
/*
* Mask and clear GPIO interrupts.
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index d9a24f6..9e6d76a 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -75,8 +75,6 @@ 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,
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
index 8c1fc06..5b63b28 100644
--- a/arch/arm/plat-orion/irq.c
+++ b/arch/arm/plat-orion/irq.c
@@ -18,7 +18,6 @@
#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)
{
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
index 7310bcf..5b4ff93 100644
--- a/arch/arm/plat-orion/mpp.c
+++ b/arch/arm/plat-orion/mpp.c
@@ -13,7 +13,6 @@
#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>
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index 8085a8a..ffb93db 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -18,6 +18,7 @@
#include <linux/irq.h>
#include <linux/sched_clock.h>
#include <plat/time.h>
+#include <asm/delay.h>
/*
* MBus bridge block registers.
@@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base)
timer_base = _timer_base;
}
+static unsigned long orion_delay_timer_read(void)
+{
+ return ~readl(timer_base + TIMER0_VAL_OFF);
+}
+
+static struct delay_timer orion_delay_timer = {
+ .read_current_timer = orion_delay_timer_read,
+};
+
void __init
orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
unsigned int irq, unsigned int tclk)
@@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
ticks_per_jiffy = (tclk + HZ/2) / HZ;
+ orion_delay_timer.freq = tclk;
+ register_current_timer_delay(&orion_delay_timer);
+
/*
* Set scale and timer for sched_clock.
*/
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 1fc9419..557b134 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -1,8 +1,9 @@
#
# Makefile for code common across different PXA processor families
#
+ccflags-$(CONFIG_ARCH_MMP) := -I$(srctree)/$(src)/include
-obj-y := dma.o
+obj-$(CONFIG_ARCH_PXA) := dma.o
obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
index daa1a65..ba13f79 100644
--- a/arch/arm/plat-pxa/ssp.c
+++ b/arch/arm/plat-pxa/ssp.c
@@ -34,7 +34,6 @@
#include <linux/of_device.h>
#include <asm/irq.h>
-#include <mach/hardware.h>
static DEFINE_MUTEX(ssp_lock);
static LIST_HEAD(ssp_list);
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 57729b9..e8229b9 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -39,7 +39,6 @@ config S3C_LOWLEVEL_UART_PORT
config SAMSUNG_ATAGS
def_bool n
- depends on !ARCH_MULTIPLATFORM
depends on ATAGS
help
This option enables ATAGS based boot support code for
@@ -70,6 +69,7 @@ config S3C_GPIO_TRACK
config S3C_ADC
bool "ADC common driver support"
+ depends on !ARCH_MULTIPLATFORM
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
@@ -225,6 +225,9 @@ config S3C24XX_PWM
Support for exporting the PWM timer blocks via the pwm device
system
+config GPIO_SAMSUNG
+ def_bool y
+
config SAMSUNG_PM_GPIO
bool
default y if GPIO_SAMSUNG && PM
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 8c91176..be172ef 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -4,7 +4,8 @@
#
# Licensed under GPLv2
-ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include
+ccflags-$(CONFIG_ARCH_S3C64XX) := -I$(srctree)/arch/arm/mach-s3c64xx/include
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include
# Objects we always build independent of SoC choice
@@ -21,6 +22,8 @@ obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o
obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o
obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o
+obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o
+
# PM support
obj-$(CONFIG_PM_SLEEP) += pm-common.o
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 83c7d15..b53d4ff 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -36,7 +36,7 @@
#include <linux/platform_data/s3c-hsotg.h>
#include <linux/platform_data/dma-s3c24xx.h>
-#include <media/s5p_hdmi.h>
+#include <linux/platform_data/media/s5p_hdmi.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
@@ -65,6 +65,7 @@
#include <linux/platform_data/usb-ohci-s3c2410.h>
#include <plat/usb-phy.h>
#include <plat/regs-spi.h>
+#include <linux/platform_data/asoc-s3c.h>
#include <linux/platform_data/spi-s3c64xx.h>
static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
@@ -74,9 +75,15 @@ static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
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"),
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+#ifdef CONFIG_S3C24XX_DMAC
+ .dma_filter = s3c24xx_dma_filter,
+#endif
+ .dma_playback = (void *)DMACH_PCM_OUT,
+ .dma_capture = (void *)DMACH_PCM_IN,
+ .dma_capture_mic = (void *)DMACH_MIC_IN,
};
struct platform_device s3c_device_ac97 = {
@@ -87,6 +94,7 @@ struct platform_device s3c_device_ac97 = {
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_ac97_pdata,
}
};
#endif /* CONFIG_CPU_S3C2440 */
@@ -111,12 +119,12 @@ struct platform_device s3c_device_adc = {
#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),
+ [1] = DEFINE_RES_IRQ(IRQ_ADC),
+ [2] = DEFINE_RES_IRQ(IRQ_TC),
};
struct platform_device s3c_device_adc = {
- .name = "samsung-adc",
+ .name = "exynos-adc",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_adc_resource),
.resource = s3c_adc_resource,
@@ -566,6 +574,14 @@ static struct resource s3c_iis_resource[] = {
[0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
};
+static struct s3c_audio_pdata s3c_iis_platdata = {
+#ifdef CONFIG_S3C24XX_DMAC
+ .dma_filter = s3c24xx_dma_filter,
+#endif
+ .dma_playback = (void *)DMACH_I2S_OUT,
+ .dma_capture = (void *)DMACH_I2S_IN,
+};
+
struct platform_device s3c_device_iis = {
.name = "s3c24xx-iis",
.id = -1,
@@ -574,6 +590,7 @@ struct platform_device s3c_device_iis = {
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c_iis_platdata,
}
};
#endif /* CONFIG_PLAT_S3C24XX */
@@ -939,31 +956,19 @@ void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_
#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)
+void __init s3c64xx_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);
+ &s3c_device_adc);
}
#endif /* CONFIG_SAMSUNG_DEV_TS */
@@ -1042,11 +1047,11 @@ struct platform_device s3c_device_usb_hsotg = {
},
};
-void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
+void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
{
- struct s3c_hsotg_plat *npd;
+ struct dwc2_hsotg_plat *npd;
- npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
+ npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat),
&s3c_device_usb_hsotg);
if (!npd->phy_init)
@@ -1100,9 +1105,7 @@ struct platform_device s3c_device_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),
+ [1] = DEFINE_RES_IRQ(IRQ_SPI0),
};
struct platform_device s3c64xx_device_spi0 = {
@@ -1130,6 +1133,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
+ pd.dma_tx = (void *)DMACH_SPI0_TX;
+ pd.dma_rx = (void *)DMACH_SPI0_RX;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
@@ -1145,9 +1150,7 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
#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),
+ [1] = DEFINE_RES_IRQ(IRQ_SPI1),
};
struct platform_device s3c64xx_device_spi1 = {
@@ -1175,12 +1178,15 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
+ pd.dma_tx = (void *)DMACH_SPI1_TX;
+ pd.dma_rx = (void *)DMACH_SPI1_RX;
#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 */
@@ -1188,9 +1194,7 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
#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),
+ [1] = DEFINE_RES_IRQ(IRQ_SPI2),
};
struct platform_device s3c64xx_device_spi2 = {
@@ -1218,6 +1222,8 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
+ pd.dma_tx = (void *)DMACH_SPI2_TX;
+ pd.dma_rx = (void *)DMACH_SPI2_RX;
#if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
diff --git a/arch/arm/plat-samsung/gpio-samsung.c b/arch/arm/plat-samsung/gpio-samsung.c
new file mode 100644
index 0000000..7861488
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio-samsung.c
@@ -0,0 +1,1328 @@
+/*
+ * Copyright (c) 2009-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/
+ *
+ * SAMSUNG - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+
+#include <asm/irq.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/pm.h>
+
+int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup;
+
+ pup = __raw_readl(reg);
+ pup &= ~(3 << shift);
+ pup |= pull << shift;
+ __raw_writel(pup, reg);
+
+ return 0;
+}
+
+samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup = __raw_readl(reg);
+
+ pup >>= shift;
+ pup &= 0x3;
+
+ return (__force samsung_gpio_pull_t)pup;
+}
+
+int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull)
+{
+ switch (pull) {
+ case S3C_GPIO_PULL_NONE:
+ pull = 0x01;
+ break;
+ case S3C_GPIO_PULL_UP:
+ pull = 0x00;
+ break;
+ case S3C_GPIO_PULL_DOWN:
+ pull = 0x02;
+ break;
+ }
+ return samsung_gpio_setpull_updown(chip, off, pull);
+}
+
+samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ samsung_gpio_pull_t pull;
+
+ pull = samsung_gpio_getpull_updown(chip, off);
+
+ switch (pull) {
+ case 0x00:
+ pull = S3C_GPIO_PULL_UP;
+ break;
+ case 0x01:
+ case 0x03:
+ pull = S3C_GPIO_PULL_NONE;
+ break;
+ case 0x02:
+ pull = S3C_GPIO_PULL_DOWN;
+ break;
+ }
+
+ return pull;
+}
+
+static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull,
+ samsung_gpio_pull_t updown)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ if (pull == updown)
+ pup &= ~(1 << off);
+ else if (pull == S3C_GPIO_PULL_NONE)
+ pup |= (1 << off);
+ else
+ return -EINVAL;
+
+ __raw_writel(pup, reg);
+ return 0;
+}
+
+static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
+ unsigned int off,
+ samsung_gpio_pull_t updown)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ pup &= (1 << off);
+ return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull)
+{
+ return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
+ unsigned int off, samsung_gpio_pull_t pull)
+{
+ return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+
+/*
+ * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ * 00 = input
+ * 01 = output
+ * 1x = special function
+ */
+
+static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off * 2;
+ u32 con;
+
+ if (samsung_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ if (cfg > 3)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x3 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
+ * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+
+static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off * 2;
+ con &= 3;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
+
+/*
+ * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+ */
+
+static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ if (samsung_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0xf << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to samsung_gpio_setcfg_4bit().
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ */
+
+static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ con = __raw_readl(reg);
+ con >>= shift;
+ con &= 0xf;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/*
+ * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+ */
+
+static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off;
+ u32 con;
+
+ if (samsung_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+
+ /* Map output to 0, and SFN2 to 1 */
+ cfg -= 1;
+ if (cfg > 1)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x1 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+/*
+ * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ * @sa samsung_gpio_getcfg_4bit
+ */
+
+static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off;
+ con &= 1;
+ con++;
+
+ return S3C_GPIO_SFN(con);
+}
+#endif
+
+static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chipcfg++) {
+ if (!chipcfg->set_config)
+ chipcfg->set_config = samsung_gpio_setcfg_4bit;
+ if (!chipcfg->get_config)
+ chipcfg->get_config = samsung_gpio_getcfg_4bit;
+ if (!chipcfg->set_pull)
+ chipcfg->set_pull = samsung_gpio_setpull_updown;
+ if (!chipcfg->get_pull)
+ chipcfg->get_pull = samsung_gpio_getpull_updown;
+ }
+}
+
+struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
+ .set_config = samsung_gpio_setcfg_2bit,
+ .get_config = samsung_gpio_getcfg_2bit,
+};
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
+ .set_config = s3c24xx_gpio_setcfg_abank,
+ .get_config = s3c24xx_gpio_getcfg_abank,
+};
+#endif
+
+static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
+ [0] = {
+ .cfg_eint = 0x0,
+ },
+ [1] = {
+ .cfg_eint = 0x3,
+ },
+ [2] = {
+ .cfg_eint = 0x7,
+ },
+ [3] = {
+ .cfg_eint = 0xF,
+ },
+ [4] = {
+ .cfg_eint = 0x0,
+ .set_config = samsung_gpio_setcfg_2bit,
+ .get_config = samsung_gpio_getcfg_2bit,
+ },
+ [5] = {
+ .cfg_eint = 0x2,
+ .set_config = samsung_gpio_setcfg_2bit,
+ .get_config = samsung_gpio_getcfg_2bit,
+ },
+ [6] = {
+ .cfg_eint = 0x3,
+ .set_config = samsung_gpio_setcfg_2bit,
+ .get_config = samsung_gpio_getcfg_2bit,
+ },
+ [7] = {
+ .set_config = samsung_gpio_setcfg_2bit,
+ .get_config = samsung_gpio_getcfg_2bit,
+ },
+};
+
+/*
+ * Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ * gpio n: 2 bits starting at (2*n)
+ * 00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ * bit n: data bit n
+*/
+
+static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long con;
+
+ samsung_gpio_lock(ourchip, flags);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+
+ __raw_writel(con, base + 0x00);
+
+ samsung_gpio_unlock(ourchip, flags);
+ return 0;
+}
+
+static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ samsung_gpio_lock(ourchip, flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+ con |= 1 << (offset * 2);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ samsung_gpio_unlock(ourchip, flags);
+ return 0;
+}
+
+/*
+ * The samsung_gpiolib_4bit routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ * bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
+ * state of the output.
+ */
+
+static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long con;
+
+ con = __raw_readl(base + GPIOCON_OFF);
+ if (ourchip->bitmap_gpio_int & BIT(offset))
+ con |= 0xf << con_4bit_shift(offset);
+ else
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, base + GPIOCON_OFF);
+
+ pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
+
+ return 0;
+}
+
+static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long con;
+ unsigned long dat;
+
+ con = __raw_readl(base + GPIOCON_OFF);
+ con &= ~(0xf << con_4bit_shift(offset));
+ con |= 0x1 << con_4bit_shift(offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(dat, base + GPIODAT_OFF);
+ __raw_writel(con, base + GPIOCON_OFF);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+ return 0;
+}
+
+/*
+ * The next set of routines are for the case where the GPIO configuration
+ * registers are 4 bits per GPIO but there is more than one register (the
+ * bank has more than 8 GPIOs.
+ *
+ * This case is the similar to the 4 bit case, but the registers are as
+ * follows:
+ *
+ * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x08: Data register, 1 bit per gpio
+ * bit n: data bit n
+ *
+ * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
+ * routines we store the 'base + 0x4' address so that these routines see
+ * the data register at ourchip->base + 0x04.
+ */
+
+static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+
+ if (offset > 7)
+ offset -= 8;
+ else
+ regcon -= 4;
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, regcon);
+
+ pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
+
+ return 0;
+}
+
+static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+ unsigned long dat;
+ unsigned con_offset = offset;
+
+ if (con_offset > 7)
+ con_offset -= 8;
+ else
+ regcon -= 4;
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(con_offset));
+ con |= 0x1 << con_4bit_shift(con_offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(dat, base + GPIODAT_OFF);
+ __raw_writel(con, regcon);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+ return 0;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/* The next set of routines are for the case of s3c24xx bank a */
+
+static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
+{
+ return -EINVAL;
+}
+
+static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ dat = __raw_readl(base + 0x04);
+
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+
+ __raw_writel(dat, base + 0x04);
+
+ con &= ~(1 << offset);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+ return 0;
+}
+#endif
+
+static void samsung_gpiolib_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+
+ samsung_gpio_lock(ourchip, flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ samsung_gpio_unlock(ourchip, flags);
+}
+
+static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+ unsigned long val;
+
+ val = __raw_readl(ourchip->base + 0x04);
+ val >>= offset;
+ val &= 1;
+
+ return val;
+}
+
+/*
+ * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own samsung_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
+{
+ unsigned int gpn;
+ int i;
+
+ gpn = chip->chip.base;
+ for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+ BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+ s3c_gpios[gpn] = chip;
+ }
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/*
+ * samsung_gpiolib_add() - add the Samsung gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+
+static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
+{
+ struct gpio_chip *gc = &chip->chip;
+ int ret;
+
+ BUG_ON(!chip->base);
+ BUG_ON(!gc->label);
+ BUG_ON(!gc->ngpio);
+
+ spin_lock_init(&chip->lock);
+
+ if (!gc->direction_input)
+ gc->direction_input = samsung_gpiolib_2bit_input;
+ if (!gc->direction_output)
+ gc->direction_output = samsung_gpiolib_2bit_output;
+ if (!gc->set)
+ gc->set = samsung_gpiolib_set;
+ if (!gc->get)
+ gc->get = samsung_gpiolib_get;
+
+#ifdef CONFIG_PM
+ if (chip->pm != NULL) {
+ if (!chip->pm->save || !chip->pm->resume)
+ pr_err("gpio: %s has missing PM functions\n",
+ gc->label);
+ } else
+ pr_err("gpio: %s has no PM function\n", gc->label);
+#endif
+
+ /* gpiochip_add() prints own failure message on error. */
+ ret = gpiochip_add_data(gc, chip);
+ if (ret >= 0)
+ s3c_gpiolib_track(chip);
+}
+
+static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
+ int nr_chips, void __iomem *base)
+{
+ int i;
+ struct gpio_chip *gc = &chip->chip;
+
+ for (i = 0 ; i < nr_chips; i++, chip++) {
+ /* skip banks not present on SoC */
+ if (chip->chip.base >= S3C_GPIO_END)
+ continue;
+
+ if (!chip->config)
+ chip->config = &s3c24xx_gpiocfg_default;
+ if (!chip->pm)
+ chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+ if ((base != NULL) && (chip->base == NULL))
+ chip->base = base + ((i) * 0x10);
+
+ if (!gc->direction_input)
+ gc->direction_input = samsung_gpiolib_2bit_input;
+ if (!gc->direction_output)
+ gc->direction_output = samsung_gpiolib_2bit_output;
+
+ samsung_gpiolib_add(chip);
+ }
+}
+
+static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
+ int nr_chips, void __iomem *base,
+ unsigned int offset)
+{
+ int i;
+
+ for (i = 0 ; i < nr_chips; i++, chip++) {
+ chip->chip.direction_input = samsung_gpiolib_2bit_input;
+ chip->chip.direction_output = samsung_gpiolib_2bit_output;
+
+ if (!chip->config)
+ chip->config = &samsung_gpio_cfgs[7];
+ if (!chip->pm)
+ chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+ if ((base != NULL) && (chip->base == NULL))
+ chip->base = base + ((i) * offset);
+
+ samsung_gpiolib_add(chip);
+ }
+}
+
+/*
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+
+static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
+ int nr_chips, void __iomem *base)
+{
+ int i;
+
+ for (i = 0 ; i < nr_chips; i++, chip++) {
+ chip->chip.direction_input = samsung_gpiolib_4bit_input;
+ chip->chip.direction_output = samsung_gpiolib_4bit_output;
+
+ if (!chip->config)
+ chip->config = &samsung_gpio_cfgs[2];
+ if (!chip->pm)
+ chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+ if ((base != NULL) && (chip->base == NULL))
+ chip->base = base + ((i) * 0x20);
+
+ chip->bitmap_gpio_int = 0;
+
+ samsung_gpiolib_add(chip);
+ }
+}
+
+static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ chip->chip.direction_input = samsung_gpiolib_4bit2_input;
+ chip->chip.direction_output = samsung_gpiolib_4bit2_output;
+
+ if (!chip->config)
+ chip->config = &samsung_gpio_cfgs[2];
+ if (!chip->pm)
+ chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+
+ samsung_gpiolib_add(chip);
+ }
+}
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
+
+ return samsung_chip->irq_base + offset;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset < 4) {
+ if (soc_is_s3c2412())
+ return IRQ_EINT0_2412 + offset;
+ else
+ return IRQ_EINT0 + offset;
+ }
+
+ if (offset < 8)
+ return IRQ_EINT4 + offset - 4;
+
+ return -EINVAL;
+}
+#endif
+
+#ifdef CONFIG_ARCH_S3C64XX
+static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+#endif
+
+struct samsung_gpio_chip s3c24xx_gpios[] = {
+#ifdef CONFIG_PLAT_S3C24XX
+ {
+ .config = &s3c24xx_gpiocfg_banka,
+ .chip = {
+ .base = S3C2410_GPA(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOA",
+ .ngpio = 27,
+ .direction_input = s3c24xx_gpiolib_banka_input,
+ .direction_output = s3c24xx_gpiolib_banka_output,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPB(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOB",
+ .ngpio = 11,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPC(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOC",
+ .ngpio = 16,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPD(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOD",
+ .ngpio = 16,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPE(0),
+ .label = "GPIOE",
+ .owner = THIS_MODULE,
+ .ngpio = 16,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPF(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOF",
+ .ngpio = 8,
+ .to_irq = s3c24xx_gpiolib_fbank_to_irq,
+ },
+ }, {
+ .irq_base = IRQ_EINT8,
+ .chip = {
+ .base = S3C2410_GPG(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOG",
+ .ngpio = 16,
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .chip = {
+ .base = S3C2410_GPH(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOH",
+ .ngpio = 15,
+ },
+ },
+ /* GPIOS for the S3C2443 and later devices. */
+ {
+ .base = S3C2440_GPJCON,
+ .chip = {
+ .base = S3C2410_GPJ(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOJ",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPKCON,
+ .chip = {
+ .base = S3C2410_GPK(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOK",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPLCON,
+ .chip = {
+ .base = S3C2410_GPL(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOL",
+ .ngpio = 15,
+ },
+ }, {
+ .base = S3C2443_GPMCON,
+ .chip = {
+ .base = S3C2410_GPM(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOM",
+ .ngpio = 2,
+ },
+ },
+#endif
+};
+
+/*
+ * GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 8 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * D 5 4Bit Yes 3
+ * E 5 4Bit Yes None
+ * F 16 2Bit Yes 4 [1]
+ * G 7 4Bit Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * K 16 4Bit[2] No None
+ * L 15 4Bit[2] No None
+ * M 6 4Bit No IRQ_EINT
+ * N 16 2Bit No IRQ_EINT
+ * O 16 2Bit Yes 7
+ * P 15 2Bit Yes 8
+ * Q 9 2Bit Yes 9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+ {
+ .chip = {
+ .base = S3C64XX_GPA(0),
+ .ngpio = S3C64XX_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .chip = {
+ .base = S3C64XX_GPB(0),
+ .ngpio = S3C64XX_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .chip = {
+ .base = S3C64XX_GPC(0),
+ .ngpio = S3C64XX_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .chip = {
+ .base = S3C64XX_GPD(0),
+ .ngpio = S3C64XX_GPIO_D_NR,
+ .label = "GPD",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[0],
+ .chip = {
+ .base = S3C64XX_GPE(0),
+ .ngpio = S3C64XX_GPIO_E_NR,
+ .label = "GPE",
+ },
+ }, {
+ .base = S3C64XX_GPG_BASE,
+ .chip = {
+ .base = S3C64XX_GPG(0),
+ .ngpio = S3C64XX_GPIO_G_NR,
+ .label = "GPG",
+ },
+ }, {
+ .base = S3C64XX_GPM_BASE,
+ .config = &samsung_gpio_cfgs[1],
+ .chip = {
+ .base = S3C64XX_GPM(0),
+ .ngpio = S3C64XX_GPIO_M_NR,
+ .label = "GPM",
+ .to_irq = s3c64xx_gpiolib_mbank_to_irq,
+ },
+ },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+ {
+ .base = S3C64XX_GPH_BASE + 0x4,
+ .chip = {
+ .base = S3C64XX_GPH(0),
+ .ngpio = S3C64XX_GPIO_H_NR,
+ .label = "GPH",
+ },
+ }, {
+ .base = S3C64XX_GPK_BASE + 0x4,
+ .config = &samsung_gpio_cfgs[0],
+ .chip = {
+ .base = S3C64XX_GPK(0),
+ .ngpio = S3C64XX_GPIO_K_NR,
+ .label = "GPK",
+ },
+ }, {
+ .base = S3C64XX_GPL_BASE + 0x4,
+ .config = &samsung_gpio_cfgs[1],
+ .chip = {
+ .base = S3C64XX_GPL(0),
+ .ngpio = S3C64XX_GPIO_L_NR,
+ .label = "GPL",
+ .to_irq = s3c64xx_gpiolib_lbank_to_irq,
+ },
+ },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
+#ifdef CONFIG_ARCH_S3C64XX
+ {
+ .base = S3C64XX_GPF_BASE,
+ .config = &samsung_gpio_cfgs[6],
+ .chip = {
+ .base = S3C64XX_GPF(0),
+ .ngpio = S3C64XX_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[7],
+ .chip = {
+ .base = S3C64XX_GPI(0),
+ .ngpio = S3C64XX_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[7],
+ .chip = {
+ .base = S3C64XX_GPJ(0),
+ .ngpio = S3C64XX_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[6],
+ .chip = {
+ .base = S3C64XX_GPO(0),
+ .ngpio = S3C64XX_GPIO_O_NR,
+ .label = "GPO",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[6],
+ .chip = {
+ .base = S3C64XX_GPP(0),
+ .ngpio = S3C64XX_GPIO_P_NR,
+ .label = "GPP",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[6],
+ .chip = {
+ .base = S3C64XX_GPQ(0),
+ .ngpio = S3C64XX_GPIO_Q_NR,
+ .label = "GPQ",
+ },
+ }, {
+ .base = S3C64XX_GPN_BASE,
+ .irq_base = IRQ_EINT(0),
+ .config = &samsung_gpio_cfgs[5],
+ .chip = {
+ .base = S3C64XX_GPN(0),
+ .ngpio = S3C64XX_GPIO_N_NR,
+ .label = "GPN",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ },
+#endif
+};
+
+/* TODO: cleanup soc_is_* */
+static __init int samsung_gpiolib_init(void)
+{
+ /*
+ * Currently there are two drivers that can provide GPIO support for
+ * Samsung SoCs. For device tree enabled platforms, the new
+ * pinctrl-samsung driver is used, providing both GPIO and pin control
+ * interfaces. For legacy (non-DT) platforms this driver is used.
+ */
+ if (of_have_populated_dt())
+ return 0;
+
+ if (soc_is_s3c24xx()) {
+ samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
+ ARRAY_SIZE(samsung_gpio_cfgs));
+ s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
+ ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
+ } else if (soc_is_s3c64xx()) {
+ samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
+ ARRAY_SIZE(samsung_gpio_cfgs));
+ samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
+ ARRAY_SIZE(s3c64xx_gpios_2bit),
+ S3C64XX_VA_GPIO + 0xE0, 0x20);
+ samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
+ ARRAY_SIZE(s3c64xx_gpios_4bit),
+ S3C64XX_VA_GPIO);
+ samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
+ ARRAY_SIZE(s3c64xx_gpios_4bit2));
+ }
+
+ return 0;
+}
+core_initcall(samsung_gpiolib_init);
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+ struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ int ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ samsung_gpio_lock(chip, flags);
+ ret = samsung_gpio_do_setcfg(chip, offset, config);
+ samsung_gpio_unlock(chip, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+ unsigned int cfg)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+ unsigned int cfg, samsung_gpio_pull_t pull)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ s3c_gpio_setpull(start, pull);
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+ struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+ unsigned long flags;
+ unsigned ret = 0;
+ int offset;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ samsung_gpio_lock(chip, flags);
+ ret = samsung_gpio_do_getcfg(chip, offset);
+ samsung_gpio_unlock(chip, flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
+{
+ struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset, ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ samsung_gpio_lock(chip, flags);
+ ret = samsung_gpio_do_setpull(chip, offset, pull);
+ samsung_gpio_unlock(chip, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+ struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ u32 pup = 0;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ samsung_gpio_lock(chip, flags);
+ pup = samsung_gpio_do_getpull(chip, offset);
+ samsung_gpio_unlock(chip, flags);
+ }
+
+ return (__force samsung_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
+#ifdef CONFIG_PLAT_S3C24XX
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+ unsigned long flags;
+ unsigned long misccr;
+
+ local_irq_save(flags);
+ misccr = __raw_readl(S3C24XX_MISCCR);
+ misccr &= ~clear;
+ misccr ^= change;
+ __raw_writel(misccr, S3C24XX_MISCCR);
+ local_irq_restore(flags);
+
+ return misccr;
+}
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 7f415ce..9dd562a 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -41,14 +41,6 @@ static inline int s3c64xx_pm_init(void)
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);
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
index 11fbbc2..3776f7e 100644
--- a/arch/arm/plat-samsung/init.c
+++ b/arch/arm/plat-samsung/init.c
@@ -152,6 +152,11 @@ static int __init s3c_arch_init(void)
{
int ret;
+ /* init is only needed for ATAGS based platforms */
+ if (!IS_ENABLED(CONFIG_ATAGS) ||
+ (!soc_is_s3c24xx() && !soc_is_s3c64xx()))
+ return 0;
+
// do the correct init for cpu
if (cpu == NULL) {
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
index 04aff2c..70f2f69 100644
--- a/arch/arm/plat-samsung/pm-check.c
+++ b/arch/arm/plat-samsung/pm-check.c
@@ -53,8 +53,8 @@ static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
if (ptr->child != NULL)
s3c_pm_run_res(ptr->child, fn, arg);
- if ((ptr->flags & IORESOURCE_MEM) &&
- strcmp(ptr->name, "System RAM") == 0) {
+ if ((ptr->flags & IORESOURCE_SYSTEM_RAM)
+ == IORESOURCE_SYSTEM_RAM) {
S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
(unsigned long)ptr->start,
(unsigned long)ptr->end);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 82777c6..d7803b4 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -23,14 +23,10 @@
#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>
diff --git a/arch/arm/vdso/vdso.S b/arch/arm/vdso/vdso.S
index b2b97e3..a62a7b6 100644
--- a/arch/arm/vdso/vdso.S
+++ b/arch/arm/vdso/vdso.S
@@ -23,9 +23,8 @@
#include <linux/const.h>
#include <asm/page.h>
- __PAGE_ALIGNED_DATA
-
.globl vdso_start, vdso_end
+ .section .data..ro_after_init
.balign PAGE_SIZE
vdso_start:
.incbin "arch/arm/vdso/vdso.so"
diff --git a/arch/arm/vdso/vdsomunge.c b/arch/arm/vdso/vdsomunge.c
index 0cebd98..f645527 100644
--- a/arch/arm/vdso/vdsomunge.c
+++ b/arch/arm/vdso/vdsomunge.c
@@ -66,7 +66,7 @@
((((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8) | \
- (((x) & 0xff000000) << 24))
+ (((x) & 0xff000000) >> 24))
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define HOST_ORDER ELFDATA2LSB
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index eeeab07..75cd734 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -12,6 +12,7 @@
#include <xen/page.h>
#include <xen/interface/sched.h>
#include <xen/xen-ops.h>
+#include <asm/paravirt.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <asm/system_misc.h>
@@ -25,6 +26,10 @@
#include <linux/cpufreq.h>
#include <linux/cpu.h>
#include <linux/console.h>
+#include <linux/pvclock_gtod.h>
+#include <linux/time64.h>
+#include <linux/timekeeping.h>
+#include <linux/timekeeper_internal.h>
#include <linux/mm.h>
@@ -79,6 +84,83 @@ int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
}
EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
+static unsigned long long xen_stolen_accounting(int cpu)
+{
+ struct vcpu_runstate_info state;
+
+ BUG_ON(cpu != smp_processor_id());
+
+ xen_get_runstate_snapshot(&state);
+
+ WARN_ON(state.state != RUNSTATE_running);
+
+ return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline];
+}
+
+static void xen_read_wallclock(struct timespec64 *ts)
+{
+ u32 version;
+ struct timespec64 now, ts_monotonic;
+ struct shared_info *s = HYPERVISOR_shared_info;
+ struct pvclock_wall_clock *wall_clock = &(s->wc);
+
+ /* get wallclock at system boot */
+ do {
+ version = wall_clock->version;
+ rmb(); /* fetch version before time */
+ now.tv_sec = ((uint64_t)wall_clock->sec_hi << 32) | wall_clock->sec;
+ now.tv_nsec = wall_clock->nsec;
+ rmb(); /* fetch time before checking version */
+ } while ((wall_clock->version & 1) || (version != wall_clock->version));
+
+ /* time since system boot */
+ ktime_get_ts64(&ts_monotonic);
+ *ts = timespec64_add(now, ts_monotonic);
+}
+
+static int xen_pvclock_gtod_notify(struct notifier_block *nb,
+ unsigned long was_set, void *priv)
+{
+ /* Protected by the calling core code serialization */
+ static struct timespec64 next_sync;
+
+ struct xen_platform_op op;
+ struct timespec64 now, system_time;
+ struct timekeeper *tk = priv;
+
+ now.tv_sec = tk->xtime_sec;
+ now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
+ system_time = timespec64_add(now, tk->wall_to_monotonic);
+
+ /*
+ * We only take the expensive HV call when the clock was set
+ * or when the 11 minutes RTC synchronization time elapsed.
+ */
+ if (!was_set && timespec64_compare(&now, &next_sync) < 0)
+ return NOTIFY_OK;
+
+ op.cmd = XENPF_settime64;
+ op.u.settime64.mbz = 0;
+ op.u.settime64.secs = now.tv_sec;
+ op.u.settime64.nsecs = now.tv_nsec;
+ op.u.settime64.system_time = timespec64_to_ns(&system_time);
+ (void)HYPERVISOR_platform_op(&op);
+
+ /*
+ * Move the next drift compensation time 11 minutes
+ * ahead. That's emulating the sync_cmos_clock() update for
+ * the hardware RTC.
+ */
+ next_sync = now;
+ next_sync.tv_sec += 11 * 60;
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block xen_pvclock_gtod_notifier = {
+ .notifier_call = xen_pvclock_gtod_notify,
+};
+
static void xen_percpu_init(void)
{
struct vcpu_register_vcpu_info info;
@@ -86,16 +168,27 @@ static void xen_percpu_init(void)
int err;
int cpu = get_cpu();
+ /*
+ * VCPUOP_register_vcpu_info cannot be called twice for the same
+ * vcpu, so if vcpu_info is already registered, just get out. This
+ * can happen with cpu-hotplug.
+ */
+ if (per_cpu(xen_vcpu, cpu) != NULL)
+ goto after_register_vcpu_info;
+
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);
+ info.mfn = virt_to_gfn(vcpup);
+ info.offset = xen_offset_in_page(vcpup);
err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
BUG_ON(err);
per_cpu(xen_vcpu, cpu) = vcpup;
+ xen_setup_runstate_info(cpu);
+
+after_register_vcpu_info:
enable_percpu_irq(xen_events_irq, 0);
put_cpu();
}
@@ -124,6 +217,9 @@ static int xen_cpu_notification(struct notifier_block *self,
case CPU_STARTING:
xen_percpu_init();
break;
+ case CPU_DYING:
+ disable_percpu_irq(xen_events_irq);
+ break;
default:
break;
}
@@ -213,7 +309,7 @@ static int __init xen_guest_init(void)
xatp.domid = DOMID_SELF;
xatp.idx = 0;
xatp.space = XENMAPSPACE_shared_info;
- xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
+ xatp.gpfn = virt_to_gfn(shared_info_page);
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
@@ -259,6 +355,11 @@ static int __init xen_guest_init(void)
register_cpu_notifier(&xen_cpu_notifier);
+ pv_time_ops.steal_clock = xen_stolen_accounting;
+ static_key_slow_inc(&paravirt_steal_enabled);
+ if (xen_initial_domain())
+ pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
+
return 0;
}
early_initcall(xen_guest_init);
@@ -270,6 +371,11 @@ static int __init xen_pm_init(void)
pm_power_off = xen_power_off;
arm_pm_restart = xen_restart;
+ if (!xen_initial_domain()) {
+ struct timespec64 ts;
+ xen_read_wallclock(&ts);
+ do_settimeofday64(&ts);
+ }
return 0;
}
@@ -284,7 +390,7 @@ void xen_arch_resume(void) { }
void xen_arch_suspend(void) { }
-/* In the hypervisor.S file. */
+/* In the hypercall.S file. */
EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version);
@@ -295,5 +401,6 @@ 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_platform_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
EXPORT_SYMBOL_GPL(privcmd_call);
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index 10fd99c..9a36f4f 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -89,6 +89,7 @@ HYPERCALL2(memory_op);
HYPERCALL2(physdev_op);
HYPERCALL3(vcpu_op);
HYPERCALL1(tmem_op);
+HYPERCALL1(platform_op_raw);
HYPERCALL2(multicall);
ENTRY(privcmd_call)
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 6dd911d..c5f9a9e 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -25,7 +25,7 @@
unsigned long xen_get_swiotlb_free_pages(unsigned int order)
{
struct memblock_region *reg;
- gfp_t flags = __GFP_NOWARN;
+ gfp_t flags = __GFP_NOWARN|__GFP_KSWAPD_RECLAIM;
for_each_memblock(memory, reg) {
if (reg->base < (phys_addr_t)0xffffffff) {
@@ -48,22 +48,22 @@ 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;
+ unsigned long xen_pfn;
size_t left = size;
- pfn = (handle >> PAGE_SHIFT) + offset / PAGE_SIZE;
- offset %= PAGE_SIZE;
+ xen_pfn = (handle >> XEN_PAGE_SHIFT) + offset / XEN_PAGE_SIZE;
+ offset %= XEN_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;
+ if (len + offset > XEN_PAGE_SIZE)
+ len = XEN_PAGE_SIZE - offset;
cflush.op = 0;
- cflush.a.dev_bus_addr = pfn << PAGE_SHIFT;
+ cflush.a.dev_bus_addr = xen_pfn << XEN_PAGE_SHIFT;
cflush.offset = offset;
cflush.length = len;
@@ -79,7 +79,7 @@ static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
offset = 0;
- pfn++;
+ xen_pfn++;
left -= len;
} while (left);
}
@@ -138,10 +138,29 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
}
bool xen_arch_need_swiotlb(struct device *dev,
- unsigned long pfn,
- unsigned long bfn)
+ phys_addr_t phys,
+ dma_addr_t dev_addr)
{
- return (!hypercall_cflush && (pfn != bfn) && !is_device_dma_coherent(dev));
+ unsigned int xen_pfn = XEN_PFN_DOWN(phys);
+ unsigned int bfn = XEN_PFN_DOWN(dev_addr);
+
+ /*
+ * The swiotlb buffer should be used if
+ * - Xen doesn't have the cache flush hypercall
+ * - The Linux page refers to foreign memory
+ * - The device doesn't support coherent DMA request
+ *
+ * The Linux page may be spanned acrros multiple Xen page, although
+ * it's not possible to have a mix of local and foreign Xen page.
+ * Furthermore, range_straddles_page_boundary is already checking
+ * if buffer is physically contiguous in the host RAM.
+ *
+ * Therefore we only need to check the first Xen page to know if we
+ * require a bounce buffer because the device doesn't support coherent
+ * memory and we are not able to flush the cache.
+ */
+ return (!hypercall_cflush && (xen_pfn != bfn) &&
+ !is_device_dma_coherent(dev));
}
int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index 887596c..0ed01f2 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -93,8 +93,8 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
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);
+ set_phys_to_machine(map_ops[i].host_addr >> XEN_PAGE_SHIFT,
+ map_ops[i].dev_bus_addr >> XEN_PAGE_SHIFT);
}
return 0;
@@ -108,7 +108,7 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
int i;
for (i = 0; i < count; i++) {
- set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT,
+ set_phys_to_machine(unmap_ops[i].host_addr >> XEN_PAGE_SHIFT,
INVALID_P2M_ENTRY);
}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 07d1811..4f43622 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -3,6 +3,7 @@ config ARM64
select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_GCOV_PROFILE_ALL
@@ -13,6 +14,7 @@ config ARM64
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select ARCH_WANT_FRAME_POINTERS
+ select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARM_AMBA
select ARM_ARCH_TIMER
select ARM_GIC
@@ -27,6 +29,7 @@ config ARM64
select CPU_PM if (SUSPEND || CPU_IDLE)
select DCACHE_WORD_ACCESS
select EDAC_SUPPORT
+ select FRAME_POINTER
select GENERIC_ALLOCATOR
select GENERIC_CLOCKEVENTS
select GENERIC_CLOCKEVENTS_BROADCAST
@@ -47,8 +50,12 @@ config ARM64
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_BITREVERSE
+ select HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
select HAVE_ARCH_KGDB
+ select HAVE_ARCH_MMAP_RND_BITS
+ select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_BPF_JIT
@@ -59,7 +66,6 @@ config ARM64
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
- select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_EFFICIENT_UNALIGNED_ACCESS
@@ -68,6 +74,7 @@ config ARM64
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if PERF_EVENTS
+ select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_MEMBLOCK
select HAVE_PATA_PLATFORM
select HAVE_PERF_EVENTS
@@ -75,6 +82,7 @@ config ARM64
select HAVE_PERF_USER_STACK_DUMP
select HAVE_RCU_TABLE_FREE
select HAVE_SYSCALL_TRACEPOINTS
+ select IOMMU_DMA if IOMMU_SUPPORT
select IRQ_DOMAIN
select IRQ_FORCED_THREADING
select MODULES_USE_ELF_RELA
@@ -89,6 +97,7 @@ config ARM64
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select HAVE_CONTEXT_TRACKING
+ select HAVE_ARM_SMCCC
help
ARM 64-bit (AArch64) Linux support.
@@ -101,6 +110,33 @@ config ARCH_PHYS_ADDR_T_64BIT
config MMU
def_bool y
+config ARCH_MMAP_RND_BITS_MIN
+ default 14 if ARM64_64K_PAGES
+ default 16 if ARM64_16K_PAGES
+ default 18
+
+# max bits determined by the following formula:
+# VA_BITS - PAGE_SHIFT - 3
+config ARCH_MMAP_RND_BITS_MAX
+ default 19 if ARM64_VA_BITS=36
+ default 24 if ARM64_VA_BITS=39
+ default 27 if ARM64_VA_BITS=42
+ default 30 if ARM64_VA_BITS=47
+ default 29 if ARM64_VA_BITS=48 && ARM64_64K_PAGES
+ default 31 if ARM64_VA_BITS=48 && ARM64_16K_PAGES
+ default 33 if ARM64_VA_BITS=48
+ default 14 if ARM64_64K_PAGES
+ default 16 if ARM64_16K_PAGES
+ default 18
+
+config ARCH_MMAP_RND_COMPAT_BITS_MIN
+ default 7 if ARM64_64K_PAGES
+ default 9 if ARM64_16K_PAGES
+ default 11
+
+config ARCH_MMAP_RND_COMPAT_BITS_MAX
+ default 16
+
config NO_IOPORT_MAP
def_bool y if !PCI
@@ -169,10 +205,12 @@ config FIX_EARLYCON_MEM
config PGTABLE_LEVELS
int
+ default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
- default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48
+ default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+ default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
source "init/Kconfig"
@@ -199,8 +237,6 @@ config PCI_SYSCALL
def_bool PCI
source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
endmenu
@@ -311,6 +347,27 @@ config ARM64_ERRATUM_832075
If unsure, say Y.
+config ARM64_ERRATUM_834220
+ bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
+ depends on KVM
+ default y
+ help
+ This option adds an alternative code sequence to work around ARM
+ erratum 834220 on Cortex-A57 parts up to r1p2.
+
+ Affected Cortex-A57 parts might report a Stage 2 translation
+ fault as the result of a Stage 1 fault for load crossing a
+ page boundary when there is a permission or device memory
+ alignment fault at Stage 1 and a translation fault at Stage 2.
+
+ The workaround is to verify that the Stage 1 translation
+ doesn't generate a fault before handling the Stage 2 fault.
+ Please note that this does not necessarily enable the workaround,
+ as it depends on the alternative framework, which will only patch
+ the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+
config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT
@@ -336,6 +393,7 @@ config ARM64_ERRATUM_843419
bool "Cortex-A53: 843419: A load or store might access an incorrect address"
depends on MODULES
default y
+ select ARM64_MODULE_CMODEL_LARGE
help
This option builds kernel modules using the large memory model in
order to avoid the use of the ADRP instruction, which can cause
@@ -348,6 +406,44 @@ config ARM64_ERRATUM_843419
If unsure, say Y.
+config CAVIUM_ERRATUM_22375
+ bool "Cavium erratum 22375, 24313"
+ default y
+ help
+ Enable workaround for erratum 22375, 24313.
+
+ This implements two gicv3-its errata workarounds for ThunderX. Both
+ with small impact affecting only ITS table allocation.
+
+ erratum 22375: only alloc 8MB table size
+ erratum 24313: ignore memory access type
+
+ The fixes are in ITS initialization and basically ignore memory access
+ type and table size provided by the TYPER and BASER registers.
+
+ If unsure, say Y.
+
+config CAVIUM_ERRATUM_23154
+ bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
+ default y
+ help
+ The gicv3 of ThunderX requires a modified version for
+ reading the IAR status to ensure data synchronization
+ (access to icc_iar1_el1 is not sync'ed before and after).
+
+ If unsure, say Y.
+
+config CAVIUM_ERRATUM_27456
+ bool "Cavium erratum 27456: Broadcast TLBI instructions may cause icache corruption"
+ default y
+ help
+ On ThunderX T88 pass 1.x through 2.1 parts, broadcast TLBI
+ instructions may cause the icache to become corrupted if it
+ contains data for a non-current ASID. The fix is to
+ invalidate the icache when changing the mm context.
+
+ If unsure, say Y.
+
endmenu
@@ -362,25 +458,37 @@ config ARM64_4K_PAGES
help
This feature enables 4KB pages support.
+config ARM64_16K_PAGES
+ bool "16KB"
+ help
+ The system will use 16KB pages support. AArch32 emulation
+ requires applications compiled with 16K (or a multiple of 16K)
+ aligned segments.
+
config ARM64_64K_PAGES
bool "64KB"
help
This feature enables 64KB pages support (4KB by default)
allowing only two levels of page tables and faster TLB
- look-up. AArch32 emulation is not available when this feature
- is enabled.
+ look-up. AArch32 emulation requires applications compiled
+ with 64K aligned segments.
endchoice
choice
prompt "Virtual address space size"
default ARM64_VA_BITS_39 if ARM64_4K_PAGES
+ default ARM64_VA_BITS_47 if ARM64_16K_PAGES
default ARM64_VA_BITS_42 if ARM64_64K_PAGES
help
Allows choosing one of multiple possible virtual address
space sizes. The level of translation table is determined by
a combination of page size and virtual address space size.
+config ARM64_VA_BITS_36
+ bool "36-bit" if EXPERT
+ depends on ARM64_16K_PAGES
+
config ARM64_VA_BITS_39
bool "39-bit"
depends on ARM64_4K_PAGES
@@ -389,6 +497,10 @@ config ARM64_VA_BITS_42
bool "42-bit"
depends on ARM64_64K_PAGES
+config ARM64_VA_BITS_47
+ bool "47-bit"
+ depends on ARM64_16K_PAGES
+
config ARM64_VA_BITS_48
bool "48-bit"
@@ -396,8 +508,10 @@ endchoice
config ARM64_VA_BITS
int
+ default 36 if ARM64_VA_BITS_36
default 39 if ARM64_VA_BITS_39
default 42 if ARM64_VA_BITS_42
+ default 47 if ARM64_VA_BITS_47
default 48 if ARM64_VA_BITS_48
config CPU_BIG_ENDIAN
@@ -427,15 +541,16 @@ config NR_CPUS
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
+ select GENERIC_IRQ_MIGRATION
help
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu.
source kernel/Kconfig.preempt
+source kernel/Kconfig.hz
-config HZ
- int
- default 100
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
config ARCH_HAS_HOLES_MEMORYMODEL
def_bool y if SPARSEMEM
@@ -454,21 +569,14 @@ config HAVE_ARCH_PFN_VALID
def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
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_PMU
-config ARCH_WANT_GENERAL_HUGETLB
+config SYS_SUPPORTS_HUGETLBFS
def_bool y
config ARCH_WANT_HUGE_PMD_SHARE
- def_bool y if !ARM64_64K_PAGES
+ def_bool y if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
config HAVE_ARCH_TRANSPARENT_HUGEPAGE
def_bool y
@@ -491,6 +599,25 @@ config SECCOMP
and the task is only allowed to execute a few safe syscalls
defined by each seccomp mode.
+config PARAVIRT
+ bool "Enable paravirtualization code"
+ help
+ This changes the kernel so it can modify itself when it is run
+ under a hypervisor, potentially improving performance significantly
+ over full virtualization.
+
+config PARAVIRT_TIME_ACCOUNTING
+ bool "Paravirtual steal time accounting"
+ select PARAVIRT
+ default n
+ help
+ Select this option to enable fine granularity task steal time
+ accounting. Time spent executing other tasks in parallel with
+ the current vCPU is discounted from the vCPU power. To account for
+ that, there can be a small performance impact.
+
+ If in doubt, say N here.
+
config XEN_DOM0
def_bool y
depends on XEN
@@ -499,13 +626,32 @@ config XEN
bool "Xen guest support on ARM64"
depends on ARM64 && OF
select SWIOTLB_XEN
+ select PARAVIRT
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.
config FORCE_MAX_ZONEORDER
int
default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+ default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
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.
+
+ We make sure that we can allocate upto a HugePage size for each configuration.
+ Hence we have :
+ MAX_ORDER = (PMD_SHIFT - PAGE_SHIFT) + 1 => PAGE_SHIFT - 2
+
+ However for 4K, we choose a higher default value, 11 as opposed to 10, giving us
+ 4M allocations matching the default size used by generic code.
menuconfig ARMV8_DEPRECATED
bool "Emulate deprecated/obsolete ARMv8 instructions"
@@ -619,12 +765,112 @@ config ARM64_LSE_ATOMICS
not support these instructions and requires the kernel to be
built with binutils >= 2.25.
+config ARM64_VHE
+ bool "Enable support for Virtualization Host Extensions (VHE)"
+ default y
+ help
+ Virtualization Host Extensions (VHE) allow the kernel to run
+ directly at EL2 (instead of EL1) on processors that support
+ it. This leads to better performance for KVM, as they reduce
+ the cost of the world switch.
+
+ Selecting this option allows the VHE feature to be detected
+ at runtime, and does not affect processors that do not
+ implement this feature.
+
endmenu
+menu "ARMv8.2 architectural features"
+
+config ARM64_UAO
+ bool "Enable support for User Access Override (UAO)"
+ default y
+ help
+ User Access Override (UAO; part of the ARMv8.2 Extensions)
+ causes the 'unprivileged' variant of the load/store instructions to
+ be overriden to be privileged.
+
+ This option changes get_user() and friends to use the 'unprivileged'
+ variant of the load/store instructions. This ensures that user-space
+ really did have access to the supplied memory. When addr_limit is
+ set to kernel memory the UAO bit will be set, allowing privileged
+ access to kernel memory.
+
+ Choosing this option will cause copy_to_user() et al to use user-space
+ memory permissions.
+
+ The feature is detected at runtime, the kernel will use the
+ regular load/store instructions if the cpu does not implement the
+ feature.
+
+endmenu
+
+config ARM64_MODULE_CMODEL_LARGE
+ bool
+
+config ARM64_MODULE_PLTS
+ bool
+ select ARM64_MODULE_CMODEL_LARGE
+ select HAVE_MOD_ARCH_SPECIFIC
+
+config RELOCATABLE
+ bool
+ help
+ This builds the kernel as a Position Independent Executable (PIE),
+ which retains all relocation metadata required to relocate the
+ kernel binary at runtime to a different virtual address than the
+ address it was linked at.
+ Since AArch64 uses the RELA relocation format, this requires a
+ relocation pass at runtime even if the kernel is loaded at the
+ same address it was linked at.
+
+config RANDOMIZE_BASE
+ bool "Randomize the address of the kernel image"
+ select ARM64_MODULE_PLTS
+ select RELOCATABLE
+ help
+ Randomizes the virtual address at which the kernel image is
+ loaded, as a security feature that deters exploit attempts
+ relying on knowledge of the location of kernel internals.
+
+ It is the bootloader's job to provide entropy, by passing a
+ random u64 value in /chosen/kaslr-seed at kernel entry.
+
+ When booting via the UEFI stub, it will invoke the firmware's
+ EFI_RNG_PROTOCOL implementation (if available) to supply entropy
+ to the kernel proper. In addition, it will randomise the physical
+ location of the kernel Image as well.
+
+ If unsure, say N.
+
+config RANDOMIZE_MODULE_REGION_FULL
+ bool "Randomize the module region independently from the core kernel"
+ depends on RANDOMIZE_BASE
+ default y
+ help
+ Randomizes the location of the module region without considering the
+ location of the core kernel. This way, it is impossible for modules
+ to leak information about the location of core kernel data structures
+ but it does imply that function calls between modules and the core
+ kernel will need to be resolved via veneers in the module PLT.
+
+ When this option is not set, the module region will be randomized over
+ a limited range that contains the [_stext, _etext] interval of the
+ core kernel, so branch relocations are always in range.
+
endmenu
menu "Boot options"
+config ARM64_ACPI_PARKING_PROTOCOL
+ bool "Enable support for the ARM64 ACPI parking protocol"
+ depends on ACPI
+ help
+ Enable support for the ARM64 ACPI parking protocol. If disabled
+ the kernel will not allow booting through the ARM64 ACPI parking
+ protocol even if the corresponding data is present in the ACPI
+ MADT table.
+
config CMDLINE
string "Default kernel command string"
default ""
@@ -680,7 +926,7 @@ source "fs/Kconfig.binfmt"
config COMPAT
bool "Kernel support for 32-bit EL0"
- depends on !ARM64_64K_PAGES || EXPERT
+ depends on ARM64_4K_PAGES || EXPERT
select COMPAT_BINFMT_ELF
select HAVE_UID16
select OLD_SIGSUSPEND3
@@ -691,9 +937,9 @@ config COMPAT
the user helper functions, VFP support and the ptrace interface are
handled appropriately by the kernel.
- If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
- will only be able to execute AArch32 binaries that were compiled with
- 64k aligned segments.
+ If you use a page size other than 4KB (i.e, 16KB or 64KB), please be aware
+ that you will only be able to execute AArch32 binaries that were compiled
+ with page size aligned segments.
If you want to execute 32-bit userspace applications, say Y.
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index d6285ef..7e76845 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -2,10 +2,6 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-config FRAME_POINTER
- bool
- default y
-
config ARM64_PTDUMP
bool "Export kernel pagetable layout to userspace via debugfs"
depends on DEBUG_KERNEL
@@ -18,20 +14,6 @@ config ARM64_PTDUMP
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.
-
config PID_IN_CONTEXTIDR
bool "Write the current PID to the CONTEXTIDR register"
help
@@ -68,16 +50,16 @@ config DEBUG_SET_MODULE_RONX
config DEBUG_RODATA
bool "Make kernel text and rodata read-only"
+ 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.
+ kernel's executable code.
- If in doubt, say Y
+ If in doubt, say Y
config DEBUG_ALIGN_RODATA
- depends on DEBUG_RODATA && !ARM64_64K_PAGES
+ depends on DEBUG_RODATA && ARM64_4K_PAGES
bool "Align linker sections up to SECTION_SIZE"
help
If this option is enabled, sections that may potentially be marked as
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 23800a1..21074f6 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -7,7 +7,9 @@ config ARCH_BCM_IPROC
config ARCH_BERLIN
bool "Marvell Berlin SoC Family"
+ select ARCH_REQUIRE_GPIOLIB
select DW_APB_ICTL
+ select PINCTRL
help
This enables support for Marvell Berlin SoC Family
@@ -28,10 +30,10 @@ config ARCH_EXYNOS7
help
This enables support for Samsung Exynos7 SoC family
-config ARCH_FSL_LS2085A
- bool "Freescale LS2085A SOC"
+config ARCH_LAYERSCAPE
+ bool "ARMv8 based Freescale Layerscape SoC family"
help
- This enables support for Freescale LS2085A SOC.
+ This enables support for the Freescale Layerscape SoC family.
config ARCH_HISI
bool "Hisilicon SoC Family"
@@ -42,6 +44,7 @@ config ARCH_MEDIATEK
bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
select ARM_GIC
select PINCTRL
+ select MTK_TIMER
help
Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
@@ -66,6 +69,28 @@ config ARCH_SEATTLE
help
This enables support for AMD Seattle SOC Family
+config ARCH_SHMOBILE
+ bool
+
+config ARCH_RENESAS
+ bool "Renesas SoC Platforms"
+ select ARCH_SHMOBILE
+ select PINCTRL
+ select PM_GENERIC_DOMAINS if PM
+ help
+ This enables support for the ARMv8 based Renesas SoCs.
+
+config ARCH_R8A7795
+ bool "Renesas R-Car H3 SoC Platform"
+ depends on ARCH_RENESAS
+ help
+ This enables support for the Renesas R-Car H3 SoC.
+
+config ARCH_STRATIX10
+ bool "Altera's Stratix 10 SoCFPGA Family"
+ help
+ This enables support for Altera's Stratix 10 SoCFPGA Family.
+
config ARCH_TEGRA
bool "NVIDIA Tegra SoC Family"
select ARCH_HAS_RESET_CONTROLLER
@@ -80,18 +105,6 @@ config ARCH_TEGRA
help
This enables support for the NVIDIA Tegra SoC family.
-config ARCH_TEGRA_132_SOC
- bool "NVIDIA Tegra132 SoC"
- depends on ARCH_TEGRA
- select PINCTRL_TEGRA124
- select USB_ULPI if USB_PHY
- select USB_ULPI_VIEWPORT if USB_PHY
- help
- Enable support for NVIDIA Tegra132 SoC, based on the Denver
- ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC,
- but contains an NVIDIA Denver CPU complex in place of
- Tegra124's "4+1" Cortex-A15 CPU complex.
-
config ARCH_SPRD
bool "Spreadtrum SoC platform"
help
@@ -102,6 +115,12 @@ config ARCH_THUNDER
help
This enables support for Cavium's Thunder Family of SoCs.
+config ARCH_UNIPHIER
+ bool "Socionext UniPhier SoC Family"
+ select PINCTRL
+ help
+ This enables support for Socionext UniPhier SoC family.
+
config ARCH_VEXPRESS
bool "ARMv8 software model (Versatile Express)"
select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index d10b5d4..354d754 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -15,6 +15,10 @@ CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
+ifneq ($(CONFIG_RELOCATABLE),)
+LDFLAGS_vmlinux += -pie
+endif
+
KBUILD_DEFCONFIG := defconfig
# Check for binutils support for specific extensions
@@ -27,6 +31,8 @@ $(warning LSE atomics not supported by binutils)
endif
KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr)
+KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
+KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads)
KBUILD_AFLAGS += $(lseinstr)
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
@@ -41,10 +47,14 @@ endif
CHECKFLAGS += -D__aarch64__
-ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
+ifeq ($(CONFIG_ARM64_MODULE_CMODEL_LARGE), y)
KBUILD_CFLAGS_MODULE += -mcmodel=large
endif
+ifeq ($(CONFIG_ARM64_MODULE_PLTS),y)
+KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/arm64/kernel/module.lds
+endif
+
# Default value
head-y := arch/arm64/kernel/head.o
@@ -55,6 +65,13 @@ else
TEXT_OFFSET := 0x00080000
endif
+# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - 3)) - (1 << 61)
+# in 32-bit arithmetic
+KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
+ (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
+ + (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - 3)) \
+ - (1 << (64 - 32 - 3)) )) )
+
export TEXT_OFFSET GZFLAGS
core-y += arch/arm64/kernel/ arch/arm64/mm/
@@ -79,7 +96,7 @@ Image: vmlinux
Image.%: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-zinstall install: vmlinux
+zinstall install:
$(Q)$(MAKE) $(build)=$(boot) $@
%.dtb: scripts
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index abcbba2..305c552 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -34,10 +34,10 @@ $(obj)/Image.lzma: $(obj)/Image FORCE
$(obj)/Image.lzo: $(obj)/Image FORCE
$(call if_changed,lzo)
-install: $(obj)/Image
+install:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image System.map "$(INSTALL_PATH)"
-zinstall: $(obj)/Image.gz
+zinstall:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index d9f8833..f832b8a 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,3 +1,4 @@
+dts-dirs += altera
dts-dirs += amd
dts-dirs += apm
dts-dirs += arm
@@ -8,9 +9,18 @@ dts-dirs += freescale
dts-dirs += hisilicon
dts-dirs += marvell
dts-dirs += mediatek
+dts-dirs += nvidia
dts-dirs += qcom
+dts-dirs += renesas
dts-dirs += rockchip
+dts-dirs += socionext
dts-dirs += sprd
dts-dirs += xilinx
subdir-y := $(dts-dirs)
+
+dtstree := $(srctree)/$(src)
+
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))
+
+always := $(dtb-y)
diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
new file mode 100644
index 0000000..d7a6416
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
new file mode 100644
index 0000000..445aa67
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -0,0 +1,358 @@
+/*
+ * Copyright Altera Corporation (C) 2015. 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/>.
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "altr,socfpga-stratix10";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ enable-method = "psci";
+ reg = <0x0>;
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ enable-method = "psci";
+ reg = <0x1>;
+ };
+
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ enable-method = "psci";
+ reg = <0x2>;
+ };
+
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a53", "arm,armv8";
+ device_type = "cpu";
+ enable-method = "psci";
+ reg = <0x3>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <0 120 8>,
+ <0 121 8>,
+ <0 122 8>,
+ <0 123 8>;
+ interrupt-affinity = <&cpu0>,
+ <&cpu1>,
+ <&cpu2>,
+ <&cpu3>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ intc: intc@fffc1000 {
+ compatible = "arm,gic-400", "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0xfffc1000 0x1000>,
+ <0x0 0xfffc2000 0x2000>,
+ <0x0 0xfffc4000 0x2000>,
+ <0x0 0xfffc6000 0x2000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ device_type = "soc";
+ interrupt-parent = <&intc>;
+ ranges = <0 0 0 0xffffffff>;
+
+ clkmgr@ffd1000 {
+ compatible = "altr,clk-mgr";
+ reg = <0xffd10000 0x1000>;
+ };
+
+ gmac0: ethernet@ff800000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff800000 0x2000>;
+ interrupts = <0 90 4>;
+ interrupt-names = "macirq";
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gmac1: ethernet@ff802000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff802000 0x2000>;
+ interrupts = <0 91 4>;
+ interrupt-names = "macirq";
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gmac2: ethernet@ff804000 {
+ compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff804000 0x2000>;
+ interrupts = <0 92 4>;
+ interrupt-names = "macirq";
+ mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+
+ gpio0: gpio@ffc03200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xffc03200 0x100>;
+ status = "disabled";
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <24>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 110 4>;
+ };
+ };
+
+ gpio1: gpio@ffc03300 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xffc03300 0x100>;
+ status = "disabled";
+
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <24>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <0 110 4>;
+ };
+ };
+
+ i2c0: i2c@ffc02800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02800 0x100>;
+ interrupts = <0 103 4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@ffc02900 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02900 0x100>;
+ interrupts = <0 104 4>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@ffc02a00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02a00 0x100>;
+ interrupts = <0 105 4>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@ffc02b00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02b00 0x100>;
+ interrupts = <0 106 4>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@ffc02c00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xffc02c00 0x100>;
+ interrupts = <0 107 4>;
+ status = "disabled";
+ };
+
+ mmc: dwmmc0@ff808000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "altr,socfpga-dw-mshc";
+ reg = <0xff808000 0x1000>;
+ interrupts = <0 96 4>;
+ fifo-depth = <0x400>;
+ status = "disabled";
+ };
+
+ ocram: sram@ffe00000 {
+ compatible = "mmio-sram";
+ reg = <0xffe00000 0x100000>;
+ };
+
+ rst: rstmgr@ffd11000 {
+ #reset-cells = <1>;
+ compatible = "altr,rst-mgr";
+ reg = <0xffd11000 0x1000>;
+ };
+
+ spi0: spi@ffda4000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xffda4000 0x1000>;
+ interrupts = <0 101 4>;
+ num-chipselect = <4>;
+ bus-num = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@ffda5000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xffda5000 0x1000>;
+ interrupts = <0 102 4>;
+ num-chipselect = <4>;
+ bus-num = <0>;
+ status = "disabled";
+ };
+
+ sysmgr: sysmgr@ffd12000 {
+ compatible = "altr,sys-mgr", "syscon";
+ reg = <0xffd12000 0x1000>;
+ };
+
+ /* Local timer */
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0xf01>,
+ <1 14 0xf01>,
+ <1 11 0xf01>,
+ <1 10 0xf01>;
+ };
+
+ timer0: timer0@ffc03000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 113 4>;
+ reg = <0xffc03000 0x100>;
+ };
+
+ timer1: timer1@ffc03100 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 114 4>;
+ reg = <0xffc03100 0x100>;
+ };
+
+ timer2: timer2@ffd00000 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 115 4>;
+ reg = <0xffd00000 0x100>;
+ };
+
+ timer3: timer3@ffd00100 {
+ compatible = "snps,dw-apb-timer";
+ interrupts = <0 116 4>;
+ reg = <0xffd00100 0x100>;
+ };
+
+ uart0: serial0@ffc02000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc02000 0x100>;
+ interrupts = <0 108 4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: serial1@ffc02100 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xffc02100 0x100>;
+ interrupts = <0 109 4>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ usbphy0: usbphy@0 {
+ #phy-cells = <0>;
+ compatible = "usb-nop-xceiv";
+ status = "okay";
+ };
+
+ usb0: usb@ffb00000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb00000 0x40000>;
+ interrupts = <0 93 4>;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb1: usb@ffb40000 {
+ compatible = "snps,dwc2";
+ reg = <0xffb40000 0x40000>;
+ interrupts = <0 94 4>;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ watchdog0: watchdog@ffd00200 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00200 0x100>;
+ interrupts = <0 117 4>;
+ status = "disabled";
+ };
+
+ watchdog1: watchdog@ffd00300 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00300 0x100>;
+ interrupts = <0 118 4>;
+ status = "disabled";
+ };
+
+ watchdog2: watchdog@ffd00400 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00400 0x100>;
+ interrupts = <0 125 4>;
+ status = "disabled";
+ };
+
+ watchdog3: watchdog@ffd00500 {
+ compatible = "snps,dw-wdt";
+ reg = <0xffd00500 0x100>;
+ interrupts = <0 126 4>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
new file mode 100644
index 0000000..41ea2db
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright Altera Corporation (C) 2015. 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/ "socfpga_stratix10.dtsi"
+
+/ {
+ model = "SoCFPGA Stratix 10 SoCDK";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the reg */
+ reg = <0 0 0 0>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amd/amd-overdrive.dts b/arch/arm64/boot/dts/amd/amd-overdrive.dts
index 564a3f7..128fa94 100644
--- a/arch/arm64/boot/dts/amd/amd-overdrive.dts
+++ b/arch/arm64/boot/dts/amd/amd-overdrive.dts
@@ -14,7 +14,6 @@
chosen {
stdout-path = &serial0;
- linux,pci-probe-only;
};
};
diff --git a/arch/arm64/boot/dts/apm/Makefile b/arch/arm64/boot/dts/apm/Makefile
index a2afabb..c75f17a4 100644
--- a/arch/arm64/boot/dts/apm/Makefile
+++ b/arch/arm64/boot/dts/apm/Makefile
@@ -1,4 +1,5 @@
dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
+dtb-$(CONFIG_ARCH_XGENE) += apm-merlin.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/apm/apm-merlin.dts b/arch/arm64/boot/dts/apm/apm-merlin.dts
new file mode 100644
index 0000000..e5ba8d5
--- /dev/null
+++ b/arch/arm64/boot/dts/apm/apm-merlin.dts
@@ -0,0 +1,84 @@
+/*
+ * dts file for AppliedMicro (APM) Merlin Board
+ *
+ * Copyright (C) 2015, Applied Micro Circuits 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.
+ */
+
+/dts-v1/;
+
+/include/ "apm-shadowcat.dtsi"
+
+/ {
+ model = "APM X-Gene Merlin board";
+ compatible = "apm,merlin", "apm,xgene-shadowcat";
+
+ chosen { };
+
+ memory {
+ device_type = "memory";
+ reg = < 0x1 0x00000000 0x0 0x80000000 >;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ button@1 {
+ label = "POWER";
+ linux,code = <116>;
+ linux,input-type = <0x1>;
+ interrupts = <0x0 0x28 0x1>;
+ };
+ };
+
+ poweroff_mbox: poweroff_mbox@10548000 {
+ compatible = "syscon";
+ reg = <0x0 0x10548000 0x0 0x30>;
+ };
+
+ poweroff: poweroff@10548010 {
+ compatible = "syscon-poweroff";
+ regmap = <&poweroff_mbox>;
+ offset = <0x10>;
+ mask = <0x1>;
+ };
+};
+
+&serial0 {
+ status = "ok";
+};
+
+&sata1 {
+ status = "ok";
+};
+
+&sata2 {
+ status = "ok";
+};
+
+&sata3 {
+ status = "ok";
+};
+
+&sgenet0 {
+ status = "ok";
+};
+
+&xgenet1 {
+ status = "ok";
+};
+
+&mmc0 {
+ status = "ok";
+};
+
+&i2c4 {
+ rtc68: rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ status = "ok";
+ };
+};
diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts
index 4c55833..178aef2 100644
--- a/arch/arm64/boot/dts/apm/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm/apm-mustang.dts
@@ -33,6 +33,18 @@
interrupts = <0x0 0x2d 0x1>;
};
};
+
+ poweroff_mbox: poweroff_mbox@10548000 {
+ compatible = "syscon";
+ reg = <0x0 0x10548000 0x0 0x30>;
+ };
+
+ poweroff: poweroff@10548010 {
+ compatible = "syscon-poweroff";
+ regmap = <&poweroff_mbox>;
+ offset = <0x10>;
+ mask = <0x1>;
+ };
};
&pcie0clk {
@@ -62,3 +74,7 @@
&xgenet {
status = "ok";
};
+
+&mmc0 {
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
new file mode 100644
index 0000000..278f106
--- /dev/null
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -0,0 +1,666 @@
+/*
+ * dts file for AppliedMicro (APM) X-Gene Shadowcat SOC
+ *
+ * Copyright (C) 2015, Applied Micro Circuits 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.
+ */
+
+/ {
+ compatible = "apm,xgene-shadowcat";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu@000 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x000>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_0>;
+ };
+ cpu@001 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x001>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_0>;
+ };
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_1>;
+ };
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x101>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_1>;
+ };
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x200>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_2>;
+ };
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x201>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_2>;
+ };
+ cpu@300 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x300>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_3>;
+ };
+ cpu@301 {
+ device_type = "cpu";
+ compatible = "apm,strega", "arm,armv8";
+ reg = <0x0 0x301>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_3>;
+ };
+ xgene_L2_0: l2-cache-0 {
+ compatible = "cache";
+ };
+ xgene_L2_1: l2-cache-1 {
+ compatible = "cache";
+ };
+ xgene_L2_2: l2-cache-2 {
+ compatible = "cache";
+ };
+ xgene_L2_3: l2-cache-3 {
+ compatible = "cache";
+ };
+ };
+
+ gic: interrupt-controller@78090000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-controller;
+ interrupts = <1 9 0xf04>; /* GIC Maintenence IRQ */
+ ranges = <0 0 0 0x79000000 0x0 0x800000>; /* MSI Range */
+ reg = <0x0 0x78090000 0x0 0x10000>, /* GIC Dist */
+ <0x0 0x780A0000 0x0 0x20000>, /* GIC CPU */
+ <0x0 0x780C0000 0x0 0x10000>, /* GIC VCPU Control */
+ <0x0 0x780E0000 0x0 0x20000>; /* GIC VCPU */
+ v2m0: v2m@0x00000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x0 0x0 0x1000>;
+ };
+ v2m1: v2m@0x10000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x10000 0x0 0x1000>;
+ };
+ v2m2: v2m@0x20000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x20000 0x0 0x1000>;
+ };
+ v2m3: v2m@0x30000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x30000 0x0 0x1000>;
+ };
+ v2m4: v2m@0x40000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x40000 0x0 0x1000>;
+ };
+ v2m5: v2m@0x50000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x50000 0x0 0x1000>;
+ };
+ v2m6: v2m@0x60000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x60000 0x0 0x1000>;
+ };
+ v2m7: v2m@0x70000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x70000 0x0 0x1000>;
+ };
+ v2m8: v2m@0x80000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x80000 0x0 0x1000>;
+ };
+ v2m9: v2m@0x90000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x90000 0x0 0x1000>;
+ };
+ v2m10: v2m@0xA0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xA0000 0x0 0x1000>;
+ };
+ v2m11: v2m@0xB0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xB0000 0x0 0x1000>;
+ };
+ v2m12: v2m@0xC0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xC0000 0x0 0x1000>;
+ };
+ v2m13: v2m@0xD0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xD0000 0x0 0x1000>;
+ };
+ v2m14: v2m@0xE0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xE0000 0x0 0x1000>;
+ };
+ v2m15: v2m@0xF0000 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xF0000 0x0 0x1000>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <1 12 0xff04>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 0 0xff04>, /* Secure Phys IRQ */
+ <1 13 0xff04>, /* Non-secure Phys IRQ */
+ <1 14 0xff04>, /* Virt IRQ */
+ <1 15 0xff04>; /* Hyp IRQ */
+ clock-frequency = <50000000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ refclk: refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <1>;
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk";
+ };
+
+ socpll: socpll@17000120 {
+ compatible = "apm,xgene-socpll-clock";
+ #clock-cells = <1>;
+ clocks = <&refclk 0>;
+ reg = <0x0 0x17000120 0x0 0x1000>;
+ clock-output-names = "socpll";
+ };
+
+ socplldiv2: socplldiv2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <1>;
+ clocks = <&socpll 0>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ clock-output-names = "socplldiv2";
+ };
+
+ ahbclk: ahbclk@17000000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x17000000 0x0 0x2000>;
+ reg-names = "div-reg";
+ divider-offset = <0x164>;
+ divider-width = <0x5>;
+ divider-shift = <0x0>;
+ clock-output-names = "ahbclk";
+ };
+
+ sbapbclk: sbapbclk@1704c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&ahbclk 0>;
+ reg = <0x0 0x1704c000 0x0 0x2000>;
+ reg-names = "div-reg";
+ divider-offset = <0x10>;
+ divider-width = <0x2>;
+ divider-shift = <0x0>;
+ clock-output-names = "sbapbclk";
+ };
+
+ sdioclk: sdioclk@1f2ac000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f2ac000 0x0 0x1000
+ 0x0 0x17000000 0x0 0x2000>;
+ reg-names = "csr-reg", "div-reg";
+ csr-offset = <0x0>;
+ csr-mask = <0x2>;
+ enable-offset = <0x8>;
+ enable-mask = <0x2>;
+ divider-offset = <0x178>;
+ divider-width = <0x8>;
+ divider-shift = <0x0>;
+ clock-output-names = "sdioclk";
+ };
+
+ pcie0clk: pcie0clk@1f2bc000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f2bc000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ clock-output-names = "pcie0clk";
+ };
+
+ pcie1clk: pcie1clk@1f2cc000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f2cc000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ clock-output-names = "pcie1clk";
+ };
+
+ xge0clk: xge0clk@1f61c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f61c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ enable-mask = <0x3>;
+ csr-mask = <0x3>;
+ clock-output-names = "xge0clk";
+ };
+
+ xge1clk: xge1clk@1f62c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f62c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ enable-mask = <0x3>;
+ csr-mask = <0x3>;
+ clock-output-names = "xge1clk";
+ };
+
+ rngpkaclk: rngpkaclk@17000000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x17000000 0x0 0x2000>;
+ reg-names = "csr-reg";
+ csr-offset = <0xc>;
+ csr-mask = <0x10>;
+ enable-offset = <0x10>;
+ enable-mask = <0x10>;
+ clock-output-names = "rngpkaclk";
+ };
+
+ i2c4clk: i2c4clk@1704c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&sbapbclk 0>;
+ reg = <0x0 0x1704c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ csr-offset = <0x0>;
+ csr-mask = <0x40>;
+ enable-offset = <0x8>;
+ enable-mask = <0x40>;
+ clock-output-names = "i2c4clk";
+ };
+ };
+
+ scu: system-clk-controller@17000000 {
+ compatible = "apm,xgene-scu","syscon";
+ reg = <0x0 0x17000000 0x0 0x400>;
+ };
+
+ reboot: reboot@17000014 {
+ compatible = "syscon-reboot";
+ regmap = <&scu>;
+ offset = <0x14>;
+ mask = <0x1>;
+ };
+
+ csw: csw@7e200000 {
+ compatible = "apm,xgene-csw", "syscon";
+ reg = <0x0 0x7e200000 0x0 0x1000>;
+ };
+
+ mcba: mcba@7e700000 {
+ compatible = "apm,xgene-mcb", "syscon";
+ reg = <0x0 0x7e700000 0x0 0x1000>;
+ };
+
+ mcbb: mcbb@7e720000 {
+ compatible = "apm,xgene-mcb", "syscon";
+ reg = <0x0 0x7e720000 0x0 0x1000>;
+ };
+
+ efuse: efuse@1054a000 {
+ compatible = "apm,xgene-efuse", "syscon";
+ reg = <0x0 0x1054a000 0x0 0x20>;
+ };
+
+ edac@78800000 {
+ compatible = "apm,xgene-edac";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ regmap-csw = <&csw>;
+ regmap-mcba = <&mcba>;
+ regmap-mcbb = <&mcbb>;
+ regmap-efuse = <&efuse>;
+ reg = <0x0 0x78800000 0x0 0x100>;
+ interrupts = <0x0 0x20 0x4>,
+ <0x0 0x21 0x4>,
+ <0x0 0x27 0x4>;
+
+ edacmc@7e800000 {
+ compatible = "apm,xgene-edac-mc";
+ reg = <0x0 0x7e800000 0x0 0x1000>;
+ memory-controller = <0>;
+ };
+
+ edacmc@7e840000 {
+ compatible = "apm,xgene-edac-mc";
+ reg = <0x0 0x7e840000 0x0 0x1000>;
+ memory-controller = <1>;
+ };
+
+ edacmc@7e880000 {
+ compatible = "apm,xgene-edac-mc";
+ reg = <0x0 0x7e880000 0x0 0x1000>;
+ memory-controller = <2>;
+ };
+
+ edacmc@7e8c0000 {
+ compatible = "apm,xgene-edac-mc";
+ reg = <0x0 0x7e8c0000 0x0 0x1000>;
+ memory-controller = <3>;
+ };
+
+ edacpmd@7c000000 {
+ compatible = "apm,xgene-edac-pmd";
+ reg = <0x0 0x7c000000 0x0 0x200000>;
+ pmd-controller = <0>;
+ };
+
+ edacpmd@7c200000 {
+ compatible = "apm,xgene-edac-pmd";
+ reg = <0x0 0x7c200000 0x0 0x200000>;
+ pmd-controller = <1>;
+ };
+
+ edacpmd@7c400000 {
+ compatible = "apm,xgene-edac-pmd";
+ reg = <0x0 0x7c400000 0x0 0x200000>;
+ pmd-controller = <2>;
+ };
+
+ edacpmd@7c600000 {
+ compatible = "apm,xgene-edac-pmd";
+ reg = <0x0 0x7c600000 0x0 0x200000>;
+ pmd-controller = <3>;
+ };
+
+ edacl3@7e600000 {
+ compatible = "apm,xgene-edac-l3-v2";
+ reg = <0x0 0x7e600000 0x0 0x1000>;
+ };
+
+ edacsoc@7e930000 {
+ compatible = "apm,xgene-edac-soc";
+ reg = <0x0 0x7e930000 0x0 0x1000>;
+ };
+ };
+
+ serial0: serial@10600000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0 0x10600000 0x0 0x1000>;
+ reg-shift = <2>;
+ clock-frequency = <10000000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0x0 0x4c 0x4>;
+ };
+
+ /* Do not change dwusb name, coded for backward compatibility */
+ usb0: dwusb@19000000 {
+ status = "disabled";
+ compatible = "snps,dwc3";
+ reg = <0x0 0x19000000 0x0 0x100000>;
+ interrupts = <0x0 0x5d 0x4>;
+ dma-coherent;
+ dr_mode = "host";
+ };
+
+ pcie0: pcie@1f2b0000 {
+ status = "disabled";
+ device_type = "pci";
+ compatible = "apm,xgene-pcie", "apm,xgene2-pcie";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = < 0x00 0x1f2b0000 0x0 0x00010000 /* Controller registers */
+ 0xc0 0xd0000000 0x0 0x00040000>; /* PCI config space */
+ reg-names = "csr", "cfg";
+ ranges = <0x01000000 0x00 0x00000000 0xc0 0x10000000 0x00 0x00010000 /* io */
+ 0x02000000 0x00 0x20000000 0xc1 0x20000000 0x00 0x20000000 /* mem */
+ 0x43000000 0xe0 0x00000000 0xe0 0x00000000 0x20 0x00000000>; /* mem */
+ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
+ 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x1
+ 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x1
+ 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x12 0x1
+ 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x13 0x1>;
+ dma-coherent;
+ clocks = <&pcie0clk 0>;
+ msi-parent = <&v2m0>;
+ };
+
+ pcie1: pcie@1f2c0000 {
+ status = "disabled";
+ device_type = "pci";
+ compatible = "apm,xgene-pcie", "apm,xgene2-pcie";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */
+ 0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */
+ reg-names = "csr", "cfg";
+ ranges = <0x01000000 0x00 0x00000000 0xa0 0x10000000 0x00 0x00010000 /* io */
+ 0x02000000 0x00 0x20000000 0xa1 0x20000000 0x00 0x20000000 /* mem */
+ 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */
+ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
+ 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x1
+ 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x1
+ 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x18 0x1
+ 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x19 0x1>;
+ dma-coherent;
+ clocks = <&pcie1clk 0>;
+ msi-parent = <&v2m0>;
+ };
+
+ sata1: sata@1a000000 {
+ compatible = "apm,xgene-ahci";
+ reg = <0x0 0x1a000000 0x0 0x1000>,
+ <0x0 0x1f200000 0x0 0x1000>,
+ <0x0 0x1f20d000 0x0 0x1000>,
+ <0x0 0x1f20e000 0x0 0x1000>;
+ interrupts = <0x0 0x5a 0x4>;
+ dma-coherent;
+ };
+
+ sata2: sata@1a200000 {
+ compatible = "apm,xgene-ahci";
+ reg = <0x0 0x1a200000 0x0 0x1000>,
+ <0x0 0x1f210000 0x0 0x1000>,
+ <0x0 0x1f21d000 0x0 0x1000>,
+ <0x0 0x1f21e000 0x0 0x1000>;
+ interrupts = <0x0 0x5b 0x4>;
+ dma-coherent;
+ };
+
+ sata3: sata@1a400000 {
+ compatible = "apm,xgene-ahci";
+ reg = <0x0 0x1a400000 0x0 0x1000>,
+ <0x0 0x1f220000 0x0 0x1000>,
+ <0x0 0x1f22d000 0x0 0x1000>,
+ <0x0 0x1f22e000 0x0 0x1000>;
+ interrupts = <0x0 0x5c 0x4>;
+ dma-coherent;
+ };
+
+ mmc0: mmc@1c000000 {
+ compatible = "arasan,sdhci-4.9a";
+ reg = <0x0 0x1c000000 0x0 0x100>;
+ interrupts = <0x0 0x49 0x4>;
+ dma-coherent;
+ no-1-8-v;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&sdioclk 0>, <&ahbclk 0>;
+ };
+
+ gfcgpio: gpio@1f63c000 {
+ compatible = "apm,xgene-gpio";
+ reg = <0x0 0x1f63c000 0x0 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ dwgpio: gpio@1c024000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0 0x1c024000 0x0 0x1000>;
+ reg-io-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
+ sbgpio: gpio@17001000{
+ compatible = "apm,xgene-gpio-sb";
+ reg = <0x0 0x17001000 0x0 0x400>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupts = <0x0 0x28 0x1>,
+ <0x0 0x29 0x1>,
+ <0x0 0x2a 0x1>,
+ <0x0 0x2b 0x1>,
+ <0x0 0x2c 0x1>,
+ <0x0 0x2d 0x1>,
+ <0x0 0x2e 0x1>,
+ <0x0 0x2f 0x1>;
+ };
+
+ sgenet0: ethernet@1f610000 {
+ compatible = "apm,xgene2-sgenet";
+ status = "disabled";
+ reg = <0x0 0x1f610000 0x0 0x10000>,
+ <0x0 0x1f600000 0x0 0Xd100>,
+ <0x0 0x20000000 0x0 0X20000>;
+ interrupts = <0 96 4>,
+ <0 97 4>;
+ dma-coherent;
+ clocks = <&xge0clk 0>;
+ local-mac-address = [00 01 73 00 00 01];
+ phy-connection-type = "sgmii";
+ };
+
+ xgenet1: ethernet@1f620000 {
+ compatible = "apm,xgene2-xgenet";
+ status = "disabled";
+ reg = <0x0 0x1f620000 0x0 0x10000>,
+ <0x0 0x1f600000 0x0 0Xd100>,
+ <0x0 0x20000000 0x0 0X220000>;
+ interrupts = <0 108 4>,
+ <0 109 4>,
+ <0 110 4>,
+ <0 111 4>,
+ <0 112 4>,
+ <0 113 4>,
+ <0 114 4>,
+ <0 115 4>;
+ port-id = <1>;
+ dma-coherent;
+ clocks = <&xge1clk 0>;
+ local-mac-address = [00 01 73 00 00 02];
+ phy-connection-type = "xgmii";
+ };
+
+ rng: rng@10520000 {
+ compatible = "apm,xgene-rng";
+ reg = <0x0 0x10520000 0x0 0x100>;
+ interrupts = <0x0 0x41 0x4>;
+ clocks = <&rngpkaclk 0>;
+ };
+
+ i2c1: i2c@10511000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x10511000 0x0 0x1000>;
+ interrupts = <0 0x45 0x4>;
+ #clock-cells = <1>;
+ clocks = <&sbapbclk 0>;
+ bus_num = <1>;
+ };
+
+ i2c4: i2c@10640000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x10640000 0x0 0x1000>;
+ interrupts = <0 0x3A 0x4>;
+ clocks = <&i2c4clk 0>;
+ bus_num = <4>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index d831bc2..b7d7109 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -25,6 +25,7 @@
reg = <0x0 0x000>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_0>;
};
cpu@001 {
device_type = "cpu";
@@ -32,6 +33,7 @@
reg = <0x0 0x001>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_0>;
};
cpu@100 {
device_type = "cpu";
@@ -39,6 +41,7 @@
reg = <0x0 0x100>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_1>;
};
cpu@101 {
device_type = "cpu";
@@ -46,6 +49,7 @@
reg = <0x0 0x101>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_1>;
};
cpu@200 {
device_type = "cpu";
@@ -53,6 +57,7 @@
reg = <0x0 0x200>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_2>;
};
cpu@201 {
device_type = "cpu";
@@ -60,6 +65,7 @@
reg = <0x0 0x201>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_2>;
};
cpu@300 {
device_type = "cpu";
@@ -67,6 +73,7 @@
reg = <0x0 0x300>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_3>;
};
cpu@301 {
device_type = "cpu";
@@ -74,6 +81,19 @@
reg = <0x0 0x301>;
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
+ next-level-cache = <&xgene_L2_3>;
+ };
+ xgene_L2_0: l2-cache-0 {
+ compatible = "cache";
+ };
+ xgene_L2_1: l2-cache-1 {
+ compatible = "cache";
+ };
+ xgene_L2_2: l2-cache-2 {
+ compatible = "cache";
+ };
+ xgene_L2_3: l2-cache-3 {
+ compatible = "cache";
};
};
@@ -97,6 +117,11 @@
clock-frequency = <50000000>;
};
+ pmu {
+ compatible = "apm,potenza-pmu", "arm,armv8-pmuv3";
+ interrupts = <1 12 0xff04>;
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -145,6 +170,35 @@
clock-output-names = "socplldiv2";
};
+ ahbclk: ahbclk@17000000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x17000000 0x0 0x2000>;
+ reg-names = "div-reg";
+ divider-offset = <0x164>;
+ divider-width = <0x5>;
+ divider-shift = <0x0>;
+ clock-output-names = "ahbclk";
+ };
+
+ sdioclk: sdioclk@1f2ac000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f2ac000 0x0 0x1000
+ 0x0 0x17000000 0x0 0x2000>;
+ reg-names = "csr-reg", "div-reg";
+ csr-offset = <0x0>;
+ csr-mask = <0x2>;
+ enable-offset = <0x8>;
+ enable-mask = <0x2>;
+ divider-offset = <0x178>;
+ divider-width = <0x8>;
+ divider-shift = <0x0>;
+ clock-output-names = "sdioclk";
+ };
+
qmlclk: qmlclk {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
@@ -207,6 +261,17 @@
clock-output-names = "xge0clk";
};
+ xge1clk: xge1clk@1f62c000 {
+ compatible = "apm,xgene-device-clock";
+ status = "disabled";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f62c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ csr-mask = <0x3>;
+ clock-output-names = "xge1clk";
+ };
+
sataphy1clk: sataphy1clk@1f21c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
@@ -396,6 +461,18 @@
0x0 0x1f 0x4>;
};
+ scu: system-clk-controller@17000000 {
+ compatible = "apm,xgene-scu","syscon";
+ reg = <0x0 0x17000000 0x0 0x400>;
+ };
+
+ reboot: reboot@17000014 {
+ compatible = "syscon-reboot";
+ regmap = <&scu>;
+ offset = <0x14>;
+ mask = <0x1>;
+ };
+
csw: csw@7e200000 {
compatible = "apm,xgene-csw", "syscon";
reg = <0x0 0x7e200000 0x0 0x1000>;
@@ -416,6 +493,11 @@
reg = <0x0 0x1054a000 0x0 0x20>;
};
+ rb: rb@7e000000 {
+ compatible = "apm,xgene-rb", "syscon";
+ reg = <0x0 0x7e000000 0x0 0x10>;
+ };
+
edac@78800000 {
compatible = "apm,xgene-edac";
#address-cells = <2>;
@@ -425,6 +507,7 @@
regmap-mcba = <&mcba>;
regmap-mcbb = <&mcbb>;
regmap-efuse = <&efuse>;
+ regmap-rb = <&rb>;
reg = <0x0 0x78800000 0x0 0x100>;
interrupts = <0x0 0x20 0x4>,
<0x0 0x21 0x4>,
@@ -477,6 +560,16 @@
reg = <0x0 0x7c600000 0x0 0x200000>;
pmd-controller = <3>;
};
+
+ edacl3@7e600000 {
+ compatible = "apm,xgene-edac-l3";
+ reg = <0x0 0x7e600000 0x0 0x1000>;
+ };
+
+ edacsoc@7e930000 {
+ compatible = "apm,xgene-edac-soc-v1";
+ reg = <0x0 0x7e930000 0x0 0x1000>;
+ };
};
pcie0: pcie@1f2b0000 {
@@ -648,6 +741,50 @@
interrupts = <0x0 0x4f 0x4>;
};
+ mmc0: mmc@1c000000 {
+ compatible = "arasan,sdhci-4.9a";
+ reg = <0x0 0x1c000000 0x0 0x100>;
+ interrupts = <0x0 0x49 0x4>;
+ dma-coherent;
+ no-1-8-v;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&sdioclk 0>, <&ahbclk 0>;
+ };
+
+ gfcgpio: gpio0@1701c000 {
+ compatible = "apm,xgene-gpio";
+ reg = <0x0 0x1701c000 0x0 0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ dwgpio: gpio@1c024000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0 0x1c024000 0x0 0x1000>;
+ reg-io-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
+ i2c0: i2c@10512000 {
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x10512000 0x0 0x1000>;
+ interrupts = <0 0x44 0x4>;
+ #clock-cells = <1>;
+ clocks = <&ahbclk 0>;
+ bus_num = <0>;
+ };
+
phy1: phy@1f21a000 {
compatible = "apm,xgene-phy";
reg = <0x0 0x1f21a000 0x0 0x100>;
@@ -722,7 +859,26 @@
phy-names = "sata-phy";
};
- sbgpio: sbgpio@17001000{
+ /* Do not change dwusb name, coded for backward compatibility */
+ usb0: dwusb@19000000 {
+ status = "disabled";
+ compatible = "snps,dwc3";
+ reg = <0x0 0x19000000 0x0 0x100000>;
+ interrupts = <0x0 0x89 0x4>;
+ dma-coherent;
+ dr_mode = "host";
+ };
+
+ usb1: dwusb@19800000 {
+ status = "disabled";
+ compatible = "snps,dwc3";
+ reg = <0x0 0x19800000 0x0 0x100000>;
+ interrupts = <0x0 0x8a 0x4>;
+ dma-coherent;
+ dr_mode = "host";
+ };
+
+ sbgpio: gpio@17001000{
compatible = "apm,xgene-gpio-sb";
reg = <0x0 0x17001000 0x0 0x400>;
#gpio-cells = <2>;
@@ -808,7 +964,13 @@
<0x0 0x18000000 0x0 0X200>;
reg-names = "enet_csr", "ring_csr", "ring_cmd";
interrupts = <0x0 0x60 0x4>,
- <0x0 0x61 0x4>;
+ <0x0 0x61 0x4>,
+ <0x0 0x62 0x4>,
+ <0x0 0x63 0x4>,
+ <0x0 0x64 0x4>,
+ <0x0 0x65 0x4>,
+ <0x0 0x66 0x4>,
+ <0x0 0x67 0x4>;
dma-coherent;
clocks = <&xge0clk 0>;
/* mac address will be overwritten by the bootloader */
@@ -816,6 +978,23 @@
phy-connection-type = "xgmii";
};
+ xgenet1: ethernet@1f620000 {
+ compatible = "apm,xgene1-xgenet";
+ status = "disabled";
+ reg = <0x0 0x1f620000 0x0 0xd100>,
+ <0x0 0x1f600000 0x0 0Xc300>,
+ <0x0 0x18000000 0x0 0X8000>;
+ reg-names = "enet_csr", "ring_csr", "ring_cmd";
+ interrupts = <0x0 0x6C 0x4>,
+ <0x0 0x6D 0x4>;
+ port-id = <1>;
+ dma-coherent;
+ clocks = <&xge1clk 0>;
+ /* mac address will be overwritten by the bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ phy-connection-type = "xgmii";
+ };
+
rng: rng@10520000 {
compatible = "apm,xgene-rng";
reg = <0x0 0x10520000 0x0 0x100>;
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index e3ee960..e5b59ca 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -17,6 +17,18 @@
};
};
+ mailbox: mhu@2b1f0000 {
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0x0 0x2b1f0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mhu_lpri_rx",
+ "mhu_hpri_rx";
+ #mbox-cells = <1>;
+ clocks = <&soc_refclk100mhz>;
+ clock-names = "apb_pclk";
+ };
+
gic: interrupt-controller@2c010000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
reg = <0x0 0x2c010000 0 0x1000>,
@@ -44,6 +56,53 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
};
+ sram: sram@2e000000 {
+ compatible = "arm,juno-sram-ns", "mmio-sram";
+ reg = <0x0 0x2e000000 0x0 0x8000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x2e000000 0x8000>;
+
+ cpu_scp_lpri: scp-shmem@0 {
+ compatible = "arm,juno-scp-shmem";
+ reg = <0x0 0x200>;
+ };
+
+ cpu_scp_hpri: scp-shmem@200 {
+ compatible = "arm,juno-scp-shmem";
+ reg = <0x200 0x200>;
+ };
+ };
+
+ scpi {
+ compatible = "arm,scpi";
+ mboxes = <&mailbox 1>;
+ shmem = <&cpu_scp_hpri>;
+
+ clocks {
+ compatible = "arm,scpi-clocks";
+
+ scpi_dvfs: scpi_clocks@0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>, <1>, <2>;
+ clock-output-names = "atlclk", "aplclk","gpuclk";
+ };
+ scpi_clk: scpi_clocks@3 {
+ compatible = "arm,scpi-variable-clocks";
+ #clock-cells = <1>;
+ clock-indices = <3>, <4>;
+ clock-output-names = "pxlclk0", "pxlclk1";
+ };
+ };
+
+ scpi_sensors0: sensors {
+ compatible = "arm,scpi-sensors";
+ #thermal-sensor-cells = <1>;
+ };
+ };
+
/include/ "juno-clocks.dtsi"
dma@7ff00000 {
@@ -56,6 +115,7 @@
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 92 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>,
diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 3c38668..413f1b9 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -103,6 +103,21 @@
};
};
+ flash@0,00000000 {
+ /* 2 * 32MiB NOR Flash memory mounted on CS0 */
+ compatible = "arm,vexpress-flash", "cfi-flash";
+ linux,part-probe = "afs";
+ reg = <0 0x00000000 0x04000000>;
+ bank-width = <4>;
+ /*
+ * Unfortunately, accessing the flash disturbs
+ * the CPU idle states (suspend) and CPU
+ * hotplug of the platform. For this reason,
+ * flash hardware access is disabled by default.
+ */
+ status = "disabled";
+ };
+
ethernet@2,00000000 {
compatible = "smsc,lan9118", "smsc,lan9115";
reg = <2 0x00000000 0x10000>;
diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts
index c627511..8826f83 100644
--- a/arch/arm64/boot/dts/arm/juno-r1.dts
+++ b/arch/arm64/boot/dts/arm/juno-r1.dts
@@ -34,12 +34,62 @@
#address-cells = <2>;
#size-cells = <0>;
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&A57_0>;
+ };
+ core1 {
+ cpu = <&A57_1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&A53_0>;
+ };
+ core1 {
+ cpu = <&A53_1>;
+ };
+ core2 {
+ cpu = <&A53_2>;
+ };
+ core3 {
+ cpu = <&A53_3>;
+ };
+ };
+ };
+
+ idle-states {
+ entry-method = "arm,psci";
+
+ CPU_SLEEP_0: cpu-sleep-0 {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0010000>;
+ local-timer-stop;
+ entry-latency-us = <300>;
+ exit-latency-us = <1200>;
+ min-residency-us = <2000>;
+ };
+
+ CLUSTER_SLEEP_0: cluster-sleep-0 {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x1010000>;
+ local-timer-stop;
+ entry-latency-us = <300>;
+ exit-latency-us = <1200>;
+ min-residency-us = <2500>;
+ };
+ };
+
A57_0: cpu@0 {
compatible = "arm,cortex-a57","arm,armv8";
reg = <0x0 0x0>;
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A57_L2>;
+ clocks = <&scpi_dvfs 0>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A57_1: cpu@1 {
@@ -48,6 +98,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A57_L2>;
+ clocks = <&scpi_dvfs 0>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_0: cpu@100 {
@@ -56,6 +108,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_1: cpu@101 {
@@ -64,6 +118,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_2: cpu@102 {
@@ -72,6 +128,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_3: cpu@103 {
@@ -80,6 +138,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A57_L2: l2-cache0 {
@@ -91,17 +151,21 @@
};
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu_a57 {
+ compatible = "arm,cortex-a57-pmu";
interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&A57_0>,
+ <&A57_1>;
+ };
+
+ pmu_a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-affinity = <&A57_0>,
- <&A57_1>,
- <&A53_0>,
+ interrupt-affinity = <&A53_0>,
<&A53_1>,
<&A53_2>,
<&A53_3>;
@@ -109,6 +173,26 @@
#include "juno-base.dtsi"
+ pcie-controller@40000000 {
+ compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic";
+ device_type = "pci";
+ reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */
+ bus-range = <0 255>;
+ linux,pci-domain = <0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ dma-coherent;
+ ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>,
+ <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
+ <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>,
+ <0 0 0 2 &gic 0 0 0 137 4>,
+ <0 0 0 3 &gic 0 0 0 138 4>,
+ <0 0 0 4 &gic 0 0 0 139 4>;
+ msi-parent = <&v2m_0>;
+ };
};
&memtimer {
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index d7cbdd4..dcfcf15 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -34,12 +34,62 @@
#address-cells = <2>;
#size-cells = <0>;
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&A57_0>;
+ };
+ core1 {
+ cpu = <&A57_1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&A53_0>;
+ };
+ core1 {
+ cpu = <&A53_1>;
+ };
+ core2 {
+ cpu = <&A53_2>;
+ };
+ core3 {
+ cpu = <&A53_3>;
+ };
+ };
+ };
+
+ idle-states {
+ entry-method = "arm,psci";
+
+ CPU_SLEEP_0: cpu-sleep-0 {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0010000>;
+ local-timer-stop;
+ entry-latency-us = <300>;
+ exit-latency-us = <1200>;
+ min-residency-us = <2000>;
+ };
+
+ CLUSTER_SLEEP_0: cluster-sleep-0 {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x1010000>;
+ local-timer-stop;
+ entry-latency-us = <300>;
+ exit-latency-us = <1200>;
+ min-residency-us = <2500>;
+ };
+ };
+
A57_0: cpu@0 {
compatible = "arm,cortex-a57","arm,armv8";
reg = <0x0 0x0>;
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A57_L2>;
+ clocks = <&scpi_dvfs 0>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A57_1: cpu@1 {
@@ -48,6 +98,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A57_L2>;
+ clocks = <&scpi_dvfs 0>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_0: cpu@100 {
@@ -56,6 +108,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_1: cpu@101 {
@@ -64,6 +118,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_2: cpu@102 {
@@ -72,6 +128,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A53_3: cpu@103 {
@@ -80,6 +138,8 @@
device_type = "cpu";
enable-method = "psci";
next-level-cache = <&A53_L2>;
+ clocks = <&scpi_dvfs 1>;
+ cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
};
A57_L2: l2-cache0 {
@@ -91,17 +151,21 @@
};
};
- pmu {
- compatible = "arm,armv8-pmuv3";
+ pmu_a57 {
+ compatible = "arm,cortex-a57-pmu";
interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&A57_0>,
+ <&A57_1>;
+ };
+
+ pmu_a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-affinity = <&A57_0>,
- <&A57_1>,
- <&A53_0>,
+ interrupt-affinity = <&A53_0>,
<&A53_1>,
<&A53_2>,
<&A53_3>;
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index 5b1d018..bb3c26d 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -186,6 +186,6 @@
<0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
- /include/ "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi"
+ /include/ "vexpress-v2m-rs1.dtsi"
};
};
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2m-rs1.dtsi b/arch/arm64/boot/dts/arm/vexpress-v2m-rs1.dtsi
new file mode 120000
index 0000000..68fd0f8
--- /dev/null
+++ b/arch/arm64/boot/dts/arm/vexpress-v2m-rs1.dtsi
@@ -0,0 +1 @@
+../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi \ No newline at end of file
diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index 244baf8..6bb3d4d 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -50,10 +50,28 @@
device_type = "memory";
reg = <0x000000000 0x80000000 0x00000000 0x40000000>;
};
+};
+
+&i2c0 {
+ status = "ok";
+};
+
+&i2c1 {
+ status = "ok";
+};
+
+&uart3 {
+ status = "ok";
+};
- soc: soc {
- uart3: serial@66130000 {
- status = "ok";
- };
+&nand {
+ nandcs@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <8>;
+ nand-ecc-step-size = <512>;
+ #address-cells = <1>;
+ #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index 3c92d92..a510d3a 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -31,6 +31,7 @@
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/bcm-ns2.h>
/memreserve/ 0x84b00000 0x00000008;
@@ -44,36 +45,44 @@
#address-cells = <2>;
#size-cells = <0>;
- cpu@0 {
+ A57_0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0 0>;
enable-method = "spin-table";
cpu-release-addr = <0 0x84b00000>;
+ next-level-cache = <&CLUSTER0_L2>;
};
- cpu@1 {
+ A57_1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0 1>;
enable-method = "spin-table";
cpu-release-addr = <0 0x84b00000>;
+ next-level-cache = <&CLUSTER0_L2>;
};
- cpu@2 {
+ A57_2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0 2>;
enable-method = "spin-table";
cpu-release-addr = <0 0x84b00000>;
+ next-level-cache = <&CLUSTER0_L2>;
};
- cpu@3 {
+ A57_3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0 3>;
enable-method = "spin-table";
cpu-release-addr = <0 0x84b00000>;
+ next-level-cache = <&CLUSTER0_L2>;
+ };
+
+ CLUSTER0_L2: l2-cache@000 {
+ compatible = "cache";
};
};
@@ -89,12 +98,154 @@
IRQ_TYPE_EDGE_RISING)>;
};
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&A57_0>,
+ <&A57_1>,
+ <&A57_2>,
+ <&A57_3>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ osc: oscillator {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ iprocmed: iprocmed {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll_scr BCM_NS2_GENPLL_SCR_SCR_CLK>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ iprocslow: iprocslow {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&genpll_scr BCM_NS2_GENPLL_SCR_SCR_CLK>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ };
+ };
+
soc: soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0 0xffffffff>;
+ smmu: mmu@64000000 {
+ compatible = "arm,mmu-500";
+ reg = <0x64000000 0x40000>;
+ #global-interrupts = <2>;
+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+ <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>,
+ <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>,
+ <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>,
+ <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>,
+ <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>,
+ <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>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+ mmu-masters;
+ };
+
+ lcpll_ddr: lcpll_ddr@6501d058 {
+ #clock-cells = <1>;
+ compatible = "brcm,ns2-lcpll-ddr";
+ reg = <0x6501d058 0x20>,
+ <0x6501c020 0x4>,
+ <0x6501d04c 0x4>;
+ clocks = <&osc>;
+ clock-output-names = "lcpll_ddr", "pcie_sata_usb",
+ "ddr", "ddr_ch2_unused",
+ "ddr_ch3_unused", "ddr_ch4_unused",
+ "ddr_ch5_unused";
+ };
+
+ lcpll_ports: lcpll_ports@6501d078 {
+ #clock-cells = <1>;
+ compatible = "brcm,ns2-lcpll-ports";
+ reg = <0x6501d078 0x20>,
+ <0x6501c020 0x4>,
+ <0x6501d054 0x4>;
+ clocks = <&osc>;
+ clock-output-names = "lcpll_ports", "wan", "rgmii",
+ "ports_ch2_unused",
+ "ports_ch3_unused",
+ "ports_ch4_unused",
+ "ports_ch5_unused";
+ };
+
+ genpll_scr: genpll_scr@6501d098 {
+ #clock-cells = <1>;
+ compatible = "brcm,ns2-genpll-scr";
+ reg = <0x6501d098 0x32>,
+ <0x6501c020 0x4>,
+ <0x6501d044 0x4>;
+ clocks = <&osc>;
+ clock-output-names = "genpll_scr", "scr", "fs",
+ "audio_ref", "scr_ch3_unused",
+ "scr_ch4_unused", "scr_ch5_unused";
+ };
+
+ genpll_sw: genpll_sw@6501d0c4 {
+ #clock-cells = <1>;
+ compatible = "brcm,ns2-genpll-sw";
+ reg = <0x6501d0c4 0x32>,
+ <0x6501c020 0x4>,
+ <0x6501d044 0x4>;
+ clocks = <&osc>;
+ clock-output-names = "genpll_sw", "rpe", "250", "nic",
+ "chimp", "port", "sdio";
+ };
+
+ crmu: crmu@65024000 {
+ compatible = "syscon";
+ reg = <0x65024000 0x100>;
+ };
+
+ reboot@65024000 {
+ compatible ="syscon-reboot";
+ regmap = <&crmu>;
+ offset = <0x90>;
+ mask = <0xfffffffd>;
+ };
+
gic: interrupt-controller@65210000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
@@ -105,14 +256,53 @@
<0x65260000 0x1000>;
};
+ i2c0: i2c@66080000 {
+ compatible = "brcm,iproc-i2c";
+ reg = <0x66080000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 394 IRQ_TYPE_NONE>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@660b0000 {
+ compatible = "brcm,iproc-i2c";
+ reg = <0x660b0000 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 395 IRQ_TYPE_NONE>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
uart3: serial@66130000 {
compatible = "snps,dw-apb-uart";
reg = <0x66130000 0x100>;
interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
- clock-frequency = <23961600>;
+ clocks = <&osc>;
status = "disabled";
};
+
+ hwrng: hwrng@66220000 {
+ compatible = "brcm,iproc-rng200";
+ reg = <0x66220000 0x28>;
+ };
+
+ nand: nand@66460000 {
+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1";
+ reg = <0x66460000 0x600>,
+ <0x67015408 0x600>,
+ <0x66460f00 0x20>;
+ reg-names = "nand", "iproc-idm", "iproc-ext";
+ interrupts = <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ brcm,nand-has-wp;
+ };
};
};
diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 5424cc4..d8767b0 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -11,6 +11,7 @@
/dts-v1/;
#include "exynos7.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "Samsung Exynos7 Espresso board based on EXYNOS7";
@@ -52,11 +53,288 @@
status = "okay";
};
+&hsi2c_4 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <200000>;
+ status = "okay";
+
+ s2mps15_pmic@66 {
+ compatible = "samsung,s2mps15-pmic";
+ reg = <0x66>;
+ interrupts = <2 IRQ_TYPE_NONE>;
+ interrupt-parent = <&gpa0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_irq>;
+ wakeup-source;
+
+ s2mps15_osc: clocks {
+ compatible = "samsung,s2mps13-clk";
+ #clock-cells = <1>;
+ clock-output-names = "s2mps13_ap", "s2mps13_cp",
+ "s2mps13_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_ldo1";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "vqmmc-sdcard";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_ldo3";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "vdd_ldo4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1110000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_ldo5";
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_ldo6";
+ regulator-min-microvolt = <2250000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_ldo7";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "vdd_ldo14";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3375000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "vmmc-sdcard";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3375000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "vdd_ldo18";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2275000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "vdd_ldo19";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3375000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "vdd_ldo21";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3375000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "vdd_ldo23";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2275000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "vdd_ldo25";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3375000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "vdd_ldo26";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1470000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "vdd_ldo27";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <2275000>;
+ regulator-enable-ramp-delay = <125>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_atlas";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_buck5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_buck7";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_buck8";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_buck9";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-always-on;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_buck10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-ramp-delay = <25000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+ };
+ };
+};
+
+&pinctrl_alive {
+ pmic_irq: pmic-irq {
+ samsung,pins = "gpa0-2";
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+};
+
&mmc_0 {
status = "okay";
num-slots = <1>;
- broken-cd;
cap-mmc-highspeed;
+ mmc-hs200-1_8v;
non-removable;
card-detect-delay = <200>;
clock-frequency = <800000000>;
@@ -80,5 +358,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
bus-width = <4>;
+ vmmc-supply = <&ldo17_reg>;
+ vqmmc-supply = <&ldo2_reg>;
disable-wp;
};
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index 2eef4a2..f77ddaf 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -586,3 +586,106 @@
samsung,pin-drv = <2>;
};
};
+
+&pinctrl_bus1 {
+ 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>;
+ };
+
+ gpf4: gpf4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf5: gpf5 {
+ 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>;
+ };
+
+ gph1: gph1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv6: gpv6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ spi5_bus: spi5-bus {
+ samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ ufs_refclk_out: ufs-refclk-out {
+ samsung,pins = "gpg2-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ ufs_rst_n: ufs-rst-n {
+ samsung,pins = "gph1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index d7a37c3..93108f1 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -26,6 +26,7 @@
pinctrl5 = &pinctrl_ese;
pinctrl6 = &pinctrl_fsys0;
pinctrl7 = &pinctrl_fsys1;
+ pinctrl8 = &pinctrl_bus1;
};
cpus {
@@ -278,6 +279,12 @@
interrupts = <0 203 0>;
};
+ pinctrl_bus1: pinctrl@14870000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x14870000 0x1000>;
+ interrupts = <0 384 0>;
+ };
+
hsi2c_0: hsi2c@13640000 {
compatible = "samsung,exynos7-hsi2c";
reg = <0x13640000 0x1000>;
@@ -447,6 +454,13 @@
reg = <0x105c0000 0x5000>;
};
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x0400>;
+ mask = <0x1>;
+ };
+
rtc: rtc@10590000 {
compatible = "samsung,s3c6410-rtc";
reg = <0x10590000 0x100>;
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 4f2de3e7..f3c2516 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -1,4 +1,7 @@
-dtb-$(CONFIG_ARCH_FSL_LS2085A) += fsl-ls2085a-simu.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
new file mode 100644
index 0000000..ce23557
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
@@ -0,0 +1,116 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1043A family SoC.
+ *
+ * Copyright 2014-2015, Freescale Semiconductor
+ *
+ * Mingkai Hu <Mingkai.hu@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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/ "fsl-ls1043a.dtsi"
+
+/ {
+ model = "LS1043A RDB Board";
+};
+
+&i2c0 {
+ status = "okay";
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+ adt7461a@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c512";
+ reg = <0x52>;
+ };
+ eeprom@53 {
+ compatible = "at24,24c512";
+ reg = <0x53>;
+ };
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+};
+
+&ifc {
+ status = "okay";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NOR, NAND Flashes and FPGA on board */
+ ranges = <0x0 0x0 0x0 0x60000000 0x08000000
+ 0x1 0x0 0x0 0x7e800000 0x00010000
+ 0x2 0x0 0x0 0x7fb00000 0x00000100>;
+
+ nor@0,0 {
+ compatible = "cfi-flash";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ compatible = "fsl,ifc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1 0x0 0x10000>;
+ };
+
+ cpld: board-control@2,0 {
+ compatible = "fsl,ls1043ardb-cpld";
+ reg = <0x2 0x0 0x0000100>;
+ };
+};
+
+&duart0 {
+ status = "okay";
+};
+
+&duart1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
new file mode 100644
index 0000000..42a6154
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -0,0 +1,527 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-1043A family SoC.
+ *
+ * Copyright 2014-2015, Freescale Semiconductor
+ *
+ * Mingkai Hu <Mingkai.hu@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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.
+ */
+
+/ {
+ compatible = "fsl,ls1043a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /*
+ * We expect the enable-method for cpu's to be "psci", but this
+ * is dependent on the SoC FW, which will fill this in.
+ *
+ * Currently supported enable-method is psci v0.2
+ */
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x0>;
+ clocks = <&clockgen 1 0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x1>;
+ clocks = <&clockgen 1 0>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x2>;
+ clocks = <&clockgen 1 0>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0 0x3>;
+ clocks = <&clockgen 1 0>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0 0x80000000>;
+ /* DRAM space 1, size: 2GiB DRAM */
+ };
+
+ sysclk: sysclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "sysclk";
+ };
+
+ reboot {
+ compatible ="syscon-reboot";
+ regmap = <&dcfg>;
+ offset = <0xb0>;
+ mask = <0x02>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0x1>, /* Physical Secure PPI */
+ <1 14 0x1>, /* Physical Non-Secure PPI */
+ <1 11 0x1>, /* Virtual PPI */
+ <1 10 0x1>; /* Hypervisor PPI */
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <0 106 0x4>,
+ <0 107 0x4>,
+ <0 95 0x4>,
+ <0 97 0x4>;
+ interrupt-affinity = <&cpu0>,
+ <&cpu1>,
+ <&cpu2>,
+ <&cpu3>;
+ };
+
+ gic: interrupt-controller@1400000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x1401000 0 0x1000>, /* GICD */
+ <0x0 0x1402000 0 0x2000>, /* GICC */
+ <0x0 0x1404000 0 0x2000>, /* GICH */
+ <0x0 0x1406000 0 0x2000>; /* GICV */
+ interrupts = <1 9 0xf08>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clockgen: clocking@1ee1000 {
+ compatible = "fsl,ls1043a-clockgen";
+ reg = <0x0 0x1ee1000 0x0 0x1000>;
+ #clock-cells = <2>;
+ clocks = <&sysclk>;
+ };
+
+ scfg: scfg@1570000 {
+ compatible = "fsl,ls1043a-scfg", "syscon";
+ reg = <0x0 0x1570000 0x0 0x10000>;
+ big-endian;
+ };
+
+ dcfg: dcfg@1ee0000 {
+ compatible = "fsl,ls1043a-dcfg", "syscon";
+ reg = <0x0 0x1ee0000 0x0 0x10000>;
+ big-endian;
+ };
+
+ ifc: ifc@1530000 {
+ compatible = "fsl,ifc", "simple-bus";
+ reg = <0x0 0x1530000 0x0 0x10000>;
+ interrupts = <0 43 0x4>;
+ };
+
+ esdhc: esdhc@1560000 {
+ compatible = "fsl,ls1043a-esdhc", "fsl,esdhc";
+ reg = <0x0 0x1560000 0x0 0x10000>;
+ interrupts = <0 62 0x4>;
+ clock-frequency = <0>;
+ voltage-ranges = <1800 1800 3300 3300>;
+ sdhci,auto-cmd12;
+ big-endian;
+ bus-width = <4>;
+ };
+
+ dspi0: dspi@2100000 {
+ compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2100000 0x0 0x10000>;
+ interrupts = <0 64 0x4>;
+ clock-names = "dspi";
+ clocks = <&clockgen 4 0>;
+ spi-num-chipselects = <5>;
+ big-endian;
+ status = "disabled";
+ };
+
+ dspi1: dspi@2110000 {
+ compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2110000 0x0 0x10000>;
+ interrupts = <0 65 0x4>;
+ clock-names = "dspi";
+ clocks = <&clockgen 4 0>;
+ 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 = <0 56 0x4>;
+ clock-names = "i2c";
+ clocks = <&clockgen 4 0>;
+ dmas = <&edma0 1 39>,
+ <&edma0 1 38>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ i2c1: i2c@2190000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2190000 0x0 0x10000>;
+ interrupts = <0 57 0x4>;
+ clock-names = "i2c";
+ clocks = <&clockgen 4 0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@21a0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x21a0000 0x0 0x10000>;
+ interrupts = <0 58 0x4>;
+ clock-names = "i2c";
+ clocks = <&clockgen 4 0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@21b0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x21b0000 0x0 0x10000>;
+ interrupts = <0 59 0x4>;
+ clock-names = "i2c";
+ clocks = <&clockgen 4 0>;
+ status = "disabled";
+ };
+
+ duart0: serial@21c0500 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x00 0x21c0500 0x0 0x100>;
+ interrupts = <0 54 0x4>;
+ clocks = <&clockgen 4 0>;
+ };
+
+ duart1: serial@21c0600 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x00 0x21c0600 0x0 0x100>;
+ interrupts = <0 54 0x4>;
+ clocks = <&clockgen 4 0>;
+ };
+
+ duart2: serial@21d0500 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21d0500 0x0 0x100>;
+ interrupts = <0 55 0x4>;
+ clocks = <&clockgen 4 0>;
+ };
+
+ duart3: serial@21d0600 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21d0600 0x0 0x100>;
+ interrupts = <0 55 0x4>;
+ clocks = <&clockgen 4 0>;
+ };
+
+ gpio1: gpio@2300000 {
+ compatible = "fsl,ls1043a-gpio";
+ reg = <0x0 0x2300000 0x0 0x10000>;
+ interrupts = <0 66 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2310000 {
+ compatible = "fsl,ls1043a-gpio";
+ reg = <0x0 0x2310000 0x0 0x10000>;
+ interrupts = <0 67 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@2320000 {
+ compatible = "fsl,ls1043a-gpio";
+ reg = <0x0 0x2320000 0x0 0x10000>;
+ interrupts = <0 68 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@2330000 {
+ compatible = "fsl,ls1043a-gpio";
+ reg = <0x0 0x2330000 0x0 0x10000>;
+ interrupts = <0 134 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ lpuart0: serial@2950000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2950000 0x0 0x1000>;
+ interrupts = <0 48 0x4>;
+ clocks = <&clockgen 0 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart1: serial@2960000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2960000 0x0 0x1000>;
+ interrupts = <0 49 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart2: serial@2970000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2970000 0x0 0x1000>;
+ interrupts = <0 50 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart3: serial@2980000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2980000 0x0 0x1000>;
+ interrupts = <0 51 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart4: serial@2990000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x2990000 0x0 0x1000>;
+ interrupts = <0 52 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart5: serial@29a0000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x0 0x29a0000 0x0 0x1000>;
+ interrupts = <0 53 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ wdog0: wdog@2ad0000 {
+ compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt";
+ reg = <0x0 0x2ad0000 0x0 0x10000>;
+ interrupts = <0 83 0x4>;
+ clocks = <&clockgen 4 0>;
+ clock-names = "wdog";
+ big-endian;
+ };
+
+ edma0: edma@2c00000 {
+ #dma-cells = <2>;
+ compatible = "fsl,vf610-edma";
+ reg = <0x0 0x2c00000 0x0 0x10000>,
+ <0x0 0x2c10000 0x0 0x10000>,
+ <0x0 0x2c20000 0x0 0x10000>;
+ interrupts = <0 103 0x4>,
+ <0 103 0x4>;
+ interrupt-names = "edma-tx", "edma-err";
+ dma-channels = <32>;
+ big-endian;
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&clockgen 4 0>,
+ <&clockgen 4 0>;
+ };
+
+ usb0: usb3@2f00000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x2f00000 0x0 0x10000>;
+ interrupts = <0 60 0x4>;
+ dr_mode = "host";
+ };
+
+ usb1: usb3@3000000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3000000 0x0 0x10000>;
+ interrupts = <0 61 0x4>;
+ dr_mode = "host";
+ };
+
+ usb2: usb3@3100000 {
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3100000 0x0 0x10000>;
+ interrupts = <0 63 0x4>;
+ dr_mode = "host";
+ };
+
+ sata: sata@3200000 {
+ compatible = "fsl,ls1043a-ahci", "fsl,ls1021a-ahci";
+ reg = <0x0 0x3200000 0x0 0x10000>;
+ interrupts = <0 69 0x4>;
+ clocks = <&clockgen 4 0>;
+ };
+
+ msi1: msi-controller1@1571000 {
+ compatible = "fsl,1s1043a-msi";
+ reg = <0x0 0x1571000 0x0 0x8>;
+ msi-controller;
+ interrupts = <0 116 0x4>;
+ };
+
+ msi2: msi-controller2@1572000 {
+ compatible = "fsl,1s1043a-msi";
+ reg = <0x0 0x1572000 0x0 0x8>;
+ msi-controller;
+ interrupts = <0 126 0x4>;
+ };
+
+ msi3: msi-controller3@1573000 {
+ compatible = "fsl,1s1043a-msi";
+ reg = <0x0 0x1573000 0x0 0x8>;
+ msi-controller;
+ interrupts = <0 160 0x4>;
+ };
+
+ pcie@3400000 {
+ compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
+ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 118 0x4>, /* controller interrupt */
+ <0 117 0x4>; /* PME interrupt */
+ interrupt-names = "intr", "pme";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <4>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&msi1>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 110 0x4>,
+ <0000 0 0 2 &gic 0 111 0x4>,
+ <0000 0 0 3 &gic 0 112 0x4>,
+ <0000 0 0 4 &gic 0 113 0x4>;
+ };
+
+ pcie@3500000 {
+ compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
+ 0x48 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 128 0x4>,
+ <0 127 0x4>;
+ interrupt-names = "intr", "pme";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <2>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&msi2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 120 0x4>,
+ <0000 0 0 2 &gic 0 121 0x4>,
+ <0000 0 0 3 &gic 0 122 0x4>,
+ <0000 0 0 4 &gic 0 123 0x4>;
+ };
+
+ pcie@3600000 {
+ compatible = "fsl,ls1043a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
+ 0x50 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 162 0x4>,
+ <0 161 0x4>;
+ interrupt-names = "intr", "pme";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <2>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&msi3>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 154 0x4>,
+ <0000 0 0 2 &gic 0 155 0x4>,
+ <0000 0 0 3 &gic 0 156 0x4>,
+ <0000 0 0 4 &gic 0 157 0x4>;
+ };
+ };
+
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
new file mode 100644
index 0000000..4cb996d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
@@ -0,0 +1,204 @@
+/*
+ * Device Tree file for Freescale LS2080a QDS Board.
+ *
+ * Copyright (C) 2015, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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/ "fsl-ls2080a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2080a QDS Board";
+ compatible = "fsl,ls2080a-qds", "fsl,ls2080a";
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ };
+
+};
+
+&esdhc {
+ status = "okay";
+};
+
+&ifc {
+ status = "okay";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x5 0x80000000 0x08000000
+ 0x2 0x0 0x5 0x30000000 0x00010000
+ 0x3 0x0 0x5 0x20000000 0x00010000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ cpld@3,0 {
+ reg = <0x3 0x0 0x10000>;
+ compatible = "fsl,ls2080aqds-fpga", "fsl,fpga-qixis";
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pca9547@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x00>;
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x02>;
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <500>;
+ };
+
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ adt7481@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "disabled";
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+&dspi {
+ status = "okay";
+ dflash0: n25q128a {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <3000000>;
+ reg = <0>;
+ };
+ dflash1: sst25wf040b {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <3000000>;
+ reg = <1>;
+ };
+ dflash2: en25s64 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <3000000>;
+ reg = <2>;
+ };
+};
+
+&qspi {
+ status = "okay";
+ qflash0: s25fl008k {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sata1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
new file mode 100644
index 0000000..e127f0b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
@@ -0,0 +1,166 @@
+/*
+ * Device Tree file for Freescale LS2080a RDB Board.
+ *
+ * Copyright (C) 2015, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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/ "fsl-ls2080a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2080a RDB Board";
+ compatible = "fsl,ls2080a-rdb", "fsl,ls2080a";
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ };
+};
+
+&esdhc {
+ status = "okay";
+};
+
+&ifc {
+ status = "okay";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x5 0x80000000 0x08000000
+ 0x2 0x0 0x5 0x30000000 0x00010000
+ 0x3 0x0 0x5 0x20000000 0x00010000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ cpld@3,0 {
+ reg = <0x3 0x0 0x10000>;
+ compatible = "fsl,ls2080aqds-fpga", "fsl,fpga-qixis";
+ };
+
+};
+
+&i2c0 {
+ status = "okay";
+ pca9547@75 {
+ compatible = "nxp,pca9547";
+ reg = <0x75>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x01>;
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ adt7481@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "disabled";
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+&dspi {
+ status = "okay";
+ dflash0: n25q512a {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p80";
+ spi-max-frequency = <3000000>;
+ reg = <0>;
+ };
+};
+
+&qspi {
+ status = "disabled";
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sata1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
new file mode 100644
index 0000000..505d038
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
@@ -0,0 +1,70 @@
+/*
+ * Device Tree file for Freescale LS2080a software Simulator model
+ *
+ * Copyright (C) 2014-2015, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.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/ "fsl-ls2080a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2080a software Simulator model";
+ compatible = "fsl,ls2080a-simu", "fsl,ls2080a";
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ };
+
+ ethernet@2210000 {
+ compatible = "smsc,lan91c111";
+ reg = <0x0 0x2210000 0x0 0x100>;
+ interrupts = <0 58 0x1>;
+ };
+};
+
+&ifc {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
new file mode 100644
index 0000000..2b23d03
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -0,0 +1,588 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-2080A family SoC.
+ *
+ * Copyright (C) 2014-2015, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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.
+ */
+
+/ {
+ compatible = "fsl,ls2080a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /*
+ * We expect the enable-method for cpu's to be "psci", but this
+ * is dependent on the SoC FW, which will fill this in.
+ *
+ * Currently supported enable-method is psci v0.2
+ */
+
+ /* We have 4 clusters having 2 Cortex-A57 cores each */
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x0>;
+ clocks = <&clockgen 1 0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x1>;
+ clocks = <&clockgen 1 0>;
+ };
+
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x100>;
+ clocks = <&clockgen 1 1>;
+ };
+
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x101>;
+ clocks = <&clockgen 1 1>;
+ };
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x200>;
+ clocks = <&clockgen 1 2>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x201>;
+ clocks = <&clockgen 1 2>;
+ };
+
+ cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x300>;
+ clocks = <&clockgen 1 3>;
+ };
+
+ cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x301>;
+ clocks = <&clockgen 1 3>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x80000000>;
+ /* DRAM space - 1, size : 2 GB DRAM */
+ };
+
+ sysclk: sysclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "sysclk";
+ };
+
+ gic: interrupt-controller@6000000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
+ <0x0 0x06100000 0 0x100000>, /* GICR (RD_base + SGI_base) */
+ <0x0 0x0c0c0000 0 0x2000>, /* GICC */
+ <0x0 0x0c0d0000 0 0x1000>, /* GICH */
+ <0x0 0x0c0e0000 0 0x20000>; /* GICV */
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+ interrupts = <1 9 0x4>;
+
+ its: gic-its@6020000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ reg = <0x0 0x6020000 0 0x20000>;
+ };
+ };
+
+ rstcr: syscon@1e60000 {
+ compatible = "fsl,ls2080a-rstcr", "syscon";
+ reg = <0x0 0x1e60000 0x0 0x4>;
+ };
+
+ reboot {
+ compatible ="syscon-reboot";
+ regmap = <&rstcr>;
+ offset = <0x0>;
+ mask = <0x2>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
+ <1 14 0x8>, /* Physical Non-Secure PPI, active-low */
+ <1 11 0x8>, /* Virtual PPI, active-low */
+ <1 10 0x8>; /* Hypervisor PPI, active-low */
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clockgen: clocking@1300000 {
+ compatible = "fsl,ls2080a-clockgen";
+ reg = <0 0x1300000 0 0xa0000>;
+ #clock-cells = <2>;
+ clocks = <&sysclk>;
+ };
+
+ serial0: serial@21c0500 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0500 0x0 0x100>;
+ clocks = <&clockgen 4 3>;
+ interrupts = <0 32 0x4>; /* Level high type */
+ };
+
+ serial1: serial@21c0600 {
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0600 0x0 0x100>;
+ clocks = <&clockgen 4 3>;
+ interrupts = <0 32 0x4>; /* Level high type */
+ };
+
+ cluster1_core0_watchdog: wdt@c000000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc000000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster1_core1_watchdog: wdt@c010000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc010000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster2_core0_watchdog: wdt@c100000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc100000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster2_core1_watchdog: wdt@c110000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc110000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster3_core0_watchdog: wdt@c200000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc200000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster3_core1_watchdog: wdt@c210000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc210000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster4_core0_watchdog: wdt@c300000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc300000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ cluster4_core1_watchdog: wdt@c310000 {
+ compatible = "arm,sp805-wdt", "arm,primecell";
+ reg = <0x0 0xc310000 0x0 0x1000>;
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "apb_pclk", "wdog_clk";
+ };
+
+ fsl_mc: fsl-mc@80c000000 {
+ compatible = "fsl,qoriq-mc";
+ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
+ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
+ };
+
+ smmu: iommu@5000000 {
+ compatible = "arm,mmu-500";
+ reg = <0 0x5000000 0 0x800000>;
+ #global-interrupts = <12>;
+ interrupts = <0 13 4>, /* global secure fault */
+ <0 14 4>, /* combined secure interrupt */
+ <0 15 4>, /* global non-secure fault */
+ <0 16 4>, /* combined non-secure interrupt */
+ /* performance counter interrupts 0-7 */
+ <0 211 4>, <0 212 4>,
+ <0 213 4>, <0 214 4>,
+ <0 215 4>, <0 216 4>,
+ <0 217 4>, <0 218 4>,
+ /* per context interrupt, 64 interrupts */
+ <0 146 4>, <0 147 4>,
+ <0 148 4>, <0 149 4>,
+ <0 150 4>, <0 151 4>,
+ <0 152 4>, <0 153 4>,
+ <0 154 4>, <0 155 4>,
+ <0 156 4>, <0 157 4>,
+ <0 158 4>, <0 159 4>,
+ <0 160 4>, <0 161 4>,
+ <0 162 4>, <0 163 4>,
+ <0 164 4>, <0 165 4>,
+ <0 166 4>, <0 167 4>,
+ <0 168 4>, <0 169 4>,
+ <0 170 4>, <0 171 4>,
+ <0 172 4>, <0 173 4>,
+ <0 174 4>, <0 175 4>,
+ <0 176 4>, <0 177 4>,
+ <0 178 4>, <0 179 4>,
+ <0 180 4>, <0 181 4>,
+ <0 182 4>, <0 183 4>,
+ <0 184 4>, <0 185 4>,
+ <0 186 4>, <0 187 4>,
+ <0 188 4>, <0 189 4>,
+ <0 190 4>, <0 191 4>,
+ <0 192 4>, <0 193 4>,
+ <0 194 4>, <0 195 4>,
+ <0 196 4>, <0 197 4>,
+ <0 198 4>, <0 199 4>,
+ <0 200 4>, <0 201 4>,
+ <0 202 4>, <0 203 4>,
+ <0 204 4>, <0 205 4>,
+ <0 206 4>, <0 207 4>,
+ <0 208 4>, <0 209 4>;
+ mmu-masters = <&fsl_mc 0x300 0>;
+ };
+
+ dspi: dspi@2100000 {
+ status = "disabled";
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2100000 0x0 0x10000>;
+ interrupts = <0 26 0x4>; /* Level high type */
+ clocks = <&clockgen 4 3>;
+ clock-names = "dspi";
+ spi-num-chipselects = <5>;
+ bus-num = <0>;
+ };
+
+ esdhc: esdhc@2140000 {
+ status = "disabled";
+ compatible = "fsl,ls2080a-esdhc", "fsl,esdhc";
+ reg = <0x0 0x2140000 0x0 0x10000>;
+ interrupts = <0 28 0x4>; /* Level high type */
+ clock-frequency = <0>; /* Updated by bootloader */
+ voltage-ranges = <1800 1800 3300 3300>;
+ sdhci,auto-cmd12;
+ little-endian;
+ bus-width = <4>;
+ };
+
+ gpio0: gpio@2300000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2300000 0x0 0x10000>;
+ interrupts = <0 36 0x4>; /* Level high type */
+ gpio-controller;
+ little-endian;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@2310000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2310000 0x0 0x10000>;
+ interrupts = <0 36 0x4>; /* Level high type */
+ gpio-controller;
+ little-endian;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2320000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2320000 0x0 0x10000>;
+ interrupts = <0 37 0x4>; /* Level high type */
+ gpio-controller;
+ little-endian;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@2330000 {
+ compatible = "fsl,qoriq-gpio";
+ reg = <0x0 0x2330000 0x0 0x10000>;
+ interrupts = <0 37 0x4>; /* Level high type */
+ gpio-controller;
+ little-endian;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ i2c0: i2c@2000000 {
+ status = "disabled";
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2000000 0x0 0x10000>;
+ interrupts = <0 34 0x4>; /* Level high type */
+ clock-names = "i2c";
+ clocks = <&clockgen 4 3>;
+ };
+
+ i2c1: i2c@2010000 {
+ status = "disabled";
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2010000 0x0 0x10000>;
+ interrupts = <0 34 0x4>; /* Level high type */
+ clock-names = "i2c";
+ clocks = <&clockgen 4 3>;
+ };
+
+ i2c2: i2c@2020000 {
+ status = "disabled";
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2020000 0x0 0x10000>;
+ interrupts = <0 35 0x4>; /* Level high type */
+ clock-names = "i2c";
+ clocks = <&clockgen 4 3>;
+ };
+
+ i2c3: i2c@2030000 {
+ status = "disabled";
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2030000 0x0 0x10000>;
+ interrupts = <0 35 0x4>; /* Level high type */
+ clock-names = "i2c";
+ clocks = <&clockgen 4 3>;
+ };
+
+ ifc: ifc@2240000 {
+ compatible = "fsl,ifc", "simple-bus";
+ reg = <0x0 0x2240000 0x0 0x20000>;
+ interrupts = <0 21 0x4>; /* Level high type */
+ little-endian;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ranges = <0 0 0x5 0x80000000 0x08000000
+ 2 0 0x5 0x30000000 0x00010000
+ 3 0 0x5 0x20000000 0x00010000>;
+ };
+
+ qspi: quadspi@20c0000 {
+ status = "disabled";
+ compatible = "fsl,vf610-qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x20c0000 0x0 0x10000>,
+ <0x0 0x20000000 0x0 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <0 25 0x4>; /* Level high type */
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "qspi_en", "qspi";
+ };
+
+ pcie@3400000 {
+ compatible = "fsl,ls2080a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
+ 0x10 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 108 0x4>; /* Level high type */
+ interrupt-names = "intr";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <4>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x10 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x10 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&its>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 0 0 109 4>,
+ <0000 0 0 2 &gic 0 0 0 110 4>,
+ <0000 0 0 3 &gic 0 0 0 111 4>,
+ <0000 0 0 4 &gic 0 0 0 112 4>;
+ };
+
+ pcie@3500000 {
+ compatible = "fsl,ls2080a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
+ 0x12 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 113 0x4>; /* Level high type */
+ interrupt-names = "intr";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <4>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x12 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x12 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&its>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 0 0 114 4>,
+ <0000 0 0 2 &gic 0 0 0 115 4>,
+ <0000 0 0 3 &gic 0 0 0 116 4>,
+ <0000 0 0 4 &gic 0 0 0 117 4>;
+ };
+
+ pcie@3600000 {
+ compatible = "fsl,ls2080a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
+ 0x14 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 118 0x4>; /* Level high type */
+ interrupt-names = "intr";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <8>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x14 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x14 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&its>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 0 0 119 4>,
+ <0000 0 0 2 &gic 0 0 0 120 4>,
+ <0000 0 0 3 &gic 0 0 0 121 4>,
+ <0000 0 0 4 &gic 0 0 0 122 4>;
+ };
+
+ pcie@3700000 {
+ compatible = "fsl,ls2080a-pcie", "snps,dw-pcie";
+ reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */
+ 0x16 0x00000000 0x0 0x00002000>; /* configuration space */
+ reg-names = "regs", "config";
+ interrupts = <0 123 0x4>; /* Level high type */
+ interrupt-names = "intr";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ num-lanes = <4>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x81000000 0x0 0x00000000 0x16 0x00010000 0x0 0x00010000 /* downstream I/O */
+ 0x82000000 0x0 0x40000000 0x16 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ msi-parent = <&its>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0000 0 0 1 &gic 0 0 0 124 4>,
+ <0000 0 0 2 &gic 0 0 0 125 4>,
+ <0000 0 0 3 &gic 0 0 0 126 4>,
+ <0000 0 0 4 &gic 0 0 0 127 4>;
+ };
+
+ sata0: sata@3200000 {
+ status = "disabled";
+ compatible = "fsl,ls2080a-ahci";
+ reg = <0x0 0x3200000 0x0 0x10000>;
+ interrupts = <0 133 0x4>; /* Level high type */
+ clocks = <&clockgen 4 3>;
+ };
+
+ sata1: sata@3210000 {
+ status = "disabled";
+ compatible = "fsl,ls2080a-ahci";
+ reg = <0x0 0x3210000 0x0 0x10000>;
+ interrupts = <0 136 0x4>; /* Level high type */
+ clocks = <&clockgen 4 3>;
+ };
+
+ usb0: usb3@3100000 {
+ status = "disabled";
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3100000 0x0 0x10000>;
+ interrupts = <0 80 0x4>; /* Level high type */
+ dr_mode = "host";
+ };
+
+ usb1: usb3@3110000 {
+ status = "disabled";
+ compatible = "snps,dwc3";
+ reg = <0x0 0x3110000 0x0 0x10000>;
+ interrupts = <0 81 0x4>; /* Level high type */
+ dr_mode = "host";
+ };
+
+ ccn@4000000 {
+ compatible = "arm,ccn-504";
+ reg = <0x0 0x04000000 0x0 0x01000000>;
+ interrupts = <0 12 4>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts
deleted file mode 100644
index 82e2a6f..0000000
--- a/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Device Tree file for Freescale LS2085a software Simulator model
- *
- * Copyright (C) 2014, Freescale Semiconductor
- *
- * Bhupesh Sharma <bhupesh.sharma@freescale.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/ "fsl-ls2085a.dtsi"
-
-/ {
- model = "Freescale Layerscape 2085a software Simulator model";
- compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
-
- ethernet@2210000 {
- compatible = "smsc,lan91c111";
- reg = <0x0 0x2210000 0x0 0x100>;
- interrupts = <0 58 0x1>;
- };
-};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
deleted file mode 100644
index e281ceb..0000000
--- a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Device Tree Include file for Freescale Layerscape-2085A family SoC.
- *
- * Copyright (C) 2014, Freescale Semiconductor
- *
- * Bhupesh Sharma <bhupesh.sharma@freescale.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 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.
- */
-
-/ {
- compatible = "fsl,ls2085a";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
-
- cpus {
- #address-cells = <2>;
- #size-cells = <0>;
-
- /*
- * We expect the enable-method for cpu's to be "psci", but this
- * is dependent on the SoC FW, which will fill this in.
- *
- * Currently supported enable-method is psci v0.2
- */
-
- /* We have 4 clusters having 2 Cortex-A57 cores each */
- cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x1>;
- };
-
- cpu@100 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x100>;
- };
-
- cpu@101 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x101>;
- };
-
- cpu@200 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x200>;
- };
-
- cpu@201 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x201>;
- };
-
- cpu@300 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x300>;
- };
-
- cpu@301 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x301>;
- };
- };
-
- memory@80000000 {
- device_type = "memory";
- reg = <0x00000000 0x80000000 0 0x80000000>;
- /* DRAM space - 1, size : 2 GB DRAM */
- };
-
- gic: interrupt-controller@6000000 {
- compatible = "arm,gic-v3";
- reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
- <0x0 0x06100000 0 0x100000>; /* GICR (RD_base + SGI_base) */
- #interrupt-cells = <3>;
- interrupt-controller;
- interrupts = <1 9 0x4>;
- };
-
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
- <1 14 0x8>, /* Physical Non-Secure PPI, active-low */
- <1 11 0x8>, /* Virtual PPI, active-low */
- <1 10 0x8>; /* Hypervisor PPI, active-low */
- };
-
- serial0: serial@21c0500 {
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550a";
- reg = <0x0 0x21c0500 0x0 0x100>;
- clock-frequency = <0>; /* Updated by bootloader */
- interrupts = <0 32 0x1>; /* edge triggered */
- };
-
- serial1: serial@21c0600 {
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550a";
- reg = <0x0 0x21c0600 0x0 0x100>;
- clock-frequency = <0>; /* Updated by bootloader */
- interrupts = <0 32 0x1>; /* edge triggered */
- };
-
- fsl_mc: fsl-mc@80c000000 {
- compatible = "fsl,qoriq-mc";
- reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
- <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
- };
-};
diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
index fa81a6e..cd158b8 100644
--- a/arch/arm64/boot/dts/hisilicon/Makefile
+++ b/arch/arm64/boot/dts/hisilicon/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
+dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e36a539..8185251 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -17,11 +17,14 @@
compatible = "hisilicon,hi6220-hikey", "hisilicon,hi6220";
aliases {
- serial0 = &uart0;
+ serial0 = &uart0; /* On board UART0 */
+ serial1 = &uart1; /* BT UART */
+ serial2 = &uart2; /* LS Expansion UART0 */
+ serial3 = &uart3; /* LS Expansion UART1 */
};
chosen {
- stdout-path = "serial0:115200n8";
+ stdout-path = "serial3:115200n8";
};
memory@0 {
@@ -29,3 +32,10 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
};
+
+&uart2 {
+ label = "LS-UART0";
+};
+&uart3 {
+ label = "LS-UART1";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 3f03380..ad1f1eb 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -5,6 +5,7 @@
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/hi6220-clock.h>
/ {
compatible = "hisilicon,hi6220";
@@ -146,6 +147,7 @@
compatible = "hisilicon,hi6220-sysctrl", "syscon";
reg = <0x0 0xf7030000 0x0 0x2000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
media_ctrl: media_ctrl@f4410000 {
@@ -164,8 +166,48 @@
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0xf8015000 0x0 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
+ clocks = <&ao_ctrl HI6220_UART0_PCLK>,
+ <&ao_ctrl HI6220_UART0_PCLK>;
clock-names = "uartclk", "apb_pclk";
};
+
+ uart1: uart@f7111000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0xf7111000 0x0 0x1000>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sys_ctrl HI6220_UART1_PCLK>,
+ <&sys_ctrl HI6220_UART1_PCLK>;
+ clock-names = "uartclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ uart2: uart@f7112000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0xf7112000 0x0 0x1000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sys_ctrl HI6220_UART2_PCLK>,
+ <&sys_ctrl HI6220_UART2_PCLK>;
+ clock-names = "uartclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ uart3: uart@f7113000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0xf7113000 0x0 0x1000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sys_ctrl HI6220_UART3_PCLK>,
+ <&sys_ctrl HI6220_UART3_PCLK>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart4: uart@f7114000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0xf7114000 0x0 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sys_ctrl HI6220_UART4_PCLK>,
+ <&sys_ctrl HI6220_UART4_PCLK>;
+ clock-names = "uartclk", "apb_pclk";
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
new file mode 100644
index 0000000..ae34e25
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
@@ -0,0 +1,36 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon 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.
+ *
+ */
+
+/dts-v1/;
+
+#include "hip05.dtsi"
+
+/ {
+ model = "Hisilicon Hip05 D02 Development Board";
+ compatible = "hisilicon,hip05-d02";
+
+ memory@00000000 {
+ device_type = "memory";
+ reg = <0x0 0x00000000 0x0 0x80000000>;
+ };
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
new file mode 100644
index 0000000..c1ea999
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -0,0 +1,276 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon 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 <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "hisilicon,hip05-d02";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ 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@20000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20000>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@20001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20001>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@20002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20002>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@20003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20003>;
+ enable-method = "psci";
+ };
+
+ cpu4: cpu@20100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20100>;
+ enable-method = "psci";
+ };
+
+ cpu5: cpu@20101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20101>;
+ enable-method = "psci";
+ };
+
+ cpu6: cpu@20102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20102>;
+ enable-method = "psci";
+ };
+
+ cpu7: cpu@20103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20103>;
+ enable-method = "psci";
+ };
+
+ cpu8: cpu@20200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20200>;
+ enable-method = "psci";
+ };
+
+ cpu9: cpu@20201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20201>;
+ enable-method = "psci";
+ };
+
+ cpu10: cpu@20202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20202>;
+ enable-method = "psci";
+ };
+
+ cpu11: cpu@20203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20203>;
+ enable-method = "psci";
+ };
+
+ cpu12: cpu@20300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20300>;
+ enable-method = "psci";
+ };
+
+ cpu13: cpu@20301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20301>;
+ enable-method = "psci";
+ };
+
+ cpu14: cpu@20302 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20302>;
+ enable-method = "psci";
+ };
+
+ cpu15: cpu@20303 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x20303>;
+ enable-method = "psci";
+ };
+ };
+
+ gic: interrupt-controller@8d000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+ #redistributor-regions = <1>;
+ redistributor-stride = <0x0 0x30000>;
+ reg = <0x0 0x8d000000 0 0x10000>, /* GICD */
+ <0x0 0x8d100000 0 0x300000>, /* GICR */
+ <0x0 0xfe000000 0 0x10000>, /* GICC */
+ <0x0 0xfe010000 0 0x10000>, /* GICH */
+ <0x0 0xfe020000 0 0x10000>; /* GICV */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+ its_totems: interrupt-controller@8c000000 {
+ compatible = "arm,gic-v3-its";
+ msi-controller;
+ reg = <0x0 0x8c000000 0x0 0x40000>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ refclk200mhz: refclk200mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+
+ peri_c_subctrl: syscon@80000000 {
+ compatible = "hisilicon,hip05-perisubc", "syscon";
+ reg = < 0x0 0x80000000 0x0 0x10000>;
+ };
+
+ uart0: uart@80300000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x80300000 0x0 0x10000>;
+ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&refclk200mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: uart@80310000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x80310000 0x0 0x10000>;
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&refclk200mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
new file mode 100644
index 0000000..933cba3
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
@@ -0,0 +1,190 @@
+soc0: soc@000000000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0x0 0x0 0x0 0x1 0x0>;
+ chip-id = <0>;
+
+ soc0_mdio0: mdio@803c0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "hisilicon,hns-mdio";
+ reg = <0x0 0x803c0000 0x0 0x10000>;
+ subctrl-vbase = <&peri_c_subctrl>;
+
+ soc0_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ };
+ soc0_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ };
+ };
+
+ dsaf0: dsa@c7000000 {
+ compatible = "hisilicon,hns-dsaf-v1";
+ mode = "6port-16rss";
+ interrupt-parent = <&mbigen_dsa>;
+
+ reg = <0x0 0xC0000000 0x0 0x420000
+ 0x0 0xC2000000 0x0 0x300000
+ 0x0 0xc5000000 0x0 0x890000
+ 0x0 0xc7000000 0x0 0x60000
+ >;
+
+ phy-handle = <0 0 0 0 &soc0_phy0 &soc0_phy1 0 0>;
+ interrupts = <
+ /* [14] ge fifo err 8 / xge 6**/
+ 149 0x4 150 0x4 151 0x4 152 0x4
+ 153 0x4 154 0x4 26 0x4 27 0x4
+ 155 0x4 156 0x4 157 0x4 158 0x4 159 0x4 160 0x4
+ /* [12] rcb com 4*3**/
+ 0x6 0x4 0x7 0x4 0x8 0x4 0x9 0x4
+ 16 0x4 17 0x4 18 0x4 19 0x4
+ 22 0x4 23 0x4 24 0x4 25 0x4
+ /* [8] ppe tnl 0-7***/
+ 0x0 0x4 0x1 0x4 0x2 0x4 0x3 0x4
+ 0x4 0x4 0x5 0x4 12 0x4 13 0x4
+ /* [21] dsaf event int 3+18**/
+ 128 0x4 129 0x4 130 0x4
+ 0x83 0x4 0x84 0x4 0x85 0x4 0x86 0x4 0x87 0x4 0x88 0x4
+ 0x89 0x4 0x8a 0x4 0x8b 0x4 0x8c 0x4 0x8d 0x4 0x8e 0x4
+ 0x8f 0x4 0x90 0x4 0x91 0x4 0x92 0x4 0x93 0x4 0x94 0x4
+ /* [4] debug rcb 2*2*/
+ 0xe 0x1 0xf 0x1 0x14 0x1 0x15 0x1
+ /* [256] sevice rcb 2*128*/
+ 0x180 0x1 0x181 0x1 0x182 0x1 0x183 0x1
+ 0x184 0x1 0x185 0x1 0x186 0x1 0x187 0x1
+ 0x188 0x1 0x189 0x1 0x18a 0x1 0x18b 0x1
+ 0x18c 0x1 0x18d 0x1 0x18e 0x1 0x18f 0x1
+ 0x190 0x1 0x191 0x1 0x192 0x1 0x193 0x1
+ 0x194 0x1 0x195 0x1 0x196 0x1 0x197 0x1
+ 0x198 0x1 0x199 0x1 0x19a 0x1 0x19b 0x1
+ 0x19c 0x1 0x19d 0x1 0x19e 0x1 0x19f 0x1
+ 0x1a0 0x1 0x1a1 0x1 0x1a2 0x1 0x1a3 0x1
+ 0x1a4 0x1 0x1a5 0x1 0x1a6 0x1 0x1a7 0x1
+ 0x1a8 0x1 0x1a9 0x1 0x1aa 0x1 0x1ab 0x1
+ 0x1ac 0x1 0x1ad 0x1 0x1ae 0x1 0x1af 0x1
+ 0x1b0 0x1 0x1b1 0x1 0x1b2 0x1 0x1b3 0x1
+ 0x1b4 0x1 0x1b5 0x1 0x1b6 0x1 0x1b7 0x1
+ 0x1b8 0x1 0x1b9 0x1 0x1ba 0x1 0x1bb 0x1
+ 0x1bc 0x1 0x1bd 0x1 0x1be 0x1 0x1bf 0x1
+ 0x1c0 0x1 0x1c1 0x1 0x1c2 0x1 0x1c3 0x1
+ 0x1c4 0x1 0x1c5 0x1 0x1c6 0x1 0x1c7 0x1
+ 0x1c8 0x1 0x1c9 0x1 0x1ca 0x1 0x1cb 0x1
+ 0x1cc 0x1 0x1cd 0x1 0x1ce 0x1 0x1cf 0x1
+ 0x1d0 0x1 0x1d1 0x1 0x1d2 0x1 0x1d3 0x1
+ 0x1d4 0x1 0x1d5 0x1 0x1d6 0x1 0x1d7 0x1
+ 0x1d8 0x1 0x1d9 0x1 0x1da 0x1 0x1db 0x1
+ 0x1dc 0x1 0x1dd 0x1 0x1de 0x1 0x1df 0x1
+ 0x1e0 0x1 0x1e1 0x1 0x1e2 0x1 0x1e3 0x1
+ 0x1e4 0x1 0x1e5 0x1 0x1e6 0x1 0x1e7 0x1
+ 0x1e8 0x1 0x1e9 0x1 0x1ea 0x1 0x1eb 0x1
+ 0x1ec 0x1 0x1ed 0x1 0x1ee 0x1 0x1ef 0x1
+ 0x1f0 0x1 0x1f1 0x1 0x1f2 0x1 0x1f3 0x1
+ 0x1f4 0x1 0x1f5 0x1 0x1f6 0x1 0x1f7 0x1
+ 0x1f8 0x1 0x1f9 0x1 0x1fa 0x1 0x1fb 0x1
+ 0x1fc 0x1 0x1fd 0x1 0x1fe 0x1 0x1ff 0x1
+ 0x200 0x1 0x201 0x1 0x202 0x1 0x203 0x1
+ 0x204 0x1 0x205 0x1 0x206 0x1 0x207 0x1
+ 0x208 0x1 0x209 0x1 0x20a 0x1 0x20b 0x1
+ 0x20c 0x1 0x20d 0x1 0x20e 0x1 0x20f 0x1
+ 0x210 0x1 0x211 0x1 0x212 0x1 0x213 0x1
+ 0x214 0x1 0x215 0x1 0x216 0x1 0x217 0x1
+ 0x218 0x1 0x219 0x1 0x21a 0x1 0x21b 0x1
+ 0x21c 0x1 0x21d 0x1 0x21e 0x1 0x21f 0x1
+ 0x220 0x1 0x221 0x1 0x222 0x1 0x223 0x1
+ 0x224 0x1 0x225 0x1 0x226 0x1 0x227 0x1
+ 0x228 0x1 0x229 0x1 0x22a 0x1 0x22b 0x1
+ 0x22c 0x1 0x22d 0x1 0x22e 0x1 0x22f 0x1
+ 0x230 0x1 0x231 0x1 0x232 0x1 0x233 0x1
+ 0x234 0x1 0x235 0x1 0x236 0x1 0x237 0x1
+ 0x238 0x1 0x239 0x1 0x23a 0x1 0x23b 0x1
+ 0x23c 0x1 0x23d 0x1 0x23e 0x1 0x23f 0x1
+ 0x240 0x1 0x241 0x1 0x242 0x1 0x243 0x1
+ 0x244 0x1 0x245 0x1 0x246 0x1 0x247 0x1
+ 0x248 0x1 0x249 0x1 0x24a 0x1 0x24b 0x1
+ 0x24c 0x1 0x24d 0x1 0x24e 0x1 0x24f 0x1
+ 0x250 0x1 0x251 0x1 0x252 0x1 0x253 0x1
+ 0x254 0x1 0x255 0x1 0x256 0x1 0x257 0x1
+ 0x258 0x1 0x259 0x1 0x25a 0x1 0x25b 0x1
+ 0x25c 0x1 0x25d 0x1 0x25e 0x1 0x25f 0x1
+ 0x260 0x1 0x261 0x1 0x262 0x1 0x263 0x1
+ 0x264 0x1 0x265 0x1 0x266 0x1 0x267 0x1
+ 0x268 0x1 0x269 0x1 0x26a 0x1 0x26b 0x1
+ 0x26c 0x1 0x26d 0x1 0x26e 0x1 0x26f 0x1
+ 0x270 0x1 0x271 0x1 0x272 0x1 0x273 0x1
+ 0x274 0x1 0x275 0x1 0x276 0x1 0x277 0x1
+ 0x278 0x1 0x279 0x1 0x27a 0x1 0x27b 0x1
+ 0x27c 0x1 0x27d 0x1 0x27e 0x1 0x27f 0x1>;
+ buf-size = <4096>;
+ desc-num = <1024>;
+ dma-coherent;
+ };
+
+ eth0: ethernet@0{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <0>;
+ local-mac-address = [00 00 00 01 00 58];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth1: ethernet@1{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <1>;
+ status = "disabled";
+ dma-coherent;
+ };
+ eth2: ethernet@2{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <2>;
+ local-mac-address = [00 00 00 01 00 5a];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth3: ethernet@3{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <3>;
+ local-mac-address = [00 00 00 01 00 5b];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth4: ethernet@4{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <4>;
+ local-mac-address = [00 00 00 01 00 5c];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth5: ethernet@5{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <5>;
+ local-mac-address = [00 00 00 01 00 5d];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth6: ethernet@6{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <6>;
+ local-mac-address = [00 00 00 01 00 5e];
+ status = "disabled";
+ dma-coherent;
+ };
+ eth7: ethernet@7{
+ compatible = "hisilicon,hns-nic-v1";
+ ae-handle = <&dsaf0>;
+ port-id = <7>;
+ local-mac-address = [00 00 00 01 00 5f];
+ status = "disabled";
+ dma-coherent;
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile
index e2f6afa..348f4db 100644
--- a/arch/arm64/boot/dts/marvell/Makefile
+++ b/arch/arm64/boot/dts/marvell/Makefile
@@ -1,4 +1,5 @@
dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb
+dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts b/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts
new file mode 100644
index 0000000..348c37e
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/berlin4ct-stb.dts
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Marvell Technology Group Ltd.
+ *
+ * Author: Jisheng Zhang <jszhang@marvell.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 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 "berlin4ct.dtsi"
+
+/ {
+ model = "Marvell BG4CT STB board";
+ compatible = "marvell,berlin4ct-stb", "marvell,berlin4ct", "marvell,berlin";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ /* the first 16MB is for firmwares' usage */
+ reg = <0 0x01000000 0 0x7f000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
index dd4a10d..099ad93 100644
--- a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
+++ b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
@@ -55,7 +55,7 @@
};
psci {
- compatible = "arm,psci-0.2";
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
method = "smc";
};
@@ -68,6 +68,7 @@
device_type = "cpu";
reg = <0x0>;
enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu1: cpu@1 {
@@ -75,6 +76,7 @@
device_type = "cpu";
reg = <0x1>;
enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu2: cpu@2 {
@@ -82,6 +84,7 @@
device_type = "cpu";
reg = <0x2>;
enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu3: cpu@3 {
@@ -89,6 +92,19 @@
device_type = "cpu";
reg = <0x3>;
enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+ CPU_SLEEP_0: cpu-sleep-0 {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ arm,psci-suspend-param = <0x0010000>;
+ entry-latency-us = <75>;
+ exit-latency-us = <155>;
+ min-residency-us = <1000>;
+ };
};
};
@@ -135,6 +151,106 @@
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ 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>;
+ };
+ };
+
+ aic: interrupt-controller@3800 {
+ compatible = "snps,dw-apb-ictl";
+ reg = <0x3800 0x30>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ soc_pinctrl: pin-controller@ea8000 {
+ compatible = "marvell,berlin4ct-soc-pinctrl";
+ reg = <0xea8000 0x14>;
+ };
+
+ avio_pinctrl: pin-controller@ea8400 {
+ compatible = "marvell,berlin4ct-avio-pinctrl";
+ reg = <0xea8400 0x8>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -151,6 +267,59 @@
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
};
+ wdt0: watchdog@3000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x3000 0x100>;
+ clocks = <&osc>;
+ interrupts = <0>;
+ };
+
+ wdt1: watchdog@4000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x4000 0x100>;
+ clocks = <&osc>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ wdt2: watchdog@5000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x5000 0x100>;
+ clocks = <&osc>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
+ sm_gpio0: gpio@8000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x8000 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>;
+ };
+ };
+
+ sm_gpio1: gpio@9000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x9000 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>;
+ };
+ };
+
uart0: uart@d000 {
compatible = "snps,dw-apb-uart";
reg = <0xd000 0x100>;
@@ -158,6 +327,18 @@
clocks = <&osc>;
reg-shift = <2>;
status = "disabled";
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
+ };
+ };
+
+ system_pinctrl: pin-controller@fe2200 {
+ compatible = "marvell,berlin4ct-system-pinctrl";
+ reg = <0xfe2200 0xc>;
+
+ uart0_pmux: uart0-pmux {
+ groups = "SM_URT0_TXD", "SM_URT0_RXD";
+ function = "uart0";
};
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..e427f04 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -13,6 +13,7 @@
*/
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "mt8173.dtsi"
/ {
@@ -32,6 +33,15 @@
};
chosen { };
+
+ usb_p1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "usb_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
};
&i2c1 {
@@ -92,6 +102,13 @@
};
&pio {
+ disp_pwm0_pins: disp_pwm0_pins {
+ pins1 {
+ pinmux = <MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM0>;
+ output-low;
+ };
+ };
+
mmc0_pins_default: mmc0default {
pins_cmd_dat {
pinmux = <MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0>,
@@ -190,6 +207,12 @@
};
};
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&disp_pwm0_pins>;
+ status = "okay";
+};
+
&pwrap {
pmic: mt6397 {
compatible = "mediatek,mt6397";
@@ -387,6 +410,30 @@
};
};
+&pio {
+ spi_pins_a: spi0 {
+ pins_spi {
+ pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
+ <MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
+ <MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
+ <MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
+ };
+ };
+};
+
+&spi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_pins_a>;
+ mediatek,pad-select = <0>;
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
+
+&usb30 {
+ vusb33-supply = <&mt6397_vusb_reg>;
+ vbus-supply = <&usb_p1_vbus>;
+ mediatek,wakeup-src = <1>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 06a1564..ec135ea 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -14,8 +14,9 @@
#include <dt-bindings/clock/mt8173-clk.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
#include <dt-bindings/power/mt8173-power.h>
-#include <dt-bindings/reset-controller/mt8173-resets.h>
+#include <dt-bindings/reset/mt8173-resets.h>
#include "mt8173-pinfunc.h"
/ {
@@ -95,7 +96,7 @@
};
psci {
- compatible = "arm,psci";
+ compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
method = "smc";
cpu_suspend = <0x84000001>;
cpu_off = <0x84000002>;
@@ -116,6 +117,13 @@
clock-output-names = "clk32k";
};
+ cpum_ck: oscillator@2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "cpum_ck";
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
@@ -227,8 +235,10 @@
#power-domain-cells = <1>;
reg = <0 0x10006000 0 0x1000>;
clocks = <&clk26m>,
- <&topckgen CLK_TOP_MM_SEL>;
- clock-names = "mfg", "mm";
+ <&topckgen CLK_TOP_MM_SEL>,
+ <&topckgen CLK_TOP_VENC_SEL>,
+ <&topckgen CLK_TOP_VENC_LT_SEL>;
+ clock-names = "mfg", "mm", "venc", "venc_lt";
infracfg = <&infracfg>;
};
@@ -238,6 +248,15 @@
reg = <0 0x10007000 0 0x100>;
};
+ timer: timer@10008000 {
+ compatible = "mediatek,mt8173-timer",
+ "mediatek,mt6577-timer";
+ reg = <0 0x10008000 0 0x1000>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_CLK_13M>,
+ <&topckgen CLK_TOP_RTC_SEL>;
+ };
+
pwrap: pwrap@1000d000 {
compatible = "mediatek,mt8173-pwrap";
reg = <0 0x1000d000 0 0x1000>;
@@ -365,7 +384,20 @@
status = "disabled";
};
- i2c3: i2c3@11010000 {
+ spi: spi@1100a000 {
+ compatible = "mediatek,mt8173-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x1100a000 0 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&pericfg CLK_PERI_SPI0>;
+ clock-names = "parent-clk", "sel-clk", "spi-clk";
+ status = "disabled";
+ };
+
+ i2c3: i2c@11010000 {
compatible = "mediatek,mt8173-i2c";
reg = <0 0x11010000 0 0x70>,
<0 0x11000280 0 0x80>;
@@ -381,7 +413,7 @@
status = "disabled";
};
- i2c4: i2c4@11011000 {
+ i2c4: i2c@11011000 {
compatible = "mediatek,mt8173-i2c";
reg = <0 0x11011000 0 0x70>,
<0 0x11000300 0 0x80>;
@@ -397,7 +429,7 @@
status = "disabled";
};
- i2c6: i2c6@11013000 {
+ i2c6: i2c@11013000 {
compatible = "mediatek,mt8173-i2c";
reg = <0 0x11013000 0 0x70>,
<0 0x11000080 0 0x80>;
@@ -487,6 +519,99 @@
clock-names = "source", "hclk";
status = "disabled";
};
+
+ usb30: usb@11270000 {
+ compatible = "mediatek,mt8173-xhci";
+ reg = <0 0x11270000 0 0x1000>,
+ <0 0x11280700 0 0x0100>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
+ clocks = <&topckgen CLK_TOP_USB30_SEL>,
+ <&pericfg CLK_PERI_USB0>,
+ <&pericfg CLK_PERI_USB1>;
+ clock-names = "sys_ck",
+ "wakeup_deb_p0",
+ "wakeup_deb_p1";
+ phys = <&phy_port0 PHY_TYPE_USB3>,
+ <&phy_port1 PHY_TYPE_USB2>;
+ mediatek,syscon-wakeup = <&pericfg>;
+ status = "okay";
+ };
+
+ u3phy: usb-phy@11290000 {
+ compatible = "mediatek,mt8173-u3phy";
+ reg = <0 0x11290000 0 0x800>;
+ clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+ clock-names = "u3phya_ref";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ status = "okay";
+
+ phy_port0: port@11290800 {
+ reg = <0 0x11290800 0 0x800>;
+ #phy-cells = <1>;
+ status = "okay";
+ };
+
+ phy_port1: port@11291000 {
+ reg = <0 0x11291000 0 0x800>;
+ #phy-cells = <1>;
+ status = "okay";
+ };
+ };
+
+ mmsys: clock-controller@14000000 {
+ compatible = "mediatek,mt8173-mmsys", "syscon";
+ reg = <0 0x14000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ pwm0: pwm@1401e000 {
+ compatible = "mediatek,mt8173-disp-pwm",
+ "mediatek,mt6595-disp-pwm";
+ reg = <0 0x1401e000 0 0x1000>;
+ #pwm-cells = <2>;
+ clocks = <&mmsys CLK_MM_DISP_PWM026M>,
+ <&mmsys CLK_MM_DISP_PWM0MM>;
+ clock-names = "main", "mm";
+ status = "disabled";
+ };
+
+ pwm1: pwm@1401f000 {
+ compatible = "mediatek,mt8173-disp-pwm",
+ "mediatek,mt6595-disp-pwm";
+ reg = <0 0x1401f000 0 0x1000>;
+ #pwm-cells = <2>;
+ clocks = <&mmsys CLK_MM_DISP_PWM126M>,
+ <&mmsys CLK_MM_DISP_PWM1MM>;
+ clock-names = "main", "mm";
+ status = "disabled";
+ };
+
+ imgsys: clock-controller@15000000 {
+ compatible = "mediatek,mt8173-imgsys", "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ vdecsys: clock-controller@16000000 {
+ compatible = "mediatek,mt8173-vdecsys", "syscon";
+ reg = <0 0x16000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ vencsys: clock-controller@18000000 {
+ compatible = "mediatek,mt8173-vencsys", "syscon";
+ reg = <0 0x18000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ vencltsys: clock-controller@19000000 {
+ compatible = "mediatek,mt8173-vencltsys", "syscon";
+ reg = <0 0x19000000 0 0x1000>;
+ #clock-cells = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
new file mode 100644
index 0000000..a7e865d
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -0,0 +1,7 @@
+dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
+dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
+
+always := $(dtb-y)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
new file mode 100644
index 0000000..62f33fc
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
@@ -0,0 +1,1132 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra132.dtsi"
+
+/ {
+ model = "NVIDIA Tegra132 Norrin";
+ compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124";
+
+ aliases {
+ rtc0 = "/i2c@0,7000d000/as3722@40";
+ rtc1 = "/rtc@0,7000e000";
+ };
+
+ chosen { };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ };
+
+ host1x@0,50000000 {
+ hdmi@0,54280000 {
+ status = "disabled";
+
+ 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: dpaux@0,545c0000 {
+ vdd-supply = <&vdd_3v3_panel>;
+ status = "okay";
+ };
+ };
+
+ gpu@0,57000000 {
+ status = "okay";
+
+ vdd-supply = <&vdd_gpu>;
+ };
+
+ pinmux@0,70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinmux_default>;
+
+ pinmux_default: pinmux@0 {
+ 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>;
+ };
+ 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",
+ "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_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>;
+ };
+ 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_nxt_py2",
+ "ulpi_stp_py3";
+ 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>;
+ };
+ 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>;
+ };
+ 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_ENABLE>;
+ };
+ pj7 {
+ nvidia,pins = "pj7";
+ nvidia,function = "uartd";
+ 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_DOWN>;
+ 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>;
+ };
+ pg4 {
+ nvidia,pins = "pg4",
+ "pg5",
+ "pg6",
+ "pi3";
+ 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>;
+ };
+ ph1 {
+ nvidia,pins = "ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <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,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",
+ "kb_col4_pq4",
+ "sdmmc3_clk_lb_out_pee4",
+ "sdmmc3_clk_lb_in_pee5",
+ "sdmmc3_cd_n_pv2";
+ 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>;
+ };
+ mic_det_l {
+ 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_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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ 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>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ 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>;
+ };
+ 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_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>;
+ };
+ 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>;
+ };
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en0_pn4 {
+ nvidia,pins = "usb_vbus_en0_pn4",
+ "usb_vbus_en1_pn5",
+ "usb_vbus_en2_pff1";
+ nvidia,function = "usb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,drive-type = <1>;
+ };
+ 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>;
+ };
+ 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_DISABLE>;
+ 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_DISABLE>;
+ 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_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ts_reset_l {
+ nvidia,pins = "pk4";
+ nvidia,function = "gmi";
+ nvidia,pull = <1>;
+ 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>;
+ };
+ 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>;
+ };
+ chromeos_write_protect {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hp_det_l {
+ nvidia,pins = "pi7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ soc_warm_reset_l {
+ nvidia,pins = "pi5";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ serial@0,70006000 {
+ status = "okay";
+ };
+
+ pwm: pwm@0,7000a000 {
+ status = "okay";
+ };
+
+ /* HDMI DDC */
+ hdmi_ddc: i2c@0,7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ as3722: pmic@40 {
+ compatible = "ams,as3722";
+ reg = <0x40>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+ ams,system-power-controller;
+
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&as3722_default>;
+
+ as3722_default: pinmux@0 {
+ 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 {
+ pins = "gpio3";
+ function = "gpio";
+ bias-high-impedance;
+ };
+
+ gpio5 {
+ pins = "gpio5";
+ function = "clk32k-out";
+ bias-pull-down;
+ };
+
+ gpio6 {
+ pins = "gpio6";
+ 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_sys>;
+ 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-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-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;
+ regulator-boot-on;
+ };
+
+ vdd_gpu: sd6 {
+ regulator-name = "+VDD_GPU_AP";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microamp = <3500000>;
+ regulator-max-microamp = <3500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo0 {
+ regulator-name = "+1.05_RUN_AVDD";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-always-on;
+ regulator-boot-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-always-on;
+ regulator-boot-on;
+ };
+
+ ldo3 {
+ regulator-name = "+1.00V_LP0_VDD_RTC";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ams,enable-tracking;
+ };
+
+ vdd_run_cam: 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 = "+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";
+
+ 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_20: i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ google,remote-bus = <0>;
+
+ charger: bq24735 {
+ 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: smart-battery {
+ compatible = "sbs,sbs-battery";
+ reg = <0xb>;
+ battery-name = "battery";
+ sbs,i2c-retry-count = <2>;
+ sbs,poll-retry-count = <10>;
+ /* power-supplies = <&charger>; */
+ };
+ };
+
+ 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)>;
+ };
+ };
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <0>;
+ #wake-cells = <3>;
+ 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;
+ nvidia,reset-gpio = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+ };
+
+ /* WIFI/BT module */
+ sdhci@0,700b0000 {
+ status = "disabled";
+ };
+
+ /* external SD/MMC */
+ sdhci@0,700b0400 {
+ 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>;
+ status = "okay";
+ bus-width = <4>;
+ vqmmc-supply = <&vddio_sdmmc3>;
+ };
+
+ /* EMMC 4.51 */
+ sdhci@0,700b0600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+ };
+
+ 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>;
+
+ 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";
+
+ lid {
+ label = "Lid";
+ gpios = <&gpio TEGRA_GPIO(R, 4) GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>;
+ linux,code = <0>;
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
+ 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 = "innolux,n116bge", "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 = <19000000>;
+ regulator-max-microvolt = <19000000>;
+ 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 = <&as3722 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";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_mux>;
+ };
+
+ vdd_usb1_vbus: regulator@6 {
+ compatible = "regulator-fixed";
+ reg = <6>;
+ 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@7 {
+ compatible = "regulator-fixed";
+ reg = <7>;
+ 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@8 {
+ compatible = "regulator-fixed";
+ reg = <8>;
+ regulator-name = "+3.3V_PANEL";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&as3722 4 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_sys>;
+ };
+
+ vdd_hdmi_pll: regulator@9 {
+ compatible = "regulator-fixed";
+ reg = <9>;
+ regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL_AP_GATE";
+ 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@10 {
+ compatible = "regulator-fixed";
+ reg = <10>;
+ 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>;
+ };
+
+ vdd_5v0_ts: regulator@11 {
+ compatible = "regulator-fixed";
+ reg = <11>;
+ regulator-name = "+5V_VDD_TS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
new file mode 100644
index 0000000..6e28e41
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -0,0 +1,990 @@
+#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>
+
+/ {
+ compatible = "nvidia,tegra132", "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>;
+ clock-names = "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 0x2000>,
+ <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>;
+ clock-names = "timer";
+ };
+
+ tegra_car: clock@0,60006000 {
+ compatible = "nvidia,tegra132-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>;
+ clock-names = "dma";
+ 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 performance. 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>;
+ clock-names = "serial";
+ 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>;
+ clock-names = "serial";
+ 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>;
+ clock-names = "serial";
+ 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>;
+ clock-names = "serial";
+ 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>;
+ clock-names = "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>;
+ clock-names = "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,tegra132-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,tegra132-emc", "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,tegra132-hda", "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", "hda2codec_2x";
+ resets = <&tegra_car 125>, /* hda */
+ <&tegra_car 128>, /* hda2hdmi */
+ <&tegra_car 111>; /* hda2codec_2x */
+ reset-names = "hda", "hda2hdmi", "hda2codec_2x";
+ status = "disabled";
+ };
+
+ padctl: padctl@0,7009f000 {
+ compatible = "nvidia,tegra132-xusb-padctl",
+ "nvidia,tegra124-xusb-padctl";
+ reg = <0x0 0x7009f000 0x0 0x1000>;
+ resets = <&tegra_car 142>;
+ reset-names = "padctl";
+
+ #phy-cells = <1>;
+
+ phys {
+ pcie-0 {
+ status = "disabled";
+ };
+
+ sata-0 {
+ status = "disabled";
+ };
+
+ usb3-0 {
+ status = "disabled";
+ };
+
+ usb3-1 {
+ status = "disabled";
+ };
+
+ utmi-0 {
+ status = "disabled";
+ };
+
+ utmi-1 {
+ status = "disabled";
+ };
+
+ utmi-2 {
+ status = "disabled";
+ };
+ };
+ };
+
+ 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>;
+ clock-names = "sdhci";
+ 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>;
+ clock-names = "sdhci";
+ 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>;
+ clock-names = "sdhci";
+ 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>;
+ clock-names = "sdhci";
+ 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>;
+ clock-names = "i2s";
+ 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>;
+ clock-names = "i2s";
+ 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>;
+ clock-names = "i2s";
+ 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>;
+ clock-names = "i2s";
+ 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>;
+ clock-names = "i2s";
+ 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>;
+ clock-names = "usb";
+ 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>;
+ clock-names = "usb";
+ 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>;
+ clock-names = "usb";
+ 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 = "nvidia,denver", "arm,armv8";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "nvidia,denver", "arm,armv8";
+ reg = <1>;
+ };
+ };
+
+ 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/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
new file mode 100644
index 0000000..2b7f889
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
@@ -0,0 +1,45 @@
+#include "tegra210.dtsi"
+
+/ {
+ model = "NVIDIA Jetson TX1";
+ compatible = "nvidia,p2180", "nvidia,tegra210";
+
+ aliases {
+ rtc1 = "/rtc@0,7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x1 0x0>;
+ };
+
+ /* debug port */
+ serial@0,70006000 {
+ status = "okay";
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ };
+
+ /* eMMC */
+ sdhci@0,700b0600 {
+ 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>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts
new file mode 100644
index 0000000..1ddd851
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+#include "tegra210-p2530.dtsi"
+#include "tegra210-p2595.dtsi"
+
+/ {
+ model = "NVIDIA Tegra210 P2371 (P2530/P2595) reference design";
+ compatible = "nvidia,p2371-0000", "nvidia,tegra210";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
new file mode 100644
index 0000000..683b339
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+#include "tegra210-p2180.dtsi"
+#include "tegra210-p2597.dtsi"
+
+/ {
+ model = "NVIDIA Jetson TX1 Developer Kit";
+ compatible = "nvidia,p2371-2180", "nvidia,tegra210";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi
new file mode 100644
index 0000000..ece0dec
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi
@@ -0,0 +1,50 @@
+#include "tegra210.dtsi"
+
+/ {
+ model = "NVIDIA Tegra210 P2530 main board";
+ compatible = "nvidia,p2530", "nvidia,tegra210";
+
+ aliases {
+ rtc1 = "/rtc@0,7000e000";
+ serial0 = &uarta;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0xc0000000>;
+ };
+
+ /* debug port */
+ serial@0,70006000 {
+ status = "okay";
+ };
+
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ pmc@0,7000e400 {
+ nvidia,invert-interrupt;
+ };
+
+ /* eMMC */
+ sdhci@0,700b0600 {
+ 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>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts
new file mode 100644
index 0000000..58d27dd
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts
@@ -0,0 +1,1302 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra210-p2530.dtsi"
+
+/ {
+ model = "NVIDIA Tegra210 P2571 reference design";
+ compatible = "nvidia,p2571", "nvidia,tegra210";
+
+ pinmux: pinmux@0,700008d4 {
+ pinctrl-names = "boot";
+ pinctrl-0 = <&state_boot>;
+
+ state_boot: pinmux {
+ pex_l0_rst_n_pa0 {
+ nvidia,pins = "pex_l0_rst_n_pa0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l0_clkreq_n_pa1 {
+ nvidia,pins = "pex_l0_clkreq_n_pa1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pex_wake_n_pa2 {
+ nvidia,pins = "pex_wake_n_pa2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_rst_n_pa3 {
+ nvidia,pins = "pex_l1_rst_n_pa3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pex_l1_clkreq_n_pa4 {
+ nvidia,pins = "pex_l1_clkreq_n_pa4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ sata_led_active_pa5 {
+ nvidia,pins = "sata_led_active_pa5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pa6 {
+ nvidia,pins = "pa6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_fs_pb0 {
+ nvidia,pins = "dap1_fs_pb0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pb1 {
+ nvidia,pins = "dap1_din_pb1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pb2 {
+ nvidia,pins = "dap1_dout_pb2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pb3 {
+ nvidia,pins = "dap1_sclk_pb3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_mosi_pb4 {
+ nvidia,pins = "spi2_mosi_pb4";
+ 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>;
+ };
+ spi2_miso_pb5 {
+ nvidia,pins = "spi2_miso_pb5";
+ 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>;
+ };
+ spi2_sck_pb6 {
+ nvidia,pins = "spi2_sck_pb6";
+ 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>;
+ };
+ spi2_cs0_pb7 {
+ nvidia,pins = "spi2_cs0_pb7";
+ 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>;
+ };
+ spi1_mosi_pc0 {
+ nvidia,pins = "spi1_mosi_pc0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_miso_pc1 {
+ nvidia,pins = "spi1_miso_pc1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_sck_pc2 {
+ nvidia,pins = "spi1_sck_pc2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs0_pc3 {
+ nvidia,pins = "spi1_cs0_pc3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs1_pc4 {
+ nvidia,pins = "spi1_cs1_pc4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_sck_pc5 {
+ nvidia,pins = "spi4_sck_pc5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_cs0_pc6 {
+ nvidia,pins = "spi4_cs0_pc6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_mosi_pc7 {
+ nvidia,pins = "spi4_mosi_pc7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_miso_pd0 {
+ nvidia,pins = "spi4_miso_pd0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_tx_pd1 {
+ nvidia,pins = "uart3_tx_pd1";
+ 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>;
+ };
+ uart3_rx_pd2 {
+ nvidia,pins = "uart3_rx_pd2";
+ 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>;
+ };
+ uart3_rts_pd3 {
+ nvidia,pins = "uart3_rts_pd3";
+ 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>;
+ };
+ uart3_cts_pd4 {
+ nvidia,pins = "uart3_cts_pd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_clk_pe0 {
+ nvidia,pins = "dmic1_clk_pe0";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_dat_pe1 {
+ nvidia,pins = "dmic1_dat_pe1";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_clk_pe2 {
+ nvidia,pins = "dmic2_clk_pe2";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_dat_pe3 {
+ nvidia,pins = "dmic2_dat_pe3";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_clk_pe4 {
+ nvidia,pins = "dmic3_clk_pe4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_dat_pe5 {
+ nvidia,pins = "dmic3_dat_pe5";
+ 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>;
+ };
+ pe6 {
+ nvidia,pins = "pe6";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pe7 {
+ nvidia,pins = "pe7";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_scl_pf0 {
+ nvidia,pins = "gen3_i2c_scl_pf0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_sda_pf1 {
+ nvidia,pins = "gen3_i2c_sda_pf1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_tx_pg0 {
+ nvidia,pins = "uart2_tx_pg0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rx_pg1 {
+ nvidia,pins = "uart2_rx_pg1";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_pg2 {
+ nvidia,pins = "uart2_rts_pg2";
+ 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>;
+ };
+ uart2_cts_pg3 {
+ nvidia,pins = "uart2_cts_pg3";
+ 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>;
+ };
+ wifi_en_ph0 {
+ nvidia,pins = "wifi_en_ph0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_rst_ph1 {
+ nvidia,pins = "wifi_rst_ph1";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_wake_ap_ph2 {
+ nvidia,pins = "wifi_wake_ap_ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_bt_ph3 {
+ nvidia,pins = "ap_wake_bt_ph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_rst_ph4 {
+ nvidia,pins = "bt_rst_ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_wake_ap_ph5 {
+ nvidia,pins = "bt_wake_ap_ph5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_nfc_ph7 {
+ nvidia,pins = "ap_wake_nfc_ph7";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_en_pi0 {
+ nvidia,pins = "nfc_en_pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_int_pi1 {
+ nvidia,pins = "nfc_int_pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_en_pi2 {
+ nvidia,pins = "gps_en_pi2";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_rst_pi3 {
+ nvidia,pins = "gps_rst_pi3";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_tx_pi4 {
+ nvidia,pins = "uart4_tx_pi4";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rx_pi5 {
+ nvidia,pins = "uart4_rx_pi5";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rts_pi6 {
+ nvidia,pins = "uart4_rts_pi6";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_cts_pi7 {
+ nvidia,pins = "uart4_cts_pi7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_sda_pj0 {
+ nvidia,pins = "gen1_i2c_sda_pj0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pj1 {
+ nvidia,pins = "gen1_i2c_scl_pj1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen2_i2c_scl_pj2 {
+ nvidia,pins = "gen2_i2c_scl_pj2";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pj3 {
+ nvidia,pins = "gen2_i2c_sda_pj3";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_fs_pj4 {
+ nvidia,pins = "dap4_fs_pj4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pj5 {
+ nvidia,pins = "dap4_din_pj5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pj6 {
+ nvidia,pins = "dap4_dout_pj6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pj7 {
+ nvidia,pins = "dap4_sclk_pj7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ 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>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ 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>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ 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>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ 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>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk5 {
+ nvidia,pins = "pk5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk6 {
+ nvidia,pins = "pk6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl0 {
+ nvidia,pins = "pl0";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl1 {
+ nvidia,pins = "pl1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_clk_pm0 {
+ nvidia,pins = "sdmmc1_clk_pm0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pm1 {
+ nvidia,pins = "sdmmc1_cmd_pm1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_pm2 {
+ nvidia,pins = "sdmmc1_dat3_pm2";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat2_pm3 {
+ nvidia,pins = "sdmmc1_dat2_pm3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat1_pm4 {
+ nvidia,pins = "sdmmc1_dat1_pm4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat0_pm5 {
+ nvidia,pins = "sdmmc1_dat0_pm5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pp0 {
+ nvidia,pins = "sdmmc3_clk_pp0";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pp1 {
+ nvidia,pins = "sdmmc3_cmd_pp1";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat3_pp2 {
+ nvidia,pins = "sdmmc3_dat3_pp2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat2_pp3 {
+ nvidia,pins = "sdmmc3_dat2_pp3";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat1_pp4 {
+ nvidia,pins = "sdmmc3_dat1_pp4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat0_pp5 {
+ nvidia,pins = "sdmmc3_dat0_pp5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_mclk_ps0 {
+ nvidia,pins = "cam1_mclk_ps0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_mclk_ps1 {
+ nvidia,pins = "cam2_mclk_ps1";
+ nvidia,function = "rsvd1";
+ 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_scl_ps2 {
+ nvidia,pins = "cam_i2c_scl_ps2";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_sda_ps3 {
+ nvidia,pins = "cam_i2c_sda_ps3";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_rst_ps4 {
+ nvidia,pins = "cam_rst_ps4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_af_en_ps5 {
+ nvidia,pins = "cam_af_en_ps5";
+ 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>;
+ };
+ cam_flash_en_ps6 {
+ nvidia,pins = "cam_flash_en_ps6";
+ 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>;
+ };
+ cam1_pwdn_ps7 {
+ nvidia,pins = "cam1_pwdn_ps7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_pwdn_pt0 {
+ nvidia,pins = "cam2_pwdn_pt0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_strobe_pt1 {
+ nvidia,pins = "cam1_strobe_pt1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_tx_pu0 {
+ nvidia,pins = "uart1_tx_pu0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rx_pu1 {
+ nvidia,pins = "uart1_rx_pu1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rts_pu2 {
+ nvidia,pins = "uart1_rts_pu2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_cts_pu3 {
+ nvidia,pins = "uart1_cts_pu3";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_pwm_pv0 {
+ nvidia,pins = "lcd_bl_pwm_pv0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_en_pv1 {
+ nvidia,pins = "lcd_bl_en_pv1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_rst_pv2 {
+ nvidia,pins = "lcd_rst_pv2";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio1_pv3 {
+ nvidia,pins = "lcd_gpio1_pv3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio2_pv4 {
+ nvidia,pins = "lcd_gpio2_pv4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_ready_pv5 {
+ nvidia,pins = "ap_ready_pv5";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_rst_pv6 {
+ nvidia,pins = "touch_rst_pv6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_clk_pv7 {
+ nvidia,pins = "touch_clk_pv7";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ modem_wake_ap_px0 {
+ nvidia,pins = "modem_wake_ap_px0";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_int_px1 {
+ nvidia,pins = "touch_int_px1";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ motion_int_px2 {
+ nvidia,pins = "motion_int_px2";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ als_prox_int_px3 {
+ nvidia,pins = "als_prox_int_px3";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ temp_alert_px4 {
+ nvidia,pins = "temp_alert_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_power_on_px5 {
+ nvidia,pins = "button_power_on_px5";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_up_px6 {
+ nvidia,pins = "button_vol_up_px6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_down_px7 {
+ nvidia,pins = "button_vol_down_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_slide_sw_py0 {
+ nvidia,pins = "button_slide_sw_py0";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_home_py1 {
+ nvidia,pins = "button_home_py1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_te_py2 {
+ nvidia,pins = "lcd_te_py2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_py3 {
+ nvidia,pins = "pwr_i2c_scl_py3";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_sda_py4 {
+ nvidia,pins = "pwr_i2c_sda_py4";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_out_py5 {
+ nvidia,pins = "clk_32k_out_py5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz0 {
+ nvidia,pins = "pz0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz1 {
+ nvidia,pins = "pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz2 {
+ nvidia,pins = "pz2";
+ 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>;
+ };
+ pz3 {
+ nvidia,pins = "pz3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz4 {
+ nvidia,pins = "pz4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz5 {
+ nvidia,pins = "pz5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_paa0 {
+ nvidia,pins = "dap2_fs_paa0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_sclk_paa1 {
+ nvidia,pins = "dap2_sclk_paa1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_din_paa2 {
+ nvidia,pins = "dap2_din_paa2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_dout_paa3 {
+ nvidia,pins = "dap2_dout_paa3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ aud_mclk_pbb0 {
+ nvidia,pins = "aud_mclk_pbb0";
+ nvidia,function = "aud";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_pbb1 {
+ nvidia,pins = "dvfs_pwm_pbb1";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_clk_pbb2 {
+ nvidia,pins = "dvfs_clk_pbb2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_pbb3 {
+ nvidia,pins = "gpio_x1_aud_pbb3";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_pbb4 {
+ nvidia,pins = "gpio_x3_aud_pbb4";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pcc0 {
+ nvidia,pins = "hdmi_cec_pcc0";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_dp_hpd_pcc1 {
+ nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pcc2 {
+ nvidia,pins = "spdif_out_pcc2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pcc3 {
+ nvidia,pins = "spdif_in_pcc3";
+ 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_en0_pcc4 {
+ nvidia,pins = "usb_vbus_en0_pcc4";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en1_pcc5 {
+ nvidia,pins = "usb_vbus_en1_pcc5";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ dp_hpd0_pcc6 {
+ nvidia,pins = "dp_hpd0_pcc6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pcc7 {
+ nvidia,pins = "pcc7";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_cs1_pdd0 {
+ nvidia,pins = "spi2_cs1_pdd0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_sck_pee0 {
+ nvidia,pins = "qspi_sck_pee0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_cs_n_pee1 {
+ nvidia,pins = "qspi_cs_n_pee1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io0_pee2 {
+ nvidia,pins = "qspi_io0_pee2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io1_pee3 {
+ nvidia,pins = "qspi_io1_pee3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io2_pee4 {
+ nvidia,pins = "qspi_io2_pee4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io3_pee5 {
+ nvidia,pins = "qspi_io3_pee5";
+ nvidia,function = "rsvd1";
+ 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 = "core";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "jtag";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ clk_req {
+ nvidia,pins = "clk_req";
+ nvidia,function = "sys";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ shutdown {
+ nvidia,pins = "shutdown";
+ nvidia,function = "shutdown";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi
new file mode 100644
index 0000000..f3f9139
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi
@@ -0,0 +1,1272 @@
+/ {
+ model = "NVIDIA Tegra210 P2595 I/O board";
+ compatible = "nvidia,p2595", "nvidia,tegra210";
+
+ pinmux: pinmux@0,700008d4 {
+ pinctrl-names = "boot";
+ pinctrl-0 = <&state_boot>;
+
+ state_boot: pinmux {
+ pex_l0_rst_n_pa0 {
+ nvidia,pins = "pex_l0_rst_n_pa0";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l0_clkreq_n_pa1 {
+ nvidia,pins = "pex_l0_clkreq_n_pa1";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_wake_n_pa2 {
+ nvidia,pins = "pex_wake_n_pa2";
+ nvidia,function = "pe";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_rst_n_pa3 {
+ nvidia,pins = "pex_l1_rst_n_pa3";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_clkreq_n_pa4 {
+ nvidia,pins = "pex_l1_clkreq_n_pa4";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ sata_led_active_pa5 {
+ nvidia,pins = "sata_led_active_pa5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pa6 {
+ nvidia,pins = "pa6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_fs_pb0 {
+ nvidia,pins = "dap1_fs_pb0";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pb1 {
+ nvidia,pins = "dap1_din_pb1";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pb2 {
+ nvidia,pins = "dap1_dout_pb2";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pb3 {
+ nvidia,pins = "dap1_sclk_pb3";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_mosi_pb4 {
+ nvidia,pins = "spi2_mosi_pb4";
+ 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>;
+ };
+ spi2_miso_pb5 {
+ nvidia,pins = "spi2_miso_pb5";
+ 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>;
+ };
+ spi2_sck_pb6 {
+ nvidia,pins = "spi2_sck_pb6";
+ 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>;
+ };
+ spi2_cs0_pb7 {
+ nvidia,pins = "spi2_cs0_pb7";
+ 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>;
+ };
+ spi1_mosi_pc0 {
+ nvidia,pins = "spi1_mosi_pc0";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_miso_pc1 {
+ nvidia,pins = "spi1_miso_pc1";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_sck_pc2 {
+ nvidia,pins = "spi1_sck_pc2";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs0_pc3 {
+ nvidia,pins = "spi1_cs0_pc3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs1_pc4 {
+ nvidia,pins = "spi1_cs1_pc4";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_sck_pc5 {
+ nvidia,pins = "spi4_sck_pc5";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_cs0_pc6 {
+ nvidia,pins = "spi4_cs0_pc6";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_mosi_pc7 {
+ nvidia,pins = "spi4_mosi_pc7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_miso_pd0 {
+ nvidia,pins = "spi4_miso_pd0";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_tx_pd1 {
+ nvidia,pins = "uart3_tx_pd1";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rx_pd2 {
+ nvidia,pins = "uart3_rx_pd2";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rts_pd3 {
+ nvidia,pins = "uart3_rts_pd3";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_pd4 {
+ nvidia,pins = "uart3_cts_pd4";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_clk_pe0 {
+ nvidia,pins = "dmic1_clk_pe0";
+ nvidia,function = "dmic1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_dat_pe1 {
+ nvidia,pins = "dmic1_dat_pe1";
+ nvidia,function = "dmic1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_clk_pe2 {
+ nvidia,pins = "dmic2_clk_pe2";
+ nvidia,function = "dmic2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_dat_pe3 {
+ nvidia,pins = "dmic2_dat_pe3";
+ nvidia,function = "dmic2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_clk_pe4 {
+ nvidia,pins = "dmic3_clk_pe4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_dat_pe5 {
+ nvidia,pins = "dmic3_dat_pe5";
+ 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>;
+ };
+ pe6 {
+ nvidia,pins = "pe6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pe7 {
+ nvidia,pins = "pe7";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_scl_pf0 {
+ nvidia,pins = "gen3_i2c_scl_pf0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_sda_pf1 {
+ nvidia,pins = "gen3_i2c_sda_pf1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_tx_pg0 {
+ nvidia,pins = "uart2_tx_pg0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rx_pg1 {
+ nvidia,pins = "uart2_rx_pg1";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_pg2 {
+ nvidia,pins = "uart2_rts_pg2";
+ 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>;
+ };
+ uart2_cts_pg3 {
+ nvidia,pins = "uart2_cts_pg3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_en_ph0 {
+ nvidia,pins = "wifi_en_ph0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_rst_ph1 {
+ nvidia,pins = "wifi_rst_ph1";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_wake_ap_ph2 {
+ nvidia,pins = "wifi_wake_ap_ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_bt_ph3 {
+ nvidia,pins = "ap_wake_bt_ph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_rst_ph4 {
+ nvidia,pins = "bt_rst_ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_wake_ap_ph5 {
+ nvidia,pins = "bt_wake_ap_ph5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_nfc_ph7 {
+ nvidia,pins = "ap_wake_nfc_ph7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_en_pi0 {
+ nvidia,pins = "nfc_en_pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_int_pi1 {
+ nvidia,pins = "nfc_int_pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_en_pi2 {
+ nvidia,pins = "gps_en_pi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_rst_pi3 {
+ nvidia,pins = "gps_rst_pi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_tx_pi4 {
+ nvidia,pins = "uart4_tx_pi4";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rx_pi5 {
+ nvidia,pins = "uart4_rx_pi5";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rts_pi6 {
+ nvidia,pins = "uart4_rts_pi6";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_cts_pi7 {
+ nvidia,pins = "uart4_cts_pi7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_sda_pj0 {
+ nvidia,pins = "gen1_i2c_sda_pj0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pj1 {
+ nvidia,pins = "gen1_i2c_scl_pj1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen2_i2c_scl_pj2 {
+ nvidia,pins = "gen2_i2c_scl_pj2";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pj3 {
+ nvidia,pins = "gen2_i2c_sda_pj3";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_fs_pj4 {
+ nvidia,pins = "dap4_fs_pj4";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pj5 {
+ nvidia,pins = "dap4_din_pj5";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pj6 {
+ nvidia,pins = "dap4_dout_pj6";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pj7 {
+ nvidia,pins = "dap4_sclk_pj7";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk5 {
+ nvidia,pins = "pk5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk6 {
+ nvidia,pins = "pk6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl0 {
+ nvidia,pins = "pl0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl1 {
+ nvidia,pins = "pl1";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_clk_pm0 {
+ nvidia,pins = "sdmmc1_clk_pm0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pm1 {
+ nvidia,pins = "sdmmc1_cmd_pm1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_pm2 {
+ nvidia,pins = "sdmmc1_dat3_pm2";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat2_pm3 {
+ nvidia,pins = "sdmmc1_dat2_pm3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat1_pm4 {
+ nvidia,pins = "sdmmc1_dat1_pm4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat0_pm5 {
+ nvidia,pins = "sdmmc1_dat0_pm5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pp0 {
+ nvidia,pins = "sdmmc3_clk_pp0";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pp1 {
+ nvidia,pins = "sdmmc3_cmd_pp1";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat3_pp2 {
+ nvidia,pins = "sdmmc3_dat3_pp2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat2_pp3 {
+ nvidia,pins = "sdmmc3_dat2_pp3";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat1_pp4 {
+ nvidia,pins = "sdmmc3_dat1_pp4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat0_pp5 {
+ nvidia,pins = "sdmmc3_dat0_pp5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_mclk_ps0 {
+ nvidia,pins = "cam1_mclk_ps0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_mclk_ps1 {
+ nvidia,pins = "cam2_mclk_ps1";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_ps2 {
+ nvidia,pins = "cam_i2c_scl_ps2";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_sda_ps3 {
+ nvidia,pins = "cam_i2c_sda_ps3";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_rst_ps4 {
+ nvidia,pins = "cam_rst_ps4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_af_en_ps5 {
+ nvidia,pins = "cam_af_en_ps5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_flash_en_ps6 {
+ nvidia,pins = "cam_flash_en_ps6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_pwdn_ps7 {
+ nvidia,pins = "cam1_pwdn_ps7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_pwdn_pt0 {
+ nvidia,pins = "cam2_pwdn_pt0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_strobe_pt1 {
+ nvidia,pins = "cam1_strobe_pt1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_tx_pu0 {
+ nvidia,pins = "uart1_tx_pu0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rx_pu1 {
+ nvidia,pins = "uart1_rx_pu1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rts_pu2 {
+ nvidia,pins = "uart1_rts_pu2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_cts_pu3 {
+ nvidia,pins = "uart1_cts_pu3";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_pwm_pv0 {
+ nvidia,pins = "lcd_bl_pwm_pv0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_en_pv1 {
+ nvidia,pins = "lcd_bl_en_pv1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_rst_pv2 {
+ nvidia,pins = "lcd_rst_pv2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio1_pv3 {
+ nvidia,pins = "lcd_gpio1_pv3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio2_pv4 {
+ nvidia,pins = "lcd_gpio2_pv4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_ready_pv5 {
+ nvidia,pins = "ap_ready_pv5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_rst_pv6 {
+ nvidia,pins = "touch_rst_pv6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_clk_pv7 {
+ nvidia,pins = "touch_clk_pv7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ modem_wake_ap_px0 {
+ nvidia,pins = "modem_wake_ap_px0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_int_px1 {
+ nvidia,pins = "touch_int_px1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ motion_int_px2 {
+ nvidia,pins = "motion_int_px2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ als_prox_int_px3 {
+ nvidia,pins = "als_prox_int_px3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ temp_alert_px4 {
+ nvidia,pins = "temp_alert_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_power_on_px5 {
+ nvidia,pins = "button_power_on_px5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_up_px6 {
+ nvidia,pins = "button_vol_up_px6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_down_px7 {
+ nvidia,pins = "button_vol_down_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_slide_sw_py0 {
+ nvidia,pins = "button_slide_sw_py0";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_home_py1 {
+ nvidia,pins = "button_home_py1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_te_py2 {
+ nvidia,pins = "lcd_te_py2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_py3 {
+ nvidia,pins = "pwr_i2c_scl_py3";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_sda_py4 {
+ nvidia,pins = "pwr_i2c_sda_py4";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_out_py5 {
+ nvidia,pins = "clk_32k_out_py5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz0 {
+ nvidia,pins = "pz0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz1 {
+ nvidia,pins = "pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz2 {
+ nvidia,pins = "pz2";
+ 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>;
+ };
+ pz3 {
+ nvidia,pins = "pz3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz4 {
+ nvidia,pins = "pz4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz5 {
+ nvidia,pins = "pz5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_paa0 {
+ nvidia,pins = "dap2_fs_paa0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_sclk_paa1 {
+ nvidia,pins = "dap2_sclk_paa1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_din_paa2 {
+ nvidia,pins = "dap2_din_paa2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_dout_paa3 {
+ nvidia,pins = "dap2_dout_paa3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ aud_mclk_pbb0 {
+ nvidia,pins = "aud_mclk_pbb0";
+ nvidia,function = "aud";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_pbb1 {
+ nvidia,pins = "dvfs_pwm_pbb1";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_clk_pbb2 {
+ nvidia,pins = "dvfs_clk_pbb2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_pbb3 {
+ nvidia,pins = "gpio_x1_aud_pbb3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_pbb4 {
+ nvidia,pins = "gpio_x3_aud_pbb4";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pcc0 {
+ nvidia,pins = "hdmi_cec_pcc0";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_dp_hpd_pcc1 {
+ nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pcc2 {
+ nvidia,pins = "spdif_out_pcc2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pcc3 {
+ nvidia,pins = "spdif_in_pcc3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pcc4 {
+ nvidia,pins = "usb_vbus_en0_pcc4";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en1_pcc5 {
+ nvidia,pins = "usb_vbus_en1_pcc5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ dp_hpd0_pcc6 {
+ nvidia,pins = "dp_hpd0_pcc6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pcc7 {
+ nvidia,pins = "pcc7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_cs1_pdd0 {
+ nvidia,pins = "spi2_cs1_pdd0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_sck_pee0 {
+ nvidia,pins = "qspi_sck_pee0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_cs_n_pee1 {
+ nvidia,pins = "qspi_cs_n_pee1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io0_pee2 {
+ nvidia,pins = "qspi_io0_pee2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io1_pee3 {
+ nvidia,pins = "qspi_io1_pee3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io2_pee4 {
+ nvidia,pins = "qspi_io2_pee4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io3_pee5 {
+ nvidia,pins = "qspi_io3_pee5";
+ nvidia,function = "rsvd1";
+ 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 = "core";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "jtag";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ clk_req {
+ nvidia,pins = "clk_req";
+ nvidia,function = "sys";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ shutdown {
+ nvidia,pins = "shutdown";
+ nvidia,function = "shutdown";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
new file mode 100644
index 0000000..be3eccb
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
@@ -0,0 +1,1270 @@
+/ {
+ model = "NVIDIA Tegra210 P2597 I/O board";
+ compatible = "nvidia,p2597", "nvidia,tegra210";
+
+ pinmux: pinmux@0,700008d4 {
+ pinctrl-names = "boot";
+ pinctrl-0 = <&state_boot>;
+
+ state_boot: pinmux {
+ pex_l0_rst_n_pa0 {
+ nvidia,pins = "pex_l0_rst_n_pa0";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l0_clkreq_n_pa1 {
+ nvidia,pins = "pex_l0_clkreq_n_pa1";
+ nvidia,function = "pe0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_wake_n_pa2 {
+ nvidia,pins = "pex_wake_n_pa2";
+ nvidia,function = "pe";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_rst_n_pa3 {
+ nvidia,pins = "pex_l1_rst_n_pa3";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ pex_l1_clkreq_n_pa4 {
+ nvidia,pins = "pex_l1_clkreq_n_pa4";
+ nvidia,function = "pe1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ sata_led_active_pa5 {
+ nvidia,pins = "sata_led_active_pa5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pa6 {
+ nvidia,pins = "pa6";
+ nvidia,function = "sata";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_fs_pb0 {
+ nvidia,pins = "dap1_fs_pb0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_din_pb1 {
+ nvidia,pins = "dap1_din_pb1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_dout_pb2 {
+ nvidia,pins = "dap1_dout_pb2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap1_sclk_pb3 {
+ nvidia,pins = "dap1_sclk_pb3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_mosi_pb4 {
+ nvidia,pins = "spi2_mosi_pb4";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_miso_pb5 {
+ nvidia,pins = "spi2_miso_pb5";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_sck_pb6 {
+ nvidia,pins = "spi2_sck_pb6";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_cs0_pb7 {
+ nvidia,pins = "spi2_cs0_pb7";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_mosi_pc0 {
+ nvidia,pins = "spi1_mosi_pc0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_miso_pc1 {
+ nvidia,pins = "spi1_miso_pc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_sck_pc2 {
+ nvidia,pins = "spi1_sck_pc2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs0_pc3 {
+ nvidia,pins = "spi1_cs0_pc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi1_cs1_pc4 {
+ nvidia,pins = "spi1_cs1_pc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_sck_pc5 {
+ nvidia,pins = "spi4_sck_pc5";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_cs0_pc6 {
+ nvidia,pins = "spi4_cs0_pc6";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_mosi_pc7 {
+ nvidia,pins = "spi4_mosi_pc7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spi4_miso_pd0 {
+ nvidia,pins = "spi4_miso_pd0";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_tx_pd1 {
+ nvidia,pins = "uart3_tx_pd1";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rx_pd2 {
+ nvidia,pins = "uart3_rx_pd2";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_rts_pd3 {
+ nvidia,pins = "uart3_rts_pd3";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart3_cts_pd4 {
+ nvidia,pins = "uart3_cts_pd4";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_clk_pe0 {
+ nvidia,pins = "dmic1_clk_pe0";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic1_dat_pe1 {
+ nvidia,pins = "dmic1_dat_pe1";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_clk_pe2 {
+ nvidia,pins = "dmic2_clk_pe2";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic2_dat_pe3 {
+ nvidia,pins = "dmic2_dat_pe3";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_clk_pe4 {
+ nvidia,pins = "dmic3_clk_pe4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dmic3_dat_pe5 {
+ nvidia,pins = "dmic3_dat_pe5";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pe6 {
+ nvidia,pins = "pe6";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pe7 {
+ nvidia,pins = "pe7";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_scl_pf0 {
+ nvidia,pins = "gen3_i2c_scl_pf0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen3_i2c_sda_pf1 {
+ nvidia,pins = "gen3_i2c_sda_pf1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_tx_pg0 {
+ nvidia,pins = "uart2_tx_pg0";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rx_pg1 {
+ nvidia,pins = "uart2_rx_pg1";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_rts_pg2 {
+ nvidia,pins = "uart2_rts_pg2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart2_cts_pg3 {
+ nvidia,pins = "uart2_cts_pg3";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_en_ph0 {
+ nvidia,pins = "wifi_en_ph0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_rst_ph1 {
+ nvidia,pins = "wifi_rst_ph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ wifi_wake_ap_ph2 {
+ nvidia,pins = "wifi_wake_ap_ph2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_bt_ph3 {
+ nvidia,pins = "ap_wake_bt_ph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_rst_ph4 {
+ nvidia,pins = "bt_rst_ph4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ bt_wake_ap_ph5 {
+ nvidia,pins = "bt_wake_ap_ph5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ph6 {
+ nvidia,pins = "ph6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_wake_nfc_ph7 {
+ nvidia,pins = "ap_wake_nfc_ph7";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_en_pi0 {
+ nvidia,pins = "nfc_en_pi0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ nfc_int_pi1 {
+ nvidia,pins = "nfc_int_pi1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_en_pi2 {
+ nvidia,pins = "gps_en_pi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gps_rst_pi3 {
+ nvidia,pins = "gps_rst_pi3";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_tx_pi4 {
+ nvidia,pins = "uart4_tx_pi4";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rx_pi5 {
+ nvidia,pins = "uart4_rx_pi5";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_rts_pi6 {
+ nvidia,pins = "uart4_rts_pi6";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart4_cts_pi7 {
+ nvidia,pins = "uart4_cts_pi7";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_sda_pj0 {
+ nvidia,pins = "gen1_i2c_sda_pj0";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen1_i2c_scl_pj1 {
+ nvidia,pins = "gen1_i2c_scl_pj1";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ gen2_i2c_scl_pj2 {
+ nvidia,pins = "gen2_i2c_scl_pj2";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ gen2_i2c_sda_pj3 {
+ nvidia,pins = "gen2_i2c_sda_pj3";
+ 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_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ dap4_fs_pj4 {
+ nvidia,pins = "dap4_fs_pj4";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_din_pj5 {
+ nvidia,pins = "dap4_din_pj5";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_dout_pj6 {
+ nvidia,pins = "dap4_dout_pj6";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap4_sclk_pj7 {
+ nvidia,pins = "dap4_sclk_pj7";
+ nvidia,function = "i2s4b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk0 {
+ nvidia,pins = "pk0";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk1 {
+ nvidia,pins = "pk1";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk2 {
+ nvidia,pins = "pk2";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk3 {
+ nvidia,pins = "pk3";
+ nvidia,function = "i2s5b";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk4 {
+ nvidia,pins = "pk4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk5 {
+ nvidia,pins = "pk5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk6 {
+ nvidia,pins = "pk6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pk7 {
+ nvidia,pins = "pk7";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl0 {
+ nvidia,pins = "pl0";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pl1 {
+ nvidia,pins = "pl1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_clk_pm0 {
+ nvidia,pins = "sdmmc1_clk_pm0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_cmd_pm1 {
+ nvidia,pins = "sdmmc1_cmd_pm1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat3_pm2 {
+ nvidia,pins = "sdmmc1_dat3_pm2";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat2_pm3 {
+ nvidia,pins = "sdmmc1_dat2_pm3";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat1_pm4 {
+ nvidia,pins = "sdmmc1_dat1_pm4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc1_dat0_pm5 {
+ nvidia,pins = "sdmmc1_dat0_pm5";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_clk_pp0 {
+ nvidia,pins = "sdmmc3_clk_pp0";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_cmd_pp1 {
+ nvidia,pins = "sdmmc3_cmd_pp1";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat3_pp2 {
+ nvidia,pins = "sdmmc3_dat3_pp2";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat2_pp3 {
+ nvidia,pins = "sdmmc3_dat2_pp3";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat1_pp4 {
+ nvidia,pins = "sdmmc3_dat1_pp4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ sdmmc3_dat0_pp5 {
+ nvidia,pins = "sdmmc3_dat0_pp5";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_mclk_ps0 {
+ nvidia,pins = "cam1_mclk_ps0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_mclk_ps1 {
+ nvidia,pins = "cam2_mclk_ps1";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_scl_ps2 {
+ nvidia,pins = "cam_i2c_scl_ps2";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_i2c_sda_ps3 {
+ nvidia,pins = "cam_i2c_sda_ps3";
+ nvidia,function = "i2cvi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ cam_rst_ps4 {
+ nvidia,pins = "cam_rst_ps4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_af_en_ps5 {
+ nvidia,pins = "cam_af_en_ps5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam_flash_en_ps6 {
+ nvidia,pins = "cam_flash_en_ps6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_pwdn_ps7 {
+ nvidia,pins = "cam1_pwdn_ps7";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam2_pwdn_pt0 {
+ nvidia,pins = "cam2_pwdn_pt0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ cam1_strobe_pt1 {
+ nvidia,pins = "cam1_strobe_pt1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_tx_pu0 {
+ nvidia,pins = "uart1_tx_pu0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rx_pu1 {
+ nvidia,pins = "uart1_rx_pu1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_rts_pu2 {
+ nvidia,pins = "uart1_rts_pu2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ uart1_cts_pu3 {
+ nvidia,pins = "uart1_cts_pu3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_pwm_pv0 {
+ nvidia,pins = "lcd_bl_pwm_pv0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_bl_en_pv1 {
+ nvidia,pins = "lcd_bl_en_pv1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_rst_pv2 {
+ nvidia,pins = "lcd_rst_pv2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio1_pv3 {
+ nvidia,pins = "lcd_gpio1_pv3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_gpio2_pv4 {
+ nvidia,pins = "lcd_gpio2_pv4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ ap_ready_pv5 {
+ nvidia,pins = "ap_ready_pv5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_rst_pv6 {
+ nvidia,pins = "touch_rst_pv6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_clk_pv7 {
+ nvidia,pins = "touch_clk_pv7";
+ nvidia,function = "touch";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ modem_wake_ap_px0 {
+ nvidia,pins = "modem_wake_ap_px0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ touch_int_px1 {
+ nvidia,pins = "touch_int_px1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ motion_int_px2 {
+ nvidia,pins = "motion_int_px2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ als_prox_int_px3 {
+ nvidia,pins = "als_prox_int_px3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ temp_alert_px4 {
+ nvidia,pins = "temp_alert_px4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_power_on_px5 {
+ nvidia,pins = "button_power_on_px5";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_up_px6 {
+ nvidia,pins = "button_vol_up_px6";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_vol_down_px7 {
+ nvidia,pins = "button_vol_down_px7";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_slide_sw_py0 {
+ nvidia,pins = "button_slide_sw_py0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ button_home_py1 {
+ nvidia,pins = "button_home_py1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ lcd_te_py2 {
+ nvidia,pins = "lcd_te_py2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_scl_py3 {
+ nvidia,pins = "pwr_i2c_scl_py3";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_i2c_sda_py4 {
+ nvidia,pins = "pwr_i2c_sda_py4";
+ nvidia,function = "i2cpmu";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ clk_32k_out_py5 {
+ nvidia,pins = "clk_32k_out_py5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz0 {
+ nvidia,pins = "pz0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz1 {
+ nvidia,pins = "pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz2 {
+ nvidia,pins = "pz2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz3 {
+ nvidia,pins = "pz3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz4 {
+ nvidia,pins = "pz4";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pz5 {
+ nvidia,pins = "pz5";
+ nvidia,function = "soc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_fs_paa0 {
+ nvidia,pins = "dap2_fs_paa0";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_sclk_paa1 {
+ nvidia,pins = "dap2_sclk_paa1";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_din_paa2 {
+ nvidia,pins = "dap2_din_paa2";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dap2_dout_paa3 {
+ nvidia,pins = "dap2_dout_paa3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ aud_mclk_pbb0 {
+ nvidia,pins = "aud_mclk_pbb0";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_pwm_pbb1 {
+ nvidia,pins = "dvfs_pwm_pbb1";
+ nvidia,function = "cldvfs";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ dvfs_clk_pbb2 {
+ nvidia,pins = "dvfs_clk_pbb2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x1_aud_pbb3 {
+ nvidia,pins = "gpio_x1_aud_pbb3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ gpio_x3_aud_pbb4 {
+ nvidia,pins = "gpio_x3_aud_pbb4";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi_cec_pcc0 {
+ nvidia,pins = "hdmi_cec_pcc0";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ hdmi_int_dp_hpd_pcc1 {
+ nvidia,pins = "hdmi_int_dp_hpd_pcc1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_out_pcc2 {
+ nvidia,pins = "spdif_out_pcc2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ spdif_in_pcc3 {
+ nvidia,pins = "spdif_in_pcc3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ usb_vbus_en0_pcc4 {
+ nvidia,pins = "usb_vbus_en0_pcc4";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ usb_vbus_en1_pcc5 {
+ nvidia,pins = "usb_vbus_en1_pcc5";
+ 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>;
+ nvidia,io-hv = <TEGRA_PIN_ENABLE>;
+ };
+ dp_hpd0_pcc6 {
+ nvidia,pins = "dp_hpd0_pcc6";
+ nvidia,function = "dp";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pcc7 {
+ nvidia,pins = "pcc7";
+ nvidia,function = "rsvd0";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ nvidia,io-hv = <TEGRA_PIN_DISABLE>;
+ };
+ spi2_cs1_pdd0 {
+ nvidia,pins = "spi2_cs1_pdd0";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_sck_pee0 {
+ nvidia,pins = "qspi_sck_pee0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_cs_n_pee1 {
+ nvidia,pins = "qspi_cs_n_pee1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io0_pee2 {
+ nvidia,pins = "qspi_io0_pee2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io1_pee3 {
+ nvidia,pins = "qspi_io1_pee3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io2_pee4 {
+ nvidia,pins = "qspi_io2_pee4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ qspi_io3_pee5 {
+ nvidia,pins = "qspi_io3_pee5";
+ nvidia,function = "rsvd1";
+ 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 = "core";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ pwr_int_n {
+ nvidia,pins = "pwr_int_n";
+ nvidia,function = "pmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <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>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ jtag_rtck {
+ nvidia,pins = "jtag_rtck";
+ nvidia,function = "jtag";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ clk_req {
+ nvidia,pins = "clk_req";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ shutdown {
+ nvidia,pins = "shutdown";
+ nvidia,function = "shutdown";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ /* MMC/SD */
+ sdhci@0,700b0000 {
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+
+ cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
new file mode 100644
index 0000000..23b0630
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -0,0 +1,805 @@
+#include <dt-bindings/clock/tegra210-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra210-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "nvidia,tegra210";
+ interrupt-parent = <&lic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ host1x@0,50000000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_CLK_HOST1X>;
+ clock-names = "host1x";
+ resets = <&tegra_car 28>;
+ reset-names = "host1x";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ranges = <0x0 0x54000000 0x0 0x54000000 0x0 0x01000000>;
+
+ dpaux1: dpaux@0,54040000 {
+ compatible = "nvidia,tegra210-dpaux";
+ reg = <0x0 0x54040000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_DPAUX1>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>;
+ clock-names = "dpaux", "parent";
+ resets = <&tegra_car 207>;
+ reset-names = "dpaux";
+ status = "disabled";
+ };
+
+ vi@0,54080000 {
+ compatible = "nvidia,tegra210-vi";
+ reg = <0x0 0x54080000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ tsec@0,54100000 {
+ compatible = "nvidia,tegra210-tsec";
+ reg = <0x0 0x54100000 0x0 0x00040000>;
+ };
+
+ dc@0,54200000 {
+ compatible = "nvidia,tegra210-dc";
+ reg = <0x0 0x54200000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_DISP1>,
+ <&tegra_car TEGRA210_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,tegra210-dc";
+ reg = <0x0 0x54240000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_DISP2>,
+ <&tegra_car TEGRA210_CLK_PLL_P>;
+ clock-names = "dc", "parent";
+ resets = <&tegra_car 26>;
+ reset-names = "dc";
+
+ iommus = <&mc TEGRA_SWGROUP_DCB>;
+
+ nvidia,head = <1>;
+ };
+
+ dsi@0,54300000 {
+ compatible = "nvidia,tegra210-dsi";
+ reg = <0x0 0x54300000 0x0 0x00040000>;
+ clocks = <&tegra_car TEGRA210_CLK_DSIA>,
+ <&tegra_car TEGRA210_CLK_DSIALP>,
+ <&tegra_car TEGRA210_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 48>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x0c0>; /* DSIA & DSIB pads */
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ vic@0,54340000 {
+ compatible = "nvidia,tegra210-vic";
+ reg = <0x0 0x54340000 0x0 0x00040000>;
+ status = "disabled";
+ };
+
+ nvjpg@0,54380000 {
+ compatible = "nvidia,tegra210-nvjpg";
+ reg = <0x0 0x54380000 0x0 0x00040000>;
+ status = "disabled";
+ };
+
+ dsi@0,54400000 {
+ compatible = "nvidia,tegra210-dsi";
+ reg = <0x0 0x54400000 0x0 0x00040000>;
+ clocks = <&tegra_car TEGRA210_CLK_DSIB>,
+ <&tegra_car TEGRA210_CLK_DSIBLP>,
+ <&tegra_car TEGRA210_CLK_PLL_D_OUT0>;
+ clock-names = "dsi", "lp", "parent";
+ resets = <&tegra_car 82>;
+ reset-names = "dsi";
+ nvidia,mipi-calibrate = <&mipi 0x300>; /* DSIC & DSID pads */
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ nvdec@0,54480000 {
+ compatible = "nvidia,tegra210-nvdec";
+ reg = <0x0 0x54480000 0x0 0x00040000>;
+ status = "disabled";
+ };
+
+ nvenc@0,544c0000 {
+ compatible = "nvidia,tegra210-nvenc";
+ reg = <0x0 0x544c0000 0x0 0x00040000>;
+ status = "disabled";
+ };
+
+ tsec@0,54500000 {
+ compatible = "nvidia,tegra210-tsec";
+ reg = <0x0 0x54500000 0x0 0x00040000>;
+ status = "disabled";
+ };
+
+ sor@0,54540000 {
+ compatible = "nvidia,tegra210-sor";
+ reg = <0x0 0x54540000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SOR0>,
+ <&tegra_car TEGRA210_CLK_PLL_D_OUT0>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>,
+ <&tegra_car TEGRA210_CLK_SOR_SAFE>;
+ clock-names = "sor", "parent", "dp", "safe";
+ resets = <&tegra_car 182>;
+ reset-names = "sor";
+ status = "disabled";
+ };
+
+ sor@0,54580000 {
+ compatible = "nvidia,tegra210-sor1";
+ reg = <0x0 0x54580000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SOR1>,
+ <&tegra_car TEGRA210_CLK_PLL_D2_OUT0>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>,
+ <&tegra_car TEGRA210_CLK_SOR_SAFE>;
+ clock-names = "sor", "parent", "dp", "safe";
+ resets = <&tegra_car 183>;
+ 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 TEGRA210_CLK_DPAUX>,
+ <&tegra_car TEGRA210_CLK_PLL_DP>;
+ clock-names = "dpaux", "parent";
+ resets = <&tegra_car 181>;
+ reset-names = "dpaux";
+ status = "disabled";
+ };
+
+ isp@0,54600000 {
+ compatible = "nvidia,tegra210-isp";
+ reg = <0x0 0x54600000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ isp@0,54680000 {
+ compatible = "nvidia,tegra210-isp";
+ reg = <0x0 0x54680000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ i2c@0,546c0000 {
+ compatible = "nvidia,tegra210-i2c-vi";
+ reg = <0x0 0x546c0000 0x0 0x00040000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
+
+ gic: interrupt-controller@0,50041000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x50041000 0x0 0x1000>,
+ <0x0 0x50042000 0x0 0x2000>,
+ <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,gm20b";
+ 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 TEGRA210_CLK_GPU>,
+ <&tegra_car TEGRA210_CLK_PLL_P_OUT5>;
+ clock-names = "gpu", "pwr";
+ resets = <&tegra_car 184>;
+ reset-names = "gpu";
+ status = "disabled";
+ };
+
+ lic: interrupt-controller@0,60004000 {
+ compatible = "nvidia,tegra210-ictlr";
+ reg = <0x0 0x60004000 0x0 0x40>, /* primary controller */
+ <0x0 0x60004100 0x0 0x40>, /* secondary controller */
+ <0x0 0x60004200 0x0 0x40>, /* tertiary controller */
+ <0x0 0x60004300 0x0 0x40>, /* quaternary controller */
+ <0x0 0x60004400 0x0 0x40>, /* quinary controller */
+ <0x0 0x60004500 0x0 0x40>; /* senary controller */
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ timer@0,60005000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_CLK_TIMER>;
+ clock-names = "timer";
+ };
+
+ tegra_car: clock@0,60006000 {
+ compatible = "nvidia,tegra210-car";
+ reg = <0x0 0x60006000 0x0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ flow-controller@0,60007000 {
+ compatible = "nvidia,tegra210-flowctrl";
+ reg = <0x0 0x60007000 0x0 0x1000>;
+ };
+
+ gpio: gpio@0,6000d000 {
+ compatible = "nvidia,tegra210-gpio", "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,tegra210-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 TEGRA210_CLK_APBDMA>;
+ clock-names = "dma";
+ resets = <&tegra_car 34>;
+ reset-names = "dma";
+ #dma-cells = <1>;
+ };
+
+ apbmisc@0,70000800 {
+ compatible = "nvidia,tegra210-apbmisc", "nvidia,tegra20-apbmisc";
+ reg = <0x0 0x70000800 0x0 0x64>, /* Chip revision */
+ <0x0 0x7000e864 0x0 0x04>; /* Strapping options */
+ };
+
+ pinmux: pinmux@0,700008d4 {
+ compatible = "nvidia,tegra210-pinmux";
+ reg = <0x0 0x700008d4 0x0 0x29c>, /* Pad control registers */
+ <0x0 0x70003000 0x0 0x294>; /* Mux registers */
+ };
+
+ /*
+ * There are two serial driver i.e. 8250 based simple serial
+ * driver and APB DMA based serial driver for higher baudrate
+ * and performance. 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,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTA>;
+ clock-names = "serial";
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ dmas = <&apbdma 8>, <&apbdma 8>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartb: serial@0,70006040 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006040 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTB>;
+ clock-names = "serial";
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ dmas = <&apbdma 9>, <&apbdma 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartc: serial@0,70006200 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006200 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTC>;
+ clock-names = "serial";
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ dmas = <&apbdma 10>, <&apbdma 10>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ uartd: serial@0,70006300 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006300 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTD>;
+ clock-names = "serial";
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ dmas = <&apbdma 19>, <&apbdma 19>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ pwm: pwm@0,7000a000 {
+ compatible = "nvidia,tegra210-pwm", "nvidia,tegra20-pwm";
+ reg = <0x0 0x7000a000 0x0 0x100>;
+ #pwm-cells = <2>;
+ clocks = <&tegra_car TEGRA210_CLK_PWM>;
+ clock-names = "pwm";
+ resets = <&tegra_car 17>;
+ reset-names = "pwm";
+ status = "disabled";
+ };
+
+ i2c@0,7000c000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_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,tegra210-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 TEGRA210_CLK_SBC4>;
+ clock-names = "spi";
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ dmas = <&apbdma 18>, <&apbdma 18>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ rtc@0,7000e000 {
+ compatible = "nvidia,tegra210-rtc", "nvidia,tegra20-rtc";
+ reg = <0x0 0x7000e000 0x0 0x100>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_RTC>;
+ clock-names = "rtc";
+ };
+
+ pmc: pmc@0,7000e400 {
+ compatible = "nvidia,tegra210-pmc";
+ reg = <0x0 0x7000e400 0x0 0x400>;
+ clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+
+ #power-domain-cells = <1>;
+ };
+
+ fuse@0,7000f800 {
+ compatible = "nvidia,tegra210-efuse";
+ reg = <0x0 0x7000f800 0x0 0x400>;
+ clocks = <&tegra_car TEGRA210_CLK_FUSE>;
+ clock-names = "fuse";
+ resets = <&tegra_car 39>;
+ reset-names = "fuse";
+ };
+
+ mc: memory-controller@0,70019000 {
+ compatible = "nvidia,tegra210-mc";
+ reg = <0x0 0x70019000 0x0 0x1000>;
+ clocks = <&tegra_car TEGRA210_CLK_MC>;
+ clock-names = "mc";
+
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+
+ #iommu-cells = <1>;
+ };
+
+ hda@0,70030000 {
+ compatible = "nvidia,tegra210-hda", "nvidia,tegra30-hda";
+ reg = <0x0 0x70030000 0x0 0x10000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_HDA>,
+ <&tegra_car TEGRA210_CLK_HDA2HDMI>,
+ <&tegra_car TEGRA210_CLK_HDA2CODEC_2X>;
+ clock-names = "hda", "hda2hdmi", "hda2codec_2x";
+ resets = <&tegra_car 125>, /* hda */
+ <&tegra_car 128>, /* hda2hdmi */
+ <&tegra_car 111>; /* hda2codec_2x */
+ reset-names = "hda", "hda2hdmi", "hda2codec_2x";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0000 {
+ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0000 0x0 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
+ clock-names = "sdhci";
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0200 {
+ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0200 0x0 0x200>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
+ clock-names = "sdhci";
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0400 {
+ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0400 0x0 0x200>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
+ clock-names = "sdhci";
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0600 {
+ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+ reg = <0x0 0x700b0600 0x0 0x200>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
+ clock-names = "sdhci";
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ mipi: mipi@0,700e3000 {
+ compatible = "nvidia,tegra210-mipi";
+ reg = <0x0 0x700e3000 0x0 0x100>;
+ clocks = <&tegra_car TEGRA210_CLK_MIPI_CAL>;
+ clock-names = "mipi-cal";
+ #nvidia,mipi-calibrate-cells = <1>;
+ };
+
+ spi@0,70410000 {
+ compatible = "nvidia,tegra210-qspi";
+ reg = <0x0 0x70410000 0x0 0x1000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA210_CLK_QSPI>;
+ clock-names = "qspi";
+ resets = <&tegra_car 211>;
+ reset-names = "qspi";
+ dmas = <&apbdma 5>, <&apbdma 5>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ usb@0,7d000000 {
+ compatible = "nvidia,tegra210-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 TEGRA210_CLK_USBD>;
+ clock-names = "usb";
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ nvidia,phy = <&phy1>;
+ status = "disabled";
+ };
+
+ phy1: usb-phy@0,7d000000 {
+ compatible = "nvidia,tegra210-usb-phy", "nvidia,tegra30-usb-phy";
+ reg = <0x0 0x7d000000 0x0 0x4000>,
+ <0x0 0x7d000000 0x0 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA210_CLK_USBD>,
+ <&tegra_car TEGRA210_CLK_PLL_U>,
+ <&tegra_car TEGRA210_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,tegra210-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 TEGRA210_CLK_USB2>;
+ clock-names = "usb";
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
+ nvidia,phy = <&phy2>;
+ status = "disabled";
+ };
+
+ phy2: usb-phy@0,7d004000 {
+ compatible = "nvidia,tegra210-usb-phy", "nvidia,tegra30-usb-phy";
+ reg = <0x0 0x7d004000 0x0 0x4000>,
+ <0x0 0x7d000000 0x0 0x4000>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA210_CLK_USB2>,
+ <&tegra_car TEGRA210_CLK_PLL_U>,
+ <&tegra_car TEGRA210_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";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <3>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-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/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 66804ff..db17c5d 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -19,6 +19,11 @@
/ {
aliases {
serial0 = &blsp1_uart2;
+ serial1 = &blsp1_uart1;
+ usid0 = &pm8916_0;
+ i2c0 = &blsp_i2c2;
+ i2c1 = &blsp_i2c6;
+ i2c3 = &blsp_i2c4;
};
chosen {
@@ -26,13 +31,52 @@
};
soc {
+ serial@78af000 {
+ label = "LS-UART0";
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp1_uart1_default>;
+ pinctrl-1 = <&blsp1_uart1_sleep>;
+ };
+
serial@78b0000 {
+ label = "LS-UART1";
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&blsp1_uart2_default>;
pinctrl-1 = <&blsp1_uart2_sleep>;
};
+ i2c@78b6000 {
+ /* On Low speed expansion */
+ label = "LS-I2C0";
+ status = "okay";
+ };
+
+ i2c@78b8000 {
+ /* On High speed expansion */
+ label = "HS-I2C2";
+ status = "okay";
+ };
+
+ i2c@78ba000 {
+ /* On Low speed expansion */
+ label = "LS-I2C1";
+ status = "okay";
+ };
+
+ spi@78b7000 {
+ /* On High speed expansion */
+ label = "HS-SPI1";
+ status = "okay";
+ };
+
+ spi@78b9000 {
+ /* On Low speed expansion */
+ label = "LS-SPI0";
+ status = "okay";
+ };
+
leds {
pinctrl-names = "default";
pinctrl-0 = <&msmgpio_leds>,
@@ -85,3 +129,7 @@
};
};
};
+
+&sdhc_1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
index fced77f..b0a064d 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
@@ -17,6 +17,6 @@
/ {
model = "Qualcomm Technologies, Inc. MSM 8916 MTP";
- compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp-smb1360",
+ compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp/1",
"qcom,msm8916", "qcom,mtp";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi
index a1aa0b2..ceeb8a6 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi
@@ -17,6 +17,7 @@
/ {
aliases {
serial0 = &blsp1_uart2;
+ usid0 = &pm8916_0;
};
chosen {
diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
index 5689568..955c6f1 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
@@ -13,6 +13,35 @@
&msmgpio {
+ blsp1_uart1_default: blsp1_uart1_default {
+ pinmux {
+ function = "blsp_uart1";
+ // TX, RX, CTS_N, RTS_N
+ pins = "gpio0", "gpio1",
+ "gpio2", "gpio3";
+ };
+ pinconf {
+ pins = "gpio0", "gpio1",
+ "gpio2", "gpio3";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1_sleep: blsp1_uart1_sleep {
+ pinmux {
+ function = "gpio";
+ pins = "gpio0", "gpio1",
+ "gpio2", "gpio3";
+ };
+ pinconf {
+ pins = "gpio0", "gpio1",
+ "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
blsp1_uart2_default: blsp1_uart2_default {
pinmux {
function = "blsp_uart2";
@@ -27,7 +56,7 @@
blsp1_uart2_sleep: blsp1_uart2_sleep {
pinmux {
- function = "blsp_uart2";
+ function = "gpio";
pins = "gpio4", "gpio5";
};
pinconf {
@@ -241,6 +270,30 @@
};
};
+ i2c2_default: i2c2_default {
+ pinmux {
+ function = "blsp_i2c2";
+ pins = "gpio6", "gpio7";
+ };
+ pinconf {
+ pins = "gpio6", "gpio7";
+ drive-strength = <16>;
+ bias-disable = <0>;
+ };
+ };
+
+ i2c2_sleep: i2c2_sleep {
+ pinmux {
+ function = "gpio";
+ pins = "gpio6", "gpio7";
+ };
+ pinconf {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable = <0>;
+ };
+ };
+
i2c4_default: i2c4_default {
pinmux {
function = "blsp_i2c4";
@@ -248,14 +301,14 @@
};
pinconf {
pins = "gpio14", "gpio15";
- drive-strength = <2>;
+ drive-strength = <16>;
bias-disable = <0>;
};
};
i2c4_sleep: i2c4_sleep {
pinmux {
- function = "blsp_i2c4";
+ function = "gpio";
pins = "gpio14", "gpio15";
};
pinconf {
@@ -265,6 +318,30 @@
};
};
+ i2c6_default: i2c6_default {
+ pinmux {
+ function = "blsp_i2c6";
+ pins = "gpio22", "gpio23";
+ };
+ pinconf {
+ pins = "gpio22", "gpio23";
+ drive-strength = <16>;
+ bias-disable = <0>;
+ };
+ };
+
+ i2c6_sleep: i2c6_sleep {
+ pinmux {
+ function = "gpio";
+ pins = "gpio22", "gpio23";
+ };
+ pinconf {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-disable = <0>;
+ };
+ };
+
sdhc2_cd_pin {
sdc2_cd_on: cd_on {
pinmux {
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 5911de0..9153214 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -37,6 +37,22 @@
reg = <0 0 0 0>;
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ reserve_aligned@86000000 {
+ reg = <0x0 0x86000000 0x0 0x0300000>;
+ no-map;
+ };
+
+ smem_mem: smem_region@86300000 {
+ reg = <0x0 0x86300000 0x0 0x0100000>;
+ no-map;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -74,6 +90,29 @@
<GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
+ clocks {
+ xo_board: xo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ };
+
+ sleep_clk: sleep_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+
+ smem {
+ compatible = "qcom,smem";
+
+ memory-region = <&smem_mem>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -99,15 +138,50 @@
compatible = "qcom,gcc-msm8916";
#clock-cells = <1>;
#reset-cells = <1>;
+ #power-domain-cells = <1>;
reg = <0x1800000 0x80000>;
};
+ tcsr_mutex_regs: syscon@1905000 {
+ compatible = "syscon";
+ reg = <0x1905000 0x20000>;
+ };
+
+ tcsr_mutex: hwlock {
+ compatible = "qcom,tcsr-mutex";
+ syscon = <&tcsr_mutex_regs 0 0x1000>;
+ #hwlock-cells = <1>;
+ };
+
+ rpm_msg_ram: memory@60000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0x60000 0x8000>;
+ };
+
+ blsp1_uart1: serial@78af000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78af000 0x200>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+ dmas = <&blsp_dma 1>, <&blsp_dma 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ apcs: syscon@b011000 {
+ compatible = "syscon";
+ reg = <0x0b011000 0x1000>;
+ };
+
blsp1_uart2: serial@78b0000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x78b0000 0x200>;
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
clock-names = "core", "iface";
+ dmas = <&blsp_dma 3>, <&blsp_dma 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -224,6 +298,21 @@
status = "disabled";
};
+ blsp_i2c2: i2c@78b6000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78b6000 0x1000>;
+ interrupts = <GIC_SPI 96 0>;
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
+ clock-names = "iface", "core";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c2_default>;
+ pinctrl-1 = <&i2c2_sleep>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
blsp_i2c4: i2c@78b8000 {
compatible = "qcom,i2c-qup-v2.2.1";
reg = <0x78b8000 0x1000>;
@@ -239,6 +328,21 @@
status = "disabled";
};
+ blsp_i2c6: i2c@78ba000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78ba000 0x1000>;
+ interrupts = <GIC_SPI 100 0>;
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>;
+ clock-names = "iface", "core";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c6_default>;
+ pinctrl-1 = <&i2c6_sleep>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
sdhc_1: sdhci@07824000 {
compatible = "qcom,sdhci-msm-v4";
reg = <0x07824900 0x11c>, <0x07824000 0x800>;
@@ -390,6 +494,56 @@
interrupt-controller;
#interrupt-cells = <4>;
};
+
+ rng@22000 {
+ compatible = "qcom,prng";
+ reg = <0x00022000 0x200>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ };
+ };
+
+ smd {
+ compatible = "qcom,smd";
+
+ rpm {
+ interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+ rpm_requests {
+ compatible = "qcom,rpm-msm8916";
+ qcom,smd-channels = "rpm_requests";
+
+ pm8916-regulators {
+ compatible = "qcom,rpm-pm8916-regulators";
+
+ pm8916_s1: s1 {};
+ pm8916_s2: s2 {};
+ pm8916_s3: s3 {};
+ pm8916_s4: s4 {};
+
+ pm8916_l1: l1 {};
+ pm8916_l2: l2 {};
+ pm8916_l3: l3 {};
+ pm8916_l4: l4 {};
+ pm8916_l5: l5 {};
+ pm8916_l6: l6 {};
+ pm8916_l7: l7 {};
+ pm8916_l8: l8 {};
+ pm8916_l9: l9 {};
+ pm8916_l10: l10 {};
+ pm8916_l11: l11 {};
+ pm8916_l12: l12 {};
+ pm8916_l13: l13 {};
+ pm8916_l14: l14 {};
+ pm8916_l15: l15 {};
+ pm8916_l16: l16 {};
+ pm8916_l17: l17 {};
+ pm8916_l18: l18 {};
+ };
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi
index b222ece..3743245 100644
--- a/arch/arm64/boot/dts/qcom/pm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi
@@ -4,8 +4,8 @@
&spmi_bus {
- usid0: pm8916@0 {
- compatible = "qcom,spmi-pmic";
+ pm8916_0: pm8916@0 {
+ compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
@@ -90,7 +90,7 @@
};
};
- usid1: pm8916@1 {
+ pm8916_1: pm8916@1 {
compatible = "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
new file mode 100644
index 0000000..9ce1890
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -0,0 +1,4 @@
+dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb
+
+always := $(dtb-y)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
new file mode 100644
index 0000000..265d12f
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -0,0 +1,251 @@
+/*
+ * Device Tree Source for the Salvator-X board
+ *
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * SSI-AK4613
+ *
+ * This command is required when Playback/Capture
+ *
+ * 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 "r8a7795.dtsi"
+
+/ {
+ model = "Renesas Salvator-X board based on r8a7795";
+ compatible = "renesas,salvator-x", "renesas,r8a7795";
+
+ aliases {
+ serial0 = &scif2;
+ serial1 = &scif1;
+ ethernet0 = &avb;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+ x12_clk: x12_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ audio_clkout: audio_clkout {
+ /*
+ * This is same as <&rcar_sound 0>
+ * but needed to avoid cs2000/rcar_sound probe dead-lock
+ */
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <11289600>;
+ };
+
+ rsnd_ak4613: sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&sndcpu>;
+ simple-audio-card,frame-master = <&sndcpu>;
+
+ sndcpu: simple-audio-card,cpu {
+ sound-dai = <&rcar_sound>;
+ };
+
+ sndcodec: simple-audio-card,codec {
+ sound-dai = <&ak4613>;
+ };
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&pfc {
+ scif1_pins: scif1 {
+ renesas,groups = "scif1_data_a", "scif1_ctrl";
+ renesas,function = "scif1";
+ };
+ scif2_pins: scif2 {
+ renesas,groups = "scif2_data_a";
+ renesas,function = "scif2";
+ };
+
+ i2c2_pins: i2c2 {
+ renesas,groups = "i2c2_a";
+ renesas,function = "i2c2";
+ };
+
+ avb_pins: avb {
+ renesas,groups = "avb_mdc";
+ renesas,function = "avb";
+ };
+
+ sound_pins: sound {
+ renesas,groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
+ renesas,function = "ssi";
+ };
+
+ sound_clk_pins: sound_clk {
+ renesas,groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
+ "audio_clkout_a", "audio_clkout3_a";
+ renesas,function = "audio_clk";
+ };
+};
+
+&scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ clock-frequency = <100000>;
+
+ ak4613: codec@10 {
+ compatible = "asahi-kasei,ak4613";
+ #sound-dai-cells = <0>;
+ reg = <0x10>;
+ clocks = <&rcar_sound 3>;
+
+ asahi-kasei,in1-single-end;
+ asahi-kasei,in2-single-end;
+ asahi-kasei,out1-single-end;
+ asahi-kasei,out2-single-end;
+ asahi-kasei,out3-single-end;
+ asahi-kasei,out4-single-end;
+ asahi-kasei,out5-single-end;
+ asahi-kasei,out6-single-end;
+ };
+
+ cs2000: clk_multiplier@4f {
+ #clock-cells = <0>;
+ compatible = "cirrus,cs2000-cp";
+ reg = <0x4f>;
+ clocks = <&audio_clkout>, <&x12_clk>;
+ clock-names = "clk_in", "ref_clk";
+
+ assigned-clocks = <&cs2000>;
+ assigned-clock-rates = <24576000>; /* 1/1 divide */
+ };
+};
+
+&rcar_sound {
+ pinctrl-0 = <&sound_pins &sound_clk_pins>;
+ pinctrl-names = "default";
+
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+
+ /* audio_clkout0/1/2/3 */
+ #clock-cells = <1>;
+ clock-frequency = <11289600>;
+
+ status = "okay";
+
+ /* update <audio_clk_b> to <cs2000> */
+ clocks = <&cpg CPG_MOD 1005>,
+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+ <&audio_clk_a>, <&cs2000>,
+ <&audio_clk_c>,
+ <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+
+ rcar_sound,dai {
+ dai0 {
+ playback = <&ssi0 &src0 &dvc0>;
+ capture = <&ssi1 &src1 &dvc1>;
+ };
+ };
+};
+
+&sata {
+ status = "okay";
+};
+
+&ssi1 {
+ shared-pin;
+};
+
+&audio_clk_a {
+ clock-frequency = <22579200>;
+};
+
+&avb {
+ pinctrl-0 = <&avb_pins>;
+ pinctrl-names = "default";
+ renesas,no-ether-link;
+ phy-handle = <&phy0>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ rxc-skew-ps = <900>;
+ rxdv-skew-ps = <0>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txc-skew-ps = <900>;
+ txen-skew-ps = <0>;
+ txd0-skew-ps = <0>;
+ txd1-skew-ps = <0>;
+ txd2-skew-ps = <0>;
+ txd3-skew-ps = <0>;
+ reg = <0>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
new file mode 100644
index 0000000..bb353cd
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -0,0 +1,779 @@
+/*
+ * Device Tree Source for the r8a7795 SoC
+ *
+ * Copyright (C) 2015 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.
+ */
+
+#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "renesas,r8a7795";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ a57_0: cpu@0 {
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x0>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+
+ a57_1: cpu@1 {
+ compatible = "arm,cortex-a57","arm,armv8";
+ reg = <0x1>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ a57_2: cpu@2 {
+ compatible = "arm,cortex-a57","arm,armv8";
+ reg = <0x2>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ a57_3: cpu@3 {
+ compatible = "arm,cortex-a57","arm,armv8";
+ reg = <0x3>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ };
+
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ extalr_clk: extalr {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ /*
+ * 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>;
+ };
+
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@0xf1010000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xf1010000 0 0x1000>,
+ <0x0 0xf1020000 0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 16>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 912>;
+ power-domains = <&cpg>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 28>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 911>;
+ power-domains = <&cpg>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 15>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 910>;
+ power-domains = <&cpg>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 16>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 909>;
+ power-domains = <&cpg>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 18>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 908>;
+ power-domains = <&cpg>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 907>;
+ power-domains = <&cpg>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055400 0 0x50>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 906>;
+ power-domains = <&cpg>;
+ };
+
+ gpio7: gpio@e6055800 {
+ compatible = "renesas,gpio-r8a7795",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055800 0 0x50>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 4>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 905>;
+ power-domains = <&cpg>;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&a57_0>,
+ <&a57_1>,
+ <&a57_2>,
+ <&a57_3>;
+ };
+
+ timer {
+ compatible = "arm,armv8-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)>;
+ };
+
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a7795-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+ clocks = <&extal_clk>, <&extalr_clk>;
+ clock-names = "extal", "extalr";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ audma0: dma-controller@ec700000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec700000 0 0x10000>;
+ interrupts = <0 350 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
+ 0 333 IRQ_TYPE_LEVEL_HIGH
+ 0 334 IRQ_TYPE_LEVEL_HIGH
+ 0 335 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 502>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ audma1: dma-controller@ec720000 {
+ compatible = "renesas,rcar-dmac";
+ reg = <0 0xec720000 0 0x10000>;
+ interrupts = <0 351 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
+ 0 346 IRQ_TYPE_LEVEL_HIGH
+ 0 347 IRQ_TYPE_LEVEL_HIGH
+ 0 348 IRQ_TYPE_LEVEL_HIGH
+ 0 349 IRQ_TYPE_LEVEL_HIGH
+ 0 382 IRQ_TYPE_LEVEL_HIGH
+ 0 383 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 501>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ pfc: pfc@e6060000 {
+ compatible = "renesas,pfc-r8a7795";
+ reg = <0 0xe6060000 0 0x50c>;
+ };
+
+ dmac0: dma-controller@e6700000 {
+ /* Empty node for now */
+ };
+
+ dmac1: dma-controller@e7300000 {
+ /* Empty node for now */
+ };
+
+ dmac2: dma-controller@e7310000 {
+ /* Empty node for now */
+ };
+
+ avb: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a7795";
+ reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <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>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 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>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <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>,
+ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19",
+ "ch20", "ch21", "ch22", "ch23",
+ "ch24";
+ clocks = <&cpg CPG_MOD 812>;
+ power-domains = <&cpg>;
+ phy-mode = "rgmii-id";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ hscif0: serial@e6540000 {
+ compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+ reg = <0 0xe6540000 0 96>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 520>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x31>, <&dmac1 0x30>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ hscif1: serial@e6550000 {
+ compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+ reg = <0 0xe6550000 0 96>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 519>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x33>, <&dmac1 0x32>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ hscif2: serial@e6560000 {
+ compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+ reg = <0 0xe6560000 0 96>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 518>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x35>, <&dmac1 0x34>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ hscif3: serial@e66a0000 {
+ compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+ reg = <0 0xe66a0000 0 96>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 517>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ hscif4: serial@e66b0000 {
+ compatible = "renesas,hscif-r8a7795", "renesas,hscif";
+ reg = <0 0xe66b0000 0 96>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 516>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6e60000 0 64>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 207>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x51>, <&dmac1 0x50>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif1: serial@e6e68000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6e68000 0 64>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 206>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x53>, <&dmac1 0x52>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif2: serial@e6e88000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6e88000 0 64>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 310>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x13>, <&dmac1 0x12>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif3: serial@e6c50000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6c50000 0 64>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 204>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif4: serial@e6c40000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6c40000 0 64>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 203>;
+ clock-names = "sci_ick";
+ dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ scif5: serial@e6f30000 {
+ compatible = "renesas,scif-r8a7795", "renesas,scif";
+ reg = <0 0xe6f30000 0 64>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 202>;
+ clock-names = "sci_ick";
+ dmas = <&dmac1 0x5b>, <&dmac1 0x5a>;
+ dma-names = "tx", "rx";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@e6500000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe6500000 0 0x40>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 931>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6508000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 930>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6510000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe6510000 0 0x40>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 929>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e66d0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe66d0000 0 0x40>;
+ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 928>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@e66d8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe66d8000 0 0x40>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 927>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@e66e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe66e0000 0 0x40>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 919>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <110>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@e66e8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,i2c-r8a7795";
+ reg = <0 0xe66e8000 0 0x40>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 918>;
+ power-domains = <&cpg>;
+ i2c-scl-internal-delay-ns = <6>;
+ status = "disabled";
+ };
+
+ rcar_sound: sound@ec500000 {
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ /*
+ * #clock-cells is required for audio_clkout0/1/2/3
+ *
+ * clkout : #clock-cells = <0>; <&rcar_sound>;
+ * clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
+ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+ clocks = <&cpg CPG_MOD 1005>,
+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+ <&audio_clk_a>, <&audio_clk_b>,
+ <&audio_clk_c>,
+ <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+ 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";
+ power-domains = <&cpg>;
+ 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";
+ };
+ };
+ };
+
+ sata: sata@ee300000 {
+ compatible = "renesas,sata-r8a7795";
+ reg = <0 0xee300000 0 0x1fff>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 815>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 601e6a2..e3f0b5f 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
always := $(dtb-y)
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts b/arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts
new file mode 100644
index 0000000..8a5275f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015 Caesar Wang <wxt@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 "rk3368-evb.dtsi"
+
+/ {
+ model = "Rockchip RK3368 EVB with ACT8846 pmic";
+ compatible = "rockchip,rk3368-evb-act8846", "rockchip,rk3368";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ 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";
+ reg = <0x41>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ 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 = <700000>;
+ regulator-max-microvolt = <1500000>;
+ 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 = <1800000>;
+ 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/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
new file mode 100644
index 0000000..8c219cc
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2015 Caesar Wang <wxt@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.
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3368.dtsi"
+
+/ {
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ backlight: 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 = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bl_en>;
+ pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>;
+ pwm-delay-us = <10000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ };
+ };
+
+ /* supplies both host and otg */
+ vcc_host: vcc-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_lan: vcc-lan-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_lan";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sys: vcc-sys-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;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ status = "okay";
+};
+
+&gmac {
+ phy-supply = <&vcc_lan>;
+ phy-mode = "rmii";
+ clock_in_out = "output";
+ snps,reset-gpio = <&gpio3 12 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+ bias-disable;
+ 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 = <0 20 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ emmc {
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 19 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 20 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 21 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 22 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 23 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 24 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 25 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+ };
+
+ emmc-clk {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+ };
+
+ emmc-cmd {
+ rockchip,pins = <1 26 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+ };
+
+ emmc_reset: emmc-reset {
+ rockchip,pins = <2 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdio {
+ wifi_reg_on: wifi-reg-on {
+ rockchip,pins = <3 4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_rst: bt-rst {
+ rockchip,pins = <3 5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm0 {
+ 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";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
index 401a812..104cbee 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
@@ -336,6 +336,12 @@
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";
+};
+
&uart2 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi
new file mode 100644
index 0000000..a10010f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-thermal.dtsi
@@ -0,0 +1,112 @@
+/*
+ * Device Tree Source for RK3368 SoC thermal
+ *
+ * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
+ * Caesar Wang <wxt@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.
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+cpu_thermal: cpu_thermal {
+ polling-delay-passive = <100>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&tsadc 0>;
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ temperature = <75000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_alert1: cpu_alert1 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ cpu_crit: cpu_crit {
+ temperature = <95000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device =
+ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&cpu_alert1>;
+ cooling-device =
+ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
+
+gpu_thermal: gpu_thermal {
+ polling-delay-passive = <100>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&tsadc 1>;
+
+ trips {
+ gpu_alert0: gpu_alert0 {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+ gpu_crit: gpu_crit {
+ temperature = <1150000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device =
+ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index cc093a4..122777b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -45,6 +45,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "rockchip,rk3368";
@@ -53,6 +54,7 @@
#size-cells = <2>;
aliases {
+ ethernet0 = &gmac;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
@@ -123,6 +125,8 @@
reg = <0x0 0x0>;
cpu-idle-states = <&cpu_sleep>;
enable-method = "psci";
+
+ #cooling-cells = <2>; /* min followed by max */
};
cpu_l1: cpu@1 {
@@ -155,6 +159,8 @@
reg = <0x0 0x100>;
cpu-idle-states = <&cpu_sleep>;
enable-method = "psci";
+
+ #cooling-cells = <2>; /* min followed by max */
};
cpu_b1: cpu@101 {
@@ -404,6 +410,27 @@
status = "disabled";
};
+ thermal-zones {
+ #include "rk3368-thermal.dtsi"
+ };
+
+ tsadc: tsadc@ff280000 {
+ compatible = "rockchip,rk3368-tsadc";
+ reg = <0x0 0xff280000 0x0 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 = "init", "default", "sleep";
+ pinctrl-0 = <&otp_gpio>;
+ pinctrl-1 = <&otp_out>;
+ pinctrl-2 = <&otp_gpio>;
+ #thermal-sensor-cells = <1>;
+ rockchip,hw-tshut-temp = <95000>;
+ status = "disabled";
+ };
+
gmac: ethernet@ff290000 {
compatible = "rockchip,rk3368-gmac";
reg = <0x0 0xff290000 0x0 0x10000>;
@@ -471,6 +498,48 @@
status = "disabled";
};
+ pwm0: pwm@ff680000 {
+ compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff680000 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ clocks = <&cru PCLK_PWM1>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm1: pwm@ff680010 {
+ compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff680010 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ clocks = <&cru PCLK_PWM1>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm2: pwm@ff680020 {
+ compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff680020 0x0 0x10>;
+ #pwm-cells = <3>;
+ clocks = <&cru PCLK_PWM1>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
+ pwm3: pwm@ff680030 {
+ compatible = "rockchip,rk3368-pwm", "rockchip,rk3288-pwm";
+ reg = <0x0 0xff680030 0x0 0x10>;
+ #pwm-cells = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ clocks = <&cru PCLK_PWM1>;
+ clock-names = "pwm";
+ status = "disabled";
+ };
+
uart2: serial@ff690000 {
compatible = "rockchip,rk3368-uart", "snps,dw-apb-uart";
reg = <0x0 0xff690000 0x0 0x100>;
@@ -510,6 +579,12 @@
status = "disabled";
};
+ timer@ff810000 {
+ compatible = "rockchip,rk3368-timer", "rockchip,rk3288-timer";
+ reg = <0x0 0xff810000 0x0 0x20>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
gic: interrupt-controller@ffb71000 {
compatible = "arm,gic-400";
interrupt-controller;
@@ -712,6 +787,24 @@
};
};
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <3 8 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <0 8 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <3 29 RK_FUNC_3 &pcfg_pull_none>;
+ };
+ };
+
sdio0 {
sdio0_bus1: sdio0-bus1 {
rockchip,pins = <2 28 RK_FUNC_1 &pcfg_pull_up>;
@@ -762,7 +855,7 @@
rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_up>;
};
- sdmmc_cd: sdmcc-cd {
+ sdmmc_cd: sdmmc-cd {
rockchip,pins = <2 11 RK_FUNC_1 &pcfg_pull_up>;
};
@@ -829,6 +922,16 @@
};
};
+ tsadc {
+ otp_gpio: otp-gpio {
+ rockchip,pins = <0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ otp_out: otp-out {
+ rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
uart0 {
uart0_xfer: uart0-xfer {
rockchip,pins = <2 24 RK_FUNC_1 &pcfg_pull_up>,
diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile
new file mode 100644
index 0000000..8d72771
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/Makefile
@@ -0,0 +1,4 @@
+dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld10-ref.dtb
+
+always := $(dtb-y)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts
new file mode 100644
index 0000000..3e53317
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts
@@ -0,0 +1,95 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD10 Reference Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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/ "uniphier-ph1-ld10.dtsi"
+/include/ "uniphier-support-card.dtsi"
+
+/ {
+ model = "UniPhier PH1-LD10 Reference Board";
+ compatible = "socionext,ph1-ld10-ref", "socionext,ph1-ld10";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0xc0000000>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ };
+};
+
+&extbus {
+ ranges = <1 0x00000000 0x42000000 0x02000000>;
+};
+
+&support_card {
+ ranges = <0x00000000 1 0x01f00000 0x00100000>;
+};
+
+&ethsc {
+ interrupts = <0 48 4>;
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi
new file mode 100644
index 0000000..0296af9
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi
@@ -0,0 +1,280 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD10 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.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.
+ */
+
+/ {
+ compatible = "socionext,ph1-ld10";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu2>;
+ };
+ core1 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0 0x000>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000100>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72", "arm,armv8";
+ reg = <0 0x001>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000100>;
+ };
+
+ cpu2: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0 0x100>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000100>;
+ };
+
+ cpu3: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0 0x101>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000100>;
+ };
+ };
+
+ clocks {
+ uart_clk: uart_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <58820000>;
+ };
+
+ i2c_clk: i2c_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0xf01>,
+ <1 14 0xf01>,
+ <1 11 0xf01>,
+ <1 10 0xf01>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+
+ extbus: extbus {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ };
+
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&uart_clk>;
+ };
+
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&uart_clk>;
+ };
+
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&uart_clk>;
+ };
+
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&uart_clk>;
+ };
+
+ i2c0: i2c@58780000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58780000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
+
+ i2c1: i2c@58781000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58781000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
+
+ i2c2: i2c@58782000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58782000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
+
+ i2c3: i2c@58783000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58783000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <100000>;
+ };
+
+ i2c4: i2c@58784000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58784000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 45 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
+
+ i2c5: i2c@58785000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58785000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 25 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
+
+ i2c6: i2c@58786000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58786000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 26 4>;
+ clocks = <&i2c_clk>;
+ clock-frequency = <400000>;
+ };
+
+ pinctrl: pinctrl@5f801000 {
+ compatible = "socionext,ph1-ld10-pinctrl", "syscon";
+ reg = <0x5f801000 0xe00>;
+ };
+
+ gic: interrupt-controller@5fe00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x5fe00000 0x10000>, /* GICD */
+ <0x5fe80000 0x80000>; /* GICR */
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <1 9 4>;
+ };
+ };
+};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi
new file mode 120000
index 0000000..f42fb6f
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi
@@ -0,0 +1 @@
+../../../../arm/boot/dts/uniphier-pinctrl.dtsi \ No newline at end of file
diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi
new file mode 120000
index 0000000..1246db9
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi
@@ -0,0 +1 @@
+../../../../arm/boot/dts/uniphier-support-card.dtsi \ No newline at end of file
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 857eda5..200fb58 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -133,6 +133,8 @@
clocks = <&misc_clk>;
interrupt-parent = <&gic>;
interrupts = <0 16 4>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
reg = <0x0 0xff0a0000 0x1000>;
};
diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh
index 12ed78a..d91e1f0 100644
--- a/arch/arm64/boot/install.sh
+++ b/arch/arm64/boot/install.sh
@@ -20,6 +20,20 @@
# $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
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 34d71dd..86581f7 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -16,7 +16,6 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
-CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_HUGETLB=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
@@ -34,27 +33,37 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_ARCH_BCM_IPROC=y
CONFIG_ARCH_BERLIN=y
CONFIG_ARCH_EXYNOS7=y
-CONFIG_ARCH_FSL_LS2085A=y
+CONFIG_ARCH_LAYERSCAPE=y
CONFIG_ARCH_HISI=y
CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_QCOM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_RENESAS=y
+CONFIG_ARCH_R8A7795=y
+CONFIG_ARCH_STRATIX10=y
CONFIG_ARCH_TEGRA=y
-CONFIG_ARCH_TEGRA_132_SOC=y
-CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SPRD=y
CONFIG_ARCH_THUNDER=y
+CONFIG_ARCH_UNIPHIER=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
CONFIG_ARCH_ZYNQMP=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_RCAR_GEN2_PCIE=y
+CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_XGENE=y
-CONFIG_SMP=y
+CONFIG_PCI_LAYERSCAPE=y
+CONFIG_PCI_HISI=y
+CONFIG_PCIE_QCOM=y
+CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_CMA=y
+CONFIG_XEN=y
CONFIG_CMDLINE="console=ttyAMA0"
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_COMPAT=y
@@ -73,7 +82,6 @@ CONFIG_BPF_JIT=y
# CONFIG_WIRELESS is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
-# CONFIG_TEGRA_AHB is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
@@ -88,15 +96,22 @@ CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_AHCI_CEVA=y
CONFIG_AHCI_XGENE=y
+CONFIG_SATA_RCAR=y
CONFIG_PATA_PLATFORM=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_NETDEVICES=y
CONFIG_TUN=y
CONFIG_VIRTIO_NET=y
+CONFIG_AMD_XGBE=y
CONFIG_NET_XGENE=y
+CONFIG_E1000E=y
+CONFIG_IGB=y
+CONFIG_IGBVF=y
CONFIG_SKY2=y
+CONFIG_RAVB=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
+CONFIG_MICREL_PHY=y
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
@@ -107,31 +122,49 @@ CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_UNIPHIER=y
+CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=11
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_QUP=y
+CONFIG_I2C_UNIPHIER_F=y
+CONFIG_I2C_RCAR=y
CONFIG_SPI=y
CONFIG_SPI_PL022=y
+CONFIG_SPI_QUP=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_GPIO_PL061=y
+CONFIG_GPIO_RCAR=y
CONFIG_GPIO_XGENE=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=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_SOC=y
+CONFIG_SND_SOC_RCAR=y
+CONFIG_SND_SOC_AK4613=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
@@ -144,7 +177,10 @@ CONFIG_MMC=y
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SPI=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_EXYNOS=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_SYSCON=y
@@ -153,19 +189,33 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
CONFIG_RTC_DRV_XGENE=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_RCAR_DMAC=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_COMMON_CLK_CS2000_CP=y
CONFIG_COMMON_CLK_QCOM=y
CONFIG_MSM_GCC_8916=y
-# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ARM_SMMU=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_ARCH_TEGRA_132_SOC=y
+CONFIG_ARCH_TEGRA_210_SOC=y
+CONFIG_HISILICON_IRQ_MBIGEN=y
CONFIG_PHY_XGENE=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_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
@@ -176,7 +226,7 @@ CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_EFIVAR_FS=y
-# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_SQUASHFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
@@ -185,6 +235,7 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
+CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
@@ -195,6 +246,7 @@ CONFIG_LOCKUP_DETECTOR=y
# CONFIG_FTRACE is not set
CONFIG_MEMTEST=y
CONFIG_SECURITY=y
+CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_ARM64_CRYPTO=y
CONFIG_CRYPTO_SHA1_ARM64_CE=y
@@ -203,3 +255,4 @@ CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_CRC32_ARM64=y
diff --git a/arch/arm64/crypto/aes-ce-cipher.c b/arch/arm64/crypto/aes-ce-cipher.c
index ce47792..f7bd9bf 100644
--- a/arch/arm64/crypto/aes-ce-cipher.c
+++ b/arch/arm64/crypto/aes-ce-cipher.c
@@ -237,7 +237,7 @@ EXPORT_SYMBOL(ce_aes_setkey);
static struct crypto_alg aes_alg = {
.cra_name = "aes",
.cra_driver_name = "aes-ce",
- .cra_priority = 300,
+ .cra_priority = 250,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypto_aes_ctx),
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 05d9e16..5c88804 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -15,6 +15,7 @@
#include <crypto/algapi.h>
#include <linux/module.h>
#include <linux/cpufeature.h>
+#include <crypto/xts.h>
#include "aes-ce-setkey.h"
@@ -85,6 +86,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
int ret;
+ ret = xts_check_key(tfm, in_key, key_len);
+ if (ret)
+ return ret;
+
ret = aes_expandkey(&ctx->key1, in_key, key_len / 2);
if (!ret)
ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2],
@@ -294,7 +299,7 @@ static struct crypto_alg aes_algs[] = { {
.cra_blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
- .ivsize = AES_BLOCK_SIZE,
+ .ivsize = 0,
.setkey = aes_setkey,
.encrypt = ecb_encrypt,
.decrypt = ecb_decrypt,
@@ -371,7 +376,7 @@ static struct crypto_alg aes_algs[] = { {
.cra_ablkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
- .ivsize = AES_BLOCK_SIZE,
+ .ivsize = 0,
.setkey = ablk_set_key,
.encrypt = ablk_encrypt,
.decrypt = ablk_decrypt,
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 70fd9ff..cff532a 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,5 +1,3 @@
-
-
generic-y += bug.h
generic-y += bugs.h
generic-y += checksum.h
@@ -31,7 +29,6 @@ generic-y += msgbuf.h
generic-y += msi.h
generic-y += mutex.h
generic-y += pci.h
-generic-y += pci-bridge.h
generic-y += poll.h
generic-y += preempt.h
generic-y += resource.h
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 208cec0..aee323b 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,7 +12,6 @@
#ifndef _ASM_ACPI_H
#define _ASM_ACPI_H
-#include <linux/irqchip/arm-gic-acpi.h>
#include <linux/mm.h>
#include <linux/psci.h>
@@ -88,8 +87,30 @@ void __init acpi_init_cpus(void);
static inline void acpi_init_cpus(void) { }
#endif /* CONFIG_ACPI */
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+bool acpi_parking_protocol_valid(int cpu);
+void __init
+acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor);
+#else
+static inline bool acpi_parking_protocol_valid(int cpu) { return false; }
+static inline void
+acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor)
+{}
+#endif
+
static inline const char *acpi_get_enable_method(int cpu)
{
- return acpi_psci_present() ? "psci" : NULL;
+ if (acpi_psci_present())
+ return "psci";
+
+ if (acpi_parking_protocol_valid(cpu))
+ return "parking-protocol";
+
+ return NULL;
}
+
+#ifdef CONFIG_ACPI_APEI
+pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
+#endif
+
#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index d56ec07..beccbde 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -1,6 +1,8 @@
#ifndef __ASM_ALTERNATIVE_H
#define __ASM_ALTERNATIVE_H
+#include <asm/cpufeature.h>
+
#ifndef __ASSEMBLY__
#include <linux/init.h>
@@ -19,7 +21,6 @@ struct alt_instr {
void __init apply_alternatives_all(void);
void apply_alternatives(void *start, size_t length);
-void free_alternatives_memory(void);
#define ALTINSTR_ENTRY(feature) \
" .word 661b - .\n" /* label */ \
@@ -64,6 +65,8 @@ void free_alternatives_memory(void);
#else
+#include <asm/assembler.h>
+
.macro altinstruction_entry orig_offset alt_offset feature orig_len alt_len
.word \orig_offset - .
.word \alt_offset - .
@@ -137,6 +140,65 @@ void free_alternatives_memory(void);
alternative_insn insn1, insn2, cap, IS_ENABLED(cfg)
+/*
+ * Generate the assembly for UAO alternatives with exception table entries.
+ * This is complicated as there is no post-increment or pair versions of the
+ * unprivileged instructions, and USER() only works for single instructions.
+ */
+#ifdef CONFIG_ARM64_UAO
+ .macro uao_ldp l, reg1, reg2, addr, post_inc
+ alternative_if_not ARM64_HAS_UAO
+8888: ldp \reg1, \reg2, [\addr], \post_inc;
+8889: nop;
+ nop;
+ alternative_else
+ ldtr \reg1, [\addr];
+ ldtr \reg2, [\addr, #8];
+ add \addr, \addr, \post_inc;
+ alternative_endif
+
+ _asm_extable 8888b,\l;
+ _asm_extable 8889b,\l;
+ .endm
+
+ .macro uao_stp l, reg1, reg2, addr, post_inc
+ alternative_if_not ARM64_HAS_UAO
+8888: stp \reg1, \reg2, [\addr], \post_inc;
+8889: nop;
+ nop;
+ alternative_else
+ sttr \reg1, [\addr];
+ sttr \reg2, [\addr, #8];
+ add \addr, \addr, \post_inc;
+ alternative_endif
+
+ _asm_extable 8888b,\l;
+ _asm_extable 8889b,\l;
+ .endm
+
+ .macro uao_user_alternative l, inst, alt_inst, reg, addr, post_inc
+ alternative_if_not ARM64_HAS_UAO
+8888: \inst \reg, [\addr], \post_inc;
+ nop;
+ alternative_else
+ \alt_inst \reg, [\addr];
+ add \addr, \addr, \post_inc;
+ alternative_endif
+
+ _asm_extable 8888b,\l;
+ .endm
+#else
+ .macro uao_ldp l, reg1, reg2, addr, post_inc
+ USER(\l, ldp \reg1, \reg2, [\addr], \post_inc)
+ .endm
+ .macro uao_stp l, reg1, reg2, addr, post_inc
+ USER(\l, stp \reg1, \reg2, [\addr], \post_inc)
+ .endm
+ .macro uao_user_alternative l, inst, alt_inst, reg, addr, post_inc
+ USER(\l, \inst \reg, [\addr], \post_inc)
+ .endm
+#endif
+
#endif /* __ASSEMBLY__ */
/*
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
new file mode 100644
index 0000000..8ec88e5
--- /dev/null
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -0,0 +1,172 @@
+/*
+ * arch/arm64/include/asm/arch_gicv3.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_ARCH_GICV3_H
+#define __ASM_ARCH_GICV3_H
+
+#include <asm/sysreg.h>
+
+#define ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1)
+#define ICC_DIR_EL1 sys_reg(3, 0, 12, 11, 1)
+#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
+#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
+#define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
+#define ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4)
+#define ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5)
+#define ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7)
+
+#define ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5)
+
+/*
+ * System register definitions
+ */
+#define ICH_VSEIR_EL2 sys_reg(3, 4, 12, 9, 4)
+#define ICH_HCR_EL2 sys_reg(3, 4, 12, 11, 0)
+#define ICH_VTR_EL2 sys_reg(3, 4, 12, 11, 1)
+#define ICH_MISR_EL2 sys_reg(3, 4, 12, 11, 2)
+#define ICH_EISR_EL2 sys_reg(3, 4, 12, 11, 3)
+#define ICH_ELSR_EL2 sys_reg(3, 4, 12, 11, 5)
+#define ICH_VMCR_EL2 sys_reg(3, 4, 12, 11, 7)
+
+#define __LR0_EL2(x) sys_reg(3, 4, 12, 12, x)
+#define __LR8_EL2(x) sys_reg(3, 4, 12, 13, x)
+
+#define ICH_LR0_EL2 __LR0_EL2(0)
+#define ICH_LR1_EL2 __LR0_EL2(1)
+#define ICH_LR2_EL2 __LR0_EL2(2)
+#define ICH_LR3_EL2 __LR0_EL2(3)
+#define ICH_LR4_EL2 __LR0_EL2(4)
+#define ICH_LR5_EL2 __LR0_EL2(5)
+#define ICH_LR6_EL2 __LR0_EL2(6)
+#define ICH_LR7_EL2 __LR0_EL2(7)
+#define ICH_LR8_EL2 __LR8_EL2(0)
+#define ICH_LR9_EL2 __LR8_EL2(1)
+#define ICH_LR10_EL2 __LR8_EL2(2)
+#define ICH_LR11_EL2 __LR8_EL2(3)
+#define ICH_LR12_EL2 __LR8_EL2(4)
+#define ICH_LR13_EL2 __LR8_EL2(5)
+#define ICH_LR14_EL2 __LR8_EL2(6)
+#define ICH_LR15_EL2 __LR8_EL2(7)
+
+#define __AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x)
+#define ICH_AP0R0_EL2 __AP0Rx_EL2(0)
+#define ICH_AP0R1_EL2 __AP0Rx_EL2(1)
+#define ICH_AP0R2_EL2 __AP0Rx_EL2(2)
+#define ICH_AP0R3_EL2 __AP0Rx_EL2(3)
+
+#define __AP1Rx_EL2(x) sys_reg(3, 4, 12, 9, x)
+#define ICH_AP1R0_EL2 __AP1Rx_EL2(0)
+#define ICH_AP1R1_EL2 __AP1Rx_EL2(1)
+#define ICH_AP1R2_EL2 __AP1Rx_EL2(2)
+#define ICH_AP1R3_EL2 __AP1Rx_EL2(3)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/stringify.h>
+#include <asm/barrier.h>
+
+/*
+ * Low-level accessors
+ *
+ * These system registers are 32 bits, but we make sure that the compiler
+ * sets the GP register's most significant bits to 0 with an explicit cast.
+ */
+
+static inline void gic_write_eoir(u32 irq)
+{
+ asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" ((u64)irq));
+ isb();
+}
+
+static inline void gic_write_dir(u32 irq)
+{
+ asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" ((u64)irq));
+ isb();
+}
+
+static inline u64 gic_read_iar_common(void)
+{
+ u64 irqstat;
+
+ asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
+ dsb(sy);
+ return irqstat;
+}
+
+/*
+ * Cavium ThunderX erratum 23154
+ *
+ * The gicv3 of ThunderX requires a modified version for reading the
+ * IAR status to ensure data synchronization (access to icc_iar1_el1
+ * is not sync'ed before and after).
+ */
+static inline u64 gic_read_iar_cavium_thunderx(void)
+{
+ u64 irqstat;
+
+ asm volatile(
+ "nop;nop;nop;nop\n\t"
+ "nop;nop;nop;nop\n\t"
+ "mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
+ "nop;nop;nop;nop"
+ : "=r" (irqstat));
+ mb();
+
+ return irqstat;
+}
+
+static inline void gic_write_pmr(u32 val)
+{
+ asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" ((u64)val));
+}
+
+static inline void gic_write_ctlr(u32 val)
+{
+ asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" ((u64)val));
+ isb();
+}
+
+static inline void gic_write_grpen1(u32 val)
+{
+ asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" ((u64)val));
+ isb();
+}
+
+static inline void gic_write_sgi1r(u64 val)
+{
+ asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
+}
+
+static inline u32 gic_read_sre(void)
+{
+ u64 val;
+
+ asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
+ return val;
+}
+
+static inline void gic_write_sre(u32 val)
+{
+ asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" ((u64)val));
+ isb();
+}
+
+#define gic_read_typer(c) readq_relaxed(c)
+#define gic_write_irouter(v, c) writeq_relaxed(v, c)
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_GICV3_H */
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index b51f2cc..70f7b9e 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -94,12 +94,19 @@
dmb \opt
.endm
+/*
+ * Emit an entry into the exception table
+ */
+ .macro _asm_extable, from, to
+ .pushsection __ex_table, "a"
+ .align 3
+ .long (\from - .), (\to - .)
+ .popsection
+ .endm
+
#define USER(l, x...) \
9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .quad 9999b,l; \
- .previous
+ _asm_extable 9999b, l
/*
* Register aliases.
@@ -193,4 +200,37 @@ lr .req x30 // link register
str \src, [\tmp, :lo12:\sym]
.endm
+ /*
+ * @sym: The name of the per-cpu variable
+ * @reg: Result of per_cpu(sym, smp_processor_id())
+ * @tmp: scratch register
+ */
+ .macro this_cpu_ptr, sym, reg, tmp
+ adr_l \reg, \sym
+ mrs \tmp, tpidr_el1
+ add \reg, \reg, \tmp
+ .endm
+
+/*
+ * Annotate a function as position independent, i.e., safe to be called before
+ * the kernel virtual mapping is activated.
+ */
+#define ENDPIPROC(x) \
+ .globl __pi_##x; \
+ .type __pi_##x, %function; \
+ .set __pi_##x, x; \
+ .size __pi_##x, . - x; \
+ ENDPROC(x)
+
+ /*
+ * Emit a 64-bit absolute little endian symbol reference in a way that
+ * ensures that it will be resolved at build time, even when building a
+ * PIE binary. This requires cooperation from the linker script, which
+ * must emit the lo32/hi32 halves individually.
+ */
+ .macro le64sym, sym
+ .long \sym\()_lo32
+ .long \sym\()_hi32
+ .endm
+
#endif /* __ASM_ASSEMBLER_H */
diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
index 35a6778..f3a3586 100644
--- a/arch/arm64/include/asm/atomic.h
+++ b/arch/arm64/include/asm/atomic.h
@@ -54,14 +54,43 @@
#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) READ_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = (i))
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
+
+#define atomic_add_return_relaxed atomic_add_return_relaxed
+#define atomic_add_return_acquire atomic_add_return_acquire
+#define atomic_add_return_release atomic_add_return_release
+#define atomic_add_return atomic_add_return
+
+#define atomic_inc_return_relaxed(v) atomic_add_return_relaxed(1, (v))
+#define atomic_inc_return_acquire(v) atomic_add_return_acquire(1, (v))
+#define atomic_inc_return_release(v) atomic_add_return_release(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+#define atomic_sub_return_relaxed atomic_sub_return_relaxed
+#define atomic_sub_return_acquire atomic_sub_return_acquire
+#define atomic_sub_return_release atomic_sub_return_release
+#define atomic_sub_return atomic_sub_return
+
+#define atomic_dec_return_relaxed(v) atomic_sub_return_relaxed(1, (v))
+#define atomic_dec_return_acquire(v) atomic_sub_return_acquire(1, (v))
+#define atomic_dec_return_release(v) atomic_sub_return_release(1, (v))
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+
+#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
+#define atomic_xchg_acquire(v, new) xchg_acquire(&((v)->counter), (new))
+#define atomic_xchg_release(v, new) xchg_release(&((v)->counter), (new))
#define atomic_xchg(v, new) xchg(&((v)->counter), (new))
+
+#define atomic_cmpxchg_relaxed(v, old, new) \
+ cmpxchg_relaxed(&((v)->counter), (old), (new))
+#define atomic_cmpxchg_acquire(v, old, new) \
+ cmpxchg_acquire(&((v)->counter), (old), (new))
+#define atomic_cmpxchg_release(v, old, new) \
+ cmpxchg_release(&((v)->counter), (old), (new))
#define atomic_cmpxchg(v, old, new) cmpxchg(&((v)->counter), (old), (new))
#define atomic_inc(v) atomic_add(1, (v))
#define atomic_dec(v) atomic_sub(1, (v))
-#define atomic_inc_return(v) atomic_add_return(1, (v))
-#define atomic_dec_return(v) atomic_sub_return(1, (v))
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
@@ -75,13 +104,39 @@
#define ATOMIC64_INIT ATOMIC_INIT
#define atomic64_read atomic_read
#define atomic64_set atomic_set
+
+#define atomic64_add_return_relaxed atomic64_add_return_relaxed
+#define atomic64_add_return_acquire atomic64_add_return_acquire
+#define atomic64_add_return_release atomic64_add_return_release
+#define atomic64_add_return atomic64_add_return
+
+#define atomic64_inc_return_relaxed(v) atomic64_add_return_relaxed(1, (v))
+#define atomic64_inc_return_acquire(v) atomic64_add_return_acquire(1, (v))
+#define atomic64_inc_return_release(v) atomic64_add_return_release(1, (v))
+#define atomic64_inc_return(v) atomic64_add_return(1, (v))
+
+#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+#define atomic64_sub_return_acquire atomic64_sub_return_acquire
+#define atomic64_sub_return_release atomic64_sub_return_release
+#define atomic64_sub_return atomic64_sub_return
+
+#define atomic64_dec_return_relaxed(v) atomic64_sub_return_relaxed(1, (v))
+#define atomic64_dec_return_acquire(v) atomic64_sub_return_acquire(1, (v))
+#define atomic64_dec_return_release(v) atomic64_sub_return_release(1, (v))
+#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
+
+#define atomic64_xchg_relaxed atomic_xchg_relaxed
+#define atomic64_xchg_acquire atomic_xchg_acquire
+#define atomic64_xchg_release atomic_xchg_release
#define atomic64_xchg atomic_xchg
+
+#define atomic64_cmpxchg_relaxed atomic_cmpxchg_relaxed
+#define atomic64_cmpxchg_acquire atomic_cmpxchg_acquire
+#define atomic64_cmpxchg_release atomic_cmpxchg_release
#define atomic64_cmpxchg atomic_cmpxchg
#define atomic64_inc(v) atomic64_add(1, (v))
#define atomic64_dec(v) atomic64_sub(1, (v))
-#define atomic64_inc_return(v) atomic64_add_return(1, (v))
-#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
#define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0)
diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index b3b5c4a..f61c84f6 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -55,40 +55,47 @@ __LL_SC_PREFIX(atomic_##op(int i, atomic_t *v)) \
} \
__LL_SC_EXPORT(atomic_##op);
-#define ATOMIC_OP_RETURN(op, asm_op) \
+#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op) \
__LL_SC_INLINE int \
-__LL_SC_PREFIX(atomic_##op##_return(int i, atomic_t *v)) \
+__LL_SC_PREFIX(atomic_##op##_return##name(int i, atomic_t *v)) \
{ \
unsigned long tmp; \
int result; \
\
- asm volatile("// atomic_" #op "_return\n" \
+ asm volatile("// atomic_" #op "_return" #name "\n" \
" prfm pstl1strm, %2\n" \
-"1: ldxr %w0, %2\n" \
+"1: ld" #acq "xr %w0, %2\n" \
" " #asm_op " %w0, %w0, %w3\n" \
-" stlxr %w1, %w0, %2\n" \
-" cbnz %w1, 1b" \
+" st" #rel "xr %w1, %w0, %2\n" \
+" cbnz %w1, 1b\n" \
+" " #mb \
: "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \
: "Ir" (i) \
- : "memory"); \
+ : cl); \
\
- smp_mb(); \
return result; \
} \
-__LL_SC_EXPORT(atomic_##op##_return);
+__LL_SC_EXPORT(atomic_##op##_return##name);
-#define ATOMIC_OPS(op, asm_op) \
- ATOMIC_OP(op, asm_op) \
- ATOMIC_OP_RETURN(op, asm_op)
+#define ATOMIC_OPS(...) \
+ ATOMIC_OP(__VA_ARGS__) \
+ ATOMIC_OP_RETURN( , dmb ish, , l, "memory", __VA_ARGS__)
-ATOMIC_OPS(add, add)
-ATOMIC_OPS(sub, sub)
+#define ATOMIC_OPS_RLX(...) \
+ ATOMIC_OPS(__VA_ARGS__) \
+ ATOMIC_OP_RETURN(_relaxed, , , , , __VA_ARGS__)\
+ ATOMIC_OP_RETURN(_acquire, , a, , "memory", __VA_ARGS__)\
+ ATOMIC_OP_RETURN(_release, , , l, "memory", __VA_ARGS__)
+
+ATOMIC_OPS_RLX(add, add)
+ATOMIC_OPS_RLX(sub, sub)
ATOMIC_OP(and, and)
ATOMIC_OP(andnot, bic)
ATOMIC_OP(or, orr)
ATOMIC_OP(xor, eor)
+#undef ATOMIC_OPS_RLX
#undef ATOMIC_OPS
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
@@ -111,40 +118,47 @@ __LL_SC_PREFIX(atomic64_##op(long i, atomic64_t *v)) \
} \
__LL_SC_EXPORT(atomic64_##op);
-#define ATOMIC64_OP_RETURN(op, asm_op) \
+#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op) \
__LL_SC_INLINE long \
-__LL_SC_PREFIX(atomic64_##op##_return(long i, atomic64_t *v)) \
+__LL_SC_PREFIX(atomic64_##op##_return##name(long i, atomic64_t *v)) \
{ \
long result; \
unsigned long tmp; \
\
- asm volatile("// atomic64_" #op "_return\n" \
+ asm volatile("// atomic64_" #op "_return" #name "\n" \
" prfm pstl1strm, %2\n" \
-"1: ldxr %0, %2\n" \
+"1: ld" #acq "xr %0, %2\n" \
" " #asm_op " %0, %0, %3\n" \
-" stlxr %w1, %0, %2\n" \
-" cbnz %w1, 1b" \
+" st" #rel "xr %w1, %0, %2\n" \
+" cbnz %w1, 1b\n" \
+" " #mb \
: "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \
: "Ir" (i) \
- : "memory"); \
+ : cl); \
\
- smp_mb(); \
return result; \
} \
-__LL_SC_EXPORT(atomic64_##op##_return);
+__LL_SC_EXPORT(atomic64_##op##_return##name);
+
+#define ATOMIC64_OPS(...) \
+ ATOMIC64_OP(__VA_ARGS__) \
+ ATOMIC64_OP_RETURN(, dmb ish, , l, "memory", __VA_ARGS__)
-#define ATOMIC64_OPS(op, asm_op) \
- ATOMIC64_OP(op, asm_op) \
- ATOMIC64_OP_RETURN(op, asm_op)
+#define ATOMIC64_OPS_RLX(...) \
+ ATOMIC64_OPS(__VA_ARGS__) \
+ ATOMIC64_OP_RETURN(_relaxed,, , , , __VA_ARGS__) \
+ ATOMIC64_OP_RETURN(_acquire,, a, , "memory", __VA_ARGS__) \
+ ATOMIC64_OP_RETURN(_release,, , l, "memory", __VA_ARGS__)
-ATOMIC64_OPS(add, add)
-ATOMIC64_OPS(sub, sub)
+ATOMIC64_OPS_RLX(add, add)
+ATOMIC64_OPS_RLX(sub, sub)
ATOMIC64_OP(and, and)
ATOMIC64_OP(andnot, bic)
ATOMIC64_OP(or, orr)
ATOMIC64_OP(xor, eor)
+#undef ATOMIC64_OPS_RLX
#undef ATOMIC64_OPS
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
@@ -172,7 +186,7 @@ __LL_SC_PREFIX(atomic64_dec_if_positive(atomic64_t *v))
}
__LL_SC_EXPORT(atomic64_dec_if_positive);
-#define __CMPXCHG_CASE(w, sz, name, mb, rel, cl) \
+#define __CMPXCHG_CASE(w, sz, name, mb, acq, rel, cl) \
__LL_SC_INLINE unsigned long \
__LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr, \
unsigned long old, \
@@ -182,7 +196,7 @@ __LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr, \
\
asm volatile( \
" prfm pstl1strm, %[v]\n" \
- "1: ldxr" #sz "\t%" #w "[oldval], %[v]\n" \
+ "1: ld" #acq "xr" #sz "\t%" #w "[oldval], %[v]\n" \
" eor %" #w "[tmp], %" #w "[oldval], %" #w "[old]\n" \
" cbnz %" #w "[tmp], 2f\n" \
" st" #rel "xr" #sz "\t%w[tmp], %" #w "[new], %[v]\n" \
@@ -199,19 +213,27 @@ __LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr, \
} \
__LL_SC_EXPORT(__cmpxchg_case_##name);
-__CMPXCHG_CASE(w, b, 1, , , )
-__CMPXCHG_CASE(w, h, 2, , , )
-__CMPXCHG_CASE(w, , 4, , , )
-__CMPXCHG_CASE( , , 8, , , )
-__CMPXCHG_CASE(w, b, mb_1, dmb ish, l, "memory")
-__CMPXCHG_CASE(w, h, mb_2, dmb ish, l, "memory")
-__CMPXCHG_CASE(w, , mb_4, dmb ish, l, "memory")
-__CMPXCHG_CASE( , , mb_8, dmb ish, l, "memory")
+__CMPXCHG_CASE(w, b, 1, , , , )
+__CMPXCHG_CASE(w, h, 2, , , , )
+__CMPXCHG_CASE(w, , 4, , , , )
+__CMPXCHG_CASE( , , 8, , , , )
+__CMPXCHG_CASE(w, b, acq_1, , a, , "memory")
+__CMPXCHG_CASE(w, h, acq_2, , a, , "memory")
+__CMPXCHG_CASE(w, , acq_4, , a, , "memory")
+__CMPXCHG_CASE( , , acq_8, , a, , "memory")
+__CMPXCHG_CASE(w, b, rel_1, , , l, "memory")
+__CMPXCHG_CASE(w, h, rel_2, , , l, "memory")
+__CMPXCHG_CASE(w, , rel_4, , , l, "memory")
+__CMPXCHG_CASE( , , rel_8, , , l, "memory")
+__CMPXCHG_CASE(w, b, mb_1, dmb ish, , l, "memory")
+__CMPXCHG_CASE(w, h, mb_2, dmb ish, , l, "memory")
+__CMPXCHG_CASE(w, , mb_4, dmb ish, , l, "memory")
+__CMPXCHG_CASE( , , mb_8, dmb ish, , l, "memory")
#undef __CMPXCHG_CASE
#define __CMPXCHG_DBL(name, mb, rel, cl) \
-__LL_SC_INLINE int \
+__LL_SC_INLINE long \
__LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1, \
unsigned long old2, \
unsigned long new1, \
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 55d740e..39c1d34 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -36,7 +36,7 @@ static inline void atomic_andnot(int i, atomic_t *v)
" stclr %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic_or(int i, atomic_t *v)
@@ -48,7 +48,7 @@ static inline void atomic_or(int i, atomic_t *v)
" stset %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic_xor(int i, atomic_t *v)
@@ -60,7 +60,7 @@ static inline void atomic_xor(int i, atomic_t *v)
" steor %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic_add(int i, atomic_t *v)
@@ -72,27 +72,35 @@ static inline void atomic_add(int i, atomic_t *v)
" stadd %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
-static inline int atomic_add_return(int i, atomic_t *v)
-{
- register int w0 asm ("w0") = i;
- register atomic_t *x1 asm ("x1") = v;
+#define ATOMIC_OP_ADD_RETURN(name, mb, cl...) \
+static inline int atomic_add_return##name(int i, atomic_t *v) \
+{ \
+ register int w0 asm ("w0") = i; \
+ register atomic_t *x1 asm ("x1") = v; \
+ \
+ asm volatile(ARM64_LSE_ATOMIC_INSN( \
+ /* LL/SC */ \
+ " nop\n" \
+ __LL_SC_ATOMIC(add_return##name), \
+ /* LSE atomics */ \
+ " ldadd" #mb " %w[i], w30, %[v]\n" \
+ " add %w[i], %w[i], w30") \
+ : [i] "+r" (w0), [v] "+Q" (v->counter) \
+ : "r" (x1) \
+ : __LL_SC_CLOBBERS, ##cl); \
+ \
+ return w0; \
+}
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC(add_return),
- /* LSE atomics */
- " ldaddal %w[i], w30, %[v]\n"
- " add %w[i], %w[i], w30")
- : [i] "+r" (w0), [v] "+Q" (v->counter)
- : "r" (x1)
- : "x30", "memory");
+ATOMIC_OP_ADD_RETURN(_relaxed, )
+ATOMIC_OP_ADD_RETURN(_acquire, a, "memory")
+ATOMIC_OP_ADD_RETURN(_release, l, "memory")
+ATOMIC_OP_ADD_RETURN( , al, "memory")
- return w0;
-}
+#undef ATOMIC_OP_ADD_RETURN
static inline void atomic_and(int i, atomic_t *v)
{
@@ -108,7 +116,7 @@ static inline void atomic_and(int i, atomic_t *v)
" stclr %w[i], %[v]")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic_sub(int i, atomic_t *v)
@@ -125,30 +133,37 @@ static inline void atomic_sub(int i, atomic_t *v)
" stadd %w[i], %[v]")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
- register int w0 asm ("w0") = i;
- register atomic_t *x1 asm ("x1") = v;
-
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC(sub_return)
- " nop",
- /* LSE atomics */
- " neg %w[i], %w[i]\n"
- " ldaddal %w[i], w30, %[v]\n"
- " add %w[i], %w[i], w30")
- : [i] "+r" (w0), [v] "+Q" (v->counter)
- : "r" (x1)
- : "x30", "memory");
-
- return w0;
+#define ATOMIC_OP_SUB_RETURN(name, mb, cl...) \
+static inline int atomic_sub_return##name(int i, atomic_t *v) \
+{ \
+ register int w0 asm ("w0") = i; \
+ register atomic_t *x1 asm ("x1") = v; \
+ \
+ asm volatile(ARM64_LSE_ATOMIC_INSN( \
+ /* LL/SC */ \
+ " nop\n" \
+ __LL_SC_ATOMIC(sub_return##name) \
+ " nop", \
+ /* LSE atomics */ \
+ " neg %w[i], %w[i]\n" \
+ " ldadd" #mb " %w[i], w30, %[v]\n" \
+ " add %w[i], %w[i], w30") \
+ : [i] "+r" (w0), [v] "+Q" (v->counter) \
+ : "r" (x1) \
+ : __LL_SC_CLOBBERS , ##cl); \
+ \
+ return w0; \
}
+ATOMIC_OP_SUB_RETURN(_relaxed, )
+ATOMIC_OP_SUB_RETURN(_acquire, a, "memory")
+ATOMIC_OP_SUB_RETURN(_release, l, "memory")
+ATOMIC_OP_SUB_RETURN( , al, "memory")
+
+#undef ATOMIC_OP_SUB_RETURN
#undef __LL_SC_ATOMIC
#define __LL_SC_ATOMIC64(op) __LL_SC_CALL(atomic64_##op)
@@ -162,7 +177,7 @@ static inline void atomic64_andnot(long i, atomic64_t *v)
" stclr %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic64_or(long i, atomic64_t *v)
@@ -174,7 +189,7 @@ static inline void atomic64_or(long i, atomic64_t *v)
" stset %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic64_xor(long i, atomic64_t *v)
@@ -186,7 +201,7 @@ static inline void atomic64_xor(long i, atomic64_t *v)
" steor %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic64_add(long i, atomic64_t *v)
@@ -198,27 +213,35 @@ static inline void atomic64_add(long i, atomic64_t *v)
" stadd %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
-static inline long atomic64_add_return(long i, atomic64_t *v)
-{
- register long x0 asm ("x0") = i;
- register atomic64_t *x1 asm ("x1") = v;
+#define ATOMIC64_OP_ADD_RETURN(name, mb, cl...) \
+static inline long atomic64_add_return##name(long i, atomic64_t *v) \
+{ \
+ register long x0 asm ("x0") = i; \
+ register atomic64_t *x1 asm ("x1") = v; \
+ \
+ asm volatile(ARM64_LSE_ATOMIC_INSN( \
+ /* LL/SC */ \
+ " nop\n" \
+ __LL_SC_ATOMIC64(add_return##name), \
+ /* LSE atomics */ \
+ " ldadd" #mb " %[i], x30, %[v]\n" \
+ " add %[i], %[i], x30") \
+ : [i] "+r" (x0), [v] "+Q" (v->counter) \
+ : "r" (x1) \
+ : __LL_SC_CLOBBERS, ##cl); \
+ \
+ return x0; \
+}
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC64(add_return),
- /* LSE atomics */
- " ldaddal %[i], x30, %[v]\n"
- " add %[i], %[i], x30")
- : [i] "+r" (x0), [v] "+Q" (v->counter)
- : "r" (x1)
- : "x30", "memory");
+ATOMIC64_OP_ADD_RETURN(_relaxed, )
+ATOMIC64_OP_ADD_RETURN(_acquire, a, "memory")
+ATOMIC64_OP_ADD_RETURN(_release, l, "memory")
+ATOMIC64_OP_ADD_RETURN( , al, "memory")
- return x0;
-}
+#undef ATOMIC64_OP_ADD_RETURN
static inline void atomic64_and(long i, atomic64_t *v)
{
@@ -234,7 +257,7 @@ static inline void atomic64_and(long i, atomic64_t *v)
" stclr %[i], %[v]")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
static inline void atomic64_sub(long i, atomic64_t *v)
@@ -251,29 +274,37 @@ static inline void atomic64_sub(long i, atomic64_t *v)
" stadd %[i], %[v]")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
- : "x30");
+ : __LL_SC_CLOBBERS);
}
-static inline long atomic64_sub_return(long i, atomic64_t *v)
-{
- register long x0 asm ("x0") = i;
- register atomic64_t *x1 asm ("x1") = v;
+#define ATOMIC64_OP_SUB_RETURN(name, mb, cl...) \
+static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
+{ \
+ register long x0 asm ("x0") = i; \
+ register atomic64_t *x1 asm ("x1") = v; \
+ \
+ asm volatile(ARM64_LSE_ATOMIC_INSN( \
+ /* LL/SC */ \
+ " nop\n" \
+ __LL_SC_ATOMIC64(sub_return##name) \
+ " nop", \
+ /* LSE atomics */ \
+ " neg %[i], %[i]\n" \
+ " ldadd" #mb " %[i], x30, %[v]\n" \
+ " add %[i], %[i], x30") \
+ : [i] "+r" (x0), [v] "+Q" (v->counter) \
+ : "r" (x1) \
+ : __LL_SC_CLOBBERS, ##cl); \
+ \
+ return x0; \
+}
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC64(sub_return)
- " nop",
- /* LSE atomics */
- " neg %[i], %[i]\n"
- " ldaddal %[i], x30, %[v]\n"
- " add %[i], %[i], x30")
- : [i] "+r" (x0), [v] "+Q" (v->counter)
- : "r" (x1)
- : "x30", "memory");
+ATOMIC64_OP_SUB_RETURN(_relaxed, )
+ATOMIC64_OP_SUB_RETURN(_acquire, a, "memory")
+ATOMIC64_OP_SUB_RETURN(_release, l, "memory")
+ATOMIC64_OP_SUB_RETURN( , al, "memory")
- return x0;
-}
+#undef ATOMIC64_OP_SUB_RETURN
static inline long atomic64_dec_if_positive(atomic64_t *v)
{
@@ -299,7 +330,7 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
"2:")
: [ret] "+&r" (x0), [v] "+Q" (v->counter)
:
- : "x30", "cc", "memory");
+ : __LL_SC_CLOBBERS, "cc", "memory");
return x0;
}
@@ -328,19 +359,27 @@ static inline unsigned long __cmpxchg_case_##name(volatile void *ptr, \
" mov %" #w "[ret], " #w "30") \
: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr) \
: [old] "r" (x1), [new] "r" (x2) \
- : "x30" , ##cl); \
+ : __LL_SC_CLOBBERS, ##cl); \
\
return x0; \
}
-__CMPXCHG_CASE(w, b, 1, )
-__CMPXCHG_CASE(w, h, 2, )
-__CMPXCHG_CASE(w, , 4, )
-__CMPXCHG_CASE(x, , 8, )
-__CMPXCHG_CASE(w, b, mb_1, al, "memory")
-__CMPXCHG_CASE(w, h, mb_2, al, "memory")
-__CMPXCHG_CASE(w, , mb_4, al, "memory")
-__CMPXCHG_CASE(x, , mb_8, al, "memory")
+__CMPXCHG_CASE(w, b, 1, )
+__CMPXCHG_CASE(w, h, 2, )
+__CMPXCHG_CASE(w, , 4, )
+__CMPXCHG_CASE(x, , 8, )
+__CMPXCHG_CASE(w, b, acq_1, a, "memory")
+__CMPXCHG_CASE(w, h, acq_2, a, "memory")
+__CMPXCHG_CASE(w, , acq_4, a, "memory")
+__CMPXCHG_CASE(x, , acq_8, a, "memory")
+__CMPXCHG_CASE(w, b, rel_1, l, "memory")
+__CMPXCHG_CASE(w, h, rel_2, l, "memory")
+__CMPXCHG_CASE(w, , rel_4, l, "memory")
+__CMPXCHG_CASE(x, , rel_8, l, "memory")
+__CMPXCHG_CASE(w, b, mb_1, al, "memory")
+__CMPXCHG_CASE(w, h, mb_2, al, "memory")
+__CMPXCHG_CASE(w, , mb_4, al, "memory")
+__CMPXCHG_CASE(x, , mb_8, al, "memory")
#undef __LL_SC_CMPXCHG
#undef __CMPXCHG_CASE
@@ -348,7 +387,7 @@ __CMPXCHG_CASE(x, , mb_8, al, "memory")
#define __LL_SC_CMPXCHG_DBL(op) __LL_SC_CALL(__cmpxchg_double##op)
#define __CMPXCHG_DBL(name, mb, cl...) \
-static inline int __cmpxchg_double##name(unsigned long old1, \
+static inline long __cmpxchg_double##name(unsigned long old1, \
unsigned long old2, \
unsigned long new1, \
unsigned long new2, \
@@ -377,7 +416,7 @@ static inline int __cmpxchg_double##name(unsigned long old1, \
[v] "+Q" (*(unsigned long *)ptr) \
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
- : "x30" , ##cl); \
+ : __LL_SC_CLOBBERS, ##cl); \
\
return x0; \
}
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 624f967..dae5c49 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -35,11 +35,11 @@
#define dma_rmb() dmb(oshld)
#define dma_wmb() dmb(oshst)
-#define smp_mb() dmb(ish)
-#define smp_rmb() dmb(ishld)
-#define smp_wmb() dmb(ishst)
+#define __smp_mb() dmb(ish)
+#define __smp_rmb() dmb(ishld)
+#define __smp_wmb() dmb(ishst)
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
switch (sizeof(*p)) { \
@@ -62,39 +62,36 @@ do { \
} \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
- typeof(*p) ___p1; \
+ union { typeof(*p) __val; char __c[1]; } __u; \
compiletime_assert_atomic_type(*p); \
switch (sizeof(*p)) { \
case 1: \
asm volatile ("ldarb %w0, %1" \
- : "=r" (___p1) : "Q" (*p) : "memory"); \
+ : "=r" (*(__u8 *)__u.__c) \
+ : "Q" (*p) : "memory"); \
break; \
case 2: \
asm volatile ("ldarh %w0, %1" \
- : "=r" (___p1) : "Q" (*p) : "memory"); \
+ : "=r" (*(__u16 *)__u.__c) \
+ : "Q" (*p) : "memory"); \
break; \
case 4: \
asm volatile ("ldar %w0, %1" \
- : "=r" (___p1) : "Q" (*p) : "memory"); \
+ : "=r" (*(__u32 *)__u.__c) \
+ : "Q" (*p) : "memory"); \
break; \
case 8: \
asm volatile ("ldar %0, %1" \
- : "=r" (___p1) : "Q" (*p) : "memory"); \
+ : "=r" (*(__u64 *)__u.__c) \
+ : "Q" (*p) : "memory"); \
break; \
} \
- ___p1; \
+ __u.__val; \
})
-#define read_barrier_depends() do { } while(0)
-#define smp_read_barrier_depends() do { } while(0)
-
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
-#define nop() asm volatile("nop");
-
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() smp_mb()
+#include <asm-generic/barrier.h>
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h
index 81151b6..ebf2481 100644
--- a/arch/arm64/include/asm/boot.h
+++ b/arch/arm64/include/asm/boot.h
@@ -11,4 +11,10 @@
#define MIN_FDT_ALIGN 8
#define MAX_FDT_SIZE SZ_2M
+/*
+ * arm64 requires the kernel image to placed
+ * TEXT_OFFSET bytes beyond a 2 MB aligned base
+ */
+#define MIN_KIMG_ALIGN SZ_2M
+
#endif
diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h
new file mode 100644
index 0000000..ed693c5
--- /dev/null
+++ b/arch/arm64/include/asm/brk-imm.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 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_BRK_IMM_H
+#define __ASM_BRK_IMM_H
+
+/*
+ * #imm16 values used for BRK instruction generation
+ * Allowed values for kgdb are 0x400 - 0x7ff
+ * 0x100: for triggering a fault on purpose (reserved)
+ * 0x400: for dynamic BRK instruction
+ * 0x401: for compile time BRK instruction
+ * 0x800: kernel-mode BUG() and WARN() traps
+ */
+#define FAULT_BRK_IMM 0x100
+#define KGDB_DYN_DBG_BRK_IMM 0x400
+#define KGDB_COMPILED_DBG_BRK_IMM 0x401
+#define BUG_BRK_IMM 0x800
+
+#endif
diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
index 4a748ce..561190d 100644
--- a/arch/arm64/include/asm/bug.h
+++ b/arch/arm64/include/asm/bug.h
@@ -18,7 +18,7 @@
#ifndef _ARCH_ARM64_ASM_BUG_H
#define _ARCH_ARM64_ASM_BUG_H
-#include <asm/debug-monitors.h>
+#include <asm/brk-imm.h>
#ifdef CONFIG_GENERIC_BUG
#define HAVE_ARCH_BUG
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
index bde4499..5082b30 100644
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -18,7 +18,7 @@
#include <asm/cachetype.h>
-#define L1_CACHE_SHIFT 6
+#define L1_CACHE_SHIFT 7
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index c75b8d0..22dda61 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -68,6 +68,7 @@
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
extern void flush_icache_range(unsigned long start, unsigned long end);
extern void __flush_dcache_area(void *addr, size_t len);
+extern void __clean_dcache_area_pou(void *addr, size_t len);
extern long __flush_cache_user_range(unsigned long start, unsigned long end);
static inline void flush_cache_mm(struct mm_struct *mm)
@@ -115,6 +116,13 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *);
+static inline void __local_flush_icache_all(void)
+{
+ asm("ic iallu");
+ dsb(nsh);
+ isb();
+}
+
static inline void __flush_icache_all(void)
{
asm("ic ialluis");
@@ -148,8 +156,4 @@ 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);
-#endif
-
#endif
diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
index da2fc9e..f558869 100644
--- a/arch/arm64/include/asm/cachetype.h
+++ b/arch/arm64/include/asm/cachetype.h
@@ -34,8 +34,8 @@
#define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK)
-#define ICACHEF_ALIASING BIT(0)
-#define ICACHEF_AIVIVT BIT(1)
+#define ICACHEF_ALIASING 0
+#define ICACHEF_AIVIVT 1
extern unsigned long __icache_flags;
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index 899e9f1..510c7b4 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -19,160 +19,156 @@
#define __ASM_CMPXCHG_H
#include <linux/bug.h>
-#include <linux/mmdebug.h>
#include <asm/atomic.h>
#include <asm/barrier.h>
#include <asm/lse.h>
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
-{
- unsigned long ret, tmp;
-
- switch (size) {
- case 1:
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " prfm pstl1strm, %2\n"
- "1: ldxrb %w0, %2\n"
- " stlxrb %w1, %w3, %2\n"
- " cbnz %w1, 1b\n"
- " dmb ish",
- /* LSE atomics */
- " nop\n"
- " nop\n"
- " swpalb %w3, %w0, %2\n"
- " nop\n"
- " nop")
- : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr)
- : "r" (x)
- : "memory");
- break;
- case 2:
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " prfm pstl1strm, %2\n"
- "1: ldxrh %w0, %2\n"
- " stlxrh %w1, %w3, %2\n"
- " cbnz %w1, 1b\n"
- " dmb ish",
- /* LSE atomics */
- " nop\n"
- " nop\n"
- " swpalh %w3, %w0, %2\n"
- " nop\n"
- " nop")
- : "=&r" (ret), "=&r" (tmp), "+Q" (*(u16 *)ptr)
- : "r" (x)
- : "memory");
- break;
- case 4:
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " prfm pstl1strm, %2\n"
- "1: ldxr %w0, %2\n"
- " stlxr %w1, %w3, %2\n"
- " cbnz %w1, 1b\n"
- " dmb ish",
- /* LSE atomics */
- " nop\n"
- " nop\n"
- " swpal %w3, %w0, %2\n"
- " nop\n"
- " nop")
- : "=&r" (ret), "=&r" (tmp), "+Q" (*(u32 *)ptr)
- : "r" (x)
- : "memory");
- break;
- case 8:
- asm volatile(ARM64_LSE_ATOMIC_INSN(
- /* LL/SC */
- " prfm pstl1strm, %2\n"
- "1: ldxr %0, %2\n"
- " stlxr %w1, %3, %2\n"
- " cbnz %w1, 1b\n"
- " dmb ish",
- /* LSE atomics */
- " nop\n"
- " nop\n"
- " swpal %3, %0, %2\n"
- " nop\n"
- " nop")
- : "=&r" (ret), "=&r" (tmp), "+Q" (*(u64 *)ptr)
- : "r" (x)
- : "memory");
- break;
- default:
- BUILD_BUG();
- }
-
- return ret;
+/*
+ * We need separate acquire parameters for ll/sc and lse, since the full
+ * barrier case is generated as release+dmb for the former and
+ * acquire+release for the latter.
+ */
+#define __XCHG_CASE(w, sz, name, mb, nop_lse, acq, acq_lse, rel, cl) \
+static inline unsigned long __xchg_case_##name(unsigned long x, \
+ volatile void *ptr) \
+{ \
+ unsigned long ret, tmp; \
+ \
+ asm volatile(ARM64_LSE_ATOMIC_INSN( \
+ /* LL/SC */ \
+ " prfm pstl1strm, %2\n" \
+ "1: ld" #acq "xr" #sz "\t%" #w "0, %2\n" \
+ " st" #rel "xr" #sz "\t%w1, %" #w "3, %2\n" \
+ " cbnz %w1, 1b\n" \
+ " " #mb, \
+ /* LSE atomics */ \
+ " nop\n" \
+ " nop\n" \
+ " swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
+ " nop\n" \
+ " " #nop_lse) \
+ : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) \
+ : "r" (x) \
+ : cl); \
+ \
+ return ret; \
}
-#define xchg(ptr,x) \
-({ \
- __typeof__(*(ptr)) __ret; \
- __ret = (__typeof__(*(ptr))) \
- __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))); \
- __ret; \
+__XCHG_CASE(w, b, 1, , , , , , )
+__XCHG_CASE(w, h, 2, , , , , , )
+__XCHG_CASE(w, , 4, , , , , , )
+__XCHG_CASE( , , 8, , , , , , )
+__XCHG_CASE(w, b, acq_1, , , a, a, , "memory")
+__XCHG_CASE(w, h, acq_2, , , a, a, , "memory")
+__XCHG_CASE(w, , acq_4, , , a, a, , "memory")
+__XCHG_CASE( , , acq_8, , , a, a, , "memory")
+__XCHG_CASE(w, b, rel_1, , , , , l, "memory")
+__XCHG_CASE(w, h, rel_2, , , , , l, "memory")
+__XCHG_CASE(w, , rel_4, , , , , l, "memory")
+__XCHG_CASE( , , rel_8, , , , , l, "memory")
+__XCHG_CASE(w, b, mb_1, dmb ish, nop, , a, l, "memory")
+__XCHG_CASE(w, h, mb_2, dmb ish, nop, , a, l, "memory")
+__XCHG_CASE(w, , mb_4, dmb ish, nop, , a, l, "memory")
+__XCHG_CASE( , , mb_8, dmb ish, nop, , a, l, "memory")
+
+#undef __XCHG_CASE
+
+#define __XCHG_GEN(sfx) \
+static inline unsigned long __xchg##sfx(unsigned long x, \
+ volatile void *ptr, \
+ int size) \
+{ \
+ switch (size) { \
+ case 1: \
+ return __xchg_case##sfx##_1(x, ptr); \
+ case 2: \
+ return __xchg_case##sfx##_2(x, ptr); \
+ case 4: \
+ return __xchg_case##sfx##_4(x, ptr); \
+ case 8: \
+ return __xchg_case##sfx##_8(x, ptr); \
+ default: \
+ BUILD_BUG(); \
+ } \
+ \
+ unreachable(); \
+}
+
+__XCHG_GEN()
+__XCHG_GEN(_acq)
+__XCHG_GEN(_rel)
+__XCHG_GEN(_mb)
+
+#undef __XCHG_GEN
+
+#define __xchg_wrapper(sfx, ptr, x) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ __ret = (__typeof__(*(ptr))) \
+ __xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \
+ __ret; \
})
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return __cmpxchg_case_1(ptr, (u8)old, new);
- case 2:
- return __cmpxchg_case_2(ptr, (u16)old, new);
- case 4:
- return __cmpxchg_case_4(ptr, old, new);
- case 8:
- return __cmpxchg_case_8(ptr, old, new);
- default:
- BUILD_BUG();
- }
-
- unreachable();
+/* xchg */
+#define xchg_relaxed(...) __xchg_wrapper( , __VA_ARGS__)
+#define xchg_acquire(...) __xchg_wrapper(_acq, __VA_ARGS__)
+#define xchg_release(...) __xchg_wrapper(_rel, __VA_ARGS__)
+#define xchg(...) __xchg_wrapper( _mb, __VA_ARGS__)
+
+#define __CMPXCHG_GEN(sfx) \
+static inline unsigned long __cmpxchg##sfx(volatile void *ptr, \
+ unsigned long old, \
+ unsigned long new, \
+ int size) \
+{ \
+ switch (size) { \
+ case 1: \
+ return __cmpxchg_case##sfx##_1(ptr, (u8)old, new); \
+ case 2: \
+ return __cmpxchg_case##sfx##_2(ptr, (u16)old, new); \
+ case 4: \
+ return __cmpxchg_case##sfx##_4(ptr, old, new); \
+ case 8: \
+ return __cmpxchg_case##sfx##_8(ptr, old, new); \
+ default: \
+ BUILD_BUG(); \
+ } \
+ \
+ unreachable(); \
}
-static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return __cmpxchg_case_mb_1(ptr, (u8)old, new);
- case 2:
- return __cmpxchg_case_mb_2(ptr, (u16)old, new);
- case 4:
- return __cmpxchg_case_mb_4(ptr, old, new);
- case 8:
- return __cmpxchg_case_mb_8(ptr, old, new);
- default:
- BUILD_BUG();
- }
-
- unreachable();
-}
+__CMPXCHG_GEN()
+__CMPXCHG_GEN(_acq)
+__CMPXCHG_GEN(_rel)
+__CMPXCHG_GEN(_mb)
-#define cmpxchg(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- __ret = (__typeof__(*(ptr))) \
- __cmpxchg_mb((ptr), (unsigned long)(o), (unsigned long)(n), \
- sizeof(*(ptr))); \
- __ret; \
-})
+#undef __CMPXCHG_GEN
-#define cmpxchg_local(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- __ret = (__typeof__(*(ptr))) \
- __cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))); \
- __ret; \
+#define __cmpxchg_wrapper(sfx, ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ __ret = (__typeof__(*(ptr))) \
+ __cmpxchg##sfx((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ __ret; \
})
+/* cmpxchg */
+#define cmpxchg_relaxed(...) __cmpxchg_wrapper( , __VA_ARGS__)
+#define cmpxchg_acquire(...) __cmpxchg_wrapper(_acq, __VA_ARGS__)
+#define cmpxchg_release(...) __cmpxchg_wrapper(_rel, __VA_ARGS__)
+#define cmpxchg(...) __cmpxchg_wrapper( _mb, __VA_ARGS__)
+#define cmpxchg_local cmpxchg_relaxed
+
+/* cmpxchg64 */
+#define cmpxchg64_relaxed cmpxchg_relaxed
+#define cmpxchg64_acquire cmpxchg_acquire
+#define cmpxchg64_release cmpxchg_release
+#define cmpxchg64 cmpxchg
+#define cmpxchg64_local cmpxchg_local
+
+/* cmpxchg_double */
#define system_has_cmpxchg_double() 1
#define __cmpxchg_double_check(ptr1, ptr2) \
@@ -202,6 +198,7 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
__ret; \
})
+/* this_cpu_cmpxchg */
#define _protect_cmpxchg_local(pcp, o, n) \
({ \
typeof(*raw_cpu_ptr(&(pcp))) __ret; \
@@ -227,9 +224,4 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
__ret; \
})
-#define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n))
-#define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n))
-
-#define cmpxchg64_relaxed(ptr,o,n) cmpxchg_local((ptr),(o),(n))
-
#endif /* __ASM_CMPXCHG_H */
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 7fbed69..eb8432b 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -23,7 +23,6 @@
*/
#include <linux/types.h>
#include <linux/sched.h>
-#include <linux/ptrace.h>
#define COMPAT_USER_HZ 100
#ifdef __AARCH64EB__
@@ -234,7 +233,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
return (u32)(unsigned long)uptr;
}
-#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
+#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
static inline void __user *arch_compat_alloc_user_space(long len)
{
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2..13a6103 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -36,6 +36,7 @@ struct cpuinfo_arm64 {
u64 reg_id_aa64isar1;
u64 reg_id_aa64mmfr0;
u64 reg_id_aa64mmfr1;
+ u64 reg_id_aa64mmfr2;
u64 reg_id_aa64pfr0;
u64 reg_id_aa64pfr1;
@@ -63,4 +64,8 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
void cpuinfo_store_cpu(void);
void __init cpuinfo_store_boot_cpu(void);
+void __init init_cpu_features(struct cpuinfo_arm64 *info);
+void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
+ struct cpuinfo_arm64 *boot);
+
#endif /* __ASM_CPU_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 1715707..b9b6494 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -10,6 +10,7 @@
#define __ASM_CPUFEATURE_H
#include <asm/hwcap.h>
+#include <asm/sysreg.h>
/*
* In the arm64 world (as in the ARM world), elf_hwcap is used both internally
@@ -27,18 +28,60 @@
#define ARM64_HAS_SYSREG_GIC_CPUIF 3
#define ARM64_HAS_PAN 4
#define ARM64_HAS_LSE_ATOMICS 5
+#define ARM64_WORKAROUND_CAVIUM_23154 6
+#define ARM64_WORKAROUND_834220 7
+#define ARM64_HAS_NO_HW_PREFETCH 8
+#define ARM64_HAS_UAO 9
+#define ARM64_ALT_PAN_NOT_UAO 10
+#define ARM64_HAS_VIRT_HOST_EXTN 11
+#define ARM64_WORKAROUND_CAVIUM_27456 12
-#define ARM64_NCAPS 6
+#define ARM64_NCAPS 13
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
+/* CPU feature register tracking */
+enum ftr_type {
+ FTR_EXACT, /* Use a predefined safe value */
+ FTR_LOWER_SAFE, /* Smaller value is safe */
+ FTR_HIGHER_SAFE,/* Bigger value is safe */
+};
+
+#define FTR_STRICT true /* SANITY check strict matching required */
+#define FTR_NONSTRICT false /* SANITY check ignored */
+
+#define FTR_SIGNED true /* Value should be treated as signed */
+#define FTR_UNSIGNED false /* Value should be treated as unsigned */
+
+struct arm64_ftr_bits {
+ bool sign; /* Value is signed ? */
+ bool strict; /* CPU Sanity check: strict matching required ? */
+ enum ftr_type type;
+ u8 shift;
+ u8 width;
+ s64 safe_val; /* safe value for discrete features */
+};
+
+/*
+ * @arm64_ftr_reg - Feature register
+ * @strict_mask Bits which should match across all CPUs for sanity.
+ * @sys_val Safe value across the CPUs (system view)
+ */
+struct arm64_ftr_reg {
+ u32 sys_id;
+ const char *name;
+ u64 strict_mask;
+ u64 sys_val;
+ struct arm64_ftr_bits *ftr_bits;
+};
+
struct arm64_cpu_capabilities {
const char *desc;
u16 capability;
bool (*matches)(const struct arm64_cpu_capabilities *);
- void (*enable)(void);
+ void (*enable)(void *); /* Called on all active CPUs */
union {
struct { /* To be used for erratum handling only */
u32 midr_model;
@@ -46,8 +89,12 @@ struct arm64_cpu_capabilities {
};
struct { /* Feature register checking */
- int field_pos;
- int min_field_value;
+ u32 sys_reg;
+ u8 field_pos;
+ u8 min_field_value;
+ u8 hwcap_type;
+ bool sign;
+ unsigned long hwcap;
};
};
};
@@ -75,19 +122,73 @@ static inline void cpus_set_cap(unsigned int num)
__set_bit(num, cpu_hwcaps);
}
-static inline int __attribute_const__ cpuid_feature_extract_field(u64 features,
- int field)
+static inline int __attribute_const__
+cpuid_feature_extract_signed_field_width(u64 features, int field, int width)
{
- return (s64)(features << (64 - 4 - field)) >> (64 - 4);
+ return (s64)(features << (64 - width - field)) >> (64 - width);
}
+static inline int __attribute_const__
+cpuid_feature_extract_signed_field(u64 features, int field)
+{
+ return cpuid_feature_extract_signed_field_width(features, field, 4);
+}
+
+static inline unsigned int __attribute_const__
+cpuid_feature_extract_unsigned_field_width(u64 features, int field, int width)
+{
+ return (u64)(features << (64 - width - field)) >> (64 - width);
+}
-void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
+static inline unsigned int __attribute_const__
+cpuid_feature_extract_unsigned_field(u64 features, int field)
+{
+ return cpuid_feature_extract_unsigned_field_width(features, field, 4);
+}
+
+static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
+{
+ return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
+}
+
+static inline int __attribute_const__
+cpuid_feature_extract_field(u64 features, int field, bool sign)
+{
+ return (sign) ?
+ cpuid_feature_extract_signed_field(features, field) :
+ cpuid_feature_extract_unsigned_field(features, field);
+}
+
+static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val)
+{
+ return (s64)cpuid_feature_extract_field(val, ftrp->shift, ftrp->sign);
+}
+
+static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
+{
+ return cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_BIGENDEL_SHIFT) == 0x1 ||
+ cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
+}
+
+void __init setup_cpu_features(void);
+
+void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
const char *info);
void check_local_cpu_errata(void);
-void check_local_cpu_features(void);
-bool cpu_supports_mixed_endian_el0(void);
-bool system_supports_mixed_endian_el0(void);
+
+void verify_local_cpu_capabilities(void);
+
+u64 read_system_reg(u32 id);
+
+static inline bool cpu_supports_mixed_endian_el0(void)
+{
+ return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}
+
+static inline bool system_supports_mixed_endian_el0(void)
+{
+ return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
+}
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ee6403d..f2309a2 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -32,12 +32,6 @@
#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK)
-#define read_cpuid(reg) ({ \
- u64 __val; \
- asm("mrs %0, " #reg : "=r" (__val)); \
- __val; \
-})
-
#define MIDR_REVISION_MASK 0xf
#define MIDR_REVISION(midr) ((midr) & MIDR_REVISION_MASK)
#define MIDR_PARTNUM_SHIFT 4
@@ -57,32 +51,49 @@
#define MIDR_IMPLEMENTOR(midr) \
(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
-#define MIDR_CPU_PART(imp, partnum) \
+#define MIDR_CPU_MODEL(imp, partnum) \
(((imp) << MIDR_IMPLEMENTOR_SHIFT) | \
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
((partnum) << MIDR_PARTNUM_SHIFT))
-#define ARM_CPU_IMP_ARM 0x41
-#define ARM_CPU_IMP_APM 0x50
+#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
+ MIDR_ARCHITECTURE_MASK)
-#define ARM_CPU_PART_AEM_V8 0xD0F
-#define ARM_CPU_PART_FOUNDATION 0xD00
-#define ARM_CPU_PART_CORTEX_A57 0xD07
-#define ARM_CPU_PART_CORTEX_A53 0xD03
+#define MIDR_IS_CPU_MODEL_RANGE(midr, model, rv_min, rv_max) \
+({ \
+ u32 _model = (midr) & MIDR_CPU_MODEL_MASK; \
+ u32 rv = (midr) & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK); \
+ \
+ _model == (model) && rv >= (rv_min) && rv <= (rv_max); \
+ })
-#define APM_CPU_PART_POTENZA 0x000
+#define ARM_CPU_IMP_ARM 0x41
+#define ARM_CPU_IMP_APM 0x50
+#define ARM_CPU_IMP_CAVIUM 0x43
-#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
-#define ID_AA64MMFR0_BIGENDEL0_MASK (0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
-#define ID_AA64MMFR0_BIGENDEL0(mmfr0) \
- (((mmfr0) & ID_AA64MMFR0_BIGENDEL0_MASK) >> ID_AA64MMFR0_BIGENDEL0_SHIFT)
-#define ID_AA64MMFR0_BIGEND_SHIFT 8
-#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
-#define ID_AA64MMFR0_BIGEND(mmfr0) \
- (((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)
+#define ARM_CPU_PART_AEM_V8 0xD0F
+#define ARM_CPU_PART_FOUNDATION 0xD00
+#define ARM_CPU_PART_CORTEX_A57 0xD07
+#define ARM_CPU_PART_CORTEX_A53 0xD03
+
+#define APM_CPU_PART_POTENZA 0x000
+
+#define CAVIUM_CPU_PART_THUNDERX 0x0A1
+
+#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#ifndef __ASSEMBLY__
+#include <asm/sysreg.h>
+
+#define read_cpuid(reg) ({ \
+ u64 __val; \
+ asm("mrs_s %0, " __stringify(SYS_ ## reg) : "=r" (__val)); \
+ __val; \
+})
+
/*
* 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
@@ -112,12 +123,6 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
{
return read_cpuid(CTR_EL0);
}
-
-static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
-{
- return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) ||
- (ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1);
-}
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
new file mode 100644
index 0000000..65e0190
--- /dev/null
+++ b/arch/arm64/include/asm/dcc.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2014-2015 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.
+ *
+ * A call to __dcc_getchar() or __dcc_putchar() is typically followed by
+ * a call to __dcc_getstatus(). We want to make sure that the CPU does
+ * not speculative read the DCC status before executing the read or write
+ * instruction. That's what the ISBs are for.
+ *
+ * The 'volatile' ensures that the compiler does not cache the status bits,
+ * and instead reads the DCC register every time.
+ */
+#ifndef __ASM_DCC_H
+#define __ASM_DCC_H
+
+#include <asm/barrier.h>
+
+static inline u32 __dcc_getstatus(void)
+{
+ u32 ret;
+
+ asm volatile("mrs %0, mdccsr_el0" : "=r" (ret));
+
+ return ret;
+}
+
+static inline char __dcc_getchar(void)
+{
+ char c;
+
+ asm volatile("mrs %0, dbgdtrrx_el0" : "=r" (c));
+ isb();
+
+ return c;
+}
+
+static inline void __dcc_putchar(char c)
+{
+ /*
+ * The typecast is to make absolutely certain that 'c' is
+ * zero-extended.
+ */
+ asm volatile("msr dbgdtrtx_el0, %0"
+ : : "r" ((unsigned long)(unsigned char)c));
+ isb();
+}
+
+#endif
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 279c85b5..2fcb9b7 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -20,6 +20,7 @@
#include <linux/errno.h>
#include <linux/types.h>
+#include <asm/brk-imm.h>
#include <asm/esr.h>
#include <asm/insn.h>
#include <asm/ptrace.h>
@@ -47,19 +48,6 @@
#define BREAK_INSTR_SIZE AARCH64_INSN_SIZE
/*
- * #imm16 values used for BRK instruction generation
- * Allowed values for kgbd are 0x400 - 0x7ff
- * 0x100: for triggering a fault on purpose (reserved)
- * 0x400: for dynamic BRK instruction
- * 0x401: for compile time BRK instruction
- * 0x800: kernel-mode BUG() and WARN() traps
- */
-#define FAULT_BRK_IMM 0x100
-#define KGDB_DYN_DBG_BRK_IMM 0x400
-#define KGDB_COMPILED_DBG_BRK_IMM 0x401
-#define BUG_BRK_IMM 0x800
-
-/*
* BRK instruction encoding
* The #imm16 value should be placed at bits[20:5] within BRK ins
*/
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index cfdb34b..ba437f0 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -18,7 +18,6 @@
#ifdef __KERNEL__
-#include <linux/acpi.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
@@ -26,22 +25,16 @@
#include <asm/xen/hypervisor.h>
#define DMA_ERROR_CODE (~(dma_addr_t)0)
-extern struct dma_map_ops *dma_ops;
extern struct dma_map_ops dummy_dma_ops;
static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
{
- if (unlikely(!dev))
- return dma_ops;
- else if (dev->archdata.dma_ops)
+ if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
- else if (acpi_disabled)
- return dma_ops;
/*
- * When ACPI is enabled, if arch_set_dma_ops is not called,
- * we will disable device DMA capability by setting it
- * to dummy_dma_ops.
+ * We expect no ISA devices, and all other DMA masters are expected to
+ * have someone call arch_setup_dma_ops at device creation time.
*/
return &dummy_dma_ops;
}
@@ -54,16 +47,15 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return __generic_dma_ops(dev);
}
-static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
- struct iommu_ops *iommu, bool coherent)
-{
- if (!acpi_disabled && !dev->archdata.dma_ops)
- dev->archdata.dma_ops = dma_ops;
-
- dev->archdata.dma_coherent = coherent;
-}
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu, bool coherent);
#define arch_setup_dma_ops arch_setup_dma_ops
+#ifdef CONFIG_IOMMU_DMA
+void arch_teardown_dma_ops(struct device *dev);
+#define arch_teardown_dma_ops arch_teardown_dma_ops
+#endif
+
/* do not use this function in a driver */
static inline bool is_device_dma_coherent(struct device *dev)
{
@@ -72,8 +64,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
return dev->archdata.dma_coherent;
}
-#include <asm-generic/dma-mapping-common.h>
-
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return (dma_addr_t)paddr;
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index ef57220..8e88a69 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -2,7 +2,9 @@
#define _ASM_EFI_H
#include <asm/io.h>
+#include <asm/mmu_context.h>
#include <asm/neon.h>
+#include <asm/tlbflush.h>
#ifdef CONFIG_EFI
extern void efi_init(void);
@@ -10,6 +12,8 @@ extern void efi_init(void);
#define efi_init()
#endif
+int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
+
#define efi_call_virt(f, ...) \
({ \
efi_##f##_t *__f; \
@@ -63,6 +67,11 @@ extern void efi_init(void);
* Services are enabled and the EFI_RUNTIME_SERVICES bit set.
*/
+static inline void efi_set_pgd(struct mm_struct *mm)
+{
+ switch_mm(NULL, mm, NULL);
+}
+
void efi_virtmap_load(void);
void efi_virtmap_unload(void);
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..24ed037 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -24,15 +24,6 @@
#include <asm/ptrace.h>
#include <asm/user.h>
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t))
-#define ELF_CORE_COPY_REGS(dest, regs) \
- *(struct user_pt_regs *)&(dest) = (regs)->user_regs;
-
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-typedef struct user_fpsimd_state elf_fpregset_t;
-
/*
* AArch64 static relocation types.
*/
@@ -86,6 +77,8 @@ typedef struct user_fpsimd_state elf_fpregset_t;
#define R_AARCH64_MOVW_PREL_G2_NC 292
#define R_AARCH64_MOVW_PREL_G3 293
+#define R_AARCH64_RELATIVE 1027
+
/*
* These are used to set parameters in the core dumps.
*/
@@ -127,6 +120,17 @@ typedef struct user_fpsimd_state elf_fpregset_t;
*/
#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
+#ifndef __ASSEMBLY__
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t))
+#define ELF_CORE_COPY_REGS(dest, regs) \
+ *(struct user_pt_regs *)&(dest) = (regs)->user_regs;
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+typedef struct user_fpsimd_state elf_fpregset_t;
+
/*
* 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
@@ -186,4 +190,6 @@ extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
#endif /* CONFIG_COMPAT */
+#endif /* !__ASSEMBLY__ */
+
#endif
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 8b9884c..caf86be 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -17,8 +17,10 @@
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
+#include <linux/sizes.h>
#include <asm/boot.h>
#include <asm/page.h>
+#include <asm/pgtable-prot.h>
/*
* Here we define all the compile-time 'special' virtual
@@ -55,16 +57,22 @@ enum fixed_addresses {
* Temporary boot-time mappings, used by early_ioremap(),
* before ioremap() is functional.
*/
-#ifdef CONFIG_ARM64_64K_PAGES
-#define NR_FIX_BTMAPS 4
-#else
-#define NR_FIX_BTMAPS 64
-#endif
+#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
#define FIX_BTMAPS_SLOTS 7
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
+
+ /*
+ * Used for kernel page table creation, so unmapped memory may be used
+ * for tables.
+ */
+ FIX_PTE,
+ FIX_PMD,
+ FIX_PUD,
+ FIX_PGD,
+
__end_of_fixed_addresses
};
diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index c5534fa..caa955f 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -28,6 +28,8 @@ struct dyn_arch_ftrace {
extern unsigned long ftrace_graph_call;
+extern void return_to_handler(void);
+
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
/*
@@ -46,7 +48,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
* See kernel/trace/trace_syscalls.c
*
* x86 code says:
- * If the user realy wants these, then they should use the
+ * If the user really wants these, then they should use the
* raw syscall tracepoints with filtering.
*/
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
index 007a69f..f2585cd 100644
--- a/arch/arm64/include/asm/futex.h
+++ b/arch/arm64/include/asm/futex.h
@@ -42,10 +42,8 @@
"4: mov %w0, %w5\n" \
" b 3b\n" \
" .popsection\n" \
-" .pushsection __ex_table,\"a\"\n" \
-" .align 3\n" \
-" .quad 1b, 4b, 2b, 4b\n" \
-" .popsection\n" \
+ _ASM_EXTABLE(1b, 4b) \
+ _ASM_EXTABLE(2b, 4b) \
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
: "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
@@ -121,6 +119,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
return -EFAULT;
asm volatile("// futex_atomic_cmpxchg_inatomic\n"
+ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
" prfm pstl1strm, %2\n"
"1: ldxr %w1, %2\n"
" sub %w3, %w1, %w4\n"
@@ -133,10 +132,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
"4: mov %w0, %w6\n"
" b 3b\n"
" .popsection\n"
-" .pushsection __ex_table,\"a\"\n"
-" .align 3\n"
-" .quad 1b, 4b, 2b, 4b\n"
-" .popsection\n"
+ _ASM_EXTABLE(1b, 4b)
+ _ASM_EXTABLE(2b, 4b)
+ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
: "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
: "r" (oldval), "r" (newval), "Ir" (-EFAULT)
: "memory");
diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index a57601f..8740297 100644
--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -20,7 +20,7 @@
#include <linux/threads.h>
#include <asm/irq.h>
-#define NR_IPI 5
+#define NR_IPI 6
typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index bb4052e..bbc1e35 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -26,36 +26,7 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
return *ptep;
}
-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);
-}
static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
unsigned long addr, unsigned long end,
@@ -97,4 +68,19 @@ static inline void arch_clear_hugepage_flags(struct page *page)
clear_bit(PG_dcache_clean, &page->flags);
}
+extern pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
+ struct page *page, int writable);
+#define arch_make_huge_pte arch_make_huge_pte
+extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
+extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty);
+extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep);
+extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep);
+extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep);
+
#endif /* __ASM_HUGETLB_H */
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 4c47cb2..115ea2a 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -17,6 +17,8 @@
#define __ASM_HW_BREAKPOINT_H
#include <asm/cputype.h>
+#include <asm/cpufeature.h>
+#include <asm/virt.h>
#ifdef __KERNEL__
@@ -34,10 +36,21 @@ struct arch_hw_breakpoint {
struct arch_hw_breakpoint_ctrl ctrl;
};
+/* Privilege Levels */
+#define AARCH64_BREAKPOINT_EL1 1
+#define AARCH64_BREAKPOINT_EL0 2
+
+#define DBG_HMC_HYP (1 << 13)
+
static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
{
- return (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
+ u32 val = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
ctrl.enabled;
+
+ if (is_kernel_in_hyp_mode() && ctrl.privilege == AARCH64_BREAKPOINT_EL1)
+ val |= DBG_HMC_HYP;
+
+ return val;
}
static inline void decode_ctrl_reg(u32 reg,
@@ -60,10 +73,6 @@ static inline void decode_ctrl_reg(u32 reg,
#define ARM_BREAKPOINT_STORE 2
#define AARCH64_ESR_ACCESS_MASK (1 << 6)
-/* Privilege Levels */
-#define AARCH64_BREAKPOINT_EL1 1
-#define AARCH64_BREAKPOINT_EL0 2
-
/* Lengths */
#define ARM_BREAKPOINT_LEN_1 0x1
#define ARM_BREAKPOINT_LEN_2 0x3
@@ -137,13 +146,19 @@ extern struct pmu perf_ops_bp;
/* Determine number of BRP registers available. */
static inline int get_num_brps(void)
{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+ u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
+ return 1 +
+ cpuid_feature_extract_unsigned_field(dfr0,
+ ID_AA64DFR0_BRPS_SHIFT);
}
/* Determine number of WRP registers available. */
static inline int get_num_wrps(void)
{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+ u64 dfr0 = read_system_reg(SYS_ID_AA64DFR0_EL1);
+ return 1 +
+ cpuid_feature_extract_unsigned_field(dfr0,
+ ID_AA64DFR0_WRPS_SHIFT);
}
#endif /* __KERNEL__ */
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 0ad7351..400b80b 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -52,6 +52,14 @@
extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
#endif
+enum {
+ CAP_HWCAP = 1,
+#ifdef CONFIG_COMPAT
+ CAP_COMPAT_HWCAP,
+ CAP_COMPAT_HWCAP2,
+#endif
+};
+
extern unsigned long elf_hwcap;
#endif
#endif
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index bbb251b..b77197d 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -1,24 +1,60 @@
#ifndef __ASM_IRQ_H
#define __ASM_IRQ_H
-#include <linux/irqchip/arm-gic-acpi.h>
+#define IRQ_STACK_SIZE THREAD_SIZE
+#define IRQ_STACK_START_SP THREAD_START_SP
+
+#ifndef __ASSEMBLER__
+
+#include <linux/percpu.h>
#include <asm-generic/irq.h>
+#include <asm/thread_info.h>
struct pt_regs;
-extern void migrate_irqs(void);
+DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
+
+/*
+ * The highest address on the stack, and the first to be used. Used to
+ * find the dummy-stack frame put down by el?_irq() in entry.S, which
+ * is structured as follows:
+ *
+ * ------------
+ * | | <- irq_stack_ptr
+ * top ------------
+ * | x19 | <- irq_stack_ptr - 0x08
+ * ------------
+ * | x29 | <- irq_stack_ptr - 0x10
+ * ------------
+ *
+ * where x19 holds a copy of the task stack pointer where the struct pt_regs
+ * from kernel_entry can be found.
+ *
+ */
+#define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP)
+
+/*
+ * The offset from irq_stack_ptr where entry.S will store the original
+ * stack pointer. Used by unwind_frame() and dump_backtrace().
+ */
+#define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08)))
+
extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
-static inline void acpi_irq_init(void)
+static inline int nr_legacy_irqs(void)
{
- /*
- * Hardcode ACPI IRQ chip initialization to GICv2 for now.
- * Proper irqchip infrastructure will be implemented along with
- * incoming GICv2m|GICv3|ITS bits.
- */
- acpi_gic_init();
+ return 0;
+}
+
+static inline bool on_irq_stack(unsigned long sp, int cpu)
+{
+ /* variable names the same as kernel/stacktrace.c */
+ unsigned long low = (unsigned long)per_cpu(irq_stack, cpu);
+ unsigned long high = low + IRQ_STACK_START_SP;
+
+ return (low <= sp && sp <= high);
}
-#define acpi_irq_init acpi_irq_init
+#endif /* !__ASSEMBLER__ */
#endif
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
new file mode 100644
index 0000000..71ad0f9
--- /dev/null
+++ b/arch/arm64/include/asm/kasan.h
@@ -0,0 +1,41 @@
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_KASAN
+
+#include <linux/linkage.h>
+#include <asm/memory.h>
+#include <asm/pgtable-types.h>
+
+/*
+ * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
+ * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
+ */
+#define KASAN_SHADOW_START (VA_START)
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
+
+/*
+ * This value is used to map an address to the corresponding shadow
+ * address by the following formula:
+ * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *
+ * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
+ * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
+ * should satisfy the following equation:
+ * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ */
+#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+
+void kasan_init(void);
+void kasan_copy_shadow(pgd_t *pgdir);
+asmlinkage void kasan_early_init(void);
+
+#else
+static inline void kasan_init(void) { }
+static inline void kasan_copy_shadow(pgd_t *pgdir) { }
+#endif
+
+#endif
+#endif
diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
new file mode 100644
index 0000000..5c6375d
--- /dev/null
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -0,0 +1,95 @@
+/*
+ * Kernel page table mapping
+ *
+ * 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_KERNEL_PGTABLE_H
+#define __ASM_KERNEL_PGTABLE_H
+
+
+/*
+ * The linear mapping and the start of memory are both 2M aligned (per
+ * the arm64 booting.txt requirements). Hence we can use section mapping
+ * with 4K (section size = 2M) but not with 16K (section size = 32M) or
+ * 64K (section size = 512M).
+ */
+#ifdef CONFIG_ARM64_4K_PAGES
+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
+#else
+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
+#endif
+
+/*
+ * The idmap and swapper page tables need some space reserved in the kernel
+ * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
+ * map the kernel. With the 64K page configuration, swapper and idmap need to
+ * map to pte level. The swapper also maps the FDT (see __create_page_tables
+ * for more information). Note that the number of ID map translation levels
+ * could be increased on the fly if system RAM is out of reach for the default
+ * VA range, so pages required to map highest possible PA are reserved in all
+ * cases.
+ */
+#if ARM64_SWAPPER_USES_SECTION_MAPS
+#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1)
+#define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
+#else
+#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS)
+#define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
+#endif
+
+#define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
+#define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
+
+/* Initial memory map size */
+#if ARM64_SWAPPER_USES_SECTION_MAPS
+#define SWAPPER_BLOCK_SHIFT SECTION_SHIFT
+#define SWAPPER_BLOCK_SIZE SECTION_SIZE
+#define SWAPPER_TABLE_SHIFT PUD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT PMD_SHIFT
+#endif
+
+/* The size of the initial kernel direct mapping */
+#define SWAPPER_INIT_MAP_SIZE (_AC(1, UL) << SWAPPER_TABLE_SHIFT)
+
+/*
+ * Initial memory map attributes.
+ */
+#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
+#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
+
+#if ARM64_SWAPPER_USES_SECTION_MAPS
+#define SWAPPER_MM_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS)
+#else
+#define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS)
+#endif
+
+/*
+ * To make optimal use of block mappings when laying out the linear
+ * mapping, round down the base of physical memory to a size that can
+ * be mapped efficiently, i.e., either PUD_SIZE (4k granule) or PMD_SIZE
+ * (64k granule), or a multiple that can be mapped using contiguous bits
+ * in the page tables: 32 * PMD_SIZE (16k granule)
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define ARM64_MEMSTART_ALIGN SZ_512M
+#else
+#define ARM64_MEMSTART_ALIGN SZ_1G
+#endif
+
+#endif /* __ASM_KERNEL_PGTABLE_H */
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 9694f26..0e391db 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,7 @@
#include <asm/types.h>
/* Hyp Configuration Register (HCR) bits */
+#define HCR_E2H (UL(1) << 34)
#define HCR_ID (UL(1) << 33)
#define HCR_CD (UL(1) << 32)
#define HCR_RW_SHIFT 31
@@ -61,7 +62,7 @@
/*
* The bits we set in HCR:
- * RW: 64bit by default, can be overriden for 32bit VMs
+ * RW: 64bit by default, can be overridden for 32bit VMs
* TAC: Trap ACTLR
* TSC: Trap SMC
* TVM: Trap VM ops (until M+C set in SCTLR_EL1)
@@ -81,7 +82,7 @@
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO)
-
+#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
/* Hyp System Control Register (SCTLR_EL2) bits */
#define SCTLR_EL2_EE (1 << 25)
@@ -107,8 +108,6 @@
#define TCR_EL2_MASK (TCR_EL2_TG0 | TCR_EL2_SH0 | \
TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
-#define TCR_EL2_FLAGS (TCR_EL2_RES1 | TCR_EL2_PS_40B)
-
/* VTCR_EL2 Registers bits */
#define VTCR_EL2_RES1 (1 << 31)
#define VTCR_EL2_PS_MASK (7 << 16)
@@ -125,6 +124,7 @@
#define VTCR_EL2_SL0_LVL1 (1 << 6)
#define VTCR_EL2_T0SZ_MASK 0x3f
#define VTCR_EL2_T0SZ_40B 24
+#define VTCR_EL2_VS 19
/*
* We configure the Stage-2 page tables to always restrict the IPA space to be
@@ -169,7 +169,7 @@
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
#define VTTBR_VMID_SHIFT (UL(48))
-#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT)
+#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
/* Hyp System Trap Register */
#define HSTR_EL2_T(x) (1 << x)
@@ -181,6 +181,7 @@
#define CPTR_EL2_TCPAC (1 << 31)
#define CPTR_EL2_TTA (1 << 20)
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
+#define CPTR_EL2_DEFAULT 0x000033ff
/* Hyp Debug Configuration Register bits */
#define MDCR_EL2_TDRA (1 << 11)
@@ -200,4 +201,23 @@
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
#define HPFAR_MASK (~UL(0xf))
+#define kvm_arm_exception_type \
+ {0, "IRQ" }, \
+ {1, "TRAP" }
+
+#define ECN(x) { ESR_ELx_EC_##x, #x }
+
+#define kvm_arm_exception_class \
+ ECN(UNKNOWN), ECN(WFx), ECN(CP15_32), ECN(CP15_64), ECN(CP14_MR), \
+ ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(CP14_64), ECN(SVC64), \
+ ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(IMP_DEF), ECN(IABT_LOW), \
+ ECN(IABT_CUR), ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \
+ ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
+ ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
+ ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
+ ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
+
+#define CPACR_EL1_FPEN (3 << 20)
+#define CPACR_EL1_TTA (1 << 28)
+
#endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 5e37710..226f49d 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -20,88 +20,14 @@
#include <asm/virt.h>
-/*
- * 0 is reserved as an invalid value.
- * Order *must* be kept in sync with the hyp switch code.
- */
-#define MPIDR_EL1 1 /* MultiProcessor Affinity Register */
-#define CSSELR_EL1 2 /* Cache Size Selection Register */
-#define SCTLR_EL1 3 /* System Control Register */
-#define ACTLR_EL1 4 /* Auxiliary Control Register */
-#define CPACR_EL1 5 /* Coprocessor Access Control */
-#define TTBR0_EL1 6 /* Translation Table Base Register 0 */
-#define TTBR1_EL1 7 /* Translation Table Base Register 1 */
-#define TCR_EL1 8 /* Translation Control Register */
-#define ESR_EL1 9 /* Exception Syndrome Register */
-#define AFSR0_EL1 10 /* Auxilary Fault Status Register 0 */
-#define AFSR1_EL1 11 /* Auxilary Fault Status Register 1 */
-#define FAR_EL1 12 /* Fault Address Register */
-#define MAIR_EL1 13 /* Memory Attribute Indirection Register */
-#define VBAR_EL1 14 /* Vector Base Address Register */
-#define CONTEXTIDR_EL1 15 /* Context ID Register */
-#define TPIDR_EL0 16 /* Thread ID, User R/W */
-#define TPIDRRO_EL0 17 /* Thread ID, User R/O */
-#define TPIDR_EL1 18 /* Thread ID, Privileged */
-#define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */
-#define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */
-#define PAR_EL1 21 /* Physical Address Register */
-#define MDSCR_EL1 22 /* Monitor Debug System Control Register */
-#define MDCCINT_EL1 23 /* Monitor Debug Comms Channel Interrupt Enable Reg */
-
-/* 32bit specific registers. Keep them at the end of the range */
-#define DACR32_EL2 24 /* Domain Access Control Register */
-#define IFSR32_EL2 25 /* Instruction Fault Status Register */
-#define FPEXC32_EL2 26 /* Floating-Point Exception Control Register */
-#define DBGVCR32_EL2 27 /* Debug Vector Catch Register */
-#define NR_SYS_REGS 28
-
-/* 32bit mapping */
-#define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
-#define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
-#define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
-#define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
-#define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
-#define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0 */
-#define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
-#define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */
-#define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */
-#define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */
-#define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */
-#define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */
-#define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
-#define c5_ADFSR (AFSR0_EL1 * 2) /* Auxiliary Data Fault Status R */
-#define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */
-#define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */
-#define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */
-#define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */
-#define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */
-#define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */
-#define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */
-#define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */
-#define c13_CID (CONTEXTIDR_EL1 * 2) /* Context ID Register */
-#define c13_TID_URW (TPIDR_EL0 * 2) /* Thread ID, User R/W */
-#define c13_TID_URO (TPIDRRO_EL0 * 2)/* Thread ID, User R/O */
-#define c13_TID_PRIV (TPIDR_EL1 * 2) /* Thread ID, Privileged */
-#define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */
-#define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */
-#define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */
-
-#define cp14_DBGDSCRext (MDSCR_EL1 * 2)
-#define cp14_DBGBCR0 (DBGBCR0_EL1 * 2)
-#define cp14_DBGBVR0 (DBGBVR0_EL1 * 2)
-#define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1)
-#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
-#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
-#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
-
-#define NR_COPRO_REGS (NR_SYS_REGS * 2)
-
#define ARM_EXCEPTION_IRQ 0
#define ARM_EXCEPTION_TRAP 1
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
+#define kvm_ksym_ref(sym) phys_to_virt((u64)&sym - kimage_voffset)
+
#ifndef __ASSEMBLY__
struct kvm;
struct kvm_vcpu;
@@ -111,9 +37,6 @@ extern char __kvm_hyp_init_end[];
extern char __kvm_hyp_vector[];
-#define __kvm_hyp_code_start __hyp_text_start
-#define __kvm_hyp_code_end __hyp_text_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);
@@ -121,9 +44,12 @@ extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
extern u64 __vgic_v3_get_ich_vtr_el2(void);
+extern void __vgic_v3_init_lrs(void);
extern u32 __kvm_get_mdcr_el2(void);
+extern void __init_stage2_translation(void);
+
#endif
#endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 17e92f0..40bc168 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -26,10 +26,10 @@
#include <asm/esr.h>
#include <asm/kvm_arm.h>
-#include <asm/kvm_asm.h>
#include <asm/kvm_mmio.h>
#include <asm/ptrace.h>
#include <asm/cputype.h>
+#include <asm/virt.h>
unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num);
unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu);
@@ -44,6 +44,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
{
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
+ if (is_kernel_in_hyp_mode())
+ vcpu->arch.hcr_el2 |= HCR_E2H;
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
vcpu->arch.hcr_el2 &= ~HCR_RW;
}
@@ -99,12 +101,22 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
*vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
}
-static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num)
+/*
+ * vcpu_get_reg and vcpu_set_reg should always be passed a register number
+ * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
+ * AArch32 with banked registers.
+ */
+static inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
+ u8 reg_num)
{
- if (vcpu_mode_is_32bit(vcpu))
- return vcpu_reg32(vcpu, reg_num);
+ return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs.regs[reg_num];
+}
- return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.regs[reg_num];
+static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
+ unsigned long val)
+{
+ if (reg_num != 31)
+ vcpu_gp_regs(vcpu)->regs.regs[reg_num] = val;
}
/* Get vcpu SPSR for current mode */
@@ -118,10 +130,14 @@ static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu)
static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
{
- u32 mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
+ u32 mode;
- if (vcpu_mode_is_32bit(vcpu))
+ if (vcpu_mode_is_32bit(vcpu)) {
+ mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
return mode > COMPAT_PSR_MODE_USR;
+ }
+
+ mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
return mode != PSR_MODE_EL0t;
}
@@ -176,6 +192,11 @@ static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu)
return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW);
}
+static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
+{
+ return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_CM);
+}
+
static inline int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu)
{
return 1 << ((kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ed03968..227ed47 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -27,6 +27,7 @@
#include <asm/kvm.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_mmio.h>
+#include <asm/kvm_perf_event.h>
#define __KVM_HAVE_ARCH_INTC_INITIALIZED
@@ -37,10 +38,11 @@
#include <kvm/arm_vgic.h>
#include <kvm/arm_arch_timer.h>
+#include <kvm/arm_pmu.h>
#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
-#define KVM_VCPU_MAX_FEATURES 3
+#define KVM_VCPU_MAX_FEATURES 4
int __attribute_const__ kvm_target_cpu(void);
int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
@@ -85,6 +87,101 @@ struct kvm_vcpu_fault_info {
u64 hpfar_el2; /* Hyp IPA Fault Address Register */
};
+/*
+ * 0 is reserved as an invalid value.
+ * Order should be kept in sync with the save/restore code.
+ */
+enum vcpu_sysreg {
+ __INVALID_SYSREG__,
+ MPIDR_EL1, /* MultiProcessor Affinity Register */
+ CSSELR_EL1, /* Cache Size Selection Register */
+ SCTLR_EL1, /* System Control Register */
+ ACTLR_EL1, /* Auxiliary Control Register */
+ CPACR_EL1, /* Coprocessor Access Control */
+ TTBR0_EL1, /* Translation Table Base Register 0 */
+ TTBR1_EL1, /* Translation Table Base Register 1 */
+ TCR_EL1, /* Translation Control Register */
+ ESR_EL1, /* Exception Syndrome Register */
+ AFSR0_EL1, /* Auxiliary Fault Status Register 0 */
+ AFSR1_EL1, /* Auxiliary Fault Status Register 1 */
+ FAR_EL1, /* Fault Address Register */
+ MAIR_EL1, /* Memory Attribute Indirection Register */
+ VBAR_EL1, /* Vector Base Address Register */
+ CONTEXTIDR_EL1, /* Context ID Register */
+ TPIDR_EL0, /* Thread ID, User R/W */
+ TPIDRRO_EL0, /* Thread ID, User R/O */
+ TPIDR_EL1, /* Thread ID, Privileged */
+ AMAIR_EL1, /* Aux Memory Attribute Indirection Register */
+ CNTKCTL_EL1, /* Timer Control Register (EL1) */
+ PAR_EL1, /* Physical Address Register */
+ MDSCR_EL1, /* Monitor Debug System Control Register */
+ MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */
+
+ /* Performance Monitors Registers */
+ PMCR_EL0, /* Control Register */
+ PMSELR_EL0, /* Event Counter Selection Register */
+ PMEVCNTR0_EL0, /* Event Counter Register (0-30) */
+ PMEVCNTR30_EL0 = PMEVCNTR0_EL0 + 30,
+ PMCCNTR_EL0, /* Cycle Counter Register */
+ PMEVTYPER0_EL0, /* Event Type Register (0-30) */
+ PMEVTYPER30_EL0 = PMEVTYPER0_EL0 + 30,
+ PMCCFILTR_EL0, /* Cycle Count Filter Register */
+ PMCNTENSET_EL0, /* Count Enable Set Register */
+ PMINTENSET_EL1, /* Interrupt Enable Set Register */
+ PMOVSSET_EL0, /* Overflow Flag Status Set Register */
+ PMSWINC_EL0, /* Software Increment Register */
+ PMUSERENR_EL0, /* User Enable Register */
+
+ /* 32bit specific registers. Keep them at the end of the range */
+ DACR32_EL2, /* Domain Access Control Register */
+ IFSR32_EL2, /* Instruction Fault Status Register */
+ FPEXC32_EL2, /* Floating-Point Exception Control Register */
+ DBGVCR32_EL2, /* Debug Vector Catch Register */
+
+ NR_SYS_REGS /* Nothing after this line! */
+};
+
+/* 32bit mapping */
+#define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
+#define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
+#define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
+#define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
+#define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
+#define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0 */
+#define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
+#define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */
+#define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */
+#define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */
+#define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */
+#define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */
+#define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
+#define c5_ADFSR (AFSR0_EL1 * 2) /* Auxiliary Data Fault Status R */
+#define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */
+#define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */
+#define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */
+#define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */
+#define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */
+#define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */
+#define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */
+#define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */
+#define c13_CID (CONTEXTIDR_EL1 * 2) /* Context ID Register */
+#define c13_TID_URW (TPIDR_EL0 * 2) /* Thread ID, User R/W */
+#define c13_TID_URO (TPIDRRO_EL0 * 2)/* Thread ID, User R/O */
+#define c13_TID_PRIV (TPIDR_EL1 * 2) /* Thread ID, Privileged */
+#define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */
+#define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */
+#define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */
+
+#define cp14_DBGDSCRext (MDSCR_EL1 * 2)
+#define cp14_DBGBCR0 (DBGBCR0_EL1 * 2)
+#define cp14_DBGBVR0 (DBGBVR0_EL1 * 2)
+#define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1)
+#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
+#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
+#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
+
+#define NR_COPRO_REGS (NR_SYS_REGS * 2)
+
struct kvm_cpu_context {
struct kvm_regs gp_regs;
union {
@@ -132,6 +229,7 @@ struct kvm_vcpu_arch {
/* VGIC state */
struct vgic_cpu vgic_cpu;
struct arch_timer_cpu timer_cpu;
+ struct kvm_pmu pmu;
/*
* Anything that is not used directly from assembly code goes
@@ -149,7 +247,10 @@ struct kvm_vcpu_arch {
u32 mdscr_el1;
} guest_debug_preserved;
- /* Don't run the guest */
+ /* vcpu power-off state */
+ bool power_off;
+
+ /* Don't run the guest (internal implementation need) */
bool pause;
/* IO related fields */
@@ -194,6 +295,12 @@ struct kvm_vcpu_stat {
u32 halt_successful_poll;
u32 halt_attempted_poll;
u32 halt_wakeup;
+ u32 hvc_exit_stat;
+ u64 wfe_exit_stat;
+ u64 wfi_exit_stat;
+ u64 mmio_exit_user;
+ u64 mmio_exit_kernel;
+ u64 exits;
};
int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
@@ -219,7 +326,9 @@ static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void);
-u64 kvm_call_hyp(void *hypfn, ...);
+u64 __kvm_call_hyp(void *hypfn, ...);
+#define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
+
void force_vm_exit(const cpumask_t *mask);
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
@@ -240,8 +349,8 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
* Call initialization code, and switch to the full blown
* HYP code.
*/
- kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
- hyp_stack_ptr, vector_ptr);
+ __kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
+ hyp_stack_ptr, vector_ptr);
}
static inline void kvm_arch_hardware_disable(void) {}
@@ -254,5 +363,18 @@ void kvm_arm_init_debug(void);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr);
+int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr);
+int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr);
+
+/* #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) */
+
+static inline void __cpu_init_stage2(void)
+{
+ kvm_call_hyp(__init_stage2_translation);
+}
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
new file mode 100644
index 0000000..a46b019
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2015 - 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 __ARM64_KVM_HYP_H__
+#define __ARM64_KVM_HYP_H__
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
+#include <asm/kvm_perf_event.h>
+#include <asm/sysreg.h>
+
+#define __hyp_text __section(.hyp.text) notrace
+
+static inline unsigned long __kern_hyp_va(unsigned long v)
+{
+ asm volatile(ALTERNATIVE("and %0, %0, %1",
+ "nop",
+ ARM64_HAS_VIRT_HOST_EXTN)
+ : "+r" (v) : "i" (HYP_PAGE_OFFSET_MASK));
+ return v;
+}
+
+#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v)))
+
+static inline unsigned long __hyp_kern_va(unsigned long v)
+{
+ u64 offset = PAGE_OFFSET - HYP_PAGE_OFFSET;
+ asm volatile(ALTERNATIVE("add %0, %0, %1",
+ "nop",
+ ARM64_HAS_VIRT_HOST_EXTN)
+ : "+r" (v) : "r" (offset));
+ return v;
+}
+
+#define hyp_kern_va(v) (typeof(v))(__hyp_kern_va((unsigned long)(v)))
+
+#define read_sysreg_elx(r,nvh,vh) \
+ ({ \
+ u64 reg; \
+ asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##nvh),\
+ "mrs_s %0, " __stringify(r##vh),\
+ ARM64_HAS_VIRT_HOST_EXTN) \
+ : "=r" (reg)); \
+ reg; \
+ })
+
+#define write_sysreg_elx(v,r,nvh,vh) \
+ do { \
+ u64 __val = (u64)(v); \
+ asm volatile(ALTERNATIVE("msr " __stringify(r##nvh) ", %x0",\
+ "msr_s " __stringify(r##vh) ", %x0",\
+ ARM64_HAS_VIRT_HOST_EXTN) \
+ : : "rZ" (__val)); \
+ } while (0)
+
+/*
+ * Unified accessors for registers that have a different encoding
+ * between VHE and non-VHE. They must be specified without their "ELx"
+ * encoding.
+ */
+#define read_sysreg_el2(r) \
+ ({ \
+ u64 reg; \
+ asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##_EL2),\
+ "mrs %0, " __stringify(r##_EL1),\
+ ARM64_HAS_VIRT_HOST_EXTN) \
+ : "=r" (reg)); \
+ reg; \
+ })
+
+#define write_sysreg_el2(v,r) \
+ do { \
+ u64 __val = (u64)(v); \
+ asm volatile(ALTERNATIVE("msr " __stringify(r##_EL2) ", %x0",\
+ "msr " __stringify(r##_EL1) ", %x0",\
+ ARM64_HAS_VIRT_HOST_EXTN) \
+ : : "rZ" (__val)); \
+ } while (0)
+
+#define read_sysreg_el0(r) read_sysreg_elx(r, _EL0, _EL02)
+#define write_sysreg_el0(v,r) write_sysreg_elx(v, r, _EL0, _EL02)
+#define read_sysreg_el1(r) read_sysreg_elx(r, _EL1, _EL12)
+#define write_sysreg_el1(v,r) write_sysreg_elx(v, r, _EL1, _EL12)
+
+/* The VHE specific system registers and their encoding */
+#define sctlr_EL12 sys_reg(3, 5, 1, 0, 0)
+#define cpacr_EL12 sys_reg(3, 5, 1, 0, 2)
+#define ttbr0_EL12 sys_reg(3, 5, 2, 0, 0)
+#define ttbr1_EL12 sys_reg(3, 5, 2, 0, 1)
+#define tcr_EL12 sys_reg(3, 5, 2, 0, 2)
+#define afsr0_EL12 sys_reg(3, 5, 5, 1, 0)
+#define afsr1_EL12 sys_reg(3, 5, 5, 1, 1)
+#define esr_EL12 sys_reg(3, 5, 5, 2, 0)
+#define far_EL12 sys_reg(3, 5, 6, 0, 0)
+#define mair_EL12 sys_reg(3, 5, 10, 2, 0)
+#define amair_EL12 sys_reg(3, 5, 10, 3, 0)
+#define vbar_EL12 sys_reg(3, 5, 12, 0, 0)
+#define contextidr_EL12 sys_reg(3, 5, 13, 0, 1)
+#define cntkctl_EL12 sys_reg(3, 5, 14, 1, 0)
+#define cntp_tval_EL02 sys_reg(3, 5, 14, 2, 0)
+#define cntp_ctl_EL02 sys_reg(3, 5, 14, 2, 1)
+#define cntp_cval_EL02 sys_reg(3, 5, 14, 2, 2)
+#define cntv_tval_EL02 sys_reg(3, 5, 14, 3, 0)
+#define cntv_ctl_EL02 sys_reg(3, 5, 14, 3, 1)
+#define cntv_cval_EL02 sys_reg(3, 5, 14, 3, 2)
+#define spsr_EL12 sys_reg(3, 5, 4, 0, 0)
+#define elr_EL12 sys_reg(3, 5, 4, 0, 1)
+
+/**
+ * hyp_alternate_select - Generates patchable code sequences that are
+ * used to switch between two implementations of a function, depending
+ * on the availability of a feature.
+ *
+ * @fname: a symbol name that will be defined as a function returning a
+ * function pointer whose type will match @orig and @alt
+ * @orig: A pointer to the default function, as returned by @fname when
+ * @cond doesn't hold
+ * @alt: A pointer to the alternate function, as returned by @fname
+ * when @cond holds
+ * @cond: a CPU feature (as described in asm/cpufeature.h)
+ */
+#define hyp_alternate_select(fname, orig, alt, cond) \
+typeof(orig) * __hyp_text fname(void) \
+{ \
+ typeof(alt) *val = orig; \
+ asm volatile(ALTERNATIVE("nop \n", \
+ "mov %0, %1 \n", \
+ cond) \
+ : "+r" (val) : "r" (alt)); \
+ return val; \
+}
+
+void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
+
+void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
+
+void __timer_save_state(struct kvm_vcpu *vcpu);
+void __timer_restore_state(struct kvm_vcpu *vcpu);
+
+void __sysreg_save_host_state(struct kvm_cpu_context *ctxt);
+void __sysreg_restore_host_state(struct kvm_cpu_context *ctxt);
+void __sysreg_save_guest_state(struct kvm_cpu_context *ctxt);
+void __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt);
+void __sysreg32_save_state(struct kvm_vcpu *vcpu);
+void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
+
+void __debug_save_state(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt);
+void __debug_restore_state(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt);
+void __debug_cond_save_host_state(struct kvm_vcpu *vcpu);
+void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu);
+
+void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
+void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
+bool __fpsimd_enabled(void);
+
+u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
+void __noreturn __hyp_do_panic(unsigned long, ...);
+
+#endif /* __ARM64_KVM_HYP_H__ */
+
diff --git a/arch/arm64/include/asm/kvm_mmio.h b/arch/arm64/include/asm/kvm_mmio.h
index 889c908..fe612a9 100644
--- a/arch/arm64/include/asm/kvm_mmio.h
+++ b/arch/arm64/include/asm/kvm_mmio.h
@@ -19,7 +19,6 @@
#define __ARM64_KVM_MMIO_H__
#include <linux/kvm_host.h>
-#include <asm/kvm_asm.h>
#include <asm/kvm_arm.h>
/*
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 6150567..22732a5 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -20,15 +20,19 @@
#include <asm/page.h>
#include <asm/memory.h>
+#include <asm/cpufeature.h>
/*
- * As we only have the TTBR0_EL2 register, we cannot express
+ * As ARMv8.0 only has the TTBR0_EL2 register, we cannot express
* "negative" addresses. This makes it impossible to directly share
* mappings with the kernel.
*
* Instead, give the HYP mode its own VA region at a fixed offset from
* the kernel by just masking the top bits (which are all ones for a
* kernel address).
+ *
+ * ARMv8.1 (using VHE) does have a TTBR1_EL2, and doesn't use these
+ * macros (the entire kernel runs at EL2).
*/
#define HYP_PAGE_OFFSET_SHIFT VA_BITS
#define HYP_PAGE_OFFSET_MASK ((UL(1) << HYP_PAGE_OFFSET_SHIFT) - 1)
@@ -55,12 +59,19 @@
#ifdef __ASSEMBLY__
+#include <asm/alternative.h>
+#include <asm/cpufeature.h>
+
/*
* Convert a kernel VA into a HYP VA.
* reg: VA to be converted.
*/
.macro kern_hyp_va reg
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
and \reg, \reg, #HYP_PAGE_OFFSET_MASK
+alternative_else
+ nop
+alternative_endif
.endm
#else
@@ -158,7 +169,6 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
#define PTRS_PER_S2_PGD_SHIFT (KVM_PHYS_SHIFT - PGDIR_SHIFT)
#endif
#define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT)
-#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
#define kvm_pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1))
@@ -230,7 +240,8 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
return (vcpu_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
}
-static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
+ kvm_pfn_t pfn,
unsigned long size,
bool ipa_uncached)
{
@@ -302,5 +313,12 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
merged_hyp_pgd[idmap_idx] = __pgd(__pa(boot_hyp_pgd) | PMD_TYPE_TABLE);
}
+static inline unsigned int kvm_get_vmid_bits(void)
+{
+ int reg = read_system_reg(SYS_ID_AA64MMFR1_EL1);
+
+ return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __ARM64_KVM_MMU_H__ */
diff --git a/arch/arm64/include/asm/kvm_perf_event.h b/arch/arm64/include/asm/kvm_perf_event.h
new file mode 100644
index 0000000..c18fdeb
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_perf_event.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 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_KVM_PERF_EVENT_H
+#define __ASM_KVM_PERF_EVENT_H
+
+#define ARMV8_PMU_MAX_COUNTERS 32
+#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1)
+
+/*
+ * Per-CPU PMCR: config reg
+ */
+#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */
+#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */
+#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */
+#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */
+#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
+/* Determines which bit of PMCCNTR_EL0 generates an overflow */
+#define ARMV8_PMU_PMCR_LC (1 << 6)
+#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */
+#define ARMV8_PMU_PMCR_N_MASK 0x1f
+#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */
+
+/*
+ * PMOVSR: counters overflow flag status reg
+ */
+#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */
+#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK
+
+/*
+ * PMXEVTYPER: Event selection reg
+ */
+#define ARMV8_PMU_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */
+#define ARMV8_PMU_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */
+
+#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR 0 /* Software increment event */
+
+/*
+ * Event filters for PMUv3
+ */
+#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31)
+#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30)
+#define ARMV8_PMU_INCLUDE_EL2 (1 << 27)
+
+/*
+ * PMUSERENR: user enable reg
+ */
+#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */
+#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */
+#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */
+#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */
+#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read at EL0 */
+
+#endif
diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h
index 3de42d6..23acc00 100644
--- a/arch/arm64/include/asm/lse.h
+++ b/arch/arm64/include/asm/lse.h
@@ -26,6 +26,7 @@ __asm__(".arch_extension lse");
/* Macro for constructing calls to out-of-line ll/sc atomics */
#define __LL_SC_CALL(op) "bl\t" __stringify(__LL_SC_PREFIX(op)) "\n"
+#define __LL_SC_CLOBBERS "x16", "x17", "x30"
/* In-line patching at runtime */
#define ARM64_LSE_ATOMIC_INSN(llsc, lse) \
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 6b4c3ad..12f8a00 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -24,6 +24,7 @@
#include <linux/compiler.h>
#include <linux/const.h>
#include <linux/types.h>
+#include <asm/bug.h>
#include <asm/sizes.h>
/*
@@ -42,16 +43,18 @@
* PAGE_OFFSET - the virtual address of the start of the kernel image (top
* (VA_BITS - 1))
* VA_BITS - the maximum number of bits for virtual addresses.
+ * VA_START - the first kernel virtual address.
* TASK_SIZE - the maximum size of a user space task.
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
- * The module space lives between the addresses given by TASK_SIZE
- * and PAGE_OFFSET - it must be within 128MB of the kernel text.
*/
#define VA_BITS (CONFIG_ARM64_VA_BITS)
+#define VA_START (UL(0xffffffffffffffff) << VA_BITS)
#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))
-#define MODULES_END (PAGE_OFFSET)
-#define MODULES_VADDR (MODULES_END - SZ_64M)
-#define PCI_IO_END (MODULES_VADDR - SZ_2M)
+#define KIMAGE_VADDR (MODULES_END)
+#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
+#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
+#define MODULES_VSIZE (SZ_128M)
+#define PCI_IO_END (PAGE_OFFSET - SZ_2M)
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
#define TASK_SIZE_64 (UL(1) << VA_BITS)
@@ -68,8 +71,14 @@
#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 4))
-#if TASK_SIZE_64 > MODULES_VADDR
-#error Top of 64-bit user space clashes with start of module space
+/*
+ * The size of the KASAN shadow region. This should be 1/8th of the
+ * size of the entire kernel virtual address space.
+ */
+#ifdef CONFIG_KASAN
+#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3))
+#else
+#define KASAN_SHADOW_SIZE (0)
#endif
/*
@@ -77,8 +86,13 @@
* private definitions which should NOT be used outside memory.h
* files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
*/
-#define __virt_to_phys(x) (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET))
-#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))
+#define __virt_to_phys(x) ({ \
+ phys_addr_t __x = (phys_addr_t)(x); \
+ __x & BIT(VA_BITS - 1) ? (__x & ~PAGE_OFFSET) + PHYS_OFFSET : \
+ (__x - kimage_voffset); })
+
+#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+#define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset))
/*
* Convert a page to/from a physical address
@@ -94,6 +108,7 @@
#define MT_DEVICE_GRE 2
#define MT_NORMAL_NC 3
#define MT_NORMAL 4
+#define MT_NORMAL_WT 5
/*
* Memory types for Stage-2 translation
@@ -101,19 +116,40 @@
#define MT_S2_NORMAL 0xf
#define MT_S2_DEVICE_nGnRE 0x1
+#ifdef CONFIG_ARM64_4K_PAGES
+#define IOREMAP_MAX_ORDER (PUD_SHIFT)
+#else
+#define IOREMAP_MAX_ORDER (PMD_SHIFT)
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#define __early_init_dt_declare_initrd(__start, __end) \
+ do { \
+ initrd_start = (__start); \
+ initrd_end = (__end); \
+ } while (0)
+#endif
+
#ifndef __ASSEMBLY__
-extern phys_addr_t memstart_addr;
+#include <linux/bitops.h>
+#include <linux/mmdebug.h>
+
+extern s64 memstart_addr;
/* PHYS_OFFSET - the physical address of the start of memory. */
-#define PHYS_OFFSET ({ memstart_addr; })
+#define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
+
+/* the virtual base of the kernel image (minus TEXT_OFFSET) */
+extern u64 kimage_vaddr;
+
+/* the offset between the kernel virtual and physical mappings */
+extern u64 kimage_voffset;
/*
- * The maximum physical address that the linear direct mapping
- * of system RAM can cover. (PAGE_OFFSET can be interpreted as
- * a 2's complement signed quantity and negated to derive the
- * maximum size of the linear mapping.)
+ * Allow all memory at the discovery stage. We will clip it later.
*/
-#define MAX_MEMBLOCK_ADDR ({ memstart_addr - PAGE_OFFSET - 1; })
+#define MIN_MEMBLOCK_ADDR 0
+#define MAX_MEMBLOCK_ADDR U64_MAX
/*
* PFNs are used to describe any physical page; this means
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 0302087..990124a 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -17,15 +17,16 @@
#define __ASM_MMU_H
typedef struct {
- unsigned int id;
- raw_spinlock_t id_lock;
- void *vdso;
+ atomic64_t id;
+ void *vdso;
} mm_context_t;
-#define INIT_MM_CONTEXT(name) \
- .context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
-
-#define ASID(mm) ((mm)->context.id & 0xffff)
+/*
+ * This macro is only used by the TLBI code, which cannot race with an
+ * ASID change and therefore doesn't need to reload the counter using
+ * atomic64_read.
+ */
+#define ASID(mm) ((mm)->context.id.counter & 0xffff)
extern void paging_init(void);
extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 8ec41e5..b1892a0 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -27,13 +27,7 @@
#include <asm-generic/mm_hooks.h>
#include <asm/cputype.h>
#include <asm/pgtable.h>
-
-#define MAX_ASID_BITS 16
-
-extern unsigned int cpu_last_asid;
-
-void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-void __new_context(struct mm_struct *mm);
+#include <asm/tlbflush.h>
#ifdef CONFIG_PID_IN_CONTEXTIDR
static inline void contextidr_thread_switch(struct task_struct *next)
@@ -55,7 +49,7 @@ static inline void contextidr_thread_switch(struct task_struct *next)
*/
static inline void cpu_set_reserved_ttbr0(void)
{
- unsigned long ttbr = page_to_phys(empty_zero_page);
+ unsigned long ttbr = virt_to_phys(empty_zero_page);
asm(
" msr ttbr0_el1, %0 // set TTBR0\n"
@@ -77,98 +71,95 @@ static inline bool __cpu_uses_extended_idmap(void)
unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)));
}
-static inline void __cpu_set_tcr_t0sz(u64 t0sz)
+/*
+ * Set TCR.T0SZ to its default value (based on VA_BITS)
+ */
+static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
{
unsigned long tcr;
- if (__cpu_uses_extended_idmap())
- asm volatile (
- " mrs %0, tcr_el1 ;"
- " bfi %0, %1, %2, %3 ;"
- " msr tcr_el1, %0 ;"
- " isb"
- : "=&r" (tcr)
- : "r"(t0sz), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
-}
+ if (!__cpu_uses_extended_idmap())
+ return;
-/*
- * Set TCR.T0SZ to the value appropriate for activating the identity map.
- */
-static inline void cpu_set_idmap_tcr_t0sz(void)
-{
- __cpu_set_tcr_t0sz(idmap_t0sz);
+ asm volatile (
+ " mrs %0, tcr_el1 ;"
+ " bfi %0, %1, %2, %3 ;"
+ " msr tcr_el1, %0 ;"
+ " isb"
+ : "=&r" (tcr)
+ : "r"(t0sz), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
}
+#define cpu_set_default_tcr_t0sz() __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS))
+#define cpu_set_idmap_tcr_t0sz() __cpu_set_tcr_t0sz(idmap_t0sz)
+
/*
- * Set TCR.T0SZ to its default value (based on VA_BITS)
+ * Remove the idmap from TTBR0_EL1 and install the pgd of the active mm.
+ *
+ * The idmap lives in the same VA range as userspace, but uses global entries
+ * and may use a different TCR_EL1.T0SZ. To avoid issues resulting from
+ * speculative TLB fetches, we must temporarily install the reserved page
+ * tables while we invalidate the TLBs and set up the correct TCR_EL1.T0SZ.
+ *
+ * If current is a not a user task, the mm covers the TTBR1_EL1 page tables,
+ * which should not be installed in TTBR0_EL1. In this case we can leave the
+ * reserved page tables in place.
*/
-static inline void cpu_set_default_tcr_t0sz(void)
+static inline void cpu_uninstall_idmap(void)
{
- __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS));
-}
+ struct mm_struct *mm = current->active_mm;
-static inline void switch_new_context(struct mm_struct *mm)
-{
- unsigned long flags;
-
- __new_context(mm);
+ cpu_set_reserved_ttbr0();
+ local_flush_tlb_all();
+ cpu_set_default_tcr_t0sz();
- local_irq_save(flags);
- cpu_switch_mm(mm->pgd, mm);
- local_irq_restore(flags);
+ if (mm != &init_mm)
+ cpu_switch_mm(mm->pgd, mm);
}
-static inline void check_and_switch_context(struct mm_struct *mm,
- struct task_struct *tsk)
+static inline void cpu_install_idmap(void)
{
- /*
- * Required during context switch to avoid speculative page table
- * walking with the wrong TTBR.
- */
cpu_set_reserved_ttbr0();
+ local_flush_tlb_all();
+ cpu_set_idmap_tcr_t0sz();
- if (!((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS))
- /*
- * The ASID is from the current generation, just switch to the
- * new pgd. This condition is only true for calls from
- * context_switch() and interrupts are already disabled.
- */
- cpu_switch_mm(mm->pgd, mm);
- else if (irqs_disabled())
- /*
- * Defer the new ASID allocation until after the context
- * switch critical region since __new_context() cannot be
- * called with interrupts disabled.
- */
- set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
- else
- /*
- * That is a direct call to switch_mm() or activate_mm() with
- * interrupts enabled and a new context.
- */
- switch_new_context(mm);
+ cpu_switch_mm(idmap_pg_dir, &init_mm);
}
-#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0)
-#define destroy_context(mm) do { } while(0)
-
-#define finish_arch_post_lock_switch \
- finish_arch_post_lock_switch
-static inline void finish_arch_post_lock_switch(void)
+/*
+ * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
+ * avoiding the possibility of conflicting TLB entries being allocated.
+ */
+static inline void cpu_replace_ttbr1(pgd_t *pgd)
{
- if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
- struct mm_struct *mm = current->mm;
- unsigned long flags;
+ typedef void (ttbr_replace_func)(phys_addr_t);
+ extern ttbr_replace_func idmap_cpu_replace_ttbr1;
+ ttbr_replace_func *replace_phys;
- __new_context(mm);
+ phys_addr_t pgd_phys = virt_to_phys(pgd);
- local_irq_save(flags);
- cpu_switch_mm(mm->pgd, mm);
- local_irq_restore(flags);
- }
+ replace_phys = (void *)virt_to_phys(idmap_cpu_replace_ttbr1);
+
+ cpu_install_idmap();
+ replace_phys(pgd_phys);
+ cpu_uninstall_idmap();
}
/*
+ * It would be nice to return ASIDs back to the allocator, but unfortunately
+ * that introduces a race with a generation rollover where we could erroneously
+ * free an ASID allocated in a future generation. We could workaround this by
+ * freeing the ASID from the context of the dying mm (e.g. in arch_exit_mmap),
+ * but we'd then need to make sure that we didn't dirty any TLBs afterwards.
+ * Setting a reserved TTBR0 or EPD0 would work, but it all gets ugly when you
+ * take CPU migration into account.
+ */
+#define destroy_context(mm) do { } while(0)
+void check_and_switch_context(struct mm_struct *mm, unsigned int cpu);
+
+#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; })
+
+/*
* This is called when "tsk" is about to enter lazy TLB mode.
*
* mm: describes the currently active mm context
@@ -194,6 +185,9 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
{
unsigned int cpu = smp_processor_id();
+ if (prev == next)
+ return;
+
/*
* init_mm.pgd does not contain any user mappings and it is always
* active for kernel addresses in TTBR1. Just set the reserved TTBR0.
@@ -203,11 +197,12 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
return;
}
- if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
- check_and_switch_context(next, tsk);
+ check_and_switch_context(next, cpu);
}
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
+void verify_cpu_asid_bits(void);
+
#endif
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index e80e232..e12af67 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -20,4 +20,21 @@
#define MODULE_ARCH_VERMAGIC "aarch64"
+#ifdef CONFIG_ARM64_MODULE_PLTS
+struct mod_arch_specific {
+ struct elf64_shdr *plt;
+ int plt_num_entries;
+ int plt_max_entries;
+};
+#endif
+
+u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
+ Elf64_Sym *sym);
+
+#ifdef CONFIG_RANDOMIZE_BASE
+extern u64 module_alloc_base;
+#else
+#define module_alloc_base ((u64)_etext - MODULES_VSIZE)
+#endif
+
#endif /* __ASM_MODULE_H */
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 7d9c7e4..ae615b9 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -20,34 +20,26 @@
#define __ASM_PAGE_H
/* PAGE_SHIFT determines the page size */
+/* CONT_SHIFT determines the number of pages which can be tracked together */
#ifdef CONFIG_ARM64_64K_PAGES
#define PAGE_SHIFT 16
+#define CONT_SHIFT 5
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define PAGE_SHIFT 14
+#define CONT_SHIFT 7
#else
#define PAGE_SHIFT 12
+#define CONT_SHIFT 4
#endif
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
- */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS)
-#else
-#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1)
-#endif
-
-#define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE (3 * PAGE_SIZE)
+#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT))
+#define CONT_MASK (~(CONT_SIZE-1))
#ifndef __ASSEMBLY__
+#include <linux/personality.h> /* for READ_IMPLIES_EXEC */
#include <asm/pgtable-types.h>
extern void __cpu_clear_user_page(void *p, unsigned long user);
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
new file mode 100644
index 0000000..fd5f428
--- /dev/null
+++ b/arch/arm64/include/asm/paravirt.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_ARM64_PARAVIRT_H
+#define _ASM_ARM64_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT
+struct static_key;
+extern struct static_key paravirt_steal_enabled;
+extern struct static_key paravirt_steal_rq_enabled;
+
+struct pv_time_ops {
+ unsigned long long (*steal_clock)(int cpu);
+};
+extern struct pv_time_ops pv_time_ops;
+
+static inline u64 paravirt_steal_clock(int cpu)
+{
+ return pv_time_ops.steal_clock(cpu);
+}
+#endif
+
+#endif
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
index b008a72..b9a7ba9 100644
--- a/arch/arm64/include/asm/pci.h
+++ b/arch/arm64/include/asm/pci.h
@@ -7,8 +7,6 @@
#include <linux/dma-mapping.h>
#include <asm/io.h>
-#include <asm-generic/pci-bridge.h>
-#include <asm-generic/pci-dma-compat.h>
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 7642056..ff98585 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -27,6 +27,7 @@
#define check_pgt_cache() do { } while (0)
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
#if CONFIG_PGTABLE_LEVELS > 2
@@ -41,11 +42,20 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
free_page((unsigned long)pmd);
}
-static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
{
- set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+ set_pud(pud, __pud(pmd | prot));
}
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE);
+}
+#else
+static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
+{
+ BUILD_BUG();
+}
#endif /* CONFIG_PGTABLE_LEVELS > 2 */
#if CONFIG_PGTABLE_LEVELS > 3
@@ -61,11 +71,20 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
free_page((unsigned long)pud);
}
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
{
- set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE));
+ set_pgd(pgdp, __pgd(pud | prot));
}
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+{
+ __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE);
+}
+#else
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
+{
+ BUILD_BUG();
+}
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
extern pgd_t *pgd_alloc(struct mm_struct *mm);
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 24154b0..5c25b83 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -16,13 +16,46 @@
#ifndef __ASM_PGTABLE_HWDEF_H
#define __ASM_PGTABLE_HWDEF_H
+/*
+ * Number of page-table levels required to address 'va_bits' wide
+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
+ *
+ * levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
+ *
+ * where DIV_ROUND_UP(n, d) => (((n) + (d) - 1) / (d))
+ *
+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
+ * due to build issues. So we open code DIV_ROUND_UP here:
+ *
+ * ((((va_bits) - PAGE_SHIFT) + (PAGE_SHIFT - 3) - 1) / (PAGE_SHIFT - 3))
+ *
+ * which gets simplified as :
+ */
+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
+
+/*
+ * Size mapped by an entry at level n ( 0 <= n <= 3)
+ * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
+ * in the final page. The maximum number of translation levels supported by
+ * the architecture is 4. Hence, starting at at level n, we have further
+ * ((4 - n) - 1) levels of translation excluding the offset within the page.
+ * So, the total number of bits mapped by an entry at level n is :
+ *
+ * ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
+ *
+ * Rearranging it a bit we get :
+ * (4 - n) * (PAGE_SHIFT - 3) + 3
+ */
+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n) ((PAGE_SHIFT - 3) * (4 - (n)) + 3)
+
#define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3))
/*
* PMD_SHIFT determines the size a level 2 page table entry can map.
*/
#if CONFIG_PGTABLE_LEVELS > 2
-#define PMD_SHIFT ((PAGE_SHIFT - 3) * 2 + 3)
+#define PMD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PTRS_PER_PMD PTRS_PER_PTE
@@ -32,7 +65,7 @@
* PUD_SHIFT determines the size a level 1 page table entry can map.
*/
#if CONFIG_PGTABLE_LEVELS > 3
-#define PUD_SHIFT ((PAGE_SHIFT - 3) * 3 + 3)
+#define PUD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
#define PUD_MASK (~(PUD_SIZE-1))
#define PTRS_PER_PUD PTRS_PER_PTE
@@ -42,7 +75,7 @@
* PGDIR_SHIFT determines the size a top-level page table entry can map
* (depending on the configuration, this level can be 0, 1 or 2).
*/
-#define PGDIR_SHIFT ((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
+#define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD (1 << (VA_BITS - PGDIR_SHIFT))
@@ -55,6 +88,29 @@
#define SECTION_MASK (~(SECTION_SIZE-1))
/*
+ * Contiguous page definitions.
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define CONT_PTE_SHIFT 5
+#define CONT_PMD_SHIFT 5
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define CONT_PTE_SHIFT 7
+#define CONT_PMD_SHIFT 5
+#else
+#define CONT_PTE_SHIFT 4
+#define CONT_PMD_SHIFT 4
+#endif
+
+#define CONT_PTES (1 << CONT_PTE_SHIFT)
+#define CONT_PTE_SIZE (CONT_PTES * PAGE_SIZE)
+#define CONT_PTE_MASK (~(CONT_PTE_SIZE - 1))
+#define CONT_PMDS (1 << CONT_PMD_SHIFT)
+#define CONT_PMD_SIZE (CONT_PMDS * PMD_SIZE)
+#define CONT_PMD_MASK (~(CONT_PMD_SIZE - 1))
+/* the the numerical offset of the PTE within a range of CONT_PTES */
+#define CONT_RANGE_OFFSET(addr) (((addr)>>PAGE_SHIFT)&(CONT_PTES-1))
+
+/*
* Hardware page table definitions.
*
* Level 1 descriptor (PUD).
@@ -83,6 +139,7 @@
#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_CONT (_AT(pmdval_t, 1) << 52)
#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53)
#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54)
@@ -105,6 +162,7 @@
#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */
#define PTE_DBM (_AT(pteval_t, 1) << 51) /* Dirty Bit Management */
+#define PTE_CONT (_AT(pteval_t, 1) << 52) /* Contiguous range */
#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
new file mode 100644
index 0000000..29fcb33
--- /dev/null
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 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_PGTABLE_PROT_H
+#define __ASM_PGTABLE_PROT_H
+
+#include <asm/memory.h>
+#include <asm/pgtable-hwdef.h>
+
+#include <linux/const.h>
+
+/*
+ * Software defined PTE bits definition.
+ */
+#define PTE_VALID (_AT(pteval_t, 1) << 0)
+#define PTE_WRITE (PTE_DBM) /* same as DBM (51) */
+#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
+#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
+#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
+
+#ifndef __ASSEMBLY__
+
+#include <asm/pgtable-types.h>
+
+#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
+#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
+
+#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
+#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
+#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
+
+#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
+#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
+
+#define _PAGE_DEFAULT (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
+
+#define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
+#define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+#define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
+
+#define PAGE_HYP __pgprot(_PAGE_DEFAULT | PTE_HYP)
+#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
+
+#define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
+#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
+
+#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
+#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
+#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
+#define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+
+#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
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_PGTABLE_PROT_H */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 26b0666..989fef1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -21,35 +21,31 @@
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
-
-/*
- * Software defined PTE bits definition.
- */
-#define PTE_VALID (_AT(pteval_t, 1) << 0)
-#define PTE_WRITE (PTE_DBM) /* same as DBM (51) */
-#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
-#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
-#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
+#include <asm/pgtable-prot.h>
/*
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
*
- * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
+ * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
* (rounded up to PUD_SIZE).
- * VMALLOC_START: beginning of the kernel VA space
+ * VMALLOC_START: beginning of the kernel vmalloc space
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
* fixed mappings and modules
*/
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
-#define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS)
+
+#define VMALLOC_START (MODULES_END)
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
-#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
+#define VMEMMAP_START (VMALLOC_END + SZ_64K)
+#define vmemmap ((struct page *)VMEMMAP_START - \
+ SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT))
#define FIRST_USER_ADDRESS 0UL
#ifndef __ASSEMBLY__
+#include <asm/fixmap.h>
#include <linux/mmdebug.h>
extern void __pte_error(const char *file, int line, unsigned long val);
@@ -57,60 +53,12 @@ extern void __pmd_error(const char *file, int line, unsigned long val);
extern void __pud_error(const char *file, int line, unsigned long val);
extern void __pgd_error(const char *file, int line, unsigned long val);
-#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
-#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
-
-#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
-#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
-#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
-
-#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
-#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
-#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
-
-#define _PAGE_DEFAULT (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
-
-#define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
-#define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
-
-#define PAGE_HYP __pgprot(_PAGE_DEFAULT | PTE_HYP)
-#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
-
-#define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
-#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
-
-#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
-#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
-#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
-#define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
-#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
-#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
-#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
-
-#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
-
/*
* 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 unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
@@ -122,16 +70,6 @@ extern struct page *empty_zero_page;
#define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0))
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
-/* Find an entry in the third-level page table. */
-#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-
-#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + pte_index(addr))
-
-#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
-
/*
* The following only work if pte_present(). Undefined behaviour otherwise.
*/
@@ -140,6 +78,8 @@ extern struct page *empty_zero_page;
#define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL))
#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
+#define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT))
+#define pte_user(pte) (!!(pte_val(pte) & PTE_USER))
#ifdef CONFIG_ARM64_HW_AFDBM
#define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
@@ -150,10 +90,18 @@ extern struct page *empty_zero_page;
#define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
#define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID))
-#define pte_valid_user(pte) \
- ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
#define pte_valid_not_user(pte) \
((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
+#define pte_valid_young(pte) \
+ ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF))
+
+/*
+ * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
+ * so that we don't erroneously return false for pages that have been
+ * remapped as PROT_NONE but are yet to be flushed from the TLB.
+ */
+#define pte_accessible(mm, pte) \
+ (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte))
static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
{
@@ -202,6 +150,22 @@ static inline pte_t pte_mkspecial(pte_t pte)
return set_pte_bit(pte, __pgprot(PTE_SPECIAL));
}
+static inline pte_t pte_mkcont(pte_t pte)
+{
+ pte = set_pte_bit(pte, __pgprot(PTE_CONT));
+ return set_pte_bit(pte, __pgprot(PTE_TYPE_PAGE));
+}
+
+static inline pte_t pte_mknoncont(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(PTE_CONT));
+}
+
+static inline pmd_t pmd_mkcont(pmd_t pmd)
+{
+ return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
+}
+
static inline void set_pte(pte_t *ptep, pte_t pte)
{
*ptep = pte;
@@ -239,13 +203,13 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
- if (pte_valid_user(pte)) {
- if (!pte_special(pte) && pte_exec(pte))
- __sync_icache_dcache(pte, addr);
+ if (pte_present(pte)) {
if (pte_sw_dirty(pte) && pte_write(pte))
pte_val(pte) &= ~PTE_RDONLY;
else
pte_val(pte) |= PTE_RDONLY;
+ if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
+ __sync_icache_dcache(pte, addr);
}
/*
@@ -253,10 +217,14 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
* hardware updates of the pte (ptep_set_access_flags safely changes
* valid ptes without going through an invalid entry).
*/
- if (IS_ENABLED(CONFIG_DEBUG_VM) && IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
- pte_valid(*ptep)) {
- BUG_ON(!pte_young(pte));
- BUG_ON(pte_write(*ptep) && !pte_dirty(pte));
+ if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) &&
+ pte_valid(*ptep) && pte_valid(pte)) {
+ VM_WARN_ONCE(!pte_young(pte),
+ "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
+ __func__, pte_val(*ptep), pte_val(pte));
+ VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(pte),
+ "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
+ __func__, pte_val(*ptep), pte_val(pte));
}
set_pte(ptep, pte);
@@ -271,7 +239,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
/*
* Hugetlb definitions.
*/
-#define HUGE_MAX_HSTATE 2
+#define HUGE_MAX_HSTATE 4
#define HPAGE_SHIFT PMD_SHIFT
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
@@ -310,21 +278,14 @@ static inline pgprot_t mk_sect_prot(pgprot_t prot)
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
-#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-struct vm_area_struct;
-void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp);
-#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
-#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
@@ -375,7 +336,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
#define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
PMD_TYPE_SECT)
-#ifdef CONFIG_ARM64_64K_PAGES
+#if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS < 3
#define pud_sect(pud) (0)
#define pud_table(pud) (1)
#else
@@ -397,13 +358,31 @@ static inline void pmd_clear(pmd_t *pmdp)
set_pmd(pmdp, __pmd(0));
}
-static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
{
- return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
+ return pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK;
}
+/* Find an entry in the third-level page table. */
+#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+#define pte_offset_phys(dir,addr) (pmd_page_paddr(*(dir)) + pte_index(addr) * sizeof(pte_t))
+#define pte_offset_kernel(dir,addr) ((pte_t *)__va(pte_offset_phys((dir), (addr))))
+
+#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+
+#define pte_set_fixmap(addr) ((pte_t *)set_fixmap_offset(FIX_PTE, addr))
+#define pte_set_fixmap_offset(pmd, addr) pte_set_fixmap(pte_offset_phys(pmd, addr))
+#define pte_clear_fixmap() clear_fixmap(FIX_PTE)
+
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
+/* use ONLY for statically allocated translation tables */
+#define pte_offset_kimg(dir,addr) ((pte_t *)__phys_to_kimg(pte_offset_phys((dir), (addr))))
+
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
@@ -430,21 +409,37 @@ static inline void pud_clear(pud_t *pudp)
set_pud(pudp, __pud(0));
}
-static inline pmd_t *pud_page_vaddr(pud_t pud)
+static inline phys_addr_t pud_page_paddr(pud_t pud)
{
- return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
+ return 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_offset_phys(dir, addr) (pud_page_paddr(*(dir)) + pmd_index(addr) * sizeof(pmd_t))
+#define pmd_offset(dir, addr) ((pmd_t *)__va(pmd_offset_phys((dir), (addr))))
+
+#define pmd_set_fixmap(addr) ((pmd_t *)set_fixmap_offset(FIX_PMD, addr))
+#define pmd_set_fixmap_offset(pud, addr) pmd_set_fixmap(pmd_offset_phys(pud, addr))
+#define pmd_clear_fixmap() clear_fixmap(FIX_PMD)
#define pud_page(pud) pfn_to_page(__phys_to_pfn(pud_val(pud) & PHYS_MASK))
+/* use ONLY for statically allocated translation tables */
+#define pmd_offset_kimg(dir,addr) ((pmd_t *)__phys_to_kimg(pmd_offset_phys((dir), (addr))))
+
+#else
+
+#define pud_page_paddr(pud) ({ BUILD_BUG(); 0; })
+
+/* Match pmd_offset folding in <asm/generic/pgtable-nopmd.h> */
+#define pmd_set_fixmap(addr) NULL
+#define pmd_set_fixmap_offset(pudp, addr) ((pmd_t *)pudp)
+#define pmd_clear_fixmap()
+
+#define pmd_offset_kimg(dir,addr) ((pmd_t *)dir)
+
#endif /* CONFIG_PGTABLE_LEVELS > 2 */
#if CONFIG_PGTABLE_LEVELS > 3
@@ -466,21 +461,37 @@ static inline void pgd_clear(pgd_t *pgdp)
set_pgd(pgdp, __pgd(0));
}
-static inline pud_t *pgd_page_vaddr(pgd_t pgd)
+static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
{
- return __va(pgd_val(pgd) & PHYS_MASK & (s32)PAGE_MASK);
+ return pgd_val(pgd) & PHYS_MASK & (s32)PAGE_MASK;
}
/* Find an entry in the frst-level page table. */
#define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
-static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
-{
- return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
-}
+#define pud_offset_phys(dir, addr) (pgd_page_paddr(*(dir)) + pud_index(addr) * sizeof(pud_t))
+#define pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr))))
+
+#define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr))
+#define pud_set_fixmap_offset(pgd, addr) pud_set_fixmap(pud_offset_phys(pgd, addr))
+#define pud_clear_fixmap() clear_fixmap(FIX_PUD)
#define pgd_page(pgd) pfn_to_page(__phys_to_pfn(pgd_val(pgd) & PHYS_MASK))
+/* use ONLY for statically allocated translation tables */
+#define pud_offset_kimg(dir,addr) ((pud_t *)__phys_to_kimg(pud_offset_phys((dir), (addr))))
+
+#else
+
+#define pgd_page_paddr(pgd) ({ BUILD_BUG(); 0;})
+
+/* Match pud_offset folding in <asm/generic/pgtable-nopud.h> */
+#define pud_set_fixmap(addr) NULL
+#define pud_set_fixmap_offset(pgdp, addr) ((pud_t *)pgdp)
+#define pud_clear_fixmap()
+
+#define pud_offset_kimg(dir,addr) ((pud_t *)dir)
+
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
@@ -488,11 +499,16 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
/* to find an entry in a page-table-directory */
#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
+#define pgd_offset_raw(pgd, addr) ((pgd) + pgd_index(addr))
+
+#define pgd_offset(mm, addr) (pgd_offset_raw((mm)->pgd, (addr)))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
+#define pgd_set_fixmap(addr) ((pgd_t *)set_fixmap_offset(FIX_PGD, addr))
+#define pgd_clear_fixmap() clear_fixmap(FIX_PGD)
+
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
@@ -612,6 +628,7 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
* bits 0-1: present (must be zero)
* bits 2-7: swap type
* bits 8-57: swap offset
+ * bit 58: PTE_PROT_NONE (must be zero)
*/
#define __SWP_TYPE_SHIFT 2
#define __SWP_TYPE_BITS 6
@@ -637,7 +654,8 @@ extern int kern_addr_valid(unsigned long addr);
#include <asm-generic/pgtable.h>
-#define pgtable_cache_init() do { } while (0)
+void pgd_cache_init(void);
+#define pgtable_cache_init pgd_cache_init
/*
* On AArch64, the cache coherency is handled via the set_pte_at() function.
@@ -646,14 +664,17 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
/*
- * set_pte() does not have a DSB for user mappings, so make sure that
- * the page table write is visible.
+ * We don't do anything here, so there's a very small chance of
+ * us retaking a user fault which we just fixed up. The alternative
+ * is doing a dsb(ishst), but that penalises the fastpath.
*/
- dsb(ishst);
}
#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+#define kc_vaddr_to_offset(v) ((v) & ~VA_START)
+#define kc_offset_to_vaddr(o) ((o) | VA_START)
+
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/include/asm/pmu.h b/arch/arm64/include/asm/pmu.h
deleted file mode 100644
index b7710a5..0000000
--- a/arch/arm64/include/asm/pmu.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Based on arch/arm/include/asm/pmu.h
- *
- * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
- * Copyright (C) 2012 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_PMU_H
-#define __ASM_PMU_H
-
-#ifdef CONFIG_HW_PERF_EVENTS
-
-/* 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;
-
- /*
- * A 1 bit for an index indicates that the counter is being used for
- * an event. A 0 means that the counter can be used.
- */
- unsigned long *used_mask;
-
- /*
- * Hardware lock to serialize accesses to PMU registers. Needed for the
- * read/modify/write sequences.
- */
- raw_spinlock_t pmu_lock;
-};
-
-struct arm_pmu {
- struct pmu pmu;
- cpumask_t active_irqs;
- int *irq_affinity;
- const char *name;
- irqreturn_t (*handle_irq)(int irq_num, void *dev);
- void (*enable)(struct hw_perf_event *evt, int idx);
- void (*disable)(struct hw_perf_event *evt, int idx);
- int (*get_event_idx)(struct pmu_hw_events *hw_events,
- struct hw_perf_event *hwc);
- int (*set_event_filter)(struct hw_perf_event *evt,
- struct perf_event_attr *attr);
- u32 (*read_counter)(int idx);
- void (*write_counter)(int idx, u32 val);
- void (*start)(void);
- void (*stop)(void);
- void (*reset)(void *);
- 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 *(*get_hw_events)(void);
-};
-
-#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
-
-int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
-
-u64 armpmu_event_update(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx);
-
-int armpmu_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx);
-
-#endif /* CONFIG_HW_PERF_EVENTS */
-#endif /* __ASM_PMU_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 98f3235..cef1cf3 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -29,8 +29,10 @@
#include <linux/string.h>
+#include <asm/alternative.h>
#include <asm/fpsimd.h>
#include <asm/hw_breakpoint.h>
+#include <asm/lse.h>
#include <asm/pgtable-hwdef.h>
#include <asm/ptrace.h>
#include <asm/types.h>
@@ -177,15 +179,18 @@ static inline void prefetchw(const void *ptr)
}
#define ARCH_HAS_SPINLOCK_PREFETCH
-static inline void spin_lock_prefetch(const void *x)
+static inline void spin_lock_prefetch(const void *ptr)
{
- prefetchw(x);
+ asm volatile(ARM64_LSE_ATOMIC_INSN(
+ "prfm pstl1strm, %a0",
+ "nop") : : "p" (ptr));
}
#define HAVE_ARCH_PICK_MMAP_LAYOUT
#endif
-void cpu_enable_pan(void);
+void cpu_enable_pan(void *__unused);
+void cpu_enable_uao(void *__unused);
#endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 536274e..a307eb6 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,7 @@
#define COMPAT_PSR_Z_BIT 0x40000000
#define COMPAT_PSR_N_BIT 0x80000000
#define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
+#define COMPAT_PSR_GE_MASK 0x000f0000
#ifdef CONFIG_CPU_BIG_ENDIAN
#define COMPAT_PSR_ENDSTATE COMPAT_PSR_E_BIT
@@ -83,14 +84,14 @@
#define compat_sp regs[13]
#define compat_lr regs[14]
#define compat_sp_hyp regs[15]
-#define compat_sp_irq regs[16]
-#define compat_lr_irq regs[17]
-#define compat_sp_svc regs[18]
-#define compat_lr_svc regs[19]
-#define compat_sp_abt regs[20]
-#define compat_lr_abt regs[21]
-#define compat_sp_und regs[22]
-#define compat_lr_und regs[23]
+#define compat_lr_irq regs[16]
+#define compat_sp_irq regs[17]
+#define compat_lr_svc regs[18]
+#define compat_sp_svc regs[19]
+#define compat_lr_abt regs[20]
+#define compat_sp_abt regs[21]
+#define compat_lr_und regs[22]
+#define compat_sp_und regs[23]
#define compat_r8_fiq regs[24]
#define compat_r9_fiq regs[25]
#define compat_r10_fiq regs[26]
@@ -151,35 +152,9 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
return regs->regs[0];
}
-/*
- * Are the current registers suitable for user mode? (used to maintain
- * security in signal handlers)
- */
-static inline int valid_user_regs(struct user_pt_regs *regs)
-{
- if (user_mode(regs) && (regs->pstate & PSR_I_BIT) == 0) {
- regs->pstate &= ~(PSR_F_BIT | PSR_A_BIT);
-
- /* The T bit is reserved for AArch64 */
- if (!(regs->pstate & PSR_MODE32_BIT))
- regs->pstate &= ~COMPAT_PSR_T_BIT;
-
- return 1;
- }
-
- /*
- * Force PSR to something logical...
- */
- regs->pstate &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \
- COMPAT_PSR_T_BIT | PSR_MODE32_BIT;
-
- if (!(regs->pstate & PSR_MODE32_BIT)) {
- regs->pstate &= ~COMPAT_PSR_T_BIT;
- regs->pstate |= PSR_MODE_EL0t;
- }
-
- return 0;
-}
+/* We must avoid circular header include via sched.h */
+struct task_struct;
+int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
index 4df608a..e368a55 100644
--- a/arch/arm64/include/asm/shmparam.h
+++ b/arch/arm64/include/asm/shmparam.h
@@ -21,7 +21,7 @@
* alignment value. Since we don't have aliasing D-caches, the rest of
* the time we can safely use PAGE_SIZE.
*/
-#define COMPAT_SHMLBA 0x4000
+#define COMPAT_SHMLBA (4 * PAGE_SIZE)
#include <asm-generic/shmparam.h>
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index d9c3d6a..817a067 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -16,6 +16,19 @@
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
+/* Values for secondary_data.status */
+
+#define CPU_MMU_OFF (-1)
+#define CPU_BOOT_SUCCESS (0)
+/* The cpu invoked ops->cpu_die, synchronise it with cpu_kill */
+#define CPU_KILL_ME (1)
+/* The cpu couldn't die gracefully and is looping in the kernel */
+#define CPU_STUCK_IN_KERNEL (2)
+/* Fatal system error detected by secondary CPU, crash the system */
+#define CPU_PANIC_KERNEL (3)
+
+#ifndef __ASSEMBLY__
+
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/thread_info.h>
@@ -54,19 +67,52 @@ asmlinkage void secondary_start_kernel(void);
/*
* Initial data for bringing up a secondary CPU.
+ * @stack - sp for the secondary CPU
+ * @status - Result passed back from the secondary CPU to
+ * indicate failure.
*/
struct secondary_data {
void *stack;
+ long status;
};
+
extern struct secondary_data secondary_data;
+extern long __early_cpu_boot_status;
extern void secondary_entry(void);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+#else
+static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+ BUILD_BUG();
+}
+#endif
+
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void);
+extern void cpu_die_early(void);
+
+static inline void cpu_park_loop(void)
+{
+ for (;;) {
+ wfe();
+ wfi();
+ }
+}
+
+static inline void update_cpu_boot_status(int val)
+{
+ WRITE_ONCE(secondary_data.status, val);
+ /* Ensure the visibility of the status update */
+ dsb(ishst);
+}
+
+#endif /* ifndef __ASSEMBLY__ */
#endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
index c85e96d..fc9682b 100644
--- a/arch/arm64/include/asm/spinlock.h
+++ b/arch/arm64/include/asm/spinlock.h
@@ -26,9 +26,28 @@
* The memory barriers are implicit with the load-acquire and store-release
* instructions.
*/
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ unsigned int tmp;
+ arch_spinlock_t lockval;
-#define arch_spin_unlock_wait(lock) \
- do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
+ asm volatile(
+" sevl\n"
+"1: wfe\n"
+"2: ldaxr %w0, %2\n"
+" eor %w1, %w0, %w0, ror #16\n"
+" cbnz %w1, 1b\n"
+ ARM64_LSE_ATOMIC_INSN(
+ /* LL/SC */
+" stxr %w1, %w0, %2\n"
+" cbnz %w1, 2b\n", /* Serialise against any concurrent lockers */
+ /* LSE atomics */
+" nop\n"
+" nop\n")
+ : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
+ :
+ : "memory");
+}
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 7318f6d..801a16db 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -16,14 +16,19 @@
#ifndef __ASM_STACKTRACE_H
#define __ASM_STACKTRACE_H
+struct task_struct;
+
struct stackframe {
unsigned long fp;
unsigned long sp;
unsigned long pc;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ unsigned int graph;
+#endif
};
-extern int unwind_frame(struct stackframe *frame);
-extern void walk_stackframe(struct stackframe *frame,
+extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
+extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data);
#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 64d2d48..2eb714c 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -36,17 +36,33 @@ extern __kernel_size_t strnlen(const char *, __kernel_size_t);
#define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *__memcpy(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMMOVE
extern void *memmove(void *, const void *, __kernel_size_t);
+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 *__memset(void *, int, __kernel_size_t);
#define __HAVE_ARCH_MEMCMP
extern int memcmp(const void *, const void *, size_t);
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
#endif
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..1a78d6e 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -20,10 +20,9 @@
#ifndef __ASM_SYSREG_H
#define __ASM_SYSREG_H
-#include <asm/opcodes.h>
+#include <linux/stringify.h>
-#define SCTLR_EL1_CP15BEN (0x1 << 5)
-#define SCTLR_EL1_SED (0x1 << 8)
+#include <asm/opcodes.h>
/*
* ARMv8 ARM reserves the following encoding for system registers:
@@ -38,41 +37,200 @@
#define sys_reg(op0, op1, crn, crm, op2) \
((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
-#define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4)
-#define SCTLR_EL1_SPAN (1 << 23)
+#define SYS_MIDR_EL1 sys_reg(3, 0, 0, 0, 0)
+#define SYS_MPIDR_EL1 sys_reg(3, 0, 0, 0, 5)
+#define SYS_REVIDR_EL1 sys_reg(3, 0, 0, 0, 6)
+
+#define SYS_ID_PFR0_EL1 sys_reg(3, 0, 0, 1, 0)
+#define SYS_ID_PFR1_EL1 sys_reg(3, 0, 0, 1, 1)
+#define SYS_ID_DFR0_EL1 sys_reg(3, 0, 0, 1, 2)
+#define SYS_ID_MMFR0_EL1 sys_reg(3, 0, 0, 1, 4)
+#define SYS_ID_MMFR1_EL1 sys_reg(3, 0, 0, 1, 5)
+#define SYS_ID_MMFR2_EL1 sys_reg(3, 0, 0, 1, 6)
+#define SYS_ID_MMFR3_EL1 sys_reg(3, 0, 0, 1, 7)
+
+#define SYS_ID_ISAR0_EL1 sys_reg(3, 0, 0, 2, 0)
+#define SYS_ID_ISAR1_EL1 sys_reg(3, 0, 0, 2, 1)
+#define SYS_ID_ISAR2_EL1 sys_reg(3, 0, 0, 2, 2)
+#define SYS_ID_ISAR3_EL1 sys_reg(3, 0, 0, 2, 3)
+#define SYS_ID_ISAR4_EL1 sys_reg(3, 0, 0, 2, 4)
+#define SYS_ID_ISAR5_EL1 sys_reg(3, 0, 0, 2, 5)
+#define SYS_ID_MMFR4_EL1 sys_reg(3, 0, 0, 2, 6)
+
+#define SYS_MVFR0_EL1 sys_reg(3, 0, 0, 3, 0)
+#define SYS_MVFR1_EL1 sys_reg(3, 0, 0, 3, 1)
+#define SYS_MVFR2_EL1 sys_reg(3, 0, 0, 3, 2)
+
+#define SYS_ID_AA64PFR0_EL1 sys_reg(3, 0, 0, 4, 0)
+#define SYS_ID_AA64PFR1_EL1 sys_reg(3, 0, 0, 4, 1)
+
+#define SYS_ID_AA64DFR0_EL1 sys_reg(3, 0, 0, 5, 0)
+#define SYS_ID_AA64DFR1_EL1 sys_reg(3, 0, 0, 5, 1)
+
+#define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0)
+#define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1)
+
+#define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0)
+#define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1)
+#define SYS_ID_AA64MMFR2_EL1 sys_reg(3, 0, 0, 7, 2)
+
+#define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0)
+#define SYS_CTR_EL0 sys_reg(3, 3, 0, 0, 1)
+#define SYS_DCZID_EL0 sys_reg(3, 3, 0, 0, 7)
+
+#define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4)
+#define REG_PSTATE_UAO_IMM sys_reg(0, 0, 4, 0, 3)
#define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
(!!x)<<8 | 0x1f)
+#define SET_PSTATE_UAO(x) __inst_arm(0xd5000000 | REG_PSTATE_UAO_IMM |\
+ (!!x)<<8 | 0x1f)
+
+/* SCTLR_EL1 */
+#define SCTLR_EL1_CP15BEN (0x1 << 5)
+#define SCTLR_EL1_SED (0x1 << 8)
+#define SCTLR_EL1_SPAN (0x1 << 23)
+
+
+/* id_aa64isar0 */
+#define ID_AA64ISAR0_RDM_SHIFT 28
+#define ID_AA64ISAR0_ATOMICS_SHIFT 20
+#define ID_AA64ISAR0_CRC32_SHIFT 16
+#define ID_AA64ISAR0_SHA2_SHIFT 12
+#define ID_AA64ISAR0_SHA1_SHIFT 8
+#define ID_AA64ISAR0_AES_SHIFT 4
+
+/* id_aa64pfr0 */
+#define ID_AA64PFR0_GIC_SHIFT 24
+#define ID_AA64PFR0_ASIMD_SHIFT 20
+#define ID_AA64PFR0_FP_SHIFT 16
+#define ID_AA64PFR0_EL3_SHIFT 12
+#define ID_AA64PFR0_EL2_SHIFT 8
+#define ID_AA64PFR0_EL1_SHIFT 4
+#define ID_AA64PFR0_EL0_SHIFT 0
+
+#define ID_AA64PFR0_FP_NI 0xf
+#define ID_AA64PFR0_FP_SUPPORTED 0x0
+#define ID_AA64PFR0_ASIMD_NI 0xf
+#define ID_AA64PFR0_ASIMD_SUPPORTED 0x0
+#define ID_AA64PFR0_EL1_64BIT_ONLY 0x1
+#define ID_AA64PFR0_EL0_64BIT_ONLY 0x1
+
+/* id_aa64mmfr0 */
+#define ID_AA64MMFR0_TGRAN4_SHIFT 28
+#define ID_AA64MMFR0_TGRAN64_SHIFT 24
+#define ID_AA64MMFR0_TGRAN16_SHIFT 20
+#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
+#define ID_AA64MMFR0_SNSMEM_SHIFT 12
+#define ID_AA64MMFR0_BIGENDEL_SHIFT 8
+#define ID_AA64MMFR0_ASID_SHIFT 4
+#define ID_AA64MMFR0_PARANGE_SHIFT 0
+
+#define ID_AA64MMFR0_TGRAN4_NI 0xf
+#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN64_NI 0xf
+#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN16_NI 0x0
+#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1
+
+/* id_aa64mmfr1 */
+#define ID_AA64MMFR1_PAN_SHIFT 20
+#define ID_AA64MMFR1_LOR_SHIFT 16
+#define ID_AA64MMFR1_HPD_SHIFT 12
+#define ID_AA64MMFR1_VHE_SHIFT 8
+#define ID_AA64MMFR1_VMIDBITS_SHIFT 4
+#define ID_AA64MMFR1_HADBS_SHIFT 0
+
+/* id_aa64mmfr2 */
+#define ID_AA64MMFR2_UAO_SHIFT 4
+
+/* id_aa64dfr0 */
+#define ID_AA64DFR0_CTX_CMPS_SHIFT 28
+#define ID_AA64DFR0_WRPS_SHIFT 20
+#define ID_AA64DFR0_BRPS_SHIFT 12
+#define ID_AA64DFR0_PMUVER_SHIFT 8
+#define ID_AA64DFR0_TRACEVER_SHIFT 4
+#define ID_AA64DFR0_DEBUGVER_SHIFT 0
+
+#define ID_ISAR5_RDM_SHIFT 24
+#define ID_ISAR5_CRC32_SHIFT 16
+#define ID_ISAR5_SHA2_SHIFT 12
+#define ID_ISAR5_SHA1_SHIFT 8
+#define ID_ISAR5_AES_SHIFT 4
+#define ID_ISAR5_SEVL_SHIFT 0
+
+#define MVFR0_FPROUND_SHIFT 28
+#define MVFR0_FPSHVEC_SHIFT 24
+#define MVFR0_FPSQRT_SHIFT 20
+#define MVFR0_FPDIVIDE_SHIFT 16
+#define MVFR0_FPTRAP_SHIFT 12
+#define MVFR0_FPDP_SHIFT 8
+#define MVFR0_FPSP_SHIFT 4
+#define MVFR0_SIMD_SHIFT 0
+
+#define MVFR1_SIMDFMAC_SHIFT 28
+#define MVFR1_FPHP_SHIFT 24
+#define MVFR1_SIMDHP_SHIFT 20
+#define MVFR1_SIMDSP_SHIFT 16
+#define MVFR1_SIMDINT_SHIFT 12
+#define MVFR1_SIMDLS_SHIFT 8
+#define MVFR1_FPDNAN_SHIFT 4
+#define MVFR1_FPFTZ_SHIFT 0
+
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT 28
+#define ID_AA64MMFR0_TGRAN64_SHIFT 24
+#define ID_AA64MMFR0_TGRAN16_SHIFT 20
+
+#define ID_AA64MMFR0_TGRAN4_NI 0xf
+#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN64_NI 0xf
+#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0
+#define ID_AA64MMFR0_TGRAN16_NI 0x0
+#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1
+
+#if defined(CONFIG_ARM64_4K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN4_SUPPORTED
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN16_SUPPORTED
+#elif defined(CONFIG_ARM64_64K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN64_SUPPORTED
+#endif
#ifdef __ASSEMBLY__
.irp num,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
- .equ __reg_num_x\num, \num
+ .equ .L__reg_num_x\num, \num
.endr
- .equ __reg_num_xzr, 31
+ .equ .L__reg_num_xzr, 31
.macro mrs_s, rt, sreg
- .inst 0xd5200000|(\sreg)|(__reg_num_\rt)
+ .inst 0xd5200000|(\sreg)|(.L__reg_num_\rt)
.endm
.macro msr_s, sreg, rt
- .inst 0xd5000000|(\sreg)|(__reg_num_\rt)
+ .inst 0xd5000000|(\sreg)|(.L__reg_num_\rt)
.endm
#else
+#include <linux/types.h>
+
asm(
" .irp num,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\n"
-" .equ __reg_num_x\\num, \\num\n"
+" .equ .L__reg_num_x\\num, \\num\n"
" .endr\n"
-" .equ __reg_num_xzr, 31\n"
+" .equ .L__reg_num_xzr, 31\n"
"\n"
" .macro mrs_s, rt, sreg\n"
-" .inst 0xd5200000|(\\sreg)|(__reg_num_\\rt)\n"
+" .inst 0xd5200000|(\\sreg)|(.L__reg_num_\\rt)\n"
" .endm\n"
"\n"
" .macro msr_s, sreg, rt\n"
-" .inst 0xd5000000|(\\sreg)|(__reg_num_\\rt)\n"
+" .inst 0xd5000000|(\\sreg)|(.L__reg_num_\\rt)\n"
" .endm\n"
);
@@ -85,6 +243,23 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
val |= set;
asm volatile("msr sctlr_el1, %0" : : "r" (val));
}
+
+/*
+ * Unlike read_cpuid, calls to read_sysreg are never expected to be
+ * optimized away or replaced with synthetic values.
+ */
+#define read_sysreg(r) ({ \
+ u64 __val; \
+ asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
+ __val; \
+})
+
+#define write_sysreg(v, r) do { \
+ u64 __val = (u64)v; \
+ asm volatile("msr " __stringify(r) ", %0" \
+ : : "r" (__val)); \
+} while (0)
+
#endif
#endif /* __ASM_SYSREG_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index dcd06d1..abd64bd 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -23,8 +23,10 @@
#include <linux/compiler.h>
-#ifndef CONFIG_ARM64_64K_PAGES
+#ifdef CONFIG_ARM64_4K_PAGES
#define THREAD_SIZE_ORDER 2
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define THREAD_SIZE_ORDER 0
#endif
#define THREAD_SIZE 16384
@@ -71,10 +73,16 @@ register unsigned long current_stack_pointer asm ("sp");
*/
static inline struct thread_info *current_thread_info(void) __attribute_const__;
+/*
+ * struct thread_info can be accessed directly via sp_el0.
+ */
static inline struct thread_info *current_thread_info(void)
{
- return (struct thread_info *)
- (current_stack_pointer & ~(THREAD_SIZE - 1));
+ unsigned long sp_el0;
+
+ asm ("mrs %0, sp_el0" : "=r" (sp_el0));
+
+ return (struct thread_info *)sp_el0;
}
#define thread_saved_pc(tsk) \
@@ -111,7 +119,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK 20
#define TIF_SINGLESTEP 21
#define TIF_32BIT 22 /* 32bit process */
-#define TIF_SWITCH_MM 23 /* deferred switch_mm */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index d6e6b66..ffdaea7 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -37,17 +37,21 @@ static inline void __tlb_remove_table(void *_table)
static inline void tlb_flush(struct mmu_gather *tlb)
{
- if (tlb->fullmm) {
- flush_tlb_mm(tlb->mm);
- } else {
- struct vm_area_struct vma = { .vm_mm = tlb->mm, };
- /*
- * The intermediate page table levels are already handled by
- * the __(pte|pmd|pud)_free_tlb() functions, so last level
- * TLBI is sufficient here.
- */
- __flush_tlb_range(&vma, tlb->start, tlb->end, true);
- }
+ struct vm_area_struct vma = { .vm_mm = tlb->mm, };
+
+ /*
+ * The ASID allocator will either invalidate the ASID or mark
+ * it as used.
+ */
+ if (tlb->fullmm)
+ return;
+
+ /*
+ * The intermediate page table levels are already handled by
+ * the __(pte|pmd|pud)_free_tlb() functions, so last level
+ * TLBI is sufficient here.
+ */
+ __flush_tlb_range(&vma, tlb->start, tlb->end, true);
}
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 7bd2da0..b460ae2 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -63,6 +63,14 @@
* only require the D-TLB to be invalidated.
* - kaddr - Kernel virtual memory address
*/
+static inline void local_flush_tlb_all(void)
+{
+ dsb(nshst);
+ asm("tlbi vmalle1");
+ dsb(nsh);
+ isb();
+}
+
static inline void flush_tlb_all(void)
{
dsb(ishst);
@@ -73,7 +81,7 @@ static inline void flush_tlb_all(void)
static inline void flush_tlb_mm(struct mm_struct *mm)
{
- unsigned long asid = (unsigned long)ASID(mm) << 48;
+ unsigned long asid = ASID(mm) << 48;
dsb(ishst);
asm("tlbi aside1is, %0" : : "r" (asid));
@@ -83,8 +91,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long uaddr)
{
- unsigned long addr = uaddr >> 12 |
- ((unsigned long)ASID(vma->vm_mm) << 48);
+ unsigned long addr = uaddr >> 12 | (ASID(vma->vm_mm) << 48);
dsb(ishst);
asm("tlbi vale1is, %0" : : "r" (addr));
@@ -101,7 +108,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end,
bool last_level)
{
- unsigned long asid = (unsigned long)ASID(vma->vm_mm) << 48;
+ unsigned long asid = ASID(vma->vm_mm) << 48;
unsigned long addr;
if ((end - start) > MAX_TLB_RANGE) {
@@ -154,9 +161,8 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
static inline void __flush_tlb_pgtable(struct mm_struct *mm,
unsigned long uaddr)
{
- unsigned long addr = uaddr >> 12 | ((unsigned long)ASID(mm) << 48);
+ unsigned long addr = uaddr >> 12 | (ASID(mm) << 48);
- dsb(ishst);
asm("tlbi vae1is, %0" : : "r" (addr));
dsb(ish);
}
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index b2ede967..0685d74 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -36,11 +36,11 @@
#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.
+ * The exception table consists of pairs of relative offsets: the first
+ * is the relative offset to an instruction that is allowed to fault,
+ * and the second is the relative offset 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,
@@ -50,9 +50,11 @@
struct exception_table_entry
{
- unsigned long insn, fixup;
+ int insn, fixup;
};
+#define ARCH_HAS_RELATIVE_EXTABLE
+
extern int fixup_exception(struct pt_regs *regs);
#define KERNEL_DS (-1UL)
@@ -64,6 +66,16 @@ extern int fixup_exception(struct pt_regs *regs);
static inline void set_fs(mm_segment_t fs)
{
current_thread_info()->addr_limit = fs;
+
+ /*
+ * Enable/disable UAO so that copy_to_user() etc can access
+ * kernel memory with the unprivileged instructions.
+ */
+ if (IS_ENABLED(CONFIG_ARM64_UAO) && fs == KERNEL_DS)
+ asm(ALTERNATIVE("nop", SET_PSTATE_UAO(1), ARM64_HAS_UAO));
+ else
+ asm(ALTERNATIVE("nop", SET_PSTATE_UAO(0), ARM64_HAS_UAO,
+ CONFIG_ARM64_UAO));
}
#define segment_eq(a, b) ((a) == (b))
@@ -105,6 +117,12 @@ static inline void set_fs(mm_segment_t fs)
#define access_ok(type, addr, size) __range_ok(addr, size)
#define user_addr_max get_fs
+#define _ASM_EXTABLE(from, to) \
+ " .pushsection __ex_table, \"a\"\n" \
+ " .align 3\n" \
+ " .long (" #from " - .), (" #to " - .)\n" \
+ " .popsection\n"
+
/*
* 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()"
@@ -113,9 +131,10 @@ static inline void set_fs(mm_segment_t fs)
* The "__xxx_error" versions set the third argument to -EFAULT if an error
* occurs, and leave it unchanged on success.
*/
-#define __get_user_asm(instr, reg, x, addr, err) \
+#define __get_user_asm(instr, alt_instr, reg, x, addr, err, feature) \
asm volatile( \
- "1: " instr " " reg "1, [%2]\n" \
+ "1:"ALTERNATIVE(instr " " reg "1, [%2]\n", \
+ alt_instr " " reg "1, [%2]\n", feature) \
"2:\n" \
" .section .fixup, \"ax\"\n" \
" .align 2\n" \
@@ -123,10 +142,7 @@ static inline void set_fs(mm_segment_t fs)
" mov %1, #0\n" \
" b 2b\n" \
" .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .quad 1b, 3b\n" \
- " .previous" \
+ _ASM_EXTABLE(1b, 3b) \
: "+r" (err), "=&r" (x) \
: "r" (addr), "i" (-EFAULT))
@@ -134,26 +150,30 @@ static inline void set_fs(mm_segment_t fs)
do { \
unsigned long __gu_val; \
__chk_user_ptr(ptr); \
- asm(ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
+ asm(ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_ALT_PAN_NOT_UAO,\
CONFIG_ARM64_PAN)); \
switch (sizeof(*(ptr))) { \
case 1: \
- __get_user_asm("ldrb", "%w", __gu_val, (ptr), (err)); \
+ __get_user_asm("ldrb", "ldtrb", "%w", __gu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 2: \
- __get_user_asm("ldrh", "%w", __gu_val, (ptr), (err)); \
+ __get_user_asm("ldrh", "ldtrh", "%w", __gu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 4: \
- __get_user_asm("ldr", "%w", __gu_val, (ptr), (err)); \
+ __get_user_asm("ldr", "ldtr", "%w", __gu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 8: \
- __get_user_asm("ldr", "%", __gu_val, (ptr), (err)); \
+ __get_user_asm("ldr", "ldtr", "%", __gu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
default: \
BUILD_BUG(); \
} \
(x) = (__force __typeof__(*(ptr)))__gu_val; \
- asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
+ asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_ALT_PAN_NOT_UAO,\
CONFIG_ARM64_PAN)); \
} while (0)
@@ -181,19 +201,17 @@ do { \
((x) = 0, -EFAULT); \
})
-#define __put_user_asm(instr, reg, x, addr, err) \
+#define __put_user_asm(instr, alt_instr, reg, x, addr, err, feature) \
asm volatile( \
- "1: " instr " " reg "1, [%2]\n" \
+ "1:"ALTERNATIVE(instr " " reg "1, [%2]\n", \
+ alt_instr " " reg "1, [%2]\n", feature) \
"2:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %w0, %3\n" \
" b 2b\n" \
" .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .quad 1b, 3b\n" \
- " .previous" \
+ _ASM_EXTABLE(1b, 3b) \
: "+r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT))
@@ -201,25 +219,29 @@ do { \
do { \
__typeof__(*(ptr)) __pu_val = (x); \
__chk_user_ptr(ptr); \
- asm(ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
+ asm(ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_ALT_PAN_NOT_UAO,\
CONFIG_ARM64_PAN)); \
switch (sizeof(*(ptr))) { \
case 1: \
- __put_user_asm("strb", "%w", __pu_val, (ptr), (err)); \
+ __put_user_asm("strb", "sttrb", "%w", __pu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 2: \
- __put_user_asm("strh", "%w", __pu_val, (ptr), (err)); \
+ __put_user_asm("strh", "sttrh", "%w", __pu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 4: \
- __put_user_asm("str", "%w", __pu_val, (ptr), (err)); \
+ __put_user_asm("str", "sttr", "%w", __pu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
case 8: \
- __put_user_asm("str", "%", __pu_val, (ptr), (err)); \
+ __put_user_asm("str", "sttr", "%", __pu_val, (ptr), \
+ (err), ARM64_HAS_UAO); \
break; \
default: \
BUILD_BUG(); \
} \
- asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
+ asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_ALT_PAN_NOT_UAO,\
CONFIG_ARM64_PAN)); \
} while (0)
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 7a5df52..9f22dd6 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -23,6 +23,8 @@
#ifndef __ASSEMBLY__
+#include <asm/ptrace.h>
+
/*
* __boot_cpu_mode records what mode CPUs were booted in.
* A correctly-implemented bootloader must start all CPUs in the same mode:
@@ -50,6 +52,14 @@ static inline bool is_hyp_mode_mismatched(void)
return __boot_cpu_mode[0] != __boot_cpu_mode[1];
}
+static inline bool is_kernel_in_hyp_mode(void)
+{
+ u64 el;
+
+ asm("mrs %0, CurrentEL" : "=r" (el));
+ return el == CurrentEL_EL2;
+}
+
/* The section containing the hypervisor text */
extern char __hyp_text_start[];
extern char __hyp_text_end[];
diff --git a/arch/arm64/include/asm/word-at-a-time.h b/arch/arm64/include/asm/word-at-a-time.h
index aab5bf0..2b79b8a 100644
--- a/arch/arm64/include/asm/word-at-a-time.h
+++ b/arch/arm64/include/asm/word-at-a-time.h
@@ -16,6 +16,8 @@
#ifndef __ASM_WORD_AT_A_TIME_H
#define __ASM_WORD_AT_A_TIME_H
+#include <asm/uaccess.h>
+
#ifndef __AARCH64EB__
#include <linux/kernel.h>
@@ -81,10 +83,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
#endif
" b 2b\n"
" .popsection\n"
- " .pushsection __ex_table,\"a\"\n"
- " .align 3\n"
- " .quad 1b, 3b\n"
- " .popsection"
+ _ASM_EXTABLE(1b, 3b)
: "=&r" (ret), "=&r" (offset)
: "r" (addr), "Q" (*(unsigned long *)addr));
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 361c8a8..a739287 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -28,5 +28,7 @@
#define HWCAP_SHA2 (1 << 6)
#define HWCAP_CRC32 (1 << 7)
#define HWCAP_ATOMICS (1 << 8)
+#define HWCAP_FPHP (1 << 9)
+#define HWCAP_ASIMDHP (1 << 10)
#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 0cd7b59..f209ea1 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -32,7 +32,7 @@
#ifndef __ASSEMBLY__
#include <linux/psci.h>
-#include <asm/types.h>
+#include <linux/types.h>
#include <asm/ptrace.h>
#define __KVM_HAVE_GUEST_DEBUG
@@ -94,6 +94,7 @@ struct kvm_regs {
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
+#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */
struct kvm_vcpu_init {
__u32 target;
@@ -204,6 +205,11 @@ struct kvm_arch_memory_slot {
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
+/* Device Control API on vcpu fd */
+#define KVM_ARM_VCPU_PMU_V3_CTRL 0
+#define KVM_ARM_VCPU_PMU_V3_IRQ 0
+#define KVM_ARM_VCPU_PMU_V3_INIT 1
+
/* KVM_IRQ_LINE irq field index values */
#define KVM_ARM_IRQ_TYPE_SHIFT 24
#define KVM_ARM_IRQ_TYPE_MASK 0xff
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 208db3d..b5c3933 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -45,6 +45,7 @@
#define PSR_A_BIT 0x00000100
#define PSR_D_BIT 0x00000200
#define PSR_PAN_BIT 0x00400000
+#define PSR_UAO_BIT 0x00800000
#define PSR_Q_BIT 0x08000000
#define PSR_V_BIT 0x10000000
#define PSR_C_BIT 0x20000000
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 22dc9bc..3793003 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -4,7 +4,6 @@
CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
-CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
CFLAGS_armv8_deprecated.o := -I$(src)
CFLAGS_REMOVE_ftrace.o = -pg
@@ -15,16 +14,23 @@ CFLAGS_REMOVE_return_address.o = -pg
arm64-obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
entry-fpsimd.o process.o ptrace.o setup.o signal.o \
sys.o stacktrace.o time.o traps.o io.o vdso.o \
- hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \
+ hyp-stub.o psci.o cpu_ops.o insn.o \
return_address.o cpuinfo.o cpu_errata.o \
cpufeature.o alternative.o cacheinfo.o \
- smp.o smp_spin_table.o topology.o
+ smp.o smp_spin_table.o topology.o smccc-call.o
+
+extra-$(CONFIG_EFI) := efi-entry.o
+
+OBJCOPYFLAGS := --prefix-symbols=__efistub_
+$(obj)/%.stub.o: $(obj)/%.o FORCE
+ $(call if_changed,objcopy)
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
sys_compat.o entry32.o \
../../arm/kernel/opcodes.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
+arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
@@ -32,15 +38,18 @@ arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
arm64-obj-$(CONFIG_KGDB) += kgdb.o
-arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o
+arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
arm64-obj-$(CONFIG_PCI) += pci.o
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
arm64-obj-$(CONFIG_ACPI) += acpi.o
+arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
+arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
+arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
head-y := head.o
-extra-y := $(head-y) vmlinux.lds
+extra-y += $(head-y) vmlinux.lds
# vDSO - this must be built first to generate the symbol offsets
$(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 19de753..d1ce8e2 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -29,6 +29,11 @@
#include <asm/cpu_ops.h>
#include <asm/smp_plat.h>
+#ifdef CONFIG_ACPI_APEI
+# include <linux/efi.h>
+# include <asm/pgtable.h>
+#endif
+
int acpi_noirq = 1; /* skip ACPI IRQ initialization */
int acpi_disabled = 1;
EXPORT_SYMBOL(acpi_disabled);
@@ -206,27 +211,26 @@ void __init acpi_boot_table_init(void)
}
}
-void __init acpi_gic_init(void)
+#ifdef CONFIG_ACPI_APEI
+pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
{
- struct acpi_table_header *table;
- acpi_status status;
- acpi_size tbl_size;
- int err;
-
- if (acpi_disabled)
- return;
-
- status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
- if (ACPI_FAILURE(status)) {
- const char *msg = acpi_format_exception(status);
-
- pr_err("Failed to get MADT table, %s\n", msg);
- return;
- }
+ /*
+ * According to "Table 8 Map: EFI memory types to AArch64 memory
+ * types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is
+ * mapped to a corresponding MAIR attribute encoding.
+ * The EFI memory attribute advises all possible capabilities
+ * of a memory region. We use the most efficient capability.
+ */
- err = gic_v2_acpi_init(table);
- if (err)
- pr_err("Failed to initialize GIC IRQ controller");
+ u64 attr;
- early_acpi_os_unmap_memory((char *)table, tbl_size);
+ attr = efi_mem_attributes(addr);
+ if (attr & EFI_MEMORY_WB)
+ return PAGE_KERNEL;
+ if (attr & EFI_MEMORY_WT)
+ return __pgprot(PROT_NORMAL_WT);
+ if (attr & EFI_MEMORY_WC)
+ return __pgprot(PROT_NORMAL_NC);
+ return __pgprot(PROT_DEVICE_nGnRnE);
}
+#endif
diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c
new file mode 100644
index 0000000..a32b401
--- /dev/null
+++ b/arch/arm64/kernel/acpi_parking_protocol.c
@@ -0,0 +1,141 @@
+/*
+ * ARM64 ACPI Parking Protocol implementation
+ *
+ * Authors: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ * Mark Salter <msalter@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/acpi.h>
+#include <linux/types.h>
+
+#include <asm/cpu_ops.h>
+
+struct parking_protocol_mailbox {
+ __le32 cpu_id;
+ __le32 reserved;
+ __le64 entry_point;
+};
+
+struct cpu_mailbox_entry {
+ struct parking_protocol_mailbox __iomem *mailbox;
+ phys_addr_t mailbox_addr;
+ u8 version;
+ u8 gic_cpu_id;
+};
+
+static struct cpu_mailbox_entry cpu_mailbox_entries[NR_CPUS];
+
+void __init acpi_set_mailbox_entry(int cpu,
+ struct acpi_madt_generic_interrupt *p)
+{
+ struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+
+ cpu_entry->mailbox_addr = p->parked_address;
+ cpu_entry->version = p->parking_version;
+ cpu_entry->gic_cpu_id = p->cpu_interface_number;
+}
+
+bool acpi_parking_protocol_valid(int cpu)
+{
+ struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+
+ return cpu_entry->mailbox_addr && cpu_entry->version;
+}
+
+static int acpi_parking_protocol_cpu_init(unsigned int cpu)
+{
+ pr_debug("%s: ACPI parked addr=%llx\n", __func__,
+ cpu_mailbox_entries[cpu].mailbox_addr);
+
+ return 0;
+}
+
+static int acpi_parking_protocol_cpu_prepare(unsigned int cpu)
+{
+ return 0;
+}
+
+static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
+{
+ struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+ struct parking_protocol_mailbox __iomem *mailbox;
+ __le32 cpu_id;
+
+ /*
+ * Map mailbox memory with attribute device nGnRE (ie ioremap -
+ * this deviates from the parking protocol specifications since
+ * the mailboxes are required to be mapped nGnRnE; the attribute
+ * discrepancy is harmless insofar as the protocol specification
+ * is concerned).
+ * If the mailbox is mistakenly allocated in the linear mapping
+ * by FW ioremap will fail since the mapping will be prevented
+ * by the kernel (it clashes with the linear mapping attributes
+ * specifications).
+ */
+ mailbox = ioremap(cpu_entry->mailbox_addr, sizeof(*mailbox));
+ if (!mailbox)
+ return -EIO;
+
+ cpu_id = readl_relaxed(&mailbox->cpu_id);
+ /*
+ * Check if firmware has set-up the mailbox entry properly
+ * before kickstarting the respective cpu.
+ */
+ if (cpu_id != ~0U) {
+ iounmap(mailbox);
+ return -ENXIO;
+ }
+
+ /*
+ * stash the mailbox address mapping to use it for further FW
+ * checks in the postboot method
+ */
+ cpu_entry->mailbox = mailbox;
+
+ /*
+ * We write the entry point and cpu id as LE regardless of the
+ * native endianness of the kernel. Therefore, any boot-loaders
+ * that read this address need to convert this address to the
+ * Boot-Loader's endianness before jumping.
+ */
+ writeq_relaxed(__pa(secondary_entry), &mailbox->entry_point);
+ writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
+
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+ return 0;
+}
+
+static void acpi_parking_protocol_cpu_postboot(void)
+{
+ int cpu = smp_processor_id();
+ struct cpu_mailbox_entry *cpu_entry = &cpu_mailbox_entries[cpu];
+ struct parking_protocol_mailbox __iomem *mailbox = cpu_entry->mailbox;
+ __le64 entry_point;
+
+ entry_point = readl_relaxed(&mailbox->entry_point);
+ /*
+ * Check if firmware has cleared the entry_point as expected
+ * by the protocol specification.
+ */
+ WARN_ON(entry_point);
+}
+
+const struct cpu_operations acpi_parking_protocol_ops = {
+ .name = "parking-protocol",
+ .cpu_init = acpi_parking_protocol_cpu_init,
+ .cpu_prepare = acpi_parking_protocol_cpu_prepare,
+ .cpu_boot = acpi_parking_protocol_cpu_boot,
+ .cpu_postboot = acpi_parking_protocol_cpu_postboot
+};
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index ab9db0e..d2ee1b2 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -158,9 +158,3 @@ void apply_alternatives(void *start, size_t length)
__apply_alternatives(&region);
}
-
-void free_alternatives_memory(void)
-{
- free_reserved_area(__alt_instructions, __alt_instructions_end,
- 0, "alternatives");
-}
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
index a85843d..678f30b0 100644
--- a/arch/arm64/kernel/arm64ksyms.c
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -26,6 +26,7 @@
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/arm-smccc.h>
#include <asm/checksum.h>
@@ -51,6 +52,9 @@ EXPORT_SYMBOL(strnlen);
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__memset);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(__memmove);
EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(memcmp);
@@ -65,3 +69,7 @@ EXPORT_SYMBOL(test_and_change_bit);
#ifdef CONFIG_FUNCTION_TRACER
EXPORT_SYMBOL(_mcount);
#endif
+
+ /* arm-smccc */
+EXPORT_SYMBOL(arm_smccc_smc);
+EXPORT_SYMBOL(arm_smccc_hvc);
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 937f5e5..c37202c 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -62,7 +62,7 @@ struct insn_emulation {
};
static LIST_HEAD(insn_emulation);
-static int nr_insn_emulated;
+static int nr_insn_emulated __initdata;
static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
static void register_emulation_hooks(struct insn_emulation_ops *ops)
@@ -173,7 +173,7 @@ static int update_insn_emulation_mode(struct insn_emulation *insn,
return ret;
}
-static void register_insn_emulation(struct insn_emulation_ops *ops)
+static void __init register_insn_emulation(struct insn_emulation_ops *ops)
{
unsigned long flags;
struct insn_emulation *insn;
@@ -237,7 +237,7 @@ static struct ctl_table ctl_abi[] = {
{ }
};
-static void register_insn_emulation_sysctl(struct ctl_table *table)
+static void __init register_insn_emulation_sysctl(struct ctl_table *table)
{
unsigned long flags;
int i = 0;
@@ -297,11 +297,8 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
"4: mov %w0, %w5\n" \
" b 3b\n" \
" .popsection" \
- " .pushsection __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .quad 0b, 4b\n" \
- " .quad 1b, 4b\n" \
- " .popsection\n" \
+ _ASM_EXTABLE(0b, 4b) \
+ _ASM_EXTABLE(1b, 4b) \
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
CONFIG_ARM64_PAN) \
: "=&r" (res), "+r" (data), "=&r" (temp) \
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 8d89cf8..3ae6b31 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -28,6 +28,7 @@
#include <asm/suspend.h>
#include <asm/vdso_datapage.h>
#include <linux/kbuild.h>
+#include <linux/arm-smccc.h>
int main(void)
{
@@ -60,7 +61,7 @@ int main(void)
DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno));
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK();
- DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
+ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));
BLANK();
DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
@@ -103,54 +104,15 @@ int main(void)
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
+ DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
+ BLANK();
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs));
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
- DEFINE(CPU_SP_EL1, offsetof(struct kvm_regs, sp_el1));
- DEFINE(CPU_ELR_EL1, offsetof(struct kvm_regs, elr_el1));
- DEFINE(CPU_SPSR, offsetof(struct kvm_regs, spsr));
- DEFINE(CPU_SYSREGS, offsetof(struct kvm_cpu_context, sys_regs));
- DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2));
- DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2));
- DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
- DEFINE(VCPU_DEBUG_FLAGS, offsetof(struct kvm_vcpu, arch.debug_flags));
- DEFINE(VCPU_DEBUG_PTR, offsetof(struct kvm_vcpu, arch.debug_ptr));
- DEFINE(DEBUG_BCR, offsetof(struct kvm_guest_debug_arch, dbg_bcr));
- DEFINE(DEBUG_BVR, offsetof(struct kvm_guest_debug_arch, dbg_bvr));
- DEFINE(DEBUG_WCR, offsetof(struct kvm_guest_debug_arch, dbg_wcr));
- DEFINE(DEBUG_WVR, offsetof(struct kvm_guest_debug_arch, dbg_wvr));
- DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2));
- DEFINE(VCPU_MDCR_EL2, offsetof(struct kvm_vcpu, arch.mdcr_el2));
- DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
+ DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2]));
DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
- DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, arch.host_debug_state));
- 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(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
- 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_V3_CPU_SRE, offsetof(struct vgic_cpu, vgic_v3.vgic_sre));
- DEFINE(VGIC_V3_CPU_HCR, offsetof(struct vgic_cpu, vgic_v3.vgic_hcr));
- DEFINE(VGIC_V3_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr));
- DEFINE(VGIC_V3_CPU_MISR, offsetof(struct vgic_cpu, vgic_v3.vgic_misr));
- DEFINE(VGIC_V3_CPU_EISR, offsetof(struct vgic_cpu, vgic_v3.vgic_eisr));
- DEFINE(VGIC_V3_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr));
- DEFINE(VGIC_V3_CPU_AP0R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r));
- DEFINE(VGIC_V3_CPU_AP1R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r));
- DEFINE(VGIC_V3_CPU_LR, offsetof(struct vgic_cpu, vgic_v3.vgic_lr));
- DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
- DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
- DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
#endif
#ifdef CONFIG_CPU_PM
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
@@ -161,5 +123,7 @@ int main(void)
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
+ DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
+ DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
return 0;
}
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 6ffd914..06afd04 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -21,23 +21,12 @@
#include <asm/cputype.h>
#include <asm/cpufeature.h>
-#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
-#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
-
-#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
- MIDR_ARCHITECTURE_MASK)
-
static bool __maybe_unused
is_affected_midr_range(const struct arm64_cpu_capabilities *entry)
{
- u32 midr = read_cpuid_id();
-
- if ((midr & CPU_MODEL_MASK) != entry->midr_model)
- return false;
-
- midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
-
- return (midr >= entry->midr_range_min && midr <= entry->midr_range_max);
+ return MIDR_IS_CPU_MODEL_RANGE(read_cpuid_id(), entry->midr_model,
+ entry->midr_range_min,
+ entry->midr_range_max);
}
#define MIDR_RANGE(model, min, max) \
@@ -74,6 +63,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
(1 << MIDR_VARIANT_SHIFT) | 2),
},
#endif
+#ifdef CONFIG_ARM64_ERRATUM_834220
+ {
+ /* Cortex-A57 r0p0 - r1p2 */
+ .desc = "ARM erratum 834220",
+ .capability = ARM64_WORKAROUND_834220,
+ MIDR_RANGE(MIDR_CORTEX_A57, 0x00,
+ (1 << MIDR_VARIANT_SHIFT) | 2),
+ },
+#endif
#ifdef CONFIG_ARM64_ERRATUM_845719
{
/* Cortex-A53 r0p[01234] */
@@ -82,11 +80,28 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
},
#endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
+ {
+ /* Cavium ThunderX, pass 1.x */
+ .desc = "Cavium erratum 23154",
+ .capability = ARM64_WORKAROUND_CAVIUM_23154,
+ MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
+ },
+#endif
+#ifdef CONFIG_CAVIUM_ERRATUM_27456
+ {
+ /* Cavium ThunderX, T88 pass 1.x - 2.1 */
+ .desc = "Cavium erratum 27456",
+ .capability = ARM64_WORKAROUND_CAVIUM_27456,
+ MIDR_RANGE(MIDR_THUNDERX, 0x00,
+ (1 << MIDR_VARIANT_SHIFT) | 1),
+ },
+#endif
{
}
};
void check_local_cpu_errata(void)
{
- check_cpu_capabilities(arm64_errata, "enabling workaround for");
+ update_cpu_capabilities(arm64_errata, "enabling workaround for");
}
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index b6bd7d4..c7cfb8f 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -25,19 +25,30 @@
#include <asm/smp_plat.h>
extern const struct cpu_operations smp_spin_table_ops;
+extern const struct cpu_operations acpi_parking_protocol_ops;
extern const struct cpu_operations cpu_psci_ops;
const struct cpu_operations *cpu_ops[NR_CPUS];
-static const struct cpu_operations *supported_cpu_ops[] __initconst = {
+static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = {
&smp_spin_table_ops,
&cpu_psci_ops,
NULL,
};
+static const struct cpu_operations *acpi_supported_cpu_ops[] __initconst = {
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+ &acpi_parking_protocol_ops,
+#endif
+ &cpu_psci_ops,
+ NULL,
+};
+
static const struct cpu_operations * __init cpu_get_ops(const char *name)
{
- const struct cpu_operations **ops = supported_cpu_ops;
+ const struct cpu_operations **ops;
+
+ ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops;
while (*ops) {
if (!strcmp(name, (*ops)->name))
@@ -75,8 +86,16 @@ static const char *__init cpu_read_enable_method(int cpu)
}
} else {
enable_method = acpi_get_enable_method(cpu);
- if (!enable_method)
- pr_err("Unsupported ACPI enable-method\n");
+ if (!enable_method) {
+ /*
+ * In ACPI systems the boot CPU does not require
+ * checking the enable method since for some
+ * boot protocol (ie parking protocol) it need not
+ * be initialized. Don't warn spuriously.
+ */
+ if (cpu != 0)
+ pr_err("Unsupported ACPI enable-method\n");
+ }
}
return enable_method;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 3c9aed3..943f514 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -16,49 +16,673 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define pr_fmt(fmt) "alternatives: " fmt
+#define pr_fmt(fmt) "CPU features: " fmt
+#include <linux/bsearch.h>
+#include <linux/sort.h>
#include <linux/types.h>
#include <asm/cpu.h>
#include <asm/cpufeature.h>
+#include <asm/cpu_ops.h>
+#include <asm/mmu_context.h>
#include <asm/processor.h>
+#include <asm/sysreg.h>
+#include <asm/virt.h>
+
+unsigned long elf_hwcap __read_mostly;
+EXPORT_SYMBOL_GPL(elf_hwcap);
+
+#ifdef CONFIG_COMPAT
+#define COMPAT_ELF_HWCAP_DEFAULT \
+ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
+ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
+ COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
+ COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
+ COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\
+ COMPAT_HWCAP_LPAE)
+unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
+unsigned int compat_elf_hwcap2 __read_mostly;
+#endif
+
+DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
+
+#define __ARM64_FTR_BITS(SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+ { \
+ .sign = SIGNED, \
+ .strict = STRICT, \
+ .type = TYPE, \
+ .shift = SHIFT, \
+ .width = WIDTH, \
+ .safe_val = SAFE_VAL, \
+ }
+
+/* Define a feature with unsigned values */
+#define ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+ __ARM64_FTR_BITS(FTR_UNSIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
+
+/* Define a feature with a signed value */
+#define S_ARM64_FTR_BITS(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+ __ARM64_FTR_BITS(FTR_SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL)
+
+#define ARM64_FTR_END \
+ { \
+ .width = 0, \
+ }
+
+/* meta feature for alternatives */
+static bool __maybe_unused
+cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry);
+
+static struct arm64_ftr_bits ftr_id_aa64isar0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64ISAR0_RDM_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 24, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_ATOMICS_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_CRC32_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_SHA2_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_SHA1_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_AES_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* RAZ */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64PFR0_GIC_SHIFT, 4, 0),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI),
+ /* Linux doesn't care about the EL3 */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, ID_AA64PFR0_EL3_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64PFR0_EL2_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_BIGENDEL0_SHIFT, 4, 0),
+ /* Linux shouldn't care about secure memory */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, ID_AA64MMFR0_SNSMEM_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_BIGENDEL_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_ASID_SHIFT, 4, 0),
+ /*
+ * Differing PARange is fine as long as all peripherals and memory are mapped
+ * within the minimum PARange of all CPUs
+ */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_PARANGE_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_PAN_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_LOR_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_HPD_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_VHE_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_VMIDBITS_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_HADBS_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_UAO_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_ctr[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
+ /*
+ * Linux can handle differing I-cache policies. Userspace JITs will
+ * make use of *minLine
+ */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0), /* L1Ip */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* IminLine */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_mmfr0[] = {
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 4, 0xf), /* InnerShr */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 24, 4, 0), /* FCSE */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, 20, 4, 0), /* AuxReg */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 16, 4, 0), /* TCM */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 12, 4, 0), /* ShareLvl */
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 4, 0xf), /* OuterShr */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* PMSA */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* VMSA */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_BRPS_SHIFT, 4, 0),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_mvfr2[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 24, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* FPMisc */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* SIMDMisc */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_dczid[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 5, 27, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 1, 1), /* DZP */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* BS */
+ ARM64_FTR_END,
+};
+
+
+static struct arm64_ftr_bits ftr_id_isar5[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_RDM_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 20, 4, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_CRC32_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_SHA2_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_SHA1_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_AES_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_SEVL_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_mmfr4[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 24, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* ac2 */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* RAZ */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_pfr0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 16, 16, 0), /* RAZ */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 12, 4, 0), /* State3 */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 4, 0), /* State2 */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* State1 */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* State0 */
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_id_dfr0[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0),
+ S_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0xf), /* PerfMon */
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 12, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 8, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0),
+ ARM64_FTR_END,
+};
+
+/*
+ * Common ftr bits for a 32bit register with all hidden, strict
+ * attributes, with 4bit feature fields and a default safe value of
+ * 0. Covers the following 32bit registers:
+ * id_isar[0-4], id_mmfr[1-3], id_pfr1, mvfr[0-1]
+ */
+static struct arm64_ftr_bits ftr_generic_32bits[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 12, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 8, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0),
+ ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_generic[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 64, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_generic32[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 32, 0),
+ ARM64_FTR_END,
+};
+
+static struct arm64_ftr_bits ftr_aa64raz[] = {
+ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 64, 0),
+ ARM64_FTR_END,
+};
+
+#define ARM64_FTR_REG(id, table) \
+ { \
+ .sys_id = id, \
+ .name = #id, \
+ .ftr_bits = &((table)[0]), \
+ }
+
+static struct arm64_ftr_reg arm64_ftr_regs[] = {
+
+ /* Op1 = 0, CRn = 0, CRm = 1 */
+ ARM64_FTR_REG(SYS_ID_PFR0_EL1, ftr_id_pfr0),
+ ARM64_FTR_REG(SYS_ID_PFR1_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_DFR0_EL1, ftr_id_dfr0),
+ ARM64_FTR_REG(SYS_ID_MMFR0_EL1, ftr_id_mmfr0),
+ ARM64_FTR_REG(SYS_ID_MMFR1_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_MMFR2_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_MMFR3_EL1, ftr_generic_32bits),
+
+ /* Op1 = 0, CRn = 0, CRm = 2 */
+ ARM64_FTR_REG(SYS_ID_ISAR0_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_ISAR1_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_ISAR2_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_ISAR3_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_ISAR4_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_ID_ISAR5_EL1, ftr_id_isar5),
+ ARM64_FTR_REG(SYS_ID_MMFR4_EL1, ftr_id_mmfr4),
+
+ /* Op1 = 0, CRn = 0, CRm = 3 */
+ ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_generic_32bits),
+ ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2),
+
+ /* Op1 = 0, CRn = 0, CRm = 4 */
+ ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
+ ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_aa64raz),
+
+ /* Op1 = 0, CRn = 0, CRm = 5 */
+ ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
+ ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_generic),
+
+ /* Op1 = 0, CRn = 0, CRm = 6 */
+ ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
+ ARM64_FTR_REG(SYS_ID_AA64ISAR1_EL1, ftr_aa64raz),
+
+ /* Op1 = 0, CRn = 0, CRm = 7 */
+ ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
+ ARM64_FTR_REG(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1),
+ ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
+
+ /* Op1 = 3, CRn = 0, CRm = 0 */
+ ARM64_FTR_REG(SYS_CTR_EL0, ftr_ctr),
+ ARM64_FTR_REG(SYS_DCZID_EL0, ftr_dczid),
+
+ /* Op1 = 3, CRn = 14, CRm = 0 */
+ ARM64_FTR_REG(SYS_CNTFRQ_EL0, ftr_generic32),
+};
+
+static int search_cmp_ftr_reg(const void *id, const void *regp)
+{
+ return (int)(unsigned long)id - (int)((const struct arm64_ftr_reg *)regp)->sys_id;
+}
+
+/*
+ * get_arm64_ftr_reg - Lookup a feature register entry using its
+ * sys_reg() encoding. With the array arm64_ftr_regs sorted in the
+ * ascending order of sys_id , we use binary search to find a matching
+ * entry.
+ *
+ * returns - Upon success, matching ftr_reg entry for id.
+ * - NULL on failure. It is upto the caller to decide
+ * the impact of a failure.
+ */
+static struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id)
+{
+ return bsearch((const void *)(unsigned long)sys_id,
+ arm64_ftr_regs,
+ ARRAY_SIZE(arm64_ftr_regs),
+ sizeof(arm64_ftr_regs[0]),
+ search_cmp_ftr_reg);
+}
+
+static u64 arm64_ftr_set_value(struct arm64_ftr_bits *ftrp, s64 reg, s64 ftr_val)
+{
+ u64 mask = arm64_ftr_mask(ftrp);
+
+ reg &= ~mask;
+ reg |= (ftr_val << ftrp->shift) & mask;
+ return reg;
+}
+
+static s64 arm64_ftr_safe_value(struct arm64_ftr_bits *ftrp, s64 new, s64 cur)
+{
+ s64 ret = 0;
+
+ switch (ftrp->type) {
+ case FTR_EXACT:
+ ret = ftrp->safe_val;
+ break;
+ case FTR_LOWER_SAFE:
+ ret = new < cur ? new : cur;
+ break;
+ case FTR_HIGHER_SAFE:
+ ret = new > cur ? new : cur;
+ break;
+ default:
+ BUG();
+ }
+
+ return ret;
+}
+
+static int __init sort_cmp_ftr_regs(const void *a, const void *b)
+{
+ return ((const struct arm64_ftr_reg *)a)->sys_id -
+ ((const struct arm64_ftr_reg *)b)->sys_id;
+}
+
+static void __init swap_ftr_regs(void *a, void *b, int size)
+{
+ struct arm64_ftr_reg tmp = *(struct arm64_ftr_reg *)a;
+ *(struct arm64_ftr_reg *)a = *(struct arm64_ftr_reg *)b;
+ *(struct arm64_ftr_reg *)b = tmp;
+}
+
+static void __init sort_ftr_regs(void)
+{
+ /* Keep the array sorted so that we can do the binary search */
+ sort(arm64_ftr_regs,
+ ARRAY_SIZE(arm64_ftr_regs),
+ sizeof(arm64_ftr_regs[0]),
+ sort_cmp_ftr_regs,
+ swap_ftr_regs);
+}
+
+/*
+ * Initialise the CPU feature register from Boot CPU values.
+ * Also initiliases the strict_mask for the register.
+ */
+static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
+{
+ u64 val = 0;
+ u64 strict_mask = ~0x0ULL;
+ struct arm64_ftr_bits *ftrp;
+ struct arm64_ftr_reg *reg = get_arm64_ftr_reg(sys_reg);
+
+ BUG_ON(!reg);
+
+ for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) {
+ s64 ftr_new = arm64_ftr_value(ftrp, new);
+
+ val = arm64_ftr_set_value(ftrp, val, ftr_new);
+ if (!ftrp->strict)
+ strict_mask &= ~arm64_ftr_mask(ftrp);
+ }
+ reg->sys_val = val;
+ reg->strict_mask = strict_mask;
+}
+
+void __init init_cpu_features(struct cpuinfo_arm64 *info)
+{
+ /* Before we start using the tables, make sure it is sorted */
+ sort_ftr_regs();
+
+ init_cpu_ftr_reg(SYS_CTR_EL0, info->reg_ctr);
+ init_cpu_ftr_reg(SYS_DCZID_EL0, info->reg_dczid);
+ init_cpu_ftr_reg(SYS_CNTFRQ_EL0, info->reg_cntfrq);
+ init_cpu_ftr_reg(SYS_ID_AA64DFR0_EL1, info->reg_id_aa64dfr0);
+ init_cpu_ftr_reg(SYS_ID_AA64DFR1_EL1, info->reg_id_aa64dfr1);
+ init_cpu_ftr_reg(SYS_ID_AA64ISAR0_EL1, info->reg_id_aa64isar0);
+ init_cpu_ftr_reg(SYS_ID_AA64ISAR1_EL1, info->reg_id_aa64isar1);
+ init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0);
+ init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
+ init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
+ init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
+ init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
+ init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
+ init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
+ init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
+ init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
+ init_cpu_ftr_reg(SYS_ID_ISAR3_EL1, info->reg_id_isar3);
+ init_cpu_ftr_reg(SYS_ID_ISAR4_EL1, info->reg_id_isar4);
+ init_cpu_ftr_reg(SYS_ID_ISAR5_EL1, info->reg_id_isar5);
+ init_cpu_ftr_reg(SYS_ID_MMFR0_EL1, info->reg_id_mmfr0);
+ init_cpu_ftr_reg(SYS_ID_MMFR1_EL1, info->reg_id_mmfr1);
+ init_cpu_ftr_reg(SYS_ID_MMFR2_EL1, info->reg_id_mmfr2);
+ init_cpu_ftr_reg(SYS_ID_MMFR3_EL1, info->reg_id_mmfr3);
+ init_cpu_ftr_reg(SYS_ID_PFR0_EL1, info->reg_id_pfr0);
+ init_cpu_ftr_reg(SYS_ID_PFR1_EL1, info->reg_id_pfr1);
+ init_cpu_ftr_reg(SYS_MVFR0_EL1, info->reg_mvfr0);
+ init_cpu_ftr_reg(SYS_MVFR1_EL1, info->reg_mvfr1);
+ init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
+}
+
+static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
+{
+ struct arm64_ftr_bits *ftrp;
+
+ for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) {
+ s64 ftr_cur = arm64_ftr_value(ftrp, reg->sys_val);
+ s64 ftr_new = arm64_ftr_value(ftrp, new);
+
+ if (ftr_cur == ftr_new)
+ continue;
+ /* Find a safe value */
+ ftr_new = arm64_ftr_safe_value(ftrp, ftr_new, ftr_cur);
+ reg->sys_val = arm64_ftr_set_value(ftrp, reg->sys_val, ftr_new);
+ }
+
+}
+
+static int check_update_ftr_reg(u32 sys_id, int cpu, u64 val, u64 boot)
+{
+ struct arm64_ftr_reg *regp = get_arm64_ftr_reg(sys_id);
+
+ BUG_ON(!regp);
+ update_cpu_ftr_reg(regp, val);
+ if ((boot & regp->strict_mask) == (val & regp->strict_mask))
+ return 0;
+ pr_warn("SANITY CHECK: Unexpected variation in %s. Boot CPU: %#016llx, CPU%d: %#016llx\n",
+ regp->name, boot, cpu, val);
+ return 1;
+}
+
+/*
+ * Update system wide CPU feature registers with the values from a
+ * non-boot CPU. Also performs SANITY checks to make sure that there
+ * aren't any insane variations from that of the boot CPU.
+ */
+void update_cpu_features(int cpu,
+ struct cpuinfo_arm64 *info,
+ struct cpuinfo_arm64 *boot)
+{
+ int taint = 0;
+
+ /*
+ * The kernel can handle differing I-cache policies, but otherwise
+ * caches should look identical. Userspace JITs will make use of
+ * *minLine.
+ */
+ taint |= check_update_ftr_reg(SYS_CTR_EL0, cpu,
+ info->reg_ctr, boot->reg_ctr);
+
+ /*
+ * Userspace may perform DC ZVA instructions. Mismatched block sizes
+ * could result in too much or too little memory being zeroed if a
+ * process is preempted and migrated between CPUs.
+ */
+ taint |= check_update_ftr_reg(SYS_DCZID_EL0, cpu,
+ info->reg_dczid, boot->reg_dczid);
+
+ /* If different, timekeeping will be broken (especially with KVM) */
+ taint |= check_update_ftr_reg(SYS_CNTFRQ_EL0, cpu,
+ info->reg_cntfrq, boot->reg_cntfrq);
+
+ /*
+ * The kernel uses self-hosted debug features and expects CPUs to
+ * support identical debug features. We presently need CTX_CMPs, WRPs,
+ * and BRPs to be identical.
+ * ID_AA64DFR1 is currently RES0.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_AA64DFR0_EL1, cpu,
+ info->reg_id_aa64dfr0, boot->reg_id_aa64dfr0);
+ taint |= check_update_ftr_reg(SYS_ID_AA64DFR1_EL1, cpu,
+ info->reg_id_aa64dfr1, boot->reg_id_aa64dfr1);
+ /*
+ * Even in big.LITTLE, processors should be identical instruction-set
+ * wise.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_AA64ISAR0_EL1, cpu,
+ info->reg_id_aa64isar0, boot->reg_id_aa64isar0);
+ taint |= check_update_ftr_reg(SYS_ID_AA64ISAR1_EL1, cpu,
+ info->reg_id_aa64isar1, boot->reg_id_aa64isar1);
+
+ /*
+ * Differing PARange support is fine as long as all peripherals and
+ * memory are mapped within the minimum PARange of all CPUs.
+ * Linux should not care about secure memory.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_AA64MMFR0_EL1, cpu,
+ info->reg_id_aa64mmfr0, boot->reg_id_aa64mmfr0);
+ taint |= check_update_ftr_reg(SYS_ID_AA64MMFR1_EL1, cpu,
+ info->reg_id_aa64mmfr1, boot->reg_id_aa64mmfr1);
+ taint |= check_update_ftr_reg(SYS_ID_AA64MMFR2_EL1, cpu,
+ info->reg_id_aa64mmfr2, boot->reg_id_aa64mmfr2);
+
+ /*
+ * EL3 is not our concern.
+ * ID_AA64PFR1 is currently RES0.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
+ info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
+ taint |= check_update_ftr_reg(SYS_ID_AA64PFR1_EL1, cpu,
+ info->reg_id_aa64pfr1, boot->reg_id_aa64pfr1);
+
+ /*
+ * If we have AArch32, we care about 32-bit features for compat. These
+ * registers should be RES0 otherwise.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_DFR0_EL1, cpu,
+ info->reg_id_dfr0, boot->reg_id_dfr0);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR0_EL1, cpu,
+ info->reg_id_isar0, boot->reg_id_isar0);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR1_EL1, cpu,
+ info->reg_id_isar1, boot->reg_id_isar1);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR2_EL1, cpu,
+ info->reg_id_isar2, boot->reg_id_isar2);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR3_EL1, cpu,
+ info->reg_id_isar3, boot->reg_id_isar3);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR4_EL1, cpu,
+ info->reg_id_isar4, boot->reg_id_isar4);
+ taint |= check_update_ftr_reg(SYS_ID_ISAR5_EL1, cpu,
+ info->reg_id_isar5, boot->reg_id_isar5);
+
+ /*
+ * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
+ * ACTLR formats could differ across CPUs and therefore would have to
+ * be trapped for virtualization anyway.
+ */
+ taint |= check_update_ftr_reg(SYS_ID_MMFR0_EL1, cpu,
+ info->reg_id_mmfr0, boot->reg_id_mmfr0);
+ taint |= check_update_ftr_reg(SYS_ID_MMFR1_EL1, cpu,
+ info->reg_id_mmfr1, boot->reg_id_mmfr1);
+ taint |= check_update_ftr_reg(SYS_ID_MMFR2_EL1, cpu,
+ info->reg_id_mmfr2, boot->reg_id_mmfr2);
+ taint |= check_update_ftr_reg(SYS_ID_MMFR3_EL1, cpu,
+ info->reg_id_mmfr3, boot->reg_id_mmfr3);
+ taint |= check_update_ftr_reg(SYS_ID_PFR0_EL1, cpu,
+ info->reg_id_pfr0, boot->reg_id_pfr0);
+ taint |= check_update_ftr_reg(SYS_ID_PFR1_EL1, cpu,
+ info->reg_id_pfr1, boot->reg_id_pfr1);
+ taint |= check_update_ftr_reg(SYS_MVFR0_EL1, cpu,
+ info->reg_mvfr0, boot->reg_mvfr0);
+ taint |= check_update_ftr_reg(SYS_MVFR1_EL1, cpu,
+ info->reg_mvfr1, boot->reg_mvfr1);
+ taint |= check_update_ftr_reg(SYS_MVFR2_EL1, cpu,
+ info->reg_mvfr2, boot->reg_mvfr2);
+
+ /*
+ * Mismatched CPU features are a recipe for disaster. Don't even
+ * pretend to support them.
+ */
+ WARN_TAINT_ONCE(taint, TAINT_CPU_OUT_OF_SPEC,
+ "Unsupported CPU feature variation.\n");
+}
+
+u64 read_system_reg(u32 id)
+{
+ struct arm64_ftr_reg *regp = get_arm64_ftr_reg(id);
+
+ /* We shouldn't get a request for an unsupported register */
+ BUG_ON(!regp);
+ return regp->sys_val;
+}
+
+#include <linux/irqchip/arm-gic-v3.h>
static bool
feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
{
- int val = cpuid_feature_extract_field(reg, entry->field_pos);
+ int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
return val >= entry->min_field_value;
}
-#define __ID_FEAT_CHK(reg) \
-static bool __maybe_unused \
-has_##reg##_feature(const struct arm64_cpu_capabilities *entry) \
-{ \
- u64 val; \
- \
- val = read_cpuid(reg##_el1); \
- return feature_matches(val, entry); \
+static bool
+has_cpuid_feature(const struct arm64_cpu_capabilities *entry)
+{
+ u64 val;
+
+ val = read_system_reg(entry->sys_reg);
+ return feature_matches(val, entry);
}
-__ID_FEAT_CHK(id_aa64pfr0);
-__ID_FEAT_CHK(id_aa64mmfr1);
-__ID_FEAT_CHK(id_aa64isar0);
+static bool has_useable_gicv3_cpuif(const struct arm64_cpu_capabilities *entry)
+{
+ bool has_sre;
+
+ if (!has_cpuid_feature(entry))
+ return false;
+
+ has_sre = gic_enable_sre();
+ if (!has_sre)
+ pr_warn_once("%s present but disabled by higher exception level\n",
+ entry->desc);
+
+ return has_sre;
+}
+
+static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry)
+{
+ u32 midr = read_cpuid_id();
+ u32 rv_min, rv_max;
+
+ /* Cavium ThunderX pass 1.x and 2.x */
+ rv_min = 0;
+ rv_max = (1 << MIDR_VARIANT_SHIFT) | MIDR_REVISION_MASK;
+
+ return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max);
+}
+
+static bool runs_at_el2(const struct arm64_cpu_capabilities *entry)
+{
+ return is_kernel_in_hyp_mode();
+}
static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "GIC system register CPU interface",
.capability = ARM64_HAS_SYSREG_GIC_CPUIF,
- .matches = has_id_aa64pfr0_feature,
- .field_pos = 24,
+ .matches = has_useable_gicv3_cpuif,
+ .sys_reg = SYS_ID_AA64PFR0_EL1,
+ .field_pos = ID_AA64PFR0_GIC_SHIFT,
+ .sign = FTR_UNSIGNED,
.min_field_value = 1,
},
#ifdef CONFIG_ARM64_PAN
{
.desc = "Privileged Access Never",
.capability = ARM64_HAS_PAN,
- .matches = has_id_aa64mmfr1_feature,
- .field_pos = 20,
+ .matches = has_cpuid_feature,
+ .sys_reg = SYS_ID_AA64MMFR1_EL1,
+ .field_pos = ID_AA64MMFR1_PAN_SHIFT,
+ .sign = FTR_UNSIGNED,
.min_field_value = 1,
.enable = cpu_enable_pan,
},
@@ -67,36 +691,309 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "LSE atomic instructions",
.capability = ARM64_HAS_LSE_ATOMICS,
- .matches = has_id_aa64isar0_feature,
- .field_pos = 20,
+ .matches = has_cpuid_feature,
+ .sys_reg = SYS_ID_AA64ISAR0_EL1,
+ .field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+ .sign = FTR_UNSIGNED,
.min_field_value = 2,
},
#endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+ {
+ .desc = "Software prefetching using PRFM",
+ .capability = ARM64_HAS_NO_HW_PREFETCH,
+ .matches = has_no_hw_prefetch,
+ },
+#ifdef CONFIG_ARM64_UAO
+ {
+ .desc = "User Access Override",
+ .capability = ARM64_HAS_UAO,
+ .matches = has_cpuid_feature,
+ .sys_reg = SYS_ID_AA64MMFR2_EL1,
+ .field_pos = ID_AA64MMFR2_UAO_SHIFT,
+ .min_field_value = 1,
+ .enable = cpu_enable_uao,
+ },
+#endif /* CONFIG_ARM64_UAO */
+#ifdef CONFIG_ARM64_PAN
+ {
+ .capability = ARM64_ALT_PAN_NOT_UAO,
+ .matches = cpufeature_pan_not_uao,
+ },
+#endif /* CONFIG_ARM64_PAN */
+ {
+ .desc = "Virtualization Host Extensions",
+ .capability = ARM64_HAS_VIRT_HOST_EXTN,
+ .matches = runs_at_el2,
+ },
+ {},
+};
+
+#define HWCAP_CAP(reg, field, s, min_value, type, cap) \
+ { \
+ .desc = #cap, \
+ .matches = has_cpuid_feature, \
+ .sys_reg = reg, \
+ .field_pos = field, \
+ .sign = s, \
+ .min_field_value = min_value, \
+ .hwcap_type = type, \
+ .hwcap = cap, \
+ }
+
+static const struct arm64_cpu_capabilities arm64_hwcaps[] = {
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_PMULL),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_AES),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA1),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA2),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_CRC32),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_ATOMICS),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_FP),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_FPHP),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_ASIMDHP),
+#ifdef CONFIG_COMPAT
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+#endif
{},
};
-void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
+static void __init cap_set_hwcap(const struct arm64_cpu_capabilities *cap)
+{
+ switch (cap->hwcap_type) {
+ case CAP_HWCAP:
+ elf_hwcap |= cap->hwcap;
+ break;
+#ifdef CONFIG_COMPAT
+ case CAP_COMPAT_HWCAP:
+ compat_elf_hwcap |= (u32)cap->hwcap;
+ break;
+ case CAP_COMPAT_HWCAP2:
+ compat_elf_hwcap2 |= (u32)cap->hwcap;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+/* Check if we have a particular HWCAP enabled */
+static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
+{
+ bool rc;
+
+ switch (cap->hwcap_type) {
+ case CAP_HWCAP:
+ rc = (elf_hwcap & cap->hwcap) != 0;
+ break;
+#ifdef CONFIG_COMPAT
+ case CAP_COMPAT_HWCAP:
+ rc = (compat_elf_hwcap & (u32)cap->hwcap) != 0;
+ break;
+ case CAP_COMPAT_HWCAP2:
+ rc = (compat_elf_hwcap2 & (u32)cap->hwcap) != 0;
+ break;
+#endif
+ default:
+ WARN_ON(1);
+ rc = false;
+ }
+
+ return rc;
+}
+
+static void __init setup_cpu_hwcaps(void)
+{
+ int i;
+ const struct arm64_cpu_capabilities *hwcaps = arm64_hwcaps;
+
+ for (i = 0; hwcaps[i].matches; i++)
+ if (hwcaps[i].matches(&hwcaps[i]))
+ cap_set_hwcap(&hwcaps[i]);
+}
+
+void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
const char *info)
{
int i;
- for (i = 0; caps[i].desc; i++) {
+ for (i = 0; caps[i].matches; i++) {
if (!caps[i].matches(&caps[i]))
continue;
- if (!cpus_have_cap(caps[i].capability))
+ if (!cpus_have_cap(caps[i].capability) && caps[i].desc)
pr_info("%s %s\n", info, caps[i].desc);
cpus_set_cap(caps[i].capability);
}
+}
+
+/*
+ * Run through the enabled capabilities and enable() it on all active
+ * CPUs
+ */
+static void __init
+enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
+{
+ int i;
+
+ for (i = 0; caps[i].matches; i++)
+ if (caps[i].enable && cpus_have_cap(caps[i].capability))
+ on_each_cpu(caps[i].enable, NULL, true);
+}
+
+/*
+ * Flag to indicate if we have computed the system wide
+ * capabilities based on the boot time active CPUs. This
+ * will be used to determine if a new booting CPU should
+ * go through the verification process to make sure that it
+ * supports the system capabilities, without using a hotplug
+ * notifier.
+ */
+static bool sys_caps_initialised;
+
+static inline void set_sys_caps_initialised(void)
+{
+ sys_caps_initialised = true;
+}
+
+/*
+ * __raw_read_system_reg() - Used by a STARTING cpu before cpuinfo is populated.
+ */
+static u64 __raw_read_system_reg(u32 sys_id)
+{
+ switch (sys_id) {
+ case SYS_ID_PFR0_EL1: return read_cpuid(ID_PFR0_EL1);
+ case SYS_ID_PFR1_EL1: return read_cpuid(ID_PFR1_EL1);
+ case SYS_ID_DFR0_EL1: return read_cpuid(ID_DFR0_EL1);
+ case SYS_ID_MMFR0_EL1: return read_cpuid(ID_MMFR0_EL1);
+ case SYS_ID_MMFR1_EL1: return read_cpuid(ID_MMFR1_EL1);
+ case SYS_ID_MMFR2_EL1: return read_cpuid(ID_MMFR2_EL1);
+ case SYS_ID_MMFR3_EL1: return read_cpuid(ID_MMFR3_EL1);
+ case SYS_ID_ISAR0_EL1: return read_cpuid(ID_ISAR0_EL1);
+ case SYS_ID_ISAR1_EL1: return read_cpuid(ID_ISAR1_EL1);
+ case SYS_ID_ISAR2_EL1: return read_cpuid(ID_ISAR2_EL1);
+ case SYS_ID_ISAR3_EL1: return read_cpuid(ID_ISAR3_EL1);
+ case SYS_ID_ISAR4_EL1: return read_cpuid(ID_ISAR4_EL1);
+ case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR4_EL1);
+ case SYS_MVFR0_EL1: return read_cpuid(MVFR0_EL1);
+ case SYS_MVFR1_EL1: return read_cpuid(MVFR1_EL1);
+ case SYS_MVFR2_EL1: return read_cpuid(MVFR2_EL1);
+
+ case SYS_ID_AA64PFR0_EL1: return read_cpuid(ID_AA64PFR0_EL1);
+ case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR0_EL1);
+ case SYS_ID_AA64DFR0_EL1: return read_cpuid(ID_AA64DFR0_EL1);
+ case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR0_EL1);
+ case SYS_ID_AA64MMFR0_EL1: return read_cpuid(ID_AA64MMFR0_EL1);
+ case SYS_ID_AA64MMFR1_EL1: return read_cpuid(ID_AA64MMFR1_EL1);
+ case SYS_ID_AA64MMFR2_EL1: return read_cpuid(ID_AA64MMFR2_EL1);
+ case SYS_ID_AA64ISAR0_EL1: return read_cpuid(ID_AA64ISAR0_EL1);
+ case SYS_ID_AA64ISAR1_EL1: return read_cpuid(ID_AA64ISAR1_EL1);
- /* second pass allows enable() to consider interacting capabilities */
- for (i = 0; caps[i].desc; i++) {
- if (cpus_have_cap(caps[i].capability) && caps[i].enable)
- caps[i].enable();
+ case SYS_CNTFRQ_EL0: return read_cpuid(CNTFRQ_EL0);
+ case SYS_CTR_EL0: return read_cpuid(CTR_EL0);
+ case SYS_DCZID_EL0: return read_cpuid(DCZID_EL0);
+ default:
+ BUG();
+ return 0;
}
}
-void check_local_cpu_features(void)
+/*
+ * Check for CPU features that are used in early boot
+ * based on the Boot CPU value.
+ */
+static void check_early_cpu_features(void)
+{
+ verify_cpu_asid_bits();
+}
+
+/*
+ * Run through the enabled system capabilities and enable() it on this CPU.
+ * The capabilities were decided based on the available CPUs at the boot time.
+ * Any new CPU should match the system wide status of the capability. If the
+ * new CPU doesn't have a capability which the system now has enabled, we
+ * cannot do anything to fix it up and could cause unexpected failures. So
+ * we park the CPU.
+ */
+void verify_local_cpu_capabilities(void)
+{
+ int i;
+ const struct arm64_cpu_capabilities *caps;
+
+ check_early_cpu_features();
+
+ /*
+ * If we haven't computed the system capabilities, there is nothing
+ * to verify.
+ */
+ if (!sys_caps_initialised)
+ return;
+
+ caps = arm64_features;
+ for (i = 0; caps[i].matches; i++) {
+ if (!cpus_have_cap(caps[i].capability) || !caps[i].sys_reg)
+ continue;
+ /*
+ * If the new CPU misses an advertised feature, we cannot proceed
+ * further, park the cpu.
+ */
+ if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i])) {
+ pr_crit("CPU%d: missing feature: %s\n",
+ smp_processor_id(), caps[i].desc);
+ cpu_die_early();
+ }
+ if (caps[i].enable)
+ caps[i].enable(NULL);
+ }
+
+ for (i = 0, caps = arm64_hwcaps; caps[i].matches; i++) {
+ if (!cpus_have_hwcap(&caps[i]))
+ continue;
+ if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i])) {
+ pr_crit("CPU%d: missing HWCAP: %s\n",
+ smp_processor_id(), caps[i].desc);
+ cpu_die_early();
+ }
+ }
+}
+
+static void __init setup_feature_capabilities(void)
+{
+ update_cpu_capabilities(arm64_features, "detected feature:");
+ enable_cpu_capabilities(arm64_features);
+}
+
+void __init setup_cpu_features(void)
+{
+ u32 cwg;
+ int cls;
+
+ /* Set the CPU feature capabilies */
+ setup_feature_capabilities();
+ setup_cpu_hwcaps();
+
+ /* Advertise that we have computed the system capabilities */
+ set_sys_caps_initialised();
+
+ /*
+ * Check for sane CTR_EL0.CWG value.
+ */
+ cwg = cache_type_cwg();
+ cls = cache_line_size();
+ if (!cwg)
+ pr_warn("No Cache Writeback Granule information, assuming cache line size %d\n",
+ cls);
+ if (L1_CACHE_BYTES < cls)
+ pr_warn("L1_CACHE_BYTES smaller than the Cache Writeback Granule (%d < %d)\n",
+ L1_CACHE_BYTES, cls);
+}
+
+static bool __maybe_unused
+cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry)
{
- check_cpu_capabilities(arm64_features, "detected feature:");
+ return (cpus_have_cap(ARM64_HAS_PAN) && !cpus_have_cap(ARM64_HAS_UAO));
}
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a86..84c8684 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -24,9 +24,13 @@
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/personality.h>
#include <linux/preempt.h>
#include <linux/printk.h>
+#include <linux/seq_file.h>
+#include <linux/sched.h>
#include <linux/smp.h>
+#include <linux/delay.h>
/*
* In case the boot CPU is hotpluggable, we record its initial state and
@@ -35,7 +39,6 @@
*/
DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
static struct cpuinfo_arm64 boot_cpu_data;
-static bool mixed_endian_el0 = true;
static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
@@ -46,157 +49,154 @@ static char *icache_policy_str[] = {
unsigned long __icache_flags;
-static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
+static const char *const hwcap_str[] = {
+ "fp",
+ "asimd",
+ "evtstrm",
+ "aes",
+ "pmull",
+ "sha1",
+ "sha2",
+ "crc32",
+ "atomics",
+ "fphp",
+ "asimdhp",
+ NULL
+};
+
+#ifdef CONFIG_COMPAT
+static const char *const compat_hwcap_str[] = {
+ "swp",
+ "half",
+ "thumb",
+ "26bit",
+ "fastmult",
+ "fpa",
+ "vfp",
+ "edsp",
+ "java",
+ "iwmmxt",
+ "crunch",
+ "thumbee",
+ "neon",
+ "vfpv3",
+ "vfpv3d16",
+ "tls",
+ "vfpv4",
+ "idiva",
+ "idivt",
+ "vfpd32",
+ "lpae",
+ "evtstrm"
+};
+
+static const char *const compat_hwcap2_str[] = {
+ "aes",
+ "pmull",
+ "sha1",
+ "sha2",
+ "crc32",
+ NULL
+};
+#endif /* CONFIG_COMPAT */
+
+static int c_show(struct seq_file *m, void *v)
{
- unsigned int cpu = smp_processor_id();
- u32 l1ip = CTR_L1IP(info->reg_ctr);
+ int i, j;
+
+ for_each_online_cpu(i) {
+ struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+ u32 midr = cpuinfo->reg_midr;
- if (l1ip != ICACHE_POLICY_PIPT) {
/*
- * VIPT caches are non-aliasing if the VA always equals the PA
- * in all bit positions that are covered by the index. This is
- * the case if the size of a way (# of sets * line size) does
- * not exceed PAGE_SIZE.
+ * glibc reads /proc/cpuinfo to determine the number of
+ * online processors, looking for lines beginning with
+ * "processor". Give glibc what it expects.
*/
- u32 waysize = icache_get_numsets() * icache_get_linesize();
+ seq_printf(m, "processor\t: %d\n", i);
- if (l1ip != ICACHE_POLICY_VIPT || waysize > PAGE_SIZE)
- set_bit(ICACHEF_ALIASING, &__icache_flags);
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000UL/HZ),
+ loops_per_jiffy / (5000UL/HZ) % 100);
+
+ /*
+ * Dump out the common processor features in a single line.
+ * Userspace should read the hwcaps with getauxval(AT_HWCAP)
+ * rather than attempting to parse this, but there's a body of
+ * software which does already (at least for 32-bit).
+ */
+ seq_puts(m, "Features\t:");
+ if (personality(current->personality) == PER_LINUX32) {
+#ifdef CONFIG_COMPAT
+ for (j = 0; compat_hwcap_str[j]; j++)
+ if (compat_elf_hwcap & (1 << j))
+ seq_printf(m, " %s", compat_hwcap_str[j]);
+
+ for (j = 0; compat_hwcap2_str[j]; j++)
+ if (compat_elf_hwcap2 & (1 << j))
+ seq_printf(m, " %s", compat_hwcap2_str[j]);
+#endif /* CONFIG_COMPAT */
+ } else {
+ for (j = 0; hwcap_str[j]; j++)
+ if (elf_hwcap & (1 << j))
+ seq_printf(m, " %s", hwcap_str[j]);
+ }
+ seq_puts(m, "\n");
+
+ seq_printf(m, "CPU implementer\t: 0x%02x\n",
+ MIDR_IMPLEMENTOR(midr));
+ seq_printf(m, "CPU architecture: 8\n");
+ seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
+ seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
+ seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
}
- if (l1ip == ICACHE_POLICY_AIVIVT)
- set_bit(ICACHEF_AIVIVT, &__icache_flags);
- pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
+ return 0;
}
-bool cpu_supports_mixed_endian_el0(void)
+static void *c_start(struct seq_file *m, loff_t *pos)
{
- return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+ return *pos < 1 ? (void *)1 : NULL;
}
-bool system_supports_mixed_endian_el0(void)
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
- return mixed_endian_el0;
+ ++*pos;
+ return NULL;
}
-static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+static void c_stop(struct seq_file *m, void *v)
{
- mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
}
-static void update_cpu_features(struct cpuinfo_arm64 *info)
-{
- update_mixed_endian_el0_support(info);
-}
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show
+};
-static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
+static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
{
- if ((boot & mask) == (cur & mask))
- return 0;
-
- pr_warn("SANITY CHECK: Unexpected variation in %s. Boot CPU: %#016lx, CPU%d: %#016lx\n",
- name, (unsigned long)boot, cpu, (unsigned long)cur);
-
- return 1;
-}
+ unsigned int cpu = smp_processor_id();
+ u32 l1ip = CTR_L1IP(info->reg_ctr);
-#define CHECK_MASK(field, mask, boot, cur, cpu) \
- check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu)
+ if (l1ip != ICACHE_POLICY_PIPT) {
+ /*
+ * VIPT caches are non-aliasing if the VA always equals the PA
+ * in all bit positions that are covered by the index. This is
+ * the case if the size of a way (# of sets * line size) does
+ * not exceed PAGE_SIZE.
+ */
+ u32 waysize = icache_get_numsets() * icache_get_linesize();
-#define CHECK(field, boot, cur, cpu) \
- CHECK_MASK(field, ~0ULL, boot, cur, cpu)
+ if (l1ip != ICACHE_POLICY_VIPT || waysize > PAGE_SIZE)
+ set_bit(ICACHEF_ALIASING, &__icache_flags);
+ }
+ if (l1ip == ICACHE_POLICY_AIVIVT)
+ set_bit(ICACHEF_AIVIVT, &__icache_flags);
-/*
- * Verify that CPUs don't have unexpected differences that will cause problems.
- */
-static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
-{
- unsigned int cpu = smp_processor_id();
- struct cpuinfo_arm64 *boot = &boot_cpu_data;
- unsigned int diff = 0;
-
- /*
- * The kernel can handle differing I-cache policies, but otherwise
- * caches should look identical. Userspace JITs will make use of
- * *minLine.
- */
- diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu);
-
- /*
- * Userspace may perform DC ZVA instructions. Mismatched block sizes
- * could result in too much or too little memory being zeroed if a
- * process is preempted and migrated between CPUs.
- */
- diff |= CHECK(dczid, boot, cur, cpu);
-
- /* If different, timekeeping will be broken (especially with KVM) */
- diff |= CHECK(cntfrq, boot, cur, cpu);
-
- /*
- * The kernel uses self-hosted debug features and expects CPUs to
- * support identical debug features. We presently need CTX_CMPs, WRPs,
- * and BRPs to be identical.
- * ID_AA64DFR1 is currently RES0.
- */
- diff |= CHECK(id_aa64dfr0, boot, cur, cpu);
- diff |= CHECK(id_aa64dfr1, boot, cur, cpu);
-
- /*
- * Even in big.LITTLE, processors should be identical instruction-set
- * wise.
- */
- diff |= CHECK(id_aa64isar0, boot, cur, cpu);
- diff |= CHECK(id_aa64isar1, boot, cur, cpu);
-
- /*
- * Differing PARange support is fine as long as all peripherals and
- * memory are mapped within the minimum PARange of all CPUs.
- * Linux should not care about secure memory.
- * ID_AA64MMFR1 is currently RES0.
- */
- diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu);
- diff |= CHECK(id_aa64mmfr1, boot, cur, cpu);
-
- /*
- * EL3 is not our concern.
- * ID_AA64PFR1 is currently RES0.
- */
- diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu);
- diff |= CHECK(id_aa64pfr1, boot, cur, cpu);
-
- /*
- * If we have AArch32, we care about 32-bit features for compat. These
- * registers should be RES0 otherwise.
- */
- diff |= CHECK(id_dfr0, boot, cur, cpu);
- diff |= CHECK(id_isar0, boot, cur, cpu);
- diff |= CHECK(id_isar1, boot, cur, cpu);
- diff |= CHECK(id_isar2, boot, cur, cpu);
- diff |= CHECK(id_isar3, boot, cur, cpu);
- diff |= CHECK(id_isar4, boot, cur, cpu);
- diff |= CHECK(id_isar5, boot, cur, cpu);
- /*
- * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
- * ACTLR formats could differ across CPUs and therefore would have to
- * be trapped for virtualization anyway.
- */
- diff |= CHECK_MASK(id_mmfr0, 0xff0fffff, boot, cur, cpu);
- diff |= CHECK(id_mmfr1, boot, cur, cpu);
- diff |= CHECK(id_mmfr2, boot, cur, cpu);
- diff |= CHECK(id_mmfr3, boot, cur, cpu);
- diff |= CHECK(id_pfr0, boot, cur, cpu);
- diff |= CHECK(id_pfr1, boot, cur, cpu);
-
- diff |= CHECK(mvfr0, boot, cur, cpu);
- diff |= CHECK(mvfr1, boot, cur, cpu);
- diff |= CHECK(mvfr2, boot, cur, cpu);
-
- /*
- * Mismatched CPU features are a recipe for disaster. Don't even
- * pretend to support them.
- */
- WARN_TAINT_ONCE(diff, TAINT_CPU_OUT_OF_SPEC,
- "Unsupported CPU feature variation.\n");
+ pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
}
static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
@@ -212,6 +212,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1);
info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
+ info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
@@ -236,15 +237,13 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
check_local_cpu_errata();
- check_local_cpu_features();
- update_cpu_features(info);
}
void cpuinfo_store_cpu(void)
{
struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
__cpuinfo_store_cpu(info);
- cpuinfo_sanity_check(info);
+ update_cpu_features(smp_processor_id(), info, &boot_cpu_data);
}
void __init cpuinfo_store_boot_cpu(void)
@@ -253,4 +252,5 @@ void __init cpuinfo_store_boot_cpu(void)
__cpuinfo_store_cpu(info);
boot_cpu_data = *info;
+ init_cpu_features(&boot_cpu_data);
}
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 253021e..c45f296 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -26,14 +26,16 @@
#include <linux/stat.h>
#include <linux/uaccess.h>
-#include <asm/debug-monitors.h>
+#include <asm/cpufeature.h>
#include <asm/cputype.h>
+#include <asm/debug-monitors.h>
#include <asm/system_misc.h>
/* Determine debug architecture. */
u8 debug_monitors_arch(void)
{
- return read_cpuid(ID_AA64DFR0_EL1) & 0xf;
+ return cpuid_feature_extract_unsigned_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+ ID_AA64DFR0_DEBUGVER_SHIFT);
}
/*
@@ -58,7 +60,7 @@ static u32 mdscr_read(void)
* Allow root to disable self-hosted debug from userspace.
* This is useful if you want to connect an external JTAG debugger.
*/
-static u32 debug_enabled = 1;
+static bool debug_enabled = true;
static int create_debug_debugfs_entry(void)
{
@@ -69,7 +71,7 @@ fs_initcall(create_debug_debugfs_entry);
static int __init early_debug_disable(char *buf)
{
- debug_enabled = 0;
+ debug_enabled = false;
return 0;
}
@@ -184,20 +186,21 @@ static void clear_regs_spsr_ss(struct pt_regs *regs)
/* EL1 Single Step Handler hooks */
static LIST_HEAD(step_hook);
-static DEFINE_RWLOCK(step_hook_lock);
+static DEFINE_SPINLOCK(step_hook_lock);
void register_step_hook(struct step_hook *hook)
{
- write_lock(&step_hook_lock);
- list_add(&hook->node, &step_hook);
- write_unlock(&step_hook_lock);
+ spin_lock(&step_hook_lock);
+ list_add_rcu(&hook->node, &step_hook);
+ spin_unlock(&step_hook_lock);
}
void unregister_step_hook(struct step_hook *hook)
{
- write_lock(&step_hook_lock);
- list_del(&hook->node);
- write_unlock(&step_hook_lock);
+ spin_lock(&step_hook_lock);
+ list_del_rcu(&hook->node);
+ spin_unlock(&step_hook_lock);
+ synchronize_rcu();
}
/*
@@ -211,24 +214,41 @@ static int call_step_hook(struct pt_regs *regs, unsigned int esr)
struct step_hook *hook;
int retval = DBG_HOOK_ERROR;
- read_lock(&step_hook_lock);
+ rcu_read_lock();
- list_for_each_entry(hook, &step_hook, node) {
+ list_for_each_entry_rcu(hook, &step_hook, node) {
retval = hook->fn(regs, esr);
if (retval == DBG_HOOK_HANDLED)
break;
}
- read_unlock(&step_hook_lock);
+ rcu_read_unlock();
return retval;
}
+static void send_user_sigtrap(int si_code)
+{
+ struct pt_regs *regs = current_pt_regs();
+ siginfo_t info = {
+ .si_signo = SIGTRAP,
+ .si_errno = 0,
+ .si_code = si_code,
+ .si_addr = (void __user *)instruction_pointer(regs),
+ };
+
+ if (WARN_ON(!user_mode(regs)))
+ return;
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+
+ force_sig_info(SIGTRAP, &info, current);
+}
+
static int single_step_handler(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
- siginfo_t info;
-
/*
* If we are stepping a pending breakpoint, call the hw_breakpoint
* handler first.
@@ -237,11 +257,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
return 0;
if (user_mode(regs)) {
- info.si_signo = SIGTRAP;
- info.si_errno = 0;
- info.si_code = TRAP_HWBKPT;
- info.si_addr = (void __user *)instruction_pointer(regs);
- force_sig_info(SIGTRAP, &info, current);
+ send_user_sigtrap(TRAP_HWBKPT);
/*
* ptrace will disable single step unless explicitly
@@ -305,17 +321,8 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr)
static int brk_handler(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
- siginfo_t info;
-
if (user_mode(regs)) {
- info = (siginfo_t) {
- .si_signo = SIGTRAP,
- .si_errno = 0,
- .si_code = TRAP_BRKPT,
- .si_addr = (void __user *)instruction_pointer(regs),
- };
-
- force_sig_info(SIGTRAP, &info, current);
+ send_user_sigtrap(TRAP_BRKPT);
} else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
pr_warning("Unexpected kernel BRK exception at EL1\n");
return -EFAULT;
@@ -326,7 +333,6 @@ static int brk_handler(unsigned long addr, unsigned int esr,
int aarch32_break_handler(struct pt_regs *regs)
{
- siginfo_t info;
u32 arm_instr;
u16 thumb_instr;
bool bp = false;
@@ -357,14 +363,7 @@ int aarch32_break_handler(struct pt_regs *regs)
if (!bp)
return -EFAULT;
- info = (siginfo_t) {
- .si_signo = SIGTRAP,
- .si_errno = 0,
- .si_code = TRAP_BRKPT,
- .si_addr = pc,
- };
-
- force_sig_info(SIGTRAP, &info, current);
+ send_user_sigtrap(TRAP_BRKPT);
return 0;
}
diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
index 8ce9b05..cae3112 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/arch/arm64/kernel/efi-entry.S
@@ -29,12 +29,13 @@
* we want to be. The kernel image wants to be placed at TEXT_OFFSET
* from start of RAM.
*/
-ENTRY(efi_stub_entry)
+ENTRY(entry)
/*
* Create a stack frame to save FP/LR with extra space
* for image_addr variable passed to efi_entry().
*/
stp x29, x30, [sp, #-32]!
+ mov x29, sp
/*
* Call efi_entry to do the real work.
@@ -61,7 +62,7 @@ ENTRY(efi_stub_entry)
*/
mov x20, x0 // DTB address
ldr x0, [sp, #16] // relocated _text address
- ldr x21, =stext_offset
+ movz x21, #:abs_g0:stext_offset
add x21, x0, x21
/*
@@ -86,8 +87,8 @@ ENTRY(efi_stub_entry)
* entries for the VA range of the current image, so no maintenance is
* necessary.
*/
- adr x0, efi_stub_entry
- adr x1, efi_stub_entry_end
+ adr x0, entry
+ adr x1, entry_end
sub x1, x1, x0
bl __flush_dcache_area
@@ -120,5 +121,5 @@ efi_load_fail:
ldp x29, x30, [sp], #32
ret
-efi_stub_entry_end:
-ENDPROC(efi_stub_entry)
+entry_end:
+ENDPROC(entry)
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
deleted file mode 100644
index 78dfbd3..0000000
--- a/arch/arm64/kernel/efi-stub.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org>
- *
- * This file implements the EFI boot stub for the arm64 kernel.
- * Adapted from ARM version by Mark Salter <msalter@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/efi.h>
-#include <asm/efi.h>
-#include <asm/sections.h>
-
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
- unsigned long *image_addr,
- unsigned long *image_size,
- unsigned long *reserve_addr,
- unsigned long *reserve_size,
- unsigned long dram_base,
- efi_loaded_image_t *image)
-{
- efi_status_t status;
- unsigned long kernel_size, kernel_memsize = 0;
- unsigned long nr_pages;
- void *old_image_addr = (void *)*image_addr;
- unsigned long preferred_offset;
-
- /*
- * The preferred offset of the kernel Image is TEXT_OFFSET bytes beyond
- * a 2 MB aligned base, which itself may be lower than dram_base, as
- * long as the resulting offset equals or exceeds it.
- */
- preferred_offset = round_down(dram_base, SZ_2M) + TEXT_OFFSET;
- if (preferred_offset < dram_base)
- preferred_offset += SZ_2M;
-
- /* Relocate the image, if required. */
- kernel_size = _edata - _text;
- if (*image_addr != preferred_offset) {
- kernel_memsize = kernel_size + (_end - _edata);
-
- /*
- * First, try a straight allocation at the preferred offset.
- * This will work around the issue where, if dram_base == 0x0,
- * efi_low_alloc() refuses to allocate at 0x0 (to prevent the
- * address of the allocation to be mistaken for a FAIL return
- * value or a NULL pointer). It will also ensure that, on
- * platforms where the [dram_base, dram_base + TEXT_OFFSET)
- * interval is partially occupied by the firmware (like on APM
- * Mustang), we can still place the kernel at the address
- * 'dram_base + TEXT_OFFSET'.
- */
- *image_addr = *reserve_addr = preferred_offset;
- nr_pages = round_up(kernel_memsize, EFI_ALLOC_ALIGN) /
- EFI_PAGE_SIZE;
- status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
- EFI_LOADER_DATA, nr_pages,
- (efi_physical_addr_t *)reserve_addr);
- if (status != EFI_SUCCESS) {
- kernel_memsize += TEXT_OFFSET;
- status = efi_low_alloc(sys_table_arg, kernel_memsize,
- SZ_2M, reserve_addr);
-
- if (status != EFI_SUCCESS) {
- pr_efi_err(sys_table_arg, "Failed to relocate kernel\n");
- return status;
- }
- *image_addr = *reserve_addr + TEXT_OFFSET;
- }
- memcpy((void *)*image_addr, old_image_addr, kernel_size);
- *reserve_size = kernel_memsize;
- }
-
-
- return EFI_SUCCESS;
-}
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 13671a9..b6abc85 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -11,317 +11,34 @@
*
*/
-#include <linux/atomic.h>
#include <linux/dmi.h>
#include <linux/efi.h>
-#include <linux/export.h>
-#include <linux/memblock.h>
-#include <linux/mm_types.h>
-#include <linux/bootmem.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
-#include <linux/preempt.h>
-#include <linux/rbtree.h>
-#include <linux/rwsem.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
+#include <linux/init.h>
-#include <asm/cacheflush.h>
#include <asm/efi.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-struct efi_memory_map memmap;
-
-static u64 efi_system_table;
-
-static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss;
-
-static struct mm_struct efi_mm = {
- .mm_rb = RB_ROOT,
- .pgd = efi_pgd,
- .mm_users = ATOMIC_INIT(2),
- .mm_count = ATOMIC_INIT(1),
- .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
- .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
- .mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
- INIT_MM_CONTEXT(efi_mm)
-};
-
-static int uefi_debug __initdata;
-static int __init uefi_debug_setup(char *str)
-{
- uefi_debug = 1;
-
- return 0;
-}
-early_param("uefi_debug", uefi_debug_setup);
-
-static int __init is_normal_ram(efi_memory_desc_t *md)
-{
- if (md->attribute & EFI_MEMORY_WB)
- return 1;
- return 0;
-}
-
-/*
- * Translate a EFI virtual address into a physical address: this is necessary,
- * as some data members of the EFI system table are virtually remapped after
- * SetVirtualAddressMap() has been called.
- */
-static phys_addr_t efi_to_phys(unsigned long addr)
+int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
{
- efi_memory_desc_t *md;
-
- for_each_efi_memory_desc(&memmap, md) {
- if (!(md->attribute & EFI_MEMORY_RUNTIME))
- continue;
- if (md->virt_addr == 0)
- /* no virtual mapping has been installed by the stub */
- break;
- if (md->virt_addr <= addr &&
- (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT))
- return md->phys_addr + addr - md->virt_addr;
- }
- return addr;
-}
-
-static int __init uefi_init(void)
-{
- efi_char16_t *c16;
- void *config_tables;
- u64 table_size;
- char vendor[100] = "unknown";
- int i, retval;
-
- efi.systab = early_memremap(efi_system_table,
- sizeof(efi_system_table_t));
- if (efi.systab == NULL) {
- pr_warn("Unable to map EFI system table.\n");
- return -ENOMEM;
- }
-
- set_bit(EFI_BOOT, &efi.flags);
- set_bit(EFI_64BIT, &efi.flags);
+ pteval_t prot_val;
/*
- * Verify the EFI Table
+ * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
+ * executable, everything else can be mapped with the XN bits
+ * set.
*/
- if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
- pr_err("System table signature incorrect\n");
- retval = -EINVAL;
- goto out;
- }
- if ((efi.systab->hdr.revision >> 16) < 2)
- pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
- efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff);
-
- /* Show what we know for posterity */
- c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor),
- sizeof(vendor) * sizeof(efi_char16_t));
- if (c16) {
- for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
- vendor[i] = c16[i];
- vendor[i] = '\0';
- early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
- }
-
- pr_info("EFI v%u.%.02u by %s\n",
- efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff, vendor);
-
- table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
- config_tables = early_memremap(efi_to_phys(efi.systab->tables),
- table_size);
-
- retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
- sizeof(efi_config_table_64_t), NULL);
-
- early_memunmap(config_tables, table_size);
-out:
- early_memunmap(efi.systab, sizeof(efi_system_table_t));
- return retval;
-}
-
-/*
- * Return true for RAM regions we want to permanently reserve.
- */
-static __init int is_reserve_region(efi_memory_desc_t *md)
-{
- switch (md->type) {
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_CONVENTIONAL_MEMORY:
- case EFI_PERSISTENT_MEMORY:
- return 0;
- default:
- break;
- }
- return is_normal_ram(md);
-}
-
-static __init void reserve_regions(void)
-{
- efi_memory_desc_t *md;
- u64 paddr, npages, size;
-
- if (uefi_debug)
- pr_info("Processing EFI memory map:\n");
-
- for_each_efi_memory_desc(&memmap, md) {
- paddr = md->phys_addr;
- npages = md->num_pages;
-
- if (uefi_debug) {
- char buf[64];
-
- pr_info(" 0x%012llx-0x%012llx %s",
- paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
- efi_md_typeattr_format(buf, sizeof(buf), md));
- }
-
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
-
- if (is_normal_ram(md))
- early_init_dt_add_memory_arch(paddr, size);
-
- if (is_reserve_region(md)) {
- memblock_reserve(paddr, size);
- if (uefi_debug)
- pr_cont("*");
- }
-
- if (uefi_debug)
- pr_cont("\n");
- }
-
- set_bit(EFI_MEMMAP, &efi.flags);
-}
-
-void __init efi_init(void)
-{
- struct efi_fdt_params params;
-
- /* Grab UEFI information placed in FDT by stub */
- if (!efi_get_fdt_params(&params, uefi_debug))
- return;
-
- efi_system_table = params.system_table;
-
- memblock_reserve(params.mmap & PAGE_MASK,
- PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK)));
- memmap.phys_map = (void *)params.mmap;
- memmap.map = early_memremap(params.mmap, params.mmap_size);
- memmap.map_end = memmap.map + params.mmap_size;
- memmap.desc_size = params.desc_size;
- memmap.desc_version = params.desc_ver;
-
- if (uefi_init() < 0)
- return;
-
- reserve_regions();
- early_memunmap(memmap.map, params.mmap_size);
-}
-
-static bool __init efi_virtmap_init(void)
-{
- efi_memory_desc_t *md;
-
- for_each_efi_memory_desc(&memmap, md) {
- u64 paddr, npages, size;
- pgprot_t prot;
-
- if (!(md->attribute & EFI_MEMORY_RUNTIME))
- continue;
- if (md->virt_addr == 0)
- return false;
-
- paddr = md->phys_addr;
- npages = md->num_pages;
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
-
- pr_info(" EFI remap 0x%016llx => %p\n",
- md->phys_addr, (void *)md->virt_addr);
-
- /*
- * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
- * executable, everything else can be mapped with the XN bits
- * set.
- */
- if (!is_normal_ram(md))
- prot = __pgprot(PROT_DEVICE_nGnRE);
- else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
- !PAGE_ALIGNED(md->phys_addr))
- prot = PAGE_KERNEL_EXEC;
- else
- prot = PAGE_KERNEL;
-
- create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, prot);
- }
- return true;
-}
-
-/*
- * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
- * non-early mapping of the UEFI system table and virtual mappings for all
- * EFI_MEMORY_RUNTIME regions.
- */
-static int __init arm64_enable_runtime_services(void)
-{
- u64 mapsize;
-
- if (!efi_enabled(EFI_BOOT)) {
- pr_info("EFI services will not be available.\n");
- return -1;
- }
-
- if (efi_runtime_disabled()) {
- pr_info("EFI runtime services will be disabled.\n");
- return -1;
- }
-
- pr_info("Remapping and enabling EFI services.\n");
-
- mapsize = memmap.map_end - memmap.map;
- memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
- mapsize);
- if (!memmap.map) {
- pr_err("Failed to remap EFI memory map\n");
- return -1;
- }
- memmap.map_end = memmap.map + mapsize;
- efi.memmap = &memmap;
-
- efi.systab = (__force void *)ioremap_cache(efi_system_table,
- sizeof(efi_system_table_t));
- if (!efi.systab) {
- pr_err("Failed to remap EFI System Table\n");
- return -1;
- }
- set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-
- if (!efi_virtmap_init()) {
- pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
- return -1;
- }
-
- /* Set up runtime services function pointers */
- efi_native_runtime_setup();
- set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-
- efi.runtime_version = efi.systab->hdr.revision;
+ if ((md->attribute & EFI_MEMORY_WB) == 0)
+ prot_val = PROT_DEVICE_nGnRE;
+ else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
+ !PAGE_ALIGNED(md->phys_addr))
+ prot_val = pgprot_val(PAGE_KERNEL_EXEC);
+ else
+ prot_val = pgprot_val(PAGE_KERNEL);
+ create_pgd_mapping(mm, md->phys_addr, md->virt_addr,
+ md->num_pages << EFI_PAGE_SHIFT,
+ __pgprot(prot_val | PTE_NG));
return 0;
}
-early_initcall(arm64_enable_runtime_services);
static int __init arm64_dmi_init(void)
{
@@ -337,30 +54,6 @@ static int __init arm64_dmi_init(void)
}
core_initcall(arm64_dmi_init);
-static void efi_set_pgd(struct mm_struct *mm)
-{
- if (mm == &init_mm)
- cpu_set_reserved_ttbr0();
- else
- cpu_switch_mm(mm->pgd, mm);
-
- flush_tlb_all();
- if (icache_is_aivivt())
- __flush_icache_all();
-}
-
-void efi_virtmap_load(void)
-{
- preempt_disable();
- efi_set_pgd(&efi_mm);
-}
-
-void efi_virtmap_unload(void)
-{
- efi_set_pgd(current->active_mm);
- preempt_enable();
-}
-
/*
* UpdateCapsule() depends on the system being shutdown via
* ResetSystem().
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 4306c93..1f7f5a2 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -27,6 +27,7 @@
#include <asm/cpufeature.h>
#include <asm/errno.h>
#include <asm/esr.h>
+#include <asm/irq.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
@@ -88,9 +89,12 @@
.if \el == 0
mrs x21, sp_el0
- get_thread_info tsk // Ensure MDSCR_EL1.SS is clear,
+ mov tsk, sp
+ and tsk, tsk, #~(THREAD_SIZE - 1) // Ensure MDSCR_EL1.SS is clear,
ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug
disable_step_tsk x19, x20 // exceptions when scheduling.
+
+ mov x29, xzr // fp pointed to user-space
.else
add x21, sp, #S_FRAME_SIZE
.endif
@@ -108,6 +112,13 @@
.endif
/*
+ * Set sp_el0 to current thread_info.
+ */
+ .if \el == 0
+ msr sp_el0, tsk
+ .endif
+
+ /*
* Registers that may be useful after this macro is invoked:
*
* x21 - aborted SP
@@ -164,8 +175,44 @@ alternative_endif
.endm
.macro get_thread_info, rd
- mov \rd, sp
- and \rd, \rd, #~(THREAD_SIZE - 1) // top of stack
+ mrs \rd, sp_el0
+ .endm
+
+ .macro irq_stack_entry
+ mov x19, sp // preserve the original sp
+
+ /*
+ * Compare sp with the current thread_info, if the top
+ * ~(THREAD_SIZE - 1) bits match, we are on a task stack, and
+ * should switch to the irq stack.
+ */
+ and x25, x19, #~(THREAD_SIZE - 1)
+ cmp x25, tsk
+ b.ne 9998f
+
+ this_cpu_ptr irq_stack, x25, x26
+ mov x26, #IRQ_STACK_START_SP
+ add x26, x25, x26
+
+ /* switch to the irq stack */
+ mov sp, x26
+
+ /*
+ * Add a dummy stack frame, this non-standard format is fixed up
+ * by unwind_frame()
+ */
+ stp x29, x19, [sp, #-16]!
+ mov x29, sp
+
+9998:
+ .endm
+
+ /*
+ * x19 should be preserved between irq_stack_entry and
+ * irq_stack_exit.
+ */
+ .macro irq_stack_exit
+ mov sp, x19
.endm
/*
@@ -183,10 +230,11 @@ tsk .req x28 // current thread_info
* Interrupt handling.
*/
.macro irq_handler
- adrp x1, handle_arch_irq
- ldr x1, [x1, #:lo12:handle_arch_irq]
+ ldr_l x1, handle_arch_irq
mov x0, sp
+ irq_stack_entry
blr x1
+ irq_stack_exit
.endm
.text
@@ -358,10 +406,10 @@ el1_irq:
bl trace_hardirqs_off
#endif
+ get_thread_info tsk
irq_handler
#ifdef CONFIG_PREEMPT
- get_thread_info tsk
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
cbnz w24, 1f // preempt count != 0
ldr x0, [tsk, #TI_FLAGS] // get flags
@@ -430,6 +478,8 @@ el0_sync_compat:
b.eq el0_fpsimd_acc
cmp x24, #ESR_ELx_EC_FP_EXC32 // FP/ASIMD exception
b.eq el0_fpsimd_exc
+ cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception
+ b.eq el0_sp_pc
cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0
b.eq el0_undef
cmp x24, #ESR_ELx_EC_CP15_32 // CP15 MRC/MCR trap
@@ -597,6 +647,8 @@ ENTRY(cpu_switch_to)
ldp x29, x9, [x8], #16
ldr lr, [x8]
mov sp, x9
+ and x9, x9, #~(THREAD_SIZE - 1)
+ msr sp_el0, x9
ret
ENDPROC(cpu_switch_to)
@@ -624,14 +676,14 @@ ret_fast_syscall_trace:
work_pending:
tbnz x1, #TIF_NEED_RESCHED, work_resched
/* TIF_SIGPENDING, TIF_NOTIFY_RESUME or TIF_FOREIGN_FPSTATE case */
- ldr x2, [sp, #S_PSTATE]
mov x0, sp // 'regs'
- tst x2, #PSR_MODE_MASK // user mode regs?
- b.ne no_work_pending // returning to kernel
enable_irq // enable interrupts for do_notify_resume()
bl do_notify_resume
b ret_to_user
work_resched:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off // the IRQs are off here, inform the tracing code
+#endif
bl schedule
/*
@@ -643,7 +695,6 @@ ret_to_user:
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
enable_step_tsk x1, x2
-no_work_pending:
kernel_exit 0
ENDPROC(ret_to_user)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c56956a..975b274 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -45,7 +45,7 @@
* been used to perform kernel mode NEON in the meantime.
*
* For (a), we add a 'cpu' field to struct fpsimd_state, which gets updated to
- * the id of the current CPU everytime the state is loaded onto a CPU. For (b),
+ * the id of the current CPU every time the state is loaded onto a CPU. For (b),
* we add the per-cpu variable 'fpsimd_last_state' (below), which contains the
* address of the userland FPSIMD state of the task that was loaded onto the CPU
* the most recently, or NULL if kernel mode NEON has been performed after that.
@@ -289,7 +289,7 @@ static struct notifier_block fpsimd_cpu_pm_notifier_block = {
.notifier_call = fpsimd_cpu_pm_notifier,
};
-static void fpsimd_pm_init(void)
+static void __init fpsimd_pm_init(void)
{
cpu_pm_register_notifier(&fpsimd_cpu_pm_notifier_block);
}
@@ -332,21 +332,15 @@ static inline void fpsimd_hotplug_init(void) { }
*/
static int __init fpsimd_init(void)
{
- u64 pfr = read_cpuid(ID_AA64PFR0_EL1);
-
- if (pfr & (0xf << 16)) {
+ if (elf_hwcap & HWCAP_FP) {
+ fpsimd_pm_init();
+ fpsimd_hotplug_init();
+ } else {
pr_notice("Floating-point is not implemented\n");
- return 0;
}
- elf_hwcap |= HWCAP_FP;
- if (pfr & (0xf << 20))
+ if (!(elf_hwcap & HWCAP_ASIMD))
pr_notice("Advanced SIMD is not implemented\n");
- else
- elf_hwcap |= HWCAP_ASIMD;
-
- fpsimd_pm_init();
- fpsimd_hotplug_init();
return 0;
}
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index c851be7..ebecf9a 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -29,12 +29,11 @@ static int ftrace_modify_code(unsigned long pc, u32 old, u32 new,
/*
* Note:
- * Due to modules and __init, code can disappear and change,
- * we need to protect against faulting as well as code changing.
- * We do this by aarch64_insn_*() which use the probe_kernel_*().
- *
- * No lock is held here because all the modifications are run
- * through stop_machine().
+ * We are paranoid about modifying text, as if a bug were to happen, it
+ * could cause us to read or write to someplace that could cause harm.
+ * Carefully read and modify the code with aarch64_insn_*() which uses
+ * probe_kernel_*(), and make sure what we read is what we expected it
+ * to be before modifying it.
*/
if (validate) {
if (aarch64_insn_read((void *)pc, &replaced))
@@ -93,6 +92,11 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
return ftrace_modify_code(pc, old, new, true);
}
+void arch_ftrace_update_code(int command)
+{
+ ftrace_modify_all_code(command);
+}
+
int __init ftrace_dyn_arch_init(void)
{
return 0;
@@ -125,23 +129,20 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
* on other archs. It's unlikely on AArch64.
*/
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;
+ if (!ftrace_graph_entry(&trace))
return;
- }
err = ftrace_push_return_trace(old, self_addr, &trace.depth,
frame_pointer);
- if (err == -EBUSY) {
- *parent = old;
+ if (err == -EBUSY)
return;
- }
+ else
+ *parent = return_hooker;
}
#ifdef CONFIG_DYNAMIC_FTRACE
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 90d09ed..6ebd204 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -29,11 +29,16 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>
#include <asm/cputype.h>
+#include <asm/elf.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/kvm_arm.h>
#include <asm/memory.h>
-#include <asm/thread_info.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
#include <asm/page.h>
+#include <asm/smp.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
#include <asm/virt.h>
#define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
@@ -46,32 +51,10 @@
#error TEXT_OFFSET must be less than 2MB
#endif
-#ifdef CONFIG_ARM64_64K_PAGES
-#define BLOCK_SHIFT PAGE_SHIFT
-#define BLOCK_SIZE PAGE_SIZE
-#define TABLE_SHIFT PMD_SHIFT
-#else
-#define BLOCK_SHIFT SECTION_SHIFT
-#define BLOCK_SIZE SECTION_SIZE
-#define TABLE_SHIFT PUD_SHIFT
-#endif
-
#define KERNEL_START _text
#define KERNEL_END _end
/*
- * Initial memory map attributes.
- */
-#define PTE_FLAGS PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
-#define PMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
-
-#ifdef CONFIG_ARM64_64K_PAGES
-#define MM_MMUFLAGS PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
-#else
-#define MM_MMUFLAGS PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS
-#endif
-
-/*
* Kernel startup entry point.
* ---------------------------
*
@@ -87,12 +70,11 @@
* in the entry routines.
*/
__HEAD
-
+_head:
/*
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
*/
#ifdef CONFIG_EFI
-efi_head:
/*
* This add instruction has no meaningful effect except that
* its opcode forms the magic "MZ" signature required by UEFI.
@@ -103,9 +85,9 @@ efi_head:
b stext // branch to kernel start, magic
.long 0 // reserved
#endif
- .quad _kernel_offset_le // Image load offset from start of RAM, little-endian
- .quad _kernel_size_le // Effective size of kernel image, little-endian
- .quad _kernel_flags_le // Informative flags, little-endian
+ le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
+ le64sym _kernel_size_le // Effective size of kernel image, little-endian
+ le64sym _kernel_flags_le // Informative flags, little-endian
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
@@ -114,14 +96,14 @@ efi_head:
.byte 0x4d
.byte 0x64
#ifdef CONFIG_EFI
- .long pe_header - efi_head // Offset to the PE header.
+ .long pe_header - _head // Offset to the PE header.
#else
.word 0 // reserved
#endif
#ifdef CONFIG_EFI
- .globl stext_offset
- .set stext_offset, stext - efi_head
+ .globl __efistub_stext_offset
+ .set __efistub_stext_offset, stext - _head
.align 3
pe_header:
.ascii "PE"
@@ -144,8 +126,8 @@ optional_header:
.long _end - stext // SizeOfCode
.long 0 // SizeOfInitializedData
.long 0 // SizeOfUninitializedData
- .long efi_stub_entry - efi_head // AddressOfEntryPoint
- .long stext_offset // BaseOfCode
+ .long __efistub_entry - _head // AddressOfEntryPoint
+ .long __efistub_stext_offset // BaseOfCode
extra_header_fields:
.quad 0 // ImageBase
@@ -159,10 +141,10 @@ extra_header_fields:
.short 0 // MinorSubsystemVersion
.long 0 // Win32VersionValue
- .long _end - efi_head // SizeOfImage
+ .long _end - _head // SizeOfImage
// Everything before the kernel image is considered part of the header
- .long stext_offset // SizeOfHeaders
+ .long __efistub_stext_offset // SizeOfHeaders
.long 0 // CheckSum
.short 0xa // Subsystem (EFI application)
.short 0 // DllCharacteristics
@@ -207,9 +189,9 @@ section_table:
.byte 0
.byte 0 // end of 0 padding of section name
.long _end - stext // VirtualSize
- .long stext_offset // VirtualAddress
+ .long __efistub_stext_offset // VirtualAddress
.long _edata - stext // SizeOfRawData
- .long stext_offset // PointerToRawData
+ .long __efistub_stext_offset // PointerToRawData
.long 0 // PointerToRelocations (0 for executables)
.long 0 // PointerToLineNumbers (0 for executables)
@@ -230,6 +212,7 @@ section_table:
ENTRY(stext)
bl preserve_boot_args
bl el2_setup // Drop to EL1, w20=cpu_boot_mode
+ mov x23, xzr // KASLR offset, defaults to 0
adrp x24, __PHYS_OFFSET
bl set_cpu_boot_mode_flag
bl __create_page_tables // x25=TTBR0, x26=TTBR1
@@ -239,11 +222,13 @@ ENTRY(stext)
* On return, the CPU will be ready for the MMU to be turned on and
* the TCR will have been set.
*/
- ldr x27, =__mmap_switched // address to jump to after
+ ldr x27, 0f // address to jump to after
// MMU has been enabled
adr_l lr, __enable_mmu // return (PIC) address
b __cpu_setup // initialise processor
ENDPROC(stext)
+ .align 3
+0: .quad __mmap_switched - (_head - TEXT_OFFSET) + KIMAGE_VADDR
/*
* Preserve the arguments passed by the bootloader in x0 .. x3
@@ -292,8 +277,11 @@ ENDPROC(preserve_boot_args)
*/
.macro create_pgd_entry, tbl, virt, tmp1, tmp2
create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
-#if SWAPPER_PGTABLE_LEVELS == 3
- create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
+#if SWAPPER_PGTABLE_LEVELS > 3
+ create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
+#endif
+#if SWAPPER_PGTABLE_LEVELS > 2
+ create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
#endif
.endm
@@ -305,15 +293,15 @@ ENDPROC(preserve_boot_args)
* Corrupts: phys, start, end, pstate
*/
.macro create_block_map, tbl, flags, phys, start, end
- lsr \phys, \phys, #BLOCK_SHIFT
- lsr \start, \start, #BLOCK_SHIFT
+ lsr \phys, \phys, #SWAPPER_BLOCK_SHIFT
+ lsr \start, \start, #SWAPPER_BLOCK_SHIFT
and \start, \start, #PTRS_PER_PTE - 1 // table index
- orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry
- lsr \end, \end, #BLOCK_SHIFT
+ orr \phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT // table entry
+ lsr \end, \end, #SWAPPER_BLOCK_SHIFT
and \end, \end, #PTRS_PER_PTE - 1 // table end index
9999: str \phys, [\tbl, \start, lsl #3] // store the entry
add \start, \start, #1 // next entry
- add \phys, \phys, #BLOCK_SIZE // next block
+ add \phys, \phys, #SWAPPER_BLOCK_SIZE // next block
cmp \start, \end
b.ls 9999b
.endm
@@ -328,7 +316,7 @@ ENDPROC(preserve_boot_args)
__create_page_tables:
adrp x25, idmap_pg_dir
adrp x26, swapper_pg_dir
- mov x27, lr
+ mov x28, lr
/*
* Invalidate the idmap and swapper page tables to avoid potential
@@ -350,7 +338,7 @@ __create_page_tables:
cmp x0, x6
b.lo 1b
- ldr x7, =MM_MMUFLAGS
+ ldr x7, =SWAPPER_MM_MMUFLAGS
/*
* Create the identity mapping.
@@ -406,9 +394,11 @@ __create_page_tables:
* Map the kernel image (starting with PHYS_OFFSET).
*/
mov x0, x26 // swapper_pg_dir
- mov x5, #PAGE_OFFSET
+ ldr x5, =KIMAGE_VADDR
+ add x5, x5, x23 // add KASLR displacement
create_pgd_entry x0, x5, x3, x6
- ldr x6, =KERNEL_END // __va(KERNEL_END)
+ ldr w6, kernel_img_size
+ add x6, x6, x5
mov x3, x24 // phys offset
create_block_map x0, x7, x3, x5, x6
@@ -422,9 +412,11 @@ __create_page_tables:
dmb sy
bl __inval_cache_range
- mov lr, x27
- ret
+ ret x28
ENDPROC(__create_page_tables)
+
+kernel_img_size:
+ .long _end - (_head - TEXT_OFFSET)
.ltorg
/*
@@ -432,18 +424,81 @@ ENDPROC(__create_page_tables)
*/
.set initial_sp, init_thread_union + THREAD_START_SP
__mmap_switched:
- adr_l x6, __bss_start
- adr_l x7, __bss_stop
+ mov x28, lr // preserve LR
+ adr_l x8, vectors // load VBAR_EL1 with virtual
+ msr vbar_el1, x8 // vector table address
+ isb
+
+ // Clear BSS
+ adr_l x0, __bss_start
+ mov x1, xzr
+ adr_l x2, __bss_stop
+ sub x2, x2, x0
+ bl __pi_memset
+ dsb ishst // Make zero page visible to PTW
+
+#ifdef CONFIG_RELOCATABLE
-1: cmp x6, x7
+ /*
+ * Iterate over each entry in the relocation table, and apply the
+ * relocations in place.
+ */
+ adr_l x8, __dynsym_start // start of symbol table
+ adr_l x9, __reloc_start // start of reloc table
+ adr_l x10, __reloc_end // end of reloc table
+
+0: cmp x9, x10
b.hs 2f
- str xzr, [x6], #8 // Clear BSS
- b 1b
-2:
+ ldp x11, x12, [x9], #24
+ ldr x13, [x9, #-8]
+ cmp w12, #R_AARCH64_RELATIVE
+ b.ne 1f
+ add x13, x13, x23 // relocate
+ str x13, [x11, x23]
+ b 0b
+
+1: cmp w12, #R_AARCH64_ABS64
+ b.ne 0b
+ add x12, x12, x12, lsl #1 // symtab offset: 24x top word
+ add x12, x8, x12, lsr #(32 - 3) // ... shifted into bottom word
+ ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx
+ ldr x15, [x12, #8] // Elf64_Sym::st_value
+ cmp w14, #-0xf // SHN_ABS (0xfff1) ?
+ add x14, x15, x23 // relocate
+ csel x15, x14, x15, ne
+ add x15, x13, x15
+ str x15, [x11, x23]
+ b 0b
+
+2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
+ dc cvac, x8 // value visible to secondaries
+ dsb sy // with MMU off
+#endif
+
adr_l sp, initial_sp, x4
+ mov x4, sp
+ and x4, x4, #~(THREAD_SIZE - 1)
+ msr sp_el0, x4 // Save thread_info
str_l x21, __fdt_pointer, x5 // Save FDT pointer
- str_l x24, memstart_addr, x6 // Save PHYS_OFFSET
+
+ ldr_l x4, kimage_vaddr // Save the offset between
+ sub x4, x4, x24 // the kernel virtual and
+ str_l x4, kimage_voffset, x5 // physical mappings
+
mov x29, #0
+#ifdef CONFIG_KASAN
+ bl kasan_early_init
+#endif
+#ifdef CONFIG_RANDOMIZE_BASE
+ cbnz x23, 0f // already running randomized?
+ mov x0, x21 // pass FDT address in x0
+ bl kaslr_early_init // parse FDT for KASLR options
+ cbz x0, 0f // KASLR disabled? just proceed
+ mov x23, x0 // record KASLR offset
+ ret x28 // we must enable KASLR, return
+ // to __enable_mmu()
+0:
+#endif
b start_kernel
ENDPROC(__mmap_switched)
@@ -452,6 +507,10 @@ ENDPROC(__mmap_switched)
* hotplug and needs to have the same protections as the text region
*/
.section ".text","ax"
+
+ENTRY(kimage_vaddr)
+ .quad _text - TEXT_OFFSET
+
/*
* If we're fortunate enough to boot at EL2, ensure that the world is
* sane before dropping to EL1.
@@ -476,9 +535,27 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1
isb
ret
+2:
+#ifdef CONFIG_ARM64_VHE
+ /*
+ * Check for VHE being present. For the rest of the EL2 setup,
+ * x2 being non-zero indicates that we do have VHE, and that the
+ * kernel is intended to run at EL2.
+ */
+ mrs x2, id_aa64mmfr1_el1
+ ubfx x2, x2, #8, #4
+#else
+ mov x2, xzr
+#endif
+
/* Hyp configuration. */
-2: mov x0, #(1 << 31) // 64-bit EL1
+ mov x0, #HCR_RW // 64-bit EL1
+ cbz x2, set_hcr
+ orr x0, x0, #HCR_TGE // Enable Host Extensions
+ orr x0, x0, #HCR_E2H
+set_hcr:
msr hcr_el2, x0
+ isb
/* Generic timers. */
mrs x0, cnthctl_el2
@@ -498,6 +575,8 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1
orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1
msr_s ICC_SRE_EL2, x0
isb // Make sure SRE is now set
+ mrs_s x0, ICC_SRE_EL2 // Read SRE back,
+ tbz x0, #0, 3f // and check that it sticks
msr_s ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults
3:
@@ -524,13 +603,25 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
#endif
/* EL2 debug */
+ mrs x0, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
+ sbfx x0, x0, #8, #4
+ cmp x0, #1
+ b.lt 4f // Skip if no PMU present
mrs x0, pmcr_el0 // Disable debug access traps
ubfx x0, x0, #11, #5 // to EL2 and allow access to
msr mdcr_el2, x0 // all PMU counters from EL1
+4:
/* Stage-2 translation */
msr vttbr_el2, xzr
+ cbz x2, install_el2_stub
+
+ mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
+ isb
+ ret
+
+install_el2_stub:
/* Hypervisor stub */
adrp x0, __hyp_stub_vectors
add x0, x0, #:lo12:__hyp_stub_vectors
@@ -610,30 +701,69 @@ ENTRY(secondary_startup)
adrp x26, swapper_pg_dir
bl __cpu_setup // initialise processor
- ldr x21, =secondary_data
- ldr x27, =__secondary_switched // address to jump to after enabling the MMU
+ ldr x8, kimage_vaddr
+ ldr w9, 0f
+ sub x27, x8, w9, sxtw // address to jump to after enabling the MMU
b __enable_mmu
ENDPROC(secondary_startup)
+0: .long (_text - TEXT_OFFSET) - __secondary_switched
ENTRY(__secondary_switched)
- ldr x0, [x21] // get secondary_data.stack
+ adr_l x5, vectors
+ msr vbar_el1, x5
+ isb
+
+ adr_l x0, secondary_data
+ ldr x0, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
mov sp, x0
+ and x0, x0, #~(THREAD_SIZE - 1)
+ msr sp_el0, x0 // save thread_info
mov x29, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
/*
+ * The booting CPU updates the failed status @__early_cpu_boot_status,
+ * with MMU turned off.
+ *
+ * update_early_cpu_boot_status tmp, status
+ * - Corrupts tmp1, tmp2
+ * - Writes 'status' to __early_cpu_boot_status and makes sure
+ * it is committed to memory.
+ */
+
+ .macro update_early_cpu_boot_status status, tmp1, tmp2
+ mov \tmp2, #\status
+ str_l \tmp2, __early_cpu_boot_status, \tmp1
+ dmb sy
+ dc ivac, \tmp1 // Invalidate potentially stale cache line
+ .endm
+
+ .pushsection .data..cacheline_aligned
+ .align L1_CACHE_SHIFT
+ENTRY(__early_cpu_boot_status)
+ .long 0
+ .popsection
+
+/*
* Enable the MMU.
*
* x0 = SCTLR_EL1 value for turning on the MMU.
* x27 = *virtual* address to jump to upon completion
*
- * other registers depend on the function called upon completion
+ * Other registers depend on the function called upon completion.
+ *
+ * Checks if the selected granule size is supported by the CPU.
+ * If it isn't, park the CPU
*/
.section ".idmap.text", "ax"
__enable_mmu:
- ldr x5, =vectors
- msr vbar_el1, x5
+ mrs x18, sctlr_el1 // preserve old SCTLR_EL1 value
+ mrs x1, ID_AA64MMFR0_EL1
+ ubfx x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+ cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
+ b.ne __no_granule_support
+ update_early_cpu_boot_status 0, x1, x2
msr ttbr0_el1, x25 // load TTBR0
msr ttbr1_el1, x26 // load TTBR1
isb
@@ -647,5 +777,33 @@ __enable_mmu:
ic iallu
dsb nsh
isb
+#ifdef CONFIG_RANDOMIZE_BASE
+ mov x19, x0 // preserve new SCTLR_EL1 value
+ blr x27
+
+ /*
+ * If we return here, we have a KASLR displacement in x23 which we need
+ * to take into account by discarding the current kernel mapping and
+ * creating a new one.
+ */
+ msr sctlr_el1, x18 // disable the MMU
+ isb
+ bl __create_page_tables // recreate kernel mapping
+
+ msr sctlr_el1, x19 // re-enable the MMU
+ isb
+ ic ialluis // flush instructions fetched
+ isb // via old mapping
+ add x27, x27, x23 // relocated __mmap_switched
+#endif
br x27
ENDPROC(__enable_mmu)
+
+__no_granule_support:
+ /* Indicate that this CPU can't boot and is stuck in the kernel */
+ update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x1, x2
+1:
+ wfe
+ wfi
+ b 1b
+ENDPROC(__no_granule_support)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index bba85c8..b45c95d 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -28,6 +28,7 @@
#include <linux/ptrace.h>
#include <linux/smp.h>
+#include <asm/compat.h>
#include <asm/current.h>
#include <asm/debug-monitors.h>
#include <asm/hw_breakpoint.h>
@@ -163,6 +164,20 @@ enum hw_breakpoint_ops {
HW_BREAKPOINT_RESTORE
};
+static int is_compat_bp(struct perf_event *bp)
+{
+ struct task_struct *tsk = bp->hw.target;
+
+ /*
+ * tsk can be NULL for per-cpu (non-ptrace) breakpoints.
+ * In this case, use the native interface, since we don't have
+ * the notion of a "compat CPU" and could end up relying on
+ * deprecated behaviour if we use unaligned watchpoints in
+ * AArch64 state.
+ */
+ return tsk && is_compat_thread(task_thread_info(tsk));
+}
+
/**
* hw_breakpoint_slot_setup - Find and setup a perf slot according to
* operations
@@ -420,7 +435,7 @@ static int arch_build_bp_info(struct perf_event *bp)
* Watchpoints can be of length 1, 2, 4 or 8 bytes.
*/
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
- if (is_compat_task()) {
+ if (is_compat_bp(bp)) {
if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
info->ctrl.len != ARM_BREAKPOINT_LEN_4)
return -EINVAL;
@@ -477,7 +492,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* AArch32 tasks expect some simple alignment fixups, so emulate
* that here.
*/
- if (is_compat_task()) {
+ if (is_compat_bp(bp)) {
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
alignment_mask = 0x7;
else
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index 8fae075..5e360ce 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -26,28 +26,40 @@
* There aren't any ELF relocations we can use to endian-swap values known only
* at link time (e.g. the subtraction of two symbol addresses), so we must get
* the linker to endian-swap certain values before emitting them.
+ *
+ * Note that, in order for this to work when building the ELF64 PIE executable
+ * (for KASLR), these values should not be referenced via R_AARCH64_ABS64
+ * relocations, since these are fixed up at runtime rather than at build time
+ * when PIE is in effect. So we need to split them up in 32-bit high and low
+ * words.
*/
#ifdef CONFIG_CPU_BIG_ENDIAN
-#define DATA_LE64(data) \
- ((((data) & 0x00000000000000ff) << 56) | \
- (((data) & 0x000000000000ff00) << 40) | \
- (((data) & 0x0000000000ff0000) << 24) | \
- (((data) & 0x00000000ff000000) << 8) | \
- (((data) & 0x000000ff00000000) >> 8) | \
- (((data) & 0x0000ff0000000000) >> 24) | \
- (((data) & 0x00ff000000000000) >> 40) | \
- (((data) & 0xff00000000000000) >> 56))
+#define DATA_LE32(data) \
+ ((((data) & 0x000000ff) << 24) | \
+ (((data) & 0x0000ff00) << 8) | \
+ (((data) & 0x00ff0000) >> 8) | \
+ (((data) & 0xff000000) >> 24))
#else
-#define DATA_LE64(data) ((data) & 0xffffffffffffffff)
+#define DATA_LE32(data) ((data) & 0xffffffff)
#endif
+#define DEFINE_IMAGE_LE64(sym, data) \
+ sym##_lo32 = DATA_LE32((data) & 0xffffffff); \
+ sym##_hi32 = DATA_LE32((data) >> 32)
+
#ifdef CONFIG_CPU_BIG_ENDIAN
-#define __HEAD_FLAG_BE 1
+#define __HEAD_FLAG_BE 1
#else
-#define __HEAD_FLAG_BE 0
+#define __HEAD_FLAG_BE 0
#endif
-#define __HEAD_FLAGS (__HEAD_FLAG_BE << 0)
+#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
+
+#define __HEAD_FLAG_PHYS_BASE 1
+
+#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \
+ (__HEAD_FLAG_PAGE_SIZE << 1) | \
+ (__HEAD_FLAG_PHYS_BASE << 3))
/*
* These will output as part of the Image header, which should be little-endian
@@ -55,8 +67,52 @@
* endian swapped in head.S, all are done here for consistency.
*/
#define HEAD_SYMBOLS \
- _kernel_size_le = DATA_LE64(_end - _text); \
- _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \
- _kernel_flags_le = DATA_LE64(__HEAD_FLAGS);
+ DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text); \
+ DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \
+ DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
+
+#ifdef CONFIG_EFI
+
+/*
+ * Prevent the symbol aliases below from being emitted into the kallsyms
+ * table, by forcing them to be absolute symbols (which are conveniently
+ * ignored by scripts/kallsyms) rather than section relative symbols.
+ * The distinction is only relevant for partial linking, and only for symbols
+ * that are defined within a section declaration (which is not the case for
+ * the definitions below) so the resulting values will be identical.
+ */
+#define KALLSYMS_HIDE(sym) ABSOLUTE(sym)
+
+/*
+ * The EFI stub has its own symbol namespace prefixed by __efistub_, to
+ * isolate it from the kernel proper. The following symbols are legally
+ * accessed by the stub, so provide some aliases to make them accessible.
+ * Only include data symbols here, or text symbols of functions that are
+ * guaranteed to be safe when executed at another offset than they were
+ * linked at. The routines below are all implemented in assembler in a
+ * position independent manner
+ */
+__efistub_memcmp = KALLSYMS_HIDE(__pi_memcmp);
+__efistub_memchr = KALLSYMS_HIDE(__pi_memchr);
+__efistub_memcpy = KALLSYMS_HIDE(__pi_memcpy);
+__efistub_memmove = KALLSYMS_HIDE(__pi_memmove);
+__efistub_memset = KALLSYMS_HIDE(__pi_memset);
+__efistub_strlen = KALLSYMS_HIDE(__pi_strlen);
+__efistub_strnlen = KALLSYMS_HIDE(__pi_strnlen);
+__efistub_strcmp = KALLSYMS_HIDE(__pi_strcmp);
+__efistub_strncmp = KALLSYMS_HIDE(__pi_strncmp);
+__efistub___flush_dcache_area = KALLSYMS_HIDE(__pi___flush_dcache_area);
+
+#ifdef CONFIG_KASAN
+__efistub___memcpy = KALLSYMS_HIDE(__pi_memcpy);
+__efistub___memmove = KALLSYMS_HIDE(__pi_memmove);
+__efistub___memset = KALLSYMS_HIDE(__pi_memset);
+#endif
+
+__efistub__text = KALLSYMS_HIDE(_text);
+__efistub__end = KALLSYMS_HIDE(_end);
+__efistub__edata = KALLSYMS_HIDE(_edata);
+
+#endif
#endif /* __ASM_IMAGE_H */
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index c08b9ad..7371455 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -2,7 +2,7 @@
* Copyright (C) 2013 Huawei Ltd.
* Author: Jiang Liu <liuj97@gmail.com>
*
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@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
@@ -363,6 +363,9 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
u32 immlo, immhi, mask;
int shift;
+ if (insn == AARCH64_BREAK_FAULT)
+ return AARCH64_BREAK_FAULT;
+
switch (type) {
case AARCH64_INSN_IMM_ADR:
shift = 0;
@@ -377,7 +380,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
}
@@ -394,9 +397,12 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
{
int shift;
+ if (insn == AARCH64_BREAK_FAULT)
+ return AARCH64_BREAK_FAULT;
+
if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
pr_err("%s: unknown register encoding %d\n", __func__, reg);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
switch (type) {
@@ -417,7 +423,7 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
default:
pr_err("%s: unknown register type encoding %d\n", __func__,
type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
insn &= ~(GENMASK(4, 0) << shift);
@@ -446,7 +452,7 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
break;
default:
pr_err("%s: unknown size encoding %d\n", __func__, type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
insn &= ~GENMASK(31, 30);
@@ -460,14 +466,17 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr,
{
long offset;
- /*
- * PC: A 64-bit Program Counter holding the address of the current
- * instruction. A64 instructions must be word-aligned.
- */
- BUG_ON((pc & 0x3) || (addr & 0x3));
+ if ((pc & 0x3) || (addr & 0x3)) {
+ pr_err("%s: A64 instructions must be word aligned\n", __func__);
+ return range;
+ }
offset = ((long)addr - (long)pc);
- BUG_ON(offset < -range || offset >= range);
+
+ if (offset < -range || offset >= range) {
+ pr_err("%s: offset out of range\n", __func__);
+ return range;
+ }
return offset;
}
@@ -484,6 +493,8 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
* texts are within +/-128M.
*/
offset = branch_imm_common(pc, addr, SZ_128M);
+ if (offset >= SZ_128M)
+ return AARCH64_BREAK_FAULT;
switch (type) {
case AARCH64_INSN_BRANCH_LINK:
@@ -493,7 +504,7 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_b_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -510,6 +521,8 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
long offset;
offset = branch_imm_common(pc, addr, SZ_1M);
+ if (offset >= SZ_1M)
+ return AARCH64_BREAK_FAULT;
switch (type) {
case AARCH64_INSN_BRANCH_COMP_ZERO:
@@ -519,7 +532,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_cbnz_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -530,7 +543,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -550,7 +563,10 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_bcond_value();
- BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL);
+ if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
+ pr_err("%s: unknown condition encoding %d\n", __func__, cond);
+ return AARCH64_BREAK_FAULT;
+ }
insn |= cond;
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
@@ -583,7 +599,7 @@ u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
insn = aarch64_insn_get_ret_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -606,7 +622,7 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
insn = aarch64_insn_get_str_reg_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown load/store encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -645,26 +661,30 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
insn = aarch64_insn_get_stp_post_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown load/store encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- /* offset must be multiples of 4 in the range [-256, 252] */
- BUG_ON(offset & 0x3);
- BUG_ON(offset < -256 || offset > 252);
+ if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
+ pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
+ __func__, offset);
+ return AARCH64_BREAK_FAULT;
+ }
shift = 2;
break;
case AARCH64_INSN_VARIANT_64BIT:
- /* offset must be multiples of 8 in the range [-512, 504] */
- BUG_ON(offset & 0x7);
- BUG_ON(offset < -512 || offset > 504);
+ if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
+ pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
+ __func__, offset);
+ return AARCH64_BREAK_FAULT;
+ }
shift = 3;
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -702,7 +722,7 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
insn = aarch64_insn_get_subs_imm_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -713,11 +733,14 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(imm & ~(SZ_4K - 1));
+ if (imm & ~(SZ_4K - 1)) {
+ pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
@@ -746,7 +769,7 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
insn = aarch64_insn_get_sbfm_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -759,12 +782,18 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
mask = GENMASK(5, 0);
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(immr & ~mask);
- BUG_ON(imms & ~mask);
+ if (immr & ~mask) {
+ pr_err("%s: invalid immr encoding %d\n", __func__, immr);
+ return AARCH64_BREAK_FAULT;
+ }
+ if (imms & ~mask) {
+ pr_err("%s: invalid imms encoding %d\n", __func__, imms);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
@@ -793,23 +822,33 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
insn = aarch64_insn_get_movn_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown movewide encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(imm & ~(SZ_64K - 1));
+ if (imm & ~(SZ_64K - 1)) {
+ pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
+ return AARCH64_BREAK_FAULT;
+ }
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift != 0 && shift != 16);
+ if (shift != 0 && shift != 16) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift != 0 && shift != 16 && shift != 32 &&
- shift != 48);
+ if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -843,20 +882,28 @@ u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
insn = aarch64_insn_get_subs_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift & ~(SZ_32 - 1));
+ if (shift & ~(SZ_32 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift & ~(SZ_64 - 1));
+ if (shift & ~(SZ_64 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -885,11 +932,15 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
insn = aarch64_insn_get_rev32_value();
break;
case AARCH64_INSN_DATA1_REVERSE_64:
- BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT);
+ if (variant != AARCH64_INSN_VARIANT_64BIT) {
+ pr_err("%s: invalid variant for reverse64 %d\n",
+ __func__, variant);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_get_rev64_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data1 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -900,7 +951,7 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -937,7 +988,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
insn = aarch64_insn_get_rorv_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data2 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -948,7 +999,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -976,7 +1027,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
insn = aarch64_insn_get_msub_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data3 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -987,7 +1038,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -1037,20 +1088,28 @@ u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
insn = aarch64_insn_get_bics_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown logical encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift & ~(SZ_32 - 1));
+ if (shift & ~(SZ_32 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift & ~(SZ_64 - 1));
+ if (shift & ~(SZ_64 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 11dc3fd..2386b26 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -27,10 +27,12 @@
#include <linux/init.h>
#include <linux/irqchip.h>
#include <linux/seq_file.h>
-#include <linux/ratelimit.h>
unsigned long irq_err_count;
+/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */
+DEFINE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack) __aligned(16);
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
show_ipi_list(p, prec);
@@ -54,64 +56,3 @@ void __init init_IRQ(void)
if (!handle_arch_irq)
panic("No interrupt controller found.");
}
-
-#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 = irq_data_get_affinity_mask(d);
- 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(irq_data_get_affinity_mask(d), 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/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
new file mode 100644
index 0000000..5829839
--- /dev/null
+++ b/arch/arm64/kernel/kaslr.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2016 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/crc32.h>
+#include <linux/init.h>
+#include <linux/libfdt.h>
+#include <linux/mm_types.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/memory.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+
+u64 __read_mostly module_alloc_base;
+u16 __initdata memstart_offset_seed;
+
+static __init u64 get_kaslr_seed(void *fdt)
+{
+ int node, len;
+ u64 *prop;
+ u64 ret;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0)
+ return 0;
+
+ prop = fdt_getprop_w(fdt, node, "kaslr-seed", &len);
+ if (!prop || len != sizeof(u64))
+ return 0;
+
+ ret = fdt64_to_cpu(*prop);
+ *prop = 0;
+ return ret;
+}
+
+static __init const u8 *get_cmdline(void *fdt)
+{
+ static __initconst const u8 default_cmdline[] = CONFIG_CMDLINE;
+
+ if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
+ int node;
+ const u8 *prop;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0)
+ goto out;
+
+ prop = fdt_getprop(fdt, node, "bootargs", NULL);
+ if (!prop)
+ goto out;
+ return prop;
+ }
+out:
+ return default_cmdline;
+}
+
+extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
+ pgprot_t prot);
+
+/*
+ * This routine will be executed with the kernel mapped at its default virtual
+ * address, and if it returns successfully, the kernel will be remapped, and
+ * start_kernel() will be executed from a randomized virtual offset. The
+ * relocation will result in all absolute references (e.g., static variables
+ * containing function pointers) to be reinitialized, and zero-initialized
+ * .bss variables will be reset to 0.
+ */
+u64 __init kaslr_early_init(u64 dt_phys)
+{
+ void *fdt;
+ u64 seed, offset, mask, module_range;
+ const u8 *cmdline, *str;
+ int size;
+
+ /*
+ * Set a reasonable default for module_alloc_base in case
+ * we end up running with module randomization disabled.
+ */
+ module_alloc_base = (u64)_etext - MODULES_VSIZE;
+
+ /*
+ * Try to map the FDT early. If this fails, we simply bail,
+ * and proceed with KASLR disabled. We will make another
+ * attempt at mapping the FDT in setup_machine()
+ */
+ early_fixmap_init();
+ fdt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
+ if (!fdt)
+ return 0;
+
+ /*
+ * Retrieve (and wipe) the seed from the FDT
+ */
+ seed = get_kaslr_seed(fdt);
+ if (!seed)
+ return 0;
+
+ /*
+ * Check if 'nokaslr' appears on the command line, and
+ * return 0 if that is the case.
+ */
+ cmdline = get_cmdline(fdt);
+ str = strstr(cmdline, "nokaslr");
+ if (str == cmdline || (str > cmdline && *(str - 1) == ' '))
+ return 0;
+
+ /*
+ * OK, so we are proceeding with KASLR enabled. Calculate a suitable
+ * kernel image offset from the seed. Let's place the kernel in the
+ * lower half of the VMALLOC area (VA_BITS - 2).
+ * Even if we could randomize at page granularity for 16k and 64k pages,
+ * let's always round to 2 MB so we don't interfere with the ability to
+ * map using contiguous PTEs
+ */
+ mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1);
+ offset = seed & mask;
+
+ /* use the top 16 bits to randomize the linear region */
+ memstart_offset_seed = seed >> 48;
+
+ /*
+ * The kernel Image should not extend across a 1GB/32MB/512MB alignment
+ * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
+ * happens, increase the KASLR offset by the size of the kernel image.
+ */
+ if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) !=
+ (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
+ offset = (offset + (u64)(_end - _text)) & mask;
+
+ if (IS_ENABLED(CONFIG_KASAN))
+ /*
+ * KASAN does not expect the module region to intersect the
+ * vmalloc region, since shadow memory is allocated for each
+ * module at load time, whereas the vmalloc region is shadowed
+ * by KASAN zero pages. So keep modules out of the vmalloc
+ * region if KASAN is enabled.
+ */
+ return offset;
+
+ if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
+ /*
+ * Randomize the module region independently from the core
+ * kernel. This prevents modules from leaking any information
+ * about the address of the kernel itself, but results in
+ * branches between modules and the core kernel that are
+ * resolved via PLTs. (Branches between modules will be
+ * resolved normally.)
+ */
+ module_range = VMALLOC_END - VMALLOC_START - MODULES_VSIZE;
+ module_alloc_base = VMALLOC_START;
+ } else {
+ /*
+ * Randomize the module region by setting module_alloc_base to
+ * a PAGE_SIZE multiple in the range [_etext - MODULES_VSIZE,
+ * _stext) . This guarantees that the resulting region still
+ * covers [_stext, _etext], and that all relative branches can
+ * be resolved without veneers.
+ */
+ module_range = MODULES_VSIZE - (u64)(_etext - _stext);
+ module_alloc_base = (u64)_etext + offset - MODULES_VSIZE;
+ }
+
+ /* use the lower 21 bits to randomize the base of the module region */
+ module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
+ module_alloc_base &= PAGE_MASK;
+
+ return offset;
+}
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index bcac81e..b67531a 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -292,8 +292,8 @@ static struct notifier_block kgdb_notifier = {
};
/*
- * kgdb_arch_init - Perform any architecture specific initalization.
- * This function will handle the initalization of any architecture
+ * kgdb_arch_init - Perform any architecture specific initialization.
+ * This function will handle the initialization of any architecture
* specific callbacks.
*/
int kgdb_arch_init(void)
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
new file mode 100644
index 0000000..1ce90d8
--- /dev/null
+++ b/arch/arm64/kernel/module-plts.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014-2016 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/elf.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sort.h>
+
+struct plt_entry {
+ /*
+ * A program that conforms to the AArch64 Procedure Call Standard
+ * (AAPCS64) must assume that a veneer that alters IP0 (x16) and/or
+ * IP1 (x17) may be inserted at any branch instruction that is
+ * exposed to a relocation that supports long branches. Since that
+ * is exactly what we are dealing with here, we are free to use x16
+ * as a scratch register in the PLT veneers.
+ */
+ __le32 mov0; /* movn x16, #0x.... */
+ __le32 mov1; /* movk x16, #0x...., lsl #16 */
+ __le32 mov2; /* movk x16, #0x...., lsl #32 */
+ __le32 br; /* br x16 */
+};
+
+u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
+ Elf64_Sym *sym)
+{
+ struct plt_entry *plt = (struct plt_entry *)mod->arch.plt->sh_addr;
+ int i = mod->arch.plt_num_entries;
+ u64 val = sym->st_value + rela->r_addend;
+
+ /*
+ * We only emit PLT entries against undefined (SHN_UNDEF) symbols,
+ * which are listed in the ELF symtab section, but without a type
+ * or a size.
+ * So, similar to how the module loader uses the Elf64_Sym::st_value
+ * field to store the resolved addresses of undefined symbols, let's
+ * borrow the Elf64_Sym::st_size field (whose value is never used by
+ * the module loader, even for symbols that are defined) to record
+ * the address of a symbol's associated PLT entry as we emit it for a
+ * zero addend relocation (which is the only kind we have to deal with
+ * in practice). This allows us to find duplicates without having to
+ * go through the table every time.
+ */
+ if (rela->r_addend == 0 && sym->st_size != 0) {
+ BUG_ON(sym->st_size < (u64)plt || sym->st_size >= (u64)&plt[i]);
+ return sym->st_size;
+ }
+
+ mod->arch.plt_num_entries++;
+ BUG_ON(mod->arch.plt_num_entries > mod->arch.plt_max_entries);
+
+ /*
+ * MOVK/MOVN/MOVZ opcode:
+ * +--------+------------+--------+-----------+-------------+---------+
+ * | sf[31] | opc[30:29] | 100101 | hw[22:21] | imm16[20:5] | Rd[4:0] |
+ * +--------+------------+--------+-----------+-------------+---------+
+ *
+ * Rd := 0x10 (x16)
+ * hw := 0b00 (no shift), 0b01 (lsl #16), 0b10 (lsl #32)
+ * opc := 0b11 (MOVK), 0b00 (MOVN), 0b10 (MOVZ)
+ * sf := 1 (64-bit variant)
+ */
+ plt[i] = (struct plt_entry){
+ cpu_to_le32(0x92800010 | (((~val ) & 0xffff)) << 5),
+ cpu_to_le32(0xf2a00010 | ((( val >> 16) & 0xffff)) << 5),
+ cpu_to_le32(0xf2c00010 | ((( val >> 32) & 0xffff)) << 5),
+ cpu_to_le32(0xd61f0200)
+ };
+
+ if (rela->r_addend == 0)
+ sym->st_size = (u64)&plt[i];
+
+ return (u64)&plt[i];
+}
+
+#define cmp_3way(a,b) ((a) < (b) ? -1 : (a) > (b))
+
+static int cmp_rela(const void *a, const void *b)
+{
+ const Elf64_Rela *x = a, *y = b;
+ int i;
+
+ /* sort by type, symbol index and addend */
+ i = cmp_3way(ELF64_R_TYPE(x->r_info), ELF64_R_TYPE(y->r_info));
+ if (i == 0)
+ i = cmp_3way(ELF64_R_SYM(x->r_info), ELF64_R_SYM(y->r_info));
+ if (i == 0)
+ i = cmp_3way(x->r_addend, y->r_addend);
+ return i;
+}
+
+static bool duplicate_rel(const Elf64_Rela *rela, int num)
+{
+ /*
+ * Entries are sorted by type, symbol index and addend. That means
+ * that, if a duplicate entry exists, it must be in the preceding
+ * slot.
+ */
+ return num > 0 && cmp_rela(rela + num, rela + num - 1) == 0;
+}
+
+static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num)
+{
+ unsigned int ret = 0;
+ Elf64_Sym *s;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ switch (ELF64_R_TYPE(rela[i].r_info)) {
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_CALL26:
+ /*
+ * We only have to consider branch targets that resolve
+ * to undefined symbols. This is not simply a heuristic,
+ * it is a fundamental limitation, since the PLT itself
+ * is part of the module, and needs to be within 128 MB
+ * as well, so modules can never grow beyond that limit.
+ */
+ s = syms + ELF64_R_SYM(rela[i].r_info);
+ if (s->st_shndx != SHN_UNDEF)
+ break;
+
+ /*
+ * Jump relocations with non-zero addends against
+ * undefined symbols are supported by the ELF spec, but
+ * do not occur in practice (e.g., 'jump n bytes past
+ * the entry point of undefined function symbol f').
+ * So we need to support them, but there is no need to
+ * take them into consideration when trying to optimize
+ * this code. So let's only check for duplicates when
+ * the addend is zero: this allows us to record the PLT
+ * entry address in the symbol table itself, rather than
+ * having to search the list for duplicates each time we
+ * emit one.
+ */
+ if (rela[i].r_addend != 0 || !duplicate_rel(rela, i))
+ ret++;
+ break;
+ }
+ }
+ return ret;
+}
+
+int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
+ char *secstrings, struct module *mod)
+{
+ unsigned long plt_max_entries = 0;
+ Elf64_Sym *syms = NULL;
+ int i;
+
+ /*
+ * Find the empty .plt section so we can expand it to store the PLT
+ * entries. Record the symtab address as well.
+ */
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (strcmp(".plt", secstrings + sechdrs[i].sh_name) == 0)
+ mod->arch.plt = sechdrs + i;
+ else if (sechdrs[i].sh_type == SHT_SYMTAB)
+ syms = (Elf64_Sym *)sechdrs[i].sh_addr;
+ }
+
+ if (!mod->arch.plt) {
+ pr_err("%s: module PLT section missing\n", mod->name);
+ return -ENOEXEC;
+ }
+ if (!syms) {
+ pr_err("%s: module symtab section missing\n", mod->name);
+ return -ENOEXEC;
+ }
+
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ Elf64_Rela *rels = (void *)ehdr + sechdrs[i].sh_offset;
+ int numrels = sechdrs[i].sh_size / sizeof(Elf64_Rela);
+ Elf64_Shdr *dstsec = sechdrs + sechdrs[i].sh_info;
+
+ if (sechdrs[i].sh_type != SHT_RELA)
+ continue;
+
+ /* ignore relocations that operate on non-exec sections */
+ if (!(dstsec->sh_flags & SHF_EXECINSTR))
+ continue;
+
+ /* sort by type, symbol index and addend */
+ sort(rels, numrels, sizeof(Elf64_Rela), cmp_rela, NULL);
+
+ plt_max_entries += count_plts(syms, rels, numrels);
+ }
+
+ mod->arch.plt->sh_type = SHT_NOBITS;
+ mod->arch.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
+ mod->arch.plt->sh_addralign = L1_CACHE_BYTES;
+ mod->arch.plt->sh_size = plt_max_entries * sizeof(struct plt_entry);
+ mod->arch.plt_num_entries = 0;
+ mod->arch.plt_max_entries = plt_max_entries;
+ return 0;
+}
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 876eb8d..7f31698 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -21,6 +21,7 @@
#include <linux/bitops.h>
#include <linux/elf.h>
#include <linux/gfp.h>
+#include <linux/kasan.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/moduleloader.h>
@@ -29,14 +30,36 @@
#include <asm/insn.h>
#include <asm/sections.h>
-#define AARCH64_INSN_IMM_MOVNZ AARCH64_INSN_IMM_MAX
-#define AARCH64_INSN_IMM_MOVK AARCH64_INSN_IMM_16
-
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));
+ void *p;
+
+ p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
+ module_alloc_base + MODULES_VSIZE,
+ GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
+ NUMA_NO_NODE, __builtin_return_address(0));
+
+ if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
+ !IS_ENABLED(CONFIG_KASAN))
+ /*
+ * KASAN can only deal with module allocations being served
+ * from the reserved module region, since the remainder of
+ * the vmalloc region is already backed by zero shadow pages,
+ * and punching holes into it is non-trivial. Since the module
+ * region is not randomized when KASAN is enabled, it is even
+ * less likely that the module region gets exhausted, so we
+ * can simply omit this fallback in that case.
+ */
+ p = __vmalloc_node_range(size, MODULE_ALIGN, VMALLOC_START,
+ VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
+ NUMA_NO_NODE, __builtin_return_address(0));
+
+ if (p && (kasan_module_alloc(p, size) < 0)) {
+ vfree(p);
+ return NULL;
+ }
+
+ return p;
}
enum aarch64_reloc_op {
@@ -65,15 +88,18 @@ static u64 do_reloc(enum aarch64_reloc_op reloc_op, void *place, u64 val)
static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
{
- u64 imm_mask = (1 << len) - 1;
s64 sval = do_reloc(op, place, val);
switch (len) {
case 16:
*(s16 *)place = sval;
+ if (sval < S16_MIN || sval > U16_MAX)
+ return -ERANGE;
break;
case 32:
*(s32 *)place = sval;
+ if (sval < S32_MIN || sval > U32_MAX)
+ return -ERANGE;
break;
case 64:
*(s64 *)place = sval;
@@ -82,34 +108,23 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
pr_err("Invalid length (%d) for data relocation\n", len);
return 0;
}
-
- /*
- * Extract the upper value bits (including the sign bit) and
- * shift them to bit 0.
- */
- sval = (s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
-
- /*
- * Overflow has occurred if the value is not representable in
- * len bits (i.e the bottom len bits are not sign-extended and
- * the top bits are not all zero).
- */
- if ((u64)(sval + 1) > 2)
- return -ERANGE;
-
return 0;
}
+enum aarch64_insn_movw_imm_type {
+ AARCH64_INSN_IMM_MOVNZ,
+ AARCH64_INSN_IMM_MOVKZ,
+};
+
static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
- int lsb, enum aarch64_insn_imm_type imm_type)
+ int lsb, enum aarch64_insn_movw_imm_type imm_type)
{
- u64 imm, limit = 0;
+ u64 imm;
s64 sval;
u32 insn = le32_to_cpu(*(u32 *)place);
sval = do_reloc(op, place, val);
- sval >>= lsb;
- imm = sval & 0xffff;
+ imm = sval >> lsb;
if (imm_type == AARCH64_INSN_IMM_MOVNZ) {
/*
@@ -118,7 +133,7 @@ static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
* immediate is less than zero.
*/
insn &= ~(3 << 29);
- if ((s64)imm >= 0) {
+ if (sval >= 0) {
/* >=0: Set the instruction to MOVZ (opcode 10b). */
insn |= 2 << 29;
} else {
@@ -130,29 +145,13 @@ static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
*/
imm = ~imm;
}
- imm_type = AARCH64_INSN_IMM_MOVK;
}
/* Update the instruction with the new encoding. */
- insn = aarch64_insn_encode_immediate(imm_type, insn, imm);
+ insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
*(u32 *)place = cpu_to_le32(insn);
- /* Shift out the immediate field. */
- sval >>= 16;
-
- /*
- * For unsigned immediates, the overflow check is straightforward.
- * For signed immediates, the sign bit is actually the bit past the
- * most significant bit of the field.
- * The AARCH64_INSN_IMM_16 immediate type is unsigned.
- */
- if (imm_type != AARCH64_INSN_IMM_16) {
- sval++;
- limit++;
- }
-
- /* Check the upper bits depending on the sign of the immediate. */
- if ((u64)sval > limit)
+ if (imm > U16_MAX)
return -ERANGE;
return 0;
@@ -257,25 +256,25 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
overflow_check = false;
case R_AARCH64_MOVW_UABS_G0:
ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
- AARCH64_INSN_IMM_16);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_UABS_G1_NC:
overflow_check = false;
case R_AARCH64_MOVW_UABS_G1:
ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16,
- AARCH64_INSN_IMM_16);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_UABS_G2_NC:
overflow_check = false;
case R_AARCH64_MOVW_UABS_G2:
ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32,
- AARCH64_INSN_IMM_16);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_UABS_G3:
/* We're using the top bits so we can't overflow. */
overflow_check = false;
ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 48,
- AARCH64_INSN_IMM_16);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_SABS_G0:
ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
@@ -292,7 +291,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
case R_AARCH64_MOVW_PREL_G0_NC:
overflow_check = false;
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
- AARCH64_INSN_IMM_MOVK);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_PREL_G0:
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
@@ -301,7 +300,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
case R_AARCH64_MOVW_PREL_G1_NC:
overflow_check = false;
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
- AARCH64_INSN_IMM_MOVK);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_PREL_G1:
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
@@ -310,7 +309,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
case R_AARCH64_MOVW_PREL_G2_NC:
overflow_check = false;
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
- AARCH64_INSN_IMM_MOVK);
+ AARCH64_INSN_IMM_MOVKZ);
break;
case R_AARCH64_MOVW_PREL_G2:
ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
@@ -378,6 +377,13 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
case R_AARCH64_CALL26:
ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26,
AARCH64_INSN_IMM_26);
+
+ if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
+ ovf == -ERANGE) {
+ val = module_emit_plt_entry(me, &rel[i], sym);
+ ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2,
+ 26, AARCH64_INSN_IMM_26);
+ }
break;
default:
diff --git a/arch/arm64/kernel/module.lds b/arch/arm64/kernel/module.lds
new file mode 100644
index 0000000..8949f6c
--- /dev/null
+++ b/arch/arm64/kernel/module.lds
@@ -0,0 +1,3 @@
+SECTIONS {
+ .plt (NOLOAD) : { BYTE(0) }
+}
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
new file mode 100644
index 0000000..53f371e
--- /dev/null
+++ b/arch/arm64/kernel/paravirt.c
@@ -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) 2013 Citrix Systems
+ *
+ * Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+ */
+
+#include <linux/export.h>
+#include <linux/jump_label.h>
+#include <linux/types.h>
+#include <asm/paravirt.h>
+
+struct static_key paravirt_steal_enabled;
+struct static_key paravirt_steal_rq_enabled;
+
+struct pv_time_ops pv_time_ops;
+EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index b3d098b..c72de66 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -19,8 +19,6 @@
#include <linux/of_platform.h>
#include <linux/slab.h>
-#include <asm/pci-bridge.h>
-
/*
* Called after each bus is probed, but before its children are examined
*/
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 3aa7483..ff46654 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -164,8 +164,11 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
frame.fp = regs->regs[29];
frame.sp = regs->sp;
frame.pc = regs->pc;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = current->curr_ret_stack;
+#endif
- walk_stackframe(&frame, callchain_trace, entry);
+ walk_stackframe(current, &frame, callchain_trace, entry);
}
unsigned long perf_instruction_pointer(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index f9a74d4..1b52269 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -18,695 +18,86 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define pr_fmt(fmt) "hw perfevents: " fmt
-
-#include <linux/bitmap.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/of_device.h>
-#include <linux/perf_event.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include <asm/cputype.h>
-#include <asm/irq.h>
#include <asm/irq_regs.h>
-#include <asm/pmu.h>
-
-/*
- * ARMv8 supports a maximum of 32 events.
- * The cycle counter is included in this total.
- */
-#define ARMPMU_MAX_HWEVENTS 32
-
-static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
-static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
-static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
-
-#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
-
-/* Set at runtime when we know what CPU type we are. */
-static struct arm_pmu *cpu_pmu;
-
-int
-armpmu_get_max_events(void)
-{
- int max_events = 0;
-
- if (cpu_pmu != NULL)
- max_events = cpu_pmu->num_events;
-
- return max_events;
-}
-EXPORT_SYMBOL_GPL(armpmu_get_max_events);
-
-int perf_num_counters(void)
-{
- return armpmu_get_max_events();
-}
-EXPORT_SYMBOL_GPL(perf_num_counters);
-
-#define HW_OP_UNSUPPORTED 0xFFFF
-
-#define C(_x) \
- PERF_COUNT_HW_CACHE_##_x
-
-#define CACHE_OP_UNSUPPORTED 0xFFFF
-
-#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, \
- }, \
-}
-
-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_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);
-}
-
-static int map_cpu_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;
-
- switch (event->attr.type) {
- case PERF_TYPE_HARDWARE:
- return armpmu_map_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 hw_perf_event *hwc,
- int idx)
-{
- struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
- 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(idx, (u64)(-left) & 0xffffffff);
-
- perf_event_update_userpage(event);
-
- return ret;
-}
-
-u64
-armpmu_event_update(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx)
-{
- struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
- u64 delta, prev_raw_count, new_raw_count;
-
-again:
- prev_raw_count = local64_read(&hwc->prev_count);
- new_raw_count = armpmu->read_counter(idx);
-
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count)
- goto again;
-
- 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)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- /* Don't read disabled counters! */
- if (hwc->idx < 0)
- return;
-
- armpmu_event_update(event, hwc, hwc->idx);
-}
-
-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(hwc, hwc->idx);
- barrier(); /* why? */
- armpmu_event_update(event, hwc, hwc->idx);
- 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, hwc, hwc->idx);
- armpmu->enable(hwc, hwc->idx);
-}
-
-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 = armpmu->get_hw_events();
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- WARN_ON(idx < 0);
-
- armpmu_stop(event, PERF_EF_UPDATE);
- hw_events->events[idx] = NULL;
- clear_bit(idx, hw_events->used_mask);
-
- 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 = armpmu->get_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, hwc);
- if (idx < 0) {
- err = idx;
- goto out;
- }
-
- /*
- * If there is an event in the counter we are going to use then make
- * sure it is disabled.
- */
- event->hw.idx = idx;
- armpmu->disable(hwc, idx);
- 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);
+#include <asm/virt.h>
-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;
- struct hw_perf_event fake_event = event->hw;
- struct pmu *leader_pmu = event->group_leader->pmu;
-
- 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->pmu != leader_pmu || 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, &fake_event) >= 0;
-}
-
-static int
-validate_group(struct perf_event *event)
-{
- struct perf_event *sibling, *leader = event->group_leader;
- struct pmu_hw_events fake_pmu;
- DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
-
- /*
- * Initialise the fake PMU. We only need to populate the
- * used_mask for the purposes of validation.
- */
- memset(fake_used_mask, 0, sizeof(fake_used_mask));
- fake_pmu.used_mask = fake_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 void
-armpmu_disable_percpu_irq(void *data)
-{
- unsigned int irq = *(unsigned int *)data;
- disable_percpu_irq(irq);
-}
-
-static void
-armpmu_release_hardware(struct arm_pmu *armpmu)
-{
- int irq;
- unsigned int i, irqs;
- struct platform_device *pmu_device = armpmu->plat_device;
-
- irqs = min(pmu_device->num_resources, num_possible_cpus());
- if (!irqs)
- return;
-
- irq = platform_get_irq(pmu_device, 0);
- if (irq <= 0)
- return;
-
- if (irq_is_percpu(irq)) {
- on_each_cpu(armpmu_disable_percpu_irq, &irq, 1);
- free_percpu_irq(irq, &cpu_hw_events);
- } else {
- for (i = 0; i < irqs; ++i) {
- int cpu = i;
-
- if (armpmu->irq_affinity)
- cpu = armpmu->irq_affinity[i];
-
- if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs))
- continue;
- irq = platform_get_irq(pmu_device, i);
- if (irq > 0)
- free_irq(irq, armpmu);
- }
- }
-}
-
-static void
-armpmu_enable_percpu_irq(void *data)
-{
- unsigned int irq = *(unsigned int *)data;
- enable_percpu_irq(irq, IRQ_TYPE_NONE);
-}
-
-static int
-armpmu_reserve_hardware(struct arm_pmu *armpmu)
-{
- int err, irq;
- unsigned int i, irqs;
- struct platform_device *pmu_device = armpmu->plat_device;
-
- if (!pmu_device)
- return -ENODEV;
-
- irqs = min(pmu_device->num_resources, num_possible_cpus());
- if (!irqs) {
- pr_err("no irqs for PMUs defined\n");
- return -ENODEV;
- }
-
- irq = platform_get_irq(pmu_device, 0);
- if (irq <= 0) {
- pr_err("failed to get valid irq for PMU device\n");
- return -ENODEV;
- }
-
- if (irq_is_percpu(irq)) {
- err = request_percpu_irq(irq, armpmu->handle_irq,
- "arm-pmu", &cpu_hw_events);
-
- if (err) {
- pr_err("unable to request percpu IRQ%d for ARM PMU counters\n",
- irq);
- armpmu_release_hardware(armpmu);
- return err;
- }
-
- on_each_cpu(armpmu_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 (armpmu->irq_affinity)
- cpu = armpmu->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_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
- irq, cpu);
- continue;
- }
-
- err = request_irq(irq, armpmu->handle_irq,
- IRQF_NOBALANCING | IRQF_NO_THREAD,
- "arm-pmu", armpmu);
- if (err) {
- pr_err("unable to request IRQ%d for ARM PMU counters\n",
- irq);
- armpmu_release_hardware(armpmu);
- return err;
- }
-
- cpumask_set_cpu(cpu, &armpmu->active_irqs);
- }
- }
-
- 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, err;
-
- 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 -EPERM;
- }
-
- /*
- * Store the event encoding into the config_base field.
- */
- hwc->config_base |= (unsigned long)mapping;
-
- if (!hwc->sample_period) {
- /*
- * 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);
- }
-
- err = 0;
- if (event->group_leader != event) {
- err = validate_group(event);
- if (err)
- return -EINVAL;
- }
-
- return err;
-}
-
-static int armpmu_event_init(struct perf_event *event)
-{
- struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
- int err = 0;
- atomic_t *active_events = &armpmu->active_events;
-
- 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 = armpmu->get_hw_events();
- int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
-
- if (enabled)
- armpmu->start();
-}
-
-static void armpmu_disable(struct pmu *pmu)
-{
- struct arm_pmu *armpmu = to_arm_pmu(pmu);
- armpmu->stop();
-}
-
-static void __init 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 __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
-{
- armpmu_init(armpmu);
- return perf_pmu_register(&armpmu->pmu, name, type);
-}
+#include <linux/of.h>
+#include <linux/perf/arm_pmu.h>
+#include <linux/platform_device.h>
/*
* ARMv8 PMUv3 Performance Events handling code.
* Common event types.
*/
-enum armv8_pmuv3_perf_types {
- /* Required events. */
- ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR = 0x00,
- ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL = 0x03,
- ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS = 0x04,
- ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
- ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES = 0x11,
- ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED = 0x12,
-
- /* At least one of the following is required. */
- ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED = 0x08,
- ARMV8_PMUV3_PERFCTR_OP_SPEC = 0x1B,
-
- /* Common architectural events. */
- ARMV8_PMUV3_PERFCTR_MEM_READ = 0x06,
- ARMV8_PMUV3_PERFCTR_MEM_WRITE = 0x07,
- ARMV8_PMUV3_PERFCTR_EXC_TAKEN = 0x09,
- ARMV8_PMUV3_PERFCTR_EXC_EXECUTED = 0x0A,
- ARMV8_PMUV3_PERFCTR_CID_WRITE = 0x0B,
- ARMV8_PMUV3_PERFCTR_PC_WRITE = 0x0C,
- ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH = 0x0D,
- ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN = 0x0E,
- ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
- ARMV8_PMUV3_PERFCTR_TTBR_WRITE = 0x1C,
-
- /* Common microarchitectural events. */
- ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL = 0x01,
- ARMV8_PMUV3_PERFCTR_ITLB_REFILL = 0x02,
- ARMV8_PMUV3_PERFCTR_DTLB_REFILL = 0x05,
- ARMV8_PMUV3_PERFCTR_MEM_ACCESS = 0x13,
- ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS = 0x14,
- ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB = 0x15,
- ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS = 0x16,
- ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL = 0x17,
- ARMV8_PMUV3_PERFCTR_L2_CACHE_WB = 0x18,
- ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
- ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
- ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
-};
+
+/* Required events. */
+#define ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR 0x00
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL 0x03
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS 0x04
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED 0x10
+#define ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES 0x11
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED 0x12
+
+/* At least one of the following is required. */
+#define ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED 0x08
+#define ARMV8_PMUV3_PERFCTR_OP_SPEC 0x1B
+
+/* Common architectural events. */
+#define ARMV8_PMUV3_PERFCTR_MEM_READ 0x06
+#define ARMV8_PMUV3_PERFCTR_MEM_WRITE 0x07
+#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x09
+#define ARMV8_PMUV3_PERFCTR_EXC_EXECUTED 0x0A
+#define ARMV8_PMUV3_PERFCTR_CID_WRITE 0x0B
+#define ARMV8_PMUV3_PERFCTR_PC_WRITE 0x0C
+#define ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH 0x0D
+#define ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN 0x0E
+#define ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS 0x0F
+#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE 0x1C
+#define ARMV8_PMUV3_PERFCTR_CHAIN 0x1E
+#define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x21
+
+/* Common microarchitectural events. */
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL 0x01
+#define ARMV8_PMUV3_PERFCTR_ITLB_REFILL 0x02
+#define ARMV8_PMUV3_PERFCTR_DTLB_REFILL 0x05
+#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x13
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS 0x14
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB 0x15
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS 0x16
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL 0x17
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_WB 0x18
+#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x19
+#define ARMV8_PMUV3_PERFCTR_MEM_ERROR 0x1A
+#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x1D
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x1F
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x20
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x22
+#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x23
+#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x24
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x25
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x26
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x27
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x28
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x29
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x2A
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x2B
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x2C
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x2D
+#define ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL 0x2E
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F
+#define ARMV8_PMUV3_PERFCTR_L21_TLB 0x30
+
+/* ARMv8 Cortex-A53 specific event types. */
+#define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL 0xC2
+
+/* ARMv8 Cortex-A57 and Cortex-A72 specific event types. */
+#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD 0x40
+#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST 0x41
+#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD 0x42
+#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST 0x43
+#define ARMV8_A57_PERFCTR_DTLB_REFILL_LD 0x4c
+#define ARMV8_A57_PERFCTR_DTLB_REFILL_ST 0x4d
/* PMUv3 HW events mapping. */
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
@@ -718,6 +109,29 @@ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
};
+/* ARM Cortex-A53 HW events mapping. */
+static const unsigned armv8_a53_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES,
+};
+
+/* ARM Cortex-A57 and Cortex-A72 events mapping. */
+static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = {
+ PERF_MAP_ALL_UNSUPPORTED,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES,
+};
+
static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
@@ -734,12 +148,191 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
};
+static const unsigned armv8_a53_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)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
+ [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_A53_PERFCTR_PREFETCH_LINEFILL,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+static const unsigned armv8_a57_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)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD,
+ [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST,
+ [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST,
+
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_LD,
+ [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_ST,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL,
+
+ [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED,
+ [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
+};
+
+#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV8_EVENT_ATTR(name, config) \
+ PMU_EVENT_ATTR_STRING(name, armv8_event_attr_##name, \
+ "event=" ARMV8_EVENT_ATTR_RESOLVE(config))
+
+ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR);
+ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL);
+ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_ITLB_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_DTLB_REFILL);
+ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_MEM_READ);
+ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_MEM_WRITE);
+ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED);
+ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN);
+ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_EXECUTED);
+ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE);
+ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE);
+ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH);
+ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN);
+ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES);
+ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED);
+ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS);
+ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB);
+ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS);
+ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2_CACHE_WB);
+ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
+ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEM_ERROR);
+ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_OP_SPEC);
+ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE);
+ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES);
+ARMV8_EVENT_ATTR(chain, ARMV8_PMUV3_PERFCTR_CHAIN);
+ARMV8_EVENT_ATTR(l1d_cache_allocate, ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l2d_cache_allocate, ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(br_retired, ARMV8_PMUV3_PERFCTR_BR_RETIRED);
+ARMV8_EVENT_ATTR(br_mis_pred_retired, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED);
+ARMV8_EVENT_ATTR(stall_frontend, ARMV8_PMUV3_PERFCTR_STALL_FRONTEND);
+ARMV8_EVENT_ATTR(stall_backend, ARMV8_PMUV3_PERFCTR_STALL_BACKEND);
+ARMV8_EVENT_ATTR(l1d_tlb, ARMV8_PMUV3_PERFCTR_L1D_TLB);
+ARMV8_EVENT_ATTR(l1i_tlb, ARMV8_PMUV3_PERFCTR_L1I_TLB);
+ARMV8_EVENT_ATTR(l2i_cache, ARMV8_PMUV3_PERFCTR_L2I_CACHE);
+ARMV8_EVENT_ATTR(l2i_cache_refill, ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache_allocate, ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l3d_cache_refill, ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache, ARMV8_PMUV3_PERFCTR_L3D_CACHE);
+ARMV8_EVENT_ATTR(l3d_cache_wb, ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB);
+ARMV8_EVENT_ATTR(l2d_tlb_refill, ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL);
+ARMV8_EVENT_ATTR(l21_tlb_refill, ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL);
+ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB);
+ARMV8_EVENT_ATTR(l21_tlb, ARMV8_PMUV3_PERFCTR_L21_TLB);
+
+static struct attribute *armv8_pmuv3_event_attrs[] = {
+ &armv8_event_attr_sw_incr.attr.attr,
+ &armv8_event_attr_l1i_cache_refill.attr.attr,
+ &armv8_event_attr_l1i_tlb_refill.attr.attr,
+ &armv8_event_attr_l1d_cache_refill.attr.attr,
+ &armv8_event_attr_l1d_cache.attr.attr,
+ &armv8_event_attr_l1d_tlb_refill.attr.attr,
+ &armv8_event_attr_ld_retired.attr.attr,
+ &armv8_event_attr_st_retired.attr.attr,
+ &armv8_event_attr_inst_retired.attr.attr,
+ &armv8_event_attr_exc_taken.attr.attr,
+ &armv8_event_attr_exc_return.attr.attr,
+ &armv8_event_attr_cid_write_retired.attr.attr,
+ &armv8_event_attr_pc_write_retired.attr.attr,
+ &armv8_event_attr_br_immed_retired.attr.attr,
+ &armv8_event_attr_br_return_retired.attr.attr,
+ &armv8_event_attr_unaligned_ldst_retired.attr.attr,
+ &armv8_event_attr_br_mis_pred.attr.attr,
+ &armv8_event_attr_cpu_cycles.attr.attr,
+ &armv8_event_attr_br_pred.attr.attr,
+ &armv8_event_attr_mem_access.attr.attr,
+ &armv8_event_attr_l1i_cache.attr.attr,
+ &armv8_event_attr_l1d_cache_wb.attr.attr,
+ &armv8_event_attr_l2d_cache.attr.attr,
+ &armv8_event_attr_l2d_cache_refill.attr.attr,
+ &armv8_event_attr_l2d_cache_wb.attr.attr,
+ &armv8_event_attr_bus_access.attr.attr,
+ &armv8_event_attr_memory_error.attr.attr,
+ &armv8_event_attr_inst_spec.attr.attr,
+ &armv8_event_attr_ttbr_write_retired.attr.attr,
+ &armv8_event_attr_bus_cycles.attr.attr,
+ &armv8_event_attr_chain.attr.attr,
+ &armv8_event_attr_l1d_cache_allocate.attr.attr,
+ &armv8_event_attr_l2d_cache_allocate.attr.attr,
+ &armv8_event_attr_br_retired.attr.attr,
+ &armv8_event_attr_br_mis_pred_retired.attr.attr,
+ &armv8_event_attr_stall_frontend.attr.attr,
+ &armv8_event_attr_stall_backend.attr.attr,
+ &armv8_event_attr_l1d_tlb.attr.attr,
+ &armv8_event_attr_l1i_tlb.attr.attr,
+ &armv8_event_attr_l2i_cache.attr.attr,
+ &armv8_event_attr_l2i_cache_refill.attr.attr,
+ &armv8_event_attr_l3d_cache_allocate.attr.attr,
+ &armv8_event_attr_l3d_cache_refill.attr.attr,
+ &armv8_event_attr_l3d_cache.attr.attr,
+ &armv8_event_attr_l3d_cache_wb.attr.attr,
+ &armv8_event_attr_l2d_tlb_refill.attr.attr,
+ &armv8_event_attr_l21_tlb_refill.attr.attr,
+ &armv8_event_attr_l2d_tlb.attr.attr,
+ &armv8_event_attr_l21_tlb.attr.attr,
+ NULL,
+};
+
+static struct attribute_group armv8_pmuv3_events_attr_group = {
+ .name = "events",
+ .attrs = armv8_pmuv3_event_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-9");
+
+static struct attribute *armv8_pmuv3_format_attrs[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group armv8_pmuv3_format_attr_group = {
+ .name = "format",
+ .attrs = armv8_pmuv3_format_attrs,
+};
+
+static const struct attribute_group *armv8_pmuv3_attr_groups[] = {
+ &armv8_pmuv3_events_attr_group,
+ &armv8_pmuv3_format_attr_group,
+ NULL,
+};
+
+
/*
* Perf Events' indices
*/
#define ARMV8_IDX_CYCLE_COUNTER 0
#define ARMV8_IDX_COUNTER0 1
-#define ARMV8_IDX_COUNTER_LAST (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
+#define ARMV8_IDX_COUNTER_LAST(cpu_pmu) \
+ (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
#define ARMV8_MAX_COUNTERS 32
#define ARMV8_COUNTER_MASK (ARMV8_MAX_COUNTERS - 1)
@@ -805,49 +398,34 @@ static inline int armv8pmu_has_overflowed(u32 pmovsr)
return pmovsr & ARMV8_OVERFLOWED_MASK;
}
-static inline int armv8pmu_counter_valid(int idx)
+static inline int armv8pmu_counter_valid(struct arm_pmu *cpu_pmu, int idx)
{
- return idx >= ARMV8_IDX_CYCLE_COUNTER && idx <= ARMV8_IDX_COUNTER_LAST;
+ return idx >= ARMV8_IDX_CYCLE_COUNTER &&
+ idx <= ARMV8_IDX_COUNTER_LAST(cpu_pmu);
}
static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
{
- int ret = 0;
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u checking wrong counter %d overflow status\n",
- smp_processor_id(), idx);
- } else {
- counter = ARMV8_IDX_TO_COUNTER(idx);
- ret = pmnc & BIT(counter);
- }
-
- return ret;
+ return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx));
}
static inline int armv8pmu_select_counter(int idx)
{
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u selecting wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV8_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV8_IDX_TO_COUNTER(idx);
asm volatile("msr pmselr_el0, %0" :: "r" (counter));
isb();
return idx;
}
-static inline u32 armv8pmu_read_counter(int idx)
+static inline u32 armv8pmu_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 (!armv8pmu_counter_valid(idx))
+ if (!armv8pmu_counter_valid(cpu_pmu, idx))
pr_err("CPU%u reading wrong counter %d\n",
smp_processor_id(), idx);
else if (idx == ARMV8_IDX_CYCLE_COUNTER)
@@ -858,9 +436,13 @@ static inline u32 armv8pmu_read_counter(int idx)
return value;
}
-static inline void armv8pmu_write_counter(int idx, u32 value)
+static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
{
- if (!armv8pmu_counter_valid(idx))
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ if (!armv8pmu_counter_valid(cpu_pmu, idx))
pr_err("CPU%u writing wrong counter %d\n",
smp_processor_id(), idx);
else if (idx == ARMV8_IDX_CYCLE_COUNTER)
@@ -879,65 +461,34 @@ static inline void armv8pmu_write_evtype(int idx, u32 val)
static inline int armv8pmu_enable_counter(int idx)
{
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u enabling wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV8_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV8_IDX_TO_COUNTER(idx);
asm volatile("msr pmcntenset_el0, %0" :: "r" (BIT(counter)));
return idx;
}
static inline int armv8pmu_disable_counter(int idx)
{
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u disabling wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV8_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV8_IDX_TO_COUNTER(idx);
asm volatile("msr pmcntenclr_el0, %0" :: "r" (BIT(counter)));
return idx;
}
static inline int armv8pmu_enable_intens(int idx)
{
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV8_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV8_IDX_TO_COUNTER(idx);
asm volatile("msr pmintenset_el1, %0" :: "r" (BIT(counter)));
return idx;
}
static inline int armv8pmu_disable_intens(int idx)
{
- u32 counter;
-
- if (!armv8pmu_counter_valid(idx)) {
- pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV8_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV8_IDX_TO_COUNTER(idx);
asm volatile("msr pmintenclr_el1, %0" :: "r" (BIT(counter)));
isb();
/* Clear the overflow flag in case an interrupt is pending. */
asm volatile("msr pmovsclr_el0, %0" :: "r" (BIT(counter)));
isb();
+
return idx;
}
@@ -955,10 +506,13 @@ static inline u32 armv8pmu_getreset_flags(void)
return value;
}
-static void armv8pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void armv8pmu_enable_event(struct perf_event *event)
{
unsigned long flags;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ 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;
/*
* Enable counter and interrupt, and set the counter to count
@@ -989,10 +543,13 @@ static void armv8pmu_enable_event(struct hw_perf_event *hwc, int idx)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void armv8pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static void armv8pmu_disable_event(struct perf_event *event)
{
unsigned long flags;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ 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;
/*
* Disable counter and interrupt
@@ -1016,7 +573,8 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev)
{
u32 pmovsr;
struct perf_sample_data data;
- struct pmu_hw_events *cpuc;
+ 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;
@@ -1036,7 +594,6 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev)
*/
regs = get_irq_regs();
- cpuc = this_cpu_ptr(&cpu_hw_events);
for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc;
@@ -1053,13 +610,13 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event);
perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event, hwc, idx))
+ if (!armpmu_event_set_period(event))
continue;
if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(hwc, idx);
+ cpu_pmu->disable(event);
}
/*
@@ -1074,10 +631,10 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev)
return IRQ_HANDLED;
}
-static void armv8pmu_start(void)
+static void armv8pmu_start(struct arm_pmu *cpu_pmu)
{
unsigned long flags;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
raw_spin_lock_irqsave(&events->pmu_lock, flags);
/* Enable all counters */
@@ -1085,10 +642,10 @@ static void armv8pmu_start(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void armv8pmu_stop(void)
+static void armv8pmu_stop(struct arm_pmu *cpu_pmu)
{
unsigned long flags;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
raw_spin_lock_irqsave(&events->pmu_lock, flags);
/* Disable all counters */
@@ -1097,10 +654,12 @@ static void armv8pmu_stop(void)
}
static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct hw_perf_event *event)
+ struct perf_event *event)
{
int idx;
- unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned long evtype = hwc->config_base & ARMV8_EVTYPE_EVENT;
/* Always place a cycle counter into the cycle counter. */
if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
@@ -1133,9 +692,12 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event,
if (attr->exclude_idle)
return -EPERM;
+ if (is_kernel_in_hyp_mode() &&
+ attr->exclude_kernel != attr->exclude_hv)
+ return -EINVAL;
if (attr->exclude_user)
config_base |= ARMV8_EXCLUDE_EL0;
- if (attr->exclude_kernel)
+ if (!is_kernel_in_hyp_mode() && attr->exclude_kernel)
config_base |= ARMV8_EXCLUDE_EL1;
if (!attr->exclude_hv)
config_base |= ARMV8_INCLUDE_EL2;
@@ -1151,184 +713,131 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event,
static void armv8pmu_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 = ARMV8_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)
- armv8pmu_disable_event(NULL, idx);
+ for (idx = ARMV8_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
+ armv8pmu_disable_counter(idx);
+ armv8pmu_disable_intens(idx);
+ }
/* Initialize & Reset PMNC: C and P bits. */
armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C);
-
- /* Disable access from userspace. */
- asm volatile("msr pmuserenr_el0, %0" :: "r" (0));
}
static int armv8_pmuv3_map_event(struct perf_event *event)
{
- return map_cpu_event(event, &armv8_pmuv3_perf_map,
+ return armpmu_map_event(event, &armv8_pmuv3_perf_map,
&armv8_pmuv3_perf_cache_map,
ARMV8_EVTYPE_EVENT);
}
-static struct arm_pmu armv8pmu = {
- .handle_irq = armv8pmu_handle_irq,
- .enable = armv8pmu_enable_event,
- .disable = armv8pmu_disable_event,
- .read_counter = armv8pmu_read_counter,
- .write_counter = armv8pmu_write_counter,
- .get_event_idx = armv8pmu_get_event_idx,
- .start = armv8pmu_start,
- .stop = armv8pmu_stop,
- .reset = armv8pmu_reset,
- .max_period = (1LLU << 32) - 1,
-};
+static int armv8_a53_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv8_a53_perf_map,
+ &armv8_a53_perf_cache_map,
+ ARMV8_EVTYPE_EVENT);
+}
+
+static int armv8_a57_map_event(struct perf_event *event)
+{
+ return armpmu_map_event(event, &armv8_a57_perf_map,
+ &armv8_a57_perf_cache_map,
+ ARMV8_EVTYPE_EVENT);
+}
-static u32 __init armv8pmu_read_num_pmnc_events(void)
+static void armv8pmu_read_num_pmnc_events(void *info)
{
- u32 nb_cnt;
+ int *nb_cnt = info;
/* Read the nb of CNTx counters supported from PMNC */
- nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMCR_N_SHIFT) & ARMV8_PMCR_N_MASK;
+ *nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMCR_N_SHIFT) & ARMV8_PMCR_N_MASK;
- /* Add the CPU cycles counter and return */
- return nb_cnt + 1;
+ /* Add the CPU cycles counter */
+ *nb_cnt += 1;
}
-static struct arm_pmu *__init armv8_pmuv3_pmu_init(void)
+static int armv8pmu_probe_num_events(struct arm_pmu *arm_pmu)
{
- armv8pmu.name = "arm/armv8-pmuv3";
- armv8pmu.map_event = armv8_pmuv3_map_event;
- armv8pmu.num_events = armv8pmu_read_num_pmnc_events();
- armv8pmu.set_event_filter = armv8pmu_set_event_filter;
- return &armv8pmu;
+ return smp_call_function_any(&arm_pmu->supported_cpus,
+ armv8pmu_read_num_pmnc_events,
+ &arm_pmu->num_events, 1);
}
-/*
- * Ensure the PMU has sane values out of reset.
- * This requires SMP to be available, so exists as a separate initcall.
- */
-static int __init
-cpu_pmu_reset(void)
+static void armv8_pmu_init(struct arm_pmu *cpu_pmu)
{
- if (cpu_pmu && cpu_pmu->reset)
- return on_each_cpu(cpu_pmu->reset, NULL, 1);
- return 0;
+ cpu_pmu->handle_irq = armv8pmu_handle_irq,
+ cpu_pmu->enable = armv8pmu_enable_event,
+ cpu_pmu->disable = armv8pmu_disable_event,
+ cpu_pmu->read_counter = armv8pmu_read_counter,
+ cpu_pmu->write_counter = armv8pmu_write_counter,
+ cpu_pmu->get_event_idx = armv8pmu_get_event_idx,
+ cpu_pmu->start = armv8pmu_start,
+ cpu_pmu->stop = armv8pmu_stop,
+ cpu_pmu->reset = armv8pmu_reset,
+ cpu_pmu->max_period = (1LLU << 32) - 1,
+ cpu_pmu->set_event_filter = armv8pmu_set_event_filter;
}
-arch_initcall(cpu_pmu_reset);
-
-/*
- * PMU platform driver and devicetree bindings.
- */
-static const struct of_device_id armpmu_of_device_ids[] = {
- {.compatible = "arm,armv8-pmuv3"},
- {},
-};
-static int armpmu_device_probe(struct platform_device *pdev)
+static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu)
{
- int i, irq, *irqs;
-
- if (!cpu_pmu)
- return -ENODEV;
-
- /* Don't bother with PPIs; they're already affine */
- irq = platform_get_irq(pdev, 0);
- if (irq >= 0 && irq_is_percpu(irq))
- goto out;
-
- 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 (dn == of_cpu_device_node_get(cpu))
- break;
-
- if (cpu >= nr_cpu_ids) {
- pr_warn("Failed to find logical CPU for %s\n",
- dn->name);
- of_node_put(dn);
- break;
- }
- of_node_put(dn);
-
- irqs[i] = cpu;
- }
-
- if (i == pdev->num_resources)
- cpu_pmu->irq_affinity = irqs;
- else
- kfree(irqs);
-
-out:
- cpu_pmu->plat_device = pdev;
- return 0;
+ armv8_pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv8_pmuv3";
+ cpu_pmu->map_event = armv8_pmuv3_map_event;
+ return armv8pmu_probe_num_events(cpu_pmu);
}
-static struct platform_driver armpmu_driver = {
- .driver = {
- .name = "arm-pmu",
- .of_match_table = armpmu_of_device_ids,
- },
- .probe = armpmu_device_probe,
-};
-
-static int __init register_pmu_driver(void)
+static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
{
- return platform_driver_register(&armpmu_driver);
+ armv8_pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv8_cortex_a53";
+ cpu_pmu->map_event = armv8_a53_map_event;
+ cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ return armv8pmu_probe_num_events(cpu_pmu);
}
-device_initcall(register_pmu_driver);
-static struct pmu_hw_events *armpmu_get_cpu_events(void)
+static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
{
- return this_cpu_ptr(&cpu_hw_events);
+ armv8_pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv8_cortex_a57";
+ cpu_pmu->map_event = armv8_a57_map_event;
+ cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ return armv8pmu_probe_num_events(cpu_pmu);
}
-static void __init cpu_pmu_init(struct arm_pmu *armpmu)
+static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
{
- int cpu;
- for_each_possible_cpu(cpu) {
- struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
- events->events = per_cpu(hw_events, cpu);
- events->used_mask = per_cpu(used_mask, cpu);
- raw_spin_lock_init(&events->pmu_lock);
- }
- armpmu->get_hw_events = armpmu_get_cpu_events;
+ armv8_pmu_init(cpu_pmu);
+ cpu_pmu->name = "armv8_cortex_a72";
+ cpu_pmu->map_event = armv8_a57_map_event;
+ cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ return armv8pmu_probe_num_events(cpu_pmu);
}
-static int __init init_hw_perf_events(void)
-{
- u64 dfr = read_cpuid(ID_AA64DFR0_EL1);
+static const struct of_device_id armv8_pmu_of_device_ids[] = {
+ {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init},
+ {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init},
+ {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init},
+ {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init},
+ {},
+};
- switch ((dfr >> 8) & 0xf) {
- case 0x1: /* PMUv3 */
- cpu_pmu = armv8_pmuv3_pmu_init();
- break;
- }
+static int armv8_pmu_device_probe(struct platform_device *pdev)
+{
+ return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids, NULL);
+}
- if (cpu_pmu) {
- pr_info("enabled with %s PMU driver, %d counters available\n",
- cpu_pmu->name, cpu_pmu->num_events);
- cpu_pmu_init(cpu_pmu);
- armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW);
- } else {
- pr_info("no hardware support available\n");
- }
+static struct platform_driver armv8_pmu_driver = {
+ .driver = {
+ .name = "armv8-pmu",
+ .of_match_table = armv8_pmu_of_device_ids,
+ },
+ .probe = armv8_pmu_device_probe,
+};
- return 0;
+static int __init register_armv8_pmu_driver(void)
+{
+ return platform_driver_register(&armv8_pmu_driver);
}
-early_initcall(init_hw_perf_events);
-
+device_initcall(register_armv8_pmu_driver);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 223b093..8062482 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -44,7 +44,9 @@
#include <linux/hw_breakpoint.h>
#include <linux/personality.h>
#include <linux/notifier.h>
+#include <trace/events/power.h>
+#include <asm/alternative.h>
#include <asm/compat.h>
#include <asm/cacheflush.h>
#include <asm/fpsimd.h>
@@ -75,8 +77,10 @@ void arch_cpu_idle(void)
* This should do all the clock switching and wait for interrupt
* tricks
*/
+ trace_cpu_idle_rcuidle(1, smp_processor_id());
cpu_do_idle();
local_irq_enable();
+ trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -277,6 +281,9 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
} else {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h;
+ if (IS_ENABLED(CONFIG_ARM64_UAO) &&
+ cpus_have_cap(ARM64_HAS_UAO))
+ childregs->pstate |= PSR_UAO_BIT;
p->thread.cpu_context.x19 = stack_start;
p->thread.cpu_context.x20 = stk_sz;
}
@@ -305,6 +312,17 @@ static void tls_thread_switch(struct task_struct *next)
: : "r" (tpidr), "r" (tpidrro));
}
+/* Restore the UAO state depending on next's addr_limit */
+static void uao_thread_switch(struct task_struct *next)
+{
+ if (IS_ENABLED(CONFIG_ARM64_UAO)) {
+ if (task_thread_info(next)->addr_limit == KERNEL_DS)
+ asm(ALTERNATIVE("nop", SET_PSTATE_UAO(1), ARM64_HAS_UAO));
+ else
+ asm(ALTERNATIVE("nop", SET_PSTATE_UAO(0), ARM64_HAS_UAO));
+ }
+}
+
/*
* Thread switching.
*/
@@ -317,6 +335,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
tls_thread_switch(next);
hw_breakpoint_thread_switch(next);
contextidr_thread_switch(next);
+ uao_thread_switch(next);
/*
* Complete any pending TLB or cache maintenance on this CPU in case
@@ -341,11 +360,14 @@ unsigned long get_wchan(struct task_struct *p)
frame.fp = thread_saved_fp(p);
frame.sp = thread_saved_sp(p);
frame.pc = thread_saved_pc(p);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = p->curr_ret_stack;
+#endif
stack_page = (unsigned long)task_stack_page(p);
do {
if (frame.sp < stack_page ||
frame.sp >= stack_page + THREAD_SIZE ||
- unwind_frame(&frame))
+ unwind_frame(p, &frame))
return 0;
if (!in_sched_functions(frame.pc))
return frame.pc;
diff --git a/arch/arm64/kernel/psci-call.S b/arch/arm64/kernel/psci-call.S
deleted file mode 100644
index cf83e61..0000000
--- a/arch/arm64/kernel/psci-call.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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: Will Deacon <will.deacon@arm.com>
- */
-
-#include <linux/linkage.h>
-
-/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
-ENTRY(__invoke_psci_fn_hvc)
- hvc #0
- ret
-ENDPROC(__invoke_psci_fn_hvc)
-
-/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
-ENTRY(__invoke_psci_fn_smc)
- smc #0
- ret
-ENDPROC(__invoke_psci_fn_smc)
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index aa94a88..42816be 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -20,7 +20,6 @@
#include <linux/smp.h>
#include <linux/delay.h>
#include <linux/psci.h>
-#include <linux/slab.h>
#include <uapi/linux/psci.h>
@@ -28,87 +27,6 @@
#include <asm/cpu_ops.h>
#include <asm/errno.h>
#include <asm/smp_plat.h>
-#include <asm/suspend.h>
-
-static bool psci_power_state_loses_context(u32 state)
-{
- return state & PSCI_0_2_POWER_STATE_TYPE_MASK;
-}
-
-static bool psci_power_state_is_valid(u32 state)
-{
- const u32 valid_mask = PSCI_0_2_POWER_STATE_ID_MASK |
- PSCI_0_2_POWER_STATE_TYPE_MASK |
- PSCI_0_2_POWER_STATE_AFFL_MASK;
-
- return !(state & ~valid_mask);
-}
-
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
-
-static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu)
-{
- int i, ret, count = 0;
- u32 *psci_states;
- struct device_node *state_node, *cpu_node;
-
- cpu_node = of_get_cpu_node(cpu, NULL);
- if (!cpu_node)
- return -ENODEV;
-
- /*
- * If the PSCI cpu_suspend function hook has not been initialized
- * idle states must not be enabled, so bail out
- */
- if (!psci_ops.cpu_suspend)
- return -EOPNOTSUPP;
-
- /* Count idle states */
- while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
- count))) {
- count++;
- of_node_put(state_node);
- }
-
- if (!count)
- return -ENODEV;
-
- psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
- if (!psci_states)
- return -ENOMEM;
-
- for (i = 0; i < count; i++) {
- u32 state;
-
- state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
-
- ret = of_property_read_u32(state_node,
- "arm,psci-suspend-param",
- &state);
- if (ret) {
- pr_warn(" * %s missing arm,psci-suspend-param property\n",
- state_node->full_name);
- of_node_put(state_node);
- goto free_mem;
- }
-
- of_node_put(state_node);
- pr_debug("psci-power-state %#x index %d\n", state, i);
- if (!psci_power_state_is_valid(state)) {
- pr_warn("Invalid PSCI power state %#x\n", state);
- ret = -EINVAL;
- goto free_mem;
- }
- psci_states[i] = state;
- }
- /* Idle states parsed correctly, initialize per-cpu pointer */
- per_cpu(psci_power_state, cpu) = psci_states;
- return 0;
-
-free_mem:
- kfree(psci_states);
- return ret;
-}
static int __init cpu_psci_cpu_init(unsigned int cpu)
{
@@ -192,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
}
#endif
-static int psci_suspend_finisher(unsigned long index)
-{
- u32 *state = __this_cpu_read(psci_power_state);
-
- return psci_ops.cpu_suspend(state[index - 1],
- virt_to_phys(cpu_resume));
-}
-
-static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
-{
- int ret;
- u32 *state = __this_cpu_read(psci_power_state);
- /*
- * idle state index 0 corresponds to wfi, should never be called
- * from the cpu_suspend operations
- */
- if (WARN_ON_ONCE(!index))
- return -EINVAL;
-
- if (!psci_power_state_loses_context(state[index - 1]))
- ret = psci_ops.cpu_suspend(state[index - 1], 0);
- else
- ret = cpu_suspend(index, psci_suspend_finisher);
-
- return ret;
-}
-
const struct cpu_operations cpu_psci_ops = {
.name = "psci",
#ifdef CONFIG_CPU_IDLE
- .cpu_init_idle = cpu_psci_cpu_init_idle,
- .cpu_suspend = cpu_psci_cpu_suspend,
+ .cpu_init_idle = psci_cpu_init_idle,
+ .cpu_suspend = psci_cpu_suspend_enter,
#endif
.cpu_init = cpu_psci_cpu_init,
.cpu_prepare = cpu_psci_cpu_prepare,
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 1971f49..3f6cd5c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -58,6 +58,12 @@
*/
void ptrace_disable(struct task_struct *child)
{
+ /*
+ * This would be better off in core code, but PTRACE_DETACH has
+ * grown its fair share of arch-specific worts and changing it
+ * is likely to cause regressions on obscure architectures.
+ */
+ user_disable_single_step(child);
}
#ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -494,7 +500,7 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
if (ret)
return ret;
- if (!valid_user_regs(&newregs))
+ if (!valid_user_regs(&newregs, target))
return -EINVAL;
task_pt_regs(target)->user_regs = newregs;
@@ -764,7 +770,7 @@ static int compat_gpr_set(struct task_struct *target,
}
- if (valid_user_regs(&newregs.user_regs))
+ if (valid_user_regs(&newregs.user_regs, target))
*task_pt_regs(target) = newregs;
else
ret = -EINVAL;
@@ -1266,3 +1272,79 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
}
+
+/*
+ * Bits which are always architecturally RES0 per ARM DDI 0487A.h
+ * Userspace cannot use these until they have an architectural meaning.
+ * We also reserve IL for the kernel; SS is handled dynamically.
+ */
+#define SPSR_EL1_AARCH64_RES0_BITS \
+ (GENMASK_ULL(63,32) | GENMASK_ULL(27, 22) | GENMASK_ULL(20, 10) | \
+ GENMASK_ULL(5, 5))
+#define SPSR_EL1_AARCH32_RES0_BITS \
+ (GENMASK_ULL(63,32) | GENMASK_ULL(24, 22) | GENMASK_ULL(20,20))
+
+static int valid_compat_regs(struct user_pt_regs *regs)
+{
+ regs->pstate &= ~SPSR_EL1_AARCH32_RES0_BITS;
+
+ if (!system_supports_mixed_endian_el0()) {
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+ regs->pstate |= COMPAT_PSR_E_BIT;
+ else
+ regs->pstate &= ~COMPAT_PSR_E_BIT;
+ }
+
+ if (user_mode(regs) && (regs->pstate & PSR_MODE32_BIT) &&
+ (regs->pstate & COMPAT_PSR_A_BIT) == 0 &&
+ (regs->pstate & COMPAT_PSR_I_BIT) == 0 &&
+ (regs->pstate & COMPAT_PSR_F_BIT) == 0) {
+ return 1;
+ }
+
+ /*
+ * Force PSR to a valid 32-bit EL0t, preserving the same bits as
+ * arch/arm.
+ */
+ regs->pstate &= COMPAT_PSR_N_BIT | COMPAT_PSR_Z_BIT |
+ COMPAT_PSR_C_BIT | COMPAT_PSR_V_BIT |
+ COMPAT_PSR_Q_BIT | COMPAT_PSR_IT_MASK |
+ COMPAT_PSR_GE_MASK | COMPAT_PSR_E_BIT |
+ COMPAT_PSR_T_BIT;
+ regs->pstate |= PSR_MODE32_BIT;
+
+ return 0;
+}
+
+static int valid_native_regs(struct user_pt_regs *regs)
+{
+ regs->pstate &= ~SPSR_EL1_AARCH64_RES0_BITS;
+
+ if (user_mode(regs) && !(regs->pstate & PSR_MODE32_BIT) &&
+ (regs->pstate & PSR_D_BIT) == 0 &&
+ (regs->pstate & PSR_A_BIT) == 0 &&
+ (regs->pstate & PSR_I_BIT) == 0 &&
+ (regs->pstate & PSR_F_BIT) == 0) {
+ return 1;
+ }
+
+ /* Force PSR to a valid 64-bit EL0t */
+ regs->pstate &= PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT;
+
+ return 0;
+}
+
+/*
+ * Are the current registers suitable for user mode? (used to maintain
+ * security in signal handlers)
+ */
+int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
+{
+ if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
+ regs->pstate &= ~DBG_SPSR_SS;
+
+ if (is_compat_thread(task_thread_info(task)))
+ return valid_compat_regs(regs);
+ else
+ return valid_native_regs(regs);
+}
diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
index 6c4fd28..1718706 100644
--- a/arch/arm64/kernel/return_address.c
+++ b/arch/arm64/kernel/return_address.c
@@ -43,8 +43,11 @@ void *return_address(unsigned int level)
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.pc = (unsigned long)return_address; /* dummy */
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = current->curr_ret_stack;
+#endif
- walk_stackframe(&frame, save_return_addr, &data);
+ walk_stackframe(current, &frame, save_return_addr, &data);
if (!data.level)
return data.addr;
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 2322479..9dc6776 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -28,7 +28,6 @@
#include <linux/console.h>
#include <linux/cache.h>
#include <linux/bootmem.h>
-#include <linux/seq_file.h>
#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/kexec.h>
@@ -44,7 +43,6 @@
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/efi.h>
-#include <linux/personality.h>
#include <linux/psci.h>
#include <asm/acpi.h>
@@ -54,6 +52,7 @@
#include <asm/elf.h>
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
+#include <asm/kasan.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/smp_plat.h>
@@ -63,23 +62,7 @@
#include <asm/memblock.h>
#include <asm/efi.h>
#include <asm/xen/hypervisor.h>
-
-unsigned long elf_hwcap __read_mostly;
-EXPORT_SYMBOL_GPL(elf_hwcap);
-
-#ifdef CONFIG_COMPAT
-#define COMPAT_ELF_HWCAP_DEFAULT \
- (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
- COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
- COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\
- COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
- COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\
- COMPAT_HWCAP_LPAE)
-unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
-unsigned int compat_elf_hwcap2 __read_mostly;
-#endif
-
-DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
+#include <asm/mmu_context.h>
phys_addr_t __fdt_pointer __initdata;
@@ -91,13 +74,13 @@ static struct resource mem_res[] = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
},
{
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
}
};
@@ -195,104 +178,6 @@ static void __init smp_build_mpidr_hash(void)
__flush_dcache_area(&mpidr_hash, sizeof(struct mpidr_hash));
}
-static void __init setup_processor(void)
-{
- u64 features;
- s64 block;
- u32 cwg;
- int cls;
-
- printk("CPU: AArch64 Processor [%08x] revision %d\n",
- read_cpuid_id(), read_cpuid_id() & 15);
-
- sprintf(init_utsname()->machine, ELF_PLATFORM);
- elf_hwcap = 0;
-
- cpuinfo_store_boot_cpu();
-
- /*
- * Check for sane CTR_EL0.CWG value.
- */
- cwg = cache_type_cwg();
- cls = cache_line_size();
- if (!cwg)
- pr_warn("No Cache Writeback Granule information, assuming cache line size %d\n",
- cls);
- if (L1_CACHE_BYTES < cls)
- pr_warn("L1_CACHE_BYTES smaller than the Cache Writeback Granule (%d < %d)\n",
- L1_CACHE_BYTES, cls);
-
- /*
- * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks.
- * The blocks we test below represent incremental functionality
- * for non-negative values. Negative values are reserved.
- */
- features = read_cpuid(ID_AA64ISAR0_EL1);
- block = cpuid_feature_extract_field(features, 4);
- if (block > 0) {
- switch (block) {
- default:
- case 2:
- elf_hwcap |= HWCAP_PMULL;
- case 1:
- elf_hwcap |= HWCAP_AES;
- case 0:
- break;
- }
- }
-
- if (cpuid_feature_extract_field(features, 8) > 0)
- elf_hwcap |= HWCAP_SHA1;
-
- if (cpuid_feature_extract_field(features, 12) > 0)
- elf_hwcap |= HWCAP_SHA2;
-
- if (cpuid_feature_extract_field(features, 16) > 0)
- elf_hwcap |= HWCAP_CRC32;
-
- block = cpuid_feature_extract_field(features, 20);
- if (block > 0) {
- switch (block) {
- default:
- case 2:
- elf_hwcap |= HWCAP_ATOMICS;
- case 1:
- /* RESERVED */
- case 0:
- break;
- }
- }
-
-#ifdef CONFIG_COMPAT
- /*
- * ID_ISAR5_EL1 carries similar information as above, but pertaining to
- * the AArch32 32-bit execution state.
- */
- features = read_cpuid(ID_ISAR5_EL1);
- block = cpuid_feature_extract_field(features, 4);
- if (block > 0) {
- switch (block) {
- default:
- case 2:
- compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
- case 1:
- compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
- case 0:
- break;
- }
- }
-
- if (cpuid_feature_extract_field(features, 8) > 0)
- compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
-
- if (cpuid_feature_extract_field(features, 12) > 0)
- compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
-
- if (cpuid_feature_extract_field(features, 16) > 0)
- compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
-#endif
-}
-
static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
void *dt_virt = fixmap_remap_fdt(dt_phys);
@@ -326,7 +211,7 @@ static void __init request_standard_resources(void)
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;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
@@ -406,8 +291,9 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
void __init setup_arch(char **cmdline_p)
{
- setup_processor();
+ pr_info("Boot CPU: AArch64 Processor [%08x]\n", read_cpuid_id());
+ sprintf(init_utsname()->machine, ELF_PLATFORM);
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata;
@@ -428,6 +314,12 @@ void __init setup_arch(char **cmdline_p)
*/
local_async_enable();
+ /*
+ * TTBR0 is only used for the identity mapping at this stage. Make it
+ * point to zero page to avoid speculatively fetching new entries.
+ */
+ cpu_uninstall_idmap();
+
efi_init();
arm64_memblock_init();
@@ -436,6 +328,9 @@ void __init setup_arch(char **cmdline_p)
paging_init();
relocate_initrd();
+
+ kasan_init();
+
request_standard_resources();
early_ioremap_reset();
@@ -494,123 +389,31 @@ static int __init topology_init(void)
}
subsys_initcall(topology_init);
-static const char *hwcap_str[] = {
- "fp",
- "asimd",
- "evtstrm",
- "aes",
- "pmull",
- "sha1",
- "sha2",
- "crc32",
- "atomics",
- NULL
-};
-
-#ifdef CONFIG_COMPAT
-static const char *compat_hwcap_str[] = {
- "swp",
- "half",
- "thumb",
- "26bit",
- "fastmult",
- "fpa",
- "vfp",
- "edsp",
- "java",
- "iwmmxt",
- "crunch",
- "thumbee",
- "neon",
- "vfpv3",
- "vfpv3d16",
- "tls",
- "vfpv4",
- "idiva",
- "idivt",
- "vfpd32",
- "lpae",
- "evtstrm"
-};
-
-static const char *compat_hwcap2_str[] = {
- "aes",
- "pmull",
- "sha1",
- "sha2",
- "crc32",
- NULL
-};
-#endif /* CONFIG_COMPAT */
-
-static int c_show(struct seq_file *m, void *v)
+/*
+ * Dump out kernel offset information on panic.
+ */
+static int dump_kernel_offset(struct notifier_block *self, unsigned long v,
+ void *p)
{
- int i, j;
+ u64 const kaslr_offset = kimage_vaddr - KIMAGE_VADDR;
- for_each_online_cpu(i) {
- struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
- u32 midr = cpuinfo->reg_midr;
-
- /*
- * 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);
-
- /*
- * Dump out the common processor features in a single line.
- * Userspace should read the hwcaps with getauxval(AT_HWCAP)
- * rather than attempting to parse this, but there's a body of
- * software which does already (at least for 32-bit).
- */
- seq_puts(m, "Features\t:");
- if (personality(current->personality) == PER_LINUX32) {
-#ifdef CONFIG_COMPAT
- for (j = 0; compat_hwcap_str[j]; j++)
- if (compat_elf_hwcap & (1 << j))
- seq_printf(m, " %s", compat_hwcap_str[j]);
-
- for (j = 0; compat_hwcap2_str[j]; j++)
- if (compat_elf_hwcap2 & (1 << j))
- seq_printf(m, " %s", compat_hwcap2_str[j]);
-#endif /* CONFIG_COMPAT */
- } else {
- for (j = 0; hwcap_str[j]; j++)
- if (elf_hwcap & (1 << j))
- seq_printf(m, " %s", hwcap_str[j]);
- }
- seq_puts(m, "\n");
-
- seq_printf(m, "CPU implementer\t: 0x%02x\n",
- MIDR_IMPLEMENTOR(midr));
- seq_printf(m, "CPU architecture: 8\n");
- seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
- seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
- seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_offset > 0) {
+ pr_emerg("Kernel Offset: 0x%llx from 0x%lx\n",
+ kaslr_offset, KIMAGE_VADDR);
+ } else {
+ pr_emerg("Kernel Offset: disabled\n");
}
-
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 struct notifier_block kernel_offset_notifier = {
+ .notifier_call = dump_kernel_offset
+};
-static void c_stop(struct seq_file *m, void *v)
+static int __init register_kernel_offset_dumper(void)
{
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &kernel_offset_notifier);
+ return 0;
}
-
-const struct seq_operations cpuinfo_op = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_show
-};
+__initcall(register_kernel_offset_dumper);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e18c48c..a8eafdb 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -115,7 +115,7 @@ static int restore_sigframe(struct pt_regs *regs,
*/
regs->syscallno = ~0UL;
- err |= !valid_user_regs(&regs->user_regs);
+ err |= !valid_user_regs(&regs->user_regs, current);
if (err == 0) {
struct fpsimd_context *fpsimd_ctx =
@@ -307,7 +307,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
/*
* Check that the resulting registers are actually sane.
*/
- ret |= !valid_user_regs(&regs->user_regs);
+ ret |= !valid_user_regs(&regs->user_regs, current);
/*
* Fast forward the stepping logic so we step into the signal
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 71ef6dc..b7063de 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -166,7 +166,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
#ifdef BUS_MCEERR_AO
/*
* Other callers might not initialize the si_lsb field,
- * so check explicitely for the right codes here.
+ * so check explicitly for the right codes here.
*/
if (from->si_signo == SIGBUS &&
(from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO))
@@ -356,7 +356,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
*/
regs->syscallno = ~0UL;
- err |= !valid_user_regs(&regs->user_regs);
+ err |= !valid_user_regs(&regs->user_regs, current);
aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
if (err == 0)
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index f586f7c..fd10eb6 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -145,6 +145,10 @@ ENTRY(cpu_resume_mmu)
ENDPROC(cpu_resume_mmu)
.popsection
cpu_resume_after_mmu:
+#ifdef CONFIG_KASAN
+ mov x0, sp
+ bl kasan_unpoison_remaining_stack
+#endif
mov x0, #0 // return zero on success
ldp x19, x20, [sp, #16]
ldp x21, x22, [sp, #32]
@@ -173,6 +177,9 @@ ENTRY(cpu_resume)
/* load physical address of identity map page table in x1 */
adrp x1, idmap_pg_dir
mov sp, x2
+ /* save thread_info */
+ and x2, x2, #~(THREAD_SIZE - 1)
+ msr sp_el0, x2
/*
* cpu_do_resume expects x0 to contain context physical address
* pointer and x1 to contain physical address of 1:1 page tables
diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
new file mode 100644
index 0000000..ae0496f
--- /dev/null
+++ b/arch/arm64/kernel/smccc-call.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 <linux/linkage.h>
+#include <asm/asm-offsets.h>
+
+ .macro SMCCC instr
+ .cfi_startproc
+ \instr #0
+ ldr x4, [sp]
+ stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
+ stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
+ ret
+ .cfi_endproc
+ .endm
+
+/*
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_smc)
+ SMCCC smc
+ENDPROC(arm_smccc_smc)
+
+/*
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ * unsigned long a3, unsigned long a4, unsigned long a5,
+ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_hvc)
+ SMCCC hvc
+ENDPROC(arm_smccc_hvc)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index dbdaacd..b2d5f4e 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -63,6 +63,8 @@
* where to place its SVC stack
*/
struct secondary_data secondary_data;
+/* Number of CPUs which aren't online, but looping in kernel text. */
+int cpus_stuck_in_kernel;
enum ipi_msg_type {
IPI_RESCHEDULE,
@@ -70,8 +72,19 @@ enum ipi_msg_type {
IPI_CPU_STOP,
IPI_TIMER,
IPI_IRQ_WORK,
+ IPI_WAKEUP
};
+#ifdef CONFIG_HOTPLUG_CPU
+static int op_cpu_kill(unsigned int cpu);
+#else
+static inline int op_cpu_kill(unsigned int cpu)
+{
+ return -ENOSYS;
+}
+#endif
+
+
/*
* Boot a secondary CPU, and assign it the specified idle task.
* This also gives us the initial stack to use for this CPU.
@@ -89,12 +102,14 @@ static DECLARE_COMPLETION(cpu_running);
int __cpu_up(unsigned int cpu, struct task_struct *idle)
{
int ret;
+ long status;
/*
* 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;
+ update_cpu_boot_status(CPU_MMU_OFF);
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
/*
@@ -118,6 +133,32 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
}
secondary_data.stack = NULL;
+ status = READ_ONCE(secondary_data.status);
+ if (ret && status) {
+
+ if (status == CPU_MMU_OFF)
+ status = READ_ONCE(__early_cpu_boot_status);
+
+ switch (status) {
+ default:
+ pr_err("CPU%u: failed in unknown state : 0x%lx\n",
+ cpu, status);
+ break;
+ case CPU_KILL_ME:
+ if (!op_cpu_kill(cpu)) {
+ pr_crit("CPU%u: died during early boot\n", cpu);
+ break;
+ }
+ /* Fall through */
+ pr_crit("CPU%u: may not have shut down cleanly\n", cpu);
+ case CPU_STUCK_IN_KERNEL:
+ pr_crit("CPU%u: is stuck in kernel\n", cpu);
+ cpus_stuck_in_kernel++;
+ break;
+ case CPU_PANIC_KERNEL:
+ panic("CPU%u detected unsupported configuration\n", cpu);
+ }
+ }
return ret;
}
@@ -142,22 +183,25 @@ asmlinkage void secondary_start_kernel(void)
*/
atomic_inc(&mm->mm_count);
current->active_mm = mm;
- cpumask_set_cpu(cpu, mm_cpumask(mm));
set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
- printk("CPU%u: Booted secondary processor\n", cpu);
/*
* TTBR0 is only used for the identity mapping at this stage. Make it
* point to zero page to avoid speculatively fetching new entries.
*/
- cpu_set_reserved_ttbr0();
- flush_tlb_all();
- cpu_set_default_tcr_t0sz();
+ cpu_uninstall_idmap();
preempt_disable();
trace_hardirqs_off();
+ /*
+ * If the system has established the capabilities, make sure
+ * this CPU ticks all of those. If it doesn't, the CPU will
+ * fail to come online.
+ */
+ verify_local_cpu_capabilities();
+
if (cpu_ops[cpu]->cpu_postboot)
cpu_ops[cpu]->cpu_postboot();
@@ -178,6 +222,11 @@ asmlinkage void secondary_start_kernel(void)
* the CPU migration code to notice that the CPU is online
* before we continue.
*/
+ pr_info("CPU%u: Booted secondary processor [%08x]\n",
+ cpu, read_cpuid_id());
+ update_cpu_boot_status(CPU_BOOT_SUCCESS);
+ /* Make sure the status update is visible before we complete */
+ smp_wmb();
set_cpu_online(cpu, true);
complete(&cpu_running);
@@ -188,7 +237,7 @@ asmlinkage void secondary_start_kernel(void)
/*
* OK, it's off to the idle thread for us
*/
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -232,12 +281,7 @@ int __cpu_disable(void)
/*
* OK - migrate IRQs away from this CPU
*/
- migrate_irqs();
-
- /*
- * Remove this CPU from the vm mask set of all processes.
- */
- clear_tasks_mm_cpumask(cpu);
+ irq_migrate_all_off_this_cpu();
return 0;
}
@@ -311,6 +355,30 @@ void cpu_die(void)
}
#endif
+/*
+ * Kill the calling secondary CPU, early in bringup before it is turned
+ * online.
+ */
+void cpu_die_early(void)
+{
+ int cpu = smp_processor_id();
+
+ pr_crit("CPU%d: will not boot\n", cpu);
+
+ /* Mark this CPU absent */
+ set_cpu_present(cpu, 0);
+
+#ifdef CONFIG_HOTPLUG_CPU
+ update_cpu_boot_status(CPU_KILL_ME);
+ /* Check if we can park ourselves */
+ if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_die)
+ cpu_ops[cpu]->cpu_die(cpu);
+#endif
+ update_cpu_boot_status(CPU_STUCK_IN_KERNEL);
+
+ cpu_park_loop();
+}
+
static void __init hyp_mode_check(void)
{
if (is_hyp_mode_available())
@@ -325,12 +393,14 @@ static void __init hyp_mode_check(void)
void __init smp_cpus_done(unsigned int max_cpus)
{
pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
+ setup_cpu_features();
hyp_mode_check();
apply_alternatives_all();
}
void __init smp_prepare_boot_cpu(void)
{
+ cpuinfo_store_boot_cpu();
set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
}
@@ -441,6 +511,17 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
/* map the logical cpu id to cpu MPIDR */
cpu_logical_map(cpu_count) = hwid;
+ /*
+ * Set-up the ACPI parking protocol cpu entries
+ * while initializing the cpu_logical_map to
+ * avoid parsing MADT entries multiple times for
+ * nothing (ie a valid cpu_logical_map entry should
+ * contain a valid parking protocol data set to
+ * initialize the cpu if the parking protocol is
+ * the only available enable method).
+ */
+ acpi_set_mailbox_entry(cpu_count, processor);
+
cpu_count++;
}
@@ -469,7 +550,7 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
* cpu logical map array containing MPIDR values related to logical
* cpus. Assumes that cpu_logical_map(0) has already been initialized.
*/
-void __init of_parse_and_init_cpus(void)
+static void __init of_parse_and_init_cpus(void)
{
struct device_node *dn = NULL;
@@ -623,6 +704,7 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
S(IPI_CPU_STOP, "CPU stop interrupts"),
S(IPI_TIMER, "Timer broadcast interrupts"),
S(IPI_IRQ_WORK, "IRQ work interrupts"),
+ S(IPI_WAKEUP, "CPU wake-up interrupts"),
};
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
@@ -666,6 +748,13 @@ void arch_send_call_function_single_ipi(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
}
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_WAKEUP);
+}
+#endif
+
#ifdef CONFIG_IRQ_WORK
void arch_irq_work_raise(void)
{
@@ -743,6 +832,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
break;
#endif
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+ case IPI_WAKEUP:
+ WARN_ONCE(!acpi_parking_protocol_valid(cpu),
+ "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
+ cpu);
+ break;
+#endif
+
default:
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
break;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index ccb6078..d9751a4 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -17,9 +17,11 @@
*/
#include <linux/kernel.h>
#include <linux/export.h>
+#include <linux/ftrace.h>
#include <linux/sched.h>
#include <linux/stacktrace.h>
+#include <asm/irq.h>
#include <asm/stacktrace.h>
/*
@@ -35,25 +37,82 @@
* ldp x29, x30, [sp]
* add sp, sp, #0x10
*/
-int notrace unwind_frame(struct stackframe *frame)
+int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
{
unsigned long high, low;
unsigned long fp = frame->fp;
+ unsigned long irq_stack_ptr;
+
+ /*
+ * Switching between stacks is valid when tracing current and in
+ * non-preemptible context.
+ */
+ if (tsk == current && !preemptible())
+ irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
+ else
+ irq_stack_ptr = 0;
low = frame->sp;
- high = ALIGN(low, THREAD_SIZE);
+ /* irq stacks are not THREAD_SIZE aligned */
+ if (on_irq_stack(frame->sp, raw_smp_processor_id()))
+ high = irq_stack_ptr;
+ else
+ high = ALIGN(low, THREAD_SIZE) - 0x20;
- if (fp < low || fp > high - 0x18 || fp & 0xf)
+ if (fp < low || fp > high || fp & 0xf)
return -EINVAL;
frame->sp = fp + 0x10;
- frame->fp = *(unsigned long *)(fp);
- frame->pc = *(unsigned long *)(fp + 8);
+ frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
+ frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if (tsk && tsk->ret_stack &&
+ (frame->pc == (unsigned long)return_to_handler)) {
+ /*
+ * This is a case where function graph tracer has
+ * modified a return address (LR) in a stack frame
+ * to hook a function return.
+ * So replace it to an original value.
+ */
+ frame->pc = tsk->ret_stack[frame->graph--].ret;
+ }
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+ /*
+ * Check whether we are going to walk through from interrupt stack
+ * to task stack.
+ * If we reach the end of the stack - and its an interrupt stack,
+ * unpack the dummy frame to find the original elr.
+ *
+ * Check the frame->fp we read from the bottom of the irq_stack,
+ * and the original task stack pointer are both in current->stack.
+ */
+ if (frame->sp == irq_stack_ptr) {
+ struct pt_regs *irq_args;
+ unsigned long orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
+
+ if (object_is_on_stack((void *)orig_sp) &&
+ object_is_on_stack((void *)frame->fp)) {
+ frame->sp = orig_sp;
+
+ /* orig_sp is the saved pt_regs, find the elr */
+ irq_args = (struct pt_regs *)orig_sp;
+ frame->pc = irq_args->pc;
+ } else {
+ /*
+ * This frame has a non-standard format, and we
+ * didn't fix it, because the data looked wrong.
+ * Refuse to output this frame.
+ */
+ return -EINVAL;
+ }
+ }
return 0;
}
-void notrace walk_stackframe(struct stackframe *frame,
+void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data)
{
while (1) {
@@ -61,7 +120,7 @@ void notrace walk_stackframe(struct stackframe *frame,
if (fn(frame, data))
break;
- ret = unwind_frame(frame);
+ ret = unwind_frame(tsk, frame);
if (ret < 0)
break;
}
@@ -112,8 +171,11 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
frame.sp = current_stack_pointer;
frame.pc = (unsigned long)save_stack_trace_tsk;
}
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = tsk->curr_ret_stack;
+#endif
- walk_stackframe(&frame, save_trace, &data);
+ walk_stackframe(tsk, &frame, save_trace, &data);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 44ca414..6605539 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -1,3 +1,4 @@
+#include <linux/ftrace.h>
#include <linux/percpu.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
@@ -41,7 +42,7 @@ void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr,
* time the notifier runs debug exceptions might have been enabled already,
* with HW breakpoints registers content still in an unknown state.
*/
-void (*hw_breakpoint_restore)(void *);
+static void (*hw_breakpoint_restore)(void *);
void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
{
/* Prevent multiple restore hook initializations */
@@ -59,7 +60,6 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
*/
int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
{
- struct mm_struct *mm = current->active_mm;
int ret;
unsigned long flags;
@@ -71,6 +71,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
local_dbg_save(flags);
/*
+ * Function graph tracer state gets incosistent when the kernel
+ * calls functions that never return (aka suspend finishers) hence
+ * disable graph tracing during their execution.
+ */
+ pause_graph_tracing();
+
+ /*
* mm context saved on the stack, it will be restored when
* the cpu comes out of reset through the identity mapped
* page tables, so that the thread address space is properly
@@ -79,22 +86,11 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
ret = __cpu_suspend_enter(arg, fn);
if (ret == 0) {
/*
- * We are resuming from reset with TTBR0_EL1 set to the
- * idmap to enable the MMU; set the TTBR0 to the reserved
- * page tables to prevent speculative TLB allocations, flush
- * the local tlb and set the default tcr_el1.t0sz so that
- * the TTBR0 address space set-up is properly restored.
- * If the current active_mm != &init_mm we entered cpu_suspend
- * with mappings in TTBR0 that must be restored, so we switch
- * them back to complete the address space configuration
- * restoration before returning.
+ * We are resuming from reset with the idmap active in TTBR0_EL1.
+ * We must uninstall the idmap and restore the expected MMU
+ * state before we can possibly return to userspace.
*/
- cpu_set_reserved_ttbr0();
- flush_tlb_all();
- cpu_set_default_tcr_t0sz();
-
- if (mm != &init_mm)
- cpu_switch_mm(mm->pgd, mm);
+ cpu_uninstall_idmap();
/*
* Restore per-cpu offset before any kernel
@@ -111,6 +107,8 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
hw_breakpoint_restore(NULL);
}
+ unpause_graph_tracing();
+
/*
* Restore pstate flags. OS lock and mdscr have been already
* restored, so from this point onwards, debugging is fully
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 149151f..5977969 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -52,8 +52,11 @@ unsigned long profile_pc(struct pt_regs *regs)
frame.fp = regs->regs[29];
frame.sp = regs->sp;
frame.pc = regs->pc;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = -1; /* no task info */
+#endif
do {
- int ret = unwind_frame(&frame);
+ int ret = unwind_frame(NULL, &frame);
if (ret < 0)
return 0;
} while (in_lock_functions(frame.pc));
@@ -67,16 +70,10 @@ void __init time_init(void)
u32 arch_timer_rate;
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
tick_setup_hrtimer_broadcast();
- /*
- * Since ACPI or FDT will only one be available in the system,
- * we can use acpi_generic_timer_init() here safely
- */
- acpi_generic_timer_init();
-
arch_timer_rate = arch_timer_get_rate();
if (!arch_timer_rate)
panic("Unable to initialise architected timer.\n");
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index f93aae5..c539208 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -103,12 +103,12 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
set_fs(fs);
}
-static void dump_backtrace_entry(unsigned long where, unsigned long stack)
+static void dump_backtrace_entry(unsigned long where)
{
+ /*
+ * Note that 'where' can have a physical address, but it's not handled.
+ */
print_ip_sym(where);
- if (in_exception_text(where))
- dump_mem("", "Exception stack", stack,
- stack + sizeof(struct pt_regs), false);
}
static void dump_instr(const char *lvl, struct pt_regs *regs)
@@ -146,17 +146,24 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
struct stackframe frame;
+ unsigned long irq_stack_ptr;
+ int skip;
+
+ /*
+ * Switching between stacks is valid when tracing current and in
+ * non-preemptible context.
+ */
+ if (tsk == current && !preemptible())
+ irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
+ else
+ irq_stack_ptr = 0;
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
if (!tsk)
tsk = current;
- if (regs) {
- frame.fp = regs->regs[29];
- frame.sp = regs->sp;
- frame.pc = regs->pc;
- } else if (tsk == current) {
+ if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.pc = (unsigned long)dump_backtrace;
@@ -168,16 +175,49 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
frame.sp = thread_saved_sp(tsk);
frame.pc = thread_saved_pc(tsk);
}
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = tsk->curr_ret_stack;
+#endif
- pr_emerg("Call trace:\n");
+ skip = !!regs;
+ printk("Call trace:\n");
while (1) {
unsigned long where = frame.pc;
+ unsigned long stack;
int ret;
- ret = unwind_frame(&frame);
+ /* skip until specified stack frame */
+ if (!skip) {
+ dump_backtrace_entry(where);
+ } else if (frame.fp == regs->regs[29]) {
+ skip = 0;
+ /*
+ * Mostly, this is the case where this function is
+ * called in panic/abort. As exception handler's
+ * stack frame does not contain the corresponding pc
+ * at which an exception has taken place, use regs->pc
+ * instead.
+ */
+ dump_backtrace_entry(regs->pc);
+ }
+ ret = unwind_frame(tsk, &frame);
if (ret < 0)
break;
- dump_backtrace_entry(where, frame.sp);
+ stack = frame.sp;
+ if (in_exception_text(where)) {
+ /*
+ * If we switched to the irq_stack before calling this
+ * exception handler, then the pt_regs will be on the
+ * task stack. The easiest way to tell is if the large
+ * pt_regs would overlap with the end of the irq_stack.
+ */
+ if (stack < irq_stack_ptr &&
+ (stack + sizeof(struct pt_regs)) > irq_stack_ptr)
+ stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
+
+ dump_mem("", "Exception stack", stack,
+ stack + sizeof(struct pt_regs), false);
+ }
}
}
@@ -451,22 +491,22 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
void __pte_error(const char *file, int line, unsigned long val)
{
- pr_crit("%s:%d: bad pte %016lx.\n", file, line, val);
+ pr_err("%s:%d: bad pte %016lx.\n", file, line, val);
}
void __pmd_error(const char *file, int line, unsigned long val)
{
- pr_crit("%s:%d: bad pmd %016lx.\n", file, line, val);
+ pr_err("%s:%d: bad pmd %016lx.\n", file, line, val);
}
void __pud_error(const char *file, int line, unsigned long val)
{
- pr_crit("%s:%d: bad pud %016lx.\n", file, line, val);
+ pr_err("%s:%d: bad pud %016lx.\n", file, line, val);
}
void __pgd_error(const char *file, int line, unsigned long val)
{
- pr_crit("%s:%d: bad pgd %016lx.\n", file, line, val);
+ pr_err("%s:%d: bad pgd %016lx.\n", file, line, val);
}
/* GENERIC_BUG traps */
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index f6fe17d..b467fd0 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -15,6 +15,9 @@ ccflags-y := -shared -fno-common -fno-builtin
ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared
# down to collect2, resulting in silent corruption of the vDSO image.
ccflags-y += -Wl,-shared
diff --git a/arch/arm64/kernel/vdso/vdso.S b/arch/arm64/kernel/vdso/vdso.S
index 60c1db5..82379a7 100644
--- a/arch/arm64/kernel/vdso/vdso.S
+++ b/arch/arm64/kernel/vdso/vdso.S
@@ -21,9 +21,8 @@
#include <linux/const.h>
#include <asm/page.h>
- __PAGE_ALIGNED_DATA
-
.globl vdso_start, vdso_end
+ .section .rodata
.balign PAGE_SIZE
vdso_start:
.incbin "arch/arm64/kernel/vdso/vdso.so"
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 9807333..4c56e7a 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,8 @@
*/
#include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/kernel-pgtable.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/page.h>
@@ -60,9 +62,12 @@ PECOFF_FILE_ALIGNMENT = 0x200;
#define PECOFF_EDATA_PADDING
#endif
-#ifdef CONFIG_DEBUG_ALIGN_RODATA
+#if defined(CONFIG_DEBUG_ALIGN_RODATA)
#define ALIGN_DEBUG_RO . = ALIGN(1<<SECTION_SHIFT);
#define ALIGN_DEBUG_RO_MIN(min) ALIGN_DEBUG_RO
+#elif defined(CONFIG_DEBUG_RODATA)
+#define ALIGN_DEBUG_RO . = ALIGN(1<<PAGE_SHIFT);
+#define ALIGN_DEBUG_RO_MIN(min) ALIGN_DEBUG_RO
#else
#define ALIGN_DEBUG_RO
#define ALIGN_DEBUG_RO_MIN(min) . = ALIGN(min);
@@ -82,15 +87,16 @@ SECTIONS
EXIT_CALL
*(.discard)
*(.discard.*)
+ *(.interp .dynamic)
}
- . = PAGE_OFFSET + TEXT_OFFSET;
+ . = KIMAGE_VADDR + TEXT_OFFSET;
.head.text : {
_text = .;
HEAD_TEXT
}
- ALIGN_DEBUG_RO
+ ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
.text : { /* Real text segment */
_stext = .; /* Text and read-only data */
__exception_text_start = .;
@@ -108,14 +114,13 @@ SECTIONS
*(.got) /* Global offset table */
}
- ALIGN_DEBUG_RO
- RO_DATA(PAGE_SIZE)
- EXCEPTION_TABLE(8)
+ ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
+ RO_DATA(PAGE_SIZE) /* everything from this point to */
+ EXCEPTION_TABLE(8) /* _etext will be marked RO NX */
NOTES
- ALIGN_DEBUG_RO
- _etext = .; /* End of text and rodata section */
ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
+ _etext = .; /* End of text and rodata section */
__init_begin = .;
INIT_TEXT_SECTION(8)
@@ -123,7 +128,6 @@ SECTIONS
ARM_EXIT_KEEP(EXIT_TEXT)
}
- ALIGN_DEBUG_RO_MIN(16)
.init.data : {
INIT_DATA
INIT_SETUP(16)
@@ -136,10 +140,7 @@ SECTIONS
ARM_EXIT_KEEP(EXIT_DATA)
}
- PERCPU_SECTION(64)
-
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
+ PERCPU_SECTION(L1_CACHE_BYTES)
. = ALIGN(4);
.altinstructions : {
@@ -150,11 +151,28 @@ SECTIONS
.altinstr_replacement : {
*(.altinstr_replacement)
}
+ .rela : ALIGN(8) {
+ __reloc_start = .;
+ *(.rela .rela*)
+ __reloc_end = .;
+ }
+ .dynsym : ALIGN(8) {
+ __dynsym_start = .;
+ *(.dynsym)
+ }
+ .dynstr : {
+ *(.dynstr)
+ }
+ .hash : {
+ *(.hash)
+ }
. = ALIGN(PAGE_SIZE);
+ __init_end = .;
+
_data = .;
_sdata = .;
- RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
+ RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
PECOFF_EDATA_PADDING
_edata = .;
@@ -185,4 +203,4 @@ ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
/*
* If padding is applied before .head.text, virt<->phys conversions will fail.
*/
-ASSERT(_text == (PAGE_OFFSET + TEXT_OFFSET), "HEAD is misaligned")
+ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned")
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 5c7e920e..de7450d 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,9 +16,13 @@ menuconfig VIRTUALIZATION
if VIRTUALIZATION
+config KVM_ARM_VGIC_V3
+ bool
+
config KVM
bool "Kernel-based Virtual Machine (KVM) support"
depends on OF
+ depends on !ARM64_16K_PAGES
select MMU_NOTIFIER
select PREEMPT_NOTIFIERS
select ANON_INODES
@@ -31,8 +35,12 @@ config KVM
select KVM_VFIO
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
+ select KVM_ARM_VGIC_V3
+ select KVM_ARM_PMU if HW_PERF_EVENTS
---help---
Support hosting virtualized guest machines.
+ We don't support KVM with 16K page tables yet, due to the multiple
+ levels of fake page tables.
If unsure, say N.
@@ -41,4 +49,12 @@ config KVM_ARM_HOST
---help---
Provides host support for ARM processors.
+config KVM_ARM_PMU
+ bool
+ ---help---
+ Adds support for a virtual Performance Monitoring Unit (PMU) in
+ virtual machines.
+
+source drivers/vhost/Kconfig
+
endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 1949fe5..122cff4 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -10,6 +10,7 @@ KVM=../../../virt/kvm
ARM=../../../arch/arm/kvm
obj-$(CONFIG_KVM_ARM_HOST) += kvm.o
+obj-$(CONFIG_KVM_ARM_HOST) += hyp/
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
@@ -22,8 +23,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generi
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2-emul.o
-kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v2-switch.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
-kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
+kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index d250160..32fad75 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -28,13 +28,21 @@
#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>
#include "trace.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[] = {
+ VCPU_STAT(hvc_exit_stat),
+ VCPU_STAT(wfe_exit_stat),
+ VCPU_STAT(wfi_exit_stat),
+ VCPU_STAT(mmio_exit_user),
+ VCPU_STAT(mmio_exit_kernel),
+ VCPU_STAT(exits),
{ NULL }
};
@@ -186,7 +194,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
u64 val;
val = kvm_arm_timer_get_reg(vcpu, reg->id);
- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
+ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
}
/**
@@ -372,3 +380,54 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
}
return 0;
}
+
+int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret;
+
+ switch (attr->group) {
+ case KVM_ARM_VCPU_PMU_V3_CTRL:
+ ret = kvm_arm_pmu_v3_set_attr(vcpu, attr);
+ break;
+ default:
+ ret = -ENXIO;
+ break;
+ }
+
+ return ret;
+}
+
+int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret;
+
+ switch (attr->group) {
+ case KVM_ARM_VCPU_PMU_V3_CTRL:
+ ret = kvm_arm_pmu_v3_get_attr(vcpu, attr);
+ break;
+ default:
+ ret = -ENXIO;
+ break;
+ }
+
+ return ret;
+}
+
+int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr)
+{
+ int ret;
+
+ switch (attr->group) {
+ case KVM_ARM_VCPU_PMU_V3_CTRL:
+ ret = kvm_arm_pmu_v3_has_attr(vcpu, attr);
+ break;
+ default:
+ ret = -ENXIO;
+ break;
+ }
+
+ return ret;
+}
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 68a0759..eba89e4 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -23,6 +23,7 @@
#include <linux/kvm_host.h>
#include <asm/esr.h>
+#include <asm/kvm_asm.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h>
@@ -37,8 +38,9 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
int ret;
- trace_kvm_hvc_arm64(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
+ trace_kvm_hvc_arm64(*vcpu_pc(vcpu), vcpu_get_reg(vcpu, 0),
kvm_vcpu_hvc_get_imm(vcpu));
+ vcpu->stat.hvc_exit_stat++;
ret = kvm_psci_call(vcpu);
if (ret < 0) {
@@ -71,9 +73,11 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
if (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WFx_ISS_WFE) {
trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true);
+ vcpu->stat.wfe_exit_stat++;
kvm_vcpu_on_spin(vcpu);
} else {
trace_kvm_wfx_arm64(*vcpu_pc(vcpu), false);
+ vcpu->stat.wfi_exit_stat++;
kvm_vcpu_block(vcpu);
}
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 178ba22..7d8747c 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -64,7 +64,7 @@ __do_hyp_init:
mrs x4, tcr_el1
ldr x5, =TCR_EL2_MASK
and x4, x4, x5
- ldr x5, =TCR_EL2_FLAGS
+ mov x5, #TCR_EL2_RES1
orr x4, x4, x5
#ifndef CONFIG_ARM64_VA_BITS_48
@@ -85,16 +85,14 @@ __do_hyp_init:
ldr_l x5, idmap_t0sz
bfi x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
#endif
- msr tcr_el2, x4
-
- ldr x4, =VTCR_EL2_FLAGS
/*
* Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in
- * VTCR_EL2.
+ * TCR_EL2.
*/
mrs x5, ID_AA64MMFR0_EL1
bfi x4, x5, #16, #3
- msr vtcr_el2, x4
+
+ msr tcr_el2, x4
mrs x4, mair_el1
msr mair_el2, x4
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index e583613..48f19a3 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -18,900 +18,11 @@
#include <linux/linkage.h>
#include <asm/alternative.h>
-#include <asm/asm-offsets.h>
#include <asm/assembler.h>
#include <asm/cpufeature.h>
-#include <asm/debug-monitors.h>
-#include <asm/esr.h>
-#include <asm/fpsimdmacros.h>
-#include <asm/kvm.h>
-#include <asm/kvm_arm.h>
-#include <asm/kvm_asm.h>
-#include <asm/kvm_mmu.h>
-#include <asm/memory.h>
-
-#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x)
-#define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
-#define CPU_SPSR_OFFSET(x) CPU_GP_REG_OFFSET(CPU_SPSR + 8*x)
-#define CPU_SYSREG_OFFSET(x) (CPU_SYSREGS + 8*x)
-
- .text
- .pushsection .hyp.text, "ax"
- .align PAGE_SHIFT
-
-.macro save_common_regs
- // x2: base address for cpu context
- // x3: tmp register
-
- add x3, x2, #CPU_XREG_OFFSET(19)
- stp x19, x20, [x3]
- stp x21, x22, [x3, #16]
- stp x23, x24, [x3, #32]
- stp x25, x26, [x3, #48]
- stp x27, x28, [x3, #64]
- stp x29, lr, [x3, #80]
-
- mrs x19, sp_el0
- mrs x20, elr_el2 // pc before entering el2
- mrs x21, spsr_el2 // pstate before entering el2
-
- stp x19, x20, [x3, #96]
- str x21, [x3, #112]
-
- mrs x22, sp_el1
- mrs x23, elr_el1
- mrs x24, spsr_el1
-
- str x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
- str x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
- str x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
-.endm
-
-.macro restore_common_regs
- // x2: base address for cpu context
- // x3: tmp register
-
- ldr x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
- ldr x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
- ldr x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
-
- msr sp_el1, x22
- msr elr_el1, x23
- msr spsr_el1, x24
-
- add x3, x2, #CPU_XREG_OFFSET(31) // SP_EL0
- ldp x19, x20, [x3]
- ldr x21, [x3, #16]
-
- msr sp_el0, x19
- msr elr_el2, x20 // pc on return from el2
- msr spsr_el2, x21 // pstate on return from el2
-
- add x3, x2, #CPU_XREG_OFFSET(19)
- ldp x19, x20, [x3]
- ldp x21, x22, [x3, #16]
- ldp x23, x24, [x3, #32]
- ldp x25, x26, [x3, #48]
- ldp x27, x28, [x3, #64]
- ldp x29, lr, [x3, #80]
-.endm
-
-.macro save_host_regs
- save_common_regs
-.endm
-
-.macro restore_host_regs
- restore_common_regs
-.endm
-
-.macro save_fpsimd
- // x2: cpu context address
- // x3, x4: tmp regs
- add x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
- fpsimd_save x3, 4
-.endm
-
-.macro restore_fpsimd
- // x2: cpu context address
- // x3, x4: tmp regs
- add x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
- fpsimd_restore x3, 4
-.endm
-
-.macro save_guest_regs
- // x0 is the vcpu address
- // x1 is the return code, do not corrupt!
- // x2 is the cpu context
- // x3 is a tmp register
- // Guest's x0-x3 are on the stack
-
- // Compute base to save registers
- add x3, x2, #CPU_XREG_OFFSET(4)
- stp x4, x5, [x3]
- stp x6, x7, [x3, #16]
- stp x8, x9, [x3, #32]
- stp x10, x11, [x3, #48]
- stp x12, x13, [x3, #64]
- stp x14, x15, [x3, #80]
- stp x16, x17, [x3, #96]
- str x18, [x3, #112]
-
- pop x6, x7 // x2, x3
- pop x4, x5 // x0, x1
-
- add x3, x2, #CPU_XREG_OFFSET(0)
- stp x4, x5, [x3]
- stp x6, x7, [x3, #16]
-
- save_common_regs
-.endm
-
-.macro restore_guest_regs
- // x0 is the vcpu address.
- // x2 is the cpu context
- // x3 is a tmp register
-
- // Prepare x0-x3 for later restore
- add x3, x2, #CPU_XREG_OFFSET(0)
- ldp x4, x5, [x3]
- ldp x6, x7, [x3, #16]
- push x4, x5 // Push x0-x3 on the stack
- push x6, x7
-
- // x4-x18
- ldp x4, x5, [x3, #32]
- ldp x6, x7, [x3, #48]
- ldp x8, x9, [x3, #64]
- ldp x10, x11, [x3, #80]
- ldp x12, x13, [x3, #96]
- ldp x14, x15, [x3, #112]
- ldp x16, x17, [x3, #128]
- ldr x18, [x3, #144]
-
- // x19-x29, lr, sp*, elr*, spsr*
- restore_common_regs
-
- // Last bits of the 64bit state
- pop x2, x3
- pop x0, x1
-
- // Do not touch any register after this!
-.endm
-
-/*
- * Macros to perform system register save/restore.
- *
- * Ordering here is absolutely critical, and must be kept consistent
- * in {save,restore}_sysregs, {save,restore}_guest_32bit_state,
- * and in kvm_asm.h.
- *
- * In other words, don't touch any of these unless you know what
- * you are doing.
- */
-.macro save_sysregs
- // x2: base address for cpu context
- // x3: tmp register
-
- add x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
-
- mrs x4, vmpidr_el2
- mrs x5, csselr_el1
- mrs x6, sctlr_el1
- mrs x7, actlr_el1
- mrs x8, cpacr_el1
- mrs x9, ttbr0_el1
- mrs x10, ttbr1_el1
- mrs x11, tcr_el1
- mrs x12, esr_el1
- mrs x13, afsr0_el1
- mrs x14, afsr1_el1
- mrs x15, far_el1
- mrs x16, mair_el1
- mrs x17, vbar_el1
- mrs x18, contextidr_el1
- mrs x19, tpidr_el0
- mrs x20, tpidrro_el0
- mrs x21, tpidr_el1
- mrs x22, amair_el1
- mrs x23, cntkctl_el1
- mrs x24, par_el1
- mrs x25, mdscr_el1
-
- stp x4, x5, [x3]
- stp x6, x7, [x3, #16]
- stp x8, x9, [x3, #32]
- stp x10, x11, [x3, #48]
- stp x12, x13, [x3, #64]
- stp x14, x15, [x3, #80]
- stp x16, x17, [x3, #96]
- stp x18, x19, [x3, #112]
- stp x20, x21, [x3, #128]
- stp x22, x23, [x3, #144]
- stp x24, x25, [x3, #160]
-.endm
-
-.macro save_debug type
- // x4: pointer to register set
- // x5: number of registers to skip
- // x6..x22 trashed
-
- adr x22, 1f
- add x22, x22, x5, lsl #2
- br x22
-1:
- mrs x21, \type\()15_el1
- mrs x20, \type\()14_el1
- mrs x19, \type\()13_el1
- mrs x18, \type\()12_el1
- mrs x17, \type\()11_el1
- mrs x16, \type\()10_el1
- mrs x15, \type\()9_el1
- mrs x14, \type\()8_el1
- mrs x13, \type\()7_el1
- mrs x12, \type\()6_el1
- mrs x11, \type\()5_el1
- mrs x10, \type\()4_el1
- mrs x9, \type\()3_el1
- mrs x8, \type\()2_el1
- mrs x7, \type\()1_el1
- mrs x6, \type\()0_el1
-
- adr x22, 1f
- add x22, x22, x5, lsl #2
- br x22
-1:
- str x21, [x4, #(15 * 8)]
- str x20, [x4, #(14 * 8)]
- str x19, [x4, #(13 * 8)]
- str x18, [x4, #(12 * 8)]
- str x17, [x4, #(11 * 8)]
- str x16, [x4, #(10 * 8)]
- str x15, [x4, #(9 * 8)]
- str x14, [x4, #(8 * 8)]
- str x13, [x4, #(7 * 8)]
- str x12, [x4, #(6 * 8)]
- str x11, [x4, #(5 * 8)]
- str x10, [x4, #(4 * 8)]
- str x9, [x4, #(3 * 8)]
- str x8, [x4, #(2 * 8)]
- str x7, [x4, #(1 * 8)]
- str x6, [x4, #(0 * 8)]
-.endm
-
-.macro restore_sysregs
- // x2: base address for cpu context
- // x3: tmp register
-
- add x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
-
- ldp x4, x5, [x3]
- ldp x6, x7, [x3, #16]
- ldp x8, x9, [x3, #32]
- ldp x10, x11, [x3, #48]
- ldp x12, x13, [x3, #64]
- ldp x14, x15, [x3, #80]
- ldp x16, x17, [x3, #96]
- ldp x18, x19, [x3, #112]
- ldp x20, x21, [x3, #128]
- ldp x22, x23, [x3, #144]
- ldp x24, x25, [x3, #160]
-
- msr vmpidr_el2, x4
- msr csselr_el1, x5
- msr sctlr_el1, x6
- msr actlr_el1, x7
- msr cpacr_el1, x8
- msr ttbr0_el1, x9
- msr ttbr1_el1, x10
- msr tcr_el1, x11
- msr esr_el1, x12
- msr afsr0_el1, x13
- msr afsr1_el1, x14
- msr far_el1, x15
- msr mair_el1, x16
- msr vbar_el1, x17
- msr contextidr_el1, x18
- msr tpidr_el0, x19
- msr tpidrro_el0, x20
- msr tpidr_el1, x21
- msr amair_el1, x22
- msr cntkctl_el1, x23
- msr par_el1, x24
- msr mdscr_el1, x25
-.endm
-
-.macro restore_debug type
- // x4: pointer to register set
- // x5: number of registers to skip
- // x6..x22 trashed
-
- adr x22, 1f
- add x22, x22, x5, lsl #2
- br x22
-1:
- ldr x21, [x4, #(15 * 8)]
- ldr x20, [x4, #(14 * 8)]
- ldr x19, [x4, #(13 * 8)]
- ldr x18, [x4, #(12 * 8)]
- ldr x17, [x4, #(11 * 8)]
- ldr x16, [x4, #(10 * 8)]
- ldr x15, [x4, #(9 * 8)]
- ldr x14, [x4, #(8 * 8)]
- ldr x13, [x4, #(7 * 8)]
- ldr x12, [x4, #(6 * 8)]
- ldr x11, [x4, #(5 * 8)]
- ldr x10, [x4, #(4 * 8)]
- ldr x9, [x4, #(3 * 8)]
- ldr x8, [x4, #(2 * 8)]
- ldr x7, [x4, #(1 * 8)]
- ldr x6, [x4, #(0 * 8)]
-
- adr x22, 1f
- add x22, x22, x5, lsl #2
- br x22
-1:
- msr \type\()15_el1, x21
- msr \type\()14_el1, x20
- msr \type\()13_el1, x19
- msr \type\()12_el1, x18
- msr \type\()11_el1, x17
- msr \type\()10_el1, x16
- msr \type\()9_el1, x15
- msr \type\()8_el1, x14
- msr \type\()7_el1, x13
- msr \type\()6_el1, x12
- msr \type\()5_el1, x11
- msr \type\()4_el1, x10
- msr \type\()3_el1, x9
- msr \type\()2_el1, x8
- msr \type\()1_el1, x7
- msr \type\()0_el1, x6
-.endm
-
-.macro skip_32bit_state tmp, target
- // Skip 32bit state if not needed
- mrs \tmp, hcr_el2
- tbnz \tmp, #HCR_RW_SHIFT, \target
-.endm
-
-.macro skip_tee_state tmp, target
- // Skip ThumbEE state if not needed
- mrs \tmp, id_pfr0_el1
- tbz \tmp, #12, \target
-.endm
-
-.macro skip_debug_state tmp, target
- ldr \tmp, [x0, #VCPU_DEBUG_FLAGS]
- tbz \tmp, #KVM_ARM64_DEBUG_DIRTY_SHIFT, \target
-.endm
-
-/*
- * Branch to target if CPTR_EL2.TFP bit is set (VFP/SIMD trapping enabled)
- */
-.macro skip_fpsimd_state tmp, target
- mrs \tmp, cptr_el2
- tbnz \tmp, #CPTR_EL2_TFP_SHIFT, \target
-.endm
-
-.macro compute_debug_state target
- // Compute debug state: If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY
- // is set, we do a full save/restore cycle and disable trapping.
- add x25, x0, #VCPU_CONTEXT
-
- // Check the state of MDSCR_EL1
- ldr x25, [x25, #CPU_SYSREG_OFFSET(MDSCR_EL1)]
- and x26, x25, #DBG_MDSCR_KDE
- and x25, x25, #DBG_MDSCR_MDE
- adds xzr, x25, x26
- b.eq 9998f // Nothing to see there
-
- // If any interesting bits was set, we must set the flag
- mov x26, #KVM_ARM64_DEBUG_DIRTY
- str x26, [x0, #VCPU_DEBUG_FLAGS]
- b 9999f // Don't skip restore
-
-9998:
- // Otherwise load the flags from memory in case we recently
- // trapped
- skip_debug_state x25, \target
-9999:
-.endm
-
-.macro save_guest_32bit_state
- skip_32bit_state x3, 1f
-
- add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
- mrs x4, spsr_abt
- mrs x5, spsr_und
- mrs x6, spsr_irq
- mrs x7, spsr_fiq
- stp x4, x5, [x3]
- stp x6, x7, [x3, #16]
-
- add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
- mrs x4, dacr32_el2
- mrs x5, ifsr32_el2
- stp x4, x5, [x3]
-
- skip_fpsimd_state x8, 2f
- mrs x6, fpexc32_el2
- str x6, [x3, #16]
-2:
- skip_debug_state x8, 1f
- mrs x7, dbgvcr32_el2
- str x7, [x3, #24]
-1:
-.endm
-
-.macro restore_guest_32bit_state
- skip_32bit_state x3, 1f
-
- add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
- ldp x4, x5, [x3]
- ldp x6, x7, [x3, #16]
- msr spsr_abt, x4
- msr spsr_und, x5
- msr spsr_irq, x6
- msr spsr_fiq, x7
-
- add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
- ldp x4, x5, [x3]
- msr dacr32_el2, x4
- msr ifsr32_el2, x5
-
- skip_debug_state x8, 1f
- ldr x7, [x3, #24]
- msr dbgvcr32_el2, x7
-1:
-.endm
-
-.macro activate_traps
- ldr x2, [x0, #VCPU_HCR_EL2]
-
- /*
- * We are about to set CPTR_EL2.TFP to trap all floating point
- * register accesses to EL2, however, the ARM ARM clearly states that
- * traps are only taken to EL2 if the operation would not otherwise
- * trap to EL1. Therefore, always make sure that for 32-bit guests,
- * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
- */
- tbnz x2, #HCR_RW_SHIFT, 99f // open code skip_32bit_state
- mov x3, #(1 << 30)
- msr fpexc32_el2, x3
- isb
-99:
- msr hcr_el2, x2
- mov x2, #CPTR_EL2_TTA
- orr x2, x2, #CPTR_EL2_TFP
- msr cptr_el2, x2
-
- mov x2, #(1 << 15) // Trap CP15 Cr=15
- msr hstr_el2, x2
-
- // Monitor Debug Config - see kvm_arm_setup_debug()
- ldr x2, [x0, #VCPU_MDCR_EL2]
- msr mdcr_el2, x2
-.endm
-
-.macro deactivate_traps
- mov x2, #HCR_RW
- msr hcr_el2, x2
- msr hstr_el2, xzr
-
- mrs x2, mdcr_el2
- and x2, x2, #MDCR_EL2_HPMN_MASK
- msr mdcr_el2, x2
-.endm
-
-.macro activate_vm
- ldr x1, [x0, #VCPU_KVM]
- kern_hyp_va x1
- ldr x2, [x1, #KVM_VTTBR]
- msr vttbr_el2, x2
-.endm
-
-.macro deactivate_vm
- msr vttbr_el2, xzr
-.endm
-
-/*
- * Call into the vgic backend for state saving
- */
-.macro save_vgic_state
-alternative_if_not ARM64_HAS_SYSREG_GIC_CPUIF
- bl __save_vgic_v2_state
-alternative_else
- bl __save_vgic_v3_state
-alternative_endif
- mrs x24, hcr_el2
- mov x25, #HCR_INT_OVERRIDE
- neg x25, x25
- and x24, x24, x25
- msr hcr_el2, x24
-.endm
-
-/*
- * Call into the vgic backend for state restoring
- */
-.macro restore_vgic_state
- mrs x24, hcr_el2
- ldr x25, [x0, #VCPU_IRQ_LINES]
- orr x24, x24, #HCR_INT_OVERRIDE
- orr x24, x24, x25
- msr hcr_el2, x24
-alternative_if_not ARM64_HAS_SYSREG_GIC_CPUIF
- bl __restore_vgic_v2_state
-alternative_else
- bl __restore_vgic_v3_state
-alternative_endif
-.endm
-
-.macro save_timer_state
- // x0: vcpu pointer
- ldr x2, [x0, #VCPU_KVM]
- kern_hyp_va x2
- ldr w3, [x2, #KVM_TIMER_ENABLED]
- cbz w3, 1f
-
- mrs x3, cntv_ctl_el0
- and x3, x3, #3
- str w3, [x0, #VCPU_TIMER_CNTV_CTL]
-
- isb
-
- mrs x3, cntv_cval_el0
- str x3, [x0, #VCPU_TIMER_CNTV_CVAL]
-
-1:
- // Disable the virtual timer
- msr cntv_ctl_el0, xzr
-
- // Allow physical timer/counter access for the host
- mrs x2, cnthctl_el2
- orr x2, x2, #3
- msr cnthctl_el2, x2
-
- // Clear cntvoff for the host
- msr cntvoff_el2, xzr
-.endm
-
-.macro restore_timer_state
- // x0: vcpu pointer
- // Disallow physical timer access for the guest
- // Physical counter access is allowed
- mrs x2, cnthctl_el2
- orr x2, x2, #1
- bic x2, x2, #2
- msr cnthctl_el2, x2
-
- ldr x2, [x0, #VCPU_KVM]
- kern_hyp_va x2
- ldr w3, [x2, #KVM_TIMER_ENABLED]
- cbz w3, 1f
-
- ldr x3, [x2, #KVM_TIMER_CNTVOFF]
- msr cntvoff_el2, x3
- ldr x2, [x0, #VCPU_TIMER_CNTV_CVAL]
- msr cntv_cval_el0, x2
- isb
-
- ldr w2, [x0, #VCPU_TIMER_CNTV_CTL]
- and x2, x2, #3
- msr cntv_ctl_el0, x2
-1:
-.endm
-
-__save_sysregs:
- save_sysregs
- ret
-
-__restore_sysregs:
- restore_sysregs
- ret
-
-/* Save debug state */
-__save_debug:
- // x2: ptr to CPU context
- // x3: ptr to debug reg struct
- // x4/x5/x6-22/x24-26: trashed
-
- mrs x26, id_aa64dfr0_el1
- ubfx x24, x26, #12, #4 // Extract BRPs
- ubfx x25, x26, #20, #4 // Extract WRPs
- mov w26, #15
- sub w24, w26, w24 // How many BPs to skip
- sub w25, w26, w25 // How many WPs to skip
-
- mov x5, x24
- add x4, x3, #DEBUG_BCR
- save_debug dbgbcr
- add x4, x3, #DEBUG_BVR
- save_debug dbgbvr
-
- mov x5, x25
- add x4, x3, #DEBUG_WCR
- save_debug dbgwcr
- add x4, x3, #DEBUG_WVR
- save_debug dbgwvr
-
- mrs x21, mdccint_el1
- str x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
- ret
-
-/* Restore debug state */
-__restore_debug:
- // x2: ptr to CPU context
- // x3: ptr to debug reg struct
- // x4/x5/x6-22/x24-26: trashed
-
- mrs x26, id_aa64dfr0_el1
- ubfx x24, x26, #12, #4 // Extract BRPs
- ubfx x25, x26, #20, #4 // Extract WRPs
- mov w26, #15
- sub w24, w26, w24 // How many BPs to skip
- sub w25, w26, w25 // How many WPs to skip
-
- mov x5, x24
- add x4, x3, #DEBUG_BCR
- restore_debug dbgbcr
- add x4, x3, #DEBUG_BVR
- restore_debug dbgbvr
-
- mov x5, x25
- add x4, x3, #DEBUG_WCR
- restore_debug dbgwcr
- add x4, x3, #DEBUG_WVR
- restore_debug dbgwvr
-
- ldr x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
- msr mdccint_el1, x21
-
- ret
-
-__save_fpsimd:
- skip_fpsimd_state x3, 1f
- save_fpsimd
-1: ret
-
-__restore_fpsimd:
- skip_fpsimd_state x3, 1f
- restore_fpsimd
-1: ret
-
-switch_to_guest_fpsimd:
- push x4, lr
-
- mrs x2, cptr_el2
- bic x2, x2, #CPTR_EL2_TFP
- msr cptr_el2, x2
- isb
-
- mrs x0, tpidr_el2
-
- ldr x2, [x0, #VCPU_HOST_CONTEXT]
- kern_hyp_va x2
- bl __save_fpsimd
-
- add x2, x0, #VCPU_CONTEXT
- bl __restore_fpsimd
-
- skip_32bit_state x3, 1f
- ldr x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
- msr fpexc32_el2, x4
-1:
- pop x4, lr
- pop x2, x3
- pop x0, x1
-
- eret
-
-/*
- * u64 __kvm_vcpu_run(struct kvm_vcpu *vcpu);
- *
- * This is the world switch. The first half of the function
- * deals with entering the guest, and anything from __kvm_vcpu_return
- * to the end of the function deals with reentering the host.
- * On the enter path, only x0 (vcpu pointer) must be preserved until
- * the last moment. On the exit path, x0 (vcpu pointer) and x1 (exception
- * code) must both be preserved until the epilogue.
- * In both cases, x2 points to the CPU context we're saving/restoring from/to.
- */
-ENTRY(__kvm_vcpu_run)
- kern_hyp_va x0
- msr tpidr_el2, x0 // Save the vcpu register
-
- // Host context
- ldr x2, [x0, #VCPU_HOST_CONTEXT]
- kern_hyp_va x2
-
- save_host_regs
- bl __save_sysregs
-
- compute_debug_state 1f
- add x3, x0, #VCPU_HOST_DEBUG_STATE
- bl __save_debug
-1:
- activate_traps
- activate_vm
-
- restore_vgic_state
- restore_timer_state
-
- // Guest context
- add x2, x0, #VCPU_CONTEXT
-
- // We must restore the 32-bit state before the sysregs, thanks
- // to Cortex-A57 erratum #852523.
- restore_guest_32bit_state
- bl __restore_sysregs
-
- skip_debug_state x3, 1f
- ldr x3, [x0, #VCPU_DEBUG_PTR]
- kern_hyp_va x3
- bl __restore_debug
-1:
- restore_guest_regs
-
- // That's it, no more messing around.
- eret
-
-__kvm_vcpu_return:
- // Assume x0 is the vcpu pointer, x1 the return code
- // Guest's x0-x3 are on the stack
-
- // Guest context
- add x2, x0, #VCPU_CONTEXT
-
- save_guest_regs
- bl __save_fpsimd
- bl __save_sysregs
-
- skip_debug_state x3, 1f
- ldr x3, [x0, #VCPU_DEBUG_PTR]
- kern_hyp_va x3
- bl __save_debug
-1:
- save_guest_32bit_state
-
- save_timer_state
- save_vgic_state
-
- deactivate_traps
- deactivate_vm
-
- // Host context
- ldr x2, [x0, #VCPU_HOST_CONTEXT]
- kern_hyp_va x2
-
- bl __restore_sysregs
- bl __restore_fpsimd
- /* Clear FPSIMD and Trace trapping */
- msr cptr_el2, xzr
-
- skip_debug_state x3, 1f
- // Clear the dirty flag for the next run, as all the state has
- // already been saved. Note that we nuke the whole 64bit word.
- // If we ever add more flags, we'll have to be more careful...
- str xzr, [x0, #VCPU_DEBUG_FLAGS]
- add x3, x0, #VCPU_HOST_DEBUG_STATE
- bl __restore_debug
-1:
- restore_host_regs
-
- mov x0, x1
- ret
-END(__kvm_vcpu_run)
-
-// void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
-ENTRY(__kvm_tlb_flush_vmid_ipa)
- dsb ishst
-
- kern_hyp_va x0
- ldr x2, [x0, #KVM_VTTBR]
- msr vttbr_el2, x2
- isb
-
- /*
- * We could do so much better if we had the VA as well.
- * Instead, we invalidate Stage-2 for this IPA, and the
- * whole of Stage-1. Weep...
- */
- lsr x1, x1, #12
- tlbi ipas2e1is, x1
- /*
- * We have to ensure completion of the invalidation at Stage-2,
- * since a table walk on another CPU could refill a TLB with a
- * complete (S1 + S2) walk based on the old Stage-2 mapping if
- * the Stage-1 invalidation happened first.
- */
- dsb ish
- tlbi vmalle1is
- dsb ish
- isb
-
- msr vttbr_el2, xzr
- ret
-ENDPROC(__kvm_tlb_flush_vmid_ipa)
-
-/**
- * void __kvm_tlb_flush_vmid(struct kvm *kvm) - Flush per-VMID TLBs
- * @struct kvm *kvm - pointer to kvm structure
- *
- * Invalidates all Stage 1 and 2 TLB entries for current VMID.
- */
-ENTRY(__kvm_tlb_flush_vmid)
- dsb ishst
-
- kern_hyp_va x0
- ldr x2, [x0, #KVM_VTTBR]
- msr vttbr_el2, x2
- isb
-
- tlbi vmalls12e1is
- dsb ish
- isb
-
- msr vttbr_el2, xzr
- ret
-ENDPROC(__kvm_tlb_flush_vmid)
-
-ENTRY(__kvm_flush_vm_context)
- dsb ishst
- tlbi alle1is
- ic ialluis
- dsb ish
- ret
-ENDPROC(__kvm_flush_vm_context)
-
-__kvm_hyp_panic:
- // Guess the context by looking at VTTBR:
- // If zero, then we're already a host.
- // Otherwise restore a minimal host context before panicing.
- mrs x0, vttbr_el2
- cbz x0, 1f
-
- mrs x0, tpidr_el2
-
- deactivate_traps
- deactivate_vm
-
- ldr x2, [x0, #VCPU_HOST_CONTEXT]
- kern_hyp_va x2
-
- bl __restore_sysregs
-
-1: adr x0, __hyp_panic_str
- adr x1, 2f
- ldp x2, x3, [x1]
- sub x0, x0, x2
- add x0, x0, x3
- mrs x1, spsr_el2
- mrs x2, elr_el2
- mrs x3, esr_el2
- mrs x4, far_el2
- mrs x5, hpfar_el2
- mrs x6, par_el1
- mrs x7, tpidr_el2
-
- mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
- PSR_MODE_EL1h)
- msr spsr_el2, lr
- ldr lr, =panic
- msr elr_el2, lr
- eret
-
- .align 3
-2: .quad HYP_PAGE_OFFSET
- .quad PAGE_OFFSET
-ENDPROC(__kvm_hyp_panic)
-
-__hyp_panic_str:
- .ascii "HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p PAR:%p\nVCPU:%p\n\0"
-
- .align 2
/*
- * u64 kvm_call_hyp(void *hypfn, ...);
+ * 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
@@ -922,183 +33,18 @@ __hyp_panic_str:
* passed as x0, x1, and x2 (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.
+ * passed in x0.
*
* A function pointer with a value of 0 has a special meaning, and is
* used to implement __hyp_get_vectors in the same way as in
* arch/arm64/kernel/hyp_stub.S.
*/
-ENTRY(kvm_call_hyp)
+ENTRY(__kvm_call_hyp)
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
hvc #0
ret
-ENDPROC(kvm_call_hyp)
-
-.macro invalid_vector label, target
- .align 2
-\label:
- b \target
-ENDPROC(\label)
-.endm
-
- /* None of these should ever happen */
- invalid_vector el2t_sync_invalid, __kvm_hyp_panic
- invalid_vector el2t_irq_invalid, __kvm_hyp_panic
- invalid_vector el2t_fiq_invalid, __kvm_hyp_panic
- invalid_vector el2t_error_invalid, __kvm_hyp_panic
- invalid_vector el2h_sync_invalid, __kvm_hyp_panic
- invalid_vector el2h_irq_invalid, __kvm_hyp_panic
- invalid_vector el2h_fiq_invalid, __kvm_hyp_panic
- invalid_vector el2h_error_invalid, __kvm_hyp_panic
- invalid_vector el1_sync_invalid, __kvm_hyp_panic
- invalid_vector el1_irq_invalid, __kvm_hyp_panic
- invalid_vector el1_fiq_invalid, __kvm_hyp_panic
- invalid_vector el1_error_invalid, __kvm_hyp_panic
-
-el1_sync: // Guest trapped into EL2
- push x0, x1
- push x2, x3
-
- mrs x1, esr_el2
- lsr x2, x1, #ESR_ELx_EC_SHIFT
-
- cmp x2, #ESR_ELx_EC_HVC64
- b.ne el1_trap
-
- mrs x3, vttbr_el2 // If vttbr is valid, the 64bit guest
- cbnz x3, el1_trap // called HVC
-
- /* Here, we're pretty sure the host called HVC. */
- pop x2, x3
- pop x0, x1
-
- /* Check for __hyp_get_vectors */
- cbnz x0, 1f
- mrs x0, vbar_el2
- b 2f
-
-1: push lr, xzr
-
- /*
- * Compute the function address in EL2, and shuffle the parameters.
- */
- kern_hyp_va x0
- mov lr, x0
- mov x0, x1
- mov x1, x2
- mov x2, x3
- blr lr
-
- pop lr, xzr
-2: eret
-
-el1_trap:
- /*
- * x1: ESR
- * x2: ESR_EC
- */
-
- /* Guest accessed VFP/SIMD registers, save host, restore Guest */
- cmp x2, #ESR_ELx_EC_FP_ASIMD
- b.eq switch_to_guest_fpsimd
-
- cmp x2, #ESR_ELx_EC_DABT_LOW
- mov x0, #ESR_ELx_EC_IABT_LOW
- ccmp x2, x0, #4, ne
- b.ne 1f // Not an abort we care about
-
- /* This is an abort. Check for permission fault */
- and x2, x1, #ESR_ELx_FSC_TYPE
- cmp x2, #FSC_PERM
- b.ne 1f // Not a permission fault
-
- /*
- * Check for Stage-1 page table walk, which is guaranteed
- * to give a valid HPFAR_EL2.
- */
- tbnz x1, #7, 1f // S1PTW is set
-
- /* Preserve PAR_EL1 */
- mrs x3, par_el1
- push x3, xzr
-
- /*
- * Permission fault, HPFAR_EL2 is invalid.
- * Resolve the IPA the hard way using the guest VA.
- * Stage-1 translation already validated the memory access rights.
- * As such, we can use the EL1 translation regime, and don't have
- * to distinguish between EL0 and EL1 access.
- */
- mrs x2, far_el2
- at s1e1r, x2
- isb
-
- /* Read result */
- mrs x3, par_el1
- pop x0, xzr // Restore PAR_EL1 from the stack
- msr par_el1, x0
- tbnz x3, #0, 3f // Bail out if we failed the translation
- ubfx x3, x3, #12, #36 // Extract IPA
- lsl x3, x3, #4 // and present it like HPFAR
- b 2f
-
-1: mrs x3, hpfar_el2
- mrs x2, far_el2
-
-2: mrs x0, tpidr_el2
- str w1, [x0, #VCPU_ESR_EL2]
- str x2, [x0, #VCPU_FAR_EL2]
- str x3, [x0, #VCPU_HPFAR_EL2]
-
- mov x1, #ARM_EXCEPTION_TRAP
- b __kvm_vcpu_return
-
- /*
- * Translation failed. Just return to the guest and
- * let it fault again. Another CPU is probably playing
- * behind our back.
- */
-3: pop x2, x3
- pop x0, x1
-
- eret
-
-el1_irq:
- push x0, x1
- push x2, x3
- mrs x0, tpidr_el2
- mov x1, #ARM_EXCEPTION_IRQ
- b __kvm_vcpu_return
-
- .ltorg
-
- .align 11
-
-ENTRY(__kvm_hyp_vector)
- ventry el2t_sync_invalid // Synchronous EL2t
- ventry el2t_irq_invalid // IRQ EL2t
- ventry el2t_fiq_invalid // FIQ EL2t
- ventry el2t_error_invalid // Error EL2t
-
- ventry el2h_sync_invalid // Synchronous EL2h
- ventry el2h_irq_invalid // IRQ EL2h
- ventry el2h_fiq_invalid // FIQ EL2h
- ventry el2h_error_invalid // Error EL2h
-
- ventry el1_sync // Synchronous 64-bit EL1
- ventry el1_irq // IRQ 64-bit EL1
- ventry el1_fiq_invalid // FIQ 64-bit EL1
- ventry el1_error_invalid // Error 64-bit EL1
-
- ventry el1_sync // Synchronous 32-bit EL1
- ventry el1_irq // IRQ 32-bit EL1
- ventry el1_fiq_invalid // FIQ 32-bit EL1
- ventry el1_error_invalid // Error 32-bit EL1
-ENDPROC(__kvm_hyp_vector)
-
-
-ENTRY(__kvm_get_mdcr_el2)
- mrs x0, mdcr_el2
- ret
-ENDPROC(__kvm_get_mdcr_el2)
-
- .popsection
+alternative_else
+ b __vhe_hyp_call
+ nop
+alternative_endif
+ENDPROC(__kvm_call_hyp)
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
new file mode 100644
index 0000000..b6a8fc5
--- /dev/null
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for Kernel-based Virtual Machine module, HYP part
+#
+
+KVM=../../../../virt/kvm
+
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
+
+obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += entry.o
+obj-$(CONFIG_KVM_ARM_HOST) += switch.o
+obj-$(CONFIG_KVM_ARM_HOST) += fpsimd.o
+obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
+obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
+obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
new file mode 100644
index 0000000..33342a7
--- /dev/null
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 - 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/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+#define read_debug(r,n) read_sysreg(r##n##_el1)
+#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+
+#define save_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: ptr[15] = read_debug(reg, 15); \
+ case 14: ptr[14] = read_debug(reg, 14); \
+ case 13: ptr[13] = read_debug(reg, 13); \
+ case 12: ptr[12] = read_debug(reg, 12); \
+ case 11: ptr[11] = read_debug(reg, 11); \
+ case 10: ptr[10] = read_debug(reg, 10); \
+ case 9: ptr[9] = read_debug(reg, 9); \
+ case 8: ptr[8] = read_debug(reg, 8); \
+ case 7: ptr[7] = read_debug(reg, 7); \
+ case 6: ptr[6] = read_debug(reg, 6); \
+ case 5: ptr[5] = read_debug(reg, 5); \
+ case 4: ptr[4] = read_debug(reg, 4); \
+ case 3: ptr[3] = read_debug(reg, 3); \
+ case 2: ptr[2] = read_debug(reg, 2); \
+ case 1: ptr[1] = read_debug(reg, 1); \
+ default: ptr[0] = read_debug(reg, 0); \
+ }
+
+#define restore_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: write_debug(ptr[15], reg, 15); \
+ case 14: write_debug(ptr[14], reg, 14); \
+ case 13: write_debug(ptr[13], reg, 13); \
+ case 12: write_debug(ptr[12], reg, 12); \
+ case 11: write_debug(ptr[11], reg, 11); \
+ case 10: write_debug(ptr[10], reg, 10); \
+ case 9: write_debug(ptr[9], reg, 9); \
+ case 8: write_debug(ptr[8], reg, 8); \
+ case 7: write_debug(ptr[7], reg, 7); \
+ case 6: write_debug(ptr[6], reg, 6); \
+ case 5: write_debug(ptr[5], reg, 5); \
+ case 4: write_debug(ptr[4], reg, 4); \
+ case 3: write_debug(ptr[3], reg, 3); \
+ case 2: write_debug(ptr[2], reg, 2); \
+ case 1: write_debug(ptr[1], reg, 1); \
+ default: write_debug(ptr[0], reg, 0); \
+ }
+
+void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ save_debug(dbg->dbg_bcr, dbgbcr, brps);
+ save_debug(dbg->dbg_bvr, dbgbvr, brps);
+ save_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ save_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
+}
+
+void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ restore_debug(dbg->dbg_bcr, dbgbcr, brps);
+ restore_debug(dbg->dbg_bvr, dbgbvr, brps);
+ restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+}
+
+void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
+{
+ /* If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
+ * a full save/restore cycle. */
+ if ((vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_KDE) ||
+ (vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_MDE))
+ vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+
+ __debug_save_state(vcpu, &vcpu->arch.host_debug_state,
+ kern_hyp_va(vcpu->arch.host_cpu_context));
+}
+
+void __hyp_text __debug_cond_restore_host_state(struct kvm_vcpu *vcpu)
+{
+ __debug_restore_state(vcpu, &vcpu->arch.host_debug_state,
+ kern_hyp_va(vcpu->arch.host_cpu_context));
+
+ if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
+ vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
+}
+
+static u32 __hyp_text __debug_read_mdcr_el2(void)
+{
+ return read_sysreg(mdcr_el2);
+}
+
+__alias(__debug_read_mdcr_el2) u32 __kvm_get_mdcr_el2(void);
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
new file mode 100644
index 0000000..ce9e5e5
--- /dev/null
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015 - 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/linkage.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/fpsimdmacros.h>
+#include <asm/kvm.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmu.h>
+
+#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x)
+#define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+.macro save_callee_saved_regs ctxt
+ stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
+ stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
+ stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
+ stp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
+ stp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
+ stp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)]
+.endm
+
+.macro restore_callee_saved_regs ctxt
+ ldp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
+ ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
+ ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
+ ldp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
+ ldp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
+ ldp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)]
+.endm
+
+/*
+ * u64 __guest_enter(struct kvm_vcpu *vcpu,
+ * struct kvm_cpu_context *host_ctxt);
+ */
+ENTRY(__guest_enter)
+ // x0: vcpu
+ // x1: host/guest context
+ // x2-x18: clobbered by macros
+
+ // Store the host regs
+ save_callee_saved_regs x1
+
+ // Preserve vcpu & host_ctxt for use at exit time
+ stp x0, x1, [sp, #-16]!
+
+ add x1, x0, #VCPU_CONTEXT
+
+ // Prepare x0-x1 for later restore by pushing them onto the stack
+ ldp x2, x3, [x1, #CPU_XREG_OFFSET(0)]
+ stp x2, x3, [sp, #-16]!
+
+ // x2-x18
+ ldp x2, x3, [x1, #CPU_XREG_OFFSET(2)]
+ ldp x4, x5, [x1, #CPU_XREG_OFFSET(4)]
+ ldp x6, x7, [x1, #CPU_XREG_OFFSET(6)]
+ ldp x8, x9, [x1, #CPU_XREG_OFFSET(8)]
+ ldp x10, x11, [x1, #CPU_XREG_OFFSET(10)]
+ ldp x12, x13, [x1, #CPU_XREG_OFFSET(12)]
+ ldp x14, x15, [x1, #CPU_XREG_OFFSET(14)]
+ ldp x16, x17, [x1, #CPU_XREG_OFFSET(16)]
+ ldr x18, [x1, #CPU_XREG_OFFSET(18)]
+
+ // x19-x29, lr
+ restore_callee_saved_regs x1
+
+ // Last bits of the 64bit state
+ ldp x0, x1, [sp], #16
+
+ // Do not touch any register after this!
+ eret
+ENDPROC(__guest_enter)
+
+ENTRY(__guest_exit)
+ // x0: vcpu
+ // x1: return code
+ // x2-x3: free
+ // x4-x29,lr: vcpu regs
+ // vcpu x0-x3 on the stack
+
+ add x2, x0, #VCPU_CONTEXT
+
+ stp x4, x5, [x2, #CPU_XREG_OFFSET(4)]
+ stp x6, x7, [x2, #CPU_XREG_OFFSET(6)]
+ stp x8, x9, [x2, #CPU_XREG_OFFSET(8)]
+ stp x10, x11, [x2, #CPU_XREG_OFFSET(10)]
+ stp x12, x13, [x2, #CPU_XREG_OFFSET(12)]
+ stp x14, x15, [x2, #CPU_XREG_OFFSET(14)]
+ stp x16, x17, [x2, #CPU_XREG_OFFSET(16)]
+ str x18, [x2, #CPU_XREG_OFFSET(18)]
+
+ ldp x6, x7, [sp], #16 // x2, x3
+ ldp x4, x5, [sp], #16 // x0, x1
+
+ stp x4, x5, [x2, #CPU_XREG_OFFSET(0)]
+ stp x6, x7, [x2, #CPU_XREG_OFFSET(2)]
+
+ save_callee_saved_regs x2
+
+ // Restore vcpu & host_ctxt from the stack
+ // (preserving return code in x1)
+ ldp x0, x2, [sp], #16
+ // Now restore the host regs
+ restore_callee_saved_regs x2
+
+ mov x0, x1
+ ret
+ENDPROC(__guest_exit)
+
+ENTRY(__fpsimd_guest_restore)
+ stp x4, lr, [sp, #-16]!
+
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
+ mrs x2, cptr_el2
+ bic x2, x2, #CPTR_EL2_TFP
+ msr cptr_el2, x2
+alternative_else
+ mrs x2, cpacr_el1
+ orr x2, x2, #CPACR_EL1_FPEN
+ msr cpacr_el1, x2
+alternative_endif
+ isb
+
+ mrs x3, tpidr_el2
+
+ ldr x0, [x3, #VCPU_HOST_CONTEXT]
+ kern_hyp_va x0
+ add x0, x0, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+ bl __fpsimd_save_state
+
+ add x2, x3, #VCPU_CONTEXT
+ add x0, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+ bl __fpsimd_restore_state
+
+ // Skip restoring fpexc32 for AArch64 guests
+ mrs x1, hcr_el2
+ tbnz x1, #HCR_RW_SHIFT, 1f
+ ldr x4, [x3, #VCPU_FPEXC32_EL2]
+ msr fpexc32_el2, x4
+1:
+ ldp x4, lr, [sp], #16
+ ldp x2, x3, [sp], #16
+ ldp x0, x1, [sp], #16
+
+ eret
+ENDPROC(__fpsimd_guest_restore)
diff --git a/arch/arm64/kvm/hyp/fpsimd.S b/arch/arm64/kvm/hyp/fpsimd.S
new file mode 100644
index 0000000..da3f22c
--- /dev/null
+++ b/arch/arm64/kvm/hyp/fpsimd.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 - 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/linkage.h>
+
+#include <asm/fpsimdmacros.h>
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+ENTRY(__fpsimd_save_state)
+ fpsimd_save x0, 1
+ ret
+ENDPROC(__fpsimd_save_state)
+
+ENTRY(__fpsimd_restore_state)
+ fpsimd_restore x0, 1
+ ret
+ENDPROC(__fpsimd_restore_state)
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
new file mode 100644
index 0000000..3488894
--- /dev/null
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 - 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/linkage.h>
+
+#include <asm/alternative.h>
+#include <asm/assembler.h>
+#include <asm/cpufeature.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmu.h>
+
+ .text
+ .pushsection .hyp.text, "ax"
+
+.macro save_x0_to_x3
+ stp x0, x1, [sp, #-16]!
+ stp x2, x3, [sp, #-16]!
+.endm
+
+.macro restore_x0_to_x3
+ ldp x2, x3, [sp], #16
+ ldp x0, x1, [sp], #16
+.endm
+
+.macro do_el2_call
+ /*
+ * Shuffle the parameters before calling the function
+ * pointed to in x0. Assumes parameters in x[1,2,3].
+ */
+ sub sp, sp, #16
+ str lr, [sp]
+ mov lr, x0
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ blr lr
+ ldr lr, [sp]
+ add sp, sp, #16
+.endm
+
+ENTRY(__vhe_hyp_call)
+ do_el2_call
+ /*
+ * We used to rely on having an exception return to get
+ * an implicit isb. In the E2H case, we don't have it anymore.
+ * rather than changing all the leaf functions, just do it here
+ * before returning to the rest of the kernel.
+ */
+ isb
+ ret
+ENDPROC(__vhe_hyp_call)
+
+el1_sync: // Guest trapped into EL2
+ save_x0_to_x3
+
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
+ mrs x1, esr_el2
+alternative_else
+ mrs x1, esr_el1
+alternative_endif
+ lsr x2, x1, #ESR_ELx_EC_SHIFT
+
+ cmp x2, #ESR_ELx_EC_HVC64
+ b.ne el1_trap
+
+ mrs x3, vttbr_el2 // If vttbr is valid, the 64bit guest
+ cbnz x3, el1_trap // called HVC
+
+ /* Here, we're pretty sure the host called HVC. */
+ restore_x0_to_x3
+
+ /* Check for __hyp_get_vectors */
+ cbnz x0, 1f
+ mrs x0, vbar_el2
+ b 2f
+
+1:
+ /*
+ * Perform the EL2 call
+ */
+ kern_hyp_va x0
+ do_el2_call
+
+2: eret
+
+el1_trap:
+ /*
+ * x1: ESR
+ * x2: ESR_EC
+ */
+
+ /* Guest accessed VFP/SIMD registers, save host, restore Guest */
+ cmp x2, #ESR_ELx_EC_FP_ASIMD
+ b.eq __fpsimd_guest_restore
+
+ mrs x0, tpidr_el2
+ mov x1, #ARM_EXCEPTION_TRAP
+ b __guest_exit
+
+el1_irq:
+ save_x0_to_x3
+ mrs x0, tpidr_el2
+ mov x1, #ARM_EXCEPTION_IRQ
+ b __guest_exit
+
+ENTRY(__hyp_do_panic)
+ mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
+ PSR_MODE_EL1h)
+ msr spsr_el2, lr
+ ldr lr, =panic
+ msr elr_el2, lr
+ eret
+ENDPROC(__hyp_do_panic)
+
+.macro invalid_vector label, target = __hyp_panic
+ .align 2
+\label:
+ b \target
+ENDPROC(\label)
+.endm
+
+ /* None of these should ever happen */
+ invalid_vector el2t_sync_invalid
+ invalid_vector el2t_irq_invalid
+ invalid_vector el2t_fiq_invalid
+ invalid_vector el2t_error_invalid
+ invalid_vector el2h_sync_invalid
+ invalid_vector el2h_irq_invalid
+ invalid_vector el2h_fiq_invalid
+ invalid_vector el2h_error_invalid
+ invalid_vector el1_sync_invalid
+ invalid_vector el1_irq_invalid
+ invalid_vector el1_fiq_invalid
+ invalid_vector el1_error_invalid
+
+ .ltorg
+
+ .align 11
+
+ENTRY(__kvm_hyp_vector)
+ ventry el2t_sync_invalid // Synchronous EL2t
+ ventry el2t_irq_invalid // IRQ EL2t
+ ventry el2t_fiq_invalid // FIQ EL2t
+ ventry el2t_error_invalid // Error EL2t
+
+ ventry el2h_sync_invalid // Synchronous EL2h
+ ventry el2h_irq_invalid // IRQ EL2h
+ ventry el2h_fiq_invalid // FIQ EL2h
+ ventry el2h_error_invalid // Error EL2h
+
+ ventry el1_sync // Synchronous 64-bit EL1
+ ventry el1_irq // IRQ 64-bit EL1
+ ventry el1_fiq_invalid // FIQ 64-bit EL1
+ ventry el1_error_invalid // Error 64-bit EL1
+
+ ventry el1_sync // Synchronous 32-bit EL1
+ ventry el1_irq // IRQ 32-bit EL1
+ ventry el1_fiq_invalid // FIQ 32-bit EL1
+ ventry el1_error_invalid // Error 32-bit EL1
+ENDPROC(__kvm_hyp_vector)
diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c
new file mode 100644
index 0000000..bfc54fd
--- /dev/null
+++ b/arch/arm64/kvm/hyp/s2-setup.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 - 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/types.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+void __hyp_text __init_stage2_translation(void)
+{
+ u64 val = VTCR_EL2_FLAGS;
+ u64 tmp;
+
+ /*
+ * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS
+ * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while
+ * PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2...
+ */
+ val |= (read_sysreg(id_aa64mmfr0_el1) & 7) << 16;
+
+ /*
+ * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS
+ * bit in VTCR_EL2.
+ */
+ tmp = (read_sysreg(id_aa64mmfr1_el1) >> 4) & 0xf;
+ val |= (tmp == 2) ? VTCR_EL2_VS : 0;
+
+ write_sysreg(val, vtcr_el2);
+}
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
new file mode 100644
index 0000000..437cfad
--- /dev/null
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2015 - 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/types.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+static bool __hyp_text __fpsimd_enabled_nvhe(void)
+{
+ return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP);
+}
+
+static bool __hyp_text __fpsimd_enabled_vhe(void)
+{
+ return !!(read_sysreg(cpacr_el1) & CPACR_EL1_FPEN);
+}
+
+static hyp_alternate_select(__fpsimd_is_enabled,
+ __fpsimd_enabled_nvhe, __fpsimd_enabled_vhe,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+bool __hyp_text __fpsimd_enabled(void)
+{
+ return __fpsimd_is_enabled()();
+}
+
+static void __hyp_text __activate_traps_vhe(void)
+{
+ u64 val;
+
+ val = read_sysreg(cpacr_el1);
+ val |= CPACR_EL1_TTA;
+ val &= ~CPACR_EL1_FPEN;
+ write_sysreg(val, cpacr_el1);
+
+ write_sysreg(__kvm_hyp_vector, vbar_el1);
+}
+
+static void __hyp_text __activate_traps_nvhe(void)
+{
+ u64 val;
+
+ val = CPTR_EL2_DEFAULT;
+ val |= CPTR_EL2_TTA | CPTR_EL2_TFP;
+ write_sysreg(val, cptr_el2);
+}
+
+static hyp_alternate_select(__activate_traps_arch,
+ __activate_traps_nvhe, __activate_traps_vhe,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
+{
+ u64 val;
+
+ /*
+ * We are about to set CPTR_EL2.TFP to trap all floating point
+ * register accesses to EL2, however, the ARM ARM clearly states that
+ * traps are only taken to EL2 if the operation would not otherwise
+ * trap to EL1. Therefore, always make sure that for 32-bit guests,
+ * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
+ */
+ val = vcpu->arch.hcr_el2;
+ if (!(val & HCR_RW)) {
+ write_sysreg(1 << 30, fpexc32_el2);
+ isb();
+ }
+ write_sysreg(val, hcr_el2);
+ /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
+ write_sysreg(1 << 15, hstr_el2);
+ /* Make sure we trap PMU access from EL0 to EL2 */
+ write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
+ write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+ __activate_traps_arch()();
+}
+
+static void __hyp_text __deactivate_traps_vhe(void)
+{
+ extern char vectors[]; /* kernel exception vectors */
+
+ write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
+ write_sysreg(CPACR_EL1_FPEN, cpacr_el1);
+ write_sysreg(vectors, vbar_el1);
+}
+
+static void __hyp_text __deactivate_traps_nvhe(void)
+{
+ write_sysreg(HCR_RW, hcr_el2);
+ write_sysreg(CPTR_EL2_DEFAULT, cptr_el2);
+}
+
+static hyp_alternate_select(__deactivate_traps_arch,
+ __deactivate_traps_nvhe, __deactivate_traps_vhe,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
+{
+ __deactivate_traps_arch()();
+ write_sysreg(0, hstr_el2);
+ write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2);
+ write_sysreg(0, pmuserenr_el0);
+}
+
+static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = kern_hyp_va(vcpu->kvm);
+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
+}
+
+static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
+{
+ write_sysreg(0, vttbr_el2);
+}
+
+static hyp_alternate_select(__vgic_call_save_state,
+ __vgic_v2_save_state, __vgic_v3_save_state,
+ ARM64_HAS_SYSREG_GIC_CPUIF);
+
+static hyp_alternate_select(__vgic_call_restore_state,
+ __vgic_v2_restore_state, __vgic_v3_restore_state,
+ ARM64_HAS_SYSREG_GIC_CPUIF);
+
+static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
+{
+ __vgic_call_save_state()(vcpu);
+ write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
+}
+
+static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
+{
+ u64 val;
+
+ val = read_sysreg(hcr_el2);
+ val |= HCR_INT_OVERRIDE;
+ val |= vcpu->arch.irq_lines;
+ write_sysreg(val, hcr_el2);
+
+ __vgic_call_restore_state()(vcpu);
+}
+
+static bool __hyp_text __true_value(void)
+{
+ return true;
+}
+
+static bool __hyp_text __false_value(void)
+{
+ return false;
+}
+
+static hyp_alternate_select(__check_arm_834220,
+ __false_value, __true_value,
+ ARM64_WORKAROUND_834220);
+
+static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
+{
+ u64 par, tmp;
+
+ /*
+ * Resolve the IPA the hard way using the guest VA.
+ *
+ * Stage-1 translation already validated the memory access
+ * rights. As such, we can use the EL1 translation regime, and
+ * don't have to distinguish between EL0 and EL1 access.
+ *
+ * We do need to save/restore PAR_EL1 though, as we haven't
+ * saved the guest context yet, and we may return early...
+ */
+ par = read_sysreg(par_el1);
+ asm volatile("at s1e1r, %0" : : "r" (far));
+ isb();
+
+ tmp = read_sysreg(par_el1);
+ write_sysreg(par, par_el1);
+
+ if (unlikely(tmp & 1))
+ return false; /* Translation failed, back to guest */
+
+ /* Convert PAR to HPFAR format */
+ *hpfar = ((tmp >> 12) & ((1UL << 36) - 1)) << 4;
+ return true;
+}
+
+static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
+{
+ u64 esr = read_sysreg_el2(esr);
+ u8 ec = esr >> ESR_ELx_EC_SHIFT;
+ u64 hpfar, far;
+
+ vcpu->arch.fault.esr_el2 = esr;
+
+ if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
+ return true;
+
+ far = read_sysreg_el2(far);
+
+ /*
+ * The HPFAR can be invalid if the stage 2 fault did not
+ * happen during a stage 1 page table walk (the ESR_EL2.S1PTW
+ * bit is clear) and one of the two following cases are true:
+ * 1. The fault was due to a permission fault
+ * 2. The processor carries errata 834220
+ *
+ * Therefore, for all non S1PTW faults where we either have a
+ * permission fault or the errata workaround is enabled, we
+ * resolve the IPA using the AT instruction.
+ */
+ if (!(esr & ESR_ELx_S1PTW) &&
+ (__check_arm_834220()() || (esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) {
+ if (!__translate_far_to_hpfar(far, &hpfar))
+ return false;
+ } else {
+ hpfar = read_sysreg(hpfar_el2);
+ }
+
+ vcpu->arch.fault.far_el2 = far;
+ vcpu->arch.fault.hpfar_el2 = hpfar;
+ return true;
+}
+
+static int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ bool fp_enabled;
+ u64 exit_code;
+
+ vcpu = kern_hyp_va(vcpu);
+ write_sysreg(vcpu, tpidr_el2);
+
+ host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ guest_ctxt = &vcpu->arch.ctxt;
+
+ __sysreg_save_host_state(host_ctxt);
+ __debug_cond_save_host_state(vcpu);
+
+ __activate_traps(vcpu);
+ __activate_vm(vcpu);
+
+ __vgic_restore_state(vcpu);
+ __timer_restore_state(vcpu);
+
+ /*
+ * We must restore the 32-bit state before the sysregs, thanks
+ * to Cortex-A57 erratum #852523.
+ */
+ __sysreg32_restore_state(vcpu);
+ __sysreg_restore_guest_state(guest_ctxt);
+ __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
+
+ /* Jump in the fire! */
+again:
+ exit_code = __guest_enter(vcpu, host_ctxt);
+ /* And we're baaack! */
+
+ if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
+ goto again;
+
+ fp_enabled = __fpsimd_enabled();
+
+ __sysreg_save_guest_state(guest_ctxt);
+ __sysreg32_save_state(vcpu);
+ __timer_save_state(vcpu);
+ __vgic_save_state(vcpu);
+
+ __deactivate_traps(vcpu);
+ __deactivate_vm(vcpu);
+
+ __sysreg_restore_host_state(host_ctxt);
+
+ if (fp_enabled) {
+ __fpsimd_save_state(&guest_ctxt->gp_regs.fp_regs);
+ __fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs);
+ }
+
+ __debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
+ __debug_cond_restore_host_state(vcpu);
+
+ return exit_code;
+}
+
+__alias(__guest_run) int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+
+static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
+
+static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par)
+{
+ unsigned long str_va = (unsigned long)__hyp_panic_string;
+
+ __hyp_do_panic(hyp_kern_va(str_va),
+ spsr, elr,
+ read_sysreg(esr_el2), read_sysreg_el2(far),
+ read_sysreg(hpfar_el2), par,
+ (void *)read_sysreg(tpidr_el2));
+}
+
+static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par)
+{
+ panic(__hyp_panic_string,
+ spsr, elr,
+ read_sysreg_el2(esr), read_sysreg_el2(far),
+ read_sysreg(hpfar_el2), par,
+ (void *)read_sysreg(tpidr_el2));
+}
+
+static hyp_alternate_select(__hyp_call_panic,
+ __hyp_call_panic_nvhe, __hyp_call_panic_vhe,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+void __hyp_text __noreturn __hyp_panic(void)
+{
+ u64 spsr = read_sysreg_el2(spsr);
+ u64 elr = read_sysreg_el2(elr);
+ u64 par = read_sysreg(par_el1);
+
+ if (read_sysreg(vttbr_el2)) {
+ struct kvm_vcpu *vcpu;
+ struct kvm_cpu_context *host_ctxt;
+
+ vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2);
+ host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ __deactivate_traps(vcpu);
+ __deactivate_vm(vcpu);
+ __sysreg_restore_host_state(host_ctxt);
+ }
+
+ /* Call panic for real */
+ __hyp_call_panic()(spsr, elr, par);
+
+ unreachable();
+}
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
new file mode 100644
index 0000000..0f7c40e
--- /dev/null
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2012-2015 - 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/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+
+/* Yes, this does nothing, on purpose */
+static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { }
+
+/*
+ * Non-VHE: Both host and guest must save everything.
+ *
+ * VHE: Host must save tpidr*_el[01], actlr_el1, sp0, pc, pstate, and
+ * guest must save everything.
+ */
+
+static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
+{
+ ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1);
+ ctxt->sys_regs[TPIDR_EL0] = read_sysreg(tpidr_el0);
+ ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0);
+ ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1);
+ ctxt->gp_regs.regs.sp = read_sysreg(sp_el0);
+ ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
+ ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
+}
+
+static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
+{
+ ctxt->sys_regs[MPIDR_EL1] = read_sysreg(vmpidr_el2);
+ ctxt->sys_regs[CSSELR_EL1] = read_sysreg(csselr_el1);
+ ctxt->sys_regs[SCTLR_EL1] = read_sysreg_el1(sctlr);
+ ctxt->sys_regs[CPACR_EL1] = read_sysreg_el1(cpacr);
+ ctxt->sys_regs[TTBR0_EL1] = read_sysreg_el1(ttbr0);
+ ctxt->sys_regs[TTBR1_EL1] = read_sysreg_el1(ttbr1);
+ ctxt->sys_regs[TCR_EL1] = read_sysreg_el1(tcr);
+ ctxt->sys_regs[ESR_EL1] = read_sysreg_el1(esr);
+ ctxt->sys_regs[AFSR0_EL1] = read_sysreg_el1(afsr0);
+ ctxt->sys_regs[AFSR1_EL1] = read_sysreg_el1(afsr1);
+ ctxt->sys_regs[FAR_EL1] = read_sysreg_el1(far);
+ ctxt->sys_regs[MAIR_EL1] = read_sysreg_el1(mair);
+ ctxt->sys_regs[VBAR_EL1] = read_sysreg_el1(vbar);
+ ctxt->sys_regs[CONTEXTIDR_EL1] = read_sysreg_el1(contextidr);
+ ctxt->sys_regs[AMAIR_EL1] = read_sysreg_el1(amair);
+ ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl);
+ ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1);
+ ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1);
+
+ ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1);
+ ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
+ ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
+}
+
+static hyp_alternate_select(__sysreg_call_save_host_state,
+ __sysreg_save_state, __sysreg_do_nothing,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+void __hyp_text __sysreg_save_host_state(struct kvm_cpu_context *ctxt)
+{
+ __sysreg_call_save_host_state()(ctxt);
+ __sysreg_save_common_state(ctxt);
+}
+
+void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt)
+{
+ __sysreg_save_state(ctxt);
+ __sysreg_save_common_state(ctxt);
+}
+
+static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt)
+{
+ write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1);
+ write_sysreg(ctxt->sys_regs[TPIDR_EL0], tpidr_el0);
+ write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
+ write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1);
+ write_sysreg(ctxt->gp_regs.regs.sp, sp_el0);
+ write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
+ write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
+}
+
+static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
+{
+ write_sysreg(ctxt->sys_regs[MPIDR_EL1], vmpidr_el2);
+ write_sysreg(ctxt->sys_regs[CSSELR_EL1], csselr_el1);
+ write_sysreg_el1(ctxt->sys_regs[SCTLR_EL1], sctlr);
+ write_sysreg_el1(ctxt->sys_regs[CPACR_EL1], cpacr);
+ write_sysreg_el1(ctxt->sys_regs[TTBR0_EL1], ttbr0);
+ write_sysreg_el1(ctxt->sys_regs[TTBR1_EL1], ttbr1);
+ write_sysreg_el1(ctxt->sys_regs[TCR_EL1], tcr);
+ write_sysreg_el1(ctxt->sys_regs[ESR_EL1], esr);
+ write_sysreg_el1(ctxt->sys_regs[AFSR0_EL1], afsr0);
+ write_sysreg_el1(ctxt->sys_regs[AFSR1_EL1], afsr1);
+ write_sysreg_el1(ctxt->sys_regs[FAR_EL1], far);
+ write_sysreg_el1(ctxt->sys_regs[MAIR_EL1], mair);
+ write_sysreg_el1(ctxt->sys_regs[VBAR_EL1], vbar);
+ write_sysreg_el1(ctxt->sys_regs[CONTEXTIDR_EL1],contextidr);
+ write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1], amair);
+ write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl);
+ write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1);
+ write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1);
+
+ write_sysreg(ctxt->gp_regs.sp_el1, sp_el1);
+ write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
+ write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
+}
+
+static hyp_alternate_select(__sysreg_call_restore_host_state,
+ __sysreg_restore_state, __sysreg_do_nothing,
+ ARM64_HAS_VIRT_HOST_EXTN);
+
+void __hyp_text __sysreg_restore_host_state(struct kvm_cpu_context *ctxt)
+{
+ __sysreg_call_restore_host_state()(ctxt);
+ __sysreg_restore_common_state(ctxt);
+}
+
+void __hyp_text __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt)
+{
+ __sysreg_restore_state(ctxt);
+ __sysreg_restore_common_state(ctxt);
+}
+
+void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
+{
+ u64 *spsr, *sysreg;
+
+ if (read_sysreg(hcr_el2) & HCR_RW)
+ return;
+
+ spsr = vcpu->arch.ctxt.gp_regs.spsr;
+ sysreg = vcpu->arch.ctxt.sys_regs;
+
+ spsr[KVM_SPSR_ABT] = read_sysreg(spsr_abt);
+ spsr[KVM_SPSR_UND] = read_sysreg(spsr_und);
+ spsr[KVM_SPSR_IRQ] = read_sysreg(spsr_irq);
+ spsr[KVM_SPSR_FIQ] = read_sysreg(spsr_fiq);
+
+ sysreg[DACR32_EL2] = read_sysreg(dacr32_el2);
+ sysreg[IFSR32_EL2] = read_sysreg(ifsr32_el2);
+
+ if (__fpsimd_enabled())
+ sysreg[FPEXC32_EL2] = read_sysreg(fpexc32_el2);
+
+ if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
+ sysreg[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
+}
+
+void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
+{
+ u64 *spsr, *sysreg;
+
+ if (read_sysreg(hcr_el2) & HCR_RW)
+ return;
+
+ spsr = vcpu->arch.ctxt.gp_regs.spsr;
+ sysreg = vcpu->arch.ctxt.sys_regs;
+
+ write_sysreg(spsr[KVM_SPSR_ABT], spsr_abt);
+ write_sysreg(spsr[KVM_SPSR_UND], spsr_und);
+ write_sysreg(spsr[KVM_SPSR_IRQ], spsr_irq);
+ write_sysreg(spsr[KVM_SPSR_FIQ], spsr_fiq);
+
+ write_sysreg(sysreg[DACR32_EL2], dacr32_el2);
+ write_sysreg(sysreg[IFSR32_EL2], ifsr32_el2);
+
+ if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
+ write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
+}
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
new file mode 100644
index 0000000..be8177c
--- /dev/null
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 - 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 <asm/kvm_hyp.h>
+
+static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
+{
+ dsb(ishst);
+
+ /* Switch to requested VMID */
+ kvm = kern_hyp_va(kvm);
+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
+ isb();
+
+ /*
+ * We could do so much better if we had the VA as well.
+ * Instead, we invalidate Stage-2 for this IPA, and the
+ * whole of Stage-1. Weep...
+ */
+ ipa >>= 12;
+ asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
+
+ /*
+ * We have to ensure completion of the invalidation at Stage-2,
+ * since a table walk on another CPU could refill a TLB with a
+ * complete (S1 + S2) walk based on the old Stage-2 mapping if
+ * the Stage-1 invalidation happened first.
+ */
+ dsb(ish);
+ asm volatile("tlbi vmalle1is" : : );
+ dsb(ish);
+ isb();
+
+ write_sysreg(0, vttbr_el2);
+}
+
+__alias(__tlb_flush_vmid_ipa) void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm,
+ phys_addr_t ipa);
+
+static void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
+{
+ dsb(ishst);
+
+ /* Switch to requested VMID */
+ kvm = kern_hyp_va(kvm);
+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
+ isb();
+
+ asm volatile("tlbi vmalls12e1is" : : );
+ dsb(ish);
+ isb();
+
+ write_sysreg(0, vttbr_el2);
+}
+
+__alias(__tlb_flush_vmid) void __kvm_tlb_flush_vmid(struct kvm *kvm);
+
+static void __hyp_text __tlb_flush_vm_context(void)
+{
+ dsb(ishst);
+ asm volatile("tlbi alle1is \n"
+ "ic ialluis ": : );
+ dsb(ish);
+}
+
+__alias(__tlb_flush_vm_context) void __kvm_flush_vm_context(void);
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
new file mode 100644
index 0000000..fff7cd4
--- /dev/null
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2012-2015 - 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/compiler.h>
+#include <linux/irqchip/arm-gic-v3.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_hyp.h>
+
+#define vtr_to_max_lr_idx(v) ((v) & 0xf)
+#define vtr_to_nr_pri_bits(v) (((u32)(v) >> 29) + 1)
+
+#define read_gicreg(r) \
+ ({ \
+ u64 reg; \
+ asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
+ reg; \
+ })
+
+#define write_gicreg(v,r) \
+ do { \
+ u64 __val = (v); \
+ asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
+ } while (0)
+
+static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
+{
+ switch (lr & 0xf) {
+ case 0:
+ return read_gicreg(ICH_LR0_EL2);
+ case 1:
+ return read_gicreg(ICH_LR1_EL2);
+ case 2:
+ return read_gicreg(ICH_LR2_EL2);
+ case 3:
+ return read_gicreg(ICH_LR3_EL2);
+ case 4:
+ return read_gicreg(ICH_LR4_EL2);
+ case 5:
+ return read_gicreg(ICH_LR5_EL2);
+ case 6:
+ return read_gicreg(ICH_LR6_EL2);
+ case 7:
+ return read_gicreg(ICH_LR7_EL2);
+ case 8:
+ return read_gicreg(ICH_LR8_EL2);
+ case 9:
+ return read_gicreg(ICH_LR9_EL2);
+ case 10:
+ return read_gicreg(ICH_LR10_EL2);
+ case 11:
+ return read_gicreg(ICH_LR11_EL2);
+ case 12:
+ return read_gicreg(ICH_LR12_EL2);
+ case 13:
+ return read_gicreg(ICH_LR13_EL2);
+ case 14:
+ return read_gicreg(ICH_LR14_EL2);
+ case 15:
+ return read_gicreg(ICH_LR15_EL2);
+ }
+
+ unreachable();
+}
+
+static void __hyp_text __gic_v3_set_lr(u64 val, int lr)
+{
+ switch (lr & 0xf) {
+ case 0:
+ write_gicreg(val, ICH_LR0_EL2);
+ break;
+ case 1:
+ write_gicreg(val, ICH_LR1_EL2);
+ break;
+ case 2:
+ write_gicreg(val, ICH_LR2_EL2);
+ break;
+ case 3:
+ write_gicreg(val, ICH_LR3_EL2);
+ break;
+ case 4:
+ write_gicreg(val, ICH_LR4_EL2);
+ break;
+ case 5:
+ write_gicreg(val, ICH_LR5_EL2);
+ break;
+ case 6:
+ write_gicreg(val, ICH_LR6_EL2);
+ break;
+ case 7:
+ write_gicreg(val, ICH_LR7_EL2);
+ break;
+ case 8:
+ write_gicreg(val, ICH_LR8_EL2);
+ break;
+ case 9:
+ write_gicreg(val, ICH_LR9_EL2);
+ break;
+ case 10:
+ write_gicreg(val, ICH_LR10_EL2);
+ break;
+ case 11:
+ write_gicreg(val, ICH_LR11_EL2);
+ break;
+ case 12:
+ write_gicreg(val, ICH_LR12_EL2);
+ break;
+ case 13:
+ write_gicreg(val, ICH_LR13_EL2);
+ break;
+ case 14:
+ write_gicreg(val, ICH_LR14_EL2);
+ break;
+ case 15:
+ write_gicreg(val, ICH_LR15_EL2);
+ break;
+ }
+}
+
+static void __hyp_text save_maint_int_state(struct kvm_vcpu *vcpu, int nr_lr)
+{
+ struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+ int i;
+ bool expect_mi;
+
+ expect_mi = !!(cpu_if->vgic_hcr & ICH_HCR_UIE);
+
+ for (i = 0; i < nr_lr; i++) {
+ if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
+ continue;
+
+ expect_mi |= (!(cpu_if->vgic_lr[i] & ICH_LR_HW) &&
+ (cpu_if->vgic_lr[i] & ICH_LR_EOI));
+ }
+
+ if (expect_mi) {
+ cpu_if->vgic_misr = read_gicreg(ICH_MISR_EL2);
+
+ if (cpu_if->vgic_misr & ICH_MISR_EOI)
+ cpu_if->vgic_eisr = read_gicreg(ICH_EISR_EL2);
+ else
+ cpu_if->vgic_eisr = 0;
+ } else {
+ cpu_if->vgic_misr = 0;
+ cpu_if->vgic_eisr = 0;
+ }
+}
+
+void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
+{
+ struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+ u64 val;
+
+ /*
+ * Make sure stores to the GIC via the memory mapped interface
+ * are now visible to the system register interface.
+ */
+ dsb(st);
+
+ cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
+
+ if (vcpu->arch.vgic_cpu.live_lrs) {
+ int i;
+ u32 max_lr_idx, nr_pri_bits;
+
+ cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2);
+
+ write_gicreg(0, ICH_HCR_EL2);
+ val = read_gicreg(ICH_VTR_EL2);
+ max_lr_idx = vtr_to_max_lr_idx(val);
+ nr_pri_bits = vtr_to_nr_pri_bits(val);
+
+ save_maint_int_state(vcpu, max_lr_idx + 1);
+
+ for (i = 0; i <= max_lr_idx; i++) {
+ if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
+ continue;
+
+ if (cpu_if->vgic_elrsr & (1 << i)) {
+ cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
+ continue;
+ }
+
+ cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
+ __gic_v3_set_lr(0, i);
+ }
+
+ switch (nr_pri_bits) {
+ case 7:
+ cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2);
+ cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2);
+ case 6:
+ cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2);
+ default:
+ cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2);
+ }
+
+ switch (nr_pri_bits) {
+ case 7:
+ cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2);
+ cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2);
+ case 6:
+ cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2);
+ default:
+ cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2);
+ }
+
+ vcpu->arch.vgic_cpu.live_lrs = 0;
+ } else {
+ cpu_if->vgic_misr = 0;
+ cpu_if->vgic_eisr = 0;
+ cpu_if->vgic_elrsr = 0xffff;
+ cpu_if->vgic_ap0r[0] = 0;
+ cpu_if->vgic_ap0r[1] = 0;
+ cpu_if->vgic_ap0r[2] = 0;
+ cpu_if->vgic_ap0r[3] = 0;
+ cpu_if->vgic_ap1r[0] = 0;
+ cpu_if->vgic_ap1r[1] = 0;
+ cpu_if->vgic_ap1r[2] = 0;
+ cpu_if->vgic_ap1r[3] = 0;
+ }
+
+ val = read_gicreg(ICC_SRE_EL2);
+ write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
+ isb(); /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
+ write_gicreg(1, ICC_SRE_EL1);
+}
+
+void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
+{
+ struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+ u64 val;
+ u32 max_lr_idx, nr_pri_bits;
+ u16 live_lrs = 0;
+ int i;
+
+ /*
+ * VFIQEn is RES1 if ICC_SRE_EL1.SRE is 1. This causes a
+ * Group0 interrupt (as generated in GICv2 mode) to be
+ * delivered as a FIQ to the guest, with potentially fatal
+ * consequences. So we must make sure that ICC_SRE_EL1 has
+ * been actually programmed with the value we want before
+ * starting to mess with the rest of the GIC.
+ */
+ write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1);
+ isb();
+
+ val = read_gicreg(ICH_VTR_EL2);
+ max_lr_idx = vtr_to_max_lr_idx(val);
+ nr_pri_bits = vtr_to_nr_pri_bits(val);
+
+ for (i = 0; i <= max_lr_idx; i++) {
+ if (cpu_if->vgic_lr[i] & ICH_LR_STATE)
+ live_lrs |= (1 << i);
+ }
+
+ write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2);
+
+ if (live_lrs) {
+ write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
+
+ switch (nr_pri_bits) {
+ case 7:
+ write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2);
+ write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2);
+ case 6:
+ write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2);
+ default:
+ write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2);
+ }
+
+ switch (nr_pri_bits) {
+ case 7:
+ write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2);
+ write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);
+ case 6:
+ write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2);
+ default:
+ write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2);
+ }
+
+ for (i = 0; i <= max_lr_idx; i++) {
+ if (!(live_lrs & (1 << i)))
+ continue;
+
+ __gic_v3_set_lr(cpu_if->vgic_lr[i], i);
+ }
+ }
+
+ /*
+ * Ensures that the above will have reached the
+ * (re)distributors. This ensure the guest will read the
+ * correct values from the memory-mapped interface.
+ */
+ isb();
+ dsb(sy);
+ vcpu->arch.vgic_cpu.live_lrs = live_lrs;
+
+ /*
+ * Prevent the guest from touching the GIC system registers if
+ * SRE isn't enabled for GICv3 emulation.
+ */
+ if (!cpu_if->vgic_sre) {
+ write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
+ ICC_SRE_EL2);
+ }
+}
+
+void __hyp_text __vgic_v3_init_lrs(void)
+{
+ int max_lr_idx = vtr_to_max_lr_idx(read_gicreg(ICH_VTR_EL2));
+ int i;
+
+ for (i = 0; i <= max_lr_idx; i++)
+ __gic_v3_set_lr(0, i);
+}
+
+static u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void)
+{
+ return read_gicreg(ICH_VTR_EL2);
+}
+
+__alias(__vgic_v3_read_ich_vtr_el2) u64 __vgic_v3_get_ich_vtr_el2(void);
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 85c5715..4d1ac81 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -27,7 +27,11 @@
#define PSTATE_FAULT_BITS_64 (PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \
PSR_I_BIT | PSR_D_BIT)
-#define EL1_EXCEPT_SYNC_OFFSET 0x200
+
+#define CURRENT_EL_SP_EL0_VECTOR 0x0
+#define CURRENT_EL_SP_ELx_VECTOR 0x200
+#define LOWER_EL_AArch64_VECTOR 0x400
+#define LOWER_EL_AArch32_VECTOR 0x600
static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
{
@@ -48,7 +52,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
/* Note: These now point to the banked copies */
*vcpu_spsr(vcpu) = new_spsr_value;
- *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
+ *vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
/* Branch to exception vector */
if (sctlr & (1 << 13))
@@ -97,6 +101,34 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
*fsr = 0x14;
}
+enum exception_type {
+ except_type_sync = 0,
+ except_type_irq = 0x80,
+ except_type_fiq = 0x100,
+ except_type_serror = 0x180,
+};
+
+static u64 get_except_vector(struct kvm_vcpu *vcpu, enum exception_type type)
+{
+ u64 exc_offset;
+
+ switch (*vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT)) {
+ case PSR_MODE_EL1t:
+ exc_offset = CURRENT_EL_SP_EL0_VECTOR;
+ break;
+ case PSR_MODE_EL1h:
+ exc_offset = CURRENT_EL_SP_ELx_VECTOR;
+ break;
+ case PSR_MODE_EL0t:
+ exc_offset = LOWER_EL_AArch64_VECTOR;
+ break;
+ default:
+ exc_offset = LOWER_EL_AArch32_VECTOR;
+ }
+
+ return vcpu_sys_reg(vcpu, VBAR_EL1) + exc_offset + type;
+}
+
static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
{
unsigned long cpsr = *vcpu_cpsr(vcpu);
@@ -108,8 +140,8 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
*vcpu_spsr(vcpu) = cpsr;
*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
+ *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
- *vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
vcpu_sys_reg(vcpu, FAR_EL1) = addr;
@@ -143,8 +175,8 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
*vcpu_spsr(vcpu) = cpsr;
*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
+ *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
- *vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
/*
* Build an unknown exception, depending on the instruction
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 91cf535..9677bf0 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -53,7 +53,7 @@ static bool cpu_has_32bit_el1(void)
{
u64 pfr0;
- pfr0 = read_cpuid(ID_AA64PFR0_EL1);
+ pfr0 = read_system_reg(SYS_ID_AA64PFR0_EL1);
return !!(pfr0 & 0x20);
}
@@ -77,7 +77,11 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_GUEST_DEBUG_HW_WPS:
r = get_num_wrps();
break;
+ case KVM_CAP_ARM_PMU_V3:
+ r = kvm_arm_support_pmu_v3();
+ break;
case KVM_CAP_SET_GUEST_DEBUG:
+ case KVM_CAP_VCPU_ATTRIBUTES:
r = 1;
break;
default:
@@ -120,6 +124,9 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
/* Reset system registers */
kvm_reset_sys_regs(vcpu);
+ /* Reset PMU */
+ kvm_pmu_vcpu_reset(vcpu);
+
/* Reset timer */
return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index d03d3af..7bbe3ff 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/bsearch.h>
#include <linux/kvm_host.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
@@ -29,10 +30,12 @@
#include <asm/debug-monitors.h>
#include <asm/esr.h>
#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_host.h>
#include <asm/kvm_mmu.h>
+#include <asm/perf_event.h>
#include <trace/events/kvm.h>
@@ -78,7 +81,7 @@ static u32 get_ccsidr(u32 csselr)
* 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 sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (!p->is_write)
@@ -94,21 +97,19 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
* sys_regs and leave it in complete control of the caches.
*/
static bool access_vm_reg(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
- unsigned long val;
bool was_enabled = vcpu_has_cache_enabled(vcpu);
BUG_ON(!p->is_write);
- val = *vcpu_reg(vcpu, p->Rt);
if (!p->is_aarch32) {
- vcpu_sys_reg(vcpu, r->reg) = val;
+ vcpu_sys_reg(vcpu, r->reg) = p->regval;
} else {
if (!p->is_32bit)
- vcpu_cp15_64_high(vcpu, r->reg) = val >> 32;
- vcpu_cp15_64_low(vcpu, r->reg) = val & 0xffffffffUL;
+ vcpu_cp15_64_high(vcpu, r->reg) = upper_32_bits(p->regval);
+ vcpu_cp15_64_low(vcpu, r->reg) = lower_32_bits(p->regval);
}
kvm_toggle_cache(vcpu, was_enabled);
@@ -122,22 +123,19 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
* for both AArch64 and AArch32 accesses.
*/
static bool access_gic_sgi(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
- u64 val;
-
if (!p->is_write)
return read_from_write_only(vcpu, p);
- val = *vcpu_reg(vcpu, p->Rt);
- vgic_v3_dispatch_sgi(vcpu, val);
+ vgic_v3_dispatch_sgi(vcpu, p->regval);
return true;
}
static bool trap_raz_wi(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write)
@@ -147,19 +145,19 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
}
static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write) {
return ignore_write(vcpu, p);
} else {
- *vcpu_reg(vcpu, p->Rt) = (1 << 3);
+ p->regval = (1 << 3);
return true;
}
}
static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write) {
@@ -167,7 +165,7 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
} else {
u32 val;
asm volatile("mrs %0, dbgauthstatus_el1" : "=r" (val));
- *vcpu_reg(vcpu, p->Rt) = val;
+ p->regval = val;
return true;
}
}
@@ -200,17 +198,17 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
* now use the debug registers.
*/
static bool trap_debug_regs(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write) {
- vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
+ vcpu_sys_reg(vcpu, r->reg) = p->regval;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
} else {
- *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg);
+ p->regval = vcpu_sys_reg(vcpu, r->reg);
}
- trace_trap_reg(__func__, r->reg, p->is_write, *vcpu_reg(vcpu, p->Rt));
+ trace_trap_reg(__func__, r->reg, p->is_write, p->regval);
return true;
}
@@ -224,11 +222,11 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
* All writes will set the KVM_ARM64_DEBUG_DIRTY flag to ensure the
* hyp.S code switches between host and guest values in future.
*/
-static inline void reg_to_dbg(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- u64 *dbg_reg)
+static void reg_to_dbg(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ u64 *dbg_reg)
{
- u64 val = *vcpu_reg(vcpu, p->Rt);
+ u64 val = p->regval;
if (p->is_32bit) {
val &= 0xffffffffUL;
@@ -239,21 +237,18 @@ static inline void reg_to_dbg(struct kvm_vcpu *vcpu,
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
}
-static inline void dbg_to_reg(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- u64 *dbg_reg)
+static void dbg_to_reg(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ u64 *dbg_reg)
{
- u64 val = *dbg_reg;
-
+ p->regval = *dbg_reg;
if (p->is_32bit)
- val &= 0xffffffffUL;
-
- *vcpu_reg(vcpu, p->Rt) = val;
+ p->regval &= 0xffffffffUL;
}
-static inline bool trap_bvr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- const struct sys_reg_desc *rd)
+static bool trap_bvr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
{
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
@@ -287,15 +282,15 @@ static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
return 0;
}
-static inline void reset_bvr(struct kvm_vcpu *vcpu,
- const struct sys_reg_desc *rd)
+static void reset_bvr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
{
vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val;
}
-static inline bool trap_bcr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- const struct sys_reg_desc *rd)
+static bool trap_bcr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
{
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
@@ -330,15 +325,15 @@ static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
return 0;
}
-static inline void reset_bcr(struct kvm_vcpu *vcpu,
- const struct sys_reg_desc *rd)
+static void reset_bcr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
{
vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val;
}
-static inline bool trap_wvr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- const struct sys_reg_desc *rd)
+static bool trap_wvr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
{
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
@@ -373,15 +368,15 @@ static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
return 0;
}
-static inline void reset_wvr(struct kvm_vcpu *vcpu,
- const struct sys_reg_desc *rd)
+static void reset_wvr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
{
vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val;
}
-static inline bool trap_wcr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- const struct sys_reg_desc *rd)
+static bool trap_wcr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
{
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
@@ -415,8 +410,8 @@ static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
return 0;
}
-static inline void reset_wcr(struct kvm_vcpu *vcpu,
- const struct sys_reg_desc *rd)
+static void reset_wcr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
{
vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val;
}
@@ -446,6 +441,344 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
vcpu_sys_reg(vcpu, MPIDR_EL1) = (1ULL << 31) | mpidr;
}
+static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+ u64 pmcr, val;
+
+ asm volatile("mrs %0, pmcr_el0\n" : "=r" (pmcr));
+ /* Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) is reset to UNKNOWN
+ * except PMCR.E resetting to zero.
+ */
+ val = ((pmcr & ~ARMV8_PMU_PMCR_MASK)
+ | (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E);
+ vcpu_sys_reg(vcpu, PMCR_EL0) = val;
+}
+
+static bool pmu_access_el0_disabled(struct kvm_vcpu *vcpu)
+{
+ u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0);
+
+ return !((reg & ARMV8_PMU_USERENR_EN) || vcpu_mode_priv(vcpu));
+}
+
+static bool pmu_write_swinc_el0_disabled(struct kvm_vcpu *vcpu)
+{
+ u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0);
+
+ return !((reg & (ARMV8_PMU_USERENR_SW | ARMV8_PMU_USERENR_EN))
+ || vcpu_mode_priv(vcpu));
+}
+
+static bool pmu_access_cycle_counter_el0_disabled(struct kvm_vcpu *vcpu)
+{
+ u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0);
+
+ return !((reg & (ARMV8_PMU_USERENR_CR | ARMV8_PMU_USERENR_EN))
+ || vcpu_mode_priv(vcpu));
+}
+
+static bool pmu_access_event_counter_el0_disabled(struct kvm_vcpu *vcpu)
+{
+ u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0);
+
+ return !((reg & (ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_EN))
+ || vcpu_mode_priv(vcpu));
+}
+
+static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 val;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ if (p->is_write) {
+ /* Only update writeable bits of PMCR */
+ val = vcpu_sys_reg(vcpu, PMCR_EL0);
+ val &= ~ARMV8_PMU_PMCR_MASK;
+ val |= p->regval & ARMV8_PMU_PMCR_MASK;
+ vcpu_sys_reg(vcpu, PMCR_EL0) = val;
+ kvm_pmu_handle_pmcr(vcpu, val);
+ } else {
+ /* PMCR.P & PMCR.C are RAZ */
+ val = vcpu_sys_reg(vcpu, PMCR_EL0)
+ & ~(ARMV8_PMU_PMCR_P | ARMV8_PMU_PMCR_C);
+ p->regval = val;
+ }
+
+ return true;
+}
+
+static bool access_pmselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_access_event_counter_el0_disabled(vcpu))
+ return false;
+
+ if (p->is_write)
+ vcpu_sys_reg(vcpu, PMSELR_EL0) = p->regval;
+ else
+ /* return PMSELR.SEL field */
+ p->regval = vcpu_sys_reg(vcpu, PMSELR_EL0)
+ & ARMV8_PMU_COUNTER_MASK;
+
+ return true;
+}
+
+static bool access_pmceid(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 pmceid;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ BUG_ON(p->is_write);
+
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ if (!(p->Op2 & 1))
+ asm volatile("mrs %0, pmceid0_el0\n" : "=r" (pmceid));
+ else
+ asm volatile("mrs %0, pmceid1_el0\n" : "=r" (pmceid));
+
+ p->regval = pmceid;
+
+ return true;
+}
+
+static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)
+{
+ u64 pmcr, val;
+
+ pmcr = vcpu_sys_reg(vcpu, PMCR_EL0);
+ val = (pmcr >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK;
+ if (idx >= val && idx != ARMV8_PMU_CYCLE_IDX)
+ return false;
+
+ return true;
+}
+
+static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 idx;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (r->CRn == 9 && r->CRm == 13) {
+ if (r->Op2 == 2) {
+ /* PMXEVCNTR_EL0 */
+ if (pmu_access_event_counter_el0_disabled(vcpu))
+ return false;
+
+ idx = vcpu_sys_reg(vcpu, PMSELR_EL0)
+ & ARMV8_PMU_COUNTER_MASK;
+ } else if (r->Op2 == 0) {
+ /* PMCCNTR_EL0 */
+ if (pmu_access_cycle_counter_el0_disabled(vcpu))
+ return false;
+
+ idx = ARMV8_PMU_CYCLE_IDX;
+ } else {
+ BUG();
+ }
+ } else if (r->CRn == 14 && (r->CRm & 12) == 8) {
+ /* PMEVCNTRn_EL0 */
+ if (pmu_access_event_counter_el0_disabled(vcpu))
+ return false;
+
+ idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
+ } else {
+ BUG();
+ }
+
+ if (!pmu_counter_idx_valid(vcpu, idx))
+ return false;
+
+ if (p->is_write) {
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ kvm_pmu_set_counter_value(vcpu, idx, p->regval);
+ } else {
+ p->regval = kvm_pmu_get_counter_value(vcpu, idx);
+ }
+
+ return true;
+}
+
+static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 idx, reg;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 1) {
+ /* PMXEVTYPER_EL0 */
+ idx = vcpu_sys_reg(vcpu, PMSELR_EL0) & ARMV8_PMU_COUNTER_MASK;
+ reg = PMEVTYPER0_EL0 + idx;
+ } else if (r->CRn == 14 && (r->CRm & 12) == 12) {
+ idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
+ if (idx == ARMV8_PMU_CYCLE_IDX)
+ reg = PMCCFILTR_EL0;
+ else
+ /* PMEVTYPERn_EL0 */
+ reg = PMEVTYPER0_EL0 + idx;
+ } else {
+ BUG();
+ }
+
+ if (!pmu_counter_idx_valid(vcpu, idx))
+ return false;
+
+ if (p->is_write) {
+ kvm_pmu_set_counter_event_type(vcpu, p->regval, idx);
+ vcpu_sys_reg(vcpu, reg) = p->regval & ARMV8_PMU_EVTYPE_MASK;
+ } else {
+ p->regval = vcpu_sys_reg(vcpu, reg) & ARMV8_PMU_EVTYPE_MASK;
+ }
+
+ return true;
+}
+
+static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 val, mask;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ mask = kvm_pmu_valid_counter_mask(vcpu);
+ if (p->is_write) {
+ val = p->regval & mask;
+ if (r->Op2 & 0x1) {
+ /* accessing PMCNTENSET_EL0 */
+ vcpu_sys_reg(vcpu, PMCNTENSET_EL0) |= val;
+ kvm_pmu_enable_counter(vcpu, val);
+ } else {
+ /* accessing PMCNTENCLR_EL0 */
+ vcpu_sys_reg(vcpu, PMCNTENSET_EL0) &= ~val;
+ kvm_pmu_disable_counter(vcpu, val);
+ }
+ } else {
+ p->regval = vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask;
+ }
+
+ return true;
+}
+
+static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 mask = kvm_pmu_valid_counter_mask(vcpu);
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (!vcpu_mode_priv(vcpu))
+ return false;
+
+ if (p->is_write) {
+ u64 val = p->regval & mask;
+
+ if (r->Op2 & 0x1)
+ /* accessing PMINTENSET_EL1 */
+ vcpu_sys_reg(vcpu, PMINTENSET_EL1) |= val;
+ else
+ /* accessing PMINTENCLR_EL1 */
+ vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val;
+ } else {
+ p->regval = vcpu_sys_reg(vcpu, PMINTENSET_EL1) & mask;
+ }
+
+ return true;
+}
+
+static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 mask = kvm_pmu_valid_counter_mask(vcpu);
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_access_el0_disabled(vcpu))
+ return false;
+
+ if (p->is_write) {
+ if (r->CRm & 0x2)
+ /* accessing PMOVSSET_EL0 */
+ kvm_pmu_overflow_set(vcpu, p->regval & mask);
+ else
+ /* accessing PMOVSCLR_EL0 */
+ vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask);
+ } else {
+ p->regval = vcpu_sys_reg(vcpu, PMOVSSET_EL0) & mask;
+ }
+
+ return true;
+}
+
+static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 mask;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (pmu_write_swinc_el0_disabled(vcpu))
+ return false;
+
+ if (p->is_write) {
+ mask = kvm_pmu_valid_counter_mask(vcpu);
+ kvm_pmu_software_increment(vcpu, p->regval & mask);
+ return true;
+ }
+
+ return false;
+}
+
+static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return trap_raz_wi(vcpu, p, r);
+
+ if (p->is_write) {
+ if (!vcpu_mode_priv(vcpu))
+ return false;
+
+ vcpu_sys_reg(vcpu, PMUSERENR_EL0) = p->regval
+ & ARMV8_PMU_USERENR_MASK;
+ } else {
+ p->regval = vcpu_sys_reg(vcpu, PMUSERENR_EL0)
+ & ARMV8_PMU_USERENR_MASK;
+ }
+
+ return true;
+}
+
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
/* DBGBVRn_EL1 */ \
@@ -461,6 +794,20 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
{ Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \
trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr }
+/* Macro to expand the PMEVCNTRn_EL0 register */
+#define PMU_PMEVCNTR_EL0(n) \
+ /* PMEVCNTRn_EL0 */ \
+ { Op0(0b11), Op1(0b011), CRn(0b1110), \
+ CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
+ access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
+
+/* Macro to expand the PMEVTYPERn_EL0 register */
+#define PMU_PMEVTYPER_EL0(n) \
+ /* PMEVTYPERn_EL0 */ \
+ { Op0(0b11), Op1(0b011), CRn(0b1110), \
+ CRm((0b1100 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
+ access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
+
/*
* Architected system registers.
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -590,10 +937,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
/* PMINTENSET_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001),
- trap_raz_wi },
+ access_pminten, reset_unknown, PMINTENSET_EL1 },
/* PMINTENCLR_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010),
- trap_raz_wi },
+ access_pminten, NULL, PMINTENSET_EL1 },
/* MAIR_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000),
@@ -630,43 +977,46 @@ static const struct sys_reg_desc sys_reg_descs[] = {
/* PMCR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000),
- trap_raz_wi },
+ access_pmcr, reset_pmcr, },
/* PMCNTENSET_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001),
- trap_raz_wi },
+ access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
/* PMCNTENCLR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010),
- trap_raz_wi },
+ access_pmcnten, NULL, PMCNTENSET_EL0 },
/* PMOVSCLR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011),
- trap_raz_wi },
+ access_pmovs, NULL, PMOVSSET_EL0 },
/* PMSWINC_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100),
- trap_raz_wi },
+ access_pmswinc, reset_unknown, PMSWINC_EL0 },
/* PMSELR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101),
- trap_raz_wi },
+ access_pmselr, reset_unknown, PMSELR_EL0 },
/* PMCEID0_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110),
- trap_raz_wi },
+ access_pmceid },
/* PMCEID1_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111),
- trap_raz_wi },
+ access_pmceid },
/* PMCCNTR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
- trap_raz_wi },
+ access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 },
/* PMXEVTYPER_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001),
- trap_raz_wi },
+ access_pmu_evtyper },
/* PMXEVCNTR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010),
- trap_raz_wi },
- /* PMUSERENR_EL0 */
+ access_pmu_evcntr },
+ /* PMUSERENR_EL0
+ * This register resets as unknown in 64bit mode while it resets as zero
+ * in 32bit mode. Here we choose to reset it as zero for consistency.
+ */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
- trap_raz_wi },
+ access_pmuserenr, reset_val, PMUSERENR_EL0, 0 },
/* PMOVSSET_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
- trap_raz_wi },
+ access_pmovs, reset_unknown, PMOVSSET_EL0 },
/* TPIDR_EL0 */
{ Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010),
@@ -675,6 +1025,77 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
NULL, reset_unknown, TPIDRRO_EL0 },
+ /* PMEVCNTRn_EL0 */
+ PMU_PMEVCNTR_EL0(0),
+ PMU_PMEVCNTR_EL0(1),
+ PMU_PMEVCNTR_EL0(2),
+ PMU_PMEVCNTR_EL0(3),
+ PMU_PMEVCNTR_EL0(4),
+ PMU_PMEVCNTR_EL0(5),
+ PMU_PMEVCNTR_EL0(6),
+ PMU_PMEVCNTR_EL0(7),
+ PMU_PMEVCNTR_EL0(8),
+ PMU_PMEVCNTR_EL0(9),
+ PMU_PMEVCNTR_EL0(10),
+ PMU_PMEVCNTR_EL0(11),
+ PMU_PMEVCNTR_EL0(12),
+ PMU_PMEVCNTR_EL0(13),
+ PMU_PMEVCNTR_EL0(14),
+ PMU_PMEVCNTR_EL0(15),
+ PMU_PMEVCNTR_EL0(16),
+ PMU_PMEVCNTR_EL0(17),
+ PMU_PMEVCNTR_EL0(18),
+ PMU_PMEVCNTR_EL0(19),
+ PMU_PMEVCNTR_EL0(20),
+ PMU_PMEVCNTR_EL0(21),
+ PMU_PMEVCNTR_EL0(22),
+ PMU_PMEVCNTR_EL0(23),
+ PMU_PMEVCNTR_EL0(24),
+ PMU_PMEVCNTR_EL0(25),
+ PMU_PMEVCNTR_EL0(26),
+ PMU_PMEVCNTR_EL0(27),
+ PMU_PMEVCNTR_EL0(28),
+ PMU_PMEVCNTR_EL0(29),
+ PMU_PMEVCNTR_EL0(30),
+ /* PMEVTYPERn_EL0 */
+ PMU_PMEVTYPER_EL0(0),
+ PMU_PMEVTYPER_EL0(1),
+ PMU_PMEVTYPER_EL0(2),
+ PMU_PMEVTYPER_EL0(3),
+ PMU_PMEVTYPER_EL0(4),
+ PMU_PMEVTYPER_EL0(5),
+ PMU_PMEVTYPER_EL0(6),
+ PMU_PMEVTYPER_EL0(7),
+ PMU_PMEVTYPER_EL0(8),
+ PMU_PMEVTYPER_EL0(9),
+ PMU_PMEVTYPER_EL0(10),
+ PMU_PMEVTYPER_EL0(11),
+ PMU_PMEVTYPER_EL0(12),
+ PMU_PMEVTYPER_EL0(13),
+ PMU_PMEVTYPER_EL0(14),
+ PMU_PMEVTYPER_EL0(15),
+ PMU_PMEVTYPER_EL0(16),
+ PMU_PMEVTYPER_EL0(17),
+ PMU_PMEVTYPER_EL0(18),
+ PMU_PMEVTYPER_EL0(19),
+ PMU_PMEVTYPER_EL0(20),
+ PMU_PMEVTYPER_EL0(21),
+ PMU_PMEVTYPER_EL0(22),
+ PMU_PMEVTYPER_EL0(23),
+ PMU_PMEVTYPER_EL0(24),
+ PMU_PMEVTYPER_EL0(25),
+ PMU_PMEVTYPER_EL0(26),
+ PMU_PMEVTYPER_EL0(27),
+ PMU_PMEVTYPER_EL0(28),
+ PMU_PMEVTYPER_EL0(29),
+ PMU_PMEVTYPER_EL0(30),
+ /* PMCCFILTR_EL0
+ * This register resets as unknown in 64bit mode while it resets as zero
+ * in 32bit mode. Here we choose to reset it as zero for consistency.
+ */
+ { Op0(0b11), Op1(0b011), CRn(0b1110), CRm(0b1111), Op2(0b111),
+ access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 },
+
/* DACR32_EL2 */
{ Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
NULL, reset_unknown, DACR32_EL2 },
@@ -687,33 +1108,33 @@ static const struct sys_reg_desc sys_reg_descs[] = {
};
static bool trap_dbgidr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write) {
return ignore_write(vcpu, p);
} else {
- u64 dfr = read_cpuid(ID_AA64DFR0_EL1);
- u64 pfr = read_cpuid(ID_AA64PFR0_EL1);
- u32 el3 = !!((pfr >> 12) & 0xf);
-
- *vcpu_reg(vcpu, p->Rt) = ((((dfr >> 20) & 0xf) << 28) |
- (((dfr >> 12) & 0xf) << 24) |
- (((dfr >> 28) & 0xf) << 20) |
- (6 << 16) | (el3 << 14) | (el3 << 12));
+ u64 dfr = read_system_reg(SYS_ID_AA64DFR0_EL1);
+ u64 pfr = read_system_reg(SYS_ID_AA64PFR0_EL1);
+ u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
+
+ p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
+ (((dfr >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) << 24) |
+ (((dfr >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) << 20)
+ | (6 << 16) | (el3 << 14) | (el3 << 12));
return true;
}
}
static bool trap_debug32(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write) {
- vcpu_cp14(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
+ vcpu_cp14(vcpu, r->reg) = p->regval;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
} else {
- *vcpu_reg(vcpu, p->Rt) = vcpu_cp14(vcpu, r->reg);
+ p->regval = vcpu_cp14(vcpu, r->reg);
}
return true;
@@ -730,9 +1151,9 @@ static bool trap_debug32(struct kvm_vcpu *vcpu,
* system is in.
*/
-static inline bool trap_xvr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
- const struct sys_reg_desc *rd)
+static bool trap_xvr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
{
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
@@ -740,12 +1161,12 @@ static inline bool trap_xvr(struct kvm_vcpu *vcpu,
u64 val = *dbg_reg;
val &= 0xffffffffUL;
- val |= *vcpu_reg(vcpu, p->Rt) << 32;
+ val |= p->regval << 32;
*dbg_reg = val;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
} else {
- *vcpu_reg(vcpu, p->Rt) = *dbg_reg >> 32;
+ p->regval = *dbg_reg >> 32;
}
trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
@@ -864,6 +1285,20 @@ static const struct sys_reg_desc cp14_64_regs[] = {
{ Op1( 0), CRm( 2), .access = trap_raz_wi },
};
+/* Macro to expand the PMEVCNTRn register */
+#define PMU_PMEVCNTR(n) \
+ /* PMEVCNTRn */ \
+ { Op1(0), CRn(0b1110), \
+ CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
+ access_pmu_evcntr }
+
+/* Macro to expand the PMEVTYPERn register */
+#define PMU_PMEVTYPER(n) \
+ /* PMEVTYPERn */ \
+ { Op1(0), CRn(0b1110), \
+ CRm((0b1100 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
+ access_pmu_evtyper }
+
/*
* Trapped cp15 registers. TTBR0/TTBR1 get a double encoding,
* depending on the way they are accessed (as a 32bit or a 64bit
@@ -892,19 +1327,21 @@ static const struct sys_reg_desc cp15_regs[] = {
{ Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw },
/* PMU */
- { Op1( 0), CRn( 9), CRm(12), Op2( 0), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 5), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 6), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(12), Op2( 7), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(13), Op2( 0), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(13), Op2( 2), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi },
- { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 0), access_pmcr },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 1), access_pmcnten },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 2), access_pmcnten },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 3), access_pmovs },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 4), access_pmswinc },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 5), access_pmselr },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 6), access_pmceid },
+ { Op1( 0), CRn( 9), CRm(12), Op2( 7), access_pmceid },
+ { Op1( 0), CRn( 9), CRm(13), Op2( 0), access_pmu_evcntr },
+ { Op1( 0), CRn( 9), CRm(13), Op2( 1), access_pmu_evtyper },
+ { Op1( 0), CRn( 9), CRm(13), Op2( 2), access_pmu_evcntr },
+ { Op1( 0), CRn( 9), CRm(14), Op2( 0), access_pmuserenr },
+ { Op1( 0), CRn( 9), CRm(14), Op2( 1), access_pminten },
+ { Op1( 0), CRn( 9), CRm(14), Op2( 2), access_pminten },
+ { Op1( 0), CRn( 9), CRm(14), Op2( 3), access_pmovs },
{ Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR },
{ Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR },
@@ -915,10 +1352,78 @@ static const struct sys_reg_desc cp15_regs[] = {
{ Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi },
{ Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID },
+
+ /* PMEVCNTRn */
+ PMU_PMEVCNTR(0),
+ PMU_PMEVCNTR(1),
+ PMU_PMEVCNTR(2),
+ PMU_PMEVCNTR(3),
+ PMU_PMEVCNTR(4),
+ PMU_PMEVCNTR(5),
+ PMU_PMEVCNTR(6),
+ PMU_PMEVCNTR(7),
+ PMU_PMEVCNTR(8),
+ PMU_PMEVCNTR(9),
+ PMU_PMEVCNTR(10),
+ PMU_PMEVCNTR(11),
+ PMU_PMEVCNTR(12),
+ PMU_PMEVCNTR(13),
+ PMU_PMEVCNTR(14),
+ PMU_PMEVCNTR(15),
+ PMU_PMEVCNTR(16),
+ PMU_PMEVCNTR(17),
+ PMU_PMEVCNTR(18),
+ PMU_PMEVCNTR(19),
+ PMU_PMEVCNTR(20),
+ PMU_PMEVCNTR(21),
+ PMU_PMEVCNTR(22),
+ PMU_PMEVCNTR(23),
+ PMU_PMEVCNTR(24),
+ PMU_PMEVCNTR(25),
+ PMU_PMEVCNTR(26),
+ PMU_PMEVCNTR(27),
+ PMU_PMEVCNTR(28),
+ PMU_PMEVCNTR(29),
+ PMU_PMEVCNTR(30),
+ /* PMEVTYPERn */
+ PMU_PMEVTYPER(0),
+ PMU_PMEVTYPER(1),
+ PMU_PMEVTYPER(2),
+ PMU_PMEVTYPER(3),
+ PMU_PMEVTYPER(4),
+ PMU_PMEVTYPER(5),
+ PMU_PMEVTYPER(6),
+ PMU_PMEVTYPER(7),
+ PMU_PMEVTYPER(8),
+ PMU_PMEVTYPER(9),
+ PMU_PMEVTYPER(10),
+ PMU_PMEVTYPER(11),
+ PMU_PMEVTYPER(12),
+ PMU_PMEVTYPER(13),
+ PMU_PMEVTYPER(14),
+ PMU_PMEVTYPER(15),
+ PMU_PMEVTYPER(16),
+ PMU_PMEVTYPER(17),
+ PMU_PMEVTYPER(18),
+ PMU_PMEVTYPER(19),
+ PMU_PMEVTYPER(20),
+ PMU_PMEVTYPER(21),
+ PMU_PMEVTYPER(22),
+ PMU_PMEVTYPER(23),
+ PMU_PMEVTYPER(24),
+ PMU_PMEVTYPER(25),
+ PMU_PMEVTYPER(26),
+ PMU_PMEVTYPER(27),
+ PMU_PMEVTYPER(28),
+ PMU_PMEVTYPER(29),
+ PMU_PMEVTYPER(30),
+ /* PMCCFILTR */
+ { Op1(0), CRn(14), CRm(15), Op2(7), access_pmu_evtyper },
};
static const struct sys_reg_desc cp15_64_regs[] = {
{ Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
+ { Op1( 0), CRn( 0), CRm( 9), Op2( 0), access_pmu_evcntr },
{ Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 },
};
@@ -949,29 +1454,32 @@ static const struct sys_reg_desc *get_target_table(unsigned target,
}
}
+#define reg_to_match_value(x) \
+ ({ \
+ unsigned long val; \
+ val = (x)->Op0 << 14; \
+ val |= (x)->Op1 << 11; \
+ val |= (x)->CRn << 7; \
+ val |= (x)->CRm << 3; \
+ val |= (x)->Op2; \
+ val; \
+ })
+
+static int match_sys_reg(const void *key, const void *elt)
+{
+ const unsigned long pval = (unsigned long)key;
+ const struct sys_reg_desc *r = elt;
+
+ return pval - reg_to_match_value(r);
+}
+
static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
const struct sys_reg_desc table[],
unsigned int num)
{
- unsigned int i;
-
- for (i = 0; i < num; i++) {
- const struct sys_reg_desc *r = &table[i];
+ unsigned long pval = reg_to_match_value(params);
- if (params->Op0 != r->Op0)
- continue;
- if (params->Op1 != r->Op1)
- continue;
- if (params->CRn != r->CRn)
- continue;
- if (params->CRm != r->CRm)
- continue;
- if (params->Op2 != r->Op2)
- continue;
-
- return r;
- }
- return NULL;
+ return bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg);
}
int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
@@ -991,7 +1499,7 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
* Return 0 if the access has been handled, and -1 if not.
*/
static int emulate_cp(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *params,
+ struct sys_reg_params *params,
const struct sys_reg_desc *table,
size_t num)
{
@@ -1014,10 +1522,9 @@ static int emulate_cp(struct kvm_vcpu *vcpu,
if (likely(r->access(vcpu, params, r))) {
/* Skip instruction, since it was emulated */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ /* Handled */
+ return 0;
}
-
- /* Handled */
- return 0;
}
/* Not handled */
@@ -1050,7 +1557,7 @@ static void unhandled_cp_access(struct kvm_vcpu *vcpu,
}
/**
- * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer
* @run: The kvm_run struct
*/
@@ -1062,12 +1569,12 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
{
struct sys_reg_params params;
u32 hsr = kvm_vcpu_get_hsr(vcpu);
+ int Rt = (hsr >> 5) & 0xf;
int Rt2 = (hsr >> 10) & 0xf;
params.is_aarch32 = true;
params.is_32bit = false;
params.CRm = (hsr >> 1) & 0xf;
- params.Rt = (hsr >> 5) & 0xf;
params.is_write = ((hsr & 1) == 0);
params.Op0 = 0;
@@ -1076,15 +1583,12 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
params.CRn = 0;
/*
- * Massive hack here. Store Rt2 in the top 32bits so we only
- * have one register to deal with. As we use the same trap
+ * Make a 64-bit value out of Rt and Rt2. As we use the same trap
* backends between AArch32 and AArch64, we get away with it.
*/
if (params.is_write) {
- u64 val = *vcpu_reg(vcpu, params.Rt);
- val &= 0xffffffff;
- val |= *vcpu_reg(vcpu, Rt2) << 32;
- *vcpu_reg(vcpu, params.Rt) = val;
+ params.regval = vcpu_get_reg(vcpu, Rt) & 0xffffffff;
+ params.regval |= vcpu_get_reg(vcpu, Rt2) << 32;
}
if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
@@ -1095,18 +1599,17 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
unhandled_cp_access(vcpu, &params);
out:
- /* Do the opposite hack for the read side */
+ /* Split up the value between registers for the read side */
if (!params.is_write) {
- u64 val = *vcpu_reg(vcpu, params.Rt);
- val >>= 32;
- *vcpu_reg(vcpu, Rt2) = val;
+ vcpu_set_reg(vcpu, Rt, lower_32_bits(params.regval));
+ vcpu_set_reg(vcpu, Rt2, upper_32_bits(params.regval));
}
return 1;
}
/**
- * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer
* @run: The kvm_run struct
*/
@@ -1118,21 +1621,24 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
{
struct sys_reg_params params;
u32 hsr = kvm_vcpu_get_hsr(vcpu);
+ int Rt = (hsr >> 5) & 0xf;
params.is_aarch32 = true;
params.is_32bit = true;
params.CRm = (hsr >> 1) & 0xf;
- params.Rt = (hsr >> 5) & 0xf;
+ params.regval = vcpu_get_reg(vcpu, Rt);
params.is_write = ((hsr & 1) == 0);
params.CRn = (hsr >> 10) & 0xf;
params.Op0 = 0;
params.Op1 = (hsr >> 14) & 0x7;
params.Op2 = (hsr >> 17) & 0x7;
- if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
- return 1;
- if (!emulate_cp(vcpu, &params, global, nr_global))
+ if (!emulate_cp(vcpu, &params, target_specific, nr_specific) ||
+ !emulate_cp(vcpu, &params, global, nr_global)) {
+ if (!params.is_write)
+ vcpu_set_reg(vcpu, Rt, params.regval);
return 1;
+ }
unhandled_cp_access(vcpu, &params);
return 1;
@@ -1175,7 +1681,7 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
}
static int emulate_sys_reg(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *params)
+ struct sys_reg_params *params)
{
size_t num;
const struct sys_reg_desc *table, *r;
@@ -1230,6 +1736,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
struct sys_reg_params params;
unsigned long esr = kvm_vcpu_get_hsr(vcpu);
+ int Rt = (esr >> 5) & 0x1f;
+ int ret;
trace_kvm_handle_sys_reg(esr);
@@ -1240,10 +1748,14 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
params.CRn = (esr >> 10) & 0xf;
params.CRm = (esr >> 1) & 0xf;
params.Op2 = (esr >> 17) & 0x7;
- params.Rt = (esr >> 5) & 0x1f;
+ params.regval = vcpu_get_reg(vcpu, Rt);
params.is_write = !(esr & 1);
- return emulate_sys_reg(vcpu, &params);
+ ret = emulate_sys_reg(vcpu, &params);
+
+ if (!params.is_write)
+ vcpu_set_reg(vcpu, Rt, params.regval);
+ return ret;
}
/******************************************************************************
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index eaa324e..dbbb01c 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -28,7 +28,7 @@ struct sys_reg_params {
u8 CRn;
u8 CRm;
u8 Op2;
- u8 Rt;
+ u64 regval;
bool is_write;
bool is_aarch32;
bool is_32bit; /* Only valid if is_aarch32 is true */
@@ -44,7 +44,7 @@ struct sys_reg_desc {
/* Trapped access from guest, if non-NULL. */
bool (*access)(struct kvm_vcpu *,
- const struct sys_reg_params *,
+ struct sys_reg_params *,
const struct sys_reg_desc *);
/* Initialization for vcpu. */
@@ -77,9 +77,9 @@ static inline bool ignore_write(struct kvm_vcpu *vcpu,
}
static inline bool read_zero(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p)
+ struct sys_reg_params *p)
{
- *vcpu_reg(vcpu, p->Rt) = 0;
+ p->regval = 0;
return true;
}
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index 1e45768..ed90578 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -31,13 +31,13 @@
#include "sys_regs.h"
static bool access_actlr(struct kvm_vcpu *vcpu,
- const struct sys_reg_params *p,
+ struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
if (p->is_write)
return ignore_write(vcpu, p);
- *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, ACTLR_EL1);
+ p->regval = vcpu_sys_reg(vcpu, ACTLR_EL1);
return true;
}
diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S
deleted file mode 100644
index 3f00071..0000000
--- a/arch/arm64/kvm/vgic-v2-switch.S
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012,2013 - 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/linkage.h>
-#include <linux/irqchip/arm-gic.h>
-
-#include <asm/assembler.h>
-#include <asm/memory.h>
-#include <asm/asm-offsets.h>
-#include <asm/kvm.h>
-#include <asm/kvm_asm.h>
-#include <asm/kvm_arm.h>
-#include <asm/kvm_mmu.h>
-
- .text
- .pushsection .hyp.text, "ax"
-
-/*
- * Save the VGIC CPU state into memory
- * x0: Register pointing to VCPU struct
- * Do not corrupt x1!!!
- */
-ENTRY(__save_vgic_v2_state)
-__save_vgic_v2_state:
- /* Get VGIC VCTRL base into x2 */
- ldr x2, [x0, #VCPU_KVM]
- kern_hyp_va x2
- ldr x2, [x2, #KVM_VGIC_VCTRL]
- kern_hyp_va x2
- cbz x2, 2f // disabled
-
- /* Compute the address of struct vgic_cpu */
- add x3, x0, #VCPU_VGIC_CPU
-
- /* Save all interesting registers */
- ldr w5, [x2, #GICH_VMCR]
- ldr w6, [x2, #GICH_MISR]
- ldr w7, [x2, #GICH_EISR0]
- ldr w8, [x2, #GICH_EISR1]
- ldr w9, [x2, #GICH_ELRSR0]
- ldr w10, [x2, #GICH_ELRSR1]
- ldr w11, [x2, #GICH_APR]
-CPU_BE( rev w5, w5 )
-CPU_BE( rev w6, w6 )
-CPU_BE( rev w7, w7 )
-CPU_BE( rev w8, w8 )
-CPU_BE( rev w9, w9 )
-CPU_BE( rev w10, w10 )
-CPU_BE( rev w11, w11 )
-
- str w5, [x3, #VGIC_V2_CPU_VMCR]
- str w6, [x3, #VGIC_V2_CPU_MISR]
-CPU_LE( str w7, [x3, #VGIC_V2_CPU_EISR] )
-CPU_LE( str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] )
-CPU_LE( str w9, [x3, #VGIC_V2_CPU_ELRSR] )
-CPU_LE( str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
-CPU_BE( str w7, [x3, #(VGIC_V2_CPU_EISR + 4)] )
-CPU_BE( str w8, [x3, #VGIC_V2_CPU_EISR] )
-CPU_BE( str w9, [x3, #(VGIC_V2_CPU_ELRSR + 4)] )
-CPU_BE( str w10, [x3, #VGIC_V2_CPU_ELRSR] )
- str w11, [x3, #VGIC_V2_CPU_APR]
-
- /* Clear GICH_HCR */
- str wzr, [x2, #GICH_HCR]
-
- /* Save list registers */
- add x2, x2, #GICH_LR0
- ldr w4, [x3, #VGIC_CPU_NR_LR]
- add x3, x3, #VGIC_V2_CPU_LR
-1: ldr w5, [x2], #4
-CPU_BE( rev w5, w5 )
- str w5, [x3], #4
- sub w4, w4, #1
- cbnz w4, 1b
-2:
- ret
-ENDPROC(__save_vgic_v2_state)
-
-/*
- * Restore the VGIC CPU state from memory
- * x0: Register pointing to VCPU struct
- */
-ENTRY(__restore_vgic_v2_state)
-__restore_vgic_v2_state:
- /* Get VGIC VCTRL base into x2 */
- ldr x2, [x0, #VCPU_KVM]
- kern_hyp_va x2
- ldr x2, [x2, #KVM_VGIC_VCTRL]
- kern_hyp_va x2
- cbz x2, 2f // disabled
-
- /* Compute the address of struct vgic_cpu */
- add x3, x0, #VCPU_VGIC_CPU
-
- /* We only restore a minimal set of registers */
- ldr w4, [x3, #VGIC_V2_CPU_HCR]
- ldr w5, [x3, #VGIC_V2_CPU_VMCR]
- ldr w6, [x3, #VGIC_V2_CPU_APR]
-CPU_BE( rev w4, w4 )
-CPU_BE( rev w5, w5 )
-CPU_BE( rev w6, w6 )
-
- str w4, [x2, #GICH_HCR]
- str w5, [x2, #GICH_VMCR]
- str w6, [x2, #GICH_APR]
-
- /* Restore list registers */
- add x2, x2, #GICH_LR0
- ldr w4, [x3, #VGIC_CPU_NR_LR]
- add x3, x3, #VGIC_V2_CPU_LR
-1: ldr w5, [x3], #4
-CPU_BE( rev w5, w5 )
- str w5, [x2], #4
- sub w4, w4, #1
- cbnz w4, 1b
-2:
- ret
-ENDPROC(__restore_vgic_v2_state)
-
- .popsection
diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S
deleted file mode 100644
index 3c20730..0000000
--- a/arch/arm64/kvm/vgic-v3-switch.S
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2012,2013 - 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/linkage.h>
-#include <linux/irqchip/arm-gic-v3.h>
-
-#include <asm/assembler.h>
-#include <asm/memory.h>
-#include <asm/asm-offsets.h>
-#include <asm/kvm.h>
-#include <asm/kvm_asm.h>
-#include <asm/kvm_arm.h>
-
- .text
- .pushsection .hyp.text, "ax"
-
-/*
- * We store LRs in reverse order to let the CPU deal with streaming
- * access. Use this macro to make it look saner...
- */
-#define LR_OFFSET(n) (VGIC_V3_CPU_LR + (15 - n) * 8)
-
-/*
- * Save the VGIC CPU state into memory
- * x0: Register pointing to VCPU struct
- * Do not corrupt x1!!!
- */
-.macro save_vgic_v3_state
- // Compute the address of struct vgic_cpu
- add x3, x0, #VCPU_VGIC_CPU
-
- // Make sure stores to the GIC via the memory mapped interface
- // are now visible to the system register interface
- dsb st
-
- // Save all interesting registers
- mrs_s x5, ICH_VMCR_EL2
- mrs_s x6, ICH_MISR_EL2
- mrs_s x7, ICH_EISR_EL2
- mrs_s x8, ICH_ELSR_EL2
-
- str w5, [x3, #VGIC_V3_CPU_VMCR]
- str w6, [x3, #VGIC_V3_CPU_MISR]
- str w7, [x3, #VGIC_V3_CPU_EISR]
- str w8, [x3, #VGIC_V3_CPU_ELRSR]
-
- msr_s ICH_HCR_EL2, xzr
-
- mrs_s x21, ICH_VTR_EL2
- mvn w22, w21
- ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4
-
- adr x24, 1f
- add x24, x24, x23
- br x24
-
-1:
- mrs_s x20, ICH_LR15_EL2
- mrs_s x19, ICH_LR14_EL2
- mrs_s x18, ICH_LR13_EL2
- mrs_s x17, ICH_LR12_EL2
- mrs_s x16, ICH_LR11_EL2
- mrs_s x15, ICH_LR10_EL2
- mrs_s x14, ICH_LR9_EL2
- mrs_s x13, ICH_LR8_EL2
- mrs_s x12, ICH_LR7_EL2
- mrs_s x11, ICH_LR6_EL2
- mrs_s x10, ICH_LR5_EL2
- mrs_s x9, ICH_LR4_EL2
- mrs_s x8, ICH_LR3_EL2
- mrs_s x7, ICH_LR2_EL2
- mrs_s x6, ICH_LR1_EL2
- mrs_s x5, ICH_LR0_EL2
-
- adr x24, 1f
- add x24, x24, x23
- br x24
-
-1:
- str x20, [x3, #LR_OFFSET(15)]
- str x19, [x3, #LR_OFFSET(14)]
- str x18, [x3, #LR_OFFSET(13)]
- str x17, [x3, #LR_OFFSET(12)]
- str x16, [x3, #LR_OFFSET(11)]
- str x15, [x3, #LR_OFFSET(10)]
- str x14, [x3, #LR_OFFSET(9)]
- str x13, [x3, #LR_OFFSET(8)]
- str x12, [x3, #LR_OFFSET(7)]
- str x11, [x3, #LR_OFFSET(6)]
- str x10, [x3, #LR_OFFSET(5)]
- str x9, [x3, #LR_OFFSET(4)]
- str x8, [x3, #LR_OFFSET(3)]
- str x7, [x3, #LR_OFFSET(2)]
- str x6, [x3, #LR_OFFSET(1)]
- str x5, [x3, #LR_OFFSET(0)]
-
- tbnz w21, #29, 6f // 6 bits
- tbz w21, #30, 5f // 5 bits
- // 7 bits
- mrs_s x20, ICH_AP0R3_EL2
- str w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
- mrs_s x19, ICH_AP0R2_EL2
- str w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
-6: mrs_s x18, ICH_AP0R1_EL2
- str w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
-5: mrs_s x17, ICH_AP0R0_EL2
- str w17, [x3, #VGIC_V3_CPU_AP0R]
-
- tbnz w21, #29, 6f // 6 bits
- tbz w21, #30, 5f // 5 bits
- // 7 bits
- mrs_s x20, ICH_AP1R3_EL2
- str w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
- mrs_s x19, ICH_AP1R2_EL2
- str w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
-6: mrs_s x18, ICH_AP1R1_EL2
- str w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
-5: mrs_s x17, ICH_AP1R0_EL2
- str w17, [x3, #VGIC_V3_CPU_AP1R]
-
- // Restore SRE_EL1 access and re-enable SRE at EL1.
- mrs_s x5, ICC_SRE_EL2
- orr x5, x5, #ICC_SRE_EL2_ENABLE
- msr_s ICC_SRE_EL2, x5
- isb
- mov x5, #1
- msr_s ICC_SRE_EL1, x5
-.endm
-
-/*
- * Restore the VGIC CPU state from memory
- * x0: Register pointing to VCPU struct
- */
-.macro restore_vgic_v3_state
- // Compute the address of struct vgic_cpu
- add x3, x0, #VCPU_VGIC_CPU
-
- // Restore all interesting registers
- ldr w4, [x3, #VGIC_V3_CPU_HCR]
- ldr w5, [x3, #VGIC_V3_CPU_VMCR]
- ldr w25, [x3, #VGIC_V3_CPU_SRE]
-
- msr_s ICC_SRE_EL1, x25
-
- // make sure SRE is valid before writing the other registers
- isb
-
- msr_s ICH_HCR_EL2, x4
- msr_s ICH_VMCR_EL2, x5
-
- mrs_s x21, ICH_VTR_EL2
-
- tbnz w21, #29, 6f // 6 bits
- tbz w21, #30, 5f // 5 bits
- // 7 bits
- ldr w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
- msr_s ICH_AP1R3_EL2, x20
- ldr w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
- msr_s ICH_AP1R2_EL2, x19
-6: ldr w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
- msr_s ICH_AP1R1_EL2, x18
-5: ldr w17, [x3, #VGIC_V3_CPU_AP1R]
- msr_s ICH_AP1R0_EL2, x17
-
- tbnz w21, #29, 6f // 6 bits
- tbz w21, #30, 5f // 5 bits
- // 7 bits
- ldr w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
- msr_s ICH_AP0R3_EL2, x20
- ldr w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
- msr_s ICH_AP0R2_EL2, x19
-6: ldr w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
- msr_s ICH_AP0R1_EL2, x18
-5: ldr w17, [x3, #VGIC_V3_CPU_AP0R]
- msr_s ICH_AP0R0_EL2, x17
-
- and w22, w21, #0xf
- mvn w22, w21
- ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4
-
- adr x24, 1f
- add x24, x24, x23
- br x24
-
-1:
- ldr x20, [x3, #LR_OFFSET(15)]
- ldr x19, [x3, #LR_OFFSET(14)]
- ldr x18, [x3, #LR_OFFSET(13)]
- ldr x17, [x3, #LR_OFFSET(12)]
- ldr x16, [x3, #LR_OFFSET(11)]
- ldr x15, [x3, #LR_OFFSET(10)]
- ldr x14, [x3, #LR_OFFSET(9)]
- ldr x13, [x3, #LR_OFFSET(8)]
- ldr x12, [x3, #LR_OFFSET(7)]
- ldr x11, [x3, #LR_OFFSET(6)]
- ldr x10, [x3, #LR_OFFSET(5)]
- ldr x9, [x3, #LR_OFFSET(4)]
- ldr x8, [x3, #LR_OFFSET(3)]
- ldr x7, [x3, #LR_OFFSET(2)]
- ldr x6, [x3, #LR_OFFSET(1)]
- ldr x5, [x3, #LR_OFFSET(0)]
-
- adr x24, 1f
- add x24, x24, x23
- br x24
-
-1:
- msr_s ICH_LR15_EL2, x20
- msr_s ICH_LR14_EL2, x19
- msr_s ICH_LR13_EL2, x18
- msr_s ICH_LR12_EL2, x17
- msr_s ICH_LR11_EL2, x16
- msr_s ICH_LR10_EL2, x15
- msr_s ICH_LR9_EL2, x14
- msr_s ICH_LR8_EL2, x13
- msr_s ICH_LR7_EL2, x12
- msr_s ICH_LR6_EL2, x11
- msr_s ICH_LR5_EL2, x10
- msr_s ICH_LR4_EL2, x9
- msr_s ICH_LR3_EL2, x8
- msr_s ICH_LR2_EL2, x7
- msr_s ICH_LR1_EL2, x6
- msr_s ICH_LR0_EL2, x5
-
- // Ensure that the above will have reached the
- // (re)distributors. This ensure the guest will read
- // the correct values from the memory-mapped interface.
- isb
- dsb sy
-
- // Prevent the guest from touching the GIC system registers
- // if SRE isn't enabled for GICv3 emulation
- cbnz x25, 1f
- mrs_s x5, ICC_SRE_EL2
- and x5, x5, #~ICC_SRE_EL2_ENABLE
- msr_s ICC_SRE_EL2, x5
-1:
-.endm
-
-ENTRY(__save_vgic_v3_state)
- save_vgic_v3_state
- ret
-ENDPROC(__save_vgic_v3_state)
-
-ENTRY(__restore_vgic_v3_state)
- restore_vgic_v3_state
- ret
-ENDPROC(__restore_vgic_v3_state)
-
-ENTRY(__vgic_v3_get_ich_vtr_el2)
- mrs_s x0, ICH_VTR_EL2
- ret
-ENDPROC(__vgic_v3_get_ich_vtr_el2)
-
- .popsection
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 1a811ec..c86b790 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -4,15 +4,16 @@ lib-y := bitops.o clear_user.o delay.o copy_from_user.o \
memcmp.o strcmp.o strncmp.o strlen.o strnlen.o \
strchr.o strrchr.o
-# Tell the compiler to treat all general purpose registers as
-# callee-saved, which allows for efficient runtime patching of the bl
-# instruction in the caller with an atomic instruction when supported by
-# the CPU. Result and argument registers are handled correctly, based on
-# the function prototype.
+# Tell the compiler to treat all general purpose registers (with the
+# exception of the IP registers, which are already handled by the caller
+# in case of a PLT) as callee-saved, which allows for efficient runtime
+# patching of the bl instruction in the caller with an atomic instruction
+# when supported by the CPU. Result and argument registers are handled
+# correctly, based on the function prototype.
lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \
-ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 \
-ffixed-x7 -fcall-saved-x8 -fcall-saved-x9 \
-fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12 \
-fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \
- -fcall-saved-x16 -fcall-saved-x17 -fcall-saved-x18
+ -fcall-saved-x18
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
index a9723c7..5d1cad3 100644
--- a/arch/arm64/lib/clear_user.S
+++ b/arch/arm64/lib/clear_user.S
@@ -33,28 +33,28 @@
* Alignment fixed up by hardware.
*/
ENTRY(__clear_user)
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
mov x2, x1 // save the size for fixup return
subs x1, x1, #8
b.mi 2f
1:
-USER(9f, str xzr, [x0], #8 )
+uao_user_alternative 9f, str, sttr, xzr, x0, 8
subs x1, x1, #8
b.pl 1b
2: adds x1, x1, #4
b.mi 3f
-USER(9f, str wzr, [x0], #4 )
+uao_user_alternative 9f, str, sttr, wzr, x0, 4
sub x1, x1, #4
3: adds x1, x1, #2
b.mi 4f
-USER(9f, strh wzr, [x0], #2 )
+uao_user_alternative 9f, strh, sttrh, wzr, x0, 2
sub x1, x1, #2
4: adds x1, x1, #1
b.mi 5f
-USER(9f, strb wzr, [x0] )
+uao_user_alternative 9f, strb, sttrb, wzr, x0, 0
5: mov x0, #0
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
ret
ENDPROC(__clear_user)
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
index 1be9ef2..17e8306 100644
--- a/arch/arm64/lib/copy_from_user.S
+++ b/arch/arm64/lib/copy_from_user.S
@@ -18,6 +18,7 @@
#include <asm/alternative.h>
#include <asm/assembler.h>
+#include <asm/cache.h>
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
@@ -31,49 +32,58 @@
* Returns:
* x0 - bytes not copied
*/
+
+ .macro ldrb1 ptr, regB, val
+ uao_user_alternative 9998f, ldrb, ldtrb, \ptr, \regB, \val
+ .endm
+
+ .macro strb1 ptr, regB, val
+ strb \ptr, [\regB], \val
+ .endm
+
+ .macro ldrh1 ptr, regB, val
+ uao_user_alternative 9998f, ldrh, ldtrh, \ptr, \regB, \val
+ .endm
+
+ .macro strh1 ptr, regB, val
+ strh \ptr, [\regB], \val
+ .endm
+
+ .macro ldr1 ptr, regB, val
+ uao_user_alternative 9998f, ldr, ldtr, \ptr, \regB, \val
+ .endm
+
+ .macro str1 ptr, regB, val
+ str \ptr, [\regB], \val
+ .endm
+
+ .macro ldp1 ptr, regB, regC, val
+ uao_ldp 9998f, \ptr, \regB, \regC, \val
+ .endm
+
+ .macro stp1 ptr, regB, regC, val
+ stp \ptr, \regB, [\regC], \val
+ .endm
+
+end .req x5
ENTRY(__copy_from_user)
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
- add x5, x1, x2 // upper user buffer boundary
- subs x2, x2, #16
- b.mi 1f
-0:
-USER(9f, ldp x3, x4, [x1], #16)
- subs x2, x2, #16
- stp x3, x4, [x0], #16
- b.pl 0b
-1: adds x2, x2, #8
- b.mi 2f
-USER(9f, ldr x3, [x1], #8 )
- sub x2, x2, #8
- str x3, [x0], #8
-2: adds x2, x2, #4
- b.mi 3f
-USER(9f, ldr w3, [x1], #4 )
- sub x2, x2, #4
- str w3, [x0], #4
-3: adds x2, x2, #2
- b.mi 4f
-USER(9f, ldrh w3, [x1], #2 )
- sub x2, x2, #2
- strh w3, [x0], #2
-4: adds x2, x2, #1
- b.mi 5f
-USER(9f, ldrb w3, [x1] )
- strb w3, [x0]
-5: mov x0, #0
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
+ add end, x0, x2
+#include "copy_template.S"
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
+ mov x0, #0 // Nothing to copy
ret
ENDPROC(__copy_from_user)
.section .fixup,"ax"
.align 2
-9: sub x2, x5, x1
- mov x3, x2
-10: strb wzr, [x0], #1 // zero remaining buffer space
- subs x3, x3, #1
- b.ne 10b
- mov x0, x2 // bytes not copied
+9998:
+ sub x0, end, dst
+9999:
+ strb wzr, [dst], #1 // zero remaining buffer space
+ cmp dst, end
+ b.lo 9999b
ret
.previous
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index 1b94661e..f7292dd0 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -20,6 +20,7 @@
#include <asm/alternative.h>
#include <asm/assembler.h>
+#include <asm/cache.h>
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
@@ -33,44 +34,52 @@
* Returns:
* x0 - bytes not copied
*/
+ .macro ldrb1 ptr, regB, val
+ uao_user_alternative 9998f, ldrb, ldtrb, \ptr, \regB, \val
+ .endm
+
+ .macro strb1 ptr, regB, val
+ uao_user_alternative 9998f, strb, sttrb, \ptr, \regB, \val
+ .endm
+
+ .macro ldrh1 ptr, regB, val
+ uao_user_alternative 9998f, ldrh, ldtrh, \ptr, \regB, \val
+ .endm
+
+ .macro strh1 ptr, regB, val
+ uao_user_alternative 9998f, strh, sttrh, \ptr, \regB, \val
+ .endm
+
+ .macro ldr1 ptr, regB, val
+ uao_user_alternative 9998f, ldr, ldtr, \ptr, \regB, \val
+ .endm
+
+ .macro str1 ptr, regB, val
+ uao_user_alternative 9998f, str, sttr, \ptr, \regB, \val
+ .endm
+
+ .macro ldp1 ptr, regB, regC, val
+ uao_ldp 9998f, \ptr, \regB, \regC, \val
+ .endm
+
+ .macro stp1 ptr, regB, regC, val
+ uao_stp 9998f, \ptr, \regB, \regC, \val
+ .endm
+
+end .req x5
ENTRY(__copy_in_user)
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
- add x5, x0, x2 // upper user buffer boundary
- subs x2, x2, #16
- b.mi 1f
-0:
-USER(9f, ldp x3, x4, [x1], #16)
- subs x2, x2, #16
-USER(9f, stp x3, x4, [x0], #16)
- b.pl 0b
-1: adds x2, x2, #8
- b.mi 2f
-USER(9f, ldr x3, [x1], #8 )
- sub x2, x2, #8
-USER(9f, str x3, [x0], #8 )
-2: adds x2, x2, #4
- b.mi 3f
-USER(9f, ldr w3, [x1], #4 )
- sub x2, x2, #4
-USER(9f, str w3, [x0], #4 )
-3: adds x2, x2, #2
- b.mi 4f
-USER(9f, ldrh w3, [x1], #2 )
- sub x2, x2, #2
-USER(9f, strh w3, [x0], #2 )
-4: adds x2, x2, #1
- b.mi 5f
-USER(9f, ldrb w3, [x1] )
-USER(9f, strb w3, [x0] )
-5: mov x0, #0
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
+ add end, x0, x2
+#include "copy_template.S"
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
+ mov x0, #0
ret
ENDPROC(__copy_in_user)
.section .fixup,"ax"
.align 2
-9: sub x0, x5, x0 // bytes not copied
+9998: sub x0, end, dst // bytes not copied
ret
.previous
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 512b9a7..4c1e700 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -18,6 +18,8 @@
#include <linux/const.h>
#include <asm/assembler.h>
#include <asm/page.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
/*
* Copy a page from src to dest (both are page aligned)
@@ -27,20 +29,65 @@
* x1 - src
*/
ENTRY(copy_page)
- /* Assume cache line size is 64 bytes. */
- prfm pldl1strm, [x1, #64]
-1: ldp x2, x3, [x1]
+alternative_if_not ARM64_HAS_NO_HW_PREFETCH
+ nop
+ nop
+alternative_else
+ # Prefetch two cache lines ahead.
+ prfm pldl1strm, [x1, #128]
+ prfm pldl1strm, [x1, #256]
+alternative_endif
+
+ ldp x2, x3, [x1]
ldp x4, x5, [x1, #16]
ldp x6, x7, [x1, #32]
ldp x8, x9, [x1, #48]
- add x1, x1, #64
- prfm pldl1strm, [x1, #64]
+ ldp x10, x11, [x1, #64]
+ ldp x12, x13, [x1, #80]
+ ldp x14, x15, [x1, #96]
+ ldp x16, x17, [x1, #112]
+
+ mov x18, #(PAGE_SIZE - 128)
+ add x1, x1, #128
+1:
+ subs x18, x18, #128
+
+alternative_if_not ARM64_HAS_NO_HW_PREFETCH
+ nop
+alternative_else
+ prfm pldl1strm, [x1, #384]
+alternative_endif
+
stnp x2, x3, [x0]
+ ldp x2, x3, [x1]
stnp x4, x5, [x0, #16]
+ ldp x4, x5, [x1, #16]
stnp x6, x7, [x0, #32]
+ ldp x6, x7, [x1, #32]
stnp x8, x9, [x0, #48]
- add x0, x0, #64
- tst x1, #(PAGE_SIZE - 1)
- b.ne 1b
+ ldp x8, x9, [x1, #48]
+ stnp x10, x11, [x0, #64]
+ ldp x10, x11, [x1, #64]
+ stnp x12, x13, [x0, #80]
+ ldp x12, x13, [x1, #80]
+ stnp x14, x15, [x0, #96]
+ ldp x14, x15, [x1, #96]
+ stnp x16, x17, [x0, #112]
+ ldp x16, x17, [x1, #112]
+
+ add x0, x0, #128
+ add x1, x1, #128
+
+ b.gt 1b
+
+ stnp x2, x3, [x0]
+ stnp x4, x5, [x0, #16]
+ stnp x6, x7, [x0, #32]
+ stnp x8, x9, [x0, #48]
+ stnp x10, x11, [x0, #64]
+ stnp x12, x13, [x0, #80]
+ stnp x14, x15, [x0, #96]
+ stnp x16, x17, [x0, #112]
+
ret
ENDPROC(copy_page)
diff --git a/arch/arm64/lib/copy_template.S b/arch/arm64/lib/copy_template.S
new file mode 100644
index 0000000..410fbdb
--- /dev/null
+++ b/arch/arm64/lib/copy_template.S
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * and re-licensed under GPLv2 for the Linux kernel. The original code can
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/>.
+ */
+
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ * x0 - dest
+ * x1 - src
+ * x2 - n
+ * Returns:
+ * x0 - dest
+ */
+dstin .req x0
+src .req x1
+count .req x2
+tmp1 .req x3
+tmp1w .req w3
+tmp2 .req x4
+tmp2w .req w4
+dst .req x6
+
+A_l .req x7
+A_h .req x8
+B_l .req x9
+B_h .req x10
+C_l .req x11
+C_h .req x12
+D_l .req x13
+D_h .req x14
+
+ mov dst, dstin
+ cmp count, #16
+ /*When memory length is less than 16, the accessed are not aligned.*/
+ b.lo .Ltiny15
+
+ neg tmp2, src
+ ands tmp2, tmp2, #15/* Bytes to reach alignment. */
+ b.eq .LSrcAligned
+ sub count, count, tmp2
+ /*
+ * Copy the leading memory data from src to dst in an increasing
+ * address order.By this way,the risk of overwritting the source
+ * memory data is eliminated when the distance between src and
+ * dst is less than 16. The memory accesses here are alignment.
+ */
+ tbz tmp2, #0, 1f
+ ldrb1 tmp1w, src, #1
+ strb1 tmp1w, dst, #1
+1:
+ tbz tmp2, #1, 2f
+ ldrh1 tmp1w, src, #2
+ strh1 tmp1w, dst, #2
+2:
+ tbz tmp2, #2, 3f
+ ldr1 tmp1w, src, #4
+ str1 tmp1w, dst, #4
+3:
+ tbz tmp2, #3, .LSrcAligned
+ ldr1 tmp1, src, #8
+ str1 tmp1, dst, #8
+
+.LSrcAligned:
+ cmp count, #64
+ b.ge .Lcpy_over64
+ /*
+ * Deal with small copies quickly by dropping straight into the
+ * exit block.
+ */
+.Ltail63:
+ /*
+ * Copy up to 48 bytes of data. At this point we only need the
+ * bottom 6 bits of count to be accurate.
+ */
+ ands tmp1, count, #0x30
+ b.eq .Ltiny15
+ cmp tmp1w, #0x20
+ b.eq 1f
+ b.lt 2f
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+1:
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+2:
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+.Ltiny15:
+ /*
+ * Prefer to break one ldp/stp into several load/store to access
+ * memory in an increasing address order,rather than to load/store 16
+ * bytes from (src-16) to (dst-16) and to backward the src to aligned
+ * address,which way is used in original cortex memcpy. If keeping
+ * the original memcpy process here, memmove need to satisfy the
+ * precondition that src address is at least 16 bytes bigger than dst
+ * address,otherwise some source data will be overwritten when memove
+ * call memcpy directly. To make memmove simpler and decouple the
+ * memcpy's dependency on memmove, withdrew the original process.
+ */
+ tbz count, #3, 1f
+ ldr1 tmp1, src, #8
+ str1 tmp1, dst, #8
+1:
+ tbz count, #2, 2f
+ ldr1 tmp1w, src, #4
+ str1 tmp1w, dst, #4
+2:
+ tbz count, #1, 3f
+ ldrh1 tmp1w, src, #2
+ strh1 tmp1w, dst, #2
+3:
+ tbz count, #0, .Lexitfunc
+ ldrb1 tmp1w, src, #1
+ strb1 tmp1w, dst, #1
+
+ b .Lexitfunc
+
+.Lcpy_over64:
+ subs count, count, #128
+ b.ge .Lcpy_body_large
+ /*
+ * Less than 128 bytes to copy, so handle 64 here and then jump
+ * to the tail.
+ */
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+ ldp1 B_l, B_h, src, #16
+ ldp1 C_l, C_h, src, #16
+ stp1 B_l, B_h, dst, #16
+ stp1 C_l, C_h, dst, #16
+ ldp1 D_l, D_h, src, #16
+ stp1 D_l, D_h, dst, #16
+
+ tst count, #0x3f
+ b.ne .Ltail63
+ b .Lexitfunc
+
+ /*
+ * Critical loop. Start at a new cache line boundary. Assuming
+ * 64 bytes per line this ensures the entire loop is in one line.
+ */
+ .p2align L1_CACHE_SHIFT
+.Lcpy_body_large:
+ /* pre-get 64 bytes data. */
+ ldp1 A_l, A_h, src, #16
+ ldp1 B_l, B_h, src, #16
+ ldp1 C_l, C_h, src, #16
+ ldp1 D_l, D_h, src, #16
+1:
+ /*
+ * interlace the load of next 64 bytes data block with store of the last
+ * loaded 64 bytes data.
+ */
+ stp1 A_l, A_h, dst, #16
+ ldp1 A_l, A_h, src, #16
+ stp1 B_l, B_h, dst, #16
+ ldp1 B_l, B_h, src, #16
+ stp1 C_l, C_h, dst, #16
+ ldp1 C_l, C_h, src, #16
+ stp1 D_l, D_h, dst, #16
+ ldp1 D_l, D_h, src, #16
+ subs count, count, #64
+ b.ge 1b
+ stp1 A_l, A_h, dst, #16
+ stp1 B_l, B_h, dst, #16
+ stp1 C_l, C_h, dst, #16
+ stp1 D_l, D_h, dst, #16
+
+ tst count, #0x3f
+ b.ne .Ltail63
+.Lexitfunc:
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index a257b47..21faae6 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -18,6 +18,7 @@
#include <asm/alternative.h>
#include <asm/assembler.h>
+#include <asm/cache.h>
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
@@ -31,44 +32,52 @@
* Returns:
* x0 - bytes not copied
*/
+ .macro ldrb1 ptr, regB, val
+ ldrb \ptr, [\regB], \val
+ .endm
+
+ .macro strb1 ptr, regB, val
+ uao_user_alternative 9998f, strb, sttrb, \ptr, \regB, \val
+ .endm
+
+ .macro ldrh1 ptr, regB, val
+ ldrh \ptr, [\regB], \val
+ .endm
+
+ .macro strh1 ptr, regB, val
+ uao_user_alternative 9998f, strh, sttrh, \ptr, \regB, \val
+ .endm
+
+ .macro ldr1 ptr, regB, val
+ ldr \ptr, [\regB], \val
+ .endm
+
+ .macro str1 ptr, regB, val
+ uao_user_alternative 9998f, str, sttr, \ptr, \regB, \val
+ .endm
+
+ .macro ldp1 ptr, regB, regC, val
+ ldp \ptr, \regB, [\regC], \val
+ .endm
+
+ .macro stp1 ptr, regB, regC, val
+ uao_stp 9998f, \ptr, \regB, \regC, \val
+ .endm
+
+end .req x5
ENTRY(__copy_to_user)
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
- add x5, x0, x2 // upper user buffer boundary
- subs x2, x2, #16
- b.mi 1f
-0:
- ldp x3, x4, [x1], #16
- subs x2, x2, #16
-USER(9f, stp x3, x4, [x0], #16)
- b.pl 0b
-1: adds x2, x2, #8
- b.mi 2f
- ldr x3, [x1], #8
- sub x2, x2, #8
-USER(9f, str x3, [x0], #8 )
-2: adds x2, x2, #4
- b.mi 3f
- ldr w3, [x1], #4
- sub x2, x2, #4
-USER(9f, str w3, [x0], #4 )
-3: adds x2, x2, #2
- b.mi 4f
- ldrh w3, [x1], #2
- sub x2, x2, #2
-USER(9f, strh w3, [x0], #2 )
-4: adds x2, x2, #1
- b.mi 5f
- ldrb w3, [x1]
-USER(9f, strb w3, [x0] )
-5: mov x0, #0
-ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
+ add end, x0, x2
+#include "copy_template.S"
+ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN)
+ mov x0, #0
ret
ENDPROC(__copy_to_user)
.section .fixup,"ax"
.align 2
-9: sub x0, x5, x0 // bytes not copied
+9998: sub x0, end, dst // bytes not copied
ret
.previous
diff --git a/arch/arm64/lib/memchr.S b/arch/arm64/lib/memchr.S
index 8636b75..4444c1d 100644
--- a/arch/arm64/lib/memchr.S
+++ b/arch/arm64/lib/memchr.S
@@ -41,4 +41,4 @@ ENTRY(memchr)
ret
2: mov x0, #0
ret
-ENDPROC(memchr)
+ENDPIPROC(memchr)
diff --git a/arch/arm64/lib/memcmp.S b/arch/arm64/lib/memcmp.S
index 6ea0776..2a4e239 100644
--- a/arch/arm64/lib/memcmp.S
+++ b/arch/arm64/lib/memcmp.S
@@ -211,7 +211,7 @@ CPU_LE( lsr tmp2, tmp2, tmp1 )
.Lunequal_proc:
cbz diff, .Lremain8
-/*There is differnence occured in the latest comparison.*/
+/* There is difference occurred in the latest comparison. */
.Lnot_limit:
/*
* For little endian,reverse the low significant equal bits into MSB,then
@@ -255,4 +255,4 @@ CPU_LE( rev data2, data2 )
.Lret0:
mov result, #0
ret
-ENDPROC(memcmp)
+ENDPIPROC(memcmp)
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index 8a9a96d..6761393 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -36,166 +36,42 @@
* Returns:
* x0 - dest
*/
-dstin .req x0
-src .req x1
-count .req x2
-tmp1 .req x3
-tmp1w .req w3
-tmp2 .req x4
-tmp2w .req w4
-tmp3 .req x5
-tmp3w .req w5
-dst .req x6
+ .macro ldrb1 ptr, regB, val
+ ldrb \ptr, [\regB], \val
+ .endm
-A_l .req x7
-A_h .req x8
-B_l .req x9
-B_h .req x10
-C_l .req x11
-C_h .req x12
-D_l .req x13
-D_h .req x14
+ .macro strb1 ptr, regB, val
+ strb \ptr, [\regB], \val
+ .endm
-ENTRY(memcpy)
- mov dst, dstin
- cmp count, #16
- /*When memory length is less than 16, the accessed are not aligned.*/
- b.lo .Ltiny15
+ .macro ldrh1 ptr, regB, val
+ ldrh \ptr, [\regB], \val
+ .endm
- neg tmp2, src
- ands tmp2, tmp2, #15/* Bytes to reach alignment. */
- b.eq .LSrcAligned
- sub count, count, tmp2
- /*
- * Copy the leading memory data from src to dst in an increasing
- * address order.By this way,the risk of overwritting the source
- * memory data is eliminated when the distance between src and
- * dst is less than 16. The memory accesses here are alignment.
- */
- tbz tmp2, #0, 1f
- ldrb tmp1w, [src], #1
- strb tmp1w, [dst], #1
-1:
- tbz tmp2, #1, 2f
- ldrh tmp1w, [src], #2
- strh tmp1w, [dst], #2
-2:
- tbz tmp2, #2, 3f
- ldr tmp1w, [src], #4
- str tmp1w, [dst], #4
-3:
- tbz tmp2, #3, .LSrcAligned
- ldr tmp1, [src],#8
- str tmp1, [dst],#8
+ .macro strh1 ptr, regB, val
+ strh \ptr, [\regB], \val
+ .endm
-.LSrcAligned:
- cmp count, #64
- b.ge .Lcpy_over64
- /*
- * Deal with small copies quickly by dropping straight into the
- * exit block.
- */
-.Ltail63:
- /*
- * Copy up to 48 bytes of data. At this point we only need the
- * bottom 6 bits of count to be accurate.
- */
- ands tmp1, count, #0x30
- b.eq .Ltiny15
- cmp tmp1w, #0x20
- b.eq 1f
- b.lt 2f
- ldp A_l, A_h, [src], #16
- stp A_l, A_h, [dst], #16
-1:
- ldp A_l, A_h, [src], #16
- stp A_l, A_h, [dst], #16
-2:
- ldp A_l, A_h, [src], #16
- stp A_l, A_h, [dst], #16
-.Ltiny15:
- /*
- * Prefer to break one ldp/stp into several load/store to access
- * memory in an increasing address order,rather than to load/store 16
- * bytes from (src-16) to (dst-16) and to backward the src to aligned
- * address,which way is used in original cortex memcpy. If keeping
- * the original memcpy process here, memmove need to satisfy the
- * precondition that src address is at least 16 bytes bigger than dst
- * address,otherwise some source data will be overwritten when memove
- * call memcpy directly. To make memmove simpler and decouple the
- * memcpy's dependency on memmove, withdrew the original process.
- */
- tbz count, #3, 1f
- ldr tmp1, [src], #8
- str tmp1, [dst], #8
-1:
- tbz count, #2, 2f
- ldr tmp1w, [src], #4
- str tmp1w, [dst], #4
-2:
- tbz count, #1, 3f
- ldrh tmp1w, [src], #2
- strh tmp1w, [dst], #2
-3:
- tbz count, #0, .Lexitfunc
- ldrb tmp1w, [src]
- strb tmp1w, [dst]
+ .macro ldr1 ptr, regB, val
+ ldr \ptr, [\regB], \val
+ .endm
-.Lexitfunc:
- ret
+ .macro str1 ptr, regB, val
+ str \ptr, [\regB], \val
+ .endm
-.Lcpy_over64:
- subs count, count, #128
- b.ge .Lcpy_body_large
- /*
- * Less than 128 bytes to copy, so handle 64 here and then jump
- * to the tail.
- */
- ldp A_l, A_h, [src],#16
- stp A_l, A_h, [dst],#16
- ldp B_l, B_h, [src],#16
- ldp C_l, C_h, [src],#16
- stp B_l, B_h, [dst],#16
- stp C_l, C_h, [dst],#16
- ldp D_l, D_h, [src],#16
- stp D_l, D_h, [dst],#16
+ .macro ldp1 ptr, regB, regC, val
+ ldp \ptr, \regB, [\regC], \val
+ .endm
- tst count, #0x3f
- b.ne .Ltail63
- ret
+ .macro stp1 ptr, regB, regC, val
+ stp \ptr, \regB, [\regC], \val
+ .endm
- /*
- * Critical loop. Start at a new cache line boundary. Assuming
- * 64 bytes per line this ensures the entire loop is in one line.
- */
- .p2align L1_CACHE_SHIFT
-.Lcpy_body_large:
- /* pre-get 64 bytes data. */
- ldp A_l, A_h, [src],#16
- ldp B_l, B_h, [src],#16
- ldp C_l, C_h, [src],#16
- ldp D_l, D_h, [src],#16
-1:
- /*
- * interlace the load of next 64 bytes data block with store of the last
- * loaded 64 bytes data.
- */
- stp A_l, A_h, [dst],#16
- ldp A_l, A_h, [src],#16
- stp B_l, B_h, [dst],#16
- ldp B_l, B_h, [src],#16
- stp C_l, C_h, [dst],#16
- ldp C_l, C_h, [src],#16
- stp D_l, D_h, [dst],#16
- ldp D_l, D_h, [src],#16
- subs count, count, #64
- b.ge 1b
- stp A_l, A_h, [dst],#16
- stp B_l, B_h, [dst],#16
- stp C_l, C_h, [dst],#16
- stp D_l, D_h, [dst],#16
-
- tst count, #0x3f
- b.ne .Ltail63
+ .weak memcpy
+ENTRY(__memcpy)
+ENTRY(memcpy)
+#include "copy_template.S"
ret
-ENDPROC(memcpy)
+ENDPIPROC(memcpy)
+ENDPROC(__memcpy)
diff --git a/arch/arm64/lib/memmove.S b/arch/arm64/lib/memmove.S
index 57b19ea2..a5a4459 100644
--- a/arch/arm64/lib/memmove.S
+++ b/arch/arm64/lib/memmove.S
@@ -57,12 +57,14 @@ C_h .req x12
D_l .req x13
D_h .req x14
+ .weak memmove
+ENTRY(__memmove)
ENTRY(memmove)
cmp dstin, src
- b.lo memcpy
+ b.lo __memcpy
add tmp1, src, count
cmp dstin, tmp1
- b.hs memcpy /* No overlap. */
+ b.hs __memcpy /* No overlap. */
add dst, dstin, count
add src, src, count
@@ -194,4 +196,5 @@ ENTRY(memmove)
tst count, #0x3f
b.ne .Ltail63
ret
-ENDPROC(memmove)
+ENDPIPROC(memmove)
+ENDPROC(__memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
index 7c72dfd..f2670a9 100644
--- a/arch/arm64/lib/memset.S
+++ b/arch/arm64/lib/memset.S
@@ -54,6 +54,8 @@ dst .req x8
tmp3w .req w9
tmp3 .req x9
+ .weak memset
+ENTRY(__memset)
ENTRY(memset)
mov dst, dstin /* Preserve return value. */
and A_lw, val, #255
@@ -213,4 +215,5 @@ ENTRY(memset)
ands count, count, zva_bits_x
b.ne .Ltail_maybe_long
ret
-ENDPROC(memset)
+ENDPIPROC(memset)
+ENDPROC(__memset)
diff --git a/arch/arm64/lib/strcmp.S b/arch/arm64/lib/strcmp.S
index 42f828b..471fe61 100644
--- a/arch/arm64/lib/strcmp.S
+++ b/arch/arm64/lib/strcmp.S
@@ -231,4 +231,4 @@ CPU_BE( orr syndrome, diff, has_nul )
lsr data1, data1, #56
sub result, data1, data2, lsr #56
ret
-ENDPROC(strcmp)
+ENDPIPROC(strcmp)
diff --git a/arch/arm64/lib/strlen.S b/arch/arm64/lib/strlen.S
index 987b68b..55ccc8e 100644
--- a/arch/arm64/lib/strlen.S
+++ b/arch/arm64/lib/strlen.S
@@ -123,4 +123,4 @@ CPU_LE( lsr tmp2, tmp2, tmp1 ) /* Shift (tmp1 & 63). */
csinv data1, data1, xzr, le
csel data2, data2, data2a, le
b .Lrealigned
-ENDPROC(strlen)
+ENDPIPROC(strlen)
diff --git a/arch/arm64/lib/strncmp.S b/arch/arm64/lib/strncmp.S
index 0224cf5..e267044 100644
--- a/arch/arm64/lib/strncmp.S
+++ b/arch/arm64/lib/strncmp.S
@@ -307,4 +307,4 @@ CPU_BE( orr syndrome, diff, has_nul )
.Lret0:
mov result, #0
ret
-ENDPROC(strncmp)
+ENDPIPROC(strncmp)
diff --git a/arch/arm64/lib/strnlen.S b/arch/arm64/lib/strnlen.S
index 2ca6657..eae38da 100644
--- a/arch/arm64/lib/strnlen.S
+++ b/arch/arm64/lib/strnlen.S
@@ -168,4 +168,4 @@ CPU_LE( lsr tmp2, tmp2, tmp4 ) /* Shift (tmp1 & 63). */
.Lhit_limit:
mov len, limit
ret
-ENDPROC(strnlen)
+ENDPIPROC(strnlen)
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 773d37a..57f57fd 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,3 +4,6 @@ obj-y := dma-mapping.o extable.o fault.o init.o \
context.o proc.o pageattr.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_ARM64_PTDUMP) += dump.o
+
+obj-$(CONFIG_KASAN) += kasan_init.o
+KASAN_SANITIZE_kasan_init.o := n
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index eb48d5d..6df0706 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -81,24 +81,30 @@ ENDPROC(__flush_cache_user_range)
/*
* __flush_dcache_area(kaddr, size)
*
- * Ensure that the data held in the page kaddr is written back to the
- * page in question.
+ * Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
+ * are cleaned and invalidated to the PoC.
*
* - kaddr - kernel address
* - size - size in question
*/
ENTRY(__flush_dcache_area)
- dcache_line_size x2, x3
- add x1, x0, x1
- sub x3, x2, #1
- bic x0, x0, x3
-1: dc civac, x0 // clean & invalidate D line / unified line
- add x0, x0, x2
- cmp x0, x1
- b.lo 1b
- dsb sy
+ dcache_by_line_op civac, sy, x0, x1, x2, x3
+ ret
+ENDPIPROC(__flush_dcache_area)
+
+/*
+ * __clean_dcache_area_pou(kaddr, size)
+ *
+ * Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
+ * are cleaned to the PoU.
+ *
+ * - kaddr - kernel address
+ * - size - size in question
+ */
+ENTRY(__clean_dcache_area_pou)
+ dcache_by_line_op cvau, ish, x0, x1, x2, x3
ret
-ENDPROC(__flush_dcache_area)
+ENDPROC(__clean_dcache_area_pou)
/*
* __inval_cache_range(start, end)
@@ -131,7 +137,7 @@ __dma_inv_range:
b.lo 2b
dsb sy
ret
-ENDPROC(__inval_cache_range)
+ENDPIPROC(__inval_cache_range)
ENDPROC(__dma_inv_range)
/*
@@ -171,7 +177,7 @@ ENTRY(__dma_flush_range)
b.lo 1b
dsb sy
ret
-ENDPROC(__dma_flush_range)
+ENDPIPROC(__dma_flush_range)
/*
* __dma_map_area(start, size, dir)
@@ -184,7 +190,7 @@ ENTRY(__dma_map_area)
cmp w2, #DMA_FROM_DEVICE
b.eq __dma_inv_range
b __dma_clean_range
-ENDPROC(__dma_map_area)
+ENDPIPROC(__dma_map_area)
/*
* __dma_unmap_area(start, size, dir)
@@ -197,4 +203,4 @@ ENTRY(__dma_unmap_area)
cmp w2, #DMA_TO_DEVICE
b.ne __dma_inv_range
ret
-ENDPROC(__dma_unmap_area)
+ENDPIPROC(__dma_unmap_area)
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index d70ff14..c90c3c5 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -17,135 +17,227 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/init.h>
+#include <linux/bitops.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/percpu.h>
+#include <asm/cpufeature.h>
#include <asm/mmu_context.h>
+#include <asm/smp.h>
#include <asm/tlbflush.h>
-#include <asm/cachetype.h>
-#define asid_bits(reg) \
- (((read_cpuid(ID_AA64MMFR0_EL1) & 0xf0) >> 2) + 8)
+static u32 asid_bits;
+static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
-#define ASID_FIRST_VERSION (1 << MAX_ASID_BITS)
+static atomic64_t asid_generation;
+static unsigned long *asid_map;
-static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
-unsigned int cpu_last_asid = ASID_FIRST_VERSION;
+static DEFINE_PER_CPU(atomic64_t, active_asids);
+static DEFINE_PER_CPU(u64, reserved_asids);
+static cpumask_t tlb_flush_pending;
-/*
- * We fork()ed a process, and we need a new context for the child to run in.
- */
-void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+#define ASID_MASK (~GENMASK(asid_bits - 1, 0))
+#define ASID_FIRST_VERSION (1UL << asid_bits)
+#define NUM_USER_ASIDS ASID_FIRST_VERSION
+
+/* Get the ASIDBits supported by the current CPU */
+static u32 get_cpu_asid_bits(void)
{
- mm->context.id = 0;
- raw_spin_lock_init(&mm->context.id_lock);
+ u32 asid;
+ int fld = cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64MMFR0_EL1),
+ ID_AA64MMFR0_ASID_SHIFT);
+
+ switch (fld) {
+ default:
+ pr_warn("CPU%d: Unknown ASID size (%d); assuming 8-bit\n",
+ smp_processor_id(), fld);
+ /* Fallthrough */
+ case 0:
+ asid = 8;
+ break;
+ case 2:
+ asid = 16;
+ }
+
+ return asid;
}
-static void flush_context(void)
+/* Check if the current cpu's ASIDBits is compatible with asid_bits */
+void verify_cpu_asid_bits(void)
{
- /* set the reserved TTBR0 before flushing the TLB */
- cpu_set_reserved_ttbr0();
- flush_tlb_all();
- if (icache_is_aivivt())
- __flush_icache_all();
+ u32 asid = get_cpu_asid_bits();
+
+ if (asid < asid_bits) {
+ /*
+ * We cannot decrease the ASID size at runtime, so panic if we support
+ * fewer ASID bits than the boot CPU.
+ */
+ pr_crit("CPU%d: smaller ASID size(%u) than boot CPU (%u)\n",
+ smp_processor_id(), asid, asid_bits);
+ update_cpu_boot_status(CPU_PANIC_KERNEL);
+ cpu_park_loop();
+ }
}
-static void set_mm_context(struct mm_struct *mm, unsigned int asid)
+static void flush_context(unsigned int cpu)
{
- unsigned long flags;
+ int i;
+ u64 asid;
+
+ /* Update the list of reserved ASIDs and the ASID bitmap. */
+ bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
/*
- * Locking needed for multi-threaded applications where the same
- * mm->context.id could be set from different CPUs during the
- * broadcast. This function is also called via IPI so the
- * mm->context.id_lock has to be IRQ-safe.
+ * Ensure the generation bump is observed before we xchg the
+ * active_asids.
*/
- raw_spin_lock_irqsave(&mm->context.id_lock, flags);
- if (likely((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS)) {
+ smp_wmb();
+
+ for_each_possible_cpu(i) {
+ asid = atomic64_xchg_relaxed(&per_cpu(active_asids, i), 0);
/*
- * Old version of ASID found. Set the new one and reset
- * mm_cpumask(mm).
+ * 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.
*/
- mm->context.id = asid;
- cpumask_clear(mm_cpumask(mm));
+ if (asid == 0)
+ asid = per_cpu(reserved_asids, i);
+ __set_bit(asid & ~ASID_MASK, asid_map);
+ per_cpu(reserved_asids, i) = asid;
}
- raw_spin_unlock_irqrestore(&mm->context.id_lock, flags);
- /*
- * Set the mm_cpumask(mm) bit for the current CPU.
- */
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+ /* Queue a TLB invalidate and flush the I-cache if necessary. */
+ cpumask_setall(&tlb_flush_pending);
+
+ if (icache_is_aivivt())
+ __flush_icache_all();
}
-/*
- * Reset the ASID on the current CPU. This function call is broadcast from the
- * CPU handling the ASID rollover and holding cpu_asid_lock.
- */
-static void reset_context(void *info)
+static bool check_update_reserved_asid(u64 asid, u64 newasid)
{
- unsigned int asid;
- unsigned int cpu = smp_processor_id();
- struct mm_struct *mm = current->active_mm;
+ int cpu;
+ bool hit = false;
/*
- * current->active_mm could be init_mm for the idle thread immediately
- * after secondary CPU boot or hotplug. TTBR0_EL1 is already set to
- * the reserved value, so no need to reset any context.
+ * Iterate over the set of reserved ASIDs looking for a match.
+ * If we find one, then we can update our mm to use newasid
+ * (i.e. the same ASID in the current generation) but we can't
+ * exit the loop early, since we need to ensure that all copies
+ * of the old ASID are updated to reflect the mm. Failure to do
+ * so could result in us missing the reserved ASID in a future
+ * generation.
*/
- if (mm == &init_mm)
- return;
-
- smp_rmb();
- asid = cpu_last_asid + cpu;
-
- flush_context();
- set_mm_context(mm, asid);
+ for_each_possible_cpu(cpu) {
+ if (per_cpu(reserved_asids, cpu) == asid) {
+ hit = true;
+ per_cpu(reserved_asids, cpu) = newasid;
+ }
+ }
- /* set the new ASID */
- cpu_switch_mm(mm->pgd, mm);
+ return hit;
}
-void __new_context(struct mm_struct *mm)
+static u64 new_context(struct mm_struct *mm, unsigned int cpu)
{
- unsigned int asid;
- unsigned int bits = asid_bits();
+ static u32 cur_idx = 1;
+ u64 asid = atomic64_read(&mm->context.id);
+ u64 generation = atomic64_read(&asid_generation);
- raw_spin_lock(&cpu_asid_lock);
- /*
- * Check the ASID again, in case the change was broadcast from another
- * CPU before we acquired the lock.
- */
- if (!unlikely((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS)) {
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
- raw_spin_unlock(&cpu_asid_lock);
- return;
+ if (asid != 0) {
+ u64 newasid = generation | (asid & ~ASID_MASK);
+
+ /*
+ * If our current ASID was active during a rollover, we
+ * can continue to use it and this was just a false alarm.
+ */
+ if (check_update_reserved_asid(asid, newasid))
+ return newasid;
+
+ /*
+ * 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))
+ return newasid;
}
+
/*
- * At this point, it is guaranteed that the current mm (with an old
- * ASID) isn't active on any other CPU since the ASIDs are changed
- * simultaneously via IPI.
+ * 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 use ASID #0 when setting a
+ * reserved TTBR0 for the init_mm.
*/
- asid = ++cpu_last_asid;
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
+ if (asid != NUM_USER_ASIDS)
+ goto set_asid;
+
+ /* We're out of ASIDs, so increment the global generation count */
+ generation = atomic64_add_return_relaxed(ASID_FIRST_VERSION,
+ &asid_generation);
+ flush_context(cpu);
+
+ /* We have at least 1 ASID per CPU, so this will always succeed */
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
+
+set_asid:
+ __set_bit(asid, asid_map);
+ cur_idx = asid;
+ return asid | generation;
+}
+
+void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
+{
+ unsigned long flags;
+ u64 asid;
+
+ asid = atomic64_read(&mm->context.id);
/*
- * If we've used up all our ASIDs, we need to start a new version and
- * flush the TLB.
+ * The memory ordering here is subtle. We rely on the control
+ * dependency between the generation read and the update of
+ * active_asids to ensure that we are synchronised with a
+ * parallel rollover (i.e. this pairs with the smp_wmb() in
+ * flush_context).
*/
- if (unlikely((asid & ((1 << bits) - 1)) == 0)) {
- /* increment the ASID version */
- cpu_last_asid += (1 << MAX_ASID_BITS) - (1 << bits);
- if (cpu_last_asid == 0)
- cpu_last_asid = ASID_FIRST_VERSION;
- asid = cpu_last_asid + smp_processor_id();
- flush_context();
- smp_wmb();
- smp_call_function(reset_context, NULL, 1);
- cpu_last_asid += NR_CPUS - 1;
+ if (!((asid ^ atomic64_read(&asid_generation)) >> asid_bits)
+ && atomic64_xchg_relaxed(&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);
}
- set_mm_context(mm, asid);
- raw_spin_unlock(&cpu_asid_lock);
+ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
+ local_flush_tlb_all();
+
+ atomic64_set(&per_cpu(active_asids, cpu), asid);
+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
+
+switch_mm_fastpath:
+ cpu_switch_mm(mm->pgd, mm);
+}
+
+static int asids_init(void)
+{
+ asid_bits = get_cpu_asid_bits();
+ /* If we end up with more CPUs than ASIDs, expect things to crash */
+ WARN_ON(NUM_USER_ASIDS < num_possible_cpus());
+ atomic64_set(&asid_generation, ASID_FIRST_VERSION);
+ asid_map = kzalloc(BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(*asid_map),
+ GFP_KERNEL);
+ if (!asid_map)
+ panic("Failed to allocate bitmap for %lu ASIDs\n",
+ NUM_USER_ASIDS);
+
+ pr_info("ASID allocator initialised with %lu entries\n", NUM_USER_ASIDS);
+ return 0;
}
+early_initcall(asids_init);
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index 13bbc3be..22e4cb4 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -24,8 +24,9 @@
void __cpu_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
+ struct page *page = virt_to_page(kto);
copy_page(kto, kfrom);
- __flush_dcache_area(kto, PAGE_SIZE);
+ flush_dcache_page(page);
}
EXPORT_SYMBOL_GPL(__cpu_copy_user_page);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 99224dc..a6e757c 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -18,6 +18,7 @@
*/
#include <linux/gfp.h>
+#include <linux/acpi.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/genalloc.h>
@@ -28,9 +29,6 @@
#include <asm/cacheflush.h>
-struct dma_map_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
-
static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
bool coherent)
{
@@ -42,7 +40,7 @@ static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
static struct gen_pool *atomic_pool;
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
-static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
+static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE;
static int __init early_coherent_pool(char *p)
{
@@ -100,7 +98,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
if (IS_ENABLED(CONFIG_ZONE_DMA) &&
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
flags |= GFP_DMA;
- if (dev_get_cma_area(dev) && (flags & __GFP_WAIT)) {
+ if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
struct page *page;
void *addr;
@@ -148,7 +146,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
size = PAGE_ALIGN(size);
- if (!coherent && !(flags & __GFP_WAIT)) {
+ if (!coherent && !gfpflags_allow_blocking(flags)) {
struct page *page = NULL;
void *addr = __alloc_from_pool(size, &page, flags);
@@ -515,13 +513,7 @@ EXPORT_SYMBOL(dummy_dma_ops);
static int __init arm64_dma_init(void)
{
- int ret;
-
- dma_ops = &swiotlb_dma_ops;
-
- ret = atomic_pool_init();
-
- return ret;
+ return atomic_pool_init();
}
arch_initcall(arm64_dma_init);
@@ -533,3 +525,471 @@ static int __init dma_debug_do_init(void)
return 0;
}
fs_initcall(dma_debug_do_init);
+
+
+#ifdef CONFIG_IOMMU_DMA
+#include <linux/dma-iommu.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+/* Thankfully, all cache ops are by VA so we can ignore phys here */
+static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
+{
+ __dma_flush_range(virt, virt + PAGE_SIZE);
+}
+
+static void *__iommu_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp,
+ struct dma_attrs *attrs)
+{
+ bool coherent = is_device_dma_coherent(dev);
+ int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
+ size_t iosize = size;
+ void *addr;
+
+ if (WARN(!dev, "cannot create IOMMU mapping for unknown device\n"))
+ return NULL;
+
+ size = PAGE_ALIGN(size);
+
+ /*
+ * Some drivers rely on this, and we probably don't want the
+ * possibility of stale kernel data being read by devices anyway.
+ */
+ gfp |= __GFP_ZERO;
+
+ if (gfpflags_allow_blocking(gfp)) {
+ struct page **pages;
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, coherent);
+
+ pages = iommu_dma_alloc(dev, iosize, gfp, ioprot, handle,
+ flush_page);
+ if (!pages)
+ return NULL;
+
+ addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
+ __builtin_return_address(0));
+ if (!addr)
+ iommu_dma_free(dev, pages, iosize, handle);
+ } else {
+ struct page *page;
+ /*
+ * In atomic context we can't remap anything, so we'll only
+ * get the virtually contiguous buffer we need by way of a
+ * physically contiguous allocation.
+ */
+ if (coherent) {
+ page = alloc_pages(gfp, get_order(size));
+ addr = page ? page_address(page) : NULL;
+ } else {
+ addr = __alloc_from_pool(size, &page, gfp);
+ }
+ if (!addr)
+ return NULL;
+
+ *handle = iommu_dma_map_page(dev, page, 0, iosize, ioprot);
+ if (iommu_dma_mapping_error(dev, *handle)) {
+ if (coherent)
+ __free_pages(page, get_order(size));
+ else
+ __free_from_pool(addr, size);
+ addr = NULL;
+ }
+ }
+ return addr;
+}
+
+static void __iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ size_t iosize = size;
+
+ size = PAGE_ALIGN(size);
+ /*
+ * @cpu_addr will be one of 3 things depending on how it was allocated:
+ * - A remapped array of pages from iommu_dma_alloc(), for all
+ * non-atomic allocations.
+ * - A non-cacheable alias from the atomic pool, for atomic
+ * allocations by non-coherent devices.
+ * - A normal lowmem address, for atomic allocations by
+ * coherent devices.
+ * Hence how dodgy the below logic looks...
+ */
+ if (__in_atomic_pool(cpu_addr, size)) {
+ iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+ __free_from_pool(cpu_addr, size);
+ } else if (is_vmalloc_addr(cpu_addr)){
+ struct vm_struct *area = find_vm_area(cpu_addr);
+
+ if (WARN_ON(!area || !area->pages))
+ return;
+ iommu_dma_free(dev, area->pages, iosize, &handle);
+ dma_common_free_remap(cpu_addr, size, VM_USERMAP);
+ } else {
+ iommu_dma_unmap_page(dev, handle, iosize, 0, NULL);
+ __free_pages(virt_to_page(cpu_addr), get_order(size));
+ }
+}
+
+static int __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)
+{
+ struct vm_struct *area;
+ int ret;
+
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
+ is_device_dma_coherent(dev));
+
+ if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ return ret;
+
+ area = find_vm_area(cpu_addr);
+ if (WARN_ON(!area || !area->pages))
+ return -ENXIO;
+
+ return iommu_dma_mmap(area->pages, size, vma);
+}
+
+static int __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 vm_struct *area = find_vm_area(cpu_addr);
+
+ if (WARN_ON(!area || !area->pages))
+ return -ENXIO;
+
+ return sg_alloc_table_from_pages(sgt, area->pages, count, 0, size,
+ GFP_KERNEL);
+}
+
+static void __iommu_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dev_addr, size_t size,
+ enum dma_data_direction dir)
+{
+ phys_addr_t phys;
+
+ if (is_device_dma_coherent(dev))
+ return;
+
+ phys = iommu_iova_to_phys(iommu_get_domain_for_dev(dev), dev_addr);
+ __dma_unmap_area(phys_to_virt(phys), size, dir);
+}
+
+static void __iommu_sync_single_for_device(struct device *dev,
+ dma_addr_t dev_addr, size_t size,
+ enum dma_data_direction dir)
+{
+ phys_addr_t phys;
+
+ if (is_device_dma_coherent(dev))
+ return;
+
+ phys = iommu_iova_to_phys(iommu_get_domain_for_dev(dev), dev_addr);
+ __dma_map_area(phys_to_virt(phys), size, dir);
+}
+
+static dma_addr_t __iommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ bool coherent = is_device_dma_coherent(dev);
+ int prot = dma_direction_to_prot(dir, coherent);
+ dma_addr_t dev_addr = iommu_dma_map_page(dev, page, offset, size, prot);
+
+ if (!iommu_dma_mapping_error(dev, dev_addr) &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __iommu_sync_single_for_device(dev, dev_addr, size, dir);
+
+ return dev_addr;
+}
+
+static void __iommu_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __iommu_sync_single_for_cpu(dev, dev_addr, size, dir);
+
+ iommu_dma_unmap_page(dev, dev_addr, size, dir, attrs);
+}
+
+static void __iommu_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sgl, int nelems,
+ enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ if (is_device_dma_coherent(dev))
+ return;
+
+ for_each_sg(sgl, sg, nelems, i)
+ __dma_unmap_area(sg_virt(sg), sg->length, dir);
+}
+
+static void __iommu_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sgl, int nelems,
+ enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ if (is_device_dma_coherent(dev))
+ return;
+
+ for_each_sg(sgl, sg, nelems, i)
+ __dma_map_area(sg_virt(sg), sg->length, dir);
+}
+
+static int __iommu_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ bool coherent = is_device_dma_coherent(dev);
+
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __iommu_sync_sg_for_device(dev, sgl, nelems, dir);
+
+ return iommu_dma_map_sg(dev, sgl, nelems,
+ dma_direction_to_prot(dir, coherent));
+}
+
+static void __iommu_unmap_sg_attrs(struct device *dev,
+ struct scatterlist *sgl, int nelems,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __iommu_sync_sg_for_cpu(dev, sgl, nelems, dir);
+
+ iommu_dma_unmap_sg(dev, sgl, nelems, dir, attrs);
+}
+
+static struct dma_map_ops iommu_dma_ops = {
+ .alloc = __iommu_alloc_attrs,
+ .free = __iommu_free_attrs,
+ .mmap = __iommu_mmap_attrs,
+ .get_sgtable = __iommu_get_sgtable,
+ .map_page = __iommu_map_page,
+ .unmap_page = __iommu_unmap_page,
+ .map_sg = __iommu_map_sg_attrs,
+ .unmap_sg = __iommu_unmap_sg_attrs,
+ .sync_single_for_cpu = __iommu_sync_single_for_cpu,
+ .sync_single_for_device = __iommu_sync_single_for_device,
+ .sync_sg_for_cpu = __iommu_sync_sg_for_cpu,
+ .sync_sg_for_device = __iommu_sync_sg_for_device,
+ .dma_supported = iommu_dma_supported,
+ .mapping_error = iommu_dma_mapping_error,
+};
+
+/*
+ * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
+ * everything it needs to - the device is only partially created and the
+ * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
+ * need this delayed attachment dance. Once IOMMU probe ordering is sorted
+ * to move the arch_setup_dma_ops() call later, all the notifier bits below
+ * become unnecessary, and will go away.
+ */
+struct iommu_dma_notifier_data {
+ struct list_head list;
+ struct device *dev;
+ const struct iommu_ops *ops;
+ u64 dma_base;
+ u64 size;
+};
+static LIST_HEAD(iommu_dma_masters);
+static DEFINE_MUTEX(iommu_dma_notifier_lock);
+
+/*
+ * Temporarily "borrow" a domain feature flag to to tell if we had to resort
+ * to creating our own domain here, in case we need to clean it up again.
+ */
+#define __IOMMU_DOMAIN_FAKE_DEFAULT (1U << 31)
+
+static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
+ u64 dma_base, u64 size)
+{
+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+
+ /*
+ * Best case: The device is either part of a group which was
+ * already attached to a domain in a previous call, or it's
+ * been put in a default DMA domain by the IOMMU core.
+ */
+ if (!domain) {
+ /*
+ * Urgh. The IOMMU core isn't going to do default domains
+ * for non-PCI devices anyway, until it has some means of
+ * abstracting the entirely implementation-specific
+ * sideband data/SoC topology/unicorn dust that may or
+ * may not differentiate upstream masters.
+ * So until then, HORRIBLE HACKS!
+ */
+ domain = ops->domain_alloc(IOMMU_DOMAIN_DMA);
+ if (!domain)
+ goto out_no_domain;
+
+ domain->ops = ops;
+ domain->type = IOMMU_DOMAIN_DMA | __IOMMU_DOMAIN_FAKE_DEFAULT;
+
+ if (iommu_attach_device(domain, dev))
+ goto out_put_domain;
+ }
+
+ if (iommu_dma_init_domain(domain, dma_base, size))
+ goto out_detach;
+
+ dev->archdata.dma_ops = &iommu_dma_ops;
+ return true;
+
+out_detach:
+ iommu_detach_device(domain, dev);
+out_put_domain:
+ if (domain->type & __IOMMU_DOMAIN_FAKE_DEFAULT)
+ iommu_domain_free(domain);
+out_no_domain:
+ pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+ dev_name(dev));
+ return false;
+}
+
+static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
+ u64 dma_base, u64 size)
+{
+ struct iommu_dma_notifier_data *iommudata;
+
+ iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
+ if (!iommudata)
+ return;
+
+ iommudata->dev = dev;
+ iommudata->ops = ops;
+ iommudata->dma_base = dma_base;
+ iommudata->size = size;
+
+ mutex_lock(&iommu_dma_notifier_lock);
+ list_add(&iommudata->list, &iommu_dma_masters);
+ mutex_unlock(&iommu_dma_notifier_lock);
+}
+
+static int __iommu_attach_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct iommu_dma_notifier_data *master, *tmp;
+
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+ mutex_lock(&iommu_dma_notifier_lock);
+ list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
+ if (do_iommu_attach(master->dev, master->ops,
+ master->dma_base, master->size)) {
+ list_del(&master->list);
+ kfree(master);
+ }
+ }
+ mutex_unlock(&iommu_dma_notifier_lock);
+ return 0;
+}
+
+static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
+{
+ struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
+ int ret;
+
+ if (!nb)
+ return -ENOMEM;
+ /*
+ * The device must be attached to a domain before the driver probe
+ * routine gets a chance to start allocating DMA buffers. However,
+ * the IOMMU driver also needs a chance to configure the iommu_group
+ * via its add_device callback first, so we need to make the attach
+ * happen between those two points. Since the IOMMU core uses a bus
+ * notifier with default priority for add_device, do the same but
+ * with a lower priority to ensure the appropriate ordering.
+ */
+ nb->notifier_call = __iommu_attach_notifier;
+ nb->priority = -100;
+
+ ret = bus_register_notifier(bus, nb);
+ if (ret) {
+ pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
+ bus->name);
+ kfree(nb);
+ }
+ return ret;
+}
+
+static int __init __iommu_dma_init(void)
+{
+ int ret;
+
+ ret = iommu_dma_init();
+ if (!ret)
+ ret = register_iommu_dma_ops_notifier(&platform_bus_type);
+ if (!ret)
+ ret = register_iommu_dma_ops_notifier(&amba_bustype);
+
+ /* handle devices queued before this arch_initcall */
+ if (!ret)
+ __iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL);
+ return ret;
+}
+arch_initcall(__iommu_dma_init);
+
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *ops)
+{
+ struct iommu_group *group;
+
+ if (!ops)
+ return;
+ /*
+ * TODO: As a concession to the future, we're ready to handle being
+ * called both early and late (i.e. after bus_add_device). Once all
+ * the platform bus code is reworked to call us late and the notifier
+ * junk above goes away, move the body of do_iommu_attach here.
+ */
+ group = iommu_group_get(dev);
+ if (group) {
+ do_iommu_attach(dev, ops, dma_base, size);
+ iommu_group_put(group);
+ } else {
+ queue_iommu_attach(dev, ops, dma_base, size);
+ }
+}
+
+void arch_teardown_dma_ops(struct device *dev)
+{
+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+
+ if (domain) {
+ iommu_detach_device(domain, dev);
+ if (domain->type & __IOMMU_DOMAIN_FAKE_DEFAULT)
+ iommu_domain_free(domain);
+ }
+
+ dev->archdata.dma_ops = NULL;
+}
+
+#else
+
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu)
+{ }
+
+#endif /* CONFIG_IOMMU_DMA */
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu, bool coherent)
+{
+ if (!dev->archdata.dma_ops)
+ dev->archdata.dma_ops = &swiotlb_dma_ops;
+
+ dev->archdata.dma_coherent = coherent;
+ __iommu_setup_dma_ops(dev, dma_base, size, iommu);
+}
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index f3d6221..f9271cb 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -27,15 +27,15 @@
#include <asm/pgtable.h>
#include <asm/pgtable-hwdef.h>
-#define LOWEST_ADDR (UL(0xffffffffffffffff) << VA_BITS)
-
struct addr_marker {
unsigned long start_address;
const char *name;
};
enum address_markers_idx {
- VMALLOC_START_NR = 0,
+ MODULES_START_NR = 0,
+ MODULES_END_NR,
+ VMALLOC_START_NR,
VMALLOC_END_NR,
#ifdef CONFIG_SPARSEMEM_VMEMMAP
VMEMMAP_START_NR,
@@ -45,12 +45,12 @@ enum address_markers_idx {
FIXADDR_END_NR,
PCI_START_NR,
PCI_END_NR,
- MODULES_START_NR,
- MODUELS_END_NR,
KERNEL_SPACE_NR,
};
static struct addr_marker address_markers[] = {
+ { MODULES_VADDR, "Modules start" },
+ { MODULES_END, "Modules end" },
{ VMALLOC_START, "vmalloc() Area" },
{ VMALLOC_END, "vmalloc() End" },
#ifdef CONFIG_SPARSEMEM_VMEMMAP
@@ -61,12 +61,16 @@ static struct addr_marker address_markers[] = {
{ FIXADDR_TOP, "Fixmap end" },
{ PCI_IO_START, "PCI I/O start" },
{ PCI_IO_END, "PCI I/O end" },
- { MODULES_VADDR, "Modules start" },
- { MODULES_END, "Modules end" },
- { PAGE_OFFSET, "Kernel Mapping" },
+ { PAGE_OFFSET, "Linear Mapping" },
{ -1, NULL },
};
+/*
+ * The page dumper groups page table entries of the same type into a single
+ * description. It uses pg_state to track the range information while
+ * iterating over the pte entries. When the continuity is broken it then
+ * dumps out a description of the range.
+ */
struct pg_state {
struct seq_file *seq;
const struct addr_marker *marker;
@@ -84,6 +88,11 @@ struct prot_bits {
static const struct prot_bits pte_bits[] = {
{
+ .mask = PTE_VALID,
+ .val = PTE_VALID,
+ .set = " ",
+ .clear = "F",
+ }, {
.mask = PTE_USER,
.val = PTE_USER,
.set = "USR",
@@ -114,6 +123,16 @@ static const struct prot_bits pte_bits[] = {
.set = "NG",
.clear = " ",
}, {
+ .mask = PTE_CONT,
+ .val = PTE_CONT,
+ .set = "CON",
+ .clear = " ",
+ }, {
+ .mask = PTE_TABLE_BIT,
+ .val = PTE_TABLE_BIT,
+ .set = " ",
+ .clear = "BLK",
+ }, {
.mask = PTE_UXN,
.val = PTE_UXN,
.set = "UXN",
@@ -198,7 +217,7 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
unsigned long delta;
if (st->current_prot) {
- seq_printf(st->seq, "0x%16lx-0x%16lx ",
+ seq_printf(st->seq, "0x%016lx-0x%016lx ",
st->start_address, addr);
delta = (addr - st->start_address) >> 10;
@@ -300,7 +319,7 @@ static int ptdump_show(struct seq_file *m, void *v)
.marker = address_markers,
};
- walk_pgd(&st, &init_mm, LOWEST_ADDR);
+ walk_pgd(&st, &init_mm, VA_START);
note_page(&st, 0, 0, 0);
return 0;
diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index 7944427..81acd47 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs)
fixup = search_exception_tables(instruction_pointer(regs));
if (fixup)
- regs->pc = fixup->fixup;
+ regs->pc = (unsigned long)&fixup->fixup + fixup->fixup;
return fixup != NULL;
}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 9fadf6d..95df28b 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -192,6 +192,14 @@ out:
return fault;
}
+static inline int permission_fault(unsigned int esr)
+{
+ unsigned int ec = (esr & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT;
+ unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE;
+
+ return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM);
+}
+
static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
@@ -225,12 +233,13 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
mm_flags |= FAULT_FLAG_WRITE;
}
- /*
- * PAN bit set implies the fault happened in kernel space, but not
- * in the arch's user access functions.
- */
- if (IS_ENABLED(CONFIG_ARM64_PAN) && (regs->pstate & PSR_PAN_BIT))
- goto no_context;
+ if (permission_fault(esr) && (addr < USER_DS)) {
+ if (get_fs() == KERNEL_DS)
+ die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
+
+ if (!search_exception_tables(regs->pc))
+ die("Accessing user space memory outside uaccess.h routines", regs, esr);
+ }
/*
* As per x86, we may deadlock here. However, since the kernel only
@@ -295,7 +304,7 @@ retry:
up_read(&mm->mmap_sem);
/*
- * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
+ * Handle the "normal" case first - VM_FAULT_MAJOR
*/
if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
VM_FAULT_BADACCESS))))
@@ -371,6 +380,13 @@ static int __kprobes do_translation_fault(unsigned long addr,
return 0;
}
+static int do_alignment_fault(unsigned long addr, unsigned int esr,
+ struct pt_regs *regs)
+{
+ do_bad_area(addr, esr, regs);
+ return 0;
+}
+
/*
* This abort handler always returns "fault".
*/
@@ -393,16 +409,16 @@ static struct fault_info {
{ 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, SIGBUS, 0, "unknown 8" },
{ do_page_fault, 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, SIGBUS, 0, "unknown 12" },
{ do_page_fault, 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 17" },
{ do_bad, SIGBUS, 0, "unknown 18" },
{ do_bad, SIGBUS, 0, "unknown 19" },
{ do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
@@ -410,16 +426,16 @@ static struct fault_info {
{ 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 25" },
{ 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, "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_alignment_fault, SIGBUS, BUS_ADRALN, "alignment fault" },
+ { do_bad, SIGBUS, 0, "unknown 34" },
{ do_bad, SIGBUS, 0, "unknown 35" },
{ do_bad, SIGBUS, 0, "unknown 36" },
{ do_bad, SIGBUS, 0, "unknown 37" },
@@ -433,21 +449,21 @@ static struct fault_info {
{ 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, "TLB conflict abort" },
{ 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, "implementation fault (unsupported exclusive)" },
{ 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 58" },
{ 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, "section domain fault" },
+ { do_bad, SIGBUS, 0, "page domain fault" },
{ do_bad, SIGBUS, 0, "unknown 63" },
};
@@ -556,8 +572,21 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
}
#ifdef CONFIG_ARM64_PAN
-void cpu_enable_pan(void)
+void cpu_enable_pan(void *__unused)
{
config_sctlr_el1(SCTLR_EL1_SPAN, 0);
}
#endif /* CONFIG_ARM64_PAN */
+
+#ifdef CONFIG_ARM64_UAO
+/*
+ * Kernel threads have fs=KERNEL_DS by default, and don't need to call
+ * set_fs(), devtmpfs in particular relies on this behaviour.
+ * We need to enable the feature at runtime (instead of adding it to
+ * PSR_MODE_EL1h) as the feature may not be implemented by the cpu.
+ */
+void cpu_enable_uao(void *__unused)
+{
+ asm(SET_PSTATE_UAO(1));
+}
+#endif /* CONFIG_ARM64_UAO */
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index c26b804..60585bd 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -34,19 +34,24 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
__flush_icache_all();
}
+static void sync_icache_aliases(void *kaddr, unsigned long len)
+{
+ unsigned long addr = (unsigned long)kaddr;
+
+ if (icache_is_aliasing()) {
+ __clean_dcache_area_pou(kaddr, len);
+ __flush_icache_all();
+ } else {
+ flush_icache_range(addr, addr + len);
+ }
+}
+
static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
unsigned long uaddr, void *kaddr,
unsigned long len)
{
- if (vma->vm_flags & VM_EXEC) {
- unsigned long addr = (unsigned long)kaddr;
- if (icache_is_aliasing()) {
- __flush_dcache_area(kaddr, len);
- __flush_icache_all();
- } else {
- flush_icache_range(addr, addr + len);
- }
- }
+ if (vma->vm_flags & VM_EXEC)
+ sync_icache_aliases(kaddr, len);
}
/*
@@ -74,13 +79,11 @@ void __sync_icache_dcache(pte_t pte, unsigned long addr)
if (!page_mapping(page))
return;
- if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
- __flush_dcache_area(page_address(page),
- PAGE_SIZE << compound_order(page));
+ if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+ sync_icache_aliases(page_address(page),
+ PAGE_SIZE << compound_order(page));
+ else if (icache_is_aivivt())
__flush_icache_all();
- } else if (icache_is_aivivt()) {
- __flush_icache_all();
- }
}
/*
@@ -99,19 +102,3 @@ EXPORT_SYMBOL(flush_dcache_page);
* Additional functions defined in assembly.
*/
EXPORT_SYMBOL(flush_icache_range);
-
-#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/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 383b03f..589fd28 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -41,15 +41,273 @@ int pud_huge(pud_t pud)
#endif
}
+static int find_num_contig(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, size_t *pgsize)
+{
+ pgd_t *pgd = pgd_offset(mm, addr);
+ pud_t *pud;
+ pmd_t *pmd;
+
+ *pgsize = PAGE_SIZE;
+ if (!pte_cont(pte))
+ return 1;
+ if (!pgd_present(*pgd)) {
+ VM_BUG_ON(!pgd_present(*pgd));
+ return 1;
+ }
+ pud = pud_offset(pgd, addr);
+ if (!pud_present(*pud)) {
+ VM_BUG_ON(!pud_present(*pud));
+ return 1;
+ }
+ pmd = pmd_offset(pud, addr);
+ if (!pmd_present(*pmd)) {
+ VM_BUG_ON(!pmd_present(*pmd));
+ return 1;
+ }
+ if ((pte_t *)pmd == ptep) {
+ *pgsize = PMD_SIZE;
+ return CONT_PMDS;
+ }
+ return CONT_PTES;
+}
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ size_t pgsize;
+ int i;
+ int ncontig = find_num_contig(mm, addr, ptep, pte, &pgsize);
+ unsigned long pfn;
+ pgprot_t hugeprot;
+
+ if (ncontig == 1) {
+ set_pte_at(mm, addr, ptep, pte);
+ return;
+ }
+
+ pfn = pte_pfn(pte);
+ hugeprot = __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
+ for (i = 0; i < ncontig; i++) {
+ pr_debug("%s: set pte %p to 0x%llx\n", __func__, ptep,
+ pte_val(pfn_pte(pfn, hugeprot)));
+ set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+ ptep++;
+ pfn += pgsize >> PAGE_SHIFT;
+ addr += pgsize;
+ }
+}
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+ unsigned long addr, unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pte_t *pte = NULL;
+
+ pr_debug("%s: addr:0x%lx sz:0x%lx\n", __func__, addr, sz);
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ if (!pud)
+ return NULL;
+
+ if (sz == PUD_SIZE) {
+ pte = (pte_t *)pud;
+ } else if (sz == (PAGE_SIZE * CONT_PTES)) {
+ pmd_t *pmd = pmd_alloc(mm, pud, addr);
+
+ WARN_ON(addr & (sz - 1));
+ /*
+ * Note that if this code were ever ported to the
+ * 32-bit arm platform then it will cause trouble in
+ * the case where CONFIG_HIGHPTE is set, since there
+ * will be no pte_unmap() to correspond with this
+ * pte_alloc_map().
+ */
+ pte = pte_alloc_map(mm, pmd, addr);
+ } else if (sz == PMD_SIZE) {
+ if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
+ pud_none(*pud))
+ pte = huge_pmd_share(mm, addr, pud);
+ else
+ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ } else if (sz == (PMD_SIZE * CONT_PMDS)) {
+ pmd_t *pmd;
+
+ pmd = pmd_alloc(mm, pud, addr);
+ WARN_ON(addr & (sz - 1));
+ return (pte_t *)pmd;
+ }
+
+ pr_debug("%s: addr:0x%lx sz:0x%lx ret pte=%p/0x%llx\n", __func__, addr,
+ sz, pte, pte_val(*pte));
+ return pte;
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd = NULL;
+ pte_t *pte = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ pr_debug("%s: addr:0x%lx pgd:%p\n", __func__, addr, pgd);
+ if (!pgd_present(*pgd))
+ return NULL;
+ pud = pud_offset(pgd, addr);
+ if (!pud_present(*pud))
+ return NULL;
+
+ if (pud_huge(*pud))
+ return (pte_t *)pud;
+ pmd = pmd_offset(pud, addr);
+ if (!pmd_present(*pmd))
+ return NULL;
+
+ if (pte_cont(pmd_pte(*pmd))) {
+ pmd = pmd_offset(
+ pud, (addr & CONT_PMD_MASK));
+ return (pte_t *)pmd;
+ }
+ if (pmd_huge(*pmd))
+ return (pte_t *)pmd;
+ pte = pte_offset_kernel(pmd, addr);
+ if (pte_present(*pte) && pte_cont(*pte)) {
+ pte = pte_offset_kernel(
+ pmd, (addr & CONT_PTE_MASK));
+ return pte;
+ }
+ return NULL;
+}
+
+pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
+ struct page *page, int writable)
+{
+ size_t pagesize = huge_page_size(hstate_vma(vma));
+
+ if (pagesize == CONT_PTE_SIZE) {
+ entry = pte_mkcont(entry);
+ } else if (pagesize == CONT_PMD_SIZE) {
+ entry = pmd_pte(pmd_mkcont(pte_pmd(entry)));
+ } else if (pagesize != PUD_SIZE && pagesize != PMD_SIZE) {
+ pr_warn("%s: unrecognized huge page size 0x%lx\n",
+ __func__, pagesize);
+ }
+ return entry;
+}
+
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ pte_t pte;
+
+ if (pte_cont(*ptep)) {
+ int ncontig, i;
+ size_t pgsize;
+ pte_t *cpte;
+ bool is_dirty = false;
+
+ cpte = huge_pte_offset(mm, addr);
+ ncontig = find_num_contig(mm, addr, cpte, *cpte, &pgsize);
+ /* save the 1st pte to return */
+ pte = ptep_get_and_clear(mm, addr, cpte);
+ for (i = 1; i < ncontig; ++i) {
+ /*
+ * If HW_AFDBM is enabled, then the HW could
+ * turn on the dirty bit for any of the page
+ * in the set, so check them all.
+ */
+ ++cpte;
+ if (pte_dirty(ptep_get_and_clear(mm, addr, cpte)))
+ is_dirty = true;
+ }
+ if (is_dirty)
+ return pte_mkdirty(pte);
+ else
+ return pte;
+ } else {
+ return ptep_get_and_clear(mm, addr, ptep);
+ }
+}
+
+int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ pte_t *cpte;
+
+ if (pte_cont(pte)) {
+ int ncontig, i, changed = 0;
+ size_t pgsize = 0;
+ unsigned long pfn = pte_pfn(pte);
+ /* Select all bits except the pfn */
+ pgprot_t hugeprot =
+ __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^
+ pte_val(pte));
+
+ cpte = huge_pte_offset(vma->vm_mm, addr);
+ pfn = pte_pfn(*cpte);
+ ncontig = find_num_contig(vma->vm_mm, addr, cpte,
+ *cpte, &pgsize);
+ for (i = 0; i < ncontig; ++i, ++cpte) {
+ changed = ptep_set_access_flags(vma, addr, cpte,
+ pfn_pte(pfn,
+ hugeprot),
+ dirty);
+ pfn += pgsize >> PAGE_SHIFT;
+ }
+ return changed;
+ } else {
+ return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+ }
+}
+
+void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ if (pte_cont(*ptep)) {
+ int ncontig, i;
+ pte_t *cpte;
+ size_t pgsize = 0;
+
+ cpte = huge_pte_offset(mm, addr);
+ ncontig = find_num_contig(mm, addr, cpte, *cpte, &pgsize);
+ for (i = 0; i < ncontig; ++i, ++cpte)
+ ptep_set_wrprotect(mm, addr, cpte);
+ } else {
+ ptep_set_wrprotect(mm, addr, ptep);
+ }
+}
+
+void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ if (pte_cont(*ptep)) {
+ int ncontig, i;
+ pte_t *cpte;
+ size_t pgsize = 0;
+
+ cpte = huge_pte_offset(vma->vm_mm, addr);
+ ncontig = find_num_contig(vma->vm_mm, addr, cpte,
+ *cpte, &pgsize);
+ for (i = 0; i < ncontig; ++i, ++cpte)
+ ptep_clear_flush(vma, addr, cpte);
+ } else {
+ ptep_clear_flush(vma, addr, ptep);
+ }
+}
+
static __init int setup_hugepagesz(char *opt)
{
unsigned long ps = memparse(opt, &opt);
+
if (ps == PMD_SIZE) {
hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
} else if (ps == PUD_SIZE) {
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
} else {
- pr_err("hugepagesz: Unsupported page size %lu M\n", ps >> 20);
+ pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10);
return 0;
}
return 1;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5c0680..61a38ea 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,7 +35,10 @@
#include <linux/efi.h>
#include <linux/swiotlb.h>
+#include <asm/boot.h>
#include <asm/fixmap.h>
+#include <asm/kasan.h>
+#include <asm/kernel-pgtable.h>
#include <asm/memory.h>
#include <asm/sections.h>
#include <asm/setup.h>
@@ -45,7 +48,13 @@
#include "mm.h"
-phys_addr_t memstart_addr __read_mostly = 0;
+/*
+ * We need to be able to catch inadvertent references to memstart_addr
+ * that occur (potentially in generic code) before arm64_memblock_init()
+ * executes, which assigns it its actual value. So use a default value
+ * that cannot be mistaken for a real physical address.
+ */
+s64 memstart_addr __read_mostly = -1;
phys_addr_t arm64_dma_phys_limit __read_mostly;
#ifdef CONFIG_BLK_DEV_INITRD
@@ -58,8 +67,8 @@ static int __init early_initrd(char *p)
if (*endp == ',') {
size = memparse(endp + 1, NULL);
- initrd_start = (unsigned long)__va(start);
- initrd_end = (unsigned long)__va(start + size);
+ initrd_start = start;
+ initrd_end = start + size;
}
return 0;
}
@@ -71,7 +80,7 @@ early_param("initrd", early_initrd);
* currently assumes that for memory starting above 4G, 32-bit devices will
* use a DMA offset.
*/
-static phys_addr_t max_zone_dma_phys(void)
+static phys_addr_t __init max_zone_dma_phys(void)
{
phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
return min(offset + (1ULL << 32), memblock_end_of_DRAM());
@@ -86,10 +95,10 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
memset(zone_size, 0, sizeof(zone_size));
/* 4GB maximum for 32-bit only capable devices */
- if (IS_ENABLED(CONFIG_ZONE_DMA)) {
- max_dma = PFN_DOWN(arm64_dma_phys_limit);
- zone_size[ZONE_DMA] = max_dma - min;
- }
+#ifdef CONFIG_ZONE_DMA
+ max_dma = PFN_DOWN(arm64_dma_phys_limit);
+ zone_size[ZONE_DMA] = max_dma - min;
+#endif
zone_size[ZONE_NORMAL] = max - max_dma;
memcpy(zhole_size, zone_size, sizeof(zhole_size));
@@ -101,11 +110,12 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
if (start >= max)
continue;
- if (IS_ENABLED(CONFIG_ZONE_DMA) && start < max_dma) {
+#ifdef CONFIG_ZONE_DMA
+ if (start < max_dma) {
unsigned long dma_end = min(end, max_dma);
zhole_size[ZONE_DMA] -= dma_end - start;
}
-
+#endif
if (end > max_dma) {
unsigned long normal_end = min(end, max);
unsigned long normal_start = max(start, max_dma);
@@ -119,17 +129,17 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
int pfn_valid(unsigned long pfn)
{
- return memblock_is_memory(pfn << PAGE_SHIFT);
+ return memblock_is_map_memory(pfn << PAGE_SHIFT);
}
EXPORT_SYMBOL(pfn_valid);
#endif
#ifndef CONFIG_SPARSEMEM
-static void arm64_memory_present(void)
+static void __init arm64_memory_present(void)
{
}
#else
-static void arm64_memory_present(void)
+static void __init arm64_memory_present(void)
{
struct memblock_region *reg;
@@ -158,7 +168,57 @@ early_param("mem", early_mem);
void __init arm64_memblock_init(void)
{
- memblock_enforce_memory_limit(memory_limit);
+ const s64 linear_region_size = -(s64)PAGE_OFFSET;
+
+ /*
+ * Ensure that the linear region takes up exactly half of the kernel
+ * virtual address space. This way, we can distinguish a linear address
+ * from a kernel/module/vmalloc address by testing a single bit.
+ */
+ BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
+
+ /*
+ * Select a suitable value for the base of physical memory.
+ */
+ memstart_addr = round_down(memblock_start_of_DRAM(),
+ ARM64_MEMSTART_ALIGN);
+
+ /*
+ * Remove the memory that we will not be able to cover with the
+ * linear mapping. Take care not to clip the kernel which may be
+ * high in memory.
+ */
+ memblock_remove(max_t(u64, memstart_addr + linear_region_size, __pa(_end)),
+ ULLONG_MAX);
+ if (memblock_end_of_DRAM() > linear_region_size)
+ memblock_remove(0, memblock_end_of_DRAM() - linear_region_size);
+
+ /*
+ * Apply the memory limit if it was set. Since the kernel may be loaded
+ * high up in memory, add back the kernel region that must be accessible
+ * via the linear mapping.
+ */
+ if (memory_limit != (phys_addr_t)ULLONG_MAX) {
+ memblock_enforce_memory_limit(memory_limit);
+ memblock_add(__pa(_text), (u64)(_end - _text));
+ }
+
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+ extern u16 memstart_offset_seed;
+ u64 range = linear_region_size -
+ (memblock_end_of_DRAM() - memblock_start_of_DRAM());
+
+ /*
+ * If the size of the linear region exceeds, by a sufficient
+ * margin, the size of the region that the available physical
+ * memory spans, randomize the linear region as well.
+ */
+ if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
+ range = range / ARM64_MEMSTART_ALIGN + 1;
+ memstart_addr -= ARM64_MEMSTART_ALIGN *
+ ((range * memstart_offset_seed) >> 16);
+ }
+ }
/*
* Register the kernel text, kernel data, initrd, and initial
@@ -166,8 +226,13 @@ void __init arm64_memblock_init(void)
*/
memblock_reserve(__pa(_text), _end - _text);
#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
+ if (initrd_start) {
+ memblock_reserve(initrd_start, initrd_end - initrd_start);
+
+ /* the generic initrd code expects virtual addresses */
+ initrd_start = __phys_to_virt(initrd_start);
+ initrd_end = __phys_to_virt(initrd_end);
+ }
#endif
early_init_fdt_scan_reserved_mem();
@@ -298,32 +363,41 @@ void __init mem_init(void)
#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
pr_notice("Virtual kernel memory layout:\n"
+#ifdef CONFIG_KASAN
+ " kasan : 0x%16lx - 0x%16lx (%6ld GB)\n"
+#endif
+ " modules : 0x%16lx - 0x%16lx (%6ld MB)\n"
" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n"
+ " .text : 0x%p" " - 0x%p" " (%6ld KB)\n"
+ " .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n"
+ " .init : 0x%p" " - 0x%p" " (%6ld KB)\n"
+ " .data : 0x%p" " - 0x%p" " (%6ld KB)\n"
#ifdef CONFIG_SPARSEMEM_VMEMMAP
" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n"
" 0x%16lx - 0x%16lx (%6ld MB actual)\n"
#endif
" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n"
" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n"
- " modules : 0x%16lx - 0x%16lx (%6ld MB)\n"
- " memory : 0x%16lx - 0x%16lx (%6ld MB)\n"
- " .init : 0x%p" " - 0x%p" " (%6ld KB)\n"
- " .text : 0x%p" " - 0x%p" " (%6ld KB)\n"
- " .data : 0x%p" " - 0x%p" " (%6ld KB)\n",
+ " memory : 0x%16lx - 0x%16lx (%6ld MB)\n",
+#ifdef CONFIG_KASAN
+ MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
+#endif
+ MLM(MODULES_VADDR, MODULES_END),
MLG(VMALLOC_START, VMALLOC_END),
+ MLK_ROUNDUP(_text, __start_rodata),
+ MLK_ROUNDUP(__start_rodata, _etext),
+ MLK_ROUNDUP(__init_begin, __init_end),
+ MLK_ROUNDUP(_sdata, _edata),
#ifdef CONFIG_SPARSEMEM_VMEMMAP
- MLG((unsigned long)vmemmap,
- (unsigned long)vmemmap + VMEMMAP_SIZE),
- MLM((unsigned long)virt_to_page(PAGE_OFFSET),
+ MLG(VMEMMAP_START,
+ VMEMMAP_START + VMEMMAP_SIZE),
+ MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
(unsigned long)virt_to_page(high_memory)),
#endif
MLK(FIXADDR_START, FIXADDR_TOP),
MLM(PCI_IO_START, PCI_IO_END),
- MLM(MODULES_VADDR, MODULES_END),
- MLM(PAGE_OFFSET, (unsigned long)high_memory),
- MLK_ROUNDUP(__init_begin, __init_end),
- MLK_ROUNDUP(_text, _etext),
- MLK_ROUNDUP(_sdata, _edata));
+ MLM(__phys_to_virt(memblock_start_of_DRAM()),
+ (unsigned long)high_memory));
#undef MLK
#undef MLM
@@ -336,8 +410,6 @@ void __init mem_init(void)
#ifdef CONFIG_COMPAT
BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64);
#endif
- BUILD_BUG_ON(TASK_SIZE_64 > MODULES_VADDR);
- BUG_ON(TASK_SIZE_64 > MODULES_VADDR);
if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
extern int sysctl_overcommit_memory;
@@ -351,9 +423,8 @@ void __init mem_init(void)
void free_initmem(void)
{
- fixup_init();
free_initmem_default(0);
- free_alternatives_memory();
+ fixup_init();
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -374,3 +445,28 @@ static int __init keepinitrd_setup(char *__unused)
__setup("keepinitrd", keepinitrd_setup);
#endif
+
+/*
+ * Dump out memory limit information on panic.
+ */
+static int dump_mem_limit(struct notifier_block *self, unsigned long v, void *p)
+{
+ if (memory_limit != (phys_addr_t)ULLONG_MAX) {
+ pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20);
+ } else {
+ pr_emerg("Memory Limit: none\n");
+ }
+ return 0;
+}
+
+static struct notifier_block mem_limit_notifier = {
+ .notifier_call = dump_mem_limit,
+};
+
+static int __init register_mem_limit_dumper(void)
+{
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &mem_limit_notifier);
+ return 0;
+}
+__initcall(register_mem_limit_dumper);
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
new file mode 100644
index 0000000..757009d
--- /dev/null
+++ b/arch/arm64/mm/kasan_init.c
@@ -0,0 +1,210 @@
+/*
+ * This file contains kasan initialization code for ARM64.
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@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 pr_fmt(fmt) "kasan: " fmt
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/start_kernel.h>
+
+#include <asm/mmu_context.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+
+static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+
+static void __init kasan_early_pte_populate(pmd_t *pmd, unsigned long addr,
+ unsigned long end)
+{
+ pte_t *pte;
+ unsigned long next;
+
+ if (pmd_none(*pmd))
+ pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+
+ pte = pte_offset_kimg(pmd, addr);
+ do {
+ next = addr + PAGE_SIZE;
+ set_pte(pte, pfn_pte(virt_to_pfn(kasan_zero_page),
+ PAGE_KERNEL));
+ } while (pte++, addr = next, addr != end && pte_none(*pte));
+}
+
+static void __init kasan_early_pmd_populate(pud_t *pud,
+ unsigned long addr,
+ unsigned long end)
+{
+ pmd_t *pmd;
+ unsigned long next;
+
+ if (pud_none(*pud))
+ pud_populate(&init_mm, pud, kasan_zero_pmd);
+
+ pmd = pmd_offset_kimg(pud, addr);
+ do {
+ next = pmd_addr_end(addr, end);
+ kasan_early_pte_populate(pmd, addr, next);
+ } while (pmd++, addr = next, addr != end && pmd_none(*pmd));
+}
+
+static void __init kasan_early_pud_populate(pgd_t *pgd,
+ unsigned long addr,
+ unsigned long end)
+{
+ pud_t *pud;
+ unsigned long next;
+
+ if (pgd_none(*pgd))
+ pgd_populate(&init_mm, pgd, kasan_zero_pud);
+
+ pud = pud_offset_kimg(pgd, addr);
+ do {
+ next = pud_addr_end(addr, end);
+ kasan_early_pmd_populate(pud, addr, next);
+ } while (pud++, addr = next, addr != end && pud_none(*pud));
+}
+
+static void __init kasan_map_early_shadow(void)
+{
+ unsigned long addr = KASAN_SHADOW_START;
+ unsigned long end = KASAN_SHADOW_END;
+ unsigned long next;
+ pgd_t *pgd;
+
+ pgd = pgd_offset_k(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ kasan_early_pud_populate(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+
+asmlinkage void __init kasan_early_init(void)
+{
+ BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
+ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+ kasan_map_early_shadow();
+}
+
+/*
+ * Copy the current shadow region into a new pgdir.
+ */
+void __init kasan_copy_shadow(pgd_t *pgdir)
+{
+ pgd_t *pgd, *pgd_new, *pgd_end;
+
+ pgd = pgd_offset_k(KASAN_SHADOW_START);
+ pgd_end = pgd_offset_k(KASAN_SHADOW_END);
+ pgd_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START);
+ do {
+ set_pgd(pgd_new, *pgd);
+ } while (pgd++, pgd_new++, pgd != pgd_end);
+}
+
+static void __init clear_pgds(unsigned long start,
+ unsigned long end)
+{
+ /*
+ * Remove references to kasan page tables from
+ * swapper_pg_dir. pgd_clear() can't be used
+ * here because it's nop on 2,3-level pagetable setups
+ */
+ for (; start < end; start += PGDIR_SIZE)
+ set_pgd(pgd_offset_k(start), __pgd(0));
+}
+
+void __init kasan_init(void)
+{
+ u64 kimg_shadow_start, kimg_shadow_end;
+ u64 mod_shadow_start, mod_shadow_end;
+ struct memblock_region *reg;
+ int i;
+
+ kimg_shadow_start = (u64)kasan_mem_to_shadow(_text);
+ kimg_shadow_end = (u64)kasan_mem_to_shadow(_end);
+
+ mod_shadow_start = (u64)kasan_mem_to_shadow((void *)MODULES_VADDR);
+ mod_shadow_end = (u64)kasan_mem_to_shadow((void *)MODULES_END);
+
+ /*
+ * We are going to perform proper setup of shadow memory.
+ * At first we should unmap early shadow (clear_pgds() call bellow).
+ * However, instrumented code couldn't execute without shadow memory.
+ * tmp_pg_dir used to keep early shadow mapped until full shadow
+ * setup will be finished.
+ */
+ memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+ dsb(ishst);
+ cpu_replace_ttbr1(tmp_pg_dir);
+
+ clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+
+ vmemmap_populate(kimg_shadow_start, kimg_shadow_end,
+ pfn_to_nid(virt_to_pfn(_text)));
+
+ /*
+ * vmemmap_populate() has populated the shadow region that covers the
+ * kernel image with SWAPPER_BLOCK_SIZE mappings, so we have to round
+ * the start and end addresses to SWAPPER_BLOCK_SIZE as well, to prevent
+ * kasan_populate_zero_shadow() from replacing the page table entries
+ * (PMD or PTE) at the edges of the shadow region for the kernel
+ * image.
+ */
+ kimg_shadow_start = round_down(kimg_shadow_start, SWAPPER_BLOCK_SIZE);
+ kimg_shadow_end = round_up(kimg_shadow_end, SWAPPER_BLOCK_SIZE);
+
+ kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
+ (void *)mod_shadow_start);
+ kasan_populate_zero_shadow((void *)kimg_shadow_end,
+ kasan_mem_to_shadow((void *)PAGE_OFFSET));
+
+ if (kimg_shadow_start > mod_shadow_end)
+ kasan_populate_zero_shadow((void *)mod_shadow_end,
+ (void *)kimg_shadow_start);
+
+ for_each_memblock(memory, reg) {
+ void *start = (void *)__phys_to_virt(reg->base);
+ void *end = (void *)__phys_to_virt(reg->base + reg->size);
+
+ if (start >= end)
+ break;
+
+ /*
+ * end + 1 here is intentional. We check several shadow bytes in
+ * advance to slightly speed up fastpath. In some rare cases
+ * we could cross boundary of mapped shadow, so we just map
+ * some more here.
+ */
+ vmemmap_populate((unsigned long)kasan_mem_to_shadow(start),
+ (unsigned long)kasan_mem_to_shadow(end) + 1,
+ pfn_to_nid(virt_to_pfn(start)));
+ }
+
+ /*
+ * KAsan may reuse the contents of kasan_zero_pte directly, so we
+ * should make sure that it maps the zero page read-only.
+ */
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ set_pte(&kasan_zero_pte[i],
+ pfn_pte(virt_to_pfn(kasan_zero_page), PAGE_KERNEL_RO));
+
+ memset(kasan_zero_page, 0, PAGE_SIZE);
+ cpu_replace_ttbr1(swapper_pg_dir);
+
+ /* At this point kasan is fully initialized. Enable error messages */
+ init_task.kasan_depth = 0;
+ pr_info("KernelAddressSanitizer initialized\n");
+}
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index ed17747..232f787 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -51,8 +51,12 @@ unsigned long arch_mmap_rnd(void)
{
unsigned long rnd;
- rnd = (unsigned long)get_random_int() & STACK_RND_MASK;
-
+#ifdef CONFIG_COMPAT
+ if (test_thread_flag(TIF_32BIT))
+ rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
+ else
+#endif
+ rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
return rnd << PAGE_SHIFT;
}
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9211b85..d2d8b8c 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -30,8 +30,11 @@
#include <linux/slab.h>
#include <linux/stop_machine.h>
+#include <asm/barrier.h>
#include <asm/cputype.h>
#include <asm/fixmap.h>
+#include <asm/kasan.h>
+#include <asm/kernel-pgtable.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/sizes.h>
@@ -43,13 +46,20 @@
u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
+u64 kimage_voffset __read_mostly;
+EXPORT_SYMBOL(kimage_voffset);
+
/*
* Empty_zero_page is a special page that is used for zero-initialized data
* and COW.
*/
-struct page *empty_zero_page;
+unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss;
EXPORT_SYMBOL(empty_zero_page);
+static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
+static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
+static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;
+
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
@@ -61,12 +71,30 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static void __init *early_alloc(unsigned long sz)
+static phys_addr_t __init early_pgtable_alloc(void)
{
- void *ptr = __va(memblock_alloc(sz, sz));
- BUG_ON(!ptr);
- memset(ptr, 0, sz);
- return ptr;
+ phys_addr_t phys;
+ void *ptr;
+
+ phys = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+ BUG_ON(!phys);
+
+ /*
+ * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE
+ * slot will be free, so we can (ab)use the FIX_PTE slot to initialise
+ * any level of table.
+ */
+ ptr = pte_set_fixmap(phys);
+
+ memset(ptr, 0, PAGE_SIZE);
+
+ /*
+ * Implicit barriers also ensure the zeroed page is visible to the page
+ * table walker
+ */
+ pte_clear_fixmap();
+
+ return phys;
}
/*
@@ -90,27 +118,33 @@ static void split_pmd(pmd_t *pmd, pte_t *pte)
static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
pgprot_t prot,
- void *(*alloc)(unsigned long size))
+ phys_addr_t (*pgtable_alloc)(void))
{
pte_t *pte;
if (pmd_none(*pmd) || pmd_sect(*pmd)) {
- pte = alloc(PTRS_PER_PTE * sizeof(pte_t));
+ phys_addr_t pte_phys;
+ BUG_ON(!pgtable_alloc);
+ pte_phys = pgtable_alloc();
+ pte = pte_set_fixmap(pte_phys);
if (pmd_sect(*pmd))
split_pmd(pmd, pte);
- __pmd_populate(pmd, __pa(pte), PMD_TYPE_TABLE);
+ __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE);
flush_tlb_all();
+ pte_clear_fixmap();
}
BUG_ON(pmd_bad(*pmd));
- pte = pte_offset_kernel(pmd, addr);
+ pte = pte_set_fixmap_offset(pmd, addr);
do {
set_pte(pte, pfn_pte(pfn, prot));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
+
+ pte_clear_fixmap();
}
-void split_pud(pud_t *old_pud, pmd_t *pmd)
+static void split_pud(pud_t *old_pud, pmd_t *pmd)
{
unsigned long addr = pud_pfn(*old_pud) << PAGE_SHIFT;
pgprot_t prot = __pgprot(pud_val(*old_pud) ^ addr);
@@ -122,10 +156,29 @@ void split_pud(pud_t *old_pud, pmd_t *pmd)
} while (pmd++, i++, i < PTRS_PER_PMD);
}
-static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end,
+#ifdef CONFIG_DEBUG_PAGEALLOC
+static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void))
+{
+
+ /*
+ * If debug_page_alloc is enabled we must map the linear map
+ * using pages. However, other mappings created by
+ * create_mapping_noalloc must use sections in some cases. Allow
+ * sections to be used in those cases, where no pgtable_alloc
+ * function is provided.
+ */
+ return !pgtable_alloc || !debug_pagealloc_enabled();
+}
+#else
+static bool block_mappings_allowed(phys_addr_t (*pgtable_alloc)(void))
+{
+ return true;
+}
+#endif
+
+static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- void *(*alloc)(unsigned long size))
+ phys_addr_t (*pgtable_alloc)(void))
{
pmd_t *pmd;
unsigned long next;
@@ -134,7 +187,10 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
* Check for initial section mappings in the pgd/pud and remove them.
*/
if (pud_none(*pud) || pud_sect(*pud)) {
- pmd = alloc(PTRS_PER_PMD * sizeof(pmd_t));
+ phys_addr_t pmd_phys;
+ BUG_ON(!pgtable_alloc);
+ pmd_phys = pgtable_alloc();
+ pmd = pmd_set_fixmap(pmd_phys);
if (pud_sect(*pud)) {
/*
* need to have the 1G of mappings continue to be
@@ -142,16 +198,18 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
*/
split_pud(pud, pmd);
}
- pud_populate(mm, pud, pmd);
+ __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE);
flush_tlb_all();
+ pmd_clear_fixmap();
}
BUG_ON(pud_bad(*pud));
- pmd = pmd_offset(pud, addr);
+ pmd = pmd_set_fixmap_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
/* try section mapping first */
- if (((addr | next | phys) & ~SECTION_MASK) == 0) {
+ if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
+ block_mappings_allowed(pgtable_alloc)) {
pmd_t old_pmd =*pmd;
set_pmd(pmd, __pmd(phys |
pgprot_val(mk_sect_prot(prot))));
@@ -162,17 +220,19 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
if (!pmd_none(old_pmd)) {
flush_tlb_all();
if (pmd_table(old_pmd)) {
- phys_addr_t table = __pa(pte_offset_map(&old_pmd, 0));
+ phys_addr_t table = pmd_page_paddr(old_pmd);
if (!WARN_ON_ONCE(slab_is_available()))
memblock_free(table, PAGE_SIZE);
}
}
} else {
alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
- prot, alloc);
+ prot, pgtable_alloc);
}
phys += next - addr;
} while (pmd++, addr = next, addr != end);
+
+ pmd_clear_fixmap();
}
static inline bool use_1G_block(unsigned long addr, unsigned long next,
@@ -187,28 +247,30 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
return true;
}
-static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end,
+static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- void *(*alloc)(unsigned long size))
+ phys_addr_t (*pgtable_alloc)(void))
{
pud_t *pud;
unsigned long next;
if (pgd_none(*pgd)) {
- pud = alloc(PTRS_PER_PUD * sizeof(pud_t));
- pgd_populate(mm, pgd, pud);
+ phys_addr_t pud_phys;
+ BUG_ON(!pgtable_alloc);
+ pud_phys = pgtable_alloc();
+ __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE);
}
BUG_ON(pgd_bad(*pgd));
- pud = pud_offset(pgd, addr);
+ pud = pud_set_fixmap_offset(pgd, addr);
do {
next = pud_addr_end(addr, end);
/*
* For 4K granule only, attempt to put down a 1GB block
*/
- if (use_1G_block(addr, next, phys)) {
+ if (use_1G_block(addr, next, phys) &&
+ block_mappings_allowed(pgtable_alloc)) {
pud_t old_pud = *pud;
set_pud(pud, __pud(phys |
pgprot_val(mk_sect_prot(prot))));
@@ -223,51 +285,74 @@ static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd,
if (!pud_none(old_pud)) {
flush_tlb_all();
if (pud_table(old_pud)) {
- phys_addr_t table = __pa(pmd_offset(&old_pud, 0));
+ phys_addr_t table = pud_page_paddr(old_pud);
if (!WARN_ON_ONCE(slab_is_available()))
memblock_free(table, PAGE_SIZE);
}
}
} else {
- alloc_init_pmd(mm, pud, addr, next, phys, prot, alloc);
+ alloc_init_pmd(pud, addr, next, phys, prot,
+ pgtable_alloc);
}
phys += next - addr;
} while (pud++, addr = next, addr != end);
+
+ pud_clear_fixmap();
}
/*
* Create the page directory entries and any necessary page tables for the
* mapping specified by 'md'.
*/
-static void __create_mapping(struct mm_struct *mm, pgd_t *pgd,
- phys_addr_t phys, unsigned long virt,
+static void init_pgd(pgd_t *pgd, phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot,
- void *(*alloc)(unsigned long size))
+ phys_addr_t (*pgtable_alloc)(void))
{
unsigned long addr, length, end, next;
+ /*
+ * If the virtual and physical address don't have the same offset
+ * within a page, we cannot map the region as the caller expects.
+ */
+ if (WARN_ON((phys ^ virt) & ~PAGE_MASK))
+ return;
+
+ phys &= PAGE_MASK;
addr = virt & PAGE_MASK;
length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
end = addr + length;
do {
next = pgd_addr_end(addr, end);
- alloc_init_pud(mm, pgd, addr, next, phys, prot, alloc);
+ alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc);
phys += next - addr;
} while (pgd++, addr = next, addr != end);
}
-static void *late_alloc(unsigned long size)
+static phys_addr_t late_pgtable_alloc(void)
{
- void *ptr;
-
- BUG_ON(size > PAGE_SIZE);
- ptr = (void *)__get_free_page(PGALLOC_GFP);
+ void *ptr = (void *)__get_free_page(PGALLOC_GFP);
BUG_ON(!ptr);
- return ptr;
+
+ /* Ensure the zeroed page is visible to the page table walker */
+ dsb(ishst);
+ return __pa(ptr);
}
-static void __init create_mapping(phys_addr_t phys, unsigned long virt,
+static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
+ unsigned long virt, phys_addr_t size,
+ pgprot_t prot,
+ phys_addr_t (*alloc)(void))
+{
+ init_pgd(pgd_offset_raw(pgdir, virt), phys, virt, size, prot, alloc);
+}
+
+/*
+ * This function can only be used to modify existing table entries,
+ * without allocating new levels of table. Note that this permits the
+ * creation of new section or page entries.
+ */
+static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot)
{
if (virt < VMALLOC_START) {
@@ -275,16 +360,16 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
&phys, virt);
return;
}
- __create_mapping(&init_mm, pgd_offset_k(virt & PAGE_MASK), phys, virt,
- size, prot, early_alloc);
+ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot,
+ NULL);
}
void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot)
{
- __create_mapping(mm, pgd_offset(mm, virt), phys, virt, size, prot,
- late_alloc);
+ __create_pgd_mapping(mm->pgd, phys, virt, size, prot,
+ late_pgtable_alloc);
}
static void create_mapping_late(phys_addr_t phys, unsigned long virt,
@@ -296,72 +381,57 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt,
return;
}
- return __create_mapping(&init_mm, pgd_offset_k(virt & PAGE_MASK),
- phys, virt, size, prot, late_alloc);
+ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot,
+ late_pgtable_alloc);
}
-#ifdef CONFIG_DEBUG_RODATA
-static void __init __map_memblock(phys_addr_t start, phys_addr_t end)
+static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
{
+ unsigned long kernel_start = __pa(_stext);
+ unsigned long kernel_end = __pa(_etext);
+
/*
- * Set up the executable regions using the existing section mappings
- * for now. This will get more fine grained later once all memory
- * is mapped
+ * Take care not to create a writable alias for the
+ * read-only text and rodata sections of the kernel image.
*/
- unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
- unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
-
- if (end < kernel_x_start) {
- create_mapping(start, __phys_to_virt(start),
- end - start, PAGE_KERNEL);
- } else if (start >= kernel_x_end) {
- create_mapping(start, __phys_to_virt(start),
- end - start, PAGE_KERNEL);
- } else {
- if (start < kernel_x_start)
- create_mapping(start, __phys_to_virt(start),
- kernel_x_start - start,
- PAGE_KERNEL);
- create_mapping(kernel_x_start,
- __phys_to_virt(kernel_x_start),
- kernel_x_end - kernel_x_start,
- PAGE_KERNEL_EXEC);
- if (kernel_x_end < end)
- create_mapping(kernel_x_end,
- __phys_to_virt(kernel_x_end),
- end - kernel_x_end,
- PAGE_KERNEL);
+
+ /* No overlap with the kernel text */
+ if (end < kernel_start || start >= kernel_end) {
+ __create_pgd_mapping(pgd, start, __phys_to_virt(start),
+ end - start, PAGE_KERNEL,
+ early_pgtable_alloc);
+ return;
}
+ /*
+ * This block overlaps the kernel text mapping.
+ * Map the portion(s) which don't overlap.
+ */
+ if (start < kernel_start)
+ __create_pgd_mapping(pgd, start,
+ __phys_to_virt(start),
+ kernel_start - start, PAGE_KERNEL,
+ early_pgtable_alloc);
+ if (kernel_end < end)
+ __create_pgd_mapping(pgd, kernel_end,
+ __phys_to_virt(kernel_end),
+ end - kernel_end, PAGE_KERNEL,
+ early_pgtable_alloc);
+
+ /*
+ * Map the linear alias of the [_stext, _etext) interval as
+ * read-only/non-executable. This makes the contents of the
+ * region accessible to subsystems such as hibernate, but
+ * protects it from inadvertent modification or execution.
+ */
+ __create_pgd_mapping(pgd, kernel_start, __phys_to_virt(kernel_start),
+ kernel_end - kernel_start, PAGE_KERNEL_RO,
+ early_pgtable_alloc);
}
-#else
-static void __init __map_memblock(phys_addr_t start, phys_addr_t end)
-{
- create_mapping(start, __phys_to_virt(start), end - start,
- PAGE_KERNEL_EXEC);
-}
-#endif
-static void __init map_mem(void)
+static void __init map_mem(pgd_t *pgd)
{
struct memblock_region *reg;
- phys_addr_t limit;
-
- /*
- * Temporarily limit the memblock range. We need to do this as
- * create_mapping requires puds, pmds and ptes to be allocated from
- * memory addressable from the initial direct kernel mapping.
- *
- * The initial direct kernel mapping, located at swapper_pg_dir, gives
- * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
- * PHYS_OFFSET (which must be aligned to 2MB as per
- * Documentation/arm64/booting.txt).
- */
- if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
- limit = PHYS_OFFSET + PMD_SIZE;
- else
- limit = PHYS_OFFSET + PUD_SIZE;
- memblock_set_current_limit(limit);
/* map all the memory banks */
for_each_memblock(memory, reg) {
@@ -370,67 +440,97 @@ static void __init map_mem(void)
if (start >= end)
break;
+ if (memblock_is_nomap(reg))
+ continue;
-#ifndef CONFIG_ARM64_64K_PAGES
- /*
- * For the first memory bank align the start address and
- * current memblock limit to prevent create_mapping() from
- * allocating pte page tables from unmapped memory.
- * When 64K pages are enabled, the pte page table for the
- * first PGDIR_SIZE is already present in swapper_pg_dir.
- */
- if (start < limit)
- start = ALIGN(start, PMD_SIZE);
- if (end < limit) {
- limit = end & PMD_MASK;
- memblock_set_current_limit(limit);
- }
-#endif
- __map_memblock(start, end);
+ __map_memblock(pgd, start, end);
}
-
- /* Limit no longer required. */
- memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
}
-void __init fixup_executable(void)
+void mark_rodata_ro(void)
{
-#ifdef CONFIG_DEBUG_RODATA
- /* now that we are actually fully mapped, make the start/end more fine grained */
- if (!IS_ALIGNED((unsigned long)_stext, SECTION_SIZE)) {
- unsigned long aligned_start = round_down(__pa(_stext),
- SECTION_SIZE);
+ unsigned long section_size;
- create_mapping(aligned_start, __phys_to_virt(aligned_start),
- __pa(_stext) - aligned_start,
- PAGE_KERNEL);
- }
+ section_size = (unsigned long)__start_rodata - (unsigned long)_stext;
+ create_mapping_late(__pa(_stext), (unsigned long)_stext,
+ section_size, PAGE_KERNEL_ROX);
+ /*
+ * mark .rodata as read only. Use _etext rather than __end_rodata to
+ * cover NOTES and EXCEPTION_TABLE.
+ */
+ section_size = (unsigned long)_etext - (unsigned long)__start_rodata;
+ create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
+ section_size, PAGE_KERNEL_RO);
+}
- if (!IS_ALIGNED((unsigned long)__init_end, SECTION_SIZE)) {
- unsigned long aligned_end = round_up(__pa(__init_end),
- SECTION_SIZE);
- create_mapping(__pa(__init_end), (unsigned long)__init_end,
- aligned_end - __pa(__init_end),
- PAGE_KERNEL);
- }
-#endif
+void fixup_init(void)
+{
+ /*
+ * Unmap the __init region but leave the VM area in place. This
+ * prevents the region from being reused for kernel modules, which
+ * is not supported by kallsyms.
+ */
+ unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin));
}
-#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void)
+static void __init map_kernel_chunk(pgd_t *pgd, void *va_start, void *va_end,
+ pgprot_t prot, struct vm_struct *vma)
{
- create_mapping_late(__pa(_stext), (unsigned long)_stext,
- (unsigned long)_etext - (unsigned long)_stext,
- PAGE_KERNEL_EXEC | PTE_RDONLY);
+ phys_addr_t pa_start = __pa(va_start);
+ unsigned long size = va_end - va_start;
+
+ BUG_ON(!PAGE_ALIGNED(pa_start));
+ BUG_ON(!PAGE_ALIGNED(size));
+ __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot,
+ early_pgtable_alloc);
+
+ vma->addr = va_start;
+ vma->phys_addr = pa_start;
+ vma->size = size;
+ vma->flags = VM_MAP;
+ vma->caller = __builtin_return_address(0);
+
+ vm_area_add_early(vma);
}
-#endif
-void fixup_init(void)
+/*
+ * Create fine-grained mappings for the kernel.
+ */
+static void __init map_kernel(pgd_t *pgd)
{
- create_mapping_late(__pa(__init_begin), (unsigned long)__init_begin,
- (unsigned long)__init_end - (unsigned long)__init_begin,
- PAGE_KERNEL);
+ static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;
+
+ map_kernel_chunk(pgd, _stext, __start_rodata, PAGE_KERNEL_EXEC, &vmlinux_text);
+ map_kernel_chunk(pgd, __start_rodata, _etext, PAGE_KERNEL, &vmlinux_rodata);
+ map_kernel_chunk(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
+ &vmlinux_init);
+ map_kernel_chunk(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);
+
+ if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {
+ /*
+ * The fixmap falls in a separate pgd to the kernel, and doesn't
+ * live in the carveout for the swapper_pg_dir. We can simply
+ * re-use the existing dir for the fixmap.
+ */
+ set_pgd(pgd_offset_raw(pgd, FIXADDR_START),
+ *pgd_offset_k(FIXADDR_START));
+ } else if (CONFIG_PGTABLE_LEVELS > 3) {
+ /*
+ * The fixmap shares its top level pgd entry with the kernel
+ * mapping. This can really only occur when we are running
+ * with 16k/4 levels, so we can simply reuse the pud level
+ * entry instead.
+ */
+ BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
+ set_pud(pud_set_fixmap_offset(pgd, FIXADDR_START),
+ __pud(__pa(bm_pmd) | PUD_TYPE_TABLE));
+ pud_clear_fixmap();
+ } else {
+ BUG();
+ }
+
+ kasan_copy_shadow(pgd);
}
/*
@@ -439,25 +539,35 @@ void fixup_init(void)
*/
void __init paging_init(void)
{
- void *zero_page;
-
- map_mem();
- fixup_executable();
+ phys_addr_t pgd_phys = early_pgtable_alloc();
+ pgd_t *pgd = pgd_set_fixmap(pgd_phys);
- /* allocate the zero page. */
- zero_page = early_alloc(PAGE_SIZE);
+ map_kernel(pgd);
+ map_mem(pgd);
- bootmem_init();
+ /*
+ * We want to reuse the original swapper_pg_dir so we don't have to
+ * communicate the new address to non-coherent secondaries in
+ * secondary_entry, and so cpu_switch_mm can generate the address with
+ * adrp+add rather than a load from some global variable.
+ *
+ * To do this we need to go via a temporary pgd.
+ */
+ cpu_replace_ttbr1(__va(pgd_phys));
+ memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
+ cpu_replace_ttbr1(swapper_pg_dir);
- empty_zero_page = virt_to_page(zero_page);
+ pgd_clear_fixmap();
+ memblock_free(pgd_phys, PAGE_SIZE);
/*
- * TTBR0 is only used for the identity mapping at this stage. Make it
- * point to zero page to avoid speculatively fetching new entries.
+ * We only reuse the PGD from the swapper_pg_dir, not the pud + pmd
+ * allocated with it.
*/
- cpu_set_reserved_ttbr0();
- flush_tlb_all();
- cpu_set_default_tcr_t0sz();
+ memblock_free(__pa(swapper_pg_dir) + PAGE_SIZE,
+ SWAPPER_DIR_SIZE - PAGE_SIZE);
+
+ bootmem_init();
}
/*
@@ -498,12 +608,12 @@ int kern_addr_valid(unsigned long addr)
return pfn_valid(pte_pfn(*pte));
}
#ifdef CONFIG_SPARSEMEM_VMEMMAP
-#ifdef CONFIG_ARM64_64K_PAGES
+#if !ARM64_SWAPPER_USES_SECTION_MAPS
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
{
return vmemmap_populate_basepages(start, end, node);
}
-#else /* !CONFIG_ARM64_64K_PAGES */
+#else /* !ARM64_SWAPPER_USES_SECTION_MAPS */
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
{
unsigned long addr = start;
@@ -544,21 +654,13 @@ void vmemmap_free(unsigned long start, unsigned long end)
}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
-static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
-#if CONFIG_PGTABLE_LEVELS > 2
-static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss;
-#endif
-#if CONFIG_PGTABLE_LEVELS > 3
-static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss;
-#endif
-
static inline pud_t * fixmap_pud(unsigned long addr)
{
pgd_t *pgd = pgd_offset_k(addr);
BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd));
- return pud_offset(pgd, addr);
+ return pud_offset_kimg(pgd, addr);
}
static inline pmd_t * fixmap_pmd(unsigned long addr)
@@ -567,16 +669,12 @@ static inline pmd_t * fixmap_pmd(unsigned long addr)
BUG_ON(pud_none(*pud) || pud_bad(*pud));
- return pmd_offset(pud, addr);
+ return pmd_offset_kimg(pud, addr);
}
static inline pte_t * fixmap_pte(unsigned long addr)
{
- pmd_t *pmd = fixmap_pmd(addr);
-
- BUG_ON(pmd_none(*pmd) || pmd_bad(*pmd));
-
- return pte_offset_kernel(pmd, addr);
+ return &bm_pte[pte_index(addr)];
}
void __init early_fixmap_init(void)
@@ -587,15 +685,26 @@ void __init early_fixmap_init(void)
unsigned long addr = FIXADDR_START;
pgd = pgd_offset_k(addr);
- pgd_populate(&init_mm, pgd, bm_pud);
- pud = pud_offset(pgd, addr);
+ if (CONFIG_PGTABLE_LEVELS > 3 &&
+ !(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa(bm_pud))) {
+ /*
+ * We only end up here if the kernel mapping and the fixmap
+ * share the top level pgd entry, which should only happen on
+ * 16k/4 levels configurations.
+ */
+ BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
+ pud = pud_offset_kimg(pgd, addr);
+ } else {
+ pgd_populate(&init_mm, pgd, bm_pud);
+ pud = fixmap_pud(addr);
+ }
pud_populate(&init_mm, pud, bm_pmd);
- pmd = pmd_offset(pud, addr);
+ pmd = fixmap_pmd(addr);
pmd_populate_kernel(&init_mm, pmd, bm_pte);
/*
* The boot-ioremap range spans multiple pmds, for which
- * we are not preparted:
+ * we are not prepared:
*/
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
@@ -634,11 +743,10 @@ void __set_fixmap(enum fixed_addresses idx,
}
}
-void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
+void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
{
const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
- pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
- int granularity, size, offset;
+ int offset;
void *dt_virt;
/*
@@ -655,7 +763,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
/*
* Make sure that the FDT region can be mapped without the need to
* allocate additional translation table pages, so that it is safe
- * to call create_mapping() this early.
+ * to call create_mapping_noalloc() this early.
*
* On 64k pages, the FDT will be mapped using PTEs, so we need to
* be in the same PMD as the rest of the fixmap.
@@ -664,37 +772,80 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
*/
BUILD_BUG_ON(dt_virt_base % SZ_2M);
- if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
- BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
- __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
-
- granularity = PAGE_SIZE;
- } else {
- BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
- __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
-
- granularity = PMD_SIZE;
- }
+ BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+ __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
- offset = dt_phys % granularity;
+ offset = dt_phys % SWAPPER_BLOCK_SIZE;
dt_virt = (void *)dt_virt_base + offset;
/* map the first chunk so we can read the size from the header */
- create_mapping(round_down(dt_phys, granularity), dt_virt_base,
- granularity, prot);
+ create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE),
+ dt_virt_base, SWAPPER_BLOCK_SIZE, prot);
if (fdt_check_header(dt_virt) != 0)
return NULL;
- size = fdt_totalsize(dt_virt);
- if (size > MAX_FDT_SIZE)
+ *size = fdt_totalsize(dt_virt);
+ if (*size > MAX_FDT_SIZE)
return NULL;
- if (offset + size > granularity)
- create_mapping(round_down(dt_phys, granularity), dt_virt_base,
- round_up(offset + size, granularity), prot);
+ if (offset + *size > SWAPPER_BLOCK_SIZE)
+ create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+ round_up(offset + *size, SWAPPER_BLOCK_SIZE), prot);
- memblock_reserve(dt_phys, size);
+ return dt_virt;
+}
+void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
+{
+ void *dt_virt;
+ int size;
+
+ dt_virt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
+ if (!dt_virt)
+ return NULL;
+
+ memblock_reserve(dt_phys, size);
return dt_virt;
}
+
+int __init arch_ioremap_pud_supported(void)
+{
+ /* only 4k granule supports level 1 block mappings */
+ return IS_ENABLED(CONFIG_ARM64_4K_PAGES);
+}
+
+int __init arch_ioremap_pmd_supported(void)
+{
+ return 1;
+}
+
+int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot)
+{
+ BUG_ON(phys & ~PUD_MASK);
+ set_pud(pud, __pud(phys | PUD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ return 1;
+}
+
+int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot)
+{
+ BUG_ON(phys & ~PMD_MASK);
+ set_pmd(pmd, __pmd(phys | PMD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ return 1;
+}
+
+int pud_clear_huge(pud_t *pud)
+{
+ if (!pud_sect(*pud))
+ return 0;
+ pud_clear(pud);
+ return 1;
+}
+
+int pmd_clear_huge(pmd_t *pmd)
+{
+ if (!pmd_sect(*pmd))
+ return 0;
+ pmd_clear(pmd);
+ return 1;
+}
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index e47ed1c..ca6d268 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
@@ -36,35 +37,62 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
return 0;
}
+/*
+ * This function assumes that the range is mapped with PAGE_SIZE pages.
+ */
+static int __change_memory_common(unsigned long start, unsigned long size,
+ pgprot_t set_mask, pgprot_t clear_mask)
+{
+ struct page_change_data data;
+ int ret;
+
+ 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, start + size);
+ return ret;
+}
+
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;
+ struct vm_struct *area;
- if (!IS_ALIGNED(addr, PAGE_SIZE)) {
+ if (!PAGE_ALIGNED(addr)) {
start &= PAGE_MASK;
end = start + size;
WARN_ON_ONCE(1);
}
- if (start < MODULES_VADDR || start >= MODULES_END)
- return -EINVAL;
-
- if (end < MODULES_VADDR || end >= MODULES_END)
+ /*
+ * Kernel VA mappings are always live, and splitting live section
+ * mappings into page mappings may cause TLB conflicts. This means
+ * we have to ensure that changing the permission bits of the range
+ * we are operating on does not result in such splitting.
+ *
+ * Let's restrict ourselves to mappings created by vmalloc (or vmap).
+ * Those are guaranteed to consist entirely of page mappings, and
+ * splitting is never needed.
+ *
+ * So check whether the [addr, addr + size) interval is entirely
+ * covered by precisely one VM area that has the VM_ALLOC flag set.
+ */
+ area = find_vm_area((void *)addr);
+ if (!area ||
+ end > (unsigned long)area->addr + area->size ||
+ !(area->flags & VM_ALLOC))
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);
+ if (!numpages)
+ return 0;
- flush_tlb_kernel_range(start, end);
- return ret;
+ return __change_memory_common(start, size, set_mask, clear_mask);
}
int set_memory_ro(unsigned long addr, int numpages)
@@ -96,3 +124,19 @@ int set_memory_x(unsigned long addr, int numpages)
__pgprot(PTE_PXN));
}
EXPORT_SYMBOL_GPL(set_memory_x);
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+void __kernel_map_pages(struct page *page, int numpages, int enable)
+{
+ unsigned long addr = (unsigned long) page_address(page);
+
+ if (enable)
+ __change_memory_common(addr, PAGE_SIZE * numpages,
+ __pgprot(PTE_VALID),
+ __pgprot(0));
+ else
+ __change_memory_common(addr, PAGE_SIZE * numpages,
+ __pgprot(0),
+ __pgprot(PTE_VALID));
+}
+#endif
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 71ca104..ae11d4e 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -28,8 +28,6 @@
#include "mm.h"
-#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
-
static struct kmem_cache *pgd_cache;
pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -48,14 +46,14 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
kmem_cache_free(pgd_cache, pgd);
}
-static int __init pgd_cache_init(void)
+void __init pgd_cache_init(void)
{
+ if (PGD_SIZE == PAGE_SIZE)
+ return;
+
/*
* Naturally aligned pgds required by the architecture.
*/
- if (PGD_SIZE != PAGE_SIZE)
- pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
- SLAB_PANIC, NULL);
- return 0;
+ pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
+ SLAB_PANIC, NULL);
}
-core_initcall(pgd_cache_init);
diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S
index 4c4d93c..e6a30e1 100644
--- a/arch/arm64/mm/proc-macros.S
+++ b/arch/arm64/mm/proc-macros.S
@@ -62,3 +62,37 @@
bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
#endif
.endm
+
+/*
+ * Macro to perform a data cache maintenance for the interval
+ * [kaddr, kaddr + size)
+ *
+ * op: operation passed to dc instruction
+ * domain: domain used in dsb instruciton
+ * kaddr: starting virtual address of the region
+ * size: size of the region
+ * Corrupts: kaddr, size, tmp1, tmp2
+ */
+ .macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
+ dcache_line_size \tmp1, \tmp2
+ add \size, \kaddr, \size
+ sub \tmp2, \tmp1, #1
+ bic \kaddr, \kaddr, \tmp2
+9998: dc \op, \kaddr
+ add \kaddr, \kaddr, \tmp1
+ cmp \kaddr, \size
+ b.lo 9998b
+ dsb \domain
+ .endm
+
+/*
+ * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
+ */
+ .macro reset_pmuserenr_el0, tmpreg
+ mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
+ sbfx \tmpreg, \tmpreg, #8, #4
+ cmp \tmpreg, #1 // Skip if no PMU present
+ b.lt 9000f
+ msr pmuserenr_el0, xzr // Disable PMU access from EL0
+9000:
+ .endm
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index e4ee7bd..543f519 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -25,12 +25,16 @@
#include <asm/hwcap.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
#include "proc-macros.S"
#ifdef CONFIG_ARM64_64K_PAGES
#define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K
-#else
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
#define TCR_TG_FLAGS TCR_TG0_4K | TCR_TG1_4K
#endif
@@ -115,6 +119,7 @@ ENTRY(cpu_do_resume)
*/
ubfx x11, x11, #1, #1
msr oslar_el1, x11
+ reset_pmuserenr_el0 x0 // Disable PMU access from EL0
mov x0, x12
dsb nsh // Make sure local tlb invalidation completed
isb
@@ -130,14 +135,50 @@ ENDPROC(cpu_do_resume)
* - pgd_phys - physical address of new TTB
*/
ENTRY(cpu_do_switch_mm)
- mmid w1, x1 // get mm->context.id
+ mmid x1, x1 // get mm->context.id
bfi x0, x1, #48, #16 // set the ASID
msr ttbr0_el1, x0 // set TTBR0
isb
+alternative_if_not ARM64_WORKAROUND_CAVIUM_27456
ret
+ nop
+ nop
+ nop
+alternative_else
+ ic iallu
+ dsb nsh
+ isb
+ ret
+alternative_endif
ENDPROC(cpu_do_switch_mm)
- .section ".text.init", #alloc, #execinstr
+ .pushsection ".idmap.text", "ax"
+/*
+ * void idmap_cpu_replace_ttbr1(phys_addr_t new_pgd)
+ *
+ * This is the low-level counterpart to cpu_replace_ttbr1, and should not be
+ * called by anything else. It can only be executed from a TTBR0 mapping.
+ */
+ENTRY(idmap_cpu_replace_ttbr1)
+ mrs x2, daif
+ msr daifset, #0xf
+
+ adrp x1, empty_zero_page
+ msr ttbr1_el1, x1
+ isb
+
+ tlbi vmalle1
+ dsb nsh
+ isb
+
+ msr ttbr1_el1, x0
+ isb
+
+ msr daif, x2
+
+ ret
+ENDPROC(idmap_cpu_replace_ttbr1)
+ .popsection
/*
* __cpu_setup
@@ -146,13 +187,14 @@ ENDPROC(cpu_do_switch_mm)
* value of the SCTLR_EL1 register.
*/
ENTRY(__cpu_setup)
- tlbi vmalle1is // invalidate I + D TLBs
- dsb ish
+ tlbi vmalle1 // Invalidate local TLB
+ dsb nsh
mov x0, #3 << 20
msr cpacr_el1, x0 // Enable FP/ASIMD
mov x0, #1 << 12 // Reset mdscr_el1 and disable
msr mdscr_el1, x0 // access to the DCC from EL0
+ reset_pmuserenr_el0 x0 // Disable PMU access from EL0
/*
* Memory region attributes for LPAE:
*
@@ -163,12 +205,14 @@ ENTRY(__cpu_setup)
* DEVICE_GRE 010 00001100
* NORMAL_NC 011 01000100
* NORMAL 100 11111111
+ * NORMAL_WT 101 10111011
*/
ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
MAIR(0x04, MT_DEVICE_nGnRE) | \
MAIR(0x0c, MT_DEVICE_GRE) | \
MAIR(0x44, MT_NORMAL_NC) | \
- MAIR(0xff, MT_NORMAL)
+ MAIR(0xff, MT_NORMAL) | \
+ MAIR(0xbb, MT_NORMAL_WT)
msr mair_el1, x5
/*
* Prepare SCTLR
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index 98a26ce..aee5637 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -1,7 +1,7 @@
/*
* BPF JIT compiler for ARM64
*
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@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
@@ -35,6 +35,7 @@
aarch64_insn_gen_comp_branch_imm(0, offset, Rt, A64_VARIANT(sf), \
AARCH64_INSN_BRANCH_COMP_##type)
#define A64_CBZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, ZERO)
+#define A64_CBNZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, NONZERO)
/* Conditional branch (immediate) */
#define A64_COND_BRANCH(cond, offset) \
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index c047598..a34420a 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1,7 +1,7 @@
/*
* BPF JIT compiler for ARM64
*
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@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
@@ -50,7 +50,7 @@ static const int bpf2a64[] = {
[BPF_REG_8] = A64_R(21),
[BPF_REG_9] = A64_R(22),
/* read-only frame pointer to access stack */
- [BPF_REG_FP] = A64_FP,
+ [BPF_REG_FP] = A64_R(25),
/* temporary register for internal BPF JIT */
[TMP_REG_1] = A64_R(23),
[TMP_REG_2] = A64_R(24),
@@ -139,6 +139,12 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
/* Stack must be multiples of 16B */
#define STACK_ALIGN(sz) (((sz) + 15) & ~15)
+#define _STACK_SIZE \
+ (MAX_BPF_STACK \
+ + 4 /* extra for skb_copy_bits buffer */)
+
+#define STACK_SIZE STACK_ALIGN(_STACK_SIZE)
+
static void build_prologue(struct jit_ctx *ctx)
{
const u8 r6 = bpf2a64[BPF_REG_6];
@@ -146,14 +152,37 @@ static void build_prologue(struct jit_ctx *ctx)
const u8 r8 = bpf2a64[BPF_REG_8];
const u8 r9 = bpf2a64[BPF_REG_9];
const u8 fp = bpf2a64[BPF_REG_FP];
- const u8 ra = bpf2a64[BPF_REG_A];
- const u8 rx = bpf2a64[BPF_REG_X];
const u8 tmp1 = bpf2a64[TMP_REG_1];
const u8 tmp2 = bpf2a64[TMP_REG_2];
- int stack_size = MAX_BPF_STACK;
- stack_size += 4; /* extra for skb_copy_bits buffer */
- stack_size = STACK_ALIGN(stack_size);
+ /*
+ * BPF prog stack layout
+ *
+ * high
+ * original A64_SP => 0:+-----+ BPF prologue
+ * |FP/LR|
+ * current A64_FP => -16:+-----+
+ * | ... | callee saved registers
+ * +-----+
+ * | | x25/x26
+ * BPF fp register => -80:+-----+ <= (BPF_FP)
+ * | |
+ * | ... | BPF prog stack
+ * | |
+ * +-----+ <= (BPF_FP - MAX_BPF_STACK)
+ * |RSVD | JIT scratchpad
+ * current A64_SP => +-----+ <= (BPF_FP - STACK_SIZE)
+ * | |
+ * | ... | Function call stack
+ * | |
+ * +-----+
+ * low
+ *
+ */
+
+ /* Save FP and LR registers to stay align with ARM64 AAPCS */
+ emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
+ emit(A64_MOV(1, A64_FP, A64_SP), ctx);
/* Save callee-saved register */
emit(A64_PUSH(r6, r7, A64_SP), ctx);
@@ -161,15 +190,14 @@ static void build_prologue(struct jit_ctx *ctx)
if (ctx->tmp_used)
emit(A64_PUSH(tmp1, tmp2, A64_SP), ctx);
- /* Set up BPF stack */
- emit(A64_SUB_I(1, A64_SP, A64_SP, stack_size), ctx);
+ /* Save fp (x25) and x26. SP requires 16 bytes alignment */
+ emit(A64_PUSH(fp, A64_R(26), A64_SP), ctx);
- /* Set up frame pointer */
+ /* Set up BPF prog stack base register (x25) */
emit(A64_MOV(1, fp, A64_SP), ctx);
- /* Clear registers A and X */
- emit_a64_mov_i64(ra, 0, ctx);
- emit_a64_mov_i64(rx, 0, ctx);
+ /* Set up function call stack */
+ emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx);
}
static void build_epilogue(struct jit_ctx *ctx)
@@ -182,13 +210,12 @@ static void build_epilogue(struct jit_ctx *ctx)
const u8 fp = bpf2a64[BPF_REG_FP];
const u8 tmp1 = bpf2a64[TMP_REG_1];
const u8 tmp2 = bpf2a64[TMP_REG_2];
- int stack_size = MAX_BPF_STACK;
-
- stack_size += 4; /* extra for skb_copy_bits buffer */
- stack_size = STACK_ALIGN(stack_size);
/* We're done with BPF stack */
- emit(A64_ADD_I(1, A64_SP, A64_SP, stack_size), ctx);
+ emit(A64_ADD_I(1, A64_SP, A64_SP, STACK_SIZE), ctx);
+
+ /* Restore fs (x25) and x26 */
+ emit(A64_POP(fp, A64_R(26), A64_SP), ctx);
/* Restore callee-saved register */
if (ctx->tmp_used)
@@ -196,8 +223,8 @@ static void build_epilogue(struct jit_ctx *ctx)
emit(A64_POP(r8, r9, A64_SP), ctx);
emit(A64_POP(r6, r7, A64_SP), ctx);
- /* Restore frame pointer */
- emit(A64_MOV(1, fp, A64_SP), ctx);
+ /* Restore FP/LR registers */
+ emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
/* Set return value */
emit(A64_MOV(1, A64_R(0), r0), ctx);
@@ -225,6 +252,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
u8 jmp_cond;
s32 jmp_offset;
+#define check_imm(bits, imm) do { \
+ if ((((imm) > 0) && ((imm) >> (bits))) || \
+ (((imm) < 0) && (~(imm) >> (bits)))) { \
+ pr_info("[%2d] imm=%d(0x%x) out of range\n", \
+ i, imm, imm); \
+ return -EINVAL; \
+ } \
+} while (0)
+#define check_imm19(imm) check_imm(19, imm)
+#define check_imm26(imm) check_imm(26, imm)
+
switch (code) {
/* dst = src */
case BPF_ALU | BPF_MOV | BPF_X:
@@ -258,15 +296,33 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
break;
case BPF_ALU | BPF_DIV | BPF_X:
case BPF_ALU64 | BPF_DIV | BPF_X:
- emit(A64_UDIV(is64, dst, dst, src), ctx);
- break;
case BPF_ALU | BPF_MOD | BPF_X:
case BPF_ALU64 | BPF_MOD | BPF_X:
- ctx->tmp_used = 1;
- emit(A64_UDIV(is64, tmp, dst, src), ctx);
- emit(A64_MUL(is64, tmp, tmp, src), ctx);
- emit(A64_SUB(is64, dst, dst, tmp), ctx);
+ {
+ const u8 r0 = bpf2a64[BPF_REG_0];
+
+ /* if (src == 0) return 0 */
+ jmp_offset = 3; /* skip ahead to else path */
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(is64, src, jmp_offset), ctx);
+ emit(A64_MOVZ(1, r0, 0, 0), ctx);
+ jmp_offset = epilogue_offset(ctx);
+ check_imm26(jmp_offset);
+ emit(A64_B(jmp_offset), ctx);
+ /* else */
+ switch (BPF_OP(code)) {
+ case BPF_DIV:
+ emit(A64_UDIV(is64, dst, dst, src), ctx);
+ break;
+ case BPF_MOD:
+ ctx->tmp_used = 1;
+ emit(A64_UDIV(is64, tmp, dst, src), ctx);
+ emit(A64_MUL(is64, tmp, tmp, src), ctx);
+ emit(A64_SUB(is64, dst, dst, tmp), ctx);
+ break;
+ }
break;
+ }
case BPF_ALU | BPF_LSH | BPF_X:
case BPF_ALU64 | BPF_LSH | BPF_X:
emit(A64_LSLV(is64, dst, dst, src), ctx);
@@ -393,17 +449,6 @@ emit_bswap_uxt:
emit(A64_ASR(is64, dst, dst, imm), ctx);
break;
-#define check_imm(bits, imm) do { \
- if ((((imm) > 0) && ((imm) >> (bits))) || \
- (((imm) < 0) && (~(imm) >> (bits)))) { \
- pr_info("[%2d] imm=%d(0x%x) out of range\n", \
- i, imm, imm); \
- return -EINVAL; \
- } \
-} while (0)
-#define check_imm19(imm) check_imm(19, imm)
-#define check_imm26(imm) check_imm(26, imm)
-
/* JUMP off */
case BPF_JMP | BPF_JA:
jmp_offset = bpf2a64_offset(i + off, i, ctx);
@@ -539,7 +584,25 @@ emit_cond_jmp:
case BPF_ST | BPF_MEM | BPF_H:
case BPF_ST | BPF_MEM | BPF_B:
case BPF_ST | BPF_MEM | BPF_DW:
- goto notyet;
+ /* Load imm to a register then store it */
+ ctx->tmp_used = 1;
+ emit_a64_mov_i(1, tmp2, off, ctx);
+ emit_a64_mov_i(1, tmp, imm, ctx);
+ switch (BPF_SIZE(code)) {
+ case BPF_W:
+ emit(A64_STR32(tmp, dst, tmp2), ctx);
+ break;
+ case BPF_H:
+ emit(A64_STRH(tmp, dst, tmp2), ctx);
+ break;
+ case BPF_B:
+ emit(A64_STRB(tmp, dst, tmp2), ctx);
+ break;
+ case BPF_DW:
+ emit(A64_STR64(tmp, dst, tmp2), ctx);
+ break;
+ }
+ break;
/* STX: *(size *)(dst + off) = src */
case BPF_STX | BPF_MEM | BPF_W:
@@ -606,7 +669,7 @@ emit_cond_jmp:
return -EINVAL;
}
emit_a64_mov_i64(r3, size, ctx);
- emit(A64_ADD_I(1, r4, fp, MAX_BPF_STACK), ctx);
+ emit(A64_SUB_I(1, r4, fp, STACK_SIZE), ctx);
emit_a64_mov_i64(r5, (unsigned long)bpf_load_pointer, ctx);
emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
emit(A64_MOV(1, A64_FP, A64_SP), ctx);
@@ -674,6 +737,20 @@ static int build_body(struct jit_ctx *ctx)
return 0;
}
+static int validate_code(struct jit_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx->idx; i++) {
+ u32 a64_insn = le32_to_cpu(ctx->image[i]);
+
+ if (a64_insn == AARCH64_BREAK_FAULT)
+ return -1;
+ }
+
+ return 0;
+}
+
static inline void bpf_flush_icache(void *start, void *end)
{
flush_icache_range((unsigned long)start, (unsigned long)end);
@@ -736,15 +813,21 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
build_epilogue(&ctx);
+ /* 3. Extra pass to validate JITed code. */
+ if (validate_code(&ctx)) {
+ bpf_jit_binary_free(header);
+ goto out;
+ }
+
/* And we're done. */
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, image_size, 2, ctx.image);
- bpf_flush_icache(ctx.image, ctx.image + ctx.idx);
+ bpf_flush_icache(header, ctx.image + ctx.idx);
set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)ctx.image;
- prog->jited = true;
+ prog->jited = 1;
out:
kfree(ctx.offset);
}
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index 8bbe940..70df80e 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -80,6 +80,7 @@ HYPERCALL2(memory_op);
HYPERCALL2(physdev_op);
HYPERCALL3(vcpu_op);
HYPERCALL1(tmem_op);
+HYPERCALL1(platform_op_raw);
HYPERCALL2(multicall);
ENTRY(privcmd_call)
diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
index 91146b4..99b0a79 100644
--- a/arch/avr32/boards/atngw100/mrmt.c
+++ b/arch/avr32/boards/atngw100/mrmt.c
@@ -21,7 +21,6 @@
#include <linux/leds_pwm.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
-#include <linux/atmel_serial.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
index 83d896c..718a6d7 100644
--- a/arch/avr32/boards/merisc/setup.c
+++ b/arch/avr32/boards/merisc/setup.c
@@ -27,7 +27,6 @@
#include <asm/io.h>
#include <asm/setup.h>
-#include <asm/gpio.h>
#include <mach/at32ap700x.h>
#include <mach/board.h>
diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h
index 97c9bdf..d74fd8c 100644
--- a/arch/avr32/include/asm/atomic.h
+++ b/arch/avr32/include/asm/atomic.h
@@ -19,8 +19,8 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
#define ATOMIC_OP_RETURN(op, asm_op, asm_con) \
static inline int __atomic_##op##_return(int i, atomic_t *v) \
diff --git a/arch/avr32/include/asm/checksum.h b/arch/avr32/include/asm/checksum.h
index 4ddbfd2..4ab7d5b 100644
--- a/arch/avr32/include/asm/checksum.h
+++ b/arch/avr32/include/asm/checksum.h
@@ -111,9 +111,8 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
asm(" add %0, %1\n"
" adc %0, %0, %2\n"
@@ -132,9 +131,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
diff --git a/arch/avr32/include/asm/cmpxchg.h b/arch/avr32/include/asm/cmpxchg.h
index 366bbea..572739b 100644
--- a/arch/avr32/include/asm/cmpxchg.h
+++ b/arch/avr32/include/asm/cmpxchg.h
@@ -57,7 +57,7 @@ static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
" brne 1b\n"
"2:\n"
: [ret] "=&r"(ret), [m] "=m"(*m)
- : "m"(m), [old] "ir"(old), [new] "r"(new)
+ : "m"(m), [old] "Ks21r"(old), [new] "r"(new)
: "memory", "cc");
return ret;
}
diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h
index ae7ac92..1115f2a 100644
--- a/arch/avr32/include/asm/dma-mapping.h
+++ b/arch/avr32/include/asm/dma-mapping.h
@@ -1,350 +1,14 @@
#ifndef __ASM_AVR32_DMA_MAPPING_H
#define __ASM_AVR32_DMA_MAPPING_H
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/scatterlist.h>
-#include <asm/processor.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
-
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
int direction);
-/*
- * 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.
- */
-static inline int dma_supported(struct device *dev, u64 mask)
-{
- /* Fix when needed. I really don't know of any limitations */
- return 1;
-}
-
-static inline int 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;
-}
+extern struct dma_map_ops avr32_dma_ops;
-/*
- * dma_map_single can't fail as it is implemented now.
- */
-static inline int dma_mapping_error(struct device *dev, dma_addr_t addr)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- return 0;
+ return &avr32_dma_ops;
}
-/**
- * dma_alloc_coherent - allocate consistent memory for DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: required memory size
- * @handle: bus-specific DMA address
- *
- * Allocate some uncached, unbuffered memory for a device for
- * performing DMA. This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
- */
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp);
-
-/**
- * dma_free_coherent - free memory allocated by dma_alloc_coherent
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: size of memory originally requested in dma_alloc_coherent
- * @cpu_addr: CPU-view address returned from dma_alloc_coherent
- * @handle: device-view address returned from dma_alloc_coherent
- *
- * Free (and unmap) a DMA buffer previously allocated by
- * dma_alloc_coherent().
- *
- * References to memory and mappings associated with cpu_addr/handle
- * during and after this call executing are illegal.
- */
-extern void dma_free_coherent(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t handle);
-
-/**
- * dma_alloc_writecombine - allocate write-combining memory for DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: required memory size
- * @handle: bus-specific DMA address
- *
- * Allocate some uncached, buffered memory for a device for
- * performing DMA. This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
- */
-extern void *dma_alloc_writecombine(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp);
-
-/**
- * dma_free_coherent - free memory allocated by dma_alloc_writecombine
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: size of memory originally requested in dma_alloc_writecombine
- * @cpu_addr: CPU-view address returned from dma_alloc_writecombine
- * @handle: device-view address returned from dma_alloc_writecombine
- *
- * Free (and unmap) a DMA buffer previously allocated by
- * dma_alloc_writecombine().
- *
- * References to memory and mappings associated with cpu_addr/handle
- * during and after this call executing are illegal.
- */
-extern void dma_free_writecombine(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t handle);
-
-/**
- * dma_map_single - map a single buffer for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @cpu_addr: CPU direct mapped address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed. The CPU
- * can regain ownership by calling dma_unmap_single() or dma_sync_single().
- */
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
- enum dma_data_direction direction)
-{
- dma_cache_sync(dev, cpu_addr, size, direction);
- return virt_to_bus(cpu_addr);
-}
-
-/**
- * dma_unmap_single - unmap a single buffer previously mapped
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation. The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
-
-}
-
-/**
- * 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() or dma_sync_single().
- */
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- return dma_map_single(dev, page_address(page) + offset,
- size, direction);
-}
-
-/**
- * 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 to map
- * @dir: DMA transfer direction
- *
- * Unmap a single streaming mode DMA translation. The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- dma_unmap_single(dev, dma_address, size, direction);
-}
-
-/**
- * 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
- * above pci_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}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction direction)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nents, i) {
- char *virt;
-
- sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
- virt = sg_virt(sg);
- dma_cache_sync(dev, virt, sg->length, direction);
- }
-
- return nents;
-}
-
-/**
- * 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 map
- * @dir: DMA transfer direction
- *
- * Unmap a set of streaming mode DMA translations.
- * Again, CPU read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
-
-}
-
-/**
- * dma_sync_single_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a single streaming mode DMA
- * translation after a transfer.
- *
- * If you perform a dma_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the DMA mapping,
- * you must call this function before doing so. At the next point you
- * give the DMA address back to the card, you must first perform a
- * dma_sync_single_for_device, and then the device again owns the
- * buffer.
- */
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- /*
- * No need to do anything since the CPU isn't supposed to
- * touch this memory after we flushed it at mapping- or
- * sync-for-device time.
- */
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything, that's all the pci API can do */
- dma_sync_single_for_cpu(dev, dma_handle, offset+size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything, that's all the pci API can do */
- dma_sync_single_for_device(dev, dma_handle, offset+size, direction);
-}
-
-/**
- * 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
- * @dir: DMA transfer direction
- *
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as dma_sync_single_for_* but for a scatter-gather list,
- * same rules and usage.
- */
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
-{
- /*
- * No need to do anything since the CPU isn't supposed to
- * touch this memory after we flushed it at mapping- or
- * sync-for-device time.
- */
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction direction)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nents, i)
- dma_cache_sync(dev, sg_virt(sg), sg->length, direction);
-}
-
-/* Now for the API extensions over the pci_ one */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
#endif /* __ASM_AVR32_DMA_MAPPING_H */
diff --git a/arch/avr32/include/asm/page.h b/arch/avr32/include/asm/page.h
index f805d1c..c5d2a3e 100644
--- a/arch/avr32/include/asm/page.h
+++ b/arch/avr32/include/asm/page.h
@@ -83,11 +83,9 @@ static inline int get_order(unsigned long size)
#ifndef CONFIG_NEED_MULTIPLE_NODES
-#define PHYS_PFN_OFFSET (CONFIG_PHYS_OFFSET >> PAGE_SHIFT)
+#define ARCH_PFN_OFFSET (CONFIG_PHYS_OFFSET >> PAGE_SHIFT)
-#define pfn_to_page(pfn) (mem_map + ((pfn) - PHYS_PFN_OFFSET))
-#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PHYS_PFN_OFFSET)
-#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
+#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < (ARCH_PFN_OFFSET + max_mapnr))
#endif /* CONFIG_NEED_MULTIPLE_NODES */
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
@@ -101,4 +99,6 @@ static inline int get_order(unsigned long size)
*/
#define HIGHMEM_START 0x20000000UL
+#include <asm-generic/memory_model.h>
+
#endif /* __ASM_AVR32_PAGE_H */
diff --git a/arch/avr32/include/asm/pci.h b/arch/avr32/include/asm/pci.h
index a32a023..0f5f134 100644
--- a/arch/avr32/include/asm/pci.h
+++ b/arch/avr32/include/asm/pci.h
@@ -5,6 +5,4 @@
#define PCI_DMA_BUS_IS_PHYS (1)
-#include <asm-generic/pci-dma-compat.h>
-
#endif /* __ASM_AVR32_PCI_H__ */
diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h
index 2b65ed6..1fd147f 100644
--- a/arch/avr32/include/uapi/asm/socket.h
+++ b/arch/avr32/include/uapi/asm/socket.h
@@ -85,4 +85,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _UAPI__ASM_AVR32_SOCKET_H */
diff --git a/arch/avr32/include/uapi/asm/unistd.h b/arch/avr32/include/uapi/asm/unistd.h
index bbe2fba..60c0f3a 100644
--- a/arch/avr32/include/uapi/asm/unistd.h
+++ b/arch/avr32/include/uapi/asm/unistd.h
@@ -333,5 +333,10 @@
#define __NR_memfd_create 318
#define __NR_bpf 319
#define __NR_execveat 320
+#define __NR_accept4 321
+#define __NR_userfaultfd 322
+#define __NR_membarrier 323
+#define __NR_mlock2 324
+#define __NR_copy_file_range 325
#endif /* _UAPI__ASM_AVR32_UNISTD_H */
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
index 164efa0..2b4c54c 100644
--- a/arch/avr32/kernel/module.c
+++ b/arch/avr32/kernel/module.c
@@ -118,9 +118,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
* Increase core size to make room for GOT and set start
* offset for GOT.
*/
- module->core_size = ALIGN(module->core_size, 4);
- module->arch.got_offset = module->core_size;
- module->core_size += module->arch.got_size;
+ module->core_layout.size = ALIGN(module->core_layout.size, 4);
+ module->arch.got_offset = module->core_layout.size;
+ module->core_layout.size += module->arch.got_size;
return 0;
@@ -177,7 +177,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
if (!info->got_initialized) {
Elf32_Addr *gotent;
- gotent = (module->module_core
+ gotent = (module->core_layout.base
+ module->arch.got_offset
+ info->got_offset);
*gotent = relocation;
@@ -255,8 +255,8 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
*/
pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
relocation, module->arch.got_offset,
- module->module_core);
- relocation -= ((unsigned long)module->module_core
+ module->core_layout.base);
+ relocation -= ((unsigned long)module->core_layout.base
+ module->arch.got_offset);
*location = relocation;
break;
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c
index 209ae5a..e692889 100644
--- a/arch/avr32/kernel/setup.c
+++ b/arch/avr32/kernel/setup.c
@@ -49,13 +49,13 @@ static struct resource __initdata kernel_data = {
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_SYSTEM_RAM,
};
static struct resource __initdata kernel_code = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_SYSTEM_RAM,
.sibling = &kernel_data,
};
@@ -134,7 +134,7 @@ add_physical_memory(resource_size_t start, resource_size_t end)
new->start = start;
new->end = end;
new->name = "System RAM";
- new->flags = IORESOURCE_MEM;
+ new->flags = IORESOURCE_SYSTEM_RAM;
*pprev = new;
}
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index f9c68fa..cb39915 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -124,3 +124,12 @@ __sys_process_vm_writev:
call sys_process_vm_writev
sub sp, -4
popm pc
+
+ .global __sys_copy_file_range
+ .type __sys_copy_file_range,@function
+__sys_copy_file_range:
+ pushm lr
+ st.w --sp, ARG6
+ call sys_copy_file_range
+ sub sp, -4
+ popm pc
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
index c3b593b..64d71a7 100644
--- a/arch/avr32/kernel/syscall_table.S
+++ b/arch/avr32/kernel/syscall_table.S
@@ -334,4 +334,9 @@ sys_call_table:
.long sys_memfd_create
.long sys_bpf
.long sys_execveat /* 320 */
+ .long sys_accept4
+ .long sys_userfaultfd
+ .long sys_membarrier
+ .long sys_mlock2
+ .long __sys_copy_file_range /* 325 */
.long sys_ni_syscall /* r8 is saturated at nr_syscalls */
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 1d8b147..bf445aa 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -17,7 +17,6 @@
#include <linux/spi/spi.h>
#include <linux/usb/atmel_usba_udc.h>
-#include <linux/platform_data/mmc-atmel-mci.h>
#include <linux/atmel-mci.h>
#include <asm/io.h>
@@ -603,18 +602,11 @@ static void __init genclk_init_parent(struct clk *clk)
clk->parent = parent;
}
-static struct dw_dma_platform_data dw_dmac0_data = {
- .nr_channels = 3,
- .block_size = 4095U,
- .nr_masters = 2,
- .data_width = { 2, 2 },
-};
-
static struct resource dw_dmac0_resource[] = {
PBMEM(0xff200000),
IRQ(2),
};
-DEFINE_DEV_DATA(dw_dmac, 0);
+DEFINE_DEV(dw_dmac, 0);
DEV_CLK(hclk, dw_dmac0, hsb, 10);
/* --------------------------------------------------------------------
@@ -1328,11 +1320,26 @@ static struct clk atmel_mci0_pclk = {
.index = 9,
};
+static bool at32_mci_dma_filter(struct dma_chan *chan, void *pdata)
+{
+ struct dw_dma_slave *sl = pdata;
+
+ if (!sl)
+ return false;
+
+ if (sl->dma_dev == chan->device->dev) {
+ chan->private = sl;
+ return true;
+ }
+
+ return false;
+}
+
struct platform_device *__init
at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{
struct platform_device *pdev;
- struct mci_dma_data *slave;
+ struct dw_dma_slave *slave;
u32 pioa_mask;
u32 piob_mask;
@@ -1351,17 +1358,18 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
ARRAY_SIZE(atmel_mci0_resource)))
goto fail;
- slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
+ slave = kzalloc(sizeof(*slave), GFP_KERNEL);
if (!slave)
goto fail;
- slave->sdata.dma_dev = &dw_dmac0_device.dev;
- slave->sdata.src_id = 0;
- slave->sdata.dst_id = 1;
- slave->sdata.src_master = 1;
- slave->sdata.dst_master = 0;
+ slave->dma_dev = &dw_dmac0_device.dev;
+ slave->src_id = 0;
+ slave->dst_id = 1;
+ slave->src_master = 1;
+ slave->dst_master = 0;
data->dma_slave = slave;
+ data->dma_filter = at32_mci_dma_filter;
if (platform_device_add_data(pdev, data,
sizeof(struct mci_platform_data)))
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index 4f61378..83c2a00 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -14,8 +14,8 @@
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
+#include <linux/gpio.h>
-#include <asm/gpio.h>
#include <asm/io.h>
#include <mach/portmux.h>
@@ -203,7 +203,7 @@ fail:
static int direction_input(struct gpio_chip *chip, unsigned offset)
{
- struct pio_device *pio = container_of(chip, struct pio_device, chip);
+ struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (!(pio_readl(pio, PSR) & mask))
@@ -215,7 +215,7 @@ static int direction_input(struct gpio_chip *chip, unsigned offset)
static int gpio_get(struct gpio_chip *chip, unsigned offset)
{
- struct pio_device *pio = container_of(chip, struct pio_device, chip);
+ struct pio_device *pio = gpiochip_get_data(chip);
return (pio_readl(pio, PDSR) >> offset) & 1;
}
@@ -224,7 +224,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value);
static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
- struct pio_device *pio = container_of(chip, struct pio_device, chip);
+ struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (!(pio_readl(pio, PSR) & mask))
@@ -237,7 +237,7 @@ static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
- struct pio_device *pio = container_of(chip, struct pio_device, chip);
+ struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (value)
@@ -335,7 +335,7 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
*/
static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip)
{
- struct pio_device *pio = container_of(chip, struct pio_device, chip);
+ struct pio_device *pio = gpiochip_get_data(chip);
u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr;
unsigned i;
u32 mask;
@@ -397,7 +397,7 @@ static int __init pio_probe(struct platform_device *pdev)
pio->chip.label = pio->name;
pio->chip.base = pdev->id * 32;
pio->chip.ngpio = 32;
- pio->chip.dev = &pdev->dev;
+ pio->chip.parent = &pdev->dev;
pio->chip.owner = THIS_MODULE;
pio->chip.direction_input = direction_input;
@@ -406,7 +406,7 @@ static int __init pio_probe(struct platform_device *pdev)
pio->chip.set = gpio_set;
pio->chip.dbg_show = pio_bank_show;
- gpiochip_add(&pio->chip);
+ gpiochip_add_data(&pio->chip, pio);
gpio_irq_setup(pio, irq, gpio_irq_base);
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
index 50cdb5b..92cf1fb 100644
--- a/arch/avr32/mm/dma-coherent.c
+++ b/arch/avr32/mm/dma-coherent.c
@@ -9,9 +9,14 @@
#include <linux/dma-mapping.h>
#include <linux/gfp.h>
#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/scatterlist.h>
-#include <asm/addrspace.h>
+#include <asm/processor.h>
#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction)
{
@@ -93,60 +98,100 @@ static void __dma_free(struct device *dev, size_t size,
__free_page(page++);
}
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp)
+static void *avr32_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
{
struct page *page;
- void *ret = NULL;
+ dma_addr_t phys;
page = __dma_alloc(dev, size, handle, gfp);
- if (page)
- ret = phys_to_uncached(page_to_phys(page));
+ if (!page)
+ return NULL;
+ phys = page_to_phys(page);
- return ret;
+ if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) {
+ /* Now, map the page into P3 with write-combining turned on */
+ *handle = phys;
+ return __ioremap(phys, size, _PAGE_BUFFER);
+ } else {
+ return phys_to_uncached(phys);
+ }
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void dma_free_coherent(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t handle)
+static void avr32_dma_free(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t handle, struct dma_attrs *attrs)
{
- void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
struct page *page;
- pr_debug("dma_free_coherent addr %p (phys %08lx) size %u\n",
- cpu_addr, (unsigned long)handle, (unsigned)size);
- BUG_ON(!virt_addr_valid(addr));
- page = virt_to_page(addr);
+ if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) {
+ iounmap(cpu_addr);
+
+ page = phys_to_page(handle);
+ } else {
+ void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
+
+ pr_debug("avr32_dma_free addr %p (phys %08lx) size %u\n",
+ cpu_addr, (unsigned long)handle, (unsigned)size);
+
+ BUG_ON(!virt_addr_valid(addr));
+ page = virt_to_page(addr);
+ }
+
__dma_free(dev, size, page, handle);
}
-EXPORT_SYMBOL(dma_free_coherent);
-void *dma_alloc_writecombine(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp)
+static dma_addr_t avr32_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
- struct page *page;
- dma_addr_t phys;
+ void *cpu_addr = page_address(page) + offset;
- page = __dma_alloc(dev, size, handle, gfp);
- if (!page)
- return NULL;
+ dma_cache_sync(dev, cpu_addr, size, direction);
+ return virt_to_bus(cpu_addr);
+}
- phys = page_to_phys(page);
- *handle = phys;
+static int avr32_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nents, i) {
+ char *virt;
- /* Now, map the page into P3 with write-combining turned on */
- return __ioremap(phys, size, _PAGE_BUFFER);
+ sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
+ virt = sg_virt(sg);
+ dma_cache_sync(dev, virt, sg->length, direction);
+ }
+
+ return nents;
}
-EXPORT_SYMBOL(dma_alloc_writecombine);
-void dma_free_writecombine(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t handle)
+static void avr32_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
- struct page *page;
+ dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
+}
- iounmap(cpu_addr);
+static void avr32_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sglist, int nents,
+ enum dma_data_direction direction)
+{
+ int i;
+ struct scatterlist *sg;
- page = phys_to_page(handle);
- __dma_free(dev, size, page, handle);
+ for_each_sg(sglist, sg, nents, i)
+ dma_cache_sync(dev, sg_virt(sg), sg->length, direction);
}
-EXPORT_SYMBOL(dma_free_writecombine);
+
+struct dma_map_ops avr32_dma_ops = {
+ .alloc = avr32_dma_alloc,
+ .free = avr32_dma_free,
+ .map_page = avr32_dma_map_page,
+ .map_sg = avr32_dma_map_sg,
+ .sync_single_for_device = avr32_dma_sync_single_for_device,
+ .sync_sg_for_device = avr32_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(avr32_dma_ops);
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index af76634..a63c122 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -1233,8 +1233,6 @@ source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
endmenu
menu "Executable file formats"
diff --git a/arch/blackfin/include/asm/barrier.h b/arch/blackfin/include/asm/barrier.h
index dfb66fe..7cca51c 100644
--- a/arch/blackfin/include/asm/barrier.h
+++ b/arch/blackfin/include/asm/barrier.h
@@ -78,8 +78,8 @@
#endif /* !CONFIG_SMP */
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
#include <asm-generic/barrier.h>
diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h
index 623cc7f..e7134bf 100644
--- a/arch/blackfin/include/asm/checksum.h
+++ b/arch/blackfin/include/asm/checksum.h
@@ -14,8 +14,8 @@
*/
static inline __wsum
-__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
unsigned int carry;
diff --git a/arch/blackfin/include/asm/cmpxchg.h b/arch/blackfin/include/asm/cmpxchg.h
index c05868c..2539288 100644
--- a/arch/blackfin/include/asm/cmpxchg.h
+++ b/arch/blackfin/include/asm/cmpxchg.h
@@ -128,6 +128,5 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
#endif /* !CONFIG_SMP */
#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
-#define tas(ptr) ((void)xchg((ptr), 1))
#endif /* __ARCH_BLACKFIN_CMPXCHG__ */
diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h
index 054d9ec..3490570 100644
--- a/arch/blackfin/include/asm/dma-mapping.h
+++ b/arch/blackfin/include/asm/dma-mapping.h
@@ -8,36 +8,6 @@
#define _BLACKFIN_DMA_MAPPING_H
#include <asm/cacheflush.h>
-struct scatterlist;
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle);
-
-/*
- * Now for the API extensions over the pci_ one
- */
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_supported(d, m) (1)
-
-static inline int
-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;
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
extern void
__dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
@@ -66,102 +36,11 @@ _dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
__dma_sync(addr, size, dir);
}
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction dir)
-{
- _dma_sync((dma_addr_t)ptr, size, dir);
- return (dma_addr_t) ptr;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- return dma_map_single(dev, page_address(page) + offset, size, dir);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
-{
- BUG_ON(!valid_dma_direction(dir));
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
-{
- dma_unmap_single(dev, dma_addr, size, dir);
-}
+extern struct dma_map_ops bfin_dma_ops;
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir);
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- BUG_ON(!valid_dma_direction(dir));
+ return &bfin_dma_ops;
}
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- BUG_ON(!valid_dma_direction(dir));
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- _dma_sync(handle + offset, size, dir);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
- enum dma_data_direction dir)
-{
- dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
- enum dma_data_direction dir)
-{
- dma_sync_single_range_for_device(dev, handle, 0, size, dir);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
-{
- BUG_ON(!valid_dma_direction(dir));
-}
-
-extern void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir);
-
-static inline void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction dir)
-{
- _dma_sync((dma_addr_t)vaddr, size, dir);
-}
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
#endif /* _BLACKFIN_DMA_MAPPING_H */
diff --git a/arch/blackfin/include/asm/pci.h b/arch/blackfin/include/asm/pci.h
index 14efc0d..11ea1cb 100644
--- a/arch/blackfin/include/asm/pci.h
+++ b/arch/blackfin/include/asm/pci.h
@@ -4,7 +4,6 @@
#define _ASM_BFIN_PCI_H
#include <linux/scatterlist.h>
-#include <asm-generic/pci-dma-compat.h>
#include <asm-generic/pci.h>
#define PCIBIOS_MIN_IO 0x00001000
diff --git a/arch/blackfin/include/asm/pgtable.h b/arch/blackfin/include/asm/pgtable.h
index b88a155..c1ee3d6 100644
--- a/arch/blackfin/include/asm/pgtable.h
+++ b/arch/blackfin/include/asm/pgtable.h
@@ -97,6 +97,8 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
unsigned long);
#define HAVE_ARCH_FB_UNMAPPED_AREA
+#define pgprot_writecombine pgprot_noncached
+
#include <asm-generic/pgtable.h>
#endif /* _BLACKFIN_PGTABLE_H */
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 90612a7..12f5d68 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -168,12 +168,6 @@ static inline int bad_user_access_length(void)
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-#define copy_to_user_ret(to, from, n, retval) ({ if (copy_to_user(to, from, n))\
- return retval; })
-
-#define copy_from_user_ret(to, from, n, retval) ({ if (copy_from_user(to, from, n))\
- return retval; })
-
static inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long n)
{
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index a017359..c5d3128 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -11,6 +11,8 @@
#include <linux/err.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/gpio/driver.h>
+/* FIXME: consumer API required for gpio_set_value() etc, get rid of this */
#include <linux/gpio.h>
#include <linux/irq.h>
@@ -1159,7 +1161,7 @@ static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio,
static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
{
- return bfin_gpio_get_value(gpio);
+ return !!bfin_gpio_get_value(gpio);
}
static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
@@ -1197,7 +1199,7 @@ static struct gpio_chip bfin_chip = {
static int __init bfin_gpiolib_setup(void)
{
- return gpiochip_add(&bfin_chip);
+ return gpiochip_add_data(&bfin_chip, NULL);
}
arch_initcall(bfin_gpiolib_setup);
#endif
diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c
index 86b1cd3..e272bca 100644
--- a/arch/blackfin/kernel/debug-mmrs.c
+++ b/arch/blackfin/kernel/debug-mmrs.c
@@ -11,9 +11,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c/bfin_twi.h>
+#include <linux/gpio.h>
#include <asm/blackfin.h>
-#include <asm/gpio.h>
#include <asm/gptimers.h>
#include <asm/bfin_can.h>
#include <asm/bfin_dma.h>
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index df437e5..771afe6 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -78,8 +78,8 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages)
spin_unlock_irqrestore(&dma_page_lock, flags);
}
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static void *bfin_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
void *ret;
@@ -92,15 +92,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void
-dma_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+static void bfin_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
__free_dma_pages((unsigned long)vaddr, get_pages(size));
}
-EXPORT_SYMBOL(dma_free_coherent);
/*
* Streaming DMA mappings
@@ -112,9 +109,9 @@ void __dma_sync(dma_addr_t addr, size_t size,
}
EXPORT_SYMBOL(__dma_sync);
-int
-dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,
- enum dma_data_direction direction)
+static int bfin_dma_map_sg(struct device *dev, struct scatterlist *sg_list,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct scatterlist *sg;
int i;
@@ -126,10 +123,10 @@ dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list,
- int nelems, enum dma_data_direction direction)
+static void bfin_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg_list, int nelems,
+ enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;
@@ -139,4 +136,31 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list,
__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+static dma_addr_t bfin_dma_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 handle = (dma_addr_t)(page_address(page) + offset);
+
+ _dma_sync(handle, size, dir);
+ return handle;
+}
+
+static inline void bfin_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ _dma_sync(handle, size, dir);
+}
+
+struct dma_map_ops bfin_dma_ops = {
+ .alloc = bfin_dma_alloc,
+ .free = bfin_dma_free,
+
+ .map_page = bfin_dma_map_page,
+ .map_sg = bfin_dma_map_sg,
+
+ .sync_single_for_device = bfin_dma_sync_single_for_device,
+ .sync_sg_for_device = bfin_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(bfin_dma_ops);
diff --git a/arch/blackfin/kernel/perf_event.c b/arch/blackfin/kernel/perf_event.c
index 1e9c8b0..170d786 100644
--- a/arch/blackfin/kernel/perf_event.c
+++ b/arch/blackfin/kernel/perf_event.c
@@ -14,7 +14,7 @@
* Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
* Copyright (C) 2009 Jaswinder Singh Rajput
* Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
* Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
*
* ppc:
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index a3a5723..80bcfd1 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -279,7 +279,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
#endif
#if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879)
-#include <linux/spi/ad7879.h>
+#include <linux/platform_data/ad7879.h>
static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.model = 7879, /* Model = AD7879 */
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index d4219e8..571edfd 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -477,7 +477,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
#endif
#if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879)
-#include <linux/spi/ad7879.h>
+#include <linux/platform_data/ad7879.h>
static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.model = 7879, /* Model = AD7879 */
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c
index a0f5856..c1acce4 100644
--- a/arch/blackfin/mach-bf527/boards/tll6527m.c
+++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -29,7 +29,7 @@
#include <asm/dpmc.h>
#if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879)
-#include <linux/spi/ad7879.h>
+#include <linux/platform_data/ad7879.h>
#define LCD_BACKLIGHT_GPIO 0x40
/* TLL6527M uses TLL7UIQ35 / ADI LCD EZ Extender. AD7879 AUX GPIO is used for
* LCD Backlight Enable
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 88a19fc..eaec7b4 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -404,7 +404,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = {
#define BFIN_NAND_PLAT_ALE 1
static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
@@ -776,7 +776,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
#endif
#if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879)
-#include <linux/spi/ad7879.h>
+#include <linux/platform_data/ad7879.h>
static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.model = 7879, /* Model = AD7879 */
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index ae2fcbb..1b6a52a 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -15,9 +15,9 @@
#include <linux/spi/flash.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/gpio.h>
#include <asm/bfin5xx_spi.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/nand.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
@@ -521,7 +521,7 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = {
#endif /* CONFIG_SPI_BFIN5XX */
#if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879)
-#include <linux/spi/ad7879.h>
+#include <linux/platform_data/ad7879.h>
static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.model = 7879, /* Model = AD7879 */
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
diff --git a/arch/blackfin/mach-bf538/ext-gpio.c b/arch/blackfin/mach-bf538/ext-gpio.c
index 471a9b1..48c1002 100644
--- a/arch/blackfin/mach-bf538/ext-gpio.c
+++ b/arch/blackfin/mach-bf538/ext-gpio.c
@@ -8,8 +8,8 @@
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/gpio.h>
#include <asm/blackfin.h>
-#include <asm/gpio.h>
#include <asm/portmux.h>
#define DEFINE_REG(reg, off) \
@@ -116,9 +116,9 @@ static struct gpio_chip bf538_porte_chip = {
static int __init bf538_extgpio_setup(void)
{
- return gpiochip_add(&bf538_portc_chip) |
- gpiochip_add(&bf538_portd_chip) |
- gpiochip_add(&bf538_porte_chip);
+ return gpiochip_add_data(&bf538_portc_chip, NULL) |
+ gpiochip_add_data(&bf538_portd_chip, NULL) |
+ gpiochip_add_data(&bf538_porte_chip, NULL);
}
arch_initcall(bf538_extgpio_setup);
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index 6d5ffde..120c994 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -17,9 +17,9 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/usb/musb.h>
+#include <linux/gpio.h>
#include <asm/bfin5xx_spi.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/nand.h>
#include <asm/portmux.h>
#include <asm/bfin_sdh.h>
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 4204b98..3cdd483 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -20,9 +20,9 @@
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_data/pinctrl-adi2.h>
+#include <linux/gpio.h>
#include <asm/bfin5xx_spi.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/nand.h>
#include <asm/dpmc.h>
#include <asm/bfin_sport.h>
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c
index 6ab9515..37f8f25 100644
--- a/arch/blackfin/mach-bf561/boards/acvilon.c
+++ b/arch/blackfin/mach-bf561/boards/acvilon.c
@@ -267,7 +267,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = {
static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 2de71e8..f35525b 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -443,7 +443,7 @@ static const struct ppi_info ppi_info = {
};
#if IS_ENABLED(CONFIG_VIDEO_ADV7183)
-#include <media/adv7183.h>
+#include <media/i2c/adv7183.h>
static struct v4l2_input adv7183_inputs[] = {
{
.index = 0,
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index 2c61fc0..aad5d74 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -21,8 +21,8 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_data/pinctrl-adi2.h>
#include <linux/spi/adi_spi3.h>
+#include <linux/gpio.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/nand.h>
#include <asm/dpmc.h>
#include <asm/portmux.h>
@@ -933,7 +933,7 @@ static struct bfin_capture_config bfin_capture_data = {
#endif
#if IS_ENABLED(CONFIG_VIDEO_ADV7842)
-#include <media/adv7842.h>
+#include <media/i2c/adv7842.h>
static struct v4l2_input adv7842_inputs[] = {
{
@@ -1084,7 +1084,7 @@ static const struct ppi_info ppi_info = {
};
#if IS_ENABLED(CONFIG_VIDEO_ADV7511)
-#include <media/adv7511.h>
+#include <media/i2c/adv7511.h>
static struct v4l2_output adv7511_outputs[] = {
{
@@ -1125,7 +1125,7 @@ static struct bfin_display_config bfin_display_data = {
#endif
#if IS_ENABLED(CONFIG_VIDEO_ADV7343)
-#include <media/adv7343.h>
+#include <media/i2c/adv7343.h>
static struct v4l2_output adv7343_outputs[] = {
{
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index e8d4d74..4986b4fb 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -17,13 +17,13 @@
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
#include <asm/delay.h>
#ifdef CONFIG_IPIPE
#include <linux/ipipe.h>
#endif
#include <asm/traps.h>
#include <asm/blackfin.h>
-#include <asm/gpio.h>
#include <asm/irq_handler.h>
#include <asm/dpmc.h>
#include <asm/traps.h>
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index a66d979..5ece38a 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -15,9 +15,9 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <asm/cplb.h>
-#include <asm/gpio.h>
#include <asm/dma.h>
#include <asm/dpmc.h>
#include <asm/pm.h>
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 0030e21..23c4ef5 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -333,7 +333,7 @@ void secondary_start_kernel(void)
/* We are done with local CPU inits, unblock the boot CPU. */
set_cpu_online(cpu, true);
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
void __init smp_prepare_boot_cpu(void)
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 77ea09b..5aa8ea8 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -17,6 +17,7 @@ config C6X
select OF_EARLY_FLATTREE
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
+ select ARCH_NO_COHERENT_DMA_MMAP
config MMU
def_bool n
@@ -35,6 +36,7 @@ config GENERIC_HWEIGHT
config GENERIC_BUG
def_bool y
+ depends on BUG
config C6X_BIG_KERNEL
bool "Build a big kernel"
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 945544e..64465e7 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -4,6 +4,7 @@ generic-y += auxvec.h
generic-y += barrier.h
generic-y += bitsperlong.h
generic-y += bugs.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h
index 7246816..249b0e4 100644
--- a/arch/c6x/include/asm/checksum.h
+++ b/arch/c6x/include/asm/checksum.h
@@ -10,8 +10,8 @@
#define _ASM_C6X_CHECKSUM_H
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
unsigned long long tmp;
diff --git a/arch/c6x/include/asm/clkdev.h b/arch/c6x/include/asm/clkdev.h
deleted file mode 100644
index 76a070b..0000000
--- a/arch/c6x/include/asm/clkdev.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ASM_CLKDEV_H
-#define _ASM_CLKDEV_H
-
-#include <linux/slab.h>
-
-struct clk;
-
-static inline int __clk_get(struct clk *clk)
-{
- return 1;
-}
-
-static inline void __clk_put(struct clk *clk)
-{
-}
-
-static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
-{
- return kzalloc(size, GFP_KERNEL);
-}
-
-#endif /* _ASM_CLKDEV_H */
diff --git a/arch/c6x/include/asm/cmpxchg.h b/arch/c6x/include/asm/cmpxchg.h
index b27c8ce..93d0a5a 100644
--- a/arch/c6x/include/asm/cmpxchg.h
+++ b/arch/c6x/include/asm/cmpxchg.h
@@ -47,8 +47,6 @@ static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size)
#define xchg(ptr, x) \
((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \
sizeof(*(ptr))))
-#define tas(ptr) xchg((ptr), 1)
-
#include <asm-generic/cmpxchg-local.h>
diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h
index bbd7774..6b5cd7b 100644
--- a/arch/c6x/include/asm/dma-mapping.h
+++ b/arch/c6x/include/asm/dma-mapping.h
@@ -12,104 +12,22 @@
#ifndef _ASM_C6X_DMA_MAPPING_H
#define _ASM_C6X_DMA_MAPPING_H
-#include <linux/dma-debug.h>
-#include <asm-generic/dma-coherent.h>
-
-#define dma_supported(d, m) 1
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t addr,
- unsigned long offset,
- size_t size,
- enum dma_data_direction dir)
-{
-}
-
-static inline int 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;
-}
-
/*
* 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 == ~0;
-}
-
-extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction dir);
+#define DMA_ERROR_CODE ~0
-extern void dma_unmap_single(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir);
+extern struct dma_map_ops c6x_dma_ops;
-extern int dma_map_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction direction);
-
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction direction);
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- dma_addr_t handle;
-
- handle = dma_map_single(dev, page_address(page) + offset, size, dir);
-
- debug_dma_map_page(dev, page, offset, size, dir, handle, false);
-
- return handle;
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- dma_unmap_single(dev, handle, size, dir);
-
- debug_dma_unmap_page(dev, handle, size, dir, false);
+ return &c6x_dma_ops;
}
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir);
-
-extern void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size,
- enum dma_data_direction dir);
-
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir);
-
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir);
-
extern void coherent_mem_init(u32 start, u32 size);
-extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
-
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
- struct vm_area_struct *vma, void *cpu_addr,
- dma_addr_t dma_addr, size_t size)
-{
- return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size)
-{
- return -EINVAL;
-}
+void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs);
+void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs);
#endif /* _ASM_C6X_DMA_MAPPING_H */
diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
index ab7b12d..8a80f3a 100644
--- a/arch/c6x/kernel/dma.c
+++ b/arch/c6x/kernel/dma.c
@@ -36,110 +36,101 @@ static void c6x_dma_sync(dma_addr_t handle, size_t size,
}
}
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction dir)
+static dma_addr_t c6x_dma_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 addr = virt_to_phys(ptr);
+ dma_addr_t handle = virt_to_phys(page_address(page) + offset);
- c6x_dma_sync(addr, size, dir);
-
- debug_dma_map_page(dev, virt_to_page(ptr),
- (unsigned long)ptr & ~PAGE_MASK, size,
- dir, addr, true);
- return addr;
+ c6x_dma_sync(handle, size, dir);
+ return handle;
}
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+static void c6x_dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir, struct dma_attrs *attrs)
{
c6x_dma_sync(handle, size, dir);
-
- debug_dma_unmap_page(dev, handle, size, dir, true);
}
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir)
+static int c6x_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct scatterlist *sg;
int i;
- for_each_sg(sglist, sg, nents, i)
- sg->dma_address = dma_map_single(dev, sg_virt(sg), sg->length,
- dir);
-
- debug_dma_map_sg(dev, sglist, nents, nents, dir);
+ for_each_sg(sglist, sg, nents, i) {
+ sg->dma_address = sg_phys(sg);
+ c6x_dma_sync(sg->dma_address, sg->length, dir);
+ }
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir)
+static void c6x_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct scatterlist *sg;
int i;
for_each_sg(sglist, sg, nents, i)
- dma_unmap_single(dev, sg_dma_address(sg), sg->length, dir);
+ c6x_dma_sync(sg_dma_address(sg), sg->length, dir);
- debug_dma_unmap_sg(dev, sglist, nents, dir);
}
-EXPORT_SYMBOL(dma_unmap_sg);
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+static void c6x_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
{
c6x_dma_sync(handle, size, dir);
- debug_dma_sync_single_for_cpu(dev, handle, size, dir);
}
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+static void c6x_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
c6x_dma_sync(handle, size, dir);
- debug_dma_sync_single_for_device(dev, handle, size, dir);
}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir)
+static void c6x_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sglist, int nents,
+ enum dma_data_direction dir)
{
struct scatterlist *sg;
int i;
for_each_sg(sglist, sg, nents, i)
- dma_sync_single_for_cpu(dev, sg_dma_address(sg),
+ c6x_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
sg->length, dir);
- debug_dma_sync_sg_for_cpu(dev, sglist, nents, dir);
}
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir)
+static void c6x_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sglist, int nents,
+ enum dma_data_direction dir)
{
struct scatterlist *sg;
int i;
for_each_sg(sglist, sg, nents, i)
- dma_sync_single_for_device(dev, sg_dma_address(sg),
+ c6x_dma_sync_single_for_device(dev, sg_dma_address(sg),
sg->length, dir);
- debug_dma_sync_sg_for_device(dev, sglist, nents, dir);
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+struct dma_map_ops c6x_dma_ops = {
+ .alloc = c6x_dma_alloc,
+ .free = c6x_dma_free,
+ .map_page = c6x_dma_map_page,
+ .unmap_page = c6x_dma_unmap_page,
+ .map_sg = c6x_dma_map_sg,
+ .unmap_sg = c6x_dma_unmap_sg,
+ .sync_single_for_device = c6x_dma_sync_single_for_device,
+ .sync_single_for_cpu = c6x_dma_sync_single_for_cpu,
+ .sync_sg_for_device = c6x_dma_sync_sg_for_device,
+ .sync_sg_for_cpu = c6x_dma_sync_sg_for_cpu,
+};
+EXPORT_SYMBOL(c6x_dma_ops);
/* Number of entries preallocated for DMA-API debugging */
#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c
index 72e17f7..786e36e 100644
--- a/arch/c6x/kernel/setup.c
+++ b/arch/c6x/kernel/setup.c
@@ -281,8 +281,6 @@ notrace void __init machine_init(unsigned long dt_ptr)
*/
set_ist(_vectors_start);
- lockdep_init();
-
/*
* dtb is passed in from bootloader.
* fdt is linked in blob.
diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c
index 4187e51..f7ee63a 100644
--- a/arch/c6x/mm/dma-coherent.c
+++ b/arch/c6x/mm/dma-coherent.c
@@ -73,8 +73,8 @@ static void __free_dma_pages(u32 addr, int order)
* Allocate DMA coherent memory space and return both the kernel
* virtual and DMA address for that space.
*/
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp)
+void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs)
{
u32 paddr;
int order;
@@ -94,13 +94,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return phys_to_virt(paddr);
}
-EXPORT_SYMBOL(dma_alloc_coherent);
/*
* Free DMA coherent memory as defined by the above mapping.
*/
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
int order;
@@ -111,7 +110,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
__free_dma_pages(virt_to_phys(vaddr), order);
}
-EXPORT_SYMBOL(dma_free_coherent);
/*
* Initialise the coherent DMA memory allocator using the given uncached region.
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index ddcb45d..43afc03 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -178,7 +178,7 @@ static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
static void __init parse_priority_map(struct megamod_pic *pic,
int *mapping, int size)
{
- struct device_node *np = pic->irqhost->of_node;
+ struct device_node *np = irq_domain_get_of_node(pic->irqhost);
const __be32 *map;
int i, maplen;
u32 val;
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 8da5653..e086f9e 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -57,7 +57,6 @@ config CRIS
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
- select GENERIC_CMOS_UPDATE
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS2
select OLD_SIGSUSPEND
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c
index 7d307cc..b6549e5 100644
--- a/arch/cris/arch-v10/kernel/debugport.c
+++ b/arch/cris/arch-v10/kernel/debugport.c
@@ -468,7 +468,7 @@ etrax_console_device(struct console* co, int *index)
#endif
}
-static struct console sercons = {
+static struct console ser_console = {
name : "ttyS",
write: console_write,
read : NULL,
@@ -480,7 +480,7 @@ static struct console sercons = {
cflag : 0,
next : NULL
};
-static struct console sercons0 = {
+static struct console ser0_console = {
name : "ttyS",
write: console_write,
read : NULL,
@@ -493,7 +493,7 @@ static struct console sercons0 = {
next : NULL
};
-static struct console sercons1 = {
+static struct console ser1_console = {
name : "ttyS",
write: console_write,
read : NULL,
@@ -505,7 +505,7 @@ static struct console sercons1 = {
cflag : 0,
next : NULL
};
-static struct console sercons2 = {
+static struct console ser2_console = {
name : "ttyS",
write: console_write,
read : NULL,
@@ -517,7 +517,7 @@ static struct console sercons2 = {
cflag : 0,
next : NULL
};
-static struct console sercons3 = {
+static struct console ser3_console = {
name : "ttyS",
write: console_write,
read : NULL,
@@ -539,17 +539,17 @@ init_etrax_debug(void)
static int first = 1;
if (!first) {
- unregister_console(&sercons);
- register_console(&sercons0);
- register_console(&sercons1);
- register_console(&sercons2);
- register_console(&sercons3);
+ unregister_console(&ser_console);
+ register_console(&ser0_console);
+ register_console(&ser1_console);
+ register_console(&ser2_console);
+ register_console(&ser3_console);
init_dummy_console();
return 0;
}
first = 0;
- register_console(&sercons);
+ register_console(&ser_console);
start_port(port);
#ifdef CONFIG_ETRAX_KGDB
start_port(kgdb_port);
diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S
index 4a146e1..a74aa23 100644
--- a/arch/cris/arch-v10/kernel/head.S
+++ b/arch/cris/arch-v10/kernel/head.S
@@ -5,6 +5,8 @@
*
*/
+#include <linux/init.h>
+
#define ASSEMBLER_MACROS_ONLY
/* The IO_* macros use the ## token concatenation operator, so
-traditional must not be used when assembling this file. */
@@ -25,7 +27,7 @@
.globl romfs_in_flash
.globl swapper_pg_dir
- .text
+ __HEAD
;; This is the entry point of the kernel. We are in supervisor mode.
;; 0x00000000 if Flash, 0x40004000 if DRAM
@@ -159,7 +161,7 @@ _inflash0:
;; Put this in a suitable section where we can reclaim storage
;; after init.
- .section ".init.text", "ax"
+ __INIT
_inflash:
#ifdef CONFIG_ETRAX_ETHERNET
;; Start MII clock to make sure it is running when tranceiver is reset
@@ -354,63 +356,6 @@ no_command_line:
blo 1b
nop
-#ifdef CONFIG_BLK_DEV_ETRAXIDE
- ;; disable ATA before enabling it in genconfig below
- moveq 0,$r0
- move.d $r0,[R_ATA_CTRL_DATA]
- move.d $r0,[R_ATA_TRANSFER_CNT]
- move.d $r0,[R_ATA_CONFIG]
-#if 0
- move.d R_PORT_G_DATA, $r1
- move.d $r0, [$r1]; assert ATA bus-reset
- nop
- nop
- nop
- nop
- nop
- nop
- move.d 0x08000000,$r0
- move.d $r0,[$r1]
-#endif
-#endif
-
-#ifdef CONFIG_JULIETTE
- ;; configure external DMA channel 0 before enabling it in genconfig
-
- moveq 0,$r0
- move.d $r0,[R_EXT_DMA_0_ADDR]
- ; cnt enable, word size, output, stop, size 0
- move.d IO_STATE (R_EXT_DMA_0_CMD, cnt, enable) \
- | IO_STATE (R_EXT_DMA_0_CMD, rqpol, ahigh) \
- | IO_STATE (R_EXT_DMA_0_CMD, apol, ahigh) \
- | IO_STATE (R_EXT_DMA_0_CMD, rq_ack, burst) \
- | IO_STATE (R_EXT_DMA_0_CMD, wid, word) \
- | IO_STATE (R_EXT_DMA_0_CMD, dir, output) \
- | IO_STATE (R_EXT_DMA_0_CMD, run, stop) \
- | IO_FIELD (R_EXT_DMA_0_CMD, trf_count, 0),$r0
- move.d $r0,[R_EXT_DMA_0_CMD]
-
- ;; reset dma4 and wait for completion
-
- moveq IO_STATE (R_DMA_CH4_CMD, cmd, reset),$r0
- move.b $r0,[R_DMA_CH4_CMD]
-1: move.b [R_DMA_CH4_CMD],$r0
- and.b IO_MASK (R_DMA_CH4_CMD, cmd),$r0
- cmp.b IO_STATE (R_DMA_CH4_CMD, cmd, reset),$r0
- beq 1b
- nop
-
- ;; reset dma5 and wait for completion
-
- moveq IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0
- move.b $r0,[R_DMA_CH5_CMD]
-1: move.b [R_DMA_CH5_CMD],$r0
- and.b IO_MASK (R_DMA_CH5_CMD, cmd),$r0
- cmp.b IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0
- beq 1b
- nop
-#endif
-
;; Etrax product HW genconfig setup
moveq 0,$r0
@@ -447,21 +392,6 @@ no_command_line:
| IO_STATE (R_GEN_CONFIG, dma9, usb),$r0
-#if defined(CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT)
- or.d IO_STATE (R_GEN_CONFIG, g0dir, out),$r0
-#endif
-
-#if defined(CONFIG_ETRAX_DEF_R_PORT_G8_15_DIR_OUT)
- or.d IO_STATE (R_GEN_CONFIG, g8_15dir, out),$r0
-#endif
-#if defined(CONFIG_ETRAX_DEF_R_PORT_G16_23_DIR_OUT)
- or.d IO_STATE (R_GEN_CONFIG, g16_23dir, out),$r0
-#endif
-
-#if defined(CONFIG_ETRAX_DEF_R_PORT_G24_DIR_OUT)
- or.d IO_STATE (R_GEN_CONFIG, g24dir, out),$r0
-#endif
-
move.d $r0,[genconfig_shadow] ; init a shadow register of R_GEN_CONFIG
move.d $r0,[R_GEN_CONFIG]
@@ -500,19 +430,9 @@ no_command_line:
;; including their shadow registers
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR,$r0
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PA7)
- or.b IO_STATE (R_PORT_PA_DIR, dir7, output),$r0
-#endif
move.b $r0,[port_pa_dir_shadow]
move.b $r0,[R_PORT_PA_DIR]
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA,$r0
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PA7)
-#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
- and.b ~(1 << 7),$r0
-#else
- or.b (1 << 7),$r0
-#endif
-#endif
move.b $r0,[port_pa_data_shadow]
move.b $r0,[R_PORT_PA_DATA]
@@ -520,19 +440,9 @@ no_command_line:
move.b $r0,[port_pb_config_shadow]
move.b $r0,[R_PORT_PB_CONFIG]
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR,$r0
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PB5)
- or.b IO_STATE (R_PORT_PB_DIR, dir5, output),$r0
-#endif
move.b $r0,[port_pb_dir_shadow]
move.b $r0,[R_PORT_PB_DIR]
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA,$r0
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PB5)
-#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
- and.b ~(1 << 5),$r0
-#else
- or.b (1 << 5),$r0
-#endif
-#endif
move.b $r0,[port_pb_data_shadow]
move.b $r0,[R_PORT_PB_DATA]
@@ -541,20 +451,6 @@ no_command_line:
move.d $r0, [R_PORT_PB_I2C]
moveq 0,$r0
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_G10)
-#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
- and.d ~(1 << 10),$r0
-#else
- or.d (1 << 10),$r0
-#endif
-#endif
-#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_G11)
-#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
- and.d ~(1 << 11),$r0
-#else
- or.d (1 << 11),$r0
-#endif
-#endif
move.d $r0,[port_g_data_shadow]
move.d $r0,[R_PORT_G_DATA]
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index 22d846b..ed71ade 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -275,7 +275,7 @@ static char remcomOutBuffer[BUFMAX];
/* Error and warning messages. */
enum error_type
{
- SUCCESS, E01, E02, E03, E04, E05, E06, E07
+ SUCCESS, E01, E02, E03, E04, E05, E06, E07, E08
};
static char *error_message[] =
{
@@ -286,7 +286,8 @@ static char *error_message[] =
"E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
"E05 Change register content - P - the register is not implemented..",
"E06 Change memory content - M - internal error.",
- "E07 Change register content - P - the register is not stored on the stack"
+ "E07 Change register content - P - the register is not stored on the stack",
+ "E08 Invalid parameter"
};
/********************************* Register image ****************************/
/* Use the order of registers as defined in "AXIS ETRAX CRIS Programmer's
@@ -351,7 +352,7 @@ char internal_stack[INTERNAL_STACK_SIZE];
breakpoint to be handled. A static breakpoint uses the content of register
BRP as it is whereas a dynamic breakpoint requires subtraction with 2
in order to execute the instruction. The first breakpoint is static. */
-static unsigned char is_dyn_brkp = 0;
+static unsigned char __used is_dyn_brkp;
/********************************* String library ****************************/
/* Single-step over library functions creates trap loops. */
@@ -413,18 +414,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base)
}
/********************************** Packet I/O ******************************/
-/* Returns the integer equivalent of a hexadecimal character. */
-static int
-hex (char ch)
-{
- if ((ch >= 'a') && (ch <= 'f'))
- return (ch - 'a' + 10);
- if ((ch >= '0') && (ch <= '9'))
- return (ch - '0');
- if ((ch >= 'A') && (ch <= 'F'))
- return (ch - 'A' + 10);
- return (-1);
-}
/* Convert the memory, pointed to by mem into hexadecimal representation.
Put the result in buf, and return a pointer to the last character
@@ -455,22 +444,6 @@ mem2hex(char *buf, unsigned char *mem, int count)
return (buf);
}
-/* Convert the array, in hexadecimal representation, pointed to by buf into
- binary representation. Put the result in mem, and return a pointer to
- the character after the last byte written. */
-static unsigned char*
-hex2mem (unsigned char *mem, char *buf, int count)
-{
- int i;
- unsigned char ch;
- for (i = 0; i < count; i++) {
- ch = hex (*buf++) << 4;
- ch = ch + hex (*buf++);
- *mem++ = ch;
- }
- return (mem);
-}
-
/* Put the content of the array, in binary representation, pointed to by buf
into memory pointed to by mem, and return a pointer to the character after
the last byte written.
@@ -524,8 +497,8 @@ getpacket (char *buffer)
buffer[count] = '\0';
if (ch == '#') {
- xmitcsum = hex (getDebugChar ()) << 4;
- xmitcsum += hex (getDebugChar ());
+ xmitcsum = hex_to_bin(getDebugChar()) << 4;
+ xmitcsum += hex_to_bin(getDebugChar());
if (checksum != xmitcsum) {
/* Wrong checksum */
putDebugChar ('-');
@@ -599,7 +572,7 @@ putDebugString (const unsigned char *str, int length)
/********************************* Register image ****************************/
/* Write a value to a specified register in the register image of the current
- thread. Returns status code SUCCESS, E02 or E05. */
+ thread. Returns status code SUCCESS, E02, E05 or E08. */
static int
write_register (int regno, char *val)
{
@@ -608,8 +581,9 @@ write_register (int regno, char *val)
if (regno >= R0 && regno <= PC) {
/* 32-bit register with simple offset. */
- hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
- val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)current_reg + regno * sizeof(unsigned int),
+ val, sizeof(unsigned int)))
+ status = E08;
}
else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
/* Do not support read-only registers. */
@@ -618,13 +592,15 @@ write_register (int regno, char *val)
else if (regno == CCR) {
/* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented,
and P7 (MOF) is 32 bits in ETRAX 100LX. */
- hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
- val, sizeof(unsigned short));
+ if (hex2bin((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
+ val, sizeof(unsigned short)))
+ status = E08;
}
else if (regno >= MOF && regno <= USP) {
/* 32 bit register with complex offset. (P8 has been taken care of.) */
- hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
- val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
+ val, sizeof(unsigned int)))
+ status = E08;
}
else {
/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
@@ -759,9 +735,11 @@ handle_exception (int sigval)
/* Write registers. GXX..XX
Each byte of register data is described by two hex digits.
Success: OK
- Failure: void. */
- hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers));
- gdb_cris_strcpy (remcomOutBuffer, "OK");
+ Failure: E08. */
+ if (hex2bin((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers)))
+ gdb_cris_strcpy (remcomOutBuffer, error_message[E08]);
+ else
+ gdb_cris_strcpy (remcomOutBuffer, "OK");
break;
case 'P':
@@ -771,7 +749,7 @@ handle_exception (int sigval)
for each byte in the register (target byte order). P1f=11223344 means
set register 31 to 44332211.
Success: OK
- Failure: E02, E05 */
+ Failure: E02, E05, E08 */
{
char *suffix;
int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
@@ -791,6 +769,10 @@ handle_exception (int sigval)
/* Do not support non-existing registers on the stack. */
gdb_cris_strcpy (remcomOutBuffer, error_message[E07]);
break;
+ case E08:
+ /* Invalid parameter. */
+ gdb_cris_strcpy (remcomOutBuffer, error_message[E08]);
+ break;
default:
/* Valid register number. */
gdb_cris_strcpy (remcomOutBuffer, "OK");
@@ -826,7 +808,7 @@ handle_exception (int sigval)
AA..AA is the start address, LLLL is the number of bytes, and
XX..XX is the hexadecimal data.
Success: OK
- Failure: void. */
+ Failure: E08. */
{
char *lenptr;
char *dataptr;
@@ -835,14 +817,15 @@ handle_exception (int sigval)
int length = gdb_cris_strtol(lenptr+1, &dataptr, 16);
if (*lenptr == ',' && *dataptr == ':') {
if (remcomInBuffer[0] == 'M') {
- hex2mem(addr, dataptr + 1, length);
- }
- else /* X */ {
+ if (hex2bin(addr, dataptr + 1, length))
+ gdb_cris_strcpy (remcomOutBuffer, error_message[E08]);
+ else
+ gdb_cris_strcpy (remcomOutBuffer, "OK");
+ } else /* X */ {
bin2mem(addr, dataptr + 1, length);
+ gdb_cris_strcpy (remcomOutBuffer, "OK");
}
- gdb_cris_strcpy (remcomOutBuffer, "OK");
- }
- else {
+ } else {
gdb_cris_strcpy (remcomOutBuffer, error_message[E06]);
}
}
@@ -970,7 +953,7 @@ asm ("\n"
" move $ibr,[cris_reg+0x4E] ; P9,\n"
" move $irp,[cris_reg+0x52] ; P10,\n"
" move $srp,[cris_reg+0x56] ; P11,\n"
-" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
+" move $bar,[cris_reg+0x5A] ; P12,\n"
" ; P13, register DCCR already saved\n"
";; Due to the old assembler-versions BRP might not be recognized\n"
" .word 0xE670 ; move brp,r0\n"
@@ -1063,7 +1046,7 @@ asm ("\n"
" move $ibr,[cris_reg+0x4E] ; P9,\n"
" move $irp,[cris_reg+0x52] ; P10,\n"
" move $srp,[cris_reg+0x56] ; P11,\n"
-" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
+" move $bar,[cris_reg+0x5A] ; P12,\n"
" ; P13, register DCCR already saved\n"
";; Due to the old assembler-versions BRP might not be recognized\n"
" .word 0xE670 ; move brp,r0\n"
diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c
index e7f8066..85e3f1b 100644
--- a/arch/cris/arch-v10/mm/init.c
+++ b/arch/cris/arch-v10/mm/init.c
@@ -68,14 +68,10 @@ paging_init(void)
*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg ) | /* bootrom */
IO_STATE(R_MMU_KSEG, seg_e, page ) |
- IO_STATE(R_MMU_KSEG, seg_d, page ) |
- IO_STATE(R_MMU_KSEG, seg_c, page ) |
+ IO_STATE(R_MMU_KSEG, seg_d, page ) |
+ IO_STATE(R_MMU_KSEG, seg_c, page ) |
IO_STATE(R_MMU_KSEG, seg_b, seg ) | /* kernel reg area */
-#ifdef CONFIG_JULIETTE
- IO_STATE(R_MMU_KSEG, seg_a, seg ) | /* ARTPEC etc. */
-#else
IO_STATE(R_MMU_KSEG, seg_a, page ) |
-#endif
IO_STATE(R_MMU_KSEG, seg_9, seg ) | /* LED's on some boards */
IO_STATE(R_MMU_KSEG, seg_8, seg ) | /* CSE0/1, flash and I/O */
IO_STATE(R_MMU_KSEG, seg_7, page ) | /* kernel vmalloc area */
@@ -92,14 +88,10 @@ paging_init(void)
IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
-#ifdef CONFIG_JULIETTE
- IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
-#else
IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
-#endif
IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) |
IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) );
-
+
*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
IO_FIELD(R_MMU_KBASE_LO, base_6, 0x4 ) |
IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 21bbd93..17dbe03 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -11,95 +11,6 @@ config ETRAX_DRAM_VIRTUAL_BASE
default "c0000000"
choice
- prompt "Nbr of Ethernet LED groups"
- depends on ETRAX_ARCH_V32
- default ETRAX_NBR_LED_GRP_ONE
- help
- Select how many Ethernet LED groups that can be used. Usually one per Ethernet
- interface is a good choice.
-
-config ETRAX_NBR_LED_GRP_ZERO
- bool "Use zero LED groups"
- help
- Select this if you do not want any Ethernet LEDs.
-
-config ETRAX_NBR_LED_GRP_ONE
- bool "Use one LED group"
- help
- Select this if you want one Ethernet LED group. This LED group
- can be used for one or more Ethernet interfaces. However, it is
- recommended that each Ethernet interface use a dedicated LED group.
-
-config ETRAX_NBR_LED_GRP_TWO
- bool "Use two LED groups"
- help
- Select this if you want two Ethernet LED groups. This is the
- best choice if you have more than one Ethernet interface and
- would like to have separate LEDs for the interfaces.
-
-endchoice
-
-config ETRAX_LED_G_NET0
- string "Ethernet LED group 0 green LED bit"
- depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
- default "PA3"
- help
- Bit to use for the green LED in Ethernet LED group 0.
-
-config ETRAX_LED_R_NET0
- string "Ethernet LED group 0 red LED bit"
- depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO)
- default "PA4"
- help
- Bit to use for the red LED in Ethernet LED group 0.
-
-config ETRAX_LED_G_NET1
- string "Ethernet group 1 green LED bit"
- depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
- default ""
- help
- Bit to use for the green LED in Ethernet LED group 1.
-
-config ETRAX_LED_R_NET1
- string "Ethernet group 1 red LED bit"
- depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO
- default ""
- help
- Bit to use for the red LED in Ethernet LED group 1.
-
-config ETRAX_V32_LED2G
- string "Second green LED bit"
- depends on ETRAX_ARCH_V32
- default "PA5"
- help
- Bit to use for the first green LED (status LED).
- Most Axis products use bit A5 here.
-
-config ETRAX_V32_LED2R
- string "Second red LED bit"
- depends on ETRAX_ARCH_V32
- default "PA6"
- help
- Bit to use for the first red LED (network LED).
- Most Axis products use bit A6 here.
-
-config ETRAX_V32_LED3G
- string "Third green LED bit"
- depends on ETRAX_ARCH_V32
- default "PA7"
- help
- Bit to use for the first green LED (drive/power LED).
- Most Axis products use bit A7 here.
-
-config ETRAX_V32_LED3R
- string "Third red LED bit"
- depends on ETRAX_ARCH_V32
- default "PA7"
- help
- Bit to use for the first red LED (drive/power LED).
- Most Axis products use bit A7 here.
-
-choice
prompt "Kernel GDB port"
depends on ETRAX_KGDB
default ETRAX_KGDB_PORT0
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index e6c523c..2735eb7 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -149,173 +149,6 @@ config ETRAX_NANDBOOT
Say Y if your boot code, kernel and root file system is in
NAND flash. Say N if they are in NOR flash.
-config ETRAX_I2C
- bool "I2C driver"
- depends on ETRAX_ARCH_V32
- help
- This option enables the I2C driver used by e.g. the RTC driver.
-
-config ETRAX_V32_I2C_DATA_PORT
- string "I2C data pin"
- depends on ETRAX_I2C
- help
- The pin to use for I2C data.
-
-config ETRAX_V32_I2C_CLK_PORT
- string "I2C clock pin"
- depends on ETRAX_I2C
- help
- The pin to use for I2C clock.
-
-config ETRAX_GPIO
- bool "GPIO support"
- depends on ETRAX_ARCH_V32
- ---help---
- Enables the ETRAX general port device (major 120, minors 0-4).
- You can use this driver to access the general port bits. It supports
- these ioctl's:
- #include <linux/etraxgpio.h>
- fd = open("/dev/gpioa", O_RDWR); // or /dev/gpiob
- ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS), bits_to_set);
- ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS), bits_to_clear);
- err = ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_READ_INBITS), &val);
- Remember that you need to setup the port directions appropriately in
- the General configuration.
-
-config ETRAX_VIRTUAL_GPIO
- bool "Virtual GPIO support"
- depends on ETRAX_GPIO
- help
- Enables the virtual Etrax general port device (major 120, minor 6).
- It uses an I/O expander for the I2C-bus.
-
-config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN
- int "Virtual GPIO interrupt pin on PA pin"
- range 0 7
- depends on ETRAX_VIRTUAL_GPIO
- help
- The pin to use on PA for virtual gpio interrupt.
-
-config ETRAX_PA_CHANGEABLE_DIR
- hex "PA user changeable dir mask"
- depends on ETRAX_GPIO
- default "0x00" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PA that a
- user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0 here, but it depends on your hardware.
-
-config ETRAX_PA_CHANGEABLE_BITS
- hex "PA user changeable bits mask"
- depends on ETRAX_GPIO
- default "0x00" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PA
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
-config ETRAX_PB_CHANGEABLE_DIR
- hex "PB user changeable dir mask"
- depends on ETRAX_GPIO
- default "0x00000" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PB
- that a user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0 here, but it depends on your hardware.
-
-config ETRAX_PB_CHANGEABLE_BITS
- hex "PB user changeable bits mask"
- depends on ETRAX_GPIO
- default "0x00000" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PB
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
-config ETRAX_PC_CHANGEABLE_DIR
- hex "PC user changeable dir mask"
- depends on ETRAX_GPIO
- default "0x00000" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PC
- that a user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0 here, but it depends on your hardware.
-
-config ETRAX_PC_CHANGEABLE_BITS
- hex "PC user changeable bits mask"
- depends on ETRAX_GPIO
- default "0x00000" if ETRAXFS
- default "0x00000000" if !ETRAXFS
- help
- This is a bitmask with information of what bits in PC
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
-config ETRAX_PD_CHANGEABLE_DIR
- hex "PD user changeable dir mask"
- depends on ETRAX_GPIO && ETRAXFS
- default "0x00000"
- help
- This is a bitmask with information of what bits in PD
- that a user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0x00000 here, but it depends on your hardware.
-
-config ETRAX_PD_CHANGEABLE_BITS
- hex "PD user changeable bits mask"
- depends on ETRAX_GPIO && ETRAXFS
- default "0x00000"
- help
- This is a bitmask (18 bits) with information of what bits in PD
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
-config ETRAX_PE_CHANGEABLE_DIR
- hex "PE user changeable dir mask"
- depends on ETRAX_GPIO && ETRAXFS
- default "0x00000"
- help
- This is a bitmask (18 bits) with information of what bits in PE
- that a user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0x00000 here, but it depends on your hardware.
-
-config ETRAX_PE_CHANGEABLE_BITS
- hex "PE user changeable bits mask"
- depends on ETRAX_GPIO && ETRAXFS
- default "0x00000"
- help
- This is a bitmask (18 bits) with information of what bits in PE
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
-config ETRAX_PV_CHANGEABLE_DIR
- hex "PV user changeable dir mask"
- depends on ETRAX_VIRTUAL_GPIO
- default "0x0000"
- help
- This is a bitmask (16 bits) with information of what bits in PV
- that a user can change direction on using ioctl's.
- Bit set = changeable.
- You probably want 0x0000 here, but it depends on your hardware.
-
-config ETRAX_PV_CHANGEABLE_BITS
- hex "PV user changeable bits mask"
- depends on ETRAX_VIRTUAL_GPIO
- default "0x0000"
- help
- This is a bitmask (16 bits) with information of what bits in PV
- that a user can change the value on using ioctl's.
- Bit set = changeable.
-
config ETRAX_CARDBUS
bool "Cardbus support"
depends on ETRAX_ARCH_V32
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile
index 15fbfef..b5a75fd 100644
--- a/arch/cris/arch-v32/drivers/Makefile
+++ b/arch/cris/arch-v32/drivers/Makefile
@@ -7,6 +7,5 @@ obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
obj-$(CONFIG_ETRAXFS) += mach-fs/
obj-$(CONFIG_CRIS_MACH_ARTPEC3) += mach-a3/
obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o
-obj-$(CONFIG_ETRAX_I2C) += i2c.o
obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
obj-$(CONFIG_PCI) += pci/
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 5387424..c6309a1 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -361,7 +361,7 @@ static int __init init_axis_flash(void)
#if 0 /* Dump flash memory so we can see what is going on */
if (main_mtd) {
- int sectoraddr, i;
+ int sectoraddr;
for (sectoraddr = 0; sectoraddr < 2*65536+4096;
sectoraddr += PAGESIZE) {
main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len,
@@ -369,21 +369,7 @@ static int __init init_axis_flash(void)
printk(KERN_INFO
"Sector at %d (length %d):\n",
sectoraddr, len);
- for (i = 0; i < PAGESIZE; i += 16) {
- printk(KERN_INFO
- "%02x %02x %02x %02x "
- "%02x %02x %02x %02x "
- "%02x %02x %02x %02x "
- "%02x %02x %02x %02x\n",
- page[i] & 255, page[i+1] & 255,
- page[i+2] & 255, page[i+3] & 255,
- page[i+4] & 255, page[i+5] & 255,
- page[i+6] & 255, page[i+7] & 255,
- page[i+8] & 255, page[i+9] & 255,
- page[i+10] & 255, page[i+11] & 255,
- page[i+12] & 255, page[i+13] & 255,
- page[i+14] & 255, page[i+15] & 255);
- }
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, page, PAGESIZE, false);
}
}
#endif
@@ -417,25 +403,11 @@ static int __init init_axis_flash(void)
#if 0 /* Dump partition table so we can see what is going on */
printk(KERN_INFO
- "axisflashmap: flash read %d bytes at 0x%08x, data: "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- len, CONFIG_ETRAX_PTABLE_SECTOR,
- page[0] & 255, page[1] & 255,
- page[2] & 255, page[3] & 255,
- page[4] & 255, page[5] & 255,
- page[6] & 255, page[7] & 255);
+ "axisflashmap: flash read %d bytes at 0x%08x, data: %8ph\n",
+ len, CONFIG_ETRAX_PTABLE_SECTOR, page);
printk(KERN_INFO
- "axisflashmap: partition table offset %d, data: "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- PARTITION_TABLE_OFFSET,
- page[PARTITION_TABLE_OFFSET+0] & 255,
- page[PARTITION_TABLE_OFFSET+1] & 255,
- page[PARTITION_TABLE_OFFSET+2] & 255,
- page[PARTITION_TABLE_OFFSET+3] & 255,
- page[PARTITION_TABLE_OFFSET+4] & 255,
- page[PARTITION_TABLE_OFFSET+5] & 255,
- page[PARTITION_TABLE_OFFSET+6] & 255,
- page[PARTITION_TABLE_OFFSET+7] & 255);
+ "axisflashmap: partition table offset %d, data: %8ph\n",
+ PARTITION_TABLE_OFFSET, page + PARTITION_TABLE_OFFSET);
#endif
}
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
deleted file mode 100644
index 3b2c82c..0000000
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/*!***************************************************************************
-*!
-*! FILE NAME : i2c.c
-*!
-*! DESCRIPTION: implements an interface for IIC/I2C, both directly from other
-*! kernel modules (i2c_writereg/readreg) and from userspace using
-*! ioctl()'s
-*!
-*! Nov 30 1998 Torbjorn Eliasson Initial version.
-*! Bjorn Wesen Elinux kernel version.
-*! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff -
-*! don't use PB_I2C if DS1302 uses same bits,
-*! use PB.
-*| June 23 2003 Pieter Grimmerink Added 'i2c_sendnack'. i2c_readreg now
-*| generates nack on last received byte,
-*| instead of ack.
-*| i2c_getack changed data level while clock
-*| was high, causing DS75 to see a stop condition
-*!
-*! ---------------------------------------------------------------------------
-*!
-*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
-*!
-*!***************************************************************************/
-
-/****************** INCLUDE FILES SECTION ***********************************/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-
-#include <asm/etraxi2c.h>
-
-#include <asm/io.h>
-#include <asm/delay.h>
-
-#include "i2c.h"
-
-/****************** I2C DEFINITION SECTION *************************/
-
-#define D(x)
-
-#define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */
-static DEFINE_MUTEX(i2c_mutex);
-static const char i2c_name[] = "i2c";
-
-#define CLOCK_LOW_TIME 8
-#define CLOCK_HIGH_TIME 8
-#define START_CONDITION_HOLD_TIME 8
-#define STOP_CONDITION_HOLD_TIME 8
-#define ENABLE_OUTPUT 0x01
-#define ENABLE_INPUT 0x00
-#define I2C_CLOCK_HIGH 1
-#define I2C_CLOCK_LOW 0
-#define I2C_DATA_HIGH 1
-#define I2C_DATA_LOW 0
-
-#define i2c_enable()
-#define i2c_disable()
-
-/* enable or disable output-enable, to select output or input on the i2c bus */
-
-#define i2c_dir_out() crisv32_io_set_dir(&cris_i2c_data, crisv32_io_dir_out)
-#define i2c_dir_in() crisv32_io_set_dir(&cris_i2c_data, crisv32_io_dir_in)
-
-/* control the i2c clock and data signals */
-
-#define i2c_clk(x) crisv32_io_set(&cris_i2c_clk, x)
-#define i2c_data(x) crisv32_io_set(&cris_i2c_data, x)
-
-/* read a bit from the i2c interface */
-
-#define i2c_getbit() crisv32_io_rd(&cris_i2c_data)
-
-#define i2c_delay(usecs) udelay(usecs)
-
-static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
-
-/****************** VARIABLE SECTION ************************************/
-
-static struct crisv32_iopin cris_i2c_clk;
-static struct crisv32_iopin cris_i2c_data;
-
-/****************** FUNCTION DEFINITION SECTION *************************/
-
-
-/* generate i2c start condition */
-
-void
-i2c_start(void)
-{
- /*
- * SCL=1 SDA=1
- */
- i2c_dir_out();
- i2c_delay(CLOCK_HIGH_TIME/6);
- i2c_data(I2C_DATA_HIGH);
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
- /*
- * SCL=1 SDA=0
- */
- i2c_data(I2C_DATA_LOW);
- i2c_delay(START_CONDITION_HOLD_TIME);
- /*
- * SCL=0 SDA=0
- */
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_LOW_TIME);
-}
-
-/* generate i2c stop condition */
-
-void
-i2c_stop(void)
-{
- i2c_dir_out();
-
- /*
- * SCL=0 SDA=0
- */
- i2c_clk(I2C_CLOCK_LOW);
- i2c_data(I2C_DATA_LOW);
- i2c_delay(CLOCK_LOW_TIME*2);
- /*
- * SCL=1 SDA=0
- */
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME*2);
- /*
- * SCL=1 SDA=1
- */
- i2c_data(I2C_DATA_HIGH);
- i2c_delay(STOP_CONDITION_HOLD_TIME);
-
- i2c_dir_in();
-}
-
-/* write a byte to the i2c interface */
-
-void
-i2c_outbyte(unsigned char x)
-{
- int i;
-
- i2c_dir_out();
-
- for (i = 0; i < 8; i++) {
- if (x & 0x80) {
- i2c_data(I2C_DATA_HIGH);
- } else {
- i2c_data(I2C_DATA_LOW);
- }
-
- i2c_delay(CLOCK_LOW_TIME/2);
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_LOW_TIME/2);
- x <<= 1;
- }
- i2c_data(I2C_DATA_LOW);
- i2c_delay(CLOCK_LOW_TIME/2);
-
- /*
- * enable input
- */
- i2c_dir_in();
-}
-
-/* read a byte from the i2c interface */
-
-unsigned char
-i2c_inbyte(void)
-{
- unsigned char aBitByte = 0;
- int i;
-
- /* Switch off I2C to get bit */
- i2c_disable();
- i2c_dir_in();
- i2c_delay(CLOCK_HIGH_TIME/2);
-
- /* Get bit */
- aBitByte |= i2c_getbit();
-
- /* Enable I2C */
- i2c_enable();
- i2c_delay(CLOCK_LOW_TIME/2);
-
- for (i = 1; i < 8; i++) {
- aBitByte <<= 1;
- /* Clock pulse */
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_LOW_TIME);
-
- /* Switch off I2C to get bit */
- i2c_disable();
- i2c_dir_in();
- i2c_delay(CLOCK_HIGH_TIME/2);
-
- /* Get bit */
- aBitByte |= i2c_getbit();
-
- /* Enable I2C */
- i2c_enable();
- i2c_delay(CLOCK_LOW_TIME/2);
- }
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
-
- /*
- * we leave the clock low, getbyte is usually followed
- * by sendack/nack, they assume the clock to be low
- */
- i2c_clk(I2C_CLOCK_LOW);
- return aBitByte;
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_getack
-*#
-*# DESCRIPTION : checks if ack was received from ic2
-*#
-*#--------------------------------------------------------------------------*/
-
-int
-i2c_getack(void)
-{
- int ack = 1;
- /*
- * enable output
- */
- i2c_dir_out();
- /*
- * Release data bus by setting
- * data high
- */
- i2c_data(I2C_DATA_HIGH);
- /*
- * enable input
- */
- i2c_dir_in();
- i2c_delay(CLOCK_HIGH_TIME/4);
- /*
- * generate ACK clock pulse
- */
- i2c_clk(I2C_CLOCK_HIGH);
-#if 0
- /*
- * Use PORT PB instead of I2C
- * for input. (I2C not working)
- */
- i2c_clk(1);
- i2c_data(1);
- /*
- * switch off I2C
- */
- i2c_data(1);
- i2c_disable();
- i2c_dir_in();
-#endif
-
- /*
- * now wait for ack
- */
- i2c_delay(CLOCK_HIGH_TIME/2);
- /*
- * check for ack
- */
- if (i2c_getbit())
- ack = 0;
- i2c_delay(CLOCK_HIGH_TIME/2);
- if (!ack) {
- if (!i2c_getbit()) /* receiver pulld SDA low */
- ack = 1;
- i2c_delay(CLOCK_HIGH_TIME/2);
- }
-
- /*
- * our clock is high now, make sure data is low
- * before we enable our output. If we keep data high
- * and enable output, we would generate a stop condition.
- */
-#if 0
- i2c_data(I2C_DATA_LOW);
-
- /*
- * end clock pulse
- */
- i2c_enable();
- i2c_dir_out();
-#endif
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_HIGH_TIME/4);
- /*
- * enable output
- */
- i2c_dir_out();
- /*
- * remove ACK clock pulse
- */
- i2c_data(I2C_DATA_HIGH);
- i2c_delay(CLOCK_LOW_TIME/2);
- return ack;
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: I2C::sendAck
-*#
-*# DESCRIPTION : Send ACK on received data
-*#
-*#--------------------------------------------------------------------------*/
-void
-i2c_sendack(void)
-{
- /*
- * enable output
- */
- i2c_delay(CLOCK_LOW_TIME);
- i2c_dir_out();
- /*
- * set ack pulse high
- */
- i2c_data(I2C_DATA_LOW);
- /*
- * generate clock pulse
- */
- i2c_delay(CLOCK_HIGH_TIME/6);
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_LOW_TIME/6);
- /*
- * reset data out
- */
- i2c_data(I2C_DATA_HIGH);
- i2c_delay(CLOCK_LOW_TIME);
-
- i2c_dir_in();
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_sendnack
-*#
-*# DESCRIPTION : Sends NACK on received data
-*#
-*#--------------------------------------------------------------------------*/
-void
-i2c_sendnack(void)
-{
- /*
- * enable output
- */
- i2c_delay(CLOCK_LOW_TIME);
- i2c_dir_out();
- /*
- * set data high
- */
- i2c_data(I2C_DATA_HIGH);
- /*
- * generate clock pulse
- */
- i2c_delay(CLOCK_HIGH_TIME/6);
- i2c_clk(I2C_CLOCK_HIGH);
- i2c_delay(CLOCK_HIGH_TIME);
- i2c_clk(I2C_CLOCK_LOW);
- i2c_delay(CLOCK_LOW_TIME);
-
- i2c_dir_in();
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_write
-*#
-*# DESCRIPTION : Writes a value to an I2C device
-*#
-*#--------------------------------------------------------------------------*/
-int
-i2c_write(unsigned char theSlave, void *data, size_t nbytes)
-{
- int error, cntr = 3;
- unsigned char bytes_wrote = 0;
- unsigned char value;
- unsigned long flags;
-
- spin_lock_irqsave(&i2c_lock, flags);
-
- do {
- error = 0;
-
- i2c_start();
- /*
- * send slave address
- */
- i2c_outbyte((theSlave & 0xfe));
- /*
- * wait for ack
- */
- if (!i2c_getack())
- error = 1;
- /*
- * send data
- */
- for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) {
- memcpy(&value, data + bytes_wrote, sizeof value);
- i2c_outbyte(value);
- /*
- * now it's time to wait for ack
- */
- if (!i2c_getack())
- error |= 4;
- }
- /*
- * end byte stream
- */
- i2c_stop();
-
- } while (error && cntr--);
-
- i2c_delay(CLOCK_LOW_TIME);
-
- spin_unlock_irqrestore(&i2c_lock, flags);
-
- return -error;
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_read
-*#
-*# DESCRIPTION : Reads a value from an I2C device
-*#
-*#--------------------------------------------------------------------------*/
-int
-i2c_read(unsigned char theSlave, void *data, size_t nbytes)
-{
- unsigned char b = 0;
- unsigned char bytes_read = 0;
- int error, cntr = 3;
- unsigned long flags;
-
- spin_lock_irqsave(&i2c_lock, flags);
-
- do {
- error = 0;
- memset(data, 0, nbytes);
- /*
- * generate start condition
- */
- i2c_start();
- /*
- * send slave address
- */
- i2c_outbyte((theSlave | 0x01));
- /*
- * wait for ack
- */
- if (!i2c_getack())
- error = 1;
- /*
- * fetch data
- */
- for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
- b = i2c_inbyte();
- memcpy(data + bytes_read, &b, sizeof b);
-
- if (bytes_read < (nbytes - 1))
- i2c_sendack();
- }
- /*
- * last received byte needs to be nacked
- * instead of acked
- */
- i2c_sendnack();
- /*
- * end sequence
- */
- i2c_stop();
- } while (error && cntr--);
-
- spin_unlock_irqrestore(&i2c_lock, flags);
-
- return -error;
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_writereg
-*#
-*# DESCRIPTION : Writes a value to an I2C device
-*#
-*#--------------------------------------------------------------------------*/
-int
-i2c_writereg(unsigned char theSlave, unsigned char theReg,
- unsigned char theValue)
-{
- int error, cntr = 3;
- unsigned long flags;
-
- spin_lock_irqsave(&i2c_lock, flags);
-
- do {
- error = 0;
-
- i2c_start();
- /*
- * send slave address
- */
- i2c_outbyte((theSlave & 0xfe));
- /*
- * wait for ack
- */
- if(!i2c_getack())
- error = 1;
- /*
- * now select register
- */
- i2c_dir_out();
- i2c_outbyte(theReg);
- /*
- * now it's time to wait for ack
- */
- if(!i2c_getack())
- error |= 2;
- /*
- * send register register data
- */
- i2c_outbyte(theValue);
- /*
- * now it's time to wait for ack
- */
- if(!i2c_getack())
- error |= 4;
- /*
- * end byte stream
- */
- i2c_stop();
- } while(error && cntr--);
-
- i2c_delay(CLOCK_LOW_TIME);
-
- spin_unlock_irqrestore(&i2c_lock, flags);
-
- return -error;
-}
-
-/*#---------------------------------------------------------------------------
-*#
-*# FUNCTION NAME: i2c_readreg
-*#
-*# DESCRIPTION : Reads a value from the decoder registers.
-*#
-*#--------------------------------------------------------------------------*/
-unsigned char
-i2c_readreg(unsigned char theSlave, unsigned char theReg)
-{
- unsigned char b = 0;
- int error, cntr = 3;
- unsigned long flags;
-
- spin_lock_irqsave(&i2c_lock, flags);
-
- do {
- error = 0;
- /*
- * generate start condition
- */
- i2c_start();
-
- /*
- * send slave address
- */
- i2c_outbyte((theSlave & 0xfe));
- /*
- * wait for ack
- */
- if(!i2c_getack())
- error = 1;
- /*
- * now select register
- */
- i2c_dir_out();
- i2c_outbyte(theReg);
- /*
- * now it's time to wait for ack
- */
- if(!i2c_getack())
- error |= 2;
- /*
- * repeat start condition
- */
- i2c_delay(CLOCK_LOW_TIME);
- i2c_start();
- /*
- * send slave address
- */
- i2c_outbyte(theSlave | 0x01);
- /*
- * wait for ack
- */
- if(!i2c_getack())
- error |= 4;
- /*
- * fetch register
- */
- b = i2c_inbyte();
- /*
- * last received byte needs to be nacked
- * instead of acked
- */
- i2c_sendnack();
- /*
- * end sequence
- */
- i2c_stop();
-
- } while(error && cntr--);
-
- spin_unlock_irqrestore(&i2c_lock, flags);
-
- return b;
-}
-
-static int
-i2c_open(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-static int
-i2c_release(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/* Main device API. ioctl's to write or read to/from i2c registers.
- */
-
-static long
-i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret;
- if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
- return -ENOTTY;
- }
-
- switch (_IOC_NR(cmd)) {
- case I2C_WRITEREG:
- /* write to an i2c slave */
- D(printk("i2cw %d %d %d\n",
- I2C_ARGSLAVE(arg),
- I2C_ARGREG(arg),
- I2C_ARGVALUE(arg)));
-
- mutex_lock(&i2c_mutex);
- ret = i2c_writereg(I2C_ARGSLAVE(arg),
- I2C_ARGREG(arg),
- I2C_ARGVALUE(arg));
- mutex_unlock(&i2c_mutex);
- return ret;
-
- case I2C_READREG:
- {
- unsigned char val;
- /* read from an i2c slave */
- D(printk("i2cr %d %d ",
- I2C_ARGSLAVE(arg),
- I2C_ARGREG(arg)));
- mutex_lock(&i2c_mutex);
- val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
- mutex_unlock(&i2c_mutex);
- D(printk("= %d\n", val));
- return val;
- }
- default:
- return -EINVAL;
-
- }
-
- return 0;
-}
-
-static const struct file_operations i2c_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = i2c_ioctl,
- .open = i2c_open,
- .release = i2c_release,
- .llseek = noop_llseek,
-};
-
-static int __init i2c_init(void)
-{
- static int res;
- static int first = 1;
-
- if (!first)
- return res;
-
- first = 0;
-
- /* Setup and enable the DATA and CLK pins */
-
- res = crisv32_io_get_name(&cris_i2c_data,
- CONFIG_ETRAX_V32_I2C_DATA_PORT);
- if (res < 0)
- return res;
-
- res = crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_V32_I2C_CLK_PORT);
- crisv32_io_set_dir(&cris_i2c_clk, crisv32_io_dir_out);
-
- return res;
-}
-
-
-static int __init i2c_register(void)
-{
- int res;
-
- res = i2c_init();
- if (res < 0)
- return res;
-
- /* register char device */
-
- res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
- if (res < 0) {
- printk(KERN_ERR "i2c: couldn't get a major number.\n");
- return res;
- }
-
- printk(KERN_INFO
- "I2C driver v2.2, (c) 1999-2007 Axis Communications AB\n");
-
- return 0;
-}
-/* this makes sure that i2c_init is called during boot */
-module_init(i2c_register);
-
-/****************** END OF FILE i2c.c ********************************/
diff --git a/arch/cris/arch-v32/drivers/i2c.h b/arch/cris/arch-v32/drivers/i2c.h
deleted file mode 100644
index d9cc856..0000000
--- a/arch/cris/arch-v32/drivers/i2c.h
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#include <linux/init.h>
-
-/* High level I2C actions */
-int i2c_write(unsigned char theSlave, void *data, size_t nbytes);
-int i2c_read(unsigned char theSlave, void *data, size_t nbytes);
-int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
-unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
-
-/* Low level I2C */
-void i2c_start(void);
-void i2c_stop(void);
-void i2c_outbyte(unsigned char x);
-unsigned char i2c_inbyte(void);
-int i2c_getack(void);
-void i2c_sendack(void);
diff --git a/arch/cris/arch-v32/drivers/mach-a3/Makefile b/arch/cris/arch-v32/drivers/mach-a3/Makefile
index 5c6d2a2..59028d0 100644
--- a/arch/cris/arch-v32/drivers/mach-a3/Makefile
+++ b/arch/cris/arch-v32/drivers/mach-a3/Makefile
@@ -3,4 +3,3 @@
#
obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o
-obj-$(CONFIG_ETRAX_GPIO) += gpio.o
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
deleted file mode 100644
index c92e1da..0000000
--- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Artec-3 general port I/O device
- *
- * Copyright (c) 2007 Axis Communications AB
- *
- * Authors: Bjorn Wesen (initial version)
- * Ola Knutsson (LED handling)
- * Johan Adolfsson (read/set directions, write, port G,
- * port to ETRAX FS.
- * Ricard Wanderlof (PWM for Artpec-3)
- *
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-
-#include <asm/etraxgpio.h>
-#include <hwregs/reg_map.h>
-#include <hwregs/reg_rdwr.h>
-#include <hwregs/gio_defs.h>
-#include <hwregs/intr_vect_defs.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <mach/pinmux.h>
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-#include "../i2c.h"
-
-#define VIRT_I2C_ADDR 0x40
-#endif
-
-/* The following gio ports on ARTPEC-3 is available:
- * pa 32 bits
- * pb 32 bits
- * pc 16 bits
- * each port has a rw_px_dout, r_px_din and rw_px_oe register.
- */
-
-#define GPIO_MAJOR 120 /* experimental MAJOR number */
-
-#define I2C_INTERRUPT_BITS 0x300 /* i2c0_done and i2c1_done bits */
-
-#define D(x)
-
-#if 0
-static int dp_cnt;
-#define DP(x) \
- do { \
- dp_cnt++; \
- if (dp_cnt % 1000 == 0) \
- x; \
- } while (0)
-#else
-#define DP(x)
-#endif
-
-static DEFINE_MUTEX(gpio_mutex);
-static char gpio_name[] = "etrax gpio";
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-#endif
-static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-static ssize_t gpio_write(struct file *file, const char __user *buf,
- size_t count, loff_t *off);
-static int gpio_open(struct inode *inode, struct file *filp);
-static int gpio_release(struct inode *inode, struct file *filp);
-static unsigned int gpio_poll(struct file *filp,
- struct poll_table_struct *wait);
-
-/* private data per open() of this driver */
-
-struct gpio_private {
- struct gpio_private *next;
- /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
- unsigned char clk_mask;
- unsigned char data_mask;
- unsigned char write_msb;
- unsigned char pad1;
- /* These fields are generic */
- unsigned long highalarm, lowalarm;
- wait_queue_head_t alarm_wq;
- int minor;
-};
-
-static void gpio_set_alarm(struct gpio_private *priv);
-static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
-static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd,
- unsigned long arg);
-
-
-/* linked list of alarms to check for */
-
-static struct gpio_private *alarmlist;
-
-static int wanted_interrupts;
-
-static DEFINE_SPINLOCK(gpio_lock);
-
-#define NUM_PORTS (GPIO_MINOR_LAST+1)
-#define GIO_REG_RD_ADDR(reg) \
- (unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
-#define GIO_REG_WR_ADDR(reg) \
- (unsigned long *)(regi_gio + REG_WR_ADDR_gio_##reg)
-static unsigned long led_dummy;
-static unsigned long port_d_dummy; /* Only input on Artpec-3 */
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static unsigned long port_e_dummy; /* Non existent on Artpec-3 */
-static unsigned long virtual_dummy;
-static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
-static unsigned short cached_virtual_gpio_read;
-#endif
-
-static unsigned long *data_out[NUM_PORTS] = {
- GIO_REG_WR_ADDR(rw_pa_dout),
- GIO_REG_WR_ADDR(rw_pb_dout),
- &led_dummy,
- GIO_REG_WR_ADDR(rw_pc_dout),
- &port_d_dummy,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &port_e_dummy,
- &virtual_dummy,
-#endif
-};
-
-static unsigned long *data_in[NUM_PORTS] = {
- GIO_REG_RD_ADDR(r_pa_din),
- GIO_REG_RD_ADDR(r_pb_din),
- &led_dummy,
- GIO_REG_RD_ADDR(r_pc_din),
- GIO_REG_RD_ADDR(r_pd_din),
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &port_e_dummy,
- &virtual_dummy,
-#endif
-};
-
-static unsigned long changeable_dir[NUM_PORTS] = {
- CONFIG_ETRAX_PA_CHANGEABLE_DIR,
- CONFIG_ETRAX_PB_CHANGEABLE_DIR,
- 0,
- CONFIG_ETRAX_PC_CHANGEABLE_DIR,
- 0,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- 0,
- CONFIG_ETRAX_PV_CHANGEABLE_DIR,
-#endif
-};
-
-static unsigned long changeable_bits[NUM_PORTS] = {
- CONFIG_ETRAX_PA_CHANGEABLE_BITS,
- CONFIG_ETRAX_PB_CHANGEABLE_BITS,
- 0,
- CONFIG_ETRAX_PC_CHANGEABLE_BITS,
- 0,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- 0,
- CONFIG_ETRAX_PV_CHANGEABLE_BITS,
-#endif
-};
-
-static unsigned long *dir_oe[NUM_PORTS] = {
- GIO_REG_WR_ADDR(rw_pa_oe),
- GIO_REG_WR_ADDR(rw_pb_oe),
- &led_dummy,
- GIO_REG_WR_ADDR(rw_pc_oe),
- &port_d_dummy,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &port_e_dummy,
- &virtual_rw_pv_oe,
-#endif
-};
-
-static void gpio_set_alarm(struct gpio_private *priv)
-{
- int bit;
- int intr_cfg;
- int mask;
- int pins;
- unsigned long flags;
-
- spin_lock_irqsave(&gpio_lock, flags);
- intr_cfg = REG_RD_INT(gio, regi_gio, rw_intr_cfg);
- pins = REG_RD_INT(gio, regi_gio, rw_intr_pins);
- mask = REG_RD_INT(gio, regi_gio, rw_intr_mask) & I2C_INTERRUPT_BITS;
-
- for (bit = 0; bit < 32; bit++) {
- int intr = bit % 8;
- int pin = bit / 8;
- if (priv->minor < GPIO_MINOR_LEDS)
- pin += priv->minor * 4;
- else
- pin += (priv->minor - 1) * 4;
-
- if (priv->highalarm & (1<<bit)) {
- intr_cfg |= (regk_gio_hi << (intr * 3));
- mask |= 1 << intr;
- wanted_interrupts = mask & 0xff;
- pins |= pin << (intr * 4);
- } else if (priv->lowalarm & (1<<bit)) {
- intr_cfg |= (regk_gio_lo << (intr * 3));
- mask |= 1 << intr;
- wanted_interrupts = mask & 0xff;
- pins |= pin << (intr * 4);
- }
- }
-
- REG_WR_INT(gio, regi_gio, rw_intr_cfg, intr_cfg);
- REG_WR_INT(gio, regi_gio, rw_intr_pins, pins);
- REG_WR_INT(gio, regi_gio, rw_intr_mask, mask);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-}
-
-static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
-{
- unsigned int mask = 0;
- struct gpio_private *priv = file->private_data;
- unsigned long data;
- unsigned long tmp;
-
- if (priv->minor >= GPIO_MINOR_PWM0 &&
- priv->minor <= GPIO_MINOR_LAST_PWM)
- return 0;
-
- poll_wait(file, &priv->alarm_wq, wait);
- if (priv->minor <= GPIO_MINOR_D) {
- data = readl(data_in[priv->minor]);
- REG_WR_INT(gio, regi_gio, rw_ack_intr, wanted_interrupts);
- tmp = REG_RD_INT(gio, regi_gio, rw_intr_mask);
- tmp &= I2C_INTERRUPT_BITS;
- tmp |= wanted_interrupts;
- REG_WR_INT(gio, regi_gio, rw_intr_mask, tmp);
- } else
- return 0;
-
- if ((data & priv->highalarm) || (~data & priv->lowalarm))
- mask = POLLIN|POLLRDNORM;
-
- DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
- return mask;
-}
-
-static irqreturn_t gpio_interrupt(int irq, void *dev_id)
-{
- reg_gio_rw_intr_mask intr_mask;
- reg_gio_r_masked_intr masked_intr;
- reg_gio_rw_ack_intr ack_intr;
- unsigned long flags;
- unsigned long tmp;
- unsigned long tmp2;
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- unsigned char enable_gpiov_ack = 0;
-#endif
-
- /* Find what PA interrupts are active */
- masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
- tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
-
- /* Find those that we have enabled */
- spin_lock_irqsave(&gpio_lock, flags);
- tmp &= wanted_interrupts;
- spin_unlock_irqrestore(&gpio_lock, flags);
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Something changed on virtual GPIO. Interrupt is acked by
- * reading the device.
- */
- if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
- i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
- sizeof(cached_virtual_gpio_read));
- enable_gpiov_ack = 1;
- }
-#endif
-
- /* Ack them */
- ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
- REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
-
- /* Disable those interrupts.. */
- intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
- tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
- tmp2 &= ~tmp;
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Do not disable interrupt on virtual GPIO. Changes on virtual
- * pins are only noticed by an interrupt.
- */
- if (enable_gpiov_ack)
- tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
- intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
- REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
-
- return IRQ_RETVAL(tmp);
-}
-
-static void gpio_write_bit(unsigned long *port, unsigned char data, int bit,
- unsigned char clk_mask, unsigned char data_mask)
-{
- unsigned long shadow = readl(port) & ~clk_mask;
- writel(shadow, port);
- if (data & 1 << bit)
- shadow |= data_mask;
- else
- shadow &= ~data_mask;
- writel(shadow, port);
- /* For FPGA: min 5.0ns (DCC) before CCLK high */
- shadow |= clk_mask;
- writel(shadow, port);
-}
-
-static void gpio_write_byte(struct gpio_private *priv, unsigned long *port,
- unsigned char data)
-{
- int i;
-
- if (priv->write_msb)
- for (i = 7; i >= 0; i--)
- gpio_write_bit(port, data, i, priv->clk_mask,
- priv->data_mask);
- else
- for (i = 0; i <= 7; i++)
- gpio_write_bit(port, data, i, priv->clk_mask,
- priv->data_mask);
-}
-
-
-static ssize_t gpio_write(struct file *file, const char __user *buf,
- size_t count, loff_t *off)
-{
- struct gpio_private *priv = file->private_data;
- unsigned long flags;
- ssize_t retval = count;
- /* Only bits 0-7 may be used for write operations but allow all
- devices except leds... */
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- if (priv->minor == GPIO_MINOR_V)
- return -EFAULT;
-#endif
- if (priv->minor == GPIO_MINOR_LEDS)
- return -EFAULT;
-
- if (priv->minor >= GPIO_MINOR_PWM0 &&
- priv->minor <= GPIO_MINOR_LAST_PWM)
- return -EFAULT;
-
- if (!access_ok(VERIFY_READ, buf, count))
- return -EFAULT;
-
- /* It must have been configured using the IO_CFG_WRITE_MODE */
- /* Perhaps a better error code? */
- if (priv->clk_mask == 0 || priv->data_mask == 0)
- return -EPERM;
-
- D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
- "msb: %i\n",
- count, priv->data_mask, priv->clk_mask, priv->write_msb));
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- while (count--)
- gpio_write_byte(priv, data_out[priv->minor], *buf++);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
- return retval;
-}
-
-static int gpio_open(struct inode *inode, struct file *filp)
-{
- struct gpio_private *priv;
- int p = iminor(inode);
-
- if (p > GPIO_MINOR_LAST_PWM ||
- (p > GPIO_MINOR_LAST && p < GPIO_MINOR_PWM0))
- return -EINVAL;
-
- priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
-
- if (!priv)
- return -ENOMEM;
-
- mutex_lock(&gpio_mutex);
- memset(priv, 0, sizeof(*priv));
-
- priv->minor = p;
- filp->private_data = priv;
-
- /* initialize the io/alarm struct, not for PWM ports though */
- if (p <= GPIO_MINOR_LAST) {
-
- priv->clk_mask = 0;
- priv->data_mask = 0;
- priv->highalarm = 0;
- priv->lowalarm = 0;
-
- init_waitqueue_head(&priv->alarm_wq);
-
- /* link it into our alarmlist */
- spin_lock_irq(&gpio_lock);
- priv->next = alarmlist;
- alarmlist = priv;
- spin_unlock_irq(&gpio_lock);
- }
-
- mutex_unlock(&gpio_mutex);
- return 0;
-}
-
-static int gpio_release(struct inode *inode, struct file *filp)
-{
- struct gpio_private *p;
- struct gpio_private *todel;
- /* local copies while updating them: */
- unsigned long a_high, a_low;
-
- /* prepare to free private structure */
- todel = filp->private_data;
-
- /* unlink from alarmlist - only for non-PWM ports though */
- if (todel->minor <= GPIO_MINOR_LAST) {
- spin_lock_irq(&gpio_lock);
- p = alarmlist;
-
- if (p == todel)
- alarmlist = todel->next;
- else {
- while (p->next != todel)
- p = p->next;
- p->next = todel->next;
- }
-
- /* Check if there are still any alarms set */
- p = alarmlist;
- a_high = 0;
- a_low = 0;
- while (p) {
- if (p->minor == GPIO_MINOR_A) {
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
- a_high |= p->highalarm;
- a_low |= p->lowalarm;
- }
-
- p = p->next;
- }
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Variable 'a_low' needs to be set here again
- * to ensure that interrupt for virtual GPIO is handled.
- */
- a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
-
- spin_unlock_irq(&gpio_lock);
- }
- kfree(todel);
-
- return 0;
-}
-
-/* Main device API. ioctl's to read/set/clear bits, as well as to
- * set alarms to wait for using a subsequent select().
- */
-
-inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
-{
- /* Set direction 0=unchanged 1=input,
- * return mask with 1=input
- */
- unsigned long flags;
- unsigned long dir_shadow;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- dir_shadow = readl(dir_oe[priv->minor]) &
- ~(arg & changeable_dir[priv->minor]);
- writel(dir_shadow, dir_oe[priv->minor]);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- if (priv->minor == GPIO_MINOR_C)
- dir_shadow ^= 0xFFFF; /* Only 16 bits */
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- else if (priv->minor == GPIO_MINOR_V)
- dir_shadow ^= 0xFFFF; /* Only 16 bits */
-#endif
- else
- dir_shadow ^= 0xFFFFFFFF; /* PA, PB and PD 32 bits */
-
- return dir_shadow;
-
-} /* setget_input */
-
-static inline unsigned long setget_output(struct gpio_private *priv,
- unsigned long arg)
-{
- unsigned long flags;
- unsigned long dir_shadow;
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- dir_shadow = readl(dir_oe[priv->minor]) |
- (arg & changeable_dir[priv->minor]);
- writel(dir_shadow, dir_oe[priv->minor]);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
- return dir_shadow;
-} /* setget_output */
-
-static long gpio_ioctl_unlocked(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- unsigned long flags;
- unsigned long val;
- unsigned long shadow;
- struct gpio_private *priv = file->private_data;
-
- if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
- return -ENOTTY;
-
- /* Check for special ioctl handlers first */
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- if (priv->minor == GPIO_MINOR_V)
- return virtual_gpio_ioctl(file, cmd, arg);
-#endif
-
- if (priv->minor == GPIO_MINOR_LEDS)
- return gpio_leds_ioctl(cmd, arg);
-
- if (priv->minor >= GPIO_MINOR_PWM0 &&
- priv->minor <= GPIO_MINOR_LAST_PWM)
- return gpio_pwm_ioctl(priv, cmd, arg);
-
- switch (_IOC_NR(cmd)) {
- case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
- /* Read the port. */
- return readl(data_in[priv->minor]);
- case IO_SETBITS:
- spin_lock_irqsave(&gpio_lock, flags);
- /* Set changeable bits with a 1 in arg. */
- shadow = readl(data_out[priv->minor]) |
- (arg & changeable_bits[priv->minor]);
- writel(shadow, data_out[priv->minor]);
- spin_unlock_irqrestore(&gpio_lock, flags);
- break;
- case IO_CLRBITS:
- spin_lock_irqsave(&gpio_lock, flags);
- /* Clear changeable bits with a 1 in arg. */
- shadow = readl(data_out[priv->minor]) &
- ~(arg & changeable_bits[priv->minor]);
- writel(shadow, data_out[priv->minor]);
- spin_unlock_irqrestore(&gpio_lock, flags);
- break;
- case IO_HIGHALARM:
- /* Set alarm when bits with 1 in arg go high. */
- priv->highalarm |= arg;
- gpio_set_alarm(priv);
- break;
- case IO_LOWALARM:
- /* Set alarm when bits with 1 in arg go low. */
- priv->lowalarm |= arg;
- gpio_set_alarm(priv);
- break;
- case IO_CLRALARM:
- /* Clear alarm for bits with 1 in arg. */
- priv->highalarm &= ~arg;
- priv->lowalarm &= ~arg;
- gpio_set_alarm(priv);
- break;
- case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
- /* Read direction 0=input 1=output */
- return readl(dir_oe[priv->minor]);
-
- case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
- /* Set direction 0=unchanged 1=input,
- * return mask with 1=input
- */
- return setget_input(priv, arg);
-
- case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
- /* Set direction 0=unchanged 1=output,
- * return mask with 1=output
- */
- return setget_output(priv, arg);
-
- case IO_CFG_WRITE_MODE:
- {
- int res = -EPERM;
- unsigned long dir_shadow, clk_mask, data_mask, write_msb;
-
- clk_mask = arg & 0xFF;
- data_mask = (arg >> 8) & 0xFF;
- write_msb = (arg >> 16) & 0x01;
-
- /* Check if we're allowed to change the bits and
- * the direction is correct
- */
- spin_lock_irqsave(&gpio_lock, flags);
- dir_shadow = readl(dir_oe[priv->minor]);
- if ((clk_mask & changeable_bits[priv->minor]) &&
- (data_mask & changeable_bits[priv->minor]) &&
- (clk_mask & dir_shadow) &&
- (data_mask & dir_shadow)) {
- priv->clk_mask = clk_mask;
- priv->data_mask = data_mask;
- priv->write_msb = write_msb;
- res = 0;
- }
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- return res;
- }
- case IO_READ_INBITS:
- /* *arg is result of reading the input pins */
- val = readl(data_in[priv->minor]);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- return 0;
- case IO_READ_OUTBITS:
- /* *arg is result of reading the output shadow */
- val = *data_out[priv->minor];
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_INPUT:
- /* bits set in *arg is set to input,
- * *arg updated with current input pins.
- */
- if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_input(priv, val);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_OUTPUT:
- /* bits set in *arg is set to output,
- * *arg updated with current output pins.
- */
- if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_output(priv, val);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- default:
- return -EINVAL;
- } /* switch */
-
- return 0;
-}
-
-static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- long ret;
-
- mutex_lock(&gpio_mutex);
- ret = gpio_ioctl_unlocked(file, cmd, arg);
- mutex_unlock(&gpio_mutex);
-
- return ret;
-}
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- unsigned long flags;
- unsigned short val;
- unsigned short shadow;
- struct gpio_private *priv = file->private_data;
-
- switch (_IOC_NR(cmd)) {
- case IO_SETBITS:
- spin_lock_irqsave(&gpio_lock, flags);
- /* Set changeable bits with a 1 in arg. */
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- shadow |= ~readl(dir_oe[priv->minor]) |
- (arg & changeable_bits[priv->minor]);
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_unlock_irqrestore(&gpio_lock, flags);
- break;
- case IO_CLRBITS:
- spin_lock_irqsave(&gpio_lock, flags);
- /* Clear changeable bits with a 1 in arg. */
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- shadow |= ~readl(dir_oe[priv->minor]) &
- ~(arg & changeable_bits[priv->minor]);
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_unlock_irqrestore(&gpio_lock, flags);
- break;
- case IO_HIGHALARM:
- /* Set alarm when bits with 1 in arg go high. */
- priv->highalarm |= arg;
- break;
- case IO_LOWALARM:
- /* Set alarm when bits with 1 in arg go low. */
- priv->lowalarm |= arg;
- break;
- case IO_CLRALARM:
- /* Clear alarm for bits with 1 in arg. */
- priv->highalarm &= ~arg;
- priv->lowalarm &= ~arg;
- break;
- case IO_CFG_WRITE_MODE:
- {
- unsigned long dir_shadow;
- dir_shadow = readl(dir_oe[priv->minor]);
-
- priv->clk_mask = arg & 0xFF;
- priv->data_mask = (arg >> 8) & 0xFF;
- priv->write_msb = (arg >> 16) & 0x01;
- /* Check if we're allowed to change the bits and
- * the direction is correct
- */
- if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
- (priv->data_mask & changeable_bits[priv->minor]) &&
- (priv->clk_mask & dir_shadow) &&
- (priv->data_mask & dir_shadow))) {
- priv->clk_mask = 0;
- priv->data_mask = 0;
- return -EPERM;
- }
- break;
- }
- case IO_READ_INBITS:
- /* *arg is result of reading the input pins */
- val = cached_virtual_gpio_read & ~readl(dir_oe[priv->minor]);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- return 0;
-
- case IO_READ_OUTBITS:
- /* *arg is result of reading the output shadow */
- i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
- val &= readl(dir_oe[priv->minor]);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_INPUT:
- {
- /* bits set in *arg is set to input,
- * *arg updated with current input pins.
- */
- unsigned short input_mask = ~readl(dir_oe[priv->minor]);
- if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_input(priv, val);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- if ((input_mask & val) != input_mask) {
- /* Input pins changed. All ports desired as input
- * should be set to logic 1.
- */
- unsigned short change = input_mask ^ val;
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
- sizeof(shadow));
- shadow &= ~change;
- shadow |= val;
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
- sizeof(shadow));
- }
- break;
- }
- case IO_SETGET_OUTPUT:
- /* bits set in *arg is set to output,
- * *arg updated with current output pins.
- */
- if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_output(priv, val);
- if (copy_to_user((void __user *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- default:
- return -EINVAL;
- } /* switch */
- return 0;
-}
-#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
-
-static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
-{
- unsigned char green;
- unsigned char red;
-
- switch (_IOC_NR(cmd)) {
- case IO_LEDACTIVE_SET:
- green = ((unsigned char) arg) & 1;
- red = (((unsigned char) arg) >> 1) & 1;
- CRIS_LED_ACTIVE_SET_G(green);
- CRIS_LED_ACTIVE_SET_R(red);
- break;
-
- default:
- return -EINVAL;
- } /* switch */
-
- return 0;
-}
-
-static int gpio_pwm_set_mode(unsigned long arg, int pwm_port)
-{
- int pinmux_pwm = pinmux_pwm0 + pwm_port;
- int mode;
- reg_gio_rw_pwm0_ctrl rw_pwm_ctrl = {
- .ccd_val = 0,
- .ccd_override = regk_gio_no,
- .mode = regk_gio_no
- };
- int allocstatus;
-
- if (get_user(mode, &((struct io_pwm_set_mode *) arg)->mode))
- return -EFAULT;
- rw_pwm_ctrl.mode = mode;
- if (mode != PWM_OFF)
- allocstatus = crisv32_pinmux_alloc_fixed(pinmux_pwm);
- else
- allocstatus = crisv32_pinmux_dealloc_fixed(pinmux_pwm);
- if (allocstatus)
- return allocstatus;
- REG_WRITE(reg_gio_rw_pwm0_ctrl, REG_ADDR(gio, regi_gio, rw_pwm0_ctrl) +
- 12 * pwm_port, rw_pwm_ctrl);
- return 0;
-}
-
-static int gpio_pwm_set_period(unsigned long arg, int pwm_port)
-{
- struct io_pwm_set_period periods;
- reg_gio_rw_pwm0_var rw_pwm_widths;
-
- if (copy_from_user(&periods, (void __user *)arg, sizeof(periods)))
- return -EFAULT;
- if (periods.lo > 8191 || periods.hi > 8191)
- return -EINVAL;
- rw_pwm_widths.lo = periods.lo;
- rw_pwm_widths.hi = periods.hi;
- REG_WRITE(reg_gio_rw_pwm0_var, REG_ADDR(gio, regi_gio, rw_pwm0_var) +
- 12 * pwm_port, rw_pwm_widths);
- return 0;
-}
-
-static int gpio_pwm_set_duty(unsigned long arg, int pwm_port)
-{
- unsigned int duty;
- reg_gio_rw_pwm0_data rw_pwm_duty;
-
- if (get_user(duty, &((struct io_pwm_set_duty *) arg)->duty))
- return -EFAULT;
- if (duty > 255)
- return -EINVAL;
- rw_pwm_duty.data = duty;
- REG_WRITE(reg_gio_rw_pwm0_data, REG_ADDR(gio, regi_gio, rw_pwm0_data) +
- 12 * pwm_port, rw_pwm_duty);
- return 0;
-}
-
-static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd,
- unsigned long arg)
-{
- int pwm_port = priv->minor - GPIO_MINOR_PWM0;
-
- switch (_IOC_NR(cmd)) {
- case IO_PWM_SET_MODE:
- return gpio_pwm_set_mode(arg, pwm_port);
- case IO_PWM_SET_PERIOD:
- return gpio_pwm_set_period(arg, pwm_port);
- case IO_PWM_SET_DUTY:
- return gpio_pwm_set_duty(arg, pwm_port);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct file_operations gpio_fops = {
- .owner = THIS_MODULE,
- .poll = gpio_poll,
- .unlocked_ioctl = gpio_ioctl,
- .write = gpio_write,
- .open = gpio_open,
- .release = gpio_release,
- .llseek = noop_llseek,
-};
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static void __init virtual_gpio_init(void)
-{
- reg_gio_rw_intr_cfg intr_cfg;
- reg_gio_rw_intr_mask intr_mask;
- unsigned short shadow;
-
- shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
- shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
-
- /* Set interrupt mask and on what state the interrupt shall trigger.
- * For virtual gpio the interrupt shall trigger on logic '0'.
- */
- intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
- intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
-
- switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
- case 0:
- intr_cfg.pa0 = regk_gio_lo;
- intr_mask.pa0 = regk_gio_yes;
- break;
- case 1:
- intr_cfg.pa1 = regk_gio_lo;
- intr_mask.pa1 = regk_gio_yes;
- break;
- case 2:
- intr_cfg.pa2 = regk_gio_lo;
- intr_mask.pa2 = regk_gio_yes;
- break;
- case 3:
- intr_cfg.pa3 = regk_gio_lo;
- intr_mask.pa3 = regk_gio_yes;
- break;
- case 4:
- intr_cfg.pa4 = regk_gio_lo;
- intr_mask.pa4 = regk_gio_yes;
- break;
- case 5:
- intr_cfg.pa5 = regk_gio_lo;
- intr_mask.pa5 = regk_gio_yes;
- break;
- case 6:
- intr_cfg.pa6 = regk_gio_lo;
- intr_mask.pa6 = regk_gio_yes;
- break;
- case 7:
- intr_cfg.pa7 = regk_gio_lo;
- intr_mask.pa7 = regk_gio_yes;
- break;
- }
-
- REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
- REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
-}
-#endif
-
-/* main driver initialization routine, called from mem.c */
-
-static int __init gpio_init(void)
-{
- int res, res2;
-
- printk(KERN_INFO "ETRAX FS GPIO driver v2.7, (c) 2003-2008 "
- "Axis Communications AB\n");
-
- /* do the formalities */
-
- res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
- if (res < 0) {
- printk(KERN_ERR "gpio: couldn't get a major number.\n");
- return res;
- }
-
- /* Clear all leds */
- CRIS_LED_NETWORK_GRP0_SET(0);
- CRIS_LED_NETWORK_GRP1_SET(0);
- CRIS_LED_ACTIVE_SET(0);
- CRIS_LED_DISK_READ(0);
- CRIS_LED_DISK_WRITE(0);
-
- res2 = request_irq(GIO_INTR_VECT, gpio_interrupt,
- IRQF_SHARED, "gpio", &alarmlist);
- if (res2) {
- printk(KERN_ERR "err: irq for gpio\n");
- return res2;
- }
-
- /* No IRQs by default. */
- REG_WR_INT(gio, regi_gio, rw_intr_pins, 0);
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- virtual_gpio_init();
-#endif
-
- return res;
-}
-
-/* this makes sure that gpio_init is called during kernel boot */
-
-module_init(gpio_init);
diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c
index 7fb5212..5aa3f51 100644
--- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c
+++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c
@@ -36,7 +36,6 @@
#define CE_BIT 12
struct mtd_info_wrapper {
- struct mtd_info info;
struct nand_chip chip;
};
@@ -52,7 +51,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
{
unsigned long flags;
reg_pio_rw_dout dout;
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
local_irq_save(flags);
@@ -148,10 +147,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
/* Get pointer to private data */
this = &wrapper->chip;
- crisv32_mtd = &wrapper->info;
-
- /* Link the private data with the MTD structure */
- crisv32_mtd->priv = this;
+ crisv32_mtd = nand_to_mtd(this);
/* Set address of NAND IO lines */
this->IO_ADDR_R = read_cs;
diff --git a/arch/cris/arch-v32/drivers/mach-fs/Makefile b/arch/cris/arch-v32/drivers/mach-fs/Makefile
index 5c6d2a2..59028d0 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/Makefile
+++ b/arch/cris/arch-v32/drivers/mach-fs/Makefile
@@ -3,4 +3,3 @@
#
obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o
-obj-$(CONFIG_ETRAX_GPIO) += gpio.o
diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
deleted file mode 100644
index 72968fb..0000000
--- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * ETRAX CRISv32 general port I/O device
- *
- * Copyright (c) 1999-2006 Axis Communications AB
- *
- * Authors: Bjorn Wesen (initial version)
- * Ola Knutsson (LED handling)
- * Johan Adolfsson (read/set directions, write, port G,
- * port to ETRAX FS.
- *
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-
-#include <asm/etraxgpio.h>
-#include <hwregs/reg_map.h>
-#include <hwregs/reg_rdwr.h>
-#include <hwregs/gio_defs.h>
-#include <hwregs/intr_vect_defs.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-#include "../i2c.h"
-
-#define VIRT_I2C_ADDR 0x40
-#endif
-
-/* The following gio ports on ETRAX FS is available:
- * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
- * pb 18 bits
- * pc 18 bits
- * pd 18 bits
- * pe 18 bits
- * each port has a rw_px_dout, r_px_din and rw_px_oe register.
- */
-
-#define GPIO_MAJOR 120 /* experimental MAJOR number */
-
-#define D(x)
-
-#if 0
-static int dp_cnt;
-#define DP(x) \
- do { \
- dp_cnt++; \
- if (dp_cnt % 1000 == 0) \
- x; \
- } while (0)
-#else
-#define DP(x)
-#endif
-
-static DEFINE_MUTEX(gpio_mutex);
-static char gpio_name[] = "etrax gpio";
-
-#if 0
-static wait_queue_head_t *gpio_wq;
-#endif
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-#endif
-static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
- loff_t *off);
-static int gpio_open(struct inode *inode, struct file *filp);
-static int gpio_release(struct inode *inode, struct file *filp);
-static unsigned int gpio_poll(struct file *filp,
- struct poll_table_struct *wait);
-
-/* private data per open() of this driver */
-
-struct gpio_private {
- struct gpio_private *next;
- /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
- unsigned char clk_mask;
- unsigned char data_mask;
- unsigned char write_msb;
- unsigned char pad1;
- /* These fields are generic */
- unsigned long highalarm, lowalarm;
- wait_queue_head_t alarm_wq;
- int minor;
-};
-
-/* linked list of alarms to check for */
-
-static struct gpio_private *alarmlist;
-
-static int gpio_some_alarms; /* Set if someone uses alarm */
-static unsigned long gpio_pa_high_alarms;
-static unsigned long gpio_pa_low_alarms;
-
-static DEFINE_SPINLOCK(alarm_lock);
-
-#define NUM_PORTS (GPIO_MINOR_LAST+1)
-#define GIO_REG_RD_ADDR(reg) \
- (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
-#define GIO_REG_WR_ADDR(reg) \
- (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
-unsigned long led_dummy;
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static unsigned long virtual_dummy;
-static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
-static unsigned short cached_virtual_gpio_read;
-#endif
-
-static volatile unsigned long *data_out[NUM_PORTS] = {
- GIO_REG_WR_ADDR(rw_pa_dout),
- GIO_REG_WR_ADDR(rw_pb_dout),
- &led_dummy,
- GIO_REG_WR_ADDR(rw_pc_dout),
- GIO_REG_WR_ADDR(rw_pd_dout),
- GIO_REG_WR_ADDR(rw_pe_dout),
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &virtual_dummy,
-#endif
-};
-
-static volatile unsigned long *data_in[NUM_PORTS] = {
- GIO_REG_RD_ADDR(r_pa_din),
- GIO_REG_RD_ADDR(r_pb_din),
- &led_dummy,
- GIO_REG_RD_ADDR(r_pc_din),
- GIO_REG_RD_ADDR(r_pd_din),
- GIO_REG_RD_ADDR(r_pe_din),
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &virtual_dummy,
-#endif
-};
-
-static unsigned long changeable_dir[NUM_PORTS] = {
- CONFIG_ETRAX_PA_CHANGEABLE_DIR,
- CONFIG_ETRAX_PB_CHANGEABLE_DIR,
- 0,
- CONFIG_ETRAX_PC_CHANGEABLE_DIR,
- CONFIG_ETRAX_PD_CHANGEABLE_DIR,
- CONFIG_ETRAX_PE_CHANGEABLE_DIR,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- CONFIG_ETRAX_PV_CHANGEABLE_DIR,
-#endif
-};
-
-static unsigned long changeable_bits[NUM_PORTS] = {
- CONFIG_ETRAX_PA_CHANGEABLE_BITS,
- CONFIG_ETRAX_PB_CHANGEABLE_BITS,
- 0,
- CONFIG_ETRAX_PC_CHANGEABLE_BITS,
- CONFIG_ETRAX_PD_CHANGEABLE_BITS,
- CONFIG_ETRAX_PE_CHANGEABLE_BITS,
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- CONFIG_ETRAX_PV_CHANGEABLE_BITS,
-#endif
-};
-
-static volatile unsigned long *dir_oe[NUM_PORTS] = {
- GIO_REG_WR_ADDR(rw_pa_oe),
- GIO_REG_WR_ADDR(rw_pb_oe),
- &led_dummy,
- GIO_REG_WR_ADDR(rw_pc_oe),
- GIO_REG_WR_ADDR(rw_pd_oe),
- GIO_REG_WR_ADDR(rw_pe_oe),
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- &virtual_rw_pv_oe,
-#endif
-};
-
-
-
-static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
-{
- unsigned int mask = 0;
- struct gpio_private *priv = file->private_data;
- unsigned long data;
- poll_wait(file, &priv->alarm_wq, wait);
- if (priv->minor == GPIO_MINOR_A) {
- reg_gio_rw_intr_cfg intr_cfg;
- unsigned long tmp;
- unsigned long flags;
-
- local_irq_save(flags);
- data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din,
- REG_RD(gio, regi_gio, r_pa_din));
- /* PA has support for interrupt
- * lets activate high for those low and with highalarm set
- */
- intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
-
- tmp = ~data & priv->highalarm & 0xFF;
- if (tmp & (1 << 0))
- intr_cfg.pa0 = regk_gio_hi;
- if (tmp & (1 << 1))
- intr_cfg.pa1 = regk_gio_hi;
- if (tmp & (1 << 2))
- intr_cfg.pa2 = regk_gio_hi;
- if (tmp & (1 << 3))
- intr_cfg.pa3 = regk_gio_hi;
- if (tmp & (1 << 4))
- intr_cfg.pa4 = regk_gio_hi;
- if (tmp & (1 << 5))
- intr_cfg.pa5 = regk_gio_hi;
- if (tmp & (1 << 6))
- intr_cfg.pa6 = regk_gio_hi;
- if (tmp & (1 << 7))
- intr_cfg.pa7 = regk_gio_hi;
- /*
- * lets activate low for those high and with lowalarm set
- */
- tmp = data & priv->lowalarm & 0xFF;
- if (tmp & (1 << 0))
- intr_cfg.pa0 = regk_gio_lo;
- if (tmp & (1 << 1))
- intr_cfg.pa1 = regk_gio_lo;
- if (tmp & (1 << 2))
- intr_cfg.pa2 = regk_gio_lo;
- if (tmp & (1 << 3))
- intr_cfg.pa3 = regk_gio_lo;
- if (tmp & (1 << 4))
- intr_cfg.pa4 = regk_gio_lo;
- if (tmp & (1 << 5))
- intr_cfg.pa5 = regk_gio_lo;
- if (tmp & (1 << 6))
- intr_cfg.pa6 = regk_gio_lo;
- if (tmp & (1 << 7))
- intr_cfg.pa7 = regk_gio_lo;
-
- REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
- local_irq_restore(flags);
- } else if (priv->minor <= GPIO_MINOR_E)
- data = *data_in[priv->minor];
- else
- return 0;
-
- if ((data & priv->highalarm) || (~data & priv->lowalarm))
- mask = POLLIN|POLLRDNORM;
-
- DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
- return mask;
-}
-
-int etrax_gpio_wake_up_check(void)
-{
- struct gpio_private *priv;
- unsigned long data = 0;
- unsigned long flags;
- int ret = 0;
- spin_lock_irqsave(&alarm_lock, flags);
- priv = alarmlist;
- while (priv) {
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- if (priv->minor == GPIO_MINOR_V)
- data = (unsigned long)cached_virtual_gpio_read;
- else {
- data = *data_in[priv->minor];
- if (priv->minor == GPIO_MINOR_A)
- priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
- }
-#else
- data = *data_in[priv->minor];
-#endif
- if ((data & priv->highalarm) ||
- (~data & priv->lowalarm)) {
- DP(printk(KERN_DEBUG
- "etrax_gpio_wake_up_check %i\n", priv->minor));
- wake_up_interruptible(&priv->alarm_wq);
- ret = 1;
- }
- priv = priv->next;
- }
- spin_unlock_irqrestore(&alarm_lock, flags);
- return ret;
-}
-
-static irqreturn_t
-gpio_poll_timer_interrupt(int irq, void *dev_id)
-{
- if (gpio_some_alarms)
- return IRQ_RETVAL(etrax_gpio_wake_up_check());
- return IRQ_NONE;
-}
-
-static irqreturn_t
-gpio_pa_interrupt(int irq, void *dev_id)
-{
- reg_gio_rw_intr_mask intr_mask;
- reg_gio_r_masked_intr masked_intr;
- reg_gio_rw_ack_intr ack_intr;
- unsigned long tmp;
- unsigned long tmp2;
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- unsigned char enable_gpiov_ack = 0;
-#endif
-
- /* Find what PA interrupts are active */
- masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
- tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
-
- /* Find those that we have enabled */
- spin_lock(&alarm_lock);
- tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
- spin_unlock(&alarm_lock);
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Something changed on virtual GPIO. Interrupt is acked by
- * reading the device.
- */
- if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
- i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
- sizeof(cached_virtual_gpio_read));
- enable_gpiov_ack = 1;
- }
-#endif
-
- /* Ack them */
- ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
- REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
-
- /* Disable those interrupts.. */
- intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
- tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
- tmp2 &= ~tmp;
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Do not disable interrupt on virtual GPIO. Changes on virtual
- * pins are only noticed by an interrupt.
- */
- if (enable_gpiov_ack)
- tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
- intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
- REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
-
- if (gpio_some_alarms)
- return IRQ_RETVAL(etrax_gpio_wake_up_check());
- return IRQ_NONE;
-}
-
-
-static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
- loff_t *off)
-{
- struct gpio_private *priv = file->private_data;
- unsigned char data, clk_mask, data_mask, write_msb;
- unsigned long flags;
- unsigned long shadow;
- volatile unsigned long *port;
- ssize_t retval = count;
- /* Only bits 0-7 may be used for write operations but allow all
- devices except leds... */
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- if (priv->minor == GPIO_MINOR_V)
- return -EFAULT;
-#endif
- if (priv->minor == GPIO_MINOR_LEDS)
- return -EFAULT;
-
- if (!access_ok(VERIFY_READ, buf, count))
- return -EFAULT;
- clk_mask = priv->clk_mask;
- data_mask = priv->data_mask;
- /* It must have been configured using the IO_CFG_WRITE_MODE */
- /* Perhaps a better error code? */
- if (clk_mask == 0 || data_mask == 0)
- return -EPERM;
- write_msb = priv->write_msb;
- D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
- "msb: %i\n", count, data_mask, clk_mask, write_msb));
- port = data_out[priv->minor];
-
- while (count--) {
- int i;
- data = *buf++;
- if (priv->write_msb) {
- for (i = 7; i >= 0; i--) {
- local_irq_save(flags);
- shadow = *port;
- *port = shadow &= ~clk_mask;
- if (data & 1<<i)
- *port = shadow |= data_mask;
- else
- *port = shadow &= ~data_mask;
- /* For FPGA: min 5.0ns (DCC) before CCLK high */
- *port = shadow |= clk_mask;
- local_irq_restore(flags);
- }
- } else {
- for (i = 0; i <= 7; i++) {
- local_irq_save(flags);
- shadow = *port;
- *port = shadow &= ~clk_mask;
- if (data & 1<<i)
- *port = shadow |= data_mask;
- else
- *port = shadow &= ~data_mask;
- /* For FPGA: min 5.0ns (DCC) before CCLK high */
- *port = shadow |= clk_mask;
- local_irq_restore(flags);
- }
- }
- }
- return retval;
-}
-
-
-
-static int
-gpio_open(struct inode *inode, struct file *filp)
-{
- struct gpio_private *priv;
- int p = iminor(inode);
-
- if (p > GPIO_MINOR_LAST)
- return -EINVAL;
-
- priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- mutex_lock(&gpio_mutex);
-
- priv->minor = p;
-
- /* initialize the io/alarm struct */
-
- priv->clk_mask = 0;
- priv->data_mask = 0;
- priv->highalarm = 0;
- priv->lowalarm = 0;
- init_waitqueue_head(&priv->alarm_wq);
-
- filp->private_data = (void *)priv;
-
- /* link it into our alarmlist */
- spin_lock_irq(&alarm_lock);
- priv->next = alarmlist;
- alarmlist = priv;
- spin_unlock_irq(&alarm_lock);
-
- mutex_unlock(&gpio_mutex);
- return 0;
-}
-
-static int
-gpio_release(struct inode *inode, struct file *filp)
-{
- struct gpio_private *p;
- struct gpio_private *todel;
- /* local copies while updating them: */
- unsigned long a_high, a_low;
- unsigned long some_alarms;
-
- /* unlink from alarmlist and free the private structure */
-
- spin_lock_irq(&alarm_lock);
- p = alarmlist;
- todel = filp->private_data;
-
- if (p == todel) {
- alarmlist = todel->next;
- } else {
- while (p->next != todel)
- p = p->next;
- p->next = todel->next;
- }
-
- kfree(todel);
- /* Check if there are still any alarms set */
- p = alarmlist;
- some_alarms = 0;
- a_high = 0;
- a_low = 0;
- while (p) {
- if (p->minor == GPIO_MINOR_A) {
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
- a_high |= p->highalarm;
- a_low |= p->lowalarm;
- }
-
- if (p->highalarm | p->lowalarm)
- some_alarms = 1;
- p = p->next;
- }
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- /* Variables 'some_alarms' and 'a_low' needs to be set here again
- * to ensure that interrupt for virtual GPIO is handled.
- */
- some_alarms = 1;
- a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
-#endif
-
- gpio_some_alarms = some_alarms;
- gpio_pa_high_alarms = a_high;
- gpio_pa_low_alarms = a_low;
- spin_unlock_irq(&alarm_lock);
-
- return 0;
-}
-
-/* Main device API. ioctl's to read/set/clear bits, as well as to
- * set alarms to wait for using a subsequent select().
- */
-
-inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
-{
- /* Set direction 0=unchanged 1=input,
- * return mask with 1=input
- */
- unsigned long flags;
- unsigned long dir_shadow;
-
- local_irq_save(flags);
- dir_shadow = *dir_oe[priv->minor];
- dir_shadow &= ~(arg & changeable_dir[priv->minor]);
- *dir_oe[priv->minor] = dir_shadow;
- local_irq_restore(flags);
-
- if (priv->minor == GPIO_MINOR_A)
- dir_shadow ^= 0xFF; /* Only 8 bits */
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- else if (priv->minor == GPIO_MINOR_V)
- dir_shadow ^= 0xFFFF; /* Only 16 bits */
-#endif
- else
- dir_shadow ^= 0x3FFFF; /* Only 18 bits */
- return dir_shadow;
-
-} /* setget_input */
-
-inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg)
-{
- unsigned long flags;
- unsigned long dir_shadow;
-
- local_irq_save(flags);
- dir_shadow = *dir_oe[priv->minor];
- dir_shadow |= (arg & changeable_dir[priv->minor]);
- *dir_oe[priv->minor] = dir_shadow;
- local_irq_restore(flags);
- return dir_shadow;
-} /* setget_output */
-
-static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
-
-static int
-gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
-{
- unsigned long flags;
- unsigned long val;
- unsigned long shadow;
- struct gpio_private *priv = file->private_data;
- if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
- return -EINVAL;
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- if (priv->minor == GPIO_MINOR_V)
- return virtual_gpio_ioctl(file, cmd, arg);
-#endif
-
- switch (_IOC_NR(cmd)) {
- case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
- /* Read the port. */
- return *data_in[priv->minor];
- break;
- case IO_SETBITS:
- local_irq_save(flags);
- /* Set changeable bits with a 1 in arg. */
- shadow = *data_out[priv->minor];
- shadow |= (arg & changeable_bits[priv->minor]);
- *data_out[priv->minor] = shadow;
- local_irq_restore(flags);
- break;
- case IO_CLRBITS:
- local_irq_save(flags);
- /* Clear changeable bits with a 1 in arg. */
- shadow = *data_out[priv->minor];
- shadow &= ~(arg & changeable_bits[priv->minor]);
- *data_out[priv->minor] = shadow;
- local_irq_restore(flags);
- break;
- case IO_HIGHALARM:
- /* Set alarm when bits with 1 in arg go high. */
- priv->highalarm |= arg;
- spin_lock_irqsave(&alarm_lock, flags);
- gpio_some_alarms = 1;
- if (priv->minor == GPIO_MINOR_A)
- gpio_pa_high_alarms |= arg;
- spin_unlock_irqrestore(&alarm_lock, flags);
- break;
- case IO_LOWALARM:
- /* Set alarm when bits with 1 in arg go low. */
- priv->lowalarm |= arg;
- spin_lock_irqsave(&alarm_lock, flags);
- gpio_some_alarms = 1;
- if (priv->minor == GPIO_MINOR_A)
- gpio_pa_low_alarms |= arg;
- spin_unlock_irqrestore(&alarm_lock, flags);
- break;
- case IO_CLRALARM:
- /* Clear alarm for bits with 1 in arg. */
- priv->highalarm &= ~arg;
- priv->lowalarm &= ~arg;
- spin_lock_irqsave(&alarm_lock, flags);
- if (priv->minor == GPIO_MINOR_A) {
- if (gpio_pa_high_alarms & arg ||
- gpio_pa_low_alarms & arg)
- /* Must update the gpio_pa_*alarms masks */
- ;
- }
- spin_unlock_irqrestore(&alarm_lock, flags);
- break;
- case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
- /* Read direction 0=input 1=output */
- return *dir_oe[priv->minor];
- case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
- /* Set direction 0=unchanged 1=input,
- * return mask with 1=input
- */
- return setget_input(priv, arg);
- break;
- case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
- /* Set direction 0=unchanged 1=output,
- * return mask with 1=output
- */
- return setget_output(priv, arg);
-
- case IO_CFG_WRITE_MODE:
- {
- unsigned long dir_shadow;
- dir_shadow = *dir_oe[priv->minor];
-
- priv->clk_mask = arg & 0xFF;
- priv->data_mask = (arg >> 8) & 0xFF;
- priv->write_msb = (arg >> 16) & 0x01;
- /* Check if we're allowed to change the bits and
- * the direction is correct
- */
- if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
- (priv->data_mask & changeable_bits[priv->minor]) &&
- (priv->clk_mask & dir_shadow) &&
- (priv->data_mask & dir_shadow))) {
- priv->clk_mask = 0;
- priv->data_mask = 0;
- return -EPERM;
- }
- break;
- }
- case IO_READ_INBITS:
- /* *arg is result of reading the input pins */
- val = *data_in[priv->minor];
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- return 0;
- break;
- case IO_READ_OUTBITS:
- /* *arg is result of reading the output shadow */
- val = *data_out[priv->minor];
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_INPUT:
- /* bits set in *arg is set to input,
- * *arg updated with current input pins.
- */
- if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_input(priv, val);
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_OUTPUT:
- /* bits set in *arg is set to output,
- * *arg updated with current output pins.
- */
- if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_output(priv, val);
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- default:
- if (priv->minor == GPIO_MINOR_LEDS)
- return gpio_leds_ioctl(cmd, arg);
- else
- return -EINVAL;
- } /* switch */
-
- return 0;
-}
-
-static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- long ret;
-
- mutex_lock(&gpio_mutex);
- ret = gpio_ioctl_unlocked(file, cmd, arg);
- mutex_unlock(&gpio_mutex);
-
- return ret;
-}
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static int
-virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- unsigned long flags;
- unsigned short val;
- unsigned short shadow;
- struct gpio_private *priv = file->private_data;
-
- switch (_IOC_NR(cmd)) {
- case IO_SETBITS:
- local_irq_save(flags);
- /* Set changeable bits with a 1 in arg. */
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- shadow |= ~*dir_oe[priv->minor];
- shadow |= (arg & changeable_bits[priv->minor]);
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- local_irq_restore(flags);
- break;
- case IO_CLRBITS:
- local_irq_save(flags);
- /* Clear changeable bits with a 1 in arg. */
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- shadow |= ~*dir_oe[priv->minor];
- shadow &= ~(arg & changeable_bits[priv->minor]);
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- local_irq_restore(flags);
- break;
- case IO_HIGHALARM:
- /* Set alarm when bits with 1 in arg go high. */
- priv->highalarm |= arg;
- spin_lock(&alarm_lock);
- gpio_some_alarms = 1;
- spin_unlock(&alarm_lock);
- break;
- case IO_LOWALARM:
- /* Set alarm when bits with 1 in arg go low. */
- priv->lowalarm |= arg;
- spin_lock(&alarm_lock);
- gpio_some_alarms = 1;
- spin_unlock(&alarm_lock);
- break;
- case IO_CLRALARM:
- /* Clear alarm for bits with 1 in arg. */
- priv->highalarm &= ~arg;
- priv->lowalarm &= ~arg;
- spin_lock(&alarm_lock);
- spin_unlock(&alarm_lock);
- break;
- case IO_CFG_WRITE_MODE:
- {
- unsigned long dir_shadow;
- dir_shadow = *dir_oe[priv->minor];
-
- priv->clk_mask = arg & 0xFF;
- priv->data_mask = (arg >> 8) & 0xFF;
- priv->write_msb = (arg >> 16) & 0x01;
- /* Check if we're allowed to change the bits and
- * the direction is correct
- */
- if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
- (priv->data_mask & changeable_bits[priv->minor]) &&
- (priv->clk_mask & dir_shadow) &&
- (priv->data_mask & dir_shadow))) {
- priv->clk_mask = 0;
- priv->data_mask = 0;
- return -EPERM;
- }
- break;
- }
- case IO_READ_INBITS:
- /* *arg is result of reading the input pins */
- val = cached_virtual_gpio_read;
- val &= ~*dir_oe[priv->minor];
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- return 0;
- break;
- case IO_READ_OUTBITS:
- /* *arg is result of reading the output shadow */
- i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
- val &= *dir_oe[priv->minor];
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- case IO_SETGET_INPUT:
- {
- /* bits set in *arg is set to input,
- * *arg updated with current input pins.
- */
- unsigned short input_mask = ~*dir_oe[priv->minor];
- if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_input(priv, val);
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- if ((input_mask & val) != input_mask) {
- /* Input pins changed. All ports desired as input
- * should be set to logic 1.
- */
- unsigned short change = input_mask ^ val;
- i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
- sizeof(shadow));
- shadow &= ~change;
- shadow |= val;
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
- sizeof(shadow));
- }
- break;
- }
- case IO_SETGET_OUTPUT:
- /* bits set in *arg is set to output,
- * *arg updated with current output pins.
- */
- if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
- return -EFAULT;
- val = setget_output(priv, val);
- if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
- return -EFAULT;
- break;
- default:
- return -EINVAL;
- } /* switch */
- return 0;
-}
-#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
-
-static int
-gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
-{
- unsigned char green;
- unsigned char red;
-
- switch (_IOC_NR(cmd)) {
- case IO_LEDACTIVE_SET:
- green = ((unsigned char) arg) & 1;
- red = (((unsigned char) arg) >> 1) & 1;
- CRIS_LED_ACTIVE_SET_G(green);
- CRIS_LED_ACTIVE_SET_R(red);
- break;
-
- default:
- return -EINVAL;
- } /* switch */
-
- return 0;
-}
-
-static const struct file_operations gpio_fops = {
- .owner = THIS_MODULE,
- .poll = gpio_poll,
- .unlocked_ioctl = gpio_ioctl,
- .write = gpio_write,
- .open = gpio_open,
- .release = gpio_release,
- .llseek = noop_llseek,
-};
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-static void
-virtual_gpio_init(void)
-{
- reg_gio_rw_intr_cfg intr_cfg;
- reg_gio_rw_intr_mask intr_mask;
- unsigned short shadow;
-
- shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
- shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
- i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
-
- /* Set interrupt mask and on what state the interrupt shall trigger.
- * For virtual gpio the interrupt shall trigger on logic '0'.
- */
- intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
- intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
-
- switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
- case 0:
- intr_cfg.pa0 = regk_gio_lo;
- intr_mask.pa0 = regk_gio_yes;
- break;
- case 1:
- intr_cfg.pa1 = regk_gio_lo;
- intr_mask.pa1 = regk_gio_yes;
- break;
- case 2:
- intr_cfg.pa2 = regk_gio_lo;
- intr_mask.pa2 = regk_gio_yes;
- break;
- case 3:
- intr_cfg.pa3 = regk_gio_lo;
- intr_mask.pa3 = regk_gio_yes;
- break;
- case 4:
- intr_cfg.pa4 = regk_gio_lo;
- intr_mask.pa4 = regk_gio_yes;
- break;
- case 5:
- intr_cfg.pa5 = regk_gio_lo;
- intr_mask.pa5 = regk_gio_yes;
- break;
- case 6:
- intr_cfg.pa6 = regk_gio_lo;
- intr_mask.pa6 = regk_gio_yes;
- break;
- case 7:
- intr_cfg.pa7 = regk_gio_lo;
- intr_mask.pa7 = regk_gio_yes;
- break;
- }
-
- REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
- REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
-
- gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
- gpio_some_alarms = 1;
-}
-#endif
-
-/* main driver initialization routine, called from mem.c */
-
-static __init int
-gpio_init(void)
-{
- int res;
-
- /* do the formalities */
-
- res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
- if (res < 0) {
- printk(KERN_ERR "gpio: couldn't get a major number.\n");
- return res;
- }
-
- /* Clear all leds */
- CRIS_LED_NETWORK_GRP0_SET(0);
- CRIS_LED_NETWORK_GRP1_SET(0);
- CRIS_LED_ACTIVE_SET(0);
- CRIS_LED_DISK_READ(0);
- CRIS_LED_DISK_WRITE(0);
-
- printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
- "Axis Communications AB\n");
- /* We call etrax_gpio_wake_up_check() from timer interrupt */
- if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt,
- IRQF_SHARED, "gpio poll", &alarmlist))
- printk(KERN_ERR "timer0 irq for gpio\n");
-
- if (request_irq(GIO_INTR_VECT, gpio_pa_interrupt,
- IRQF_SHARED, "gpio PA", &alarmlist))
- printk(KERN_ERR "PA irq for gpio\n");
-
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- virtual_gpio_init();
-#endif
-
- return res;
-}
-
-/* this makes sure that gpio_init is called during kernel boot */
-
-module_init(gpio_init);
diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c
index e032384..a7c17b0 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c
@@ -31,7 +31,6 @@
#define BY_BIT 7
struct mtd_info_wrapper {
- struct mtd_info info;
struct nand_chip chip;
};
@@ -51,7 +50,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd,
{
unsigned long flags;
reg_gio_rw_pa_dout dout;
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
local_irq_save(flags);
@@ -129,7 +128,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
/* Get pointer to private data */
this = &wrapper->chip;
- crisv32_mtd = &wrapper->info;
+ crisv32_mtd = nand_to_mtd(this);
pa_oe.oe |= 1 << CE_BIT;
pa_oe.oe |= 1 << ALE_BIT;
@@ -141,9 +140,6 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
bif_cfg.gated_csp1 = regk_bif_core_wr;
REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
- /* Link the private data with the MTD structure */
- crisv32_mtd->priv = this;
-
/* Set address of NAND IO lines */
this->IO_ADDR_R = read_cs;
this->IO_ADDR_W = write_cs;
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index ee55578..8d5efa5 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -16,21 +16,18 @@
#include <linux/gfp.h>
#include <asm/io.h>
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static void *v32_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
void *ret;
- int order = get_order(size);
+
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
- if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
- return ret;
-
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
gfp |= GFP_DMA;
- ret = (void *)__get_free_pages(gfp, order);
+ ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
@@ -39,12 +36,45 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
+static void v32_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
+{
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static inline dma_addr_t v32_dma_map_page(struct device *dev,
+ struct page *page, unsigned long offset, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- int order = get_order(size);
+ return page_to_phys(page) + offset;
+}
- if (!dma_release_from_coherent(dev, order, vaddr))
- free_pages((unsigned long)vaddr, order);
+static inline int v32_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ printk("Map sg\n");
+ return nents;
+}
+
+static inline int v32_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+ return 1;
}
+struct dma_map_ops v32_dma_ops = {
+ .alloc = v32_dma_alloc,
+ .free = v32_dma_free,
+ .map_page = v32_dma_map_page,
+ .map_sg = v32_dma_map_sg,
+ .dma_supported = v32_dma_supported,
+};
+EXPORT_SYMBOL(v32_dma_ops);
diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c
index bde8d1a..b056635 100644
--- a/arch/cris/arch-v32/kernel/crisksyms.c
+++ b/arch/cris/arch-v32/kernel/crisksyms.c
@@ -3,7 +3,6 @@
#include <arch/dma.h>
#include <arch/intmem.h>
#include <mach/pinmux.h>
-#include <arch/io.h>
/* Functions for allocating DMA channels */
EXPORT_SYMBOL(crisv32_request_dma);
@@ -20,8 +19,6 @@ EXPORT_SYMBOL(crisv32_pinmux_alloc);
EXPORT_SYMBOL(crisv32_pinmux_alloc_fixed);
EXPORT_SYMBOL(crisv32_pinmux_dealloc);
EXPORT_SYMBOL(crisv32_pinmux_dealloc_fixed);
-EXPORT_SYMBOL(crisv32_io_get_name);
-EXPORT_SYMBOL(crisv32_io_get);
/* Functions masking/unmasking interrupts */
EXPORT_SYMBOL(crisv32_mask_irq);
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
index 02e33eb..d2f3f9c 100644
--- a/arch/cris/arch-v32/kernel/debugport.c
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -77,8 +77,6 @@ static struct dbg_port *port =
&ports[2];
#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
&ports[3];
-#elif defined(CONFIG_ETRAX_DEBUG_PORT4)
- &ports[4];
#else
NULL;
#endif
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S
index 74a66e0..5ce83eb 100644
--- a/arch/cris/arch-v32/kernel/head.S
+++ b/arch/cris/arch-v32/kernel/head.S
@@ -4,6 +4,8 @@
* Copyright (C) 2003, Axis Communications AB
*/
+#include <linux/init.h>
+
#define ASSEMBLER_MACROS_ONLY
/*
@@ -36,7 +38,7 @@
.global nand_boot
.global swapper_pg_dir
- .text
+ __HEAD
tstart:
;; This is the entry point of the kernel. The CPU is currently in
;; supervisor mode.
@@ -177,7 +179,7 @@ _inflash0:
;; Put the following in a section so that storage for it can be
;; reclaimed after init is finished.
- .section ".init.text", "ax"
+ __INIT
_inflash:
@@ -292,11 +294,7 @@ _no_romfs_in_flash:
;; For cramfs, partition starts with magic and length.
;; For jffs2, a jhead is prepended which contains with magic and length.
;; The jhead is not part of the jffs2 partition however.
-#ifndef CONFIG_ETRAXFS_SIM
move.d __bss_start, $r0
-#else
- move.d __end, $r0
-#endif
move.d [$r0], $r1
cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
beq 2f ; yes, jump
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index 6a881e0..6de8db6 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -37,7 +37,7 @@
#define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ))
#elif defined(CONFIG_ETRAX_KGDB_PORT1)
#define IGNOREMASK (1 << (SER1_INTR_VECT - FIRST_IRQ))
-#elif defined(CONFIG_ETRAX_KGB_PORT2)
+#elif defined(CONFIG_ETRAX_KGDB_PORT2)
#define IGNOREMASK (1 << (SER2_INTR_VECT - FIRST_IRQ))
#elif defined(CONFIG_ETRAX_KGDB_PORT3)
#define IGNOREMASK (1 << (SER3_INTR_VECT - FIRST_IRQ))
@@ -464,14 +464,14 @@ init_IRQ(void)
etrax_irv->v[i] = weird_irq;
np = of_find_compatible_node(NULL, NULL, "axis,crisv32-intc");
- domain = irq_domain_add_legacy(np, NR_IRQS - FIRST_IRQ,
+ domain = irq_domain_add_legacy(np, NBR_INTR_VECT - FIRST_IRQ,
FIRST_IRQ, FIRST_IRQ,
&crisv32_irq_ops, NULL);
BUG_ON(!domain);
irq_set_default_host(domain);
of_node_put(np);
- for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
+ for (i = FIRST_IRQ, j = 0; j < NBR_INTR_VECT; i++, j++) {
set_exception_vector(i, interrupt[j]);
}
diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c
index b06813a..e0fdea7 100644
--- a/arch/cris/arch-v32/kernel/kgdb.c
+++ b/arch/cris/arch-v32/kernel/kgdb.c
@@ -384,19 +384,11 @@ int getDebugChar(void);
/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */
void putDebugChar(int val);
-/* Returns the integer equivalent of a hexadecimal character. */
-static int hex(char ch);
-
/* Convert the memory, pointed to by mem into hexadecimal representation.
Put the result in buf, and return a pointer to the last character
in buf (null). */
static char *mem2hex(char *buf, unsigned char *mem, int count);
-/* Convert the array, in hexadecimal representation, pointed to by buf into
- binary representation. Put the result in mem, and return a pointer to
- the character after the last byte written. */
-static unsigned char *hex2mem(unsigned char *mem, char *buf, int count);
-
/* Put the content of the array, in binary representation, pointed to by buf
into memory pointed to by mem, and return a pointer to
the character after the last byte written. */
@@ -449,7 +441,7 @@ static char output_buffer[BUFMAX];
/* Error and warning messages. */
enum error_type
{
- SUCCESS, E01, E02, E03, E04, E05, E06,
+ SUCCESS, E01, E02, E03, E04, E05, E06, E07, E08
};
static char *error_message[] =
@@ -461,6 +453,8 @@ static char *error_message[] =
"E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
"E05 Change register content - P - the register is not implemented..",
"E06 Change memory content - M - internal error.",
+ "E07 Change register content - P - the register is not stored on the stack",
+ "E08 Invalid parameter"
};
/********************************** Breakpoint *******************************/
@@ -539,7 +533,7 @@ gdb_cris_strtol(const char *s, char **endptr, int base)
/********************************* Register image ****************************/
/* Write a value to a specified register in the register image of the current
- thread. Returns status code SUCCESS, E02 or E05. */
+ thread. Returns status code SUCCESS, E02, E05 or E08. */
static int
write_register(int regno, char *val)
{
@@ -547,8 +541,9 @@ write_register(int regno, char *val)
if (regno >= R0 && regno <= ACR) {
/* Consecutive 32-bit registers. */
- hex2mem((unsigned char *)&reg.r0 + (regno - R0) * sizeof(unsigned int),
- val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)&reg.r0 + (regno - R0) * sizeof(unsigned int),
+ val, sizeof(unsigned int)))
+ status = E08;
} else if (regno == BZ || regno == VR || regno == WZ || regno == DZ) {
/* Read-only registers. */
@@ -557,16 +552,19 @@ write_register(int regno, char *val)
} else if (regno == PID) {
/* 32-bit register. (Even though we already checked SRS and WZ, we cannot
combine this with the EXS - SPC write since SRS and WZ have different size.) */
- hex2mem((unsigned char *)&reg.pid, val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)&reg.pid, val, sizeof(unsigned int)))
+ status = E08;
} else if (regno == SRS) {
/* 8-bit register. */
- hex2mem((unsigned char *)&reg.srs, val, sizeof(unsigned char));
+ if (hex2bin((unsigned char *)&reg.srs, val, sizeof(unsigned char)))
+ status = E08;
} else if (regno >= EXS && regno <= SPC) {
/* Consecutive 32-bit registers. */
- hex2mem((unsigned char *)&reg.exs + (regno - EXS) * sizeof(unsigned int),
- val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)&reg.exs + (regno - EXS) * sizeof(unsigned int),
+ val, sizeof(unsigned int)))
+ status = E08;
} else if (regno == PC) {
/* Pseudo-register. Treat as read-only. */
@@ -574,7 +572,9 @@ write_register(int regno, char *val)
} else if (regno >= S0 && regno <= S15) {
/* 32-bit registers. */
- hex2mem((unsigned char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int), val, sizeof(unsigned int));
+ if (hex2bin((unsigned char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int),
+ val, sizeof(unsigned int)))
+ status = E08;
} else {
/* Non-existing register. */
status = E05;
@@ -630,19 +630,6 @@ read_register(char regno, unsigned int *valptr)
}
/********************************** Packet I/O ******************************/
-/* Returns the integer equivalent of a hexadecimal character. */
-static int
-hex(char ch)
-{
- if ((ch >= 'a') && (ch <= 'f'))
- return (ch - 'a' + 10);
- if ((ch >= '0') && (ch <= '9'))
- return (ch - '0');
- if ((ch >= 'A') && (ch <= 'F'))
- return (ch - 'A' + 10);
- return -1;
-}
-
/* Convert the memory, pointed to by mem into hexadecimal representation.
Put the result in buf, and return a pointer to the last character
in buf (null). */
@@ -689,22 +676,6 @@ mem2hex_nbo(char *buf, unsigned char *mem, int count)
return buf;
}
-/* Convert the array, in hexadecimal representation, pointed to by buf into
- binary representation. Put the result in mem, and return a pointer to
- the character after the last byte written. */
-static unsigned char*
-hex2mem(unsigned char *mem, char *buf, int count)
-{
- int i;
- unsigned char ch;
- for (i = 0; i < count; i++) {
- ch = hex (*buf++) << 4;
- ch = ch + hex (*buf++);
- *mem++ = ch;
- }
- return mem;
-}
-
/* Put the content of the array, in binary representation, pointed to by buf
into memory pointed to by mem, and return a pointer to the character after
the last byte written.
@@ -763,8 +734,8 @@ getpacket(char *buffer)
buffer[count] = 0;
if (ch == '#') {
- xmitcsum = hex(getDebugChar()) << 4;
- xmitcsum += hex(getDebugChar());
+ xmitcsum = hex_to_bin(getDebugChar()) << 4;
+ xmitcsum += hex_to_bin(getDebugChar());
if (checksum != xmitcsum) {
/* Wrong checksum */
putDebugChar('-');
@@ -1304,14 +1275,17 @@ handle_exception(int sigval)
/* Write registers. GXX..XX
Each byte of register data is described by two hex digits.
Success: OK
- Failure: void. */
+ Failure: E08. */
/* General and special registers. */
- hex2mem((char *)&reg, &input_buffer[1], sizeof(registers));
+ if (hex2bin((char *)&reg, &input_buffer[1], sizeof(registers)))
+ gdb_cris_strcpy(output_buffer, error_message[E08]);
/* Support registers. */
- hex2mem((char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
+ else if (hex2bin((char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
&input_buffer[1] + sizeof(registers),
- 16 * sizeof(unsigned int));
- gdb_cris_strcpy(output_buffer, "OK");
+ 16 * sizeof(unsigned int)))
+ gdb_cris_strcpy(output_buffer, error_message[E08]);
+ else
+ gdb_cris_strcpy(output_buffer, "OK");
break;
case 'P':
@@ -1338,6 +1312,10 @@ handle_exception(int sigval)
/* Do not support non-existing registers. */
gdb_cris_strcpy(output_buffer, error_message[E05]);
break;
+ case E08:
+ /* Invalid parameter. */
+ gdb_cris_strcpy(output_buffer, error_message[E08]);
+ break;
default:
/* Valid register number. */
gdb_cris_strcpy(output_buffer, "OK");
@@ -1380,7 +1358,7 @@ handle_exception(int sigval)
AA..AA is the start address, LLLL is the number of bytes, and
XX..XX is the hexadecimal data.
Success: OK
- Failure: void. */
+ Failure: E08. */
{
char *lenptr;
char *dataptr;
@@ -1389,13 +1367,15 @@ handle_exception(int sigval)
int len = gdb_cris_strtol(lenptr+1, &dataptr, 16);
if (*lenptr == ',' && *dataptr == ':') {
if (input_buffer[0] == 'M') {
- hex2mem(addr, dataptr + 1, len);
+ if (hex2bin(addr, dataptr + 1, len))
+ gdb_cris_strcpy(output_buffer, error_message[E08]);
+ else
+ gdb_cris_strcpy(output_buffer, "OK");
} else /* X */ {
bin2mem(addr, dataptr + 1, len);
+ gdb_cris_strcpy(output_buffer, "OK");
}
- gdb_cris_strcpy(output_buffer, "OK");
- }
- else {
+ } else {
gdb_cris_strcpy(output_buffer, error_message[E06]);
}
}
diff --git a/arch/cris/arch-v32/kernel/setup.c b/arch/cris/arch-v32/kernel/setup.c
index cd1865d..fe50287 100644
--- a/arch/cris/arch-v32/kernel/setup.c
+++ b/arch/cris/arch-v32/kernel/setup.c
@@ -129,10 +129,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
#ifdef CONFIG_RTC_DRV_PCF8563
{I2C_BOARD_INFO("pcf8563", 0x51)},
#endif
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- {I2C_BOARD_INFO("vgpio", 0x20)},
- {I2C_BOARD_INFO("vgpio", 0x21)},
-#endif
{I2C_BOARD_INFO("pca9536", 0x41)},
{I2C_BOARD_INFO("fnp300", 0x40)},
{I2C_BOARD_INFO("fnp300", 0x42)},
@@ -146,10 +142,6 @@ static struct i2c_board_info __initdata i2c_info2[] = {
{I2C_BOARD_INFO("tmp100", 0x4C)},
{I2C_BOARD_INFO("tmp100", 0x4D)},
{I2C_BOARD_INFO("tmp100", 0x4E)},
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
- {I2C_BOARD_INFO("vgpio", 0x20)},
- {I2C_BOARD_INFO("vgpio", 0x21)},
-#endif
{I2C_BOARD_INFO("pca9536", 0x41)},
{I2C_BOARD_INFO("fnp300", 0x40)},
{I2C_BOARD_INFO("fnp300", 0x42)},
diff --git a/arch/cris/arch-v32/mach-a3/Makefile b/arch/cris/arch-v32/mach-a3/Makefile
index 18a2271..0cc6eeb 100644
--- a/arch/cris/arch-v32/mach-a3/Makefile
+++ b/arch/cris/arch-v32/mach-a3/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-obj-y := dma.o pinmux.o io.o arbiter.o
+obj-y := dma.o pinmux.o arbiter.o
clean:
diff --git a/arch/cris/arch-v32/mach-a3/io.c b/arch/cris/arch-v32/mach-a3/io.c
deleted file mode 100644
index 090ceb9..0000000
--- a/arch/cris/arch-v32/mach-a3/io.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Helper functions for I/O pins.
- *
- * Copyright (c) 2005-2007 Axis Communications AB.
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <mach/pinmux.h>
-#include <hwregs/gio_defs.h>
-
-struct crisv32_ioport crisv32_ioports[] = {
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
- 32
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
- 32
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
- 16
- },
-};
-
-#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports)
-
-struct crisv32_iopin crisv32_led_net0_green;
-struct crisv32_iopin crisv32_led_net0_red;
-struct crisv32_iopin crisv32_led2_green;
-struct crisv32_iopin crisv32_led2_red;
-struct crisv32_iopin crisv32_led3_green;
-struct crisv32_iopin crisv32_led3_red;
-
-/* Dummy port used when green LED and red LED is on the same bit */
-static unsigned long io_dummy;
-static struct crisv32_ioport dummy_port = {
- &io_dummy,
- &io_dummy,
- &io_dummy,
- 32
-};
-static struct crisv32_iopin dummy_led = {
- &dummy_port,
- 0
-};
-
-static int __init crisv32_io_init(void)
-{
- int ret = 0;
-
- u32 i;
-
- /* Locks *should* be dynamically initialized. */
- for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
- spin_lock_init(&crisv32_ioports[i].lock);
- spin_lock_init(&dummy_port.lock);
-
- /* Initialize LEDs */
-#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
- ret += crisv32_io_get_name(&crisv32_led_net0_green,
- CONFIG_ETRAX_LED_G_NET0);
- crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
- if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
- ret += crisv32_io_get_name(&crisv32_led_net0_red,
- CONFIG_ETRAX_LED_R_NET0);
- crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
- } else
- crisv32_led_net0_red = dummy_led;
-#endif
-
- ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
- ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
- ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
- ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);
-
- crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
-
- return ret;
-}
-
-__initcall(crisv32_io_init);
-
-int crisv32_io_get(struct crisv32_iopin *iopin,
- unsigned int port, unsigned int pin)
-{
- if (port > NBR_OF_PORTS)
- return -EINVAL;
- if (port > crisv32_ioports[port].pin_count)
- return -EINVAL;
-
- iopin->bit = 1 << pin;
- iopin->port = &crisv32_ioports[port];
-
- if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
- return -EIO;
-
- return 0;
-}
-
-int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
-{
- int port;
- int pin;
-
- if (toupper(*name) == 'P')
- name++;
-
- if (toupper(*name) < 'A' || toupper(*name) > 'E')
- return -EINVAL;
-
- port = toupper(*name) - 'A';
- name++;
- pin = simple_strtoul(name, NULL, 10);
-
- if (pin < 0 || pin > crisv32_ioports[port].pin_count)
- return -EINVAL;
-
- iopin->bit = 1 << pin;
- iopin->port = &crisv32_ioports[port];
-
- if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
- return -EIO;
-
- return 0;
-}
-
-#ifdef CONFIG_PCI
-/* PCI I/O access stuff */
-struct cris_io_operations *cris_iops = NULL;
-EXPORT_SYMBOL(cris_iops);
-#endif
-
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
index 774de82..7d1ab97 100644
--- a/arch/cris/arch-v32/mach-fs/Kconfig
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -192,25 +192,6 @@ config ETRAX_DEF_GIO_PE_OUT
Configures the initial data for the general port E bits. Most
products should use 00000 here.
-config ETRAX_DEF_GIO_PV_OE
- hex "GIO_PV_OE"
- depends on ETRAX_VIRTUAL_GPIO
- default "0000"
- help
- Configures the direction of virtual general port V bits. 1 is out,
- 0 is in. This is often totally different depending on the product
- used. These bits are used for all kinds of stuff. If you don't know
- what to use, it is always safe to put all as inputs, although
- floating inputs isn't good.
-
-config ETRAX_DEF_GIO_PV_OUT
- hex "GIO_PV_OUT"
- depends on ETRAX_VIRTUAL_GPIO
- default "0000"
- help
- Configures the initial data for the virtual general port V bits.
- Most products should use 0000 here.
-
endmenu
endif
diff --git a/arch/cris/arch-v32/mach-fs/Makefile b/arch/cris/arch-v32/mach-fs/Makefile
index 18a2271..0cc6eeb 100644
--- a/arch/cris/arch-v32/mach-fs/Makefile
+++ b/arch/cris/arch-v32/mach-fs/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-obj-y := dma.o pinmux.o io.o arbiter.o
+obj-y := dma.o pinmux.o arbiter.o
clean:
diff --git a/arch/cris/arch-v32/mach-fs/io.c b/arch/cris/arch-v32/mach-fs/io.c
deleted file mode 100644
index a695866..0000000
--- a/arch/cris/arch-v32/mach-fs/io.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Helper functions for I/O pins.
- *
- * Copyright (c) 2004-2007 Axis Communications AB.
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <mach/pinmux.h>
-#include <hwregs/gio_defs.h>
-
-#ifndef DEBUG
-#define DEBUG(x)
-#endif
-
-struct crisv32_ioport crisv32_ioports[] = {
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
- 8
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
- 18
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
- 18
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pd_din),
- 18
- },
- {
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_oe),
- (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_dout),
- (unsigned long *)REG_ADDR(gio, regi_gio, r_pe_din),
- 18
- }
-};
-
-#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports)
-
-struct crisv32_iopin crisv32_led_net0_green;
-struct crisv32_iopin crisv32_led_net0_red;
-struct crisv32_iopin crisv32_led_net1_green;
-struct crisv32_iopin crisv32_led_net1_red;
-struct crisv32_iopin crisv32_led2_green;
-struct crisv32_iopin crisv32_led2_red;
-struct crisv32_iopin crisv32_led3_green;
-struct crisv32_iopin crisv32_led3_red;
-
-/* Dummy port used when green LED and red LED is on the same bit */
-static unsigned long io_dummy;
-static struct crisv32_ioport dummy_port = {
- &io_dummy,
- &io_dummy,
- &io_dummy,
- 18
-};
-static struct crisv32_iopin dummy_led = {
- &dummy_port,
- 0
-};
-
-static int __init crisv32_io_init(void)
-{
- int ret = 0;
-
- u32 i;
-
- /* Locks *should* be dynamically initialized. */
- for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
- spin_lock_init(&crisv32_ioports[i].lock);
- spin_lock_init(&dummy_port.lock);
-
- /* Initialize LEDs */
-#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
- ret +=
- crisv32_io_get_name(&crisv32_led_net0_green,
- CONFIG_ETRAX_LED_G_NET0);
- crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
- if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
- ret +=
- crisv32_io_get_name(&crisv32_led_net0_red,
- CONFIG_ETRAX_LED_R_NET0);
- crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
- } else
- crisv32_led_net0_red = dummy_led;
-#endif
-
-#ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO
- ret +=
- crisv32_io_get_name(&crisv32_led_net1_green,
- CONFIG_ETRAX_LED_G_NET1);
- crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out);
- if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) {
- crisv32_io_get_name(&crisv32_led_net1_red,
- CONFIG_ETRAX_LED_R_NET1);
- crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out);
- } else
- crisv32_led_net1_red = dummy_led;
-#endif
-
- ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
- ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
- ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
- ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);
-
- crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
- crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
-
- return ret;
-}
-
-__initcall(crisv32_io_init);
-
-int crisv32_io_get(struct crisv32_iopin *iopin,
- unsigned int port, unsigned int pin)
-{
- if (port > NBR_OF_PORTS)
- return -EINVAL;
- if (port > crisv32_ioports[port].pin_count)
- return -EINVAL;
-
- iopin->bit = 1 << pin;
- iopin->port = &crisv32_ioports[port];
-
- /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
- /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
- if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
- return -EIO;
- DEBUG(printk(KERN_DEBUG "crisv32_io_get: Allocated pin %d on port %d\n",
- pin, port));
-
- return 0;
-}
-
-int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
-{
- int port;
- int pin;
-
- if (toupper(*name) == 'P')
- name++;
-
- if (toupper(*name) < 'A' || toupper(*name) > 'E')
- return -EINVAL;
-
- port = toupper(*name) - 'A';
- name++;
- pin = simple_strtoul(name, NULL, 10);
-
- if (pin < 0 || pin > crisv32_ioports[port].pin_count)
- return -EINVAL;
-
- iopin->bit = 1 << pin;
- iopin->port = &crisv32_ioports[port];
-
- /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */
- /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */
- if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio))
- return -EIO;
-
- DEBUG(printk(KERN_DEBUG
- "crisv32_io_get_name: Allocated pin %d on port %d\n",
- pin, port));
-
- return 0;
-}
-
-#ifdef CONFIG_PCI
-/* PCI I/O access stuff */
-struct cris_io_operations *cris_iops = NULL;
-EXPORT_SYMBOL(cris_iops);
-#endif
diff --git a/arch/cris/boot/dts/artpec3.dtsi b/arch/cris/boot/dts/artpec3.dtsi
new file mode 100644
index 0000000..be15be6
--- /dev/null
+++ b/arch/cris/boot/dts/artpec3.dtsi
@@ -0,0 +1,46 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "axis,crisv32";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ model = "artpec3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller {
+ compatible = "axis,crisv32-intc";
+ reg = <0xb002a000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gio: gpio@b0020000 {
+ compatible = "axis,artpec3-gio";
+ reg = <0xb0020000 0x1000>;
+ interrupts = <61>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ };
+
+ serial@b003e000 {
+ compatible = "axis,etraxfs-uart";
+ reg = <0xb003e000 0x1000>;
+ interrupts = <64>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/cris/boot/dts/dev88.dts b/arch/cris/boot/dts/dev88.dts
index 4fa5a3f..b9a230d 100644
--- a/arch/cris/boot/dts/dev88.dts
+++ b/arch/cris/boot/dts/dev88.dts
@@ -1,5 +1,7 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+
/include/ "etraxfs.dtsi"
/ {
@@ -15,4 +17,51 @@
status = "okay";
};
};
+
+ spi {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-sck = <&gio 1 0 0xd>;
+ gpio-miso = <&gio 4 0 0xd>;
+ gpio-mosi = <&gio 0 0 0xd>;
+ cs-gpios = <&gio 3 0 0xd>;
+ num-chipselects = <1>;
+
+ temp-sensor@0 {
+ compatible = "ti,lm70";
+ reg = <0>;
+
+ spi-max-frequency = <100000>;
+ };
+ };
+
+ i2c {
+ compatible = "i2c-gpio";
+ gpios = <&gio 5 0 0xd>, <&gio 6 0 0xd>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ network {
+ label = "network";
+ gpios = <&gio 2 GPIO_ACTIVE_LOW 0xa>;
+ };
+
+ status {
+ label = "status";
+ gpios = <&gio 3 GPIO_ACTIVE_LOW 0xa>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
};
diff --git a/arch/cris/boot/dts/etraxfs.dtsi b/arch/cris/boot/dts/etraxfs.dtsi
index 909bced..bf1b858 100644
--- a/arch/cris/boot/dts/etraxfs.dtsi
+++ b/arch/cris/boot/dts/etraxfs.dtsi
@@ -28,6 +28,14 @@
#interrupt-cells = <1>;
};
+ gio: gpio@b001a000 {
+ compatible = "axis,etraxfs-gio";
+ reg = <0xb001a000 0x1000>;
+ interrupts = <50>;
+ gpio-controller;
+ #gpio-cells = <3>;
+ };
+
serial@b00260000 {
compatible = "axis,etraxfs-uart";
reg = <0xb0026000 0x1000>;
diff --git a/arch/cris/boot/dts/include/dt-bindings b/arch/cris/boot/dts/include/dt-bindings
new file mode 120000
index 0000000..08c00e4
--- /dev/null
+++ b/arch/cris/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings \ No newline at end of file
diff --git a/arch/cris/boot/dts/p1343.dts b/arch/cris/boot/dts/p1343.dts
new file mode 100644
index 0000000..fab7bdb
--- /dev/null
+++ b/arch/cris/boot/dts/p1343.dts
@@ -0,0 +1,76 @@
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/include/ "artpec3.dtsi"
+
+/ {
+ model = "Axis P1343 Network Camera";
+ compatible = "axis,p1343";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ uart0: serial@b003e000 {
+ status = "okay";
+ };
+ };
+
+ i2c {
+ compatible = "i2c-gpio";
+ gpios = <&gio 3 0 0xa>, <&gio 2 0 0xa>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status_green {
+ label = "status:green";
+ gpios = <&gio 0 GPIO_ACTIVE_LOW 0xc>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ status_red {
+ label = "status:red";
+ gpios = <&gio 1 GPIO_ACTIVE_LOW 0xc>;
+ };
+
+ network_green {
+ label = "network:green";
+ gpios = <&gio 2 GPIO_ACTIVE_LOW 0xc>;
+ };
+
+ network_red {
+ label = "network:red";
+ gpios = <&gio 3 GPIO_ACTIVE_LOW 0xc>;
+ };
+
+ power_red {
+ label = "power:red";
+ gpios = <&gio 4 GPIO_ACTIVE_LOW 0xc>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ activity-button@0 {
+ label = "Activity Button";
+ linux,code = <KEY_FN>;
+ gpios = <&gio 13 GPIO_ACTIVE_LOW 0xd>;
+ };
+ };
+};
diff --git a/arch/cris/boot/rescue/head_v10.S b/arch/cris/boot/rescue/head_v10.S
index af55df0..1c05492 100644
--- a/arch/cris/boot/rescue/head_v10.S
+++ b/arch/cris/boot/rescue/head_v10.S
@@ -281,9 +281,6 @@ wait_ser:
#ifdef CONFIG_ETRAX_PB_LEDS
move.b $r2, [R_PORT_PB_DATA]
#endif
-#ifdef CONFIG_ETRAX_90000000_LEDS
- move.b $r2, [0x90000000]
-#endif
#endif
;; check if we got something on the serial port
diff --git a/arch/cris/include/arch-v10/arch/checksum.h b/arch/cris/include/arch-v10/arch/checksum.h
index b8000c5..d1d1bd9 100644
--- a/arch/cris/include/arch-v10/arch/checksum.h
+++ b/arch/cris/include/arch-v10/arch/checksum.h
@@ -9,8 +9,8 @@
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
__wsum res;
__asm__ ("add.d %2, %0\n\t"
diff --git a/arch/cris/include/arch-v32/arch/checksum.h b/arch/cris/include/arch-v32/arch/checksum.h
index e5dcfce..65cf205 100644
--- a/arch/cris/include/arch-v32/arch/checksum.h
+++ b/arch/cris/include/arch-v32/arch/checksum.h
@@ -11,7 +11,7 @@
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len, unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
__wsum res;
diff --git a/arch/cris/include/arch-v32/arch/io.h b/arch/cris/include/arch-v32/arch/io.h
deleted file mode 100644
index adc5484..0000000
--- a/arch/cris/include/arch-v32/arch/io.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef _ASM_ARCH_CRIS_IO_H
-#define _ASM_ARCH_CRIS_IO_H
-
-#include <linux/spinlock.h>
-#include <hwregs/reg_map.h>
-#include <hwregs/reg_rdwr.h>
-#include <hwregs/gio_defs.h>
-
-enum crisv32_io_dir
-{
- crisv32_io_dir_in = 0,
- crisv32_io_dir_out = 1
-};
-
-struct crisv32_ioport
-{
- volatile unsigned long *oe;
- volatile unsigned long *data;
- volatile unsigned long *data_in;
- unsigned int pin_count;
- spinlock_t lock;
-};
-
-struct crisv32_iopin
-{
- struct crisv32_ioport* port;
- int bit;
-};
-
-extern struct crisv32_ioport crisv32_ioports[];
-
-extern struct crisv32_iopin crisv32_led1_green;
-extern struct crisv32_iopin crisv32_led1_red;
-extern struct crisv32_iopin crisv32_led2_green;
-extern struct crisv32_iopin crisv32_led2_red;
-extern struct crisv32_iopin crisv32_led3_green;
-extern struct crisv32_iopin crisv32_led3_red;
-
-extern struct crisv32_iopin crisv32_led_net0_green;
-extern struct crisv32_iopin crisv32_led_net0_red;
-extern struct crisv32_iopin crisv32_led_net1_green;
-extern struct crisv32_iopin crisv32_led_net1_red;
-
-static inline void crisv32_io_set(struct crisv32_iopin *iopin, int val)
-{
- unsigned long flags;
- spin_lock_irqsave(&iopin->port->lock, flags);
-
- if (iopin->port->data) {
- if (val)
- *iopin->port->data |= iopin->bit;
- else
- *iopin->port->data &= ~iopin->bit;
- }
-
- spin_unlock_irqrestore(&iopin->port->lock, flags);
-}
-
-static inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
- enum crisv32_io_dir dir)
-{
- unsigned long flags;
- spin_lock_irqsave(&iopin->port->lock, flags);
-
- if (iopin->port->oe) {
- if (dir == crisv32_io_dir_in)
- *iopin->port->oe &= ~iopin->bit;
- else
- *iopin->port->oe |= iopin->bit;
- }
-
- spin_unlock_irqrestore(&iopin->port->lock, flags);
-}
-
-static inline int crisv32_io_rd(struct crisv32_iopin* iopin)
-{
- return ((*iopin->port->data_in & iopin->bit) ? 1 : 0);
-}
-
-int crisv32_io_get(struct crisv32_iopin* iopin,
- unsigned int port, unsigned int pin);
-int crisv32_io_get_name(struct crisv32_iopin* iopin,
- const char *name);
-
-#define CRIS_LED_OFF 0x00
-#define CRIS_LED_GREEN 0x01
-#define CRIS_LED_RED 0x02
-#define CRIS_LED_ORANGE (CRIS_LED_GREEN | CRIS_LED_RED)
-
-#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
-#define CRIS_LED_NETWORK_GRP0_SET(x) \
- do { \
- CRIS_LED_NETWORK_GRP0_SET_G((x) & CRIS_LED_GREEN); \
- CRIS_LED_NETWORK_GRP0_SET_R((x) & CRIS_LED_RED); \
- } while (0)
-#else
-#define CRIS_LED_NETWORK_GRP0_SET(x) while (0) {}
-#endif
-
-#define CRIS_LED_NETWORK_GRP0_SET_G(x) \
- crisv32_io_set(&crisv32_led_net0_green, !(x));
-
-#define CRIS_LED_NETWORK_GRP0_SET_R(x) \
- crisv32_io_set(&crisv32_led_net0_red, !(x));
-
-#if defined(CONFIG_ETRAX_NBR_LED_GRP_TWO)
-#define CRIS_LED_NETWORK_GRP1_SET(x) \
- do { \
- CRIS_LED_NETWORK_GRP1_SET_G((x) & CRIS_LED_GREEN); \
- CRIS_LED_NETWORK_GRP1_SET_R((x) & CRIS_LED_RED); \
- } while (0)
-#else
-#define CRIS_LED_NETWORK_GRP1_SET(x) while (0) {}
-#endif
-
-#define CRIS_LED_NETWORK_GRP1_SET_G(x) \
- crisv32_io_set(&crisv32_led_net1_green, !(x));
-
-#define CRIS_LED_NETWORK_GRP1_SET_R(x) \
- crisv32_io_set(&crisv32_led_net1_red, !(x));
-
-#define CRIS_LED_ACTIVE_SET(x) \
- do { \
- CRIS_LED_ACTIVE_SET_G((x) & CRIS_LED_GREEN); \
- CRIS_LED_ACTIVE_SET_R((x) & CRIS_LED_RED); \
- } while (0)
-
-#define CRIS_LED_ACTIVE_SET_G(x) \
- crisv32_io_set(&crisv32_led2_green, !(x));
-#define CRIS_LED_ACTIVE_SET_R(x) \
- crisv32_io_set(&crisv32_led2_red, !(x));
-#define CRIS_LED_DISK_WRITE(x) \
- do{\
- crisv32_io_set(&crisv32_led3_green, !(x)); \
- crisv32_io_set(&crisv32_led3_red, !(x)); \
- }while(0)
-#define CRIS_LED_DISK_READ(x) \
- crisv32_io_set(&crisv32_led3_green, !(x));
-
-#endif
diff --git a/arch/cris/include/arch-v32/arch/irq.h b/arch/cris/include/arch-v32/arch/irq.h
index 0c1b4d3..8270a1b 100644
--- a/arch/cris/include/arch-v32/arch/irq.h
+++ b/arch/cris/include/arch-v32/arch/irq.h
@@ -4,7 +4,7 @@
#include <hwregs/intr_vect.h>
/* Number of non-cpu interrupts. */
-#define NR_IRQS NBR_INTR_VECT /* Exceptions + IRQs */
+#define NR_IRQS (NBR_INTR_VECT + 256) /* Exceptions + IRQs */
#define FIRST_IRQ 0x31 /* Exception number for first IRQ */
#define NR_REAL_IRQS (NBR_INTR_VECT - FIRST_IRQ) /* IRQs */
#if NR_REAL_IRQS > 32
diff --git a/arch/cris/include/asm/checksum.h b/arch/cris/include/asm/checksum.h
index 75dcb77d..ea949c6 100644
--- a/arch/cris/include/asm/checksum.h
+++ b/arch/cris/include/asm/checksum.h
@@ -63,9 +63,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
diff --git a/arch/cris/include/asm/dma-mapping.h b/arch/cris/include/asm/dma-mapping.h
index 57f794e..5a37017 100644
--- a/arch/cris/include/asm/dma-mapping.h
+++ b/arch/cris/include/asm/dma-mapping.h
@@ -1,156 +1,20 @@
-/* DMA mapping. Nothing tricky here, just virt_to_phys */
-
#ifndef _ASM_CRIS_DMA_MAPPING_H
#define _ASM_CRIS_DMA_MAPPING_H
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/scatterlist.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
#ifdef CONFIG_PCI
-#include <asm-generic/dma-coherent.h>
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
+extern struct dma_map_ops v32_dma_ops;
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-#else
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- BUG();
- return NULL;
+ return &v32_dma_ops;
}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
+#else
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- BUG();
+ BUG();
+ return NULL;
}
#endif
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- return virt_to_phys(ptr);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
-{
- printk("Map sg\n");
- return nents;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- return page_to_phys(page) + offset;
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s,
- * so we can't guarantee allocations that must be
- * within a tighter range than GFP_DMA..
- */
- if(mask < 0x00ffffff)
- return 0;
-
- return 1;
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
- if(!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
-}
static inline void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
@@ -158,15 +22,4 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{
}
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
-
#endif
diff --git a/arch/cris/include/asm/eshlibld.h b/arch/cris/include/asm/eshlibld.h
index 10ce36c..70aa448 100644
--- a/arch/cris/include/asm/eshlibld.h
+++ b/arch/cris/include/asm/eshlibld.h
@@ -45,8 +45,7 @@
assumed that we want to share code when debugging (exposes more
trouble). */
#ifndef SHARE_LIB_CORE
-# if (defined(__KERNEL__) || !defined(RELOC_DEBUG)) \
- && !defined(CONFIG_SHARE_SHLIB_CORE)
+# if (defined(__KERNEL__) || !defined(RELOC_DEBUG))
# define SHARE_LIB_CORE 0
# else
# define SHARE_LIB_CORE 1
diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h
index 752a3f4..cce8664 100644
--- a/arch/cris/include/asm/io.h
+++ b/arch/cris/include/asm/io.h
@@ -2,7 +2,9 @@
#define _ASM_CRIS_IO_H
#include <asm/page.h> /* for __va, __pa */
+#ifdef CONFIG_ETRAX_ARCH_V10
#include <arch/io.h>
+#endif
#include <asm-generic/iomap.h>
#include <linux/kernel.h>
diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h
index c15b4b4..b1b289d 100644
--- a/arch/cris/include/asm/pci.h
+++ b/arch/cris/include/asm/pci.h
@@ -48,9 +48,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
#endif /* __KERNEL__ */
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
/* generic pci stuff */
#include <asm-generic/pci.h>
diff --git a/arch/cris/include/uapi/asm/etraxgpio.h b/arch/cris/include/uapi/asm/etraxgpio.h
index 461c089..c6e7d57 100644
--- a/arch/cris/include/uapi/asm/etraxgpio.h
+++ b/arch/cris/include/uapi/asm/etraxgpio.h
@@ -11,26 +11,6 @@
* g1-g7 and g25-g31 is both input and outputs but on different pins
* Also note that some bits change pins depending on what interfaces
* are enabled.
- *
- * For ETRAX FS (CONFIG_ETRAXFS):
- * /dev/gpioa minor 0, 8 bit GPIO, each bit can change direction
- * /dev/gpiob minor 1, 18 bit GPIO, each bit can change direction
- * /dev/gpioc minor 3, 18 bit GPIO, each bit can change direction
- * /dev/gpiod minor 4, 18 bit GPIO, each bit can change direction
- * /dev/gpioe minor 5, 18 bit GPIO, each bit can change direction
- * /dev/leds minor 2, Access to leds depending on kernelconfig
- *
- * For ARTPEC-3 (CONFIG_CRIS_MACH_ARTPEC3):
- * /dev/gpioa minor 0, 32 bit GPIO, each bit can change direction
- * /dev/gpiob minor 1, 32 bit GPIO, each bit can change direction
- * /dev/gpioc minor 3, 16 bit GPIO, each bit can change direction
- * /dev/gpiod minor 4, 32 bit GPIO, input only
- * /dev/leds minor 2, Access to leds depending on kernelconfig
- * /dev/pwm0 minor 16, PWM channel 0 on PA30
- * /dev/pwm1 minor 17, PWM channel 1 on PA31
- * /dev/pwm2 minor 18, PWM channel 2 on PB26
- * /dev/ppwm minor 19, PPWM channel
- *
*/
#ifndef _ASM_ETRAXGPIO_H
#define _ASM_ETRAXGPIO_H
@@ -40,52 +20,12 @@
#define ETRAXGPIO_IOCTYPE 43
/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
-#ifdef CONFIG_ETRAX_ARCH_V10
#define GPIO_MINOR_A 0
#define GPIO_MINOR_B 1
#define GPIO_MINOR_LEDS 2
#define GPIO_MINOR_G 3
#define GPIO_MINOR_LAST 3
#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST
-#endif
-
-#ifdef CONFIG_ETRAXFS
-#define GPIO_MINOR_A 0
-#define GPIO_MINOR_B 1
-#define GPIO_MINOR_LEDS 2
-#define GPIO_MINOR_C 3
-#define GPIO_MINOR_D 4
-#define GPIO_MINOR_E 5
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-#define GPIO_MINOR_V 6
-#define GPIO_MINOR_LAST 6
-#else
-#define GPIO_MINOR_LAST 5
-#endif
-#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST
-#endif
-
-#ifdef CONFIG_CRIS_MACH_ARTPEC3
-#define GPIO_MINOR_A 0
-#define GPIO_MINOR_B 1
-#define GPIO_MINOR_LEDS 2
-#define GPIO_MINOR_C 3
-#define GPIO_MINOR_D 4
-#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
-#define GPIO_MINOR_V 6
-#define GPIO_MINOR_LAST 6
-#else
-#define GPIO_MINOR_LAST 4
-#endif
-#define GPIO_MINOR_FIRST_PWM 16
-#define GPIO_MINOR_PWM0 (GPIO_MINOR_FIRST_PWM+0)
-#define GPIO_MINOR_PWM1 (GPIO_MINOR_FIRST_PWM+1)
-#define GPIO_MINOR_PWM2 (GPIO_MINOR_FIRST_PWM+2)
-#define GPIO_MINOR_PPWM (GPIO_MINOR_FIRST_PWM+3)
-#define GPIO_MINOR_LAST_PWM GPIO_MINOR_PPWM
-#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST_PWM
-#endif
-
/* supported ioctl _IOC_NR's */
@@ -139,101 +79,4 @@
#define IO_SETGET_OUTPUT 0x13 /* bits set in *arg is set to output, */
/* *arg updated with current output pins. */
-/* The following ioctl's are applicable to the PWM channels only */
-
-#define IO_PWM_SET_MODE 0x20
-
-enum io_pwm_mode {
- PWM_OFF = 0, /* disabled, deallocated */
- PWM_STANDARD = 1, /* 390 kHz, duty cycle 0..255/256 */
- PWM_FAST = 2, /* variable freq, w/ 10ns active pulse len */
- PWM_VARFREQ = 3, /* individually configurable high/low periods */
- PWM_SOFT = 4 /* software generated */
-};
-
-struct io_pwm_set_mode {
- enum io_pwm_mode mode;
-};
-
-/* Only for mode PWM_VARFREQ. Period lo/high set in increments of 10ns
- * from 10ns (value = 0) to 81920ns (value = 8191)
- * (Resulting frequencies range from 50 MHz (10ns + 10ns) down to
- * 6.1 kHz (81920ns + 81920ns) at 50% duty cycle, to 12.2 kHz at min/max duty
- * cycle (81920 + 10ns or 10ns + 81920ns, respectively).)
- */
-#define IO_PWM_SET_PERIOD 0x21
-
-struct io_pwm_set_period {
- unsigned int lo; /* 0..8191 */
- unsigned int hi; /* 0..8191 */
-};
-
-/* Only for modes PWM_STANDARD and PWM_FAST.
- * For PWM_STANDARD, set duty cycle of 390 kHz PWM output signal, from
- * 0 (value = 0) to 255/256 (value = 255).
- * For PWM_FAST, set duty cycle of PWM output signal from
- * 0% (value = 0) to 100% (value = 255). Output signal in this mode
- * is a 10ns pulse surrounded by a high or low level depending on duty
- * cycle (except for 0% and 100% which result in a constant output).
- * Resulting output frequency varies from 50 MHz at 50% duty cycle,
- * down to 390 kHz at min/max duty cycle.
- */
-#define IO_PWM_SET_DUTY 0x22
-
-struct io_pwm_set_duty {
- int duty; /* 0..255 */
-};
-
-/* Returns information about the latest PWM pulse.
- * lo: Length of the latest low period, in units of 10ns.
- * hi: Length of the latest high period, in units of 10ns.
- * cnt: Time since last detected edge, in units of 10ns.
- *
- * The input source to PWM is decied by IO_PWM_SET_INPUT_SRC.
- *
- * NOTE: All PWM devices is connected to the same input source.
- */
-#define IO_PWM_GET_PERIOD 0x23
-
-struct io_pwm_get_period {
- unsigned int lo;
- unsigned int hi;
- unsigned int cnt;
-};
-
-/* Sets the input source for the PWM input. For the src value see the
- * register description for gio:rw_pwm_in_cfg.
- *
- * NOTE: All PWM devices is connected to the same input source.
- */
-#define IO_PWM_SET_INPUT_SRC 0x24
-struct io_pwm_set_input_src {
- unsigned int src; /* 0..7 */
-};
-
-/* Sets the duty cycles in steps of 1/256, 0 = 0%, 255 = 100% duty cycle */
-#define IO_PPWM_SET_DUTY 0x25
-
-struct io_ppwm_set_duty {
- int duty; /* 0..255 */
-};
-
-/* Configuraton struct for the IO_PWMCLK_SET_CONFIG ioctl to configure
- * PWM capable gpio pins:
- */
-#define IO_PWMCLK_SETGET_CONFIG 0x26
-struct gpio_pwmclk_conf {
- unsigned int gpiopin; /* The pin number based on the opened device */
- unsigned int baseclk; /* The base clock to use, or sw will select one close*/
- unsigned int low; /* The number of low periods of the baseclk */
- unsigned int high; /* The number of high periods of the baseclk */
-};
-
-/* Examples:
- * To get a symmetric 12 MHz clock without knowing anything about the hardware:
- * baseclk = 12000000, low = 0, high = 0
- * To just get info of current setting:
- * baseclk = 0, low = 0, high = 0, the values will be updated by driver.
- */
-
#endif
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
index e704f81..31b4bd2 100644
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -18,7 +18,6 @@
#include <asm/pgtable.h>
#include <asm/fasttimer.h>
-extern unsigned long get_cmos_time(void);
extern void __Udiv(void);
extern void __Umod(void);
extern void __Div(void);
@@ -30,7 +29,6 @@ extern void __negdi2(void);
extern void iounmap(volatile void * __iomem);
/* Platform dependent support */
-EXPORT_SYMBOL(get_cmos_time);
EXPORT_SYMBOL(loops_per_usec);
/* Math functions */
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 7780d37..2dda6da 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -39,31 +39,6 @@
extern unsigned long loops_per_jiffy; /* init/main.c */
unsigned long loops_per_usec;
-int set_rtc_mmss(unsigned long nowtime)
-{
- D(printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime));
- return 0;
-}
-
-/* grab the time from the RTC chip */
-unsigned long get_cmos_time(void)
-{
- return 0;
-}
-
-
-int update_persistent_clock(struct timespec now)
-{
- return set_rtc_mmss(now.tv_sec);
-}
-
-void read_persistent_clock(struct timespec *ts)
-{
- ts->tv_sec = 0;
- ts->tv_nsec = 0;
-}
-
-
extern void cris_profile_sample(struct pt_regs* regs);
void
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
index a68b983..7552c25 100644
--- a/arch/cris/kernel/vmlinux.lds.S
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -40,6 +40,7 @@ SECTIONS
_stext = .;
__stext = .;
.text : {
+ HEAD_TEXT
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 34aa193..eefd9a4 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -10,10 +10,12 @@ config FRV
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_WANT_IPC_PARSE_VERSION
select OLD_SIGSUSPEND3
select OLD_SIGACTION
select HAVE_DEBUG_STACKOVERFLOW
+ select ARCH_NO_COHERENT_DMA_MMAP
config ZONE_DMA
bool
diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
index 0da689d..64f02d4 100644
--- a/arch/frv/include/asm/atomic.h
+++ b/arch/frv/include/asm/atomic.h
@@ -32,8 +32,8 @@
*/
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = (i))
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
static inline int atomic_inc_return(atomic_t *v)
{
diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h
index 269da09..b77388c 100644
--- a/arch/frv/include/asm/checksum.h
+++ b/arch/frv/include/asm/checksum.h
@@ -105,8 +105,8 @@ static inline __sum16 csum_fold(__wsum sum)
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
asm(" addcc %1,%0,%0,icc0 \n"
" addxcc %2,%0,%0,icc0 \n"
@@ -120,8 +120,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
}
static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
@@ -135,7 +135,7 @@ extern __sum16 ip_compute_csum(const void *buff, int len);
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
unsigned long tmp, tmp2;
diff --git a/arch/frv/include/asm/cmpxchg.h b/arch/frv/include/asm/cmpxchg.h
index 5b04dd0..a899765 100644
--- a/arch/frv/include/asm/cmpxchg.h
+++ b/arch/frv/include/asm/cmpxchg.h
@@ -69,8 +69,6 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
#endif
-#define tas(ptr) (xchg((ptr), 1))
-
/*****************************************************************************/
/*
* compare and conditionally exchange value with memory
diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h
index 2840adc..9a82bfa 100644
--- a/arch/frv/include/asm/dma-mapping.h
+++ b/arch/frv/include/asm/dma-mapping.h
@@ -1,128 +1,17 @@
#ifndef _ASM_DMA_MAPPING_H
#define _ASM_DMA_MAPPING_H
-#include <linux/device.h>
-#include <linux/scatterlist.h>
#include <asm/cache.h>
#include <asm/cacheflush.h>
-#include <asm/io.h>
-
-/*
- * See Documentation/DMA-API.txt for the description of how the
- * following DMA API should work.
- */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
-void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
-
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction);
-
-static inline
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
-
-static inline
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-extern
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction);
-
-static inline
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-
-static inline
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- flush_write_buffers();
-}
-
-static inline
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- flush_write_buffers();
-}
-
-static inline
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- flush_write_buffers();
-}
-
-static inline
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-static inline
-int dma_supported(struct device *dev, u64 mask)
-{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s,
- * so we can't guarantee allocations that must be
- * within a tighter range than GFP_DMA..
- */
- if (mask < 0x00ffffff)
- return 0;
-
- return 1;
-}
+extern struct dma_map_ops frv_dma_ops;
-static inline
-int dma_set_mask(struct device *dev, u64 mask)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
+ return &frv_dma_ops;
}
static inline
@@ -132,19 +21,4 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
flush_write_buffers();
}
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
- struct vm_area_struct *vma, void *cpu_addr,
- dma_addr_t dma_addr, size_t size)
-{
- return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size)
-{
- return -EINVAL;
-}
-
#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h
index b3adc93..1f58938 100644
--- a/arch/frv/include/asm/highmem.h
+++ b/arch/frv/include/asm/highmem.h
@@ -62,8 +62,6 @@ extern void kunmap_high(struct page *page);
extern void *kmap(struct page *page);
extern void kunmap(struct page *page);
-extern struct page *kmap_atomic_to_page(void *ptr);
-
#endif /* !__ASSEMBLY__ */
/*
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index 70dfbea..8062fc7 100644
--- a/arch/frv/include/asm/io.h
+++ b/arch/frv/include/asm/io.h
@@ -43,9 +43,20 @@ static inline unsigned long _swapl(unsigned long v)
//#define __iormb() asm volatile("membar")
//#define __iowmb() asm volatile("membar")
-#define __raw_readb __builtin_read8
-#define __raw_readw __builtin_read16
-#define __raw_readl __builtin_read32
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+ return __builtin_read8((volatile void __iomem *)addr);
+}
+
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+ return __builtin_read16((volatile void __iomem *)addr);
+}
+
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+ return __builtin_read32((volatile void __iomem *)addr);
+}
#define __raw_writeb(datum, addr) __builtin_write8(addr, datum)
#define __raw_writew(datum, addr) __builtin_write16(addr, datum)
diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h
index 8c97068..688d807 100644
--- a/arch/frv/include/asm/page.h
+++ b/arch/frv/include/asm/page.h
@@ -34,7 +34,7 @@ typedef struct page *pgtable_t;
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
+#define __pmd(x) ((pmd_t) { { (x) } } )
#define __pud(x) ((pud_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h
index e43d22c..809cfc6 100644
--- a/arch/frv/include/asm/pci.h
+++ b/arch/frv/include/asm/pci.h
@@ -15,7 +15,6 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
-#include <asm-generic/pci-dma-compat.h>
#include <asm-generic/pci.h>
struct pci_dev;
@@ -32,12 +31,6 @@ extern void consistent_sync_page(struct page *page, unsigned long offset,
size_t size, int direction);
#endif
-extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
- dma_addr_t *dma_handle);
-
-extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
/* Return the index of the PCI controller for device PDEV. */
#define pci_controller_num(PDEV) (0)
diff --git a/arch/frv/include/asm/serial.h b/arch/frv/include/asm/serial.h
index dbb8259..bce0d0d 100644
--- a/arch/frv/include/asm/serial.h
+++ b/arch/frv/include/asm/serial.h
@@ -13,6 +13,6 @@
*/
#define BASE_BAUD 0
-#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
+#define STD_COM_FLAGS UPF_BOOT_AUTOCONF
#define SERIAL_PORT_DFNS
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h
index 4823ad1..afbc98f0 100644
--- a/arch/frv/include/uapi/asm/socket.h
+++ b/arch/frv/include/uapi/asm/socket.h
@@ -85,5 +85,10 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 8eeea0d..082be49 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -34,7 +34,8 @@ struct dma_alloc_record {
static DEFINE_SPINLOCK(dma_alloc_lock);
static LIST_HEAD(dma_alloc_list);
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+static void *frv_dma_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, struct dma_attrs *attrs)
{
struct dma_alloc_record *new;
struct list_head *this = &dma_alloc_list;
@@ -84,9 +85,8 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
return NULL;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void frv_dma_free(struct device *hwdev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
struct dma_alloc_record *rec;
unsigned long flags;
@@ -105,22 +105,9 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
BUG();
}
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-
- frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
-
- return virt_to_bus(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction direction)
+static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -135,14 +122,49 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
+static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
BUG_ON(direction == DMA_NONE);
flush_dcache_page(page);
return (dma_addr_t) page_to_phys(page) + offset;
}
-EXPORT_SYMBOL(dma_map_page);
+static void frv_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+static void frv_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+
+static int frv_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+ return 1;
+}
+
+struct dma_map_ops frv_dma_ops = {
+ .alloc = frv_dma_alloc,
+ .free = frv_dma_free,
+ .map_page = frv_dma_map_page,
+ .map_sg = frv_dma_map_sg,
+ .sync_single_for_device = frv_dma_sync_single_for_device,
+ .sync_sg_for_device = frv_dma_sync_sg_for_device,
+ .dma_supported = frv_dma_supported,
+};
+EXPORT_SYMBOL(frv_dma_ops);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 4d1f01d..316b7b6 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -18,7 +18,9 @@
#include <linux/scatterlist.h>
#include <asm/io.h>
-void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
+static void *frv_dma_alloc(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp,
+ struct dma_attrs *attrs)
{
void *ret;
@@ -29,29 +31,15 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void frv_dma_free(struct device *hwdev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
consistent_free(vaddr);
}
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-
- frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
-
- return virt_to_bus(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction direction)
+static int frv_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
unsigned long dampr2;
void *vaddr;
@@ -79,14 +67,48 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
+static dma_addr_t frv_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
- BUG_ON(direction == DMA_NONE);
flush_dcache_page(page);
return (dma_addr_t) page_to_phys(page) + offset;
}
-EXPORT_SYMBOL(dma_map_page);
+static void frv_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+static void frv_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+
+static int frv_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+ return 1;
+}
+
+struct dma_map_ops frv_dma_ops = {
+ .alloc = frv_dma_alloc,
+ .free = frv_dma_free,
+ .map_page = frv_dma_map_page,
+ .map_sg = frv_dma_map_sg,
+ .sync_single_for_device = frv_dma_sync_single_for_device,
+ .sync_sg_for_device = frv_dma_sync_sg_for_device,
+ .dma_supported = frv_dma_supported,
+};
+EXPORT_SYMBOL(frv_dma_ops);
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 785344b..45750fb 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -32,11 +32,6 @@ void kunmap(struct page *page)
EXPORT_SYMBOL(kunmap);
-struct page *kmap_atomic_to_page(void *ptr)
-{
- return virt_to_page(ptr);
-}
-
void *kmap_atomic(struct page *page)
{
unsigned long paddr;
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index db58916..986ea84 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -15,7 +15,11 @@ config H8300
select OF_IRQ
select OF_EARLY_FLATTREE
select HAVE_MEMBLOCK
- select HAVE_DMA_ATTRS
+ select CLKSRC_OF
+ select H8300_TMR8
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_LZO
+ select HAVE_ARCH_KGDB
config RWSEM_GENERIC_SPINLOCK
def_bool y
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
index 0d2d96e..e1c02ca 100644
--- a/arch/h8300/Makefile
+++ b/arch/h8300/Makefile
@@ -22,7 +22,9 @@ KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
KBUILD_AFLAGS += $(aflags-y)
LDFLAGS += $(ldflags-y)
+ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := h8300-unknown-linux-
+endif
core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
ifneq '$(CONFIG_H8300_BUILTIN_DTB)' '""'
diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile
index 87d03b7..7643633 100644
--- a/arch/h8300/boot/compressed/Makefile
+++ b/arch/h8300/boot/compressed/Makefile
@@ -14,11 +14,12 @@ OBJECTS = $(obj)/head.o $(obj)/misc.o
# in order to suppress error message.
#
CONFIG_MEMORY_START ?= 0x00400000
-CONFIG_BOOT_LINK_OFFSET ?= 0x00140000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00280000
IMAGE_OFFSET := $(shell printf "0x%08x" $$(($(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET))))
LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds
+LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup -T $(obj)/vmlinux.lds \
+ --defsym output=$(CONFIG_MEMORY_START)
$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
$(call if_changed,ld)
@@ -27,11 +28,16 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
- $(call if_changed,gzip)
+suffix-$(CONFIG_KERNEL_GZIP) := gzip
+suffix-$(CONFIG_KERNEL_LZO) := lzo
+
+$(obj)/vmlinux.bin.$(suffix-y): $(obj)/vmlinux.bin FORCE
+ $(call if_changed,$(suffix-y))
LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300-linux -T
OBJCOPYFLAGS := -O binary
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
$(call if_changed,ld)
+
+CFLAGS_misc.o = -O0
diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S
index 74c0d8cc..0436350 100644
--- a/arch/h8300/boot/compressed/head.S
+++ b/arch/h8300/boot/compressed/head.S
@@ -9,8 +9,8 @@
.section .text..startup,"ax"
.global startup
startup:
+ mov.l #startup, sp
mov.l er0, er4
- mov.l er0, sp
mov.l #__sbss, er0
mov.l #__ebss, er1
sub.l er0, er1
@@ -24,7 +24,7 @@ startup:
bne 1b
jsr @decompress_kernel
mov.l er4, er0
- jmp @0x400000
+ jmp @output
.align 9
fake_headers_as_bzImage:
diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c
index c4f2cfc..9f64fe8 100644
--- a/arch/h8300/boot/compressed/misc.c
+++ b/arch/h8300/boot/compressed/misc.c
@@ -28,11 +28,17 @@ static unsigned long free_mem_end_ptr;
extern char input_data[];
extern int input_len;
-static unsigned char *output;
+extern char output[];
#define HEAP_SIZE 0x10000
+#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
void *memset(void *s, int c, size_t n)
{
@@ -56,15 +62,10 @@ void *memcpy(void *dest, const void *src, size_t n)
static void error(char *x)
{
-
while (1)
; /* Halt */
}
-#define STACK_SIZE (4096)
-long user_stack[STACK_SIZE];
-long *stack_start = &user_stack[STACK_SIZE];
-
void decompress_kernel(void)
{
free_mem_ptr = (unsigned long)&_end;
diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds
index a0a3a0e..ad848a7 100644
--- a/arch/h8300/boot/compressed/vmlinux.lds
+++ b/arch/h8300/boot/compressed/vmlinux.lds
@@ -13,20 +13,22 @@ SECTIONS
{
*(.rodata)
}
+ . = ALIGN(0x4) ;
.data :
{
+ . = ALIGN(0x4) ;
__sdata = . ;
___data_start = . ;
*(.data.*)
}
+ . = ALIGN(0x4) ;
.bss :
{
- . = ALIGN(0x4) ;
__sbss = . ;
*(.bss*)
. = ALIGN(0x4) ;
__ebss = . ;
- __end = . ;
}
+ _end = . ;
}
diff --git a/arch/h8300/boot/dts/Makefile b/arch/h8300/boot/dts/Makefile
index 0abaf1a..6c08467 100644
--- a/arch/h8300/boot/dts/Makefile
+++ b/arch/h8300/boot/dts/Makefile
@@ -8,5 +8,8 @@ dtb-$(CONFIG_H8300H_SIM) := h8300h_sim.dtb
dtb-$(CONFIG_H8S_SIM) := h8s_sim.dtb
dtb-$(CONFIG_H8S_EDOSK2674) := edosk2674.dtb
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+
always := $(dtb-y)
clean-files := *.dtb.S *.dtb
diff --git a/arch/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts
index dfb5c10..4ce9fa8 100644
--- a/arch/h8300/boot/dts/edosk2674.dts
+++ b/arch/h8300/boot/dts/edosk2674.dts
@@ -7,7 +7,7 @@
chosen {
bootargs = "console=ttySC2,38400";
- stdout-path = <&sci2>;
+ stdout-path = &sci2;
};
aliases {
serial0 = &sci0;
@@ -25,13 +25,13 @@
compatible = "renesas,h8s2678-pll-clock";
clocks = <&xclk>;
#clock-cells = <0>;
- reg = <0xfee03b 2>, <0xfee045 2>;
+ reg = <0xffff3b 1>, <0xffff45 1>;
};
core_clk: core_clk {
compatible = "renesas,h8300-div-clock";
clocks = <&pllclk>;
#clock-cells = <0>;
- reg = <0xfee03b 2>;
+ reg = <0xffff3b 1>;
renesas,width = <3>;
};
fclk: fclk {
diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h
index 702ee53..4435a44 100644
--- a/arch/h8300/include/asm/atomic.h
+++ b/arch/h8300/include/asm/atomic.h
@@ -11,8 +11,8 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
#include <linux/kernel.h>
diff --git a/arch/h8300/include/asm/dma-mapping.h b/arch/h8300/include/asm/dma-mapping.h
index d9b5b80..7ac7fad 100644
--- a/arch/h8300/include/asm/dma-mapping.h
+++ b/arch/h8300/include/asm/dma-mapping.h
@@ -8,6 +8,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &h8300_dma_map_ops;
}
-#include <asm-generic/dma-mapping-common.h>
-
#endif
diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h
index 1d09b2f..2e221c5 100644
--- a/arch/h8300/include/asm/io.h
+++ b/arch/h8300/include/asm/io.h
@@ -3,55 +3,62 @@
#ifdef __KERNEL__
-#include <asm-generic/io.h>
-
/* H8/300 internal I/O functions */
-static inline unsigned char ctrl_inb(unsigned long addr)
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
{
- return *(volatile unsigned char *)addr;
+ return *(volatile u8 *)addr;
}
-static inline unsigned short ctrl_inw(unsigned long addr)
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
{
- return *(volatile unsigned short *)addr;
+ return *(volatile u16 *)addr;
}
-static inline unsigned long ctrl_inl(unsigned long addr)
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
{
- return *(volatile unsigned long *)addr;
+ return *(volatile u32 *)addr;
}
-static inline void ctrl_outb(unsigned char b, unsigned long addr)
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 b, const volatile void __iomem *addr)
{
- *(volatile unsigned char *)addr = b;
+ *(volatile u8 *)addr = b;
}
-static inline void ctrl_outw(unsigned short b, unsigned long addr)
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 b, const volatile void __iomem *addr)
{
- *(volatile unsigned short *)addr = b;
+ *(volatile u16 *)addr = b;
}
-static inline void ctrl_outl(unsigned long b, unsigned long addr)
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 b, const volatile void __iomem *addr)
{
- *(volatile unsigned long *)addr = b;
+ *(volatile u32 *)addr = b;
}
-static inline void ctrl_bclr(int b, unsigned long addr)
+static inline void ctrl_bclr(int b, void __iomem *addr)
{
if (__builtin_constant_p(b))
- __asm__("bclr %1,%0" : : "WU"(addr), "i"(b));
+ __asm__("bclr %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
else
- __asm__("bclr %w1,%0" : : "WU"(addr), "r"(b));
+ __asm__("bclr %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
}
-static inline void ctrl_bset(int b, unsigned long addr)
+static inline void ctrl_bset(int b, void __iomem *addr)
{
if (__builtin_constant_p(b))
- __asm__("bset %1,%0" : : "WU"(addr), "i"(b));
+ __asm__("bset %1,%0" : "+WU"(*(u8 *)addr): "i"(b));
else
- __asm__("bset %w1,%0" : : "WU"(addr), "r"(b));
+ __asm__("bset %w1,%0" : "+WU"(*(u8 *)addr): "r"(b));
}
+#include <asm-generic/io.h>
+
#endif /* __KERNEL__ */
#endif /* _H8300_IO_H */
diff --git a/arch/h8300/include/asm/kgdb.h b/arch/h8300/include/asm/kgdb.h
new file mode 100644
index 0000000..726ff8f
--- /dev/null
+++ b/arch/h8300/include/asm/kgdb.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * 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_H8300_KGDB_H
+#define _ASM_H8300_KGDB_H
+
+#define CACHE_FLUSH_IS_SAFE 1
+#define BUFMAX 2048
+
+enum regnames {
+ GDB_ER0, GDB_ER1, GDB_ER2, GDB_ER3,
+ GDB_ER4, GDB_ER5, GDB_ER6, GDB_SP,
+ GDB_CCR, GDB_PC,
+ GDB_CYCLLE,
+#if defined(CONFIG_CPU_H8S)
+ GDB_EXR,
+#endif
+ GDB_TICK, GDB_INST,
+#if defined(CONFIG_CPU_H8S)
+ GDB_MACH, GDB_MACL,
+#endif
+ /* do not change the last entry or anything below! */
+ GDB_NUMREGBYTES, /* number of registers */
+};
+
+#define GDB_SIZEOF_REG sizeof(u32)
+#if defined(CONFIG_CPU_H8300H)
+#define DBG_MAX_REG_NUM (13)
+#elif defined(CONFIG_CPU_H8S)
+#define DBG_MAX_REG_NUM (14)
+#endif
+#define NUMREGBYTES (DBG_MAX_REG_NUM * GDB_SIZEOF_REG)
+
+#define BREAK_INSTR_SIZE 2
+static inline void arch_kgdb_breakpoint(void)
+{
+ __asm__ __volatile__("trapa #2");
+}
+
+#endif /* _ASM_H8300_KGDB_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index 544c307..b408fe6 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -13,6 +13,12 @@
#ifdef __KERNEL__
+/*
+ * Size of kernel stack for each process. This must be a power of 2...
+ */
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE 8192 /* 2 pages */
+
#ifndef __ASSEMBLY__
/*
@@ -46,14 +52,6 @@ struct thread_info {
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
-
-/*
- * Size of kernel stack for each process. This must be a power of 2...
- */
-#define THREAD_SIZE_ORDER 1
-#define THREAD_SIZE 8192 /* 2 pages */
-
-
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
diff --git a/arch/h8300/include/asm/traps.h b/arch/h8300/include/asm/traps.h
index aa34e75..15e70113 100644
--- a/arch/h8300/include/asm/traps.h
+++ b/arch/h8300/include/asm/traps.h
@@ -36,6 +36,6 @@ extern unsigned long *_interrupt_redirect_table;
extern char _start, _etext;
#define check_kernel_text(addr) \
((addr >= (unsigned long)(&_start)) && \
- (addr < (unsigned long)(&_etext)))
+ (addr < (unsigned long)(&_etext)) && !(addr & 1))
#endif /* _H8300_TRAPS_H */
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
index 5bc33f2..253f8e3 100644
--- a/arch/h8300/kernel/Makefile
+++ b/arch/h8300/kernel/Makefile
@@ -17,3 +17,5 @@ obj-$(CONFIG_H8S_SIM) += sim-console.o
obj-$(CONFIG_CPU_H8300H) += ptrace_h.o
obj-$(CONFIG_CPU_H8S) += ptrace_s.o
+
+obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S
index 797dfa8..4f67d4b 100644
--- a/arch/h8300/kernel/entry.S
+++ b/arch/h8300/kernel/entry.S
@@ -188,7 +188,11 @@ _interrupt_redirect_table:
jsr @_interrupt_entry /* NMI */
jmp @_system_call /* TRAPA #0 (System call) */
.long 0
+#if defined(CONFIG_KGDB)
+ jmp @_kgdb_trap
+#else
.long 0
+#endif
jmp @_trace_break /* TRAPA #3 (breakpoint) */
.rept INTERRUPTS-12
jsr @_interrupt_entry
@@ -242,6 +246,7 @@ _system_call:
/* save top of frame */
mov.l sp,er0
jsr @set_esp0
+ andc #0x3f,ccr
mov.l sp,er2
and.w #0xe000,r2
mov.l @(TI_FLAGS:16,er2),er2
@@ -405,6 +410,20 @@ _nmi:
mov.l @sp+, er0
jmp @_interrupt_entry
+#if defined(CONFIG_KGDB)
+_kgdb_trap:
+ subs #4,sp
+ SAVE_ALL
+ mov.l sp,er0
+ add.l #LRET,er0
+ mov.l er0,@(LSP,sp)
+ jsr @set_esp0
+ mov.l sp,er0
+ subs #4,er0
+ jsr @h8300_kgdb_trap
+ jmp @ret_from_exception
+#endif
+
.section .bss
_sw_ksp:
.space 4
diff --git a/arch/h8300/kernel/kgdb.c b/arch/h8300/kernel/kgdb.c
new file mode 100644
index 0000000..602e478
--- /dev/null
+++ b/arch/h8300/kernel/kgdb.c
@@ -0,0 +1,135 @@
+/*
+ * H8/300 KGDB support
+ *
+ * Copyright (C) 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * 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/ptrace.h>
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/io.h>
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
+ { "er0", GDB_SIZEOF_REG, offsetof(struct pt_regs, er0) },
+ { "er1", GDB_SIZEOF_REG, offsetof(struct pt_regs, er1) },
+ { "er2", GDB_SIZEOF_REG, offsetof(struct pt_regs, er2) },
+ { "er3", GDB_SIZEOF_REG, offsetof(struct pt_regs, er3) },
+ { "er4", GDB_SIZEOF_REG, offsetof(struct pt_regs, er4) },
+ { "er5", GDB_SIZEOF_REG, offsetof(struct pt_regs, er5) },
+ { "er6", GDB_SIZEOF_REG, offsetof(struct pt_regs, er6) },
+ { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
+ { "ccr", GDB_SIZEOF_REG, offsetof(struct pt_regs, ccr) },
+ { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, pc) },
+ { "cycles", GDB_SIZEOF_REG, -1 },
+#if defined(CONFIG_CPU_H8S)
+ { "exr", GDB_SIZEOF_REG, offsetof(struct pt_regs, exr) },
+#endif
+ { "tick", GDB_SIZEOF_REG, -1 },
+ { "inst", GDB_SIZEOF_REG, -1 },
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ switch (regno) {
+ case GDB_CCR:
+#if defined(CONFIG_CPU_H8S)
+ case GDB_EXR:
+#endif
+ *(u32 *)mem = *(u16 *)((void *)regs +
+ dbg_reg_def[regno].offset);
+ break;
+ default:
+ if (dbg_reg_def[regno].offset >= 0)
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ else
+ memset(mem, 0, dbg_reg_def[regno].size);
+ break;
+ }
+ 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;
+
+ switch (regno) {
+ case GDB_CCR:
+#if defined(CONFIG_CPU_H8S)
+ case GDB_EXR:
+#endif
+ *(u16 *)((void *)regs +
+ dbg_reg_def[regno].offset) = *(u32 *)mem;
+ break;
+ default:
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+ }
+ return 0;
+}
+
+asmlinkage void h8300_kgdb_trap(struct pt_regs *regs)
+{
+ regs->pc &= 0x00ffffff;
+ if (kgdb_handle_exception(10, SIGTRAP, 0, regs))
+ return;
+ if (*(u16 *)(regs->pc) == *(u16 *)&arch_kgdb_ops.gdb_bpt_instr)
+ regs->pc += BREAK_INSTR_SIZE;
+ regs->pc |= regs->ccr << 24;
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+ memset((char *)gdb_regs, 0, NUMREGBYTES);
+ gdb_regs[GDB_SP] = p->thread.ksp;
+ gdb_regs[GDB_PC] = KSTK_EIP(p);
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->pc = pc;
+}
+
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+ char *remcom_in_buffer, char *remcom_out_buffer,
+ struct pt_regs *regs)
+{
+ char *ptr;
+ unsigned long addr;
+
+ switch (remcom_in_buffer[0]) {
+ case 's':
+ case 'c':
+ /* handle the optional parameters */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ regs->pc = addr;
+
+ return 0;
+ }
+
+ return -1; /* this means that we do not want to exit from the handler */
+}
+
+int kgdb_arch_init(void)
+{
+ return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+ /* Nothing to do */
+}
+
+const struct kgdb_arch arch_kgdb_ops = {
+ /* Breakpoint instruction: trapa #2 */
+ .gdb_bpt_instr = { 0x57, 0x20 },
+};
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
index 0fd1fe6..e4985df 100644
--- a/arch/h8300/kernel/setup.c
+++ b/arch/h8300/kernel/setup.c
@@ -29,6 +29,7 @@
#include <linux/clk-provider.h>
#include <linux/memblock.h>
#include <linux/screen_info.h>
+#include <linux/clocksource.h>
#include <asm/setup.h>
#include <asm/irq.h>
@@ -206,14 +207,14 @@ device_initcall(device_probe);
#define get_wait(base, addr) ({ \
int baddr; \
baddr = ((addr) / 0x200000 * 2); \
- w *= (ctrl_inw((unsigned long)(base) + 2) & (3 << baddr)) + 1; \
+ w *= (readw((base) + 2) & (3 << baddr)) + 1; \
})
#endif
#if defined(CONFIG_CPU_H8S)
#define get_wait(base, addr) ({ \
int baddr; \
baddr = ((addr) / 0x200000 * 16); \
- w *= (ctrl_inl((unsigned long)(base) + 2) & (7 << baddr)) + 1; \
+ w *= (readl((base) + 2) & (7 << baddr)) + 1; \
})
#endif
@@ -227,8 +228,8 @@ static __init int access_timing(void)
bsc = of_find_compatible_node(NULL, NULL, "renesas,h8300-bsc");
base = of_iomap(bsc, 0);
- w = (ctrl_inb((unsigned long)base + 0) & bit)?2:1;
- if (ctrl_inb((unsigned long)base + 1) & bit)
+ w = (readb(base + 0) & bit)?2:1;
+ if (readb(base + 1) & bit)
w *= get_wait(base, addr);
else
w *= 2;
@@ -252,4 +253,5 @@ void __init calibrate_delay(void)
void __init time_init(void)
{
of_clk_init(NULL);
+ clocksource_probe();
}
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 380fffd..ad1f81f 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -95,7 +95,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
regs->ccr |= ccr;
regs->orig_er0 = -1; /* disable syscall checks */
err |= __get_user(usp, &usc->sc_usp);
- wrusp(usp);
+ regs->sp = usp;
err |= __get_user(er0, &usc->sc_er0);
*pd0 = er0;
@@ -180,7 +180,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT;
/* Set up to return from userspace. */
- ret = frame->retcode;
+ ret = (unsigned char *)&frame->retcode;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
else {
@@ -196,8 +196,8 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT;
/* Set up registers for signal handler */
- wrusp((unsigned long) frame);
- regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
+ regs->sp = (unsigned long)frame;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
regs->er0 = ksig->sig;
regs->er1 = (unsigned long)&(frame->info);
regs->er2 = (unsigned long)&frame->uc;
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index 1b2d7cd..044a361 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -125,17 +125,18 @@ void show_stack(struct task_struct *task, unsigned long *esp)
pr_info("Stack from %08lx:", (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) {
- if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
+ if (((unsigned long)stack & (THREAD_SIZE - 1)) >=
+ THREAD_SIZE-4)
break;
if (i % 8 == 0)
- pr_info("\n ");
- pr_info(" %08lx", *stack++);
+ pr_info(" ");
+ pr_cont(" %08lx", *stack++);
}
- pr_info("\nCall Trace:");
+ pr_info("\nCall Trace:\n");
i = 0;
stack = esp;
- while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) {
+ while (((unsigned long)stack & (THREAD_SIZE - 1)) < THREAD_SIZE-4) {
addr = *stack++;
/*
* If the address is either in the text segment of the
@@ -147,15 +148,10 @@ void show_stack(struct task_struct *task, unsigned long *esp)
*/
if (check_kernel_text(addr)) {
if (i % 4 == 0)
- pr_info("\n ");
- pr_info(" [<%08lx>]", addr);
+ pr_info(" ");
+ pr_cont(" [<%08lx>]", addr);
i++;
}
}
pr_info("\n");
}
-
-void show_trace_task(struct task_struct *tsk)
-{
- show_stack(tsk, (unsigned long *)tsk->thread.esp0);
-}
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 7c302dc..cb5dfb0 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -1,5 +1,6 @@
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
+#include <asm/thread_info.h>
#define ROMTOP 0x000000
#define RAMTOP 0x400000
@@ -42,11 +43,10 @@ SECTIONS
. = RAMTOP;
_ramstart = .;
#define ADDR(x) ROMEND
-#else
#endif
_sdata = . ;
__data_start = . ;
- RW_DATA_SECTION(0,0,0)
+ RW_DATA_SECTION(0, PAGE_SIZE, THREAD_SIZE)
#if defined(CONFIG_ROMKERNEL)
#undef ADDR
#endif
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 4dc89d1..57298e7 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -27,7 +27,6 @@ config HEXAGON
select GENERIC_CLOCKEVENTS_BROADCAST
select MODULES_USE_ELF_RELA
select GENERIC_CPU_DEVICES
- select HAVE_DMA_ATTRS
---help---
Qualcomm Hexagon is a processor architecture designed for high
performance and low power across a wide variety of applications.
diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h
index 811d61f..55696c4 100644
--- a/arch/hexagon/include/asm/atomic.h
+++ b/arch/hexagon/include/asm/atomic.h
@@ -48,7 +48,7 @@ static inline void atomic_set(atomic_t *v, int new)
*
* Assumes all word reads on our architecture are atomic.
*/
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
/**
* atomic_xchg - atomic
diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h
index 46ec8a7..d9f58d6 100644
--- a/arch/hexagon/include/asm/checksum.h
+++ b/arch/hexagon/include/asm/checksum.h
@@ -38,12 +38,12 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst,
* returns a 16-bit checksum, already complemented
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
-__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
- unsigned short len, unsigned short proto, __wsum sum);
+__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum);
#define csum_tcpudp_magic csum_tcpudp_magic
-__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
- unsigned short len, unsigned short proto, __wsum sum);
+__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum);
#include <asm-generic/checksum.h>
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h
index 268fde8..aa62034 100644
--- a/arch/hexagon/include/asm/dma-mapping.h
+++ b/arch/hexagon/include/asm/dma-mapping.h
@@ -49,8 +49,6 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
-#include <asm-generic/dma-mapping-common.h>
-
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index ff759f2..983bae7d2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -180,7 +180,7 @@ void start_secondary(void)
local_irq_enable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c
index 8169f78..617506d 100644
--- a/arch/hexagon/lib/checksum.c
+++ b/arch/hexagon/lib/checksum.c
@@ -60,18 +60,16 @@ static inline unsigned short from64to16(u64 x)
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented.
*/
-__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
- unsigned short len, unsigned short proto,
- __wsum sum)
+__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
(__force u64)sum + ((len + proto) << 8));
}
-__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
- unsigned short len, unsigned short proto,
- __wsum sum)
+__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum)
{
u64 result;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index eb0249e..b534eba 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -25,7 +25,6 @@ config IA64
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
select HAVE_FUNCTION_TRACER
- select HAVE_DMA_ATTRS
select TTY
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
@@ -575,12 +574,8 @@ config PCI_DOMAINS
config PCI_SYSCALL
def_bool PCI
-source "drivers/pci/pcie/Kconfig"
-
source "drivers/pci/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
source "drivers/pcmcia/Kconfig"
endmenu
diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
index be4beeb..8dfb5f6 100644
--- a/arch/ia64/include/asm/atomic.h
+++ b/arch/ia64/include/asm/atomic.h
@@ -21,11 +21,11 @@
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic64_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic64_read(v) READ_ONCE((v)->counter)
-#define atomic_set(v,i) (((v)->counter) = (i))
-#define atomic64_set(v,i) (((v)->counter) = (i))
+#define atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
+#define atomic64_set(v,i) WRITE_ONCE(((v)->counter), (i))
#define ATOMIC_OP(op, c_op) \
static __inline__ int \
diff --git a/arch/ia64/include/asm/barrier.h b/arch/ia64/include/asm/barrier.h
index df896a1..588f161 100644
--- a/arch/ia64/include/asm/barrier.h
+++ b/arch/ia64/include/asm/barrier.h
@@ -42,34 +42,24 @@
#define dma_rmb() mb()
#define dma_wmb() mb()
-#ifdef CONFIG_SMP
-# define smp_mb() mb()
-#else
-# define smp_mb() barrier()
-#endif
+# define __smp_mb() mb()
-#define smp_rmb() smp_mb()
-#define smp_wmb() smp_mb()
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
-
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
/*
* IA64 GCC turns volatile stores into st.rel and volatile loads into ld.acq no
* need for asm trickery!
*/
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
barrier(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
@@ -77,12 +67,12 @@ do { \
___p1; \
})
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); mb(); } while (0)
-
/*
* The group barrier in front of the rsm & ssm are necessary to ensure
* that none of the previous instructions in the same group are
* affected by the rsm/ssm.
*/
+#include <asm-generic/barrier.h>
+
#endif /* _ASM_IA64_BARRIER_H */
diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h
index 97af155..7accf54 100644
--- a/arch/ia64/include/asm/checksum.h
+++ b/arch/ia64/include/asm/checksum.h
@@ -16,15 +16,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* Computes the checksum of the TCP/UDP pseudo-header returns a 16-bit
* checksum, already complemented
*/
-extern __sum16 csum_tcpudp_magic (__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum);
+extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum);
-extern __wsum csum_tcpudp_nofold (__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum);
+extern __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto, __wsum sum);
/*
* Computes the checksum of a memory block at buff, length len,
@@ -73,7 +69,7 @@ static inline __sum16 csum_fold(__wsum csum)
#define _HAVE_ARCH_IPV6_CSUM 1
struct in6_addr;
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
- const struct in6_addr *daddr, __u32 len, unsigned short proto,
- __wsum csum);
+ const struct in6_addr *daddr,
+ __u32 len, __u8 proto, __wsum csum);
#endif /* _ASM_IA64_CHECKSUM_H */
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 9beccf8..d472805 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -25,8 +25,6 @@ extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
#define get_dma_ops(dev) platform_dma_get_ops(dev)
-#include <asm-generic/dma-mapping-common.h>
-
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
diff --git a/arch/ia64/include/asm/early_ioremap.h b/arch/ia64/include/asm/early_ioremap.h
new file mode 100644
index 0000000..eec9e1d
--- /dev/null
+++ b/arch/ia64/include/asm/early_ioremap.h
@@ -0,0 +1,10 @@
+#ifndef _ASM_IA64_EARLY_IOREMAP_H
+#define _ASM_IA64_EARLY_IOREMAP_H
+
+extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
+#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size)
+
+extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
+#define early_memunmap(addr, size) early_iounmap(addr, size)
+
+#endif
diff --git a/arch/ia64/include/asm/gpio.h b/arch/ia64/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/ia64/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 9041bbe..5de673a 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -20,6 +20,7 @@
*/
#include <asm/unaligned.h>
+#include <asm/early_ioremap.h>
/* We don't use IO slowdowns on the ia64, but.. */
#define __SLOW_DOWN_IO do { } while (0)
@@ -427,15 +428,12 @@ __writeq (unsigned long val, volatile void __iomem *addr)
extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap (volatile void __iomem *addr);
-extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
-#define early_memremap(phys_addr, size) early_ioremap(phys_addr, size)
-extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
-#define early_memunmap(addr, size) early_iounmap(addr, size)
static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
{
return ioremap(phys_addr, size);
}
#define ioremap_cache ioremap_cache
+#define ioremap_uc ioremap_nocache
/*
diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h
index ec48bb9..e8c486e 100644
--- a/arch/ia64/include/asm/page.h
+++ b/arch/ia64/include/asm/page.h
@@ -105,6 +105,7 @@ extern struct page *vmem_map;
#ifdef CONFIG_DISCONTIGMEM
# define page_to_pfn(page) ((unsigned long) (page - vmem_map))
# define pfn_to_page(pfn) (vmem_map + (pfn))
+# define __pfn_to_phys(pfn) PFN_PHYS(pfn)
#else
# include <asm-generic/memory_model.h>
#endif
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 36d2c1e3..c0835b0 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -50,8 +50,6 @@ struct pci_dev;
extern unsigned long ia64_max_iommu_merge_mask;
#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL)
-#include <asm-generic/pci-dma-compat.h>
-
#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);
@@ -64,11 +62,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define pci_legacy_read platform_pci_legacy_read
#define pci_legacy_write platform_pci_legacy_write
-struct iospace_resource {
- struct list_head list;
- struct resource res;
-};
-
struct pci_controller {
struct acpi_device *companion;
void *iommu;
diff --git a/arch/ia64/include/asm/percpu.h b/arch/ia64/include/asm/percpu.h
index 0ec484d..b929579 100644
--- a/arch/ia64/include/asm/percpu.h
+++ b/arch/ia64/include/asm/percpu.h
@@ -6,8 +6,6 @@
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
-#define PERCPU_ENOUGH_ROOM PERCPU_PAGE_SIZE
-
#ifdef __ASSEMBLY__
# define THIS_CPU(var) (var) /* use this to mark accesses to per-CPU variables... */
#else /* !__ASSEMBLY__ */
diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h
index 3027e75..ce11247 100644
--- a/arch/ia64/include/asm/rwsem.h
+++ b/arch/ia64/include/asm/rwsem.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2003 Ken Chen <kenneth.w.chen@intel.com>
* Copyright (C) 2003 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2005 Christoph Lameter <clameter@sgi.com>
+ * Copyright (C) 2005 Christoph Lameter <cl@linux.com>
*
* Based on asm-i386/rwsem.h and other architecture implementation.
*
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index db73390..6a86850 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -11,7 +11,7 @@
-#define NR_syscalls 322 /* length of syscall table */
+#define NR_syscalls 324 /* length of syscall table */
/*
* The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h
index 59be3d8..0018fad 100644
--- a/arch/ia64/include/uapi/asm/socket.h
+++ b/arch/ia64/include/uapi/asm/socket.h
@@ -94,4 +94,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h
index 9038726..41369a1 100644
--- a/arch/ia64/include/uapi/asm/unistd.h
+++ b/arch/ia64/include/uapi/asm/unistd.h
@@ -335,5 +335,7 @@
#define __NR_userfaultfd 1343
#define __NR_membarrier 1344
#define __NR_kcmp 1345
+#define __NR_mlock2 1346
+#define __NR_copy_file_range 1347
#endif /* _UAPI_ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index caae3f4..300dac3 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -1178,7 +1178,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
efi_memory_desc_t *md;
u64 efi_desc_size;
char *name;
- unsigned long flags;
+ unsigned long flags, desc;
efi_map_start = __va(ia64_boot_param->efi_memmap);
efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -1193,6 +1193,8 @@ efi_initialize_iomem_resources(struct resource *code_resource,
continue;
flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ desc = IORES_DESC_NONE;
+
switch (md->type) {
case EFI_MEMORY_MAPPED_IO:
@@ -1207,14 +1209,17 @@ efi_initialize_iomem_resources(struct resource *code_resource,
if (md->attribute & EFI_MEMORY_WP) {
name = "System ROM";
flags |= IORESOURCE_READONLY;
- } else if (md->attribute == EFI_MEMORY_UC)
+ } else if (md->attribute == EFI_MEMORY_UC) {
name = "Uncached RAM";
- else
+ } else {
name = "System RAM";
+ flags |= IORESOURCE_SYSRAM;
+ }
break;
case EFI_ACPI_MEMORY_NVS:
name = "ACPI Non-volatile Storage";
+ desc = IORES_DESC_ACPI_NV_STORAGE;
break;
case EFI_UNUSABLE_MEMORY:
@@ -1224,6 +1229,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
case EFI_PERSISTENT_MEMORY:
name = "Persistent Memory";
+ desc = IORES_DESC_PERSISTENT_MEMORY;
break;
case EFI_RESERVED_TYPE:
@@ -1246,6 +1252,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
res->start = md->phys_addr;
res->end = md->phys_addr + efi_md_size(md) - 1;
res->flags = flags;
+ res->desc = desc;
if (insert_resource(&iomem_resource, res) < 0)
kfree(res);
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index dcd97f8..477c55e 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1771,5 +1771,7 @@ sys_call_table:
data8 sys_userfaultfd
data8 sys_membarrier
data8 sys_kcmp // 1345
+ data8 sys_mlock2
+ data8 sys_copy_file_range
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/ftrace.c b/arch/ia64/kernel/ftrace.c
index 3b0c2aa..cee411e 100644
--- a/arch/ia64/kernel/ftrace.c
+++ b/arch/ia64/kernel/ftrace.c
@@ -97,13 +97,11 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
unsigned char replaced[MCOUNT_INSN_SIZE];
/*
- * Note: Due to modules and __init, code can
- * disappear and change, we need to protect against faulting
- * as well as code changing. We do this by using the
- * probe_kernel_* functions.
- *
- * No real locking needed, this code is run through
- * kstop_machine, or before SMP starts.
+ * Note:
+ * We are paranoid about modifying text, as if a bug was to happen, it
+ * could cause us to read or write to someplace that could cause harm.
+ * Carefully read and modify the code with probe_kernel_*(), and make
+ * sure what we read is what we expected it to be before modifying it.
*/
if (!do_check)
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index d2fae05..90fde5b 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -256,7 +256,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
}
static void
-nop (struct irq_data *data)
+iosapic_nop (struct irq_data *data)
{
/* do nothing... */
}
@@ -415,7 +415,7 @@ iosapic_unmask_level_irq (struct irq_data *data)
#define iosapic_shutdown_level_irq mask_irq
#define iosapic_enable_level_irq unmask_irq
#define iosapic_disable_level_irq mask_irq
-#define iosapic_ack_level_irq nop
+#define iosapic_ack_level_irq iosapic_nop
static struct irq_chip irq_type_iosapic_level = {
.name = "IO-SAPIC-level",
@@ -453,7 +453,7 @@ iosapic_ack_edge_irq (struct irq_data *data)
}
#define iosapic_enable_edge_irq unmask_irq
-#define iosapic_disable_edge_irq nop
+#define iosapic_disable_edge_irq iosapic_nop
static struct irq_chip irq_type_iosapic_edge = {
.name = "IO-SAPIC-edge",
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index b15933c..6ab0ae7 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
static inline int
in_init (const struct module *mod, uint64_t addr)
{
- return addr - (uint64_t) mod->module_init < mod->init_size;
+ return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size;
}
static inline int
in_core (const struct module *mod, uint64_t addr)
{
- return addr - (uint64_t) mod->module_core < mod->core_size;
+ return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size;
}
static inline int
@@ -675,7 +675,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
break;
case RV_BDREL:
- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
+ val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base);
break;
case RV_LTV:
@@ -810,15 +810,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
* addresses have been selected...
*/
uint64_t gp;
- if (mod->core_size > MAX_LTOFF)
+ if (mod->core_layout.size > MAX_LTOFF)
/*
* This takes advantage of fact that SHF_ARCH_SMALL gets allocated
* at the end of the module.
*/
- gp = mod->core_size - MAX_LTOFF / 2;
+ gp = mod->core_layout.size - MAX_LTOFF / 2;
else
- gp = mod->core_size / 2;
- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
+ gp = mod->core_layout.size / 2;
+ gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8);
mod->arch.gp = gp;
DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 60e02f7..9cd607b 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2332,8 +2332,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
*/
insert_vm_struct(mm, vma);
- vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
- vma_pages(vma));
+ vm_stat_account(vma->vm_mm, vma->vm_flags, vma_pages(vma));
up_write(&task->mm->mmap_sem);
/*
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 4f118b0..2029a38 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -80,17 +80,17 @@ unsigned long vga_console_membase;
static struct resource data_resource = {
.name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource code_resource = {
.name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource bss_resource = {
.name = "Kernel bss",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
unsigned long ia64_max_cacheline_size;
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 0e76fad..74fe317 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -454,7 +454,7 @@ start_secondary (void *unused)
preempt_disable();
smp_callin();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
return 0;
}
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 622772b..e7ae608 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1336,8 +1336,11 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
* Don't call tty_write_message() if we're in the kernel; we might
* be holding locks...
*/
- if (user_mode(regs))
- tty_write_message(current->signal->tty, buf);
+ if (user_mode(regs)) {
+ struct tty_struct *tty = get_current_tty();
+ tty_write_message(tty, buf);
+ tty_kref_put(tty);
+ }
buf[len-1] = '\0'; /* drop '\r' */
/* watch for command names containing %s */
printk(KERN_WARNING "%s", buf);
diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c
index 9fc9550..2cb23cb 100644
--- a/arch/ia64/lib/checksum.c
+++ b/arch/ia64/lib/checksum.c
@@ -34,8 +34,8 @@ from64to16 (unsigned long x)
* returns a 16-bit checksum, already complemented.
*/
__sum16
-csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
@@ -45,8 +45,8 @@ csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len,
EXPORT_SYMBOL(csum_tcpudp_magic);
__wsum
-csum_tcpudp_nofold (__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
unsigned long result;
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index f50d4b3..85de86d 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -38,7 +38,7 @@ huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
if (pud) {
pmd = pmd_alloc(mm, pud, taddr);
if (pmd)
- pte = pte_alloc_map(mm, NULL, pmd, taddr);
+ pte = pte_alloc_map(mm, pmd, taddr);
}
return pte;
}
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index fc505d5..41caa99 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -17,14 +17,14 @@
*
* The standard boot ROM sequence for an x86 machine uses the BIOS
* to select an initial video card for boot display. This boot video
- * card will have it's BIOS copied to C0000 in system RAM.
+ * card will have its BIOS copied to 0xC0000 in system RAM.
* IORESOURCE_ROM_SHADOW is used to associate the boot video
* card with this copy. On laptops this copy has to be used since
* the main ROM may be compressed or combined with another image.
* See pci_map_rom() for use of this flag. Before marking the device
* with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
- * by either arch cde or vga-arbitration, if so only apply the fixup to this
- * already determined primary video card.
+ * by either arch code or vga-arbitration; if so only apply the fixup to this
+ * already-determined primary video card.
*/
static void pci_fixup_video(struct pci_dev *pdev)
@@ -32,6 +32,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
struct pci_dev *bridge;
struct pci_bus *bus;
u16 config;
+ struct resource *res;
if ((strcmp(ia64_platform_name, "dig") != 0)
&& (strcmp(ia64_platform_name, "hpzx1") != 0))
@@ -61,8 +62,18 @@ static void pci_fixup_video(struct pci_dev *pdev)
if (!vga_default_device() || pdev == vga_default_device()) {
pci_read_config_word(pdev, PCI_COMMAND, &config);
if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
- pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
- dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n");
+ res = &pdev->resource[PCI_ROM_RESOURCE];
+
+ pci_disable_rom(pdev);
+ if (res->parent)
+ release_resource(res);
+
+ res->start = 0xC0000;
+ res->end = res->start + 0x20000 - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+ IORESOURCE_PCI_FIXED;
+ dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n",
+ res);
}
}
}
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7cc3be9..8f6ac2f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -115,33 +115,13 @@ struct pci_ops pci_root_ops = {
.write = pci_write,
};
-/* Called by ACPI when it finds a new root bus. */
-
-static struct pci_controller *alloc_pci_controller(int seg)
-{
- struct pci_controller *controller;
-
- controller = kzalloc(sizeof(*controller), GFP_KERNEL);
- if (!controller)
- return NULL;
-
- controller->segment = seg;
- return controller;
-}
-
struct pci_root_info {
- struct acpi_device *bridge;
- struct pci_controller *controller;
- struct list_head resources;
- struct resource *res;
- resource_size_t *res_offset;
- unsigned int res_num;
+ struct acpi_pci_root_info common;
+ struct pci_controller controller;
struct list_head io_resources;
- char *name;
};
-static unsigned int
-new_space (u64 phys_base, int sparse)
+static unsigned int new_space(u64 phys_base, int sparse)
{
u64 mmio_base;
int i;
@@ -168,39 +148,36 @@ new_space (u64 phys_base, int sparse)
return i;
}
-static u64 add_io_space(struct pci_root_info *info,
- struct acpi_resource_address64 *addr)
+static int add_io_space(struct device *dev, struct pci_root_info *info,
+ struct resource_entry *entry)
{
- struct iospace_resource *iospace;
- struct resource *resource;
+ struct resource_entry *iospace;
+ struct resource *resource, *res = entry->res;
char *name;
unsigned long base, min, max, base_port;
unsigned int sparse = 0, space_nr, len;
- len = strlen(info->name) + 32;
- iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+ len = strlen(info->common.name) + 32;
+ iospace = resource_list_create_entry(NULL, len);
if (!iospace) {
- dev_err(&info->bridge->dev,
- "PCI: No memory for %s I/O port space\n",
- info->name);
- goto out;
+ dev_err(dev, "PCI: No memory for %s I/O port space\n",
+ info->common.name);
+ return -ENOMEM;
}
- name = (char *)(iospace + 1);
-
- min = addr->address.minimum;
- max = min + addr->address.address_length - 1;
- if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
+ if (res->flags & IORESOURCE_IO_SPARSE)
sparse = 1;
-
- space_nr = new_space(addr->address.translation_offset, sparse);
+ space_nr = new_space(entry->offset, sparse);
if (space_nr == ~0)
goto free_resource;
+ name = (char *)(iospace + 1);
+ min = res->start - entry->offset;
+ max = res->end - entry->offset;
base = __pa(io_space[space_nr].mmio_base);
base_port = IO_SPACE_BASE(space_nr);
- snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
- base_port + min, base_port + max);
+ snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
+ base_port + min, base_port + max);
/*
* The SDM guarantees the legacy 0-64K space is sparse, but if the
@@ -210,270 +187,125 @@ static u64 add_io_space(struct pci_root_info *info,
if (space_nr == 0)
sparse = 1;
- resource = &iospace->res;
+ resource = iospace->res;
resource->name = name;
resource->flags = IORESOURCE_MEM;
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
if (insert_resource(&iomem_resource, resource)) {
- dev_err(&info->bridge->dev,
- "can't allocate host bridge io space resource %pR\n",
- resource);
+ dev_err(dev,
+ "can't allocate host bridge io space resource %pR\n",
+ resource);
goto free_resource;
}
- list_add_tail(&iospace->list, &info->io_resources);
- return base_port;
+ entry->offset = base_port;
+ res->start = min + base_port;
+ res->end = max + base_port;
+ resource_list_add_tail(iospace, &info->io_resources);
-free_resource:
- kfree(iospace);
-out:
- return ~0;
-}
-
-static acpi_status resource_to_window(struct acpi_resource *resource,
- struct acpi_resource_address64 *addr)
-{
- acpi_status status;
+ return 0;
- /*
- * We're only interested in _CRS descriptors that are
- * - address space descriptors for memory or I/O space
- * - non-zero size
- */
- status = acpi_resource_to_address64(resource, addr);
- if (ACPI_SUCCESS(status) &&
- (addr->resource_type == ACPI_MEMORY_RANGE ||
- addr->resource_type == ACPI_IO_RANGE) &&
- addr->address.address_length)
- return AE_OK;
-
- return AE_ERROR;
+free_resource:
+ resource_list_free_entry(iospace);
+ return -ENOSPC;
}
-static acpi_status count_window(struct acpi_resource *resource, void *data)
+/*
+ * An IO port or MMIO resource assigned to a PCI host bridge may be
+ * consumed by the host bridge itself or available to its child
+ * bus/devices. The ACPI specification defines a bit (Producer/Consumer)
+ * to tell whether the resource is consumed by the host bridge itself,
+ * but firmware hasn't used that bit consistently, so we can't rely on it.
+ *
+ * On x86 and IA64 platforms, all IO port and MMIO resources are assumed
+ * to be available to child bus/devices except one special case:
+ * IO port [0xCF8-0xCFF] is consumed by the host bridge itself
+ * to access PCI configuration space.
+ *
+ * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
+ */
+static bool resource_is_pcicfg_ioport(struct resource *res)
{
- unsigned int *windows = (unsigned int *) data;
- struct acpi_resource_address64 addr;
- acpi_status status;
-
- status = resource_to_window(resource, &addr);
- if (ACPI_SUCCESS(status))
- (*windows)++;
-
- return AE_OK;
+ return (res->flags & IORESOURCE_IO) &&
+ res->start == 0xCF8 && res->end == 0xCFF;
}
-static acpi_status add_window(struct acpi_resource *res, void *data)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
- struct pci_root_info *info = data;
- struct resource *resource;
- struct acpi_resource_address64 addr;
- acpi_status status;
- unsigned long flags, offset = 0;
- struct resource *root;
-
- /* Return AE_OK for non-window resources to keep scanning for more */
- status = resource_to_window(res, &addr);
- if (!ACPI_SUCCESS(status))
- return AE_OK;
-
- if (addr.resource_type == ACPI_MEMORY_RANGE) {
- flags = IORESOURCE_MEM;
- root = &iomem_resource;
- offset = addr.address.translation_offset;
- } else if (addr.resource_type == ACPI_IO_RANGE) {
- flags = IORESOURCE_IO;
- root = &ioport_resource;
- offset = add_io_space(info, &addr);
- if (offset == ~0)
- return AE_OK;
- } else
- return AE_OK;
-
- resource = &info->res[info->res_num];
- resource->name = info->name;
- resource->flags = flags;
- resource->start = addr.address.minimum + offset;
- resource->end = resource->start + addr.address.address_length - 1;
- info->res_offset[info->res_num] = offset;
-
- if (insert_resource(root, resource)) {
- dev_err(&info->bridge->dev,
- "can't allocate host bridge window %pR\n",
- resource);
- } else {
- if (offset)
- dev_info(&info->bridge->dev, "host bridge window %pR "
- "(PCI address [%#llx-%#llx])\n",
- resource,
- resource->start - offset,
- resource->end - offset);
- else
- dev_info(&info->bridge->dev,
- "host bridge window %pR\n", resource);
+ struct device *dev = &ci->bridge->dev;
+ struct pci_root_info *info;
+ struct resource *res;
+ struct resource_entry *entry, *tmp;
+ int status;
+
+ status = acpi_pci_probe_root_resources(ci);
+ if (status > 0) {
+ info = container_of(ci, struct pci_root_info, common);
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+ res = entry->res;
+ if (res->flags & IORESOURCE_MEM) {
+ /*
+ * HP's firmware has a hack to work around a
+ * Windows bug. Ignore these tiny memory ranges.
+ */
+ if (resource_size(res) <= 16) {
+ resource_list_del(entry);
+ insert_resource(&iomem_resource,
+ entry->res);
+ resource_list_add_tail(entry,
+ &info->io_resources);
+ }
+ } else if (res->flags & IORESOURCE_IO) {
+ if (resource_is_pcicfg_ioport(entry->res))
+ resource_list_destroy_entry(entry);
+ else if (add_io_space(dev, info, entry))
+ resource_list_destroy_entry(entry);
+ }
+ }
}
- /* HP's firmware has a hack to work around a Windows bug.
- * Ignore these tiny memory ranges */
- if (!((resource->flags & IORESOURCE_MEM) &&
- (resource->end - resource->start < 16)))
- pci_add_resource_offset(&info->resources, resource,
- info->res_offset[info->res_num]);
-
- info->res_num++;
- return AE_OK;
-}
-static void free_pci_root_info_res(struct pci_root_info *info)
-{
- struct iospace_resource *iospace, *tmp;
-
- list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
- kfree(iospace);
-
- kfree(info->name);
- kfree(info->res);
- info->res = NULL;
- kfree(info->res_offset);
- info->res_offset = NULL;
- info->res_num = 0;
- kfree(info->controller);
- info->controller = NULL;
+ return status;
}
-static void __release_pci_root_info(struct pci_root_info *info)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
{
- int i;
- struct resource *res;
- struct iospace_resource *iospace;
+ struct pci_root_info *info;
+ struct resource_entry *entry, *tmp;
- list_for_each_entry(iospace, &info->io_resources, list)
- release_resource(&iospace->res);
-
- for (i = 0; i < info->res_num; i++) {
- res = &info->res[i];
-
- if (!res->parent)
- continue;
-
- if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- continue;
-
- release_resource(res);
+ info = container_of(ci, struct pci_root_info, common);
+ resource_list_for_each_entry_safe(entry, tmp, &info->io_resources) {
+ release_resource(entry->res);
+ resource_list_destroy_entry(entry);
}
-
- free_pci_root_info_res(info);
kfree(info);
}
-static void release_pci_root_info(struct pci_host_bridge *bridge)
-{
- struct pci_root_info *info = bridge->release_data;
-
- __release_pci_root_info(info);
-}
-
-static int
-probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
- int busnum, int domain)
-{
- char *name;
-
- name = kmalloc(16, GFP_KERNEL);
- if (!name)
- return -ENOMEM;
-
- sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
- info->bridge = device;
- info->name = name;
-
- acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
- &info->res_num);
- if (info->res_num) {
- info->res =
- kzalloc_node(sizeof(*info->res) * info->res_num,
- GFP_KERNEL, info->controller->node);
- if (!info->res) {
- kfree(name);
- return -ENOMEM;
- }
-
- info->res_offset =
- kzalloc_node(sizeof(*info->res_offset) * info->res_num,
- GFP_KERNEL, info->controller->node);
- if (!info->res_offset) {
- kfree(name);
- kfree(info->res);
- info->res = NULL;
- return -ENOMEM;
- }
-
- info->res_num = 0;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- add_window, info);
- } else
- kfree(name);
-
- return 0;
-}
+static struct acpi_pci_root_ops pci_acpi_root_ops = {
+ .pci_ops = &pci_root_ops,
+ .release_info = pci_acpi_root_release_info,
+ .prepare_resources = pci_acpi_root_prepare_resources,
+};
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
struct acpi_device *device = root->device;
- int domain = root->segment;
- int bus = root->secondary.start;
- struct pci_controller *controller;
- struct pci_root_info *info = NULL;
- int busnum = root->secondary.start;
- struct pci_bus *pbus;
- int ret;
-
- controller = alloc_pci_controller(domain);
- if (!controller)
- return NULL;
-
- controller->companion = device;
- controller->node = acpi_get_node(device->handle);
+ struct pci_root_info *info;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
dev_err(&device->dev,
- "pci_bus %04x:%02x: ignored (out of memory)\n",
- domain, busnum);
- kfree(controller);
+ "pci_bus %04x:%02x: ignored (out of memory)\n",
+ root->segment, (int)root->secondary.start);
return NULL;
}
- info->controller = controller;
+ info->controller.segment = root->segment;
+ info->controller.companion = device;
+ info->controller.node = acpi_get_node(device->handle);
INIT_LIST_HEAD(&info->io_resources);
- INIT_LIST_HEAD(&info->resources);
-
- ret = probe_pci_root_info(info, device, busnum, domain);
- if (ret) {
- kfree(info->controller);
- kfree(info);
- return NULL;
- }
- /* insert busn resource at first */
- pci_add_resource(&info->resources, &root->secondary);
- /*
- * See arch/x86/pci/acpi.c.
- * The desired pci bus might already be scanned in a quirk. We
- * should handle the case here, but it appears that IA64 hasn't
- * such quirk. So we just ignore the case now.
- */
- pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
- &info->resources);
- if (!pbus) {
- pci_free_resource_list(&info->resources);
- __release_pci_root_info(info);
- return NULL;
- }
-
- pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
- release_pci_root_info, info);
- pci_scan_child_bus(pbus);
- return pbus;
+ return acpi_pci_root_create(root, &pci_acpi_root_ops,
+ &info->common, &info->controller);
}
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index 0640739..231234c 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -429,7 +429,8 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
void __iomem *addr;
struct pcidev_info *pcidev_info = NULL;
struct sn_irq_info *sn_irq_info = NULL;
- size_t image_size, size;
+ struct resource *res;
+ size_t size;
if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
panic("%s: Failure obtaining pcidev_info for %s\n",
@@ -443,17 +444,20 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
* of the shadowed copy, and the actual length of the ROM image.
*/
size = pci_resource_len(dev, PCI_ROM_RESOURCE);
- addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
- size);
- image_size = pci_get_rom_size(dev, addr, size);
- dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
- dev->resource[PCI_ROM_RESOURCE].end =
- (unsigned long) addr + image_size - 1;
- dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY;
+
+ res = &dev->resource[PCI_ROM_RESOURCE];
+
+ pci_disable_rom(dev);
+ if (res->parent)
+ release_resource(res);
+
+ res->start = pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE];
+ res->end = res->start + size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+ IORESOURCE_PCI_FIXED;
}
sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
}
-
EXPORT_SYMBOL(sn_acpi_slot_fixup);
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 1be65eb..c15a41e 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -150,7 +150,8 @@ void
sn_io_slot_fixup(struct pci_dev *dev)
{
int idx;
- unsigned long addr, end, size, start;
+ struct resource *res;
+ unsigned long addr, size;
struct pcidev_info *pcidev_info;
struct sn_irq_info *sn_irq_info;
int status;
@@ -175,55 +176,41 @@ sn_io_slot_fixup(struct pci_dev *dev)
/* Copy over PIO Mapped Addresses */
for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
-
- if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
+ if (!pcidev_info->pdi_pio_mapped_addr[idx])
continue;
- }
- start = dev->resource[idx].start;
- end = dev->resource[idx].end;
- size = end - start;
- if (size == 0) {
+ res = &dev->resource[idx];
+
+ size = res->end - res->start;
+ if (size == 0)
continue;
- }
- addr = pcidev_info->pdi_pio_mapped_addr[idx];
- addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
- dev->resource[idx].start = addr;
- dev->resource[idx].end = addr + size;
+
+ res->start = pcidev_info->pdi_pio_mapped_addr[idx];
+ res->end = addr + size;
/*
* if it's already in the device structure, remove it before
* inserting
*/
- if (dev->resource[idx].parent && dev->resource[idx].parent->child)
- release_resource(&dev->resource[idx]);
+ if (res->parent && res->parent->child)
+ release_resource(res);
- if (dev->resource[idx].flags & IORESOURCE_IO)
- insert_resource(&ioport_resource, &dev->resource[idx]);
+ if (res->flags & IORESOURCE_IO)
+ insert_resource(&ioport_resource, res);
else
- insert_resource(&iomem_resource, &dev->resource[idx]);
+ insert_resource(&iomem_resource, res);
/*
- * If ROM, set the actual ROM image size, and mark as
- * shadowed in PROM.
+ * If ROM, mark as shadowed in PROM.
*/
if (idx == PCI_ROM_RESOURCE) {
- size_t image_size;
- void __iomem *rom;
-
- rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
- size + 1);
- image_size = pci_get_rom_size(dev, rom, size + 1);
- dev->resource[PCI_ROM_RESOURCE].end =
- dev->resource[PCI_ROM_RESOURCE].start +
- image_size - 1;
- dev->resource[PCI_ROM_RESOURCE].flags |=
- IORESOURCE_ROM_BIOS_COPY;
+ pci_disable_rom(dev);
+ res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+ IORESOURCE_PCI_FIXED;
}
}
sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
}
-
EXPORT_SYMBOL(sn_io_slot_fixup);
/*
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 9e44bbd..c82b292 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -13,6 +13,7 @@ config M32R
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_ATOMIC64
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_USES_GETTIMEOFFSET
select MODULES_USE_ELF_RELA
select HAVE_DEBUG_STACKOVERFLOW
@@ -275,6 +276,7 @@ source "kernel/Kconfig.preempt"
config SMP
bool "Symmetric multi-processing support"
+ depends on MMU
---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
@@ -385,8 +387,6 @@ config ISA
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
endmenu
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index fd104bd..860e440 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -3,6 +3,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += irq_work.h
+generic-y += kvm_para.h
generic-y += mcs_spinlock.h
generic-y += mm-arch-hooks.h
generic-y += module.h
diff --git a/arch/m32r/include/asm/atomic.h b/arch/m32r/include/asm/atomic.h
index 025e2a1..ea35160 100644
--- a/arch/m32r/include/asm/atomic.h
+++ b/arch/m32r/include/asm/atomic.h
@@ -28,7 +28,7 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
/**
* atomic_set - set atomic variable
@@ -37,7 +37,7 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic_set(v,i) (((v)->counter) = (i))
+#define atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
#ifdef CONFIG_CHIP_M32700_TS1
#define __ATOMIC_CLOBBER , "r4"
diff --git a/arch/m32r/include/asm/checksum.h b/arch/m32r/include/asm/checksum.h
index a7a7c4f..d68e93c 100644
--- a/arch/m32r/include/asm/checksum.h
+++ b/arch/m32r/include/asm/checksum.h
@@ -114,9 +114,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
#if defined(__LITTLE_ENDIAN)
unsigned long len_proto = (proto + len) << 8;
@@ -145,9 +144,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index 61b8931..4b0f5e0 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -168,13 +168,21 @@ static inline void _writel(unsigned long l, unsigned long addr)
#define writew_relaxed writew
#define writel_relaxed writel
-#define ioread8 read
+#define ioread8 readb
#define ioread16 readw
#define ioread32 readl
#define iowrite8 writeb
#define iowrite16 writew
#define iowrite32 writel
+#define ioread8_rep(p, dst, count) insb((unsigned long)(p), (dst), (count))
+#define ioread16_rep(p, dst, count) insw((unsigned long)(p), (dst), (count))
+#define ioread32_rep(p, dst, count) insl((unsigned long)(p), (dst), (count))
+
+#define iowrite8_rep(p, src, count) outsb((unsigned long)(p), (src), (count))
+#define iowrite16_rep(p, src, count) outsw((unsigned long)(p), (src), (count))
+#define iowrite32_rep(p, src, count) outsl((unsigned long)(p), (src), (count))
+
#define ioread16be(addr) be16_to_cpu(readw(addr))
#define ioread32be(addr) be32_to_cpu(readl(addr))
#define iowrite16be(v, addr) writew(cpu_to_be16(v), (addr))
diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h
index 7bc4cb2..5fe42fc 100644
--- a/arch/m32r/include/uapi/asm/socket.h
+++ b/arch/m32r/include/uapi/asm/socket.h
@@ -85,4 +85,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index 0392112..136c69f 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -70,18 +70,21 @@ static struct resource data_resource = {
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource code_resource = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
unsigned long memory_start;
+EXPORT_SYMBOL(memory_start);
+
unsigned long memory_end;
+EXPORT_SYMBOL(memory_end);
void __init setup_arch(char **);
int get_cpuinfo(char *);
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index a468467..f98d2f6 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -432,7 +432,7 @@ int __init start_secondary(void *unused)
*/
local_flush_tlb_all();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
return 0;
}
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index 0d4146f..11fa717 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -59,21 +59,24 @@ void free_initrd_mem(unsigned long, unsigned long);
void __init zone_sizes_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, };
- unsigned long max_dma;
- unsigned long low;
unsigned long start_pfn;
#ifdef CONFIG_MMU
- start_pfn = START_PFN(0);
- max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- low = MAX_LOW_PFN(0);
-
- if (low < max_dma){
- zones_size[ZONE_DMA] = low - start_pfn;
- zones_size[ZONE_NORMAL] = 0;
- } else {
- zones_size[ZONE_DMA] = low - start_pfn;
- zones_size[ZONE_NORMAL] = low - max_dma;
+ {
+ unsigned long low;
+ unsigned long max_dma;
+
+ start_pfn = START_PFN(0);
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = MAX_LOW_PFN(0);
+
+ if (low < max_dma) {
+ zones_size[ZONE_DMA] = low - start_pfn;
+ zones_size[ZONE_NORMAL] = 0;
+ } else {
+ zones_size[ZONE_DMA] = low - start_pfn;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
}
#else
zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
diff --git a/arch/m68k/68360/Makefile b/arch/m68k/68360/Makefile
deleted file mode 100644
index 591ce42..0000000
--- a/arch/m68k/68360/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for 68360 machines.
-#
-model-y := ram
-model-$(CONFIG_ROMKERNEL) := rom
-
-obj-y := config.o commproc.o entry.o ints.o
-
-extra-y := head.o
-
-$(obj)/head.o: $(obj)/head-$(model-y).o
- ln -sf head-$(model-y).o $(obj)/head.o
diff --git a/arch/m68k/68360/commproc.c b/arch/m68k/68360/commproc.c
deleted file mode 100644
index 14d7f35..0000000
--- a/arch/m68k/68360/commproc.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * General Purpose functions for the global management of the
- * Communication Processor Module.
- *
- * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
- * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
- *
- * In addition to the individual control of the communication
- * channels, there are a few functions that globally affect the
- * communication processor.
- *
- * Buffer descriptors must be allocated from the dual ported memory
- * space. The allocator for that is here. When the communication
- * process is reset, we reclaim the memory available. There is
- * currently no deallocator for this memory.
- * The amount of space available is platform dependent. On the
- * MBX, the EPPC software loads additional microcode into the
- * communication processor, and uses some of the DP ram for this
- * purpose. Current, the first 512 bytes and the last 256 bytes of
- * memory are used. Right now I am conservative and only use the
- * memory that can never be used for microcode. If there are
- * applications that require more DP ram, we can expand the boundaries
- * but then we have to be careful of any downloaded microcode.
- *
- */
-
-/*
- * Michael Leslie <mleslie@lineo.com>
- * adapted Dan Malek's ppc8xx drivers to M68360
- *
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <asm/m68360.h>
-#include <asm/commproc.h>
-
-/* #include <asm/page.h> */
-/* #include <asm/pgtable.h> */
-extern void *_quicc_base;
-extern unsigned int system_clock;
-
-
-static uint dp_alloc_base; /* Starting offset in DP ram */
-static uint dp_alloc_top; /* Max offset + 1 */
-
-#if 0
-static void *host_buffer; /* One page of host buffer */
-static void *host_end; /* end + 1 */
-#endif
-
-/* struct cpm360_t *cpmp; */ /* Pointer to comm processor space */
-
-QUICC *pquicc;
-/* QUICC *quicc_dpram; */ /* mleslie - temporary; use extern pquicc elsewhere instead */
-
-
-/* CPM interrupt vector functions. */
-struct cpm_action {
- irq_handler_t handler;
- void *dev_id;
-};
-static struct cpm_action cpm_vecs[CPMVEC_NR];
-static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
-static void cpm_error_interrupt(void *);
-
-/* prototypes: */
-void cpm_install_handler(int vec, irq_handler_t handler, void *dev_id);
-void m360_cpm_reset(void);
-
-
-
-
-void __init m360_cpm_reset()
-{
-/* pte_t *pte; */
-
- pquicc = (struct quicc *)(_quicc_base); /* initialized in crt0_rXm.S */
-
- /* Perform a CPM reset. */
- pquicc->cp_cr = (SOFTWARE_RESET | CMD_FLAG);
-
- /* Wait for CPM to become ready (should be 2 clocks). */
- while (pquicc->cp_cr & CMD_FLAG);
-
- /* On the recommendation of the 68360 manual, p. 7-60
- * - Set sdma interrupt service mask to 7
- * - Set sdma arbitration ID to 4
- */
- pquicc->sdma_sdcr = 0x0740;
-
-
- /* Claim the DP memory for our use.
- */
- dp_alloc_base = CPM_DATAONLY_BASE;
- dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
-
-
- /* Set the host page for allocation.
- */
- /* host_buffer = host_page_addr; */
- /* host_end = host_page_addr + PAGE_SIZE; */
-
- /* pte = find_pte(&init_mm, host_page_addr); */
- /* pte_val(*pte) |= _PAGE_NO_CACHE; */
- /* flush_tlb_page(current->mm->mmap, host_buffer); */
-
- /* Tell everyone where the comm processor resides.
- */
-/* cpmp = (cpm360_t *)commproc; */
-}
-
-
-/* This is called during init_IRQ. We used to do it above, but this
- * was too early since init_IRQ was not yet called.
- */
-void
-cpm_interrupt_init(void)
-{
- /* Initialize the CPM interrupt controller.
- * NOTE THAT pquicc had better have been initialized!
- * reference: MC68360UM p. 7-377
- */
- pquicc->intr_cicr =
- (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
- (CPM_INTERRUPT << 13) |
- CICR_HP_MASK |
- (CPM_VECTOR_BASE << 5) |
- CICR_SPS;
-
- /* mask all CPM interrupts from reaching the cpu32 core: */
- pquicc->intr_cimr = 0;
-
-
- /* mles - If I understand correctly, the 360 just pops over to the CPM
- * specific vector, obviating the necessity to vector through the IRQ
- * whose priority the CPM is set to. This needs a closer look, though.
- */
-
- /* Set our interrupt handler with the core CPU. */
-/* if (request_irq(CPM_INTERRUPT, cpm_interrupt, 0, "cpm", NULL) != 0) */
-/* panic("Could not allocate CPM IRQ!"); */
-
- /* Install our own error handler.
- */
- /* I think we want to hold off on this one for the moment - mles */
- /* cpm_install_handler(CPMVEC_ERROR, cpm_error_interrupt, NULL); */
-
- /* master CPM interrupt enable */
- /* pquicc->intr_cicr |= CICR_IEN; */ /* no such animal for 360 */
-}
-
-
-
-/* CPM interrupt controller interrupt.
-*/
-static void
-cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
-{
- /* uint vec; */
-
- /* mles: Note that this stuff is currently being performed by
- * M68360_do_irq(int vec, struct pt_regs *fp), in ../ints.c */
-
- /* figure out the vector */
- /* call that vector's handler */
- /* clear the irq's bit in the service register */
-
-#if 0 /* old 860 stuff: */
- /* Get the vector by setting the ACK bit and then reading
- * the register.
- */
- ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
- vec = ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr;
- vec >>= 11;
-
-
- if (cpm_vecs[vec].handler != 0)
- (*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id);
- else
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec);
-
- /* After servicing the interrupt, we have to remove the status
- * indicator.
- */
- ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec);
-#endif
-
-}
-
-/* The CPM can generate the error interrupt when there is a race condition
- * between generating and masking interrupts. All we have to do is ACK it
- * and return. This is a no-op function so we don't need any special
- * tests in the interrupt handler.
- */
-static void
-cpm_error_interrupt(void *dev)
-{
-}
-
-/* Install a CPM interrupt handler.
-*/
-void
-cpm_install_handler(int vec, irq_handler_t handler, void *dev_id)
-{
-
- request_irq(vec, handler, 0, "timer", dev_id);
-
-/* if (cpm_vecs[vec].handler != 0) */
-/* printk(KERN_INFO "CPM interrupt %x replacing %x\n", */
-/* (uint)handler, (uint)cpm_vecs[vec].handler); */
-/* cpm_vecs[vec].handler = handler; */
-/* cpm_vecs[vec].dev_id = dev_id; */
-
- /* ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << vec); */
-/* pquicc->intr_cimr |= (1 << vec); */
-
-}
-
-/* Free a CPM interrupt handler.
-*/
-void
-cpm_free_handler(int vec)
-{
- cpm_vecs[vec].handler = NULL;
- cpm_vecs[vec].dev_id = NULL;
- /* ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec); */
- pquicc->intr_cimr &= ~(1 << vec);
-}
-
-
-
-
-/* Allocate some memory from the dual ported ram. We may want to
- * enforce alignment restrictions, but right now everyone is a good
- * citizen.
- */
-uint
-m360_cpm_dpalloc(uint size)
-{
- uint retloc;
-
- if ((dp_alloc_base + size) >= dp_alloc_top)
- return(CPM_DP_NOSPACE);
-
- retloc = dp_alloc_base;
- dp_alloc_base += size;
-
- return(retloc);
-}
-
-
-#if 0 /* mleslie - for now these are simply kmalloc'd */
-/* We also own one page of host buffer space for the allocation of
- * UART "fifos" and the like.
- */
-uint
-m360_cpm_hostalloc(uint size)
-{
- uint retloc;
-
- if ((host_buffer + size) >= host_end)
- return(0);
-
- retloc = host_buffer;
- host_buffer += size;
-
- return(retloc);
-}
-#endif
-
-
-/* Set a baud rate generator. This needs lots of work. There are
- * four BRGs, any of which can be wired to any channel.
- * The internal baud rate clock is the system clock divided by 16.
- * This assumes the baudrate is 16x oversampled by the uart.
- */
-/* #define BRG_INT_CLK (((bd_t *)__res)->bi_intfreq * 1000000) */
-#define BRG_INT_CLK system_clock
-#define BRG_UART_CLK (BRG_INT_CLK/16)
-
-void
-m360_cpm_setbrg(uint brg, uint rate)
-{
- volatile uint *bp;
-
- /* This is good enough to get SMCs running.....
- */
- /* bp = (uint *)&cpmp->cp_brgc1; */
- bp = (volatile uint *)(&pquicc->brgc[0].l);
- bp += brg;
- *bp = ((BRG_UART_CLK / rate - 1) << 1) | CPM_BRG_EN;
-}
-
-
-/*
- * Local variables:
- * c-indent-level: 4
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/arch/m68k/68360/config.c b/arch/m68k/68360/config.c
deleted file mode 100644
index b65fe4e..0000000
--- a/arch/m68k/68360/config.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * config.c - non-mmu 68360 platform initialization code
- *
- * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
- * Copyright (C) 1993 Hamish Macdonald
- * Copyright (C) 1999 D. Jeff Dionne <jeff@uclinux.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.
- */
-
-#include <stdarg.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/setup.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/m68360.h>
-
-#ifdef CONFIG_UCQUICC
-#include <asm/bootstd.h>
-#endif
-
-extern void m360_cpm_reset(void);
-
-// Mask to select if the PLL prescaler is enabled.
-#define MCU_PREEN ((unsigned short)(0x0001 << 13))
-
-#if defined(CONFIG_UCQUICC)
-#define OSCILLATOR (unsigned long int)33000000
-#endif
-
-static irq_handler_t timer_interrupt;
-unsigned long int system_clock;
-
-extern QUICC *pquicc;
-
-/* TODO DON"T Hard Code this */
-/* calculate properly using the right PLL and prescaller */
-// unsigned int system_clock = 33000000l;
-extern unsigned long int system_clock; //In kernel setup.c
-
-
-static irqreturn_t hw_tick(int irq, void *dummy)
-{
- /* Reset Timer1 */
- /* TSTAT &= 0; */
-
- pquicc->timer_ter1 = 0x0002; /* clear timer event */
-
- return timer_interrupt(irq, dummy);
-}
-
-static struct irqaction m68360_timer_irq = {
- .name = "timer",
- .flags = IRQF_TIMER,
- .handler = hw_tick,
-};
-
-void hw_timer_init(irq_handler_t handler)
-{
- unsigned char prescaler;
- unsigned short tgcr_save;
-
-#if 0
- /* Restart mode, Enable int, 32KHz, Enable timer */
- TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
- /* Set prescaler (Divide 32KHz by 32)*/
- TPRER = 31;
- /* Set compare register 32Khz / 32 / 10 = 100 */
- TCMP = 10;
-
- request_irq(IRQ_MACHSPEC | 1, timer_routine, 0, "timer", NULL);
-#endif
-
- /* General purpose quicc timers: MC68360UM p7-20 */
-
- /* Set up timer 1 (in [1..4]) to do 100Hz */
- tgcr_save = pquicc->timer_tgcr & 0xfff0;
- pquicc->timer_tgcr = tgcr_save; /* stop and reset timer 1 */
- /* pquicc->timer_tgcr |= 0x4444; */ /* halt timers when FREEZE (ie bdm freeze) */
-
- prescaler = 8;
- pquicc->timer_tmr1 = 0x001a | /* or=1, frr=1, iclk=01b */
- (unsigned short)((prescaler - 1) << 8);
-
- pquicc->timer_tcn1 = 0x0000; /* initial count */
- /* calculate interval for 100Hz based on the _system_clock: */
- pquicc->timer_trr1 = (system_clock/ prescaler) / HZ; /* reference count */
-
- pquicc->timer_ter1 = 0x0003; /* clear timer events */
-
- timer_interrupt = handler;
-
- /* enable timer 1 interrupt in CIMR */
- setup_irq(CPMVEC_TIMER1, &m68360_timer_irq);
-
- /* Start timer 1: */
- tgcr_save = (pquicc->timer_tgcr & 0xfff0) | 0x0001;
- pquicc->timer_tgcr = tgcr_save;
-}
-
-void BSP_reset (void)
-{
- local_irq_disable();
- asm volatile (
- "moveal #_start, %a0;\n"
- "moveb #0, 0xFFFFF300;\n"
- "moveal 0(%a0), %sp;\n"
- "moveal 4(%a0), %a0;\n"
- "jmp (%a0);\n"
- );
-}
-
-unsigned char *scc1_hwaddr;
-static int errno;
-
-#if defined (CONFIG_UCQUICC)
-_bsc0(char *, getserialnum)
-_bsc1(unsigned char *, gethwaddr, int, a)
-_bsc1(char *, getbenv, char *, a)
-#endif
-
-
-void __init config_BSP(char *command, int len)
-{
- unsigned char *p;
-
- m360_cpm_reset();
-
- /* Calculate the real system clock value. */
- {
- unsigned int local_pllcr = (unsigned int)(pquicc->sim_pllcr);
- if( local_pllcr & MCU_PREEN ) // If the prescaler is dividing by 128
- {
- int mf = (int)(pquicc->sim_pllcr & 0x0fff);
- system_clock = (OSCILLATOR / 128) * (mf + 1);
- }
- else
- {
- int mf = (int)(pquicc->sim_pllcr & 0x0fff);
- system_clock = (OSCILLATOR) * (mf + 1);
- }
- }
-
- printk(KERN_INFO "\n68360 QUICC support (C) 2000 Lineo Inc.\n");
-
-#if defined(CONFIG_UCQUICC) && 0
- printk(KERN_INFO "uCquicc serial string [%s]\n",getserialnum());
- p = scc1_hwaddr = gethwaddr(0);
- printk(KERN_INFO "uCquicc hwaddr %pM\n", p);
-
- p = getbenv("APPEND");
- if (p)
- strcpy(p,command);
- else
- command[0] = 0;
-#else
- scc1_hwaddr = "\00\01\02\03\04\05";
-#endif
-
- mach_reset = BSP_reset;
-}
diff --git a/arch/m68k/68360/entry.S b/arch/m68k/68360/entry.S
deleted file mode 100644
index 22eb302..0000000
--- a/arch/m68k/68360/entry.S
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * entry.S - non-mmu 68360 interrupt and exceptions entry points
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 2001 SED Systems, a Division of Calian Ltd.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
- * Linux/m68k support by Hamish Macdonald
- * M68360 Port by SED Systems, and Lineo.
- */
-
-#include <linux/linkage.h>
-#include <asm/thread_info.h>
-#include <asm/unistd.h>
-#include <asm/errno.h>
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/traps.h>
-#include <asm/asm-offsets.h>
-#include <asm/entry.h>
-
-.text
-
-.globl system_call
-.globl resume
-.globl ret_from_exception
-.globl ret_from_signal
-.globl sys_call_table
-.globl bad_interrupt
-.globl inthandler
-
-badsys:
- movel #-ENOSYS,%sp@(PT_OFF_D0)
- jra ret_from_exception
-
-do_trace:
- movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
- subql #4,%sp
- SAVE_SWITCH_STACK
- jbsr syscall_trace_enter
- RESTORE_SWITCH_STACK
- addql #4,%sp
- movel %sp@(PT_OFF_ORIG_D0),%d1
- movel #-ENOSYS,%d0
- cmpl #NR_syscalls,%d1
- jcc 1f
- lsl #2,%d1
- lea sys_call_table, %a0
- jbsr %a0@(%d1)
-
-1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
- subql #4,%sp /* dummy return address */
- SAVE_SWITCH_STACK
- jbsr syscall_trace_leave
-
-ret_from_signal:
- RESTORE_SWITCH_STACK
- addql #4,%sp
- jra ret_from_exception
-
-ENTRY(system_call)
- SAVE_ALL_SYS
-
- /* save top of frame*/
- pea %sp@
- jbsr set_esp0
- addql #4,%sp
-
- movel %sp@(PT_OFF_ORIG_D0),%d0
-
- movel %sp,%d1 /* get thread_info pointer */
- andl #-THREAD_SIZE,%d1
- movel %d1,%a2
- btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
- jne do_trace
- cmpl #NR_syscalls,%d0
- jcc badsys
- lsl #2,%d0
- lea sys_call_table,%a0
- movel %a0@(%d0), %a0
- jbsr %a0@
- movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
-
-ret_from_exception:
- btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
- jeq Luser_return /* if so, skip resched, signals*/
-
-Lkernel_return:
- RESTORE_ALL
-
-Luser_return:
- /* only allow interrupts when we are really the last one on the*/
- /* kernel stack, otherwise stack overflow can occur during*/
- /* heavy interrupt load*/
- andw #ALLOWINT,%sr
-
- movel %sp,%d1 /* get thread_info pointer */
- andl #-THREAD_SIZE,%d1
- movel %d1,%a2
-1:
- move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
- jne Lwork_to_do
- RESTORE_ALL
-
-Lwork_to_do:
- movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
- btst #TIF_NEED_RESCHED,%d1
- jne reschedule
-
-Lsignal_return:
- subql #4,%sp /* dummy return address*/
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- bsrw do_notify_resume
- addql #4,%sp
- RESTORE_SWITCH_STACK
- addql #4,%sp
- jra 1b
-
-/*
- * This is the main interrupt handler, responsible for calling do_IRQ()
- */
-inthandler:
- SAVE_ALL_INT
- movew %sp@(PT_OFF_FORMATVEC), %d0
- and.l #0x3ff, %d0
- lsr.l #0x02, %d0
-
- movel %sp,%sp@-
- movel %d0,%sp@- /* put vector # on stack*/
- jbsr do_IRQ /* process the IRQ */
- addql #8,%sp /* pop parameters off stack*/
- jra ret_from_exception
-
-/*
- * Handler for uninitialized and spurious interrupts.
- */
-bad_interrupt:
- addql #1,irq_err_count
- rte
-
-/*
- * Beware - when entering resume, prev (the current task) is
- * in a0, next (the new task) is in a1, so don't change these
- * registers until their contents are no longer needed.
- */
-ENTRY(resume)
- movel %a0,%d1 /* save prev thread in d1 */
- movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
- SAVE_SWITCH_STACK
- movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
- movel %usp,%a3 /* save usp */
- movel %a3,%a0@(TASK_THREAD+THREAD_USP)
-
- movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
- movel %a3,%usp
- movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
- RESTORE_SWITCH_STACK
- movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
- rts
-
diff --git a/arch/m68k/68360/head-ram.S b/arch/m68k/68360/head-ram.S
deleted file mode 100644
index 62bc56f..0000000
--- a/arch/m68k/68360/head-ram.S
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * head-ram.S - startup code for Motorola 68360
- *
- * Copyright 2001 (C) SED Systems, a Division of Calian Ltd.
- * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
- * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
- * uClinux Kernel
- * Copyright (C) Michael Leslie <mleslie@lineo.com>
- * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
- * Copyright (C) 1998 D. Jeff Dionne <jeff@uclinux.org>,
- *
- */
-#define ASSEMBLY
-
-.global _stext
-.global _start
-
-.global _rambase
-.global _ramvec
-.global _ramstart
-.global _ramend
-
-.global _quicc_base
-.global _periph_base
-
-#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE)
-#define ROMEND (CONFIG_ROMBASE + CONFIG_ROMSIZE)
-
-#define REGB 0x1000
-#define PEPAR (_dprbase + REGB + 0x0016)
-#define GMR (_dprbase + REGB + 0x0040)
-#define OR0 (_dprbase + REGB + 0x0054)
-#define BR0 (_dprbase + REGB + 0x0050)
-#define OR1 (_dprbase + REGB + 0x0064)
-#define BR1 (_dprbase + REGB + 0x0060)
-#define OR4 (_dprbase + REGB + 0x0094)
-#define BR4 (_dprbase + REGB + 0x0090)
-#define OR6 (_dprbase + REGB + 0x00b4)
-#define BR6 (_dprbase + REGB + 0x00b0)
-#define OR7 (_dprbase + REGB + 0x00c4)
-#define BR7 (_dprbase + REGB + 0x00c0)
-
-#define MCR (_dprbase + REGB + 0x0000)
-#define AVR (_dprbase + REGB + 0x0008)
-
-#define SYPCR (_dprbase + REGB + 0x0022)
-
-#define PLLCR (_dprbase + REGB + 0x0010)
-#define CLKOCR (_dprbase + REGB + 0x000C)
-#define CDVCR (_dprbase + REGB + 0x0014)
-
-#define BKAR (_dprbase + REGB + 0x0030)
-#define BKCR (_dprbase + REGB + 0x0034)
-#define SWIV (_dprbase + REGB + 0x0023)
-#define PICR (_dprbase + REGB + 0x0026)
-#define PITR (_dprbase + REGB + 0x002A)
-
-/* Define for all memory configuration */
-#define MCU_SIM_GMR 0x00000000
-#define SIM_OR_MASK 0x0fffffff
-
-/* Defines for chip select zero - the flash */
-#define SIM_OR0_MASK 0x20000002
-#define SIM_BR0_MASK 0x00000001
-
-
-/* Defines for chip select one - the RAM */
-#define SIM_OR1_MASK 0x10000000
-#define SIM_BR1_MASK 0x00000001
-
-#define MCU_SIM_MBAR_ADRS 0x0003ff00
-#define MCU_SIM_MBAR_BA_MASK 0xfffff000
-#define MCU_SIM_MBAR_AS_MASK 0x00000001
-
-#define MCU_SIM_PEPAR 0x00B4
-
-#define MCU_DISABLE_INTRPTS 0x2700
-#define MCU_SIM_AVR 0x00
-
-#define MCU_SIM_MCR 0x00005cff
-
-#define MCU_SIM_CLKOCR 0x00
-#define MCU_SIM_PLLCR 0x8000
-#define MCU_SIM_CDVCR 0x0000
-
-#define MCU_SIM_SYPCR 0x0000
-#define MCU_SIM_SWIV 0x00
-#define MCU_SIM_PICR 0x0000
-#define MCU_SIM_PITR 0x0000
-
-
-#include <asm/m68360_regs.h>
-
-
-/*
- * By the time this RAM specific code begins to execute, DPRAM
- * and DRAM should already be mapped and accessible.
- */
-
- .text
-_start:
-_stext:
- nop
- ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */
- /* We should not need to setup the boot stack the reset should do it. */
- movea.l #RAMEND, %sp /*set up stack at the end of DRAM:*/
-
-set_mbar_register:
- moveq.l #0x07, %d1 /* Setup MBAR */
- movec %d1, %dfc
-
- lea.l MCU_SIM_MBAR_ADRS, %a0
- move.l #_dprbase, %d0
- andi.l #MCU_SIM_MBAR_BA_MASK, %d0
- ori.l #MCU_SIM_MBAR_AS_MASK, %d0
- moves.l %d0, %a0@
-
- moveq.l #0x05, %d1
- movec.l %d1, %dfc
-
- /* Now we can begin to access registers in DPRAM */
-
-set_sim_mcr:
- /* Set Module Configuration Register */
- move.l #MCU_SIM_MCR, MCR
-
- /* to do: Determine cause of reset */
-
- /*
- * configure system clock MC68360 p. 6-40
- * (value +1)*osc/128 = system clock
- */
-set_sim_clock:
- move.w #MCU_SIM_PLLCR, PLLCR
- move.b #MCU_SIM_CLKOCR, CLKOCR
- move.w #MCU_SIM_CDVCR, CDVCR
-
- /* Wait for the PLL to settle */
- move.w #16384, %d0
-pll_settle_wait:
- subi.w #1, %d0
- bne pll_settle_wait
-
- /* Setup the system protection register, and watchdog timer register */
- move.b #MCU_SIM_SWIV, SWIV
- move.w #MCU_SIM_PICR, PICR
- move.w #MCU_SIM_PITR, PITR
- move.w #MCU_SIM_SYPCR, SYPCR
-
- /* Clear DPRAM - system + parameter */
- movea.l #_dprbase, %a0
- movea.l #_dprbase+0x2000, %a1
-
- /* Copy 0 to %a0 until %a0 == %a1 */
-clear_dpram:
- movel #0, %a0@+
- cmpal %a0, %a1
- bhi clear_dpram
-
-configure_memory_controller:
- /* Set up Global Memory Register (GMR) */
- move.l #MCU_SIM_GMR, %d0
- move.l %d0, GMR
-
-configure_chip_select_0:
- move.l #RAMEND, %d0
- subi.l #__ramstart, %d0
- subq.l #0x01, %d0
- eori.l #SIM_OR_MASK, %d0
- ori.l #SIM_OR0_MASK, %d0
- move.l %d0, OR0
-
- move.l #__ramstart, %d0
- ori.l #SIM_BR0_MASK, %d0
- move.l %d0, BR0
-
-configure_chip_select_1:
- move.l #ROMEND, %d0
- subi.l #__rom_start, %d0
- subq.l #0x01, %d0
- eori.l #SIM_OR_MASK, %d0
- ori.l #SIM_OR1_MASK, %d0
- move.l %d0, OR1
-
- move.l #__rom_start, %d0
- ori.l #SIM_BR1_MASK, %d0
- move.l %d0, BR1
-
- move.w #MCU_SIM_PEPAR, PEPAR
-
- /* point to vector table: */
- move.l #_romvec, %a0
- move.l #_ramvec, %a1
-copy_vectors:
- move.l %a0@, %d0
- move.l %d0, %a1@
- move.l %a0@, %a1@
- addq.l #0x04, %a0
- addq.l #0x04, %a1
- cmp.l #_start, %a0
- blt copy_vectors
-
- move.l #_ramvec, %a1
- movec %a1, %vbr
-
-
- /* Copy data segment from ROM to RAM */
- moveal #_stext, %a0
- moveal #_sdata, %a1
- moveal #_edata, %a2
-
- /* Copy %a0 to %a1 until %a1 == %a2 */
-LD1:
- move.l %a0@, %d0
- addq.l #0x04, %a0
- move.l %d0, %a1@
- addq.l #0x04, %a1
- cmp.l #_edata, %a1
- blt LD1
-
- moveal #__bss_start, %a0
- moveal #__bss_stop, %a1
-
- /* Copy 0 to %a0 until %a0 == %a1 */
-L1:
- movel #0, %a0@+
- cmpal %a0, %a1
- bhi L1
-
-load_quicc:
- move.l #_dprbase, _quicc_base
-
-store_ram_size:
- /* Set ram size information */
- move.l #_sdata, _rambase
- move.l #__bss_stop, _ramstart
- move.l #RAMEND, %d0
- sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/
- move.l %d0, _ramend /* Different from RAMEND.*/
-
- pea 0
- pea env
- pea %sp@(4)
- pea 0
-
- lea init_thread_union, %a2
- lea 0x2000(%a2), %sp
-
-lp:
- jsr start_kernel
-
-_exit:
- jmp _exit
-
-
- .data
- .align 4
-env:
- .long 0
-_quicc_base:
- .long 0
-_periph_base:
- .long 0
-_ramvec:
- .long 0
-_rambase:
- .long 0
-_ramstart:
- .long 0
-_ramend:
- .long 0
-_dprbase:
- .long 0xffffe000
-
- .text
-
- /*
- * These are the exception vectors at boot up, they are copied into RAM
- * and then overwritten as needed.
- */
-
-.section ".data..initvect","awx"
- .long RAMEND /* Reset: Initial Stack Pointer - 0. */
- .long _start /* Reset: Initial Program Counter - 1. */
- .long buserr /* Bus Error - 2. */
- .long trap /* Address Error - 3. */
- .long trap /* Illegal Instruction - 4. */
- .long trap /* Divide by zero - 5. */
- .long trap /* CHK, CHK2 Instructions - 6. */
- .long trap /* TRAPcc, TRAPV Instructions - 7. */
- .long trap /* Privilege Violation - 8. */
- .long trap /* Trace - 9. */
- .long trap /* Line 1010 Emulator - 10. */
- .long trap /* Line 1111 Emualtor - 11. */
- .long trap /* Harware Breakpoint - 12. */
- .long trap /* (Reserved for Coprocessor Protocol Violation)- 13. */
- .long trap /* Format Error - 14. */
- .long trap /* Uninitialized Interrupt - 15. */
- .long trap /* (Unassigned, Reserver) - 16. */
- .long trap /* (Unassigned, Reserver) - 17. */
- .long trap /* (Unassigned, Reserver) - 18. */
- .long trap /* (Unassigned, Reserver) - 19. */
- .long trap /* (Unassigned, Reserver) - 20. */
- .long trap /* (Unassigned, Reserver) - 21. */
- .long trap /* (Unassigned, Reserver) - 22. */
- .long trap /* (Unassigned, Reserver) - 23. */
- .long trap /* Spurious Interrupt - 24. */
- .long trap /* Level 1 Interrupt Autovector - 25. */
- .long trap /* Level 2 Interrupt Autovector - 26. */
- .long trap /* Level 3 Interrupt Autovector - 27. */
- .long trap /* Level 4 Interrupt Autovector - 28. */
- .long trap /* Level 5 Interrupt Autovector - 29. */
- .long trap /* Level 6 Interrupt Autovector - 30. */
- .long trap /* Level 7 Interrupt Autovector - 31. */
- .long system_call /* Trap Instruction Vectors 0 - 32. */
- .long trap /* Trap Instruction Vectors 1 - 33. */
- .long trap /* Trap Instruction Vectors 2 - 34. */
- .long trap /* Trap Instruction Vectors 3 - 35. */
- .long trap /* Trap Instruction Vectors 4 - 36. */
- .long trap /* Trap Instruction Vectors 5 - 37. */
- .long trap /* Trap Instruction Vectors 6 - 38. */
- .long trap /* Trap Instruction Vectors 7 - 39. */
- .long trap /* Trap Instruction Vectors 8 - 40. */
- .long trap /* Trap Instruction Vectors 9 - 41. */
- .long trap /* Trap Instruction Vectors 10 - 42. */
- .long trap /* Trap Instruction Vectors 11 - 43. */
- .long trap /* Trap Instruction Vectors 12 - 44. */
- .long trap /* Trap Instruction Vectors 13 - 45. */
- .long trap /* Trap Instruction Vectors 14 - 46. */
- .long trap /* Trap Instruction Vectors 15 - 47. */
- .long 0 /* (Reserved for Coprocessor) - 48. */
- .long 0 /* (Reserved for Coprocessor) - 49. */
- .long 0 /* (Reserved for Coprocessor) - 50. */
- .long 0 /* (Reserved for Coprocessor) - 51. */
- .long 0 /* (Reserved for Coprocessor) - 52. */
- .long 0 /* (Reserved for Coprocessor) - 53. */
- .long 0 /* (Reserved for Coprocessor) - 54. */
- .long 0 /* (Reserved for Coprocessor) - 55. */
- .long 0 /* (Reserved for Coprocessor) - 56. */
- .long 0 /* (Reserved for Coprocessor) - 57. */
- .long 0 /* (Reserved for Coprocessor) - 58. */
- .long 0 /* (Unassigned, Reserved) - 59. */
- .long 0 /* (Unassigned, Reserved) - 60. */
- .long 0 /* (Unassigned, Reserved) - 61. */
- .long 0 /* (Unassigned, Reserved) - 62. */
- .long 0 /* (Unassigned, Reserved) - 63. */
- /* The assignment of these vectors to the CPM is */
- /* dependent on the configuration of the CPM vba */
- /* fields. */
- .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */
- .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
- .long 0 /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
- .long 0 /* (User-Defined Vectors 4) CPM SMC2 / PIP - 67. */
- .long 0 /* (User-Defined Vectors 5) CPM SMC1 - 68. */
- .long 0 /* (User-Defined Vectors 6) CPM SPI - 69. */
- .long 0 /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
- .long 0 /* (User-Defined Vectors 8) CPM Timer 4 - 71. */
- .long 0 /* (User-Defined Vectors 9) CPM Reserved - 72. */
- .long 0 /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
- .long 0 /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
- .long 0 /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
- .long 0 /* (User-Defined Vectors 13) CPM Timer 3 - 76. */
- .long 0 /* (User-Defined Vectors 14) CPM Reserved - 77. */
- .long 0 /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
- .long 0 /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
- .long 0 /* (User-Defined Vectors 17) CPM Reserved - 80. */
- .long 0 /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
- .long 0 /* (User-Defined Vectors 19) CPM Timer 2 - 82. */
- .long 0 /* (User-Defined Vectors 21) CPM Reserved - 83. */
- .long 0 /* (User-Defined Vectors 22) CPM IDMA2 - 84. */
- .long 0 /* (User-Defined Vectors 23) CPM IDMA1 - 85. */
- .long 0 /* (User-Defined Vectors 24) CPM SDMA Bus Err - 86. */
- .long 0 /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
- .long 0 /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
- .long 0 /* (User-Defined Vectors 27) CPM Timer 1 - 89. */
- .long 0 /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
- .long 0 /* (User-Defined Vectors 29) CPM SCC 4 - 91. */
- .long 0 /* (User-Defined Vectors 30) CPM SCC 3 - 92. */
- .long 0 /* (User-Defined Vectors 31) CPM SCC 2 - 93. */
- .long 0 /* (User-Defined Vectors 32) CPM SCC 1 - 94. */
- .long 0 /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
- /* I don't think anything uses the vectors after here. */
- .long 0 /* (User-Defined Vectors 34) - 96. */
- .long 0,0,0,0,0 /* (User-Defined Vectors 35 - 39). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 40 - 49). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 50 - 59). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 60 - 69). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 70 - 79). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 80 - 89). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 90 - 99). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 100 - 109). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 110 - 119). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 120 - 129). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 130 - 139). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 140 - 149). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 150 - 159). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 160 - 169). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 170 - 179). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 180 - 189). */
- .long 0,0,0 /* (User-Defined Vectors 190 - 192). */
-.text
-ignore: rte
diff --git a/arch/m68k/68360/head-rom.S b/arch/m68k/68360/head-rom.S
deleted file mode 100644
index b3a7e40..0000000
--- a/arch/m68k/68360/head-rom.S
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * head-rom.S - startup code for Motorola 68360
- *
- * Copyright (C) SED Systems, a Division of Calian Ltd.
- * Based on: arch/m68knommu/platform/68328/pilot/crt0_rom.S
- * Based on: arch/m68knommu/platform/68360/uCquicc/crt0_rom.S, 2.0.38.1.pre7
- * uClinux Kernel
- * Copyright (C) Michael Leslie <mleslie@lineo.com>
- * Based on: arch/m68knommu/platform/68EZ328/ucsimm/crt0_rom.S
- * Copyright (C) 1998 D. Jeff Dionne <jeff@uclinux.org>,
- *
- */
-
-.global _stext
-.global __bss_start
-.global _start
-
-.global _rambase
-.global _ramvec
-.global _ramstart
-.global _ramend
-
-.global _quicc_base
-.global _periph_base
-
-#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE)
-
-#define REGB 0x1000
-#define PEPAR (_dprbase + REGB + 0x0016)
-#define GMR (_dprbase + REGB + 0x0040)
-#define OR0 (_dprbase + REGB + 0x0054)
-#define BR0 (_dprbase + REGB + 0x0050)
-
-#define OR1 (_dprbase + REGB + 0x0064)
-#define BR1 (_dprbase + REGB + 0x0060)
-
-#define OR2 (_dprbase + REGB + 0x0074)
-#define BR2 (_dprbase + REGB + 0x0070)
-
-#define OR3 (_dprbase + REGB + 0x0084)
-#define BR3 (_dprbase + REGB + 0x0080)
-
-#define OR4 (_dprbase + REGB + 0x0094)
-#define BR4 (_dprbase + REGB + 0x0090)
-
-#define OR5 (_dprbase + REGB + 0x00A4)
-#define BR5 (_dprbase + REGB + 0x00A0)
-
-#define OR6 (_dprbase + REGB + 0x00b4)
-#define BR6 (_dprbase + REGB + 0x00b0)
-
-#define OR7 (_dprbase + REGB + 0x00c4)
-#define BR7 (_dprbase + REGB + 0x00c0)
-
-#define MCR (_dprbase + REGB + 0x0000)
-#define AVR (_dprbase + REGB + 0x0008)
-
-#define SYPCR (_dprbase + REGB + 0x0022)
-
-#define PLLCR (_dprbase + REGB + 0x0010)
-#define CLKOCR (_dprbase + REGB + 0x000C)
-#define CDVCR (_dprbase + REGB + 0x0014)
-
-#define BKAR (_dprbase + REGB + 0x0030)
-#define BKCR (_dprbase + REGB + 0x0034)
-#define SWIV (_dprbase + REGB + 0x0023)
-#define PICR (_dprbase + REGB + 0x0026)
-#define PITR (_dprbase + REGB + 0x002A)
-
-/* Define for all memory configuration */
-#define MCU_SIM_GMR 0x00000000
-#define SIM_OR_MASK 0x0fffffff
-
-/* Defines for chip select zero - the flash */
-#define SIM_OR0_MASK 0x20000000
-#define SIM_BR0_MASK 0x00000001
-
-/* Defines for chip select one - the RAM */
-#define SIM_OR1_MASK 0x10000000
-#define SIM_BR1_MASK 0x00000001
-
-#define MCU_SIM_MBAR_ADRS 0x0003ff00
-#define MCU_SIM_MBAR_BA_MASK 0xfffff000
-#define MCU_SIM_MBAR_AS_MASK 0x00000001
-
-#define MCU_SIM_PEPAR 0x00B4
-
-#define MCU_DISABLE_INTRPTS 0x2700
-#define MCU_SIM_AVR 0x00
-
-#define MCU_SIM_MCR 0x00005cff
-
-#define MCU_SIM_CLKOCR 0x00
-#define MCU_SIM_PLLCR 0x8000
-#define MCU_SIM_CDVCR 0x0000
-
-#define MCU_SIM_SYPCR 0x0000
-#define MCU_SIM_SWIV 0x00
-#define MCU_SIM_PICR 0x0000
-#define MCU_SIM_PITR 0x0000
-
-
-#include <asm/m68360_regs.h>
-
-
-/*
- * By the time this RAM specific code begins to execute, DPRAM
- * and DRAM should already be mapped and accessible.
- */
-
- .text
-_start:
-_stext:
- nop
- ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */
- /* We should not need to setup the boot stack the reset should do it. */
- movea.l #RAMEND, %sp /* set up stack at the end of DRAM:*/
-
-
-set_mbar_register:
- moveq.l #0x07, %d1 /* Setup MBAR */
- movec %d1, %dfc
-
- lea.l MCU_SIM_MBAR_ADRS, %a0
- move.l #_dprbase, %d0
- andi.l #MCU_SIM_MBAR_BA_MASK, %d0
- ori.l #MCU_SIM_MBAR_AS_MASK, %d0
- moves.l %d0, %a0@
-
- moveq.l #0x05, %d1
- movec.l %d1, %dfc
-
- /* Now we can begin to access registers in DPRAM */
-
-set_sim_mcr:
- /* Set Module Configuration Register */
- move.l #MCU_SIM_MCR, MCR
-
- /* to do: Determine cause of reset */
-
- /*
- * configure system clock MC68360 p. 6-40
- * (value +1)*osc/128 = system clock
- * or
- * (value + 1)*osc = system clock
- * You do not need to divide the oscillator by 128 unless you want to.
- */
-set_sim_clock:
- move.w #MCU_SIM_PLLCR, PLLCR
- move.b #MCU_SIM_CLKOCR, CLKOCR
- move.w #MCU_SIM_CDVCR, CDVCR
-
- /* Wait for the PLL to settle */
- move.w #16384, %d0
-pll_settle_wait:
- subi.w #1, %d0
- bne pll_settle_wait
-
- /* Setup the system protection register, and watchdog timer register */
- move.b #MCU_SIM_SWIV, SWIV
- move.w #MCU_SIM_PICR, PICR
- move.w #MCU_SIM_PITR, PITR
- move.w #MCU_SIM_SYPCR, SYPCR
-
- /* Clear DPRAM - system + parameter */
- movea.l #_dprbase, %a0
- movea.l #_dprbase+0x2000, %a1
-
- /* Copy 0 to %a0 until %a0 == %a1 */
-clear_dpram:
- movel #0, %a0@+
- cmpal %a0, %a1
- bhi clear_dpram
-
-configure_memory_controller:
- /* Set up Global Memory Register (GMR) */
- move.l #MCU_SIM_GMR, %d0
- move.l %d0, GMR
-
-configure_chip_select_0:
- move.l #0x00400000, %d0
- subq.l #0x01, %d0
- eori.l #SIM_OR_MASK, %d0
- ori.l #SIM_OR0_MASK, %d0
- move.l %d0, OR0
-
- move.l #__rom_start, %d0
- ori.l #SIM_BR0_MASK, %d0
- move.l %d0, BR0
-
- move.l #0x0, BR1
- move.l #0x0, BR2
- move.l #0x0, BR3
- move.l #0x0, BR4
- move.l #0x0, BR5
- move.l #0x0, BR6
- move.l #0x0, BR7
-
- move.w #MCU_SIM_PEPAR, PEPAR
-
- /* point to vector table: */
- move.l #_romvec, %a0
- move.l #_ramvec, %a1
-copy_vectors:
- move.l %a0@, %d0
- move.l %d0, %a1@
- move.l %a0@, %a1@
- addq.l #0x04, %a0
- addq.l #0x04, %a1
- cmp.l #_start, %a0
- blt copy_vectors
-
- move.l #_ramvec, %a1
- movec %a1, %vbr
-
-
- /* Copy data segment from ROM to RAM */
- moveal #_etext, %a0
- moveal #_sdata, %a1
- moveal #_edata, %a2
-
- /* Copy %a0 to %a1 until %a1 == %a2 */
-LD1:
- move.l %a0@, %d0
- addq.l #0x04, %a0
- move.l %d0, %a1@
- addq.l #0x04, %a1
- cmp.l #_edata, %a1
- blt LD1
-
- moveal #__bss_start, %a0
- moveal #__bss_stop, %a1
-
- /* Copy 0 to %a0 until %a0 == %a1 */
-L1:
- movel #0, %a0@+
- cmpal %a0, %a1
- bhi L1
-
-load_quicc:
- move.l #_dprbase, _quicc_base
-
-store_ram_size:
- /* Set ram size information */
- move.l #_sdata, _rambase
- move.l #__bss_stop, _ramstart
- move.l #RAMEND, %d0
- sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/
- move.l %d0, _ramend /* Different from RAMEND.*/
-
- pea 0
- pea env
- pea %sp@(4)
- pea 0
-
- lea init_thread_union, %a2
- lea 0x2000(%a2), %sp
-
-lp:
- jsr start_kernel
-
-_exit:
- jmp _exit
-
-
- .data
- .align 4
-env:
- .long 0
-_quicc_base:
- .long 0
-_periph_base:
- .long 0
-_ramvec:
- .long 0
-_rambase:
- .long 0
-_ramstart:
- .long 0
-_ramend:
- .long 0
-_dprbase:
- .long 0xffffe000
-
-
- .text
-
- /*
- * These are the exception vectors at boot up, they are copied into RAM
- * and then overwritten as needed.
- */
-
-.section ".data..initvect","awx"
- .long RAMEND /* Reset: Initial Stack Pointer - 0. */
- .long _start /* Reset: Initial Program Counter - 1. */
- .long buserr /* Bus Error - 2. */
- .long trap /* Address Error - 3. */
- .long trap /* Illegal Instruction - 4. */
- .long trap /* Divide by zero - 5. */
- .long trap /* CHK, CHK2 Instructions - 6. */
- .long trap /* TRAPcc, TRAPV Instructions - 7. */
- .long trap /* Privilege Violation - 8. */
- .long trap /* Trace - 9. */
- .long trap /* Line 1010 Emulator - 10. */
- .long trap /* Line 1111 Emualtor - 11. */
- .long trap /* Harware Breakpoint - 12. */
- .long trap /* (Reserved for Coprocessor Protocol Violation)- 13. */
- .long trap /* Format Error - 14. */
- .long trap /* Uninitialized Interrupt - 15. */
- .long trap /* (Unassigned, Reserver) - 16. */
- .long trap /* (Unassigned, Reserver) - 17. */
- .long trap /* (Unassigned, Reserver) - 18. */
- .long trap /* (Unassigned, Reserver) - 19. */
- .long trap /* (Unassigned, Reserver) - 20. */
- .long trap /* (Unassigned, Reserver) - 21. */
- .long trap /* (Unassigned, Reserver) - 22. */
- .long trap /* (Unassigned, Reserver) - 23. */
- .long trap /* Spurious Interrupt - 24. */
- .long trap /* Level 1 Interrupt Autovector - 25. */
- .long trap /* Level 2 Interrupt Autovector - 26. */
- .long trap /* Level 3 Interrupt Autovector - 27. */
- .long trap /* Level 4 Interrupt Autovector - 28. */
- .long trap /* Level 5 Interrupt Autovector - 29. */
- .long trap /* Level 6 Interrupt Autovector - 30. */
- .long trap /* Level 7 Interrupt Autovector - 31. */
- .long system_call /* Trap Instruction Vectors 0 - 32. */
- .long trap /* Trap Instruction Vectors 1 - 33. */
- .long trap /* Trap Instruction Vectors 2 - 34. */
- .long trap /* Trap Instruction Vectors 3 - 35. */
- .long trap /* Trap Instruction Vectors 4 - 36. */
- .long trap /* Trap Instruction Vectors 5 - 37. */
- .long trap /* Trap Instruction Vectors 6 - 38. */
- .long trap /* Trap Instruction Vectors 7 - 39. */
- .long trap /* Trap Instruction Vectors 8 - 40. */
- .long trap /* Trap Instruction Vectors 9 - 41. */
- .long trap /* Trap Instruction Vectors 10 - 42. */
- .long trap /* Trap Instruction Vectors 11 - 43. */
- .long trap /* Trap Instruction Vectors 12 - 44. */
- .long trap /* Trap Instruction Vectors 13 - 45. */
- .long trap /* Trap Instruction Vectors 14 - 46. */
- .long trap /* Trap Instruction Vectors 15 - 47. */
- .long 0 /* (Reserved for Coprocessor) - 48. */
- .long 0 /* (Reserved for Coprocessor) - 49. */
- .long 0 /* (Reserved for Coprocessor) - 50. */
- .long 0 /* (Reserved for Coprocessor) - 51. */
- .long 0 /* (Reserved for Coprocessor) - 52. */
- .long 0 /* (Reserved for Coprocessor) - 53. */
- .long 0 /* (Reserved for Coprocessor) - 54. */
- .long 0 /* (Reserved for Coprocessor) - 55. */
- .long 0 /* (Reserved for Coprocessor) - 56. */
- .long 0 /* (Reserved for Coprocessor) - 57. */
- .long 0 /* (Reserved for Coprocessor) - 58. */
- .long 0 /* (Unassigned, Reserved) - 59. */
- .long 0 /* (Unassigned, Reserved) - 60. */
- .long 0 /* (Unassigned, Reserved) - 61. */
- .long 0 /* (Unassigned, Reserved) - 62. */
- .long 0 /* (Unassigned, Reserved) - 63. */
- /* The assignment of these vectors to the CPM is */
- /* dependent on the configuration of the CPM vba */
- /* fields. */
- .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */
- .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
- .long 0 /* (User-Defined Vectors 3) CPM Parallel IO PC10- 66. */
- .long 0 /* (User-Defined Vectors 4) CPM SMC2 / PIP - 67. */
- .long 0 /* (User-Defined Vectors 5) CPM SMC1 - 68. */
- .long 0 /* (User-Defined Vectors 6) CPM SPI - 69. */
- .long 0 /* (User-Defined Vectors 7) CPM Parallel IO PC9 - 70. */
- .long 0 /* (User-Defined Vectors 8) CPM Timer 4 - 71. */
- .long 0 /* (User-Defined Vectors 9) CPM Reserved - 72. */
- .long 0 /* (User-Defined Vectors 10) CPM Parallel IO PC8- 73. */
- .long 0 /* (User-Defined Vectors 11) CPM Parallel IO PC7- 74. */
- .long 0 /* (User-Defined Vectors 12) CPM Parallel IO PC6- 75. */
- .long 0 /* (User-Defined Vectors 13) CPM Timer 3 - 76. */
- .long 0 /* (User-Defined Vectors 14) CPM Reserved - 77. */
- .long 0 /* (User-Defined Vectors 15) CPM Parallel IO PC5- 78. */
- .long 0 /* (User-Defined Vectors 16) CPM Parallel IO PC4- 79. */
- .long 0 /* (User-Defined Vectors 17) CPM Reserved - 80. */
- .long 0 /* (User-Defined Vectors 18) CPM RISC Timer Tbl - 81. */
- .long 0 /* (User-Defined Vectors 19) CPM Timer 2 - 82. */
- .long 0 /* (User-Defined Vectors 21) CPM Reserved - 83. */
- .long 0 /* (User-Defined Vectors 22) CPM IDMA2 - 84. */
- .long 0 /* (User-Defined Vectors 23) CPM IDMA1 - 85. */
- .long 0 /* (User-Defined Vectors 24) CPM SDMA Bus Err - 86. */
- .long 0 /* (User-Defined Vectors 25) CPM Parallel IO PC3- 87. */
- .long 0 /* (User-Defined Vectors 26) CPM Parallel IO PC2- 88. */
- .long 0 /* (User-Defined Vectors 27) CPM Timer 1 - 89. */
- .long 0 /* (User-Defined Vectors 28) CPM Parallel IO PC1- 90. */
- .long 0 /* (User-Defined Vectors 29) CPM SCC 4 - 91. */
- .long 0 /* (User-Defined Vectors 30) CPM SCC 3 - 92. */
- .long 0 /* (User-Defined Vectors 31) CPM SCC 2 - 93. */
- .long 0 /* (User-Defined Vectors 32) CPM SCC 1 - 94. */
- .long 0 /* (User-Defined Vectors 33) CPM Parallel IO PC0- 95. */
- /* I don't think anything uses the vectors after here. */
- .long 0 /* (User-Defined Vectors 34) - 96. */
- .long 0,0,0,0,0 /* (User-Defined Vectors 35 - 39). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 40 - 49). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 50 - 59). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 60 - 69). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 70 - 79). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 80 - 89). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 90 - 99). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 100 - 109). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 110 - 119). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 120 - 129). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 130 - 139). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 140 - 149). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 150 - 159). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 160 - 169). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 170 - 179). */
- .long 0,0,0,0,0,0,0,0,0,0 /* (User-Defined Vectors 180 - 189). */
- .long 0,0,0 /* (User-Defined Vectors 190 - 192). */
-.text
-ignore: rte
diff --git a/arch/m68k/68360/ints.c b/arch/m68k/68360/ints.c
deleted file mode 100644
index 2360fc0..0000000
--- a/arch/m68k/68360/ints.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * ints.c - first level interrupt handlers
- *
- * 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) 2000 Michael Leslie <mleslie@lineo.com>
- * Copyright (c) 1996 Roman Zippel
- * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org>
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/m68360.h>
-
-/* from quicc/commproc.c: */
-extern QUICC *pquicc;
-extern void cpm_interrupt_init(void);
-
-#define INTERNAL_IRQS (96)
-
-/* assembler routines */
-asmlinkage void system_call(void);
-asmlinkage void buserr(void);
-asmlinkage void trap(void);
-asmlinkage void bad_interrupt(void);
-asmlinkage void inthandler(void);
-
-static void intc_irq_unmask(struct irq_data *d)
-{
- pquicc->intr_cimr |= (1 << d->irq);
-}
-
-static void intc_irq_mask(struct irq_data *d)
-{
- pquicc->intr_cimr &= ~(1 << d->irq);
-}
-
-static void intc_irq_ack(struct irq_data *d)
-{
- pquicc->intr_cisr = (1 << d->irq);
-}
-
-static struct irq_chip intc_irq_chip = {
- .name = "M68K-INTC",
- .irq_mask = intc_irq_mask,
- .irq_unmask = intc_irq_unmask,
- .irq_ack = intc_irq_ack,
-};
-
-/*
- * This function should be called during kernel startup to initialize
- * the vector table.
- */
-void __init trap_init(void)
-{
- int vba = (CPM_VECTOR_BASE<<4);
-
- /* set up the vectors */
- _ramvec[2] = buserr;
- _ramvec[3] = trap;
- _ramvec[4] = trap;
- _ramvec[5] = trap;
- _ramvec[6] = trap;
- _ramvec[7] = trap;
- _ramvec[8] = trap;
- _ramvec[9] = trap;
- _ramvec[10] = trap;
- _ramvec[11] = trap;
- _ramvec[12] = trap;
- _ramvec[13] = trap;
- _ramvec[14] = trap;
- _ramvec[15] = trap;
-
- _ramvec[32] = system_call;
- _ramvec[33] = trap;
-
- cpm_interrupt_init();
-
- /* set up CICR for vector base address and irq level */
- /* irl = 4, hp = 1f - see MC68360UM p 7-377 */
- pquicc->intr_cicr = 0x00e49f00 | vba;
-
- /* CPM interrupt vectors: (p 7-376) */
- _ramvec[vba+CPMVEC_ERROR] = bad_interrupt; /* Error */
- _ramvec[vba+CPMVEC_PIO_PC11] = inthandler; /* pio - pc11 */
- _ramvec[vba+CPMVEC_PIO_PC10] = inthandler; /* pio - pc10 */
- _ramvec[vba+CPMVEC_SMC2] = inthandler; /* smc2/pip */
- _ramvec[vba+CPMVEC_SMC1] = inthandler; /* smc1 */
- _ramvec[vba+CPMVEC_SPI] = inthandler; /* spi */
- _ramvec[vba+CPMVEC_PIO_PC9] = inthandler; /* pio - pc9 */
- _ramvec[vba+CPMVEC_TIMER4] = inthandler; /* timer 4 */
- _ramvec[vba+CPMVEC_RESERVED1] = inthandler; /* reserved */
- _ramvec[vba+CPMVEC_PIO_PC8] = inthandler; /* pio - pc8 */
- _ramvec[vba+CPMVEC_PIO_PC7] = inthandler; /* pio - pc7 */
- _ramvec[vba+CPMVEC_PIO_PC6] = inthandler; /* pio - pc6 */
- _ramvec[vba+CPMVEC_TIMER3] = inthandler; /* timer 3 */
- _ramvec[vba+CPMVEC_PIO_PC5] = inthandler; /* pio - pc5 */
- _ramvec[vba+CPMVEC_PIO_PC4] = inthandler; /* pio - pc4 */
- _ramvec[vba+CPMVEC_RESERVED2] = inthandler; /* reserved */
- _ramvec[vba+CPMVEC_RISCTIMER] = inthandler; /* timer table */
- _ramvec[vba+CPMVEC_TIMER2] = inthandler; /* timer 2 */
- _ramvec[vba+CPMVEC_RESERVED3] = inthandler; /* reserved */
- _ramvec[vba+CPMVEC_IDMA2] = inthandler; /* idma 2 */
- _ramvec[vba+CPMVEC_IDMA1] = inthandler; /* idma 1 */
- _ramvec[vba+CPMVEC_SDMA_CB_ERR] = inthandler; /* sdma channel bus error */
- _ramvec[vba+CPMVEC_PIO_PC3] = inthandler; /* pio - pc3 */
- _ramvec[vba+CPMVEC_PIO_PC2] = inthandler; /* pio - pc2 */
- /* _ramvec[vba+CPMVEC_TIMER1] = cpm_isr_timer1; */ /* timer 1 */
- _ramvec[vba+CPMVEC_TIMER1] = inthandler; /* timer 1 */
- _ramvec[vba+CPMVEC_PIO_PC1] = inthandler; /* pio - pc1 */
- _ramvec[vba+CPMVEC_SCC4] = inthandler; /* scc 4 */
- _ramvec[vba+CPMVEC_SCC3] = inthandler; /* scc 3 */
- _ramvec[vba+CPMVEC_SCC2] = inthandler; /* scc 2 */
- _ramvec[vba+CPMVEC_SCC1] = inthandler; /* scc 1 */
- _ramvec[vba+CPMVEC_PIO_PC0] = inthandler; /* pio - pc0 */
-
-
- /* turn off all CPM interrupts */
- pquicc->intr_cimr = 0x00000000;
-}
-
-void init_IRQ(void)
-{
- int i;
-
- for (i = 0; (i < NR_IRQS); i++) {
- irq_set_chip(i, &intc_irq_chip);
- irq_set_handler(i, handle_level_irq);
- }
-}
-
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index c496d48..0dfcf12 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -114,13 +114,6 @@ config M68VZ328
help
Motorola 68VZ328 processor support.
-config M68360
- bool "MC68360"
- depends on !MMU
- select MCPU32
- help
- Motorola 68360 processor support.
-
endif # M68KCLASSIC
if COLDFIRE
diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug
index 64776d7..50a67d0 100644
--- a/arch/m68k/Kconfig.debug
+++ b/arch/m68k/Kconfig.debug
@@ -12,7 +12,7 @@ config BOOTPARAM_STRING
config EARLY_PRINTK
bool "Early printk"
- depends on !(SUN3 || M68360 || M68000 || COLDFIRE)
+ depends on !(SUN3 || M68000 || COLDFIRE)
help
Write kernel log output directly to a serial port.
Where implemented, output goes to the framebuffer as well.
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 61dc643..2a5c7ab 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -187,12 +187,6 @@ config MEMORY_RESERVE
help
Reserve certain memory regions on 68x328 based boards.
-config UCQUICC
- bool "Lineo uCquicc board support"
- depends on M68360
- help
- Support for the Lineo uCquicc board.
-
config ARN5206
bool "Arnewsh 5206 board support"
depends on M5206
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index 0b29dcf..f0dd9fc 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -39,7 +39,6 @@ cpuflags-$(CONFIG_M68040) := -m68040
endif
cpuflags-$(CONFIG_M68030) :=
cpuflags-$(CONFIG_M68020) :=
-cpuflags-$(CONFIG_M68360) := -m68332
cpuflags-$(CONFIG_M68000) := -m68000
cpuflags-$(CONFIG_M5441x) := $(call cc-option,-mcpu=54455,-mcfv4e)
cpuflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200)
@@ -92,7 +91,6 @@ endif
#
head-y := arch/m68k/kernel/head.o
head-$(CONFIG_SUN3) := arch/m68k/kernel/sun3-head.o
-head-$(CONFIG_M68360) := arch/m68k/68360/head.o
head-$(CONFIG_M68000) := arch/m68k/68000/head.o
head-$(CONFIG_COLDFIRE) := arch/m68k/coldfire/head.o
@@ -114,7 +112,6 @@ core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
-core-$(CONFIG_M68360) += arch/m68k/68360/
core-$(CONFIG_M68000) += arch/m68k/68000/
core-$(CONFIG_COLDFIRE) += arch/m68k/coldfire/
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 192b00f..cbd5991 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -858,7 +858,7 @@ static struct platform_device *atari_netusbee_devices[] __initdata = {
};
#endif /* CONFIG_ATARI_ETHERNEC */
-#ifdef CONFIG_ATARI_SCSI
+#if IS_ENABLED(CONFIG_ATARI_SCSI)
static const struct resource atari_scsi_st_rsrc[] __initconst = {
{
.flags = IORESOURCE_IRQ,
@@ -910,7 +910,7 @@ int __init atari_platform_init(void)
}
#endif
-#ifdef CONFIG_ATARI_SCSI
+#if IS_ENABLED(CONFIG_ATARI_SCSI)
if (ATARIHW_PRESENT(ST_SCSI))
platform_device_register_simple("atari_scsi", -1,
atari_scsi_st_rsrc, ARRAY_SIZE(atari_scsi_st_rsrc));
diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
index 71ea4c0..a0fc0c1 100644
--- a/arch/m68k/coldfire/device.c
+++ b/arch/m68k/coldfire/device.c
@@ -89,7 +89,7 @@ static struct platform_device mcf_uart = {
.dev.platform_data = mcf_uart_platform_data,
};
-#ifdef CONFIG_FEC
+#if IS_ENABLED(CONFIG_FEC)
#ifdef CONFIG_M5441x
#define FEC_NAME "enet-fec"
@@ -329,7 +329,7 @@ static struct platform_device mcf_qspi = {
static struct platform_device *mcf_devices[] __initdata = {
&mcf_uart,
-#ifdef CONFIG_FEC
+#if IS_ENABLED(CONFIG_FEC)
&mcf_fec0,
#ifdef MCFFEC_BASE1
&mcf_fec1,
diff --git a/arch/m68k/coldfire/gpio.c b/arch/m68k/coldfire/gpio.c
index e7e4286..8832083 100644
--- a/arch/m68k/coldfire/gpio.c
+++ b/arch/m68k/coldfire/gpio.c
@@ -121,7 +121,7 @@ static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
{
- return __mcfgpio_get_value(offset);
+ return !!__mcfgpio_get_value(offset);
}
static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
@@ -178,7 +178,7 @@ static struct gpio_chip mcfgpio_chip = {
static int __init mcfgpio_sysinit(void)
{
- gpiochip_add(&mcfgpio_chip);
+ gpiochip_add_data(&mcfgpio_chip, NULL);
return subsys_system_register(&mcfgpio_subsys, NULL);
}
diff --git a/arch/m68k/coldfire/m54xx.c b/arch/m68k/coldfire/m54xx.c
index f7836c6..c32f767 100644
--- a/arch/m68k/coldfire/m54xx.c
+++ b/arch/m68k/coldfire/m54xx.c
@@ -98,7 +98,7 @@ static void __init mcf54xx_bootmem_alloc(void)
memstart = PAGE_ALIGN(_ramstart);
min_low_pfn = PFN_DOWN(_rambase);
start_pfn = PFN_DOWN(memstart);
- max_low_pfn = PFN_DOWN(_ramend);
+ max_pfn = max_low_pfn = PFN_DOWN(_ramend);
high_memory = (void *)_ramend;
m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6;
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 5b4ec54..d1fc479 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -108,6 +108,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -266,6 +268,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -276,6 +284,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -365,6 +374,7 @@ CONFIG_ARIADNE=y
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
CONFIG_HYDRA=y
CONFIG_APNE=y
CONFIG_ZORRO8390=y
@@ -532,11 +542,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -559,6 +571,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 6e5198e..9bfe8be 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -264,6 +266,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -274,6 +282,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -343,6 +352,7 @@ CONFIG_VETH=m
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -372,6 +382,7 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=m
CONFIG_SERIO=m
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
@@ -490,11 +501,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -517,6 +530,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index f75600b..ebdcfae 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -264,6 +266,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -274,6 +282,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -352,6 +361,7 @@ CONFIG_ATARILANCE=y
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
CONFIG_NE2000=y
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
@@ -512,11 +522,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -539,6 +551,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index a42d91c..8acc65e 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -262,6 +264,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -272,6 +280,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -342,6 +351,7 @@ CONFIG_BVME6000_NET=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -483,11 +493,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -510,6 +522,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 77f4a11..0c6a3d5 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -106,6 +106,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -264,6 +266,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -274,6 +282,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -344,6 +353,7 @@ CONFIG_HPLANCE=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -375,6 +385,7 @@ CONFIG_MOUSE_SERIAL=m
CONFIG_INPUT_MISC=y
CONFIG_HP_SDC_RTC=m
CONFIG_SERIO_SERPORT=m
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
@@ -492,11 +503,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -519,6 +532,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 5a329f7..12a8a6c 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -105,6 +105,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -266,6 +268,12 @@ CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -276,6 +284,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -361,6 +370,7 @@ CONFIG_MAC89x0=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
CONFIG_MACSONIC=y
+# CONFIG_NET_VENDOR_NETRONOME is not set
CONFIG_MAC8390=y
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
@@ -394,6 +404,7 @@ CONFIG_MOUSE_SERIAL=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_M68K_BEEP=m
CONFIG_SERIO=m
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_PMACZILOG=y
@@ -514,11 +525,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -541,6 +554,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 83c80d2..64ff2dc 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -115,6 +115,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -276,6 +278,12 @@ CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -286,6 +294,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -403,6 +412,7 @@ CONFIG_MVME16x_NET=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
CONFIG_MACSONIC=y
+# CONFIG_NET_VENDOR_NETRONOME is not set
CONFIG_HYDRA=y
CONFIG_MAC8390=y
CONFIG_NE2000=y
@@ -449,6 +459,7 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_M68K_BEEP=m
CONFIG_HP_SDC_RTC=m
CONFIG_SERIO_Q40KBD=y
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_PMACZILOG=y
@@ -594,11 +605,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -621,6 +634,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 6cb42c3..07fc6ab 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -103,6 +103,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -261,6 +263,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -271,6 +279,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -342,6 +351,7 @@ CONFIG_MVME147_NET=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -483,11 +493,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -510,6 +522,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index c7508c3..69903de 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -262,6 +264,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -272,6 +280,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -342,6 +351,7 @@ CONFIG_MVME16x_NET=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -483,11 +493,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -510,6 +522,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 64b7166..bd84016 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -104,6 +104,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -262,6 +264,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -272,6 +280,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -351,6 +360,7 @@ CONFIG_VETH=m
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
CONFIG_NE2000=y
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
@@ -385,6 +395,7 @@ CONFIG_MOUSE_SERIAL=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_M68K_BEEP=m
CONFIG_SERIO_Q40KBD=y
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_PRINTER=m
@@ -505,11 +516,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -532,6 +545,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 9a4cab7..5f9fb3a 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -101,6 +101,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -259,6 +261,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -269,6 +277,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -339,6 +348,7 @@ CONFIG_SUN3_82586=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -369,6 +379,7 @@ CONFIG_INPUT_EVDEV=m
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=m
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
@@ -484,11 +495,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -510,6 +523,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 1a2eaac..5d1c674 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -101,6 +101,8 @@ CONFIG_NFT_NAT=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -259,6 +261,12 @@ CONFIG_L2TP=m
CONFIG_BRIDGE=m
CONFIG_ATALK=m
CONFIG_6LOWPAN=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
+CONFIG_6LOWPAN_GHC_UDP=m
+CONFIG_6LOWPAN_GHC_ICMPV6=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=m
CONFIG_BATMAN_ADV_DAT=y
@@ -269,6 +277,7 @@ CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=m
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_L3_MASTER_DEV=y
# CONFIG_WIRELESS is not set
# CONFIG_UEVENT_HELPER is not set
CONFIG_DEVTMPFS=y
@@ -340,6 +349,7 @@ CONFIG_SUN3LANCE=y
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
@@ -369,6 +379,7 @@ CONFIG_INPUT_EVDEV=m
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=m
+CONFIG_USERIO=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
@@ -484,11 +495,13 @@ CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_TEST_HEXDUMP=m
CONFIG_TEST_STRING_HELPERS=m
CONFIG_TEST_KSTRTOX=m
+CONFIG_TEST_PRINTF=m
CONFIG_TEST_RHASHTABLE=m
CONFIG_TEST_LKM=m
CONFIG_TEST_USER_COPY=m
@@ -511,6 +524,7 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index f2a00c5..e9110b9 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -59,7 +59,7 @@ struct nfhd_device {
struct gendisk *disk;
};
-static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
+static blk_qc_t nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
struct bio_vec bvec;
@@ -77,6 +77,7 @@ static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
sec += len;
}
bio_endio(bio);
+ return BLK_QC_T_NONE;
}
static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
diff --git a/arch/m68k/include/asm/MC68328.h b/arch/m68k/include/asm/MC68328.h
index 4ebf098..1a8080c 100644
--- a/arch/m68k/include/asm/MC68328.h
+++ b/arch/m68k/include/asm/MC68328.h
@@ -798,7 +798,7 @@
/**********
*
- * 0xFFFFF7xx -- Serial Periferial Interface Slave (SPIS)
+ * 0xFFFFF7xx -- Serial Peripheral Interface Slave (SPIS)
*
**********/
@@ -824,7 +824,7 @@
/**********
*
- * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ * 0xFFFFF8xx -- Serial Peripheral Interface Master (SPIM)
*
**********/
@@ -904,7 +904,7 @@
#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */
#define UBAUD_PRESCALER_SHIFT 0
-#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divisor */
#define UBAUD_DIVIDE_SHIFT 8
#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */
#define UBAUD_GPIOSRC 0x1000 /* GPIO source */
diff --git a/arch/m68k/include/asm/MC68EZ328.h b/arch/m68k/include/asm/MC68EZ328.h
index d1bde58..fedac87 100644
--- a/arch/m68k/include/asm/MC68EZ328.h
+++ b/arch/m68k/include/asm/MC68EZ328.h
@@ -631,7 +631,7 @@
/**********
*
- * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ * 0xFFFFF8xx -- Serial Peripheral Interface Master (SPIM)
*
**********/
@@ -712,7 +712,7 @@
#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */
#define UBAUD_PRESCALER_SHIFT 0
-#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divisor */
#define UBAUD_DIVIDE_SHIFT 8
#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */
#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */
@@ -1160,7 +1160,7 @@ typedef volatile struct {
#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */
#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */
#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */
-#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */
+#define DRAMMC_REF_MASK 0x001f /* Refresh Cycle */
#define DRAMMC_REF_SHIFT 0
/*
diff --git a/arch/m68k/include/asm/MC68VZ328.h b/arch/m68k/include/asm/MC68VZ328.h
index 6bd1bf1..34a51b2 100644
--- a/arch/m68k/include/asm/MC68VZ328.h
+++ b/arch/m68k/include/asm/MC68VZ328.h
@@ -724,7 +724,7 @@
/**********
*
- * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM)
+ * 0xFFFFF8xx -- Serial Peripheral Interface Master (SPIM)
*
**********/
@@ -806,7 +806,7 @@
#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */
#define UBAUD_PRESCALER_SHIFT 0
-#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */
+#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divisor */
#define UBAUD_DIVIDE_SHIFT 8
#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */
#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */
@@ -1256,7 +1256,7 @@ typedef struct {
#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */
#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */
#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */
-#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */
+#define DRAMMC_REF_MASK 0x001f /* Refresh Cycle */
#define DRAMMC_REF_SHIFT 0
/*
diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h
index 039fac1..4858178 100644
--- a/arch/m68k/include/asm/atomic.h
+++ b/arch/m68k/include/asm/atomic.h
@@ -17,8 +17,8 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
/*
* The ColdFire parts cannot do some immediate to memory operations,
diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h
index 2f88d86..75e91f0 100644
--- a/arch/m68k/include/asm/checksum.h
+++ b/arch/m68k/include/asm/checksum.h
@@ -117,7 +117,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
diff --git a/arch/m68k/include/asm/commproc.h b/arch/m68k/include/asm/commproc.h
deleted file mode 100644
index f41c968..0000000
--- a/arch/m68k/include/asm/commproc.h
+++ /dev/null
@@ -1,664 +0,0 @@
-
-/*
- * 68360 Communication Processor Module.
- * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com> (mc68360) after:
- * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> (mpc8xx)
- *
- * This file contains structures and information for the communication
- * processor channels. Some CPM control and status is available
- * through the 68360 internal memory map. See include/asm/360_immap.h for details.
- * This file is not a complete map of all of the 360 QUICC's capabilities
- *
- * On the MBX board, EPPC-Bug loads CPM microcode into the first 512
- * bytes of the DP RAM and relocates the I2C parameter area to the
- * IDMA1 space. The remaining DP RAM is available for buffer descriptors
- * or other use.
- */
-#ifndef __CPM_360__
-#define __CPM_360__
-
-
-/* CPM Command register masks: */
-#define CPM_CR_RST ((ushort)0x8000)
-#define CPM_CR_OPCODE ((ushort)0x0f00)
-#define CPM_CR_CHAN ((ushort)0x00f0)
-#define CPM_CR_FLG ((ushort)0x0001)
-
-/* CPM Command set (opcodes): */
-#define CPM_CR_INIT_TRX ((ushort)0x0000)
-#define CPM_CR_INIT_RX ((ushort)0x0001)
-#define CPM_CR_INIT_TX ((ushort)0x0002)
-#define CPM_CR_HUNT_MODE ((ushort)0x0003)
-#define CPM_CR_STOP_TX ((ushort)0x0004)
-#define CPM_CR_GRSTOP_TX ((ushort)0x0005)
-#define CPM_CR_RESTART_TX ((ushort)0x0006)
-#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
-#define CPM_CR_SET_GADDR ((ushort)0x0008)
-#define CPM_CR_GCI_TIMEOUT ((ushort)0x0009)
-#define CPM_CR_GCI_ABORT ((ushort)0x000a)
-#define CPM_CR_RESET_BCS ((ushort)0x000a)
-
-/* CPM Channel numbers. */
-#define CPM_CR_CH_SCC1 ((ushort)0x0000)
-#define CPM_CR_CH_SCC2 ((ushort)0x0004)
-#define CPM_CR_CH_SPI ((ushort)0x0005) /* SPI / Timers */
-#define CPM_CR_CH_TMR ((ushort)0x0005)
-#define CPM_CR_CH_SCC3 ((ushort)0x0008)
-#define CPM_CR_CH_SMC1 ((ushort)0x0009) /* SMC1 / IDMA1 */
-#define CPM_CR_CH_IDMA1 ((ushort)0x0009)
-#define CPM_CR_CH_SCC4 ((ushort)0x000c)
-#define CPM_CR_CH_SMC2 ((ushort)0x000d) /* SMC2 / IDMA2 */
-#define CPM_CR_CH_IDMA2 ((ushort)0x000d)
-
-
-#define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4))
-
-#if 1 /* mleslie: I dinna think we have any such restrictions on
- * DP RAM aboard the 360 board - see the MC68360UM p.3-3 */
-
-/* The dual ported RAM is multi-functional. Some areas can be (and are
- * being) used for microcode. There is an area that can only be used
- * as data ram for buffer descriptors, which is all we use right now.
- * Currently the first 512 and last 256 bytes are used for microcode.
- */
-/* mleslie: The uCquicc board is using no extra microcode in DPRAM */
-#define CPM_DATAONLY_BASE ((uint)0x0000)
-#define CPM_DATAONLY_SIZE ((uint)0x0800)
-#define CPM_DP_NOSPACE ((uint)0x7fffffff)
-
-#endif
-
-
-/* Export the base address of the communication processor registers
- * and dual port ram. */
-/* extern cpm360_t *cpmp; */ /* Pointer to comm processor */
-extern QUICC *pquicc;
-uint m360_cpm_dpalloc(uint size);
-/* void *m360_cpm_hostalloc(uint size); */
-void m360_cpm_setbrg(uint brg, uint rate);
-
-#if 0 /* use QUICC_BD declared in include/asm/m68360_quicc.h */
-/* Buffer descriptors used by many of the CPM protocols. */
-typedef struct cpm_buf_desc {
- ushort cbd_sc; /* Status and Control */
- ushort cbd_datlen; /* Data length in buffer */
- uint cbd_bufaddr; /* Buffer address in host memory */
-} cbd_t;
-#endif
-
-
-/* rx bd status/control bits */
-#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */
-#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor in table */
-#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */
-#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame OR control char */
-
-#define BD_SC_FIRST ((ushort)0x0400) /* 1st buffer in an HDLC frame */
-#define BD_SC_ADDR ((ushort)0x0400) /* 1st byte is a multidrop address */
-
-#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */
-#define BD_SC_ID ((ushort)0x0100) /* Received too many idles */
-
-#define BD_SC_AM ((ushort)0x0080) /* Multidrop address match */
-#define BD_SC_DE ((ushort)0x0080) /* DPLL Error (HDLC) */
-
-#define BD_SC_BR ((ushort)0x0020) /* Break received */
-#define BD_SC_LG ((ushort)0x0020) /* Frame length violation (HDLC) */
-
-#define BD_SC_FR ((ushort)0x0010) /* Framing error */
-#define BD_SC_NO ((ushort)0x0010) /* Nonoctet aligned frame (HDLC) */
-
-#define BD_SC_PR ((ushort)0x0008) /* Parity error */
-#define BD_SC_AB ((ushort)0x0008) /* Received abort Sequence (HDLC) */
-
-#define BD_SC_OV ((ushort)0x0002) /* Overrun */
-#define BD_SC_CD ((ushort)0x0001) /* Carrier Detect lost */
-
-/* tx bd status/control bits (as differ from rx bd) */
-#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */
-#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */
-#define BD_SC_P ((ushort)0x0100) /* xmt preamble */
-#define BD_SC_UN ((ushort)0x0002) /* Underrun */
-
-
-
-
-/* Parameter RAM offsets. */
-
-
-
-/* In 2.4 ppc, the PROFF_S?C? are used as byte offsets into DPRAM.
- * In 2.0, we use a more structured C struct map of DPRAM, and so
- * instead, we need only a parameter ram `slot' */
-
-#define PRSLOT_SCC1 0
-#define PRSLOT_SCC2 1
-#define PRSLOT_SCC3 2
-#define PRSLOT_SMC1 2
-#define PRSLOT_SCC4 3
-#define PRSLOT_SMC2 3
-
-
-/* #define PROFF_SCC1 ((uint)0x0000) */
-/* #define PROFF_SCC2 ((uint)0x0100) */
-/* #define PROFF_SCC3 ((uint)0x0200) */
-/* #define PROFF_SMC1 ((uint)0x0280) */
-/* #define PROFF_SCC4 ((uint)0x0300) */
-/* #define PROFF_SMC2 ((uint)0x0380) */
-
-
-/* Define enough so I can at least use the serial port as a UART.
- * The MBX uses SMC1 as the host serial port.
- */
-typedef struct smc_uart {
- ushort smc_rbase; /* Rx Buffer descriptor base address */
- ushort smc_tbase; /* Tx Buffer descriptor base address */
- u_char smc_rfcr; /* Rx function code */
- u_char smc_tfcr; /* Tx function code */
- ushort smc_mrblr; /* Max receive buffer length */
- uint smc_rstate; /* Internal */
- uint smc_idp; /* Internal */
- ushort smc_rbptr; /* Internal */
- ushort smc_ibc; /* Internal */
- uint smc_rxtmp; /* Internal */
- uint smc_tstate; /* Internal */
- uint smc_tdp; /* Internal */
- ushort smc_tbptr; /* Internal */
- ushort smc_tbc; /* Internal */
- uint smc_txtmp; /* Internal */
- ushort smc_maxidl; /* Maximum idle characters */
- ushort smc_tmpidl; /* Temporary idle counter */
- ushort smc_brklen; /* Last received break length */
- ushort smc_brkec; /* rcv'd break condition counter */
- ushort smc_brkcr; /* xmt break count register */
- ushort smc_rmask; /* Temporary bit mask */
-} smc_uart_t;
-
-/* Function code bits.
-*/
-#define SMC_EB ((u_char)0x10) /* Set big endian byte order */
-
-/* SMC uart mode register.
-*/
-#define SMCMR_REN ((ushort)0x0001)
-#define SMCMR_TEN ((ushort)0x0002)
-#define SMCMR_DM ((ushort)0x000c)
-#define SMCMR_SM_GCI ((ushort)0x0000)
-#define SMCMR_SM_UART ((ushort)0x0020)
-#define SMCMR_SM_TRANS ((ushort)0x0030)
-#define SMCMR_SM_MASK ((ushort)0x0030)
-#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */
-#define SMCMR_REVD SMCMR_PM_EVEN
-#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */
-#define SMCMR_BS SMCMR_PEN
-#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */
-#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */
-#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK)
-
-/* SMC2 as Centronics parallel printer. It is half duplex, in that
- * it can only receive or transmit. The parameter ram values for
- * each direction are either unique or properly overlap, so we can
- * include them in one structure.
- */
-typedef struct smc_centronics {
- ushort scent_rbase;
- ushort scent_tbase;
- u_char scent_cfcr;
- u_char scent_smask;
- ushort scent_mrblr;
- uint scent_rstate;
- uint scent_r_ptr;
- ushort scent_rbptr;
- ushort scent_r_cnt;
- uint scent_rtemp;
- uint scent_tstate;
- uint scent_t_ptr;
- ushort scent_tbptr;
- ushort scent_t_cnt;
- uint scent_ttemp;
- ushort scent_max_sl;
- ushort scent_sl_cnt;
- ushort scent_character1;
- ushort scent_character2;
- ushort scent_character3;
- ushort scent_character4;
- ushort scent_character5;
- ushort scent_character6;
- ushort scent_character7;
- ushort scent_character8;
- ushort scent_rccm;
- ushort scent_rccr;
-} smc_cent_t;
-
-/* Centronics Status Mask Register.
-*/
-#define SMC_CENT_F ((u_char)0x08)
-#define SMC_CENT_PE ((u_char)0x04)
-#define SMC_CENT_S ((u_char)0x02)
-
-/* SMC Event and Mask register.
-*/
-#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */
-#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */
-#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */
-#define SMCM_BSY ((unsigned char)0x04)
-#define SMCM_TX ((unsigned char)0x02)
-#define SMCM_RX ((unsigned char)0x01)
-
-/* Baud rate generators.
-*/
-#define CPM_BRG_RST ((uint)0x00020000)
-#define CPM_BRG_EN ((uint)0x00010000)
-#define CPM_BRG_EXTC_INT ((uint)0x00000000)
-#define CPM_BRG_EXTC_CLK2 ((uint)0x00004000)
-#define CPM_BRG_EXTC_CLK6 ((uint)0x00008000)
-#define CPM_BRG_ATB ((uint)0x00002000)
-#define CPM_BRG_CD_MASK ((uint)0x00001ffe)
-#define CPM_BRG_DIV16 ((uint)0x00000001)
-
-/* SCCs.
-*/
-#define SCC_GSMRH_IRP ((uint)0x00040000)
-#define SCC_GSMRH_GDE ((uint)0x00010000)
-#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000)
-#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000)
-#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000)
-#define SCC_GSMRH_REVD ((uint)0x00002000)
-#define SCC_GSMRH_TRX ((uint)0x00001000)
-#define SCC_GSMRH_TTX ((uint)0x00000800)
-#define SCC_GSMRH_CDP ((uint)0x00000400)
-#define SCC_GSMRH_CTSP ((uint)0x00000200)
-#define SCC_GSMRH_CDS ((uint)0x00000100)
-#define SCC_GSMRH_CTSS ((uint)0x00000080)
-#define SCC_GSMRH_TFL ((uint)0x00000040)
-#define SCC_GSMRH_RFW ((uint)0x00000020)
-#define SCC_GSMRH_TXSY ((uint)0x00000010)
-#define SCC_GSMRH_SYNL16 ((uint)0x0000000c)
-#define SCC_GSMRH_SYNL8 ((uint)0x00000008)
-#define SCC_GSMRH_SYNL4 ((uint)0x00000004)
-#define SCC_GSMRH_RTSM ((uint)0x00000002)
-#define SCC_GSMRH_RSYN ((uint)0x00000001)
-
-#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */
-#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000)
-#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000)
-#define SCC_GSMRL_EDGE_POS ((uint)0x20000000)
-#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000)
-#define SCC_GSMRL_TCI ((uint)0x10000000)
-#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000)
-#define SCC_GSMRL_TSNC_4 ((uint)0x08000000)
-#define SCC_GSMRL_TSNC_14 ((uint)0x04000000)
-#define SCC_GSMRL_TSNC_INF ((uint)0x00000000)
-#define SCC_GSMRL_RINV ((uint)0x02000000)
-#define SCC_GSMRL_TINV ((uint)0x01000000)
-#define SCC_GSMRL_TPL_128 ((uint)0x00c00000)
-#define SCC_GSMRL_TPL_64 ((uint)0x00a00000)
-#define SCC_GSMRL_TPL_48 ((uint)0x00800000)
-#define SCC_GSMRL_TPL_32 ((uint)0x00600000)
-#define SCC_GSMRL_TPL_16 ((uint)0x00400000)
-#define SCC_GSMRL_TPL_8 ((uint)0x00200000)
-#define SCC_GSMRL_TPL_NONE ((uint)0x00000000)
-#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000)
-#define SCC_GSMRL_TPP_01 ((uint)0x00100000)
-#define SCC_GSMRL_TPP_10 ((uint)0x00080000)
-#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000)
-#define SCC_GSMRL_TEND ((uint)0x00040000)
-#define SCC_GSMRL_TDCR_32 ((uint)0x00030000)
-#define SCC_GSMRL_TDCR_16 ((uint)0x00020000)
-#define SCC_GSMRL_TDCR_8 ((uint)0x00010000)
-#define SCC_GSMRL_TDCR_1 ((uint)0x00000000)
-#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000)
-#define SCC_GSMRL_RDCR_16 ((uint)0x00008000)
-#define SCC_GSMRL_RDCR_8 ((uint)0x00004000)
-#define SCC_GSMRL_RDCR_1 ((uint)0x00000000)
-#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000)
-#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000)
-#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000)
-#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800)
-#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000)
-#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600)
-#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400)
-#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200)
-#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100)
-#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000)
-#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */
-#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080)
-#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040)
-#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000)
-#define SCC_GSMRL_ENR ((uint)0x00000020)
-#define SCC_GSMRL_ENT ((uint)0x00000010)
-#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c)
-#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009)
-#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008)
-#define SCC_GSMRL_MODE_V14 ((uint)0x00000007)
-#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006)
-#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005)
-#define SCC_GSMRL_MODE_UART ((uint)0x00000004)
-#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003)
-#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002)
-#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000)
-
-#define SCC_TODR_TOD ((ushort)0x8000)
-
-/* SCC Event and Mask register.
-*/
-#define SCCM_TXE ((unsigned char)0x10)
-#define SCCM_BSY ((unsigned char)0x04)
-#define SCCM_TX ((unsigned char)0x02)
-#define SCCM_RX ((unsigned char)0x01)
-
-typedef struct scc_param {
- ushort scc_rbase; /* Rx Buffer descriptor base address */
- ushort scc_tbase; /* Tx Buffer descriptor base address */
- u_char scc_rfcr; /* Rx function code */
- u_char scc_tfcr; /* Tx function code */
- ushort scc_mrblr; /* Max receive buffer length */
- uint scc_rstate; /* Internal */
- uint scc_idp; /* Internal */
- ushort scc_rbptr; /* Internal */
- ushort scc_ibc; /* Internal */
- uint scc_rxtmp; /* Internal */
- uint scc_tstate; /* Internal */
- uint scc_tdp; /* Internal */
- ushort scc_tbptr; /* Internal */
- ushort scc_tbc; /* Internal */
- uint scc_txtmp; /* Internal */
- uint scc_rcrc; /* Internal */
- uint scc_tcrc; /* Internal */
-} sccp_t;
-
-
-/* Function code bits.
- */
-#define SCC_EB ((u_char)0x10) /* Set big endian byte order */
-#define SCC_FC_DMA ((u_char)0x08) /* Set SDMA */
-
-/* CPM Ethernet through SCC1.
- */
-typedef struct scc_enet {
- sccp_t sen_genscc;
- uint sen_cpres; /* Preset CRC */
- uint sen_cmask; /* Constant mask for CRC */
- uint sen_crcec; /* CRC Error counter */
- uint sen_alec; /* alignment error counter */
- uint sen_disfc; /* discard frame counter */
- ushort sen_pads; /* Tx short frame pad character */
- ushort sen_retlim; /* Retry limit threshold */
- ushort sen_retcnt; /* Retry limit counter */
- ushort sen_maxflr; /* maximum frame length register */
- ushort sen_minflr; /* minimum frame length register */
- ushort sen_maxd1; /* maximum DMA1 length */
- ushort sen_maxd2; /* maximum DMA2 length */
- ushort sen_maxd; /* Rx max DMA */
- ushort sen_dmacnt; /* Rx DMA counter */
- ushort sen_maxb; /* Max BD byte count */
- ushort sen_gaddr1; /* Group address filter */
- ushort sen_gaddr2;
- ushort sen_gaddr3;
- ushort sen_gaddr4;
- uint sen_tbuf0data0; /* Save area 0 - current frame */
- uint sen_tbuf0data1; /* Save area 1 - current frame */
- uint sen_tbuf0rba; /* Internal */
- uint sen_tbuf0crc; /* Internal */
- ushort sen_tbuf0bcnt; /* Internal */
- ushort sen_paddrh; /* physical address (MSB) */
- ushort sen_paddrm;
- ushort sen_paddrl; /* physical address (LSB) */
- ushort sen_pper; /* persistence */
- ushort sen_rfbdptr; /* Rx first BD pointer */
- ushort sen_tfbdptr; /* Tx first BD pointer */
- ushort sen_tlbdptr; /* Tx last BD pointer */
- uint sen_tbuf1data0; /* Save area 0 - current frame */
- uint sen_tbuf1data1; /* Save area 1 - current frame */
- uint sen_tbuf1rba; /* Internal */
- uint sen_tbuf1crc; /* Internal */
- ushort sen_tbuf1bcnt; /* Internal */
- ushort sen_txlen; /* Tx Frame length counter */
- ushort sen_iaddr1; /* Individual address filter */
- ushort sen_iaddr2;
- ushort sen_iaddr3;
- ushort sen_iaddr4;
- ushort sen_boffcnt; /* Backoff counter */
-
- /* NOTE: Some versions of the manual have the following items
- * incorrectly documented. Below is the proper order.
- */
- ushort sen_taddrh; /* temp address (MSB) */
- ushort sen_taddrm;
- ushort sen_taddrl; /* temp address (LSB) */
-} scc_enet_t;
-
-
-
-#if defined (CONFIG_UCQUICC)
-/* uCquicc has the following signals connected to Ethernet:
- * 68360 - lxt905
- * PA0/RXD1 - rxd
- * PA1/TXD1 - txd
- * PA8/CLK1 - tclk
- * PA9/CLK2 - rclk
- * PC0/!RTS1 - t_en
- * PC1/!CTS1 - col
- * PC5/!CD1 - cd
- */
-#define PA_ENET_RXD PA_RXD1
-#define PA_ENET_TXD PA_TXD1
-#define PA_ENET_TCLK PA_CLK1
-#define PA_ENET_RCLK PA_CLK2
-#define PC_ENET_TENA PC_RTS1
-#define PC_ENET_CLSN PC_CTS1
-#define PC_ENET_RENA PC_CD1
-
-/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
- * SCC1.
- */
-#define SICR_ENET_MASK ((uint)0x000000ff)
-#define SICR_ENET_CLKRT ((uint)0x0000002c)
-
-#endif /* config_ucquicc */
-
-
-#ifdef MBX
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use. The TCLK and RCLK seem unique
- * to the MBX860 board. Any two of the four available clocks could be
- * used, and the MPC860 cookbook manual has an example using different
- * clock pins.
- */
-#define PA_ENET_RXD ((ushort)0x0001)
-#define PA_ENET_TXD ((ushort)0x0002)
-#define PA_ENET_TCLK ((ushort)0x0200)
-#define PA_ENET_RCLK ((ushort)0x0800)
-#define PC_ENET_TENA ((ushort)0x0001)
-#define PC_ENET_CLSN ((ushort)0x0010)
-#define PC_ENET_RENA ((ushort)0x0020)
-
-/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
- * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
- */
-#define SICR_ENET_MASK ((uint)0x000000ff)
-#define SICR_ENET_CLKRT ((uint)0x0000003d)
-#endif
-
-/* SCC Event register as used by Ethernet.
-*/
-#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */
-#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */
-#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */
-#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */
-#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */
-#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */
-
-/* SCC Mode Register (PMSR) as used by Ethernet.
-*/
-#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */
-#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */
-#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */
-#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */
-#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */
-#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */
-#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */
-#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */
-#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */
-#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */
-#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */
-#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */
-#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */
-
-/* Buffer descriptor control/status used by Ethernet receive.
-*/
-#define BD_ENET_RX_EMPTY ((ushort)0x8000)
-#define BD_ENET_RX_WRAP ((ushort)0x2000)
-#define BD_ENET_RX_INTR ((ushort)0x1000)
-#define BD_ENET_RX_LAST ((ushort)0x0800)
-#define BD_ENET_RX_FIRST ((ushort)0x0400)
-#define BD_ENET_RX_MISS ((ushort)0x0100)
-#define BD_ENET_RX_LG ((ushort)0x0020)
-#define BD_ENET_RX_NO ((ushort)0x0010)
-#define BD_ENET_RX_SH ((ushort)0x0008)
-#define BD_ENET_RX_CR ((ushort)0x0004)
-#define BD_ENET_RX_OV ((ushort)0x0002)
-#define BD_ENET_RX_CL ((ushort)0x0001)
-#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */
-
-/* Buffer descriptor control/status used by Ethernet transmit.
-*/
-#define BD_ENET_TX_READY ((ushort)0x8000)
-#define BD_ENET_TX_PAD ((ushort)0x4000)
-#define BD_ENET_TX_WRAP ((ushort)0x2000)
-#define BD_ENET_TX_INTR ((ushort)0x1000)
-#define BD_ENET_TX_LAST ((ushort)0x0800)
-#define BD_ENET_TX_TC ((ushort)0x0400)
-#define BD_ENET_TX_DEF ((ushort)0x0200)
-#define BD_ENET_TX_HB ((ushort)0x0100)
-#define BD_ENET_TX_LC ((ushort)0x0080)
-#define BD_ENET_TX_RL ((ushort)0x0040)
-#define BD_ENET_TX_RCMASK ((ushort)0x003c)
-#define BD_ENET_TX_UN ((ushort)0x0002)
-#define BD_ENET_TX_CSL ((ushort)0x0001)
-#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */
-
-/* SCC as UART
-*/
-typedef struct scc_uart {
- sccp_t scc_genscc;
- uint scc_res1; /* Reserved */
- uint scc_res2; /* Reserved */
- ushort scc_maxidl; /* Maximum idle chars */
- ushort scc_idlc; /* temp idle counter */
- ushort scc_brkcr; /* Break count register */
- ushort scc_parec; /* receive parity error counter */
- ushort scc_frmec; /* receive framing error counter */
- ushort scc_nosec; /* receive noise counter */
- ushort scc_brkec; /* receive break condition counter */
- ushort scc_brkln; /* last received break length */
- ushort scc_uaddr1; /* UART address character 1 */
- ushort scc_uaddr2; /* UART address character 2 */
- ushort scc_rtemp; /* Temp storage */
- ushort scc_toseq; /* Transmit out of sequence char */
- ushort scc_char1; /* control character 1 */
- ushort scc_char2; /* control character 2 */
- ushort scc_char3; /* control character 3 */
- ushort scc_char4; /* control character 4 */
- ushort scc_char5; /* control character 5 */
- ushort scc_char6; /* control character 6 */
- ushort scc_char7; /* control character 7 */
- ushort scc_char8; /* control character 8 */
- ushort scc_rccm; /* receive control character mask */
- ushort scc_rccr; /* receive control character register */
- ushort scc_rlbc; /* receive last break character */
-} scc_uart_t;
-
-/* SCC Event and Mask registers when it is used as a UART.
-*/
-#define UART_SCCM_GLR ((ushort)0x1000)
-#define UART_SCCM_GLT ((ushort)0x0800)
-#define UART_SCCM_AB ((ushort)0x0200)
-#define UART_SCCM_IDL ((ushort)0x0100)
-#define UART_SCCM_GRA ((ushort)0x0080)
-#define UART_SCCM_BRKE ((ushort)0x0040)
-#define UART_SCCM_BRKS ((ushort)0x0020)
-#define UART_SCCM_CCR ((ushort)0x0008)
-#define UART_SCCM_BSY ((ushort)0x0004)
-#define UART_SCCM_TX ((ushort)0x0002)
-#define UART_SCCM_RX ((ushort)0x0001)
-
-/* The SCC PMSR when used as a UART.
-*/
-#define SCU_PMSR_FLC ((ushort)0x8000)
-#define SCU_PMSR_SL ((ushort)0x4000)
-#define SCU_PMSR_CL ((ushort)0x3000)
-#define SCU_PMSR_UM ((ushort)0x0c00)
-#define SCU_PMSR_FRZ ((ushort)0x0200)
-#define SCU_PMSR_RZS ((ushort)0x0100)
-#define SCU_PMSR_SYN ((ushort)0x0080)
-#define SCU_PMSR_DRT ((ushort)0x0040)
-#define SCU_PMSR_PEN ((ushort)0x0010)
-#define SCU_PMSR_RPM ((ushort)0x000c)
-#define SCU_PMSR_REVP ((ushort)0x0008)
-#define SCU_PMSR_TPM ((ushort)0x0003)
-#define SCU_PMSR_TEVP ((ushort)0x0003)
-
-/* CPM Transparent mode SCC.
- */
-typedef struct scc_trans {
- sccp_t st_genscc;
- uint st_cpres; /* Preset CRC */
- uint st_cmask; /* Constant mask for CRC */
-} scc_trans_t;
-
-#define BD_SCC_TX_LAST ((ushort)0x0800)
-
-
-
-/* CPM interrupts. There are nearly 32 interrupts generated by CPM
- * channels or devices. All of these are presented to the PPC core
- * as a single interrupt. The CPM interrupt handler dispatches its
- * own handlers, in a similar fashion to the PPC core handler. We
- * use the table as defined in the manuals (i.e. no special high
- * priority and SCC1 == SCCa, etc...).
- */
-/* #define CPMVEC_NR 32 */
-/* #define CPMVEC_PIO_PC15 ((ushort)0x1f) */
-/* #define CPMVEC_SCC1 ((ushort)0x1e) */
-/* #define CPMVEC_SCC2 ((ushort)0x1d) */
-/* #define CPMVEC_SCC3 ((ushort)0x1c) */
-/* #define CPMVEC_SCC4 ((ushort)0x1b) */
-/* #define CPMVEC_PIO_PC14 ((ushort)0x1a) */
-/* #define CPMVEC_TIMER1 ((ushort)0x19) */
-/* #define CPMVEC_PIO_PC13 ((ushort)0x18) */
-/* #define CPMVEC_PIO_PC12 ((ushort)0x17) */
-/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */
-/* #define CPMVEC_IDMA1 ((ushort)0x15) */
-/* #define CPMVEC_IDMA2 ((ushort)0x14) */
-/* #define CPMVEC_TIMER2 ((ushort)0x12) */
-/* #define CPMVEC_RISCTIMER ((ushort)0x11) */
-/* #define CPMVEC_I2C ((ushort)0x10) */
-/* #define CPMVEC_PIO_PC11 ((ushort)0x0f) */
-/* #define CPMVEC_PIO_PC10 ((ushort)0x0e) */
-/* #define CPMVEC_TIMER3 ((ushort)0x0c) */
-/* #define CPMVEC_PIO_PC9 ((ushort)0x0b) */
-/* #define CPMVEC_PIO_PC8 ((ushort)0x0a) */
-/* #define CPMVEC_PIO_PC7 ((ushort)0x09) */
-/* #define CPMVEC_TIMER4 ((ushort)0x07) */
-/* #define CPMVEC_PIO_PC6 ((ushort)0x06) */
-/* #define CPMVEC_SPI ((ushort)0x05) */
-/* #define CPMVEC_SMC1 ((ushort)0x04) */
-/* #define CPMVEC_SMC2 ((ushort)0x03) */
-/* #define CPMVEC_PIO_PC5 ((ushort)0x02) */
-/* #define CPMVEC_PIO_PC4 ((ushort)0x01) */
-/* #define CPMVEC_ERROR ((ushort)0x00) */
-
-extern void cpm_install_handler(int vec, irq_handler_t handler, void *dev_id);
-
-/* CPM interrupt configuration vector.
-*/
-#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */
-#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */
-#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */
-#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */
-#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */
-#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
-#define CICR_IEN ((uint)0x00000080) /* Int. enable */
-#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
-#endif /* __CPM_360__ */
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
index 05aa535..96c5361 100644
--- a/arch/m68k/include/asm/dma-mapping.h
+++ b/arch/m68k/include/asm/dma-mapping.h
@@ -1,123 +1,17 @@
#ifndef _M68K_DMA_MAPPING_H
#define _M68K_DMA_MAPPING_H
-#include <asm/cache.h>
+extern struct dma_map_ops m68k_dma_ops;
-struct scatterlist;
-
-static inline int dma_supported(struct device *dev, u64 mask)
-{
- return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
- return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
- dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
- void *, dma_addr_t);
-
-static inline void *dma_alloc_attrs(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag,
- struct dma_attrs *attrs)
-{
- /* attrs is not supported and ignored */
- return dma_alloc_coherent(dev, size, dma_handle, flag);
-}
-
-static inline void dma_free_attrs(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t dma_handle,
- struct dma_attrs *attrs)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- /* attrs is not supported and ignored */
- dma_free_coherent(dev, size, cpu_addr, dma_handle);
+ return &m68k_dma_ops;
}
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t flag)
-{
- return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
- void *addr, dma_addr_t handle)
-{
- dma_free_coherent(dev, size, addr, handle);
-}
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
{
/* we use coherent allocation, so not much to do here. */
}
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
- enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
- unsigned long, size_t size,
- enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
- enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
- return 0;
-}
-
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
index 6d13cae..59e1710 100644
--- a/arch/m68k/include/asm/m54xxacr.h
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -23,8 +23,8 @@
#define CACR_IEC 0x00008000 /* Enable instruction cache */
#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */
#define CACR_IDPI 0x00001000 /* Disable CPUSHL */
-#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */
-#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */
+#define CACR_IHLCK 0x00000800 /* Instruction cache half lock */
+#define CACR_IDCM 0x00000400 /* Instruction cache inhibit */
#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */
#define CACR_EUSP 0x00000020 /* Enable separate user a7 */
diff --git a/arch/m68k/include/asm/m68360.h b/arch/m68k/include/asm/m68360.h
deleted file mode 100644
index 4664180..0000000
--- a/arch/m68k/include/asm/m68360.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <asm/m68360_regs.h>
-#include <asm/m68360_pram.h>
-#include <asm/m68360_quicc.h>
-#include <asm/m68360_enet.h>
-
-#ifdef CONFIG_M68360
-
-#define CPM_INTERRUPT 4
-
-/* see MC68360 User's Manual, p. 7-377 */
-#define CPM_VECTOR_BASE 0x04 /* 3 MSbits of CPM vector */
-
-#endif /* CONFIG_M68360 */
diff --git a/arch/m68k/include/asm/m68360_enet.h b/arch/m68k/include/asm/m68360_enet.h
deleted file mode 100644
index 4d04037..0000000
--- a/arch/m68k/include/asm/m68360_enet.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/***********************************
- * $Id: m68360_enet.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
- ***********************************
- *
- ***************************************
- * Definitions for the ETHERNET controllers
- ***************************************
- */
-
-#ifndef __ETHER_H
-#define __ETHER_H
-
-#include <asm/quicc_simple.h>
-
-/*
- * transmit BD's
- */
-#define T_R 0x8000 /* ready bit */
-#define E_T_PAD 0x4000 /* short frame padding */
-#define T_W 0x2000 /* wrap bit */
-#define T_I 0x1000 /* interrupt on completion */
-#define T_L 0x0800 /* last in frame */
-#define T_TC 0x0400 /* transmit CRC (when last) */
-
-#define T_DEF 0x0200 /* defer indication */
-#define T_HB 0x0100 /* heartbeat */
-#define T_LC 0x0080 /* error: late collision */
-#define T_RL 0x0040 /* error: retransmission limit */
-#define T_RC 0x003c /* retry count */
-#define T_UN 0x0002 /* error: underrun */
-#define T_CSL 0x0001 /* carier sense lost */
-#define T_ERROR (T_HB | T_LC | T_RL | T_UN | T_CSL)
-
-/*
- * receive BD's
- */
-#define R_E 0x8000 /* buffer empty */
-#define R_W 0x2000 /* wrap bit */
-#define R_I 0x1000 /* interrupt on reception */
-#define R_L 0x0800 /* last BD in frame */
-#define R_F 0x0400 /* first BD in frame */
-#define R_M 0x0100 /* received because of promisc. mode */
-
-#define R_LG 0x0020 /* frame too long */
-#define R_NO 0x0010 /* non-octet aligned */
-#define R_SH 0x0008 /* short frame */
-#define R_CR 0x0004 /* receive CRC error */
-#define R_OV 0x0002 /* receive overrun */
-#define R_CL 0x0001 /* collision */
-#define ETHER_R_ERROR (R_LG | R_NO | R_SH | R_CR | R_OV | R_CL)
-
-
-/*
- * ethernet interrupts
- */
-#define ETHERNET_GRA 0x0080 /* graceful stop complete */
-#define ETHERNET_TXE 0x0010 /* transmit error */
-#define ETHERNET_RXF 0x0008 /* receive frame */
-#define ETHERNET_BSY 0x0004 /* busy condition */
-#define ETHERNET_TXB 0x0002 /* transmit buffer */
-#define ETHERNET_RXB 0x0001 /* receive buffer */
-
-/*
- * ethernet protocol specific mode register (PSMR)
- */
-#define ETHER_HBC 0x8000 /* heartbeat checking */
-#define ETHER_FC 0x4000 /* force collision */
-#define ETHER_RSH 0x2000 /* receive short frames */
-#define ETHER_IAM 0x1000 /* individual address mode */
-#define ETHER_CRC_32 (0x2<<10) /* Enable CRC */
-#define ETHER_PRO 0x0200 /* promiscuous */
-#define ETHER_BRO 0x0100 /* broadcast address */
-#define ETHER_SBT 0x0080 /* stop backoff timer */
-#define ETHER_LPB 0x0040 /* Loop Back Mode */
-#define ETHER_SIP 0x0020 /* sample input pins */
-#define ETHER_LCW 0x0010 /* late collision window */
-#define ETHER_NIB_13 (0x0<<1) /* # of ignored bits 13 */
-#define ETHER_NIB_14 (0x1<<1) /* # of ignored bits 14 */
-#define ETHER_NIB_15 (0x2<<1) /* # of ignored bits 15 */
-#define ETHER_NIB_16 (0x3<<1) /* # of ignored bits 16 */
-#define ETHER_NIB_21 (0x4<<1) /* # of ignored bits 21 */
-#define ETHER_NIB_22 (0x5<<1) /* # of ignored bits 22 */
-#define ETHER_NIB_23 (0x6<<1) /* # of ignored bits 23 */
-#define ETHER_NIB_24 (0x7<<1) /* # of ignored bits 24 */
-
-/*
- * ethernet specific parameters
- */
-#define CRC_WORD 4 /* Length in bytes of CRC */
-#define C_PRES 0xffffffff /* preform 32 bit CRC */
-#define C_MASK 0xdebb20e3 /* comply with 32 bit CRC */
-#define CRCEC 0x00000000
-#define ALEC 0x00000000
-#define DISFC 0x00000000
-#define PADS 0x00000000
-#define RET_LIM 0x000f /* retry 15 times to send a frame before interrupt */
-#define ETH_MFLR 0x05ee /* 1518 max frame size */
-#define MINFLR 0x0040 /* Minimum frame size 64 */
-#define MAXD1 0x05ee /* Max dma count 1518 */
-#define MAXD2 0x05ee
-#define GADDR1 0x00000000 /* Clear group address */
-#define GADDR2 0x00000000
-#define GADDR3 0x00000000
-#define GADDR4 0x00000000
-#define P_PER 0x00000000 /*not used */
-#define IADDR1 0x00000000 /* Individual hash table not used */
-#define IADDR2 0x00000000
-#define IADDR3 0x00000000
-#define IADDR4 0x00000000
-#define TADDR_H 0x00000000 /* clear this regs */
-#define TADDR_M 0x00000000
-#define TADDR_L 0x00000000
-
-/* SCC Parameter Ram */
-#define RFCR 0x18 /* normal operation */
-#define TFCR 0x18 /* normal operation */
-#define E_MRBLR 1518 /* Max ethernet frame length */
-
-/*
- * ethernet specific structure
- */
-typedef union {
- unsigned char b[6];
- struct {
- unsigned short high;
- unsigned short middl;
- unsigned short low;
- } w;
-} ETHER_ADDR;
-
-typedef struct {
- int max_frame_length;
- int promisc_mode;
- int reject_broadcast;
- ETHER_ADDR phys_adr;
-} ETHER_SPECIFIC;
-
-typedef struct {
- ETHER_ADDR dst_addr;
- ETHER_ADDR src_addr;
- unsigned short type_or_len;
- unsigned char data[1];
-} ETHER_FRAME;
-
-#define MAX_DATALEN 1500
-typedef struct {
- ETHER_ADDR dst_addr;
- ETHER_ADDR src_addr;
- unsigned short type_or_len;
- unsigned char data[MAX_DATALEN];
- unsigned char fcs[CRC_WORD];
-} ETHER_MAX_FRAME;
-
-
-/*
- * Internal ethernet function prototypes
- */
-void ether_interrupt(int scc_num);
-/* mleslie: debug */
-/* static void ethernet_rx_internal(int scc_num); */
-/* static void ethernet_tx_internal(int scc_num); */
-
-/*
- * User callable routines prototypes (ethernet specific)
- */
-void ethernet_init(int scc_number,
- alloc_routine *alloc_buffer,
- free_routine *free_buffer,
- store_rx_buffer_routine *store_rx_buffer,
- handle_tx_error_routine *handle_tx_error,
- handle_rx_error_routine *handle_rx_error,
- handle_lost_error_routine *handle_lost_error,
- ETHER_SPECIFIC *ether_spec);
-int ethernet_tx(int scc_number, void *buf, int length);
-
-#endif
-
diff --git a/arch/m68k/include/asm/m68360_pram.h b/arch/m68k/include/asm/m68360_pram.h
deleted file mode 100644
index c0cbd96..0000000
--- a/arch/m68k/include/asm/m68360_pram.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/***********************************
- * $Id: m68360_pram.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
- ***********************************
- *
- ***************************************
- * Definitions of the parameter area RAM.
- * Note that different structures are overlaid
- * at the same offsets for the different modes
- * of operation.
- ***************************************
- */
-
-#ifndef __PRAM_H
-#define __PRAM_H
-
-/* Time slot assignment table */
-#define VALID_SLOT 0x8000
-#define WRAP_SLOT 0x4000
-
-/*****************************************************************
- Global Multichannel parameter RAM
-*****************************************************************/
-struct global_multi_pram {
- /*
- * Global Multichannel parameter RAM
- */
- unsigned long mcbase; /* Multichannel Base pointer */
- unsigned short qmcstate; /* Multichannel Controller state */
- unsigned short mrblr; /* Maximum Receive Buffer Length */
- unsigned short tx_s_ptr; /* TSTATx Pointer */
- unsigned short rxptr; /* Current Time slot entry in TSATRx */
- unsigned short grfthr; /* Global Receive frame threshold */
- unsigned short grfcnt; /* Global Receive Frame Count */
- unsigned long intbase; /* Multichannel Base address */
- unsigned long iintptr; /* Pointer to interrupt queue */
- unsigned short rx_s_ptr; /* TSTARx Pointer */
-
- unsigned short txptr; /* Current Time slot entry in TSATTx */
- unsigned long c_mask32; /* CRC Constant (debb20e3) */
- unsigned short tsatrx[32]; /* Time Slot Assignment Table Rx */
- unsigned short tsattx[32]; /* Time Slot Assignment Table Tx */
- unsigned short c_mask16; /* CRC Constant (f0b8) */
-};
-
-/*****************************************************************
- Quicc32 HDLC parameter RAM
-*****************************************************************/
-struct quicc32_pram {
-
- unsigned short tbase; /* Tx Buffer Descriptors Base Address */
- unsigned short chamr; /* Channel Mode Register */
- unsigned long tstate; /* Tx Internal State */
- unsigned long txintr; /* Tx Internal Data Pointer */
- unsigned short tbptr; /* Tx Buffer Descriptor Pointer */
- unsigned short txcntr; /* Tx Internal Byte Count */
- unsigned long tupack; /* (Tx Temp) */
- unsigned long zistate; /* Zero Insertion machine state */
- unsigned long tcrc; /* Temp Transmit CRC */
- unsigned short intmask; /* Channel's interrupt mask flags */
- unsigned short bdflags;
- unsigned short rbase; /* Rx Buffer Descriptors Base Address */
- unsigned short mflr; /* Max Frame Length Register */
- unsigned long rstate; /* Rx Internal State */
- unsigned long rxintr; /* Rx Internal Data Pointer */
- unsigned short rbptr; /* Rx Buffer Descriptor Pointer */
- unsigned short rxbyc; /* Rx Internal Byte Count */
- unsigned long rpack; /* (Rx Temp) */
- unsigned long zdstate; /* Zero Deletion machine state */
- unsigned long rcrc; /* Temp Transmit CRC */
- unsigned short maxc; /* Max_length counter */
- unsigned short tmp_mb; /* Temp */
-};
-
-
-/*****************************************************************
- HDLC parameter RAM
-*****************************************************************/
-
-struct hdlc_pram {
- /*
- * SCC parameter RAM
- */
- unsigned short rbase; /* RX BD base address */
- unsigned short tbase; /* TX BD base address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned long rcrc; /* temp receive CRC */
- unsigned long tcrc; /* temp transmit CRC */
-
- /*
- * HDLC specific parameter RAM
- */
- unsigned char RESERVED1[4]; /* Reserved area */
- unsigned long c_mask; /* CRC constant */
- unsigned long c_pres; /* CRC preset */
- unsigned short disfc; /* discarded frame counter */
- unsigned short crcec; /* CRC error counter */
- unsigned short abtsc; /* abort sequence counter */
- unsigned short nmarc; /* nonmatching address rx cnt */
- unsigned short retrc; /* frame retransmission cnt */
- unsigned short mflr; /* maximum frame length reg */
- unsigned short max_cnt; /* maximum length counter */
- unsigned short rfthr; /* received frames threshold */
- unsigned short rfcnt; /* received frames count */
- unsigned short hmask; /* user defined frm addr mask */
- unsigned short haddr1; /* user defined frm address 1 */
- unsigned short haddr2; /* user defined frm address 2 */
- unsigned short haddr3; /* user defined frm address 3 */
- unsigned short haddr4; /* user defined frm address 4 */
- unsigned short tmp; /* temp */
- unsigned short tmp_mb; /* temp */
-};
-
-
-
-/*****************************************************************
- UART parameter RAM
-*****************************************************************/
-
-/*
- * bits in uart control characters table
- */
-#define CC_INVALID 0x8000 /* control character is valid */
-#define CC_REJ 0x4000 /* don't store char in buffer */
-#define CC_CHAR 0x00ff /* control character */
-
-/* UART */
-struct uart_pram {
- /*
- * SCC parameter RAM
- */
- unsigned short rbase; /* RX BD base address */
- unsigned short tbase; /* TX BD base address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rx_temp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned long rcrc; /* temp receive CRC */
- unsigned long tcrc; /* temp transmit CRC */
-
- /*
- * UART specific parameter RAM
- */
- unsigned char RESERVED1[8]; /* Reserved area */
- unsigned short max_idl; /* maximum idle characters */
- unsigned short idlc; /* rx idle counter (internal) */
- unsigned short brkcr; /* break count register */
-
- unsigned short parec; /* Rx parity error counter */
- unsigned short frmer; /* Rx framing error counter */
- unsigned short nosec; /* Rx noise counter */
- unsigned short brkec; /* Rx break character counter */
- unsigned short brkln; /* Receive break length */
-
- unsigned short uaddr1; /* address character 1 */
- unsigned short uaddr2; /* address character 2 */
- unsigned short rtemp; /* temp storage */
- unsigned short toseq; /* Tx out of sequence char */
- unsigned short cc[8]; /* Rx control characters */
- unsigned short rccm; /* Rx control char mask */
- unsigned short rccr; /* Rx control char register */
- unsigned short rlbc; /* Receive last break char */
-};
-
-
-
-/*****************************************************************
- BISYNC parameter RAM
-*****************************************************************/
-
-struct bisync_pram {
- /*
- * SCC parameter RAM
- */
- unsigned short rbase; /* RX BD base address */
- unsigned short tbase; /* TX BD base address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned long rcrc; /* temp receive CRC */
- unsigned long tcrc; /* temp transmit CRC */
-
- /*
- * BISYNC specific parameter RAM
- */
- unsigned char RESERVED1[4]; /* Reserved area */
- unsigned long crcc; /* CRC Constant Temp Value */
- unsigned short prcrc; /* Preset Receiver CRC-16/LRC */
- unsigned short ptcrc; /* Preset Transmitter CRC-16/LRC */
- unsigned short parec; /* Receive Parity Error Counter */
- unsigned short bsync; /* BISYNC SYNC Character */
- unsigned short bdle; /* BISYNC DLE Character */
- unsigned short cc[8]; /* Rx control characters */
- unsigned short rccm; /* Receive Control Character Mask */
-};
-
-/*****************************************************************
- IOM2 parameter RAM
- (overlaid on tx bd[5] of SCC channel[2])
-*****************************************************************/
-struct iom2_pram {
- unsigned short ci_data; /* ci data */
- unsigned short monitor_data; /* monitor data */
- unsigned short tstate; /* transmitter state */
- unsigned short rstate; /* receiver state */
-};
-
-/*****************************************************************
- SPI/SMC parameter RAM
- (overlaid on tx bd[6,7] of SCC channel[2])
-*****************************************************************/
-
-#define SPI_R 0x8000 /* Ready bit in BD */
-
-struct spi_pram {
- unsigned short rbase; /* Rx BD Base Address */
- unsigned short tbase; /* Tx BD Base Address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
-};
-
-struct smc_uart_pram {
- unsigned short rbase; /* Rx BD Base Address */
- unsigned short tbase; /* Tx BD Base Address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned short max_idl; /* Maximum IDLE Characters */
- unsigned short idlc; /* Temporary IDLE Counter */
- unsigned short brkln; /* Last Rx Break Length */
- unsigned short brkec; /* Rx Break Condition Counter */
- unsigned short brkcr; /* Break Count Register (Tx) */
- unsigned short r_mask; /* Temporary bit mask */
-};
-
-struct smc_trnsp_pram {
- unsigned short rbase; /* rx BD Base Address */
- unsigned short tbase; /* Tx BD Base Address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned short reserved[5]; /* Reserved */
-};
-
-struct idma_pram {
- unsigned short ibase; /* IDMA BD Base Address */
- unsigned short ibptr; /* IDMA buffer descriptor pointer */
- unsigned long istate; /* IDMA internal state */
- unsigned long itemp; /* IDMA temp */
-};
-
-struct ethernet_pram {
- /*
- * SCC parameter RAM
- */
- unsigned short rbase; /* RX BD base address */
- unsigned short tbase; /* TX BD base address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned long rcrc; /* temp receive CRC */
- unsigned long tcrc; /* temp transmit CRC */
-
- /*
- * ETHERNET specific parameter RAM
- */
- unsigned long c_pres; /* preset CRC */
- unsigned long c_mask; /* constant mask for CRC */
- unsigned long crcec; /* CRC error counter */
- unsigned long alec; /* alignment error counter */
- unsigned long disfc; /* discard frame counter */
- unsigned short pads; /* short frame PAD characters */
- unsigned short ret_lim; /* retry limit threshold */
- unsigned short ret_cnt; /* retry limit counter */
- unsigned short mflr; /* maximum frame length reg */
- unsigned short minflr; /* minimum frame length reg */
- unsigned short maxd1; /* maximum DMA1 length reg */
- unsigned short maxd2; /* maximum DMA2 length reg */
- unsigned short maxd; /* rx max DMA */
- unsigned short dma_cnt; /* rx dma counter */
- unsigned short max_b; /* max bd byte count */
- unsigned short gaddr1; /* group address filter 1 */
- unsigned short gaddr2; /* group address filter 2 */
- unsigned short gaddr3; /* group address filter 3 */
- unsigned short gaddr4; /* group address filter 4 */
- unsigned long tbuf0_data0; /* save area 0 - current frm */
- unsigned long tbuf0_data1; /* save area 1 - current frm */
- unsigned long tbuf0_rba0;
- unsigned long tbuf0_crc;
- unsigned short tbuf0_bcnt;
- union {
- unsigned char b[6];
- struct {
- unsigned short high;
- unsigned short middl;
- unsigned short low;
- } w;
- } paddr;
- unsigned short p_per; /* persistence */
- unsigned short rfbd_ptr; /* rx first bd pointer */
- unsigned short tfbd_ptr; /* tx first bd pointer */
- unsigned short tlbd_ptr; /* tx last bd pointer */
- unsigned long tbuf1_data0; /* save area 0 - next frame */
- unsigned long tbuf1_data1; /* save area 1 - next frame */
- unsigned long tbuf1_rba0;
- unsigned long tbuf1_crc;
- unsigned short tbuf1_bcnt;
- unsigned short tx_len; /* tx frame length counter */
- unsigned short iaddr1; /* individual address filter 1*/
- unsigned short iaddr2; /* individual address filter 2*/
- unsigned short iaddr3; /* individual address filter 3*/
- unsigned short iaddr4; /* individual address filter 4*/
- unsigned short boff_cnt; /* back-off counter */
- unsigned short taddr_h; /* temp address (MSB) */
- unsigned short taddr_m; /* temp address */
- unsigned short taddr_l; /* temp address (LSB) */
-};
-
-struct transparent_pram {
- /*
- * SCC parameter RAM
- */
- unsigned short rbase; /* RX BD base address */
- unsigned short tbase; /* TX BD base address */
- unsigned char rfcr; /* Rx function code */
- unsigned char tfcr; /* Tx function code */
- unsigned short mrblr; /* Rx buffer length */
- unsigned long rstate; /* Rx internal state */
- unsigned long rptr; /* Rx internal data pointer */
- unsigned short rbptr; /* rb BD Pointer */
- unsigned short rcount; /* Rx internal byte count */
- unsigned long rtemp; /* Rx temp */
- unsigned long tstate; /* Tx internal state */
- unsigned long tptr; /* Tx internal data pointer */
- unsigned short tbptr; /* Tx BD pointer */
- unsigned short tcount; /* Tx byte count */
- unsigned long ttemp; /* Tx temp */
- unsigned long rcrc; /* temp receive CRC */
- unsigned long tcrc; /* temp transmit CRC */
-
- /*
- * TRANSPARENT specific parameter RAM
- */
- unsigned long crc_p; /* CRC Preset */
- unsigned long crc_c; /* CRC constant */
-};
-
-struct timer_pram {
- /*
- * RISC timers parameter RAM
- */
- unsigned short tm_base; /* RISC timer table base adr */
- unsigned short tm_ptr; /* RISC timer table pointer */
- unsigned short r_tmr; /* RISC timer mode register */
- unsigned short r_tmv; /* RISC timer valid register */
- unsigned long tm_cmd; /* RISC timer cmd register */
- unsigned long tm_cnt; /* RISC timer internal cnt */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/m68360_quicc.h b/arch/m68k/include/asm/m68360_quicc.h
deleted file mode 100644
index 59414cc..0000000
--- a/arch/m68k/include/asm/m68360_quicc.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/***********************************
- * $Id: m68360_quicc.h,v 1.1 2002/03/02 15:01:07 gerg Exp $
- ***********************************
- *
- ***************************************
- * Definitions of QUICC memory structures
- ***************************************
- */
-
-#ifndef __M68360_QUICC_H
-#define __M68360_QUICC_H
-
-/*
- * include registers and
- * parameter ram definitions files
- */
-#include <asm/m68360_regs.h>
-#include <asm/m68360_pram.h>
-
-
-
-/* Buffer Descriptors */
-typedef struct quicc_bd {
- volatile unsigned short status;
- volatile unsigned short length;
- volatile unsigned char *buf; /* WARNING: This is only true if *char is 32 bits */
-} QUICC_BD;
-
-
-#ifdef MOTOROLA_ORIGINAL
-struct user_data {
- /* BASE + 0x000: user data memory */
- volatile unsigned char udata_bd_ucode[0x400]; /*user data bd's Ucode*/
- volatile unsigned char udata_bd[0x200]; /*user data Ucode */
- volatile unsigned char ucode_ext[0x100]; /*Ucode Extension ram */
- volatile unsigned char RESERVED1[0x500]; /* Reserved area */
-};
-#else
-struct user_data {
- /* BASE + 0x000: user data memory */
- volatile unsigned char udata_bd_ucode[0x400]; /* user data, bds, Ucode*/
- volatile unsigned char udata_bd1[0x200]; /* user, bds */
- volatile unsigned char ucode_bd_scratch[0x100]; /* user, bds, ucode scratch */
- volatile unsigned char udata_bd2[0x100]; /* user, bds */
- volatile unsigned char RESERVED1[0x400]; /* Reserved area */
-};
-#endif
-
-
-/*
- * internal ram
- */
-typedef struct quicc {
- union {
- struct quicc32_pram ch_pram_tbl[32]; /* 32*64(bytes) per channel */
- struct user_data u;
- }ch_or_u; /* multipul or user space */
-
- /* BASE + 0xc00: PARAMETER RAM */
- union {
- struct scc_pram {
- union {
- struct hdlc_pram h;
- struct uart_pram u;
- struct bisync_pram b;
- struct transparent_pram t;
- unsigned char RESERVED66[0x70];
- } pscc; /* scc parameter area (protocol dependent) */
- union {
- struct {
- unsigned char RESERVED70[0x10];
- struct spi_pram spi;
- unsigned char RESERVED72[0x8];
- struct timer_pram timer;
- } timer_spi;
- struct {
- struct idma_pram idma;
- unsigned char RESERVED67[0x4];
- union {
- struct smc_uart_pram u;
- struct smc_trnsp_pram t;
- } psmc;
- } idma_smc;
- } pothers;
- } scc;
- struct ethernet_pram enet_scc;
- struct global_multi_pram m;
- unsigned char pr[0x100];
- } pram[4];
-
- /* reserved */
-
- /* BASE + 0x1000: INTERNAL REGISTERS */
- /* SIM */
- volatile unsigned long sim_mcr; /* module configuration reg */
- volatile unsigned short sim_simtr; /* module test register */
- volatile unsigned char RESERVED2[0x2]; /* Reserved area */
- volatile unsigned char sim_avr; /* auto vector reg */
- volatile unsigned char sim_rsr; /* reset status reg */
- volatile unsigned char RESERVED3[0x2]; /* Reserved area */
- volatile unsigned char sim_clkocr; /* CLCO control register */
- volatile unsigned char RESERVED62[0x3]; /* Reserved area */
- volatile unsigned short sim_pllcr; /* PLL control register */
- volatile unsigned char RESERVED63[0x2]; /* Reserved area */
- volatile unsigned short sim_cdvcr; /* Clock devider control register */
- volatile unsigned short sim_pepar; /* Port E pin assignment register */
- volatile unsigned char RESERVED64[0xa]; /* Reserved area */
- volatile unsigned char sim_sypcr; /* system protection control*/
- volatile unsigned char sim_swiv; /* software interrupt vector*/
- volatile unsigned char RESERVED6[0x2]; /* Reserved area */
- volatile unsigned short sim_picr; /* periodic interrupt control reg */
- volatile unsigned char RESERVED7[0x2]; /* Reserved area */
- volatile unsigned short sim_pitr; /* periodic interrupt timing reg */
- volatile unsigned char RESERVED8[0x3]; /* Reserved area */
- volatile unsigned char sim_swsr; /* software service */
- volatile unsigned long sim_bkar; /* breakpoint address register*/
- volatile unsigned long sim_bkcr; /* breakpoint control register*/
- volatile unsigned char RESERVED10[0x8]; /* Reserved area */
- /* MEMC */
- volatile unsigned long memc_gmr; /* Global memory register */
- volatile unsigned short memc_mstat; /* MEMC status register */
- volatile unsigned char RESERVED11[0xa]; /* Reserved area */
- volatile unsigned long memc_br0; /* base register 0 */
- volatile unsigned long memc_or0; /* option register 0 */
- volatile unsigned char RESERVED12[0x8]; /* Reserved area */
- volatile unsigned long memc_br1; /* base register 1 */
- volatile unsigned long memc_or1; /* option register 1 */
- volatile unsigned char RESERVED13[0x8]; /* Reserved area */
- volatile unsigned long memc_br2; /* base register 2 */
- volatile unsigned long memc_or2; /* option register 2 */
- volatile unsigned char RESERVED14[0x8]; /* Reserved area */
- volatile unsigned long memc_br3; /* base register 3 */
- volatile unsigned long memc_or3; /* option register 3 */
- volatile unsigned char RESERVED15[0x8]; /* Reserved area */
- volatile unsigned long memc_br4; /* base register 3 */
- volatile unsigned long memc_or4; /* option register 3 */
- volatile unsigned char RESERVED16[0x8]; /* Reserved area */
- volatile unsigned long memc_br5; /* base register 3 */
- volatile unsigned long memc_or5; /* option register 3 */
- volatile unsigned char RESERVED17[0x8]; /* Reserved area */
- volatile unsigned long memc_br6; /* base register 3 */
- volatile unsigned long memc_or6; /* option register 3 */
- volatile unsigned char RESERVED18[0x8]; /* Reserved area */
- volatile unsigned long memc_br7; /* base register 3 */
- volatile unsigned long memc_or7; /* option register 3 */
- volatile unsigned char RESERVED9[0x28]; /* Reserved area */
- /* TEST */
- volatile unsigned short test_tstmra; /* master shift a */
- volatile unsigned short test_tstmrb; /* master shift b */
- volatile unsigned short test_tstsc; /* shift count */
- volatile unsigned short test_tstrc; /* repetition counter */
- volatile unsigned short test_creg; /* control */
- volatile unsigned short test_dreg; /* destributed register */
- volatile unsigned char RESERVED58[0x404]; /* Reserved area */
- /* IDMA1 */
- volatile unsigned short idma_iccr; /* channel configuration reg*/
- volatile unsigned char RESERVED19[0x2]; /* Reserved area */
- volatile unsigned short idma1_cmr; /* dma mode reg */
- volatile unsigned char RESERVED68[0x2]; /* Reserved area */
- volatile unsigned long idma1_sapr; /* dma source addr ptr */
- volatile unsigned long idma1_dapr; /* dma destination addr ptr */
- volatile unsigned long idma1_bcr; /* dma byte count reg */
- volatile unsigned char idma1_fcr; /* function code reg */
- volatile unsigned char RESERVED20; /* Reserved area */
- volatile unsigned char idma1_cmar; /* channel mask reg */
- volatile unsigned char RESERVED21; /* Reserved area */
- volatile unsigned char idma1_csr; /* channel status reg */
- volatile unsigned char RESERVED22[0x3]; /* Reserved area */
- /* SDMA */
- volatile unsigned char sdma_sdsr; /* status reg */
- volatile unsigned char RESERVED23; /* Reserved area */
- volatile unsigned short sdma_sdcr; /* configuration reg */
- volatile unsigned long sdma_sdar; /* address reg */
- /* IDMA2 */
- volatile unsigned char RESERVED69[0x2]; /* Reserved area */
- volatile unsigned short idma2_cmr; /* dma mode reg */
- volatile unsigned long idma2_sapr; /* dma source addr ptr */
- volatile unsigned long idma2_dapr; /* dma destination addr ptr */
- volatile unsigned long idma2_bcr; /* dma byte count reg */
- volatile unsigned char idma2_fcr; /* function code reg */
- volatile unsigned char RESERVED24; /* Reserved area */
- volatile unsigned char idma2_cmar; /* channel mask reg */
- volatile unsigned char RESERVED25; /* Reserved area */
- volatile unsigned char idma2_csr; /* channel status reg */
- volatile unsigned char RESERVED26[0x7]; /* Reserved area */
- /* Interrupt Controller */
- volatile unsigned long intr_cicr; /* CP interrupt configuration reg*/
- volatile unsigned long intr_cipr; /* CP interrupt pending reg */
- volatile unsigned long intr_cimr; /* CP interrupt mask reg */
- volatile unsigned long intr_cisr; /* CP interrupt in service reg*/
- /* Parallel I/O */
- volatile unsigned short pio_padir; /* port A data direction reg */
- volatile unsigned short pio_papar; /* port A pin assignment reg */
- volatile unsigned short pio_paodr; /* port A open drain reg */
- volatile unsigned short pio_padat; /* port A data register */
- volatile unsigned char RESERVED28[0x8]; /* Reserved area */
- volatile unsigned short pio_pcdir; /* port C data direction reg*/
- volatile unsigned short pio_pcpar; /* port C pin assignment reg*/
- volatile unsigned short pio_pcso; /* port C special options */
- volatile unsigned short pio_pcdat; /* port C data register */
- volatile unsigned short pio_pcint; /* port C interrupt cntrl reg */
- volatile unsigned char RESERVED29[0x16]; /* Reserved area */
- /* Timer */
- volatile unsigned short timer_tgcr; /* timer global configuration reg */
- volatile unsigned char RESERVED30[0xe]; /* Reserved area */
- volatile unsigned short timer_tmr1; /* timer 1 mode reg */
- volatile unsigned short timer_tmr2; /* timer 2 mode reg */
- volatile unsigned short timer_trr1; /* timer 1 referance reg */
- volatile unsigned short timer_trr2; /* timer 2 referance reg */
- volatile unsigned short timer_tcr1; /* timer 1 capture reg */
- volatile unsigned short timer_tcr2; /* timer 2 capture reg */
- volatile unsigned short timer_tcn1; /* timer 1 counter reg */
- volatile unsigned short timer_tcn2; /* timer 2 counter reg */
- volatile unsigned short timer_tmr3; /* timer 3 mode reg */
- volatile unsigned short timer_tmr4; /* timer 4 mode reg */
- volatile unsigned short timer_trr3; /* timer 3 referance reg */
- volatile unsigned short timer_trr4; /* timer 4 referance reg */
- volatile unsigned short timer_tcr3; /* timer 3 capture reg */
- volatile unsigned short timer_tcr4; /* timer 4 capture reg */
- volatile unsigned short timer_tcn3; /* timer 3 counter reg */
- volatile unsigned short timer_tcn4; /* timer 4 counter reg */
- volatile unsigned short timer_ter1; /* timer 1 event reg */
- volatile unsigned short timer_ter2; /* timer 2 event reg */
- volatile unsigned short timer_ter3; /* timer 3 event reg */
- volatile unsigned short timer_ter4; /* timer 4 event reg */
- volatile unsigned char RESERVED34[0x8]; /* Reserved area */
- /* CP */
- volatile unsigned short cp_cr; /* command register */
- volatile unsigned char RESERVED35[0x2]; /* Reserved area */
- volatile unsigned short cp_rccr; /* main configuration reg */
- volatile unsigned char RESERVED37; /* Reserved area */
- volatile unsigned char cp_rmds; /* development support status reg */
- volatile unsigned long cp_rmdr; /* development support control reg */
- volatile unsigned short cp_rctr1; /* ram break register 1 */
- volatile unsigned short cp_rctr2; /* ram break register 2 */
- volatile unsigned short cp_rctr3; /* ram break register 3 */
- volatile unsigned short cp_rctr4; /* ram break register 4 */
- volatile unsigned char RESERVED59[0x2]; /* Reserved area */
- volatile unsigned short cp_rter; /* RISC timers event reg */
- volatile unsigned char RESERVED38[0x2]; /* Reserved area */
- volatile unsigned short cp_rtmr; /* RISC timers mask reg */
- volatile unsigned char RESERVED39[0x14]; /* Reserved area */
- /* BRG */
- union {
- volatile unsigned long l;
- struct {
- volatile unsigned short BRGC_RESERV:14;
- volatile unsigned short rst:1;
- volatile unsigned short en:1;
- volatile unsigned short extc:2;
- volatile unsigned short atb:1;
- volatile unsigned short cd:12;
- volatile unsigned short div16:1;
- } b;
- } brgc[4]; /* BRG1-BRG4 configuration regs*/
- /* SCC registers */
- struct scc_regs {
- union {
- struct {
- /* Low word. */
- volatile unsigned short GSMR_RESERV2:1;
- volatile unsigned short edge:2;
- volatile unsigned short tci:1;
- volatile unsigned short tsnc:2;
- volatile unsigned short rinv:1;
- volatile unsigned short tinv:1;
- volatile unsigned short tpl:3;
- volatile unsigned short tpp:2;
- volatile unsigned short tend:1;
- volatile unsigned short tdcr:2;
- volatile unsigned short rdcr:2;
- volatile unsigned short renc:3;
- volatile unsigned short tenc:3;
- volatile unsigned short diag:2;
- volatile unsigned short enr:1;
- volatile unsigned short ent:1;
- volatile unsigned short mode:4;
- /* High word. */
- volatile unsigned short GSMR_RESERV1:14;
- volatile unsigned short pri:1;
- volatile unsigned short gde:1;
- volatile unsigned short tcrc:2;
- volatile unsigned short revd:1;
- volatile unsigned short trx:1;
- volatile unsigned short ttx:1;
- volatile unsigned short cdp:1;
- volatile unsigned short ctsp:1;
- volatile unsigned short cds:1;
- volatile unsigned short ctss:1;
- volatile unsigned short tfl:1;
- volatile unsigned short rfw:1;
- volatile unsigned short txsy:1;
- volatile unsigned short synl:2;
- volatile unsigned short rtsm:1;
- volatile unsigned short rsyn:1;
- } b;
- struct {
- volatile unsigned long low;
- volatile unsigned long high;
- } w;
- } scc_gsmr; /* SCC general mode reg */
- volatile unsigned short scc_psmr; /* protocol specific mode reg */
- volatile unsigned char RESERVED42[0x2]; /* Reserved area */
- volatile unsigned short scc_todr; /* SCC transmit on demand */
- volatile unsigned short scc_dsr; /* SCC data sync reg */
- volatile unsigned short scc_scce; /* SCC event reg */
- volatile unsigned char RESERVED43[0x2];/* Reserved area */
- volatile unsigned short scc_sccm; /* SCC mask reg */
- volatile unsigned char RESERVED44[0x1];/* Reserved area */
- volatile unsigned char scc_sccs; /* SCC status reg */
- volatile unsigned char RESERVED45[0x8]; /* Reserved area */
- } scc_regs[4];
- /* SMC */
- struct smc_regs {
- volatile unsigned char RESERVED46[0x2]; /* Reserved area */
- volatile unsigned short smc_smcmr; /* SMC mode reg */
- volatile unsigned char RESERVED60[0x2]; /* Reserved area */
- volatile unsigned char smc_smce; /* SMC event reg */
- volatile unsigned char RESERVED47[0x3]; /* Reserved area */
- volatile unsigned char smc_smcm; /* SMC mask reg */
- volatile unsigned char RESERVED48[0x5]; /* Reserved area */
- } smc_regs[2];
- /* SPI */
- volatile unsigned short spi_spmode; /* SPI mode reg */
- volatile unsigned char RESERVED51[0x4]; /* Reserved area */
- volatile unsigned char spi_spie; /* SPI event reg */
- volatile unsigned char RESERVED52[0x3]; /* Reserved area */
- volatile unsigned char spi_spim; /* SPI mask reg */
- volatile unsigned char RESERVED53[0x2]; /* Reserved area */
- volatile unsigned char spi_spcom; /* SPI command reg */
- volatile unsigned char RESERVED54[0x4]; /* Reserved area */
- /* PIP */
- volatile unsigned short pip_pipc; /* pip configuration reg */
- volatile unsigned char RESERVED65[0x2]; /* Reserved area */
- volatile unsigned short pip_ptpr; /* pip timing parameters reg */
- volatile unsigned long pip_pbdir; /* port b data direction reg */
- volatile unsigned long pip_pbpar; /* port b pin assignment reg */
- volatile unsigned long pip_pbodr; /* port b open drain reg */
- volatile unsigned long pip_pbdat; /* port b data reg */
- volatile unsigned char RESERVED71[0x18]; /* Reserved area */
- /* Serial Interface */
- volatile unsigned long si_simode; /* SI mode register */
- volatile unsigned char si_sigmr; /* SI global mode register */
- volatile unsigned char RESERVED55; /* Reserved area */
- volatile unsigned char si_sistr; /* SI status register */
- volatile unsigned char si_sicmr; /* SI command register */
- volatile unsigned char RESERVED56[0x4]; /* Reserved area */
- volatile unsigned long si_sicr; /* SI clock routing */
- volatile unsigned long si_sirp; /* SI ram pointers */
- volatile unsigned char RESERVED57[0xc]; /* Reserved area */
- volatile unsigned short si_siram[0x80]; /* SI routing ram */
-} QUICC;
-
-#endif
-
-/*
- * Local variables:
- * c-indent-level: 4
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/arch/m68k/include/asm/m68360_regs.h b/arch/m68k/include/asm/m68360_regs.h
deleted file mode 100644
index d57217c..0000000
--- a/arch/m68k/include/asm/m68360_regs.h
+++ /dev/null
@@ -1,408 +0,0 @@
-/***********************************
- * $Id: m68360_regs.h,v 1.2 2002/10/26 15:03:55 gerg Exp $
- ***********************************
- *
- ***************************************
- * Definitions of the QUICC registers
- ***************************************
- */
-
-#ifndef __REGISTERS_H
-#define __REGISTERS_H
-
-#define CLEAR_BIT(x, bit) x =bit
-
-/*****************************************************************
- Command Register
-*****************************************************************/
-
-/* bit fields within command register */
-#define SOFTWARE_RESET 0x8000
-#define CMD_OPCODE 0x0f00
-#define CMD_CHANNEL 0x00f0
-#define CMD_FLAG 0x0001
-
-/* general command opcodes */
-#define INIT_RXTX_PARAMS 0x0000
-#define INIT_RX_PARAMS 0x0100
-#define INIT_TX_PARAMS 0x0200
-#define ENTER_HUNT_MODE 0x0300
-#define STOP_TX 0x0400
-#define GR_STOP_TX 0x0500
-#define RESTART_TX 0x0600
-#define CLOSE_RX_BD 0x0700
-#define SET_ENET_GROUP 0x0800
-#define RESET_ENET_GROUP 0x0900
-
-/* quicc32 CP commands */
-#define STOP_TX_32 0x0e00 /*add chan# bits 2-6 */
-#define ENTER_HUNT_MODE_32 0x1e00
-
-/* quicc32 mask/event SCC register */
-#define GOV 0x01
-#define GUN 0x02
-#define GINT 0x04
-#define IQOV 0x08
-
-
-/* Timer commands */
-#define SET_TIMER 0x0800
-
-/* Multi channel Interrupt structure */
-#define INTR_VALID 0x8000 /* Valid interrupt entry */
-#define INTR_WRAP 0x4000 /* Wrap bit in the interrupt entry table */
-#define INTR_CH_NU 0x07c0 /* Channel Num in interrupt table */
-#define INTR_MASK_BITS 0x383f
-
-/*
- * General SCC mode register (GSMR)
- */
-
-#define MODE_HDLC 0x0
-#define MODE_APPLE_TALK 0x2
-#define MODE_SS7 0x3
-#define MODE_UART 0x4
-#define MODE_PROFIBUS 0x5
-#define MODE_ASYNC_HDLC 0x6
-#define MODE_V14 0x7
-#define MODE_BISYNC 0x8
-#define MODE_DDCMP 0x9
-#define MODE_MULTI_CHANNEL 0xa
-#define MODE_ETHERNET 0xc
-
-#define DIAG_NORMAL 0x0
-#define DIAG_LOCAL_LPB 0x1
-#define DIAG_AUTO_ECHO 0x2
-#define DIAG_LBP_ECHO 0x3
-
-/* For RENC and TENC fields in GSMR */
-#define ENC_NRZ 0x0
-#define ENC_NRZI 0x1
-#define ENC_FM0 0x2
-#define ENC_MANCH 0x4
-#define ENC_DIFF_MANC 0x6
-
-/* For TDCR and RDCR fields in GSMR */
-#define CLOCK_RATE_1 0x0
-#define CLOCK_RATE_8 0x1
-#define CLOCK_RATE_16 0x2
-#define CLOCK_RATE_32 0x3
-
-#define TPP_00 0x0
-#define TPP_10 0x1
-#define TPP_01 0x2
-#define TPP_11 0x3
-
-#define TPL_NO 0x0
-#define TPL_8 0x1
-#define TPL_16 0x2
-#define TPL_32 0x3
-#define TPL_48 0x4
-#define TPL_64 0x5
-#define TPL_128 0x6
-
-#define TSNC_INFINITE 0x0
-#define TSNC_14_65 0x1
-#define TSNC_4_15 0x2
-#define TSNC_3_1 0x3
-
-#define EDGE_BOTH 0x0
-#define EDGE_POS 0x1
-#define EDGE_NEG 0x2
-#define EDGE_NO 0x3
-
-#define SYNL_NO 0x0
-#define SYNL_4 0x1
-#define SYNL_8 0x2
-#define SYNL_16 0x3
-
-#define TCRC_CCITT16 0x0
-#define TCRC_CRC16 0x1
-#define TCRC_CCITT32 0x2
-
-
-/*****************************************************************
- TODR (Transmit on demand) Register
-*****************************************************************/
-#define TODR_TOD 0x8000 /* Transmit on demand */
-
-
-/*****************************************************************
- CICR register settings
-*****************************************************************/
-
-/* note that relative irq priorities of the SCCs can be reordered
- * if desired - see p. 7-377 of the MC68360UM */
-#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */
-#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */
-#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */
-#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */
-
-#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */
-#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
-#define CICR_VBA_MASK ((uint)0x000000e0) /* Vector Base Address */
-#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
-
-
-/*****************************************************************
- Interrupt bits for CIPR and CIMR (MC68360UM p. 7-379)
-*****************************************************************/
-
-#define INTR_PIO_PC0 0x80000000 /* parallel I/O C bit 0 */
-#define INTR_SCC1 0x40000000 /* SCC port 1 */
-#define INTR_SCC2 0x20000000 /* SCC port 2 */
-#define INTR_SCC3 0x10000000 /* SCC port 3 */
-#define INTR_SCC4 0x08000000 /* SCC port 4 */
-#define INTR_PIO_PC1 0x04000000 /* parallel i/o C bit 1 */
-#define INTR_TIMER1 0x02000000 /* timer 1 */
-#define INTR_PIO_PC2 0x01000000 /* parallel i/o C bit 2 */
-#define INTR_PIO_PC3 0x00800000 /* parallel i/o C bit 3 */
-#define INTR_SDMA_BERR 0x00400000 /* SDMA channel bus error */
-#define INTR_DMA1 0x00200000 /* idma 1 */
-#define INTR_DMA2 0x00100000 /* idma 2 */
-#define INTR_TIMER2 0x00040000 /* timer 2 */
-#define INTR_CP_TIMER 0x00020000 /* CP timer */
-#define INTR_PIP_STATUS 0x00010000 /* PIP status */
-#define INTR_PIO_PC4 0x00008000 /* parallel i/o C bit 4 */
-#define INTR_PIO_PC5 0x00004000 /* parallel i/o C bit 5 */
-#define INTR_TIMER3 0x00001000 /* timer 3 */
-#define INTR_PIO_PC6 0x00000800 /* parallel i/o C bit 6 */
-#define INTR_PIO_PC7 0x00000400 /* parallel i/o C bit 7 */
-#define INTR_PIO_PC8 0x00000200 /* parallel i/o C bit 8 */
-#define INTR_TIMER4 0x00000080 /* timer 4 */
-#define INTR_PIO_PC9 0x00000040 /* parallel i/o C bit 9 */
-#define INTR_SCP 0x00000020 /* SCP */
-#define INTR_SMC1 0x00000010 /* SMC 1 */
-#define INTR_SMC2 0x00000008 /* SMC 2 */
-#define INTR_PIO_PC10 0x00000004 /* parallel i/o C bit 10 */
-#define INTR_PIO_PC11 0x00000002 /* parallel i/o C bit 11 */
-#define INTR_ERR 0x00000001 /* error */
-
-
-/*****************************************************************
- CPM Interrupt vector encodings (MC68360UM p. 7-376)
-*****************************************************************/
-
-#define CPMVEC_NR 32
-#define CPMVEC_PIO_PC0 0x1f
-#define CPMVEC_SCC1 0x1e
-#define CPMVEC_SCC2 0x1d
-#define CPMVEC_SCC3 0x1c
-#define CPMVEC_SCC4 0x1b
-#define CPMVEC_PIO_PC1 0x1a
-#define CPMVEC_TIMER1 0x19
-#define CPMVEC_PIO_PC2 0x18
-#define CPMVEC_PIO_PC3 0x17
-#define CPMVEC_SDMA_CB_ERR 0x16
-#define CPMVEC_IDMA1 0x15
-#define CPMVEC_IDMA2 0x14
-#define CPMVEC_RESERVED3 0x13
-#define CPMVEC_TIMER2 0x12
-#define CPMVEC_RISCTIMER 0x11
-#define CPMVEC_RESERVED2 0x10
-#define CPMVEC_PIO_PC4 0x0f
-#define CPMVEC_PIO_PC5 0x0e
-#define CPMVEC_TIMER3 0x0c
-#define CPMVEC_PIO_PC6 0x0b
-#define CPMVEC_PIO_PC7 0x0a
-#define CPMVEC_PIO_PC8 0x09
-#define CPMVEC_RESERVED1 0x08
-#define CPMVEC_TIMER4 0x07
-#define CPMVEC_PIO_PC9 0x06
-#define CPMVEC_SPI 0x05
-#define CPMVEC_SMC1 0x04
-#define CPMVEC_SMC2 0x03
-#define CPMVEC_PIO_PC10 0x02
-#define CPMVEC_PIO_PC11 0x01
-#define CPMVEC_ERROR 0x00
-
-/* #define CPMVEC_PIO_PC0 ((ushort)0x1f) */
-/* #define CPMVEC_SCC1 ((ushort)0x1e) */
-/* #define CPMVEC_SCC2 ((ushort)0x1d) */
-/* #define CPMVEC_SCC3 ((ushort)0x1c) */
-/* #define CPMVEC_SCC4 ((ushort)0x1b) */
-/* #define CPMVEC_PIO_PC1 ((ushort)0x1a) */
-/* #define CPMVEC_TIMER1 ((ushort)0x19) */
-/* #define CPMVEC_PIO_PC2 ((ushort)0x18) */
-/* #define CPMVEC_PIO_PC3 ((ushort)0x17) */
-/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */
-/* #define CPMVEC_IDMA1 ((ushort)0x15) */
-/* #define CPMVEC_IDMA2 ((ushort)0x14) */
-/* #define CPMVEC_RESERVED3 ((ushort)0x13) */
-/* #define CPMVEC_TIMER2 ((ushort)0x12) */
-/* #define CPMVEC_RISCTIMER ((ushort)0x11) */
-/* #define CPMVEC_RESERVED2 ((ushort)0x10) */
-/* #define CPMVEC_PIO_PC4 ((ushort)0x0f) */
-/* #define CPMVEC_PIO_PC5 ((ushort)0x0e) */
-/* #define CPMVEC_TIMER3 ((ushort)0x0c) */
-/* #define CPMVEC_PIO_PC6 ((ushort)0x0b) */
-/* #define CPMVEC_PIO_PC7 ((ushort)0x0a) */
-/* #define CPMVEC_PIO_PC8 ((ushort)0x09) */
-/* #define CPMVEC_RESERVED1 ((ushort)0x08) */
-/* #define CPMVEC_TIMER4 ((ushort)0x07) */
-/* #define CPMVEC_PIO_PC9 ((ushort)0x06) */
-/* #define CPMVEC_SPI ((ushort)0x05) */
-/* #define CPMVEC_SMC1 ((ushort)0x04) */
-/* #define CPMVEC_SMC2 ((ushort)0x03) */
-/* #define CPMVEC_PIO_PC10 ((ushort)0x02) */
-/* #define CPMVEC_PIO_PC11 ((ushort)0x01) */
-/* #define CPMVEC_ERROR ((ushort)0x00) */
-
-
-/*****************************************************************
- * PIO control registers
- *****************************************************************/
-
-/* Port A - See 360UM p. 7-358
- *
- * Note that most of these pins have alternate functions
- */
-
-
-/* The macros are nice, but there are all sorts of references to 1-indexed
- * facilities on the 68360... */
-/* #define PA_RXD(n) ((ushort)(0x01<<(2*n))) */
-/* #define PA_TXD(n) ((ushort)(0x02<<(2*n))) */
-
-#define PA_RXD1 ((ushort)0x0001)
-#define PA_TXD1 ((ushort)0x0002)
-#define PA_RXD2 ((ushort)0x0004)
-#define PA_TXD2 ((ushort)0x0008)
-#define PA_RXD3 ((ushort)0x0010)
-#define PA_TXD3 ((ushort)0x0020)
-#define PA_RXD4 ((ushort)0x0040)
-#define PA_TXD4 ((ushort)0x0080)
-
-#define PA_CLK1 ((ushort)0x0100)
-#define PA_CLK2 ((ushort)0x0200)
-#define PA_CLK3 ((ushort)0x0400)
-#define PA_CLK4 ((ushort)0x0800)
-#define PA_CLK5 ((ushort)0x1000)
-#define PA_CLK6 ((ushort)0x2000)
-#define PA_CLK7 ((ushort)0x4000)
-#define PA_CLK8 ((ushort)0x8000)
-
-
-/* Port B - See 360UM p. 7-362
- */
-
-
-/* Port C - See 360UM p. 7-365
- */
-
-#define PC_RTS1 ((ushort)0x0001)
-#define PC_RTS2 ((ushort)0x0002)
-#define PC__RTS3 ((ushort)0x0004) /* !RTS3 */
-#define PC__RTS4 ((ushort)0x0008) /* !RTS4 */
-
-#define PC_CTS1 ((ushort)0x0010)
-#define PC_CD1 ((ushort)0x0020)
-#define PC_CTS2 ((ushort)0x0040)
-#define PC_CD2 ((ushort)0x0080)
-#define PC_CTS3 ((ushort)0x0100)
-#define PC_CD3 ((ushort)0x0200)
-#define PC_CTS4 ((ushort)0x0400)
-#define PC_CD4 ((ushort)0x0800)
-
-
-
-/*****************************************************************
- chip select option register
-*****************************************************************/
-#define DTACK 0xe000
-#define ADR_MASK 0x1ffc
-#define RDWR_MASK 0x0002
-#define FC_MASK 0x0001
-
-/*****************************************************************
- tbase and rbase registers
-*****************************************************************/
-#define TBD_ADDR(quicc,pram) ((struct quicc_bd *) \
- (quicc->ch_or_u.u.udata_bd_ucode + pram->tbase))
-#define RBD_ADDR(quicc,pram) ((struct quicc_bd *) \
- (quicc->ch_or_u.u.udata_bd_ucode + pram->rbase))
-#define TBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
- (quicc->ch_or_u.u.udata_bd_ucode + pram->tbptr))
-#define RBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \
- (quicc->ch_or_u.u.udata_bd_ucode + pram->rbptr))
-#define TBD_SET_CUR_ADDR(bd,quicc,pram) pram->tbptr = \
- ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
-#define RBD_SET_CUR_ADDR(bd,quicc,pram) pram->rbptr = \
- ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode)))
-#define INCREASE_TBD(bd,quicc,pram) { \
- if((bd)->status & T_W) \
- (bd) = TBD_ADDR(quicc,pram); \
- else \
- (bd)++; \
-}
-#define DECREASE_TBD(bd,quicc,pram) { \
- if ((bd) == TBD_ADDR(quicc, pram)) \
- while (!((bd)->status & T_W)) \
- (bd)++; \
- else \
- (bd)--; \
-}
-#define INCREASE_RBD(bd,quicc,pram) { \
- if((bd)->status & R_W) \
- (bd) = RBD_ADDR(quicc,pram); \
- else \
- (bd)++; \
-}
-#define DECREASE_RBD(bd,quicc,pram) { \
- if ((bd) == RBD_ADDR(quicc, pram)) \
- while (!((bd)->status & T_W)) \
- (bd)++; \
- else \
- (bd)--; \
-}
-
-/*****************************************************************
- Macros for Multi channel
-*****************************************************************/
-#define QMC_BASE(quicc,page) (struct global_multi_pram *)(&quicc->pram[page])
-#define MCBASE(quicc,page) (unsigned long)(quicc->pram[page].m.mcbase)
-#define CHANNEL_PRAM_BASE(quicc,channel) ((struct quicc32_pram *) \
- (&(quicc->ch_or_u.ch_pram_tbl[channel])))
-#define TBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
- (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbase)))
-#define RBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \
- (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbase)))
-#define TBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
- (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbptr)))
-#define RBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \
- (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbptr)))
-#define TBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
- CHANNEL_PRAM_BASE(quicc,channel)->tbptr = \
- ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
-#define RBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \
- CHANNEL_PRAM_BASE(quicc,channel)->rbptr = \
- ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page))))
-
-#define INCREASE_TBD_32(bd,quicc,page,channel) { \
- if((bd)->status & T_W) \
- (bd) = TBD_32_ADDR(quicc,page,channel); \
- else \
- (bd)++; \
-}
-#define DECREASE_TBD_32(bd,quicc,page,channel) { \
- if ((bd) == TBD_32_ADDR(quicc, page,channel)) \
- while (!((bd)->status & T_W)) \
- (bd)++; \
- else \
- (bd)--; \
-}
-#define INCREASE_RBD_32(bd,quicc,page,channel) { \
- if((bd)->status & R_W) \
- (bd) = RBD_32_ADDR(quicc,page,channel); \
- else \
- (bd)++; \
-}
-#define DECREASE_RBD_32(bd,quicc,page,channel) { \
- if ((bd) == RBD_32_ADDR(quicc, page,channel)) \
- while (!((bd)->status & T_W)) \
- (bd)++; \
- else \
- (bd)--; \
-}
-
-#endif
diff --git a/arch/m68k/include/asm/mac_iop.h b/arch/m68k/include/asm/mac_iop.h
index fde874a..42566fd 100644
--- a/arch/m68k/include/asm/mac_iop.h
+++ b/arch/m68k/include/asm/mac_iop.h
@@ -48,7 +48,7 @@
/* IOP message status codes */
-#define IOP_MSGSTATUS_UNUSED 0 /* Unusued message structure */
+#define IOP_MSGSTATUS_UNUSED 0 /* Unused message structure */
#define IOP_MSGSTATUS_WAITING 1 /* waiting for channel */
#define IOP_MSGSTATUS_SENT 2 /* message sent, awaiting reply */
#define IOP_MSGSTATUS_COMPLETE 3 /* message complete and reply rcvd */
diff --git a/arch/m68k/include/asm/mac_psc.h b/arch/m68k/include/asm/mac_psc.h
index e5c0d71..9233051 100644
--- a/arch/m68k/include/asm/mac_psc.h
+++ b/arch/m68k/include/asm/mac_psc.h
@@ -209,7 +209,6 @@
#ifndef __ASSEMBLY__
extern volatile __u8 *psc;
-extern int psc_present;
extern void psc_register_interrupts(void);
extern void psc_irq_enable(int);
diff --git a/arch/m68k/include/asm/mcftimer.h b/arch/m68k/include/asm/mcftimer.h
index 089f0f1..1150e42 100644
--- a/arch/m68k/include/asm/mcftimer.h
+++ b/arch/m68k/include/asm/mcftimer.h
@@ -51,7 +51,7 @@
* Bit definitions for the Timer Event Registers (TER).
*/
#define MCFTIMER_TER_CAP 0x01 /* Capture event */
-#define MCFTIMER_TER_REF 0x02 /* Refernece event */
+#define MCFTIMER_TER_REF 0x02 /* Reference event */
/****************************************************************************/
#endif /* mcftimer_h */
diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index 38b024a..430d4d5 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -48,6 +48,9 @@ extern unsigned long _ramend;
#include <asm/page_no.h>
#endif
+#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
+#define __pfn_to_phys(pfn) PFN_PHYS(pfn)
+
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h
index 848c3df..3a3dbcf 100644
--- a/arch/m68k/include/asm/pci.h
+++ b/arch/m68k/include/asm/pci.h
@@ -1,7 +1,6 @@
#ifndef _ASM_M68K_PCI_H
#define _ASM_M68K_PCI_H
-#include <asm-generic/pci-dma-compat.h>
#include <asm-generic/pci.h>
/* The PCI address space does equal the physical memory
diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h
index 06d0cb1..6d44970 100644
--- a/arch/m68k/include/asm/serial.h
+++ b/arch/m68k/include/asm/serial.h
@@ -18,11 +18,11 @@
/* Standard COM flags (except for COM4, because of the 8514 problem) */
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
+#define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
+#define STD_COM4_FLAGS UPF_BOOT_AUTOCONF
#endif
#ifdef CONFIG_ISA
diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h
index 68bbe9b..1bdf152 100644
--- a/arch/m68k/include/asm/uaccess_no.h
+++ b/arch/m68k/include/asm/uaccess_no.h
@@ -135,10 +135,6 @@ extern int __get_user_bad(void);
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
/*
* Copy a null terminated string from userspace.
*/
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 0793a7f..bafaff6 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -4,7 +4,7 @@
#include <uapi/asm/unistd.h>
-#define NR_syscalls 375
+#define NR_syscalls 377
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_OLD_STAT
diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h
index 5e6fae6..0ca7296 100644
--- a/arch/m68k/include/uapi/asm/unistd.h
+++ b/arch/m68k/include/uapi/asm/unistd.h
@@ -380,5 +380,7 @@
#define __NR_sendmmsg 372
#define __NR_userfaultfd 373
#define __NR_membarrier 374
+#define __NR_mlock2 375
+#define __NR_copy_file_range 376
#endif /* _UAPI_ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 564665f..cbc78b4 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -18,8 +18,8 @@
#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t flag)
+static void *m68k_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t flag, struct dma_attrs *attrs)
{
struct page *page, **map;
pgprot_t pgprot;
@@ -61,8 +61,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return addr;
}
-void dma_free_coherent(struct device *dev, size_t size,
- void *addr, dma_addr_t handle)
+static void m68k_dma_free(struct device *dev, size_t size, void *addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
{
pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
vfree(addr);
@@ -72,8 +72,8 @@ void dma_free_coherent(struct device *dev, size_t size,
#include <asm/cacheflush.h>
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static void *m68k_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
void *ret;
/* ignore region specifiers */
@@ -90,19 +90,16 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
+static void m68k_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
free_pages((unsigned long)vaddr, get_order(size));
}
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
-EXPORT_SYMBOL(dma_alloc_coherent);
-EXPORT_SYMBOL(dma_free_coherent);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
+static void m68k_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
{
switch (dir) {
case DMA_BIDIRECTIONAL:
@@ -118,10 +115,9 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
break;
}
}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir)
+static void m68k_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sglist, int nents, enum dma_data_direction dir)
{
int i;
struct scatterlist *sg;
@@ -131,31 +127,19 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
dir);
}
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
- enum dma_data_direction dir)
-{
- dma_addr_t handle = virt_to_bus(addr);
-
- dma_sync_single_for_device(dev, handle, size, dir);
- return handle;
-}
-EXPORT_SYMBOL(dma_map_single);
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
+static dma_addr_t m68k_dma_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 handle = page_to_phys(page) + offset;
dma_sync_single_for_device(dev, handle, size, dir);
return handle;
}
-EXPORT_SYMBOL(dma_map_page);
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction dir)
+static int m68k_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -167,4 +151,13 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
}
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
+
+struct dma_map_ops m68k_dma_ops = {
+ .alloc = m68k_dma_alloc,
+ .free = m68k_dma_free,
+ .map_page = m68k_dma_map_page,
+ .map_sg = m68k_dma_map_sg,
+ .sync_single_for_device = m68k_dma_sync_single_for_device,
+ .sync_sg_for_device = m68k_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(m68k_dma_ops);
diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
index ff9708d..7d3fe08a 100644
--- a/arch/m68k/kernel/early_printk.c
+++ b/arch/m68k/kernel/early_printk.c
@@ -20,8 +20,8 @@ asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
static void __ref debug_cons_write(struct console *c,
const char *s, unsigned n)
{
-#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68360) || \
- defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE))
+#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \
+ defined(CONFIG_COLDFIRE))
if (MACH_IS_MVME16x)
mvme16x_cons_write(c, s, n);
else
@@ -52,8 +52,8 @@ early_param("earlyprintk", setup_early_printk);
* debug_cons_nputs() defined in arch/m68k/kernel/head.S cannot be called
* after init sections are discarded (for platforms that use it).
*/
-#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68360) || \
- defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE))
+#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \
+ defined(CONFIG_COLDFIRE))
static int __init unregister_early_console(void)
{
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index b54ac7a..97cd3ea 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -71,13 +71,19 @@ ENTRY(__sys_vfork)
ENTRY(sys_sigreturn)
SAVE_SWITCH_STACK
+ movel %sp,%sp@- | switch_stack pointer
+ pea %sp@(SWITCH_STACK_SIZE+4) | pt_regs pointer
jbsr do_sigreturn
+ addql #8,%sp
RESTORE_SWITCH_STACK
rts
ENTRY(sys_rt_sigreturn)
SAVE_SWITCH_STACK
+ movel %sp,%sp@- | switch_stack pointer
+ pea %sp@(SWITCH_STACK_SIZE+4) | pt_regs pointer
jbsr do_rt_sigreturn
+ addql #8,%sp
RESTORE_SWITCH_STACK
rts
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index 88c27d9..9309789 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -68,9 +68,6 @@ void (*mach_power_off)(void);
#define CPU_NAME "MC68000"
#endif
#endif /* CONFIG_M68000 */
-#ifdef CONFIG_M68360
-#define CPU_NAME "MC68360"
-#endif
#ifndef CPU_NAME
#define CPU_NAME "UNKNOWN"
#endif
@@ -209,10 +206,6 @@ void __init setup_arch(char **cmdline_p)
#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
printk(KERN_INFO "PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
#endif
-#if defined (CONFIG_M68360)
- printk(KERN_INFO "QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
- printk(KERN_INFO "based on 2.0.38 port by Lineo Inc. <mleslie@lineo.com>.\n");
-#endif
#ifdef CONFIG_DRAGEN2
printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
#endif
@@ -238,11 +231,14 @@ void __init setup_arch(char **cmdline_p)
* Give all the memory to the bootmap allocator, tell it to put the
* boot mem_map at the start of memory.
*/
+ min_low_pfn = PFN_DOWN(memory_start);
+ max_pfn = max_low_pfn = PFN_DOWN(memory_end);
+
bootmap_size = init_bootmem_node(
NODE_DATA(0),
- memory_start >> PAGE_SHIFT, /* map goes here */
- PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
- memory_end >> PAGE_SHIFT);
+ min_low_pfn, /* map goes here */
+ PFN_DOWN(PAGE_OFFSET),
+ max_pfn);
/*
* Free the usable memory, we have to make sure we do not free
* the bootmem bitmap so we then reserve it after freeing it :-)
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index af1c4f3..2dcee3a 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -737,10 +737,8 @@ badframe:
return 1;
}
-asmlinkage int do_sigreturn(unsigned long __unused)
+asmlinkage int do_sigreturn(struct pt_regs *regs, struct switch_stack *sw)
{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
unsigned long usp = rdusp();
struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
sigset_t set;
@@ -764,10 +762,8 @@ badframe:
return 0;
}
-asmlinkage int do_rt_sigreturn(unsigned long __unused)
+asmlinkage int do_rt_sigreturn(struct pt_regs *regs, struct switch_stack *sw)
{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
unsigned long usp = rdusp();
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
sigset_t set;
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S
index 5dd0e80..8bb9426 100644
--- a/arch/m68k/kernel/syscalltable.S
+++ b/arch/m68k/kernel/syscalltable.S
@@ -395,3 +395,5 @@ ENTRY(sys_call_table)
.long sys_sendmmsg
.long sys_userfaultfd
.long sys_membarrier
+ .long sys_mlock2 /* 375 */
+ .long sys_copy_file_range
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 5c1a6b2..9f98c08 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -174,7 +174,7 @@ void __init mac_init_IRQ(void)
oss_register_interrupts();
else
via_register_interrupts();
- if (psc_present)
+ if (psc)
psc_register_interrupts();
if (baboon_present)
baboon_register_interrupts();
@@ -212,7 +212,7 @@ void mac_irq_enable(struct irq_data *data)
case 4:
case 5:
case 6:
- if (psc_present)
+ if (psc)
psc_irq_enable(irq);
else if (oss_present)
oss_irq_enable(irq);
@@ -242,7 +242,7 @@ void mac_irq_disable(struct irq_data *data)
case 4:
case 5:
case 6:
- if (psc_present)
+ if (psc)
psc_irq_disable(irq);
else if (oss_present)
oss_irq_disable(irq);
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index cd38f29..cb2b1a3 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -27,8 +27,8 @@
#define DEBUG_PSC
-int psc_present;
volatile __u8 *psc;
+EXPORT_SYMBOL_GPL(psc);
/*
* Debugging dump, used in various places to see what's going on.
@@ -38,7 +38,9 @@ static void psc_debug_dump(void)
{
int i;
- if (!psc_present) return;
+ if (!psc)
+ return;
+
for (i = 0x30 ; i < 0x70 ; i += 0x10) {
printk("PSC #%d: IFR = 0x%02X IER = 0x%02X\n",
i >> 4,
@@ -80,7 +82,6 @@ void __init psc_init(void)
&& macintosh_config->ident != MAC_MODEL_Q840)
{
psc = NULL;
- psc_present = 0;
return;
}
@@ -90,7 +91,6 @@ void __init psc_init(void)
*/
psc = (void *) PSC_BASE;
- psc_present = 1;
printk("PSC detected at %p\n", psc);
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index ce56e04..920ff63 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -68,7 +68,7 @@ static int gIER,gIFR,gBufA,gBufB;
* interrupt. This limitation also seems to apply to VIA clone logic cores in
* Quadra-like ASICs. (RBV and OSS machines don't have this limitation.)
*
- * We used to fake it by configuring the relevent VIA pin as an output
+ * We used to fake it by configuring the relevant VIA pin as an output
* (to mask the interrupt) or input (to unmask). That scheme did not work on
* (at least) the Quadra 700. A NuBus card's /NMRQ signal is an open-collector
* circuit (see Designing Cards and Drivers for Macintosh II and Macintosh SE,
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index b958916..8f37fdd 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -250,7 +250,7 @@ void __init paging_init(void)
high_memory = phys_to_virt(max_addr);
min_low_pfn = availmem >> PAGE_SHIFT;
- max_low_pfn = max_addr >> PAGE_SHIFT;
+ max_pfn = max_low_pfn = max_addr >> PAGE_SHIFT;
for (i = 0; i < m68k_num_memory; i++) {
addr = m68k_memory[i].addr;
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index a8b942b..71884bf 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -118,13 +118,13 @@ static void __init sun3_bootmem_alloc(unsigned long memory_start,
memory_end = memory_end & PAGE_MASK;
start_page = __pa(memory_start) >> PAGE_SHIFT;
- num_pages = __pa(memory_end) >> PAGE_SHIFT;
+ max_pfn = num_pages = __pa(memory_end) >> PAGE_SHIFT;
high_memory = (void *)memory_end;
availmem = memory_start;
m68k_setup_node(0);
- availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
+ availmem += init_bootmem(start_page, num_pages);
availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
free_bootmem(__pa(availmem), memory_end - (availmem));
@@ -171,7 +171,7 @@ static void __init sun3_sched_init(irq_handler_t timer_routine)
intersil_clear();
}
-#ifdef CONFIG_SUN3_SCSI
+#if IS_ENABLED(CONFIG_SUN3_SCSI)
static const struct resource sun3_scsi_vme_rsrc[] __initconst = {
{
diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c
index c86ac37..cfe9aa4 100644
--- a/arch/m68k/sun3/idprom.c
+++ b/arch/m68k/sun3/idprom.c
@@ -125,8 +125,5 @@ void __init idprom_init(void)
display_system_type(idprom->id_machtype);
- printk("Ethernet address: %x:%x:%x:%x:%x:%x\n",
- idprom->id_ethaddr[0], idprom->id_ethaddr[1],
- idprom->id_ethaddr[2], idprom->id_ethaddr[3],
- idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
+ printk("Ethernet address: %pM\n", idprom->id_ethaddr);
}
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index 0b389a8..a0fa88d 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -36,9 +36,6 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config RWSEM_GENERIC_SPINLOCK
def_bool y
diff --git a/arch/metag/Makefile b/arch/metag/Makefile
index 9739857..033a582 100644
--- a/arch/metag/Makefile
+++ b/arch/metag/Makefile
@@ -72,7 +72,7 @@ $(boot_targets): vmlinux
$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
dtbs: scripts
- $(Q)$(MAKE) $(build)=$(boot)/dts dtbs
+ $(Q)$(MAKE) $(build)=$(boot)/dts
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
diff --git a/arch/metag/boot/dts/Makefile b/arch/metag/boot/dts/Makefile
index 72c1218..097c6da 100644
--- a/arch/metag/boot/dts/Makefile
+++ b/arch/metag/boot/dts/Makefile
@@ -12,11 +12,10 @@ endif
dtb-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb
obj-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb.o
-targets += dtbs
-targets += $(dtb-y)
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
-dtbs: $(addprefix $(obj)/, $(dtb-y))
-
+always += $(dtb-y)
clean-files += *.dtb *.dtb.S
diff --git a/arch/metag/include/asm/atomic_lnkget.h b/arch/metag/include/asm/atomic_lnkget.h
index 21c4c26..a625818 100644
--- a/arch/metag/include/asm/atomic_lnkget.h
+++ b/arch/metag/include/asm/atomic_lnkget.h
@@ -3,7 +3,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_set(v, i) ((v)->counter = (i))
+#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
#include <linux/compiler.h>
diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h
index f8efe38..0295d9b 100644
--- a/arch/metag/include/asm/atomic_lock1.h
+++ b/arch/metag/include/asm/atomic_lock1.h
@@ -10,7 +10,7 @@
static inline int atomic_read(const atomic_t *v)
{
- return (v)->counter;
+ return READ_ONCE((v)->counter);
}
/*
diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h
index 172b7e5..5418517 100644
--- a/arch/metag/include/asm/barrier.h
+++ b/arch/metag/include/asm/barrier.h
@@ -44,16 +44,6 @@ static inline void wr_fence(void)
#define rmb() barrier()
#define wmb() mb()
-#define dma_rmb() rmb()
-#define dma_wmb() wmb()
-
-#ifndef CONFIG_SMP
-#define fence() do { } while (0)
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#else
-
#ifdef CONFIG_METAG_SMP_WRITE_REORDERING
/*
* Write to the atomic memory unlock system event register (command 0). This is
@@ -63,45 +53,32 @@ static inline void wr_fence(void)
* incoherence). It is therefore ineffective if used after and on the same
* thread as a write.
*/
-static inline void fence(void)
+static inline void metag_fence(void)
{
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
barrier();
*flushptr = 0;
barrier();
}
-#define smp_mb() fence()
-#define smp_rmb() fence()
-#define smp_wmb() barrier()
+#define __smp_mb() metag_fence()
+#define __smp_rmb() metag_fence()
+#define __smp_wmb() barrier()
#else
-#define fence() do { } while (0)
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#endif
+#define metag_fence() do { } while (0)
+#define __smp_mb() barrier()
+#define __smp_rmb() barrier()
+#define __smp_wmb() barrier()
#endif
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
-
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); smp_mb(); } while (0)
-
-#define smp_store_release(p, v) \
-do { \
- compiletime_assert_atomic_type(*p); \
- smp_mb(); \
- WRITE_ONCE(*p, v); \
-} while (0)
+#ifdef CONFIG_SMP
+#define fence() metag_fence()
+#else
+#define fence() do { } while (0)
+#endif
-#define smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_ONCE(*p); \
- compiletime_assert_atomic_type(*p); \
- smp_mb(); \
- ___p1; \
-})
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#include <asm-generic/barrier.h>
#endif /* _ASM_METAG_BARRIER_H */
diff --git a/arch/metag/include/asm/checksum.h b/arch/metag/include/asm/checksum.h
index 08dd1cc..f65fe83 100644
--- a/arch/metag/include/asm/checksum.h
+++ b/arch/metag/include/asm/checksum.h
@@ -59,8 +59,7 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* returns a 16-bit checksum, already complemented
*/
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
unsigned long len_proto = (proto + len) << 8;
@@ -78,8 +77,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
}
static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
diff --git a/arch/metag/include/asm/dma-mapping.h b/arch/metag/include/asm/dma-mapping.h
index eb5cdec..27af5d47 100644
--- a/arch/metag/include/asm/dma-mapping.h
+++ b/arch/metag/include/asm/dma-mapping.h
@@ -1,177 +1,11 @@
#ifndef _ASM_METAG_DMA_MAPPING_H
#define _ASM_METAG_DMA_MAPPING_H
-#include <linux/mm.h>
+extern struct dma_map_ops metag_dma_ops;
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <linux/scatterlist.h>
-#include <asm/bug.h>
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
-void dma_sync_for_device(void *vaddr, size_t size, int dma_direction);
-void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction);
-
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- WARN_ON(size == 0);
- dma_sync_for_device(ptr, size, direction);
- return virt_to_phys(ptr);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- dma_sync_for_cpu(phys_to_virt(dma_addr), size, direction);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction direction)
-{
- struct scatterlist *sg;
- int i;
-
- BUG_ON(!valid_dma_direction(direction));
- WARN_ON(nents == 0 || sglist[0].length == 0);
-
- for_each_sg(sglist, sg, nents, i) {
- BUG_ON(!sg_page(sg));
-
- sg->dma_address = sg_phys(sg);
- dma_sync_for_device(sg_virt(sg), sg->length, direction);
- }
-
- return nents;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- dma_sync_for_device((void *)(page_to_phys(page) + offset), size,
- direction);
- return page_to_phys(page) + offset;
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
-}
-
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nhwentries,
- enum dma_data_direction direction)
-{
- struct scatterlist *sg;
- int i;
-
- BUG_ON(!valid_dma_direction(direction));
- WARN_ON(nhwentries == 0 || sglist[0].length == 0);
-
- for_each_sg(sglist, sg, nhwentries, i) {
- BUG_ON(!sg_page(sg));
-
- sg->dma_address = sg_phys(sg);
- dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
- }
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- dma_sync_for_cpu(phys_to_virt(dma_handle)+offset, size,
- direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- dma_sync_for_device(phys_to_virt(dma_handle)+offset, size,
- direction);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nelems,
- enum dma_data_direction direction)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- dma_sync_for_device(sg_virt(sg), sg->length, direction);
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- return 0;
-}
-
-#define dma_supported(dev, mask) (1)
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
+ return &metag_dma_ops;
}
/*
@@ -184,11 +18,4 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{
}
-/* drivers/base/dma-mapping.c */
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
#endif
diff --git a/arch/metag/include/asm/gpio.h b/arch/metag/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/metag/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/metag/include/asm/highmem.h b/arch/metag/include/asm/highmem.h
index 6646a15..9b1d172 100644
--- a/arch/metag/include/asm/highmem.h
+++ b/arch/metag/include/asm/highmem.h
@@ -56,7 +56,6 @@ extern void kunmap(struct page *page);
extern void *kmap_atomic(struct page *page);
extern void __kunmap_atomic(void *kvaddr);
extern void *kmap_atomic_pfn(unsigned long pfn);
-extern struct page *kmap_atomic_to_page(void *ptr);
#endif
#endif
diff --git a/arch/metag/include/asm/irq.h b/arch/metag/include/asm/irq.h
index ad6bd0e..6ac6d4a 100644
--- a/arch/metag/include/asm/irq.h
+++ b/arch/metag/include/asm/irq.h
@@ -6,8 +6,12 @@ extern void irq_ctx_init(int cpu);
extern void irq_ctx_exit(int cpu);
# define __ARCH_HAS_DO_SOFTIRQ
#else
-# define irq_ctx_init(cpu) do { } while (0)
-# define irq_ctx_exit(cpu) do { } while (0)
+static inline void irq_ctx_init(int cpu)
+{
+}
+static inline void irq_ctx_exit(int cpu)
+{
+}
#endif
void tbi_startup_interrupt(int);
diff --git a/arch/metag/kernel/dma.c b/arch/metag/kernel/dma.c
index c700d62..e12368d 100644
--- a/arch/metag/kernel/dma.c
+++ b/arch/metag/kernel/dma.c
@@ -171,8 +171,8 @@ out:
* Allocate DMA-coherent memory space and return both the kernel remapped
* virtual and bus address for that space.
*/
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t gfp)
+static void *metag_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
{
struct page *page;
struct metag_vm_region *c;
@@ -263,13 +263,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
no_page:
return NULL;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
/*
* free a page as defined by the above mapping.
*/
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
+static void metag_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
struct metag_vm_region *c;
unsigned long flags, addr;
@@ -329,16 +328,19 @@ no_area:
__func__, vaddr);
dump_stack();
}
-EXPORT_SYMBOL(dma_free_coherent);
-
-static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
+static int metag_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;
-
unsigned long flags, user_size, kern_size;
struct metag_vm_region *c;
+ int ret = -ENXIO;
+
+ if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@ -364,25 +366,6 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
return ret;
}
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_coherent);
-
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_writecombine);
-
-
-
-
/*
* Initialise the consistent memory allocation.
*/
@@ -423,7 +406,7 @@ early_initcall(dma_alloc_init);
/*
* make an area consistent to devices.
*/
-void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
+static void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
{
/*
* Ensure any writes get through the write combiner. This is necessary
@@ -465,12 +448,11 @@ void dma_sync_for_device(void *vaddr, size_t size, int dma_direction)
wmb();
}
-EXPORT_SYMBOL(dma_sync_for_device);
/*
* make an area consistent to the core.
*/
-void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
+static void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
{
/*
* Hardware L2 cache prefetch doesn't occur across 4K physical
@@ -497,4 +479,100 @@ void dma_sync_for_cpu(void *vaddr, size_t size, int dma_direction)
rmb();
}
-EXPORT_SYMBOL(dma_sync_for_cpu);
+
+static dma_addr_t metag_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ dma_sync_for_device((void *)(page_to_phys(page) + offset), size,
+ direction);
+ return page_to_phys(page) + offset;
+}
+
+static void metag_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
+}
+
+static int metag_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sglist, sg, nents, i) {
+ BUG_ON(!sg_page(sg));
+
+ sg->dma_address = sg_phys(sg);
+ dma_sync_for_device(sg_virt(sg), sg->length, direction);
+ }
+
+ return nents;
+}
+
+
+static void metag_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+ int nhwentries, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sglist, sg, nhwentries, i) {
+ BUG_ON(!sg_page(sg));
+
+ sg->dma_address = sg_phys(sg);
+ dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+ }
+}
+
+static void metag_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
+}
+
+static void metag_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
+}
+
+static void metag_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sglist, int nelems,
+ enum dma_data_direction direction)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nelems, i)
+ dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+}
+
+static void metag_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sglist, int nelems,
+ enum dma_data_direction direction)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nelems, i)
+ dma_sync_for_device(sg_virt(sg), sg->length, direction);
+}
+
+struct dma_map_ops metag_dma_ops = {
+ .alloc = metag_dma_alloc,
+ .free = metag_dma_free,
+ .map_page = metag_dma_map_page,
+ .map_sg = metag_dma_map_sg,
+ .sync_single_for_device = metag_dma_sync_single_for_device,
+ .sync_single_for_cpu = metag_dma_sync_single_for_cpu,
+ .sync_sg_for_cpu = metag_dma_sync_sg_for_cpu,
+ .mmap = metag_dma_mmap,
+};
+EXPORT_SYMBOL(metag_dma_ops);
diff --git a/arch/metag/kernel/ftrace.c b/arch/metag/kernel/ftrace.c
index ed1d685..ac8c039 100644
--- a/arch/metag/kernel/ftrace.c
+++ b/arch/metag/kernel/ftrace.c
@@ -54,12 +54,11 @@ static int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
unsigned char replaced[MCOUNT_INSN_SIZE];
/*
- * Note: Due to modules and __init, code can
- * disappear and change, we need to protect against faulting
- * as well as code changing.
- *
- * No real locking needed, this code is run through
- * kstop_machine.
+ * Note:
+ * We are paranoid about modifying text, as if a bug was to happen, it
+ * could cause us to read or write to someplace that could cause harm.
+ * Carefully read and modify the code with probe_kernel_*(), and make
+ * sure what we read is what we expected it to be before modifying it.
*/
/* read the text we want to modify */
diff --git a/arch/metag/kernel/module.c b/arch/metag/kernel/module.c
index 986331c..bb8dfba 100644
--- a/arch/metag/kernel/module.c
+++ b/arch/metag/kernel/module.c
@@ -176,8 +176,8 @@ static uint32_t do_plt_call(void *location, Elf32_Addr val,
tramp[1] = 0xac000001 | ((val & 0x0000ffff) << 3);
/* Init, or core PLT? */
- if (location >= mod->module_core
- && location < mod->module_core + mod->core_size)
+ if (location >= mod->core_layout.base
+ && location < mod->core_layout.base + mod->core_layout.size)
entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
else
entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
diff --git a/arch/metag/kernel/smp.c b/arch/metag/kernel/smp.c
index ac3a199..bad1323 100644
--- a/arch/metag/kernel/smp.c
+++ b/arch/metag/kernel/smp.c
@@ -312,6 +312,7 @@ void cpu_die(void)
{
local_irq_disable();
idle_task_exit();
+ irq_ctx_exit(smp_processor_id());
(void)cpu_report_death();
@@ -366,6 +367,7 @@ asmlinkage void secondary_start_kernel(void)
panic("No TBI found!");
per_cpu_trap_init(cpu);
+ irq_ctx_init(cpu);
preempt_disable();
@@ -394,7 +396,7 @@ asmlinkage void secondary_start_kernel(void)
/*
* OK, it's off to the idle thread for us
*/
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
void __init smp_cpus_done(unsigned int max_cpus)
diff --git a/arch/metag/mm/highmem.c b/arch/metag/mm/highmem.c
index 807f1b1..f19a87f 100644
--- a/arch/metag/mm/highmem.c
+++ b/arch/metag/mm/highmem.c
@@ -111,20 +111,6 @@ void *kmap_atomic_pfn(unsigned long pfn)
return (void *)vaddr;
}
-struct page *kmap_atomic_to_page(void *ptr)
-{
- unsigned long vaddr = (unsigned long)ptr;
- int idx;
- pte_t *pte;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- idx = virt_to_fix(vaddr);
- pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
- return pte_page(*pte);
-}
-
void __init kmap_init(void)
{
unsigned long kmap_vstart;
diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
index 53f0f6c..b38700ae 100644
--- a/arch/metag/mm/hugetlbpage.c
+++ b/arch/metag/mm/hugetlbpage.c
@@ -67,7 +67,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
pgd = pgd_offset(mm, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
- pte = pte_alloc_map(mm, NULL, pmd, addr);
+ pte = pte_alloc_map(mm, pmd, addr);
pgd->pgd &= ~_PAGE_SZ_MASK;
pgd->pgd |= _PAGE_SZHUGE;
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 0bce820..3d793b5 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -19,7 +19,6 @@ config MICROBLAZE
select HAVE_ARCH_KGDB
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
- select HAVE_DMA_ATTRS
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
@@ -67,9 +66,6 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -271,6 +267,9 @@ config PCI
config PCI_DOMAINS
def_bool PCI
+config PCI_DOMAINS_GENERIC
+ def_bool PCI_DOMAINS
+
config PCI_SYSCALL
def_bool PCI
diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig
index e2f6543..dc5dd5b 100644
--- a/arch/microblaze/configs/mmu_defconfig
+++ b/arch/microblaze/configs/mmu_defconfig
@@ -87,5 +87,4 @@ CONFIG_KGDB_KDB=y
CONFIG_EARLY_PRINTK=y
CONFIG_KEYS=y
CONFIG_ENCRYPTED_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig
index a29ebd4..4cdaf56 100644
--- a/arch/microblaze/configs/nommu_defconfig
+++ b/arch/microblaze/configs/nommu_defconfig
@@ -92,7 +92,6 @@ CONFIG_DEBUG_INFO=y
CONFIG_EARLY_PRINTK=y
CONFIG_KEYS=y
CONFIG_ENCRYPTED_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
index 0185cbe..adeeceb 100644
--- a/arch/microblaze/include/asm/checksum.h
+++ b/arch/microblaze/include/asm/checksum.h
@@ -16,8 +16,8 @@
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
__asm__("add %0, %0, %1\n\t"
"addc %0, %0, %2\n\t"
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
index 24b1297..1884783 100644
--- a/arch/microblaze/include/asm/dma-mapping.h
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -44,8 +44,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &dma_direct_ops;
}
-#include <asm-generic/dma-mapping-common.h>
-
static inline void __dma_sync(unsigned long paddr,
size_t size, enum dma_data_direction direction)
{
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/microblaze/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/microblaze/include/asm/highmem.h b/arch/microblaze/include/asm/highmem.h
index d046389..67925ef 100644
--- a/arch/microblaze/include/asm/highmem.h
+++ b/arch/microblaze/include/asm/highmem.h
@@ -76,19 +76,6 @@ static inline void *kmap_atomic(struct page *page)
return kmap_atomic_prot(page, kmap_prot);
}
-static inline struct page *kmap_atomic_to_page(void *ptr)
-{
- unsigned long idx, vaddr = (unsigned long) ptr;
- pte_t *pte;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- idx = virt_to_fix(vaddr);
- pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
- return pte_page(*pte);
-}
-
#define flush_cache_kmaps() { flush_icache(); flush_dcache(); }
#endif /* __KERNEL__ */
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index dc9eb66..fc3ecb5 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -22,8 +22,6 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
-#include <asm-generic/pci-dma-compat.h>
-
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index c89da63..bf4dec2 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -61,7 +61,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg);
- __dma_sync(sg_phys(sg), sg->length, direction);
+ __dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
+ sg->length, direction);
}
return nents;
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index ab5b488..f31ebb5 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -130,8 +130,6 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
memset(__bss_start, 0, __bss_stop-__bss_start);
memset(_ssbss, 0, _esbss-_ssbss);
- lockdep_init();
-
/* initialize device tree for usage in early_printk */
early_init_devtree(_fdt_start);
@@ -194,7 +192,7 @@ void __init time_init(void)
{
of_clk_init(NULL);
setup_cpuinfo_clk();
- clocksource_of_init();
+ clocksource_probe();
}
#ifdef CONFIG_DEBUG_FS
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index ae838ed..35654be 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -123,17 +123,6 @@ unsigned long pci_address_to_pio(phys_addr_t address)
}
EXPORT_SYMBOL_GPL(pci_address_to_pio);
-/*
- * Return the domain number for this bus.
- */
-int pci_domain_nr(struct pci_bus *bus)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
-
- return hose->global_number;
-}
-EXPORT_SYMBOL(pci_domain_nr);
-
/* This routine is meant to be used early during boot, when the
* PCI bus numbers have not yet been assigned, and you need to
* issue PCI config cycles to an OF device.
@@ -863,26 +852,10 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
void pcibios_fixup_bus(struct pci_bus *bus)
{
- /* When called from the generic PCI probe, read PCI<->PCI bridge
- * bases. This is -not- called when generating the PCI tree from
- * the OF device-tree.
- */
- if (bus->self != NULL)
- pci_read_bridge_bases(bus);
-
- /* Now fixup the bus bus */
- pcibios_setup_bus_self(bus);
-
- /* Now fixup devices on that bus */
- pcibios_setup_bus_devices(bus);
+ /* nothing to do */
}
EXPORT_SYMBOL(pcibios_fixup_bus);
-static int skip_isa_ioresource_align(struct pci_dev *dev)
-{
- return 0;
-}
-
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
@@ -899,20 +872,18 @@ static int skip_isa_ioresource_align(struct pci_dev *dev)
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;
- resource_size_t start = res->start;
-
- if (res->flags & IORESOURCE_IO) {
- if (skip_isa_ioresource_align(dev))
- return start;
- if (start & 0x300)
- start = (start + 0x3ff) & ~0x3ff;
- }
-
- return start;
+ return res->start;
}
EXPORT_SYMBOL(pcibios_align_resource);
+int pcibios_add_device(struct pci_dev *dev)
+{
+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(pcibios_add_device);
+
/*
* Reparent resource children of pr that conflict with res
* under res, and make res replace those children.
@@ -1333,13 +1304,6 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
(unsigned long)hose->io_base_virt - _IO_BASE);
}
-struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
-{
- struct pci_controller *hose = bus->sysdata;
-
- return of_node_get(hose->dn);
-}
-
static void pcibios_scan_phb(struct pci_controller *hose)
{
LIST_HEAD(resources);
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
index dd29533..5c3f688 100644
--- a/arch/mips/Kbuild
+++ b/arch/mips/Kbuild
@@ -17,6 +17,7 @@ obj- := $(platform-)
obj-y += kernel/
obj-y += mm/
obj-y += net/
+obj-y += vdso/
ifdef CONFIG_KVM
obj-y += kvm/
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index a424e46..c5cd63a 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -21,6 +21,7 @@ platforms += mti-malta
platforms += mti-sead3
platforms += netlogic
platforms += paravirt
+platforms += pic32
platforms += pistachio
platforms += pmcs-msp71xx
platforms += pnx833x
@@ -33,6 +34,7 @@ platforms += sibyte
platforms += sni
platforms += txx9
platforms += vr41xx
+platforms += xilfpga
# include the platform specific files
include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e3aa5b0..7c4a4ce 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -5,6 +5,7 @@ config MIPS
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
+ select ARCH_USE_BUILTIN_BSWAP
select HAVE_CONTEXT_TRACKING
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE
@@ -30,7 +31,6 @@ config MIPS
select RTC_LIB if !MACH_LOONGSON64
select GENERIC_ATOMIC64 if !64BIT
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
- select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DMA_API_DEBUG
select GENERIC_IRQ_PROBE
@@ -60,6 +60,8 @@ config MIPS
select SYSCTL_EXCEPTION_TRACE
select HAVE_VIRT_CPU_ACCOUNTING_GEN
select HAVE_IRQ_TIME_ACCOUNTING
+ select GENERIC_TIME_VSYSCALL
+ select ARCH_CLOCKSOURCE_DATA
menu "Machine selection"
@@ -149,6 +151,7 @@ config BMIPS_GENERIC
select CSRC_R4K
select SYNC_R4K
select COMMON_CLK
+ select BCM6345_L1_IRQ
select BCM7038_L1_IRQ
select BCM7120_L2_IRQ
select BRCMSTB_L2_IRQ
@@ -167,6 +170,7 @@ config BMIPS_GENERIC
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Build a generic DT-based kernel image that boots on select
BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
@@ -401,6 +405,28 @@ config MACH_PISTACHIO
help
This enables support for the IMG Pistachio SoC platform.
+config MACH_XILFPGA
+ bool "MIPSfpga Xilinx based boards"
+ select ARCH_REQUIRE_GPIOLIB
+ select BOOT_ELF32
+ select BOOT_RAW
+ select BUILTIN_DTB
+ select CEVT_R4K
+ select COMMON_CLK
+ select CSRC_R4K
+ select IRQ_MIPS_CPU
+ select LIBFDT
+ select MIPS_CPU_SCACHE
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ select USE_OF
+ select USE_GENERIC_EARLY_PRINTK_8250
+ help
+ This enables support for the IMG University Program MIPSfpga platform.
+
config MIPS_MALTA
bool "MIPS Malta board"
select ARCH_MAY_HAVE_PC_FDC
@@ -424,6 +450,7 @@ config MIPS_MALTA
select MIPS_L1_CACHE_SHIFT_6
select PCI_GT64XXX_PCI0
select MIPS_MSC
+ select SMP_UP if SMP
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
@@ -449,10 +476,20 @@ config MIPS_MALTA
select SYS_SUPPORTS_ZBOOT
select USE_OF
select ZONE_DMA32 if 64BIT
+ select BUILTIN_DTB
+ select LIBFDT
help
This enables support for the MIPS Technologies Malta evaluation
board.
+config MACH_PIC32
+ bool "Microchip PIC32 Family"
+ help
+ This enables support for the Microchip PIC32 family of platforms.
+
+ Microchip PIC32 is a family of general-purpose 32 bit MIPS core
+ microcontrollers.
+
config MIPS_SEAD3
bool "MIPS SEAD3 board"
select BOOT_ELF32
@@ -952,6 +989,7 @@ source "arch/mips/jazz/Kconfig"
source "arch/mips/jz4740/Kconfig"
source "arch/mips/lantiq/Kconfig"
source "arch/mips/lasat/Kconfig"
+source "arch/mips/pic32/Kconfig"
source "arch/mips/pistachio/Kconfig"
source "arch/mips/pmcs-msp71xx/Kconfig"
source "arch/mips/ralink/Kconfig"
@@ -964,6 +1002,7 @@ source "arch/mips/loongson32/Kconfig"
source "arch/mips/loongson64/Kconfig"
source "arch/mips/netlogic/Kconfig"
source "arch/mips/paravirt/Kconfig"
+source "arch/mips/xilfpga/Kconfig"
endmenu
@@ -1036,6 +1075,9 @@ config CSRC_R4K
config CSRC_SB1250
bool
+config MIPS_CLOCK_VSYSCALL
+ def_bool CSRC_R4K || CLKSRC_MIPS_GIC
+
config GPIO_TXX9
select ARCH_REQUIRE_GPIOLIB
bool
@@ -1724,6 +1766,10 @@ config SYS_SUPPORTS_ZBOOT_UART16550
bool
select SYS_SUPPORTS_ZBOOT
+config SYS_SUPPORTS_ZBOOT_UART_PROM
+ bool
+ select SYS_SUPPORTS_ZBOOT
+
config CPU_LOONGSON2
bool
select CPU_SUPPORTS_32BIT_KERNEL
@@ -1986,7 +2032,8 @@ config KVM_GUEST
bool "KVM Guest Kernel"
depends on BROKEN_ON_SMP
help
- Select this option if building a guest kernel for KVM (Trap & Emulate) mode
+ Select this option if building a guest kernel for KVM (Trap & Emulate)
+ mode.
config KVM_GUEST_TIMER_FREQ
int "Count/Compare Timer Frequency (MHz)"
@@ -2039,7 +2086,7 @@ config PAGE_SIZE_32KB
config PAGE_SIZE_64KB
bool "64kB"
- depends on !CPU_R3000 && !CPU_TX39XX
+ depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000
help
Using 64kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available on
@@ -2123,7 +2170,6 @@ config MIPS_MT_SMP
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
select SYNC_R4K
- select MIPS_GIC_IPI
select MIPS_MT
select SMP
select SMP_UP
@@ -2221,7 +2267,6 @@ config MIPS_VPE_APSP_API_MT
config MIPS_CMP
bool "MIPS CMP framework support (DEPRECATED)"
depends on SYS_SUPPORTS_MIPS_CMP && !CPU_MIPSR6
- select MIPS_GIC_IPI
select SMP
select SYNC_R4K
select SYS_SUPPORTS_SMP
@@ -2241,7 +2286,6 @@ config MIPS_CPS
select MIPS_CM
select MIPS_CPC
select MIPS_CPS_PM if HOTPLUG_CPU
- select MIPS_GIC_IPI
select SMP
select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
select SYS_SUPPORTS_HOTPLUG_CPU
@@ -2259,9 +2303,6 @@ config MIPS_CPS_PM
select MIPS_CPC
bool
-config MIPS_GIC_IPI
- bool
-
config MIPS_CM
bool
@@ -2529,6 +2570,9 @@ choice
help
Allows the configuration of the timer frequency.
+ config HZ_24
+ bool "24 HZ" if SYS_SUPPORTS_24HZ || SYS_SUPPORTS_ARBIT_HZ
+
config HZ_48
bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ
@@ -2552,6 +2596,9 @@ choice
endchoice
+config SYS_SUPPORTS_24HZ
+ bool
+
config SYS_SUPPORTS_48HZ
bool
@@ -2575,13 +2622,18 @@ config SYS_SUPPORTS_1024HZ
config SYS_SUPPORTS_ARBIT_HZ
bool
- default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \
- !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \
- !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \
+ default y if !SYS_SUPPORTS_24HZ && \
+ !SYS_SUPPORTS_48HZ && \
+ !SYS_SUPPORTS_100HZ && \
+ !SYS_SUPPORTS_128HZ && \
+ !SYS_SUPPORTS_250HZ && \
+ !SYS_SUPPORTS_256HZ && \
+ !SYS_SUPPORTS_1000HZ && \
!SYS_SUPPORTS_1024HZ
config HZ
int
+ default 24 if HZ_24
default 48 if HZ_48
default 100 if HZ_100
default 128 if HZ_128
@@ -2685,7 +2737,7 @@ config BUILTIN_DTB
bool
choice
- prompt "Kernel appended dtb support" if OF
+ prompt "Kernel appended dtb support" if USE_OF
default MIPS_NO_APPENDED_DTB
config MIPS_NO_APPENDED_DTB
@@ -2693,6 +2745,20 @@ choice
help
Do not enable appended dtb support.
+ config MIPS_ELF_APPENDED_DTB
+ bool "vmlinux"
+ help
+ With this option, the boot code will look for a device tree binary
+ DTB) included in the vmlinux ELF section .appended_dtb. By default
+ it is empty and the DTB can be appended using binutils command
+ objcopy:
+
+ objcopy --update-section .appended_dtb=<filename>.dtb vmlinux
+
+ This is meant as a backward compatiblity convenience for those
+ systems with a bootloader that can't be upgraded to accommodate
+ the documented boot protocol using a device tree.
+
config MIPS_RAW_APPENDED_DTB
bool "vmlinux.bin"
help
@@ -2729,6 +2795,25 @@ choice
if you don't intend to always append a DTB.
endchoice
+choice
+ prompt "Kernel command line type" if !CMDLINE_OVERRIDE
+ default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \
+ !MIPS_MALTA && !MIPS_SEAD3 && \
+ !CAVIUM_OCTEON_SOC
+ default MIPS_CMDLINE_FROM_BOOTLOADER
+
+ config MIPS_CMDLINE_FROM_DTB
+ depends on USE_OF
+ bool "Dtb kernel arguments if available"
+
+ config MIPS_CMDLINE_DTB_EXTEND
+ depends on USE_OF
+ bool "Extend dtb kernel arguments with bootloader arguments"
+
+ config MIPS_CMDLINE_FROM_BOOTLOADER
+ bool "Bootloader kernel arguments if available"
+endchoice
+
endmenu
config LOCKDEP_SUPPORT
@@ -2739,6 +2824,10 @@ config STACKTRACE_SUPPORT
bool
default y
+config HAVE_LATENCYTOP_SUPPORT
+ bool
+ default y
+
config PGTABLE_LEVELS
int
default 3 if 64BIT && !PAGE_SIZE_64KB
@@ -2782,8 +2871,6 @@ config PCI_DOMAINS
source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
-
#
# ISA support is now enabled via select. Too many systems still have the one
# or other ISA chip on the board that users don't know about so don't expect
@@ -2843,8 +2930,6 @@ config ZONE_DMA32
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
config RAPIDIO
tristate "RapidIO support"
depends on PCI
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index e250524..f0e314c 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -113,4 +113,76 @@ config SPINLOCK_TEST
help
Add several files to the debugfs to test spinlock speed.
+if CPU_MIPSR6
+
+choice
+ prompt "Compact branch policy"
+ default MIPS_COMPACT_BRANCHES_OPTIMAL
+
+config MIPS_COMPACT_BRANCHES_NEVER
+ bool "Never (force delay slot branches)"
+ help
+ Pass the -mcompact-branches=never flag to the compiler in order to
+ force it to always emit branches with delay slots, and make no use
+ of the compact branch instructions introduced by MIPSr6. This is
+ useful if you suspect there may be an issue with compact branches in
+ either the compiler or the CPU.
+
+config MIPS_COMPACT_BRANCHES_OPTIMAL
+ bool "Optimal (use where beneficial)"
+ help
+ Pass the -mcompact-branches=optimal flag to the compiler in order for
+ it to make use of compact branch instructions where it deems them
+ beneficial, and use branches with delay slots elsewhere. This is the
+ default compiler behaviour, and should be used unless you have a
+ reason to choose otherwise.
+
+config MIPS_COMPACT_BRANCHES_ALWAYS
+ bool "Always (force compact branches)"
+ help
+ Pass the -mcompact-branches=always flag to the compiler in order to
+ force it to always emit compact branches, making no use of branch
+ instructions with delay slots. This can result in more compact code
+ which may be beneficial in some scenarios.
+
+endchoice
+
+endif # CPU_MIPSR6
+
+config SCACHE_DEBUGFS
+ bool "L2 cache debugfs entries"
+ depends on DEBUG_FS
+ help
+ Enable this to allow parts of the L2 cache configuration, such as
+ whether or not prefetching is enabled, to be exposed to userland
+ via debugfs.
+
+ If unsure, say N.
+
+menuconfig MIPS_CPS_NS16550
+ bool "CPS SMP NS16550 UART output"
+ depends on MIPS_CPS
+ help
+ Output debug information via an ns16550 compatible UART if exceptions
+ occur early in the boot process of a secondary core.
+
+if MIPS_CPS_NS16550
+
+config MIPS_CPS_NS16550_BASE
+ hex "UART Base Address"
+ default 0x1b0003f8 if MIPS_MALTA
+ help
+ The base address of the ns16550 compatible UART on which to output
+ debug information from the early stages of core startup.
+
+config MIPS_CPS_NS16550_SHIFT
+ int "UART Register Shift"
+ default 0 if MIPS_MALTA
+ help
+ The number of bits to shift ns16550 register indices by in order to
+ form their addresses. That is, log base 2 of the span between
+ adjacent ns16550 registers in the system.
+
+endif # MIPS_CPS_NS16550
+
endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 252e347..e78d60d 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -166,16 +166,6 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap
-#
-# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
-# as MIPS64 R1; older versions as just R1. This leaves the possibility open
-# that GCC might generate R2 code for -march=loongson3a which then is rejected
-# by GAS. The cc-option can't probe for this behaviour so -march=loongson3a
-# can't easily be used safely within the kbuild framework.
-#
-cflags-$(CONFIG_CPU_LOONGSON3) += \
- $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
- -Wa,-mips64r2 -Wa,--trap
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
@@ -204,6 +194,10 @@ toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(
cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA
endif
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal
+cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS) += -mcompact-branches=always
+
#
# Firmware support
#
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c
index f9bc4f5..e6b90e7 100644
--- a/arch/mips/alchemy/common/gpiolib.c
+++ b/arch/mips/alchemy/common/gpiolib.c
@@ -40,7 +40,7 @@
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
- return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
+ return !!alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
}
static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -68,7 +68,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
static int gpio1_get(struct gpio_chip *chip, unsigned offset)
{
- return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
+ return !!alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
}
static void gpio1_set(struct gpio_chip *chip,
@@ -119,7 +119,7 @@ struct gpio_chip alchemy_gpio_chip[] = {
static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
{
- return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
+ return !!au1300_gpio_get_value(off + AU1300_GPIO_BASE);
}
static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
@@ -160,14 +160,14 @@ static int __init alchemy_gpiochip_init(void)
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
- ret = gpiochip_add(&alchemy_gpio_chip[0]);
+ ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL);
break;
case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200:
- ret = gpiochip_add(&alchemy_gpio_chip[0]);
- ret |= gpiochip_add(&alchemy_gpio_chip[1]);
+ ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL);
+ ret |= gpiochip_add_data(&alchemy_gpio_chip[1], NULL);
break;
case ALCHEMY_CPU_AU1300:
- ret = gpiochip_add(&au1300_gpiochip);
+ ret = gpiochip_add_data(&au1300_gpiochip, NULL);
break;
}
return ret;
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
index 8c13675..992442a 100644
--- a/arch/mips/alchemy/devboards/db1200.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -200,7 +200,7 @@ static struct i2c_board_info db1200_i2c_devs[] __initdata = {
static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c
index b580770..d3c087f 100644
--- a/arch/mips/alchemy/devboards/db1300.c
+++ b/arch/mips/alchemy/devboards/db1300.c
@@ -150,7 +150,7 @@ static void __init db1300_gpio_config(void)
static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
index 5740bcf..b518f02 100644
--- a/arch/mips/alchemy/devboards/db1550.c
+++ b/arch/mips/alchemy/devboards/db1550.c
@@ -128,7 +128,7 @@ static struct i2c_board_info db1550_i2c_devs[] __initdata = {
static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c
index f493045..ed5b3d2 100644
--- a/arch/mips/ar7/gpio.c
+++ b/arch/mips/ar7/gpio.c
@@ -33,17 +33,15 @@ struct ar7_gpio_chip {
static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
- return readl(gpio_in) & (1 << gpio);
+ return !!(readl(gpio_in) & (1 << gpio));
}
static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
@@ -53,8 +51,7 @@ static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
static void ar7_gpio_set_value(struct gpio_chip *chip,
unsigned gpio, int value)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
unsigned tmp;
@@ -67,8 +64,7 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
static void titan_gpio_set_value(struct gpio_chip *chip,
unsigned gpio, int value)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
unsigned tmp;
@@ -81,8 +77,7 @@ static void titan_gpio_set_value(struct gpio_chip *chip,
static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
@@ -92,8 +87,7 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
@@ -108,8 +102,7 @@ static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
static int ar7_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
ar7_gpio_set_value(chip, gpio, value);
@@ -121,8 +114,7 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
static int titan_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
- struct ar7_gpio_chip *gpch =
- container_of(chip, struct ar7_gpio_chip, chip);
+ struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
@@ -335,7 +327,7 @@ int __init ar7_gpio_init(void)
return -ENOMEM;
}
- ret = gpiochip_add(&gpch->chip);
+ ret = gpiochip_add_data(&gpch->chip, gpch);
if (ret) {
printk(KERN_ERR "%s: failed to add gpiochip\n",
gpch->chip.label);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index ca7cc19..870c6b2 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -23,7 +23,6 @@ void ath79_clocks_init(void);
unsigned long ath79_get_sys_clk_rate(const char *id);
void ath79_ddr_ctrl_init(void);
-void ath79_ddr_wb_flush(unsigned int reg);
void ath79_gpio_init(void);
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index eeb3953..2dfff1f 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -26,98 +26,6 @@
#include "common.h"
#include "machtypes.h"
-static void ath79_misc_irq_handler(struct irq_desc *desc)
-{
- void __iomem *base = ath79_reset_base;
- u32 pending;
-
- pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
- __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
- if (!pending) {
- spurious_interrupt();
- return;
- }
-
- while (pending) {
- int bit = __ffs(pending);
-
- generic_handle_irq(ATH79_MISC_IRQ(bit));
- pending &= ~BIT(bit);
- }
-}
-
-static void ar71xx_misc_irq_unmask(struct irq_data *d)
-{
- unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
- void __iomem *base = ath79_reset_base;
- u32 t;
-
- t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
- __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
- /* flush write */
- __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-}
-
-static void ar71xx_misc_irq_mask(struct irq_data *d)
-{
- unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
- void __iomem *base = ath79_reset_base;
- u32 t;
-
- t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-
- /* flush write */
- __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-}
-
-static void ar724x_misc_irq_ack(struct irq_data *d)
-{
- unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
- void __iomem *base = ath79_reset_base;
- u32 t;
-
- t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
- /* flush write */
- __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
-}
-
-static struct irq_chip ath79_misc_irq_chip = {
- .name = "MISC",
- .irq_unmask = ar71xx_misc_irq_unmask,
- .irq_mask = ar71xx_misc_irq_mask,
-};
-
-static void __init ath79_misc_irq_init(void)
-{
- void __iomem *base = ath79_reset_base;
- int i;
-
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
- if (soc_is_ar71xx() || soc_is_ar913x())
- ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
- else if (soc_is_ar724x() ||
- soc_is_ar933x() ||
- soc_is_ar934x() ||
- soc_is_qca955x())
- ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
- else
- BUG();
-
- for (i = ATH79_MISC_IRQ_BASE;
- i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
- irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
- handle_level_irq);
- }
-
- irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
-}
static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
{
@@ -220,139 +128,12 @@ static void qca955x_irq_init(void)
irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
}
-/*
- * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
- * these devices typically allocate coherent DMA memory, however the
- * DMA controller may still have some unsynchronized data in the FIFO.
- * Issue a flush in the handlers to ensure that the driver sees
- * the update.
- *
- * This array map the interrupt lines to the DDR write buffer channels.
- */
-
-static unsigned irq_wb_chan[8] = {
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned long pending;
- int irq;
-
- pending = read_c0_status() & read_c0_cause() & ST0_IM;
-
- if (!pending) {
- spurious_interrupt();
- return;
- }
-
- pending >>= CAUSEB_IP;
- while (pending) {
- irq = fls(pending) - 1;
- if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1)
- ath79_ddr_wb_flush(irq_wb_chan[irq]);
- do_IRQ(MIPS_CPU_IRQ_BASE + irq);
- pending &= ~BIT(irq);
- }
-}
-
-#ifdef CONFIG_IRQCHIP
-static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-{
- irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
- return 0;
-}
-
-static const struct irq_domain_ops misc_irq_domain_ops = {
- .xlate = irq_domain_xlate_onecell,
- .map = misc_map,
-};
-
-static int __init ath79_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
-{
- void __iomem *base = ath79_reset_base;
- struct irq_domain *domain;
- int irq;
-
- irq = irq_of_parse_and_map(node, 0);
- if (!irq)
- panic("Failed to get MISC IRQ");
-
- domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
- ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
- if (!domain)
- panic("Failed to add MISC irqdomain");
-
- /* Disable and clear all interrupts */
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
-
- irq_set_chained_handler(irq, ath79_misc_irq_handler);
-
- return 0;
-}
-
-static int __init ar7100_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
-{
- ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
- return ath79_misc_intc_of_init(node, parent);
-}
-
-IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
- ar7100_misc_intc_of_init);
-
-static int __init ar7240_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
-{
- ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
- return ath79_misc_intc_of_init(node, parent);
-}
-
-IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
- ar7240_misc_intc_of_init);
-
-static int __init ar79_cpu_intc_of_init(
- struct device_node *node, struct device_node *parent)
-{
- int err, i, count;
-
- /* Fill the irq_wb_chan table */
- count = of_count_phandle_with_args(
- node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
-
- for (i = 0; i < count; i++) {
- struct of_phandle_args args;
- u32 irq = i;
-
- of_property_read_u32_index(
- node, "qca,ddr-wb-channel-interrupts", i, &irq);
- if (irq >= ARRAY_SIZE(irq_wb_chan))
- continue;
-
- err = of_parse_phandle_with_args(
- node, "qca,ddr-wb-channels",
- "#qca,ddr-wb-channel-cells",
- i, &args);
- if (err)
- return err;
-
- irq_wb_chan[irq] = args.args[0];
- pr_info("IRQ: Set flush channel of IRQ%d to %d\n",
- irq, args.args[0]);
- }
-
- return mips_cpu_irq_of_init(node, parent);
-}
-IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
- ar79_cpu_intc_of_init);
-
-#endif
-
void __init arch_init_irq(void)
{
+ unsigned irq_wb_chan2 = -1;
+ unsigned irq_wb_chan3 = -1;
+ bool misc_is_ar71xx;
+
if (mips_machtype == ATH79_MACH_GENERIC_OF) {
irqchip_init();
return;
@@ -360,14 +141,26 @@ void __init arch_init_irq(void)
if (soc_is_ar71xx() || soc_is_ar724x() ||
soc_is_ar913x() || soc_is_ar933x()) {
- irq_wb_chan[2] = 3;
- irq_wb_chan[3] = 2;
+ irq_wb_chan2 = 3;
+ irq_wb_chan3 = 2;
} else if (soc_is_ar934x()) {
- irq_wb_chan[3] = 2;
+ irq_wb_chan3 = 2;
}
- mips_cpu_irq_init();
- ath79_misc_irq_init();
+ ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3);
+
+ if (soc_is_ar71xx() || soc_is_ar913x())
+ misc_is_ar71xx = true;
+ else if (soc_is_ar724x() ||
+ soc_is_ar933x() ||
+ soc_is_ar934x() ||
+ soc_is_qca955x())
+ misc_is_ar71xx = false;
+ else
+ BUG();
+ ath79_misc_irq_init(
+ ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS,
+ ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx);
if (soc_is_ar934x())
ar934x_ip2_irq_init();
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 1ba2120..be451ee4a 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -36,10 +36,6 @@
#define ATH79_SYS_TYPE_LEN 64
-#define AR71XX_BASE_FREQ 40000000
-#define AR724X_BASE_FREQ 5000000
-#define AR913X_BASE_FREQ 5000000
-
static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
static void ath79_restart(char *command)
@@ -216,9 +212,9 @@ void __init plat_mem_setup(void)
AR71XX_RESET_SIZE);
ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
AR71XX_PLL_SIZE);
+ ath79_detect_sys_type();
ath79_ddr_ctrl_init();
- ath79_detect_sys_type();
if (mips_machtype != ATH79_MACH_GENERIC_OF)
detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
@@ -272,12 +268,12 @@ void __init device_tree_init(void)
unflatten_and_copy_device_tree();
}
-static void __init ath79_generic_init(void)
-{
- /* Nothing to do */
-}
-
MIPS_MACHINE(ATH79_MACH_GENERIC,
"Generic",
"Generic AR71XX/AR724X/AR913X based board",
- ath79_generic_init);
+ NULL);
+
+MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
+ "DTB",
+ "Generic AR71XX/AR724X/AR913X based board (DT)",
+ NULL);
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index 51ed599..e970fd9 100644
--- a/arch/mips/bcm47xx/Kconfig
+++ b/arch/mips/bcm47xx/Kconfig
@@ -4,6 +4,7 @@ config BCM47XX_SSB
bool "SSB Support for Broadcom BCM47XX"
select SYS_HAS_CPU_BMIPS32_3300
select SSB
+ select SSB_HOST_SOC
select SSB_DRIVER_MIPS
select SSB_DRIVER_EXTIF
select SSB_EMBEDDED
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 17503a0..c807e32 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -101,33 +101,13 @@ static void bcm47xx_machine_halt(void)
}
#ifdef CONFIG_BCM47XX_SSB
-static int bcm47xx_get_invariants(struct ssb_bus *bus,
- struct ssb_init_invariants *iv)
-{
- char buf[20];
-
- /* Fill boardinfo structure */
- memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo));
-
- bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
-
- memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
- bcm47xx_fill_sprom(&iv->sprom, NULL, false);
-
- if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
- iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
-
- return 0;
-}
-
static void __init bcm47xx_register_ssb(void)
{
int err;
char buf[100];
struct ssb_mipscore *mcore;
- err = ssb_bus_ssbbus_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE,
- bcm47xx_get_invariants);
+ err = ssb_bus_host_soc_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE);
if (err)
panic("Failed to initialize SSB bus (err %d)", err);
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index 2d5c7a7..959c145 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -60,9 +60,9 @@ static int get_nvram_var(const char *prefix, const char *postfix,
}
#define NVRAM_READ_VAL(type) \
-static void nvram_read_ ## type (const char *prefix, \
- const char *postfix, const char *name, \
- type *val, type allset, bool fallback) \
+static void nvram_read_ ## type(const char *prefix, \
+ const char *postfix, const char *name, \
+ type *val, type allset, bool fallback) \
{ \
char buf[100]; \
int err; \
@@ -422,7 +422,10 @@ static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
int i;
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
- struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+ struct ssb_sprom_core_pwr_info *pwr_info;
+
+ pwr_info = &sprom->core_pwr_info[i];
+
snprintf(postfix, sizeof(postfix), "%i", i);
nvram_read_u8(prefix, postfix, "maxp2ga",
&pwr_info->maxpwr_2g, 0, fallback);
@@ -470,7 +473,10 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
int i;
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
- struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+ struct ssb_sprom_core_pwr_info *pwr_info;
+
+ pwr_info = &sprom->core_pwr_info[i];
+
snprintf(postfix, sizeof(postfix), "%i", i);
nvram_read_u16(prefix, postfix, "pa2gw3a",
&pwr_info->pa_2g[3], 0, fallback);
@@ -535,10 +541,11 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
/* The address prefix 00:90:4C is used by Broadcom in their initial
- configuration. When a mac address with the prefix 00:90:4C is used
- all devices from the same series are sharing the same mac address.
- To prevent mac address collisions we replace them with a mac address
- based on the base address. */
+ * configuration. When a mac address with the prefix 00:90:4C is used
+ * all devices from the same series are sharing the same mac address.
+ * To prevent mac address collisions we replace them with a mac address
+ * based on the base address.
+ */
if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
u8 mac[6];
@@ -592,32 +599,23 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
}
-#ifdef CONFIG_BCM47XX_SSB
-void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
- const char *prefix)
-{
- nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
- true);
- if (!boardinfo->vendor)
- boardinfo->vendor = SSB_BOARDVENDOR_BCM;
-
- nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
-}
-#endif
-
#if defined(CONFIG_BCM47XX_SSB)
static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
{
char prefix[10];
- if (bus->bustype == SSB_BUSTYPE_PCI) {
+ switch (bus->bustype) {
+ case SSB_BUSTYPE_SSB:
+ bcm47xx_fill_sprom(out, NULL, false);
+ return 0;
+ case SSB_BUSTYPE_PCI:
memset(out, 0, sizeof(struct ssb_sprom));
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
bus->host_pci->bus->number + 1,
PCI_SLOT(bus->host_pci->devfn));
bcm47xx_fill_sprom(out, prefix, false);
return 0;
- } else {
+ default:
pr_warn("Unable to fill SPROM for given bustype.\n");
return -EINVAL;
}
@@ -668,9 +666,15 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
memset(out, 0, sizeof(struct ssb_sprom));
- snprintf(buf, sizeof(buf), "pci/%u/%u/",
- bus->host_pci->bus->number + 1,
- PCI_SLOT(bus->host_pci->devfn));
+ /* On BCM47XX all PCI buses share the same domain */
+ if (config_enabled(CONFIG_BCM47XX))
+ snprintf(buf, sizeof(buf), "pci/%u/%u/",
+ bus->host_pci->bus->number + 1,
+ PCI_SLOT(bus->host_pci->devfn));
+ else
+ snprintf(buf, sizeof(buf), "pci/%u/%u/",
+ pci_domain_nr(bus->host_pci->bus) + 1,
+ bus->host_pci->bus->number);
bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
prefix = buf;
break;
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 33727e7..b2097c0 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -7,6 +7,8 @@
* Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -31,7 +33,6 @@
#include <uapi/linux/bcm933xx_hcs.h>
-#define PFX "board_bcm963xx: "
#define HCS_OFFSET_128K 0x20000
@@ -740,7 +741,7 @@ int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
return 0;
} else {
- printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+ pr_err("unable to fill SPROM for given bustype\n");
return -EINVAL;
}
}
@@ -784,7 +785,7 @@ void __init board_prom_init(void)
cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
else
strcpy(cfe_version, "unknown");
- printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+ pr_info("CFE version: %s\n", cfe_version);
bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
@@ -808,8 +809,7 @@ void __init board_prom_init(void)
char name[17];
memcpy(name, board_name, 16);
name[16] = 0;
- printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
- name);
+ pr_err("unknown bcm963xx board: %s\n", name);
return;
}
@@ -854,7 +854,7 @@ void __init board_setup(void)
{
if (!board.name[0])
panic("unable to detect bcm963xx board");
- printk(KERN_INFO PFX "board name: %s\n", board.name);
+ pr_info("board name: %s\n", board.name);
/* make sure we're running on expected cpu */
if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
@@ -910,7 +910,7 @@ int __init board_register_devices(void)
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
if (ssb_arch_register_fallback_sprom(
&bcm63xx_get_fallback_sprom) < 0)
- pr_err(PFX "failed to register fallback SPROM\n");
+ pr_err("failed to register fallback SPROM\n");
}
#endif
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 307ec8b..1c7c3fb 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -376,10 +376,10 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_cpu_freq = detect_cpu_clock();
bcm63xx_memory_size = detect_memory_size();
- printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
- bcm63xx_cpu_id, bcm63xx_cpu_rev);
- printk(KERN_INFO "CPU frequency is %u MHz\n",
- bcm63xx_cpu_freq / 1000000);
- printk(KERN_INFO "%uMB of RAM installed\n",
- bcm63xx_memory_size >> 20);
+ pr_info("Detected Broadcom 0x%04x CPU revision %02x\n",
+ bcm63xx_cpu_id, bcm63xx_cpu_rev);
+ pr_info("CPU frequency is %u MHz\n",
+ bcm63xx_cpu_freq / 1000000);
+ pr_info("%uMB of RAM installed\n",
+ bcm63xx_memory_size >> 20);
}
diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c
index a551bab..9496cd2 100644
--- a/arch/mips/bcm63xx/dev-pcmcia.c
+++ b/arch/mips/bcm63xx/dev-pcmcia.c
@@ -139,6 +139,6 @@ int __init bcm63xx_pcmcia_register(void)
return platform_device_register(&bcm63xx_pcmcia_device);
out_err:
- printk(KERN_ERR "unable to set pcmcia chip select\n");
+ pr_err("unable to set pcmcia chip select\n");
return ret;
}
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c
index ad448e41..2323854 100644
--- a/arch/mips/bcm63xx/dev-spi.c
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -18,29 +18,6 @@
#include <bcm63xx_dev_spi.h>
#include <bcm63xx_regs.h>
-/*
- * register offsets
- */
-static const unsigned long bcm6348_regs_spi[] = {
- __GEN_SPI_REGS_TABLE(6348)
-};
-
-static const unsigned long bcm6358_regs_spi[] = {
- __GEN_SPI_REGS_TABLE(6358)
-};
-
-const unsigned long *bcm63xx_regs_spi;
-EXPORT_SYMBOL(bcm63xx_regs_spi);
-
-static __init void bcm63xx_spi_regs_init(void)
-{
- if (BCMCPU_IS_6338() || BCMCPU_IS_6348())
- bcm63xx_regs_spi = bcm6348_regs_spi;
- if (BCMCPU_IS_3368() || BCMCPU_IS_6358() ||
- BCMCPU_IS_6362() || BCMCPU_IS_6368())
- bcm63xx_regs_spi = bcm6358_regs_spi;
-}
-
static struct resource spi_resources[] = {
{
.start = -1, /* filled at runtime */
@@ -53,19 +30,10 @@ static struct resource spi_resources[] = {
},
};
-static struct bcm63xx_spi_pdata spi_pdata = {
- .bus_num = 0,
- .num_chipselect = 8,
-};
-
static struct platform_device bcm63xx_spi_device = {
- .name = "bcm63xx-spi",
.id = -1,
.num_resources = ARRAY_SIZE(spi_resources),
.resource = spi_resources,
- .dev = {
- .platform_data = &spi_pdata,
- },
};
int __init bcm63xx_spi_register(void)
@@ -78,21 +46,15 @@ int __init bcm63xx_spi_register(void)
spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+ bcm63xx_spi_device.name = "bcm6348-spi",
spi_resources[0].end += BCM_6348_RSET_SPI_SIZE - 1;
- spi_pdata.fifo_size = SPI_6348_MSG_DATA_SIZE;
- spi_pdata.msg_type_shift = SPI_6348_MSG_TYPE_SHIFT;
- spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH;
}
if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() ||
BCMCPU_IS_6368()) {
+ bcm63xx_spi_device.name = "bcm6358-spi",
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
- spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
- spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
- spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
}
- bcm63xx_spi_regs_init();
-
return platform_device_register(&bcm63xx_spi_device);
}
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
index 468bc7b..7c256da 100644
--- a/arch/mips/bcm63xx/gpio.c
+++ b/arch/mips/bcm63xx/gpio.c
@@ -11,7 +11,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_gpio.h>
@@ -147,5 +147,5 @@ int __init bcm63xx_gpio_init(void)
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
- return gpiochip_add(&bcm63xx_gpio_chip);
+ return gpiochip_add_data(&bcm63xx_gpio_chip, NULL);
}
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 1a47ec2..c961390 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -311,7 +311,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
break;
default:
- printk(KERN_ERR "bogus flow type combination given !\n");
+ pr_err("bogus flow type combination given !\n");
return -EINVAL;
}
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c
index 4b50d40..05757ae 100644
--- a/arch/mips/bcm63xx/nvram.c
+++ b/arch/mips/bcm63xx/nvram.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
+#include <linux/bcm963xx_nvram.h>
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/export.h>
@@ -18,23 +19,6 @@
#include <bcm63xx_nvram.h>
-/*
- * nvram structure
- */
-struct bcm963xx_nvram {
- u32 version;
- u8 reserved1[256];
- u8 name[16];
- u32 main_tp_number;
- u32 psi_size;
- u32 mac_addr_count;
- u8 mac_addr_base[ETH_ALEN];
- u8 reserved2[2];
- u32 checksum_old;
- u8 reserved3[720];
- u32 checksum_high;
-};
-
#define BCM63XX_DEFAULT_PSI_SIZE 64
static struct bcm963xx_nvram nvram;
@@ -42,27 +26,14 @@ static int mac_addr_used;
void __init bcm63xx_nvram_init(void *addr)
{
- unsigned int check_len;
u32 crc, expected_crc;
u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
/* extract nvram data */
- memcpy(&nvram, addr, sizeof(nvram));
+ memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE);
/* check checksum before using data */
- if (nvram.version <= 4) {
- check_len = offsetof(struct bcm963xx_nvram, reserved3);
- expected_crc = nvram.checksum_old;
- nvram.checksum_old = 0;
- } else {
- check_len = sizeof(nvram);
- expected_crc = nvram.checksum_high;
- nvram.checksum_high = 0;
- }
-
- crc = crc32_le(~0, (u8 *)&nvram, check_len);
-
- if (crc != expected_crc)
+ if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc))
pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
expected_crc, crc);
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 240fb4f..2be9caa 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -24,7 +24,7 @@
void bcm63xx_machine_halt(void)
{
- printk(KERN_INFO "System halted\n");
+ pr_info("System halted\n");
while (1)
;
}
@@ -34,7 +34,7 @@ static void bcm6348_a1_reboot(void)
u32 reg;
/* soft reset all blocks */
- printk(KERN_INFO "soft-resetting all blocks ...\n");
+ pr_info("soft-resetting all blocks ...\n");
reg = bcm_perf_readl(PERF_SOFTRESET_REG);
reg &= ~SOFTRESET_6348_ALL;
bcm_perf_writel(reg, PERF_SOFTRESET_REG);
@@ -46,7 +46,7 @@ static void bcm6348_a1_reboot(void)
mdelay(10);
/* Jump to the power on address. */
- printk(KERN_INFO "jumping to reset vector.\n");
+ pr_info("jumping to reset vector.\n");
/* set high vectors (base at 0xbfc00000 */
set_c0_status(ST0_BEV | ST0_ERL);
/* run uncached in kseg0 */
@@ -110,7 +110,7 @@ void bcm63xx_machine_reboot(void)
if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
bcm6348_a1_reboot();
- printk(KERN_INFO "triggering watchdog soft-reset...\n");
+ pr_info("triggering watchdog soft-reset...\n");
if (BCMCPU_IS_6328()) {
bcm_wdt_writel(1, WDT_SOFTRESET_REG);
} else {
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
index 5f11359..2110359 100644
--- a/arch/mips/bcm63xx/timer.c
+++ b/arch/mips/bcm63xx/timer.c
@@ -195,7 +195,7 @@ int bcm63xx_timer_init(void)
irq = bcm63xx_get_irq_number(IRQ_TIMER);
ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
if (ret) {
- printk(KERN_ERR "bcm63xx_timer: failed to register irq\n");
+ pr_err("%s: failed to register irq\n", __func__);
return ret;
}
diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c
index e7fc6f934..7efefcf 100644
--- a/arch/mips/bmips/irq.c
+++ b/arch/mips/bmips/irq.c
@@ -15,6 +15,12 @@
#include <asm/irq_cpu.h>
#include <asm/time.h>
+static const struct of_device_id smp_intc_dt_match[] = {
+ { .compatible = "brcm,bcm7038-l1-intc" },
+ { .compatible = "brcm,bcm6345-l1-intc" },
+ {}
+};
+
unsigned int get_c0_compare_int(void)
{
return CP0_LEGACY_COMPARE_IRQ;
@@ -24,8 +30,8 @@ void __init arch_init_irq(void)
{
struct device_node *dn;
- /* Only the STB (bcm7038) controller supports SMP IRQ affinity */
- dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc");
+ /* Only these controllers support SMP IRQ affinity */
+ dn = of_find_matching_node(NULL, smp_intc_dt_match);
if (dn)
of_node_put(dn);
else
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c
index 526ec27..3553528 100644
--- a/arch/mips/bmips/setup.c
+++ b/arch/mips/bmips/setup.c
@@ -105,6 +105,7 @@ static const struct bmips_quirk bmips_quirk_list[] = {
{ "brcm,bcm33843-viper", &bcm3384_viper_quirks },
{ "brcm,bcm6328", &bcm6328_quirks },
{ "brcm,bcm6368", &bcm6368_quirks },
+ { "brcm,bcm63168", &bcm6368_quirks },
{ },
};
@@ -157,7 +158,6 @@ void __init plat_mem_setup(void)
panic("no dtb found");
__dt_setup_arch(dtb);
- strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
for (q = bmips_quirk_list; q->quirk_fn; q++) {
if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index d5bdee1..4eff1ef 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -29,20 +29,23 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
-targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
-
# decompressor objects (linked with vmlinuz)
vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
ifdef CONFIG_DEBUG_ZBOOT
vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o
vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o
vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o
endif
-ifdef CONFIG_KERNEL_XZ
-vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
-endif
+vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
+
+$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib
+$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c
+ $(call cmd,shipped)
+
+targets := $(notdir $(vmlinuzobjs-y))
targets += vmlinux.bin
OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
@@ -60,7 +63,7 @@ targets += vmlinux.bin.z
$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
$(call if_changed,$(tool_y))
-targets += piggy.o
+targets += piggy.o dummy.o
OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
--set-section-flags=.image=contents,alloc,load,readonly,data
$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
index 408799a..f752114 100644
--- a/arch/mips/boot/compressed/uart-16550.c
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -17,7 +17,7 @@
#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
#endif
-#ifdef CONFIG_MACH_JZ4740
+#if defined(CONFIG_MACH_JZ4740) || defined(CONFIG_MACH_JZ4780)
#include <asm/mach-jz4740/base.h>
#define PORT(offset) (CKSEG1ADDR(JZ4740_UART0_BASE_ADDR) + (4 * offset))
#endif
diff --git a/arch/mips/boot/compressed/uart-prom.c b/arch/mips/boot/compressed/uart-prom.c
new file mode 100644
index 0000000..1c3d51b
--- /dev/null
+++ b/arch/mips/boot/compressed/uart-prom.c
@@ -0,0 +1,7 @@
+
+extern void prom_putchar(unsigned char ch);
+
+void putc(char c)
+{
+ prom_putchar(c);
+}
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index 778a340..fc7a0a9 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -4,11 +4,16 @@ dts-dirs += ingenic
dts-dirs += lantiq
dts-dirs += mti
dts-dirs += netlogic
+dts-dirs += pic32
dts-dirs += qca
dts-dirs += ralink
+dts-dirs += xilfpga
obj-y := $(addsuffix /, $(dts-dirs))
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))
+
always := $(dtb-y)
subdir-y := $(dts-dirs)
clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi
index 41891c1..9d19236 100644
--- a/arch/mips/boot/dts/brcm/bcm6328.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi
@@ -31,6 +31,7 @@
};
aliases {
+ leds0 = &leds0;
uart0 = &uart0;
};
@@ -73,7 +74,7 @@
timer: timer@10000040 {
compatible = "syscon";
reg = <0x10000040 0x2c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -82,5 +83,13 @@
offset = <0x28>;
mask = <0x1>;
};
+
+ leds0: led-controller@10000800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,bcm6328-leds";
+ reg = <0x10000800 0x24>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi
index 45152bc..1f6b9b5 100644
--- a/arch/mips/boot/dts/brcm/bcm6368.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi
@@ -32,6 +32,7 @@
};
aliases {
+ leds0 = &leds0;
uart0 = &uart0;
};
@@ -50,6 +51,19 @@
compatible = "simple-bus";
ranges;
+ periph_cntl: syscon@10000000 {
+ compatible = "syscon";
+ reg = <0x10000000 0x14>;
+ native-endian;
+ };
+
+ reboot: syscon-reboot@10000008 {
+ compatible = "syscon-reboot";
+ regmap = <&periph_cntl>;
+ offset = <0x8>;
+ mask = <0x1>;
+ };
+
periph_intc: periph_intc@10000020 {
compatible = "brcm,bcm3380-l2-intc";
reg = <0x10000024 0x4 0x1000002c 0x4>,
@@ -62,6 +76,14 @@
interrupts = <2>;
};
+ leds0: led-controller@100000d0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,bcm6358-leds";
+ reg = <0x100000d0 0x8>;
+ status = "disabled";
+ };
+
uart0: serial@10000100 {
compatible = "brcm,bcm6345-uart";
reg = <0x10000100 0x18>;
diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi
index 1a7efa8..3ae1605 100644
--- a/arch/mips/boot/dts/brcm/bcm7125.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi
@@ -98,7 +98,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
- little-endian;
+ native-endian;
};
reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi
index d817bb4..be79919 100644
--- a/arch/mips/boot/dts/brcm/bcm7346.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi
@@ -87,20 +87,38 @@
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406780 0x8>;
- brcm,int-map-mask = <0x44>;
+ brcm,int-map-mask = <0x44>, <0xf000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
- interrupts = <59>;
+ interrupts = <59>, <57>;
+ interrupt-names = "upg_main", "upg_bsc";
+ };
+
+ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+ compatible = "brcm,bcm7120-l2-intc";
+ reg = <0x408b80 0x8>;
+
+ brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+ brcm,int-fwd-mask = <0>;
+ brcm,irq-can-wake;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&periph_intc>;
+ interrupts = <60>, <58>, <62>;
+ interrupt-names = "upg_main_aon", "upg_bsc_aon",
+ "upg_spi";
};
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -144,6 +162,56 @@
status = "disabled";
};
+ bsca: i2c@406200 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406200 0x58>;
+ interrupts = <24>;
+ interrupt-names = "upg_bsca";
+ status = "disabled";
+ };
+
+ bscb: i2c@406280 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406280 0x58>;
+ interrupts = <25>;
+ interrupt-names = "upg_bscb";
+ status = "disabled";
+ };
+
+ bscc: i2c@406300 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406300 0x58>;
+ interrupts = <26>;
+ interrupt-names = "upg_bscc";
+ status = "disabled";
+ };
+
+ bscd: i2c@406380 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406380 0x58>;
+ interrupts = <27>;
+ interrupt-names = "upg_bscd";
+ status = "disabled";
+ };
+
+ bsce: i2c@408980 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_aon_irq0_intc>;
+ reg = <0x408980 0x58>;
+ interrupts = <27>;
+ interrupt-names = "upg_bsce";
+ status = "disabled";
+ };
+
enet0: ethernet@430000 {
phy-mode = "internal";
phy-handle = <&phy1>;
@@ -246,5 +314,47 @@
interrupts = <76>;
status = "disabled";
};
+
+ sata: sata@181000 {
+ compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+ reg-names = "ahci", "top-ctrl";
+ reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+ interrupt-parent = <&periph_intc>;
+ interrupts = <40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,broken-ncq;
+ brcm,broken-phy;
+ status = "disabled";
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ phys = <&sata_phy0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ phys = <&sata_phy1>;
+ };
+ };
+
+ sata_phy: sata-phy@1800000 {
+ compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+ reg = <0x180100 0x0eff>;
+ reg-names = "phy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata_phy0: sata-phy@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ sata_phy1: sata-phy@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
};
};
diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi
index 277a90a..060805b 100644
--- a/arch/mips/boot/dts/brcm/bcm7358.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi
@@ -81,20 +81,38 @@
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406600 0x8>;
- brcm,int-map-mask = <0x44>;
+ brcm,int-map-mask = <0x44>, <0x7000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
- interrupts = <56>;
+ interrupts = <56>, <54>;
+ interrupt-names = "upg_main", "upg_bsc";
+ };
+
+ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+ compatible = "brcm,bcm7120-l2-intc";
+ reg = <0x408b80 0x8>;
+
+ brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+ brcm,int-fwd-mask = <0>;
+ brcm,irq-can-wake;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&periph_intc>;
+ interrupts = <57>, <55>, <59>;
+ interrupt-names = "upg_main_aon", "upg_bsc_aon",
+ "upg_spi";
};
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -138,6 +156,46 @@
status = "disabled";
};
+ bsca: i2c@406200 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406200 0x58>;
+ interrupts = <24>;
+ interrupt-names = "upg_bsca";
+ status = "disabled";
+ };
+
+ bscb: i2c@406280 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406280 0x58>;
+ interrupts = <25>;
+ interrupt-names = "upg_bscb";
+ status = "disabled";
+ };
+
+ bscc: i2c@406300 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406300 0x58>;
+ interrupts = <26>;
+ interrupt-names = "upg_bscc";
+ status = "disabled";
+ };
+
+ bscd: i2c@408980 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_aon_irq0_intc>;
+ reg = <0x408980 0x58>;
+ interrupts = <27>;
+ interrupt-names = "upg_bscd";
+ status = "disabled";
+ };
+
enet0: ethernet@430000 {
phy-mode = "internal";
phy-handle = <&phy1>;
diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi
index 9e1e571..bcdb09b 100644
--- a/arch/mips/boot/dts/brcm/bcm7360.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi
@@ -81,20 +81,38 @@
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406600 0x8>;
- brcm,int-map-mask = <0x44>;
+ brcm,int-map-mask = <0x44>, <0x7000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
- interrupts = <56>;
+ interrupts = <56>, <54>;
+ interrupt-names = "upg_main", "upg_bsc";
+ };
+
+ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+ compatible = "brcm,bcm7120-l2-intc";
+ reg = <0x408b80 0x8>;
+
+ brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+ brcm,int-fwd-mask = <0>;
+ brcm,irq-can-wake;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&periph_intc>;
+ interrupts = <57>, <55>, <59>;
+ interrupt-names = "upg_main_aon", "upg_bsc_aon",
+ "upg_spi";
};
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -138,6 +156,46 @@
status = "disabled";
};
+ bsca: i2c@406200 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406200 0x58>;
+ interrupts = <24>;
+ interrupt-names = "upg_bsca";
+ status = "disabled";
+ };
+
+ bscb: i2c@406280 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406280 0x58>;
+ interrupts = <25>;
+ interrupt-names = "upg_bscb";
+ status = "disabled";
+ };
+
+ bscc: i2c@406300 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406300 0x58>;
+ interrupts = <26>;
+ interrupt-names = "upg_bscc";
+ status = "disabled";
+ };
+
+ bscd: i2c@408980 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_aon_irq0_intc>;
+ reg = <0x408980 0x58>;
+ interrupts = <27>;
+ interrupt-names = "upg_bscd";
+ status = "disabled";
+ };
+
enet0: ethernet@430000 {
phy-mode = "internal";
phy-handle = <&phy1>;
diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi
index 6e65db8..d3b1b76 100644
--- a/arch/mips/boot/dts/brcm/bcm7362.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi
@@ -87,20 +87,38 @@
compatible = "brcm,bcm7120-l2-intc";
reg = <0x406600 0x8>;
- brcm,int-map-mask = <0x44>;
+ brcm,int-map-mask = <0x44>, <0x7000000>;
brcm,int-fwd-mask = <0x70000>;
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&periph_intc>;
- interrupts = <56>;
+ interrupts = <56>, <54>;
+ interrupt-names = "upg_main", "upg_bsc";
+ };
+
+ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
+ compatible = "brcm,bcm7120-l2-intc";
+ reg = <0x408b80 0x8>;
+
+ brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>;
+ brcm,int-fwd-mask = <0>;
+ brcm,irq-can-wake;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&periph_intc>;
+ interrupts = <57>, <55>, <59>;
+ interrupt-names = "upg_main_aon", "upg_bsc_aon",
+ "upg_spi";
};
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -144,6 +162,36 @@
status = "disabled";
};
+ bsca: i2c@406200 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406200 0x58>;
+ interrupts = <24>;
+ interrupt-names = "upg_bsca";
+ status = "disabled";
+ };
+
+ bscb: i2c@406280 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_irq0_intc>;
+ reg = <0x406280 0x58>;
+ interrupts = <25>;
+ interrupt-names = "upg_bscb";
+ status = "disabled";
+ };
+
+ bscd: i2c@408980 {
+ clock-frequency = <390000>;
+ compatible = "brcm,brcmstb-i2c";
+ interrupt-parent = <&upg_aon_irq0_intc>;
+ reg = <0x408980 0x58>;
+ interrupts = <27>;
+ interrupt-names = "upg_bscd";
+ status = "disabled";
+ };
+
enet0: ethernet@430000 {
phy-mode = "internal";
phy-handle = <&phy1>;
@@ -189,5 +237,47 @@
interrupts = <66>;
status = "disabled";
};
+
+ sata: sata@181000 {
+ compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+ reg-names = "ahci", "top-ctrl";
+ reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+ interrupt-parent = <&periph_intc>;
+ interrupts = <86>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,broken-ncq;
+ brcm,broken-phy;
+ status = "disabled";
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ phys = <&sata_phy0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ phys = <&sata_phy1>;
+ };
+ };
+
+ sata_phy: sata-phy@1800000 {
+ compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+ reg = <0x180100 0x0eff>;
+ reg-names = "phy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata_phy0: sata-phy@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ sata_phy1: sata-phy@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
};
};
diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi
index 5f55d0a..3302a1b 100644
--- a/arch/mips/boot/dts/brcm/bcm7420.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi
@@ -99,7 +99,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
- little-endian;
+ native-endian;
};
reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi
index 5b660b6..15b27aa 100644
--- a/arch/mips/boot/dts/brcm/bcm7425.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi
@@ -100,7 +100,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
@@ -221,5 +221,47 @@
interrupts = <73>;
status = "disabled";
};
+
+ sata: sata@181000 {
+ compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci";
+ reg-names = "ahci", "top-ctrl";
+ reg = <0x181000 0xa9c>, <0x180020 0x1c>;
+ interrupt-parent = <&periph_intc>;
+ interrupts = <40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ brcm,broken-ncq;
+ brcm,broken-phy;
+ status = "disabled";
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ phys = <&sata_phy0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ phys = <&sata_phy1>;
+ };
+ };
+
+ sata_phy: sata-phy@1800000 {
+ compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3";
+ reg = <0x180100 0x0eff>;
+ reg-names = "phy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ sata_phy0: sata-phy@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ sata_phy1: sata-phy@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
};
};
diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi
index 8b9432c..adb33e3 100644
--- a/arch/mips/boot/dts/brcm/bcm7435.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi
@@ -114,7 +114,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
- little-endian;
+ native-endian;
};
reboot {
diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
index 3fe0445..d3d2881 100644
--- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
+++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
@@ -29,6 +29,26 @@
status = "okay";
};
+&bsca {
+ status = "okay";
+};
+
+&bscb {
+ status = "okay";
+};
+
+&bscc {
+ status = "okay";
+};
+
+&bscd {
+ status = "okay";
+};
+
+&bsce {
+ status = "okay";
+};
+
&enet0 {
status = "okay";
};
@@ -64,3 +84,11 @@
&ohci3 {
status = "okay";
};
+
+&sata {
+ status = "okay";
+};
+
+&sata_phy {
+ status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts
index a8dc01e..02ce6b4 100644
--- a/arch/mips/boot/dts/brcm/bcm97358svmb.dts
+++ b/arch/mips/boot/dts/brcm/bcm97358svmb.dts
@@ -29,6 +29,22 @@
status = "okay";
};
+&bsca {
+ status = "okay";
+};
+
+&bscb {
+ status = "okay";
+};
+
+&bscc {
+ status = "okay";
+};
+
+&bscd {
+ status = "okay";
+};
+
&enet0 {
status = "okay";
};
diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts
index eee8b0e..d48462e 100644
--- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts
+++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts
@@ -29,6 +29,22 @@
status = "okay";
};
+&bsca {
+ status = "okay";
+};
+
+&bscb {
+ status = "okay";
+};
+
+&bscc {
+ status = "okay";
+};
+
+&bscd {
+ status = "okay";
+};
+
&enet0 {
status = "okay";
};
diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts
index 739c2ef..3cfcaeb 100644
--- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts
+++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts
@@ -29,6 +29,18 @@
status = "okay";
};
+&bsca {
+ status = "okay";
+};
+
+&bscb {
+ status = "okay";
+};
+
+&bscd {
+ status = "okay";
+};
+
&enet0 {
status = "okay";
};
@@ -40,3 +52,11 @@
&ohci0 {
status = "okay";
};
+
+&sata {
+ status = "okay";
+};
+
+&sata_phy {
+ status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 9fcb9e7..1652d8d 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -42,3 +42,67 @@
&uart4 {
status = "okay";
};
+
+&nemc {
+ status = "okay";
+
+ nandc: nand-controller@1 {
+ compatible = "ingenic,jz4780-nand";
+ reg = <1 0 0x1000000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ingenic,bch-controller = <&bch>;
+
+ ingenic,nemc-tAS = <10>;
+ ingenic,nemc-tAH = <5>;
+ ingenic,nemc-tBP = <10>;
+ ingenic,nemc-tAW = <15>;
+ ingenic,nemc-tSTRV = <100>;
+
+ nand@1 {
+ reg = <1>;
+
+ nand-ecc-step-size = <1024>;
+ nand-ecc-strength = <24>;
+ nand-ecc-mode = "hw";
+ nand-on-flash-bbt;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x0 0x0 0x800000>;
+ };
+
+ partition@0x800000 {
+ label = "u-boot";
+ reg = <0x0 0x800000 0x0 0x200000>;
+ };
+
+ partition@0xa00000 {
+ label = "u-boot-env";
+ reg = <0x0 0xa00000 0x0 0x200000>;
+ };
+
+ partition@0xc00000 {
+ label = "boot";
+ reg = <0x0 0xc00000 0x0 0x4000000>;
+ };
+
+ partition@0x8c00000 {
+ label = "system";
+ reg = <0x0 0x4c00000 0x1 0xfb400000>;
+ };
+ };
+ };
+ };
+};
+
+&bch {
+ status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index 65389f6..b868b42 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -108,4 +108,30 @@
status = "disabled";
};
+
+ nemc: nemc@13410000 {
+ compatible = "ingenic,jz4780-nemc";
+ reg = <0x13410000 0x10000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <1 0 0x1b000000 0x1000000
+ 2 0 0x1a000000 0x1000000
+ 3 0 0x19000000 0x1000000
+ 4 0 0x18000000 0x1000000
+ 5 0 0x17000000 0x1000000
+ 6 0 0x16000000 0x1000000>;
+
+ clocks = <&cgu JZ4780_CLK_NEMC>;
+
+ status = "disabled";
+ };
+
+ bch: bch@134d0000 {
+ compatible = "ingenic,jz4780-bch";
+ reg = <0x134d0000 0x10000>;
+
+ clocks = <&cgu JZ4780_CLK_BCH>;
+
+ status = "disabled";
+ };
};
diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts
index c678115..b18c466 100644
--- a/arch/mips/boot/dts/mti/malta.dts
+++ b/arch/mips/boot/dts/mti/malta.dts
@@ -1,5 +1,9 @@
/dts-v1/;
+/memreserve/ 0x00000000 0x00001000; /* YAMON exception vectors */
+/memreserve/ 0x00001000 0x000ef000; /* YAMON */
+/memreserve/ 0x000f0000 0x00010000; /* PIIX4 ISA memory */
+
/ {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/mips/boot/dts/pic32/Makefile b/arch/mips/boot/dts/pic32/Makefile
new file mode 100644
index 0000000..7ac7905
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/Makefile
@@ -0,0 +1,12 @@
+dtb-$(CONFIG_DTB_PIC32_MZDA_SK) += pic32mzda_sk.dtb
+
+dtb-$(CONFIG_DTB_PIC32_NONE) += \
+ pic32mzda_sk.dtb
+
+obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj- += dummy.o
+
+always := $(dtb-y)
+clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
new file mode 100644
index 0000000..ef13350
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
@@ -0,0 +1,236 @@
+/*
+ * Device Tree Source for PIC32MZDA clock data
+ *
+ * Purna Chandra Mandal <purna.mandal@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/* all fixed rate clocks */
+
+/ {
+ POSC:posc_clk { /* On-chip primary oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ FRC:frc_clk { /* internal FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <8000000>;
+ };
+
+ BFRC:bfrc_clk { /* internal backup FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <8000000>;
+ };
+
+ LPRC:lprc_clk { /* internal low-power FRC oscillator */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+
+ /* UPLL provides clock to USBCORE */
+ UPLL:usb_phy_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "usbphy_clk";
+ };
+
+ TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ status = "disabled";
+ };
+
+ /* external clock input on REFCLKIx pin */
+ REFIx:refix_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ status = "disabled";
+ };
+
+ /* PIC32 specific clks */
+ pic32_clktree {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1f801200 0x200>;
+ compatible = "microchip,pic32mzda-clk";
+ ranges = <0 0x1f801200 0x200>;
+
+ /* secondary oscillator; external input on SOSCI pin */
+ SOSC:sosc_clk@0 {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sosc";
+ clock-frequency = <32768>;
+ reg = <0x000 0x10>, /* enable reg */
+ <0x1d0 0x10>; /* status reg */
+ microchip,bit-mask = <0x02>; /* enable mask */
+ microchip,status-bit-mask = <0x10>; /* status-mask*/
+ };
+
+ FRCDIV:frcdiv_clk {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-frcdivclk";
+ clocks = <&FRC>;
+ clock-output-names = "frcdiv_clk";
+ };
+
+ /* System PLL clock */
+ SYSPLL:spll_clk@020 {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-syspll";
+ reg = <0x020 0x10>, /* SPLL register */
+ <0x1d0 0x10>; /* CLKSTAT register */
+ clocks = <&POSC>, <&FRC>;
+ clock-output-names = "sys_pll";
+ microchip,status-bit-mask = <0x80>; /* SPLLRDY */
+ };
+
+ /* system clock; mux with postdiv & slew */
+ SYSCLK:sys_clk@1c0 {
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-sysclk-v2";
+ reg = <0x1c0 0x04>; /* SLEWCON */
+ clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
+ <&LPRC>, <&FRCDIV>;
+ microchip,clock-indices = <0>, <1>, <2>, <4>,
+ <5>, <7>;
+ clock-output-names = "sys_clk";
+ };
+
+ /* Peripheral bus1 clock */
+ PBCLK1:pb1_clk@140 {
+ reg = <0x140 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb1_clk";
+ /* used by system modules, not gateable */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus2 clock */
+ PBCLK2:pb2_clk@150 {
+ reg = <0x150 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb2_clk";
+ /* avoid gating even if unused */
+ microchip,ignore-unused;
+ };
+
+ /* Peripheral bus3 clock */
+ PBCLK3:pb3_clk@160 {
+ reg = <0x160 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb3_clk";
+ };
+
+ /* Peripheral bus4 clock(I/O ports, GPIO) */
+ PBCLK4:pb4_clk@170 {
+ reg = <0x170 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb4_clk";
+ };
+
+ /* Peripheral bus clock */
+ PBCLK5:pb5_clk@180 {
+ reg = <0x180 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ clock-output-names = "pb5_clk";
+ };
+
+ /* Peripheral Bus6 clock; */
+ PBCLK6:pb6_clk@190 {
+ reg = <0x190 0x10>;
+ compatible = "microchip,pic32mzda-pbclk";
+ clocks = <&SYSCLK>;
+ #clock-cells = <0>;
+ };
+
+ /* Peripheral bus7 clock */
+ PBCLK7:pb7_clk@1a0 {
+ reg = <0x1a0 0x10>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-pbclk";
+ /* CPU is driven by this clock; so named */
+ clock-output-names = "cpu_clk";
+ clocks = <&SYSCLK>;
+ };
+
+ /* Reference Oscillator clock for SPI/I2S */
+ REFCLKO1:refo1_clk@80 {
+ reg = <0x080 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ clock-output-names = "refo1_clk";
+ };
+
+ /* Reference Oscillator clock for SQI */
+ REFCLKO2:refo2_clk@a0 {
+ reg = <0x0a0 0x20>;
+ #clock-cells = <0>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ clock-output-names = "refo2_clk";
+ };
+
+ /* Reference Oscillator clock, ADC */
+ REFCLKO3:refo3_clk@c0 {
+ reg = <0x0c0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo3_clk";
+ };
+
+ /* Reference Oscillator clock */
+ REFCLKO4:refo4_clk@e0 {
+ reg = <0x0e0 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+ <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo4_clk";
+ };
+
+ /* Reference Oscillator clock, LCD */
+ REFCLKO5:refo5_clk@100 {
+ reg = <0x100 0x20>;
+ compatible = "microchip,pic32mzda-refoclk";
+ clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
+ <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
+ microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <5>, <7>, <8>, <9>;
+ #clock-cells = <0>;
+ clock-output-names = "refo5_clk";
+ };
+ };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda.dtsi b/arch/mips/boot/dts/pic32/pic32mzda.dtsi
new file mode 100644
index 0000000..ad9e3318
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda.dtsi
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute 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 "pic32mzda-clk.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&evic>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ gpio5 = &gpio5;
+ gpio6 = &gpio6;
+ gpio7 = &gpio7;
+ gpio8 = &gpio8;
+ gpio9 = &gpio9;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &uart6;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "mti,mips14KEc";
+ device_type = "cpu";
+ };
+ };
+
+ soc {
+ compatible = "microchip,pic32mzda-infra";
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ evic: interrupt-controller@1f810000 {
+ compatible = "microchip,pic32mzda-evic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1f810000 0x1000>;
+ microchip,external-irqs = <3 8 13 18 23>;
+ };
+
+ pic32_pinctrl: pinctrl@1f801400{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "microchip,pic32mzda-pinctrl";
+ reg = <0x1f801400 0x400>;
+ clocks = <&PBCLK1>;
+ };
+
+ /* PORTA */
+ gpio0: gpio0@1f860000 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860000 0x100>;
+ interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <0>;
+ gpio-ranges = <&pic32_pinctrl 0 0 16>;
+ };
+
+ /* PORTB */
+ gpio1: gpio1@1f860100 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860100 0x100>;
+ interrupts = <119 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <1>;
+ gpio-ranges = <&pic32_pinctrl 0 16 16>;
+ };
+
+ /* PORTC */
+ gpio2: gpio2@1f860200 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860200 0x100>;
+ interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <2>;
+ gpio-ranges = <&pic32_pinctrl 0 32 16>;
+ };
+
+ /* PORTD */
+ gpio3: gpio3@1f860300 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860300 0x100>;
+ interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <3>;
+ gpio-ranges = <&pic32_pinctrl 0 48 16>;
+ };
+
+ /* PORTE */
+ gpio4: gpio4@1f860400 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860400 0x100>;
+ interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <4>;
+ gpio-ranges = <&pic32_pinctrl 0 64 16>;
+ };
+
+ /* PORTF */
+ gpio5: gpio5@1f860500 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860500 0x100>;
+ interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <5>;
+ gpio-ranges = <&pic32_pinctrl 0 80 16>;
+ };
+
+ /* PORTG */
+ gpio6: gpio6@1f860600 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860600 0x100>;
+ interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <6>;
+ gpio-ranges = <&pic32_pinctrl 0 96 16>;
+ };
+
+ /* PORTH */
+ gpio7: gpio7@1f860700 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860700 0x100>;
+ interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <7>;
+ gpio-ranges = <&pic32_pinctrl 0 112 16>;
+ };
+
+ /* PORTI does not exist */
+
+ /* PORTJ */
+ gpio8: gpio8@1f860800 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860800 0x100>;
+ interrupts = <126 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <8>;
+ gpio-ranges = <&pic32_pinctrl 0 128 16>;
+ };
+
+ /* PORTK */
+ gpio9: gpio9@1f860900 {
+ compatible = "microchip,pic32mzda-gpio";
+ reg = <0x1f860900 0x100>;
+ interrupts = <127 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&PBCLK4>;
+ microchip,gpio-bank = <9>;
+ gpio-ranges = <&pic32_pinctrl 0 144 16>;
+ };
+
+ sdhci: sdhci@1f8ec000 {
+ compatible = "microchip,pic32mzda-sdhci";
+ reg = <0x1f8ec000 0x100>;
+ interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&REFCLKO4>, <&PBCLK5>;
+ clock-names = "base_clk", "sys_clk";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ status = "disabled";
+ };
+
+ uart1: serial@1f822000 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822000 0x50>;
+ interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
+ <113 IRQ_TYPE_LEVEL_HIGH>,
+ <114 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart2: serial@1f822200 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822200 0x50>;
+ interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
+ <146 IRQ_TYPE_LEVEL_HIGH>,
+ <147 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart3: serial@1f822400 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822400 0x50>;
+ interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
+ <158 IRQ_TYPE_LEVEL_HIGH>,
+ <159 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart4: serial@1f822600 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822600 0x50>;
+ interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
+ <171 IRQ_TYPE_LEVEL_HIGH>,
+ <172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart5: serial@1f822800 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822800 0x50>;
+ interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
+ <180 IRQ_TYPE_LEVEL_HIGH>,
+ <181 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+
+ uart6: serial@1f822A00 {
+ compatible = "microchip,pic32mzda-uart";
+ reg = <0x1f822A00 0x50>;
+ interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
+ <189 IRQ_TYPE_LEVEL_HIGH>,
+ <190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&PBCLK2>;
+ status = "disabled";
+ };
+};
diff --git a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts
new file mode 100644
index 0000000..5d434a5
--- /dev/null
+++ b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can 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 "pic32mzda.dtsi"
+
+/ {
+ compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda";
+ model = "Microchip PIC32MZDA Starter Kit";
+
+ memory {
+ device_type = "memory";
+ reg = <0x08000000 0x08000000>;
+ };
+
+ chosen {
+ bootargs = "earlyprintk=ttyPIC1,115200n8r console=ttyPIC1,115200n8";
+ };
+
+ leds0 {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ led@1 {
+ label = "pic32mzda_sk:red:led1";
+ gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led@2 {
+ label = "pic32mzda_sk:yellow:led2";
+ gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ };
+
+ led@3 {
+ label = "pic32mzda_sk:green:led3";
+ gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ keys0 {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&user_buttons_s0>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@sw1 {
+ label = "ESC";
+ linux,code = <1>;
+ gpios = <&gpio1 12 0>;
+ };
+
+ button@sw2 {
+ label = "Home";
+ linux,code = <102>;
+ gpios = <&gpio1 13 0>;
+ };
+
+ button@sw3 {
+ label = "Menu";
+ linux,code = <139>;
+ gpios = <&gpio1 14 0>;
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&sdhci {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhc1>;
+ status = "okay";
+ assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
+ assigned-clock-rates = <50000000>,<25000000>,<40000000>;
+};
+
+&pic32_pinctrl {
+
+ pinctrl_sdhc1: sdhc1_pins0 {
+ pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0";
+ microchip,digital;
+ };
+
+ user_leds_s0: user_leds_s0 {
+ pins = "H0", "H1", "H2";
+ output-low;
+ microchip,digital;
+ };
+
+ user_buttons_s0: user_buttons_s0 {
+ pins = "B12", "B13", "B14";
+ microchip,digital;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pinctrl_uart2: pinctrl_uart2 {
+ uart2-tx {
+ pins = "G9";
+ function = "U2TX";
+ microchip,digital;
+ output-high;
+ };
+ uart2-rx {
+ pins = "B0";
+ function = "U2RX";
+ microchip,digital;
+ input-enable;
+ };
+ };
+
+ pinctrl_uart4: uart4-0 {
+ uart4-tx {
+ pins = "C3";
+ function = "U4TX";
+ microchip,digital;
+ output-high;
+ };
+ uart4-rx {
+ pins = "E8";
+ function = "U4RX";
+ microchip,digital;
+ input-enable;
+ };
+ };
+};
diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi
index fb7734e..3ad4ba9 100644
--- a/arch/mips/boot/dts/qca/ar9132.dtsi
+++ b/arch/mips/boot/dts/qca/ar9132.dtsi
@@ -107,7 +107,7 @@
miscintc: interrupt-controller@18060010 {
compatible = "qca,ar9132-misc-intc",
"qca,ar7100-misc-intc";
- reg = <0x18060010 0x4>;
+ reg = <0x18060010 0x8>;
interrupt-parent = <&cpuintc>;
interrupts = <6>;
@@ -125,6 +125,21 @@
};
};
+ usb@1b000100 {
+ compatible = "qca,ar7100-ehci", "generic-ehci";
+ reg = <0x1b000100 0x100>;
+
+ interrupts = <3>;
+ resets = <&rst 5>;
+
+ has-transaction-translator;
+
+ phy-names = "usb";
+ phys = <&usb_phy>;
+
+ status = "disabled";
+ };
+
spi@1f000000 {
compatible = "qca,ar9132-spi", "qca,ar7100-spi";
reg = <0x1f000000 0x10>;
@@ -138,4 +153,15 @@
#size-cells = <0>;
};
};
+
+ usb_phy: usb-phy {
+ compatible = "qca,ar7100-usb-phy";
+
+ reset-names = "usb-phy", "usb-suspend-override";
+ resets = <&rst 4>, <&rst 3>;
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
};
diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
index 003015a..e535ee3 100644
--- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
+++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
@@ -35,6 +35,10 @@
};
};
+ usb@1b000100 {
+ status = "okay";
+ };
+
spi@1f000000 {
status = "okay";
num-cs = <1>;
@@ -65,6 +69,10 @@
};
};
+ usb-phy {
+ status = "okay";
+ };
+
gpio-keys {
compatible = "gpio-keys-polled";
#address-cells = <1>;
diff --git a/arch/mips/boot/dts/xilfpga/Makefile b/arch/mips/boot/dts/xilfpga/Makefile
new file mode 100644
index 0000000..913a752
--- /dev/null
+++ b/arch/mips/boot/dts/xilfpga/Makefile
@@ -0,0 +1,9 @@
+dtb-$(CONFIG_XILFPGA_NEXYS4DDR) += nexys4ddr.dtb
+
+obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj- += dummy.o
+
+always := $(dtb-y)
+clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/xilfpga/microAptiv.dtsi b/arch/mips/boot/dts/xilfpga/microAptiv.dtsi
new file mode 100644
index 0000000..81d518e
--- /dev/null
+++ b/arch/mips/boot/dts/xilfpga/microAptiv.dtsi
@@ -0,0 +1,21 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "img,xilfpga";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "mips,m14Kc";
+ clocks = <&ext>;
+ reg = <0>;
+ };
+ };
+
+ ext: ext {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+};
diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
new file mode 100644
index 0000000..686ebd1
--- /dev/null
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+#include "microAptiv.dtsi"
+
+/ {
+ compatible = "digilent,nexys4ddr";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x08000000>;
+ };
+
+ cpuintc: interrupt-controller@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ axi_gpio: gpio@10600000 {
+ #gpio-cells = <1>;
+ compatible = "xlnx,xps-gpio-1.00.a";
+ gpio-controller;
+ reg = <0x10600000 0x10000>;
+ xlnx,all-inputs = <0x0>;
+ xlnx,dout-default = <0x0>;
+ xlnx,gpio-width = <0x16>;
+ xlnx,interrupt-present = <0x0>;
+ xlnx,is-dual = <0x0>;
+ xlnx,tri-default = <0xffffffff>;
+ } ;
+
+ axi_uart16550: serial@10400000 {
+ compatible = "ns16550a";
+ reg = <0x10400000 0x10000>;
+
+ reg-shift = <2>;
+ reg-offset = <0x1000>;
+
+ clocks = <&ext>;
+ };
+};
+
+&ext {
+ clock-frequency = <50000000>;
+};
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 0352bc8..4f9eb05 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -1094,7 +1094,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
unsigned int pin;
unsigned int trigger;
- if (d->of_node != node)
+ if (irq_domain_get_of_node(d) != node)
return -EINVAL;
if (intsize < 2)
@@ -2163,7 +2163,7 @@ static int octeon_irq_cib_map(struct irq_domain *d,
if (hw >= host_data->max_bits) {
pr_err("ERROR: %s mapping %u is to big!\n",
- d->of_node->name, (unsigned)hw);
+ irq_domain_get_of_node(d)->name, (unsigned)hw);
return -EINVAL;
}
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index bd63425..cd7101f 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -1081,6 +1081,7 @@ void __init prom_free_prom_memory(void)
int octeon_prune_device_tree(void);
+extern const char __appended_dtb;
extern const char __dtb_octeon_3xxx_begin;
extern const char __dtb_octeon_68xx_begin;
void __init device_tree_init(void)
@@ -1088,11 +1089,19 @@ void __init device_tree_init(void)
const void *fdt;
bool do_prune;
+#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
+ if (!fdt_check_header(&__appended_dtb)) {
+ fdt = &__appended_dtb;
+ do_prune = false;
+ pr_info("Using appended Device Tree.\n");
+ } else
+#endif
if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
if (fdt_check_header(fdt))
panic("Corrupt Device Tree passed to kernel.");
do_prune = false;
+ pr_info("Using passed Device Tree.\n");
} else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
fdt = &__dtb_octeon_68xx_begin;
do_prune = true;
@@ -1106,8 +1115,6 @@ void __init device_tree_init(void)
if (do_prune) {
octeon_prune_device_tree();
pr_info("Using internal Device Tree.\n");
- } else {
- pr_info("Using passed Device Tree.\n");
}
unflatten_and_copy_device_tree();
}
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 1cdff6b..e070dac 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -122,20 +122,20 @@ CONFIG_EEPROM_MAX6875=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_IT8213=m
CONFIG_BLK_DEV_TC86C001=m
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_CHR_DEV_SCH=m
CONFIG_ATA=y
CONFIG_SATA_SIL24=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_IT8213=m
CONFIG_PATA_SIL680=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
@@ -247,7 +247,6 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
diff --git a/arch/mips/configs/bmips_be_defconfig b/arch/mips/configs/bmips_be_defconfig
index f5585c8..24dcb90 100644
--- a/arch/mips/configs/bmips_be_defconfig
+++ b/arch/mips/configs/bmips_be_defconfig
@@ -8,7 +8,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y
# CONFIG_SWAP is not set
CONFIG_NO_HZ=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_RD_GZIP is not set
+CONFIG_RD_GZIP=y
CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
@@ -33,6 +33,7 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_MTD=y
CONFIG_MTD_CFI=y
diff --git a/arch/mips/configs/bmips_stb_defconfig b/arch/mips/configs/bmips_stb_defconfig
index 400a47e..4eb5d6e 100644
--- a/arch/mips/configs/bmips_stb_defconfig
+++ b/arch/mips/configs/bmips_stb_defconfig
@@ -9,7 +9,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y
# CONFIG_SWAP is not set
CONFIG_NO_HZ=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_RD_GZIP is not set
+CONFIG_RD_GZIP=y
CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
@@ -34,6 +34,7 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PRINTK_TIME=y
CONFIG_BRCMSTB_GISB_ARB=y
CONFIG_MTD=y
CONFIG_MTD_CFI=y
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 5135dc0..2924ba3 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -31,9 +31,9 @@ CONFIG_NETWORK_SECMARK=y
CONFIG_IP_SCTP=m
CONFIG_FW_LOADER=m
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
CONFIG_NETDEVICES=y
CONFIG_PHYLIB=m
CONFIG_MARVELL_PHY=m
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 0126e66..e94d266 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -14,9 +14,9 @@ CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig
index a75c65d..8743589 100644
--- a/arch/mips/configs/fuloong2e_defconfig
+++ b/arch/mips/configs/fuloong2e_defconfig
@@ -34,7 +34,7 @@ CONFIG_MIPS32_N32=y
CONFIG_PM=y
# CONFIG_SUSPEND is not set
CONFIG_HIBERNATION=y
-CONFIG_PM_STD_PARTITION="/dev/hda3"
+CONFIG_PM_STD_PARTITION="/dev/sda3"
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -114,20 +114,16 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_RAM=m
CONFIG_CDROM_PKTCDVD=m
CONFIG_ATA_OVER_ETH=m
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_VIA82CXXX=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_VIA=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_NETDEVICES=y
CONFIG_MACVLAN=m
CONFIG_VETH=m
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 57ed466..6ba9ce9 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -358,7 +358,6 @@ CONFIG_DLM=m
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 48e16d9..77e9f50 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -346,7 +346,6 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_DLM=m
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITYFS=y
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_NULL=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index fe48220..f9af98f 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -181,7 +181,6 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_ECB=y
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index 4f37a59..a5e85e1 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -362,7 +362,6 @@ CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
CONFIG_DLM=m
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_LRW=m
diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig
index 0179c7f..e620a2c 100644
--- a/arch/mips/configs/lasat_defconfig
+++ b/arch/mips/configs/lasat_defconfig
@@ -35,11 +35,11 @@ CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_CMD64X=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
index 54cc385..d1f198b 100644
--- a/arch/mips/configs/lemote2f_defconfig
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -108,16 +108,11 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_AMD74XX=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_AMD=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
@@ -417,7 +412,6 @@ CONFIG_DEBUG_FS=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 61a4460..5afb484 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -241,14 +241,11 @@ CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_CDROM_PKTCDVD=m
CONFIG_ATA_OVER_ETH=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
CONFIG_RAID_ATTRS=m
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_CONSTANTS=y
@@ -265,6 +262,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
CONFIG_ATA=y
CONFIG_ATA_PIIX=y
+CONFIG_PATA_LEGACY=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig
index d41742d..98f1387 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -248,17 +248,12 @@ CONFIG_CDROM_PKTCDVD=m
CONFIG_ATA_OVER_ETH=m
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
CONFIG_BLK_DEV_TC86C001=m
CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_MULTI_LUN=y
@@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig
index a7806e8..3b5d591 100644
--- a/arch/mips/configs/malta_kvm_guest_defconfig
+++ b/arch/mips/configs/malta_kvm_guest_defconfig
@@ -248,17 +248,12 @@ CONFIG_ATA_OVER_ETH=m
CONFIG_VIRTIO_BLK=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
CONFIG_BLK_DEV_TC86C001=m
CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_MULTI_LUN=y
@@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig
index 4bce1f8..7f50dd6 100644
--- a/arch/mips/configs/malta_qemu_32r6_defconfig
+++ b/arch/mips/configs/malta_qemu_32r6_defconfig
@@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y
CONFIG_DEVTMPFS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig
index fb042ce..a9d433a 100644
--- a/arch/mips/configs/maltaaprp_defconfig
+++ b/arch/mips/configs/maltaaprp_defconfig
@@ -81,15 +81,14 @@ CONFIG_NET_CLS_IND=y
CONFIG_DEVTMPFS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig
index c83338a..2774ef0 100644
--- a/arch/mips/configs/maltasmvp_eva_defconfig
+++ b/arch/mips/configs/maltasmvp_eva_defconfig
@@ -85,15 +85,14 @@ CONFIG_NET_CLS_IND=y
CONFIG_DEVTMPFS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig
index 6234464..9bbd221 100644
--- a/arch/mips/configs/maltaup_defconfig
+++ b/arch/mips/configs/maltaup_defconfig
@@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y
CONFIG_DEVTMPFS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig
index c388bff..7322157 100644
--- a/arch/mips/configs/maltaup_xpa_defconfig
+++ b/arch/mips/configs/maltaup_xpa_defconfig
@@ -244,17 +244,12 @@ CONFIG_CDROM_PKTCDVD=m
CONFIG_ATA_OVER_ETH=m
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_IT8213=m
CONFIG_BLK_DEV_TC86C001=m
CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_CONSTANTS=y
@@ -269,6 +264,13 @@ CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_ATA=y
+CONFIG_ATA_PIIX=y
+CONFIG_PATA_IT8213=m
+CONFIG_PATA_OLDPIIX=y
+CONFIG_PATA_MPIIX=y
+CONFIG_ATA_GENERIC=y
+CONFIG_PATA_LEGACY=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 7a34660..a2c045f 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -27,9 +27,9 @@ CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_NETWORK_SECMARK=y
CONFIG_CONNECTOR=m
CONFIG_ATA_OVER_ETH=m
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_LEGACY=y
CONFIG_NETDEVICES=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
diff --git a/arch/mips/configs/pic32mzda_defconfig b/arch/mips/configs/pic32mzda_defconfig
new file mode 100644
index 0000000..52192c6
--- /dev/null
+++ b/arch/mips/configs/pic32mzda_defconfig
@@ -0,0 +1,89 @@
+CONFIG_MACH_PIC32=y
+CONFIG_DTB_PIC32_MZDA_SK=y
+CONFIG_HZ_100=y
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+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_RELAY=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_SGI_PARTITION=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_SUSPEND is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_INPUT_LEDS=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_GPIO_POLLED=m
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PIC32=y
+CONFIG_SERIAL_PIC32_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_RAW_DRIVER=m
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_HIDRAW=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_MIPS_PLATFORM_DEVICES is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_FSCACHE=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index 642b509..8b74291 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -257,7 +257,6 @@ CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_TEST=m
CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_RTC_CLASS=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index db029f4..82db4e3 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -453,7 +453,6 @@ CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
CONFIG_DLM=m
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_LRW=m
diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
index 51bab13..7fca09fe 100644
--- a/arch/mips/configs/sb1250_swarm_defconfig
+++ b/arch/mips/configs/sb1250_swarm_defconfig
@@ -87,7 +87,6 @@ CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_DLM=m
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
diff --git a/arch/mips/configs/xilfpga_defconfig b/arch/mips/configs/xilfpga_defconfig
new file mode 100644
index 0000000..ed1dce3
--- /dev/null
+++ b/arch/mips/configs/xilfpga_defconfig
@@ -0,0 +1,40 @@
+CONFIG_MACH_XILFPGA=y
+# CONFIG_COMPACTION is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_BLOCK is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_UEVENT_HELPER is not set
+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_ALLOW_DEV_COREDUMP 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_HW_CONSOLE_BINDING=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_XILINX=y
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MIPS_PLATFORM_DEVICES is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h
index 37f8407..9407608 100644
--- a/arch/mips/include/asm/abi.h
+++ b/arch/mips/include/asm/abi.h
@@ -11,19 +11,20 @@
#include <asm/signal.h>
#include <asm/siginfo.h>
+#include <asm/vdso.h>
struct mips_abi {
int (* const setup_frame)(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set);
- const unsigned long signal_return_offset;
int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *set);
- const unsigned long rt_signal_return_offset;
const unsigned long restart;
unsigned off_sc_fpregs;
unsigned off_sc_fpc_csr;
unsigned off_sc_used_math;
+
+ struct mips_vdso_image *vdso;
};
#endif /* _ASM_ABI_H */
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 4c42fd9..835b402 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -30,7 +30,7 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
/*
* atomic_set - set atomic variable
@@ -39,7 +39,7 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic_set(v, i) ((v)->counter = (i))
+#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
#define ATOMIC_OP(op, c_op, asm_op) \
static __inline__ void atomic_##op(int i, atomic_t * v) \
@@ -315,14 +315,14 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
* @v: pointer of type atomic64_t
*
*/
-#define atomic64_read(v) ACCESS_ONCE((v)->counter)
+#define atomic64_read(v) READ_ONCE((v)->counter)
/*
* atomic64_set - set atomic variable
* @v: pointer of type atomic64_t
* @i: required value
*/
-#define atomic64_set(v, i) ((v)->counter = (i))
+#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i))
#define ATOMIC64_OP(op, c_op, asm_op) \
static __inline__ void atomic64_##op(long i, atomic64_t * v) \
@@ -507,7 +507,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
* @u: ...unless v is equal to u.
*
* Atomically adds @a to @v, so long as it was not @u.
- * Returns the old value of @v.
+ * Returns true iff @v was not @u.
*/
static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
{
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index 752e0b8..d296633 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -10,9 +10,6 @@
#include <asm/addrspace.h>
-#define read_barrier_depends() do { } while(0)
-#define smp_read_barrier_depends() do { } while(0)
-
#ifdef CONFIG_CPU_HAS_SYNC
#define __sync() \
__asm__ __volatile__( \
@@ -87,23 +84,21 @@
#define wmb() fast_wmb()
#define rmb() fast_rmb()
-#define dma_wmb() fast_wmb()
-#define dma_rmb() fast_rmb()
-#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
+#if defined(CONFIG_WEAK_ORDERING)
# ifdef CONFIG_CPU_CAVIUM_OCTEON
-# define smp_mb() __sync()
-# define smp_rmb() barrier()
-# define smp_wmb() __syncw()
+# define __smp_mb() __sync()
+# define __smp_rmb() barrier()
+# define __smp_wmb() __syncw()
# else
-# define smp_mb() __asm__ __volatile__("sync" : : :"memory")
-# define smp_rmb() __asm__ __volatile__("sync" : : :"memory")
-# define smp_wmb() __asm__ __volatile__("sync" : : :"memory")
+# define __smp_mb() __asm__ __volatile__("sync" : : :"memory")
+# define __smp_rmb() __asm__ __volatile__("sync" : : :"memory")
+# define __smp_wmb() __asm__ __volatile__("sync" : : :"memory")
# endif
#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
+#define __smp_mb() barrier()
+#define __smp_rmb() barrier()
+#define __smp_wmb() barrier()
#endif
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
@@ -112,13 +107,11 @@
#define __WEAK_LLSC_MB " \n"
#endif
-#define smp_store_mb(var, value) \
- do { WRITE_ONCE(var, value); smp_mb(); } while (0)
-
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#define smp_mb__before_llsc() smp_wmb()
+#define __smp_mb__before_llsc() __smp_wmb()
/* Cause previous writes to become visible on all CPUs as soon as possible */
#define nudge_writes() __asm__ __volatile__(".set push\n\t" \
".set arch=octeon\n\t" \
@@ -126,25 +119,13 @@
".set pop" : : : "memory")
#else
#define smp_mb__before_llsc() smp_llsc_mb()
+#define __smp_mb__before_llsc() smp_llsc_mb()
#define nudge_writes() mb()
#endif
-#define smp_store_release(p, v) \
-do { \
- compiletime_assert_atomic_type(*p); \
- smp_mb(); \
- WRITE_ONCE(*p, v); \
-} while (0)
-
-#define smp_load_acquire(p) \
-({ \
- typeof(*p) ___p1 = READ_ONCE(*p); \
- compiletime_assert_atomic_type(*p); \
- smp_mb(); \
- ___p1; \
-})
-
-#define smp_mb__before_atomic() smp_mb__before_llsc()
-#define smp_mb__after_atomic() smp_llsc_mb()
+#define __smp_mb__before_atomic() __smp_mb__before_llsc()
+#define __smp_mb__after_atomic() smp_llsc_mb()
+
+#include <asm-generic/barrier.h>
#endif /* __ASM_BARRIER_H */
diff --git a/arch/mips/include/asm/bcache.h b/arch/mips/include/asm/bcache.h
index 8c34484..a00857b 100644
--- a/arch/mips/include/asm/bcache.h
+++ b/arch/mips/include/asm/bcache.h
@@ -9,6 +9,7 @@
#ifndef _ASM_BCACHE_H
#define _ASM_BCACHE_H
+#include <linux/types.h>
/* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
chipset implemented caches. On machines with other CPUs the CPU does the
@@ -18,6 +19,9 @@ struct bcache_ops {
void (*bc_disable)(void);
void (*bc_wback_inv)(unsigned long page, unsigned long size);
void (*bc_inv)(unsigned long page, unsigned long size);
+ void (*bc_prefetch_enable)(void);
+ void (*bc_prefetch_disable)(void);
+ bool (*bc_prefetch_is_enabled)(void);
};
extern void indy_sc_init(void);
@@ -46,6 +50,26 @@ static inline void bc_inv(unsigned long page, unsigned long size)
bcops->bc_inv(page, size);
}
+static inline void bc_prefetch_enable(void)
+{
+ if (bcops->bc_prefetch_enable)
+ bcops->bc_prefetch_enable();
+}
+
+static inline void bc_prefetch_disable(void)
+{
+ if (bcops->bc_prefetch_disable)
+ bcops->bc_prefetch_disable();
+}
+
+static inline bool bc_prefetch_is_enabled(void)
+{
+ if (bcops->bc_prefetch_is_enabled)
+ return bcops->bc_prefetch_is_enabled();
+
+ return false;
+}
+
#else /* !defined(CONFIG_BOARD_SCACHE) */
/* Not R4000 / R4400 / R4600 / R5000. */
@@ -54,6 +78,9 @@ static inline void bc_inv(unsigned long page, unsigned long size)
#define bc_disable() do { } while (0)
#define bc_wback_inv(page, size) do { } while (0)
#define bc_inv(page, size) do { } while (0)
+#define bc_prefetch_enable() do { } while (0)
+#define bc_prefetch_disable() do { } while (0)
+#define bc_prefetch_is_enabled() 0
#endif /* !defined(CONFIG_BOARD_SCACHE) */
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
index 06b9bc7..c3212ff 100644
--- a/arch/mips/include/asm/cacheops.h
+++ b/arch/mips/include/asm/cacheops.h
@@ -12,54 +12,76 @@
#define __ASM_CACHEOPS_H
/*
+ * Most cache ops are split into a 2 bit field identifying the cache, and a 3
+ * bit field identifying the cache operation.
+ */
+#define CacheOp_Cache 0x03
+#define CacheOp_Op 0x1c
+
+#define Cache_I 0x00
+#define Cache_D 0x01
+#define Cache_T 0x02
+#define Cache_S 0x03
+
+#define Index_Writeback_Inv 0x00
+#define Index_Load_Tag 0x04
+#define Index_Store_Tag 0x08
+#define Hit_Invalidate 0x10
+#define Hit_Writeback_Inv 0x14 /* not with Cache_I though */
+#define Hit_Writeback 0x18
+
+/*
* Cache Operations available on all MIPS processors with R4000-style caches
*/
-#define Index_Invalidate_I 0x00
-#define Index_Writeback_Inv_D 0x01
-#define Index_Load_Tag_I 0x04
-#define Index_Load_Tag_D 0x05
-#define Index_Store_Tag_I 0x08
-#define Index_Store_Tag_D 0x09
-#define Hit_Invalidate_I 0x10
-#define Hit_Invalidate_D 0x11
-#define Hit_Writeback_Inv_D 0x15
+#define Index_Invalidate_I (Cache_I | Index_Writeback_Inv)
+#define Index_Writeback_Inv_D (Cache_D | Index_Writeback_Inv)
+#define Index_Load_Tag_I (Cache_I | Index_Load_Tag)
+#define Index_Load_Tag_D (Cache_D | Index_Load_Tag)
+#define Index_Store_Tag_I (Cache_I | Index_Store_Tag)
+#define Index_Store_Tag_D (Cache_D | Index_Store_Tag)
+#define Hit_Invalidate_I (Cache_I | Hit_Invalidate)
+#define Hit_Invalidate_D (Cache_D | Hit_Invalidate)
+#define Hit_Writeback_Inv_D (Cache_D | Hit_Writeback_Inv)
/*
* R4000-specific cacheops
*/
-#define Create_Dirty_Excl_D 0x0d
-#define Fill 0x14
-#define Hit_Writeback_I 0x18
-#define Hit_Writeback_D 0x19
+#define Create_Dirty_Excl_D (Cache_D | 0x0c)
+#define Fill (Cache_I | 0x14)
+#define Hit_Writeback_I (Cache_I | Hit_Writeback)
+#define Hit_Writeback_D (Cache_D | Hit_Writeback)
/*
* R4000SC and R4400SC-specific cacheops
*/
-#define Index_Invalidate_SI 0x02
-#define Index_Writeback_Inv_SD 0x03
-#define Index_Load_Tag_SI 0x06
-#define Index_Load_Tag_SD 0x07
-#define Index_Store_Tag_SI 0x0A
-#define Index_Store_Tag_SD 0x0B
-#define Create_Dirty_Excl_SD 0x0f
-#define Hit_Invalidate_SI 0x12
-#define Hit_Invalidate_SD 0x13
-#define Hit_Writeback_Inv_SD 0x17
-#define Hit_Writeback_SD 0x1b
-#define Hit_Set_Virtual_SI 0x1e
-#define Hit_Set_Virtual_SD 0x1f
+#define Cache_SI 0x02
+#define Cache_SD 0x03
+
+#define Index_Invalidate_SI (Cache_SI | Index_Writeback_Inv)
+#define Index_Writeback_Inv_SD (Cache_SD | Index_Writeback_Inv)
+#define Index_Load_Tag_SI (Cache_SI | Index_Load_Tag)
+#define Index_Load_Tag_SD (Cache_SD | Index_Load_Tag)
+#define Index_Store_Tag_SI (Cache_SI | Index_Store_Tag)
+#define Index_Store_Tag_SD (Cache_SD | Index_Store_Tag)
+#define Create_Dirty_Excl_SD (Cache_SD | 0x0c)
+#define Hit_Invalidate_SI (Cache_SI | Hit_Invalidate)
+#define Hit_Invalidate_SD (Cache_SD | Hit_Invalidate)
+#define Hit_Writeback_Inv_SD (Cache_SD | Hit_Writeback_Inv)
+#define Hit_Writeback_SD (Cache_SD | Hit_Writeback)
+#define Hit_Set_Virtual_SI (Cache_SI | 0x1c)
+#define Hit_Set_Virtual_SD (Cache_SD | 0x1c)
/*
* R5000-specific cacheops
*/
-#define R5K_Page_Invalidate_S 0x17
+#define R5K_Page_Invalidate_S (Cache_S | 0x14)
/*
* RM7000-specific cacheops
*/
-#define Page_Invalidate_T 0x16
-#define Index_Store_Tag_T 0x0a
-#define Index_Load_Tag_T 0x06
+#define Page_Invalidate_T (Cache_T | 0x14)
+#define Index_Store_Tag_T (Cache_T | Index_Store_Tag)
+#define Index_Load_Tag_T (Cache_T | Index_Load_Tag)
/*
* R10000-specific cacheops
@@ -67,22 +89,22 @@
* Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
* Most of the _S cacheops are identical to the R4000SC _SD cacheops.
*/
-#define Index_Writeback_Inv_S 0x03
-#define Index_Load_Tag_S 0x07
-#define Index_Store_Tag_S 0x0B
-#define Hit_Invalidate_S 0x13
+#define Index_Writeback_Inv_S (Cache_S | Index_Writeback_Inv)
+#define Index_Load_Tag_S (Cache_S | Index_Load_Tag)
+#define Index_Store_Tag_S (Cache_S | Index_Store_Tag)
+#define Hit_Invalidate_S (Cache_S | Hit_Invalidate)
#define Cache_Barrier 0x14
-#define Hit_Writeback_Inv_S 0x17
-#define Index_Load_Data_I 0x18
-#define Index_Load_Data_D 0x19
-#define Index_Load_Data_S 0x1b
-#define Index_Store_Data_I 0x1c
-#define Index_Store_Data_D 0x1d
-#define Index_Store_Data_S 0x1f
+#define Hit_Writeback_Inv_S (Cache_S | Hit_Writeback_Inv)
+#define Index_Load_Data_I (Cache_I | 0x18)
+#define Index_Load_Data_D (Cache_D | 0x18)
+#define Index_Load_Data_S (Cache_S | 0x18)
+#define Index_Store_Data_I (Cache_I | 0x1c)
+#define Index_Store_Data_D (Cache_D | 0x1c)
+#define Index_Store_Data_S (Cache_S | 0x1c)
/*
* Loongson2-specific cacheops
*/
-#define Hit_Invalidate_I_Loongson2 0x00
+#define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00)
#endif /* __ASM_CACHEOPS_H */
diff --git a/arch/mips/include/asm/cdmm.h b/arch/mips/include/asm/cdmm.h
index bece206..c06dbf8b 100644
--- a/arch/mips/include/asm/cdmm.h
+++ b/arch/mips/include/asm/cdmm.h
@@ -84,6 +84,17 @@ void mips_cdmm_driver_unregister(struct mips_cdmm_driver *);
module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \
mips_cdmm_driver_unregister)
+/*
+ * builtin_mips_cdmm_driver() - Helper macro for drivers that don't do anything
+ * special in init and have no exit. This eliminates some boilerplate. Each
+ * driver may only use this macro once, and calling it replaces device_initcall
+ * (or in some cases, the legacy __initcall). This is meant to be a direct
+ * parallel of module_mips_cdmm_driver() above but without the __exit stuff that
+ * is not used for builtin cases.
+ */
+#define builtin_mips_cdmm_driver(__mips_cdmm_driver) \
+ builtin_driver(__mips_cdmm_driver, mips_cdmm_driver_register)
+
/* drivers/tty/mips_ejtag_fdc.c */
#ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
index 3ceacde..bce1ce5 100644
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -160,9 +160,9 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
#define ip_fast_csum ip_fast_csum
-static inline __wsum csum_tcpudp_nofold(__be32 saddr,
- __be32 daddr, unsigned short len, unsigned short proto,
- __wsum sum)
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto,
+ __wsum sum)
{
__asm__(
" .set push # csum_tcpudp_nofold\n"
@@ -215,7 +215,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
__wsum tmp;
diff --git a/arch/mips/include/asm/clocksource.h b/arch/mips/include/asm/clocksource.h
new file mode 100644
index 0000000..3deb1d0
--- /dev/null
+++ b/arch/mips/include/asm/clocksource.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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_CLOCKSOURCE_H
+#define __ASM_CLOCKSOURCE_H
+
+#include <linux/types.h>
+
+/* VDSO clocksources. */
+#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */
+#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */
+#define VDSO_CLOCK_GIC 2 /* Use the GIC. */
+
+/**
+ * struct arch_clocksource_data - Architecture-specific clocksource information.
+ * @vdso_clock_mode: Method the VDSO should use to access the clocksource.
+ */
+struct arch_clocksource_data {
+ u8 vdso_clock_mode;
+};
+
+#endif /* __ASM_CLOCKSOURCE_H */
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index c4bd54a..a958009 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -130,6 +130,8 @@ typedef union compat_sigval {
compat_uptr_t sival_ptr;
} compat_sigval_t;
+/* Can't use the generic version because si_code and si_errno are swapped */
+
#define SI_PAD_SIZE32 (128/sizeof(int) - 3)
typedef struct compat_siginfo {
@@ -138,57 +140,61 @@ typedef struct compat_siginfo {
int si_errno;
union {
- int _pad[SI_PAD_SIZE32];
+ int _pad[128 / sizeof(int) - 3];
/* kill() */
struct {
compat_pid_t _pid; /* sender's pid */
- __compat_uid_t _uid; /* sender's uid */
+ __compat_uid32_t _uid; /* sender's uid */
} _kill;
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid32_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
/* SIGCHLD */
struct {
compat_pid_t _pid; /* which child */
- __compat_uid_t _uid; /* sender's uid */
+ __compat_uid32_t _uid; /* sender's uid */
int _status; /* exit code */
compat_clock_t _utime;
compat_clock_t _stime;
} _sigchld;
- /* IRIX SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- compat_clock_t _utime;
- int _status; /* exit code */
- compat_clock_t _stime;
- } _irix_sigchld;
-
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
struct {
- s32 _addr; /* faulting insn/memory ref. */
+ compat_uptr_t _addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ short _addr_lsb; /* LSB of the reported address */
+ struct {
+ compat_uptr_t _lower;
+ compat_uptr_t _upper;
+ } _addr_bnd;
} _sigfault;
- /* SIGPOLL, SIGXFSZ (To do ...) */
+ /* SIGPOLL */
struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
- /* POSIX.1b timers */
- struct {
- timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval;/* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
struct {
- compat_pid_t _pid; /* sender's pid */
- __compat_uid_t _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
+ compat_uptr_t _call_addr; /* calling insn */
+ int _syscall; /* triggering system call number */
+ compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */
+ } _sigsys;
} _sifields;
} compat_siginfo_t;
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index fe67f12..eeec8c8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -131,11 +131,7 @@
#endif
#ifndef cpu_has_rixi
-# ifdef CONFIG_64BIT
-# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
-# else /* CONFIG_32BIT */
-# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits)
-# endif
+#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
#endif
#ifndef cpu_has_mmips
@@ -418,4 +414,11 @@
# define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP)
#endif
+#ifndef cpu_has_nan_legacy
+#define cpu_has_nan_legacy (cpu_data[0].options & MIPS_CPU_NAN_LEGACY)
+#endif
+#ifndef cpu_has_nan_2008
+#define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008)
+#endif
+
#endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 82ad15f..a97ca97 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -386,6 +386,8 @@ enum cpu_type_enum {
#define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */
#define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */
#define MIPS_CPU_FTLB 0x20000000000ull /* CPU has Fixed-page-size TLB */
+#define MIPS_CPU_NAN_LEGACY 0x40000000000ull /* Legacy NaN implemented */
+#define MIPS_CPU_NAN_2008 0x80000000000ull /* 2008 NaN implemented */
/*
* CPU ASE encodings
diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h
new file mode 100644
index 0000000..254f00d
--- /dev/null
+++ b/arch/mips/include/asm/debug.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 __MIPS_ASM_DEBUG_H__
+#define __MIPS_ASM_DEBUG_H__
+
+#include <linux/dcache.h>
+
+/*
+ * mips_debugfs_dir corresponds to the "mips" directory at the top level
+ * of the DebugFS hierarchy. MIPS-specific DebugFS entires should be
+ * placed beneath this directory.
+ */
+extern struct dentry *mips_debugfs_dir;
+
+#endif /* __MIPS_ASM_DEBUG_H__ */
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index e604f76..12fa79e 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -29,8 +29,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
static inline void dma_mark_clean(void *addr, size_t size) {}
-#include <asm-generic/dma-mapping-common.h>
-
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 53b2693..e090fc3 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -8,10 +8,10 @@
#ifndef _ASM_ELF_H
#define _ASM_ELF_H
+#include <linux/auxvec.h>
#include <linux/fs.h>
#include <uapi/linux/elf.h>
-#include <asm/cpu-info.h>
#include <asm/current.h>
/* ELF header e_flags defines. */
@@ -43,6 +43,7 @@
#define EF_MIPS_OPTIONS_FIRST 0x00000080
#define EF_MIPS_32BITMODE 0x00000100
#define EF_MIPS_FP64 0x00000200
+#define EF_MIPS_NAN2008 0x00000400
#define EF_MIPS_ABI 0x0000f000
#define EF_MIPS_ARCH 0xf0000000
@@ -226,7 +227,7 @@ struct mips_elf_abiflags_v0 {
int __res = 1; \
struct elfhdr *__h = (hdr); \
\
- if (__h->e_machine != EM_MIPS) \
+ if (!mips_elf_check_machine(__h)) \
__res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \
@@ -257,7 +258,7 @@ struct mips_elf_abiflags_v0 {
int __res = 1; \
struct elfhdr *__h = (hdr); \
\
- if (__h->e_machine != EM_MIPS) \
+ if (!mips_elf_check_machine(__h)) \
__res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS64) \
__res = 0; \
@@ -284,6 +285,11 @@ struct mips_elf_abiflags_v0 {
#endif /* !defined(ELF_ARCH) */
+#define mips_elf_check_machine(x) ((x)->e_machine == EM_MIPS)
+
+#define vmcore_elf32_check_arch mips_elf_check_machine
+#define vmcore_elf64_check_arch mips_elf_check_machine
+
struct mips_abi;
extern struct mips_abi mips_abi;
@@ -304,7 +310,7 @@ do { \
\
current->thread.abi = &mips_abi; \
\
- current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \
+ mips_set_personality_nan(state); \
} while (0)
#endif /* CONFIG_32BIT */
@@ -366,7 +372,7 @@ do { \
else \
current->thread.abi = &mips_abi; \
\
- current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \
+ mips_set_personality_nan(state); \
\
p = personality(current->personality); \
if (p != PER_LINUX32 && p != PER_LINUX) \
@@ -419,12 +425,19 @@ extern const char *__elf_platform;
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
#endif
+#define ARCH_DLINFO \
+do { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+ (unsigned long)current->mm->context.vdso); \
+} while (0)
+
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
struct linux_binprm;
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
struct arch_elf_state {
+ int nan_2008;
int fp_abi;
int interp_fp_abi;
int overall_fp_mode;
@@ -433,17 +446,23 @@ struct arch_elf_state {
#define MIPS_ABI_FP_UNKNOWN (-1) /* Unknown FP ABI (kernel internal) */
#define INIT_ARCH_ELF_STATE { \
+ .nan_2008 = -1, \
.fp_abi = MIPS_ABI_FP_UNKNOWN, \
.interp_fp_abi = MIPS_ABI_FP_UNKNOWN, \
.overall_fp_mode = -1, \
}
+/* Whether to accept legacy-NaN and 2008-NaN user binaries. */
+extern bool mips_use_nan_legacy;
+extern bool mips_use_nan_2008;
+
extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
bool is_interp, struct arch_elf_state *state);
-extern int arch_check_elf(void *ehdr, bool has_interpreter,
+extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
struct arch_elf_state *state);
+extern void mips_set_personality_nan(struct arch_elf_state *state);
extern void mips_set_personality_fp(struct arch_elf_state *state);
#endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index 9cbf383..f06f97b 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -179,6 +179,10 @@ static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)
if (save)
_save_fp(tsk);
__disable_fpu();
+ } else {
+ /* FPU should not have been left enabled with no owner */
+ WARN(read_c0_status() & ST0_CU1,
+ "Orphaned FPU left enabled");
}
KSTK_STATUS(tsk) &= ~ST0_CU1;
clear_tsk_thread_flag(tsk, TIF_USEDFPU);
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index 2f021cd..3225c3c 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
/*
* Break instruction with special math emu break code set
*/
-#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
+#define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
#define SIGNALLING_NAN 0x7ff800007ff80000LL
diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h
index f3e6978..d0ef8b4 100644
--- a/arch/mips/include/asm/fw/fw.h
+++ b/arch/mips/include/asm/fw/fw.h
@@ -10,21 +10,6 @@
#include <asm/bootinfo.h> /* For cleaner code... */
-enum fw_memtypes {
- fw_dontuse,
- fw_code,
- fw_free,
-};
-
-typedef struct {
- unsigned long base; /* Within KSEG0 */
- unsigned int size; /* bytes */
- enum fw_memtypes type; /* fw_memtypes */
-} fw_memblock_t;
-
-/* Maximum number of memory block descriptors. */
-#define FW_MAX_MEMBLOCKS 32
-
extern int fw_argc;
extern int *_fw_argv;
extern int *_fw_envp;
@@ -38,7 +23,6 @@ extern int *_fw_envp;
extern void fw_init_cmdline(void);
extern char *fw_getcmdline(void);
-extern fw_memblock_t *fw_getmdesc(int);
extern void fw_meminit(void);
extern char *fw_getenv(char *name);
extern unsigned long fw_getenvl(char *name);
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
index 572e63e..01880b3 100644
--- a/arch/mips/include/asm/highmem.h
+++ b/arch/mips/include/asm/highmem.h
@@ -49,7 +49,6 @@ extern void kunmap(struct page *page);
extern void *kmap_atomic(struct page *page);
extern void __kunmap_atomic(void *kvaddr);
extern void *kmap_atomic_pfn(unsigned long pfn);
-extern struct page *kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() flush_cache_all()
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index d10fd80..2b4dc7a 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -275,6 +275,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
*/
#define ioremap_cachable(offset, size) \
__ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cache ioremap_cachable
/*
* These two are MIPS specific ioremap variant. ioremap_cacheable_cow
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index e7b138b..65c351e 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -84,41 +84,11 @@ static inline void arch_local_irq_restore(unsigned long flags)
: "memory");
}
-static inline void __arch_local_irq_restore(unsigned long flags)
-{
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set noat \n"
-#if defined(CONFIG_IRQ_MIPS_CPU)
- /*
- * Slow, but doesn't suffer from a relatively unlikely race
- * condition we're having since days 1.
- */
- " beqz %[flags], 1f \n"
- " di \n"
- " ei \n"
- "1: \n"
-#else
- /*
- * Fast, dangerous. Life is fun, life is good.
- */
- " mfc0 $1, $12 \n"
- " ins $1, %[flags], 0, 1 \n"
- " mtc0 $1, $12 \n"
-#endif
- " " __stringify(__irq_disable_hazard) " \n"
- " .set pop \n"
- : [flags] "=r" (flags)
- : "0" (flags)
- : "memory");
-}
#else
/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
void arch_local_irq_disable(void);
unsigned long arch_local_irq_save(void);
void arch_local_irq_restore(unsigned long flags);
-void __arch_local_irq_restore(unsigned long flags);
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
static inline void arch_local_irq_enable(void)
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 5a1a882..f6b1279 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -58,7 +58,7 @@
#define KVM_MAX_VCPUS 1
#define KVM_USER_MEM_SLOTS 8
/* memory slots that does not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS 0
+#define KVM_PRIVATE_MEM_SLOTS 0
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_HALT_POLL_NS_DEFAULT 500000
@@ -92,18 +92,10 @@
#define KVM_INVALID_INST 0xdeadbeef
#define KVM_INVALID_ADDR 0xdeadbeef
-#define KVM_MALTA_GUEST_RTC_ADDR 0xb8000070UL
-
-#define GUEST_TICKS_PER_JIFFY (40000000/HZ)
-#define MS_TO_NS(x) (x * 1E6L)
-
-#define CAUSEB_DC 27
-#define CAUSEF_DC (_ULCAST_(1) << 27)
-
extern atomic_t kvm_mips_instance;
-extern pfn_t(*kvm_mips_gfn_to_pfn) (struct kvm *kvm, gfn_t gfn);
-extern void (*kvm_mips_release_pfn_clean) (pfn_t pfn);
-extern bool(*kvm_mips_is_error_pfn) (pfn_t pfn);
+extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
+extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
+extern bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
struct kvm_vm_stat {
u32 remote_tlb_flush;
@@ -289,34 +281,6 @@ enum mips_mmu_types {
MMU_TYPE_R8000
};
-/*
- * Trap codes
- */
-#define T_INT 0 /* Interrupt pending */
-#define T_TLB_MOD 1 /* TLB modified fault */
-#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */
-#define T_TLB_ST_MISS 3 /* TLB miss on a store */
-#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */
-#define T_ADDR_ERR_ST 5 /* Address error on a store */
-#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */
-#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */
-#define T_SYSCALL 8 /* System call */
-#define T_BREAK 9 /* Breakpoint */
-#define T_RES_INST 10 /* Reserved instruction exception */
-#define T_COP_UNUSABLE 11 /* Coprocessor unusable */
-#define T_OVFLOW 12 /* Arithmetic overflow */
-
-/*
- * Trap definitions added for r4000 port.
- */
-#define T_TRAP 13 /* Trap instruction */
-#define T_VCEI 14 /* Virtual coherency exception */
-#define T_MSAFPE 14 /* MSA floating point exception */
-#define T_FPE 15 /* Floating point exception */
-#define T_MSADIS 21 /* MSA disabled exception */
-#define T_WATCH 23 /* Watch address reference */
-#define T_VCED 31 /* Virtual coherency data */
-
/* Resume Flags */
#define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
@@ -686,7 +650,6 @@ extern void kvm_mips_dump_host_tlbs(void);
extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
extern void kvm_mips_flush_host_tlb(int skip_kseg0);
extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
-extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
unsigned long entryhi);
@@ -847,5 +810,7 @@ static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot) {}
static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
#endif /* __MIPS_KVM_HOST_H__ */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 4eee221..441faa9 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void)
return soc_is_qca9556() || soc_is_qca9558();
}
+void ath79_ddr_wb_flush(unsigned int reg);
void ath79_ddr_set_pci_windows(void);
extern void __iomem *ath79_pll_base;
@@ -143,4 +144,8 @@ static inline u32 ath79_reset_rr(unsigned reg)
void ath79_device_reset_set(u32 mask);
void ath79_device_reset_clear(u32 mask);
+void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3);
+void ath79_misc_irq_init(void __iomem *regs, int irq,
+ int irq_base, bool is_ar71xx);
+
#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index 1461c10..71e4096 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -48,11 +48,6 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type;
void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
bool fallback);
-#ifdef CONFIG_BCM47XX_SSB
-void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
- const char *prefix);
-#endif
-
void bcm47xx_set_system_type(u16 chip_id);
#endif /* __ASM_BCM47XX_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
index 2573765..dd29954 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
@@ -7,48 +7,4 @@
int __init bcm63xx_spi_register(void);
-struct bcm63xx_spi_pdata {
- unsigned int fifo_size;
- unsigned int msg_type_shift;
- unsigned int msg_ctl_width;
- int bus_num;
- int num_chipselect;
-};
-
-enum bcm63xx_regs_spi {
- SPI_CMD,
- SPI_INT_STATUS,
- SPI_INT_MASK_ST,
- SPI_INT_MASK,
- SPI_ST,
- SPI_CLK_CFG,
- SPI_FILL_BYTE,
- SPI_MSG_TAIL,
- SPI_RX_TAIL,
- SPI_MSG_CTL,
- SPI_MSG_DATA,
- SPI_RX_DATA,
-};
-
-#define __GEN_SPI_REGS_TABLE(__cpu) \
- [SPI_CMD] = SPI_## __cpu ##_CMD, \
- [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \
- [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \
- [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \
- [SPI_ST] = SPI_## __cpu ##_ST, \
- [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \
- [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \
- [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \
- [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \
- [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \
- [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \
- [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA,
-
-static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
-{
- extern const unsigned long *bcm63xx_regs_spi;
-
- return bcm63xx_regs_spi[reg];
-}
-
#endif /* BCM63XX_DEV_SPI_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
deleted file mode 100644
index 1e6b587..0000000
--- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef __BCM963XX_TAG_H
-#define __BCM963XX_TAG_H
-
-#define TAGVER_LEN 4 /* Length of Tag Version */
-#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
-#define SIG1_LEN 20 /* Company Signature 1 Length */
-#define SIG2_LEN 14 /* Company Signature 2 Length */
-#define BOARDID_LEN 16 /* Length of BoardId */
-#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
-#define CHIPID_LEN 6 /* Chip Id Length */
-#define IMAGE_LEN 10 /* Length of Length Field */
-#define ADDRESS_LEN 12 /* Length of Address field */
-#define DUALFLAG_LEN 2 /* Dual Image flag Length */
-#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
-#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
-#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
-#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
-#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
-#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
-
-#define NUM_PIRELLI 2
-#define IMAGETAG_CRC_START 0xFFFFFFFF
-
-#define PIRELLI_BOARDS { \
- "AGPF-S0", \
- "DWV-S0", \
-}
-
-/*
- * The broadcom firmware assumes the rootfs starts the image,
- * therefore uses the rootfs start (flash_image_address)
- * to determine where to flash the image. Since we have the kernel first
- * we have to give it the kernel address, but the crc uses the length
- * associated with this address (root_length), which is added to the kernel
- * length (kernel_length) to determine the length of image to flash and thus
- * needs to be rootfs + deadcode (jffs2 EOF marker)
-*/
-
-struct bcm_tag {
- /* 0-3: Version of the image tag */
- char tag_version[TAGVER_LEN];
- /* 4-23: Company Line 1 */
- char sig_1[SIG1_LEN];
- /* 24-37: Company Line 2 */
- char sig_2[SIG2_LEN];
- /* 38-43: Chip this image is for */
- char chip_id[CHIPID_LEN];
- /* 44-59: Board name */
- char board_id[BOARDID_LEN];
- /* 60-61: Map endianness -- 1 BE 0 LE */
- char big_endian[ENDIANFLAG_LEN];
- /* 62-71: Total length of image */
- char total_length[IMAGE_LEN];
- /* 72-83: Address in memory of CFE */
- char cfe__address[ADDRESS_LEN];
- /* 84-93: Size of CFE */
- char cfe_length[IMAGE_LEN];
- /* 94-105: Address in memory of image start
- * (kernel for OpenWRT, rootfs for stock firmware)
- */
- char flash_image_start[ADDRESS_LEN];
- /* 106-115: Size of rootfs */
- char root_length[IMAGE_LEN];
- /* 116-127: Address in memory of kernel */
- char kernel_address[ADDRESS_LEN];
- /* 128-137: Size of kernel */
- char kernel_length[IMAGE_LEN];
- /* 138-139: Unused at the moment */
- char dual_image[DUALFLAG_LEN];
- /* 140-141: Unused at the moment */
- char inactive_flag[INACTIVEFLAG_LEN];
- /* 142-161: RSA Signature (not used; some vendors may use this) */
- char rsa_signature[RSASIG_LEN];
- /* 162-191: Compilation and related information (not used in OpenWrt) */
- char information1[TAGINFO1_LEN];
- /* 192-195: Version flash layout */
- char flash_layout_ver[FLASHLAYOUTVER_LEN];
- /* 196-199: kernel+rootfs CRC32 */
- __u32 fskernel_crc;
- /* 200-215: Unused except on Alice Gate where is is information */
- char information2[TAGINFO2_LEN];
- /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
- __u32 image_crc;
- /* 220-223: CRC32 of rootfs partition */
- __u32 rootfs_crc;
- /* 224-227: CRC32 of kernel partition */
- __u32 kernel_crc;
- /* 228-235: Unused at present */
- char reserved1[8];
- /* 236-239: CRC32 of header excluding last 20 bytes */
- __u32 header_crc;
- /* 240-255: Unused at present */
- char reserved2[16];
-};
-
-#endif /* __BCM63XX_TAG_H */
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index 133336b..dd6005b 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -35,6 +35,17 @@
#define SOC_ID_VRX268_2 0x00C /* v1.2 */
#define SOC_ID_GRX288_2 0x00D /* v1.2 */
#define SOC_ID_GRX282_2 0x00E /* v1.2 */
+#define SOC_ID_VRX220 0x000
+
+#define SOC_ID_ARX362 0x004
+#define SOC_ID_ARX368 0x005
+#define SOC_ID_ARX382 0x007
+#define SOC_ID_ARX388 0x008
+#define SOC_ID_URX388 0x009
+#define SOC_ID_GRX383 0x010
+#define SOC_ID_GRX369 0x011
+#define SOC_ID_GRX387 0x00F
+#define SOC_ID_GRX389 0x012
/* SoC Types */
#define SOC_TYPE_DANUBE 0x01
@@ -43,6 +54,9 @@
#define SOC_TYPE_VR9 0x04 /* v1.1 */
#define SOC_TYPE_VR9_2 0x05 /* v1.2 */
#define SOC_TYPE_AMAZON_SE 0x06
+#define SOC_TYPE_AR10 0x07
+#define SOC_TYPE_GRX390 0x08
+#define SOC_TYPE_VRX220 0x09
/* BOOT_SEL - find what boot media we have */
#define BS_EXT_ROM 0x0
diff --git a/arch/mips/include/asm/mach-malta/malta-dtshim.h b/arch/mips/include/asm/mach-malta/malta-dtshim.h
new file mode 100644
index 0000000..cfd7776
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/malta-dtshim.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 __MIPS_MALTA_DTSHIM_H__
+#define __MIPS_MALTA_DTSHIM_H__
+
+#include <linux/init.h>
+
+#ifdef CONFIG_MIPS_MALTA
+
+extern void __init *malta_dt_shim(void *fdt);
+
+#else /* !CONFIG_MIPS_MALTA */
+
+static inline void *malta_dt_shim(void *fdt)
+{
+ return fdt;
+}
+
+#endif /* !CONFIG_MIPS_MALTA */
+
+#endif /* __MIPS_MALTA_DTSHIM_H__ */
diff --git a/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h b/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
new file mode 100644
index 0000000..4682308
--- /dev/null
+++ b/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
@@ -0,0 +1,32 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * 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_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * CPU feature overrides for PIC32 boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_vint 1
+#define cpu_has_veic 0
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_fpu 0
+#define cpu_has_counter 1
+#define cpu_has_llsc 1
+#define cpu_has_nofpuex 0
+#define cpu_icache_snoops_remote_store 1
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#error This platform does not support 64bit.
+#endif
+
+#endif /* __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-pic32/irq.h b/arch/mips/include/asm/mach-pic32/irq.h
new file mode 100644
index 0000000..864330c
--- /dev/null
+++ b/arch/mips/include/asm/mach-pic32/irq.h
@@ -0,0 +1,22 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 __ASM_MACH_PIC32_IRQ_H
+#define __ASM_MACH_PIC32_IRQ_H
+
+#define NR_IRQS 256
+#define MIPS_CPU_IRQ_BASE 0
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_PIC32_IRQ_H */
diff --git a/arch/mips/include/asm/mach-pic32/pic32.h b/arch/mips/include/asm/mach-pic32/pic32.h
new file mode 100644
index 0000000..ce52e91
--- /dev/null
+++ b/arch/mips/include/asm/mach-pic32/pic32.h
@@ -0,0 +1,44 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 _ASM_MACH_PIC32_H
+#define _ASM_MACH_PIC32_H
+
+#include <linux/io.h>
+
+/*
+ * PIC32 register offsets for SET/CLR/INV where supported.
+ */
+#define PIC32_CLR(_reg) ((_reg) + 0x04)
+#define PIC32_SET(_reg) ((_reg) + 0x08)
+#define PIC32_INV(_reg) ((_reg) + 0x0C)
+
+/*
+ * PIC32 Base Register Offsets
+ */
+#define PIC32_BASE_CONFIG 0x1f800000
+#define PIC32_BASE_OSC 0x1f801200
+#define PIC32_BASE_RESET 0x1f801240
+#define PIC32_BASE_PPS 0x1f801400
+#define PIC32_BASE_UART 0x1f822000
+#define PIC32_BASE_PORT 0x1f860000
+#define PIC32_BASE_DEVCFG2 0x1fc4ff44
+
+/*
+ * Register unlock sequence required for some register access.
+ */
+void pic32_syskey_unlock_debug(const char *fn, const ulong ln);
+#define pic32_syskey_unlock() \
+ pic32_syskey_unlock_debug(__func__, __LINE__)
+
+#endif /* _ASM_MACH_PIC32_H */
diff --git a/arch/mips/include/asm/mach-pic32/spaces.h b/arch/mips/include/asm/mach-pic32/spaces.h
new file mode 100644
index 0000000..046a0a9
--- /dev/null
+++ b/arch/mips/include/asm/mach-pic32/spaces.h
@@ -0,0 +1,24 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 _ASM_MACH_PIC32_SPACES_H
+#define _ASM_MACH_PIC32_SPACES_H
+
+#ifdef CONFIG_PIC32MZDA
+#define PHYS_OFFSET _AC(0x08000000, UL)
+#define UNCAC_BASE _AC(0xa8000000, UL)
+#endif
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_MACH_PIC32_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ralink/irq.h b/arch/mips/include/asm/mach-ralink/irq.h
new file mode 100644
index 0000000..4321865
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/irq.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_RALINK_IRQ_H
+#define __ASM_MACH_RALINK_IRQ_H
+
+#define GIC_NUM_INTRS 64
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
index 1976fb8..455d406 100644
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
@@ -13,17 +13,11 @@
#ifndef _MT7620_REGS_H_
#define _MT7620_REGS_H_
-enum mt762x_soc_type {
- MT762X_SOC_UNKNOWN = 0,
- MT762X_SOC_MT7620A,
- MT762X_SOC_MT7620N,
- MT762X_SOC_MT7628AN,
-};
-
#define MT7620_SYSC_BASE 0x10000000
#define SYSC_REG_CHIP_NAME0 0x00
#define SYSC_REG_CHIP_NAME1 0x04
+#define SYSC_REG_EFUSE_CFG 0x08
#define SYSC_REG_CHIP_REV 0x0c
#define SYSC_REG_SYSTEM_CONFIG0 0x10
#define SYSC_REG_SYSTEM_CONFIG1 0x14
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
new file mode 100644
index 0000000..610b61e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can 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) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _MT7621_REGS_H_
+#define _MT7621_REGS_H_
+
+#define MT7621_PALMBUS_BASE 0x1C000000
+#define MT7621_PALMBUS_SIZE 0x03FFFFFF
+
+#define MT7621_SYSC_BASE 0x1E000000
+
+#define SYSC_REG_CHIP_NAME0 0x00
+#define SYSC_REG_CHIP_NAME1 0x04
+#define SYSC_REG_CHIP_REV 0x0c
+#define SYSC_REG_SYSTEM_CONFIG0 0x10
+#define SYSC_REG_SYSTEM_CONFIG1 0x14
+
+#define CHIP_REV_PKG_MASK 0x1
+#define CHIP_REV_PKG_SHIFT 16
+#define CHIP_REV_VER_MASK 0xf
+#define CHIP_REV_VER_SHIFT 8
+#define CHIP_REV_ECO_MASK 0xf
+
+#define MT7621_DRAM_BASE 0x0
+#define MT7621_DDR2_SIZE_MIN 32
+#define MT7621_DDR2_SIZE_MAX 256
+
+#define MT7621_CHIP_NAME0 0x3637544D
+#define MT7621_CHIP_NAME1 0x20203132
+
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
+
+#endif
diff --git a/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
new file mode 100644
index 0000000..15db1b3
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
@@ -0,0 +1,65 @@
+/*
+ * Ralink MT7621 specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef _MT7621_CPU_FEATURE_OVERRIDES_H
+#define _MT7621_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+
+#define cpu_has_prefetch 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 1
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 1
+#define cpu_has_dsp2 0
+#define cpu_has_mipsmt 1
+
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#define cpu_has_dc_aliases 0
+#define cpu_has_vtag_icache 0
+
+#define cpu_has_rixi 0
+#define cpu_has_tlbinv 0
+#define cpu_has_userlocal 1
+
+#endif /* _MT7621_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
index bd93014..4c9fba6 100644
--- a/arch/mips/include/asm/mach-ralink/ralink_regs.h
+++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
@@ -13,6 +13,23 @@
#ifndef _RALINK_REGS_H_
#define _RALINK_REGS_H_
+enum ralink_soc_type {
+ RALINK_UNKNOWN = 0,
+ RT2880_SOC,
+ RT3883_SOC,
+ RT305X_SOC_RT3050,
+ RT305X_SOC_RT3052,
+ RT305X_SOC_RT3350,
+ RT305X_SOC_RT3352,
+ RT305X_SOC_RT5350,
+ MT762X_SOC_MT7620A,
+ MT762X_SOC_MT7620N,
+ MT762X_SOC_MT7621AT,
+ MT762X_SOC_MT7628AN,
+ MT762X_SOC_MT7688,
+};
+extern enum ralink_soc_type ralink_soc;
+
extern __iomem void *rt_sysc_membase;
extern __iomem void *rt_memc_membase;
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
index 96f731b..2eea793 100644
--- a/arch/mips/include/asm/mach-ralink/rt305x.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -13,25 +13,16 @@
#ifndef _RT305X_REGS_H_
#define _RT305X_REGS_H_
-enum rt305x_soc_type {
- RT305X_SOC_UNKNOWN = 0,
- RT305X_SOC_RT3050,
- RT305X_SOC_RT3052,
- RT305X_SOC_RT3350,
- RT305X_SOC_RT3352,
- RT305X_SOC_RT5350,
-};
-
-extern enum rt305x_soc_type rt305x_soc;
+extern enum ralink_soc_type ralink_soc;
static inline int soc_is_rt3050(void)
{
- return rt305x_soc == RT305X_SOC_RT3050;
+ return ralink_soc == RT305X_SOC_RT3050;
}
static inline int soc_is_rt3052(void)
{
- return rt305x_soc == RT305X_SOC_RT3052;
+ return ralink_soc == RT305X_SOC_RT3052;
}
static inline int soc_is_rt305x(void)
@@ -41,17 +32,17 @@ static inline int soc_is_rt305x(void)
static inline int soc_is_rt3350(void)
{
- return rt305x_soc == RT305X_SOC_RT3350;
+ return ralink_soc == RT305X_SOC_RT3350;
}
static inline int soc_is_rt3352(void)
{
- return rt305x_soc == RT305X_SOC_RT3352;
+ return ralink_soc == RT305X_SOC_RT3352;
}
static inline int soc_is_rt5350(void)
{
- return rt305x_soc == RT305X_SOC_RT5350;
+ return ralink_soc == RT305X_SOC_RT5350;
}
#define RT305X_SYSC_BASE 0x10000000
diff --git a/arch/mips/include/asm/mach-xilfpga/irq.h b/arch/mips/include/asm/mach-xilfpga/irq.h
new file mode 100644
index 0000000..0132a5b9
--- /dev/null
+++ b/arch/mips/include/asm/mach-xilfpga/irq.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 __MIPS_ASM_MACH_XILFPGA_IRQ_H__
+#define __MIPS_ASM_MACH_XILFPGA_IRQ_H__
+
+#define NR_IRQS 32
+
+#include_next <irq.h>
+
+#endif /* __MIPS_ASM_MACH_XILFPGA_IRQ_H__ */
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 1f1927a..b196825 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -11,6 +11,7 @@
#ifndef __MIPS_ASM_MIPS_CM_H__
#define __MIPS_ASM_MIPS_CM_H__
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/types.h>
@@ -36,12 +37,12 @@ extern phys_addr_t __mips_cm_phys_base(void);
/*
* mips_cm_is64 - determine CM register width
*
- * The CM register width is processor and CM specific. A 64-bit processor
- * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit
- * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs
- * can be done either using regular 64-bit load/store instructions, or 32-bit
- * load/store instruction on 32-bit register pairs. We opt for using 64-bit
- * accesses on 64-bit CMs and kernels and 32-bit in any other case.
+ * The CM register width is determined by the version of the CM, with CM3
+ * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs.
+ * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs,
+ * or vice-versa. This variable indicates the width of the memory accesses
+ * that the kernel will perform to GCRs, which may differ from the actual
+ * width of the GCRs.
*
* It's set to 0 for 32-bit accesses and 1 for 64-bit accesses.
*/
@@ -125,7 +126,17 @@ static inline u32 read32_gcr_##name(void) \
\
static inline u64 read64_gcr_##name(void) \
{ \
- return __raw_readq(addr_gcr_##name()); \
+ void __iomem *addr = addr_gcr_##name(); \
+ u64 ret; \
+ \
+ if (mips_cm_is64) { \
+ ret = __raw_readq(addr); \
+ } else { \
+ ret = __raw_readl(addr); \
+ ret |= (u64)__raw_readl(addr + 0x4) << 32; \
+ } \
+ \
+ return ret; \
} \
\
static inline unsigned long read_gcr_##name(void) \
@@ -195,6 +206,8 @@ BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)
BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)
BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130)
BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150)
+BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300)
+BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308)
/* Core Local & Core Other register accessor functions */
BUILD_CM_Cx_RW(reset_release, 0x00)
@@ -230,6 +243,10 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
#define CM_GCR_BASE_CMDEFTGT_IOCU0 2
#define CM_GCR_BASE_CMDEFTGT_IOCU1 3
+/* GCR_RESET_EXT_BASE register fields */
+#define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31)
+#define CM_GCR_RESET_EXT_BASE_UEB BIT(30)
+
/* GCR_ACCESS register fields */
#define CM_GCR_ACCESS_ACCESSEN_SHF 0
#define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0)
@@ -245,11 +262,14 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
((minor) << CM_GCR_REV_MINOR_SHF))
#define CM_REV_CM2 CM_ENCODE_REV(6, 0)
+#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0)
#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
/* GCR_ERROR_CAUSE register fields */
#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27
#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27)
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58)
#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0
#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0)
@@ -321,6 +341,20 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0
#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0)
+/* GCR_L2_PFT_CONTROL register fields */
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12)
+#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8
+#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8)
+#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0
+#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0)
+
+/* GCR_L2_PFT_CONTROL_B register fields */
+#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8
+#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8)
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0)
+
/* GCR_Cx_COHERENCE register fields */
#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0
#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0)
@@ -329,11 +363,15 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10
#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10)
#define CM_GCR_Cx_CONFIG_PVPE_SHF 0
-#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x1ff) << 0)
+#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0)
/* GCR_Cx_OTHER register fields */
#define CM_GCR_Cx_OTHER_CORENUM_SHF 16
#define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16)
+#define CM3_GCR_Cx_OTHER_CORE_SHF 8
+#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8)
+#define CM3_GCR_Cx_OTHER_VP_SHF 0
+#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0)
/* GCR_Cx_RESET_BASE register fields */
#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12
@@ -444,4 +482,32 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu)
return (core * mips_cm_max_vp_width()) + vp;
}
+#ifdef CONFIG_MIPS_CM
+
+/**
+ * mips_cm_lock_other - lock access to another core
+ * @core: the other core to be accessed
+ * @vp: the VP within the other core to be accessed
+ *
+ * Call before operating upon a core via the 'other' register region in
+ * order to prevent the region being moved during access. Must be followed
+ * by a call to mips_cm_unlock_other.
+ */
+extern void mips_cm_lock_other(unsigned int core, unsigned int vp);
+
+/**
+ * mips_cm_unlock_other - unlock access to another core
+ *
+ * Call after operating upon another core via the 'other' register region.
+ * Must be called after mips_cm_lock_other.
+ */
+extern void mips_cm_unlock_other(void);
+
+#else /* !CONFIG_MIPS_CM */
+
+static inline void mips_cm_lock_other(unsigned int core) { }
+static inline void mips_cm_unlock_other(void) { }
+
+#endif /* !CONFIG_MIPS_CM */
+
#endif /* __MIPS_ASM_MIPS_CM_H__ */
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index f386f32..e090352 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -149,7 +149,8 @@ BUILD_CPC_Cx_RW(other, 0x10)
* core: the other core to be accessed
*
* Call before operating upon a core via the 'other' register region in
- * order to prevent the region being moved during access. Must be followed
+ * order to prevent the region being moved during access. Must be called
+ * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed
* by a call to mips_cpc_unlock_other.
*/
extern void mips_cpc_lock_other(unsigned int core);
diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h
index 4b89f28..1f6ea83 100644
--- a/arch/mips/include/asm/mips-r2-to-r6-emul.h
+++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h
@@ -52,7 +52,7 @@ do { \
__this_cpu_inc(mipsr2emustats.M); \
err = __get_user(nir, (u32 __user *)regs->cp0_epc); \
if (!err) { \
- if (nir == BREAK_MATH) \
+ if (nir == BREAK_MATH(0)) \
__this_cpu_inc(mipsr2bdemustats.M); \
} \
preempt_enable(); \
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index c64781c..3ad19ad 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -50,7 +50,9 @@
#define CP0_PAGEMASK $5
#define CP0_WIRED $6
#define CP0_INFO $7
+#define CP0_HWRENA $7, 0
#define CP0_BADVADDR $8
+#define CP0_BADINSTR $8, 1
#define CP0_COUNT $9
#define CP0_ENTRYHI $10
#define CP0_COMPARE $11
@@ -58,7 +60,11 @@
#define CP0_CAUSE $13
#define CP0_EPC $14
#define CP0_PRID $15
+#define CP0_EBASE $15, 1
+#define CP0_CMGCRBASE $15, 3
#define CP0_CONFIG $16
+#define CP0_CONFIG3 $16, 3
+#define CP0_CONFIG5 $16, 5
#define CP0_LLADDR $17
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
@@ -126,15 +132,9 @@
#define R3K_ENTRYLO_N (_ULCAST_(1) << 11)
/* MIPS32/64 EntryLo bit definitions */
-#ifdef CONFIG_64BIT
-/* as read by dmfc0 */
-#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62)
-#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63)
-#else
-/* as read by mfc0 */
-#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30)
-#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31)
-#endif
+#define MIPS_ENTRYLO_PFN_SHIFT 6
+#define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2))
+#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1))
/*
* Values for PageMask register
@@ -394,6 +394,8 @@
#define CAUSEF_IV (_ULCAST_(1) << 23)
#define CAUSEB_PCI 26
#define CAUSEF_PCI (_ULCAST_(1) << 26)
+#define CAUSEB_DC 27
+#define CAUSEF_DC (_ULCAST_(1) << 27)
#define CAUSEB_CE 28
#define CAUSEF_CE (_ULCAST_(3) << 28)
#define CAUSEB_TI 30
@@ -402,6 +404,38 @@
#define CAUSEF_BD (_ULCAST_(1) << 31)
/*
+ * Cause.ExcCode trap codes.
+ */
+#define EXCCODE_INT 0 /* Interrupt pending */
+#define EXCCODE_MOD 1 /* TLB modified fault */
+#define EXCCODE_TLBL 2 /* TLB miss on load or ifetch */
+#define EXCCODE_TLBS 3 /* TLB miss on a store */
+#define EXCCODE_ADEL 4 /* Address error on a load or ifetch */
+#define EXCCODE_ADES 5 /* Address error on a store */
+#define EXCCODE_IBE 6 /* Bus error on an ifetch */
+#define EXCCODE_DBE 7 /* Bus error on a load or store */
+#define EXCCODE_SYS 8 /* System call */
+#define EXCCODE_BP 9 /* Breakpoint */
+#define EXCCODE_RI 10 /* Reserved instruction exception */
+#define EXCCODE_CPU 11 /* Coprocessor unusable */
+#define EXCCODE_OV 12 /* Arithmetic overflow */
+#define EXCCODE_TR 13 /* Trap instruction */
+#define EXCCODE_MSAFPE 14 /* MSA floating point exception */
+#define EXCCODE_FPE 15 /* Floating point exception */
+#define EXCCODE_TLBRI 19 /* TLB Read-Inhibit exception */
+#define EXCCODE_TLBXI 20 /* TLB Execution-Inhibit exception */
+#define EXCCODE_MSADIS 21 /* MSA disabled exception */
+#define EXCCODE_MDMX 22 /* MDMX unusable exception */
+#define EXCCODE_WATCH 23 /* Watch address reference */
+#define EXCCODE_MCHECK 24 /* Machine check */
+#define EXCCODE_THREAD 25 /* Thread exceptions (MT) */
+#define EXCCODE_DSPDIS 26 /* DSP disabled exception */
+#define EXCCODE_GE 27 /* Virtualized guest exception (VZ) */
+
+/* Implementation specific trap codes used by MIPS cores */
+#define MIPS_EXCCODE_TLBPAR 16 /* TLB parity error exception */
+
+/*
* Bits in the coprocessor 0 config register.
*/
/* Generic bits. */
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 774bb45..19e139c 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -275,6 +275,11 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
}
+static inline void cvmx_writeq_csr(void __iomem *csr_addr, uint64_t val)
+{
+ cvmx_write_csr((__force uint64_t)csr_addr, val);
+}
+
static inline void cvmx_write_io(uint64_t io_addr, uint64_t val)
{
cvmx_write64(io_addr, val);
@@ -287,6 +292,10 @@ static inline uint64_t cvmx_read_csr(uint64_t csr_addr)
return val;
}
+static inline uint64_t cvmx_readq_csr(void __iomem *csr_addr)
+{
+ return cvmx_read_csr((__force uint64_t) csr_addr);
+}
static inline void cvmx_send_single(uint64_t data)
{
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
index 8ebd3f57..3ed10a8 100644
--- a/arch/mips/include/asm/octeon/octeon-feature.h
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -128,7 +128,8 @@ static inline int octeon_has_feature(enum octeon_feature feature)
case OCTEON_FEATURE_PCIE:
return OCTEON_IS_MODEL(OCTEON_CN56XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX)
- || OCTEON_IS_MODEL(OCTEON_CN6XXX);
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX)
+ || OCTEON_IS_MODEL(OCTEON_CN7XXX);
case OCTEON_FEATURE_SRIO:
return OCTEON_IS_MODEL(OCTEON_CN63XX)
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 89dd7fe..21ed715 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -200,8 +200,9 @@ static inline int pfn_valid(unsigned long pfn)
{
/* avoid <linux/mm.h> include hell */
extern unsigned long max_mapnr;
+ unsigned long pfn_offset = ARCH_PFN_OFFSET;
- return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr;
+ return pfn >= pfn_offset && pfn < max_mapnr;
}
#elif defined(CONFIG_SPARSEMEM)
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 98c31e5..8c16fb7 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -102,7 +102,6 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <asm/io.h>
-#include <asm-generic/pci-bridge.h>
struct pci_dev;
@@ -125,9 +124,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
#endif /* __KERNEL__ */
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
/* Do platform specific device initialization at pci_enable_device() time */
extern int pcibios_plat_dev_init(struct pci_dev *dev);
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index ff7ad91..97b3138 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -131,14 +131,12 @@
/* Huge TLB page */
#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
-#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
-#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
#endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
/* XI - page cannot be executed */
-#ifdef _PAGE_SPLITTING_SHIFT
-#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#ifdef _PAGE_HUGE_SHIFT
+#define _PAGE_NO_EXEC_SHIFT (_PAGE_HUGE_SHIFT + 1)
#else
#define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
#endif
@@ -153,8 +151,8 @@
#if defined(_PAGE_NO_READ_SHIFT)
#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
-#elif defined(_PAGE_SPLITTING_SHIFT)
-#define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#elif defined(_PAGE_HUGE_SHIFT)
+#define _PAGE_GLOBAL_SHIFT (_PAGE_HUGE_SHIFT + 1)
#else
#define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
#endif
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 8957f15..9a4fe01 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -353,7 +353,7 @@ static inline pte_t pte_mkdirty(pte_t pte)
static inline pte_t pte_mkyoung(pte_t pte)
{
pte_val(pte) |= _PAGE_ACCESSED;
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (!(pte_val(pte) & _PAGE_NO_READ))
pte_val(pte) |= _PAGE_SILENT_READ;
else
@@ -482,27 +482,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
return pmd;
}
-static inline int pmd_trans_splitting(pmd_t pmd)
-{
- return !!(pmd_val(pmd) & _PAGE_SPLITTING);
-}
-
-static inline pmd_t pmd_mksplitting(pmd_t pmd)
-{
- pmd_val(pmd) |= _PAGE_SPLITTING;
-
- return pmd;
-}
-
extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd);
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-/* Extern to avoid header file madness */
-extern void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long address,
- pmd_t *pmdp);
-
#define __HAVE_ARCH_PMD_WRITE
static inline int pmd_write(pmd_t pmd)
{
@@ -560,7 +542,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
{
pmd_val(pmd) |= _PAGE_ACCESSED;
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (!(pmd_val(pmd) & _PAGE_NO_READ))
pmd_val(pmd) |= _PAGE_SILENT_READ;
else
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 59ee6dc..041153f 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -36,12 +36,6 @@ extern unsigned int vced_count, vcei_count;
*/
#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
-/*
- * A special page (the vdso) is mapped into all processes at the very
- * top of the virtual memory space.
- */
-#define SPECIAL_PAGES_SIZE PAGE_SIZE
-
#ifdef CONFIG_32BIT
#ifdef CONFIG_KVM_GUEST
/* User space process size is limited to 1GB in KVM Guest Mode */
@@ -51,7 +45,7 @@ extern unsigned int vced_count, vcei_count;
* User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
-#define TASK_SIZE 0x7fff8000UL
+#define TASK_SIZE 0x80000000UL
#endif
#define STACK_TOP_MAX TASK_SIZE
@@ -80,7 +74,7 @@ extern unsigned int vced_count, vcei_count;
#endif
-#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+#define STACK_TOP (TASK_SIZE & PAGE_MASK)
/*
* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index 6ba1fb8..db7c322 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -44,8 +44,9 @@ static inline void plat_smp_setup(void)
mp_ops->smp_setup();
}
-extern void gic_send_ipi_single(int cpu, unsigned int action);
-extern void gic_send_ipi_mask(const struct cpumask *mask, unsigned int action);
+extern void mips_smp_send_ipi_single(int cpu, unsigned int action);
+extern void mips_smp_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action);
#else /* !CONFIG_SMP */
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index a71da57..eebf395 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -289,7 +289,7 @@
.set reorder
.set noat
mfc0 a0, CP0_STATUS
- li v1, 0xff00
+ li v1, ST0_CU1 | ST0_IM
ori a0, STATMASK
xori a0, STATMASK
mtc0 a0, CP0_STATUS
@@ -330,7 +330,7 @@
ori a0, STATMASK
xori a0, STATMASK
mtc0 a0, CP0_STATUS
- li v1, 0xff00
+ li v1, ST0_CU1 | ST0_FR | ST0_IM
and a0, v1
LONG_L v0, PT_STATUS(sp)
nor v1, $0, v1
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
index 6499d93..47bc45a 100644
--- a/arch/mips/include/asm/syscall.h
+++ b/arch/mips/include/asm/syscall.h
@@ -101,10 +101,8 @@ static inline void syscall_get_arguments(struct task_struct *task,
/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
if ((config_enabled(CONFIG_32BIT) ||
test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
- (regs->regs[2] == __NR_syscall)) {
+ (regs->regs[2] == __NR_syscall))
i++;
- n++;
- }
while (n--)
ret |= mips_get_syscall_arg(args++, task, regs, i++);
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 5305d69..095ecaf 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -599,7 +599,7 @@ extern void __put_user_unknown(void);
* On error, the variable @x is set to zero.
*/
#define __get_user_unaligned(x,ptr) \
- __get_user__unalignednocheck((x),(ptr),sizeof(*(ptr)))
+ __get_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
/*
* Yuck. We need two variants, one for 64bit operation and one
@@ -620,8 +620,8 @@ extern void __get_user_unaligned_unknown(void);
do { \
switch (size) { \
case 1: __get_data_asm(val, "lb", ptr); break; \
- case 2: __get_user_unaligned_asm(val, "ulh", ptr); break; \
- case 4: __get_user_unaligned_asm(val, "ulw", ptr); break; \
+ case 2: __get_data_unaligned_asm(val, "ulh", ptr); break; \
+ case 4: __get_data_unaligned_asm(val, "ulw", ptr); break; \
case 8: __GET_USER_UNALIGNED_DW(val, ptr); break; \
default: __get_user_unaligned_unknown(); break; \
} \
@@ -1122,9 +1122,15 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
__cu_to = (to); \
__cu_from = (from); \
__cu_len = (n); \
- might_fault(); \
- __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
- __cu_len); \
+ if (eva_kernel_access()) { \
+ __cu_len = __invoke_copy_from_kernel(__cu_to, \
+ __cu_from, \
+ __cu_len); \
+ } else { \
+ might_fault(); \
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
+ __cu_len); \
+ } \
__cu_len; \
})
@@ -1229,16 +1235,28 @@ __clear_user(void __user *addr, __kernel_size_t size)
{
__kernel_size_t res;
- might_fault();
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, $0\n\t"
- "move\t$6, %2\n\t"
- __MODULE_JAL(__bzero)
- "move\t%0, $6"
- : "=r" (res)
- : "r" (addr), "r" (size)
- : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+ if (eva_kernel_access()) {
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, $0\n\t"
+ "move\t$6, %2\n\t"
+ __MODULE_JAL(__bzero_kernel)
+ "move\t%0, $6"
+ : "=r" (res)
+ : "r" (addr), "r" (size)
+ : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+ } else {
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, $0\n\t"
+ "move\t$6, %2\n\t"
+ __MODULE_JAL(__bzero)
+ "move\t%0, $6"
+ : "=r" (res)
+ : "r" (addr), "r" (size)
+ : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+ }
return res;
}
@@ -1384,7 +1402,7 @@ static inline long strlen_user(const char __user *s)
might_fault();
__asm__ __volatile__(
"move\t$4, %1\n\t"
- __MODULE_JAL(__strlen_kernel_asm)
+ __MODULE_JAL(__strlen_user_asm)
"move\t%0, $2"
: "=r" (res)
: "r" (s)
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
index cca56aa..8f4ca5d 100644
--- a/arch/mips/include/asm/vdso.h
+++ b/arch/mips/include/asm/vdso.h
@@ -1,29 +1,136 @@
/*
- * 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) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
*
- * Copyright (C) 2009 Cavium Networks
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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_VDSO_H
#define __ASM_VDSO_H
-#include <linux/types.h>
+#include <linux/mm_types.h>
+#include <asm/barrier.h>
-#ifdef CONFIG_32BIT
-struct mips_vdso {
- u32 signal_trampoline[2];
- u32 rt_signal_trampoline[2];
+/**
+ * struct mips_vdso_image - Details of a VDSO image.
+ * @data: Pointer to VDSO image data (page-aligned).
+ * @size: Size of the VDSO image data (page-aligned).
+ * @off_sigreturn: Offset of the sigreturn() trampoline.
+ * @off_rt_sigreturn: Offset of the rt_sigreturn() trampoline.
+ * @mapping: Special mapping structure.
+ *
+ * This structure contains details of a VDSO image, including the image data
+ * and offsets of certain symbols required by the kernel. It is generated as
+ * part of the VDSO build process, aside from the mapping page array, which is
+ * populated at runtime.
+ */
+struct mips_vdso_image {
+ void *data;
+ unsigned long size;
+
+ unsigned long off_sigreturn;
+ unsigned long off_rt_sigreturn;
+
+ struct vm_special_mapping mapping;
};
-#else /* !CONFIG_32BIT */
-struct mips_vdso {
- u32 o32_signal_trampoline[2];
- u32 o32_rt_signal_trampoline[2];
- u32 rt_signal_trampoline[2];
- u32 n32_rt_signal_trampoline[2];
+
+/*
+ * The following structures are auto-generated as part of the build for each
+ * ABI by genvdso, see arch/mips/vdso/Makefile.
+ */
+
+extern struct mips_vdso_image vdso_image;
+
+#ifdef CONFIG_MIPS32_O32
+extern struct mips_vdso_image vdso_image_o32;
+#endif
+
+#ifdef CONFIG_MIPS32_N32
+extern struct mips_vdso_image vdso_image_n32;
+#endif
+
+/**
+ * union mips_vdso_data - Data provided by the kernel for the VDSO.
+ * @xtime_sec: Current real time (seconds part).
+ * @xtime_nsec: Current real time (nanoseconds part, shifted).
+ * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
+ * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
+ * @seq_count: Counter to synchronise updates (odd = updating).
+ * @cs_shift: Clocksource shift value.
+ * @clock_mode: Clocksource to use for time functions.
+ * @cs_mult: Clocksource multiplier value.
+ * @cs_cycle_last: Clock cycle value at last update.
+ * @cs_mask: Clocksource mask value.
+ * @tz_minuteswest: Minutes west of Greenwich (from timezone).
+ * @tz_dsttime: Type of DST correction (from timezone).
+ *
+ * This structure contains data needed by functions within the VDSO. It is
+ * populated by the kernel and mapped read-only into user memory. The time
+ * fields are mirrors of internal data from the timekeeping infrastructure.
+ *
+ * Note: Care should be taken when modifying as the layout must remain the same
+ * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
+ */
+union mips_vdso_data {
+ struct {
+ u64 xtime_sec;
+ u64 xtime_nsec;
+ u32 wall_to_mono_sec;
+ u32 wall_to_mono_nsec;
+ u32 seq_count;
+ u32 cs_shift;
+ u8 clock_mode;
+ u32 cs_mult;
+ u64 cs_cycle_last;
+ u64 cs_mask;
+ s32 tz_minuteswest;
+ s32 tz_dsttime;
+ };
+
+ u8 page[PAGE_SIZE];
};
-#endif /* CONFIG_32BIT */
+
+static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
+{
+ u32 seq;
+
+ while (true) {
+ seq = ACCESS_ONCE(data->seq_count);
+ if (likely(!(seq & 1))) {
+ /* Paired with smp_wmb() in vdso_data_write_*(). */
+ smp_rmb();
+ return seq;
+ }
+
+ cpu_relax();
+ }
+}
+
+static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
+ u32 start_seq)
+{
+ /* Paired with smp_wmb() in vdso_data_write_*(). */
+ smp_rmb();
+ return unlikely(data->seq_count != start_seq);
+}
+
+static inline void vdso_data_write_begin(union mips_vdso_data *data)
+{
+ ++data->seq_count;
+
+ /* Ensure sequence update is written before other data page values. */
+ smp_wmb();
+}
+
+static inline void vdso_data_write_end(union mips_vdso_data *data)
+{
+ /* Ensure data values are written before updating sequence again. */
+ smp_wmb();
+ ++data->seq_count;
+}
#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/include/uapi/asm/Kbuild b/arch/mips/include/uapi/asm/Kbuild
index 96fe739..f2cf414 100644
--- a/arch/mips/include/uapi/asm/Kbuild
+++ b/arch/mips/include/uapi/asm/Kbuild
@@ -1,9 +1,9 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-generic-y += auxvec.h
generic-y += ipcbuf.h
+header-y += auxvec.h
header-y += bitfield.h
header-y += bitsperlong.h
header-y += break.h
diff --git a/arch/mips/include/uapi/asm/auxvec.h b/arch/mips/include/uapi/asm/auxvec.h
new file mode 100644
index 0000000..c9c7195
--- /dev/null
+++ b/arch/mips/include/uapi/asm/auxvec.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* Location of VDSO image. */
+#define AT_SYSINFO_EHDR 33
+
+#endif /* __ASM_AUXVEC_H */
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h
index 9b44d5a..ddea53e 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -116,7 +116,8 @@ enum cop_op {
dmtc_op = 0x05, ctc_op = 0x06,
mthc0_op = 0x06, mthc_op = 0x07,
bc_op = 0x08, bc1eqz_op = 0x09,
- bc1nez_op = 0x0d, cop_op = 0x10,
+ mfmc0_op = 0x0b, bc1nez_op = 0x0d,
+ wrpgpr_op = 0x0e, cop_op = 0x10,
copm_op = 0x18
};
@@ -529,7 +530,7 @@ enum MIPS6e_i8_func {
};
/*
- * (microMIPS & MIPS16e) NOP instruction.
+ * (microMIPS) NOP instruction.
*/
#define MM_NOP16 0x0c00
@@ -679,7 +680,7 @@ struct fp0_format { /* FPU multiply and add format (MIPS32) */
;))))))
};
-struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */
+struct mm_fp0_format { /* FPU multiply and add format (microMIPS) */
__BITFIELD_FIELD(unsigned int opcode : 6,
__BITFIELD_FIELD(unsigned int ft : 5,
__BITFIELD_FIELD(unsigned int fs : 5,
@@ -799,6 +800,13 @@ struct mm_x_format { /* Scaled indexed load format (microMIPS) */
;)))))
};
+struct mm_a_format { /* ADDIUPC format (microMIPS) */
+ __BITFIELD_FIELD(unsigned int opcode : 6,
+ __BITFIELD_FIELD(unsigned int rs : 3,
+ __BITFIELD_FIELD(signed int simmediate : 23,
+ ;)))
+};
+
/*
* microMIPS instruction formats (16-bit length)
*/
@@ -940,6 +948,7 @@ union mips_instruction {
struct mm_i_format mm_i_format;
struct mm_m_format mm_m_format;
struct mm_x_format mm_x_format;
+ struct mm_a_format mm_a_format;
struct mm_b0_format mm_b0_format;
struct mm_b1_format mm_b1_format;
struct mm16_m_format mm16_m_format ;
diff --git a/arch/mips/include/uapi/asm/mman.h b/arch/mips/include/uapi/asm/mman.h
index cfcb876..ccdcfcb 100644
--- a/arch/mips/include/uapi/asm/mman.h
+++ b/arch/mips/include/uapi/asm/mman.h
@@ -61,6 +61,12 @@
*/
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
+#define MCL_ONFAULT 4 /* lock all pages that are faulted in */
+
+/*
+ * Flags for mlock
+ */
+#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */
#define MADV_NORMAL 0 /* no further special treatment */
#define MADV_RANDOM 1 /* expect random page references */
@@ -69,6 +75,7 @@
#define MADV_DONTNEED 4 /* don't need these pages */
/* common parameters: try to keep these consistent across architectures */
+#define MADV_FREE 8 /* free pages only if memory pressure */
#define MADV_REMOVE 9 /* remove these pages & resources */
#define MADV_DONTFORK 10 /* don't inherit across fork */
#define MADV_DOFORK 11 /* do inherit across fork */
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index dec3c85..2027240a 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -103,4 +103,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h
index cfabadb..3129795 100644
--- a/arch/mips/include/uapi/asm/unistd.h
+++ b/arch/mips/include/uapi/asm/unistd.h
@@ -379,16 +379,18 @@
#define __NR_execveat (__NR_Linux + 356)
#define __NR_userfaultfd (__NR_Linux + 357)
#define __NR_membarrier (__NR_Linux + 358)
+#define __NR_mlock2 (__NR_Linux + 359)
+#define __NR_copy_file_range (__NR_Linux + 360)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 358
+#define __NR_Linux_syscalls 360
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 358
+#define __NR_O32_Linux_syscalls 360
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -715,16 +717,18 @@
#define __NR_execveat (__NR_Linux + 316)
#define __NR_userfaultfd (__NR_Linux + 317)
#define __NR_membarrier (__NR_Linux + 318)
+#define __NR_mlock2 (__NR_Linux + 319)
+#define __NR_copy_file_range (__NR_Linux + 320)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 318
+#define __NR_Linux_syscalls 320
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 318
+#define __NR_64_Linux_syscalls 320
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -1055,15 +1059,17 @@
#define __NR_execveat (__NR_Linux + 320)
#define __NR_userfaultfd (__NR_Linux + 321)
#define __NR_membarrier (__NR_Linux + 322)
+#define __NR_mlock2 (__NR_Linux + 323)
+#define __NR_copy_file_range (__NR_Linux + 324)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 322
+#define __NR_Linux_syscalls 324
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 322
+#define __NR_N32_Linux_syscalls 324
#endif /* _UAPI_ASM_UNISTD_H */
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 459cb01..934b15b 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -25,6 +25,7 @@
#include <linux/power_supply.h>
#include <linux/power/jz4740-battery.h>
#include <linux/power/gpio-charger.h>
+#include <linux/pwm.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/jz4740_fb.h>
@@ -34,8 +35,6 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
-#include <linux/leds_pwm.h>
-
#include <asm/mach-jz4740/platform.h>
#include "clock.h"
@@ -399,13 +398,15 @@ static struct platform_device avt2_usb_regulator_device = {
}
};
+static struct pwm_lookup qi_lb60_pwm_lookup[] = {
+ PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0,
+ PWM_POLARITY_NORMAL),
+};
+
/* beeper */
static struct platform_device qi_lb60_pwm_beeper = {
.name = "pwm-beeper",
.id = -1,
- .dev = {
- .platform_data = (void *)4,
- },
};
/* charger */
@@ -491,6 +492,8 @@ static int __init qi_lb60_init_platform_devices(void)
platform_device_register(&jz4740_usb_ohci_device);
}
+ pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup));
+
return platform_add_devices(jz_platform_devices,
ARRAY_SIZE(jz_platform_devices));
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 8c6d76c..b765773 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -18,6 +18,8 @@
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/gpio/driver.h>
+/* FIXME: needed for gpio_request(), try to remove consumer API from driver */
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -91,9 +93,9 @@ static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
return &jz4740_gpio_chips[gpio >> 5];
}
-static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
+static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gc)
{
- return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
+ return gpiochip_get_data(gc);
}
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
@@ -234,7 +236,7 @@ static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
{
- struct jz_gpio_chip *jz_gpio = gpio_chip_to_jz_gpio_chip(chip);
+ struct jz_gpio_chip *jz_gpio = gpiochip_get_data(chip);
return jz_gpio->irq_base + gpio;
}
@@ -270,7 +272,7 @@ uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
}
EXPORT_SYMBOL(jz_gpio_port_get_value);
-#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
+#define IRQ_TO_BIT(irq) BIT((irq - JZ4740_IRQ_GPIO(0)) & 0x1f)
static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
{
@@ -449,7 +451,7 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
- gpiochip_add(&chip->gpio_chip);
+ gpiochip_add_data(&chip->gpio_chip, chip);
}
static int __init jz4740_gpio_init(void)
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d982be1..b0988fd 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -51,7 +51,7 @@ obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
obj-$(CONFIG_MIPS_CPS) += smp-cps.o cps-vec.o
-obj-$(CONFIG_MIPS_GIC_IPI) += smp-gic.o
+obj-$(CONFIG_MIPS_CPS_NS16550) += cps-vec-ns16550.o
obj-$(CONFIG_MIPS_SPRAM) += spram.o
obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
index 1188e00..1b992c6 100644
--- a/arch/mips/kernel/binfmt_elfn32.c
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -35,7 +35,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
int __res = 1; \
struct elfhdr *__h = (hdr); \
\
- if (__h->e_machine != EM_MIPS) \
+ if (!mips_elf_check_machine(__h)) \
__res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index 9287678..abd3aff 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -47,7 +47,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
int __res = 1; \
struct elfhdr *__h = (hdr); \
\
- if (__h->e_machine != EM_MIPS) \
+ if (!mips_elf_check_machine(__h)) \
__res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \
diff --git a/arch/mips/kernel/cps-vec-ns16550.S b/arch/mips/kernel/cps-vec-ns16550.S
new file mode 100644
index 0000000..6d246ad
--- /dev/null
+++ b/arch/mips/kernel/cps-vec-ns16550.S
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/addrspace.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <linux/serial_reg.h>
+
+#define UART_TX_OFS (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT)
+#define UART_LSR_OFS (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT)
+
+/**
+ * _mips_cps_putc() - write a character to the UART
+ * @a0: ASCII character to write
+ * @t9: UART base address
+ */
+LEAF(_mips_cps_putc)
+1: lw t0, UART_LSR_OFS(t9)
+ andi t0, t0, UART_LSR_TEMT
+ beqz t0, 1b
+ sb a0, UART_TX_OFS(t9)
+ jr ra
+ END(_mips_cps_putc)
+
+/**
+ * _mips_cps_puts() - write a string to the UART
+ * @a0: pointer to NULL-terminated ASCII string
+ * @t9: UART base address
+ *
+ * Write a null-terminated ASCII string to the UART.
+ */
+NESTED(_mips_cps_puts, 0, ra)
+ move s7, ra
+ move s6, a0
+
+1: lb a0, 0(s6)
+ beqz a0, 2f
+ jal _mips_cps_putc
+ PTR_ADDIU s6, s6, 1
+ b 1b
+
+2: jr s7
+ END(_mips_cps_puts)
+
+/**
+ * _mips_cps_putx4 - write a 4b hex value to the UART
+ * @a0: the 4b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a single hexadecimal character to the UART.
+ */
+NESTED(_mips_cps_putx4, 0, ra)
+ andi a0, a0, 0xf
+ li t0, '0'
+ blt a0, 10, 1f
+ li t0, 'a'
+ addiu a0, a0, -10
+1: addu a0, a0, t0
+ b _mips_cps_putc
+ END(_mips_cps_putx4)
+
+/**
+ * _mips_cps_putx8 - write an 8b hex value to the UART
+ * @a0: the 8b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx8, 0, ra)
+ move s3, ra
+ move s2, a0
+ srl a0, a0, 4
+ jal _mips_cps_putx4
+ move a0, s2
+ move ra, s3
+ b _mips_cps_putx4
+ END(_mips_cps_putx8)
+
+/**
+ * _mips_cps_putx16 - write a 16b hex value to the UART
+ * @a0: the 16b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx16, 0, ra)
+ move s5, ra
+ move s4, a0
+ srl a0, a0, 8
+ jal _mips_cps_putx8
+ move a0, s4
+ move ra, s5
+ b _mips_cps_putx8
+ END(_mips_cps_putx16)
+
+/**
+ * _mips_cps_putx32 - write a 32b hex value to the UART
+ * @a0: the 32b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx32, 0, ra)
+ move s7, ra
+ move s6, a0
+ srl a0, a0, 16
+ jal _mips_cps_putx16
+ move a0, s6
+ move ra, s7
+ b _mips_cps_putx16
+ END(_mips_cps_putx32)
+
+#ifdef CONFIG_64BIT
+
+/**
+ * _mips_cps_putx64 - write a 64b hex value to the UART
+ * @a0: the 64b value to write to the UART
+ * @t9: UART base address
+ *
+ * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART.
+ */
+NESTED(_mips_cps_putx64, 0, ra)
+ move sp, ra
+ move s8, a0
+ dsrl32 a0, a0, 0
+ jal _mips_cps_putx32
+ move a0, s8
+ move ra, sp
+ b _mips_cps_putx32
+ END(_mips_cps_putx64)
+
+#define _mips_cps_putxlong _mips_cps_putx64
+
+#else /* !CONFIG_64BIT */
+
+#define _mips_cps_putxlong _mips_cps_putx32
+
+#endif /* !CONFIG_64BIT */
+
+/**
+ * mips_cps_bev_dump() - dump relevant exception state to UART
+ * @a0: pointer to NULL-terminated ASCII string naming the exception
+ *
+ * Write information that may be useful in debugging an exception to the
+ * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception
+ * will only be run if something goes horribly wrong very early during
+ * the bringup of a core and it is very likely to be unsafe to perform
+ * memory accesses at that point (cache state indeterminate, EVA may not
+ * be configured, coherence may be disabled) let alone have a stack,
+ * this is all written in assembly using only registers & unmapped
+ * uncached access to the UART registers.
+ */
+LEAF(mips_cps_bev_dump)
+ move s0, ra
+ move s1, a0
+
+ li t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE)
+
+ PTR_LA a0, str_newline
+ jal _mips_cps_puts
+ PTR_LA a0, str_bev
+ jal _mips_cps_puts
+ move a0, s1
+ jal _mips_cps_puts
+ PTR_LA a0, str_newline
+ jal _mips_cps_puts
+ PTR_LA a0, str_newline
+ jal _mips_cps_puts
+
+#define DUMP_COP0_REG(reg, name, sz, _mfc0) \
+ PTR_LA a0, 8f; \
+ jal _mips_cps_puts; \
+ _mfc0 a0, reg; \
+ jal _mips_cps_putx##sz; \
+ PTR_LA a0, str_newline; \
+ jal _mips_cps_puts; \
+ TEXT(name)
+
+ DUMP_COP0_REG(CP0_CAUSE, "Cause: 0x", 32, mfc0)
+ DUMP_COP0_REG(CP0_STATUS, "Status: 0x", 32, mfc0)
+ DUMP_COP0_REG(CP0_EBASE, "EBase: 0x", long, MFC0)
+ DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0)
+ DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0)
+
+ PTR_LA a0, str_newline
+ jal _mips_cps_puts
+ jr s0
+ END(mips_cps_bev_dump)
+
+.pushsection .data
+str_bev: .asciiz "BEV Exception: "
+str_newline: .asciiz "\r\n"
+.popsection
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index 209ded1..ac81edd 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -25,14 +25,32 @@
.set noreorder
+#ifdef CONFIG_64BIT
+# define STATUS_BITDEPS ST0_KX
+#else
+# define STATUS_BITDEPS 0
+#endif
+
+#ifdef CONFIG_MIPS_CPS_NS16550
+
+#define DUMP_EXCEP(name) \
+ PTR_LA a0, 8f; \
+ jal mips_cps_bev_dump; \
+ nop; \
+ TEXT(name)
+
+#else /* !CONFIG_MIPS_CPS_NS16550 */
+
+#define DUMP_EXCEP(name)
+
+#endif /* !CONFIG_MIPS_CPS_NS16550 */
+
/*
* Set dest to non-zero if the core supports the MT ASE, else zero. If
* MT is not supported then branch to nomt.
*/
.macro has_mt dest, nomt
- mfc0 \dest, CP0_CONFIG
- bgez \dest, \nomt
- mfc0 \dest, CP0_CONFIG, 1
+ mfc0 \dest, CP0_CONFIG, 1
bgez \dest, \nomt
mfc0 \dest, CP0_CONFIG, 2
bgez \dest, \nomt
@@ -47,11 +65,9 @@
LEAF(mips_cps_core_entry)
/*
- * These first 12 bytes will be patched by cps_smp_setup to load the
- * base address of the CM GCRs into register v1 and the CCA to use into
- * register s0.
+ * These first 4 bytes will be patched by cps_smp_setup to load the
+ * CCA to use into register s0.
*/
- .quad 0
.word 0
/* Check whether we're here due to an NMI */
@@ -71,7 +87,7 @@ not_nmi:
mtc0 t0, CP0_CAUSE
/* Setup Status */
- li t0, ST0_CU1 | ST0_CU0
+ li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS
mtc0 t0, CP0_STATUS
/*
@@ -151,6 +167,12 @@ dcache_done:
mtc0 t0, CP0_CONFIG
ehb
+ /* Calculate an uncached address for the CM GCRs */
+ MFC0 v1, CP0_CMGCRBASE
+ PTR_SLL v1, v1, 4
+ PTR_LI t0, UNCAC_BASE
+ PTR_ADDU v1, v1, t0
+
/* Enter the coherent domain */
li t0, 0xff
sw t0, GCR_CL_COHERENCE_OFS(v1)
@@ -188,36 +210,42 @@ dcache_done:
.org 0x200
LEAF(excep_tlbfill)
+ DUMP_EXCEP("TLB Fill")
b .
nop
END(excep_tlbfill)
.org 0x280
LEAF(excep_xtlbfill)
+ DUMP_EXCEP("XTLB Fill")
b .
nop
END(excep_xtlbfill)
.org 0x300
LEAF(excep_cache)
+ DUMP_EXCEP("Cache")
b .
nop
END(excep_cache)
.org 0x380
LEAF(excep_genex)
+ DUMP_EXCEP("General")
b .
nop
END(excep_genex)
.org 0x400
LEAF(excep_intex)
+ DUMP_EXCEP("Interrupt")
b .
nop
END(excep_intex)
.org 0x480
LEAF(excep_ejtag)
+ DUMP_EXCEP("EJTAG")
PTR_LA k0, ejtag_debug_handler
jr k0
nop
@@ -229,7 +257,6 @@ LEAF(mips_cps_core_init)
has_mt t0, 3f
.set push
- .set mips64r2
.set mt
/* Only allow 1 TC per VPE to execute... */
@@ -348,7 +375,6 @@ LEAF(mips_cps_boot_vpes)
nop
.set push
- .set mips64r2
.set mt
1: /* Enter VPE configuration state */
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index 09f4034..6392dbe 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -190,7 +190,7 @@ static inline void check_daddi(void)
printk("Checking for the daddi bug... ");
local_irq_save(flags);
- handler = set_except_vector(12, handle_daddi_ov);
+ handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
/*
* The following code fails to trigger an overflow exception
* when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
@@ -214,7 +214,7 @@ static inline void check_daddi(void)
".set pop"
: "=r" (v), "=&r" (tmp)
: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
- set_except_vector(12, handler);
+ set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
if (daddi_ov) {
@@ -225,14 +225,14 @@ static inline void check_daddi(void)
printk("yes, workaround... ");
local_irq_save(flags);
- handler = set_except_vector(12, handle_daddi_ov);
+ handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
asm volatile(
"addiu %1, $0, %2\n\t"
"dsrl %1, %1, 1\n\t"
"daddi %0, %1, %3"
: "=r" (v), "=&r" (tmp)
: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
- set_except_vector(12, handler);
+ set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
if (daddi_ov) {
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 09a51d0..b725b71 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -99,6 +99,161 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
}
/*
+ * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
+ * supported by FPU hardware.
+ */
+static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
+{
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+ unsigned long sr, fir, fcsr, fcsr0, fcsr1;
+
+ sr = read_c0_status();
+ __enable_fpu(FPU_AS_IS);
+
+ fir = read_32bit_cp1_register(CP1_REVISION);
+ if (fir & MIPS_FPIR_HAS2008) {
+ fcsr = read_32bit_cp1_register(CP1_STATUS);
+
+ fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+ write_32bit_cp1_register(CP1_STATUS, fcsr0);
+ fcsr0 = read_32bit_cp1_register(CP1_STATUS);
+
+ fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+ write_32bit_cp1_register(CP1_STATUS, fcsr1);
+ fcsr1 = read_32bit_cp1_register(CP1_STATUS);
+
+ write_32bit_cp1_register(CP1_STATUS, fcsr);
+
+ if (!(fcsr0 & FPU_CSR_NAN2008))
+ c->options |= MIPS_CPU_NAN_LEGACY;
+ if (fcsr1 & FPU_CSR_NAN2008)
+ c->options |= MIPS_CPU_NAN_2008;
+
+ if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
+ c->fpu_msk31 &= ~FPU_CSR_ABS2008;
+ else
+ c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;
+
+ if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
+ c->fpu_msk31 &= ~FPU_CSR_NAN2008;
+ else
+ c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
+ } else {
+ c->options |= MIPS_CPU_NAN_LEGACY;
+ }
+
+ write_c0_status(sr);
+ } else {
+ c->options |= MIPS_CPU_NAN_LEGACY;
+ }
+}
+
+/*
+ * IEEE 754 conformance mode to use. Affects the NaN encoding and the
+ * ABS.fmt/NEG.fmt execution mode.
+ */
+static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
+
+/*
+ * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
+ * to support by the FPU emulator according to the IEEE 754 conformance
+ * mode selected. Note that "relaxed" straps the emulator so that it
+ * allows 2008-NaN binaries even for legacy processors.
+ */
+static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
+{
+ c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
+ c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+ c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+
+ switch (ieee754) {
+ case STRICT:
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+ MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+ MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+ c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+ } else {
+ c->options |= MIPS_CPU_NAN_LEGACY;
+ c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+ }
+ break;
+ case LEGACY:
+ c->options |= MIPS_CPU_NAN_LEGACY;
+ c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+ break;
+ case STD2008:
+ c->options |= MIPS_CPU_NAN_2008;
+ c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+ c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+ break;
+ case RELAXED:
+ c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+ break;
+ }
+}
+
+/*
+ * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * according to the "ieee754=" parameter.
+ */
+static void cpu_set_nan_2008(struct cpuinfo_mips *c)
+{
+ switch (ieee754) {
+ case STRICT:
+ mips_use_nan_legacy = !!cpu_has_nan_legacy;
+ mips_use_nan_2008 = !!cpu_has_nan_2008;
+ break;
+ case LEGACY:
+ mips_use_nan_legacy = !!cpu_has_nan_legacy;
+ mips_use_nan_2008 = !cpu_has_nan_legacy;
+ break;
+ case STD2008:
+ mips_use_nan_legacy = !cpu_has_nan_2008;
+ mips_use_nan_2008 = !!cpu_has_nan_2008;
+ break;
+ case RELAXED:
+ mips_use_nan_legacy = true;
+ mips_use_nan_2008 = true;
+ break;
+ }
+}
+
+/*
+ * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
+ * settings:
+ *
+ * strict: accept binaries that request a NaN encoding supported by the FPU
+ * legacy: only accept legacy-NaN binaries
+ * 2008: only accept 2008-NaN binaries
+ * relaxed: accept any binaries regardless of whether supported by the FPU
+ */
+static int __init ieee754_setup(char *s)
+{
+ if (!s)
+ return -1;
+ else if (!strcmp(s, "strict"))
+ ieee754 = STRICT;
+ else if (!strcmp(s, "legacy"))
+ ieee754 = LEGACY;
+ else if (!strcmp(s, "2008"))
+ ieee754 = STD2008;
+ else if (!strcmp(s, "relaxed"))
+ ieee754 = RELAXED;
+ else
+ return -1;
+
+ if (!(boot_cpu_data.options & MIPS_CPU_FPU))
+ cpu_set_nofpu_2008(&boot_cpu_data);
+ cpu_set_nan_2008(&boot_cpu_data);
+
+ return 0;
+}
+
+early_param("ieee754", ieee754_setup);
+
+/*
* Set the FIR feature flags for the FPU emulator.
*/
static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
@@ -113,6 +268,8 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+ if (c->options & MIPS_CPU_NAN_2008)
+ value |= MIPS_FPIR_HAS2008;
c->fpu_id = value;
}
@@ -137,6 +294,8 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
}
cpu_set_fpu_fcsr_mask(c);
+ cpu_set_fpu_2008(c);
+ cpu_set_nan_2008(c);
}
/*
@@ -147,6 +306,8 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
c->options &= ~MIPS_CPU_FPU;
c->fpu_msk31 = mips_nofpu_msk31;
+ cpu_set_nofpu_2008(c);
+ cpu_set_nan_2008(c);
cpu_set_nofpu_id(c);
}
@@ -536,8 +697,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
c->options |= MIPS_CPU_SEGMENTS;
if (config3 & MIPS_CONF3_MSA)
c->ases |= MIPS_ASE_MSA;
- /* Only tested on 32-bit cores */
- if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) {
+ if (config3 & MIPS_CONF3_PW) {
c->htw_seq = 0;
c->options |= MIPS_CPU_HTW;
}
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index e5ed7ad..1f91056 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -28,6 +28,43 @@ static u64 notrace r4k_read_sched_clock(void)
return read_c0_count();
}
+static inline unsigned int rdhwr_count(void)
+{
+ unsigned int count;
+
+ __asm__ __volatile__(
+ " .set push\n"
+ " .set mips32r2\n"
+ " rdhwr %0, $2\n"
+ " .set pop\n"
+ : "=r" (count));
+
+ return count;
+}
+
+static bool rdhwr_count_usable(void)
+{
+ unsigned int prev, curr, i;
+
+ /*
+ * Older QEMUs have a broken implementation of RDHWR for the CP0 count
+ * which always returns a constant value. Try to identify this and don't
+ * use it in the VDSO if it is broken. This workaround can be removed
+ * once the fix has been in QEMU stable for a reasonable amount of time.
+ */
+ for (i = 0, prev = rdhwr_count(); i < 100; i++) {
+ curr = rdhwr_count();
+
+ if (curr != prev)
+ return true;
+
+ prev = curr;
+ }
+
+ pr_warn("Not using R4K clocksource in VDSO due to broken RDHWR\n");
+ return false;
+}
+
int __init init_r4k_clocksource(void)
{
if (!cpu_has_counter || !mips_hpt_frequency)
@@ -36,6 +73,13 @@ int __init init_r4k_clocksource(void)
/* Calculate a somewhat reasonable rating value */
clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+ /*
+ * R2 onwards makes the count accessible to user mode so it can be used
+ * by the VDSO (HWREna is configured by configure_hwrena()).
+ */
+ if (cpu_has_mips_r2_r6 && rdhwr_count_usable())
+ clocksource_mips.archdata.vdso_clock_mode = VDSO_CLOCK_R4K;
+
clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 4a4d9e0..c3c234d 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -11,6 +11,12 @@
#include <linux/elf.h>
#include <linux/sched.h>
+#include <asm/cpu-info.h>
+
+/* Whether to accept legacy-NaN and 2008-NaN user binaries. */
+bool mips_use_nan_legacy;
+bool mips_use_nan_2008;
+
/* FPU modes */
enum {
FP_FRE,
@@ -68,15 +74,23 @@ static struct mode_req none_req = { true, true, false, true, true };
int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
bool is_interp, struct arch_elf_state *state)
{
- struct elf32_hdr *ehdr32 = _ehdr;
+ union {
+ struct elf32_hdr e32;
+ struct elf64_hdr e64;
+ } *ehdr = _ehdr;
struct elf32_phdr *phdr32 = _phdr;
struct elf64_phdr *phdr64 = _phdr;
struct mips_elf_abiflags_v0 abiflags;
+ bool elf32;
+ u32 flags;
int ret;
+ elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+ flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
/* Lets see if this is an O32 ELF */
- if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
- if (ehdr32->e_flags & EF_MIPS_FP64) {
+ if (elf32) {
+ if (flags & EF_MIPS_FP64) {
/*
* Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
* later if needed
@@ -120,13 +134,50 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
return 0;
}
-int arch_check_elf(void *_ehdr, bool has_interpreter,
+int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
struct arch_elf_state *state)
{
- struct elf32_hdr *ehdr = _ehdr;
+ union {
+ struct elf32_hdr e32;
+ struct elf64_hdr e64;
+ } *ehdr = _ehdr;
+ union {
+ struct elf32_hdr e32;
+ struct elf64_hdr e64;
+ } *iehdr = _interp_ehdr;
struct mode_req prog_req, interp_req;
int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
- bool is_mips64;
+ bool elf32;
+ u32 flags;
+
+ elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+ flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
+ /*
+ * Determine the NaN personality, reject the binary if not allowed.
+ * Also ensure that any interpreter matches the executable.
+ */
+ if (flags & EF_MIPS_NAN2008) {
+ if (mips_use_nan_2008)
+ state->nan_2008 = 1;
+ else
+ return -ENOEXEC;
+ } else {
+ if (mips_use_nan_legacy)
+ state->nan_2008 = 0;
+ else
+ return -ENOEXEC;
+ }
+ if (has_interpreter) {
+ bool ielf32;
+ u32 iflags;
+
+ ielf32 = iehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+ iflags = ielf32 ? iehdr->e32.e_flags : iehdr->e64.e_flags;
+
+ if ((flags ^ iflags) & EF_MIPS_NAN2008)
+ return -ELIBBAD;
+ }
if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
return 0;
@@ -142,21 +193,18 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
abi0 = abi1 = fp_abi;
}
- is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
- (ehdr->e_flags & EF_MIPS_ABI2);
+ if (elf32 && !(flags & EF_MIPS_ABI2)) {
+ /* Default to a mode capable of running code expecting FR=0 */
+ state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
- if (is_mips64) {
+ /* Allow all ABIs we know about */
+ max_abi = MIPS_ABI_FP_64A;
+ } else {
/* MIPS64 code always uses FR=1, thus the default is easy */
state->overall_fp_mode = FP_FR1;
/* Disallow access to the various FPXX & FP64 ABIs */
max_abi = MIPS_ABI_FP_SOFT;
- } else {
- /* Default to a mode capable of running code expecting FR=0 */
- state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
-
- /* Allow all ABIs we know about */
- max_abi = MIPS_ABI_FP_64A;
}
if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
@@ -254,3 +302,27 @@ void mips_set_personality_fp(struct arch_elf_state *state)
BUG();
}
}
+
+/*
+ * Select the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * in FCSR according to the ELF NaN personality.
+ */
+void mips_set_personality_nan(struct arch_elf_state *state)
+{
+ struct cpuinfo_mips *c = &boot_cpu_data;
+ struct task_struct *t = current;
+
+ t->thread.fpu.fcr31 = c->fpu_csr31;
+ switch (state->nan_2008) {
+ case 0:
+ break;
+ case 1:
+ if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+ t->thread.fpu.fcr31 |= FPU_CSR_NAN2008;
+ if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+ t->thread.fpu.fcr31 |= FPU_CSR_ABS2008;
+ break;
+ default:
+ BUG();
+ }
+}
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c
index c6854d9..cbd47f3 100644
--- a/arch/mips/kernel/gpio_txx9.c
+++ b/arch/mips/kernel/gpio_txx9.c
@@ -10,7 +10,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <asm/txx9pio.h>
@@ -21,7 +21,7 @@ static struct txx9_pio_reg __iomem *txx9_pioptr;
static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
- return __raw_readl(&txx9_pioptr->din) & (1 << offset);
+ return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset));
}
static void txx9_gpio_set_raw(unsigned int offset, int value)
@@ -85,5 +85,5 @@ int __init txx9_gpio_init(unsigned long baseaddr,
return -ENODEV;
txx9_gpio_chip.base = base;
txx9_gpio_chip.ngpio = num;
- return gpiochip_add(&txx9_gpio_chip);
+ return gpiochip_add_data(&txx9_gpio_chip, NULL);
}
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index ab1478d..46794d6 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -134,6 +134,16 @@ void __init check_wait(void)
return;
}
+ /*
+ * MIPSr6 specifies that masked interrupts should unblock an executing
+ * wait instruction, and thus that it is safe for us to use
+ * r4k_wait_irqoff. Yippee!
+ */
+ if (cpu_has_mips_r6) {
+ cpu_wait = r4k_wait_irqoff;
+ return;
+ }
+
switch (current_cpu_type()) {
case CPU_R3081:
case CPU_R3081E:
@@ -155,12 +165,12 @@ void __init check_wait(void)
case CPU_4KEC:
case CPU_4KSC:
case CPU_5KC:
+ case CPU_5KE:
case CPU_25KF:
case CPU_PR4450:
case CPU_BMIPS3300:
case CPU_BMIPS4350:
case CPU_BMIPS4380:
- case CPU_BMIPS5000:
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
@@ -171,7 +181,9 @@ void __init check_wait(void)
case CPU_XLP:
cpu_wait = r4k_wait;
break;
-
+ case CPU_BMIPS5000:
+ cpu_wait = r4k_wait_irqoff;
+ break;
case CPU_RM7000:
cpu_wait = rm7k_wait_irqoff;
break;
@@ -196,7 +208,6 @@ void __init check_wait(void)
case CPU_INTERAPTIV:
case CPU_M5150:
case CPU_QEMU_GENERIC:
- case CPU_I6400:
cpu_wait = r4k_wait;
if (read_c0_config7() & MIPS_CONF7_WII)
cpu_wait = r4k_wait_irqoff;
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index b8ceee5..1448c1f 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -9,6 +9,8 @@
*/
#include <linux/errno.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
#include <asm/mips-cm.h>
#include <asm/mipsregs.h>
@@ -136,6 +138,9 @@ static char *cm3_causes[32] = {
"0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f"
};
+static DEFINE_PER_CPU_ALIGNED(spinlock_t, cm_core_lock);
+static DEFINE_PER_CPU_ALIGNED(unsigned long, cm_core_lock_flags);
+
phys_addr_t __mips_cm_phys_base(void)
{
u32 config3 = read_c0_config3();
@@ -200,6 +205,7 @@ int mips_cm_probe(void)
{
phys_addr_t addr;
u32 base_reg;
+ unsigned cpu;
/*
* No need to probe again if we have already been
@@ -247,38 +253,70 @@ int mips_cm_probe(void)
/* determine register width for this CM */
mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);
+ for_each_possible_cpu(cpu)
+ spin_lock_init(&per_cpu(cm_core_lock, cpu));
+
return 0;
}
-void mips_cm_error_report(void)
+void mips_cm_lock_other(unsigned int core, unsigned int vp)
{
- unsigned long revision = mips_cm_revision();
+ unsigned curr_core;
+ u32 val;
+
+ preempt_disable();
+ curr_core = current_cpu_data.core;
+ spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
+ per_cpu(cm_core_lock_flags, curr_core));
+
+ if (mips_cm_revision() >= CM_REV_CM3) {
+ val = core << CM3_GCR_Cx_OTHER_CORE_SHF;
+ val |= vp << CM3_GCR_Cx_OTHER_VP_SHF;
+ } else {
+ BUG_ON(vp != 0);
+ val = core << CM_GCR_Cx_OTHER_CORENUM_SHF;
+ }
+
+ write_gcr_cl_other(val);
+
/*
- * CM3 has a 64-bit Error cause register with 0:57 containing the error
- * info and 63:58 the error type. For old CMs, everything is contained
- * in a single 32-bit register (0:26 and 31:27 respectively). Even
- * though the cm_error is u64, we will simply ignore the upper word
- * for CM2.
+ * Ensure the core-other region reflects the appropriate core &
+ * VP before any accesses to it occur.
*/
- u64 cm_error = read_gcr_error_cause();
- int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
- ((revision >= CM_REV_CM3) ? 31 : 0);
- unsigned long cm_addr = read_gcr_error_addr();
- unsigned long cm_other = read_gcr_error_mult();
+ mb();
+}
+
+void mips_cm_unlock_other(void)
+{
+ unsigned curr_core = current_cpu_data.core;
+
+ spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core),
+ per_cpu(cm_core_lock_flags, curr_core));
+ preempt_enable();
+}
+
+void mips_cm_error_report(void)
+{
+ u64 cm_error, cm_addr, cm_other;
+ unsigned long revision;
int ocause, cause;
char buf[256];
if (!mips_cm_present())
return;
- cause = cm_error >> cm_error_cause_sft;
+ revision = mips_cm_revision();
- if (!cause)
- /* All good */
- return;
-
- ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
if (revision < CM_REV_CM3) { /* CM2 */
+ cm_error = read_gcr_error_cause();
+ cm_addr = read_gcr_error_addr();
+ cm_other = read_gcr_error_mult();
+ cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+ ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+
+ if (!cause)
+ return;
+
if (cause < 16) {
unsigned long cca_bits = (cm_error >> 15) & 7;
unsigned long tr_bits = (cm_error >> 12) & 7;
@@ -310,18 +348,30 @@ void mips_cm_error_report(void)
}
pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
cm2_causes[cause], buf);
- pr_err("CM_ADDR =%08lx\n", cm_addr);
- pr_err("CM_OTHER=%08lx %s\n", cm_other, cm2_causes[ocause]);
+ pr_err("CM_ADDR =%08llx\n", cm_addr);
+ pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]);
} else { /* CM3 */
- /* Used by cause == {1,2,3} */
- unsigned long core_id_bits = (cm_error >> 22) & 0xf;
- unsigned long vp_id_bits = (cm_error >> 18) & 0xf;
- unsigned long cmd_bits = (cm_error >> 14) & 0xf;
- unsigned long cmd_group_bits = (cm_error >> 11) & 0xf;
- unsigned long cm3_cca_bits = (cm_error >> 8) & 7;
- unsigned long mcp_bits = (cm_error >> 5) & 0xf;
- unsigned long cm3_tr_bits = (cm_error >> 1) & 0xf;
- unsigned long sched_bit = cm_error & 0x1;
+ ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
+ ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
+
+ cm_error = read64_gcr_error_cause();
+ cm_addr = read64_gcr_error_addr();
+ cm_other = read64_gcr_error_mult();
+ cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+ ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+
+ if (!cause)
+ return;
+
+ /* Used by cause == {1,2,3} */
+ core_id_bits = (cm_error >> 22) & 0xf;
+ vp_id_bits = (cm_error >> 18) & 0xf;
+ cmd_bits = (cm_error >> 14) & 0xf;
+ cmd_group_bits = (cm_error >> 11) & 0xf;
+ cm3_cca_bits = (cm_error >> 8) & 7;
+ mcp_bits = (cm_error >> 5) & 0xf;
+ cm3_tr_bits = (cm_error >> 1) & 0xf;
+ sched_bit = cm_error & 0x1;
if (cause == 1 || cause == 3) { /* Tag ECC */
unsigned long tag_ecc = (cm_error >> 57) & 0x1;
@@ -363,12 +413,14 @@ void mips_cm_error_report(void)
cm3_cmd_group[cmd_group_bits],
cm3_cca_bits, 1 << mcp_bits,
cm3_tr[cm3_tr_bits], sched_bit);
+ } else {
+ buf[0] = 0;
}
pr_err("CM_ERROR=%llx %s <%s>\n", cm_error,
cm3_causes[cause], buf);
- pr_err("CM_ADDR =%lx\n", cm_addr);
- pr_err("CM_OTHER=%lx %s\n", cm_other, cm3_causes[ocause]);
+ pr_err("CM_ADDR =%llx\n", cm_addr);
+ pr_err("CM_OTHER=%llx %s\n", cm_other, cm3_causes[ocause]);
}
/* reprime cause register */
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 8af4d62..566b8d2 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -76,6 +76,12 @@ void mips_cpc_lock_other(unsigned int core)
spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
per_cpu(cpc_core_lock_flags, curr_core));
write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF);
+
+ /*
+ * Ensure the core-other region reflects the appropriate core &
+ * VP before any accesses to it occur.
+ */
+ mb();
}
void mips_cpc_unlock_other(void)
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index f2977f0..1f5aac7 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -22,6 +22,7 @@
#include <asm/asm.h>
#include <asm/branch.h>
#include <asm/break.h>
+#include <asm/debug.h>
#include <asm/fpu.h>
#include <asm/fpu_emulator.h>
#include <asm/inst.h>
@@ -2363,7 +2364,6 @@ static const struct file_operations mipsr2_clear_fops = {
static int __init mipsr2_init_debugfs(void)
{
- extern struct dentry *mips_debugfs_dir;
struct dentry *mipsr2_emul;
if (!mips_debugfs_dir)
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 291af0b..e2b6ab7 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -17,6 +17,7 @@
#include <asm/fpu.h>
#include <asm/msa.h>
+extern void *__bzero_kernel(void *__s, size_t __count);
extern void *__bzero(void *__s, size_t __count);
extern long __strncpy_from_kernel_nocheck_asm(char *__to,
const char *__from, long __len);
@@ -64,6 +65,7 @@ EXPORT_SYMBOL(__copy_from_user_eva);
EXPORT_SYMBOL(__copy_in_user_eva);
EXPORT_SYMBOL(__copy_to_user_eva);
EXPORT_SYMBOL(__copy_user_inatomic_eva);
+EXPORT_SYMBOL(__bzero_kernel);
#endif
EXPORT_SYMBOL(__bzero);
EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index f2975d4..eddd5fd 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -65,12 +65,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
status |= KU_USER;
regs->cp0_status = status;
+ lose_fpu(0);
+ clear_thread_flag(TIF_MSA_CTX_LIVE);
clear_used_math();
- clear_fpu_owner();
init_dsp();
- clear_thread_flag(TIF_USEDMSA);
- clear_thread_flag(TIF_MSA_CTX_LIVE);
- disable_msa();
regs->cp0_epc = pc;
regs->regs[29] = sp;
}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 4f0ac78..a5279b2 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -548,9 +548,6 @@ static const struct pt_regs_offset regoffset_table[] = {
REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
REG_OFFSET_NAME(c0_cause, cp0_cause),
REG_OFFSET_NAME(c0_epc, cp0_epc),
-#ifdef CONFIG_MIPS_MT_SMTC
- REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
-#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
REG_OFFSET_NAME(mpl0, mpl[0]),
REG_OFFSET_NAME(mpl1, mpl[1]),
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index 5ce3b74..b4ac637 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -125,7 +125,7 @@ LEAF(_restore_fp_context)
END(_restore_fp_context)
.set reorder
- .type fault@function
+ .type fault, @function
.ent fault
fault: li v0, -EFAULT
jr ra
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index f09546e..17732f8 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -358,7 +358,7 @@ LEAF(_restore_msa_all_upper)
.set reorder
- .type fault@function
+ .type fault, @function
.ent fault
fault: li v0, -EFAULT # failure
jr ra
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 65a74e4..a563174 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -594,3 +594,5 @@ EXPORT(sys_call_table)
PTR sys_execveat
PTR sys_userfaultfd
PTR sys_membarrier
+ PTR sys_mlock2
+ PTR sys_copy_file_range /* 4360 */
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index e732981..2b2dc14 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -432,4 +432,6 @@ EXPORT(sys_call_table)
PTR sys_execveat
PTR sys_userfaultfd
PTR sys_membarrier
+ PTR sys_mlock2
+ PTR sys_copy_file_range /* 5320 */
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index c794843..2bf5c85 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -422,4 +422,6 @@ EXPORT(sysn32_call_table)
PTR compat_sys_execveat /* 6320 */
PTR sys_userfaultfd
PTR sys_membarrier
+ PTR sys_mlock2
+ PTR sys_copy_file_range
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 6369cfd..c5b759e 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -577,4 +577,6 @@ EXPORT(sys32_call_table)
PTR compat_sys_execveat
PTR sys_userfaultfd
PTR sys_membarrier
+ PTR sys_mlock2
+ PTR sys_copy_file_range /* 4360 */
.size sys32_call_table,.-sys32_call_table
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
index 076ead2..87bc74a 100644
--- a/arch/mips/kernel/segment.c
+++ b/arch/mips/kernel/segment.c
@@ -10,6 +10,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/cpu.h>
+#include <asm/debug.h>
#include <asm/mipsregs.h>
static void build_segment_config(char *str, unsigned int cfg)
@@ -91,7 +92,6 @@ static const struct file_operations segments_fops = {
static int __init segments_info(void)
{
- extern struct dentry *mips_debugfs_dir;
struct dentry *segments;
if (cpu_has_segments) {
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4795151..4f60734 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -33,11 +33,16 @@
#include <asm/cache.h>
#include <asm/cdmm.h>
#include <asm/cpu.h>
+#include <asm/debug.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/smp-ops.h>
#include <asm/prom.h>
+#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
+const char __section(.appended_dtb) __appended_dtb[0x100000];
+#endif /* CONFIG_MIPS_ELF_APPENDED_DTB */
+
struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_data);
@@ -616,6 +621,10 @@ static void __init request_crashkernel(struct resource *res)
}
#endif /* !defined(CONFIG_KEXEC) */
+#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
+#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
+#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
+
static void __init arch_mem_init(char **cmdline_p)
{
struct memblock_region *reg;
@@ -640,18 +649,24 @@ static void __init arch_mem_init(char **cmdline_p)
pr_info("Determined physical RAM map:\n");
print_memory_map();
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
+#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
#else
+ if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
+ (USE_DTB_CMDLINE && !boot_command_line[0]))
+ strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+
+ if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+ strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+ }
+
+#if defined(CONFIG_CMDLINE_BOOL)
if (builtin_cmdline[0]) {
- strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
- strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+ strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
}
- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
#endif
-#else
- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
#endif
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
@@ -717,21 +732,23 @@ static void __init resource_init(void)
end = HIGHMEM_START - 1;
res = alloc_bootmem(sizeof(struct resource));
+
+ res->start = start;
+ res->end = end;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
switch (boot_mem_map.map[i].type) {
case BOOT_MEM_RAM:
case BOOT_MEM_INIT_RAM:
case BOOT_MEM_ROM_DATA:
res->name = "System RAM";
+ res->flags |= IORESOURCE_SYSRAM;
break;
case BOOT_MEM_RESERVED:
default:
res->name = "reserved";
}
- res->start = start;
- res->end = end;
-
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
/*
@@ -767,6 +784,7 @@ static inline void prefill_possible_map(void) {}
void __init setup_arch(char **cmdline_p)
{
cpu_probe();
+ mips_cm_probe();
prom_init();
setup_early_fdc_console();
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 2fec67b..bf792e2 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -36,7 +36,6 @@
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
-#include <asm/vdso.h>
#include <asm/dsp.h>
#include <asm/inst.h>
#include <asm/msa.h>
@@ -752,16 +751,15 @@ static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
struct mips_abi mips_abi = {
#ifdef CONFIG_TRAD_SIGNALS
.setup_frame = setup_frame,
- .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
#endif
.setup_rt_frame = setup_rt_frame,
- .rt_signal_return_offset =
- offsetof(struct mips_vdso, rt_signal_trampoline),
.restart = __NR_restart_syscall,
.off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
.off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
.off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
+
+ .vdso = &vdso_image,
};
static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
@@ -801,11 +799,11 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
}
if (sig_uses_siginfo(&ksig->ka))
- ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+ ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn,
ksig, regs, oldset);
else
- ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
- regs, oldset);
+ ret = abi->setup_frame(vdso + abi->vdso->off_sigreturn,
+ ksig, regs, oldset);
signal_setup_done(ret, ksig, 0);
}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index f7e89524..4909639 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -31,7 +31,6 @@
#include <asm/ucontext.h>
#include <asm/fpu.h>
#include <asm/war.h>
-#include <asm/vdso.h>
#include <asm/dsp.h>
#include "signal-common.h"
@@ -406,14 +405,12 @@ static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
*/
struct mips_abi mips_abi_32 = {
.setup_frame = setup_frame_32,
- .signal_return_offset =
- offsetof(struct mips_vdso, o32_signal_trampoline),
.setup_rt_frame = setup_rt_frame_32,
- .rt_signal_return_offset =
- offsetof(struct mips_vdso, o32_rt_signal_trampoline),
.restart = __NR_O32_restart_syscall,
.off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
.off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
.off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
+
+ .vdso = &vdso_image_o32,
};
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 0d017fd..a7bc384 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -38,7 +38,6 @@
#include <asm/fpu.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
-#include <asm/vdso.h>
#include "signal-common.h"
@@ -151,11 +150,11 @@ static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
struct mips_abi mips_abi_n32 = {
.setup_rt_frame = setup_rt_frame_n32,
- .rt_signal_return_offset =
- offsetof(struct mips_vdso, n32_rt_signal_trampoline),
.restart = __NR_N32_restart_syscall,
.off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
.off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
.off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
+
+ .vdso = &vdso_image_n32,
};
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index d5e0f94..7692334 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -149,8 +149,8 @@ void __init cmp_prepare_cpus(unsigned int max_cpus)
}
struct plat_smp_ops cmp_smp_ops = {
- .send_ipi_single = gic_send_ipi_single,
- .send_ipi_mask = gic_send_ipi_mask,
+ .send_ipi_single = mips_smp_send_ipi_single,
+ .send_ipi_mask = mips_smp_send_ipi_mask,
.init_secondary = cmp_init_secondary,
.smp_finish = cmp_smp_finish,
.boot_secondary = cmp_boot_secondary,
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index c889377..253e140 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -8,6 +8,7 @@
* option) any later version.
*/
+#include <linux/delay.h>
#include <linux/io.h>
#include <linux/irqchip/mips-gic.h>
#include <linux/sched.h>
@@ -37,8 +38,9 @@ static unsigned core_vpe_count(unsigned core)
if (!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
return 1;
- write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
+ mips_cm_lock_other(core, 0);
cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
+ mips_cm_unlock_other();
return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
}
@@ -133,11 +135,9 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
/*
* Patch the start of mips_cps_core_entry to provide:
*
- * v1 = CM base address
* s0 = kseg0 CCA
*/
entry_code = (u32 *)&mips_cps_core_entry;
- UASM_i_LA(&entry_code, 3, (long)mips_cm_base);
uasm_i_addiu(&entry_code, 16, 0, cca);
blast_dcache_range((unsigned long)&mips_cps_core_entry,
(unsigned long)entry_code);
@@ -190,10 +190,11 @@ err_out:
static void boot_core(unsigned core)
{
- u32 access;
+ u32 access, stat, seq_state;
+ unsigned timeout;
/* Select the appropriate core */
- write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
+ mips_cm_lock_other(core, 0);
/* Set its reset vector */
write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -201,6 +202,9 @@ static void boot_core(unsigned core)
/* Ensure its coherency is disabled */
write_gcr_co_coherence(0);
+ /* Start it with the legacy memory map and exception base */
+ write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
+
/* Ensure the core can access the GCRs */
access = read_gcr_access();
access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
@@ -210,12 +214,36 @@ static void boot_core(unsigned core)
/* Reset the core */
mips_cpc_lock_other(core);
write_cpc_co_cmd(CPC_Cx_CMD_RESET);
+
+ timeout = 100;
+ while (true) {
+ stat = read_cpc_co_stat_conf();
+ seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+
+ /* U6 == coherent execution, ie. the core is up */
+ if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6)
+ break;
+
+ /* Delay a little while before we start warning */
+ if (timeout) {
+ timeout--;
+ mdelay(10);
+ continue;
+ }
+
+ pr_warn("Waiting for core %u to start... STAT_CONF=0x%x\n",
+ core, stat);
+ mdelay(1000);
+ }
+
mips_cpc_unlock_other();
} else {
/* Take the core out of reset */
write_gcr_co_reset_release(0);
}
+ mips_cm_unlock_other();
+
/* The core is now powered up */
bitmap_set(core_power, core, 1);
}
@@ -444,8 +472,8 @@ static struct plat_smp_ops cps_smp_ops = {
.boot_secondary = cps_boot_secondary,
.init_secondary = cps_init_secondary,
.smp_finish = cps_smp_finish,
- .send_ipi_single = gic_send_ipi_single,
- .send_ipi_mask = gic_send_ipi_mask,
+ .send_ipi_single = mips_smp_send_ipi_single,
+ .send_ipi_mask = mips_smp_send_ipi_mask,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = cps_cpu_disable,
.cpu_die = cps_cpu_die,
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c
index 5f0ab5b..9b63829 100644
--- a/arch/mips/kernel/smp-gic.c
+++ b/arch/mips/kernel/smp-gic.c
@@ -46,9 +46,11 @@ void gic_send_ipi_single(int cpu, unsigned int action)
if (mips_cpc_present() && (core != current_cpu_data.core)) {
while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
+ mips_cm_lock_other(core, 0);
mips_cpc_lock_other(core);
write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
mips_cpc_unlock_other();
+ mips_cm_unlock_other();
}
}
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 86311a1..4f9570a 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -121,7 +121,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action)
#ifdef CONFIG_MIPS_GIC
if (gic_present) {
- gic_send_ipi_single(cpu, action);
+ mips_smp_send_ipi_single(cpu, action);
return;
}
#endif
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index bd4385a..37708d9 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -33,12 +33,16 @@
#include <linux/cpu.h>
#include <linux/err.h>
#include <linux/ftrace.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/atomic.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/idle.h>
#include <asm/r4k-timer.h>
+#include <asm/mips-cpc.h>
#include <asm/mmu_context.h>
#include <asm/time.h>
#include <asm/setup.h>
@@ -79,6 +83,11 @@ static cpumask_t cpu_core_setup_map;
cpumask_t cpu_coherent_mask;
+#ifdef CONFIG_GENERIC_IRQ_IPI
+static struct irq_desc *call_desc;
+static struct irq_desc *sched_desc;
+#endif
+
static inline void set_cpu_sibling_map(int cpu)
{
int i;
@@ -121,6 +130,7 @@ static inline void calculate_cpu_foreign_map(void)
cpumask_t temp_foreign_map;
/* Re-calculate the mask */
+ cpumask_clear(&temp_foreign_map);
for_each_online_cpu(i) {
core_present = 0;
for_each_cpu(k, &temp_foreign_map)
@@ -145,6 +155,133 @@ void register_smp_ops(struct plat_smp_ops *ops)
mp_ops = ops;
}
+#ifdef CONFIG_GENERIC_IRQ_IPI
+void mips_smp_send_ipi_single(int cpu, unsigned int action)
+{
+ mips_smp_send_ipi_mask(cpumask_of(cpu), action);
+}
+
+void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned long flags;
+ unsigned int core;
+ int cpu;
+
+ local_irq_save(flags);
+
+ switch (action) {
+ case SMP_CALL_FUNCTION:
+ __ipi_send_mask(call_desc, mask);
+ break;
+
+ case SMP_RESCHEDULE_YOURSELF:
+ __ipi_send_mask(sched_desc, mask);
+ break;
+
+ default:
+ BUG();
+ }
+
+ if (mips_cpc_present()) {
+ for_each_cpu(cpu, mask) {
+ core = cpu_data[cpu].core;
+
+ if (core == current_cpu_data.core)
+ continue;
+
+ while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
+ mips_cpc_lock_other(core);
+ write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
+ mips_cpc_unlock_other();
+ }
+ }
+ }
+
+ local_irq_restore(flags);
+}
+
+
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
+{
+ scheduler_ipi();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
+{
+ generic_smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = IRQF_PERCPU,
+ .name = "IPI resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = IRQF_PERCPU,
+ .name = "IPI call"
+};
+
+static __init void smp_ipi_init_one(unsigned int virq,
+ struct irqaction *action)
+{
+ int ret;
+
+ irq_set_handler(virq, handle_percpu_irq);
+ ret = setup_irq(virq, action);
+ BUG_ON(ret);
+}
+
+static int __init mips_smp_ipi_init(void)
+{
+ unsigned int call_virq, sched_virq;
+ struct irq_domain *ipidomain;
+ struct device_node *node;
+
+ node = of_irq_find_parent(of_root);
+ ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI);
+
+ /*
+ * Some platforms have half DT setup. So if we found irq node but
+ * didn't find an ipidomain, try to search for one that is not in the
+ * DT.
+ */
+ if (node && !ipidomain)
+ ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI);
+
+ BUG_ON(!ipidomain);
+
+ call_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask);
+ BUG_ON(!call_virq);
+
+ sched_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask);
+ BUG_ON(!sched_virq);
+
+ if (irq_domain_is_ipi_per_cpu(ipidomain)) {
+ int cpu;
+
+ for_each_cpu(cpu, cpu_possible_mask) {
+ smp_ipi_init_one(call_virq + cpu, &irq_call);
+ smp_ipi_init_one(sched_virq + cpu, &irq_resched);
+ }
+ } else {
+ smp_ipi_init_one(call_virq, &irq_call);
+ smp_ipi_init_one(sched_virq, &irq_resched);
+ }
+
+ call_desc = irq_to_desc(call_virq);
+ sched_desc = irq_to_desc(sched_virq);
+
+ return 0;
+}
+early_initcall(mips_smp_ipi_init);
+#endif
+
/*
* First C code run on the secondary CPUs after being started up by
* the master.
@@ -191,7 +328,7 @@ asmlinkage void start_secondary(void)
WARN_ON_ONCE(!irqs_disabled());
mp_ops->smp_finish();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
static void stop_this_cpu(void *dummy)
diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c
index 39f7ab7..f7d8695 100644
--- a/arch/mips/kernel/spinlock_test.c
+++ b/arch/mips/kernel/spinlock_test.c
@@ -5,7 +5,7 @@
#include <linux/debugfs.h>
#include <linux/export.h>
#include <linux/spinlock.h>
-
+#include <asm/debug.h>
static int ss_get(void *data, u64 *val)
{
@@ -115,8 +115,6 @@ static int multi_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
-
-extern struct dentry *mips_debugfs_dir;
static int __init spinlock_test(void)
{
struct dentry *d;
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index 1ba775d..506021f 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -12,14 +12,15 @@
* Save stack-backtrace addresses into a stack_trace buffer:
*/
static void save_raw_context_stack(struct stack_trace *trace,
- unsigned long reg29)
+ unsigned long reg29, int savesched)
{
unsigned long *sp = (unsigned long *)reg29;
unsigned long addr;
while (!kstack_end(sp)) {
addr = *sp++;
- if (__kernel_text_address(addr)) {
+ if (__kernel_text_address(addr) &&
+ (savesched || !in_sched_functions(addr))) {
if (trace->skip > 0)
trace->skip--;
else
@@ -31,7 +32,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
}
static void save_context_stack(struct stack_trace *trace,
- struct task_struct *tsk, struct pt_regs *regs)
+ struct task_struct *tsk, struct pt_regs *regs, int savesched)
{
unsigned long sp = regs->regs[29];
#ifdef CONFIG_KALLSYMS
@@ -43,20 +44,22 @@ static void save_context_stack(struct stack_trace *trace,
(unsigned long)task_stack_page(tsk);
if (stack_page && sp >= stack_page &&
sp <= stack_page + THREAD_SIZE - 32)
- save_raw_context_stack(trace, sp);
+ save_raw_context_stack(trace, sp, savesched);
return;
}
do {
- if (trace->skip > 0)
- trace->skip--;
- else
- trace->entries[trace->nr_entries++] = pc;
- if (trace->nr_entries >= trace->max_entries)
- break;
+ if (savesched || !in_sched_functions(pc)) {
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = pc;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ }
pc = unwind_stack(tsk, &sp, pc, &ra);
} while (pc);
#else
- save_raw_context_stack(trace, sp);
+ save_raw_context_stack(trace, sp, savesched);
#endif
}
@@ -82,6 +85,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
regs->cp0_epc = tsk->thread.reg31;
} else
prepare_frametrace(regs);
- save_context_stack(trace, tsk, regs);
+ save_context_stack(trace, tsk, regs, tsk == current);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
index 2242bdd..4472a7f 100644
--- a/arch/mips/kernel/sync-r4k.c
+++ b/arch/mips/kernel/sync-r4k.c
@@ -17,35 +17,23 @@
#include <asm/barrier.h>
#include <asm/mipsregs.h>
-static atomic_t count_start_flag = ATOMIC_INIT(0);
+static unsigned int initcount = 0;
static atomic_t count_count_start = ATOMIC_INIT(0);
static atomic_t count_count_stop = ATOMIC_INIT(0);
-static atomic_t count_reference = ATOMIC_INIT(0);
#define COUNTON 100
-#define NR_LOOPS 5
+#define NR_LOOPS 3
void synchronise_count_master(int cpu)
{
int i;
unsigned long flags;
- unsigned int initcount;
printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
local_irq_save(flags);
/*
- * Notify the slaves that it's time to start
- */
- atomic_set(&count_reference, read_c0_count());
- atomic_set(&count_start_flag, cpu);
- smp_wmb();
-
- /* Count will be initialised to current timer for all CPU's */
- initcount = read_c0_count();
-
- /*
* We loop a few times to get a primed instruction cache,
* then the last pass is more or less synchronised and
* the master and slaves each set their cycle counters to a known
@@ -63,9 +51,13 @@ void synchronise_count_master(int cpu)
atomic_set(&count_count_stop, 0);
smp_wmb();
- /* this lets the slaves write their count register */
+ /* Let the slave writes its count register */
atomic_inc(&count_count_start);
+ /* Count will be initialised to current timer */
+ if (i == 1)
+ initcount = read_c0_count();
+
/*
* Everyone initialises count in the last loop:
*/
@@ -73,7 +65,7 @@ void synchronise_count_master(int cpu)
write_c0_count(initcount);
/*
- * Wait for all slaves to leave the synchronization point:
+ * Wait for slave to leave the synchronization point:
*/
while (atomic_read(&count_count_stop) != 1)
mb();
@@ -83,7 +75,6 @@ void synchronise_count_master(int cpu)
}
/* Arrange for an interrupt in a short while */
write_c0_compare(read_c0_count() + COUNTON);
- atomic_set(&count_start_flag, 0);
local_irq_restore(flags);
@@ -98,19 +89,12 @@ void synchronise_count_master(int cpu)
void synchronise_count_slave(int cpu)
{
int i;
- unsigned int initcount;
/*
* Not every cpu is online at the time this gets called,
* so we first wait for the master to say everyone is ready
*/
- while (atomic_read(&count_start_flag) != cpu)
- mb();
-
- /* Count will be initialised to next expire for all CPU's */
- initcount = atomic_read(&count_reference);
-
for (i = 0; i < NR_LOOPS; i++) {
atomic_inc(&count_count_start);
while (atomic_read(&count_count_start) != 2)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index fdb392b..bf14da9 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -37,6 +37,7 @@
#include <linux/irq.h>
#include <linux/perf_event.h>
+#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
#include <asm/break.h>
@@ -662,7 +663,7 @@ static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode)
return -1;
}
-static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned short opcode)
+static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned int opcode)
{
if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
int rd = (opcode & MM_RS) >> 16;
@@ -689,15 +690,15 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
asmlinkage void do_ov(struct pt_regs *regs)
{
enum ctx_state prev_state;
- siginfo_t info;
+ siginfo_t info = {
+ .si_signo = SIGFPE,
+ .si_code = FPE_INTOVF,
+ .si_addr = (void __user *)regs->cp0_epc,
+ };
prev_state = exception_enter();
die_if_kernel("Integer overflow", regs);
- info.si_code = FPE_INTOVF;
- info.si_signo = SIGFPE;
- info.si_errno = 0;
- info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
exception_exit(prev_state);
}
@@ -873,7 +874,7 @@ out:
void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
const char *str)
{
- siginfo_t info;
+ siginfo_t info = { 0 };
char b[40];
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -902,7 +903,6 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
else
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
- info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
@@ -1118,11 +1118,12 @@ no_r2_instr:
if (get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 };
- if (unlikely(get_user(mmop[0], epc) < 0))
+ if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0))
status = SIGSEGV;
- if (unlikely(get_user(mmop[1], epc) < 0))
+ if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0))
status = SIGSEGV;
- opcode = (mmop[0] << 16) | mmop[1];
+ opcode = mmop[0];
+ opcode = (opcode << 16) | mmop[1];
if (status < 0)
status = simulate_rdhwr_mm(regs, opcode);
@@ -1368,26 +1369,12 @@ asmlinkage void do_cpu(struct pt_regs *regs)
if (unlikely(compute_return_epc(regs) < 0))
break;
- if (get_isa16_mode(regs->cp0_epc)) {
- unsigned short mmop[2] = { 0 };
-
- if (unlikely(get_user(mmop[0], epc) < 0))
- status = SIGSEGV;
- if (unlikely(get_user(mmop[1], epc) < 0))
- status = SIGSEGV;
- opcode = (mmop[0] << 16) | mmop[1];
-
- if (status < 0)
- status = simulate_rdhwr_mm(regs, opcode);
- } else {
+ if (!get_isa16_mode(regs->cp0_epc)) {
if (unlikely(get_user(opcode, epc) < 0))
status = SIGSEGV;
if (!cpu_has_llsc && status < 0)
status = simulate_llsc(regs, opcode);
-
- if (status < 0)
- status = simulate_rdhwr_normal(regs, opcode);
}
if (status < 0)
@@ -1856,12 +1843,14 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs)
{
char str[100];
+ nmi_enter();
raw_notifier_call_chain(&nmi_chain, 0, regs);
bust_spinlocks(1);
snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
smp_processor_id(), regs->cp0_epc);
regs->cp0_epc = read_c0_errorepc();
die(str, regs);
+ nmi_exit();
}
#define VECTORSPACING 0x100 /* for EI/VI mode */
@@ -2204,12 +2193,8 @@ void __init trap_init(void)
ebase = (unsigned long)
__alloc_bootmem(size, 1 << fls(size), 0);
} else {
-#ifdef CONFIG_KVM_GUEST
-#define KVM_GUEST_KSEG0 0x40000000
- ebase = KVM_GUEST_KSEG0;
-#else
- ebase = CKSEG0;
-#endif
+ ebase = CAC_BASE;
+
if (cpu_has_mips_r2_r6)
ebase += (read_c0_ebase() & 0x3ffff000);
}
@@ -2251,7 +2236,7 @@ void __init trap_init(void)
* Only some CPUs have the watch exceptions.
*/
if (cpu_has_watch)
- set_except_vector(23, handle_watch);
+ set_except_vector(EXCCODE_WATCH, handle_watch);
/*
* Initialise interrupt handlers
@@ -2278,27 +2263,27 @@ void __init trap_init(void)
if (board_be_init)
board_be_init();
- set_except_vector(0, using_rollback_handler() ? rollback_handle_int
- : handle_int);
- set_except_vector(1, handle_tlbm);
- set_except_vector(2, handle_tlbl);
- set_except_vector(3, handle_tlbs);
+ set_except_vector(EXCCODE_INT, using_rollback_handler() ?
+ rollback_handle_int : handle_int);
+ set_except_vector(EXCCODE_MOD, handle_tlbm);
+ set_except_vector(EXCCODE_TLBL, handle_tlbl);
+ set_except_vector(EXCCODE_TLBS, handle_tlbs);
- set_except_vector(4, handle_adel);
- set_except_vector(5, handle_ades);
+ set_except_vector(EXCCODE_ADEL, handle_adel);
+ set_except_vector(EXCCODE_ADES, handle_ades);
- set_except_vector(6, handle_ibe);
- set_except_vector(7, handle_dbe);
+ set_except_vector(EXCCODE_IBE, handle_ibe);
+ set_except_vector(EXCCODE_DBE, handle_dbe);
- set_except_vector(8, handle_sys);
- set_except_vector(9, handle_bp);
- set_except_vector(10, rdhwr_noopt ? handle_ri :
+ set_except_vector(EXCCODE_SYS, handle_sys);
+ set_except_vector(EXCCODE_BP, handle_bp);
+ set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
(cpu_has_vtag_icache ?
handle_ri_rdhwr_vivt : handle_ri_rdhwr));
- set_except_vector(11, handle_cpu);
- set_except_vector(12, handle_ov);
- set_except_vector(13, handle_tr);
- set_except_vector(14, handle_msa_fpe);
+ set_except_vector(EXCCODE_CPU, handle_cpu);
+ set_except_vector(EXCCODE_OV, handle_ov);
+ set_except_vector(EXCCODE_TR, handle_tr);
+ set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
if (current_cpu_type() == CPU_R6000 ||
current_cpu_type() == CPU_R6000A) {
@@ -2319,25 +2304,25 @@ void __init trap_init(void)
board_nmi_handler_setup();
if (cpu_has_fpu && !cpu_has_nofpuex)
- set_except_vector(15, handle_fpe);
+ set_except_vector(EXCCODE_FPE, handle_fpe);
- set_except_vector(16, handle_ftlb);
+ set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
if (cpu_has_rixiex) {
- set_except_vector(19, tlb_do_page_fault_0);
- set_except_vector(20, tlb_do_page_fault_0);
+ set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0);
+ set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0);
}
- set_except_vector(21, handle_msa);
- set_except_vector(22, handle_mdmx);
+ set_except_vector(EXCCODE_MSADIS, handle_msa);
+ set_except_vector(EXCCODE_MDMX, handle_mdmx);
if (cpu_has_mcheck)
- set_except_vector(24, handle_mcheck);
+ set_except_vector(EXCCODE_MCHECK, handle_mcheck);
if (cpu_has_mipsmt)
- set_except_vector(25, handle_mt);
+ set_except_vector(EXCCODE_THREAD, handle_mt);
- set_except_vector(26, handle_dsp);
+ set_except_vector(EXCCODE_DSPDIS, handle_dsp);
if (board_cache_error_setup)
board_cache_error_setup();
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 990354d..490cea5 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -85,6 +85,7 @@
#include <asm/branch.h>
#include <asm/byteorder.h>
#include <asm/cop2.h>
+#include <asm/debug.h>
#include <asm/fpu.h>
#include <asm/fpu_emulator.h>
#include <asm/inst.h>
@@ -2295,7 +2296,6 @@ sigbus:
}
#ifdef CONFIG_DEBUG_FS
-extern struct dentry *mips_debugfs_dir;
static int __init debugfs_unaligned(void)
{
struct dentry *d;
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index ed2a278..975e997 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -1,122 +1,175 @@
/*
- * 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) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
*
- * Copyright (C) 2009, 2010 Cavium Networks, 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/err.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/unistd.h>
-#include <linux/random.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
+#include <asm/abi.h>
#include <asm/vdso.h>
-#include <asm/uasm.h>
-#include <asm/processor.h>
+
+/* Kernel-provided data used by the VDSO. */
+static union mips_vdso_data vdso_data __page_aligned_data;
/*
- * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
+ * what we map and where within the area they are mapped is determined at
+ * runtime.
*/
-#define __NR_O32_sigreturn 4119
-#define __NR_O32_rt_sigreturn 4193
-#define __NR_N32_rt_sigreturn 6211
+static struct page *no_pages[] = { NULL };
+static struct vm_special_mapping vdso_vvar_mapping = {
+ .name = "[vvar]",
+ .pages = no_pages,
+};
-static struct page *vdso_page;
-
-static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+static void __init init_vdso_image(struct mips_vdso_image *image)
{
- uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */
- uasm_i_syscall(&tramp, 0);
+ unsigned long num_pages, i;
+
+ BUG_ON(!PAGE_ALIGNED(image->data));
+ BUG_ON(!PAGE_ALIGNED(image->size));
+
+ num_pages = image->size / PAGE_SIZE;
+
+ for (i = 0; i < num_pages; i++) {
+ image->mapping.pages[i] =
+ virt_to_page(image->data + (i * PAGE_SIZE));
+ }
}
static int __init init_vdso(void)
{
- struct mips_vdso *vdso;
-
- vdso_page = alloc_page(GFP_KERNEL);
- if (!vdso_page)
- panic("Cannot allocate vdso");
-
- vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
- if (!vdso)
- panic("Cannot map vdso");
- clear_page(vdso);
-
- install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
-#ifdef CONFIG_32BIT
- install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
-#else
- install_trampoline(vdso->n32_rt_signal_trampoline,
- __NR_N32_rt_sigreturn);
- install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
- install_trampoline(vdso->o32_rt_signal_trampoline,
- __NR_O32_rt_sigreturn);
+ init_vdso_image(&vdso_image);
+
+#ifdef CONFIG_MIPS32_O32
+ init_vdso_image(&vdso_image_o32);
#endif
- vunmap(vdso);
+#ifdef CONFIG_MIPS32_N32
+ init_vdso_image(&vdso_image_n32);
+#endif
return 0;
}
subsys_initcall(init_vdso);
-static unsigned long vdso_addr(unsigned long start)
+void update_vsyscall(struct timekeeper *tk)
{
- unsigned long offset = 0UL;
-
- if (current->flags & PF_RANDOMIZE) {
- offset = get_random_int();
- offset <<= PAGE_SHIFT;
- if (TASK_IS_32BIT_ADDR)
- offset &= 0xfffffful;
- else
- offset &= 0xffffffful;
+ vdso_data_write_begin(&vdso_data);
+
+ vdso_data.xtime_sec = tk->xtime_sec;
+ vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec;
+ vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec;
+ vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec;
+ vdso_data.cs_shift = tk->tkr_mono.shift;
+
+ vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
+ if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
+ vdso_data.cs_mult = tk->tkr_mono.mult;
+ vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last;
+ vdso_data.cs_mask = tk->tkr_mono.mask;
}
- return STACK_TOP + offset;
+ vdso_data_write_end(&vdso_data);
+}
+
+void update_vsyscall_tz(void)
+{
+ if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
+ vdso_data.tz_minuteswest = sys_tz.tz_minuteswest;
+ vdso_data.tz_dsttime = sys_tz.tz_dsttime;
+ }
}
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
- int ret;
- unsigned long addr;
+ struct mips_vdso_image *image = current->thread.abi->vdso;
struct mm_struct *mm = current->mm;
+ unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr;
+ struct vm_area_struct *vma;
+ struct resource gic_res;
+ int ret;
down_write(&mm->mmap_sem);
- addr = vdso_addr(mm->start_stack);
+ /*
+ * Determine total area size. This includes the VDSO data itself, the
+ * data page, and the GIC user page if present. Always create a mapping
+ * for the GIC user area if the GIC is present regardless of whether it
+ * is the current clocksource, in case it comes into use later on. We
+ * only map a page even though the total area is 64K, as we only need
+ * the counter registers at the start.
+ */
+ gic_size = gic_present ? PAGE_SIZE : 0;
+ vvar_size = gic_size + PAGE_SIZE;
+ size = vvar_size + image->size;
+
+ base = get_unmapped_area(NULL, 0, size, 0, 0);
+ if (IS_ERR_VALUE(base)) {
+ ret = base;
+ goto out;
+ }
+
+ data_addr = base + gic_size;
+ vdso_addr = data_addr + PAGE_SIZE;
- addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
- if (IS_ERR_VALUE(addr)) {
- ret = addr;
- goto up_fail;
+ vma = _install_special_mapping(mm, base, vvar_size,
+ VM_READ | VM_MAYREAD,
+ &vdso_vvar_mapping);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto out;
}
- ret = install_special_mapping(mm, addr, PAGE_SIZE,
- VM_READ|VM_EXEC|
- VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- &vdso_page);
+ /* Map GIC user page. */
+ if (gic_size) {
+ ret = gic_get_usm_range(&gic_res);
+ if (ret)
+ goto out;
+
+ ret = io_remap_pfn_range(vma, base,
+ gic_res.start >> PAGE_SHIFT,
+ gic_size,
+ pgprot_noncached(PAGE_READONLY));
+ if (ret)
+ goto out;
+ }
+ /* Map data page. */
+ ret = remap_pfn_range(vma, data_addr,
+ virt_to_phys(&vdso_data) >> PAGE_SHIFT,
+ PAGE_SIZE, PAGE_READONLY);
if (ret)
- goto up_fail;
+ goto out;
+
+ /* Map VDSO image. */
+ vma = _install_special_mapping(mm, vdso_addr, image->size,
+ VM_READ | VM_EXEC |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+ &image->mapping);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto out;
+ }
- mm->context.vdso = (void *)addr;
+ mm->context.vdso = (void *)vdso_addr;
+ ret = 0;
-up_fail:
+out:
up_write(&mm->mmap_sem);
return ret;
}
-
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
- return "[vdso]";
- return NULL;
-}
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 07d32a4..0a93e83 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -17,7 +17,9 @@ OUTPUT_ARCH(mips)
ENTRY(kernel_entry)
PHDRS {
text PT_LOAD FLAGS(7); /* RWX */
+#ifndef CONFIG_CAVIUM_OCTEON_SOC
note PT_NOTE FLAGS(4); /* R__ */
+#endif /* CAVIUM_OCTEON_SOC */
}
#ifdef CONFIG_32BIT
@@ -71,7 +73,12 @@ SECTIONS
__stop___dbe_table = .;
}
- NOTES :text :note
+#ifdef CONFIG_CAVIUM_OCTEON_SOC
+#define NOTES_HEADER
+#else /* CONFIG_CAVIUM_OCTEON_SOC */
+#define NOTES_HEADER :note
+#endif /* CONFIG_CAVIUM_OCTEON_SOC */
+ NOTES :text NOTES_HEADER
.dummy : { *(.dummy) } :text
_sdata = .; /* Start of data section */
@@ -132,6 +139,11 @@ SECTIONS
__appended_dtb = .;
/* leave space for appended DTB */
. += 0x100000;
+#elif defined(CONFIG_MIPS_ELF_APPENDED_DTB)
+ .appended_dtb : AT(ADDR(.appended_dtb) - LOAD_OFFSET) {
+ *(.appended_dtb)
+ KEEP(*(.appended_dtb))
+ }
#endif
/*
* Align to 64K in attempt to eliminate holes before the
@@ -181,6 +193,7 @@ SECTIONS
DISCARDS
/DISCARD/ : {
/* ABI crap starts here */
+ *(.MIPS.abiflags)
*(.MIPS.options)
*(.options)
*(.pdr)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 9067b65..544ea21 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -205,11 +205,11 @@ static void layout_sections(struct module *mod, const Elf_Ehdr *hdr,
|| s->sh_entsize != ~0UL)
continue;
s->sh_entsize =
- get_offset((unsigned long *)&mod->core_size, s);
+ get_offset((unsigned long *)&mod->core_layout.size, s);
}
if (m == 0)
- mod->core_text_size = mod->core_size;
+ mod->core_layout.text_size = mod->core_layout.size;
}
}
@@ -641,7 +641,7 @@ static int vpe_elfload(struct vpe *v)
layout_sections(&mod, hdr, sechdrs, secstrings);
}
- v->load_addr = alloc_progmem(mod.core_size);
+ v->load_addr = alloc_progmem(mod.core_layout.size);
if (!v->load_addr)
return -ENOMEM;
diff --git a/arch/mips/kvm/callback.c b/arch/mips/kvm/callback.c
index 313c2e3..d88aa21 100644
--- a/arch/mips/kvm/callback.c
+++ b/arch/mips/kvm/callback.c
@@ -11,4 +11,4 @@
#include <linux/kvm_host.h>
struct kvm_mips_callbacks *kvm_mips_callbacks;
-EXPORT_SYMBOL(kvm_mips_callbacks);
+EXPORT_SYMBOL_GPL(kvm_mips_callbacks);
diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c
index 521121b..f1527a4 100644
--- a/arch/mips/kvm/dyntrans.c
+++ b/arch/mips/kvm/dyntrans.c
@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
} else {
mfc0_inst = LW_TEMPLATE;
mfc0_inst |= ((rt & 0x1f) << 16);
- mfc0_inst |=
- offsetof(struct mips_coproc,
- reg[rd][sel]) + offsetof(struct kvm_mips_commpage,
- cop0);
+ mfc0_inst |= offsetof(struct kvm_mips_commpage,
+ cop0.reg[rd][sel]);
}
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
sel = inst & 0x7;
mtc0_inst |= ((rt & 0x1f) << 16);
- mtc0_inst |=
- offsetof(struct mips_coproc,
- reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0);
+ mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]);
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
kseg0_opc =
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index d5fa3ea..b37954c 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -20,6 +20,7 @@
#include <linux/random.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
+#include <asm/cacheops.h>
#include <asm/cpu-info.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
@@ -29,7 +30,6 @@
#include <asm/r4kcache.h>
#define CONFIG_MIPS_MT
-#include "opcode.h"
#include "interrupt.h"
#include "commpage.h"
@@ -1239,21 +1239,20 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
er = EMULATE_FAIL;
break;
- case mfmcz_op:
+ case mfmc0_op:
#ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
cop0->stat[MIPS_CP0_STATUS][0]++;
#endif
- if (rt != 0) {
+ if (rt != 0)
vcpu->arch.gprs[rt] =
kvm_read_c0_guest_status(cop0);
- }
/* EI */
if (inst & 0x20) {
- kvm_debug("[%#lx] mfmcz_op: EI\n",
+ kvm_debug("[%#lx] mfmc0_op: EI\n",
vcpu->arch.pc);
kvm_set_c0_guest_status(cop0, ST0_IE);
} else {
- kvm_debug("[%#lx] mfmcz_op: DI\n",
+ kvm_debug("[%#lx] mfmc0_op: DI\n",
vcpu->arch.pc);
kvm_clear_c0_guest_status(cop0, ST0_IE);
}
@@ -1525,7 +1524,7 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu)
struct kvm *kvm = vcpu->kvm;
unsigned long pa;
gfn_t gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
gfn = va >> PAGE_SHIFT;
@@ -1545,19 +1544,6 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu)
return 0;
}
-#define MIPS_CACHE_OP_INDEX_INV 0x0
-#define MIPS_CACHE_OP_INDEX_LD_TAG 0x1
-#define MIPS_CACHE_OP_INDEX_ST_TAG 0x2
-#define MIPS_CACHE_OP_IMP 0x3
-#define MIPS_CACHE_OP_HIT_INV 0x4
-#define MIPS_CACHE_OP_FILL_WB_INV 0x5
-#define MIPS_CACHE_OP_HIT_HB 0x6
-#define MIPS_CACHE_OP_FETCH_LOCK 0x7
-
-#define MIPS_CACHE_ICACHE 0x0
-#define MIPS_CACHE_DCACHE 0x1
-#define MIPS_CACHE_SEC 0x3
-
enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
uint32_t cause,
struct kvm_run *run,
@@ -1581,9 +1567,9 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
base = (inst >> 21) & 0x1f;
op_inst = (inst >> 16) & 0x1f;
- offset = inst & 0xffff;
- cache = (inst >> 16) & 0x3;
- op = (inst >> 18) & 0x7;
+ offset = (int16_t)inst;
+ cache = op_inst & CacheOp_Cache;
+ op = op_inst & CacheOp_Op;
va = arch->gprs[base] + offset;
@@ -1595,14 +1581,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
* invalidate the caches entirely by stepping through all the
* ways/indexes
*/
- if (op == MIPS_CACHE_OP_INDEX_INV) {
+ if (op == Index_Writeback_Inv) {
kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
arch->gprs[base], offset);
- if (cache == MIPS_CACHE_DCACHE)
+ if (cache == Cache_D)
r4k_blast_dcache();
- else if (cache == MIPS_CACHE_ICACHE)
+ else if (cache == Cache_I)
r4k_blast_icache();
else {
kvm_err("%s: unsupported CACHE INDEX operation\n",
@@ -1675,9 +1661,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
skip_fault:
/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
- if (cache == MIPS_CACHE_DCACHE
- && (op == MIPS_CACHE_OP_FILL_WB_INV
- || op == MIPS_CACHE_OP_HIT_INV)) {
+ if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
flush_dcache_line(va);
#ifdef CONFIG_KVM_MIPS_DYN_TRANS
@@ -1687,7 +1671,7 @@ skip_fault:
*/
kvm_mips_trans_cache_va(inst, opc, vcpu);
#endif
- } else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) {
+ } else if (op_inst == Hit_Invalidate_I) {
flush_dcache_line(va);
flush_icache_line(va);
@@ -1781,7 +1765,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned long cause,
kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_SYSCALL << CAUSEB_EXCCODE));
+ (EXCCODE_SYS << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -1828,7 +1812,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause,
}
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+ (EXCCODE_TLBL << CAUSEB_EXCCODE));
/* setup badvaddr, context and entryhi registers for the guest */
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1874,7 +1858,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause,
}
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+ (EXCCODE_TLBL << CAUSEB_EXCCODE));
/* setup badvaddr, context and entryhi registers for the guest */
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1918,7 +1902,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause,
}
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+ (EXCCODE_TLBS << CAUSEB_EXCCODE));
/* setup badvaddr, context and entryhi registers for the guest */
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1962,7 +1946,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause,
}
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+ (EXCCODE_TLBS << CAUSEB_EXCCODE));
/* setup badvaddr, context and entryhi registers for the guest */
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2033,7 +2017,8 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause,
arch->pc = KVM_GUEST_KSEG0 + 0x180;
}
- kvm_change_c0_guest_cause(cop0, (0xff), (T_TLB_MOD << CAUSEB_EXCCODE));
+ kvm_change_c0_guest_cause(cop0, (0xff),
+ (EXCCODE_MOD << CAUSEB_EXCCODE));
/* setup badvaddr, context and entryhi registers for the guest */
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2068,7 +2053,7 @@ enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause,
arch->pc = KVM_GUEST_KSEG0 + 0x180;
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_COP_UNUSABLE << CAUSEB_EXCCODE));
+ (EXCCODE_CPU << CAUSEB_EXCCODE));
kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));
return EMULATE_DONE;
@@ -2096,7 +2081,7 @@ enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause,
kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_RES_INST << CAUSEB_EXCCODE));
+ (EXCCODE_RI << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2131,7 +2116,7 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause,
kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_BREAK << CAUSEB_EXCCODE));
+ (EXCCODE_BP << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2166,7 +2151,7 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_TRAP << CAUSEB_EXCCODE));
+ (EXCCODE_TR << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2201,7 +2186,7 @@ enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_MSAFPE << CAUSEB_EXCCODE));
+ (EXCCODE_MSAFPE << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2236,7 +2221,7 @@ enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_FPE << CAUSEB_EXCCODE));
+ (EXCCODE_FPE << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2271,7 +2256,7 @@ enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause,
kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_MSADIS << CAUSEB_EXCCODE));
+ (EXCCODE_MSADIS << CAUSEB_EXCCODE));
/* Set PC to the exception entry point */
arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2480,25 +2465,25 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
if (usermode) {
switch (exccode) {
- case T_INT:
- case T_SYSCALL:
- case T_BREAK:
- case T_RES_INST:
- case T_TRAP:
- case T_MSAFPE:
- case T_FPE:
- case T_MSADIS:
+ case EXCCODE_INT:
+ case EXCCODE_SYS:
+ case EXCCODE_BP:
+ case EXCCODE_RI:
+ case EXCCODE_TR:
+ case EXCCODE_MSAFPE:
+ case EXCCODE_FPE:
+ case EXCCODE_MSADIS:
break;
- case T_COP_UNUSABLE:
+ case EXCCODE_CPU:
if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
er = EMULATE_PRIV_FAIL;
break;
- case T_TLB_MOD:
+ case EXCCODE_MOD:
break;
- case T_TLB_LD_MISS:
+ case EXCCODE_TLBL:
/*
* We we are accessing Guest kernel space, then send an
* address error exception to the guest
@@ -2507,12 +2492,12 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
kvm_debug("%s: LD MISS @ %#lx\n", __func__,
badvaddr);
cause &= ~0xff;
- cause |= (T_ADDR_ERR_LD << CAUSEB_EXCCODE);
+ cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE);
er = EMULATE_PRIV_FAIL;
}
break;
- case T_TLB_ST_MISS:
+ case EXCCODE_TLBS:
/*
* We we are accessing Guest kernel space, then send an
* address error exception to the guest
@@ -2521,26 +2506,26 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
kvm_debug("%s: ST MISS @ %#lx\n", __func__,
badvaddr);
cause &= ~0xff;
- cause |= (T_ADDR_ERR_ST << CAUSEB_EXCCODE);
+ cause |= (EXCCODE_ADES << CAUSEB_EXCCODE);
er = EMULATE_PRIV_FAIL;
}
break;
- case T_ADDR_ERR_ST:
+ case EXCCODE_ADES:
kvm_debug("%s: address error ST @ %#lx\n", __func__,
badvaddr);
if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
cause &= ~0xff;
- cause |= (T_TLB_ST_MISS << CAUSEB_EXCCODE);
+ cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE);
}
er = EMULATE_PRIV_FAIL;
break;
- case T_ADDR_ERR_LD:
+ case EXCCODE_ADEL:
kvm_debug("%s: address error LD @ %#lx\n", __func__,
badvaddr);
if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
cause &= ~0xff;
- cause |= (T_TLB_LD_MISS << CAUSEB_EXCCODE);
+ cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE);
}
er = EMULATE_PRIV_FAIL;
break;
@@ -2583,13 +2568,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
* an entry into the guest TLB.
*/
index = kvm_mips_guest_tlb_lookup(vcpu,
- (va & VPN2_MASK) |
- (kvm_read_c0_guest_entryhi
- (vcpu->arch.cop0) & ASID_MASK));
+ (va & VPN2_MASK) |
+ (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK));
if (index < 0) {
- if (exccode == T_TLB_LD_MISS) {
+ if (exccode == EXCCODE_TLBL) {
er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
- } else if (exccode == T_TLB_ST_MISS) {
+ } else if (exccode == EXCCODE_TLBS) {
er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
} else {
kvm_err("%s: invalid exc code: %d\n", __func__,
@@ -2604,10 +2588,10 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
* exception to the guest
*/
if (!TLB_IS_VALID(*tlb, va)) {
- if (exccode == T_TLB_LD_MISS) {
+ if (exccode == EXCCODE_TLBL) {
er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
vcpu);
- } else if (exccode == T_TLB_ST_MISS) {
+ } else if (exccode == EXCCODE_TLBS) {
er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
vcpu);
} else {
diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c
index 9b44459..95f7906 100644
--- a/arch/mips/kvm/interrupt.c
+++ b/arch/mips/kvm/interrupt.c
@@ -128,7 +128,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
allowed = 1;
- exccode = T_INT;
+ exccode = EXCCODE_INT;
}
break;
@@ -137,7 +137,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
allowed = 1;
- exccode = T_INT;
+ exccode = EXCCODE_INT;
}
break;
@@ -146,7 +146,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
allowed = 1;
- exccode = T_INT;
+ exccode = EXCCODE_INT;
}
break;
@@ -155,7 +155,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
allowed = 1;
- exccode = T_INT;
+ exccode = EXCCODE_INT;
}
break;
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
index c567240..81687ab 100644
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -36,14 +36,6 @@
#define PT_HOST_USERLOCAL PT_EPC
#define CP0_DDATA_LO $28,3
-#define CP0_CONFIG3 $16,3
-#define CP0_CONFIG5 $16,5
-#define CP0_EBASE $15,1
-
-#define CP0_INTCTL $12,1
-#define CP0_SRSCTL $12,2
-#define CP0_SRSMAP $12,3
-#define CP0_HWRENA $7,0
/* Resume Flags */
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
@@ -165,9 +157,11 @@ FEXPORT(__kvm_mips_vcpu_run)
FEXPORT(__kvm_mips_load_asid)
/* Set the ASID for the Guest Kernel */
- INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */
- /* addresses shift to 0x80000000 */
- bltz t0, 1f /* If kernel */
+ PTR_L t0, VCPU_COP0(k1)
+ LONG_L t0, COP0_STATUS(t0)
+ andi t0, KSU_USER | ST0_ERL | ST0_EXL
+ xori t0, KSU_USER
+ bnez t0, 1f /* If kernel */
INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */
1:
@@ -341,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Now restore the host state just enough to run the handlers */
- /* Swtich EBASE to the one used by Linux */
+ /* Switch EBASE to the one used by Linux */
/* load up the host EBASE */
mfc0 v0, CP0_STATUS
@@ -482,9 +476,11 @@ __kvm_mips_return_to_guest:
mtc0 t0, CP0_EPC
/* Set the ASID for the Guest Kernel */
- INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */
- /* addresses shift to 0x80000000 */
- bltz t0, 1f /* If kernel */
+ PTR_L t0, VCPU_COP0(k1)
+ LONG_L t0, COP0_STATUS(t0)
+ andi t0, KSU_USER | ST0_ERL | ST0_EXL
+ xori t0, KSU_USER
+ bnez t0, 1f /* If kernel */
INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */
1:
@@ -494,11 +490,11 @@ __kvm_mips_return_to_guest:
REG_ADDU t3, t1, t2
LONG_L k0, (t3)
andi k0, k0, 0xff
- mtc0 k0,CP0_ENTRYHI
+ mtc0 k0, CP0_ENTRYHI
ehb
/* Disable RDHWR access */
- mtc0 zero, CP0_HWRENA
+ mtc0 zero, CP0_HWRENA
/* load the guest context from VCPU and return */
LONG_L $0, VCPU_R0(k1)
@@ -610,11 +606,11 @@ __kvm_mips_return_to_host:
/* Restore RDHWR access */
PTR_LI k0, 0x2000000F
- mtc0 k0, CP0_HWRENA
+ mtc0 k0, CP0_HWRENA
/* Restore RA, which is the address we will return to */
- LONG_L ra, PT_R31(k1)
- j ra
+ LONG_L ra, PT_R31(k1)
+ j ra
nop
VECTOR_END(MIPSX(GuestExceptionEnd))
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 49ff3bf..70ef1a4 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
if (!kvm->arch.guest_pmap) {
- kvm_err("Failed to allocate guest PMAP");
+ kvm_err("Failed to allocate guest PMAP\n");
return;
}
@@ -279,7 +279,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
if (!gebase) {
err = -ENOMEM;
- goto out_free_cpu;
+ goto out_uninit_cpu;
}
kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",
ALIGN(size, PAGE_SIZE), gebase);
@@ -343,6 +343,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
out_free_gebase:
kfree(gebase);
+out_uninit_cpu:
+ kvm_vcpu_uninit(vcpu);
+
out_free_cpu:
kfree(vcpu);
@@ -442,8 +445,8 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
dvcpu->arch.wait = 0;
- if (waitqueue_active(&dvcpu->wq))
- wake_up_interruptible(&dvcpu->wq);
+ if (swait_active(&dvcpu->wq))
+ swake_up(&dvcpu->wq);
return 0;
}
@@ -699,7 +702,7 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
void __user *uaddr = (void __user *)(long)reg->addr;
- return copy_to_user(uaddr, vs, 16);
+ return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0;
} else {
return -EINVAL;
}
@@ -729,7 +732,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
void __user *uaddr = (void __user *)(long)reg->addr;
- return copy_from_user(vs, uaddr, 16);
+ return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0;
} else {
return -EINVAL;
}
@@ -1171,8 +1174,8 @@ static void kvm_mips_comparecount_func(unsigned long data)
kvm_mips_callbacks->queue_timer_int(vcpu);
vcpu->arch.wait = 0;
- if (waitqueue_active(&vcpu->wq))
- wake_up_interruptible(&vcpu->wq);
+ if (swait_active(&vcpu->wq))
+ swake_up(&vcpu->wq);
}
/* low level hrtimer wake routine */
@@ -1261,8 +1264,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
}
switch (exccode) {
- case T_INT:
- kvm_debug("[%d]T_INT @ %p\n", vcpu->vcpu_id, opc);
+ case EXCCODE_INT:
+ kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc);
++vcpu->stat.int_exits;
trace_kvm_exit(vcpu, INT_EXITS);
@@ -1273,8 +1276,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = RESUME_GUEST;
break;
- case T_COP_UNUSABLE:
- kvm_debug("T_COP_UNUSABLE: @ PC: %p\n", opc);
+ case EXCCODE_CPU:
+ kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc);
++vcpu->stat.cop_unusable_exits;
trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS);
@@ -1284,13 +1287,13 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = RESUME_HOST;
break;
- case T_TLB_MOD:
+ case EXCCODE_MOD:
++vcpu->stat.tlbmod_exits;
trace_kvm_exit(vcpu, TLBMOD_EXITS);
ret = kvm_mips_callbacks->handle_tlb_mod(vcpu);
break;
- case T_TLB_ST_MISS:
+ case EXCCODE_TLBS:
kvm_debug("TLB ST fault: cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n",
cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc,
badvaddr);
@@ -1300,7 +1303,7 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu);
break;
- case T_TLB_LD_MISS:
+ case EXCCODE_TLBL:
kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n",
cause, opc, badvaddr);
@@ -1309,55 +1312,55 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu);
break;
- case T_ADDR_ERR_ST:
+ case EXCCODE_ADES:
++vcpu->stat.addrerr_st_exits;
trace_kvm_exit(vcpu, ADDRERR_ST_EXITS);
ret = kvm_mips_callbacks->handle_addr_err_st(vcpu);
break;
- case T_ADDR_ERR_LD:
+ case EXCCODE_ADEL:
++vcpu->stat.addrerr_ld_exits;
trace_kvm_exit(vcpu, ADDRERR_LD_EXITS);
ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu);
break;
- case T_SYSCALL:
+ case EXCCODE_SYS:
++vcpu->stat.syscall_exits;
trace_kvm_exit(vcpu, SYSCALL_EXITS);
ret = kvm_mips_callbacks->handle_syscall(vcpu);
break;
- case T_RES_INST:
+ case EXCCODE_RI:
++vcpu->stat.resvd_inst_exits;
trace_kvm_exit(vcpu, RESVD_INST_EXITS);
ret = kvm_mips_callbacks->handle_res_inst(vcpu);
break;
- case T_BREAK:
+ case EXCCODE_BP:
++vcpu->stat.break_inst_exits;
trace_kvm_exit(vcpu, BREAK_INST_EXITS);
ret = kvm_mips_callbacks->handle_break(vcpu);
break;
- case T_TRAP:
+ case EXCCODE_TR:
++vcpu->stat.trap_inst_exits;
trace_kvm_exit(vcpu, TRAP_INST_EXITS);
ret = kvm_mips_callbacks->handle_trap(vcpu);
break;
- case T_MSAFPE:
+ case EXCCODE_MSAFPE:
++vcpu->stat.msa_fpe_exits;
trace_kvm_exit(vcpu, MSA_FPE_EXITS);
ret = kvm_mips_callbacks->handle_msa_fpe(vcpu);
break;
- case T_FPE:
+ case EXCCODE_FPE:
++vcpu->stat.fpe_exits;
trace_kvm_exit(vcpu, FPE_EXITS);
ret = kvm_mips_callbacks->handle_fpe(vcpu);
break;
- case T_MSADIS:
+ case EXCCODE_MSADIS:
++vcpu->stat.msa_disabled_exits;
trace_kvm_exit(vcpu, MSA_DISABLED_EXITS);
ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
@@ -1617,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = {
.notifier_call = kvm_mips_csr_die_notify,
};
-int __init kvm_mips_init(void)
+static int __init kvm_mips_init(void)
{
int ret;
@@ -1643,7 +1646,7 @@ int __init kvm_mips_init(void)
return 0;
}
-void __exit kvm_mips_exit(void)
+static void __exit kvm_mips_exit(void)
{
kvm_exit();
diff --git a/arch/mips/kvm/opcode.h b/arch/mips/kvm/opcode.h
deleted file mode 100644
index 03a6ae8..0000000
--- a/arch/mips/kvm/opcode.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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) 2012 MIPS Technologies, Inc. All rights reserved.
- * Authors: Sanjay Lal <sanjayl@kymasys.com>
- */
-
-/* Define opcode values not defined in <asm/isnt.h> */
-
-#ifndef __KVM_MIPS_OPCODE_H__
-#define __KVM_MIPS_OPCODE_H__
-
-/* COP0 Ops */
-#define mfmcz_op 0x0b /* 01011 */
-#define wrpgpr_op 0x0e /* 01110 */
-
-/* COP0 opcodes (only if COP0 and CO=1): */
-#define wait_op 0x20 /* 100000 */
-
-#endif /* __KVM_MIPS_OPCODE_H__ */
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index aed0ac2..a08c439 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -35,17 +35,17 @@
#define PRIx64 "llx"
atomic_t kvm_mips_instance;
-EXPORT_SYMBOL(kvm_mips_instance);
+EXPORT_SYMBOL_GPL(kvm_mips_instance);
/* These function pointers are initialized once the KVM module is loaded */
-pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
-EXPORT_SYMBOL(kvm_mips_gfn_to_pfn);
+kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
+EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn);
-void (*kvm_mips_release_pfn_clean)(pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_release_pfn_clean);
+void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean);
-bool (*kvm_mips_is_error_pfn)(pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_is_error_pfn);
+bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn);
uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
{
@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void)
mtc0_tlbw_hazard();
local_irq_restore(flags);
}
-EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs);
void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
{
@@ -139,12 +139,12 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
(tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
}
}
-EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
{
int srcu_idx, err = 0;
- pfn_t pfn;
+ kvm_pfn_t pfn;
if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE)
return 0;
@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
}
-EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
+EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa);
/* XXXKYMA: Must be called with interrupts disabled */
/* set flush_dcache_mask == 0 if no dcache flush required */
@@ -262,7 +262,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
struct kvm_vcpu *vcpu)
{
gfn_t gfn;
- pfn_t pfn0, pfn1;
+ kvm_pfn_t pfn0, pfn1;
unsigned long vaddr = 0;
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
int even;
@@ -308,12 +308,12 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
flush_dcache_mask);
}
-EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault);
int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
struct kvm_vcpu *vcpu)
{
- pfn_t pfn0, pfn1;
+ kvm_pfn_t pfn0, pfn1;
unsigned long flags, old_entryhi = 0, vaddr = 0;
unsigned long entrylo0 = 0, entrylo1 = 0;
@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
return 0;
}
-EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault);
int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
struct kvm_mips_tlb *tlb,
@@ -360,7 +360,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
{
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
struct kvm *kvm = vcpu->kvm;
- pfn_t pfn0, pfn1;
+ kvm_pfn_t pfn0, pfn1;
if ((tlb->tlb_hi & VPN2_MASK) == 0) {
pfn0 = 0;
@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
tlb->tlb_mask);
}
-EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault);
int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
{
@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
return index;
}
-EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup);
int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
{
@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
return idx;
}
-EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup);
int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
{
@@ -505,44 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
return 0;
}
-EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
-
-/* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */
-int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index)
-{
- unsigned long flags, old_entryhi;
-
- if (index >= current_cpu_data.tlbsize)
- BUG();
-
- local_irq_save(flags);
-
- old_entryhi = read_c0_entryhi();
-
- write_c0_entryhi(UNIQUE_ENTRYHI(index));
- mtc0_tlbw_hazard();
-
- write_c0_index(index);
- mtc0_tlbw_hazard();
-
- write_c0_entrylo0(0);
- mtc0_tlbw_hazard();
-
- write_c0_entrylo1(0);
- mtc0_tlbw_hazard();
-
- tlb_write_indexed();
- mtc0_tlbw_hazard();
- tlbw_use_hazard();
-
- write_c0_entryhi(old_entryhi);
- mtc0_tlbw_hazard();
- tlbw_use_hazard();
-
- local_irq_restore(flags);
-
- return 0;
-}
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv);
void kvm_mips_flush_host_tlb(int skip_kseg0)
{
@@ -594,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
local_irq_restore(flags);
}
-EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
+EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb);
void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
struct kvm_vcpu *vcpu)
@@ -642,7 +605,7 @@ void kvm_local_flush_tlb_all(void)
local_irq_restore(flags);
}
-EXPORT_SYMBOL(kvm_local_flush_tlb_all);
+EXPORT_SYMBOL_GPL(kvm_local_flush_tlb_all);
/**
* kvm_mips_migrate_count() - Migrate timer.
@@ -673,8 +636,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
local_irq_save(flags);
- if (((vcpu->arch.
- guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) {
+ if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) &
+ ASID_VERSION_MASK) {
kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
vcpu->arch.guest_kernel_asid[cpu] =
vcpu->arch.guest_kernel_mm.context.asid[cpu];
@@ -739,7 +702,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
local_irq_restore(flags);
}
-EXPORT_SYMBOL(kvm_arch_vcpu_load);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_load);
/* ASID can change if another task is scheduled during preemption */
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -768,7 +731,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
local_irq_restore(flags);
}
-EXPORT_SYMBOL(kvm_arch_vcpu_put);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_put);
uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
{
@@ -813,4 +776,4 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
return inst;
}
-EXPORT_SYMBOL(kvm_get_inst);
+EXPORT_SYMBOL_GPL(kvm_get_inst);
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index d836ed5..ad98800 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -16,7 +16,6 @@
#include <linux/kvm_host.h>
-#include "opcode.h"
#include "interrupt.h"
static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
index 3fc2e6d..a0706fd 100644
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -99,6 +99,23 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL(clk_set_rate);
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (unlikely(!clk_good(clk)))
+ return 0;
+ if (clk->rates && *clk->rates) {
+ unsigned long *r = clk->rates;
+
+ while (*r && (*r != rate))
+ r++;
+ if (!*r) {
+ return clk->rate;
+ }
+ }
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
int clk_enable(struct clk *clk)
{
if (unlikely(!clk_good(clk)))
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
index 77e4bdb..7376ce8 100644
--- a/arch/mips/lantiq/clk.h
+++ b/arch/mips/lantiq/clk.h
@@ -31,13 +31,18 @@
#define CLOCK_240M 240000000
#define CLOCK_250M 250000000
#define CLOCK_266M 266666666
+#define CLOCK_288M 288888888
#define CLOCK_300M 300000000
#define CLOCK_333M 333333333
+#define CLOCK_360M 360000000
#define CLOCK_393M 393215332
#define CLOCK_400M 400000000
+#define CLOCK_432M 432000000
#define CLOCK_450M 450000000
#define CLOCK_500M 500000000
#define CLOCK_600M 600000000
+#define CLOCK_666M 666666666
+#define CLOCK_720M 720000000
/* clock out speeds */
#define CLOCK_32_768K 32768
@@ -80,4 +85,12 @@ extern unsigned long ltq_vr9_cpu_hz(void);
extern unsigned long ltq_vr9_fpi_hz(void);
extern unsigned long ltq_vr9_pp32_hz(void);
+extern unsigned long ltq_ar10_cpu_hz(void);
+extern unsigned long ltq_ar10_fpi_hz(void);
+extern unsigned long ltq_ar10_pp32_hz(void);
+
+extern unsigned long ltq_grx390_cpu_hz(void);
+extern unsigned long ltq_grx390_fpi_hz(void);
+extern unsigned long ltq_grx390_pp32_hz(void);
+
#endif
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 2c218c3..2e7f60c 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -369,8 +369,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
if (of_address_to_resource(node, i, &res))
panic("Failed to get icu memory range");
- if (request_mem_region(res.start, resource_size(&res),
- res.name) < 0)
+ if (!request_mem_region(res.start, resource_size(&res),
+ res.name))
pr_err("Failed to request icu memory");
ltq_icu_membase[i] = ioremap_nocache(res.start,
@@ -449,8 +449,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
if (ret != exin_avail)
panic("failed to load external irq resources");
- if (request_mem_region(res.start, resource_size(&res),
- res.name) < 0)
+ if (!request_mem_region(res.start, resource_size(&res),
+ res.name))
pr_err("Failed to request eiu memory");
ltq_eiu_membase = ioremap_nocache(res.start,
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 0db099e..297bcaa 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -77,8 +77,6 @@ void __init plat_mem_setup(void)
* parsed resulting in our memory appearing
*/
__dt_setup_arch(__dtb_start);
-
- strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
}
void __init device_tree_init(void)
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c
index 8750dc0..07f6d5b 100644
--- a/arch/mips/lantiq/xway/clk.c
+++ b/arch/mips/lantiq/xway/clk.c
@@ -4,6 +4,7 @@
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
*/
#include <linux/io.h>
@@ -25,9 +26,9 @@ static unsigned int ram_clocks[] = {
/* legacy xway clock */
#define CGU_SYS 0x10
-/* vr9 clock */
-#define CGU_SYS_VR9 0x0c
-#define CGU_IF_CLK_VR9 0x24
+/* vr9, ar10/grx390 clock */
+#define CGU_SYS_XRX 0x0c
+#define CGU_IF_CLK_AR10 0x24
unsigned long ltq_danube_fpi_hz(void)
{
@@ -87,8 +88,9 @@ unsigned long ltq_ar9_fpi_hz(void)
unsigned long sys = ltq_ar9_sys_hz();
if (ltq_cgu_r32(CGU_SYS) & BIT(0))
- return sys;
- return sys >> 1;
+ return sys / 3;
+ else
+ return sys / 2;
}
unsigned long ltq_ar9_cpu_hz(void)
@@ -104,7 +106,7 @@ unsigned long ltq_vr9_cpu_hz(void)
unsigned int cpu_sel;
unsigned long clk;
- cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
+ cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf;
switch (cpu_sel) {
case 0:
@@ -145,7 +147,7 @@ unsigned long ltq_vr9_fpi_hz(void)
unsigned long clk;
cpu_clk = ltq_vr9_cpu_hz();
- ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
+ ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3;
switch (ocp_sel) {
case 0:
@@ -174,15 +176,18 @@ unsigned long ltq_vr9_fpi_hz(void)
unsigned long ltq_vr9_pp32_hz(void)
{
- unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3;
+ unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
unsigned long clk;
switch (clksys) {
+ case 0:
+ clk = CLOCK_500M;
+ break;
case 1:
- clk = CLOCK_450M;
+ clk = CLOCK_432M;
break;
case 2:
- clk = CLOCK_300M;
+ clk = CLOCK_288M;
break;
default:
clk = CLOCK_500M;
@@ -191,3 +196,158 @@ unsigned long ltq_vr9_pp32_hz(void)
return clk;
}
+
+unsigned long ltq_ar10_cpu_hz(void)
+{
+ unsigned int clksys;
+ int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1;
+ int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7;
+
+ switch (cpu_fs) {
+ case 0:
+ clksys = CLOCK_500M;
+ break;
+ case 1:
+ clksys = CLOCK_600M;
+ break;
+ default:
+ clksys = CLOCK_500M;
+ break;
+ }
+
+ switch (freq_div) {
+ case 0:
+ return clksys;
+ case 1:
+ return clksys >> 1;
+ case 2:
+ return clksys >> 2;
+ default:
+ return clksys;
+ }
+}
+
+unsigned long ltq_ar10_fpi_hz(void)
+{
+ int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf;
+
+ switch (freq_fpi) {
+ case 1:
+ return CLOCK_300M;
+ case 5:
+ return CLOCK_250M;
+ case 2:
+ return CLOCK_150M;
+ case 6:
+ return CLOCK_125M;
+
+ default:
+ return CLOCK_125M;
+ }
+}
+
+unsigned long ltq_ar10_pp32_hz(void)
+{
+ unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
+ unsigned long clk;
+
+ switch (clksys) {
+ case 1:
+ clk = CLOCK_250M;
+ break;
+ case 4:
+ clk = CLOCK_400M;
+ break;
+ default:
+ clk = CLOCK_250M;
+ break;
+ }
+
+ return clk;
+}
+
+unsigned long ltq_grx390_cpu_hz(void)
+{
+ unsigned int clksys;
+ int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3);
+ int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7);
+
+ switch (cpu_fs) {
+ case 0:
+ clksys = CLOCK_600M;
+ break;
+ case 1:
+ clksys = CLOCK_666M;
+ break;
+ case 2:
+ clksys = CLOCK_720M;
+ break;
+ default:
+ clksys = CLOCK_600M;
+ break;
+ }
+
+ switch (freq_div) {
+ case 0:
+ return clksys;
+ case 1:
+ return clksys >> 1;
+ case 2:
+ return clksys >> 2;
+ default:
+ return clksys;
+ }
+}
+
+unsigned long ltq_grx390_fpi_hz(void)
+{
+ /* fpi clock is derived from ddr_clk */
+ unsigned int clksys;
+ int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3);
+ int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7);
+ switch (cpu_fs) {
+ case 0:
+ clksys = CLOCK_600M;
+ break;
+ case 1:
+ clksys = CLOCK_666M;
+ break;
+ case 2:
+ clksys = CLOCK_720M;
+ break;
+ default:
+ clksys = CLOCK_600M;
+ break;
+ }
+
+ switch (freq_div) {
+ case 1:
+ return clksys >> 1;
+ case 2:
+ return clksys >> 2;
+ default:
+ return clksys >> 1;
+ }
+}
+
+unsigned long ltq_grx390_pp32_hz(void)
+{
+ unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7;
+ unsigned long clk;
+
+ switch (clksys) {
+ case 1:
+ clk = CLOCK_250M;
+ break;
+ case 2:
+ clk = CLOCK_432M;
+ break;
+ case 4:
+ clk = CLOCK_400M;
+ break;
+ default:
+ clk = CLOCK_250M;
+ break;
+ }
+ return clk;
+}
diff --git a/arch/mips/lantiq/xway/prom.c b/arch/mips/lantiq/xway/prom.c
index 248429a..8f6e02f 100644
--- a/arch/mips/lantiq/xway/prom.c
+++ b/arch/mips/lantiq/xway/prom.c
@@ -4,6 +4,7 @@
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
*/
#include <linux/export.h>
@@ -19,8 +20,11 @@
#define SOC_TWINPASS "Twinpass"
#define SOC_AMAZON_SE "Amazon_SE"
#define SOC_AR9 "AR9"
-#define SOC_GR9 "GR9"
-#define SOC_VR9 "VR9"
+#define SOC_GR9 "GRX200"
+#define SOC_VR9 "xRX200"
+#define SOC_VRX220 "xRX220"
+#define SOC_AR10 "xRX300"
+#define SOC_GRX390 "xRX330"
#define COMP_DANUBE "lantiq,danube"
#define COMP_TWINPASS "lantiq,twinpass"
@@ -28,6 +32,8 @@
#define COMP_AR9 "lantiq,ar9"
#define COMP_GR9 "lantiq,gr9"
#define COMP_VR9 "lantiq,vr9"
+#define COMP_AR10 "lantiq,ar10"
+#define COMP_GRX390 "lantiq,grx390"
#define PART_SHIFT 12
#define PART_MASK 0x0FFFFFFF
@@ -101,6 +107,12 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
i->compatible = COMP_VR9;
break;
+ case SOC_ID_VRX220:
+ i->name = SOC_VRX220;
+ i->type = SOC_TYPE_VRX220;
+ i->compatible = COMP_VR9;
+ break;
+
case SOC_ID_GRX282_2:
case SOC_ID_GRX288_2:
i->name = SOC_GR9;
@@ -108,6 +120,25 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
i->compatible = COMP_GR9;
break;
+ case SOC_ID_ARX362:
+ case SOC_ID_ARX368:
+ case SOC_ID_ARX382:
+ case SOC_ID_ARX388:
+ case SOC_ID_URX388:
+ i->name = SOC_AR10;
+ i->type = SOC_TYPE_AR10;
+ i->compatible = COMP_AR10;
+ break;
+
+ case SOC_ID_GRX383:
+ case SOC_ID_GRX369:
+ case SOC_ID_GRX387:
+ case SOC_ID_GRX389:
+ i->name = SOC_GRX390;
+ i->type = SOC_TYPE_GRX390;
+ i->compatible = COMP_GRX390;
+ break;
+
default:
unreachable();
break;
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index fe68f9a..bc29bb3 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -4,6 +4,7 @@
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
*/
#include <linux/init.h>
@@ -22,9 +23,6 @@
#include "../prom.h"
-#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
-#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
-
/* reset request register */
#define RCU_RST_REQ 0x0010
/* reset status register */
@@ -32,11 +30,33 @@
/* vr9 gphy registers */
#define RCU_GFS_ADD0_XRX200 0x0020
#define RCU_GFS_ADD1_XRX200 0x0068
+/* xRX300 gphy registers */
+#define RCU_GFS_ADD0_XRX300 0x0020
+#define RCU_GFS_ADD1_XRX300 0x0058
+#define RCU_GFS_ADD2_XRX300 0x00AC
+/* xRX330 gphy registers */
+#define RCU_GFS_ADD0_XRX330 0x0020
+#define RCU_GFS_ADD1_XRX330 0x0058
+#define RCU_GFS_ADD2_XRX330 0x00AC
+#define RCU_GFS_ADD3_XRX330 0x0264
+
+/* xbar BE flag */
+#define RCU_AHB_ENDIAN 0x004C
+#define RCU_VR9_BE_AHB1S 0x00000008
/* reboot bit */
#define RCU_RD_GPHY0_XRX200 BIT(31)
#define RCU_RD_SRST BIT(30)
#define RCU_RD_GPHY1_XRX200 BIT(29)
+/* xRX300 bits */
+#define RCU_RD_GPHY0_XRX300 BIT(31)
+#define RCU_RD_GPHY1_XRX300 BIT(29)
+#define RCU_RD_GPHY2_XRX300 BIT(28)
+/* xRX330 bits */
+#define RCU_RD_GPHY0_XRX330 BIT(31)
+#define RCU_RD_GPHY1_XRX330 BIT(29)
+#define RCU_RD_GPHY2_XRX330 BIT(28)
+#define RCU_RD_GPHY3_XRX330 BIT(10)
/* reset cause */
#define RCU_STAT_SHIFT 26
@@ -44,9 +64,60 @@
#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
+/* dwc2 USB configuration registers */
+#define RCU_USB1CFG 0x0018
+#define RCU_USB2CFG 0x0034
+
+/* USB DMA endianness bits */
+#define RCU_USBCFG_HDSEL_BIT BIT(11)
+#define RCU_USBCFG_HOST_END_BIT BIT(10)
+#define RCU_USBCFG_SLV_END_BIT BIT(9)
+
+/* USB reset bits */
+#define RCU_USBRESET 0x0010
+
+#define USBRESET_BIT BIT(4)
+
+#define RCU_USBRESET2 0x0048
+
+#define USB1RESET_BIT BIT(4)
+#define USB2RESET_BIT BIT(5)
+
+#define RCU_CFG1A 0x0038
+#define RCU_CFG1B 0x003C
+
+/* USB PMU devices */
+#define PMU_AHBM BIT(15)
+#define PMU_USB0 BIT(6)
+#define PMU_USB1 BIT(27)
+
+/* USB PHY PMU devices */
+#define PMU_USB0_P BIT(0)
+#define PMU_USB1_P BIT(26)
+
/* remapped base addr of the reset control unit */
static void __iomem *ltq_rcu_membase;
static struct device_node *ltq_rcu_np;
+static DEFINE_SPINLOCK(ltq_rcu_lock);
+
+static void ltq_rcu_w32(uint32_t val, uint32_t reg_off)
+{
+ ltq_w32(val, ltq_rcu_membase + reg_off);
+}
+
+static uint32_t ltq_rcu_r32(uint32_t reg_off)
+{
+ return ltq_r32(ltq_rcu_membase + reg_off);
+}
+
+static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ltq_rcu_lock, flags);
+ ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off);
+ spin_unlock_irqrestore(&ltq_rcu_lock, flags);
+}
/* This function is used by the watchdog driver */
int ltq_reset_cause(void)
@@ -67,15 +138,40 @@ unsigned char ltq_boot_select(void)
return RCU_BOOT_SEL(val);
}
-/* reset / boot a gphy */
-static struct ltq_xrx200_gphy_reset {
+struct ltq_gphy_reset {
u32 rd;
u32 addr;
-} xrx200_gphy[] = {
+};
+
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx200_gphy[] = {
{RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
{RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
};
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx300_gphy[] = {
+ {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300},
+ {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300},
+ {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300},
+};
+
+/* reset / boot a gphy */
+static struct ltq_gphy_reset xrx330_gphy[] = {
+ {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330},
+ {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330},
+ {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330},
+ {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330},
+};
+
+static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs,
+ dma_addr_t dev_addr)
+{
+ ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ);
+ ltq_rcu_w32(dev_addr, phy_regs->addr);
+ ltq_rcu_w32_mask(phy_regs->rd, 0, RCU_RST_REQ);
+}
+
/* reset and boot a gphy. these phys only exist on xrx200 SoC */
int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
{
@@ -86,23 +182,34 @@ int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
return -EINVAL;
}
- clk = clk_get_sys("1f203000.rcu", "gphy");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- clk_enable(clk);
-
- if (id > 1) {
- dev_err(dev, "%u is an invalid gphy id\n", id);
- return -EINVAL;
+ if (of_machine_is_compatible("lantiq,vr9")) {
+ clk = clk_get_sys("1f203000.rcu", "gphy");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ clk_enable(clk);
}
+
dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd,
- RCU_RST_REQ);
- ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd,
- RCU_RST_REQ);
+ if (of_machine_is_compatible("lantiq,vr9")) {
+ if (id >= ARRAY_SIZE(xrx200_gphy)) {
+ dev_err(dev, "%u is an invalid gphy id\n", id);
+ return -EINVAL;
+ }
+ xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr);
+ } else if (of_machine_is_compatible("lantiq,ar10")) {
+ if (id >= ARRAY_SIZE(xrx300_gphy)) {
+ dev_err(dev, "%u is an invalid gphy id\n", id);
+ return -EINVAL;
+ }
+ xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr);
+ } else if (of_machine_is_compatible("lantiq,grx390")) {
+ if (id >= ARRAY_SIZE(xrx330_gphy)) {
+ dev_err(dev, "%u is an invalid gphy id\n", id);
+ return -EINVAL;
+ }
+ xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr);
+ }
return 0;
}
@@ -200,6 +307,45 @@ static void ltq_machine_power_off(void)
unreachable();
}
+static void ltq_usb_init(void)
+{
+ /* Power for USB cores 1 & 2 */
+ ltq_pmu_enable(PMU_AHBM);
+ ltq_pmu_enable(PMU_USB0);
+ ltq_pmu_enable(PMU_USB1);
+
+ ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
+
+ /* Enable USB PHY power for cores 1 & 2 */
+ ltq_pmu_enable(PMU_USB0_P);
+ ltq_pmu_enable(PMU_USB1_P);
+
+ /* Configure cores to host mode */
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
+ RCU_USB1CFG);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
+ RCU_USB2CFG);
+
+ /* Select DMA endianness (Host-endian: big-endian) */
+ ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
+ | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
+ ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
+ | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
+
+ /* Hard reset USB state machines */
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
+ udelay(50 * 1000);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
+
+ /* Soft reset USB state machines */
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
+ | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
+ udelay(50 * 1000);
+ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
+ & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
+}
+
static int __init mips_reboot_setup(void)
{
struct resource res;
@@ -216,13 +362,21 @@ static int __init mips_reboot_setup(void)
if (of_address_to_resource(ltq_rcu_np, 0, &res))
panic("Failed to get rcu memory range");
- if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
+ if (!request_mem_region(res.start, resource_size(&res), res.name))
pr_err("Failed to request rcu memory");
ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
if (!ltq_rcu_membase)
panic("Failed to remap core memory");
+ if (of_machine_is_compatible("lantiq,ar9") ||
+ of_machine_is_compatible("lantiq,vr9"))
+ ltq_usb_init();
+
+ if (of_machine_is_compatible("lantiq,vr9"))
+ ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S,
+ RCU_AHB_ENDIAN);
+
_machine_restart = ltq_machine_restart;
_machine_halt = ltq_machine_halt;
pm_power_off = ltq_machine_power_off;
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 2b15491..80554e8 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -4,11 +4,13 @@
* by the Free Software Foundation.
*
* Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
*/
#include <linux/ioport.h>
#include <linux/export.h>
#include <linux/clkdev.h>
+#include <linux/spinlock.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
@@ -18,16 +20,18 @@
#include "../clk.h"
#include "../prom.h"
-/* clock control register */
+/* clock control register for legacy */
#define CGU_IFCCR 0x0018
#define CGU_IFCCR_VR9 0x0024
-/* system clock register */
+/* system clock register for legacy */
#define CGU_SYS 0x0010
/* pci control register */
#define CGU_PCICR 0x0034
#define CGU_PCICR_VR9 0x0038
/* ephy configuration register */
#define CGU_EPHY 0x10
+
+/* Legacy PMU register for ar9, ase, danube */
/* power control register */
#define PMU_PWDCR 0x1C
/* power status register */
@@ -41,13 +45,56 @@
/* power status register */
#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
+
+/* PMU register for ar10 and grx390 */
+
+/* First register set */
+#define PMU_CLK_SR 0x20 /* status */
+#define PMU_CLK_CR_A 0x24 /* Enable */
+#define PMU_CLK_CR_B 0x28 /* Disable */
+/* Second register set */
+#define PMU_CLK_SR1 0x30 /* status */
+#define PMU_CLK_CR1_A 0x34 /* Enable */
+#define PMU_CLK_CR1_B 0x38 /* Disable */
+/* Third register set */
+#define PMU_ANA_SR 0x40 /* status */
+#define PMU_ANA_CR_A 0x44 /* Enable */
+#define PMU_ANA_CR_B 0x48 /* Disable */
+
+/* Status */
+static u32 pmu_clk_sr[] = {
+ PMU_CLK_SR,
+ PMU_CLK_SR1,
+ PMU_ANA_SR,
+};
+
+/* Enable */
+static u32 pmu_clk_cr_a[] = {
+ PMU_CLK_CR_A,
+ PMU_CLK_CR1_A,
+ PMU_ANA_CR_A,
+};
+
+/* Disable */
+static u32 pmu_clk_cr_b[] = {
+ PMU_CLK_CR_B,
+ PMU_CLK_CR1_B,
+ PMU_ANA_CR_B,
+};
+
+#define PWDCR_EN_XRX(x) (pmu_clk_cr_a[(x)])
+#define PWDCR_DIS_XRX(x) (pmu_clk_cr_b[(x)])
+#define PWDSR_XRX(x) (pmu_clk_sr[(x)])
+
/* clock gates that we can en/disable */
#define PMU_USB0_P BIT(0)
+#define PMU_ASE_SDIO BIT(2) /* ASE special */
#define PMU_PCI BIT(4)
#define PMU_DMA BIT(5)
#define PMU_USB0 BIT(6)
#define PMU_ASC0 BIT(7)
#define PMU_EPHY BIT(7) /* ase */
+#define PMU_USIF BIT(7) /* from vr9 until grx390 */
#define PMU_SPI BIT(8)
#define PMU_DFE BIT(9)
#define PMU_EBU BIT(10)
@@ -56,12 +103,15 @@
#define PMU_AHBS BIT(13) /* vr9 */
#define PMU_FPI BIT(14)
#define PMU_AHBM BIT(15)
+#define PMU_SDIO BIT(16) /* danube, ar9, vr9 */
#define PMU_ASC1 BIT(17)
#define PMU_PPE_QSB BIT(18)
#define PMU_PPE_SLL01 BIT(19)
+#define PMU_DEU BIT(20)
#define PMU_PPE_TC BIT(21)
#define PMU_PPE_EMA BIT(22)
#define PMU_PPE_DPLUM BIT(23)
+#define PMU_PPE_DP BIT(23)
#define PMU_PPE_DPLUS BIT(24)
#define PMU_USB1_P BIT(26)
#define PMU_USB1 BIT(27)
@@ -70,30 +120,59 @@
#define PMU_GPHY BIT(30)
#define PMU_PCIE_CLK BIT(31)
-#define PMU1_PCIE_PHY BIT(0)
+#define PMU1_PCIE_PHY BIT(0) /* vr9-specific,moved in ar10/grx390 */
#define PMU1_PCIE_CTL BIT(1)
#define PMU1_PCIE_PDI BIT(4)
#define PMU1_PCIE_MSI BIT(5)
+#define PMU1_CKE BIT(6)
+#define PMU1_PCIE1_CTL BIT(17)
+#define PMU1_PCIE1_PDI BIT(20)
+#define PMU1_PCIE1_MSI BIT(21)
+#define PMU1_PCIE2_CTL BIT(25)
+#define PMU1_PCIE2_PDI BIT(26)
+#define PMU1_PCIE2_MSI BIT(27)
+
+#define PMU_ANALOG_USB0_P BIT(0)
+#define PMU_ANALOG_USB1_P BIT(1)
+#define PMU_ANALOG_PCIE0_P BIT(8)
+#define PMU_ANALOG_PCIE1_P BIT(9)
+#define PMU_ANALOG_PCIE2_P BIT(10)
+#define PMU_ANALOG_DSL_AFE BIT(16)
+#define PMU_ANALOG_DCDC_2V5 BIT(17)
+#define PMU_ANALOG_DCDC_1VX BIT(18)
+#define PMU_ANALOG_DCDC_1V0 BIT(19)
#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y))
#define pmu_r32(x) ltq_r32(pmu_membase + (x))
+#define XBAR_ALWAYS_LAST 0x430
+#define XBAR_FPI_BURST_EN BIT(1)
+#define XBAR_AHB_BURST_EN BIT(2)
+
+#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y))
+#define xbar_r32(x) ltq_r32(ltq_xbar_membase + (x))
+
static void __iomem *pmu_membase;
+static void __iomem *ltq_xbar_membase;
void __iomem *ltq_cgu_membase;
void __iomem *ltq_ebu_membase;
static u32 ifccr = CGU_IFCCR;
static u32 pcicr = CGU_PCICR;
+static DEFINE_SPINLOCK(g_pmu_lock);
+
/* legacy function kept alive to ease clkdev transition */
void ltq_pmu_enable(unsigned int module)
{
- int err = 1000000;
+ int retry = 1000000;
+ spin_lock(&g_pmu_lock);
pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
- do {} while (--err && (pmu_r32(PMU_PWDSR) & module));
+ do {} while (--retry && (pmu_r32(PMU_PWDSR) & module));
+ spin_unlock(&g_pmu_lock);
- if (!err)
+ if (!retry)
panic("activating PMU module failed!");
}
EXPORT_SYMBOL(ltq_pmu_enable);
@@ -101,7 +180,15 @@ EXPORT_SYMBOL(ltq_pmu_enable);
/* legacy function kept alive to ease clkdev transition */
void ltq_pmu_disable(unsigned int module)
{
+ int retry = 1000000;
+
+ spin_lock(&g_pmu_lock);
pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
+ do {} while (--retry && (!(pmu_r32(PMU_PWDSR) & module)));
+ spin_unlock(&g_pmu_lock);
+
+ if (!retry)
+ pr_warn("deactivating PMU module failed!");
}
EXPORT_SYMBOL(ltq_pmu_disable);
@@ -123,9 +210,20 @@ static int pmu_enable(struct clk *clk)
{
int retry = 1000000;
- pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
- PWDCR(clk->module));
- do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
+ if (of_machine_is_compatible("lantiq,ar10")
+ || of_machine_is_compatible("lantiq,grx390")) {
+ pmu_w32(clk->bits, PWDCR_EN_XRX(clk->module));
+ do {} while (--retry &&
+ (!(pmu_r32(PWDSR_XRX(clk->module)) & clk->bits)));
+
+ } else {
+ spin_lock(&g_pmu_lock);
+ pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
+ PWDCR(clk->module));
+ do {} while (--retry &&
+ (pmu_r32(PWDSR(clk->module)) & clk->bits));
+ spin_unlock(&g_pmu_lock);
+ }
if (!retry)
panic("activating PMU module failed!");
@@ -136,8 +234,24 @@ static int pmu_enable(struct clk *clk)
/* disable a clock gate */
static void pmu_disable(struct clk *clk)
{
- pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
- PWDCR(clk->module));
+ int retry = 1000000;
+
+ if (of_machine_is_compatible("lantiq,ar10")
+ || of_machine_is_compatible("lantiq,grx390")) {
+ pmu_w32(clk->bits, PWDCR_DIS_XRX(clk->module));
+ do {} while (--retry &&
+ (pmu_r32(PWDSR_XRX(clk->module)) & clk->bits));
+ } else {
+ spin_lock(&g_pmu_lock);
+ pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
+ PWDCR(clk->module));
+ do {} while (--retry &&
+ (!(pmu_r32(PWDSR(clk->module)) & clk->bits)));
+ spin_unlock(&g_pmu_lock);
+ }
+
+ if (!retry)
+ pr_warn("deactivating PMU module failed!");
}
/* the pci enable helper */
@@ -179,6 +293,16 @@ static void pci_ext_disable(struct clk *clk)
ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
}
+static void xbar_fpi_burst_disable(void)
+{
+ u32 reg;
+
+ /* bit 1 as 1 --burst; bit 1 as 0 -- single */
+ reg = xbar_r32(XBAR_ALWAYS_LAST);
+ reg &= ~XBAR_FPI_BURST_EN;
+ xbar_w32(reg, XBAR_ALWAYS_LAST);
+}
+
/* enable a clockout source */
static int clkout_enable(struct clk *clk)
{
@@ -202,8 +326,8 @@ static int clkout_enable(struct clk *clk)
}
/* manage the clock gates via PMU */
-static void clkdev_add_pmu(const char *dev, const char *con,
- unsigned int module, unsigned int bits)
+static void clkdev_add_pmu(const char *dev, const char *con, bool deactivate,
+ unsigned int module, unsigned int bits)
{
struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
@@ -214,6 +338,13 @@ static void clkdev_add_pmu(const char *dev, const char *con,
clk->disable = pmu_disable;
clk->module = module;
clk->bits = bits;
+ if (deactivate) {
+ /*
+ * Disable it during the initialization. Module should enable
+ * when used
+ */
+ pmu_disable(clk);
+ }
clkdev_add(&clk->cl);
}
@@ -312,12 +443,12 @@ void __init ltq_soc_init(void)
of_address_to_resource(np_ebu, 0, &res_ebu))
panic("Failed to get core resources");
- if ((request_mem_region(res_pmu.start, resource_size(&res_pmu),
- res_pmu.name) < 0) ||
- (request_mem_region(res_cgu.start, resource_size(&res_cgu),
- res_cgu.name) < 0) ||
- (request_mem_region(res_ebu.start, resource_size(&res_ebu),
- res_ebu.name) < 0))
+ if (!request_mem_region(res_pmu.start, resource_size(&res_pmu),
+ res_pmu.name) ||
+ !request_mem_region(res_cgu.start, resource_size(&res_cgu),
+ res_cgu.name) ||
+ !request_mem_region(res_ebu.start, resource_size(&res_ebu),
+ res_ebu.name))
pr_err("Failed to request core resources");
pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu));
@@ -328,17 +459,37 @@ void __init ltq_soc_init(void)
if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
panic("Failed to remap core resources");
+ if (of_machine_is_compatible("lantiq,vr9")) {
+ struct resource res_xbar;
+ struct device_node *np_xbar =
+ of_find_compatible_node(NULL, NULL,
+ "lantiq,xbar-xway");
+
+ if (!np_xbar)
+ panic("Failed to load xbar nodes from devicetree");
+ if (of_address_to_resource(np_pmu, 0, &res_xbar))
+ panic("Failed to get xbar resources");
+ if (request_mem_region(res_xbar.start, resource_size(&res_xbar),
+ res_xbar.name) < 0)
+ panic("Failed to get xbar resources");
+
+ ltq_xbar_membase = ioremap_nocache(res_xbar.start,
+ resource_size(&res_xbar));
+ if (!ltq_xbar_membase)
+ panic("Failed to remap xbar resources");
+ }
+
/* make sure to unprotect the memory region where flash is located */
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
/* add our generic xway clocks */
- clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI);
- clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0);
- clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT);
- clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP);
- clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA);
- clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI);
- clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU);
+ clkdev_add_pmu("10000000.fpi", NULL, 0, 0, PMU_FPI);
+ clkdev_add_pmu("1e100400.serial", NULL, 0, 0, PMU_ASC0);
+ clkdev_add_pmu("1e100a00.gptu", NULL, 1, 0, PMU_GPT);
+ clkdev_add_pmu("1e100bb0.stp", NULL, 1, 0, PMU_STP);
+ clkdev_add_pmu("1e104100.dma", NULL, 1, 0, PMU_DMA);
+ clkdev_add_pmu("1e100800.spi", NULL, 1, 0, PMU_SPI);
+ clkdev_add_pmu("1e105300.ebu", NULL, 0, 0, PMU_EBU);
clkdev_add_clkout();
/* add the soc dependent clocks */
@@ -346,14 +497,30 @@ void __init ltq_soc_init(void)
ifccr = CGU_IFCCR_VR9;
pcicr = CGU_PCICR_VR9;
} else {
- clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE);
+ clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE);
}
if (!of_machine_is_compatible("lantiq,ase")) {
- clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1);
+ clkdev_add_pmu("1e100c00.serial", NULL, 0, 0, PMU_ASC1);
clkdev_add_pci();
}
+ if (of_machine_is_compatible("lantiq,grx390") ||
+ of_machine_is_compatible("lantiq,ar10")) {
+ clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P);
+ clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P);
+ /* rc 0 */
+ clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
+ clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
+ clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
+ clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
+ /* rc 1 */
+ clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P);
+ clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI);
+ clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI);
+ clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL);
+ }
+
if (of_machine_is_compatible("lantiq,ase")) {
if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
clkdev_add_static(CLOCK_266M, CLOCK_133M,
@@ -361,28 +528,84 @@ void __init ltq_soc_init(void)
else
clkdev_add_static(CLOCK_133M, CLOCK_133M,
CLOCK_133M, CLOCK_133M);
- clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY),
- clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY);
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
+ clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
+ clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
+ clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+ } else if (of_machine_is_compatible("lantiq,grx390")) {
+ clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(),
+ ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz());
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+ /* rc 2 */
+ clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
+ clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
+ clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
+ clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
+ clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ } else if (of_machine_is_compatible("lantiq,ar10")) {
+ clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(),
+ ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+ clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
+ PMU_PPE_DP | PMU_PPE_TC);
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
} else if (of_machine_is_compatible("lantiq,vr9")) {
clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
- clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY);
- clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK);
- clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI);
- clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
- clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
- clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
- clkdev_add_pmu("1e108000.eth", NULL, 0,
+ clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM);
+ clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
+ clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM);
+ clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
+ clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
+ clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
+ clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI);
+ clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
+ clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
+
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
PMU_PPE_QSB | PMU_PPE_TOP);
- clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY);
+ clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+ clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
} else if (of_machine_is_compatible("lantiq,ar9")) {
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
ltq_ar9_fpi_hz(), CLOCK_250M);
- clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH);
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+ clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
+ clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
+ clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+ clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+ clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
}
+
+ if (of_machine_is_compatible("lantiq,vr9"))
+ xbar_fpi_burst_disable();
}
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
index 2bcd839..b420958 100644
--- a/arch/mips/lasat/picvue_proc.c
+++ b/arch/mips/lasat/picvue_proc.c
@@ -22,7 +22,6 @@
static DEFINE_MUTEX(pvc_mutex);
static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
static int pvc_linedata[PVC_NLINES];
-static struct proc_dir_entry *pvc_display_dir;
static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
#define DISPLAY_DIR_NAME "display"
static int scroll_dir, scroll_interval;
@@ -169,22 +168,17 @@ void pvc_proc_timerfunc(unsigned long data)
static void pvc_proc_cleanup(void)
{
- int i;
- for (i = 0; i < PVC_NLINES; i++)
- remove_proc_entry(pvc_linename[i], pvc_display_dir);
- remove_proc_entry("scroll", pvc_display_dir);
- remove_proc_entry(DISPLAY_DIR_NAME, NULL);
-
+ remove_proc_subtree(DISPLAY_DIR_NAME, NULL);
del_timer_sync(&timer);
}
static int __init pvc_proc_init(void)
{
- struct proc_dir_entry *proc_entry;
+ struct proc_dir_entry *dir, *proc_entry;
int i;
- pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
- if (pvc_display_dir == NULL)
+ dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
+ if (dir == NULL)
goto error;
for (i = 0; i < PVC_NLINES; i++) {
@@ -192,12 +186,12 @@ static int __init pvc_proc_init(void)
pvc_linedata[i] = i;
}
for (i = 0; i < PVC_NLINES; i++) {
- proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir,
+ proc_entry = proc_create_data(pvc_linename[i], 0644, dir,
&pvc_line_proc_fops, &pvc_linedata[i]);
if (proc_entry == NULL)
goto error;
}
- proc_entry = proc_create("scroll", 0644, pvc_display_dir,
+ proc_entry = proc_create("scroll", 0644, dir,
&pvc_scroll_proc_fops);
if (proc_entry == NULL)
goto error;
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 1e9e900..0344e57 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
# libgcc-style stuff needed in the kernel
-obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
+obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c
new file mode 100644
index 0000000..77e5f9c1
--- /dev/null
+++ b/arch/mips/lib/bswapdi.c
@@ -0,0 +1,15 @@
+#include <linux/module.h>
+
+unsigned long long __bswapdi2(unsigned long long u)
+{
+ return (((u) & 0xff00000000000000ull) >> 56) |
+ (((u) & 0x00ff000000000000ull) >> 40) |
+ (((u) & 0x0000ff0000000000ull) >> 24) |
+ (((u) & 0x000000ff00000000ull) >> 8) |
+ (((u) & 0x00000000ff000000ull) << 8) |
+ (((u) & 0x0000000000ff0000ull) << 24) |
+ (((u) & 0x000000000000ff00ull) << 40) |
+ (((u) & 0x00000000000000ffull) << 56);
+}
+
+EXPORT_SYMBOL(__bswapdi2);
diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c
new file mode 100644
index 0000000..2b302ff
--- /dev/null
+++ b/arch/mips/lib/bswapsi.c
@@ -0,0 +1,11 @@
+#include <linux/module.h>
+
+unsigned int __bswapsi2(unsigned int u)
+{
+ return (((u) & 0xff000000) >> 24) |
+ (((u) & 0x00ff0000) >> 8) |
+ (((u) & 0x0000ff00) << 8) |
+ (((u) & 0x000000ff) << 24);
+}
+
+EXPORT_SYMBOL(__bswapsi2);
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index b8e63fd..8f0019a 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -283,6 +283,8 @@ LEAF(memset)
1:
#ifndef CONFIG_EVA
FEXPORT(__bzero)
+#else
+FEXPORT(__bzero_kernel)
#endif
__BUILD_BZERO LEGACY_MODE
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
index 272af8a..5530070 100644
--- a/arch/mips/lib/mips-atomic.c
+++ b/arch/mips/lib/mips-atomic.c
@@ -57,7 +57,6 @@ notrace void arch_local_irq_disable(void)
}
EXPORT_SYMBOL(arch_local_irq_disable);
-
notrace unsigned long arch_local_irq_save(void)
{
unsigned long flags;
@@ -111,31 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags)
}
EXPORT_SYMBOL(arch_local_irq_restore);
-
-notrace void __arch_local_irq_restore(unsigned long flags)
-{
- unsigned long __tmp1;
-
- preempt_disable();
-
- __asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set noat \n"
- " mfc0 $1, $12 \n"
- " andi %[flags], 1 \n"
- " ori $1, 0x1f \n"
- " xori $1, 0x1f \n"
- " or %[flags], $1 \n"
- " mtc0 %[flags], $12 \n"
- " " __stringify(__irq_disable_hazard) " \n"
- " .set pop \n"
- : [flags] "=r" (__tmp1)
- : "0" (flags)
- : "memory");
-
- preempt_enable();
-}
-EXPORT_SYMBOL(__arch_local_irq_restore);
-
-#endif /* !CONFIG_CPU_MIPSR2 */
+#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 497912b..8e6e292 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -120,11 +120,6 @@ config RS780_HPET
If unsure, say Yes.
-config LOONGSON_SUSPEND
- bool
- default y
- depends on CPU_SUPPORTS_CPUFREQ && SUSPEND
-
config LOONGSON_UART_BASE
bool
default y
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
index 2e48e83..85d8089 100644
--- a/arch/mips/loongson64/Platform
+++ b/arch/mips/loongson64/Platform
@@ -22,6 +22,27 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
endif
endif
+cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
+#
+# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
+# as MIPS64 R2; older versions as just R1. This leaves the possibility open
+# that GCC might generate R2 code for -march=loongson3a which then is rejected
+# by GAS. The cc-option can't probe for this behaviour so -march=loongson3a
+# can't easily be used safely within the kbuild framework.
+#
+ifeq ($(call cc-ifversion, -ge, 0409, y), y)
+ ifeq ($(call ld-ifversion, -ge, 22500000, y), y)
+ cflags-$(CONFIG_CPU_LOONGSON3) += \
+ $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+ else
+ cflags-$(CONFIG_CPU_LOONGSON3) += \
+ $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+ endif
+else
+ cflags-$(CONFIG_CPU_LOONGSON3) += \
+ $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+endif
+
#
# Loongson Machines' Support
#
diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile
index f2e8153..074d9cb 100644
--- a/arch/mips/loongson64/common/Makefile
+++ b/arch/mips/loongson64/common/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_CS5536) += cs5536/
# Suspend Support
#
-obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
#
# Big Memory (SWIOTLB) Support
diff --git a/arch/mips/loongson64/lemote-2f/Makefile b/arch/mips/loongson64/lemote-2f/Makefile
index 4f9eaa3..08b8abc 100644
--- a/arch/mips/loongson64/lemote-2f/Makefile
+++ b/arch/mips/loongson64/lemote-2f/Makefile
@@ -8,4 +8,4 @@ obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o
# Suspend Support
#
-obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c
index bf9f1a7..a2631a5 100644
--- a/arch/mips/loongson64/loongson-3/hpet.c
+++ b/arch/mips/loongson64/loongson-3/hpet.c
@@ -13,6 +13,9 @@
#define SMBUS_PCI_REG64 0x64
#define SMBUS_PCI_REGB4 0xb4
+#define HPET_MIN_CYCLES 64
+#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
static DEFINE_SPINLOCK(hpet_lock);
DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
@@ -161,8 +164,9 @@ static int hpet_next_event(unsigned long delta,
cnt += delta;
hpet_write(HPET_T0_CMP, cnt);
- res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
- return res;
+ res = (int)(cnt - hpet_read(HPET_COUNTER));
+
+ return res < HPET_MIN_CYCLES ? -ETIME : 0;
}
static irqreturn_t hpet_irq_handler(int irq, void *data)
@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void)
cd->cpumask = cpumask_of(cpu);
clockevent_set_clock(cd, HPET_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = 5000;
+ cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
clockevents_register_device(cd);
setup_irq(HPET_T0_IRQ, &hpet_irq);
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 1a4738a..509832a9 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -30,13 +30,13 @@
#include "smp.h"
DEFINE_PER_CPU(int, cpu_state);
-DEFINE_PER_CPU(uint32_t, core0_c0count);
static void *ipi_set0_regs[16];
static void *ipi_clear0_regs[16];
static void *ipi_status0_regs[16];
static void *ipi_en0_regs[16];
static void *ipi_mailbox_buf[16];
+static uint32_t core0_c0count[NR_CPUS];
/* read a 32bit value from ipi register */
#define loongson3_ipi_read32(addr) readl(addr)
@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
if (action & SMP_ASK_C0COUNT) {
BUG_ON(cpu != 0);
c0count = read_c0_count();
- for (i = 1; i < num_possible_cpus(); i++)
- per_cpu(core0_c0count, i) = c0count;
+ c0count = c0count ? c0count : 1;
+ for (i = 1; i < nr_cpu_ids; i++)
+ core0_c0count[i] = c0count;
+ __wbflush(); /* Let others see the result ASAP */
}
}
-#define MAX_LOOPS 1111
+#define MAX_LOOPS 800
/*
* SMP init and finish on secondary CPUs
*/
@@ -305,16 +307,20 @@ static void loongson3_init_secondary(void)
cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
i = 0;
- __this_cpu_write(core0_c0count, 0);
+ core0_c0count[cpu] = 0;
loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
- while (!__this_cpu_read(core0_c0count)) {
+ while (!core0_c0count[cpu]) {
i++;
cpu_relax();
}
if (i > MAX_LOOPS)
i = MAX_LOOPS;
- initcount = __this_cpu_read(core0_c0count) + i;
+ if (cpu_data[cpu].package)
+ initcount = core0_c0count[cpu] + i;
+ else /* Local access is faster for loops */
+ initcount = core0_c0count[cpu] + i/2;
+
write_c0_count(initcount);
}
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 32f0e19..cdfd44f 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -1266,6 +1266,8 @@ branch_common:
*/
sig = mips_dsemul(xcp, ir,
contpc);
+ if (sig < 0)
+ break;
if (sig)
xcp->cp0_epc = bcpc;
/*
@@ -1319,6 +1321,8 @@ branch_common:
* instruction in the dslot
*/
sig = mips_dsemul(xcp, ir, contpc);
+ if (sig < 0)
+ break;
if (sig)
xcp->cp0_epc = bcpc;
/* SIGILL forces out of the emulation loop. */
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index 926d56b..eb96485 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -23,27 +23,39 @@
union ieee754dp ieee754dp_neg(union ieee754dp x)
{
- unsigned int oldrm;
union ieee754dp y;
- oldrm = ieee754_csr.rm;
- ieee754_csr.rm = FPU_CSR_RD;
- y = ieee754dp_sub(ieee754dp_zero(0), x);
- ieee754_csr.rm = oldrm;
+ if (ieee754_csr.abs2008) {
+ y = x;
+ DPSIGN(y) = !DPSIGN(x);
+ } else {
+ unsigned int oldrm;
+
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ y = ieee754dp_sub(ieee754dp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ }
return y;
}
union ieee754dp ieee754dp_abs(union ieee754dp x)
{
- unsigned int oldrm;
union ieee754dp y;
- oldrm = ieee754_csr.rm;
- ieee754_csr.rm = FPU_CSR_RD;
- if (DPSIGN(x))
- y = ieee754dp_sub(ieee754dp_zero(0), x);
- else
- y = ieee754dp_add(ieee754dp_zero(0), x);
- ieee754_csr.rm = oldrm;
+ if (ieee754_csr.abs2008) {
+ y = x;
+ DPSIGN(y) = 0;
+ } else {
+ unsigned int oldrm;
+
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ if (DPSIGN(x))
+ y = ieee754dp_sub(ieee754dp_zero(0), x);
+ else
+ y = ieee754dp_add(ieee754dp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ }
return y;
}
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
index 6ffc336..f398561 100644
--- a/arch/mips/math-emu/dp_tint.c
+++ b/arch/mips/math-emu/dp_tint.c
@@ -38,10 +38,13 @@ int ieee754dp_tint(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
- case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
+ case IEEE754_CLASS_INF:
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754si_overflow(xs);
+
case IEEE754_CLASS_ZERO:
return 0;
@@ -53,7 +56,7 @@ int ieee754dp_tint(union ieee754dp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754si_indef();
+ return ieee754si_overflow(xs);
}
/* oh gawd */
if (xe > DP_FBITS) {
@@ -93,7 +96,7 @@ int ieee754dp_tint(union ieee754dp x)
if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754si_indef();
+ return ieee754si_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
index 9cdc145..748fa10 100644
--- a/arch/mips/math-emu/dp_tlong.c
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -38,10 +38,13 @@ s64 ieee754dp_tlong(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
- case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
+ case IEEE754_CLASS_INF:
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754di_overflow(xs);
+
case IEEE754_CLASS_ZERO:
return 0;
@@ -56,7 +59,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754di_indef();
+ return ieee754di_overflow(xs);
}
/* oh gawd */
if (xe > DP_FBITS) {
@@ -97,7 +100,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
if ((xm >> 63) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754di_indef();
+ return ieee754di_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index cbb36c1..46b964d 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -31,17 +31,41 @@ struct emuframe {
unsigned long epc;
};
+/*
+ * Set up an emulation frame for instruction IR, from a delay slot of
+ * a branch jumping to CPC. Return 0 if successful, -1 if no emulation
+ * required, otherwise a signal number causing a frame setup failure.
+ */
int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
+ int isa16 = get_isa16_mode(regs->cp0_epc);
+ mips_instruction break_math;
struct emuframe __user *fr;
int err;
- if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) ||
- (ir == 0)) {
- /* NOP is easy */
- regs->cp0_epc = cpc;
- clear_delay_slot(regs);
- return 0;
+ /* NOP is easy */
+ if (ir == 0)
+ return -1;
+
+ /* microMIPS instructions */
+ if (isa16) {
+ union mips_instruction insn = { .word = ir };
+
+ /* NOP16 aka MOVE16 $0, $0 */
+ if ((ir >> 16) == MM_NOP16)
+ return -1;
+
+ /* ADDIUPC */
+ if (insn.mm_a_format.opcode == mm_addiupc_op) {
+ unsigned int rs;
+ s32 v;
+
+ rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2);
+ v = regs->cp0_epc & ~3;
+ v += insn.mm_a_format.simmediate << 2;
+ regs->regs[rs] = (long)v;
+ return -1;
+ }
}
pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
@@ -55,14 +79,10 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
* Algorithmics used a system call instruction, and
* borrowed that vector. MIPS/Linux version is a bit
* more heavyweight in the interests of portability and
- * multiprocessor support. For Linux we generate a
- * an unaligned access and force an address error exception.
- *
- * For embedded systems (stand-alone) we prefer to use a
- * non-existing CP1 instruction. This prevents us from emulating
- * branches, but gives us a cleaner interface to the exception
- * handler (single entry point).
+ * multiprocessor support. For Linux we use a BREAK 514
+ * instruction causing a breakpoint exception.
*/
+ break_math = BREAK_MATH(isa16);
/* Ensure that the two instructions are in the same cache line */
fr = (struct emuframe __user *)
@@ -72,14 +92,18 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
return SIGBUS;
- if (get_isa16_mode(regs->cp0_epc)) {
- err = __put_user(ir >> 16, (u16 __user *)(&fr->emul));
- err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2));
- err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst));
- err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2));
+ if (isa16) {
+ err = __put_user(ir >> 16,
+ (u16 __user *)(&fr->emul));
+ err |= __put_user(ir & 0xffff,
+ (u16 __user *)((long)(&fr->emul) + 2));
+ err |= __put_user(break_math >> 16,
+ (u16 __user *)(&fr->badinst));
+ err |= __put_user(break_math & 0xffff,
+ (u16 __user *)((long)(&fr->badinst) + 2));
} else {
err = __put_user(ir, &fr->emul);
- err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst);
+ err |= __put_user(break_math, &fr->badinst);
}
err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
@@ -90,8 +114,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
return SIGBUS;
}
- regs->cp0_epc = ((unsigned long) &fr->emul) |
- get_isa16_mode(regs->cp0_epc);
+ regs->cp0_epc = (unsigned long)&fr->emul | isa16;
flush_cache_sigtramp((unsigned long)&fr->emul);
@@ -100,6 +123,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
int do_dsemulret(struct pt_regs *xcp)
{
+ int isa16 = get_isa16_mode(xcp->cp0_epc);
struct emuframe __user *fr;
unsigned long epc;
u32 insn, cookie;
@@ -122,16 +146,19 @@ int do_dsemulret(struct pt_regs *xcp)
* - Is the instruction pointed to by the EPC an BREAK_MATH?
* - Is the following memory word the BD_COOKIE?
*/
- if (get_isa16_mode(xcp->cp0_epc)) {
- err = __get_user(instr[0], (u16 __user *)(&fr->badinst));
- err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2));
+ if (isa16) {
+ err = __get_user(instr[0],
+ (u16 __user *)(&fr->badinst));
+ err |= __get_user(instr[1],
+ (u16 __user *)((long)(&fr->badinst) + 2));
insn = (instr[0] << 16) | instr[1];
} else {
err = __get_user(insn, &fr->badinst);
}
err |= __get_user(cookie, &fr->cookie);
- if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
+ if (unlikely(err ||
+ insn != BREAK_MATH(isa16) || cookie != BD_COOKIE)) {
MIPS_FPU_EMU_INC_STATS(errors);
return 0;
}
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
index 8e97acb..e16ae7b 100644
--- a/arch/mips/math-emu/ieee754.c
+++ b/arch/mips/math-emu/ieee754.c
@@ -59,7 +59,8 @@ const union ieee754dp __ieee754dp_spcvals[] = {
DPCNST(1, 3, 0x4000000000000ULL), /* - 10.0 */
DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL), /* + infinity */
DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL), /* - infinity */
- DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + indef quiet Nan */
+ DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + ind legacy qNaN */
+ DPCNST(0, DP_EMAX + 1, 0x8000000000000ULL), /* + indef 2008 qNaN */
DPCNST(0, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* + max */
DPCNST(1, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* - max */
DPCNST(0, DP_EMIN, 0x0000000000000ULL), /* + min normal */
@@ -82,7 +83,8 @@ const union ieee754sp __ieee754sp_spcvals[] = {
SPCNST(1, 3, 0x200000), /* - 10.0 */
SPCNST(0, SP_EMAX + 1, 0x000000), /* + infinity */
SPCNST(1, SP_EMAX + 1, 0x000000), /* - infinity */
- SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef quiet Nan */
+ SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef legacy quiet NaN */
+ SPCNST(0, SP_EMAX + 1, 0x400000), /* + indef 2008 quiet NaN */
SPCNST(0, SP_EMAX, 0x7FFFFF), /* + max normal */
SPCNST(1, SP_EMAX, 0x7FFFFF), /* - max normal */
SPCNST(0, SP_EMIN, 0x000000), /* + min normal */
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index df94720..d3be351 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -221,15 +221,16 @@ union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
#define IEEE754_SPCVAL_NTEN 5 /* -10.0 */
#define IEEE754_SPCVAL_PINFINITY 6 /* +inf */
#define IEEE754_SPCVAL_NINFINITY 7 /* -inf */
-#define IEEE754_SPCVAL_INDEF 8 /* quiet NaN */
-#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
-#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
-#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
-#define IEEE754_SPCVAL_NMIN 12 /* -min norm */
-#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
-#define IEEE754_SPCVAL_NMIND 14 /* -min denorm */
-#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
+#define IEEE754_SPCVAL_INDEF_LEG 8 /* legacy quiet NaN */
+#define IEEE754_SPCVAL_INDEF_2008 9 /* IEEE 754-2008 quiet NaN */
+#define IEEE754_SPCVAL_PMAX 10 /* +max norm */
+#define IEEE754_SPCVAL_NMAX 11 /* -max norm */
+#define IEEE754_SPCVAL_PMIN 12 /* +min norm */
+#define IEEE754_SPCVAL_NMIN 13 /* -min norm */
+#define IEEE754_SPCVAL_PMIND 14 /* +min denorm */
+#define IEEE754_SPCVAL_NMIND 15 /* -min denorm */
+#define IEEE754_SPCVAL_P1E31 16 /* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63 17 /* + 1.0e63 */
extern const union ieee754dp __ieee754dp_spcvals[];
extern const union ieee754sp __ieee754sp_spcvals[];
@@ -243,7 +244,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+ ieee754_csr.nan2008])
#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -254,7 +256,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+ ieee754_csr.nan2008])
#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -266,12 +269,25 @@ extern const union ieee754sp __ieee754sp_spcvals[];
*/
static inline int ieee754si_indef(void)
{
- return INT_MAX;
+ return ieee754_csr.nan2008 ? 0 : INT_MAX;
}
static inline s64 ieee754di_indef(void)
{
- return S64_MAX;
+ return ieee754_csr.nan2008 ? 0 : S64_MAX;
+}
+
+/*
+ * Overflow integer value
+ */
+static inline int ieee754si_overflow(int xs)
+{
+ return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX;
+}
+
+static inline s64 ieee754di_overflow(int xs)
+{
+ return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX;
}
/* result types for xctx.rt */
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
index 522d843..ad3c734 100644
--- a/arch/mips/math-emu/ieee754dp.c
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -37,8 +37,11 @@ static inline int ieee754dp_isnan(union ieee754dp x)
static inline int ieee754dp_issnan(union ieee754dp x)
{
+ int qbit;
+
assert(ieee754dp_isnan(x));
- return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+ qbit = (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+ return ieee754_csr.nan2008 ^ qbit;
}
@@ -51,7 +54,12 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
assert(ieee754dp_issnan(r));
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754dp_indef();
+ if (ieee754_csr.nan2008)
+ DPMANT(r) |= DP_MBIT(DP_FBITS - 1);
+ else
+ r = ieee754dp_indef();
+
+ return r;
}
static u64 ieee754dp_get_rounding(int sn, u64 xm)
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
index 6383e2c..ed7bb27 100644
--- a/arch/mips/math-emu/ieee754int.h
+++ b/arch/mips/math-emu/ieee754int.h
@@ -63,10 +63,10 @@ static inline int ieee754_class_nan(int xc)
if (ve == SP_EMAX+1+SP_EBIAS) { \
if (vm == 0) \
vc = IEEE754_CLASS_INF; \
- else if (vm & SP_MBIT(SP_FBITS-1)) \
- vc = IEEE754_CLASS_SNAN; \
- else \
+ else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
vc = IEEE754_CLASS_QNAN; \
+ else \
+ vc = IEEE754_CLASS_SNAN; \
} else if (ve == SP_EMIN-1+SP_EBIAS) { \
if (vm) { \
ve = SP_EMIN; \
@@ -97,10 +97,10 @@ static inline int ieee754_class_nan(int xc)
if (ve == DP_EMAX+1+DP_EBIAS) { \
if (vm == 0) \
vc = IEEE754_CLASS_INF; \
- else if (vm & DP_MBIT(DP_FBITS-1)) \
- vc = IEEE754_CLASS_SNAN; \
- else \
+ else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
vc = IEEE754_CLASS_QNAN; \
+ else \
+ vc = IEEE754_CLASS_SNAN; \
} else if (ve == DP_EMIN-1+DP_EBIAS) { \
if (vm) { \
ve = DP_EMIN; \
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
index ca8e35e..def00ff 100644
--- a/arch/mips/math-emu/ieee754sp.c
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -37,8 +37,11 @@ static inline int ieee754sp_isnan(union ieee754sp x)
static inline int ieee754sp_issnan(union ieee754sp x)
{
+ int qbit;
+
assert(ieee754sp_isnan(x));
- return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
+ qbit = (SPMANT(x) & SP_MBIT(SP_FBITS - 1)) == SP_MBIT(SP_FBITS - 1);
+ return ieee754_csr.nan2008 ^ qbit;
}
@@ -51,7 +54,12 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
assert(ieee754sp_issnan(r));
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754sp_indef();
+ if (ieee754_csr.nan2008)
+ SPMANT(r) |= SP_MBIT(SP_FBITS - 1);
+ else
+ r = ieee754sp_indef();
+
+ return r;
}
static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c
index 506a67a..be650ed 100644
--- a/arch/mips/math-emu/me-debugfs.c
+++ b/arch/mips/math-emu/me-debugfs.c
@@ -4,6 +4,7 @@
#include <linux/init.h>
#include <linux/percpu.h>
#include <linux/types.h>
+#include <asm/debug.h>
#include <asm/fpu_emulator.h>
#include <asm/local.h>
@@ -27,7 +28,6 @@ static int fpuemu_stat_get(void *data, u64 *val)
}
DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
-extern struct dentry *mips_debugfs_dir;
static int __init debugfs_fpuemu(void)
{
struct dentry *d, *dir;
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
index 3797148..5060e8f 100644
--- a/arch/mips/math-emu/sp_fdp.c
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -44,13 +44,16 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
- return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
-
+ x = ieee754dp_nanxcpt(x);
+ EXPLODEXDP;
+ /* Fall through. */
case IEEE754_CLASS_QNAN:
y = ieee754sp_nan_fdp(xs, xm);
- EXPLODEYSP;
- if (!ieee754_class_nan(yc))
- y = ieee754sp_indef();
+ if (!ieee754_csr.nan2008) {
+ EXPLODEYSP;
+ if (!ieee754_class_nan(yc))
+ y = ieee754sp_indef();
+ }
return y;
case IEEE754_CLASS_INF:
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index c50e945..756c9cf 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -23,27 +23,39 @@
union ieee754sp ieee754sp_neg(union ieee754sp x)
{
- unsigned int oldrm;
union ieee754sp y;
- oldrm = ieee754_csr.rm;
- ieee754_csr.rm = FPU_CSR_RD;
- y = ieee754sp_sub(ieee754sp_zero(0), x);
- ieee754_csr.rm = oldrm;
+ if (ieee754_csr.abs2008) {
+ y = x;
+ SPSIGN(y) = !SPSIGN(x);
+ } else {
+ unsigned int oldrm;
+
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ y = ieee754sp_sub(ieee754sp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ }
return y;
}
union ieee754sp ieee754sp_abs(union ieee754sp x)
{
- unsigned int oldrm;
union ieee754sp y;
- oldrm = ieee754_csr.rm;
- ieee754_csr.rm = FPU_CSR_RD;
- if (SPSIGN(x))
- y = ieee754sp_sub(ieee754sp_zero(0), x);
- else
- y = ieee754sp_add(ieee754sp_zero(0), x);
- ieee754_csr.rm = oldrm;
+ if (ieee754_csr.abs2008) {
+ y = x;
+ SPSIGN(y) = 0;
+ } else {
+ unsigned int oldrm;
+
+ oldrm = ieee754_csr.rm;
+ ieee754_csr.rm = FPU_CSR_RD;
+ if (SPSIGN(x))
+ y = ieee754sp_sub(ieee754sp_zero(0), x);
+ else
+ y = ieee754sp_add(ieee754sp_zero(0), x);
+ ieee754_csr.rm = oldrm;
+ }
return y;
}
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
index 091299a..f4b4cab 100644
--- a/arch/mips/math-emu/sp_tint.c
+++ b/arch/mips/math-emu/sp_tint.c
@@ -38,10 +38,13 @@ int ieee754sp_tint(union ieee754sp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
- case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
+ case IEEE754_CLASS_INF:
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754si_overflow(xs);
+
case IEEE754_CLASS_ZERO:
return 0;
@@ -56,7 +59,7 @@ int ieee754sp_tint(union ieee754sp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754si_indef();
+ return ieee754si_overflow(xs);
}
/* oh gawd */
if (xe > SP_FBITS) {
@@ -97,7 +100,7 @@ int ieee754sp_tint(union ieee754sp x)
if ((xm >> 31) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754si_indef();
+ return ieee754si_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index 9f3c742..a2450c7 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -39,10 +39,13 @@ s64 ieee754sp_tlong(union ieee754sp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
- case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
+ case IEEE754_CLASS_INF:
+ ieee754_setcx(IEEE754_INVALID_OPERATION);
+ return ieee754di_overflow(xs);
+
case IEEE754_CLASS_ZERO:
return 0;
@@ -57,7 +60,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754di_indef();
+ return ieee754di_overflow(xs);
}
/* oh gawd */
if (xe > SP_FBITS) {
@@ -94,7 +97,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
if ((xm >> 63) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
- return ieee754di_indef();
+ return ieee754di_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 67ede4e..b4c64bd 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
+obj-$(CONFIG_SCACHE_DEBUGFS) += sc-debugfs.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 5d3a25e..caac3d7 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -587,7 +587,8 @@ static inline void local_r4k_flush_cache_page(void *args)
* another ASID than the current one.
*/
map_coherent = (cpu_has_dc_aliases &&
- page_mapped(page) && !Page_dcache_dirty(page));
+ page_mapcount(page) &&
+ !Page_dcache_dirty(page));
if (map_coherent)
vaddr = kmap_coherent(page, addr);
else
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index aab218c..3f159ca 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -106,7 +106,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
unsigned long addr = (unsigned long) page_address(page);
if (pages_do_alias(addr, vmaddr)) {
- if (page_mapped(page) && !Page_dcache_dirty(page)) {
+ if (page_mapcount(page) && !Page_dcache_dirty(page)) {
void *kaddr;
kaddr = kmap_coherent(page, vmaddr);
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index d8117be..730d394 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -145,7 +145,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
gfp = massage_gfp_flags(dev, gfp);
- if (IS_ENABLED(CONFIG_DMA_CMA) && !(gfp & GFP_ATOMIC))
+ if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp))
page = dma_alloc_from_contiguous(dev,
count, get_order(size));
if (!page)
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 349995d..6cdffc7 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
@@ -64,7 +64,7 @@ static inline void get_head_page_multiple(struct page *page, int nr)
{
VM_BUG_ON(page != compound_head(page));
VM_BUG_ON(page_count(page) == 0);
- atomic_add(nr, &page->_count);
+ page_ref_add(page, nr);
SetPageReferenced(page);
}
@@ -87,8 +87,6 @@ static int gup_huge_pmd(pmd_t pmd, unsigned long addr, unsigned long end,
do {
VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page;
- if (PageTail(page))
- get_huge_page_tail(page);
(*nr)++;
page++;
refs++;
@@ -109,18 +107,7 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
pmd_t pmd = *pmdp;
next = pmd_addr_end(addr, end);
- /*
- * The pmd_trans_splitting() check below explains why
- * pmdp_splitting_flush has to flush the tlb, to stop
- * this gup-fast code from running while we set the
- * splitting bit in the pmd. Returning zero will take
- * the slow path that will call wait_split_huge_page()
- * if the pmd is still in splitting state. gup-fast
- * can't because it has irq disabled and
- * wait_split_huge_page() would never return as the
- * tlb flush IPI wouldn't run.
- */
- if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+ if (pmd_none(pmd))
return 0;
if (unlikely(pmd_huge(pmd))) {
if (!gup_huge_pmd(pmd, addr, next, write, pages,nr))
@@ -153,8 +140,6 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
do {
VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page;
- if (PageTail(page))
- get_huge_page_tail(page);
(*nr)++;
page++;
refs++;
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 11661cb..d7258a1 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -118,19 +118,6 @@ void *kmap_atomic_pfn(unsigned long pfn)
return (void*) vaddr;
}
-struct page *kmap_atomic_to_page(void *ptr)
-{
- unsigned long idx, vaddr = (unsigned long)ptr;
- pte_t *pte;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- idx = virt_to_fix(vaddr);
- pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
- return pte_page(*pte);
-}
-
void __init kmap_init(void)
{
unsigned long kmap_vstart;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8770e61..7e5fa09 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -165,7 +165,7 @@ void copy_user_highpage(struct page *to, struct page *from,
vto = kmap_atomic(to);
if (cpu_has_dc_aliases &&
- page_mapped(from) && !Page_dcache_dirty(from)) {
+ page_mapcount(from) && !Page_dcache_dirty(from)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
kunmap_coherent();
@@ -187,7 +187,7 @@ void copy_to_user_page(struct vm_area_struct *vma,
unsigned long len)
{
if (cpu_has_dc_aliases &&
- page_mapped(page) && !Page_dcache_dirty(page)) {
+ page_mapcount(page) && !Page_dcache_dirty(page)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent();
@@ -205,7 +205,7 @@ void copy_from_user_page(struct vm_area_struct *vma,
unsigned long len)
{
if (cpu_has_dc_aliases &&
- page_mapped(page) && !Page_dcache_dirty(page)) {
+ page_mapcount(page) && !Page_dcache_dirty(page)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent();
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 5c81fdd..3530376 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -146,7 +146,7 @@ unsigned long arch_mmap_rnd(void)
{
unsigned long rnd;
- rnd = (unsigned long)get_random_int();
+ rnd = get_random_long();
rnd <<= PAGE_SHIFT;
if (TASK_IS_32BIT_ADDR)
rnd &= 0xfffffful;
@@ -174,7 +174,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
static inline unsigned long brk_rnd(void)
{
- unsigned long rnd = get_random_int();
+ unsigned long rnd = get_random_long();
rnd = rnd << PAGE_SHIFT;
/* 8MB for 32bit, 256MB for 64bit */
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index e8adc00..ce4473e 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -62,20 +62,6 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
}
#endif
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-
-void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long address,
- pmd_t *pmdp)
-{
- if (!pmd_trans_splitting(*pmdp)) {
- pmd_t pmd = pmd_mksplitting(*pmdp);
- set_pmd_at(vma->vm_mm, address, pmdp, pmd);
- }
-}
-
-#endif
-
pmd_t mk_pmd(struct page *page, pgprot_t prot)
{
pmd_t pmd;
diff --git a/arch/mips/mm/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c
new file mode 100644
index 0000000..5eefe32
--- /dev/null
+++ b/arch/mips/mm/sc-debugfs.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/bcache.h>
+#include <asm/debug.h>
+#include <asm/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/init.h>
+
+static ssize_t sc_prefetch_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ bool enabled = bc_prefetch_is_enabled();
+ char buf[3];
+
+ buf[0] = enabled ? 'Y' : 'N';
+ buf[1] = '\n';
+ buf[2] = 0;
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t sc_prefetch_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[32];
+ ssize_t buf_size;
+ bool enabled;
+ int err;
+
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ err = strtobool(buf, &enabled);
+ if (err)
+ return err;
+
+ if (enabled)
+ bc_prefetch_enable();
+ else
+ bc_prefetch_disable();
+
+ return count;
+}
+
+static const struct file_operations sc_prefetch_fops = {
+ .open = simple_open,
+ .llseek = default_llseek,
+ .read = sc_prefetch_read,
+ .write = sc_prefetch_write,
+};
+
+static int __init sc_debugfs_init(void)
+{
+ struct dentry *dir, *file;
+
+ if (!mips_debugfs_dir)
+ return -ENODEV;
+
+ dir = debugfs_create_dir("l2cache", mips_debugfs_dir);
+ if (IS_ERR(dir))
+ return PTR_ERR(dir);
+
+ file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir,
+ NULL, &sc_prefetch_fops);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ return 0;
+}
+late_initcall(sc_debugfs_init);
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 53ea839..91dec32 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -51,11 +51,69 @@ static void mips_sc_disable(void)
/* L2 cache is permanently enabled */
}
+static void mips_sc_prefetch_enable(void)
+{
+ unsigned long pftctl;
+
+ if (mips_cm_revision() < CM_REV_CM2_5)
+ return;
+
+ /*
+ * If there is one or more L2 prefetch unit present then enable
+ * prefetching for both code & data, for all ports.
+ */
+ pftctl = read_gcr_l2_pft_control();
+ if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) {
+ pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
+ pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
+ pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+ write_gcr_l2_pft_control(pftctl);
+
+ pftctl = read_gcr_l2_pft_control_b();
+ pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
+ pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+ write_gcr_l2_pft_control_b(pftctl);
+ }
+}
+
+static void mips_sc_prefetch_disable(void)
+{
+ unsigned long pftctl;
+
+ if (mips_cm_revision() < CM_REV_CM2_5)
+ return;
+
+ pftctl = read_gcr_l2_pft_control();
+ pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+ write_gcr_l2_pft_control(pftctl);
+
+ pftctl = read_gcr_l2_pft_control_b();
+ pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
+ pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+ write_gcr_l2_pft_control_b(pftctl);
+}
+
+static bool mips_sc_prefetch_is_enabled(void)
+{
+ unsigned long pftctl;
+
+ if (mips_cm_revision() < CM_REV_CM2_5)
+ return false;
+
+ pftctl = read_gcr_l2_pft_control();
+ if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK))
+ return false;
+ return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK);
+}
+
static struct bcache_ops mips_sc_ops = {
.bc_enable = mips_sc_enable,
.bc_disable = mips_sc_disable,
.bc_wback_inv = mips_sc_wback_inv,
- .bc_inv = mips_sc_inv
+ .bc_inv = mips_sc_inv,
+ .bc_prefetch_enable = mips_sc_prefetch_enable,
+ .bc_prefetch_disable = mips_sc_prefetch_disable,
+ .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled,
};
/*
@@ -106,11 +164,13 @@ static int __init mips_sc_probe_cm3(void)
sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
- c->scache.sets = 64 << sets;
+ if (sets)
+ c->scache.sets = 64 << sets;
line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
- c->scache.linesz = 2 << line_sz;
+ if (line_sz)
+ c->scache.linesz = 2 << line_sz;
assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
@@ -118,13 +178,12 @@ static int __init mips_sc_probe_cm3(void)
c->scache.waysize = c->scache.sets * c->scache.linesz;
c->scache.waybit = __ffs(c->scache.waysize);
- c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
-
- return 1;
-}
+ if (c->scache.linesz) {
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+ return 1;
+ }
-void __weak platform_early_l2_init(void)
-{
+ return 0;
}
static inline int __init mips_sc_probe(void)
@@ -136,12 +195,6 @@ static inline int __init mips_sc_probe(void)
/* Mark as not present until probe completed */
c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
- /*
- * Do we need some platform specific probing before
- * we configure L2?
- */
- platform_early_l2_init();
-
if (mips_cm_revision() >= CM_REV_CM3)
return mips_sc_probe_cm3();
@@ -162,13 +215,13 @@ static inline int __init mips_sc_probe(void)
return 0;
tmp = (config2 >> 8) & 0x0f;
- if (0 <= tmp && tmp <= 7)
+ if (tmp <= 7)
c->scache.sets = 64 << tmp;
else
return 0;
tmp = (config2 >> 0) & 0x0f;
- if (0 <= tmp && tmp <= 7)
+ if (tmp <= 7)
c->scache.ways = tmp + 1;
else
return 0;
@@ -186,6 +239,7 @@ int mips_sc_init(void)
int found = mips_sc_probe();
if (found) {
mips_sc_enable();
+ mips_sc_prefetch_enable();
bcops = &mips_sc_ops;
}
return found;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 323d1d3..5a04b6f 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -240,9 +240,8 @@ static void output_pgtable_bits_defines(void)
pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT);
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
- pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT);
#endif
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (cpu_has_rixi) {
#ifdef _PAGE_NO_EXEC_SHIFT
pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
@@ -311,6 +310,7 @@ static struct uasm_label labels[128];
static struct uasm_reloc relocs[128];
static int check_for_high_segbits;
+static bool fill_includes_sw_bits;
static unsigned int kscratch_used_mask;
@@ -630,8 +630,14 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
unsigned int reg)
{
- if (cpu_has_rixi) {
- UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
+ if (cpu_has_rixi && _PAGE_NO_EXEC) {
+ if (fill_includes_sw_bits) {
+ UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
+ } else {
+ UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, reg, reg,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ }
} else {
#ifdef CONFIG_PHYS_ADDR_T_64BIT
uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -1005,21 +1011,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
* 64bit address support (36bit on a 32bit CPU) in a 32bit
* Kernel is a special case. Only a few CPUs use it.
*/
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
- if (cpu_has_64bits) {
- uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
- uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
- if (cpu_has_rixi) {
- UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
- UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
- } else {
- uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
- UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
- }
- UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
- } else {
+ if (config_enabled(CONFIG_PHYS_ADDR_T_64BIT) && !cpu_has_64bits) {
int pte_off_even = sizeof(pte_t) / 2;
int pte_off_odd = pte_off_even + sizeof(pte_t);
#ifdef CONFIG_XPA
@@ -1043,31 +1035,23 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
uasm_i_mthc0(p, tmp, C0_ENTRYLO0);
uasm_i_mthc0(p, ptep, C0_ENTRYLO1);
#endif
+ return;
}
-#else
+
UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
if (r45k_bvahwbug())
build_tlb_probe_entry(p);
- if (cpu_has_rixi) {
- UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
- if (r4k_250MHZhwbug())
- UASM_i_MTC0(p, 0, C0_ENTRYLO0);
- UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
- } else {
- UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
- if (r4k_250MHZhwbug())
- UASM_i_MTC0(p, 0, C0_ENTRYLO0);
- UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
- if (r45k_bvahwbug())
- uasm_i_mfc0(p, tmp, C0_INDEX);
- }
+ build_convert_pte_to_entrylo(p, tmp);
+ if (r4k_250MHZhwbug())
+ UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ build_convert_pte_to_entrylo(p, ptep);
+ if (r45k_bvahwbug())
+ uasm_i_mfc0(p, tmp, C0_INDEX);
if (r4k_250MHZhwbug())
UASM_i_MTC0(p, 0, C0_ENTRYLO1);
UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
-#endif
}
struct mips_huge_tlb_info {
@@ -2299,6 +2283,10 @@ static void config_htw_params(void)
/* re-initialize the PTI field including the even/odd bit */
pwfield &= ~MIPS_PWFIELD_PTI_MASK;
pwfield |= PAGE_SHIFT << MIPS_PWFIELD_PTI_SHIFT;
+ if (CONFIG_PGTABLE_LEVELS >= 3) {
+ pwfield &= ~MIPS_PWFIELD_MDI_MASK;
+ pwfield |= PMD_SHIFT << MIPS_PWFIELD_MDI_SHIFT;
+ }
/* Set the PTEI right shift */
ptei = _PAGE_GLOBAL_SHIFT << MIPS_PWFIELD_PTEI_SHIFT;
pwfield |= ptei;
@@ -2320,9 +2308,11 @@ static void config_htw_params(void)
pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT;
pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT;
+ if (CONFIG_PGTABLE_LEVELS >= 3)
+ pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT;
/* If XPA has been enabled, PTEs are 64-bit in size. */
- if (read_c0_pagegrain() & PG_ELPA)
+ if (config_enabled(CONFIG_64BITS) || (read_c0_pagegrain() & PG_ELPA))
pwsize |= 1;
write_c0_pwsize(pwsize);
@@ -2360,6 +2350,41 @@ static void config_xpa_params(void)
#endif
}
+static void check_pabits(void)
+{
+ unsigned long entry;
+ unsigned pabits, fillbits;
+
+ if (!cpu_has_rixi || !_PAGE_NO_EXEC) {
+ /*
+ * We'll only be making use of the fact that we can rotate bits
+ * into the fill if the CPU supports RIXI, so don't bother
+ * probing this for CPUs which don't.
+ */
+ return;
+ }
+
+ write_c0_entrylo0(~0ul);
+ back_to_back_c0_hazard();
+ entry = read_c0_entrylo0();
+
+ /* clear all non-PFN bits */
+ entry &= ~((1 << MIPS_ENTRYLO_PFN_SHIFT) - 1);
+ entry &= ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+
+ /* find a lower bound on PABITS, and upper bound on fill bits */
+ pabits = fls_long(entry) + 6;
+ fillbits = max_t(int, (int)BITS_PER_LONG - pabits, 0);
+
+ /* minus the RI & XI bits */
+ fillbits -= min_t(unsigned, fillbits, 2);
+
+ if (fillbits >= ilog2(_PAGE_NO_EXEC))
+ fill_includes_sw_bits = true;
+
+ pr_debug("Entry* registers contain %u fill bits\n", fillbits);
+}
+
void build_tlb_refill_handler(void)
{
/*
@@ -2370,6 +2395,7 @@ void build_tlb_refill_handler(void)
static int run_once = 0;
output_pgtable_bits_defines();
+ check_pabits();
#ifdef CONFIG_64BIT
check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile
index ea35587..5827af7 100644
--- a/arch/mips/mti-malta/Makefile
+++ b/arch/mips/mti-malta/Makefile
@@ -5,9 +5,18 @@
# Copyright (C) 2008 Wind River Systems, Inc.
# written by Ralf Baechle <ralf@linux-mips.org>
#
-obj-y := malta-display.o malta-dt.o malta-init.o \
- malta-int.o malta-memory.o malta-platform.o \
- malta-reset.o malta-setup.o malta-time.o
+obj-y += malta-display.o
+obj-y += malta-dt.o
+obj-y += malta-dtshim.o
+obj-y += malta-init.o
+obj-y += malta-int.o
+obj-y += malta-memory.o
+obj-y += malta-platform.o
+obj-y += malta-reset.o
+obj-y += malta-setup.o
+obj-y += malta-time.o
obj-$(CONFIG_MIPS_CMP) += malta-amon.o
obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o
+
+CFLAGS_malta-dtshim.o = -I$(src)/../../../scripts/dtc/libfdt
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
new file mode 100644
index 0000000..f7133ef
--- /dev/null
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/bug.h>
+#include <linux/kernel.h>
+#include <linux/libfdt.h>
+#include <linux/of_fdt.h>
+#include <linux/sizes.h>
+#include <asm/bootinfo.h>
+#include <asm/fw/fw.h>
+#include <asm/page.h>
+
+static unsigned char fdt_buf[16 << 10] __initdata;
+
+/* determined physical memory size, not overridden by command line args */
+extern unsigned long physical_memsize;
+
+#define MAX_MEM_ARRAY_ENTRIES 1
+
+static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size)
+{
+ unsigned long size_preio;
+ unsigned entries;
+
+ entries = 1;
+ mem_array[0] = cpu_to_be32(PHYS_OFFSET);
+ if (config_enabled(CONFIG_EVA)) {
+ /*
+ * The current Malta EVA configuration is "special" in that it
+ * always makes use of addresses in the upper half of the 32 bit
+ * physical address map, which gives it a contiguous region of
+ * DDR but limits it to 2GB.
+ */
+ mem_array[1] = cpu_to_be32(size);
+ } else {
+ size_preio = min_t(unsigned long, size, SZ_256M);
+ mem_array[1] = cpu_to_be32(size_preio);
+ }
+
+ BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES);
+ return entries;
+}
+
+static void __init append_memory(void *fdt, int root_off)
+{
+ __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
+ unsigned long memsize;
+ unsigned mem_entries;
+ int i, err, mem_off;
+ char *var, param_name[10], *var_names[] = {
+ "ememsize", "memsize",
+ };
+
+ /* if a memory node already exists, leave it alone */
+ mem_off = fdt_path_offset(fdt, "/memory");
+ if (mem_off >= 0)
+ return;
+
+ /* find memory size from the bootloader environment */
+ for (i = 0; i < ARRAY_SIZE(var_names); i++) {
+ var = fw_getenv(var_names[i]);
+ if (!var)
+ continue;
+
+ err = kstrtoul(var, 0, &physical_memsize);
+ if (!err)
+ break;
+
+ pr_warn("Failed to read the '%s' env variable '%s'\n",
+ var_names[i], var);
+ }
+
+ if (!physical_memsize) {
+ pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
+ physical_memsize = 32 << 20;
+ }
+
+ if (config_enabled(CONFIG_CPU_BIG_ENDIAN)) {
+ /*
+ * SOC-it swaps, or perhaps doesn't swap, when DMA'ing
+ * the last word of physical memory.
+ */
+ physical_memsize -= PAGE_SIZE;
+ }
+
+ /* default to using all available RAM */
+ memsize = physical_memsize;
+
+ /* allow the user to override the usable memory */
+ for (i = 0; i < ARRAY_SIZE(var_names); i++) {
+ snprintf(param_name, sizeof(param_name), "%s=", var_names[i]);
+ var = strstr(arcs_cmdline, param_name);
+ if (!var)
+ continue;
+
+ memsize = memparse(var + strlen(param_name), NULL);
+ }
+
+ /* if the user says there's more RAM than we thought, believe them */
+ physical_memsize = max_t(unsigned long, physical_memsize, memsize);
+
+ /* append memory to the DT */
+ mem_off = fdt_add_subnode(fdt, root_off, "memory");
+ if (mem_off < 0)
+ panic("Unable to add memory node to DT: %d", mem_off);
+
+ err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
+ if (err)
+ panic("Unable to set memory node device_type: %d", err);
+
+ mem_entries = gen_fdt_mem_array(mem_array, physical_memsize);
+ err = fdt_setprop(fdt, mem_off, "reg", mem_array,
+ mem_entries * 2 * sizeof(mem_array[0]));
+ if (err)
+ panic("Unable to set memory regs property: %d", err);
+
+ mem_entries = gen_fdt_mem_array(mem_array, memsize);
+ err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array,
+ mem_entries * 2 * sizeof(mem_array[0]));
+ if (err)
+ panic("Unable to set linux,usable-memory property: %d", err);
+}
+
+void __init *malta_dt_shim(void *fdt)
+{
+ int root_off, len, err;
+ const char *compat;
+
+ if (fdt_check_header(fdt))
+ panic("Corrupt DT");
+
+ err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf));
+ if (err)
+ panic("Unable to open FDT: %d", err);
+
+ root_off = fdt_path_offset(fdt_buf, "/");
+ if (root_off < 0)
+ panic("No / node in DT");
+
+ compat = fdt_getprop(fdt_buf, root_off, "compatible", &len);
+ if (!compat)
+ panic("No root compatible property in DT: %d", len);
+
+ /* if this isn't Malta, leave the DT alone */
+ if (strncmp(compat, "mti,malta", len))
+ return fdt;
+
+ append_memory(fdt_buf, root_off);
+
+ err = fdt_pack(fdt_buf);
+ if (err)
+ panic("Unable to pack FDT: %d\n", err);
+
+ return fdt_buf;
+}
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 53c2478..dc2c521 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -293,7 +293,6 @@ mips_pci_controller:
console_config();
#endif
/* Early detection of CMP support */
- mips_cm_probe();
mips_cpc_probe();
if (!register_cps_smp_ops())
@@ -302,11 +301,5 @@ mips_pci_controller:
return;
if (!register_vsmp_smp_ops())
return;
-}
-
-void platform_early_l2_init(void)
-{
- /* L2 configuration lives in the CM3 */
- if (mips_cm_revision() >= CM_REV_CM3)
- mips_cm_probe();
+ register_up_smp_ops();
}
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index dadeb83..d5f8dae 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -21,147 +21,20 @@
#include <asm/sections.h>
#include <asm/fw/fw.h>
-static fw_memblock_t mdesc[FW_MAX_MEMBLOCKS];
-
/* determined physical memory size, not overridden by command line args */
unsigned long physical_memsize = 0L;
-fw_memblock_t * __init fw_getmdesc(int eva)
-{
- char *memsize_str, *ememsize_str = NULL, *ptr;
- unsigned long memsize = 0, ememsize = 0;
- static char cmdline[COMMAND_LINE_SIZE] __initdata;
- int tmp;
-
- /* otherwise look in the environment */
-
- memsize_str = fw_getenv("memsize");
- if (memsize_str) {
- tmp = kstrtoul(memsize_str, 0, &memsize);
- if (tmp)
- pr_warn("Failed to read the 'memsize' env variable.\n");
- }
- if (eva) {
- /* Look for ememsize for EVA */
- ememsize_str = fw_getenv("ememsize");
- if (ememsize_str) {
- tmp = kstrtoul(ememsize_str, 0, &ememsize);
- if (tmp)
- pr_warn("Failed to read the 'ememsize' env variable.\n");
- }
- }
- if (!memsize && !ememsize) {
- pr_warn("memsize not set in YAMON, set to default (32Mb)\n");
- physical_memsize = 0x02000000;
- } else {
- if (memsize > (256 << 20)) { /* memsize should be capped to 256M */
- pr_warn("Unsupported memsize value (0x%lx) detected! "
- "Using 0x10000000 (256M) instead\n",
- memsize);
- memsize = 256 << 20;
- }
- /* If ememsize is set, then set physical_memsize to that */
- physical_memsize = ememsize ? : memsize;
- }
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
- /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
- word of physical memory */
- physical_memsize -= PAGE_SIZE;
-#endif
-
- /* Check the command line for a memsize directive that overrides
- the physical/default amount */
- strcpy(cmdline, arcs_cmdline);
- ptr = strstr(cmdline, "memsize=");
- if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
- ptr = strstr(ptr, " memsize=");
- /* And now look for ememsize */
- if (eva) {
- ptr = strstr(cmdline, "ememsize=");
- if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
- ptr = strstr(ptr, " ememsize=");
- }
-
- if (ptr)
- memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr);
- else
- memsize = physical_memsize;
-
- /* Last 64K for HIGHMEM arithmetics */
- if (memsize > 0x7fff0000)
- memsize = 0x7fff0000;
-
- memset(mdesc, 0, sizeof(mdesc));
-
- mdesc[0].type = fw_dontuse;
- mdesc[0].base = PHYS_OFFSET;
- mdesc[0].size = 0x00001000;
-
- mdesc[1].type = fw_code;
- mdesc[1].base = mdesc[0].base + 0x00001000UL;
- mdesc[1].size = 0x000ef000;
-
- /*
- * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
- * south bridge and PCI access always forwarded to the ISA Bus and
- * BIOSCS# is always generated.
- * This mean that this area can't be used as DMA memory for PCI
- * devices.
- */
- mdesc[2].type = fw_dontuse;
- mdesc[2].base = mdesc[0].base + 0x000f0000UL;
- mdesc[2].size = 0x00010000;
-
- mdesc[3].type = fw_dontuse;
- mdesc[3].base = mdesc[0].base + 0x00100000UL;
- mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) -
- 0x00100000UL;
-
- mdesc[4].type = fw_free;
- mdesc[4].base = mdesc[0].base + CPHYSADDR(PFN_ALIGN(&_end));
- mdesc[4].size = memsize - CPHYSADDR(mdesc[4].base);
-
- return &mdesc[0];
-}
-
static void free_init_pages_eva_malta(void *begin, void *end)
{
free_init_pages("unused kernel", __pa_symbol((unsigned long *)begin),
__pa_symbol((unsigned long *)end));
}
-static int __init fw_memtype_classify(unsigned int type)
-{
- switch (type) {
- case fw_free:
- return BOOT_MEM_RAM;
- case fw_code:
- return BOOT_MEM_ROM_DATA;
- default:
- return BOOT_MEM_RESERVED;
- }
-}
-
void __init fw_meminit(void)
{
- fw_memblock_t *p;
-
- p = fw_getmdesc(config_enabled(CONFIG_EVA));
- free_init_pages_eva = (config_enabled(CONFIG_EVA) ?
- free_init_pages_eva_malta : NULL);
+ bool eva = config_enabled(CONFIG_EVA);
- while (p->size) {
- long type;
- unsigned long base, size;
-
- type = fw_memtype_classify(p->type);
- base = p->base;
- size = p->size;
-
- add_memory_region(base, size, type);
- p++;
- }
+ free_init_pages_eva = eva ? free_init_pages_eva_malta : NULL;
}
void __init prom_free_prom_memory(void)
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index 9d1e7f5..4740c82 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -27,6 +27,7 @@
#include <linux/time.h>
#include <asm/fw/fw.h>
+#include <asm/mach-malta/malta-dtshim.h>
#include <asm/mips-cm.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/malta.h>
@@ -250,8 +251,10 @@ static void __init bonito_quirks_setup(void)
void __init plat_mem_setup(void)
{
unsigned int i;
+ void *fdt = __dtb_start;
- __dt_setup_arch(__dtb_start);
+ fdt = malta_dt_shim(fdt);
+ __dt_setup_arch(fdt);
if (config_enabled(CONFIG_EVA))
/* EVA has already been configured in mach-malta/kernel-init.h */
diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile
index 2e52cbd..7a584e0 100644
--- a/arch/mips/mti-sead3/Makefile
+++ b/arch/mips/mti-sead3/Makefile
@@ -12,6 +12,4 @@ obj-y := sead3-lcd.o sead3-display.o sead3-init.o \
sead3-int.o sead3-platform.o sead3-reset.o \
sead3-setup.o sead3-time.o
-obj-y += leds-sead3.o
-
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
diff --git a/arch/mips/mti-sead3/leds-sead3.c b/arch/mips/mti-sead3/leds-sead3.c
deleted file mode 100644
index c938cee..0000000
--- a/arch/mips/mti-sead3/leds-sead3.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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) 2012 MIPS Technologies, Inc. All rights reserved.
- * Copyright (C) 2015 Imagination Technologies, Inc.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/mips-boards/sead3-addr.h>
-
-static void sead3_pled_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- writel(value, (void __iomem *)SEAD3_CPLD_P_LED);
-}
-
-static void sead3_fled_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- writel(value, (void __iomem *)SEAD3_CPLD_F_LED);
-}
-
-static struct led_classdev sead3_pled = {
- .name = "sead3::pled",
- .brightness_set = sead3_pled_set,
- .flags = LED_CORE_SUSPENDRESUME,
-};
-
-static struct led_classdev sead3_fled = {
- .name = "sead3::fled",
- .brightness_set = sead3_fled_set,
- .flags = LED_CORE_SUSPENDRESUME,
-};
-
-static int sead3_led_probe(struct platform_device *pdev)
-{
- int ret;
-
- ret = led_classdev_register(&pdev->dev, &sead3_pled);
- if (ret < 0)
- return ret;
-
- ret = led_classdev_register(&pdev->dev, &sead3_fled);
- if (ret < 0)
- led_classdev_unregister(&sead3_pled);
-
- return ret;
-}
-
-static int sead3_led_remove(struct platform_device *pdev)
-{
- led_classdev_unregister(&sead3_pled);
- led_classdev_unregister(&sead3_fled);
- return 0;
-}
-
-static struct platform_driver sead3_led_driver = {
- .probe = sead3_led_probe,
- .remove = sead3_led_remove,
- .driver = {
- .name = "sead3-led",
- },
-};
-
-module_platform_driver(sead3_led_driver);
-
-MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
-MODULE_DESCRIPTION("SEAD3 LED driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
index 0c4a133..1a8c960 100644
--- a/arch/mips/net/bpf_jit.c
+++ b/arch/mips/net/bpf_jit.c
@@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num)
return num;
}
-static 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 save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
{
int i = 0, real_off = 0;
@@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
static void build_prologue(struct jit_ctx *ctx)
{
- u16 first_inst = ctx->skf->insns[0].code;
int sp_off;
/* Calculate the total offset for the stack pointer */
@@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx)
emit_jit_reg_move(r_X, r_zero, ctx);
/* Do not leak kernel data to userspace */
- if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
+ if (bpf_needs_clear_a(&ctx->skf->insns[0]))
emit_jit_reg_move(r_A, r_zero, ctx);
}
@@ -1251,7 +1237,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
bpf_jit_dump(fp->len, alloc_size, 2, ctx.target);
fp->bpf_func = (void *)ctx.target;
- fp->jited = true;
+ fp->jited = 1;
out:
kfree(ctx.offsets);
diff --git a/arch/mips/netlogic/xlp/dt.c b/arch/mips/netlogic/xlp/dt.c
index a625bdb..856a6e6 100644
--- a/arch/mips/netlogic/xlp/dt.c
+++ b/arch/mips/netlogic/xlp/dt.c
@@ -87,7 +87,6 @@ void __init *xlp_dt_init(void *fdtp)
void __init xlp_early_init_devtree(void)
{
__dt_setup_arch(xlp_fdt_blob);
- strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
}
void __init device_tree_init(void)
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 2eda01e..139ad1d 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
diff --git a/arch/mips/pci/fixup-loongson3.c b/arch/mips/pci/fixup-loongson3.c
index d708ae4..2b6d5e1 100644
--- a/arch/mips/pci/fixup-loongson3.c
+++ b/arch/mips/pci/fixup-loongson3.c
@@ -40,20 +40,25 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
static void pci_fixup_radeon(struct pci_dev *pdev)
{
- if (pdev->resource[PCI_ROM_RESOURCE].start)
+ struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+
+ if (res->start)
return;
if (!loongson_sysconf.vgabios_addr)
return;
- pdev->resource[PCI_ROM_RESOURCE].start =
- loongson_sysconf.vgabios_addr;
- pdev->resource[PCI_ROM_RESOURCE].end =
- loongson_sysconf.vgabios_addr + 256*1024 - 1;
- pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_COPY;
+ pci_disable_rom(pdev);
+ if (res->parent)
+ release_resource(res);
+
+ res->start = virt_to_phys((void *) loongson_sysconf.vgabios_addr);
+ res->end = res->start + 256*1024 - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+ IORESOURCE_PCI_FIXED;
dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n",
- PCI_ROM_RESOURCE, &pdev->resource[PCI_ROM_RESOURCE]);
+ PCI_ROM_RESOURCE, res);
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
new file mode 100644
index 0000000..1ae932c2
--- /dev/null
+++ b/arch/mips/pci/pci-mt7620.c
@@ -0,0 +1,426 @@
+/*
+ * Ralink MT7620A SoC PCI support
+ *
+ * Copyright (C) 2007-2013 Bruce Chang (Mediatek)
+ * Copyright (C) 2013-2016 John Crispin <blogic@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/types.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7620.h>
+
+#define RALINK_PCI_IO_MAP_BASE 0x10160000
+#define RALINK_PCI_MEMORY_BASE 0x0
+
+#define RALINK_INT_PCIE0 4
+
+#define RALINK_CLKCFG1 0x30
+#define RALINK_GPIOMODE 0x60
+
+#define PPLL_CFG1 0x9c
+#define PDRV_SW_SET BIT(23)
+
+#define PPLL_DRV 0xa0
+#define PDRV_SW_SET (1<<31)
+#define LC_CKDRVPD (1<<19)
+#define LC_CKDRVOHZ (1<<18)
+#define LC_CKDRVHZ (1<<17)
+#define LC_CKTEST (1<<16)
+
+/* PCI Bridge registers */
+#define RALINK_PCI_PCICFG_ADDR 0x00
+#define PCIRST BIT(1)
+
+#define RALINK_PCI_PCIENA 0x0C
+#define PCIINT2 BIT(20)
+
+#define RALINK_PCI_CONFIG_ADDR 0x20
+#define RALINK_PCI_CONFIG_DATA_VIRT_REG 0x24
+#define RALINK_PCI_MEMBASE 0x28
+#define RALINK_PCI_IOBASE 0x2C
+
+/* PCI RC registers */
+#define RALINK_PCI0_BAR0SETUP_ADDR 0x10
+#define RALINK_PCI0_IMBASEBAR0_ADDR 0x18
+#define RALINK_PCI0_ID 0x30
+#define RALINK_PCI0_CLASS 0x34
+#define RALINK_PCI0_SUBID 0x38
+#define RALINK_PCI0_STATUS 0x50
+#define PCIE_LINK_UP_ST BIT(0)
+
+#define PCIEPHY0_CFG 0x90
+
+#define RALINK_PCIEPHY_P0_CTL_OFFSET 0x7498
+#define RALINK_PCIE0_CLK_EN (1 << 26)
+
+#define BUSY 0x80000000
+#define WAITRETRY_MAX 10
+#define WRITE_MODE (1UL << 23)
+#define DATA_SHIFT 0
+#define ADDR_SHIFT 8
+
+
+static void __iomem *bridge_base;
+static void __iomem *pcie_base;
+
+static struct reset_control *rstpcie0;
+
+static inline void bridge_w32(u32 val, unsigned reg)
+{
+ iowrite32(val, bridge_base + reg);
+}
+
+static inline u32 bridge_r32(unsigned reg)
+{
+ return ioread32(bridge_base + reg);
+}
+
+static inline void pcie_w32(u32 val, unsigned reg)
+{
+ iowrite32(val, pcie_base + reg);
+}
+
+static inline u32 pcie_r32(unsigned reg)
+{
+ return ioread32(pcie_base + reg);
+}
+
+static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
+{
+ u32 val = pcie_r32(reg);
+
+ val &= ~clr;
+ val |= set;
+ pcie_w32(val, reg);
+}
+
+static int wait_pciephy_busy(void)
+{
+ unsigned long reg_value = 0x0, retry = 0;
+
+ while (1) {
+ reg_value = pcie_r32(PCIEPHY0_CFG);
+
+ if (reg_value & BUSY)
+ mdelay(100);
+ else
+ break;
+ if (retry++ > WAITRETRY_MAX) {
+ printk(KERN_WARN "PCIE-PHY retry failed.\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void pcie_phy(unsigned long addr, unsigned long val)
+{
+ wait_pciephy_busy();
+ pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT),
+ PCIEPHY0_CFG);
+ mdelay(1);
+ wait_pciephy_busy();
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ unsigned int slot = PCI_SLOT(devfn);
+ u8 func = PCI_FUNC(devfn);
+ u32 address;
+ u32 data;
+ u32 num = 0;
+
+ if (bus)
+ num = bus->number;
+
+ address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+ (func << 8) | (where & 0xfc) | 0x80000000;
+ bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+ data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+ switch (size) {
+ case 1:
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ break;
+ case 2:
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ break;
+ case 4:
+ *val = data;
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ unsigned int slot = PCI_SLOT(devfn);
+ u8 func = PCI_FUNC(devfn);
+ u32 address;
+ u32 data;
+ u32 num = 0;
+
+ if (bus)
+ num = bus->number;
+
+ address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+ (func << 8) | (where & 0xfc) | 0x80000000;
+ bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+ data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+ switch (size) {
+ case 1:
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 2:
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 4:
+ data = val;
+ break;
+ }
+
+ bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mt7620_pci_ops = {
+ .read = pci_config_read,
+ .write = pci_config_write,
+};
+
+static struct resource mt7620_res_pci_mem1;
+static struct resource mt7620_res_pci_io1;
+struct pci_controller mt7620_controller = {
+ .pci_ops = &mt7620_pci_ops,
+ .mem_resource = &mt7620_res_pci_mem1,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &mt7620_res_pci_io1,
+ .io_offset = 0x00000000UL,
+ .io_map_base = 0xa0000000,
+};
+
+static int mt7620_pci_hw_init(struct platform_device *pdev)
+{
+ /* bypass PCIe DLL */
+ pcie_phy(0x0, 0x80);
+ pcie_phy(0x1, 0x04);
+
+ /* Elastic buffer control */
+ pcie_phy(0x68, 0xB4);
+
+ /* put core into reset */
+ pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
+ reset_control_assert(rstpcie0);
+
+ /* disable power and all clocks */
+ rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+
+ /* bring core out of reset */
+ reset_control_deassert(rstpcie0);
+ rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+ mdelay(100);
+
+ if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
+ dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
+ reset_control_assert(rstpcie0);
+ rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ return -1;
+ }
+
+ /* power up the bus */
+ rt_sysc_m32(LC_CKDRVHZ | LC_CKDRVOHZ, LC_CKDRVPD | PDRV_SW_SET,
+ PPLL_DRV);
+
+ return 0;
+}
+
+static int mt7628_pci_hw_init(struct platform_device *pdev)
+{
+ u32 val = 0;
+
+ /* bring the core out of reset */
+ rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+ reset_control_deassert(rstpcie0);
+
+ /* enable the pci clk */
+ rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+ mdelay(100);
+
+ /* voodoo from the SDK driver */
+ pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+
+ pci_config_read(NULL, 0, 0x70c, 4, &val);
+ val &= ~(0xff) << 8;
+ val |= 0x50 << 8;
+ pci_config_write(NULL, 0, 0x70c, 4, val);
+
+ pci_config_read(NULL, 0, 0x70c, 4, &val);
+ dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
+
+ return 0;
+}
+
+static int mt7620_pci_probe(struct platform_device *pdev)
+{
+ struct resource *bridge_res = platform_get_resource(pdev,
+ IORESOURCE_MEM, 0);
+ struct resource *pcie_res = platform_get_resource(pdev,
+ IORESOURCE_MEM, 1);
+ u32 val = 0;
+
+ rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0");
+ if (IS_ERR(rstpcie0))
+ return PTR_ERR(rstpcie0);
+
+ bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res);
+ if (IS_ERR(bridge_base))
+ return PTR_ERR(bridge_base);
+
+ pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
+ if (IS_ERR(pcie_base))
+ return PTR_ERR(pcie_base);
+
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+
+ /* bring up the pci core */
+ switch (ralink_soc) {
+ case MT762X_SOC_MT7620A:
+ if (mt7620_pci_hw_init(pdev))
+ return -1;
+ break;
+
+ case MT762X_SOC_MT7628AN:
+ if (mt7628_pci_hw_init(pdev))
+ return -1;
+ break;
+
+ default:
+ dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
+ return -1;
+ }
+ mdelay(50);
+
+ /* enable write access */
+ pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+ mdelay(100);
+
+ /* check if there is a card present */
+ if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
+ reset_control_assert(rstpcie0);
+ rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ if (ralink_soc == MT762X_SOC_MT7620A)
+ rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+ dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
+ return -1;
+ }
+
+ /* setup ranges */
+ bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
+ bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
+
+ pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+ pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
+ pcie_w32(0x06040001, RALINK_PCI0_CLASS);
+
+ /* enable interrupts */
+ pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
+
+ /* voodoo from the SDK driver */
+ pci_config_read(NULL, 0, 4, 4, &val);
+ pci_config_write(NULL, 0, 4, 4, val | 0x7);
+
+ pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
+ register_pci_controller(&mt7620_controller);
+
+ return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u16 cmd;
+ u32 val;
+ int irq = 0;
+
+ if ((dev->bus->number == 0) && (slot == 0)) {
+ pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+ pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4,
+ RALINK_PCI_MEMORY_BASE);
+ pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
+ } else if ((dev->bus->number == 1) && (slot == 0x0)) {
+ irq = RALINK_INT_PCIE0;
+ } else {
+ dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n",
+ dev->bus->number, slot);
+ return 0;
+ }
+ dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
+ dev->bus->number, slot, irq);
+
+ /* configure the cache line size to 0x14 */
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
+
+ /* configure latency timer to 0xff */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff);
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+ /* setup the slot */
+ cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+ return irq;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static const struct of_device_id mt7620_pci_ids[] = {
+ { .compatible = "mediatek,mt7620-pci" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt7620_pci_ids);
+
+static struct platform_driver mt7620_pci_driver = {
+ .probe = mt7620_pci_probe,
+ .driver = {
+ .name = "mt7620-pci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mt7620_pci_ids),
+ },
+};
+
+static int __init mt7620_pci_init(void)
+{
+ return platform_driver_register(&mt7620_pci_driver);
+}
+
+arch_initcall(mt7620_pci_init);
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c
index 8a97802..a245cad 100644
--- a/arch/mips/pci/pci-rt2880.c
+++ b/arch/mips/pci/pci-rt2880.c
@@ -11,6 +11,7 @@
* by the Free Software Foundation.
*/
+#include <linux/delay.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/io.h>
@@ -220,7 +221,6 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
static int rt288x_pci_probe(struct platform_device *pdev)
{
void __iomem *io_map_base;
- int i;
rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
@@ -232,8 +232,7 @@ static int rt288x_pci_probe(struct platform_device *pdev)
ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
- for (i = 0; i < 0xfffff; i++)
- ;
+ udelay(1);
rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index ed6732f9..53a42b0 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -432,8 +432,7 @@ static int rt3883_pci_probe(struct platform_device *pdev)
/* find the interrupt controller child node */
for_each_child_of_node(np, child) {
- if (of_get_property(child, "interrupt-controller", NULL) &&
- of_node_get(child)) {
+ if (of_get_property(child, "interrupt-controller", NULL)) {
rpc->intc_of_node = child;
break;
}
@@ -449,8 +448,7 @@ static int rt3883_pci_probe(struct platform_device *pdev)
/* find the PCI host bridge child node */
for_each_child_of_node(np, child) {
if (child->type &&
- of_node_cmp(child->type, "pci") == 0 &&
- of_node_get(child)) {
+ of_node_cmp(child->type, "pci") == 0) {
rpc->pci_controller.of_node = child;
break;
}
diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig
new file mode 100644
index 0000000..fde56a8
--- /dev/null
+++ b/arch/mips/pic32/Kconfig
@@ -0,0 +1,51 @@
+if MACH_PIC32
+
+choice
+ prompt "Machine Type"
+
+config PIC32MZDA
+ bool "Microchip PIC32MZDA Platform"
+ select BOOT_ELF32
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_MACH_CLKDEV
+ select COMMON_CLK
+ select CLKDEV_LOOKUP
+ select LIBFDT
+ select USE_OF
+ select PINCTRL
+ select PIC32_EVIC
+ help
+ Support for the Microchip PIC32MZDA microcontroller.
+
+ This is a 32-bit microcontroller with support for external or
+ internally packaged DDR2 memory up to 128MB.
+
+ For more information, see <http://www.microchip.com/>.
+
+endchoice
+
+choice
+ prompt "Devicetree selection"
+ default DTB_PIC32_NONE
+ help
+ Select the devicetree.
+
+config DTB_PIC32_NONE
+ bool "None"
+
+config DTB_PIC32_MZDA_SK
+ bool "PIC32MZDA Starter Kit"
+ depends on PIC32MZDA
+ select BUILTIN_DTB
+
+endchoice
+
+endif # MACH_PIC32
diff --git a/arch/mips/pic32/Makefile b/arch/mips/pic32/Makefile
new file mode 100644
index 0000000..fd357f4
--- /dev/null
+++ b/arch/mips/pic32/Makefile
@@ -0,0 +1,6 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
+#
+obj-$(CONFIG_MACH_PIC32) += common/
+obj-$(CONFIG_PIC32MZDA) += pic32mzda/
diff --git a/arch/mips/pic32/Platform b/arch/mips/pic32/Platform
new file mode 100644
index 0000000..cd2084f4
--- /dev/null
+++ b/arch/mips/pic32/Platform
@@ -0,0 +1,7 @@
+#
+# PIC32MZDA
+#
+platform-$(CONFIG_PIC32MZDA) += pic32/
+cflags-$(CONFIG_PIC32MZDA) += -I$(srctree)/arch/mips/include/asm/mach-pic32
+load-$(CONFIG_PIC32MZDA) += 0xffffffff88000000
+all-$(CONFIG_PIC32MZDA) := $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/pic32/common/Makefile b/arch/mips/pic32/common/Makefile
new file mode 100644
index 0000000..be1909c
--- /dev/null
+++ b/arch/mips/pic32/common/Makefile
@@ -0,0 +1,5 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
+#
+obj-y = reset.o irq.o
diff --git a/arch/mips/pic32/common/irq.c b/arch/mips/pic32/common/irq.c
new file mode 100644
index 0000000..6df347e
--- /dev/null
+++ b/arch/mips/pic32/common/irq.c
@@ -0,0 +1,21 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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/irqchip.h>
+#include <asm/irq.h>
+
+void __init arch_init_irq(void)
+{
+ irqchip_init();
+}
diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c
new file mode 100644
index 0000000..8334575
--- /dev/null
+++ b/arch/mips/pic32/common/reset.c
@@ -0,0 +1,62 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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/pm.h>
+#include <asm/reboot.h>
+#include <asm/mach-pic32/pic32.h>
+
+#define PIC32_RSWRST 0x10
+
+static void pic32_halt(void)
+{
+ while (1) {
+ __asm__(".set push;\n"
+ ".set arch=r4000;\n"
+ "wait;\n"
+ ".set pop;\n"
+ );
+ }
+}
+
+static void pic32_machine_restart(char *command)
+{
+ void __iomem *reg =
+ ioremap(PIC32_BASE_RESET + PIC32_RSWRST, sizeof(u32));
+
+ pic32_syskey_unlock();
+
+ /* magic write/read */
+ __raw_writel(1, reg);
+ (void)__raw_readl(reg);
+
+ pic32_halt();
+}
+
+static void pic32_machine_halt(void)
+{
+ local_irq_disable();
+
+ pic32_halt();
+}
+
+static int __init mips_reboot_setup(void)
+{
+ _machine_restart = pic32_machine_restart;
+ _machine_halt = pic32_machine_halt;
+ pm_power_off = pic32_machine_halt;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/pic32/pic32mzda/Makefile b/arch/mips/pic32/pic32mzda/Makefile
new file mode 100644
index 0000000..4a4c272
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/Makefile
@@ -0,0 +1,9 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
+#
+obj-y := init.o time.o config.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_console.o \
+ early_pin.o \
+ early_clk.o
diff --git a/arch/mips/pic32/pic32mzda/config.c b/arch/mips/pic32/pic32mzda/config.c
new file mode 100644
index 0000000..fe293a0
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/config.c
@@ -0,0 +1,126 @@
+/*
+ * Purna Chandra Mandal, purna.mandal@microchip.com
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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/of_platform.h>
+
+#include <asm/mach-pic32/pic32.h>
+
+#include "pic32mzda.h"
+
+#define PIC32_CFGCON 0x0000
+#define PIC32_DEVID 0x0020
+#define PIC32_SYSKEY 0x0030
+#define PIC32_CFGEBIA 0x00c0
+#define PIC32_CFGEBIC 0x00d0
+#define PIC32_CFGCON2 0x00f0
+#define PIC32_RCON 0x1240
+
+static void __iomem *pic32_conf_base;
+static DEFINE_SPINLOCK(config_lock);
+static u32 pic32_reset_status;
+
+static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask)
+{
+ u32 v;
+
+ v = readl(pic32_conf_base + offset);
+ v >>= rshift;
+ v &= mask;
+
+ return v;
+}
+
+static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set)
+{
+ u32 v;
+ unsigned long flags;
+
+ spin_lock_irqsave(&config_lock, flags);
+ v = readl(pic32_conf_base + offset);
+ v &= ~mask;
+ v |= (set & mask);
+ writel(v, pic32_conf_base + offset);
+ spin_unlock_irqrestore(&config_lock, flags);
+
+ return 0;
+}
+
+int pic32_enable_lcd(void)
+{
+ return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31));
+}
+
+int pic32_disable_lcd(void)
+{
+ return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0);
+}
+
+int pic32_set_lcd_mode(int mode)
+{
+ u32 mask = mode ? BIT(30) : 0;
+
+ return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask);
+}
+
+int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh)
+{
+ u32 clr, set;
+
+ clr = (0x3ff << 4) | (0x3ff << 16);
+ set = (rthrsh << 4) | (wthrsh << 16);
+ return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set);
+}
+
+void pic32_syskey_unlock_debug(const char *func, const ulong line)
+{
+ void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY;
+
+ pr_debug("%s: called from %s:%lu\n", __func__, func, line);
+ writel(0x00000000, syskey);
+ writel(0xAA996655, syskey);
+ writel(0x556699AA, syskey);
+}
+
+static u32 pic32_get_device_id(void)
+{
+ return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff);
+}
+
+static u32 pic32_get_device_version(void)
+{
+ return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf);
+}
+
+u32 pic32_get_boot_status(void)
+{
+ return pic32_reset_status;
+}
+EXPORT_SYMBOL(pic32_get_boot_status);
+
+void __init pic32_config_init(void)
+{
+ pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110);
+ if (!pic32_conf_base)
+ panic("pic32: config base not mapped");
+
+ /* Boot Status */
+ pic32_reset_status = readl(pic32_conf_base + PIC32_RCON);
+ writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON));
+
+ /* Device Inforation */
+ pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n",
+ pic32_get_device_id(),
+ pic32_get_device_version());
+}
diff --git a/arch/mips/pic32/pic32mzda/early_clk.c b/arch/mips/pic32/pic32mzda/early_clk.c
new file mode 100644
index 0000000..96c090e
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_clk.c
@@ -0,0 +1,106 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 <asm/mach-pic32/pic32.h>
+
+#include "pic32mzda.h"
+
+/* Oscillators, PLL & clocks */
+#define ICLK_MASK 0x00000080
+#define PLLDIV_MASK 0x00000007
+#define CUROSC_MASK 0x00000007
+#define PLLMUL_MASK 0x0000007F
+#define PB_MASK 0x00000007
+#define FRC1 0
+#define FRC2 7
+#define SPLL 1
+#define POSC 2
+#define FRC_CLK 8000000
+
+#define PIC32_POSC_FREQ 24000000
+
+#define OSCCON 0x0000
+#define SPLLCON 0x0020
+#define PB1DIV 0x0140
+
+u32 pic32_get_sysclk(void)
+{
+ u32 osc_freq = 0;
+ u32 pllclk;
+ u32 frcdivn;
+ u32 osccon;
+ u32 spllcon;
+ int curr_osc;
+
+ u32 plliclk;
+ u32 pllidiv;
+ u32 pllodiv;
+ u32 pllmult;
+ u32 frcdiv;
+
+ void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
+
+ osccon = __raw_readl(osc_base + OSCCON);
+ spllcon = __raw_readl(osc_base + SPLLCON);
+
+ plliclk = (spllcon & ICLK_MASK);
+ pllidiv = ((spllcon >> 8) & PLLDIV_MASK) + 1;
+ pllodiv = ((spllcon >> 24) & PLLDIV_MASK);
+ pllmult = ((spllcon >> 16) & PLLMUL_MASK) + 1;
+ frcdiv = ((osccon >> 24) & PLLDIV_MASK);
+
+ pllclk = plliclk ? FRC_CLK : PIC32_POSC_FREQ;
+ frcdivn = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7));
+
+ if (pllodiv < 2)
+ pllodiv = 2;
+ else if (pllodiv < 5)
+ pllodiv = (1 << pllodiv);
+ else
+ pllodiv = 32;
+
+ curr_osc = (int)((osccon >> 12) & CUROSC_MASK);
+
+ switch (curr_osc) {
+ case FRC1:
+ case FRC2:
+ osc_freq = FRC_CLK / frcdivn;
+ break;
+ case SPLL:
+ osc_freq = ((pllclk / pllidiv) * pllmult) / pllodiv;
+ break;
+ case POSC:
+ osc_freq = PIC32_POSC_FREQ;
+ break;
+ default:
+ break;
+ }
+
+ iounmap(osc_base);
+
+ return osc_freq;
+}
+
+u32 pic32_get_pbclk(int bus)
+{
+ u32 clk_freq;
+ void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
+ u32 pbxdiv = PB1DIV + ((bus - 1) * 0x10);
+ u32 pbdiv = (__raw_readl(osc_base + pbxdiv) & PB_MASK) + 1;
+
+ iounmap(osc_base);
+
+ clk_freq = pic32_get_sysclk();
+
+ return clk_freq / pbdiv;
+}
diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
new file mode 100644
index 0000000..d7b7834
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_console.c
@@ -0,0 +1,171 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 <asm/mach-pic32/pic32.h>
+#include <asm/fw/fw.h>
+
+#include "pic32mzda.h"
+#include "early_pin.h"
+
+/* Default early console parameters */
+#define EARLY_CONSOLE_PORT 1
+#define EARLY_CONSOLE_BAUDRATE 115200
+
+#define UART_ENABLE BIT(15)
+#define UART_ENABLE_RX BIT(12)
+#define UART_ENABLE_TX BIT(10)
+#define UART_TX_FULL BIT(9)
+
+/* UART1(x == 0) - UART6(x == 5) */
+#define UART_BASE(x) ((x) * 0x0200)
+#define U_MODE(x) UART_BASE(x)
+#define U_STA(x) (UART_BASE(x) + 0x10)
+#define U_TXR(x) (UART_BASE(x) + 0x20)
+#define U_BRG(x) (UART_BASE(x) + 0x40)
+
+static void __iomem *uart_base;
+static char console_port = -1;
+
+static int __init configure_uart_pins(int port)
+{
+ switch (port) {
+ case 1:
+ pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
+ pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
+ break;
+ case 5:
+ pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
+ pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __init configure_uart(char port, int baud)
+{
+ u32 pbclk;
+
+ pbclk = pic32_get_pbclk(2);
+
+ __raw_writel(0, uart_base + U_MODE(port));
+ __raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
+ __raw_writel(UART_ENABLE, uart_base + U_MODE(port));
+ __raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
+ uart_base + PIC32_SET(U_STA(port)));
+}
+
+static void __init setup_early_console(char port, int baud)
+{
+ if (configure_uart_pins(port))
+ return;
+
+ console_port = port;
+ configure_uart(console_port, baud);
+}
+
+static char * __init pic32_getcmdline(void)
+{
+ /*
+ * arch_mem_init() has not been called yet, so we don't have a real
+ * command line setup if using CONFIG_CMDLINE_BOOL.
+ */
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ return CONFIG_CMDLINE;
+#else
+ return fw_getcmdline();
+#endif
+}
+
+static int __init get_port_from_cmdline(char *arch_cmdline)
+{
+ char *s;
+ int port = -1;
+
+ if (!arch_cmdline || *arch_cmdline == '\0')
+ goto _out;
+
+ s = strstr(arch_cmdline, "earlyprintk=");
+ if (s) {
+ s = strstr(s, "ttyS");
+ if (s)
+ s += 4;
+ else
+ goto _out;
+
+ port = (*s) - '0';
+ }
+
+_out:
+ return port;
+}
+
+static int __init get_baud_from_cmdline(char *arch_cmdline)
+{
+ char *s;
+ int baud = -1;
+
+ if (!arch_cmdline || *arch_cmdline == '\0')
+ goto _out;
+
+ s = strstr(arch_cmdline, "earlyprintk=");
+ if (s) {
+ s = strstr(s, "ttyS");
+ if (s)
+ s += 6;
+ else
+ goto _out;
+
+ baud = 0;
+ while (*s >= '0' && *s <= '9')
+ baud = baud * 10 + *s++ - '0';
+ }
+
+_out:
+ return baud;
+}
+
+void __init fw_init_early_console(char port)
+{
+ char *arch_cmdline = pic32_getcmdline();
+ int baud = -1;
+
+ uart_base = ioremap_nocache(PIC32_BASE_UART, 0xc00);
+
+ baud = get_baud_from_cmdline(arch_cmdline);
+ if (port == -1)
+ port = get_port_from_cmdline(arch_cmdline);
+
+ if (port == -1)
+ port = EARLY_CONSOLE_PORT;
+
+ if (baud == -1)
+ baud = EARLY_CONSOLE_BAUDRATE;
+
+ setup_early_console(port, baud);
+}
+
+int prom_putchar(char c)
+{
+ if (console_port >= 0) {
+ while (__raw_readl(
+ uart_base + U_STA(console_port)) & UART_TX_FULL)
+ ;
+
+ __raw_writel(c, uart_base + U_TXR(console_port));
+ }
+
+ return 1;
+}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.c b/arch/mips/pic32/pic32mzda/early_pin.c
new file mode 100644
index 0000000..aa673f8
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_pin.c
@@ -0,0 +1,275 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 <asm/io.h>
+
+#include "early_pin.h"
+
+#define PPS_BASE 0x1f800000
+
+/* Input PPS Registers */
+#define INT1R 0x1404
+#define INT2R 0x1408
+#define INT3R 0x140C
+#define INT4R 0x1410
+#define T2CKR 0x1418
+#define T3CKR 0x141C
+#define T4CKR 0x1420
+#define T5CKR 0x1424
+#define T6CKR 0x1428
+#define T7CKR 0x142C
+#define T8CKR 0x1430
+#define T9CKR 0x1434
+#define IC1R 0x1438
+#define IC2R 0x143C
+#define IC3R 0x1440
+#define IC4R 0x1444
+#define IC5R 0x1448
+#define IC6R 0x144C
+#define IC7R 0x1450
+#define IC8R 0x1454
+#define IC9R 0x1458
+#define OCFAR 0x1460
+#define U1RXR 0x1468
+#define U1CTSR 0x146C
+#define U2RXR 0x1470
+#define U2CTSR 0x1474
+#define U3RXR 0x1478
+#define U3CTSR 0x147C
+#define U4RXR 0x1480
+#define U4CTSR 0x1484
+#define U5RXR 0x1488
+#define U5CTSR 0x148C
+#define U6RXR 0x1490
+#define U6CTSR 0x1494
+#define SDI1R 0x149C
+#define SS1R 0x14A0
+#define SDI2R 0x14A8
+#define SS2R 0x14AC
+#define SDI3R 0x14B4
+#define SS3R 0x14B8
+#define SDI4R 0x14C0
+#define SS4R 0x14C4
+#define SDI5R 0x14CC
+#define SS5R 0x14D0
+#define SDI6R 0x14D8
+#define SS6R 0x14DC
+#define C1RXR 0x14E0
+#define C2RXR 0x14E4
+#define REFCLKI1R 0x14E8
+#define REFCLKI3R 0x14F0
+#define REFCLKI4R 0x14F4
+
+static const struct
+{
+ int function;
+ int reg;
+} input_pin_reg[] = {
+ { IN_FUNC_INT3, INT3R },
+ { IN_FUNC_T2CK, T2CKR },
+ { IN_FUNC_T6CK, T6CKR },
+ { IN_FUNC_IC3, IC3R },
+ { IN_FUNC_IC7, IC7R },
+ { IN_FUNC_U1RX, U1RXR },
+ { IN_FUNC_U2CTS, U2CTSR },
+ { IN_FUNC_U5RX, U5RXR },
+ { IN_FUNC_U6CTS, U6CTSR },
+ { IN_FUNC_SDI1, SDI1R },
+ { IN_FUNC_SDI3, SDI3R },
+ { IN_FUNC_SDI5, SDI5R },
+ { IN_FUNC_SS6, SS6R },
+ { IN_FUNC_REFCLKI1, REFCLKI1R },
+ { IN_FUNC_INT4, INT4R },
+ { IN_FUNC_T5CK, T5CKR },
+ { IN_FUNC_T7CK, T7CKR },
+ { IN_FUNC_IC4, IC4R },
+ { IN_FUNC_IC8, IC8R },
+ { IN_FUNC_U3RX, U3RXR },
+ { IN_FUNC_U4CTS, U4CTSR },
+ { IN_FUNC_SDI2, SDI2R },
+ { IN_FUNC_SDI4, SDI4R },
+ { IN_FUNC_C1RX, C1RXR },
+ { IN_FUNC_REFCLKI4, REFCLKI4R },
+ { IN_FUNC_INT2, INT2R },
+ { IN_FUNC_T3CK, T3CKR },
+ { IN_FUNC_T8CK, T8CKR },
+ { IN_FUNC_IC2, IC2R },
+ { IN_FUNC_IC5, IC5R },
+ { IN_FUNC_IC9, IC9R },
+ { IN_FUNC_U1CTS, U1CTSR },
+ { IN_FUNC_U2RX, U2RXR },
+ { IN_FUNC_U5CTS, U5CTSR },
+ { IN_FUNC_SS1, SS1R },
+ { IN_FUNC_SS3, SS3R },
+ { IN_FUNC_SS4, SS4R },
+ { IN_FUNC_SS5, SS5R },
+ { IN_FUNC_C2RX, C2RXR },
+ { IN_FUNC_INT1, INT1R },
+ { IN_FUNC_T4CK, T4CKR },
+ { IN_FUNC_T9CK, T9CKR },
+ { IN_FUNC_IC1, IC1R },
+ { IN_FUNC_IC6, IC6R },
+ { IN_FUNC_U3CTS, U3CTSR },
+ { IN_FUNC_U4RX, U4RXR },
+ { IN_FUNC_U6RX, U6RXR },
+ { IN_FUNC_SS2, SS2R },
+ { IN_FUNC_SDI6, SDI6R },
+ { IN_FUNC_OCFA, OCFAR },
+ { IN_FUNC_REFCLKI3, REFCLKI3R },
+};
+
+void pic32_pps_input(int function, int pin)
+{
+ void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0xF4);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(input_pin_reg); i++) {
+ if (input_pin_reg[i].function == function) {
+ __raw_writel(pin, pps_base + input_pin_reg[i].reg);
+ return;
+ }
+ }
+
+ iounmap(pps_base);
+}
+
+/* Output PPS Registers */
+#define RPA14R 0x1538
+#define RPA15R 0x153C
+#define RPB0R 0x1540
+#define RPB1R 0x1544
+#define RPB2R 0x1548
+#define RPB3R 0x154C
+#define RPB5R 0x1554
+#define RPB6R 0x1558
+#define RPB7R 0x155C
+#define RPB8R 0x1560
+#define RPB9R 0x1564
+#define RPB10R 0x1568
+#define RPB14R 0x1578
+#define RPB15R 0x157C
+#define RPC1R 0x1584
+#define RPC2R 0x1588
+#define RPC3R 0x158C
+#define RPC4R 0x1590
+#define RPC13R 0x15B4
+#define RPC14R 0x15B8
+#define RPD0R 0x15C0
+#define RPD1R 0x15C4
+#define RPD2R 0x15C8
+#define RPD3R 0x15CC
+#define RPD4R 0x15D0
+#define RPD5R 0x15D4
+#define RPD6R 0x15D8
+#define RPD7R 0x15DC
+#define RPD9R 0x15E4
+#define RPD10R 0x15E8
+#define RPD11R 0x15EC
+#define RPD12R 0x15F0
+#define RPD14R 0x15F8
+#define RPD15R 0x15FC
+#define RPE3R 0x160C
+#define RPE5R 0x1614
+#define RPE8R 0x1620
+#define RPE9R 0x1624
+#define RPF0R 0x1640
+#define RPF1R 0x1644
+#define RPF2R 0x1648
+#define RPF3R 0x164C
+#define RPF4R 0x1650
+#define RPF5R 0x1654
+#define RPF8R 0x1660
+#define RPF12R 0x1670
+#define RPF13R 0x1674
+#define RPG0R 0x1680
+#define RPG1R 0x1684
+#define RPG6R 0x1698
+#define RPG7R 0x169C
+#define RPG8R 0x16A0
+#define RPG9R 0x16A4
+
+static const struct
+{
+ int pin;
+ int reg;
+} output_pin_reg[] = {
+ { OUT_RPD2, RPD2R },
+ { OUT_RPG8, RPG8R },
+ { OUT_RPF4, RPF4R },
+ { OUT_RPD10, RPD10R },
+ { OUT_RPF1, RPF1R },
+ { OUT_RPB9, RPB9R },
+ { OUT_RPB10, RPB10R },
+ { OUT_RPC14, RPC14R },
+ { OUT_RPB5, RPB5R },
+ { OUT_RPC1, RPC1R },
+ { OUT_RPD14, RPD14R },
+ { OUT_RPG1, RPG1R },
+ { OUT_RPA14, RPA14R },
+ { OUT_RPD6, RPD6R },
+ { OUT_RPD3, RPD3R },
+ { OUT_RPG7, RPG7R },
+ { OUT_RPF5, RPF5R },
+ { OUT_RPD11, RPD11R },
+ { OUT_RPF0, RPF0R },
+ { OUT_RPB1, RPB1R },
+ { OUT_RPE5, RPE5R },
+ { OUT_RPC13, RPC13R },
+ { OUT_RPB3, RPB3R },
+ { OUT_RPC4, RPC4R },
+ { OUT_RPD15, RPD15R },
+ { OUT_RPG0, RPG0R },
+ { OUT_RPA15, RPA15R },
+ { OUT_RPD7, RPD7R },
+ { OUT_RPD9, RPD9R },
+ { OUT_RPG6, RPG6R },
+ { OUT_RPB8, RPB8R },
+ { OUT_RPB15, RPB15R },
+ { OUT_RPD4, RPD4R },
+ { OUT_RPB0, RPB0R },
+ { OUT_RPE3, RPE3R },
+ { OUT_RPB7, RPB7R },
+ { OUT_RPF12, RPF12R },
+ { OUT_RPD12, RPD12R },
+ { OUT_RPF8, RPF8R },
+ { OUT_RPC3, RPC3R },
+ { OUT_RPE9, RPE9R },
+ { OUT_RPD1, RPD1R },
+ { OUT_RPG9, RPG9R },
+ { OUT_RPB14, RPB14R },
+ { OUT_RPD0, RPD0R },
+ { OUT_RPB6, RPB6R },
+ { OUT_RPD5, RPD5R },
+ { OUT_RPB2, RPB2R },
+ { OUT_RPF3, RPF3R },
+ { OUT_RPF13, RPF13R },
+ { OUT_RPC2, RPC2R },
+ { OUT_RPE8, RPE8R },
+ { OUT_RPF2, RPF2R },
+};
+
+void pic32_pps_output(int function, int pin)
+{
+ void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0x170);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(output_pin_reg); i++) {
+ if (output_pin_reg[i].pin == pin) {
+ __raw_writel(function,
+ pps_base + output_pin_reg[i].reg);
+ return;
+ }
+ }
+
+ iounmap(pps_base);
+}
diff --git a/arch/mips/pic32/pic32mzda/early_pin.h b/arch/mips/pic32/pic32mzda/early_pin.h
new file mode 100644
index 0000000..417fae9
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/early_pin.h
@@ -0,0 +1,241 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 _PIC32MZDA_EARLY_PIN_H
+#define _PIC32MZDA_EARLY_PIN_H
+
+/*
+ * This is a complete, yet overly simplistic and unoptimized, PIC32MZDA PPS
+ * configuration only useful before we have full pinctrl initialized.
+ */
+
+/* Input PPS Functions */
+enum {
+ IN_FUNC_INT3,
+ IN_FUNC_T2CK,
+ IN_FUNC_T6CK,
+ IN_FUNC_IC3,
+ IN_FUNC_IC7,
+ IN_FUNC_U1RX,
+ IN_FUNC_U2CTS,
+ IN_FUNC_U5RX,
+ IN_FUNC_U6CTS,
+ IN_FUNC_SDI1,
+ IN_FUNC_SDI3,
+ IN_FUNC_SDI5,
+ IN_FUNC_SS6,
+ IN_FUNC_REFCLKI1,
+ IN_FUNC_INT4,
+ IN_FUNC_T5CK,
+ IN_FUNC_T7CK,
+ IN_FUNC_IC4,
+ IN_FUNC_IC8,
+ IN_FUNC_U3RX,
+ IN_FUNC_U4CTS,
+ IN_FUNC_SDI2,
+ IN_FUNC_SDI4,
+ IN_FUNC_C1RX,
+ IN_FUNC_REFCLKI4,
+ IN_FUNC_INT2,
+ IN_FUNC_T3CK,
+ IN_FUNC_T8CK,
+ IN_FUNC_IC2,
+ IN_FUNC_IC5,
+ IN_FUNC_IC9,
+ IN_FUNC_U1CTS,
+ IN_FUNC_U2RX,
+ IN_FUNC_U5CTS,
+ IN_FUNC_SS1,
+ IN_FUNC_SS3,
+ IN_FUNC_SS4,
+ IN_FUNC_SS5,
+ IN_FUNC_C2RX,
+ IN_FUNC_INT1,
+ IN_FUNC_T4CK,
+ IN_FUNC_T9CK,
+ IN_FUNC_IC1,
+ IN_FUNC_IC6,
+ IN_FUNC_U3CTS,
+ IN_FUNC_U4RX,
+ IN_FUNC_U6RX,
+ IN_FUNC_SS2,
+ IN_FUNC_SDI6,
+ IN_FUNC_OCFA,
+ IN_FUNC_REFCLKI3,
+};
+
+/* Input PPS Pins */
+#define IN_RPD2 0x00
+#define IN_RPG8 0x01
+#define IN_RPF4 0x02
+#define IN_RPD10 0x03
+#define IN_RPF1 0x04
+#define IN_RPB9 0x05
+#define IN_RPB10 0x06
+#define IN_RPC14 0x07
+#define IN_RPB5 0x08
+#define IN_RPC1 0x0A
+#define IN_RPD14 0x0B
+#define IN_RPG1 0x0C
+#define IN_RPA14 0x0D
+#define IN_RPD6 0x0E
+#define IN_RPD3 0x00
+#define IN_RPG7 0x01
+#define IN_RPF5 0x02
+#define IN_RPD11 0x03
+#define IN_RPF0 0x04
+#define IN_RPB1 0x05
+#define IN_RPE5 0x06
+#define IN_RPC13 0x07
+#define IN_RPB3 0x08
+#define IN_RPC4 0x0A
+#define IN_RPD15 0x0B
+#define IN_RPG0 0x0C
+#define IN_RPA15 0x0D
+#define IN_RPD7 0x0E
+#define IN_RPD9 0x00
+#define IN_RPG6 0x01
+#define IN_RPB8 0x02
+#define IN_RPB15 0x03
+#define IN_RPD4 0x04
+#define IN_RPB0 0x05
+#define IN_RPE3 0x06
+#define IN_RPB7 0x07
+#define IN_RPF12 0x09
+#define IN_RPD12 0x0A
+#define IN_RPF8 0x0B
+#define IN_RPC3 0x0C
+#define IN_RPE9 0x0D
+#define IN_RPD1 0x00
+#define IN_RPG9 0x01
+#define IN_RPB14 0x02
+#define IN_RPD0 0x03
+#define IN_RPB6 0x05
+#define IN_RPD5 0x06
+#define IN_RPB2 0x07
+#define IN_RPF3 0x08
+#define IN_RPF13 0x09
+#define IN_RPF2 0x0B
+#define IN_RPC2 0x0C
+#define IN_RPE8 0x0D
+
+/* Output PPS Pins */
+enum {
+ OUT_RPD2,
+ OUT_RPG8,
+ OUT_RPF4,
+ OUT_RPD10,
+ OUT_RPF1,
+ OUT_RPB9,
+ OUT_RPB10,
+ OUT_RPC14,
+ OUT_RPB5,
+ OUT_RPC1,
+ OUT_RPD14,
+ OUT_RPG1,
+ OUT_RPA14,
+ OUT_RPD6,
+ OUT_RPD3,
+ OUT_RPG7,
+ OUT_RPF5,
+ OUT_RPD11,
+ OUT_RPF0,
+ OUT_RPB1,
+ OUT_RPE5,
+ OUT_RPC13,
+ OUT_RPB3,
+ OUT_RPC4,
+ OUT_RPD15,
+ OUT_RPG0,
+ OUT_RPA15,
+ OUT_RPD7,
+ OUT_RPD9,
+ OUT_RPG6,
+ OUT_RPB8,
+ OUT_RPB15,
+ OUT_RPD4,
+ OUT_RPB0,
+ OUT_RPE3,
+ OUT_RPB7,
+ OUT_RPF12,
+ OUT_RPD12,
+ OUT_RPF8,
+ OUT_RPC3,
+ OUT_RPE9,
+ OUT_RPD1,
+ OUT_RPG9,
+ OUT_RPB14,
+ OUT_RPD0,
+ OUT_RPB6,
+ OUT_RPD5,
+ OUT_RPB2,
+ OUT_RPF3,
+ OUT_RPF13,
+ OUT_RPC2,
+ OUT_RPE8,
+ OUT_RPF2,
+};
+
+/* Output PPS Functions */
+#define OUT_FUNC_U3TX 0x01
+#define OUT_FUNC_U4RTS 0x02
+#define OUT_FUNC_SDO1 0x05
+#define OUT_FUNC_SDO2 0x06
+#define OUT_FUNC_SDO3 0x07
+#define OUT_FUNC_SDO5 0x09
+#define OUT_FUNC_SS6 0x0A
+#define OUT_FUNC_OC3 0x0B
+#define OUT_FUNC_OC6 0x0C
+#define OUT_FUNC_REFCLKO4 0x0D
+#define OUT_FUNC_C2OUT 0x0E
+#define OUT_FUNC_C1TX 0x0F
+#define OUT_FUNC_U1TX 0x01
+#define OUT_FUNC_U2RTS 0x02
+#define OUT_FUNC_U5TX 0x03
+#define OUT_FUNC_U6RTS 0x04
+#define OUT_FUNC_SDO1 0x05
+#define OUT_FUNC_SDO2 0x06
+#define OUT_FUNC_SDO3 0x07
+#define OUT_FUNC_SDO4 0x08
+#define OUT_FUNC_SDO5 0x09
+#define OUT_FUNC_OC4 0x0B
+#define OUT_FUNC_OC7 0x0C
+#define OUT_FUNC_REFCLKO1 0x0F
+#define OUT_FUNC_U3RTS 0x01
+#define OUT_FUNC_U4TX 0x02
+#define OUT_FUNC_U6TX 0x04
+#define OUT_FUNC_SS1 0x05
+#define OUT_FUNC_SS3 0x07
+#define OUT_FUNC_SS4 0x08
+#define OUT_FUNC_SS5 0x09
+#define OUT_FUNC_SDO6 0x0A
+#define OUT_FUNC_OC5 0x0B
+#define OUT_FUNC_OC8 0x0C
+#define OUT_FUNC_C1OUT 0x0E
+#define OUT_FUNC_REFCLKO3 0x0F
+#define OUT_FUNC_U1RTS 0x01
+#define OUT_FUNC_U2TX 0x02
+#define OUT_FUNC_U5RTS 0x03
+#define OUT_FUNC_U6TX 0x04
+#define OUT_FUNC_SS2 0x06
+#define OUT_FUNC_SDO4 0x08
+#define OUT_FUNC_SDO6 0x0A
+#define OUT_FUNC_OC2 0x0B
+#define OUT_FUNC_OC1 0x0C
+#define OUT_FUNC_OC9 0x0D
+#define OUT_FUNC_C2TX 0x0F
+
+void pic32_pps_input(int function, int pin);
+void pic32_pps_output(int function, int pin);
+
+#endif
diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
new file mode 100644
index 0000000..775ff90
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/init.c
@@ -0,0 +1,156 @@
+/*
+ * Joshua Henderson, joshua.henderson@microchip.com
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/sdhci-pic32.h>
+
+#include <asm/fw/fw.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/prom.h>
+
+#include "pic32mzda.h"
+
+const char *get_system_type(void)
+{
+ return "PIC32MZDA";
+}
+
+static ulong get_fdtaddr(void)
+{
+ ulong ftaddr = 0;
+
+ if ((fw_arg0 == -2) && fw_arg1 && !fw_arg2 && !fw_arg3)
+ return (ulong)fw_arg1;
+
+ if (__dtb_start < __dtb_end)
+ ftaddr = (ulong)__dtb_start;
+
+ return ftaddr;
+}
+
+void __init plat_mem_setup(void)
+{
+ void *dtb;
+
+ dtb = (void *)get_fdtaddr();
+ if (!dtb) {
+ pr_err("pic32: no DTB found.\n");
+ return;
+ }
+
+ /*
+ * Load the builtin device tree. This causes the chosen node to be
+ * parsed resulting in our memory appearing.
+ */
+ __dt_setup_arch(dtb);
+
+ pr_info("Found following command lines\n");
+ pr_info(" boot_command_line: %s\n", boot_command_line);
+ pr_info(" arcs_cmdline : %s\n", arcs_cmdline);
+#ifdef CONFIG_CMDLINE_BOOL
+ pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE);
+#endif
+ if (dtb != __dtb_start)
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+
+#ifdef CONFIG_EARLY_PRINTK
+ fw_init_early_console(-1);
+#endif
+ pic32_config_init();
+}
+
+static __init void pic32_init_cmdline(int argc, char *argv[])
+{
+ unsigned int count = COMMAND_LINE_SIZE - 1;
+ int i;
+ char *dst = &(arcs_cmdline[0]);
+ char *src;
+
+ for (i = 1; i < argc && count; ++i) {
+ src = argv[i];
+ while (*src && count) {
+ *dst++ = *src++;
+ --count;
+ }
+ *dst++ = ' ';
+ }
+ if (i > 1)
+ --dst;
+
+ *dst = 0;
+}
+
+void __init prom_init(void)
+{
+ pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init device_tree_init(void)
+{
+ if (!initial_boot_params)
+ return;
+
+ unflatten_and_copy_device_tree();
+}
+
+static struct pic32_sdhci_platform_data sdhci_data = {
+ .setup_dma = pic32_set_sdhci_adma_fifo_threshold,
+};
+
+static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data),
+ { /* sentinel */}
+};
+
+static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup)
+{
+ struct device_node *root, *np;
+ struct resource res;
+
+ root = of_find_node_by_path("/");
+
+ for (; lookup->compatible; lookup++) {
+ np = of_find_compatible_node(NULL, NULL, lookup->compatible);
+ if (np) {
+ lookup->name = (char *)np->name;
+ if (lookup->phys_addr)
+ continue;
+ if (!of_address_to_resource(np, 0, &res))
+ lookup->phys_addr = res.start;
+ }
+ }
+
+ return 0;
+}
+
+static int __init plat_of_setup(void)
+{
+ if (!of_have_populated_dt())
+ panic("Device tree not present");
+
+ pic32_of_prepare_platform_data(pic32_auxdata_lookup);
+ if (of_platform_populate(NULL, of_default_bus_match_table,
+ pic32_auxdata_lookup, NULL))
+ panic("Failed to populate DT");
+
+ return 0;
+}
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/pic32/pic32mzda/pic32mzda.h b/arch/mips/pic32/pic32mzda/pic32mzda.h
new file mode 100644
index 0000000..96d10e2
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/pic32mzda.h
@@ -0,0 +1,29 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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 PIC32MZDA_COMMON_H
+#define PIC32MZDA_COMMON_H
+
+/* early clock */
+u32 pic32_get_pbclk(int bus);
+u32 pic32_get_sysclk(void);
+
+/* Device configuration */
+void __init pic32_config_init(void);
+int pic32_set_lcd_mode(int mode);
+int pic32_set_sdhci_adma_fifo_threshold(u32 rthrs, u32 wthrs);
+u32 pic32_get_boot_status(void);
+int pic32_disable_lcd(void);
+int pic32_enable_lcd(void);
+
+#endif
diff --git a/arch/mips/pic32/pic32mzda/time.c b/arch/mips/pic32/pic32mzda/time.c
new file mode 100644
index 0000000..ca6a62b
--- /dev/null
+++ b/arch/mips/pic32/pic32mzda/time.c
@@ -0,0 +1,73 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * 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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/time.h>
+
+#include "pic32mzda.h"
+
+static const struct of_device_id pic32_infra_match[] = {
+ { .compatible = "microchip,pic32mzda-infra", },
+ { },
+};
+
+#define DEFAULT_CORE_TIMER_INTERRUPT 0
+
+static unsigned int pic32_xlate_core_timer_irq(void)
+{
+ static struct device_node *node;
+ unsigned int irq;
+
+ node = of_find_matching_node(NULL, pic32_infra_match);
+
+ if (WARN_ON(!node))
+ goto default_map;
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (!irq)
+ goto default_map;
+
+ return irq;
+
+default_map:
+
+ return irq_create_mapping(NULL, DEFAULT_CORE_TIMER_INTERRUPT);
+}
+
+unsigned int get_c0_compare_int(void)
+{
+ return pic32_xlate_core_timer_irq();
+}
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ of_clk_init(NULL);
+ clk = clk_get_sys("cpu_clk", NULL);
+ if (IS_ERR(clk))
+ panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+
+ clk_prepare_enable(clk);
+ pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+
+ clocksource_probe();
+}
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c
index 8bd8ebb..96ba2cc 100644
--- a/arch/mips/pistachio/init.c
+++ b/arch/mips/pistachio/init.c
@@ -58,7 +58,6 @@ void __init plat_mem_setup(void)
panic("Device-tree not present");
__dt_setup_arch((void *)fw_arg1);
- strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
plat_setup_iocoherency();
}
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 8a37734..1022201 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -39,7 +39,7 @@ void __init plat_time_init(void)
struct clk *clk;
of_clk_init(NULL);
- clocksource_of_init();
+ clocksource_probe();
np = of_get_cpu_node(0, NULL);
if (!np) {
diff --git a/arch/mips/pmcs-msp71xx/msp_serial.c b/arch/mips/pmcs-msp71xx/msp_serial.c
index d304be2..8e6e8db 100644
--- a/arch/mips/pmcs-msp71xx/msp_serial.c
+++ b/arch/mips/pmcs-msp71xx/msp_serial.c
@@ -110,7 +110,7 @@ void __init msp_serial_setup(void)
up.uartclk = uartclk;
up.regshift = 2;
up.iotype = UPIO_MEM;
- up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
up.type = PORT_16550A;
up.line = 0;
up.serial_out = msp_serial_out;
diff --git a/arch/mips/pmcs-msp71xx/msp_setup.c b/arch/mips/pmcs-msp71xx/msp_setup.c
index 4f925e0..9d293b3 100644
--- a/arch/mips/pmcs-msp71xx/msp_setup.c
+++ b/arch/mips/pmcs-msp71xx/msp_setup.c
@@ -10,6 +10,8 @@
* option) any later version.
*/
+#include <linux/delay.h>
+
#include <asm/bootinfo.h>
#include <asm/cacheflush.h>
#include <asm/idle.h>
@@ -37,7 +39,6 @@ extern void msp_serial_setup(void);
void msp7120_reset(void)
{
void *start, *end, *iptr;
- register int i;
/* Diasble all interrupts */
local_irq_disable();
@@ -77,7 +78,7 @@ void msp7120_reset(void)
*/
/* Wait a bit for the DDRC to settle */
- for (i = 0; i < 100000000; i++);
+ mdelay(125);
#if defined(CONFIG_PMC_MSP7120_GW)
/*
diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c
index b4b774b..3cd3577 100644
--- a/arch/mips/pnx833x/common/platform.c
+++ b/arch/mips/pnx833x/common/platform.c
@@ -180,7 +180,7 @@ static struct platform_device pnx833x_sata_device = {
static void
pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
- struct nand_chip *this = mtd->priv;
+ struct nand_chip *this = mtd_to_nand(mtd);
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
if (cmd == NAND_CMD_NONE)
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index e9bc8c9..813826a 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -12,6 +12,11 @@ config RALINK_ILL_ACC
depends on SOC_RT305X
default y
+config IRQ_INTC
+ bool
+ default y
+ depends on !SOC_MT7621
+
choice
prompt "Ralink SoC selection"
default SOC_RT305X
@@ -33,7 +38,18 @@ choice
config SOC_MT7620
bool "MT7620/8"
+ select HW_HAS_PCI
+ config SOC_MT7621
+ bool "MT7621"
+ select MIPS_CPU_SCACHE
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_MIPS_CPS
+ select MIPS_GIC
+ select COMMON_CLK
+ select CLKSRC_MIPS_GIC
+ select HW_HAS_PCI
endchoice
choice
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index a6c9d00..0d1795a 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -6,16 +6,24 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-obj-y := prom.o of.o reset.o clk.o irq.o timer.o
+obj-y := prom.o of.o reset.o
+
+ifndef CONFIG_MIPS_GIC
+ obj-y += clk.o timer.o
+endif
obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
+obj-$(CONFIG_IRQ_INTC) += irq.o
+obj-$(CONFIG_MIPS_GIC) += irq-gic.o timer-gic.o
+
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
obj-$(CONFIG_SOC_RT3883) += rt3883.o
obj-$(CONFIG_SOC_MT7620) += mt7620.o
+obj-$(CONFIG_SOC_MT7621) += mt7621.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
index 6d9c8c4..6095fcc 100644
--- a/arch/mips/ralink/Platform
+++ b/arch/mips/ralink/Platform
@@ -27,3 +27,8 @@ cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt
#
load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000
cflags-$(CONFIG_SOC_MT7620) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620
+
+# Ralink MT7621
+#
+load-$(CONFIG_SOC_MT7621) += 0xffffffff80001000
+cflags-$(CONFIG_SOC_MT7621) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7621
diff --git a/arch/mips/ralink/cevt-rt3352.c b/arch/mips/ralink/cevt-rt3352.c
index a8e70a9..e46f91f 100644
--- a/arch/mips/ralink/cevt-rt3352.c
+++ b/arch/mips/ralink/cevt-rt3352.c
@@ -48,7 +48,7 @@ static int systick_next_event(unsigned long delta,
sdev = container_of(evt, struct systick_device, dev);
count = ioread32(sdev->membase + SYSTICK_COUNT);
count = (count + delta) % SYSTICK_FREQ;
- iowrite32(count + delta, sdev->membase + SYSTICK_COMPARE);
+ iowrite32(count, sdev->membase + SYSTICK_COMPARE);
return 0;
}
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index feb5a9b..25c4a61 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -75,5 +75,5 @@ void __init plat_time_init(void)
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
mips_hpt_frequency = clk_get_rate(clk) / 2;
clk_put(clk);
- clocksource_of_init();
+ clocksource_probe();
}
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
index 255d695..3c59ffe 100644
--- a/arch/mips/ralink/early_printk.c
+++ b/arch/mips/ralink/early_printk.c
@@ -25,11 +25,13 @@
#define MT7628_CHIP_NAME1 0x20203832
#define UART_REG_TX 0x04
+#define UART_REG_LCR 0x0c
#define UART_REG_LSR 0x14
#define UART_REG_LSR_RT2880 0x1c
static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE);
+static int init_complete;
static inline void uart_w32(u32 val, unsigned reg)
{
@@ -47,8 +49,32 @@ static inline int soc_is_mt7628(void)
(__raw_readl(chipid_membase) == MT7628_CHIP_NAME1);
}
+static void find_uart_base(void)
+{
+ int i;
+
+ if (!soc_is_mt7628())
+ return;
+
+ for (i = 0; i < 3; i++) {
+ u32 reg = uart_r32(UART_REG_LCR + (0x100 * i));
+
+ if (!reg)
+ continue;
+
+ uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE +
+ (0x100 * i));
+ break;
+ }
+}
+
void prom_putchar(unsigned char ch)
{
+ if (!init_complete) {
+ find_uart_base();
+ init_complete = 1;
+ }
+
if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) {
uart_w32(ch, UART_TX);
while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
new file mode 100644
index 0000000..50d6c55
--- /dev/null
+++ b/arch/mips/ralink/irq-gic.c
@@ -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.
+ *
+ * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+
+#include <linux/of.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/mips-gic.h>
+
+int get_c0_perfcount_int(void)
+{
+ return gic_get_c0_perfcount_int();
+}
+EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+
+void __init arch_init_irq(void)
+{
+ irqchip_init();
+}
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index 2ea5ff6..0d3d1a9 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -37,8 +37,17 @@
#define PMU1_CFG 0x8C
#define DIG_SW_SEL BIT(25)
-/* is this a MT7620 or a MT7628 */
-enum mt762x_soc_type mt762x_soc;
+/* clock scaling */
+#define CLKCFG_FDIV_MASK 0x1f00
+#define CLKCFG_FDIV_USB_VAL 0x0300
+#define CLKCFG_FFRAC_MASK 0x001f
+#define CLKCFG_FFRAC_USB_VAL 0x0003
+
+/* EFUSE bits */
+#define EFUSE_MT7688 0x100000
+
+/* DRAM type bit */
+#define DRAM_TYPE_MT7628_MASK 0x1
/* does the board have sdram or ddram */
static int dram_type;
@@ -98,31 +107,31 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
};
static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
- FUNC("sdcx", 3, 19, 1),
+ FUNC("sdxc d6", 3, 19, 1),
FUNC("utif", 2, 19, 1),
FUNC("gpio", 1, 19, 1),
- FUNC("pwm", 0, 19, 1),
+ FUNC("pwm1", 0, 19, 1),
};
static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
- FUNC("sdcx", 3, 18, 1),
+ FUNC("sdxc d7", 3, 18, 1),
FUNC("utif", 2, 18, 1),
FUNC("gpio", 1, 18, 1),
- FUNC("pwm", 0, 18, 1),
+ FUNC("pwm0", 0, 18, 1),
};
static struct rt2880_pmx_func uart2_grp_mt7628[] = {
- FUNC("sdcx", 3, 20, 2),
+ FUNC("sdxc d5 d4", 3, 20, 2),
FUNC("pwm", 2, 20, 2),
FUNC("gpio", 1, 20, 2),
- FUNC("uart", 0, 20, 2),
+ FUNC("uart2", 0, 20, 2),
};
static struct rt2880_pmx_func uart1_grp_mt7628[] = {
- FUNC("sdcx", 3, 45, 2),
+ FUNC("sw_r", 3, 45, 2),
FUNC("pwm", 2, 45, 2),
FUNC("gpio", 1, 45, 2),
- FUNC("uart", 0, 45, 2),
+ FUNC("uart1", 0, 45, 2),
};
static struct rt2880_pmx_func i2c_grp_mt7628[] = {
@@ -134,21 +143,21 @@ static struct rt2880_pmx_func i2c_grp_mt7628[] = {
static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
-static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) };
+static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
FUNC("jtag", 3, 22, 8),
FUNC("utif", 2, 22, 8),
FUNC("gpio", 1, 22, 8),
- FUNC("sdcx", 0, 22, 8),
+ FUNC("sdxc", 0, 22, 8),
};
static struct rt2880_pmx_func uart0_grp_mt7628[] = {
FUNC("-", 3, 12, 2),
FUNC("-", 2, 12, 2),
FUNC("gpio", 1, 12, 2),
- FUNC("uart", 0, 12, 2),
+ FUNC("uart0", 0, 12, 2),
};
static struct rt2880_pmx_func i2s_grp_mt7628[] = {
@@ -162,7 +171,7 @@ static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
FUNC("-", 3, 6, 1),
FUNC("refclk", 2, 6, 1),
FUNC("gpio", 1, 6, 1),
- FUNC("spi", 0, 6, 1),
+ FUNC("spi cs1", 0, 6, 1),
};
static struct rt2880_pmx_func spis_grp_mt7628[] = {
@@ -179,28 +188,44 @@ static struct rt2880_pmx_func gpio_grp_mt7628[] = {
FUNC("gpio", 0, 11, 1),
};
-#define MT7628_GPIO_MODE_MASK 0x3
-
-#define MT7628_GPIO_MODE_PWM1 30
-#define MT7628_GPIO_MODE_PWM0 28
-#define MT7628_GPIO_MODE_UART2 26
-#define MT7628_GPIO_MODE_UART1 24
-#define MT7628_GPIO_MODE_I2C 20
-#define MT7628_GPIO_MODE_REFCLK 18
-#define MT7628_GPIO_MODE_PERST 16
-#define MT7628_GPIO_MODE_WDT 14
-#define MT7628_GPIO_MODE_SPI 12
-#define MT7628_GPIO_MODE_SDMODE 10
-#define MT7628_GPIO_MODE_UART0 8
-#define MT7628_GPIO_MODE_I2S 6
-#define MT7628_GPIO_MODE_CS1 4
-#define MT7628_GPIO_MODE_SPIS 2
-#define MT7628_GPIO_MODE_GPIO 0
+static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {
+ FUNC("rsvd", 3, 35, 1),
+ FUNC("rsvd", 2, 35, 1),
+ FUNC("gpio", 1, 35, 1),
+ FUNC("wled_kn", 0, 35, 1),
+};
+
+static struct rt2880_pmx_func wled_an_grp_mt7628[] = {
+ FUNC("rsvd", 3, 35, 1),
+ FUNC("rsvd", 2, 35, 1),
+ FUNC("gpio", 1, 35, 1),
+ FUNC("wled_an", 0, 35, 1),
+};
+
+#define MT7628_GPIO_MODE_MASK 0x3
+
+#define MT7628_GPIO_MODE_WLED_KN 48
+#define MT7628_GPIO_MODE_WLED_AN 32
+#define MT7628_GPIO_MODE_PWM1 30
+#define MT7628_GPIO_MODE_PWM0 28
+#define MT7628_GPIO_MODE_UART2 26
+#define MT7628_GPIO_MODE_UART1 24
+#define MT7628_GPIO_MODE_I2C 20
+#define MT7628_GPIO_MODE_REFCLK 18
+#define MT7628_GPIO_MODE_PERST 16
+#define MT7628_GPIO_MODE_WDT 14
+#define MT7628_GPIO_MODE_SPI 12
+#define MT7628_GPIO_MODE_SDMODE 10
+#define MT7628_GPIO_MODE_UART0 8
+#define MT7628_GPIO_MODE_I2S 6
+#define MT7628_GPIO_MODE_CS1 4
+#define MT7628_GPIO_MODE_SPIS 2
+#define MT7628_GPIO_MODE_GPIO 0
static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
1, MT7628_GPIO_MODE_PWM1),
- GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+ GRP_G("pmw0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
1, MT7628_GPIO_MODE_PWM0),
GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
1, MT7628_GPIO_MODE_UART2),
@@ -224,9 +249,19 @@ static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
1, MT7628_GPIO_MODE_SPIS),
GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
1, MT7628_GPIO_MODE_GPIO),
+ GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+ 1, MT7628_GPIO_MODE_WLED_AN),
+ GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+ 1, MT7628_GPIO_MODE_WLED_KN),
{ 0 }
};
+static inline int is_mt76x8(void)
+{
+ return ralink_soc == MT762X_SOC_MT7628AN ||
+ ralink_soc == MT762X_SOC_MT7688;
+}
+
static __init u32
mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
{
@@ -381,7 +416,7 @@ void __init ralink_clk_init(void)
#define RINT(x) ((x) / 1000000)
#define RFRAC(x) (((x) / 1000) % 1000)
- if (mt762x_soc == MT762X_SOC_MT7628AN) {
+ if (is_mt76x8()) {
if (xtal_rate == MHZ(40))
cpu_rate = MHZ(580);
else
@@ -421,8 +456,25 @@ void __init ralink_clk_init(void)
ralink_clk_add("10000100.timer", periph_rate);
ralink_clk_add("10000120.watchdog", periph_rate);
ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
ralink_clk_add("10000c00.uartlite", periph_rate);
+ ralink_clk_add("10000d00.uart1", periph_rate);
+ ralink_clk_add("10000e00.uart2", periph_rate);
ralink_clk_add("10180000.wmac", xtal_rate);
+
+ if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) {
+ /*
+ * When the CPU goes into sleep mode, the BUS clock will be
+ * too low for USB to function properly. Adjust the busses
+ * fractional divider to fix this
+ */
+ u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
+
+ val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
+ val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
+
+ rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG);
+ }
}
void __init ralink_of_remap(void)
@@ -499,36 +551,44 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) {
if (bga) {
- mt762x_soc = MT762X_SOC_MT7620A;
+ ralink_soc = MT762X_SOC_MT7620A;
name = "MT7620A";
soc_info->compatible = "ralink,mt7620a-soc";
} else {
- mt762x_soc = MT762X_SOC_MT7620N;
+ ralink_soc = MT762X_SOC_MT7620N;
name = "MT7620N";
soc_info->compatible = "ralink,mt7620n-soc";
-#ifdef CONFIG_PCI
- panic("mt7620n is only supported for non pci kernels");
-#endif
}
} else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) {
- mt762x_soc = MT762X_SOC_MT7628AN;
- name = "MT7628AN";
+ u32 efuse = __raw_readl(sysc + SYSC_REG_EFUSE_CFG);
+
+ if (efuse & EFUSE_MT7688) {
+ ralink_soc = MT762X_SOC_MT7688;
+ name = "MT7688";
+ } else {
+ ralink_soc = MT762X_SOC_MT7628AN;
+ name = "MT7628AN";
+ }
soc_info->compatible = "ralink,mt7628an-soc";
} else {
panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
}
snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
- "Ralink %s ver:%u eco:%u",
+ "MediaTek %s ver:%u eco:%u",
name,
(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
(rev & CHIP_REV_ECO_MASK));
cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0);
- dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK;
+ if (is_mt76x8())
+ dram_type = cfg0 & DRAM_TYPE_MT7628_MASK;
+ else
+ dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) &
+ SYSCFG0_DRAM_TYPE_MASK;
soc_info->mem_base = MT7620_DRAM_BASE;
- if (mt762x_soc == MT762X_SOC_MT7628AN)
+ if (is_mt76x8())
mt7628_dram_init(soc_info);
else
mt7620_dram_init(soc_info);
@@ -541,7 +601,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
pr_info("Digital PMU set to %s control\n",
(pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
- if (mt762x_soc == MT762X_SOC_MT7628AN)
+ if (is_mt76x8())
rt2880_pinmux_data = mt7628an_pinmux_data;
else
rt2880_pinmux_data = mt7620a_pinmux_data;
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
new file mode 100644
index 0000000..e9b9fa3
--- /dev/null
+++ b/arch/mips/ralink/mt7621.c
@@ -0,0 +1,226 @@
+/*
+ * This program is free software; you can 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) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/smp-ops.h>
+#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7621.h>
+
+#include <pinmux.h>
+
+#include "common.h"
+
+#define SYSC_REG_SYSCFG 0x10
+#define SYSC_REG_CPLL_CLKCFG0 0x2c
+#define SYSC_REG_CUR_CLK_STS 0x44
+#define CPU_CLK_SEL (BIT(30) | BIT(31))
+
+#define MT7621_GPIO_MODE_UART1 1
+#define MT7621_GPIO_MODE_I2C 2
+#define MT7621_GPIO_MODE_UART3_MASK 0x3
+#define MT7621_GPIO_MODE_UART3_SHIFT 3
+#define MT7621_GPIO_MODE_UART3_GPIO 1
+#define MT7621_GPIO_MODE_UART2_MASK 0x3
+#define MT7621_GPIO_MODE_UART2_SHIFT 5
+#define MT7621_GPIO_MODE_UART2_GPIO 1
+#define MT7621_GPIO_MODE_JTAG 7
+#define MT7621_GPIO_MODE_WDT_MASK 0x3
+#define MT7621_GPIO_MODE_WDT_SHIFT 8
+#define MT7621_GPIO_MODE_WDT_GPIO 1
+#define MT7621_GPIO_MODE_PCIE_RST 0
+#define MT7621_GPIO_MODE_PCIE_REF 2
+#define MT7621_GPIO_MODE_PCIE_MASK 0x3
+#define MT7621_GPIO_MODE_PCIE_SHIFT 10
+#define MT7621_GPIO_MODE_PCIE_GPIO 1
+#define MT7621_GPIO_MODE_MDIO_MASK 0x3
+#define MT7621_GPIO_MODE_MDIO_SHIFT 12
+#define MT7621_GPIO_MODE_MDIO_GPIO 1
+#define MT7621_GPIO_MODE_RGMII1 14
+#define MT7621_GPIO_MODE_RGMII2 15
+#define MT7621_GPIO_MODE_SPI_MASK 0x3
+#define MT7621_GPIO_MODE_SPI_SHIFT 16
+#define MT7621_GPIO_MODE_SPI_GPIO 1
+#define MT7621_GPIO_MODE_SDHCI_MASK 0x3
+#define MT7621_GPIO_MODE_SDHCI_SHIFT 18
+#define MT7621_GPIO_MODE_SDHCI_GPIO 1
+
+static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
+static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
+static struct rt2880_pmx_func uart3_grp[] = {
+ FUNC("uart3", 0, 5, 4),
+ FUNC("i2s", 2, 5, 4),
+ FUNC("spdif3", 3, 5, 4),
+};
+static struct rt2880_pmx_func uart2_grp[] = {
+ FUNC("uart2", 0, 9, 4),
+ FUNC("pcm", 2, 9, 4),
+ FUNC("spdif2", 3, 9, 4),
+};
+static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
+static struct rt2880_pmx_func wdt_grp[] = {
+ FUNC("wdt rst", 0, 18, 1),
+ FUNC("wdt refclk", 2, 18, 1),
+};
+static struct rt2880_pmx_func pcie_rst_grp[] = {
+ FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
+ FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
+};
+static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
+static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
+static struct rt2880_pmx_func spi_grp[] = {
+ FUNC("spi", 0, 34, 7),
+ FUNC("nand1", 2, 34, 7),
+};
+static struct rt2880_pmx_func sdhci_grp[] = {
+ FUNC("sdhci", 0, 41, 8),
+ FUNC("nand2", 2, 41, 8),
+};
+static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
+
+static struct rt2880_pmx_group mt7621_pinmux_data[] = {
+ GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
+ GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
+ GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK,
+ MT7621_GPIO_MODE_UART3_GPIO, MT7621_GPIO_MODE_UART3_SHIFT),
+ GRP_G("uart2", uart2_grp, MT7621_GPIO_MODE_UART2_MASK,
+ MT7621_GPIO_MODE_UART2_GPIO, MT7621_GPIO_MODE_UART2_SHIFT),
+ GRP("jtag", jtag_grp, 1, MT7621_GPIO_MODE_JTAG),
+ GRP_G("wdt", wdt_grp, MT7621_GPIO_MODE_WDT_MASK,
+ MT7621_GPIO_MODE_WDT_GPIO, MT7621_GPIO_MODE_WDT_SHIFT),
+ GRP_G("pcie", pcie_rst_grp, MT7621_GPIO_MODE_PCIE_MASK,
+ MT7621_GPIO_MODE_PCIE_GPIO, MT7621_GPIO_MODE_PCIE_SHIFT),
+ GRP_G("mdio", mdio_grp, MT7621_GPIO_MODE_MDIO_MASK,
+ MT7621_GPIO_MODE_MDIO_GPIO, MT7621_GPIO_MODE_MDIO_SHIFT),
+ GRP("rgmii2", rgmii2_grp, 1, MT7621_GPIO_MODE_RGMII2),
+ GRP_G("spi", spi_grp, MT7621_GPIO_MODE_SPI_MASK,
+ MT7621_GPIO_MODE_SPI_GPIO, MT7621_GPIO_MODE_SPI_SHIFT),
+ GRP_G("sdhci", sdhci_grp, MT7621_GPIO_MODE_SDHCI_MASK,
+ MT7621_GPIO_MODE_SDHCI_GPIO, MT7621_GPIO_MODE_SDHCI_SHIFT),
+ GRP("rgmii1", rgmii1_grp, 1, MT7621_GPIO_MODE_RGMII1),
+ { 0 }
+};
+
+phys_addr_t mips_cpc_default_phys_base(void)
+{
+ panic("Cannot detect cpc address");
+}
+
+void __init ralink_clk_init(void)
+{
+ int cpu_fdiv = 0;
+ int cpu_ffrac = 0;
+ int fbdiv = 0;
+ u32 clk_sts, syscfg;
+ u8 clk_sel = 0, xtal_mode;
+ u32 cpu_clk;
+
+ if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
+ clk_sel = 1;
+
+ switch (clk_sel) {
+ case 0:
+ clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+ cpu_fdiv = ((clk_sts >> 8) & 0x1F);
+ cpu_ffrac = (clk_sts & 0x1F);
+ cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
+ break;
+
+ case 1:
+ fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
+ syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
+ xtal_mode = (syscfg >> 6) & 0x7;
+ if (xtal_mode >= 6) {
+ /* 25Mhz Xtal */
+ cpu_clk = 25 * fbdiv * 1000 * 1000;
+ } else if (xtal_mode >= 3) {
+ /* 40Mhz Xtal */
+ cpu_clk = 40 * fbdiv * 1000 * 1000;
+ } else {
+ /* 20Mhz Xtal */
+ cpu_clk = 20 * fbdiv * 1000 * 1000;
+ }
+ break;
+ }
+}
+
+void __init ralink_of_remap(void)
+{
+ rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
+ rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
+
+ if (!rt_sysc_membase || !rt_memc_membase)
+ panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+ unsigned char *name = NULL;
+ u32 n0;
+ u32 n1;
+ u32 rev;
+
+ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+
+ if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
+ name = "MT7621";
+ soc_info->compatible = "mtk,mt7621-soc";
+ } else {
+ panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+ }
+
+ rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "MediaTek %s ver:%u eco:%u",
+ name,
+ (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+ (rev & CHIP_REV_ECO_MASK));
+
+ soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
+ soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
+ soc_info->mem_base = MT7621_DRAM_BASE;
+
+ rt2880_pinmux_data = mt7621_pinmux_data;
+
+ /* Early detection of CMP support */
+ mips_cm_probe();
+ mips_cpc_probe();
+
+ if (mips_cm_numiocu()) {
+ /*
+ * mips_cm_probe() wipes out bootloader
+ * config for CM regions and we have to configure them
+ * again. This SoC cannot talk to pamlbus devices
+ * witout proper iocu region set up.
+ *
+ * FIXME: it would be better to do this with values
+ * from DT, but we need this very early because
+ * without this we cannot talk to pretty much anything
+ * including serial.
+ */
+ write_gcr_reg0_base(MT7621_PALMBUS_BASE);
+ write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
+ CM_GCR_REGn_MASK_CMTGT_IOCU0);
+ }
+
+ if (!register_cps_smp_ops())
+ return;
+ if (!register_cmp_smp_ops())
+ return;
+ if (!register_vsmp_smp_ops())
+ return;
+}
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index 0d30dcd..f9eda5d 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -74,8 +74,6 @@ void __init plat_mem_setup(void)
*/
__dt_setup_arch(__dtb_start);
- strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-
of_scan_flat_dt(early_init_dt_find_memory, NULL);
if (memory_dtb)
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c
index 09419f6..39a9142f 100644
--- a/arch/mips/ralink/prom.c
+++ b/arch/mips/ralink/prom.c
@@ -15,11 +15,16 @@
#include <asm/bootinfo.h>
#include <asm/addrspace.h>
+#include <asm/mach-ralink/ralink_regs.h>
+
#include "common.h"
struct ralink_soc_info soc_info;
struct rt2880_pmx_group *rt2880_pinmux_data = NULL;
+enum ralink_soc_type ralink_soc;
+EXPORT_SYMBOL_GPL(ralink_soc);
+
const char *get_system_type(void)
{
return soc_info.sys_type;
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c
index 55c7ec5..ee117c4 100644
--- a/arch/mips/ralink/reset.c
+++ b/arch/mips/ralink/reset.c
@@ -11,6 +11,7 @@
#include <linux/pm.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/delay.h>
#include <linux/reset-controller.h>
#include <asm/reboot.h>
@@ -18,8 +19,10 @@
#include <asm/mach-ralink/ralink_regs.h>
/* Reset Control */
-#define SYSC_REG_RESET_CTRL 0x034
-#define RSTCTL_RESET_SYSTEM BIT(0)
+#define SYSC_REG_RESET_CTRL 0x034
+
+#define RSTCTL_RESET_PCI BIT(26)
+#define RSTCTL_RESET_SYSTEM BIT(0)
static int ralink_assert_device(struct reset_controller_dev *rcdev,
unsigned long id)
@@ -83,6 +86,11 @@ void ralink_rst_init(void)
static void ralink_restart(char *command)
{
+ if (IS_ENABLED(CONFIG_PCI)) {
+ rt_sysc_m32(0, RSTCTL_RESET_PCI, SYSC_REG_RESET_CTRL);
+ mdelay(50);
+ }
+
local_irq_disable();
rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
unreachable();
@@ -98,7 +106,6 @@ static int __init mips_reboot_setup(void)
{
_machine_restart = ralink_restart;
_machine_halt = ralink_halt;
- pm_power_off = ralink_halt;
return 0;
}
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
index 738cec8..3c84166 100644
--- a/arch/mips/ralink/rt288x.c
+++ b/arch/mips/ralink/rt288x.c
@@ -119,4 +119,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
rt2880_pinmux_data = rt2880_pinmux_data_act;
+ ralink_soc = RT2880_SOC;
}
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
index c40776a..d7c4ba4 100644
--- a/arch/mips/ralink/rt305x.c
+++ b/arch/mips/ralink/rt305x.c
@@ -21,8 +21,6 @@
#include "common.h"
-enum rt305x_soc_type rt305x_soc;
-
static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
static struct rt2880_pmx_func uartf_func[] = {
@@ -201,7 +199,9 @@ void __init ralink_clk_init(void)
}
ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("sys", sys_rate);
ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
ralink_clk_add("10000100.timer", wdt_rate);
ralink_clk_add("10000120.watchdog", wdt_rate);
ralink_clk_add("10000500.uart", uart_rate);
@@ -235,24 +235,24 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
icache_sets = (read_c0_config1() >> 22) & 7;
if (icache_sets == 1) {
- rt305x_soc = RT305X_SOC_RT3050;
+ ralink_soc = RT305X_SOC_RT3050;
name = "RT3050";
soc_info->compatible = "ralink,rt3050-soc";
} else {
- rt305x_soc = RT305X_SOC_RT3052;
+ ralink_soc = RT305X_SOC_RT3052;
name = "RT3052";
soc_info->compatible = "ralink,rt3052-soc";
}
} else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) {
- rt305x_soc = RT305X_SOC_RT3350;
+ ralink_soc = RT305X_SOC_RT3350;
name = "RT3350";
soc_info->compatible = "ralink,rt3350-soc";
} else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) {
- rt305x_soc = RT305X_SOC_RT3352;
+ ralink_soc = RT305X_SOC_RT3352;
name = "RT3352";
soc_info->compatible = "ralink,rt3352-soc";
} else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) {
- rt305x_soc = RT305X_SOC_RT5350;
+ ralink_soc = RT305X_SOC_RT5350;
name = "RT5350";
soc_info->compatible = "ralink,rt5350-soc";
} else {
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
index 86a535c..fafec94 100644
--- a/arch/mips/ralink/rt3883.c
+++ b/arch/mips/ralink/rt3883.c
@@ -109,6 +109,7 @@ void __init ralink_clk_init(void)
ralink_clk_add("10000120.watchdog", sys_rate);
ralink_clk_add("10000500.uart", 40000000);
ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000b40.spi", sys_rate);
ralink_clk_add("10000c00.uartlite", 40000000);
ralink_clk_add("10100000.ethernet", sys_rate);
ralink_clk_add("10180000.wmac", 40000000);
@@ -153,4 +154,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
soc_info->mem_size_max = RT3883_MEM_SIZE_MAX;
rt2880_pinmux_data = rt3883_pinmux_data;
+
+ ralink_soc == RT3883_SOC;
}
diff --git a/arch/mips/ralink/timer-gic.c b/arch/mips/ralink/timer-gic.c
new file mode 100644
index 0000000..5b4f186
--- /dev/null
+++ b/arch/mips/ralink/timer-gic.c
@@ -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.
+ *
+ * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+#include "common.h"
+
+void __init plat_time_init(void)
+{
+ ralink_of_remap();
+
+ of_clk_init(NULL);
+ clocksource_probe();
+}
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index 9bd7a2d..0966adc 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -148,7 +148,7 @@ static int rb532_dev_ready(struct mtd_info *mtd)
static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
unsigned char orbits, nandbits;
if (ctrl & NAND_CTRL_CHANGE) {
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index 650d5d3..fdc704a 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -32,7 +32,7 @@
#include <linux/export.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <asm/mach-rc32434/rb.h>
#include <asm/mach-rc32434/gpio.h>
@@ -88,8 +88,8 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct rb532_gpio_chip *gpch;
- gpch = container_of(chip, struct rb532_gpio_chip, chip);
- return rb532_get_bit(offset, gpch->regbase + GPIOD);
+ gpch = gpiochip_get_data(chip);
+ return !!rb532_get_bit(offset, gpch->regbase + GPIOD);
}
/*
@@ -100,7 +100,7 @@ static void rb532_gpio_set(struct gpio_chip *chip,
{
struct rb532_gpio_chip *gpch;
- gpch = container_of(chip, struct rb532_gpio_chip, chip);
+ gpch = gpiochip_get_data(chip);
rb532_set_bit(value, offset, gpch->regbase + GPIOD);
}
@@ -111,7 +111,7 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct rb532_gpio_chip *gpch;
- gpch = container_of(chip, struct rb532_gpio_chip, chip);
+ gpch = gpiochip_get_data(chip);
/* disable alternate function in case it's set */
rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
@@ -128,7 +128,7 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip,
{
struct rb532_gpio_chip *gpch;
- gpch = container_of(chip, struct rb532_gpio_chip, chip);
+ gpch = gpiochip_get_data(chip);
/* disable alternate function in case it's set */
rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
@@ -200,7 +200,7 @@ int __init rb532_gpio_init(void)
}
/* Register our GPIO chip */
- gpiochip_add(&rb532_gpio_chip->chip);
+ gpiochip_add_data(&rb532_gpio_chip->chip, rb532_gpio_chip);
return 0;
}
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c
index 244f942..6afa343 100644
--- a/arch/mips/sni/reset.c
+++ b/arch/mips/sni/reset.c
@@ -3,6 +3,8 @@
*
* Reset a SNI machine.
*/
+#include <linux/delay.h>
+
#include <asm/io.h>
#include <asm/reboot.h>
#include <asm/sni.h>
@@ -24,7 +26,7 @@ static inline void kb_wait(void)
/* XXX This ends up at the ARC firmware prompt ... */
void sni_machine_restart(char *command)
{
- int i, j;
+ int i;
/* This does a normal via the keyboard controller like a PC.
We can do that easier ... */
@@ -32,9 +34,9 @@ void sni_machine_restart(char *command)
for (;;) {
for (i = 0; i < 100; i++) {
kb_wait();
- for (j = 0; j < 100000 ; j++)
- /* nothing */;
+ udelay(50);
outb_p(0xfe, 0x64); /* pulse reset low */
+ udelay(50);
}
}
}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 9d9962a..108f8a8 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -17,7 +17,7 @@
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/mtd/physmap.h>
@@ -687,16 +687,14 @@ struct txx9_iocled_data {
static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
{
- struct txx9_iocled_data *data =
- container_of(chip, struct txx9_iocled_data, chip);
- return data->cur_val & (1 << offset);
+ struct txx9_iocled_data *data = gpiochip_get_data(chip);
+ return !!(data->cur_val & (1 << offset));
}
static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
- struct txx9_iocled_data *data =
- container_of(chip, struct txx9_iocled_data, chip);
+ struct txx9_iocled_data *data = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&txx9_iocled_lock, flags);
if (value)
@@ -749,7 +747,7 @@ void __init txx9_iocled_init(unsigned long baseaddr,
iocled->chip.label = "iocled";
iocled->chip.base = basenum;
iocled->chip.ngpio = num;
- if (gpiochip_add(&iocled->chip))
+ if (gpiochip_add_data(&iocled->chip, iocled))
goto out_unmap;
if (basenum < 0)
basenum = iocled->chip.base;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index e3733cd..402ac2e 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -320,11 +320,12 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
#if IS_ENABLED(CONFIG_TC35815)
static u32 tx4939_get_eth_speed(struct net_device *dev)
{
- struct ethtool_cmd cmd;
- if (__ethtool_get_settings(dev, &cmd))
+ struct ethtool_link_ksettings cmd;
+
+ if (__ethtool_get_link_ksettings(dev, &cmd))
return 100; /* default 100Mbps */
- return ethtool_cmd_speed(&cmd);
+ return cmd.base.speed;
}
static int tx4939_netdev_event(struct notifier_block *this,
diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c
index 3dbad99..d833dd2 100644
--- a/arch/mips/txx9/generic/spi_eeprom.c
+++ b/arch/mips/txx9/generic/spi_eeprom.c
@@ -80,7 +80,6 @@ static int __init early_seeprom_probe(struct spi_device *spi)
static struct spi_driver early_seeprom_driver __initdata = {
.driver = {
.name = "at25",
- .owner = THIS_MODULE,
},
.probe = early_seeprom_probe,
};
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index c9afd05..54de668 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -14,6 +14,7 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/mtd/physmap.h>
@@ -335,7 +336,7 @@ static void __init rbtx4938_mtd_init(void)
static void __init rbtx4938_arch_init(void)
{
- gpiochip_add(&rbtx4938_spi_gpio_chip);
+ gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL);
rbtx4938_pci_setup();
rbtx4938_spi_init();
}
diff --git a/arch/mips/vdso/.gitignore b/arch/mips/vdso/.gitignore
new file mode 100644
index 0000000..5286a7d
--- /dev/null
+++ b/arch/mips/vdso/.gitignore
@@ -0,0 +1,4 @@
+*.so*
+vdso-*image.c
+genvdso
+vdso*.lds
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
new file mode 100644
index 0000000..ee3617c
--- /dev/null
+++ b/arch/mips/vdso/Makefile
@@ -0,0 +1,160 @@
+# Objects to go into the VDSO.
+obj-vdso-y := elf.o gettimeofday.o sigreturn.o
+
+# Common compiler flags between ABIs.
+ccflags-vdso := \
+ $(filter -I%,$(KBUILD_CFLAGS)) \
+ $(filter -E%,$(KBUILD_CFLAGS)) \
+ $(filter -march=%,$(KBUILD_CFLAGS))
+cflags-vdso := $(ccflags-vdso) \
+ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+ -O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
+ $(call cc-option, -fno-stack-protector)
+aflags-vdso := $(ccflags-vdso) \
+ $(filter -I%,$(KBUILD_CFLAGS)) \
+ $(filter -E%,$(KBUILD_CFLAGS)) \
+ -D__ASSEMBLY__ -Wa,-gdwarf-2
+
+#
+# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
+# the base address of VDSO, the linker will emit a R_MIPS_PC32
+# relocation in binutils > 2.25 but it will fail with older versions
+# because that relocation is not supported for that symbol. As a result
+# of which we are forced to disable the VDSO symbols when building
+# with < 2.25 binutils on pre-R6 kernels. For more references on why we
+# can't use other methods to get the base address of VDSO please refer to
+# the comments on that file.
+#
+ifndef CONFIG_CPU_MIPSR6
+ ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
+ $(warning MIPS VDSO requires binutils >= 2.25)
+ obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
+ ccflags-vdso += -DDISABLE_MIPS_VDSO
+ endif
+endif
+
+# VDSO linker flags.
+VDSO_LDFLAGS := \
+ -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \
+ -nostdlib -shared \
+ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
+ $(call cc-ldoption, -Wl$(comma)--build-id)
+
+GCOV_PROFILE := n
+
+#
+# Shared build commands.
+#
+
+quiet_cmd_vdsold = VDSO $@
+ cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
+ -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
+
+hostprogs-y := genvdso
+
+quiet_cmd_genvdso = GENVDSO $@
+define cmd_genvdso
+ cp $< $(<:%.dbg=%) && \
+ $(OBJCOPY) -S $< $(<:%.dbg=%) && \
+ $(obj)/genvdso $< $(<:%.dbg=%) $@ $(VDSO_NAME)
+endef
+
+#
+# Build native VDSO.
+#
+
+native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS))
+
+targets += $(obj-vdso-y)
+targets += vdso.lds vdso.so.dbg vdso.so vdso-image.c
+
+obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o)
+
+$(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi)
+$(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
+
+$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi)
+
+$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
+ $(call if_changed,vdsold)
+
+$(obj)/vdso-image.c: $(obj)/vdso.so.dbg $(obj)/genvdso FORCE
+ $(call if_changed,genvdso)
+
+obj-y += vdso-image.o
+
+#
+# Build O32 VDSO.
+#
+
+# Define these outside the ifdef to ensure they are picked up by clean.
+targets += $(obj-vdso-y:%.o=%-o32.o)
+targets += vdso-o32.lds vdso-o32.so.dbg vdso-o32.so vdso-o32-image.c
+
+ifdef CONFIG_MIPS32_O32
+
+obj-vdso-o32 := $(obj-vdso-y:%.o=$(obj)/%-o32.o)
+
+$(obj-vdso-o32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=32
+$(obj-vdso-o32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=32
+
+$(obj)/%-o32.o: $(src)/%.S FORCE
+ $(call if_changed_dep,as_o_S)
+
+$(obj)/%-o32.o: $(src)/%.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_c)
+
+$(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := -mabi=32
+$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
+$(obj)/vdso-o32.so.dbg: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
+ $(call if_changed,vdsold)
+
+$(obj)/vdso-o32-image.c: VDSO_NAME := o32
+$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg $(obj)/genvdso FORCE
+ $(call if_changed,genvdso)
+
+obj-y += vdso-o32-image.o
+
+endif
+
+#
+# Build N32 VDSO.
+#
+
+targets += $(obj-vdso-y:%.o=%-n32.o)
+targets += vdso-n32.lds vdso-n32.so.dbg vdso-n32.so vdso-n32-image.c
+
+ifdef CONFIG_MIPS32_N32
+
+obj-vdso-n32 := $(obj-vdso-y:%.o=$(obj)/%-n32.o)
+
+$(obj-vdso-n32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=n32
+$(obj-vdso-n32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=n32
+
+$(obj)/%-n32.o: $(src)/%.S FORCE
+ $(call if_changed_dep,as_o_S)
+
+$(obj)/%-n32.o: $(src)/%.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_c)
+
+$(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := -mabi=n32
+$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
+$(obj)/vdso-n32.so.dbg: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
+ $(call if_changed,vdsold)
+
+$(obj)/vdso-n32-image.c: VDSO_NAME := n32
+$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg $(obj)/genvdso FORCE
+ $(call if_changed,genvdso)
+
+obj-y += vdso-n32-image.o
+
+endif
+
+# FIXME: Need install rule for debug.
+# Needs to deal with dependency for generation of dbg by cmd_genvdso...
diff --git a/arch/mips/vdso/elf.S b/arch/mips/vdso/elf.S
new file mode 100644
index 0000000..be37bbb
--- /dev/null
+++ b/arch/mips/vdso/elf.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 "vdso.h"
+
+#include <linux/elfnote.h>
+#include <linux/version.h>
+
+ELFNOTE_START(Linux, 0, "a")
+ .long LINUX_VERSION_CODE
+ELFNOTE_END
+
+/*
+ * The .MIPS.abiflags section must be defined with the FP ABI flags set
+ * to 'any' to be able to link with both old and new libraries.
+ * Newer toolchains are capable of automatically generating this, but we want
+ * to work with older toolchains as well. Therefore, we define the contents of
+ * this section here (under different names), and then genvdso will patch
+ * it to have the correct name and type.
+ *
+ * We base the .MIPS.abiflags section on preprocessor definitions rather than
+ * CONFIG_* because we need to match the particular ABI we are building the
+ * VDSO for.
+ *
+ * See https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
+ * for the .MIPS.abiflags section description.
+ */
+
+ .section .mips_abiflags, "a"
+ .align 3
+__mips_abiflags:
+ .hword 0 /* version */
+ .byte __mips /* isa_level */
+
+ /* isa_rev */
+#ifdef __mips_isa_rev
+ .byte __mips_isa_rev
+#else
+ .byte 0
+#endif
+
+ /* gpr_size */
+#ifdef __mips64
+ .byte 2 /* AFL_REG_64 */
+#else
+ .byte 1 /* AFL_REG_32 */
+#endif
+
+ /* cpr1_size */
+#if (defined(__mips_isa_rev) && __mips_isa_rev >= 6) || defined(__mips64)
+ .byte 2 /* AFL_REG_64 */
+#else
+ .byte 1 /* AFL_REG_32 */
+#endif
+
+ .byte 0 /* cpr2_size (AFL_REG_NONE) */
+ .byte 0 /* fp_abi (Val_GNU_MIPS_ABI_FP_ANY) */
+ .word 0 /* isa_ext */
+ .word 0 /* ases */
+ .word 0 /* flags1 */
+ .word 0 /* flags2 */
diff --git a/arch/mips/vdso/genvdso.c b/arch/mips/vdso/genvdso.c
new file mode 100644
index 0000000..530a36f
--- /dev/null
+++ b/arch/mips/vdso/genvdso.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/*
+ * This tool is used to generate the real VDSO images from the raw image. It
+ * first patches up the MIPS ABI flags and GNU attributes sections defined in
+ * elf.S to have the correct name and type. It then generates a C source file
+ * to be compiled into the kernel containing the VDSO image data and a
+ * mips_vdso_image struct for it, including symbol offsets extracted from the
+ * image.
+ *
+ * We need to be passed both a stripped and unstripped VDSO image. The stripped
+ * image is compiled into the kernel, but we must also patch up the unstripped
+ * image's ABI flags sections so that it can be installed and used for
+ * debugging.
+ */
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <byteswap.h>
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Define these in case the system elf.h is not new enough to have them. */
+#ifndef SHT_GNU_ATTRIBUTES
+# define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#endif
+#ifndef SHT_MIPS_ABIFLAGS
+# define SHT_MIPS_ABIFLAGS 0x7000002a
+#endif
+
+enum {
+ ABI_O32 = (1 << 0),
+ ABI_N32 = (1 << 1),
+ ABI_N64 = (1 << 2),
+
+ ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64,
+};
+
+/* Symbols the kernel requires offsets for. */
+static struct {
+ const char *name;
+ const char *offset_name;
+ unsigned int abis;
+} vdso_symbols[] = {
+ { "__vdso_sigreturn", "off_sigreturn", ABI_O32 },
+ { "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL },
+ {}
+};
+
+static const char *program_name;
+static const char *vdso_name;
+static unsigned char elf_class;
+static unsigned int elf_abi;
+static bool need_swap;
+static FILE *out_file;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define HOST_ORDER ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define HOST_ORDER ELFDATA2MSB
+#endif
+
+#define BUILD_SWAP(bits) \
+ static uint##bits##_t swap_uint##bits(uint##bits##_t val) \
+ { \
+ return need_swap ? bswap_##bits(val) : val; \
+ }
+
+BUILD_SWAP(16)
+BUILD_SWAP(32)
+BUILD_SWAP(64)
+
+#define __FUNC(name, bits) name##bits
+#define _FUNC(name, bits) __FUNC(name, bits)
+#define FUNC(name) _FUNC(name, ELF_BITS)
+
+#define __ELF(x, bits) Elf##bits##_##x
+#define _ELF(x, bits) __ELF(x, bits)
+#define ELF(x) _ELF(x, ELF_BITS)
+
+/*
+ * Include genvdso.h twice with ELF_BITS defined differently to get functions
+ * for both ELF32 and ELF64.
+ */
+
+#define ELF_BITS 64
+#include "genvdso.h"
+#undef ELF_BITS
+
+#define ELF_BITS 32
+#include "genvdso.h"
+#undef ELF_BITS
+
+static void *map_vdso(const char *path, size_t *_size)
+{
+ int fd;
+ struct stat stat;
+ void *addr;
+ const Elf32_Ehdr *ehdr;
+
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
+ path, strerror(errno));
+ return NULL;
+ }
+
+ if (fstat(fd, &stat) != 0) {
+ fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name,
+ path, strerror(errno));
+ return NULL;
+ }
+
+ addr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+ 0);
+ if (addr == MAP_FAILED) {
+ fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name,
+ path, strerror(errno));
+ return NULL;
+ }
+
+ /* ELF32/64 header formats are the same for the bits we're checking. */
+ ehdr = addr;
+
+ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
+ fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name,
+ path);
+ return NULL;
+ }
+
+ elf_class = ehdr->e_ident[EI_CLASS];
+ switch (elf_class) {
+ case ELFCLASS32:
+ case ELFCLASS64:
+ break;
+ default:
+ fprintf(stderr, "%s: '%s' has invalid ELF class\n",
+ program_name, path);
+ return NULL;
+ }
+
+ switch (ehdr->e_ident[EI_DATA]) {
+ case ELFDATA2LSB:
+ case ELFDATA2MSB:
+ need_swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
+ break;
+ default:
+ fprintf(stderr, "%s: '%s' has invalid ELF data order\n",
+ program_name, path);
+ return NULL;
+ }
+
+ if (swap_uint16(ehdr->e_machine) != EM_MIPS) {
+ fprintf(stderr,
+ "%s: '%s' has invalid ELF machine (expected EM_MIPS)\n",
+ program_name, path);
+ return NULL;
+ } else if (swap_uint16(ehdr->e_type) != ET_DYN) {
+ fprintf(stderr,
+ "%s: '%s' has invalid ELF type (expected ET_DYN)\n",
+ program_name, path);
+ return NULL;
+ }
+
+ *_size = stat.st_size;
+ return addr;
+}
+
+static bool patch_vdso(const char *path, void *vdso)
+{
+ if (elf_class == ELFCLASS64)
+ return patch_vdso64(path, vdso);
+ else
+ return patch_vdso32(path, vdso);
+}
+
+static bool get_symbols(const char *path, void *vdso)
+{
+ if (elf_class == ELFCLASS64)
+ return get_symbols64(path, vdso);
+ else
+ return get_symbols32(path, vdso);
+}
+
+int main(int argc, char **argv)
+{
+ const char *dbg_vdso_path, *vdso_path, *out_path;
+ void *dbg_vdso, *vdso;
+ size_t dbg_vdso_size, vdso_size, i;
+
+ program_name = argv[0];
+
+ if (argc < 4 || argc > 5) {
+ fprintf(stderr,
+ "Usage: %s <debug VDSO> <stripped VDSO> <output file> [<name>]\n",
+ program_name);
+ return EXIT_FAILURE;
+ }
+
+ dbg_vdso_path = argv[1];
+ vdso_path = argv[2];
+ out_path = argv[3];
+ vdso_name = (argc > 4) ? argv[4] : "";
+
+ dbg_vdso = map_vdso(dbg_vdso_path, &dbg_vdso_size);
+ if (!dbg_vdso)
+ return EXIT_FAILURE;
+
+ vdso = map_vdso(vdso_path, &vdso_size);
+ if (!vdso)
+ return EXIT_FAILURE;
+
+ /* Patch both the VDSOs' ABI flags sections. */
+ if (!patch_vdso(dbg_vdso_path, dbg_vdso))
+ return EXIT_FAILURE;
+ if (!patch_vdso(vdso_path, vdso))
+ return EXIT_FAILURE;
+
+ if (msync(dbg_vdso, dbg_vdso_size, MS_SYNC) != 0) {
+ fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
+ dbg_vdso_path, strerror(errno));
+ return EXIT_FAILURE;
+ } else if (msync(vdso, vdso_size, MS_SYNC) != 0) {
+ fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
+ vdso_path, strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ out_file = fopen(out_path, "w");
+ if (!out_file) {
+ fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
+ out_path, strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ fprintf(out_file, "/* Automatically generated - do not edit */\n");
+ fprintf(out_file, "#include <linux/linkage.h>\n");
+ fprintf(out_file, "#include <linux/mm.h>\n");
+ fprintf(out_file, "#include <asm/vdso.h>\n");
+
+ /* Write out the stripped VDSO data. */
+ fprintf(out_file,
+ "static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t",
+ vdso_size);
+ for (i = 0; i < vdso_size; i++) {
+ if (!(i % 10))
+ fprintf(out_file, "\n\t");
+ fprintf(out_file, "0x%02x, ", ((unsigned char *)vdso)[i]);
+ }
+ fprintf(out_file, "\n};\n");
+
+ /* Preallocate a page array. */
+ fprintf(out_file,
+ "static struct page *vdso_pages[PAGE_ALIGN(%zu) / PAGE_SIZE];\n",
+ vdso_size);
+
+ fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n",
+ (vdso_name[0]) ? "_" : "", vdso_name);
+ fprintf(out_file, "\t.data = vdso_data,\n");
+ fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size);
+ fprintf(out_file, "\t.mapping = {\n");
+ fprintf(out_file, "\t\t.name = \"[vdso]\",\n");
+ fprintf(out_file, "\t\t.pages = vdso_pages,\n");
+ fprintf(out_file, "\t},\n");
+
+ /* Calculate and write symbol offsets to <output file> */
+ if (!get_symbols(dbg_vdso_path, dbg_vdso)) {
+ unlink(out_path);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(out_file, "};\n");
+
+ return EXIT_SUCCESS;
+}
diff --git a/arch/mips/vdso/genvdso.h b/arch/mips/vdso/genvdso.h
new file mode 100644
index 0000000..9433472
--- /dev/null
+++ b/arch/mips/vdso/genvdso.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+static inline bool FUNC(patch_vdso)(const char *path, void *vdso)
+{
+ const ELF(Ehdr) *ehdr = vdso;
+ void *shdrs;
+ ELF(Shdr) *shdr;
+ char *shstrtab, *name;
+ uint16_t sh_count, sh_entsize, i;
+ unsigned int local_gotno, symtabno, gotsym;
+ ELF(Dyn) *dyn = NULL;
+
+ shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff);
+ sh_count = swap_uint16(ehdr->e_shnum);
+ sh_entsize = swap_uint16(ehdr->e_shentsize);
+
+ shdr = shdrs + (sh_entsize * swap_uint16(ehdr->e_shstrndx));
+ shstrtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+
+ for (i = 0; i < sh_count; i++) {
+ shdr = shdrs + (i * sh_entsize);
+ name = shstrtab + swap_uint32(shdr->sh_name);
+
+ /*
+ * Ensure there are no relocation sections - ld.so does not
+ * relocate the VDSO so if there are relocations things will
+ * break.
+ */
+ switch (swap_uint32(shdr->sh_type)) {
+ case SHT_REL:
+ case SHT_RELA:
+ fprintf(stderr,
+ "%s: '%s' contains relocation sections\n",
+ program_name, path);
+ return false;
+ case SHT_DYNAMIC:
+ dyn = vdso + FUNC(swap_uint)(shdr->sh_offset);
+ break;
+ }
+
+ /* Check for existing sections. */
+ if (strcmp(name, ".MIPS.abiflags") == 0) {
+ fprintf(stderr,
+ "%s: '%s' already contains a '.MIPS.abiflags' section\n",
+ program_name, path);
+ return false;
+ }
+
+ if (strcmp(name, ".mips_abiflags") == 0) {
+ strcpy(name, ".MIPS.abiflags");
+ shdr->sh_type = swap_uint32(SHT_MIPS_ABIFLAGS);
+ shdr->sh_entsize = shdr->sh_size;
+ }
+ }
+
+ /*
+ * Ensure the GOT has no entries other than the standard 2, for the same
+ * reason we check that there's no relocation sections above.
+ * The standard two entries are:
+ * - Lazy resolver
+ * - Module pointer
+ */
+ if (dyn) {
+ local_gotno = symtabno = gotsym = 0;
+
+ while (FUNC(swap_uint)(dyn->d_tag) != DT_NULL) {
+ switch (FUNC(swap_uint)(dyn->d_tag)) {
+ /*
+ * This member holds the number of local GOT entries.
+ */
+ case DT_MIPS_LOCAL_GOTNO:
+ local_gotno = FUNC(swap_uint)(dyn->d_un.d_val);
+ break;
+ /*
+ * This member holds the number of entries in the
+ * .dynsym section.
+ */
+ case DT_MIPS_SYMTABNO:
+ symtabno = FUNC(swap_uint)(dyn->d_un.d_val);
+ break;
+ /*
+ * This member holds the index of the first dynamic
+ * symbol table entry that corresponds to an entry in
+ * the GOT.
+ */
+ case DT_MIPS_GOTSYM:
+ gotsym = FUNC(swap_uint)(dyn->d_un.d_val);
+ break;
+ }
+
+ dyn++;
+ }
+
+ if (local_gotno > 2 || symtabno - gotsym) {
+ fprintf(stderr,
+ "%s: '%s' contains unexpected GOT entries\n",
+ program_name, path);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static inline bool FUNC(get_symbols)(const char *path, void *vdso)
+{
+ const ELF(Ehdr) *ehdr = vdso;
+ void *shdrs, *symtab;
+ ELF(Shdr) *shdr;
+ const ELF(Sym) *sym;
+ char *strtab, *name;
+ uint16_t sh_count, sh_entsize, st_count, st_entsize, i, j;
+ uint64_t offset;
+ uint32_t flags;
+
+ shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff);
+ sh_count = swap_uint16(ehdr->e_shnum);
+ sh_entsize = swap_uint16(ehdr->e_shentsize);
+
+ for (i = 0; i < sh_count; i++) {
+ shdr = shdrs + (i * sh_entsize);
+
+ if (swap_uint32(shdr->sh_type) == SHT_SYMTAB)
+ break;
+ }
+
+ if (i == sh_count) {
+ fprintf(stderr, "%s: '%s' has no symbol table\n", program_name,
+ path);
+ return false;
+ }
+
+ /* Get flags */
+ flags = swap_uint32(ehdr->e_flags);
+ if (elf_class == ELFCLASS64)
+ elf_abi = ABI_N64;
+ else if (flags & EF_MIPS_ABI2)
+ elf_abi = ABI_N32;
+ else
+ elf_abi = ABI_O32;
+
+ /* Get symbol table. */
+ symtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+ st_entsize = FUNC(swap_uint)(shdr->sh_entsize);
+ st_count = FUNC(swap_uint)(shdr->sh_size) / st_entsize;
+
+ /* Get string table. */
+ shdr = shdrs + (swap_uint32(shdr->sh_link) * sh_entsize);
+ strtab = vdso + FUNC(swap_uint)(shdr->sh_offset);
+
+ /* Write offsets for symbols needed by the kernel. */
+ for (i = 0; vdso_symbols[i].name; i++) {
+ if (!(vdso_symbols[i].abis & elf_abi))
+ continue;
+
+ for (j = 0; j < st_count; j++) {
+ sym = symtab + (j * st_entsize);
+ name = strtab + swap_uint32(sym->st_name);
+
+ if (!strcmp(name, vdso_symbols[i].name)) {
+ offset = FUNC(swap_uint)(sym->st_value);
+
+ fprintf(out_file,
+ "\t.%s = 0x%" PRIx64 ",\n",
+ vdso_symbols[i].offset_name, offset);
+ break;
+ }
+ }
+
+ if (j == st_count) {
+ fprintf(stderr,
+ "%s: '%s' is missing required symbol '%s'\n",
+ program_name, path, vdso_symbols[i].name);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
new file mode 100644
index 0000000..ce89c9e
--- /dev/null
+++ b/arch/mips/vdso/gettimeofday.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 "vdso.h"
+
+#include <linux/compiler.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/time.h>
+
+#include <asm/clocksource.h>
+#include <asm/io.h>
+#include <asm/mips-cm.h>
+#include <asm/unistd.h>
+#include <asm/vdso.h>
+
+static __always_inline int do_realtime_coarse(struct timespec *ts,
+ const union mips_vdso_data *data)
+{
+ u32 start_seq;
+
+ do {
+ start_seq = vdso_data_read_begin(data);
+
+ ts->tv_sec = data->xtime_sec;
+ ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
+ } while (vdso_data_read_retry(data, start_seq));
+
+ return 0;
+}
+
+static __always_inline int do_monotonic_coarse(struct timespec *ts,
+ const union mips_vdso_data *data)
+{
+ u32 start_seq;
+ u32 to_mono_sec;
+ u32 to_mono_nsec;
+
+ do {
+ start_seq = vdso_data_read_begin(data);
+
+ ts->tv_sec = data->xtime_sec;
+ ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
+
+ to_mono_sec = data->wall_to_mono_sec;
+ to_mono_nsec = data->wall_to_mono_nsec;
+ } while (vdso_data_read_retry(data, start_seq));
+
+ ts->tv_sec += to_mono_sec;
+ timespec_add_ns(ts, to_mono_nsec);
+
+ return 0;
+}
+
+#ifdef CONFIG_CSRC_R4K
+
+static __always_inline u64 read_r4k_count(void)
+{
+ unsigned int count;
+
+ __asm__ __volatile__(
+ " .set push\n"
+ " .set mips32r2\n"
+ " rdhwr %0, $2\n"
+ " .set pop\n"
+ : "=r" (count));
+
+ return count;
+}
+
+#endif
+
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+
+static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
+{
+ void __iomem *gic = get_gic(data);
+ u32 hi, hi2, lo;
+
+ do {
+ hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+ lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS);
+ hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS);
+ } while (hi2 != hi);
+
+ return (((u64)hi) << 32) + lo;
+}
+
+#endif
+
+static __always_inline u64 get_ns(const union mips_vdso_data *data)
+{
+ u64 cycle_now, delta, nsec;
+
+ switch (data->clock_mode) {
+#ifdef CONFIG_CSRC_R4K
+ case VDSO_CLOCK_R4K:
+ cycle_now = read_r4k_count();
+ break;
+#endif
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+ case VDSO_CLOCK_GIC:
+ cycle_now = read_gic_count(data);
+ break;
+#endif
+ default:
+ return 0;
+ }
+
+ delta = (cycle_now - data->cs_cycle_last) & data->cs_mask;
+
+ nsec = (delta * data->cs_mult) + data->xtime_nsec;
+ nsec >>= data->cs_shift;
+
+ return nsec;
+}
+
+static __always_inline int do_realtime(struct timespec *ts,
+ const union mips_vdso_data *data)
+{
+ u32 start_seq;
+ u64 ns;
+
+ do {
+ start_seq = vdso_data_read_begin(data);
+
+ if (data->clock_mode == VDSO_CLOCK_NONE)
+ return -ENOSYS;
+
+ ts->tv_sec = data->xtime_sec;
+ ns = get_ns(data);
+ } while (vdso_data_read_retry(data, start_seq));
+
+ ts->tv_nsec = 0;
+ timespec_add_ns(ts, ns);
+
+ return 0;
+}
+
+static __always_inline int do_monotonic(struct timespec *ts,
+ const union mips_vdso_data *data)
+{
+ u32 start_seq;
+ u64 ns;
+ u32 to_mono_sec;
+ u32 to_mono_nsec;
+
+ do {
+ start_seq = vdso_data_read_begin(data);
+
+ if (data->clock_mode == VDSO_CLOCK_NONE)
+ return -ENOSYS;
+
+ ts->tv_sec = data->xtime_sec;
+ ns = get_ns(data);
+
+ to_mono_sec = data->wall_to_mono_sec;
+ to_mono_nsec = data->wall_to_mono_nsec;
+ } while (vdso_data_read_retry(data, start_seq));
+
+ ts->tv_sec += to_mono_sec;
+ ts->tv_nsec = 0;
+ timespec_add_ns(ts, ns + to_mono_nsec);
+
+ return 0;
+}
+
+#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
+
+/*
+ * This is behind the ifdef so that we don't provide the symbol when there's no
+ * possibility of there being a usable clocksource, because there's nothing we
+ * can do without it. When libc fails the symbol lookup it should fall back on
+ * the standard syscall path.
+ */
+int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ const union mips_vdso_data *data = get_vdso_data();
+ struct timespec ts;
+ int ret;
+
+ ret = do_realtime(&ts, data);
+ if (ret)
+ return ret;
+
+ if (tv) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+
+ if (tz) {
+ tz->tz_minuteswest = data->tz_minuteswest;
+ tz->tz_dsttime = data->tz_dsttime;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_CLKSRC_MIPS_GIC */
+
+int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
+{
+ const union mips_vdso_data *data = get_vdso_data();
+ int ret;
+
+ switch (clkid) {
+ case CLOCK_REALTIME_COARSE:
+ ret = do_realtime_coarse(ts, data);
+ break;
+ case CLOCK_MONOTONIC_COARSE:
+ ret = do_monotonic_coarse(ts, data);
+ break;
+ case CLOCK_REALTIME:
+ ret = do_realtime(ts, data);
+ break;
+ case CLOCK_MONOTONIC:
+ ret = do_monotonic(ts, data);
+ break;
+ default:
+ ret = -ENOSYS;
+ break;
+ }
+
+ /* If we return -ENOSYS libc should fall back to a syscall. */
+ return ret;
+}
diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S
new file mode 100644
index 0000000..715bf59
--- /dev/null
+++ b/arch/mips/vdso/sigreturn.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 "vdso.h"
+
+#include <uapi/asm/unistd.h>
+
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+ .section .text
+ .cfi_sections .debug_frame
+
+LEAF(__vdso_rt_sigreturn)
+ .cfi_startproc
+ .frame sp, 0, ra
+ .mask 0x00000000, 0
+ .fmask 0x00000000, 0
+ .cfi_signal_frame
+
+ li v0, __NR_rt_sigreturn
+ syscall
+
+ .cfi_endproc
+ END(__vdso_rt_sigreturn)
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+LEAF(__vdso_sigreturn)
+ .cfi_startproc
+ .frame sp, 0, ra
+ .mask 0x00000000, 0
+ .fmask 0x00000000, 0
+ .cfi_signal_frame
+
+ li v0, __NR_sigreturn
+ syscall
+
+ .cfi_endproc
+ END(__vdso_sigreturn)
+
+#endif
diff --git a/arch/mips/vdso/vdso.h b/arch/mips/vdso/vdso.h
new file mode 100644
index 0000000..cfb1be4
--- /dev/null
+++ b/arch/mips/vdso/vdso.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/sgidefs.h>
+
+#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
+
+/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
+#undef CONFIG_64BIT
+#define CONFIG_32BIT 1
+#ifndef __ASSEMBLY__
+#include <asm-generic/atomic64.h>
+#endif
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <asm/asm.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+static inline unsigned long get_vdso_base(void)
+{
+ unsigned long addr;
+
+ /*
+ * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
+ * kernel symbol.
+ */
+#ifdef CONFIG_CPU_MIPSR6
+ /*
+ * lapc <symbol> is an alias to addiupc reg, <symbol> - .
+ *
+ * We can't use addiupc because there is no label-label
+ * support for the addiupc reloc
+ */
+ __asm__("lapc %0, _start \n"
+ : "=r" (addr) : :);
+#else
+ /*
+ * Get the base load address of the VDSO. We have to avoid generating
+ * relocations and references to the GOT because ld.so does not peform
+ * relocations on the VDSO. We use the current offset from the VDSO base
+ * and perform a PC-relative branch which gives the absolute address in
+ * ra, and take the difference. The assembler chokes on
+ * "li %0, _start - .", so embed the offset as a word and branch over
+ * it.
+ *
+ */
+
+ __asm__(
+ " .set push \n"
+ " .set noreorder \n"
+ " bal 1f \n"
+ " nop \n"
+ " .word _start - . \n"
+ "1: lw %0, 0($31) \n"
+ " " STR(PTR_ADDU) " %0, $31, %0 \n"
+ " .set pop \n"
+ : "=r" (addr)
+ :
+ : "$31");
+#endif /* CONFIG_CPU_MIPSR6 */
+
+ return addr;
+}
+
+static inline const union mips_vdso_data *get_vdso_data(void)
+{
+ return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
+}
+
+#ifdef CONFIG_CLKSRC_MIPS_GIC
+
+static inline void __iomem *get_gic(const union mips_vdso_data *data)
+{
+ return (void __iomem *)data - PAGE_SIZE;
+}
+
+#endif /* CONFIG_CLKSRC_MIPS_GIC */
+
+#endif /* __ASSEMBLY__ */
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
new file mode 100644
index 0000000..8df7dd5
--- /dev/null
+++ b/arch/mips/vdso/vdso.lds.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips")
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", "elf32-ntradlittlemips")
+#else
+OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
+#endif
+
+OUTPUT_ARCH(mips)
+
+SECTIONS
+{
+ PROVIDE(_start = .);
+ . = SIZEOF_HEADERS;
+
+ /*
+ * In order to retain compatibility with older toolchains we provide the
+ * ABI flags section ourself. Newer assemblers will automatically
+ * generate .MIPS.abiflags sections so we discard such input sections,
+ * and then manually define our own section here. genvdso will patch
+ * this section to have the correct name/type.
+ */
+ .mips_abiflags : { *(.mips_abiflags) } :text :abiflags
+
+ .reginfo : { *(.reginfo) } :text :reginfo
+
+ .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
+
+ .text : { *(.text*) } :text
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+
+ _end = .;
+ PROVIDE(end = .);
+
+ /DISCARD/ : {
+ *(.MIPS.abiflags)
+ *(.gnu.attributes)
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
+}
+
+PHDRS
+{
+ /*
+ * Provide a PT_MIPS_ABIFLAGS header to assign the ABI flags section
+ * to. We can specify the header type directly here so no modification
+ * is needed later on.
+ */
+ abiflags 0x70000003;
+
+ /*
+ * The ABI flags header must exist directly after the PT_INTERP header,
+ * so we must explicitly place the PT_MIPS_REGINFO header after it to
+ * stop the linker putting one in at the start.
+ */
+ reginfo 0x70000000;
+
+ 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 {
+#ifndef DISABLE_MIPS_VDSO
+ global:
+ __vdso_clock_gettime;
+ __vdso_gettimeofday;
+#endif
+ local: *;
+ };
+}
diff --git a/arch/mips/xilfpga/Kconfig b/arch/mips/xilfpga/Kconfig
new file mode 100644
index 0000000..42a030a
--- /dev/null
+++ b/arch/mips/xilfpga/Kconfig
@@ -0,0 +1,9 @@
+choice
+ prompt "Machine type"
+ depends on MACH_XILFPGA
+ default XILFPGA_NEXYS4DDR
+
+config XILFPGA_NEXYS4DDR
+ bool "Nexys4DDR by Digilent"
+
+endchoice
diff --git a/arch/mips/xilfpga/Makefile b/arch/mips/xilfpga/Makefile
new file mode 100644
index 0000000..a4deec6
--- /dev/null
+++ b/arch/mips/xilfpga/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Xilfpga
+#
+
+obj-y += init.o
+obj-y += intc.o
+obj-y += time.o
diff --git a/arch/mips/xilfpga/Platform b/arch/mips/xilfpga/Platform
new file mode 100644
index 0000000..ed375af
--- /dev/null
+++ b/arch/mips/xilfpga/Platform
@@ -0,0 +1,3 @@
+platform-$(CONFIG_MACH_XILFPGA) += xilfpga/
+cflags-$(CONFIG_MACH_XILFPGA) += -I$(srctree)/arch/mips/include/asm/mach-xilfpga
+load-$(CONFIG_MACH_XILFPGA) += 0xffffffff80100000
diff --git a/arch/mips/xilfpga/init.c b/arch/mips/xilfpga/init.c
new file mode 100644
index 0000000..ce2aee2
--- /dev/null
+++ b/arch/mips/xilfpga/init.c
@@ -0,0 +1,57 @@
+/*
+ * Xilfpga platform setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/prom.h>
+
+#define XILFPGA_UART_BASE 0xb0401000
+
+const char *get_system_type(void)
+{
+ return "MIPSfpga";
+}
+
+void __init plat_mem_setup(void)
+{
+ __dt_setup_arch(__dtb_start);
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+}
+
+void __init prom_init(void)
+{
+ setup_8250_early_printk_port(XILFPGA_UART_BASE, 2, 50000);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init device_tree_init(void)
+{
+ if (!initial_boot_params)
+ return;
+
+ unflatten_and_copy_device_tree();
+}
+
+static int __init plat_of_setup(void)
+{
+ if (!of_have_populated_dt())
+ panic("Device tree not present");
+
+ if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL))
+ panic("Failed to populate DT");
+
+ return 0;
+}
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/xilfpga/intc.c b/arch/mips/xilfpga/intc.c
new file mode 100644
index 0000000..c4d1a71
--- /dev/null
+++ b/arch/mips/xilfpga/intc.c
@@ -0,0 +1,25 @@
+/*
+ * Xilfpga interrupt controller setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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/of.h>
+#include <linux/of_irq.h>
+
+#include <asm/irq_cpu.h>
+
+static struct of_device_id of_irq_ids[] __initdata = {
+ { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
+ {},
+};
+
+void __init arch_init_irq(void)
+{
+ of_irq_init(of_irq_ids);
+}
diff --git a/arch/mips/xilfpga/time.c b/arch/mips/xilfpga/time.c
new file mode 100644
index 0000000..cbb3fca
--- /dev/null
+++ b/arch/mips/xilfpga/time.c
@@ -0,0 +1,41 @@
+/*
+ * Xilfpga clocksource/timer setup
+ *
+ * Copyright (C) 2015 Imagination Technologies
+ * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.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/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/of.h>
+
+#include <asm/time.h>
+
+void __init plat_time_init(void)
+{
+ struct device_node *np;
+ struct clk *clk;
+
+ of_clk_init(NULL);
+ clocksource_probe();
+
+ np = of_get_cpu_node(0, NULL);
+ if (!np) {
+ pr_err("Failed to get CPU node\n");
+ return;
+ }
+
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
+ return;
+ }
+
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+ clk_put(clk);
+}
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 4434b54..06ddb55 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -1,6 +1,7 @@
config MN10300
def_bool y
select HAVE_OPROFILE
+ select HAVE_UID16
select GENERIC_IRQ_SHOW
select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_ARCH_TRACEHOOK
@@ -13,6 +14,7 @@ config MN10300
select OLD_SIGSUSPEND3
select OLD_SIGACTION
select HAVE_DEBUG_STACKOVERFLOW
+ select ARCH_NO_COHERENT_DMA_MMAP
config AM33_2
def_bool n
@@ -37,9 +39,6 @@ config HIGHMEM
config NUMA
def_bool n
-config UID16
- def_bool y
-
config RWSEM_GENERIC_SPINLOCK
def_bool y
@@ -54,6 +53,7 @@ config GENERIC_HWEIGHT
config GENERIC_BUG
def_bool y
+ depends on BUG
config QUICKLIST
def_bool y
diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h
index 375e591..ce318d5 100644
--- a/arch/mn10300/include/asm/atomic.h
+++ b/arch/mn10300/include/asm/atomic.h
@@ -34,7 +34,7 @@
*
* Atomically reads the value of @v. Note that the guaranteed
*/
-#define atomic_read(v) (ACCESS_ONCE((v)->counter))
+#define atomic_read(v) READ_ONCE((v)->counter)
/**
* atomic_set - set atomic variable
@@ -43,7 +43,7 @@
*
* Atomically sets the value of @v to @i. Note that the guaranteed
*/
-#define atomic_set(v, i) (((v)->counter) = (i))
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
#define ATOMIC_OP(op) \
static inline void atomic_##op(int i, atomic_t *v) \
diff --git a/arch/mn10300/include/asm/checksum.h b/arch/mn10300/include/asm/checksum.h
index 9fb2a8d..c80df5b 100644
--- a/arch/mn10300/include/asm/checksum.h
+++ b/arch/mn10300/include/asm/checksum.h
@@ -37,16 +37,11 @@ static inline __sum16 csum_fold(__wsum sum)
return (~sum) >> 16;
}
-static inline __wsum csum_tcpudp_nofold(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto,
__wsum sum)
{
- __wsum tmp;
-
- tmp = (__wsum) ntohs(len) << 16;
- tmp += (__wsum) proto << 8;
+ __wsum tmp = (__wsum)((len + proto) << 8);
asm(
" add %1,%0 \n"
@@ -64,10 +59,8 @@ static inline __wsum csum_tcpudp_nofold(unsigned long saddr,
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
-static inline __sum16 csum_tcpudp_magic(unsigned long saddr,
- unsigned long daddr,
- unsigned short len,
- unsigned short proto,
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h
index a18abfc..1dcd447 100644
--- a/arch/mn10300/include/asm/dma-mapping.h
+++ b/arch/mn10300/include/asm/dma-mapping.h
@@ -11,154 +11,14 @@
#ifndef _ASM_DMA_MAPPING_H
#define _ASM_DMA_MAPPING_H
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-
#include <asm/cache.h>
#include <asm/io.h>
-/*
- * See Documentation/DMA-API.txt for the description of how the
- * following DMA API should work.
- */
-
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int flag);
-
-extern void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
-
-static inline
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- mn10300_dcache_flush_inv();
- return virt_to_bus(ptr);
-}
-
-static inline
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-static inline
-int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
- enum dma_data_direction direction)
-{
- struct scatterlist *sg;
- int i;
-
- BUG_ON(!valid_dma_direction(direction));
- WARN_ON(nents == 0 || sglist[0].length == 0);
-
- for_each_sg(sglist, sg, nents, i) {
- BUG_ON(!sg_page(sg));
-
- sg->dma_address = sg_phys(sg);
- }
+extern struct dma_map_ops mn10300_dma_ops;
- mn10300_dcache_flush_inv();
- return nents;
-}
-
-static inline
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
-}
-
-static inline
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- return page_to_bus(page) + offset;
-}
-
-static inline
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
-}
-
-static inline
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
-}
-
-static inline
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- mn10300_dcache_flush_inv();
-}
-
-static inline
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- mn10300_dcache_flush_inv();
-}
-
-
-static inline
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction)
-{
-}
-
-static inline
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction)
-{
- mn10300_dcache_flush_inv();
-}
-
-static inline
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-static inline
-int dma_supported(struct device *dev, u64 mask)
-{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s, so we can't
- * guarantee allocations that must be within a tighter range than
- * GFP_DMA
- */
- if (mask < 0x00ffffff)
- return 0;
- return 1;
-}
-
-static inline
-int dma_set_mask(struct device *dev, u64 mask)
-{
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
- return 0;
+ return &mn10300_dma_ops;
}
static inline
@@ -168,19 +28,4 @@ void dma_cache_sync(void *vaddr, size_t size,
mn10300_dcache_flush_inv();
}
-/* Not supported for now */
-static inline int dma_mmap_coherent(struct device *dev,
- struct vm_area_struct *vma, void *cpu_addr,
- dma_addr_t dma_addr, size_t size)
-{
- return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size)
-{
- return -EINVAL;
-}
-
#endif
diff --git a/arch/mn10300/include/asm/page.h b/arch/mn10300/include/asm/page.h
index 8288e12..3810a6f 100644
--- a/arch/mn10300/include/asm/page.h
+++ b/arch/mn10300/include/asm/page.h
@@ -107,6 +107,7 @@ static inline int get_order(unsigned long size)
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define pfn_to_page(pfn) (mem_map + ((pfn) - __pfn_disp))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + __pfn_disp)
+#define __pfn_to_phys(pfn) PFN_PHYS(pfn)
#define pfn_valid(pfn) \
({ \
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index be3debb..51159ff 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -80,9 +80,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
#endif /* __KERNEL__ */
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
return channel ? 15 : 14;
diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h
index c199021..594ebff 100644
--- a/arch/mn10300/include/asm/serial.h
+++ b/arch/mn10300/include/asm/serial.h
@@ -14,15 +14,15 @@
/* Standard COM flags (except for COM4, because of the 8514 problem) */
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
+#define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
+#define STD_COM4_FLAGS UPF_BOOT_AUTOCONF
#endif
#ifdef CONFIG_SERIAL_8250_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
+#define FOURPORT_FLAGS UPF_FOURPORT
#define ACCENT_FLAGS 0
#define BOCA_FLAGS 0
#define HUB6_FLAGS 0
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 5372787..20f7bf6 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -110,21 +110,6 @@ extern int fixup_exception(struct pt_regs *regs);
#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x, ptr, ret) \
- ({ if (put_user((x), (ptr))) return (ret); })
-#define get_user_ret(x, ptr, ret) \
- ({ if (get_user((x), (ptr))) return (ret); })
-#define __put_user_ret(x, ptr, ret) \
- ({ if (__put_user((x), (ptr))) return (ret); })
-#define __get_user_ret(x, ptr, ret) \
- ({ if (__get_user((x), (ptr))) return (ret); })
-
struct __large_struct { unsigned long buf[100]; };
#define __m(x) (*(struct __large_struct *)(x))
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h
index cab7d6d..5129f23 100644
--- a/arch/mn10300/include/uapi/asm/socket.h
+++ b/arch/mn10300/include/uapi/asm/socket.h
@@ -85,4 +85,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/mn10300/kernel/fpu-nofpu.c b/arch/mn10300/kernel/fpu-nofpu.c
index 31c765b..8d0e041 100644
--- a/arch/mn10300/kernel/fpu-nofpu.c
+++ b/arch/mn10300/kernel/fpu-nofpu.c
@@ -9,6 +9,7 @@
* 2 of the Licence, or (at your option) any later version.
*/
#include <asm/fpu.h>
+#include <asm/elf.h>
/*
* handle an FPU operational exception
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index f984193..426173c 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -675,7 +675,7 @@ int __init start_secondary(void *unused)
#ifdef CONFIG_GENERIC_CLOCKEVENTS
init_clockevents();
#endif
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
return 0;
}
diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c
index e244ebe..8842394 100644
--- a/arch/mn10300/mm/dma-alloc.c
+++ b/arch/mn10300/mm/dma-alloc.c
@@ -20,8 +20,8 @@
static unsigned long pci_sram_allocated = 0xbc000000;
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+static void *mn10300_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
unsigned long addr;
void *ret;
@@ -61,10 +61,9 @@ done:
printk("dma_alloc_coherent() = %p [%x]\n", ret, *dma_handle);
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+static void mn10300_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
unsigned long addr = (unsigned long) vaddr & ~0x20000000;
@@ -73,4 +72,60 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
free_pages(addr, get_order(size));
}
-EXPORT_SYMBOL(dma_free_coherent);
+
+static int mn10300_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sglist, sg, nents, i) {
+ BUG_ON(!sg_page(sg));
+
+ sg->dma_address = sg_phys(sg);
+ }
+
+ mn10300_dcache_flush_inv();
+ return nents;
+}
+
+static dma_addr_t mn10300_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ return page_to_bus(page) + offset;
+}
+
+static void mn10300_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ mn10300_dcache_flush_inv();
+}
+
+static void mn10300_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nelems, enum dma_data_direction direction)
+{
+ mn10300_dcache_flush_inv();
+}
+
+static int mn10300_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s, so we can't
+ * guarantee allocations that must be within a tighter range than
+ * GFP_DMA
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+ return 1;
+}
+
+struct dma_map_ops mn10300_dma_ops = {
+ .alloc = mn10300_dma_alloc,
+ .free = mn10300_dma_free,
+ .map_page = mn10300_dma_map_page,
+ .map_sg = mn10300_dma_map_sg,
+ .sync_single_for_device = mn10300_dma_sync_single_for_device,
+ .sync_sg_for_device = mn10300_dma_sync_sg_for_device,
+};
diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h
index 6bc1f0d..703c5ee 100644
--- a/arch/nios2/include/asm/checksum.h
+++ b/arch/nios2/include/asm/checksum.h
@@ -45,8 +45,7 @@ static inline __sum16 csum_fold(__wsum sum)
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__(
@@ -60,7 +59,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
"cmpltu r8, %0, %3\n"
"add %0, %0, r8\n" /* add carry */
: "=r" (sum), "=r" (saddr)
- : "r" (daddr), "r" ((ntohs(len) << 16) + (proto * 256)),
+ : "r" (daddr), "r" ((len + proto) << 8),
"0" (sum),
"1" (saddr)
: "r8");
@@ -69,8 +68,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
}
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
diff --git a/arch/nios2/include/asm/cmpxchg.h b/arch/nios2/include/asm/cmpxchg.h
index 8593871..a7978f1 100644
--- a/arch/nios2/include/asm/cmpxchg.h
+++ b/arch/nios2/include/asm/cmpxchg.h
@@ -9,53 +9,6 @@
#ifndef _ASM_NIOS2_CMPXCHG_H
#define _ASM_NIOS2_CMPXCHG_H
-#include <linux/irqflags.h>
-
-#define xchg(ptr, x) \
- ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((volatile struct __xchg_dummy *)(x))
-
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
- int size)
-{
- unsigned long tmp, flags;
-
- local_irq_save(flags);
-
- switch (size) {
- case 1:
- __asm__ __volatile__(
- "ldb %0, %2\n"
- "stb %1, %2\n"
- : "=&r" (tmp)
- : "r" (x), "m" (*__xg(ptr))
- : "memory");
- break;
- case 2:
- __asm__ __volatile__(
- "ldh %0, %2\n"
- "sth %1, %2\n"
- : "=&r" (tmp)
- : "r" (x), "m" (*__xg(ptr))
- : "memory");
- break;
- case 4:
- __asm__ __volatile__(
- "ldw %0, %2\n"
- "stw %1, %2\n"
- : "=&r" (tmp)
- : "r" (x), "m" (*__xg(ptr))
- : "memory");
- break;
- }
-
- local_irq_restore(flags);
- return tmp;
-}
-
#include <asm-generic/cmpxchg.h>
-#include <asm-generic/cmpxchg-local.h>
#endif /* _ASM_NIOS2_CMPXCHG_H */
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
index b556723..bec8ac8 100644
--- a/arch/nios2/include/asm/dma-mapping.h
+++ b/arch/nios2/include/asm/dma-mapping.h
@@ -10,131 +10,20 @@
#ifndef _ASM_NIOS2_DMA_MAPPING_H
#define _ASM_NIOS2_DMA_MAPPING_H
-#include <linux/scatterlist.h>
-#include <linux/cache.h>
-#include <asm/cacheflush.h>
+extern struct dma_map_ops nios2_dma_ops;
-static inline void __dma_sync_for_device(void *vaddr, size_t size,
- enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- switch (direction) {
- case DMA_FROM_DEVICE:
- invalidate_dcache_range((unsigned long)vaddr,
- (unsigned long)(vaddr + size));
- break;
- case DMA_TO_DEVICE:
- /*
- * We just need to flush the caches here , but Nios2 flush
- * instruction will do both writeback and invalidate.
- */
- case DMA_BIDIRECTIONAL: /* flush and invalidate */
- flush_dcache_range((unsigned long)vaddr,
- (unsigned long)(vaddr + size));
- break;
- default:
- BUG();
- }
-}
-
-static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
- enum dma_data_direction direction)
-{
- switch (direction) {
- case DMA_BIDIRECTIONAL:
- case DMA_FROM_DEVICE:
- invalidate_dcache_range((unsigned long)vaddr,
- (unsigned long)(vaddr + size));
- break;
- case DMA_TO_DEVICE:
- break;
- default:
- BUG();
- }
-}
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
-static inline dma_addr_t dma_map_single(struct device *dev, void *ptr,
- size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- __dma_sync_for_device(ptr, size, direction);
- return virt_to_phys(ptr);
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction)
-{
-}
-
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction direction);
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction direction);
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction);
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction);
-
-static inline int dma_supported(struct device *dev, u64 mask)
-{
- return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
+ return &nios2_dma_ops;
}
/*
-* dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to
-* do any flushing here.
-*/
+ * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to
+ * do any flushing here.
+ */
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
}
-/* drivers/base/dma-mapping.c */
-extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size);
-extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size);
-
-#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
-#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
-
#endif /* _ASM_NIOS2_DMA_MAPPING_H */
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index b101a43..a4ff86d 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -104,7 +104,7 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
unsigned r7)
{
unsigned dtb_passed = 0;
- char cmdline_passed[COMMAND_LINE_SIZE] = { 0, };
+ char cmdline_passed[COMMAND_LINE_SIZE] __maybe_unused = { 0, };
#if defined(CONFIG_NIOS2_PASS_CMDLINE)
if (r4 == 0x534f494e) { /* r4 is magic NIOS */
diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
index bbc3f91..e835dda 100644
--- a/arch/nios2/kernel/time.c
+++ b/arch/nios2/kernel/time.c
@@ -324,7 +324,7 @@ void __init time_init(void)
if (count < 2)
panic("%d timer is found, it needs 2 timers in system\n", count);
- clocksource_of_init();
+ clocksource_probe();
}
CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
diff --git a/arch/nios2/lib/memmove.c b/arch/nios2/lib/memmove.c
index c65ef51..866c021 100644
--- a/arch/nios2/lib/memmove.c
+++ b/arch/nios2/lib/memmove.c
@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <linux/string.h>
-#ifdef __HAVE_ARCH_MEMMOVE
void *memmove(void *d, const void *s, size_t count)
{
unsigned long dst, src;
@@ -79,4 +78,3 @@ restdown:
return d;
}
-#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/nios2/lib/memset.c b/arch/nios2/lib/memset.c
index 65e9780..c2cfcb1 100644
--- a/arch/nios2/lib/memset.c
+++ b/arch/nios2/lib/memset.c
@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <linux/string.h>
-#ifdef __HAVE_ARCH_MEMSET
void *memset(void *s, int c, size_t count)
{
int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
@@ -78,4 +77,3 @@ void *memset(void *s, int c, size_t count)
return s;
}
-#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/nios2/mm/cacheflush.c b/arch/nios2/mm/cacheflush.c
index 223cdcc..87bf88e 100644
--- a/arch/nios2/mm/cacheflush.c
+++ b/arch/nios2/mm/cacheflush.c
@@ -23,22 +23,6 @@ static void __flush_dcache(unsigned long start, unsigned long end)
end += (cpuinfo.dcache_line_size - 1);
end &= ~(cpuinfo.dcache_line_size - 1);
- for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) {
- __asm__ __volatile__ (" flushda 0(%0)\n"
- : /* Outputs */
- : /* Inputs */ "r"(addr)
- /* : No clobber */);
- }
-}
-
-static void __flush_dcache_all(unsigned long start, unsigned long end)
-{
- unsigned long addr;
-
- start &= ~(cpuinfo.dcache_line_size - 1);
- end += (cpuinfo.dcache_line_size - 1);
- end &= ~(cpuinfo.dcache_line_size - 1);
-
if (end > start + cpuinfo.dcache_size)
end = start + cpuinfo.dcache_size;
@@ -112,7 +96,7 @@ static void flush_aliases(struct address_space *mapping, struct page *page)
void flush_cache_all(void)
{
- __flush_dcache_all(0, cpuinfo.dcache_size);
+ __flush_dcache(0, cpuinfo.dcache_size);
__flush_icache(0, cpuinfo.icache_size);
}
@@ -182,7 +166,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
*/
unsigned long start = (unsigned long)page_address(page);
- __flush_dcache_all(start, start + PAGE_SIZE);
+ __flush_dcache(start, start + PAGE_SIZE);
}
void flush_dcache_page(struct page *page)
@@ -268,7 +252,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
{
flush_cache_page(vma, user_vaddr, page_to_pfn(page));
memcpy(dst, src, len);
- __flush_dcache_all((unsigned long)src, (unsigned long)src + len);
+ __flush_dcache((unsigned long)src, (unsigned long)src + len);
if (vma->vm_flags & VM_EXEC)
__flush_icache((unsigned long)src, (unsigned long)src + len);
}
@@ -279,7 +263,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
{
flush_cache_page(vma, user_vaddr, page_to_pfn(page));
memcpy(dst, src, len);
- __flush_dcache_all((unsigned long)dst, (unsigned long)dst + len);
+ __flush_dcache((unsigned long)dst, (unsigned long)dst + len);
if (vma->vm_flags & VM_EXEC)
__flush_icache((unsigned long)dst, (unsigned long)dst + len);
}
diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c
index ac5da75..90422c3 100644
--- a/arch/nios2/mm/dma-mapping.c
+++ b/arch/nios2/mm/dma-mapping.c
@@ -20,9 +20,46 @@
#include <linux/cache.h>
#include <asm/cacheflush.h>
+static inline void __dma_sync_for_device(void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ switch (direction) {
+ case DMA_FROM_DEVICE:
+ invalidate_dcache_range((unsigned long)vaddr,
+ (unsigned long)(vaddr + size));
+ break;
+ case DMA_TO_DEVICE:
+ /*
+ * We just need to flush the caches here , but Nios2 flush
+ * instruction will do both writeback and invalidate.
+ */
+ case DMA_BIDIRECTIONAL: /* flush and invalidate */
+ flush_dcache_range((unsigned long)vaddr,
+ (unsigned long)(vaddr + size));
+ break;
+ default:
+ BUG();
+ }
+}
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ switch (direction) {
+ case DMA_BIDIRECTIONAL:
+ case DMA_FROM_DEVICE:
+ invalidate_dcache_range((unsigned long)vaddr,
+ (unsigned long)(vaddr + size));
+ break;
+ case DMA_TO_DEVICE:
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void *nios2_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
void *ret;
@@ -45,24 +82,21 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+static void nios2_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
unsigned long addr = (unsigned long) CAC_ADDR((unsigned long) vaddr);
free_pages(addr, get_order(size));
}
-EXPORT_SYMBOL(dma_free_coherent);
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static int nios2_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
int i;
- BUG_ON(!valid_dma_direction(direction));
-
for_each_sg(sg, sg, nents, i) {
void *addr;
@@ -75,40 +109,32 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
+static dma_addr_t nios2_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- void *addr;
-
- BUG_ON(!valid_dma_direction(direction));
+ void *addr = page_address(page) + offset;
- addr = page_address(page) + offset;
__dma_sync_for_device(addr, size, direction);
-
return page_to_phys(page) + offset;
}
-EXPORT_SYMBOL(dma_map_page);
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
+static void nios2_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
- BUG_ON(!valid_dma_direction(direction));
-
__dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
}
-EXPORT_SYMBOL(dma_unmap_page);
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
+static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
void *addr;
int i;
- BUG_ON(!valid_dma_direction(direction));
-
if (direction == DMA_TO_DEVICE)
return;
@@ -118,69 +144,54 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
__dma_sync_for_cpu(addr, sg->length, direction);
}
}
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- __dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
-}
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
-
- __dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
-}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
+static void nios2_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
- BUG_ON(!valid_dma_direction(direction));
-
__dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
}
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
+static void nios2_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
- BUG_ON(!valid_dma_direction(direction));
-
__dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
}
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
+static void nios2_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
{
int i;
- BUG_ON(!valid_dma_direction(direction));
-
/* Make sure that gcc doesn't leave the empty loop body. */
for_each_sg(sg, sg, nelems, i)
__dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
}
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction direction)
+static void nios2_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
{
int i;
- BUG_ON(!valid_dma_direction(direction));
-
/* Make sure that gcc doesn't leave the empty loop body. */
for_each_sg(sg, sg, nelems, i)
__dma_sync_for_device(sg_virt(sg), sg->length, direction);
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+struct dma_map_ops nios2_dma_ops = {
+ .alloc = nios2_dma_alloc,
+ .free = nios2_dma_free,
+ .map_page = nios2_dma_map_page,
+ .unmap_page = nios2_dma_unmap_page,
+ .map_sg = nios2_dma_map_sg,
+ .unmap_sg = nios2_dma_unmap_sg,
+ .sync_single_for_device = nios2_dma_sync_single_for_device,
+ .sync_single_for_cpu = nios2_dma_sync_single_for_cpu,
+ .sync_sg_for_cpu = nios2_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = nios2_dma_sync_sg_for_device,
+};
+EXPORT_SYMBOL(nios2_dma_ops);
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 443f44d..e118c02 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -29,9 +29,6 @@ config OPENRISC
config MMU
def_bool y
-config HAVE_DMA_ATTRS
- def_bool y
-
config RWSEM_GENERIC_SPINLOCK
def_bool y
diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h
index 413bfcf..1f260bc 100644
--- a/arch/openrisc/include/asm/dma-mapping.h
+++ b/arch/openrisc/include/asm/dma-mapping.h
@@ -42,6 +42,4 @@ static inline int dma_supported(struct device *dev, u64 dma_mask)
return dma_mask == DMA_BIT_MASK(32);
}
-#include <asm-generic/dma-mapping-common.h>
-
#endif /* __ASM_OPENRISC_DMA_MAPPING_H */
diff --git a/arch/openrisc/include/asm/gpio.h b/arch/openrisc/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/openrisc/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index c365469..14f655c 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -29,6 +29,7 @@ config PARISC
select TTY # Needed for pdc_cons.c
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_ARCH_AUDITSYSCALL
+ select ARCH_NO_COHERENT_DMA_MMAP
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
@@ -79,9 +80,6 @@ config TIME_LOW_RES
depends on SMP
default y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
# unless you want to implement ACPI on PA-RISC ... ;-)
config PM
bool
@@ -108,6 +106,9 @@ config PGTABLE_LEVELS
default 3 if 64BIT && PARISC_PAGE_SIZE_4KB
default 2
+config SYS_SUPPORTS_HUGETLBFS
+ def_bool y if PA20
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 9387cc2..db8f56b 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -183,7 +183,6 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_DEBUG_RODATA=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 0490199..1a4f776 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -193,7 +193,6 @@ CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
diff --git a/arch/parisc/configs/default_defconfig b/arch/parisc/configs/default_defconfig
index 4d8127e..310b665 100644
--- a/arch/parisc/configs/default_defconfig
+++ b/arch/parisc/configs/default_defconfig
@@ -211,7 +211,6 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_MD4=m
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
index 0ffb08f..5b04d70 100644
--- a/arch/parisc/configs/generic-32bit_defconfig
+++ b/arch/parisc/configs/generic-32bit_defconfig
@@ -301,7 +301,6 @@ CONFIG_RCU_CPU_STALL_INFO=y
CONFIG_LATENCYTOP=y
CONFIG_LKDTM=m
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index 2536965..1d10999 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -67,7 +67,7 @@ static __inline__ void atomic_set(atomic_t *v, int i)
static __inline__ int atomic_read(const atomic_t *v)
{
- return ACCESS_ONCE((v)->counter);
+ return READ_ONCE((v)->counter);
}
/* exported interface */
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index 47f11c7..df0f52b 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -7,20 +7,12 @@
/*
- * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have
- * 32-byte cachelines. The default configuration is not for SMP anyway,
- * so if you're building for SMP, you should select the appropriate
- * processor type. There is a potential livelock danger when running
- * a machine with this value set too small, but it's more probable you'll
- * just ruin performance.
+ * PA 2.0 processors have 64 and 128-byte L2 cachelines; PA 1.1 processors
+ * have 32-byte cachelines. The L1 length appears to be 16 bytes but this
+ * is not clearly documented.
*/
-#ifdef CONFIG_PA20
-#define L1_CACHE_BYTES 64
-#define L1_CACHE_SHIFT 6
-#else
-#define L1_CACHE_BYTES 32
-#define L1_CACHE_SHIFT 5
-#endif
+#define L1_CACHE_BYTES 16
+#define L1_CACHE_SHIFT 4
#ifndef __ASSEMBLY__
@@ -30,6 +22,9 @@
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+/* Read-only memory is marked before mark_rodata_ro() is called. */
+#define __ro_after_init __read_mostly
+
void parisc_cache_init(void); /* initializes cache-flushing */
void disable_sr_hashing_asm(int); /* low level support for above */
void disable_sr_hashing(void); /* turns off space register hashing */
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index ec2df4b..7bd69bd 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -121,10 +121,6 @@ flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vma
}
}
-#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void);
-#endif
-
#include <asm/kmap_types.h>
#define ARCH_HAS_KMAP
@@ -156,7 +152,6 @@ static inline void __kunmap_atomic(void *addr)
#define kmap_atomic_prot(page, prot) kmap_atomic(page)
#define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn))
-#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
#endif /* _PARISC_CACHEFLUSH_H */
diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
index c84b2fc..60c2c42 100644
--- a/arch/parisc/include/asm/checksum.h
+++ b/arch/parisc/include/asm/checksum.h
@@ -85,9 +85,8 @@ static inline __sum16 csum_fold(__wsum csum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
__asm__(
" add %1, %0, %0\n"
@@ -104,9 +103,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
@@ -124,7 +122,7 @@ static inline __sum16 ip_compute_csum(const void *buf, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__ (
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 94710cf..0448a2c 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -206,10 +206,10 @@ struct compat_ipc64_perm {
struct compat_semid64_ds {
struct compat_ipc64_perm sem_perm;
- compat_time_t sem_otime;
unsigned int __unused1;
- compat_time_t sem_ctime;
+ compat_time_t sem_otime;
unsigned int __unused2;
+ compat_time_t sem_ctime;
compat_ulong_t sem_nsems;
compat_ulong_t __unused3;
compat_ulong_t __unused4;
diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h
index d8d60a5..16e0246 100644
--- a/arch/parisc/include/asm/dma-mapping.h
+++ b/arch/parisc/include/asm/dma-mapping.h
@@ -1,30 +1,11 @@
#ifndef _PARISC_DMA_MAPPING_H
#define _PARISC_DMA_MAPPING_H
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
#include <asm/cacheflush.h>
-/* See Documentation/DMA-API-HOWTO.txt */
-struct hppa_dma_ops {
- int (*dma_supported)(struct device *dev, u64 mask);
- void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
- void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag);
- void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
- dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
- void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
- int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction);
- void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nhwents, enum dma_data_direction direction);
- void (*dma_sync_single_for_cpu)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
- void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
- void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
- void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
-};
-
/*
-** We could live without the hppa_dma_ops indirection if we didn't want
-** to support 4 different coherent dma models with one binary (they will
-** someday be loadable modules):
+** We need to support 4 different coherent dma models with one binary:
+**
** I/O MMU consistent method dma_sync behavior
** ============= ====================== =======================
** a) PA-7x00LC uncachable host memory flush/purge
@@ -40,158 +21,22 @@ struct hppa_dma_ops {
*/
#ifdef CONFIG_PA11
-extern struct hppa_dma_ops pcxl_dma_ops;
-extern struct hppa_dma_ops pcx_dma_ops;
+extern struct dma_map_ops pcxl_dma_ops;
+extern struct dma_map_ops pcx_dma_ops;
#endif
-extern struct hppa_dma_ops *hppa_dma_ops;
-
-#define dma_alloc_attrs(d, s, h, f, a) dma_alloc_coherent(d, s, h, f)
-#define dma_free_attrs(d, s, h, f, a) dma_free_coherent(d, s, h, f)
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
-}
-
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
-}
-
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
-{
- return hppa_dma_ops->map_single(dev, ptr, size, direction);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
-{
- hppa_dma_ops->unmap_single(dev, dma_addr, size, direction);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
-{
- return hppa_dma_ops->map_sg(dev, sg, nents, direction);
-}
+extern struct dma_map_ops *hppa_dma_ops;
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
-{
- hppa_dma_ops->unmap_sg(dev, sg, nhwentries, direction);
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
-{
- return dma_map_single(dev, (page_address(page) + (offset)), size, direction);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
- dma_unmap_single(dev, dma_address, size, direction);
-}
-
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_single_for_cpu)
- hppa_dma_ops->dma_sync_single_for_cpu(dev, dma_handle, 0, size, direction);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_single_for_device)
- hppa_dma_ops->dma_sync_single_for_device(dev, dma_handle, 0, size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_single_for_cpu)
- hppa_dma_ops->dma_sync_single_for_cpu(dev, dma_handle, offset, size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_single_for_device)
- hppa_dma_ops->dma_sync_single_for_device(dev, dma_handle, offset, size, direction);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_sg_for_cpu)
- hppa_dma_ops->dma_sync_sg_for_cpu(dev, sg, nelems, direction);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- if(hppa_dma_ops->dma_sync_sg_for_device)
- hppa_dma_ops->dma_sync_sg_for_device(dev, sg, nelems, direction);
-}
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
- return hppa_dma_ops->dma_supported(dev, mask);
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
- if(!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
+ return hppa_dma_ops;
}
static inline void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
- if(hppa_dma_ops->dma_sync_single_for_cpu)
+ if (hppa_dma_ops->sync_single_for_cpu)
flush_kernel_dcache_range((unsigned long)vaddr, size);
}
@@ -238,22 +83,4 @@ struct parisc_device;
void * sba_get_iommu(struct parisc_device *dev);
#endif
-/* At the moment, we panic on error for IOMMU resource exaustion */
-#define dma_mapping_error(dev, x) 0
-
-/* This API cannot be supported on PA-RISC */
-static inline int dma_mmap_coherent(struct device *dev,
- struct vm_area_struct *vma, void *cpu_addr,
- dma_addr_t dma_addr, size_t size)
-{
- return -EINVAL;
-}
-
-static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size)
-{
- return -EINVAL;
-}
-
#endif
diff --git a/arch/parisc/include/asm/floppy.h b/arch/parisc/include/asm/floppy.h
index f84ff12..6d8276cd 100644
--- a/arch/parisc/include/asm/floppy.h
+++ b/arch/parisc/include/asm/floppy.h
@@ -33,7 +33,7 @@
* floppy accesses go through the track buffer.
*/
#define _CROSS_64KB(a,s,vdma) \
-(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
+(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
new file mode 100644
index 0000000..a65d888
--- /dev/null
+++ b/arch/parisc/include/asm/hugetlb.h
@@ -0,0 +1,73 @@
+#ifndef _ASM_PARISC64_HUGETLB_H
+#define _ASM_PARISC64_HUGETLB_H
+
+#include <asm/page.h>
+#include <asm-generic/hugetlb.h>
+
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
+
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep);
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+ unsigned long addr,
+ unsigned long len) {
+ return 0;
+}
+
+/*
+ * If the arch doesn't supply something else, assume that hugepage
+ * size aligned regions are ok without further preparation.
+ */
+static inline int prepare_hugepage_range(struct file *file,
+ unsigned long addr, unsigned long len)
+{
+ if (len & ~HPAGE_MASK)
+ return -EINVAL;
+ if (addr & ~HPAGE_MASK)
+ return -EINVAL;
+ return 0;
+}
+
+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 void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+}
+
+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);
+}
+
+void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep);
+
+int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty);
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+ return *ptep;
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
+#endif /* _ASM_PARISC64_HUGETLB_H */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index 60d5d17..80e742a 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -145,11 +145,22 @@ extern int npmem_ranges;
#endif /* CONFIG_DISCONTIGMEM */
#ifdef CONFIG_HUGETLB_PAGE
-#define HPAGE_SHIFT 22 /* 4MB (is this fixed?) */
+#define HPAGE_SHIFT PMD_SHIFT /* fixed for transparent huge pages */
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+
+#if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
+# define REAL_HPAGE_SHIFT 20 /* 20 = 1MB */
+# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_1M
+#elif !defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
+# define REAL_HPAGE_SHIFT 22 /* 22 = 4MB */
+# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4M
+#else
+# define REAL_HPAGE_SHIFT 24 /* 24 = 16MB */
+# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16M
#endif
+#endif /* CONFIG_HUGETLB_PAGE */
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 71889ea..defebd9 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -167,6 +167,7 @@ static inline void pcibios_register_hba(struct pci_hba_data *x)
{
}
#endif
+extern void pcibios_init_bridge(struct pci_dev *);
/*
* pcibios_assign_all_busses() is used in drivers/pci/pci.c:pci_do_scan_bus()
@@ -193,9 +194,6 @@ static inline void pcibios_register_hba(struct pci_hba_data *x)
#define PCIBIOS_MIN_IO 0x10
#define PCIBIOS_MIN_MEM 0x1000 /* NBPG - but pci/setup-res.c dies */
-/* export the pci_ DMA API in terms of the dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
return channel ? 15 : 14;
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 7eb616e..451906d 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -63,7 +63,7 @@ struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
tc_page : 1, /* 0 = 2K page-size-machine, 1 = 4k page size */
tc_cst : 3, /* 0 = incoherent operations, else coherent operations */
tc_aid : 5, /* ITLB: width of access ids of processor (encoded!) */
- tc_pad1 : 8; /* ITLB: width of space-registers (encoded) */
+ tc_sr : 8; /* ITLB: width of space-registers (encoded) */
};
struct pdc_cache_info { /* main-PDC_CACHE-structure (caches & TLB's) */
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index 3edbb9f..f2fd327 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -35,7 +35,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
PxD_FLAG_VALID |
PxD_FLAG_ATTACHED)
+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
- /* The first pmd entry also is marked with _PAGE_GATEWAY as
+ /* The first pmd entry also is marked with PxD_FLAG_ATTACHED as
* a signal that this pmd may not be freed */
__pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
#endif
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index f93c4a4..291cee2 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -83,7 +83,11 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
/* This is the size of the initially mapped kernel memory */
-#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */
+#ifdef CONFIG_64BIT
+#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */
+#else
+#define KERNEL_INITIAL_ORDER 24 /* 1<<24 = 16MB */
+#endif
#define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER)
#if CONFIG_PGTABLE_LEVELS == 3
@@ -167,7 +171,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
#define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */
#define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */
#define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */
-/* bit 21 was formerly the FLUSH bit but is now unused */
+#define _PAGE_HPAGE_BIT 21 /* (0x400) Software: Huge Page */
#define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */
/* N.B. The bits are defined in terms of a 32 bit word above, so the */
@@ -194,6 +198,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
#define _PAGE_NO_CACHE (1 << xlate_pabit(_PAGE_NO_CACHE_BIT))
#define _PAGE_ACCESSED (1 << xlate_pabit(_PAGE_ACCESSED_BIT))
#define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT))
+#define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT))
#define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT))
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
@@ -217,7 +222,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
#define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT))
#define PxD_FLAG_MASK (0xf)
#define PxD_FLAG_SHIFT (4)
-#define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */
+#define PxD_VALUE_SHIFT (PFN_PTE_SHIFT-PxD_FLAG_SHIFT)
#ifndef __ASSEMBLY__
@@ -363,6 +368,19 @@ static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
/*
+ * Huge pte definitions.
+ */
+#ifdef CONFIG_HUGETLB_PAGE
+#define pte_huge(pte) (pte_val(pte) & _PAGE_HUGE)
+#define pte_mkhuge(pte) (__pte(pte_val(pte) | \
+ (parisc_requires_coherency() ? 0 : _PAGE_HUGE)))
+#else
+#define pte_huge(pte) (0)
+#define pte_mkhuge(pte) (pte)
+#endif
+
+
+/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
@@ -410,8 +428,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
/* Find an entry in the second-level page table.. */
#if CONFIG_PGTABLE_LEVELS == 3
+#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pmd_offset(dir,address) \
-((pmd_t *) pgd_page_vaddr(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1)))
+((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address))
#else
#define pmd_offset(dir,addr) ((pmd_t *) dir)
#endif
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 54adb60..2e674e1 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -192,33 +192,6 @@ void show_trace(struct task_struct *task, unsigned long *stack);
*/
typedef unsigned int elf_caddr_t;
-#define start_thread_som(regs, new_pc, new_sp) do { \
- unsigned long *sp = (unsigned long *)new_sp; \
- __u32 spaceid = (__u32)current->mm->context; \
- unsigned long pc = (unsigned long)new_pc; \
- /* offset pc for priv. level */ \
- pc |= 3; \
- \
- regs->iasq[0] = spaceid; \
- regs->iasq[1] = spaceid; \
- regs->iaoq[0] = pc; \
- regs->iaoq[1] = pc + 4; \
- regs->sr[2] = LINUX_GATEWAY_SPACE; \
- regs->sr[3] = 0xffff; \
- regs->sr[4] = spaceid; \
- regs->sr[5] = spaceid; \
- regs->sr[6] = spaceid; \
- regs->sr[7] = spaceid; \
- regs->gr[ 0] = USER_PSW; \
- regs->gr[30] = ((new_sp)+63)&~63; \
- regs->gr[31] = pc; \
- \
- get_user(regs->gr[26],&sp[0]); \
- get_user(regs->gr[25],&sp[-1]); \
- get_user(regs->gr[24],&sp[-2]); \
- get_user(regs->gr[23],&sp[-3]); \
-} while(0)
-
/* The ELF abi wants things done a "wee bit" differently than
* som does. Supporting this behavior here avoids
* having our own version of create_elf_tables.
@@ -338,18 +311,17 @@ extern unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
#define cpu_relax_lowlatency() cpu_relax()
-/* Used as a macro to identify the combined VIPT/PIPT cached
- * CPUs which require a guarantee of coherency (no inequivalent
- * aliases with different data, whether clean or not) to operate */
-static inline int parisc_requires_coherency(void)
-{
+/*
+ * parisc_requires_coherency() is used to identify the combined VIPT/PIPT
+ * cached CPUs which require a guarantee of coherency (no inequivalent aliases
+ * with different data, whether clean or not) to operate
+ */
#ifdef CONFIG_PA8X00
- return (boot_cpu_data.cpu_type == mako) ||
- (boot_cpu_data.cpu_type == mako2);
+extern int _parisc_requires_coherency;
+#define parisc_requires_coherency() _parisc_requires_coherency
#else
- return 0;
+#define parisc_requires_coherency() (0)
#endif
-}
#endif /* __ASSEMBLY__ */
diff --git a/arch/parisc/include/uapi/asm/ipcbuf.h b/arch/parisc/include/uapi/asm/ipcbuf.h
index bd956c4..790c411 100644
--- a/arch/parisc/include/uapi/asm/ipcbuf.h
+++ b/arch/parisc/include/uapi/asm/ipcbuf.h
@@ -1,6 +1,9 @@
#ifndef __PARISC_IPCBUF_H__
#define __PARISC_IPCBUF_H__
+#include <asm/bitsperlong.h>
+#include <linux/posix_types.h>
+
/*
* The ipc64_perm structure for PA-RISC is almost identical to
* kern_ipc_perm as we have always had 32-bit UIDs and GIDs in the kernel.
@@ -10,16 +13,18 @@
struct ipc64_perm
{
- key_t key;
- uid_t uid;
- gid_t gid;
- uid_t cuid;
- gid_t cgid;
+ __kernel_key_t key;
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_uid_t cuid;
+ __kernel_gid_t cgid;
+#if __BITS_PER_LONG != 64
unsigned short int __pad1;
- mode_t mode;
+#endif
+ __kernel_mode_t mode;
unsigned short int __pad2;
unsigned short int seq;
- unsigned int __pad3;
+ unsigned int __pad3;
unsigned long long int __unused1;
unsigned long long int __unused2;
};
diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h
index 294d251..f3db7d8 100644
--- a/arch/parisc/include/uapi/asm/mman.h
+++ b/arch/parisc/include/uapi/asm/mman.h
@@ -31,6 +31,9 @@
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
+#define MCL_ONFAULT 4 /* lock all pages that are faulted in */
+
+#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */
#define MADV_NORMAL 0 /* no further special treatment */
#define MADV_RANDOM 1 /* expect random page references */
@@ -42,20 +45,11 @@
#define MADV_VPS_INHERIT 7 /* Inherit parents page size */
/* common/generic parameters */
+#define MADV_FREE 8 /* free pages only if memory pressure */
#define MADV_REMOVE 9 /* remove these pages & resources */
#define MADV_DONTFORK 10 /* don't inherit across fork */
#define MADV_DOFORK 11 /* do inherit across fork */
-/* The range 12-64 is reserved for page size specification. */
-#define MADV_4K_PAGES 12 /* Use 4K pages */
-#define MADV_16K_PAGES 14 /* Use 16K pages */
-#define MADV_64K_PAGES 16 /* Use 64K pages */
-#define MADV_256K_PAGES 18 /* Use 256K pages */
-#define MADV_1M_PAGES 20 /* Use 1 Megabyte pages */
-#define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */
-#define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */
-#define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */
-
#define MADV_MERGEABLE 65 /* KSM may merge identical pages */
#define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */
diff --git a/arch/parisc/include/uapi/asm/msgbuf.h b/arch/parisc/include/uapi/asm/msgbuf.h
index 3421389..2e83ac7 100644
--- a/arch/parisc/include/uapi/asm/msgbuf.h
+++ b/arch/parisc/include/uapi/asm/msgbuf.h
@@ -27,13 +27,13 @@ struct msqid64_ds {
unsigned int __pad3;
#endif
__kernel_time_t msg_ctime; /* last change time */
- unsigned int msg_cbytes; /* current number of bytes on queue */
- unsigned int msg_qnum; /* number of messages in queue */
- unsigned int msg_qbytes; /* max number of bytes on queue */
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
__kernel_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_pid_t msg_lrpid; /* last receive pid */
- unsigned int __unused1;
- unsigned int __unused2;
+ unsigned long __unused1;
+ unsigned long __unused2;
};
#endif /* _PARISC_MSGBUF_H */
diff --git a/arch/parisc/include/uapi/asm/posix_types.h b/arch/parisc/include/uapi/asm/posix_types.h
index b934425..f3b5f70 100644
--- a/arch/parisc/include/uapi/asm/posix_types.h
+++ b/arch/parisc/include/uapi/asm/posix_types.h
@@ -7,8 +7,10 @@
* assume GCC is being used.
*/
+#ifndef __LP64__
typedef unsigned short __kernel_mode_t;
#define __kernel_mode_t __kernel_mode_t
+#endif
typedef unsigned short __kernel_ipc_pid_t;
#define __kernel_ipc_pid_t __kernel_ipc_pid_t
diff --git a/arch/parisc/include/uapi/asm/sembuf.h b/arch/parisc/include/uapi/asm/sembuf.h
index f01d89e..c20971b 100644
--- a/arch/parisc/include/uapi/asm/sembuf.h
+++ b/arch/parisc/include/uapi/asm/sembuf.h
@@ -23,9 +23,9 @@ struct semid64_ds {
unsigned int __pad2;
#endif
__kernel_time_t sem_ctime; /* last change time */
- unsigned int sem_nsems; /* no. of semaphores in array */
- unsigned int __unused1;
- unsigned int __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused1;
+ unsigned long __unused2;
};
#endif /* _PARISC_SEMBUF_H */
diff --git a/arch/parisc/include/uapi/asm/shmbuf.h b/arch/parisc/include/uapi/asm/shmbuf.h
index 8496c38..750e13e 100644
--- a/arch/parisc/include/uapi/asm/shmbuf.h
+++ b/arch/parisc/include/uapi/asm/shmbuf.h
@@ -30,12 +30,12 @@ struct shmid64_ds {
#if __BITS_PER_LONG != 64
unsigned int __pad4;
#endif
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
- unsigned int shm_nattch; /* no. of current attaches */
- unsigned int __unused1;
- unsigned int __unused2;
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused1;
+ unsigned long __unused2;
};
struct shminfo64 {
diff --git a/arch/parisc/include/uapi/asm/siginfo.h b/arch/parisc/include/uapi/asm/siginfo.h
index d703472..8fd10f8 100644
--- a/arch/parisc/include/uapi/asm/siginfo.h
+++ b/arch/parisc/include/uapi/asm/siginfo.h
@@ -1,9 +1,10 @@
#ifndef _PARISC_SIGINFO_H
#define _PARISC_SIGINFO_H
-#include <asm-generic/siginfo.h>
+#if defined(__LP64__)
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#endif
-#undef NSIGTRAP
-#define NSIGTRAP 4
+#include <asm-generic/siginfo.h>
#endif
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index a5cd40c..9c935d7 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -84,4 +84,9 @@
#define SO_ATTACH_BPF 0x402B
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 0x402C
+#define SO_ATTACH_REUSEPORT_EBPF 0x402D
+
+#define SO_CNX_ADVICE 0x402E
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/parisc/include/uapi/asm/stat.h b/arch/parisc/include/uapi/asm/stat.h
index b606b36..3310d2a 100644
--- a/arch/parisc/include/uapi/asm/stat.h
+++ b/arch/parisc/include/uapi/asm/stat.h
@@ -36,37 +36,6 @@ struct stat {
#define STAT_HAVE_NSEC
-struct hpux_stat64 {
- unsigned int st_dev; /* dev_t is 32 bits on parisc */
- unsigned int st_ino; /* 32 bits */
- unsigned short st_mode; /* 16 bits */
- unsigned short st_nlink; /* 16 bits */
- unsigned short st_reserved1; /* old st_uid */
- unsigned short st_reserved2; /* old st_gid */
- unsigned int st_rdev;
- signed long long st_size;
- signed int st_atime;
- unsigned int st_spare1;
- signed int st_mtime;
- unsigned int st_spare2;
- signed int st_ctime;
- unsigned int st_spare3;
- int st_blksize;
- unsigned long long st_blocks;
- unsigned int __unused1; /* ACL stuff */
- unsigned int __unused2; /* network */
- unsigned int __unused3; /* network */
- unsigned int __unused4; /* cnodes */
- unsigned short __unused5; /* netsite */
- short st_fstype;
- unsigned int st_realdev;
- unsigned short st_basemode;
- unsigned short st_spareshort;
- unsigned int st_uid;
- unsigned int st_gid;
- unsigned int st_spare4[3];
-};
-
/* This is the struct that 32-bit userspace applications are expecting.
* How 64-bit apps are going to be compiled, I have no idea. But at least
* this way, we don't have a wrapper in the kernel.
diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h
index 2e639d7..b75039f 100644
--- a/arch/parisc/include/uapi/asm/unistd.h
+++ b/arch/parisc/include/uapi/asm/unistd.h
@@ -358,8 +358,12 @@
#define __NR_memfd_create (__NR_Linux + 340)
#define __NR_bpf (__NR_Linux + 341)
#define __NR_execveat (__NR_Linux + 342)
+#define __NR_membarrier (__NR_Linux + 343)
+#define __NR_userfaultfd (__NR_Linux + 344)
+#define __NR_mlock2 (__NR_Linux + 345)
+#define __NR_copy_file_range (__NR_Linux + 346)
-#define __NR_Linux_syscalls (__NR_execveat + 1)
+#define __NR_Linux_syscalls (__NR_copy_file_range + 1)
#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 59001ce..d2f6257 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -290,6 +290,14 @@ int main(void)
DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
DEFINE(ASM_PT_INITIAL, PT_INITIAL);
BLANK();
+ /* HUGEPAGE_SIZE is only used in vmlinux.lds.S to align kernel text
+ * and kernel data on physical huge pages */
+#ifdef CONFIG_HUGETLB_PAGE
+ DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT);
+#else
+ DEFINE(HUGEPAGE_SIZE, PAGE_SIZE);
+#endif
+ BLANK();
DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index cda6dbb..91c2a39 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -172,6 +172,24 @@ parisc_cache_init(void)
cache_info.ic_count,
cache_info.ic_loop);
+ printk("IT base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx off_base 0x%lx off_stride 0x%lx off_count 0x%lx\n",
+ cache_info.it_sp_base,
+ cache_info.it_sp_stride,
+ cache_info.it_sp_count,
+ cache_info.it_loop,
+ cache_info.it_off_base,
+ cache_info.it_off_stride,
+ cache_info.it_off_count);
+
+ printk("DT base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx off_base 0x%lx off_stride 0x%lx off_count 0x%lx\n",
+ cache_info.dt_sp_base,
+ cache_info.dt_sp_stride,
+ cache_info.dt_sp_count,
+ cache_info.dt_loop,
+ cache_info.dt_off_base,
+ cache_info.dt_off_stride,
+ cache_info.dt_off_count);
+
printk("ic_conf = 0x%lx alias %d blk %d line %d shift %d\n",
*(unsigned long *) (&cache_info.ic_conf),
cache_info.ic_conf.cc_alias,
@@ -184,19 +202,19 @@ parisc_cache_init(void)
cache_info.ic_conf.cc_cst,
cache_info.ic_conf.cc_hv);
- printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
+ printk("D-TLB conf: sh %d page %d cst %d aid %d sr %d\n",
cache_info.dt_conf.tc_sh,
cache_info.dt_conf.tc_page,
cache_info.dt_conf.tc_cst,
cache_info.dt_conf.tc_aid,
- cache_info.dt_conf.tc_pad1);
+ cache_info.dt_conf.tc_sr);
- printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
+ printk("I-TLB conf: sh %d page %d cst %d aid %d sr %d\n",
cache_info.it_conf.tc_sh,
cache_info.it_conf.tc_page,
cache_info.it_conf.tc_cst,
cache_info.it_conf.tc_aid,
- cache_info.it_conf.tc_pad1);
+ cache_info.it_conf.tc_sr);
#endif
split_tlb = 0;
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index dba508f..f815066 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -40,7 +40,7 @@
#include <asm/parisc-device.h>
/* See comments in include/asm-parisc/pci.h */
-struct hppa_dma_ops *hppa_dma_ops __read_mostly;
+struct dma_map_ops *hppa_dma_ops __read_mostly;
EXPORT_SYMBOL(hppa_dma_ops);
static struct device root = {
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c5ef408..623496c 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -502,21 +502,38 @@
STREG \pte,0(\ptp)
.endm
+ /* We have (depending on the page size):
+ * - 38 to 52-bit Physical Page Number
+ * - 12 to 26-bit page offset
+ */
/* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
* to a CPU TLB 4k PFN (4k => 12 bits to shift) */
- #define PAGE_ADD_SHIFT (PAGE_SHIFT-12)
+ #define PAGE_ADD_SHIFT (PAGE_SHIFT-12)
+ #define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12)
/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
- .macro convert_for_tlb_insert20 pte
+ .macro convert_for_tlb_insert20 pte,tmp
+#ifdef CONFIG_HUGETLB_PAGE
+ copy \pte,\tmp
+ extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+ 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+
+ depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
+ (63-58)+PAGE_ADD_SHIFT,\pte
+ extrd,u,*= \tmp,_PAGE_HPAGE_BIT+32,1,%r0
+ depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
+ (63-58)+PAGE_ADD_HUGE_SHIFT,\pte
+#else /* Huge pages disabled */
extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
(63-58)+PAGE_ADD_SHIFT,\pte
+#endif
.endm
/* Convert the pte and prot to tlb insertion values. How
* this happens is quite subtle, read below */
- .macro make_insert_tlb spc,pte,prot
+ .macro make_insert_tlb spc,pte,prot,tmp
space_to_prot \spc \prot /* create prot id from space */
/* The following is the real subtlety. This is depositing
* T <-> _PAGE_REFTRAP
@@ -553,7 +570,7 @@
depdi 1,12,1,\prot
/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
- convert_for_tlb_insert20 \pte
+ convert_for_tlb_insert20 \pte \tmp
.endm
/* Identical macro to make_insert_tlb above, except it
@@ -646,17 +663,12 @@
/*
- * Align fault_vector_20 on 4K boundary so that both
- * fault_vector_11 and fault_vector_20 are on the
- * same page. This is only necessary as long as we
- * write protect the kernel text, which we may stop
- * doing once we use large page translations to cover
- * the static part of the kernel address space.
+ * Fault_vectors are architecturally required to be aligned on a 2K
+ * boundary
*/
.text
-
- .align 4096
+ .align 2048
ENTRY(fault_vector_20)
/* First vector is invalid (0) */
@@ -1147,7 +1159,7 @@ dtlb_miss_20w:
tlb_lock spc,ptp,pte,t0,t1,dtlb_check_alias_20w
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
idtlbt pte,prot
@@ -1173,7 +1185,7 @@ nadtlb_miss_20w:
tlb_lock spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
idtlbt pte,prot
@@ -1267,7 +1279,7 @@ dtlb_miss_20:
tlb_lock spc,ptp,pte,t0,t1,dtlb_check_alias_20
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
f_extend pte,t1
@@ -1295,7 +1307,7 @@ nadtlb_miss_20:
tlb_lock spc,ptp,pte,t0,t1,nadtlb_check_alias_20
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
f_extend pte,t1
@@ -1404,7 +1416,7 @@ itlb_miss_20w:
tlb_lock spc,ptp,pte,t0,t1,itlb_fault
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
iitlbt pte,prot
@@ -1428,7 +1440,7 @@ naitlb_miss_20w:
tlb_lock spc,ptp,pte,t0,t1,naitlb_check_alias_20w
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
iitlbt pte,prot
@@ -1514,7 +1526,7 @@ itlb_miss_20:
tlb_lock spc,ptp,pte,t0,t1,itlb_fault
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
f_extend pte,t1
@@ -1534,7 +1546,7 @@ naitlb_miss_20:
tlb_lock spc,ptp,pte,t0,t1,naitlb_check_alias_20
update_accessed ptp,pte,t0,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
f_extend pte,t1
@@ -1566,7 +1578,7 @@ dbit_trap_20w:
tlb_lock spc,ptp,pte,t0,t1,dbit_fault
update_dirty ptp,pte,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
idtlbt pte,prot
@@ -1610,7 +1622,7 @@ dbit_trap_20:
tlb_lock spc,ptp,pte,t0,t1,dbit_fault
update_dirty ptp,pte,t1
- make_insert_tlb spc,pte,prot
+ make_insert_tlb spc,pte,prot,t1
f_extend pte,t1
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index e7d6452..75aa0db 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -69,7 +69,7 @@ $bss_loop:
stw,ma %arg2,4(%r1)
stw,ma %arg3,4(%r1)
- /* Initialize startup VM. Just map first 8/16 MB of memory */
+ /* Initialize startup VM. Just map first 16/32 MB of memory */
load32 PA(swapper_pg_dir),%r4
mtctl %r4,%cr24 /* Initialize kernel root pointer */
mtctl %r4,%cr25 /* Initialize user root pointer */
@@ -107,7 +107,7 @@ $bss_loop:
/* Now initialize the PTEs themselves. We use RWX for
* everything ... it will get remapped correctly later */
ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
- ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
+ load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
load32 PA(pg0),%r1
$pgt_fill_loop:
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 3c63a82..b9d75d9 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -42,9 +42,9 @@
* We are not doing SEGREL32 handling correctly. According to the ABI, we
* should do a value offset, like this:
* if (in_init(me, (void *)val))
- * val -= (uint32_t)me->module_init;
+ * val -= (uint32_t)me->init_layout.base;
* else
- * val -= (uint32_t)me->module_core;
+ * val -= (uint32_t)me->core_layout.base;
* However, SEGREL32 is used only for PARISC unwind entries, and we want
* those entries to have an absolute address, and not just an offset.
*
@@ -100,14 +100,14 @@
* or init pieces the location is */
static inline int in_init(struct module *me, void *loc)
{
- return (loc >= me->module_init &&
- loc <= (me->module_init + me->init_size));
+ return (loc >= me->init_layout.base &&
+ loc <= (me->init_layout.base + me->init_layout.size));
}
static inline int in_core(struct module *me, void *loc)
{
- return (loc >= me->module_core &&
- loc <= (me->module_core + me->core_size));
+ return (loc >= me->core_layout.base &&
+ loc <= (me->core_layout.base + me->core_layout.size));
}
static inline int in_local(struct module *me, void *loc)
@@ -367,13 +367,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
}
/* align things a bit */
- me->core_size = ALIGN(me->core_size, 16);
- me->arch.got_offset = me->core_size;
- me->core_size += gots * sizeof(struct got_entry);
+ me->core_layout.size = ALIGN(me->core_layout.size, 16);
+ me->arch.got_offset = me->core_layout.size;
+ me->core_layout.size += gots * sizeof(struct got_entry);
- me->core_size = ALIGN(me->core_size, 16);
- me->arch.fdesc_offset = me->core_size;
- me->core_size += fdescs * sizeof(Elf_Fdesc);
+ me->core_layout.size = ALIGN(me->core_layout.size, 16);
+ me->arch.fdesc_offset = me->core_layout.size;
+ me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
me->arch.got_max = gots;
me->arch.fdesc_max = fdescs;
@@ -391,7 +391,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
BUG_ON(value == 0);
- got = me->module_core + me->arch.got_offset;
+ got = me->core_layout.base + me->arch.got_offset;
for (i = 0; got[i].addr; i++)
if (got[i].addr == value)
goto out;
@@ -409,7 +409,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
#ifdef CONFIG_64BIT
static Elf_Addr get_fdesc(struct module *me, unsigned long value)
{
- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
+ Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
if (!value) {
printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
@@ -427,7 +427,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
/* Create new one */
fdesc->addr = value;
- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
+ fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
return (Elf_Addr)fdesc;
}
#endif /* CONFIG_64BIT */
@@ -839,7 +839,7 @@ register_unwind_table(struct module *me,
table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
end = table + sechdrs[me->arch.unwind_section].sh_size;
- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
+ gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index b9402c9..a27e492 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -413,7 +413,8 @@ pcxl_dma_init(void)
__initcall(pcxl_dma_init);
-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
+static void *pa11_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
{
unsigned long vaddr;
unsigned long paddr;
@@ -439,7 +440,8 @@ static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_ad
return (void *)vaddr;
}
-static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void pa11_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle, struct dma_attrs *attrs)
{
int order;
@@ -450,15 +452,20 @@ static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vad
free_pages((unsigned long)__va(dma_handle), order);
}
-static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
+static dma_addr_t pa11_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction, struct dma_attrs *attrs)
{
+ void *addr = page_address(page) + offset;
BUG_ON(direction == DMA_NONE);
flush_kernel_dcache_range((unsigned long) addr, size);
return virt_to_phys(addr);
}
-static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+static void pa11_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
BUG_ON(direction == DMA_NONE);
@@ -475,7 +482,9 @@ static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, siz
return;
}
-static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
+static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -492,7 +501,9 @@ static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int n
return nents;
}
-static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
+static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -509,18 +520,24 @@ static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, in
return;
}
-static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
+static void pa11_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
- flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
+ flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle),
+ size);
}
-static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
+static void pa11_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
- flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
+ flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle),
+ size);
}
static void pa11_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
@@ -545,32 +562,28 @@ static void pa11_dma_sync_sg_for_device(struct device *dev, struct scatterlist *
flush_kernel_vmap_range(sg_virt(sg), sg->length);
}
-struct hppa_dma_ops pcxl_dma_ops = {
+struct dma_map_ops pcxl_dma_ops = {
.dma_supported = pa11_dma_supported,
- .alloc_consistent = pa11_dma_alloc_consistent,
- .alloc_noncoherent = pa11_dma_alloc_consistent,
- .free_consistent = pa11_dma_free_consistent,
- .map_single = pa11_dma_map_single,
- .unmap_single = pa11_dma_unmap_single,
+ .alloc = pa11_dma_alloc,
+ .free = pa11_dma_free,
+ .map_page = pa11_dma_map_page,
+ .unmap_page = pa11_dma_unmap_page,
.map_sg = pa11_dma_map_sg,
.unmap_sg = pa11_dma_unmap_sg,
- .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
- .dma_sync_single_for_device = pa11_dma_sync_single_for_device,
- .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
- .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
+ .sync_single_for_device = pa11_dma_sync_single_for_device,
+ .sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = pa11_dma_sync_sg_for_device,
};
-static void *fail_alloc_consistent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- return NULL;
-}
-
-static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
+static void *pcx_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
{
void *addr;
+ if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
+ return NULL;
+
addr = (void *)__get_free_pages(flag, get_order(size));
if (addr)
*dma_handle = (dma_addr_t)virt_to_phys(addr);
@@ -578,24 +591,23 @@ static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
return addr;
}
-static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t iova)
+static void pcx_dma_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t iova, struct dma_attrs *attrs)
{
free_pages((unsigned long)vaddr, get_order(size));
return;
}
-struct hppa_dma_ops pcx_dma_ops = {
+struct dma_map_ops pcx_dma_ops = {
.dma_supported = pa11_dma_supported,
- .alloc_consistent = fail_alloc_consistent,
- .alloc_noncoherent = pa11_dma_alloc_noncoherent,
- .free_consistent = pa11_dma_free_noncoherent,
- .map_single = pa11_dma_map_single,
- .unmap_single = pa11_dma_unmap_single,
+ .alloc = pcx_dma_alloc,
+ .free = pcx_dma_free,
+ .map_page = pa11_dma_map_page,
+ .unmap_page = pa11_dma_unmap_page,
.map_sg = pa11_dma_map_sg,
.unmap_sg = pa11_dma_unmap_sg,
- .dma_sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
- .dma_sync_single_for_device = pa11_dma_sync_single_for_device,
- .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
- .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
+ .sync_single_for_device = pa11_dma_sync_single_for_device,
+ .sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = pa11_dma_sync_sg_for_device,
};
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 64f2764..0903c6a 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -170,23 +170,31 @@ void pcibios_set_master(struct pci_dev *dev)
(0x80 << 8) | pci_cache_line_size);
}
-
-void __init pcibios_init_bus(struct pci_bus *bus)
+/*
+ * pcibios_init_bridge() initializes cache line and default latency
+ * for pci controllers and pci-pci bridges
+ */
+void __init pcibios_init_bridge(struct pci_dev *dev)
{
- struct pci_dev *dev = bus->self;
- unsigned short bridge_ctl;
+ unsigned short bridge_ctl, bridge_ctl_new;
/* We deal only with pci controllers and pci-pci bridges. */
if (!dev || (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
return;
/* PCI-PCI bridge - set the cache line and default latency
- (32) for primary and secondary buses. */
+ * (32) for primary and secondary buses.
+ */
pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bridge_ctl);
- bridge_ctl |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
- pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
+
+ bridge_ctl_new = bridge_ctl | PCI_BRIDGE_CTL_PARITY |
+ PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_MASTER_ABORT;
+ dev_info(&dev->dev, "Changing bridge control from 0x%08x to 0x%08x\n",
+ bridge_ctl, bridge_ctl_new);
+
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl_new);
}
/*
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index b68d977..e81ccf1 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -44,6 +44,10 @@
struct system_cpuinfo_parisc boot_cpu_data __read_mostly;
EXPORT_SYMBOL(boot_cpu_data);
+#ifdef CONFIG_PA8X00
+int _parisc_requires_coherency __read_mostly;
+EXPORT_SYMBOL(_parisc_requires_coherency);
+#endif
DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data);
@@ -277,8 +281,12 @@ void __init collect_boot_cpu_data(void)
boot_cpu_data.cpu_type = parisc_get_cpu_type(boot_cpu_data.hversion);
boot_cpu_data.cpu_name = cpu_name_version[boot_cpu_data.cpu_type][0];
boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
-}
+#ifdef CONFIG_PA8X00
+ _parisc_requires_coherency = (boot_cpu_data.cpu_type == mako) ||
+ (boot_cpu_data.cpu_type == mako2);
+#endif
+}
/**
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 9585c81..ce0b2b4 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long do_syscall_trace_enter(struct pt_regs *regs)
{
- long ret = 0;
-
/* Do the secure computing check first. */
secure_computing_strict(regs->gr[20]);
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
- tracehook_report_syscall_entry(regs))
- ret = -1L;
+ tracehook_report_syscall_entry(regs)) {
+ /*
+ * Tracing decided this syscall should not happen or the
+ * debugger stored an invalid system call number. Skip
+ * the system call and the system call restart handling.
+ */
+ regs->gr[20] = -1UL;
+ goto out;
+ }
#ifdef CONFIG_64BIT
if (!is_compat_task())
@@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_regs *regs)
regs->gr[24] & 0xffffffff,
regs->gr[23] & 0xffffffff);
- return ret ? : regs->gr[20];
+out:
+ return regs->gr[20];
}
void do_syscall_trace_exit(struct pt_regs *regs)
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 72a3c65..f7ea626 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -130,7 +130,16 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "The 32-bit Kernel has started...\n");
#endif
- printk(KERN_INFO "Default page size is %dKB.\n", (int)(PAGE_SIZE / 1024));
+ printk(KERN_INFO "Kernel default page size is %d KB. Huge pages ",
+ (int)(PAGE_SIZE / 1024));
+#ifdef CONFIG_HUGETLB_PAGE
+ printk(KERN_CONT "enabled with %d MB physical and %d MB virtual size",
+ 1 << (REAL_HPAGE_SHIFT - 20), 1 << (HPAGE_SHIFT - 20));
+#else
+ printk(KERN_CONT "disabled");
+#endif
+ printk(KERN_CONT ".\n");
+
pdc_console_init();
@@ -377,6 +386,7 @@ arch_initcall(parisc_init);
void start_parisc(void)
{
extern void start_kernel(void);
+ extern void early_trap_init(void);
int ret, cpunum;
struct pdc_coproc_cfg coproc_cfg;
@@ -397,6 +407,8 @@ void start_parisc(void)
panic("must have an fpu to boot linux");
}
+ early_trap_init(); /* initialize checksum of fault_vector */
+
start_kernel();
// not reached
}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index dc1ea79..2264f68 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -435,6 +435,55 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
regs->gr[28]);
}
+/*
+ * Check how the syscall number gets loaded into %r20 within
+ * the delay branch in userspace and adjust as needed.
+ */
+
+static void check_syscallno_in_delay_branch(struct pt_regs *regs)
+{
+ u32 opcode, source_reg;
+ u32 __user *uaddr;
+ int err;
+
+ /* Usually we don't have to restore %r20 (the system call number)
+ * because it gets loaded in the delay slot of the branch external
+ * instruction via the ldi instruction.
+ * In some cases a register-to-register copy instruction might have
+ * been used instead, in which case we need to copy the syscall
+ * number into the source register before returning to userspace.
+ */
+
+ /* A syscall is just a branch, so all we have to do is fiddle the
+ * return pointer so that the ble instruction gets executed again.
+ */
+ regs->gr[31] -= 8; /* delayed branching */
+
+ /* Get assembler opcode of code in delay branch */
+ uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
+ err = get_user(opcode, uaddr);
+ if (err)
+ return;
+
+ /* Check if delay branch uses "ldi int,%r20" */
+ if ((opcode & 0xffff0000) == 0x34140000)
+ return; /* everything ok, just return */
+
+ /* Check if delay branch uses "nop" */
+ if (opcode == INSN_NOP)
+ return;
+
+ /* Check if delay branch uses "copy %rX,%r20" */
+ if ((opcode & 0xffe0ffff) == 0x08000254) {
+ source_reg = (opcode >> 16) & 31;
+ regs->gr[source_reg] = regs->gr[20];
+ return;
+ }
+
+ pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
+ current->comm, task_pid_nr(current), opcode);
+}
+
static inline void
syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{
@@ -457,10 +506,7 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
}
/* fallthrough */
case -ERESTARTNOINTR:
- /* A syscall is just a branch, so all
- * we have to do is fiddle the return pointer.
- */
- regs->gr[31] -= 8; /* delayed branching */
+ check_syscallno_in_delay_branch(regs);
break;
}
}
@@ -510,15 +556,9 @@ insert_restart_trampoline(struct pt_regs *regs)
}
case -ERESTARTNOHAND:
case -ERESTARTSYS:
- case -ERESTARTNOINTR: {
- /* Hooray for delayed branching. We don't
- * have to restore %r20 (the system call
- * number) because it gets loaded in the delay
- * slot of the branch external instruction.
- */
- regs->gr[31] -= 8;
+ case -ERESTARTNOINTR:
+ check_syscallno_in_delay_branch(regs);
return;
- }
default:
break;
}
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 52e8597..c2a9cc5 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -305,7 +305,7 @@ void __init smp_callin(void)
local_irq_enable(); /* Interrupts have been off until now */
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
/* NOTREACHED */
panic("smp_callin() AAAAaaaaahhhh....\n");
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 0b8d26d..fbafa0d 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -343,7 +343,7 @@ tracesys_next:
#endif
comiclr,>>= __NR_Linux_syscalls, %r20, %r0
- b,n .Lsyscall_nosys
+ b,n .Ltracesys_nosys
LDREGX %r20(%r19), %r19
@@ -359,6 +359,9 @@ tracesys_next:
be 0(%sr7,%r19)
ldo R%tracesys_exit(%r2),%r2
+.Ltracesys_nosys:
+ ldo -ENOSYS(%r0),%r28 /* set errno */
+
/* Do *not* call this function on the gateway page, because it
makes a direct call to syscall_trace. */
@@ -369,7 +372,7 @@ tracesys_exit:
ldo -16(%r30),%r29 /* Reference param save area */
#endif
ldo TASK_REGS(%r1),%r26
- bl do_syscall_trace_exit,%r2
+ BL do_syscall_trace_exit,%r2
STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
@@ -390,7 +393,7 @@ tracesys_sigexit:
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
- bl do_syscall_trace_exit,%r2
+ BL do_syscall_trace_exit,%r2
ldo TASK_REGS(%r1),%r26
ldil L%syscall_exit_rfi,%r1
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 8eefb12..585d50f 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -438,6 +438,10 @@
ENTRY_SAME(memfd_create) /* 340 */
ENTRY_SAME(bpf)
ENTRY_COMP(execveat)
+ ENTRY_SAME(membarrier)
+ ENTRY_SAME(userfaultfd)
+ ENTRY_SAME(mlock2) /* 345 */
+ ENTRY_SAME(copy_file_range)
.ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index b99b39f..553b098 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -807,7 +807,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
}
-int __init check_ivt(void *iva)
+void __init initialize_ivt(const void *iva)
{
extern u32 os_hpmc_size;
extern const u32 os_hpmc[];
@@ -818,8 +818,8 @@ int __init check_ivt(void *iva)
u32 *hpmcp;
u32 length;
- if (strcmp((char *)iva, "cows can fly"))
- return -1;
+ if (strcmp((const char *)iva, "cows can fly"))
+ panic("IVT invalid");
ivap = (u32 *)iva;
@@ -839,28 +839,23 @@ int __init check_ivt(void *iva)
check += ivap[i];
ivap[5] = -check;
-
- return 0;
}
-#ifndef CONFIG_64BIT
-extern const void fault_vector_11;
-#endif
-extern const void fault_vector_20;
-void __init trap_init(void)
+/* early_trap_init() is called before we set up kernel mappings and
+ * write-protect the kernel */
+void __init early_trap_init(void)
{
- void *iva;
+ extern const void fault_vector_20;
- if (boot_cpu_data.cpu_type >= pcxu)
- iva = (void *) &fault_vector_20;
- else
-#ifdef CONFIG_64BIT
- panic("Can't boot 64-bit OS on PA1.1 processor!");
-#else
- iva = (void *) &fault_vector_11;
+#ifndef CONFIG_64BIT
+ extern const void fault_vector_11;
+ initialize_ivt(&fault_vector_11);
#endif
- if (check_ivt(iva))
- panic("IVT invalid");
+ initialize_ivt(&fault_vector_20);
+}
+
+void __init trap_init(void)
+{
}
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 0dacc5c..308f290 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -60,7 +60,7 @@ SECTIONS
EXIT_DATA
}
PERCPU_SECTION(8)
- . = ALIGN(PAGE_SIZE);
+ . = ALIGN(HUGEPAGE_SIZE);
__init_end = .;
/* freed after init ends here */
@@ -116,7 +116,7 @@ SECTIONS
* that we can properly leave these
* as writable
*/
- . = ALIGN(PAGE_SIZE);
+ . = ALIGN(HUGEPAGE_SIZE);
data_start = .;
EXCEPTION_TABLE(8)
@@ -135,8 +135,11 @@ SECTIONS
_edata = .;
/* BSS */
- BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8)
+ BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE)
+
+ /* bootmap is allocated in setup_bootmem() directly behind bss. */
+ . = ALIGN(HUGEPAGE_SIZE);
_end = . ;
STABS_DEBUG
diff --git a/arch/parisc/mm/Makefile b/arch/parisc/mm/Makefile
index 758ceef..134393d 100644
--- a/arch/parisc/mm/Makefile
+++ b/arch/parisc/mm/Makefile
@@ -3,3 +3,4 @@
#
obj-y := init.o fault.o ioremap.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
new file mode 100644
index 0000000..5d6eea9
--- /dev/null
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -0,0 +1,197 @@
+/*
+ * PARISC64 Huge TLB page support.
+ *
+ * This parisc implementation is heavily based on the SPARC and x86 code.
+ *
+ * Copyright (C) 2015 Helge Deller <deller@gmx.de>
+ */
+
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/sysctl.h>
+
+#include <asm/mman.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
+
+
+unsigned long
+hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct hstate *h = hstate_file(file);
+
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
+ if (flags & MAP_FIXED)
+ if (prepare_hugepage_range(file, addr, len))
+ return -EINVAL;
+
+ if (addr)
+ addr = ALIGN(addr, huge_page_size(h));
+
+ /* we need to make sure the colouring is OK */
+ return arch_get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+ unsigned long addr, unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte = NULL;
+
+ /* We must align the address, because our caller will run
+ * set_huge_pte_at() on whatever we return, which writes out
+ * all of the sub-ptes for the hugepage range. So we have
+ * to give it the first such sub-pte.
+ */
+ addr &= HPAGE_MASK;
+
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ if (pud) {
+ pmd = pmd_alloc(mm, pud, addr);
+ if (pmd)
+ pte = pte_alloc_map(mm, pmd, addr);
+ }
+ return pte;
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte = NULL;
+
+ addr &= HPAGE_MASK;
+
+ pgd = pgd_offset(mm, addr);
+ if (!pgd_none(*pgd)) {
+ pud = pud_offset(pgd, addr);
+ if (!pud_none(*pud)) {
+ pmd = pmd_offset(pud, addr);
+ if (!pmd_none(*pmd))
+ pte = pte_offset_map(pmd, addr);
+ }
+ }
+ return pte;
+}
+
+/* Purge data and instruction TLB entries. Must be called holding
+ * the pa_tlb_lock. The TLB purge instructions are slow on SMP
+ * machines since the purge must be broadcast to all CPUs.
+ */
+static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long addr)
+{
+ int i;
+
+ /* We may use multiple physical huge pages (e.g. 2x1 MB) to emulate
+ * Linux standard huge pages (e.g. 2 MB) */
+ BUILD_BUG_ON(REAL_HPAGE_SHIFT > HPAGE_SHIFT);
+
+ addr &= HPAGE_MASK;
+ addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT;
+
+ for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
+ purge_tlb_entries(mm, addr);
+ addr += (1UL << REAL_HPAGE_SHIFT);
+ }
+}
+
+/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
+static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
+{
+ unsigned long addr_start;
+ int i;
+
+ addr &= HPAGE_MASK;
+ addr_start = addr;
+
+ for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+ set_pte(ptep, entry);
+ ptep++;
+
+ addr += PAGE_SIZE;
+ pte_val(entry) += PAGE_SIZE;
+ }
+
+ purge_tlb_entries_huge(mm, addr_start);
+}
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
+{
+ unsigned long flags;
+
+ purge_tlb_start(flags);
+ __set_huge_pte_at(mm, addr, ptep, entry);
+ purge_tlb_end(flags);
+}
+
+
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ unsigned long flags;
+ pte_t entry;
+
+ purge_tlb_start(flags);
+ entry = *ptep;
+ __set_huge_pte_at(mm, addr, ptep, __pte(0));
+ purge_tlb_end(flags);
+
+ return entry;
+}
+
+
+void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long flags;
+ pte_t old_pte;
+
+ purge_tlb_start(flags);
+ old_pte = *ptep;
+ __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+ purge_tlb_end(flags);
+}
+
+int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ unsigned long flags;
+ int changed;
+
+ purge_tlb_start(flags);
+ changed = !pte_same(*ptep, pte);
+ if (changed) {
+ __set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+ }
+ purge_tlb_end(flags);
+ return changed;
+}
+
+
+int pmd_huge(pmd_t pmd)
+{
+ return 0;
+}
+
+int pud_huge(pud_t pud)
+{
+ return 0;
+}
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index c229427..3c07d6b 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -23,6 +23,7 @@
#include <linux/unistd.h>
#include <linux/nodemask.h> /* for node_online_map */
#include <linux/pagemap.h> /* for release_pages and page_cache_release */
+#include <linux/compat.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
@@ -30,6 +31,7 @@
#include <asm/pdc_chassis.h>
#include <asm/mmzone.h>
#include <asm/sections.h>
+#include <asm/msgbuf.h>
extern int data_start;
extern void parisc_kernel_start(void); /* Kernel entry point in head.S */
@@ -53,12 +55,12 @@ signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
static struct resource data_resource = {
.name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource code_resource = {
.name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource pdcdata_resource = {
@@ -199,7 +201,7 @@ static void __init setup_bootmem(void)
res->name = "System RAM";
res->start = pmem_ranges[i].start_pfn << PAGE_SHIFT;
res->end = res->start + (pmem_ranges[i].pages << PAGE_SHIFT)-1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
}
@@ -407,15 +409,11 @@ static void __init map_pages(unsigned long start_vaddr,
unsigned long vaddr;
unsigned long ro_start;
unsigned long ro_end;
- unsigned long fv_addr;
- unsigned long gw_addr;
- extern const unsigned long fault_vector_20;
- extern void * const linux_gateway_page;
+ unsigned long kernel_end;
ro_start = __pa((unsigned long)_text);
ro_end = __pa((unsigned long)&data_start);
- fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
- gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
+ kernel_end = __pa((unsigned long)&_end);
end_paddr = start_paddr + size;
@@ -473,24 +471,25 @@ static void __init map_pages(unsigned long start_vaddr,
for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) {
pte_t pte;
- /*
- * Map the fault vector writable so we can
- * write the HPMC checksum.
- */
if (force)
pte = __mk_pte(address, pgprot);
- else if (parisc_text_address(vaddr) &&
- address != fv_addr)
+ else if (parisc_text_address(vaddr)) {
pte = __mk_pte(address, PAGE_KERNEL_EXEC);
+ if (address >= ro_start && address < kernel_end)
+ pte = pte_mkhuge(pte);
+ }
else
#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
- if (address >= ro_start && address < ro_end
- && address != fv_addr
- && address != gw_addr)
- pte = __mk_pte(address, PAGE_KERNEL_RO);
- else
+ if (address >= ro_start && address < ro_end) {
+ pte = __mk_pte(address, PAGE_KERNEL_EXEC);
+ pte = pte_mkhuge(pte);
+ } else
#endif
+ {
pte = __mk_pte(address, pgprot);
+ if (address >= ro_start && address < kernel_end)
+ pte = pte_mkhuge(pte);
+ }
if (address >= end_paddr) {
if (force)
@@ -534,15 +533,12 @@ void free_initmem(void)
/* force the kernel to see the new TLB entries */
__flush_tlb_range(0, init_begin, init_end);
- /* Attempt to catch anyone trying to execute code here
- * by filling the page with BRK insns.
- */
- memset((void *)init_begin, 0x00, init_end - init_begin);
+
/* finally dump all the instructions which were cached, since the
* pages are no-longer executable */
flush_icache_range(init_begin, init_end);
- free_initmem_default(-1);
+ free_initmem_default(POISON_FREE_INITMEM);
/* set up a new led state on systems shipped LED State panel */
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
@@ -590,6 +586,20 @@ unsigned long pcxl_dma_start __read_mostly;
void __init mem_init(void)
{
+ /* Do sanity checks on IPC (compat) structures */
+ BUILD_BUG_ON(sizeof(struct ipc64_perm) != 48);
+#ifndef CONFIG_64BIT
+ BUILD_BUG_ON(sizeof(struct semid64_ds) != 80);
+ BUILD_BUG_ON(sizeof(struct msqid64_ds) != 104);
+ BUILD_BUG_ON(sizeof(struct shmid64_ds) != 104);
+#endif
+#ifdef CONFIG_COMPAT
+ BUILD_BUG_ON(sizeof(struct compat_ipc64_perm) != sizeof(struct ipc64_perm));
+ BUILD_BUG_ON(sizeof(struct compat_semid64_ds) != 80);
+ BUILD_BUG_ON(sizeof(struct compat_msqid64_ds) != 104);
+ BUILD_BUG_ON(sizeof(struct compat_shmid64_ds) != 104);
+#endif
+
/* Do sanity checks on page table constants */
BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
@@ -712,8 +722,8 @@ static void __init pagetable_init(void)
unsigned long size;
start_paddr = pmem_ranges[range].start_pfn << PAGE_SHIFT;
- end_paddr = start_paddr + (pmem_ranges[range].pages << PAGE_SHIFT);
size = pmem_ranges[range].pages << PAGE_SHIFT;
+ end_paddr = start_paddr + size;
map_pages((unsigned long)__va(start_paddr), start_paddr,
size, PAGE_KERNEL, 0);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9a7057e..7cd32c0 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -47,9 +47,6 @@ config STACKTRACE_SUPPORT
bool
default y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config TRACE_IRQFLAGS_SUPPORT
bool
default y
@@ -97,6 +94,7 @@ config PPC
select OF_RESERVED_MEM
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
+ select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select SYSCTL_EXCEPTION_TRACE
@@ -111,7 +109,6 @@ config PPC
select HAVE_ARCH_TRACEHOOK
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
- select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_OPROFILE
select HAVE_DEBUG_KMEMLEAK
@@ -159,7 +156,10 @@ config PPC
select EDAC_SUPPORT
select EDAC_ATOMIC_SCRUB
select ARCH_HAS_DMA_SET_COHERENT_MASK
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select HAVE_ARCH_SECCOMP_FILTER
+ select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
config GENERIC_CSUM
def_bool CPU_LITTLE_ENDIAN
@@ -305,7 +305,7 @@ config ZONE_DMA32
config PGTABLE_LEVELS
int
default 2 if !PPC64
- default 3 if PPC_64K_PAGES
+ default 3 if PPC_64K_PAGES && !PPC_BOOK3S_64
default 4
source "init/Kconfig"
@@ -375,6 +375,24 @@ config PPC_TRANSACTIONAL_MEM
---help---
Support user-mode Transactional Memory on POWERPC.
+config DISABLE_MPROFILE_KERNEL
+ bool "Disable use of mprofile-kernel for kernel tracing"
+ depends on PPC64 && CPU_LITTLE_ENDIAN
+ default y
+ help
+ Selecting this options disables use of the mprofile-kernel ABI for
+ kernel tracing. That will cause options such as live patching
+ (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to
+ be disabled also.
+
+ If you have a toolchain which supports mprofile-kernel, then you can
+ enable this. Otherwise leave it disabled. If you're not sure, say
+ "N".
+
+config MPROFILE_KERNEL
+ depends on PPC64 && CPU_LITTLE_ENDIAN
+ def_bool !DISABLE_MPROFILE_KERNEL
+
config IOMMU_HELPER
def_bool PPC64
@@ -391,7 +409,7 @@ config SWIOTLB
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && (PPC_PSERIES || \
- PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
+ PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE)
---help---
Say Y here to be able to disable and re-enable individual
CPUs at runtime on SMP machines.
@@ -419,7 +437,7 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
config KEXEC
bool "kexec system call"
- depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP))
+ depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E
select KEXEC_CORE
help
kexec is a system call that implements the ability to shutdown your
@@ -559,6 +577,7 @@ choice
config PPC_4K_PAGES
bool "4k page size"
+ select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
config PPC_16K_PAGES
bool "16k page size"
@@ -567,6 +586,7 @@ config PPC_16K_PAGES
config PPC_64K_PAGES
bool "64k page size"
depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64)
+ select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
config PPC_256K_PAGES
bool "256k page size"
@@ -828,14 +848,10 @@ config PCI_8260
select PPC_INDIRECT_PCI
default y
-source "drivers/pci/pcie/Kconfig"
-
source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
config HAS_RAPIDIO
bool
default n
@@ -1074,8 +1090,6 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/powerpc/sysdev/qe_lib/Kconfig"
-
source "lib/Kconfig"
source "arch/powerpc/Kconfig.debug"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 3a510f4..638f9ce 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -64,17 +64,17 @@ config PPC_EMULATED_STATS
emulated.
config CODE_PATCHING_SELFTEST
- bool "Run self-tests of the code-patching code."
+ bool "Run self-tests of the code-patching code"
depends on DEBUG_KERNEL
default n
config FTR_FIXUP_SELFTEST
- bool "Run self-tests of the feature-fixup code."
+ bool "Run self-tests of the feature-fixup code"
depends on DEBUG_KERNEL
default n
config MSI_BITMAP_SELFTEST
- bool "Run self-tests of the MSI bitmap code."
+ bool "Run self-tests of the MSI bitmap code"
depends on DEBUG_KERNEL
default n
@@ -335,18 +335,6 @@ config PPC_EARLY_DEBUG_CPM_ADDR
platform probing is done, all platforms selected must
share the same address.
-config STRICT_DEVMEM
- def_bool y
- prompt "Filter access to /dev/mem"
- help
- This option restricts access to /dev/mem. If this option is
- disabled, you allow userspace access to all memory, including
- kernel and userspace memory. Accidental memory access is likely
- to be disastrous.
- Memory access is required for experts who want to debug the kernel.
-
- If you are unsure, say Y.
-
config FAIL_IOMMU
bool "Fault-injection capability for IOMMU"
depends on FAULT_INJECTION
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index b9b4af2..709a22a 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -133,6 +133,21 @@ else
CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
endif
+ifdef CONFIG_MPROFILE_KERNEL
+ ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK)
+ CC_FLAGS_FTRACE := -pg -mprofile-kernel
+ KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL
+ else
+ # If the user asked for mprofile-kernel but the toolchain doesn't
+ # support it, emit a warning and deliberately break the build later
+ # with mprofile-kernel-not-supported. We would prefer to make this an
+ # error right here, but then the user would never be able to run
+ # oldconfig to change their configuration.
+ $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL)
+ CC_FLAGS_FTRACE := -mprofile-kernel-not-supported
+ endif
+endif
+
CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell)
CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4)
CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
@@ -157,8 +172,6 @@ CFLAGS-$(CONFIG_E500) += $(call cc-option,-mcpu=8540 -msoft-float,-mcpu=powerpc)
endif
endif
-CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell)
-
asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr)
@@ -288,6 +301,10 @@ PHONY += pseries_le_defconfig
pseries_le_defconfig:
$(call merge_into_defconfig,pseries_defconfig,le)
+PHONY += ppc64le_defconfig
+ppc64le_defconfig:
+ $(call merge_into_defconfig,ppc64_defconfig,le)
+
PHONY += mpc85xx_defconfig
mpc85xx_defconfig:
$(call merge_into_defconfig,mpc85xx_basic_defconfig,\
@@ -308,6 +325,16 @@ corenet64_smp_defconfig:
$(call merge_into_defconfig,corenet_basic_defconfig,\
85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw)
+PHONY += mpc86xx_defconfig
+mpc86xx_defconfig:
+ $(call merge_into_defconfig,mpc86xx_basic_defconfig,\
+ 86xx-hw fsl-emb-nonhw)
+
+PHONY += mpc86xx_smp_defconfig
+mpc86xx_smp_defconfig:
+ $(call merge_into_defconfig,mpc86xx_basic_defconfig,\
+ 86xx-smp 86xx-hw fsl-emb-nonhw)
+
define archhelp
@echo '* zImage - Build default images selected by kernel config'
@echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 4eec430..6116510 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -113,7 +113,6 @@ src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
-src-plat-$(CONFIG_PPC_CELL_QPACE) += pseries-head.S
src-wlib := $(sort $(src-wlib-y))
src-plat := $(sort $(src-plat-y))
@@ -217,7 +216,6 @@ image-$(CONFIG_PPC_POWERNV) += zImage.pseries
image-$(CONFIG_PPC_MAPLE) += zImage.maple
image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
image-$(CONFIG_PPC_PS3) += dtbImage.ps3
-image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
@@ -364,6 +362,9 @@ $(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits)
$(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits)
$(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb)
+$(obj)/cuImage.%: vmlinux $(obj)/fsl/%.dtb $(wrapperbits)
+ $(call if_changed,wrap,cuboot-$*,,$(obj)/fsl/$*.dtb)
+
$(obj)/simpleImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits)
$(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz)
diff --git a/arch/powerpc/boot/dts/b4420qds.dts b/arch/powerpc/boot/dts/b4420qds.dts
deleted file mode 100644
index 508dbdf..0000000
--- a/arch/powerpc/boot/dts/b4420qds.dts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * B4420DS Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor, Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/b4420si-pre.dtsi"
-/include/ "b4qds.dtsi"
-
-/ {
- model = "fsl,B4420QDS";
- compatible = "fsl,B4420QDS";
-
- ifc: localbus@ffe124000 {
- board-control@3,0 {
- compatible = "fsl,b4420qds-fpga", "fsl,fpga-qixis";
- };
- };
-
-};
-
-/include/ "fsl/b4420si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/b4860qds.dts b/arch/powerpc/boot/dts/b4860qds.dts
deleted file mode 100644
index 6bb3707..0000000
--- a/arch/powerpc/boot/dts/b4860qds.dts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * B4860DS Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/b4860si-pre.dtsi"
-/include/ "b4qds.dtsi"
-
-/ {
- model = "fsl,B4860QDS";
- compatible = "fsl,B4860QDS";
-
- ifc: localbus@ffe124000 {
- board-control@3,0 {
- compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis";
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-
-};
-
-/include/ "fsl/b4860si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/b4qds.dtsi b/arch/powerpc/boot/dts/b4qds.dtsi
deleted file mode 100644
index 559d006..0000000
--- a/arch/powerpc/boot/dts/b4qds.dtsi
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * B4420DS Device Tree Source
- *
- * Copyright 2012 - 2014 Freescale Semiconductor, Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- model = "fsl,B4QDS";
- compatible = "fsl,B4QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 10MB for Linux Kernel Image */
- reg = <0x00200000 0x00A00000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@c00000 {
- /* 500MB for Root file System Image */
- reg = <0x00c00000 0x1F400000>;
- label = "NAND RFS Image";
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,b4qds-fpga", "fsl,fpga-qixis";
- reg = <3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01052000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sst,sst25wf040";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- };
- };
-
- sdhc@114000 {
- /*Disabled as there is no sdhc connector on B4420QDS board*/
- status = "disabled";
- };
-
- i2c@118000 {
- mux@77 {
- compatible = "nxp,pca9547";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- eeprom@50 {
- compatible = "at24,24c64";
- reg = <0x50>;
- };
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@53 {
- compatible = "at24,24c256";
- reg = <0x53>;
- };
- eeprom@57 {
- compatible = "at24,24c256";
- reg = <0x57>;
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- };
- };
-
- i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x2>;
-
- ina220@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
- };
-
- i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x3>;
-
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
- };
- };
-
- usb@210000 {
- dr_mode = "host";
- phy_type = "ulpi";
- };
-
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
-};
-
-/include/ "fsl/b4si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/bsc9131rdb.dts b/arch/powerpc/boot/dts/bsc9131rdb.dts
deleted file mode 100644
index e13d2d4..0000000
--- a/arch/powerpc/boot/dts/bsc9131rdb.dts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * BSC9131 RDB Device Tree Source
- *
- * Copyright 2011-2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/bsc9131si-pre.dtsi"
-
-/ {
- model = "fsl,bsc9131rdb";
- compatible = "fsl,bsc9131rdb";
-
- memory {
- device_type = "memory";
- };
-
- board_ifc: ifc: ifc@ff71e000 {
- /* NAND Flash on board */
- ranges = <0x0 0x0 0x0 0xff800000 0x00004000>;
- reg = <0x0 0xff71e000 0x0 0x2000>;
- };
-
- board_soc: soc: soc@ff700000 {
- ranges = <0x0 0x0 0xff700000 0x100000>;
- };
-};
-
-/include/ "bsc9131rdb.dtsi"
-/include/ "fsl/bsc9131si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/bsc9131rdb.dtsi
deleted file mode 100644
index 45efcba..0000000
--- a/arch/powerpc/boot/dts/bsc9131rdb.dtsi
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * BSC9131 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011-2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&board_ifc {
-
- nand@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x0 0x0 0x4000>;
-
- };
-};
-
-&board_soc {
- /* BSC9131RDB does not have any device on i2c@3100 */
- i2c@3100 {
- status = "disabled";
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <50000000>;
-
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x3>;
- };
- };
-
- sdhc@2e000 {
- status = "disabled";
- };
-
- enet0: ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/bsc9132qds.dts b/arch/powerpc/boot/dts/bsc9132qds.dts
deleted file mode 100644
index 6cab106..0000000
--- a/arch/powerpc/boot/dts/bsc9132qds.dts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * BSC9132 QDS Device Tree Source
- *
- * 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 as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/bsc9132si-pre.dtsi"
-
-/ {
- model = "fsl,bsc9132qds";
- compatible = "fsl,bsc9132qds";
-
- memory {
- device_type = "memory";
- };
-
- ifc: ifc@ff71e000 {
- /* NOR, NAND Flash on board */
- ranges = <0x0 0x0 0x0 0x88000000 0x08000000
- 0x1 0x0 0x0 0xff800000 0x00010000>;
- reg = <0x0 0xff71e000 0x0 0x2000>;
- };
-
- soc: soc@ff700000 {
- ranges = <0x0 0x0 0xff700000 0x100000>;
- };
-};
-
-/include/ "bsc9132qds.dtsi"
-/include/ "fsl/bsc9132si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/bsc9132qds.dtsi b/arch/powerpc/boot/dts/bsc9132qds.dtsi
deleted file mode 100644
index af8e888..0000000
--- a/arch/powerpc/boot/dts/bsc9132qds.dtsi
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * BSC9132 QDS Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&ifc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x1 0x0 0x4000>;
- };
-};
-
-&soc {
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <30000000>;
- };
- };
-
- i2c@3000 {
- fpga: fpga@66 {
- compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c";
- reg = <0x66>;
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <0x1>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x1f>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy1>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-};
diff --git a/arch/powerpc/boot/dts/c293pcie.dts b/arch/powerpc/boot/dts/c293pcie.dts
deleted file mode 100644
index 6681cc2..0000000
--- a/arch/powerpc/boot/dts/c293pcie.dts
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * C293 PCIE Device Tree Source
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/c293si-pre.dtsi"
-
-/ {
- model = "fsl,C293PCIE";
- compatible = "fsl,C293PCIE";
-
- memory {
- device_type = "memory";
- };
-
- ifc: ifc@fffe1e000 {
- reg = <0xf 0xffe1e000 0 0x2000>;
- ranges = <0x0 0x0 0xf 0xec000000 0x04000000
- 0x1 0x0 0xf 0xff800000 0x00010000
- 0x2 0x0 0xf 0xffdf0000 0x00010000>;
-
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-&ifc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x4000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* 1MB for DTB Image */
- reg = <0x0 0x00100000>;
- label = "NOR DTB Image";
- };
-
- partition@100000 {
- /* 8 MB for Linux Kernel Image */
- reg = <0x00100000 0x00800000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@900000 {
- /* 53MB for rootfs */
- reg = <0x00900000 0x03500000>;
- label = "NOR Rootfs Image";
- };
-
- partition@3e00000 {
- /* 1MB for blob encrypted key */
- reg = <0x03e00000 0x00100000>;
- label = "NOR blob encrypted key";
- };
-
- partition@3f00000 {
- /* 512KB for u-boot Bootloader Image and evn */
- reg = <0x03f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x1 0x0 0x10000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 16MB for Linux Kernel Image */
- reg = <0x00200000 0x01000000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@1200000 {
- /* 4078MB for Root file System Image */
- reg = <0x00600000 0xfee00000>;
- label = "NAND RFS Image";
- };
- };
-
- cpld@2,0 {
- compatible = "fsl,c293pcie-cpld";
- reg = <0x2 0x0 0x20>;
- };
-};
-
-&soc {
- i2c@3000 {
- eeprom@50 {
- compatible = "st,24c1024";
- reg = <0x50>;
- };
-
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <50000000>;
-
- partition@0 {
- /* 1MB for u-boot Bootloader Image */
- /* 1MB for Environment */
- reg = <0x0 0x00100000>;
- label = "SPI Flash U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 512KB for DTB Image */
- reg = <0x00100000 0x00080000>;
- label = "SPI Flash DTB Image";
- };
-
- partition@180000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00180000 0x00400000>;
- label = "SPI Flash Linux Kernel Image";
- };
-
- partition@580000 {
- /* 10.5MB for RFS Image */
- reg = <0x00580000 0x00a80000>;
- label = "SPI Flash RFS Image";
- };
- };
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <2 1 0 0>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x2>;
- };
- };
-
- enet0: ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
-/include/ "fsl/c293si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/b4420qds.dts b/arch/powerpc/boot/dts/fsl/b4420qds.dts
new file mode 100644
index 0000000..cd9203c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/b4420qds.dts
@@ -0,0 +1,50 @@
+/*
+ * B4420DS Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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/ "b4420si-pre.dtsi"
+/include/ "b4qds.dtsi"
+
+/ {
+ model = "fsl,B4420QDS";
+ compatible = "fsl,B4420QDS";
+
+ ifc: localbus@ffe124000 {
+ board-control@3,0 {
+ compatible = "fsl,b4420qds-fpga", "fsl,fpga-qixis";
+ };
+ };
+
+};
+
+/include/ "b4420si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
index 1ea8602..f996cce 100644
--- a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
@@ -89,7 +89,9 @@
compatible = "fsl,b4420-rcpm", "fsl,qoriq-rcpm-2.0";
};
- L2: l2-cache-controller@c20000 {
+ L2_1: l2-cache-controller@c20000 {
compatible = "fsl,b4420-l2-cache-controller";
+ reg = <0xc20000 0x40000>;
+ next-level-cache = <&cpc>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
index 338af7e..bc3bf93 100644
--- a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* B4420 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -54,8 +54,13 @@
dma0 = &dma0;
dma1 = &dma1;
sdhc = &sdhc;
- };
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ };
cpus {
#address-cells = <1>;
@@ -65,14 +70,14 @@
device_type = "cpu";
reg = <0 1>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
cpu1: PowerPC,e6500@2 {
device_type = "cpu";
reg = <2 3>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/b4860qds.dts b/arch/powerpc/boot/dts/fsl/b4860qds.dts
new file mode 100644
index 0000000..a8bc419
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/b4860qds.dts
@@ -0,0 +1,117 @@
+/*
+ * B4860DS Device Tree Source
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "b4860si-pre.dtsi"
+/include/ "b4qds.dtsi"
+
+/ {
+ model = "fsl,B4860QDS";
+ compatible = "fsl,B4860QDS";
+
+ aliases {
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xaui_slot1 = &phy_xaui_slot1;
+ phy_xaui_slot2 = &phy_xaui_slot2;
+ };
+
+ ifc: localbus@ffe124000 {
+ board-control@3,0 {
+ compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis";
+ };
+ };
+
+ soc@ffe000000 {
+ fman@400000 {
+ ethernet@e8000 {
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@ea000 {
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xaui_slot1>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&phy_xaui_slot2>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@fc000 {
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ status = "disabled";
+ };
+
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ status = "disabled";
+ };
+ };
+
+ mdio@fd000 {
+ phy_xaui_slot1: xaui-phy@slot1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x7>;
+ status = "disabled";
+ };
+
+ phy_xaui_slot2: xaui-phy@slot2 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x6>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+/include/ "b4860si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
index 9ba904b..8687198 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
@@ -1,7 +1,7 @@
/*
* B4860 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -51,14 +51,12 @@
#address-cells = <2>;
#size-cells = <2>;
cell-index = <1>;
- fsl,liodn-reg = <&guts 0x510>; /* RIO1LIODNR */
};
port2 {
#address-cells = <2>;
#size-cells = <2>;
cell-index = <2>;
- fsl,liodn-reg = <&guts 0x514>; /* RIO2LIODNR */
};
};
@@ -260,7 +258,27 @@
compatible = "fsl,b4860-rcpm", "fsl,qoriq-rcpm-2.0";
};
- L2: l2-cache-controller@c20000 {
+/include/ "qoriq-fman3-0-1g-4.dtsi"
+/include/ "qoriq-fman3-0-1g-5.dtsi"
+/include/ "qoriq-fman3-0-10g-0.dtsi"
+/include/ "qoriq-fman3-0-10g-1.dtsi"
+ fman@400000 {
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@ea000 {
+ };
+
+ enet6: ethernet@f0000 {
+ };
+
+ enet7: ethernet@f2000 {
+ };
+ };
+
+ L2_1: l2-cache-controller@c20000 {
compatible = "fsl,b4860-l2-cache-controller";
+ reg = <0xc20000 0x40000>;
+ next-level-cache = <&cpc>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
index 1948f73..8797ce1 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* B4860 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2012 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -54,6 +54,16 @@
dma0 = &dma0;
dma1 = &dma1;
sdhc = &sdhc;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ ethernet6 = &enet6;
+ ethernet7 = &enet7;
};
@@ -65,28 +75,28 @@
device_type = "cpu";
reg = <0 1>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
cpu1: PowerPC,e6500@2 {
device_type = "cpu";
reg = <2 3>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
cpu2: PowerPC,e6500@4 {
device_type = "cpu";
reg = <4 5>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
cpu3: PowerPC,e6500@6 {
device_type = "cpu";
reg = <6 7>;
clocks = <&mux0>;
- next-level-cache = <&L2>;
+ next-level-cache = <&L2_1>;
fsl,portid-mapping = <0x80000000>;
};
};
diff --git a/arch/powerpc/boot/dts/fsl/b4qds.dtsi b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
new file mode 100644
index 0000000..3785ef8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/b4qds.dtsi
@@ -0,0 +1,279 @@
+/*
+ * B4420DS Device Tree Source
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor, Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ model = "fsl,B4QDS";
+ compatible = "fsl,B4QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_sgmii_10 = &phy_sgmii_10;
+ phy_sgmii_11 = &phy_sgmii_11;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 10MB for Linux Kernel Image */
+ reg = <0x00200000 0x00A00000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@c00000 {
+ /* 500MB for Root file System Image */
+ reg = <0x00c00000 0x1F400000>;
+ label = "NAND RFS Image";
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,b4qds-fpga", "fsl,fpga-qixis";
+ reg = <3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01052000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ };
+ };
+
+ sdhc@114000 {
+ /*Disabled as there is no sdhc connector on B4420QDS board*/
+ status = "disabled";
+ };
+
+ i2c@118000 {
+ mux@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@50 {
+ compatible = "at24,24c64";
+ reg = <0x50>;
+ };
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@53 {
+ compatible = "at24,24c256";
+ reg = <0x53>;
+ };
+ eeprom@57 {
+ compatible = "at24,24c256";
+ reg = <0x57>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+ };
+ };
+
+ usb@210000 {
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_10>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_11>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_1c>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@fc000 {
+ phy_sgmii_10: ethernet-phy@10 {
+ reg = <0x10>;
+ };
+
+ phy_sgmii_11: ethernet-phy@11 {
+ reg = <0x11>;
+ };
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ status = "disabled";
+ };
+
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "b4si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
index 603910a..1b33f51 100644
--- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
@@ -1,7 +1,7 @@
/*
* B4420 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2012 - 2014 Freescale Semiconductor, Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -466,9 +466,37 @@
interrupts = <16 2 1 29>;
};
- L2: l2-cache-controller@c20000 {
- compatible = "fsl,b4-l2-cache-controller";
- reg = <0xc20000 0x1000>;
- next-level-cache = <&cpc>;
+/include/ "qoriq-fman3-0.dtsi"
+/include/ "qoriq-fman3-0-1g-0.dtsi"
+/include/ "qoriq-fman3-0-1g-1.dtsi"
+/include/ "qoriq-fman3-0-1g-2.dtsi"
+/include/ "qoriq-fman3-0-1g-3.dtsi"
+ fman@400000 {
+ interrupts = <96 2 0 0>, <16 2 1 30>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x80000>;
+ };
+
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ mdio@fc000 {
+ interrupts = <100 1 0 0>;
+ };
+
+ mdio@fd000 {
+ interrupts = <101 1 0 0>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
new file mode 100644
index 0000000..26366e6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
@@ -0,0 +1,34 @@
+/*
+ * BSC9131 RDB Device Tree Source
+ *
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "bsc9131si-pre.dtsi"
+
+/ {
+ model = "fsl,bsc9131rdb";
+ compatible = "fsl,bsc9131rdb";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_ifc: ifc: ifc@ff71e000 {
+ /* NAND Flash on board */
+ ranges = <0x0 0x0 0x0 0xff800000 0x00004000>;
+ reg = <0x0 0xff71e000 0x0 0x2000>;
+ };
+
+ board_soc: soc: soc@ff700000 {
+ ranges = <0x0 0x0 0xff700000 0x100000>;
+ };
+};
+
+/include/ "bsc9131rdb.dtsi"
+/include/ "bsc9131si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
new file mode 100644
index 0000000..53f8b95
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
@@ -0,0 +1,104 @@
+/*
+ * BSC9131 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&board_ifc {
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x0 0x0 0x4000>;
+
+ };
+};
+
+&board_soc {
+ /* BSC9131RDB does not have any device on i2c@3100 */
+ i2c@3100 {
+ status = "disabled";
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x3>;
+ };
+ };
+
+ sdhc@2e000 {
+ status = "disabled";
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xcccccccd>;
+ fsl,tmr-fiper1 = <999999995>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <249999999>;
+ };
+
+ enet0: ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dts b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts
new file mode 100644
index 0000000..56e6f13
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dts
@@ -0,0 +1,50 @@
+/*
+ * BSC9132 QDS Device Tree Source
+ *
+ * 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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "bsc9132si-pre.dtsi"
+
+/ {
+ model = "fsl,bsc9132qds";
+ compatible = "fsl,bsc9132qds";
+
+ memory {
+ device_type = "memory";
+ };
+
+ ifc: ifc@ff71e000 {
+ /* NOR, NAND Flash on board */
+ ranges = <0x0 0x0 0x0 0x88000000 0x08000000
+ 0x1 0x0 0x0 0xff800000 0x00010000>;
+ reg = <0x0 0xff71e000 0x0 0x2000>;
+ };
+
+ soc: soc@ff700000 {
+ ranges = <0x0 0x0 0xff700000 0x100000>;
+ };
+
+ pci0: pcie@ff70a000 {
+ reg = <0 0xff70a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x90000000 0 0x90000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xc0010000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x90000000
+ 0x2000000 0x0 0x90000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "bsc9132qds.dtsi"
+/include/ "bsc9132si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
new file mode 100644
index 0000000..fead484
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
@@ -0,0 +1,113 @@
+/*
+ * BSC9132 QDS Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&ifc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x1 0x0 0x4000>;
+ };
+};
+
+&soc {
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <30000000>;
+ };
+ };
+
+ i2c@3000 {
+ fpga: fpga@66 {
+ compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c";
+ reg = <0x66>;
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x1f>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xcccccccd>;
+ fsl,tmr-fiper1 = <999999995>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <249999999>;
+ };
+
+ enet0: ethernet@b0000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
index c723071..b5f0715 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi
@@ -40,6 +40,34 @@
interrupts = <16 2 0 0 20 2 0 0>;
};
+/* controller at 0xa000 */
+&pci0 {
+ compatible = "fsl,bsc9132-pcie", "fsl,qoriq-pcie-v2.2";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 255>;
+ interrupts = <16 2 0 0>;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 0 0>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x0 0x2 0x0 0x0
+ 0000 0x0 0x0 0x2 &mpic 0x1 0x2 0x0 0x0
+ 0000 0x0 0x0 0x3 &mpic 0x2 0x2 0x0 0x0
+ 0000 0x0 0x0 0x4 &mpic 0x3 0x2 0x0 0x0
+ >;
+ };
+};
+
&soc {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi
index 301a9db..90f7949 100644
--- a/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi
@@ -45,6 +45,7 @@
serial0 = &serial0;
ethernet0 = &enet0;
ethernet1 = &enet1;
+ pci0 = &pci0;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts
new file mode 100644
index 0000000..6670978
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts
@@ -0,0 +1,224 @@
+/*
+ * C293 PCIE Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "c293si-pre.dtsi"
+
+/ {
+ model = "fsl,C293PCIE";
+ compatible = "fsl,C293PCIE";
+
+ memory {
+ device_type = "memory";
+ };
+
+ ifc: ifc@fffe1e000 {
+ reg = <0xf 0xffe1e000 0 0x2000>;
+ ranges = <0x0 0x0 0xf 0xec000000 0x04000000
+ 0x1 0x0 0xf 0xff800000 0x00010000
+ 0x2 0x0 0xf 0xffdf0000 0x00010000>;
+
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+&ifc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x4000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* 1MB for DTB Image */
+ reg = <0x0 0x00100000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@100000 {
+ /* 8 MB for Linux Kernel Image */
+ reg = <0x00100000 0x00800000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@900000 {
+ /* 53MB for rootfs */
+ reg = <0x00900000 0x03500000>;
+ label = "NOR Rootfs Image";
+ };
+
+ partition@3e00000 {
+ /* 1MB for blob encrypted key */
+ reg = <0x03e00000 0x00100000>;
+ label = "NOR blob encrypted key";
+ };
+
+ partition@3f00000 {
+ /* 512KB for u-boot Bootloader Image and evn */
+ reg = <0x03f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x1 0x0 0x10000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 16MB for Linux Kernel Image */
+ reg = <0x00200000 0x01000000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@1200000 {
+ /* 4078MB for Root file System Image */
+ reg = <0x00600000 0xfee00000>;
+ label = "NAND RFS Image";
+ };
+ };
+
+ cpld@2,0 {
+ compatible = "fsl,c293pcie-cpld";
+ reg = <0x2 0x0 0x20>;
+ };
+};
+
+&soc {
+ i2c@3000 {
+ eeprom@50 {
+ compatible = "st,24c1024";
+ reg = <0x50>;
+ };
+
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partition@0 {
+ /* 1MB for u-boot Bootloader Image */
+ /* 1MB for Environment */
+ reg = <0x0 0x00100000>;
+ label = "SPI Flash U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 512KB for DTB Image */
+ reg = <0x00100000 0x00080000>;
+ label = "SPI Flash DTB Image";
+ };
+
+ partition@180000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00180000 0x00400000>;
+ label = "SPI Flash Linux Kernel Image";
+ };
+
+ partition@580000 {
+ /* 10.5MB for RFS Image */
+ reg = <0x00580000 0x00a80000>;
+ label = "SPI Flash RFS Image";
+ };
+ };
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <2 1 0 0>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x2>;
+ };
+ };
+
+ enet0: ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
+/include/ "c293si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/cyrus_p5020.dts b/arch/powerpc/boot/dts/fsl/cyrus_p5020.dts
new file mode 100644
index 0000000..c603390
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/cyrus_p5020.dts
@@ -0,0 +1,155 @@
+/*
+ * Cyrus 5020 Device Tree Source, based on p5020ds.dts
+ *
+ * Copyright 2015 Andy Fleming
+ *
+ * p5020ds.dts copyright:
+ * Copyright 2010 - 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/ "p5020si-pre.dtsi"
+
+/ {
+ model = "varisys,CYRUS";
+ compatible = "varisys,CYRUS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ };
+
+ i2c@118100 {
+ };
+
+ i2c@119100 {
+ rtc@6f {
+ compatible = "microchip,mcp7941x";
+ reg = <0x6f>;
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xffa00000 0x00040000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p5020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/ge_imp3a.dts b/arch/powerpc/boot/dts/fsl/ge_imp3a.dts
new file mode 100644
index 0000000..a2bb47f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/ge_imp3a.dts
@@ -0,0 +1,255 @@
+/*
+ * GE IMP3A Device Tree Source
+ *
+ * Copyright 2010-2011 GE Intelligent Platforms Embedded Systems, 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.
+ *
+ * Based on: P2020 DS Device Tree Source
+ * Copyright 2009 Freescale Semiconductor Inc.
+ */
+
+/include/ "p2020si-pre.dtsi"
+
+/ {
+ model = "GE_IMP3A";
+ compatible = "ge,imp3a";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fef05000 {
+ reg = <0 0xfef05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xff000000 0x01000000
+ 0x1 0x0 0x0 0xe0000000 0x08000000
+ 0x2 0x0 0x0 0xe8000000 0x08000000
+ 0x3 0x0 0x0 0xfc100000 0x00020000
+ 0x4 0x0 0x0 0xfc000000 0x00008000
+ 0x5 0x0 0x0 0xfc008000 0x00008000
+ 0x6 0x0 0x0 0xfee00000 0x00040000
+ 0x7 0x0 0x0 0xfee80000 0x00040000>;
+
+ /* nor@0,0 is a mirror of part of the memory in nor@1,0
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ge,imp3a-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1000000>;
+ read-only;
+ };
+ };
+ */
+
+ nor@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ge,imp3a-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
+
+ nvram@3,0 {
+ device_type = "nvram";
+ compatible = "simtek,stk14ca8";
+ reg = <0x3 0x0 0x20000>;
+ };
+
+ fpga@4,0 {
+ compatible = "ge,imp3a-fpga-regs";
+ reg = <0x4 0x0 0x20>;
+ };
+
+ gef_pic: pic@4,20 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ compatible = "ge,imp3a-fpga-pic", "gef,fpga-pic-1.00";
+ reg = <0x4 0x20 0x20>;
+ interrupts = <6 7 0 0>;
+ };
+
+ gef_gpio: gpio@4,400 {
+ #gpio-cells = <2>;
+ compatible = "ge,imp3a-gpio";
+ reg = <0x4 0x400 0x24>;
+ gpio-controller;
+ };
+
+ wdt@4,800 {
+ compatible = "ge,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x800 0x8>;
+ interrupts = <10 4>;
+ interrupt-parent = <&gef_pic>;
+ };
+
+ /* Second watchdog available, driver currently supports one.
+ wdt@4,808 {
+ compatible = "gef,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x808 0x8>;
+ interrupts = <9 4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ */
+
+ nand@6,0 {
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x6 0x0 0x40000>;
+ };
+
+ nand@7,0 {
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x7 0x0 0x40000>;
+ };
+ };
+
+ soc: soc@fef00000 {
+ ranges = <0x0 0 0xfef00000 0x100000>;
+
+ i2c@3000 {
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x51>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ dr_mode = "host";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0xc 0x4>;
+ reg = <0x1>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0xb 0x4>;
+ reg = <0x2>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26520 {
+ status = "disabled";
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "gmii";
+ };
+
+ enet2: ethernet@26000 {
+ status = "disabled";
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xfe020000 0x0 0x10000>;
+ reg = <0 0xfef08000 0 0x1000>;
+
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci1: pcie@fef09000 {
+ reg = <0 0xfef09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xfe010000 0x0 0x10000>;
+
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+
+ };
+
+ pci2: pcie@fef0a000 {
+ reg = <0 0xfef0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xfe000000 0x0 0x10000>;
+
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
+
+/include/ "p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts
new file mode 100644
index 0000000..0424fc2
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts
@@ -0,0 +1,216 @@
+/*
+ * GE PPC9A Device Tree Source
+ *
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
+ */
+
+/include/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "GEF_PPC9A";
+ compatible = "gef,ppc9a";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // set by uboot
+ };
+
+ lbc: localbus@fef05000 {
+ reg = <0xfef05000 0x1000>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe8000000 0x08000000 // Paged Flash 0
+ 2 0 0xe0000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00008000 // FPGA
+ 5 0 0xfc008000 0x00008000 // AFIX FPGA
+ 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
+ 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "gef,ppc9a-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
+
+ nvram@3,0 {
+ device_type = "nvram";
+ compatible = "simtek,stk14ca8";
+ reg = <0x3 0x0 0x20000>;
+ };
+
+ fpga@4,0 {
+ compatible = "gef,ppc9a-fpga-regs";
+ reg = <0x4 0x0 0x40>;
+ };
+
+ wdt@4,2000 {
+ compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ /* Second watchdog available, driver currently supports one.
+ wdt@4,2010 {
+ compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ */
+ gef_pic: pic@4,4000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
+ reg = <0x4 0x4000 0x20>;
+ interrupts = <0x8 0x9 0 0>;
+
+ };
+ gef_gpio: gpio@7,14000 {
+ #gpio-cells = <2>;
+ compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
+ reg = <0x7 0x14000 0x24>;
+ gpio-controller;
+ };
+ };
+
+ soc: soc@fef00000 {
+ ranges = <0x0 0xfef00000 0x00100000>;
+
+ i2c@3000 {
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x00000051>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@25000 {
+ status = "disabled";
+ };
+
+ mdio@25520 {
+ status = "disabled";
+ };
+
+ enet3: ethernet@27000 {
+ status = "disabled";
+ };
+
+ mdio@27520 {
+ status = "disabled";
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ reg = <0xfef08000 0x1000>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+ 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x40000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts
new file mode 100644
index 0000000..84b3d38
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts
@@ -0,0 +1,260 @@
+/*
+ * GE SBC310 Device Tree Source
+ *
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
+ */
+
+/include/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "GEF_SBC310";
+ compatible = "gef,sbc310";
+
+ aliases {
+ pci1 = &pci1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // set by uboot
+ };
+
+ lbc: localbus@fef05000 {
+ reg = <0xfef05000 0x1000>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe0000000 0x08000000 // Paged Flash 0
+ 2 0 0xe8000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00010000>; // FPGA
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "gef,sbc310-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x01000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x01000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "gef,sbc310-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
+
+ nvram@3,0 {
+ device_type = "nvram";
+ compatible = "simtek,stk14ca8";
+ reg = <0x3 0x0 0x20000>;
+ };
+
+ fpga@4,0 {
+ compatible = "gef,fpga-regs";
+ reg = <0x4 0x0 0x40>;
+ };
+
+ wdt@4,2000 {
+ compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+/*
+ wdt@4,2010 {
+ compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+*/
+ gef_pic: pic@4,4000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic";
+ reg = <0x4 0x4000 0x20>;
+ interrupts = <0x8 0x9 0 0>;
+
+ };
+ gef_gpio: gpio@4,8000 {
+ #gpio-cells = <2>;
+ compatible = "gef,sbc310-gpio";
+ reg = <0x4 0x8000 0x24>;
+ gpio-controller;
+ };
+ };
+
+ soc: soc@fef00000 {
+ ranges = <0x0 0xfef00000 0x00100000>;
+
+ i2c@3000 {
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x00000051>;
+ };
+ };
+
+ i2c@3100 {
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@25000 {
+ status = "disabled";
+ };
+
+ mdio@25520 {
+ status = "disabled";
+ };
+
+ enet3: ethernet@27000 {
+ status = "disabled";
+ };
+
+ mdio@27520 {
+ status = "disabled";
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ reg = <0xfef08000 0x1000>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+ 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
+ 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
+ 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
+ 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
+ >;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x40000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+
+ pci1: pcie@fef09000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xfef09000 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>;
+ clock-frequency = <100000000>;
+ interrupts = <0x19 0x2 0 0>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2
+ 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2
+ 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2
+ 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xc0000000
+ 0x02000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts
new file mode 100644
index 0000000..974446a
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts
@@ -0,0 +1,214 @@
+/*
+ * GE SBC610 Device Tree Source
+ *
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts
+ */
+
+/include/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "GEF_SBC610";
+ compatible = "gef,sbc610";
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // set by uboot
+ };
+
+ lbc: localbus@fef05000 {
+ reg = <0xfef05000 0x1000>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe8000000 0x08000000 // Paged Flash 0
+ 2 0 0xe0000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00008000 // FPGA
+ 5 0 0xfc008000 0x00008000 // AFIX FPGA
+ 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
+ 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "gef,sbc610-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "gef,sbc610-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
+
+ nvram@3,0 {
+ device_type = "nvram";
+ compatible = "simtek,stk14ca8";
+ reg = <0x3 0x0 0x20000>;
+ };
+
+ fpga@4,0 {
+ compatible = "gef,fpga-regs";
+ reg = <0x4 0x0 0x40>;
+ };
+
+ wdt@4,2000 {
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ /* Second watchdog available, driver currently supports one.
+ wdt@4,2010 {
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ */
+ gef_pic: pic@4,4000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "gef,fpga-pic";
+ reg = <0x4 0x4000 0x20>;
+ interrupts = <0x8 0x9 0 0>;
+
+ };
+ gef_gpio: gpio@7,14000 {
+ #gpio-cells = <2>;
+ compatible = "gef,sbc610-gpio";
+ reg = <0x7 0x14000 0x24>;
+ gpio-controller;
+ };
+ };
+
+ soc: soc@fef00000 {
+ ranges = <0x0 0xfef00000 0x00100000>;
+
+ i2c@3000 {
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x00000051>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "gmii";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@25000 {
+ status = "disabled";
+ };
+
+ mdio@25520 {
+ status = "disabled";
+ };
+
+ enet3: ethernet@27000 {
+ status = "disabled";
+ };
+
+ mdio@27520 {
+ status = "disabled";
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ reg = <0xfef08000 0x1000>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+ 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x40000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/kmcoge4.dts b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
new file mode 100644
index 0000000..2d4b64f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
@@ -0,0 +1,179 @@
+/*
+ * Keymile kmcoge4 Device Tree Source, based on the P2041RDB DTS
+ *
+ * (C) Copyright 2014
+ * Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p2041si-pre.dtsi"
+
+/ {
+ model = "keymile,kmcoge4";
+ compatible = "keymile,kmcoge4", "keymile,kmp204x";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl256s1", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <20000000>; /* input clock */
+ };
+
+ network_clock@1 {
+ compatible = "zarlink,zl30343";
+ reg = <1>;
+ spi-max-frequency = <8000000>;
+ };
+
+ flash@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,m25p32", "jedec,spi-nor";
+ reg = <2>;
+ spi-max-frequency = <15000000>;
+ };
+ };
+
+ i2c@119000 {
+ status = "disabled";
+ };
+
+ i2c@119100 {
+ status = "disabled";
+ };
+
+ usb0: usb@210000 {
+ status = "disabled";
+ };
+
+ usb1: usb@211000 {
+ status = "disabled";
+ };
+
+ sata@220000 {
+ status = "disabled";
+ };
+
+ sata@221000 {
+ status = "disabled";
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ status = "disabled";
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xffa00000 0x00040000 /* LB 0 */
+ 1 0 0xf 0xfb000000 0x00010000 /* LB 1 */
+ 2 0 0xf 0xd0000000 0x10000000 /* LB 2 */
+ 3 0 0xf 0xe0000000 0x10000000>; /* LB 3 */
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0 0 0x40000>;
+ };
+
+ board-control@1,0 {
+ compatible = "keymile,qriox";
+ reg = <1 0 0x80>;
+ };
+
+ chassis-mgmt@3,0 {
+ compatible = "keymile,bfticu";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <3 0 0x100>;
+ interrupt-parent = <&mpic>;
+ interrupts = <6 1 0 0>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ status = "disabled";
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p2041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds.dts b/arch/powerpc/boot/dts/fsl/mpc8536ds.dts
new file mode 100644
index 0000000..96cdce8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8536ds.dts
@@ -0,0 +1,109 @@
+/*
+ * MPC8536 DS Device Tree Source
+ *
+ * Copyright 2008, 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc8536si-pre.dtsi"
+
+/ {
+ model = "fsl,mpc8536ds";
+ compatible = "fsl,mpc8536ds";
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8536@0 {
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0 0>; // Filled by U-Boot
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+ 0x2 0x0 0x0 0xffa00000 0x00040000
+ 0x3 0x0 0x0 0xffdf0000 0x00008000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0 0xffe00000 0x100000>;
+ };
+
+ pci0: pci@ffe08000 {
+ reg = <0 0xffe08000 0 0x1000>;
+ ranges = <0x02000000 0 0x80000000 0 0x80000000 0 0x10000000
+ 0x01000000 0 0x00000000 0 0xffc00000 0 0x00010000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x11 J17 Slot 1 */
+ 0x8800 0 0 1 &mpic 1 1 0 0
+ 0x8800 0 0 2 &mpic 2 1 0 0
+ 0x8800 0 0 3 &mpic 3 1 0 0
+ 0x8800 0 0 4 &mpic 4 1 0 0>;
+ };
+
+ pci1: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x02000000 0 0x98000000 0 0x98000000 0 0x08000000
+ 0x01000000 0 0x00000000 0 0xffc20000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x98000000
+ 0x02000000 0 0x98000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x02000000 0 0x90000000 0 0x90000000 0 0x08000000
+ 0x01000000 0 0x00000000 0 0xffc10000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0x90000000
+ 0x02000000 0 0x90000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe0b000 {
+ reg = <0 0xffe0b000 0 0x1000>;
+ ranges = <0x02000000 0 0xa0000000 0 0xa0000000 0 0x20000000
+ 0x01000000 0 0x00000000 0 0xffc30000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00100000>;
+ };
+ };
+};
+
+/include/ "mpc8536si-post.dtsi"
+/include/ "mpc8536ds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi
new file mode 100644
index 0000000..a925fe4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi
@@ -0,0 +1,244 @@
+/*
+ * MPC8536DS Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ reg = <0x0 0x03000000>;
+ label = "ramdisk-nor";
+ };
+
+ partition@3000000 {
+ reg = <0x03000000 0x00e00000>;
+ label = "diagnostic-nor";
+ read-only;
+ };
+
+ partition@3e00000 {
+ reg = <0x03e00000 0x00200000>;
+ label = "dink-nor";
+ read-only;
+ };
+
+ partition@4000000 {
+ reg = <0x04000000 0x00400000>;
+ label = "kernel-nor";
+ };
+
+ partition@4400000 {
+ reg = <0x04400000 0x03b00000>;
+ label = "fs-nor";
+ };
+
+ partition@7f00000 {
+ reg = <0x07f00000 0x00080000>;
+ label = "dtb-nor";
+ };
+
+ partition@7f80000 {
+ reg = <0x07f80000 0x00080000>;
+ label = "u-boot-nor";
+ read-only;
+ };
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8536-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ reg = <0x0 0x02000000>;
+ label = "u-boot-nand";
+ read-only;
+ };
+
+ partition@2000000 {
+ reg = <0x02000000 0x10000000>;
+ label = "fs-nand";
+ };
+
+ partition@12000000 {
+ reg = <0x12000000 0x08000000>;
+ label = "ramdisk-nand";
+ };
+
+ partition@1a000000 {
+ reg = <0x1a000000 0x04000000>;
+ label = "kernel-nand";
+ };
+
+ partition@1e000000 {
+ reg = <0x1e000000 0x01000000>;
+ label = "dtb-nand";
+ };
+
+ partition@1f000000 {
+ reg = <0x1f000000 0x21000000>;
+ label = "empty-nand";
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,mpc8536ds-fpga-pixis";
+ reg = <0x3 0x0 0x8000>;
+ };
+};
+
+&board_soc {
+ i2c@3100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0 0x1 0 0>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ flash@1 {
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <1>;
+ spi-max-frequency = <40000000>;
+ };
+ flash@2 {
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <2>;
+ spi-max-frequency = <40000000>;
+ };
+ flash@3 {
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <3>;
+ spi-max-frequency = <40000000>;
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ usb@23000 {
+ phy_type = "ulpi";
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <10 0x1 0 0>;
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <10 0x1 0 0>;
+ reg = <1>;
+ };
+ sgmii_phy0: sgmii-phy@0 {
+ interrupts = <6 1 0 0>;
+ reg = <0x1d>;
+ };
+ sgmii_phy1: sgmii-phy@1 {
+ interrupts = <6 1 0 0>;
+ reg = <0x1c>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@26000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x26520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ usb@2b000 {
+ dr_mode = "peripheral";
+ phy_type = "ulpi";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts
new file mode 100644
index 0000000..38d326c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts
@@ -0,0 +1,109 @@
+/*
+ * MPC8536DS Device Tree Source (36-bit address map)
+ *
+ * Copyright 2008-2009, 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc8536si-pre.dtsi"
+
+/ {
+ model = "fsl,mpc8536ds";
+ compatible = "fsl,mpc8536ds";
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8536@0 {
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0 0>; // Filled by U-Boot
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
+ 0x2 0x0 0xf 0xffa00000 0x00040000
+ 0x3 0x0 0xf 0xffdf0000 0x00008000>;
+ };
+
+ board_soc: soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pci@fffe08000 {
+ reg = <0xf 0xffe08000 0 0x1000>;
+ ranges = <0x02000000 0 0xf0000000 0xc 0x00000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xffc00000 0 0x00010000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x11 J17 Slot 1 */
+ 0x8800 0 0 1 &mpic 1 1 0 0
+ 0x8800 0 0 2 &mpic 2 1 0 0
+ 0x8800 0 0 3 &mpic 3 1 0 0
+ 0x8800 0 0 4 &mpic 4 1 0 0>;
+ };
+
+ pci1: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x02000000 0 0xf8000000 0xc 0x18000000 0 0x08000000
+ 0x01000000 0 0x00000000 0xf 0xffc20000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xf8000000
+ 0x02000000 0 0xf8000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x02000000 0 0xf8000000 0xc 0x10000000 0 0x08000000
+ 0x01000000 0 0x00000000 0xf 0xffc10000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xf8000000
+ 0x02000000 0 0xf8000000
+ 0 0x08000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@fffe0b000 {
+ reg = <0xf 0xffe0b000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xffc30000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00100000>;
+ };
+ };
+};
+
+/include/ "mpc8536si-post.dtsi"
+/include/ "mpc8536ds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
index c8b2daa..4193570 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
@@ -172,7 +172,7 @@
/* mark compat w/8572 to get some erratum treatment */
gpio-controller@f000 {
- compatible = "fsl,mpc8572-gpio", "fsl,pq3-gpio";
+ compatible = "fsl,mpc8572-gpio";
};
sata@18000 {
diff --git a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
new file mode 100644
index 0000000..e6d0b16
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
@@ -0,0 +1,359 @@
+/*
+ * MPC8540 ADS Device Tree Source
+ *
+ * Copyright 2006, 2008 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/ "e500v2_power_isa.dtsi"
+
+/ {
+ model = "MPC8540ADS";
+ compatible = "MPC8540ADS", "MPC85xxADS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8540@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x8000000>; // 128M at 0x0
+ };
+
+ soc8540@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <0>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8540-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8540-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8540-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8540-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8540-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8540-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <2>;
+ device_type = "network";
+ model = "FEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <41 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4500 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4600 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+ };
+
+ pci0: pci@e0008000 {
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x02 */
+ 0x1000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x1000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x1000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x1000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 0x03 */
+ 0x1800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x1800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x1800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x1800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x04 */
+ 0x2000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x2000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x2000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x2000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x05 */
+ 0x2800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x2800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x2800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x2800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x0c */
+ 0x6000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x6000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x6000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x6000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 0x0d */
+ 0x6800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x6800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x6800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x6800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x0e */
+ 0x7000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x7000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x7000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x7000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x0f */
+ 0x7800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x7800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x7800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x7800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x12 */
+ 0x9000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 0x13 */
+ 0x9800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x9800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x9800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x9800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x14 */
+ 0xa000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0xa000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0xa000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0xa000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0x1 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0008000 0x1000>;
+ compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci";
+ device_type = "pci";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
new file mode 100644
index 0000000..9fa2c73
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
@@ -0,0 +1,379 @@
+/*
+ * MPC8541 CDS Device Tree Source
+ *
+ * Copyright 2006, 2008 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/ "e500v2_power_isa.dtsi"
+
+/ {
+ model = "MPC8541CDS";
+ compatible = "MPC8541CDS", "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8541@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x8000000>; // 128M at 0x0
+ };
+
+ soc8541@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <0>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8541-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8541-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8541-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8541-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8541-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8541-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8541-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4500 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4600 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x7e>;
+ fsl,descriptor-types-mask = <0x01010ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ cpm@919c0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8541-cpm", "fsl,cpm2";
+ reg = <0x919c0 0x30>;
+ ranges;
+
+ muram@80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x80000 0x10000>;
+
+ data@0 {
+ compatible = "fsl,cpm-muram-data";
+ reg = <0x0 0x2000 0x9000 0x1000>;
+ };
+ };
+
+ brg@919f0 {
+ compatible = "fsl,mpc8541-brg",
+ "fsl,cpm2-brg",
+ "fsl,cpm-brg";
+ reg = <0x919f0 0x10 0x915f0 0x10>;
+ };
+
+ cpmpic: pic@90c00 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <46 2>;
+ interrupt-parent = <&mpic>;
+ reg = <0x90c00 0x80>;
+ compatible = "fsl,mpc8541-cpm-pic", "fsl,cpm2-pic";
+ };
+ };
+ };
+
+ pci0: pci@e0008000 {
+ interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x11 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1
+ 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0008000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+
+ i8259@19000 {
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <0x19000 0x0 0x0 0x0 0x1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <1>;
+ interrupt-parent = <&pci0>;
+ };
+ };
+
+ pci1: pci@e0009000 {
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0009000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8544ds.dts b/arch/powerpc/boot/dts/fsl/mpc8544ds.dts
new file mode 100644
index 0000000..5a6e4686
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8544ds.dts
@@ -0,0 +1,107 @@
+/*
+ * MPC8544 DS Device Tree Source
+ *
+ * Copyright 2007, 2008 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/ "mpc8544si-pre.dtsi"
+
+/ {
+ model = "MPC8544DS";
+ compatible = "MPC8544DS", "MPC85xxDS";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0 0>; // Filled by U-Boot
+ };
+
+ board_lbc: lbc: localbus@e0005000 {
+ reg = <0 0xe0005000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xff800000 0x800000>;
+ };
+
+ board_soc: soc: soc8544@e0000000 {
+ ranges = <0x0 0x0 0xe0000000 0x100000>;
+ };
+
+ pci0: pci@e0008000 {
+ reg = <0 0xe0008000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xe1000000 0x0 0x10000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x11 J17 Slot 1 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1 0 0
+ 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1 0 0
+ 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1 0 0
+ 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1 0 0
+
+ /* IDSEL 0x12 J16 Slot 2 */
+
+ 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1 0 0
+ 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1 0 0
+ 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
+ 0x9000 0x0 0x0 0x4 &mpic 0x1 0x1 0 0>;
+ };
+
+ pci1: pcie@e0009000 {
+ reg = <0x0 0xe0009000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xe1010000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ reg = <0x0 0xe000a000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xe1020000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ board_pci3: pci3: pcie@e000b000 {
+ reg = <0x0 0xe000b000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xb0000000 0 0xb0000000 0x0 0x100000
+ 0x1000000 0x0 0x00000000 0 0xb0100000 0x0 0x100000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xb0000000
+ 0x2000000 0x0 0xb0000000
+ 0x0 0x100000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/*
+ * mpc8544ds.dtsi must be last to ensure board_pci3 overrides pci3 settings
+ * for interrupt-map & interrupt-map-mask
+ */
+
+/include/ "mpc8544si-post.dtsi"
+/include/ "mpc8544ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544ds.dtsi
index 47d986b..47d986b 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8544ds.dtsi
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548cds.dtsi
index 3bc7d47..3bc7d47 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8548cds.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts b/arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts
new file mode 100644
index 0000000..e4620bb
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts
@@ -0,0 +1,86 @@
+/*
+ * MPC8548 CDS Device Tree Source (32-bit address map)
+ *
+ * Copyright 2006, 2008, 2011-2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc8548si-pre.dtsi"
+
+/ {
+ model = "MPC8548CDS";
+ compatible = "MPC8548CDS", "MPC85xxCDS";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0x0 0x8000000>; // 128M at 0x0
+ };
+
+ board_lbc: lbc: localbus@e0005000 {
+ reg = <0 0xe0005000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xff000000 0x01000000
+ 0x1 0x0 0x0 0xf8004000 0x00001000>;
+
+ };
+
+ board_soc: soc: soc8548@e0000000 {
+ ranges = <0 0x0 0xe0000000 0x100000>;
+ };
+
+ board_pci0: pci0: pci@e0008000 {
+ reg = <0 0xe0008000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xe2000000 0x0 0x800000>;
+ clock-frequency = <66666666>;
+ };
+
+ pci1: pci@e0009000 {
+ reg = <0 0xe0009000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x90000000 0 0x90000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xe2800000 0x0 0x800000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 0 0
+ 0xa800 0x0 0x0 0x2 &mpic 0x1 0x1 0 0
+ 0xa800 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
+ 0xa800 0x0 0x0 0x4 &mpic 0x3 0x1 0 0>;
+ };
+
+ pci2: pcie@e000a000 {
+ reg = <0 0xe000a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xe3000000 0x0 0x100000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ rio: rapidio@e00c0000 {
+ reg = <0x0 0xe00c0000 0x0 0x20000>;
+ port1 {
+ ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
+ };
+ };
+};
+
+/*
+ * mpc8548cds.dtsi must be last to ensure board_pci0 overrides pci0 settings
+ * for interrupt-map & interrupt-map-mask.
+ */
+
+/include/ "mpc8548si-post.dtsi"
+/include/ "mpc8548cds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts
new file mode 100644
index 0000000..bca7c09
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts
@@ -0,0 +1,86 @@
+/*
+ * MPC8548 CDS Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc8548si-pre.dtsi"
+
+/ {
+ model = "MPC8548CDS";
+ compatible = "MPC8548CDS", "MPC85xxCDS";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0x0 0x8000000>; // 128M at 0x0
+ };
+
+ board_lbc: lbc: localbus@fe0005000 {
+ reg = <0xf 0xe0005000 0 0x1000>;
+
+ ranges = <0x0 0x0 0xf 0xff000000 0x01000000
+ 0x1 0x0 0xf 0xf8004000 0x00001000>;
+
+ };
+
+ board_soc: soc: soc8548@fe0000000 {
+ ranges = <0 0xf 0xe0000000 0x100000>;
+ };
+
+ board_pci0: pci0: pci@fe0008000 {
+ reg = <0xf 0xe0008000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0xf 0xe2000000 0x0 0x800000>;
+ clock-frequency = <66666666>;
+ };
+
+ pci1: pci@fe0009000 {
+ reg = <0xf 0xe0009000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0xf 0xe2800000 0x0 0x800000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 0 0
+ 0xa800 0x0 0x0 0x2 &mpic 0x1 0x1 0 0
+ 0xa800 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
+ 0xa800 0x0 0x0 0x4 &mpic 0x3 0x1 0 0>;
+ };
+
+ pci2: pcie@fe000a000 {
+ reg = <0xf 0xe000a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xe3000000 0x0 0x100000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ rio: rapidio@fe00c0000 {
+ reg = <0xf 0xe00c0000 0x0 0x20000>;
+ port1 {
+ ranges = <0x0 0x0 0xc 0x40000000 0x0 0x20000000>;
+ };
+ };
+};
+
+/*
+ * mpc8548cds.dtsi must be last to ensure board_pci0 overrides pci0 settings
+ * for interrupt-map & interrupt-map-mask.
+ */
+
+/include/ "mpc8548si-post.dtsi"
+/include/ "mpc8548cds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
new file mode 100644
index 0000000..272f08c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
@@ -0,0 +1,379 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006, 2008 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/ "e500v2_power_isa.dtsi"
+
+/ {
+ model = "MPC8555CDS";
+ compatible = "MPC8555CDS", "MPC85xxCDS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8555@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ bus-frequency = <0>; // 166 MHz
+ clock-frequency = <0>; // 825 MHz, from uboot
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x8000000>; // 128M at 0x0
+ };
+
+ soc8555@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <0>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8555-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8555-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8555-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8555-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4500 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550";
+ reg = <0x4600 0x100>; // reg base, size
+ clock-frequency = <0>; // should we fill in in uboot?
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x7e>;
+ fsl,descriptor-types-mask = <0x01010ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ cpm@919c0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8555-cpm", "fsl,cpm2";
+ reg = <0x919c0 0x30>;
+ ranges;
+
+ muram@80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x80000 0x10000>;
+
+ data@0 {
+ compatible = "fsl,cpm-muram-data";
+ reg = <0x0 0x2000 0x9000 0x1000>;
+ };
+ };
+
+ brg@919f0 {
+ compatible = "fsl,mpc8555-brg",
+ "fsl,cpm2-brg",
+ "fsl,cpm-brg";
+ reg = <0x919f0 0x10 0x915f0 0x10>;
+ };
+
+ cpmpic: pic@90c00 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <46 2>;
+ interrupt-parent = <&mpic>;
+ reg = <0x90c00 0x80>;
+ compatible = "fsl,mpc8555-cpm-pic", "fsl,cpm2-pic";
+ };
+ };
+ };
+
+ pci0: pci@e0008000 {
+ interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x10 */
+ 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x11 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x12 (Slot 1) */
+ 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x13 (Slot 2) */
+ 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1
+
+ /* IDSEL 0x14 (Slot 3) */
+ 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1
+ 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x15 (Slot 4) */
+ 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* Bus 1 (Tundra Bridge) */
+ /* IDSEL 0x12 (ISA bridge) */
+ 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0008000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+
+ i8259@19000 {
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ reg = <0x19000 0x0 0x0 0x0 0x1>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <1>;
+ interrupt-parent = <&pci0>;
+ };
+ };
+
+ pci1: pci@e0009000 {
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x15 */
+ 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0009000 0x1000>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
new file mode 100644
index 0000000..7a822b0
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
@@ -0,0 +1,392 @@
+/*
+ * MPC8560 ADS Device Tree Source
+ *
+ * Copyright 2006, 2008 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/ "e500v2_power_isa.dtsi"
+
+/ {
+ model = "MPC8560ADS";
+ compatible = "MPC8560ADS", "MPC85xxADS";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8560@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <82500000>;
+ bus-frequency = <330000000>;
+ clock-frequency = <825000000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x10000000>;
+ };
+
+ soc8560@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xe0000000 0x100000>;
+ bus-frequency = <330000000>;
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <8>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8540-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8540-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8560-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8560-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8560-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8560-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8560-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "TSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ cpm@919c0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8560-cpm", "fsl,cpm2";
+ reg = <0x919c0 0x30>;
+ ranges;
+
+ muram@80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x80000 0x10000>;
+
+ data@0 {
+ compatible = "fsl,cpm-muram-data";
+ reg = <0x0 0x4000 0x9000 0x2000>;
+ };
+ };
+
+ brg@919f0 {
+ compatible = "fsl,mpc8560-brg",
+ "fsl,cpm2-brg",
+ "fsl,cpm-brg";
+ reg = <0x919f0 0x10 0x915f0 0x10>;
+ clock-frequency = <165000000>;
+ };
+
+ cpmpic: pic@90c00 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <46 2>;
+ interrupt-parent = <&mpic>;
+ reg = <0x90c00 0x80>;
+ compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic";
+ };
+
+ serial0: serial@91a00 {
+ device_type = "serial";
+ compatible = "fsl,mpc8560-scc-uart",
+ "fsl,cpm2-scc-uart";
+ reg = <0x91a00 0x20 0x88000 0x100>;
+ fsl,cpm-brg = <1>;
+ fsl,cpm-command = <0x800000>;
+ current-speed = <115200>;
+ interrupts = <40 8>;
+ interrupt-parent = <&cpmpic>;
+ };
+
+ serial1: serial@91a20 {
+ device_type = "serial";
+ compatible = "fsl,mpc8560-scc-uart",
+ "fsl,cpm2-scc-uart";
+ reg = <0x91a20 0x20 0x88100 0x100>;
+ fsl,cpm-brg = <2>;
+ fsl,cpm-command = <0x4a00000>;
+ current-speed = <115200>;
+ interrupts = <41 8>;
+ interrupt-parent = <&cpmpic>;
+ };
+
+ enet2: ethernet@91320 {
+ device_type = "network";
+ compatible = "fsl,mpc8560-fcc-enet",
+ "fsl,cpm2-fcc-enet";
+ reg = <0x91320 0x20 0x88500 0x100 0x913b0 0x1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ fsl,cpm-command = <0x16200300>;
+ interrupts = <33 8>;
+ interrupt-parent = <&cpmpic>;
+ phy-handle = <&phy2>;
+ };
+
+ enet3: ethernet@91340 {
+ device_type = "network";
+ compatible = "fsl,mpc8560-fcc-enet",
+ "fsl,cpm2-fcc-enet";
+ reg = <0x91340 0x20 0x88600 0x100 0x913d0 0x1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ fsl,cpm-command = <0x1a400300>;
+ interrupts = <34 8>;
+ interrupt-parent = <&cpmpic>;
+ phy-handle = <&phy3>;
+ };
+ };
+ };
+
+ pci0: pci@e0008000 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci";
+ device_type = "pci";
+ reg = <0xe0008000 0x1000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+
+ /* IDSEL 0x2 */
+ 0x1000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x1000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x1000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x1000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 0x3 */
+ 0x1800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x1800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x1800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x1800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 0x4 */
+ 0x2000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x2000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x2000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x2000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x5 */
+ 0x2800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x2800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x2800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x2800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 12 */
+ 0x6000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x6000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x6000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x6000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 13 */
+ 0x6800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x6800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x6800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x6800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 14*/
+ 0x7000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x7000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x7000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x7000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 15 */
+ 0x7800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x7800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x7800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x7800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 18 */
+ 0x9000 0x0 0x0 0x1 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x2 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x3 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1
+
+ /* IDSEL 19 */
+ 0x9800 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0x9800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x9800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x9800 0x0 0x0 0x4 &mpic 0x3 0x1
+
+ /* IDSEL 20 */
+ 0xa000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0xa000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0xa000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0xa000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 21 */
+ 0xa800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0xa800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0xa800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0xa800 0x0 0x0 0x4 &mpic 0x1 0x1>;
+
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0 0>;
+ ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x0 0xe2000000 0x0 0x1000000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8568mds.dts b/arch/powerpc/boot/dts/fsl/mpc8568mds.dts
new file mode 100644
index 0000000..01706a3
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8568mds.dts
@@ -0,0 +1,314 @@
+/*
+ * MPC8568E MDS Device Tree Source
+ *
+ * Copyright 2007, 2008 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/ "mpc8568si-pre.dtsi"
+
+/ {
+ model = "MPC8568EMDS";
+ compatible = "MPC8568EMDS", "MPC85xxMDS";
+
+ aliases {
+ pci0 = &pci0;
+ pci1 = &pci1;
+ rapidio0 = &rio;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x0>;
+ };
+
+ lbc: localbus@e0005000 {
+ reg = <0x0 0xe0005000 0x0 0x1000>;
+ ranges = <0x0 0x0 0xfe000000 0x02000000
+ 0x1 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0xf0000000 0x04000000
+ 0x4 0x0 0xf8008000 0x00008000
+ 0x5 0x0 0xf8010000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8568mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+
+ bcsr5: gpio-controller@11 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8568mds-bcsr-gpio";
+ reg = <0x5 0x1>;
+ gpio-controller;
+ };
+ };
+
+ pib@4,0 {
+ compatible = "fsl,mpc8568mds-pib";
+ reg = <4 0 0x8000>;
+ };
+
+ pib@5,0 {
+ compatible = "fsl,mpc8568mds-pib";
+ reg = <5 0 0x8000>;
+ };
+ };
+
+ soc: soc8568@e0000000 {
+ ranges = <0x0 0x0 0xe0000000 0x100000>;
+
+ i2c-sleep-nexus {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <3 1 0 0>;
+ };
+ };
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy2>;
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@7 {
+ interrupts = <1 1 0 0>;
+ reg = <0x7>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupts = <1 1 0 0>;
+ reg = <0x2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupts = <2 1 0 0>;
+ reg = <0x3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy3>;
+ sleep = <&pmc 0x00000040>;
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ par_io@e0100 {
+ num-ports = <7>;
+
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x4 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
+ 0x4 0x9 0x1 0x0 0x2 0x0 /* TxD1 */
+ 0x4 0x8 0x1 0x0 0x2 0x0 /* TxD2 */
+ 0x4 0x7 0x1 0x0 0x2 0x0 /* TxD3 */
+ 0x4 0x17 0x1 0x0 0x2 0x0 /* TxD4 */
+ 0x4 0x16 0x1 0x0 0x2 0x0 /* TxD5 */
+ 0x4 0x15 0x1 0x0 0x2 0x0 /* TxD6 */
+ 0x4 0x14 0x1 0x0 0x2 0x0 /* TxD7 */
+ 0x4 0xf 0x2 0x0 0x2 0x0 /* RxD0 */
+ 0x4 0xe 0x2 0x0 0x2 0x0 /* RxD1 */
+ 0x4 0xd 0x2 0x0 0x2 0x0 /* RxD2 */
+ 0x4 0xc 0x2 0x0 0x2 0x0 /* RxD3 */
+ 0x4 0x1d 0x2 0x0 0x2 0x0 /* RxD4 */
+ 0x4 0x1c 0x2 0x0 0x2 0x0 /* RxD5 */
+ 0x4 0x1b 0x2 0x0 0x2 0x0 /* RxD6 */
+ 0x4 0x1a 0x2 0x0 0x2 0x0 /* RxD7 */
+ 0x4 0xb 0x1 0x0 0x2 0x0 /* TX_EN */
+ 0x4 0x18 0x1 0x0 0x2 0x0 /* TX_ER */
+ 0x4 0x10 0x2 0x0 0x2 0x0 /* RX_DV */
+ 0x4 0x1e 0x2 0x0 0x2 0x0 /* RX_ER */
+ 0x4 0x11 0x2 0x0 0x2 0x0 /* RX_CLK */
+ 0x4 0x13 0x1 0x0 0x2 0x0 /* GTX_CLK */
+ 0x1 0x1f 0x2 0x0 0x3 0x0>; /* GTX125 */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x5 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
+ 0x5 0x9 0x1 0x0 0x2 0x0 /* TxD1 */
+ 0x5 0x8 0x1 0x0 0x2 0x0 /* TxD2 */
+ 0x5 0x7 0x1 0x0 0x2 0x0 /* TxD3 */
+ 0x5 0x17 0x1 0x0 0x2 0x0 /* TxD4 */
+ 0x5 0x16 0x1 0x0 0x2 0x0 /* TxD5 */
+ 0x5 0x15 0x1 0x0 0x2 0x0 /* TxD6 */
+ 0x5 0x14 0x1 0x0 0x2 0x0 /* TxD7 */
+ 0x5 0xf 0x2 0x0 0x2 0x0 /* RxD0 */
+ 0x5 0xe 0x2 0x0 0x2 0x0 /* RxD1 */
+ 0x5 0xd 0x2 0x0 0x2 0x0 /* RxD2 */
+ 0x5 0xc 0x2 0x0 0x2 0x0 /* RxD3 */
+ 0x5 0x1d 0x2 0x0 0x2 0x0 /* RxD4 */
+ 0x5 0x1c 0x2 0x0 0x2 0x0 /* RxD5 */
+ 0x5 0x1b 0x2 0x0 0x2 0x0 /* RxD6 */
+ 0x5 0x1a 0x2 0x0 0x2 0x0 /* RxD7 */
+ 0x5 0xb 0x1 0x0 0x2 0x0 /* TX_EN */
+ 0x5 0x18 0x1 0x0 0x2 0x0 /* TX_ER */
+ 0x5 0x10 0x2 0x0 0x2 0x0 /* RX_DV */
+ 0x5 0x1e 0x2 0x0 0x2 0x0 /* RX_ER */
+ 0x5 0x11 0x2 0x0 0x2 0x0 /* RX_CLK */
+ 0x5 0x13 0x1 0x0 0x2 0x0 /* GTX_CLK */
+ 0x1 0x1f 0x2 0x0 0x3 0x0 /* GTX125 */
+ 0x4 0x6 0x3 0x0 0x2 0x0 /* MDIO */
+ 0x4 0x5 0x1 0x0 0x2 0x0>; /* MDC */
+ };
+ };
+ };
+
+ qe: qe@e0080000 {
+ ranges = <0x0 0x0 0xe0080000 0x40000>;
+ reg = <0x0 0xe0080000 0x0 0x480>;
+
+ spi@4c0 {
+ mode = "cpu";
+ };
+
+ spi@500 {
+ mode = "cpu";
+ };
+
+ enet2: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk16";
+ pio-handle = <&pio1>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet3: ucc@3000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk16";
+ pio-handle = <&pio2>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ /* These are the same PHYs as on
+ * gianfar's MDIO bus */
+ qe_phy0: ethernet-phy@07 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1 0 0>;
+ reg = <0x7>;
+ };
+ qe_phy1: ethernet-phy@01 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ qe_phy2: ethernet-phy@02 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1 0 0>;
+ reg = <0x2>;
+ };
+ qe_phy3: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1 0 0>;
+ reg = <0x3>;
+ };
+ };
+ };
+
+ pci0: pci@e0008000 {
+ reg = <0x0 0xe0008000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0x0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xe2000000 0x0 0x800000>;
+ clock-frequency = <66666666>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x12 AD18 */
+ 0x9000 0x0 0x0 0x1 &mpic 0x5 0x1 0 0
+ 0x9000 0x0 0x0 0x2 &mpic 0x6 0x1 0 0
+ 0x9000 0x0 0x0 0x3 &mpic 0x7 0x1 0 0
+ 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1 0 0
+
+ /* IDSEL 0x13 AD19 */
+ 0x9800 0x0 0x0 0x1 &mpic 0x6 0x1 0 0
+ 0x9800 0x0 0x0 0x2 &mpic 0x7 0x1 0 0
+ 0x9800 0x0 0x0 0x3 &mpic 0x4 0x1 0 0
+ 0x9800 0x0 0x0 0x4 &mpic 0x5 0x1 0 0>;
+ };
+
+ /* PCI Express */
+ pci1: pcie@e000a000 {
+ ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0x0 0xe2800000 0x0 0x800000>;
+ reg = <0x0 0xe000a000 0x0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x800000>;
+ };
+ };
+
+ rio: rapidio@e00c00000 {
+ reg = <0x0 0xe00c0000 0x0 0x20000>;
+ port1 {
+ ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ green {
+ gpios = <&bcsr5 1 0>;
+ };
+
+ amber {
+ gpios = <&bcsr5 2 0>;
+ };
+
+ red {
+ gpios = <&bcsr5 3 0>;
+ };
+ };
+};
+
+/include/ "mpc8568si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8569mds.dts b/arch/powerpc/boot/dts/fsl/mpc8569mds.dts
new file mode 100644
index 0000000..a95ff7d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8569mds.dts
@@ -0,0 +1,447 @@
+/*
+ * MPC8569E MDS Device Tree Source
+ *
+ * Copyright (C) 2009 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/ "mpc8569si-pre.dtsi"
+
+/ {
+ model = "MPC8569EMDS";
+ compatible = "fsl,MPC8569EMDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet5 = &enet5;
+ ethernet7 = &enet7;
+ rapidio0 = &rio;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@e0005000 {
+ reg = <0x0 0xe0005000 0x0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xfe000000 0x02000000
+ 0x1 0x0 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0x0 0xf0000000 0x04000000
+ 0x3 0x0 0x0 0xfc000000 0x00008000
+ 0x4 0x0 0x0 0xf8008000 0x00008000
+ 0x5 0x0 0x0 0xf8010000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x02000000>;
+ bank-width = <1>;
+ device-width = <1>;
+ partition@0 {
+ label = "ramdisk";
+ reg = <0x00000000 0x01c00000>;
+ };
+ partition@1c00000 {
+ label = "kernel";
+ reg = <0x01c00000 0x002e0000>;
+ };
+ partiton@1ee0000 {
+ label = "dtb";
+ reg = <0x01ee0000 0x00020000>;
+ };
+ partition@1f00000 {
+ label = "firmware";
+ reg = <0x01f00000 0x00080000>;
+ read-only;
+ };
+ partition@1f80000 {
+ label = "u-boot";
+ reg = <0x01f80000 0x00080000>;
+ read-only;
+ };
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8569mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+
+ bcsr17: gpio-controller@11 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569mds-bcsr-gpio";
+ reg = <0x11 0x1>;
+ gpio-controller;
+ };
+ };
+
+ nand@3,0 {
+ compatible = "fsl,mpc8569-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <3 0 0x8000>;
+ };
+
+ pib@4,0 {
+ compatible = "fsl,mpc8569mds-pib";
+ reg = <4 0 0x8000>;
+ };
+
+ pib@5,0 {
+ compatible = "fsl,mpc8569mds-pib";
+ reg = <5 0 0x8000>;
+ };
+ };
+
+ soc: soc@e0000000 {
+ ranges = <0x0 0x0 0xe0000000 0x100000>;
+
+ i2c-sleep-nexus {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <3 1 0 0>;
+ };
+ };
+ };
+
+ sdhc@2e000 {
+ status = "disabled";
+ sdhci,1-bit-only;
+ bus-width = <1>;
+ };
+
+ par_io@e0100 {
+ num-ports = <7>;
+
+ qe_pio_e: gpio-controller@80 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569-qe-pario-bank",
+ "fsl,mpc8323-qe-pario-bank";
+ reg = <0x80 0x18>;
+ gpio-controller;
+ };
+
+ qe_pio_f: gpio-controller@a0 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569-qe-pario-bank",
+ "fsl,mpc8323-qe-pario-bank";
+ reg = <0xa0 0x18>;
+ gpio-controller;
+ };
+
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
+ 0x0 0x0 0x1 0x0 0x3 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x1 0x1 0x0 0x3 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0x2 0x1 0x0 0x1 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0x3 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x3 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0x7 0x2 0x0 0x1 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0x9 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x4 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xc 0x2 0x0 0x3 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x2 0x8 0x2 0x0 0x1 0x0 /* ENET1_GRXCLK */
+ 0x2 0x14 0x1 0x0 0x2 0x0>; /* ENET1_GTXCLK */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
+ 0x0 0xe 0x1 0x0 0x2 0x0 /* ENET2_TXD0_SER2_TXD0 */
+ 0x0 0xf 0x1 0x0 0x2 0x0 /* ENET2_TXD1_SER2_TXD1 */
+ 0x0 0x10 0x1 0x0 0x1 0x0 /* ENET2_TXD2_SER2_TXD2 */
+ 0x0 0x11 0x1 0x0 0x1 0x0 /* ENET2_TXD3_SER2_TXD3 */
+ 0x0 0x14 0x2 0x0 0x2 0x0 /* ENET2_RXD0_SER2_RXD0 */
+ 0x0 0x15 0x2 0x0 0x1 0x0 /* ENET2_RXD1_SER2_RXD1 */
+ 0x0 0x16 0x2 0x0 0x1 0x0 /* ENET2_RXD2_SER2_RXD2 */
+ 0x0 0x17 0x2 0x0 0x1 0x0 /* ENET2_RXD3_SER2_RXD3 */
+ 0x0 0x12 0x1 0x0 0x2 0x0 /* ENET2_TX_EN_SER2_RTS_B */
+ 0x0 0x1a 0x2 0x0 0x3 0x0 /* ENET2_RX_DV_SER2_CTS_B */
+ 0x2 0x3 0x2 0x0 0x1 0x0 /* ENET2_GRXCLK */
+ 0x2 0x2 0x1 0x0 0x2 0x0>; /* ENET2_GTXCLK */
+ };
+
+ pio3: ucc_pin@03 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
+ 0x0 0x1d 0x1 0x0 0x2 0x0 /* ENET3_TXD0_SER3_TXD0 */
+ 0x0 0x1e 0x1 0x0 0x3 0x0 /* ENET3_TXD1_SER3_TXD1 */
+ 0x0 0x1f 0x1 0x0 0x2 0x0 /* ENET3_TXD2_SER3_TXD2 */
+ 0x1 0x0 0x1 0x0 0x3 0x0 /* ENET3_TXD3_SER3_TXD3 */
+ 0x1 0x3 0x2 0x0 0x3 0x0 /* ENET3_RXD0_SER3_RXD0 */
+ 0x1 0x4 0x2 0x0 0x1 0x0 /* ENET3_RXD1_SER3_RXD1 */
+ 0x1 0x5 0x2 0x0 0x2 0x0 /* ENET3_RXD2_SER3_RXD2 */
+ 0x1 0x6 0x2 0x0 0x3 0x0 /* ENET3_RXD3_SER3_RXD3 */
+ 0x1 0x1 0x1 0x0 0x1 0x0 /* ENET3_TX_EN_SER3_RTS_B */
+ 0x1 0x9 0x2 0x0 0x3 0x0 /* ENET3_RX_DV_SER3_CTS_B */
+ 0x2 0x9 0x2 0x0 0x2 0x0 /* ENET3_GRXCLK */
+ 0x2 0x19 0x1 0x0 0x2 0x0>; /* ENET3_GTXCLK */
+ };
+
+ pio4: ucc_pin@04 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
+ 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
+ 0x1 0xc 0x1 0x0 0x2 0x0 /* ENET4_TXD0_SER4_TXD0 */
+ 0x1 0xd 0x1 0x0 0x2 0x0 /* ENET4_TXD1_SER4_TXD1 */
+ 0x1 0xe 0x1 0x0 0x1 0x0 /* ENET4_TXD2_SER4_TXD2 */
+ 0x1 0xf 0x1 0x0 0x2 0x0 /* ENET4_TXD3_SER4_TXD3 */
+ 0x1 0x12 0x2 0x0 0x2 0x0 /* ENET4_RXD0_SER4_RXD0 */
+ 0x1 0x13 0x2 0x0 0x1 0x0 /* ENET4_RXD1_SER4_RXD1 */
+ 0x1 0x14 0x2 0x0 0x1 0x0 /* ENET4_RXD2_SER4_RXD2 */
+ 0x1 0x15 0x2 0x0 0x2 0x0 /* ENET4_RXD3_SER4_RXD3 */
+ 0x1 0x10 0x1 0x0 0x2 0x0 /* ENET4_TX_EN_SER4_RTS_B */
+ 0x1 0x18 0x2 0x0 0x3 0x0 /* ENET4_RX_DV_SER4_CTS_B */
+ 0x2 0x11 0x2 0x0 0x2 0x0 /* ENET4_GRXCLK */
+ 0x2 0x18 0x1 0x0 0x2 0x0>; /* ENET4_GTXCLK */
+ };
+ };
+ };
+
+ qe: qe@e0080000 {
+ ranges = <0x0 0x0 0xe0080000 0x40000>;
+ reg = <0x0 0xe0080000 0x0 0x480>;
+
+ spi@4c0 {
+ gpios = <&qe_pio_e 30 0>;
+ mode = "cpu-qe";
+
+ serial-flash@0 {
+ compatible = "stm,m25p40";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+ };
+ };
+
+ spi@500 {
+ mode = "cpu";
+ };
+
+ usb@6c0 {
+ fsl,fullspeed-clock = "clk5";
+ fsl,lowspeed-clock = "brg10";
+ gpios = <&qe_pio_f 3 0 /* USBOE */
+ &qe_pio_f 4 0 /* USBTP */
+ &qe_pio_f 5 0 /* USBTN */
+ &qe_pio_f 6 0 /* USBRP */
+ &qe_pio_f 8 0 /* USBRN */
+ &bcsr17 1 0 /* SPEED */
+ &bcsr17 2 0>; /* POWER */
+ };
+
+ enet0: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk12";
+ pio-handle = <&pio1>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ qe_phy0: ethernet-phy@07 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1 0 0>;
+ reg = <0x7>;
+ };
+ qe_phy1: ethernet-phy@01 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ qe_phy2: ethernet-phy@02 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1 0 0>;
+ reg = <0x2>;
+ };
+ qe_phy3: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1 0 0>;
+ reg = <0x3>;
+ };
+ qe_phy5: ethernet-phy@04 {
+ reg = <0x04>;
+ };
+ qe_phy7: ethernet-phy@06 {
+ reg = <0x6>;
+ };
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ mdio@3520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3520 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ tbi6: tbi-phy@15 {
+ reg = <0x15>;
+ device_type = "tbi-phy";
+ };
+ };
+ mdio@3720 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3720 0x38>;
+ compatible = "fsl,ucc-mdio";
+ tbi8: tbi-phy@17 {
+ reg = <0x17>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ucc@2200 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk12";
+ pio-handle = <&pio3>;
+ tbi-handle = <&tbi3>;
+ phy-handle = <&qe_phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@2320 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2320 0x18>;
+ compatible = "fsl,ucc-mdio";
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ucc@3000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk17";
+ pio-handle = <&pio2>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3120 0x18>;
+ compatible = "fsl,ucc-mdio";
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ucc@3200 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk17";
+ pio-handle = <&pio4>;
+ tbi-handle = <&tbi4>;
+ phy-handle = <&qe_phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@3320 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3320 0x18>;
+ compatible = "fsl,ucc-mdio";
+ tbi4: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet5: ucc@3400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "none";
+ tbi-handle = <&tbi6>;
+ phy-handle = <&qe_phy5>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet7: ucc@3600 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "none";
+ tbi-handle = <&tbi8>;
+ phy-handle = <&qe_phy7>;
+ phy-connection-type = "sgmii";
+ };
+ };
+
+ /* PCI Express */
+ pci1: pcie@e000a000 {
+ reg = <0x0 0xe000a000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000
+ 0x1000000 0x0 0x00000000 0 0xe2800000 0x0 0x00800000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x10000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x800000>;
+ };
+ };
+
+ rio: rapidio@e00c00000 {
+ reg = <0x0 0xe00c0000 0x0 0x20000>;
+ port1 {
+ ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
+ };
+ port2 {
+ status = "disabled";
+ };
+ };
+};
+
+/include/ "mpc8569si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8572ds.dts b/arch/powerpc/boot/dts/fsl/mpc8572ds.dts
new file mode 100644
index 0000000..8ee5b24
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8572ds.dts
@@ -0,0 +1,90 @@
+/*
+ * MPC8572 DS Device Tree Source
+ *
+ * Copyright 2007-2009 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/ "mpc8572si-pre.dtsi"
+
+/ {
+ model = "fsl,MPC8572DS";
+ compatible = "fsl,MPC8572DS";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+ 0x1 0x0 0x0 0xe0000000 0x08000000
+ 0x2 0x0 0x0 0xffa00000 0x00040000
+ 0x3 0x0 0x0 0xffdf0000 0x00008000
+ 0x4 0x0 0x0 0xffa40000 0x00040000
+ 0x5 0x0 0x0 0xffa80000 0x00040000
+ 0x6 0x0 0x0 0xffac0000 0x00040000>;
+ };
+
+ board_soc: soc: soc8572@ffe00000 {
+ ranges = <0x0 0 0xffe00000 0x100000>;
+ };
+
+ board_pci0: pci0: pcie@ffe08000 {
+ reg = <0 0xffe08000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci1: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci2: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
+
+/*
+ * mpc8572ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
+ * for interrupt-map & interrupt-map-mask
+ */
+
+/include/ "mpc8572si-post.dtsi"
+/include/ "mpc8572ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi
index 357490b..357490b 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts
new file mode 100644
index 0000000..5c48b46
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts
@@ -0,0 +1,90 @@
+/*
+ * MPC8572DS Device Tree Source (36-bit address map)
+ *
+ * Copyright 2007-2009 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/ "mpc8572si-pre.dtsi"
+
+/ {
+ model = "fsl,MPC8572DS";
+ compatible = "fsl,MPC8572DS";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
+ 0x1 0x0 0xf 0xe0000000 0x08000000
+ 0x2 0x0 0xf 0xffa00000 0x00040000
+ 0x3 0x0 0xf 0xffdf0000 0x00008000
+ 0x4 0x0 0xf 0xffa40000 0x00040000
+ 0x5 0x0 0xf 0xffa80000 0x00040000
+ 0x6 0x0 0xf 0xffac0000 0x00040000>;
+ };
+
+ board_soc: soc: soc8572@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ board_pci0: pci0: pcie@fffe08000 {
+ reg = <0xf 0xffe08000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci1: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci2: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
+
+/*
+ * mpc8572ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
+ * for interrupt-map & interrupt-map-mask
+ */
+
+/include/ "mpc8572si-post.dtsi"
+/include/ "mpc8572ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core0.dts
index ef9ef56..ef9ef56 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core0.dts
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core1.dts
index 24564ee..24564ee 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
+++ b/arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core1.dts
diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
index d44e25a..49294cf 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
@@ -162,7 +162,7 @@
/include/ "pq3-dma-1.dtsi"
/include/ "pq3-gpio-0.dtsi"
gpio-controller@f000 {
- compatible = "fsl,mpc8572-gpio", "fsl,pq3-gpio";
+ compatible = "fsl,mpc8572-gpio";
};
L2: l2-cache-controller@20000 {
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts
new file mode 100644
index 0000000..554001f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts
@@ -0,0 +1,420 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2006 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/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "MPC8641HPCN";
+ compatible = "fsl,mpc8641hpcn";
+
+ aliases {
+ pci1 = &pci1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; // 1G at 0x0
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0xffe05000 0x1000>;
+
+ ranges = <0 0 0xef800000 0x00800000
+ 2 0 0xffdf8000 0x00008000
+ 3 0 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x00300000>;
+ };
+ partition@300000 {
+ label = "firmware b";
+ reg = <0x00300000 0x00100000>;
+ read-only;
+ };
+ partition@400000 {
+ label = "fs";
+ reg = <0x00400000 0x00300000>;
+ };
+ partition@700000 {
+ label = "firmware a";
+ reg = <0x00700000 0x00100000>;
+ read-only;
+ };
+ };
+ };
+
+ soc: soc8641@ffe00000 {
+ ranges = <0x00000000 0xffe00000 0x00100000>;
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <10 1 0 0>;
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <10 1 0 0>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupts = <10 1 0 0>;
+ reg = <2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupts = <10 1 0 0>;
+ reg = <3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@27000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@27520 {
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ rmu: rmu@d3000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,srio-rmu";
+ reg = <0xd3000 0x500>;
+ ranges = <0x0 0xd3000 0x500>;
+
+ message-unit@0 {
+ compatible = "fsl,srio-msg-unit";
+ reg = <0x0 0x100>;
+ interrupts = <
+ 53 2 0 0 /* msg1_tx_irq */
+ 54 2 0 0>;/* msg1_rx_irq */
+ };
+ message-unit@100 {
+ compatible = "fsl,srio-msg-unit";
+ reg = <0x100 0x100>;
+ interrupts = <
+ 55 2 0 0 /* msg2_tx_irq */
+ 56 2 0 0>;/* msg2_rx_irq */
+ };
+ doorbell-unit@400 {
+ compatible = "fsl,srio-dbell-unit";
+ reg = <0x400 0x80>;
+ interrupts = <
+ 49 2 0 0 /* bell_outb_irq */
+ 50 2 0 0>;/* bell_inb_irq */
+ };
+ port-write-unit@4e0 {
+ compatible = "fsl,srio-port-write-unit";
+ reg = <0x4e0 0x20>;
+ interrupts = <48 2 0 0>;
+ };
+ };
+ };
+
+ pci0: pcie@ffe08000 {
+ reg = <0xffe08000 0x1000>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 0x8800 0 0 1 &mpic 2 1
+ 0x8800 0 0 2 &mpic 3 1
+ 0x8800 0 0 3 &mpic 4 1
+ 0x8800 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 0x8900 0 0 1 &mpic 2 1
+ 0x8900 0 0 2 &mpic 3 1
+ 0x8900 0 0 3 &mpic 4 1
+ 0x8900 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 0x8a00 0 0 1 &mpic 2 1
+ 0x8a00 0 0 2 &mpic 3 1
+ 0x8a00 0 0 3 &mpic 4 1
+ 0x8a00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 0x8b00 0 0 1 &mpic 2 1
+ 0x8b00 0 0 2 &mpic 3 1
+ 0x8b00 0 0 3 &mpic 4 1
+ 0x8b00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 0x8c00 0 0 1 &mpic 2 1
+ 0x8c00 0 0 2 &mpic 3 1
+ 0x8c00 0 0 3 &mpic 4 1
+ 0x8c00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 0x8d00 0 0 1 &mpic 2 1
+ 0x8d00 0 0 2 &mpic 3 1
+ 0x8d00 0 0 3 &mpic 4 1
+ 0x8d00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 0x8e00 0 0 1 &mpic 2 1
+ 0x8e00 0 0 2 &mpic 3 1
+ 0x8e00 0 0 3 &mpic 4 1
+ 0x8e00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 0x8f00 0 0 1 &mpic 2 1
+ 0x8f00 0 0 2 &mpic 3 1
+ 0x8f00 0 0 3 &mpic 4 1
+ 0x8f00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 0x9000 0 0 1 &mpic 3 1
+ 0x9000 0 0 2 &mpic 4 1
+ 0x9000 0 0 3 &mpic 1 1
+ 0x9000 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 0x9100 0 0 1 &mpic 3 1
+ 0x9100 0 0 2 &mpic 4 1
+ 0x9100 0 0 3 &mpic 1 1
+ 0x9100 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 0x9200 0 0 1 &mpic 3 1
+ 0x9200 0 0 2 &mpic 4 1
+ 0x9200 0 0 3 &mpic 1 1
+ 0x9200 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 0x9300 0 0 1 &mpic 3 1
+ 0x9300 0 0 2 &mpic 4 1
+ 0x9300 0 0 3 &mpic 1 1
+ 0x9300 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 0x9400 0 0 1 &mpic 3 1
+ 0x9400 0 0 2 &mpic 4 1
+ 0x9400 0 0 3 &mpic 1 1
+ 0x9400 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 0x9500 0 0 1 &mpic 3 1
+ 0x9500 0 0 2 &mpic 4 1
+ 0x9500 0 0 3 &mpic 1 1
+ 0x9500 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 0x9600 0 0 1 &mpic 3 1
+ 0x9600 0 0 2 &mpic 4 1
+ 0x9600 0 0 3 &mpic 1 1
+ 0x9600 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 0x9700 0 0 1 &mpic 3 1
+ 0x9700 0 0 2 &mpic 4 1
+ 0x9700 0 0 3 &mpic 1 1
+ 0x9700 0 0 4 &mpic 2 1
+
+ // IDSEL 0x1c USB
+ 0xe000 0 0 1 &i8259 12 2
+ 0xe100 0 0 2 &i8259 9 2
+ 0xe200 0 0 3 &i8259 10 2
+ 0xe300 0 0 4 &i8259 11 2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0 0 1 &i8259 6 2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0 0 1 &i8259 7 2
+ 0xf100 0 0 1 &i8259 7 2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0 0 1 &i8259 14 2
+ 0xf900 0 0 1 &i8259 5 2
+ >;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ uli1575@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x20000000
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ isa@1e {
+ device_type = "isa";
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0 0 0 0>;
+ ranges = <1 0 0x01000000 0 0
+ 0x00001000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <1 0x20 2
+ 1 0xa0 2
+ 1 0x4d0 2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <9 2 0 0>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <1 0x60 1 1 0x64 1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent = <&i8259>;
+
+ keyboard@0 {
+ reg = <0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible =
+ "pnpPNP,b00";
+ reg = <1 0x70 2>;
+ };
+
+ gpio@400 {
+ reg = <1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci1: pcie@ffe09000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xffe09000 0x1000>;
+ bus-range = <0 0xff>;
+ ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>;
+ clock-frequency = <100000000>;
+ interrupts = <25 2 0 0>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0x0000 0 0 1 &mpic 4 1
+ 0x0000 0 0 2 &mpic 5 1
+ 0x0000 0 0 3 &mpic 6 1
+ 0x0000 0 0 4 &mpic 7 1
+ >;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xa0000000
+ 0x02000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ };
+ };
+/*
+ * Only one of Rapid IO or PCI can be present due to HW limitations and
+ * due to the fact that the 2 now share address space in the new memory
+ * map. The most likely case is that we have PCI, so comment out the
+ * rapidio node. Leave it here for reference.
+
+ rapidio@ffec0000 {
+ reg = <0xffec0000 0x11000>;
+ compatible = "fsl,srio";
+ interrupts = <48 2 0 0>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ fsl,srio-rmu-handle = <&rmu>;
+ ranges;
+
+ port1 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ cell-index = <1>;
+ ranges = <0 0 0x80000000 0 0x20000000>;
+ };
+ };
+*/
+
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts
new file mode 100644
index 0000000..fec5867
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts
@@ -0,0 +1,363 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2008-2009 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/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "MPC8641HPCN";
+ compatible = "fsl,mpc8641hpcn";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ pci1 = &pci1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0x0f 0xffe05000 0x0 0x1000>;
+
+ ranges = <0 0 0xf 0xef800000 0x00800000
+ 2 0 0xf 0xffdf8000 0x00008000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x00300000>;
+ };
+ partition@300000 {
+ label = "firmware b";
+ reg = <0x00300000 0x00100000>;
+ read-only;
+ };
+ partition@400000 {
+ label = "fs";
+ reg = <0x00400000 0x00300000>;
+ };
+ partition@700000 {
+ label = "firmware a";
+ reg = <0x00700000 0x00100000>;
+ read-only;
+ };
+ };
+ };
+
+ soc: soc8641@fffe00000 {
+ ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <10 1 0 0>;
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <10 1 0 0>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupts = <10 1 0 0>;
+ reg = <2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupts = <10 1 0 0>;
+ reg = <3>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@27000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@27520 {
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ pci0: pcie@fffe08000 {
+ reg = <0x0f 0xffe08000 0x0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
+ interrupt-map-mask = <0xff00 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 0x8800 0 0 1 &mpic 2 1
+ 0x8800 0 0 2 &mpic 3 1
+ 0x8800 0 0 3 &mpic 4 1
+ 0x8800 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 0x8900 0 0 1 &mpic 2 1
+ 0x8900 0 0 2 &mpic 3 1
+ 0x8900 0 0 3 &mpic 4 1
+ 0x8900 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 0x8a00 0 0 1 &mpic 2 1
+ 0x8a00 0 0 2 &mpic 3 1
+ 0x8a00 0 0 3 &mpic 4 1
+ 0x8a00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 0x8b00 0 0 1 &mpic 2 1
+ 0x8b00 0 0 2 &mpic 3 1
+ 0x8b00 0 0 3 &mpic 4 1
+ 0x8b00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 0x8c00 0 0 1 &mpic 2 1
+ 0x8c00 0 0 2 &mpic 3 1
+ 0x8c00 0 0 3 &mpic 4 1
+ 0x8c00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 0x8d00 0 0 1 &mpic 2 1
+ 0x8d00 0 0 2 &mpic 3 1
+ 0x8d00 0 0 3 &mpic 4 1
+ 0x8d00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 0x8e00 0 0 1 &mpic 2 1
+ 0x8e00 0 0 2 &mpic 3 1
+ 0x8e00 0 0 3 &mpic 4 1
+ 0x8e00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 0x8f00 0 0 1 &mpic 2 1
+ 0x8f00 0 0 2 &mpic 3 1
+ 0x8f00 0 0 3 &mpic 4 1
+ 0x8f00 0 0 4 &mpic 1 1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 0x9000 0 0 1 &mpic 3 1
+ 0x9000 0 0 2 &mpic 4 1
+ 0x9000 0 0 3 &mpic 1 1
+ 0x9000 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 0x9100 0 0 1 &mpic 3 1
+ 0x9100 0 0 2 &mpic 4 1
+ 0x9100 0 0 3 &mpic 1 1
+ 0x9100 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 0x9200 0 0 1 &mpic 3 1
+ 0x9200 0 0 2 &mpic 4 1
+ 0x9200 0 0 3 &mpic 1 1
+ 0x9200 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 0x9300 0 0 1 &mpic 3 1
+ 0x9300 0 0 2 &mpic 4 1
+ 0x9300 0 0 3 &mpic 1 1
+ 0x9300 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 0x9400 0 0 1 &mpic 3 1
+ 0x9400 0 0 2 &mpic 4 1
+ 0x9400 0 0 3 &mpic 1 1
+ 0x9400 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 0x9500 0 0 1 &mpic 3 1
+ 0x9500 0 0 2 &mpic 4 1
+ 0x9500 0 0 3 &mpic 1 1
+ 0x9500 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 0x9600 0 0 1 &mpic 3 1
+ 0x9600 0 0 2 &mpic 4 1
+ 0x9600 0 0 3 &mpic 1 1
+ 0x9600 0 0 4 &mpic 2 1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 0x9700 0 0 1 &mpic 3 1
+ 0x9700 0 0 2 &mpic 4 1
+ 0x9700 0 0 3 &mpic 1 1
+ 0x9700 0 0 4 &mpic 2 1
+
+ // IDSEL 0x1c USB
+ 0xe000 0 0 1 &i8259 12 2
+ 0xe100 0 0 2 &i8259 9 2
+ 0xe200 0 0 3 &i8259 10 2
+ 0xe300 0 0 4 &i8259 11 2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0 0 1 &i8259 6 2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0 0 1 &i8259 7 2
+ 0xf100 0 0 1 &i8259 7 2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0 0 1 &i8259 14 2
+ 0xf900 0 0 1 &i8259 5 2
+ >;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ uli1575@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ isa@1e {
+ device_type = "isa";
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0 0 0 0>;
+ ranges = <1 0 0x01000000 0 0
+ 0x00001000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <1 0x20 2
+ 1 0xa0 2
+ 1 0x4d0 2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <9 2 0 0>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <1 0x60 1 1 0x64 1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent = <&i8259>;
+
+ keyboard@0 {
+ reg = <0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible =
+ "pnpPNP,b00";
+ reg = <1 0x70 2>;
+ };
+
+ gpio@400 {
+ reg = <1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci1: pcie@fffe09000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0x0f 0xffe09000 0x0 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
+ clock-frequency = <100000000>;
+ interrupts = <25 2 0 0>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0x0000 0 0 1 &mpic 4 1
+ 0x0000 0 0 2 &mpic 5 1
+ 0x0000 0 0 3 &mpic 6 1
+ 0x0000 0 0 4 &mpic 7 1
+ >;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xe0000000
+ 0x02000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00010000>;
+ };
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi
new file mode 100644
index 0000000..70889d8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi
@@ -0,0 +1,120 @@
+/*
+ * MPC8641 Silicon/SoC Device Tree Source (post include)
+ *
+ * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+&lbc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-localbus", "simple-bus";
+ interrupts = <19 2 0 0>;
+};
+
+&soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,mpc8641-soc", "simple-bus";
+ bus-frequency = <0>;
+
+ mcm-law@0 {
+ compatible = "fsl,mcm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <10>;
+ };
+
+ mcm@1000 {
+ compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+ reg = <0x1000 0x1000>;
+ interrupts = <17 2 0 0>;
+ };
+
+/include/ "pq3-i2c-0.dtsi"
+/include/ "pq3-i2c-1.dtsi"
+/include/ "pq3-duart-0.dtsi"
+ serial@4600 {
+ interrupts = <28 2 0 0>;
+ };
+/include/ "pq3-dma-0.dtsi"
+ dma@21300 {
+ compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+ };
+ dma-channel@0 {
+ compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel";
+ };
+
+/include/ "pq3-etsec1-0.dtsi"
+ ethernet@24000 {
+ model = "TSEC";
+ };
+/include/ "pq3-etsec1-1.dtsi"
+ ethernet@25000 {
+ model = "TSEC";
+ };
+/include/ "pq3-etsec1-2.dtsi"
+ ethernet@26000 {
+ model = "TSEC";
+ };
+/include/ "pq3-etsec1-3.dtsi"
+ ethernet@27000 {
+ model = "TSEC";
+ };
+
+/include/ "qoriq-mpic.dtsi"
+ msi@41600 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ };
+ msi@41800 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ };
+ msi@41a00 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ };
+
+ global-utilities@e0000 {
+ compatible = "fsl,mpc8641-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+};
+
+&pci0 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <100000000>;
+ interrupts = <24 2 0 0>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi
new file mode 100644
index 0000000..9e03328
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi
@@ -0,0 +1,58 @@
+/*
+ * MPC8641 Silicon/SoC Device Tree Source (pre include)
+ *
+ * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8641@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-size = <32768>;
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+
+ PowerPC,8641@1 {
+ device_type = "cpu";
+ reg = <1>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-size = <32768>;
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mvme2500.dts b/arch/powerpc/boot/dts/fsl/mvme2500.dts
new file mode 100644
index 0000000..69559e97
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mvme2500.dts
@@ -0,0 +1,280 @@
+/*
+ * Device tree source for the Emerson/Artesyn MVME2500
+ *
+ * Copyright 2014 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 on: P2020 DS Device Tree Source
+ * Copyright 2009 Freescale Semiconductor Inc.
+ */
+
+/include/ "p2020si-pre.dtsi"
+
+/ {
+ model = "MVME2500";
+ compatible = "artesyn,MVME2500";
+
+ aliases {
+ serial2 = &serial2;
+ serial3 = &serial3;
+ serial4 = &serial4;
+ serial5 = &serial5;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0 0xffe00000 0x100000>;
+
+ i2c@3000 {
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ interrupts = <8 1 0 0>;
+ };
+
+ eeprom@54 {
+ compatible = "atmel,24c64";
+ reg = <0x54>;
+ };
+
+ eeprom@52 {
+ compatible = "atmel,24c512";
+ reg = <0x52>;
+ };
+
+ eeprom@53 {
+ compatible = "atmel,24c512";
+ reg = <0x53>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+
+ };
+
+ spi0: spi@7000 {
+ fsl,espi-num-chipselects = <2>;
+
+ flash@0 {
+ compatible = "atmel,at25df641", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+ flash@1 {
+ compatible = "atmel,at25df641", "jedec,spi-nor";
+ reg = <1>;
+ spi-max-frequency = <10000000>;
+ };
+ };
+
+ usb@22000 {
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy1: ethernet-phy@1 {
+ compatible = "brcm,bcm54616S";
+ interrupts = <6 1 0 0>;
+ reg = <0x1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ compatible = "brcm,bcm54616S";
+ interrupts = <6 1 0 0>;
+ reg = <0x2>;
+ };
+
+ phy3: ethernet-phy@3 {
+ compatible = "brcm,bcm54616S";
+ interrupts = <5 1 0 0>;
+ reg = <0x3>;
+ };
+
+ phy7: ethernet-phy@7 {
+ compatible = "brcm,bcm54616S";
+ interrupts = <7 1 0 0>;
+ reg = <0x7>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy7>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xfff00000 0x00080000
+ 0x1 0x0 0x0 0xffc40000 0x00010000
+ 0x2 0x0 0x0 0xffc50000 0x00010000
+ 0x3 0x0 0x0 0xffc60000 0x00010000
+ 0x4 0x0 0x0 0xffc70000 0x00010000
+ 0x6 0x0 0x0 0xffc80000 0x00010000
+ 0x5 0x0 0x0 0xffdf0000 0x00008000>;
+
+ serial2: serial@1,0 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x1 0x0 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <11 2 0 0>;
+ };
+
+ serial3: serial@2,0 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x2 0x0 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <1 2 0 0>;
+ };
+
+ serial4: serial@3,0 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x3 0x0 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <2 2 0 0>;
+ };
+
+ serial5: serial@4,0 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4 0x0 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <3 2 0 0>;
+ };
+
+ mram@0,0 {
+ compatible = "everspin,mram", "mtd-ram";
+ reg = <0x0 0x0 0x80000>;
+ bank-width = <2>;
+ };
+
+ board-control@5,0 {
+ compatible = "artesyn,mvme2500-fpga";
+ reg = <0x5 0x0 0x01000>;
+ };
+
+ cpld@6,0 {
+ compatible = "artesyn,mvme2500-cpld";
+ reg = <0x6 0x0 0x10000>;
+ interrupts = <9 1 0 0>;
+ };
+ };
+
+ pci0: pcie@ffe08000 {
+ reg = <0 0xffe08000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci1: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+
+ };
+
+ pci2: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
+
+/include/ "p2020si-post.dtsi"
+
+/ {
+ soc@ffe00000 {
+ serial@4600 {
+ status = "disabled";
+ };
+
+ i2c@3100 {
+ status = "disabled";
+ };
+
+ sdhc@2e000 {
+ compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+ non-removable;
+ };
+
+ };
+
+};
diff --git a/arch/powerpc/boot/dts/fsl/oca4080.dts b/arch/powerpc/boot/dts/fsl/oca4080.dts
new file mode 100644
index 0000000..17bc6f3
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/oca4080.dts
@@ -0,0 +1,145 @@
+/*
+ * OCA4080 Device Tree Source
+ *
+ * Copyright 2014 Prodrive Technologies B.V.
+ *
+ * Based on:
+ * P4080DS Device Tree Source
+ * Copyright 2009-2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p4080si-pre.dtsi"
+
+/ {
+ model = "fsl,OCA4080";
+ compatible = "fsl,OCA4080";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ i2c@118000 {
+ status = "disabled";
+ };
+
+ i2c@118100 {
+ status = "disabled";
+ };
+
+ i2c@119000 {
+ status = "disabled";
+ };
+
+ i2c@119100 {
+ status = "disabled";
+ };
+
+ usb0: usb@210000 {
+ status = "disabled";
+ };
+
+ usb1: usb@211000 {
+ status = "disabled";
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xef800000 0x800000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ status = "disabled";
+ };
+
+ pci1: pcie@ffe201000 {
+ status = "disabled";
+ };
+
+ pci2: pcie@ffe202000 {
+ status = "disabled";
+ };
+};
+
+/include/ "p4080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts
new file mode 100644
index 0000000..e4ab53c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts
@@ -0,0 +1,23 @@
+/*
+ * P1010 RDB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB";
+ compatible = "fsl,P1010RDB";
+
+ /include/ "p1010rdb_32b.dtsi"
+};
+
+/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pa.dtsi"
+/include/ "p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pa.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb-pa.dtsi
index 434fb2d..434fb2d 100644
--- a/arch/powerpc/boot/dts/p1010rdb-pa.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pa.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts
new file mode 100644
index 0000000..03bd76c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts
@@ -0,0 +1,46 @@
+/*
+ * P1010 RDB Device Tree Source (36-bit address map)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB";
+ compatible = "fsl,P1010RDB";
+
+ /include/ "p1010rdb_36b.dtsi"
+};
+
+/include/ "p1010rdb.dtsi"
+/include/ "p1010rdb-pa.dtsi"
+/include/ "p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
new file mode 100644
index 0000000..37681fd
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
@@ -0,0 +1,35 @@
+/*
+ * P1010 RDB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB-PB";
+ compatible = "fsl,P1010RDB-PB";
+
+ /include/ "p1010rdb_32b.dtsi"
+};
+
+/include/ "p1010rdb.dtsi"
+
+&phy0 {
+ interrupts = <0 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <1 1 0 0>;
+};
+
+/include/ "p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts b/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
new file mode 100644
index 0000000..4cf255f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
@@ -0,0 +1,58 @@
+/*
+ * P1010 RDB Device Tree Source (36-bit address map)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1010si-pre.dtsi"
+
+/ {
+ model = "fsl,P1010RDB-PB";
+ compatible = "fsl,P1010RDB-PB";
+
+ /include/ "p1010rdb_36b.dtsi"
+};
+
+/include/ "p1010rdb.dtsi"
+
+&phy0 {
+ interrupts = <0 1 0 0>;
+};
+
+&phy1 {
+ interrupts = <2 1 0 0>;
+};
+
+&phy2 {
+ interrupts = <1 1 0 0>;
+};
+
+/include/ "p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
new file mode 100644
index 0000000..a8e4ba0
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
@@ -0,0 +1,233 @@
+/*
+ * P1010 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&board_ifc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x2000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 7 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00700000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@800000 {
+ /* 20MB for JFFS2 based Root file System */
+ reg = <0x00800000 0x01400000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@1f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x01f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ ifc_nand: nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x1 0x0 0x10000>;
+ };
+
+ cpld@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1010rdb-cpld";
+ reg = <0x3 0x0 0x0000020>;
+ bank-width = <1>;
+ device-width = <1>;
+ };
+};
+
+&board_soc {
+ i2c@3000 {
+ eeprom@50 {
+ compatible = "st,24c256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3100 {
+ eeprom@52 {
+ compatible = "atmel,24c01";
+ reg = <0x52>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ /* 1MB for u-boot Bootloader Image */
+ /* 1MB for Environment */
+ reg = <0x0 0x00100000>;
+ label = "SPI Flash U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 512KB for DTB Image */
+ reg = <0x00100000 0x00080000>;
+ label = "SPI Flash DTB Image";
+ };
+
+ partition@180000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00180000 0x00400000>;
+ label = "SPI Flash Linux Kernel Image";
+ };
+
+ partition@580000 {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00580000 0x00400000>;
+ label = "SPI Flash Compressed RFSImage";
+ };
+
+ partition@980000 {
+ /* 6.5MB for JFFS2 based RFS */
+ reg = <0x00980000 0x00680000>;
+ label = "SPI Flash JFFS2 RFS";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "utmi";
+ dr_mode = "host";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ reg = <0x1>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <0x0>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ tbi-phy@3 {
+ device_type = "tbi-phy";
+ reg = <0x3>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <10>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0x80000016>;
+ fsl,tmr-fiper1 = <999999990>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <199999999>;
+ };
+
+ enet0: ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy2>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "sgmii";
+ };
+};
+
+&pci0 {
+ pcie@0 {
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ /*
+ *irq[4:5] are active-high
+ *irq[6:7] are active-low
+ */
+ 0000 0x0 0x0 0x1 &mpic 0x4 0x2 0x0 0x0
+ 0000 0x0 0x0 0x2 &mpic 0x5 0x2 0x0 0x0
+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1 0x0 0x0
+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1 0x0 0x0
+ >;
+ };
+};
diff --git a/arch/powerpc/boot/dts/p1010rdb_32b.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi
index fdc19aa..fdc19aa 100644
--- a/arch/powerpc/boot/dts/p1010rdb_32b.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi
diff --git a/arch/powerpc/boot/dts/p1010rdb_36b.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi
index de2fcee..de2fcee 100644
--- a/arch/powerpc/boot/dts/p1010rdb_36b.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi
index a24699c..a24699c 100644
--- a/arch/powerpc/boot/dts/p1020mbg-pc.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts
new file mode 100644
index 0000000..b29d1fc
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts
@@ -0,0 +1,89 @@
+/*
+ * P1020 MBG-PC Device Tree Source (32-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020MBG-PC";
+ compatible = "fsl,P1020MBG-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0x0 0xffe05000 0x0 0x1000>;
+
+ /* NOR and L2 switch */
+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000
+ 0x1 0x0 0x0 0xffa00000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0x0 0xffe09000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0x0 0xffe0a000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020mbg-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts
new file mode 100644
index 0000000..678d0ee
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts
@@ -0,0 +1,89 @@
+/*
+ * P1020 MBG-PC Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020MBG-PC";
+ compatible = "fsl,P1020MBG-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0x0 0x1000>;
+
+ /* NOR and L2 switch */
+ ranges = <0x0 0x0 0xf 0xec000000 0x04000000
+ 0x1 0x0 0xf 0xffa00000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020mbg-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi
new file mode 100644
index 0000000..25f81ee
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi
@@ -0,0 +1,247 @@
+/*
+ * P1020 RDB-PC Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND Compressed RFS Image";
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+
+ cpld@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cpld";
+ reg = <0x3 0x0 0x20000>;
+ read-only;
+ };
+};
+
+&soc {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@u-boot {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ partition@dtb {
+ /* 512KB for DTB Image*/
+ reg = <0x00080000 0x00080000>;
+ label = "dtb";
+ };
+
+ partition@kernel {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "kernel";
+ };
+
+ partition@fs {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "file system";
+ };
+
+ partition@jffs-fs {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "file system jffs2";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ /* USB2 is shared with localbus, so it must be disabled
+ by default. We can't put 'status = "disabled";' here
+ since U-Boot doesn't clear the status property when
+ it enables USB2. OTOH, U-Boot does create a new node
+ when there isn't any. So, just comment it out.
+ usb@23000 {
+ phy_type = "ulpi";
+ };
+ */
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+
+ tbi0: tbi-phy@11 {
+ device_type = "tbi-phy";
+ reg = <0x11>;
+ };
+ };
+
+ mdio@25000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@b0000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts
new file mode 100644
index 0000000..8175bf6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts
@@ -0,0 +1,90 @@
+/*
+ * P1020 RDB-PC Device Tree Source (32-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020RDB-PC";
+ compatible = "fsl,P1020RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xff800000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000
+ 0x3 0x0 0x0 0xffa00000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020rdb-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts
new file mode 100644
index 0000000..01c3057
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts
@@ -0,0 +1,90 @@
+/*
+ * P1020 RDB-PC Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020RDB-PC";
+ compatible = "fsl,P1020RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xff800000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00040000
+ 0x3 0x0 0xf 0xffa00000 0x00020000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020rdb-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb-pc_camp_core0.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core0.dts
index f411515..f411515 100644
--- a/arch/powerpc/boot/dts/p1020rdb-pc_camp_core0.dts
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core0.dts
diff --git a/arch/powerpc/boot/dts/p1020rdb-pc_camp_core1.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core1.dts
index a91335a..a91335a 100644
--- a/arch/powerpc/boot/dts/p1020rdb-pc_camp_core1.dts
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core1.dts
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
new file mode 100644
index 0000000..f2dc6c0
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
@@ -0,0 +1,292 @@
+/*
+ * P1020 RDB-PD Device Tree Source (32-bit address map)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020RDB-PD";
+ compatible = "fsl,P1020RDB-PD";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0x0 0xffe05000 0x0 0x1000>;
+
+ /* NOR, NAND flash, L2 switch and CPLD */
+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000
+ 0x1 0x0 0x0 0xff800000 0x00040000
+ 0x2 0x0 0x0 0xffa00000 0x00020000
+ 0x3 0x0 0x0 0xffb00000 0x00020000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x4000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* 128KB for DTB Image */
+ reg = <0x0 0x00020000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@20000 {
+ /* 3.875 MB for Linux Kernel Image */
+ reg = <0x00020000 0x003e0000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 58MB for Root file System */
+ reg = <0x00400000 0x03a00000>;
+ label = "NOR Root File System";
+ };
+
+ partition@3e00000 {
+ /* This location must not be altered */
+ /* 1M for Vitesse 7385 Switch firmware */
+ reg = <0x3e00000 0x00100000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@3f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x03f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 122MB for File System Image */
+ reg = <0x00600000 0x07a00000>;
+ label = "NAND File System Image";
+ };
+ };
+
+ cpld@2,0 {
+ compatible = "fsl,p1020rdb-pd-cpld";
+ reg = <0x2 0x0 0x20000>;
+ };
+
+ L2switch@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x3 0x0 0x20000>;
+ };
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ /* input clock */
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI U-Boot Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 512KB for DTB Image*/
+ reg = <0x00080000 0x00080000>;
+ label = "SPI DTB Image";
+ };
+
+ partition@100000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI Linux Kernel Image";
+ };
+
+ partition@500000 {
+ /* 11MB for FS System Image */
+ reg = <0x00500000 0x00b00000>;
+ label = "SPI File System Image";
+ };
+ };
+
+ slic@0 {
+ compatible = "zarlink,le88266";
+ reg = <1>;
+ spi-max-frequency = <8000000>;
+ };
+
+ slic@1 {
+ compatible = "zarlink,le88266";
+ reg = <2>;
+ spi-max-frequency = <8000000>;
+ };
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ };
+
+ mdio@25000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <10>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0x80000016>;
+ fsl,tmr-fiper1 = <999999990>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <199999999>;
+ };
+
+ enet0: ethernet@b0000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0x0 0xffe09000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0x0 0xffe0a000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0x0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb.dts b/arch/powerpc/boot/dts/fsl/p1020rdb.dts
new file mode 100644
index 0000000..8136225
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb.dts
@@ -0,0 +1,66 @@
+/*
+ * P1020 RDB Device Tree Source
+ *
+ * Copyright 2009-2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020RDB";
+ compatible = "fsl,P1020RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xffa00000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020rdb.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi
new file mode 100644
index 0000000..703142e
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi
@@ -0,0 +1,246 @@
+/*
+ * P1020 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&board_lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR (RO) Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR (RO) DTB Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR (RW) JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR (RO) U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND (RW) Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+};
+
+&board_soc {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@u-boot {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ partition@dtb {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "dtb";
+ read-only;
+ };
+
+ partition@kernel {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "kernel";
+ read-only;
+ };
+
+ partition@fs {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "file system";
+ read-only;
+ };
+
+ partition@jffs-fs {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "file system jffs2";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ dr_mode = "host";
+ };
+
+ /* USB2 is shared with localbus. It is used
+ only in case of SPI and SD boot after
+ appropriate device-tree fixup done by uboot */
+ usb@23000 {
+ phy_type = "ulpi";
+ dr_mode = "host";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+
+ tbi-phy@2 {
+ device_type = "tbi-phy";
+ reg = <0x2>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@b0000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts b/arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts
new file mode 100644
index 0000000..74471e3
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts
@@ -0,0 +1,66 @@
+/*
+ * P1020 RDB Device Tree Source (36-bit address map)
+ *
+ * Copyright 2009-2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020RDB";
+ compatible = "fsl,P1020RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xffa00000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00020000>;
+ };
+
+ board_soc: soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020rdb.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020utm-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi
index 7ea85ea..7ea85ea 100644
--- a/arch/powerpc/boot/dts/p1020utm-pc.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts
new file mode 100644
index 0000000..bc03ef6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts
@@ -0,0 +1,89 @@
+/*
+ * P1020 UTM-PC Device Tree Source (32-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020UTM-PC";
+ compatible = "fsl,P1020UTM-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0x0 0xffe05000 0x0 0x1000>;
+
+ /* NOR */
+ ranges = <0x0 0x0 0x0 0xec000000 0x02000000
+ 0x1 0x0 0x0 0xffa00000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0x0 0xffe09000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0x0 0xffe0a000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020utm-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts
new file mode 100644
index 0000000..32766f6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts
@@ -0,0 +1,89 @@
+/*
+ * P1020 UTM-PC Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1020UTM-PC";
+ compatible = "fsl,P1020UTM-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0x0 0x1000>;
+
+ /* NOR */
+ ranges = <0x0 0x0 0xf 0xec000000 0x02000000
+ 0x1 0x0 0xf 0xffa00000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0x0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1020utm-pc.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1021mds.dts b/arch/powerpc/boot/dts/fsl/p1021mds.dts
new file mode 100644
index 0000000..291454c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1021mds.dts
@@ -0,0 +1,323 @@
+/*
+ * P1021 MDS Device Tree Source
+ *
+ * Copyright 2010,2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1021";
+ compatible = "fsl,P1021MDS";
+
+ aliases {
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0x0 0xffe05000 0x0 0x1000>;
+
+ /* NAND Flash, BCSR, PMC0/1*/
+ ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
+ 0x1 0x0 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0x0 0xf8010000 0x00020000
+ 0x3 0x0 0x0 0xf8020000 0x00020000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x0 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 5MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00500000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@b00000 {
+ /* 6MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00600000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 14MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00e00000>;
+ label = "NAND (RW) Writable User area";
+ };
+
+ partition@1f00000 {
+ /* 1MB for microcode */
+ reg = <0x01f00000 0x00100000>;
+ label = "NAND (RO) QE Ucode";
+ read-only;
+ };
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+ };
+
+ pib@2,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <2 0 0x10000>;
+ };
+
+ pib@3,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <3 0 0x10000>;
+ };
+ };
+
+ soc: soc@ffe00000 {
+ compatible = "fsl,p1021-immr", "simple-bus";
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@u-boot {
+ label = "u-boot-spi";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel-spi";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb-spi";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system-spi";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ dr_mode = "host";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <1 1 0 0>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+ tbi-phy@5 {
+ device_type = "tbi-phy";
+ reg = <0x5>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ ethernet@b1000 {
+ phy-handle = <&phy4>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x60>;
+ ranges = <0x0 0xe0100 0x60>;
+ device_type = "par_io";
+ num-ports = <3>;
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
+ 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
+ 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
+ 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
+ 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
+ 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
+ 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
+ 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
+ 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
+ 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
+ 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
+ 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
+ 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
+ };
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@ffe80000 {
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ status = "disabled"; /* no firmware loaded */
+
+ enet3: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "clk12";
+ tx-clock-name = "clk9";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "mii";
+ };
+
+ mdio@2120 {
+ qe_phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1 0 0>;
+ reg = <0x0>;
+ };
+ qe_phy1: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1 0 0>;
+ reg = <0x3>;
+ };
+ tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ucc@2400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk13";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rmii";
+ };
+ };
+};
+
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
new file mode 100644
index 0000000..18f9b31
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
@@ -0,0 +1,256 @@
+/*
+ * P1021 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 10.75MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00ac0000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@ec0000 {
+ /* This location must not be altered */
+ /* 256KB for QE ucode firmware*/
+ reg = <0x00ec0000 0x00040000>;
+ label = "NOR QE microcode firmware";
+ read-only;
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND Compressed RFS Image";
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for User Writable Area */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+};
+
+&soc {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@u-boot {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI Flash U-Boot Image";
+ read-only;
+ };
+
+ partition@dtb {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "SPI Flash DTB Image";
+ };
+
+ partition@kernel {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI Flash Linux Kernel Image";
+ };
+
+ partition@fs {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "SPI Flash Compressed RFSImage";
+ };
+
+ partition@jffs-fs {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "SPI Flash JFFS2 RFS";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@25000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <10>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0x80000016>;
+ fsl,tmr-fiper1 = <999999990>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <199999999>;
+ };
+
+ enet0: ethernet@b0000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi2>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts
new file mode 100644
index 0000000..d2b4710
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts
@@ -0,0 +1,96 @@
+/*
+ * P1021 RDB Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1021RDB";
+ compatible = "fsl,P1021RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xff800000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@ffe80000 {
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ };
+};
+
+/include/ "p1021rdb-pc.dtsi"
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts
new file mode 100644
index 0000000..e298c29
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts
@@ -0,0 +1,96 @@
+/*
+ * P1021 RDB Device Tree Source (36-bit address map)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1021RDB";
+ compatible = "fsl,P1021RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xff800000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00020000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ reg = <0xf 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@fffe80000 {
+ ranges = <0x0 0xf 0xffe80000 0x40000>;
+ reg = <0xf 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ };
+};
+
+/include/ "p1021rdb-pc.dtsi"
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi
new file mode 100644
index 0000000..ddefbf6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi
@@ -0,0 +1,239 @@
+/*
+ * P1022 DS Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+&board_lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ reg = <0x0 0x03000000>;
+ label = "ramdisk-nor";
+ read-only;
+ };
+
+ partition@3000000 {
+ reg = <0x03000000 0x00e00000>;
+ label = "diagnostic-nor";
+ read-only;
+ };
+
+ partition@3e00000 {
+ reg = <0x03e00000 0x00200000>;
+ label = "dink-nor";
+ read-only;
+ };
+
+ partition@4000000 {
+ reg = <0x04000000 0x00400000>;
+ label = "kernel-nor";
+ read-only;
+ };
+
+ partition@4400000 {
+ reg = <0x04400000 0x03b00000>;
+ label = "jffs2-nor";
+ };
+
+ partition@7f00000 {
+ reg = <0x07f00000 0x00080000>;
+ label = "dtb-nor";
+ read-only;
+ };
+
+ partition@7f80000 {
+ reg = <0x07f80000 0x00080000>;
+ label = "u-boot-nor";
+ read-only;
+ };
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ reg = <0x0 0x02000000>;
+ label = "u-boot-nand";
+ read-only;
+ };
+
+ partition@2000000 {
+ reg = <0x02000000 0x10000000>;
+ label = "jffs2-nand";
+ };
+
+ partition@12000000 {
+ reg = <0x12000000 0x10000000>;
+ label = "ramdisk-nand";
+ read-only;
+ };
+
+ partition@22000000 {
+ reg = <0x22000000 0x04000000>;
+ label = "kernel-nand";
+ };
+
+ partition@26000000 {
+ reg = <0x26000000 0x01000000>;
+ label = "dtb-nand";
+ read-only;
+ };
+
+ partition@27000000 {
+ reg = <0x27000000 0x19000000>;
+ label = "reserved-nand";
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ interrupt-parent = <&mpic>;
+ /*
+ * IRQ8 is generated if the "EVENT" switch is pressed
+ * and PX_CTL[EVESEL] is set to 00.
+ */
+ interrupts = <8 0 0 0>;
+ };
+};
+
+&board_soc {
+ i2c@3100 {
+ wm8776:codec@1a {
+ compatible = "wlf,wm8776";
+ reg = <0x1a>;
+ /*
+ * clock-frequency will be set by U-Boot if
+ * the clock is enabled.
+ */
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@0 {
+ label = "u-boot-spi";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@100000 {
+ label = "kernel-spi";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@600000 {
+ label = "dtb-spi";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@700000 {
+ label = "file system-spi";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ ssi@15000 {
+ fsl,mode = "i2s-slave";
+ codec-handle = <&wm8776>;
+ fsl,ssi-asynchronous;
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ usb@23000 {
+ status = "disabled";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x1>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <9 1 0 0>;
+ reg = <0x2>;
+ };
+ tbi-phy@2 {
+ device_type = "tbi-phy";
+ reg = <0x2>;
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xc01ebd3d>;
+ fsl,tmr-fiper1 = <999999995>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <266499999>;
+ };
+
+ ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ ethernet@b1000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1022ds_32b.dts b/arch/powerpc/boot/dts/fsl/p1022ds_32b.dts
new file mode 100644
index 0000000..5a7eace
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1022ds_32b.dts
@@ -0,0 +1,103 @@
+/*
+ * P1022 DS 32-bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "p1022si-pre.dtsi"
+/ {
+ model = "fsl,P1022DS";
+ compatible = "fsl,P1022DS";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+ 0x1 0x0 0x0 0xe0000000 0x08000000
+ 0x2 0x0 0x0 0xff800000 0x00040000
+ 0x3 0x0 0x0 0xffdf0000 0x00008000>;
+ reg = <0x0 0xffe05000 0 0x1000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0x0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@ffe0b000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ reg = <0 0xffe0b000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1022si-post.dtsi"
+/include/ "p1022ds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1022ds_36b.dts b/arch/powerpc/boot/dts/fsl/p1022ds_36b.dts
new file mode 100644
index 0000000..88063cd
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1022ds_36b.dts
@@ -0,0 +1,103 @@
+/*
+ * P1022 DS 36-bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "p1022si-pre.dtsi"
+/ {
+ model = "fsl,P1022DS";
+ compatible = "fsl,P1022DS";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@fffe05000 {
+ ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
+ 0x1 0x0 0xf 0xe0000000 0x08000000
+ 0x2 0x0 0xf 0xff800000 0x00040000
+ 0x3 0x0 0xf 0xffdf0000 0x00008000>;
+ reg = <0xf 0xffe05000 0 0x1000>;
+ };
+
+ board_soc: soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ reg = <0xf 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x10000>;
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@fffe0b000 {
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ reg = <0xf 0xffe0b000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1022si-post.dtsi"
+/include/ "p1022ds.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1022rdk.dts b/arch/powerpc/boot/dts/fsl/p1022rdk.dts
new file mode 100644
index 0000000..d505d7c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1022rdk.dts
@@ -0,0 +1,188 @@
+/*
+ * P1022 RDK 32-bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "p1022si-pre.dtsi"
+/ {
+ model = "fsl,P1022RDK";
+ compatible = "fsl,P1022RDK";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ /* The P1022 RDK does not have any localbus devices */
+ status = "disabled";
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+
+ i2c@3100 {
+ wm8960:codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ /* MCLK source is a stand-alone oscillator */
+ clock-frequency = <12288000>;
+ };
+ rtc@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
+ adt7461@4c{
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ zl6100@21{
+ compatible = "isil,zl6100";
+ reg = <0x21>;
+ };
+ zl6100@24{
+ compatible = "isil,zl6100";
+ reg = <0x24>;
+ };
+ zl6100@26{
+ compatible = "isil,zl6100";
+ reg = <0x26>;
+ };
+ zl6100@29{
+ compatible = "isil,zl6100";
+ reg = <0x29>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,m25p80", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ partition@0 {
+ label = "full-spi-flash";
+ reg = <0x00000000 0x00100000>;
+ };
+ };
+ };
+
+ ssi@15000 {
+ fsl,mode = "i2s-slave";
+ codec-handle = <&wm8960>;
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ usb@23000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x1>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <9 1 0 0>;
+ reg = <0x2>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ ethernet@b1000 {
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0x0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@ffe0b000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ reg = <0 0xffe0b000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1022si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
index 426bf41..5f51b7b 100644
--- a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
@@ -224,10 +224,12 @@
/include/ "pq3-etsec2-0.dtsi"
enet0: enet0_grp2: ethernet@b0000 {
+ fsl,wake-on-filer;
};
/include/ "pq3-etsec2-1.dtsi"
enet1: enet1_grp2: ethernet@b1000 {
+ fsl,wake-on-filer;
};
global-utilities@e0000 {
diff --git a/arch/powerpc/boot/dts/fsl/p1023rdb.dts b/arch/powerpc/boot/dts/fsl/p1023rdb.dts
new file mode 100644
index 0000000..9716ca6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1023rdb.dts
@@ -0,0 +1,260 @@
+/*
+ * P1023 RDB Device Tree Source
+ *
+ * Copyright 2013 - 2014 Freescale Semiconductor Inc.
+ *
+ * Author: Chunhe Lan <Chunhe.Lan@freescale.com>
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1023si-pre.dtsi"
+
+/ {
+ model = "fsl,P1023";
+ compatible = "fsl,P1023RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ qportals: qman-portals@ff000000 {
+ ranges = <0x0 0xf 0xff000000 0x200000>;
+ };
+
+ bportals: bman-portals@ff200000 {
+ ranges = <0x0 0xf 0xff200000 0x200000>;
+ };
+
+ soc: soc@ff600000 {
+ ranges = <0x0 0x0 0xff600000 0x200000>;
+
+ i2c@3000 {
+ eeprom@53 {
+ compatible = "at24,24c04";
+ reg = <0x53>;
+ };
+
+ rtc@6f {
+ compatible = "microchip,mcp7941x";
+ reg = <0x6f>;
+ };
+ };
+
+ usb@22000 {
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+ };
+
+ lbc: localbus@ff605000 {
+ reg = <0 0xff605000 0 0x1000>;
+
+ /* NOR, NAND Flashes */
+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000
+ 0x1 0x0 0x0 0xffa00000 0x08000000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x04000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* 48MB for Root File System */
+ reg = <0x00000000 0x03000000>;
+ label = "NOR Root File System";
+ };
+
+ partition@3000000 {
+ /* 1MB for DTB Image */
+ reg = <0x03000000 0x00100000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@3100000 {
+ /* 14MB for Linux Kernel Image */
+ reg = <0x03100000 0x00e00000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@3f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x03f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 14MB for Linux Kernel Image */
+ reg = <0x00200000 0x00e00000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@1000000 {
+ /* 96MB for Root File System Image */
+ reg = <0x01000000 0x06000000>;
+ label = "NAND Root File System";
+ };
+
+ partition@7000000 {
+ /* 16MB for User Writable Area */
+ reg = <0x07000000 0x01000000>;
+ label = "NAND Writable User area";
+ };
+ };
+ };
+
+ pci0: pcie@ff60a000 {
+ reg = <0 0xff60a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ pcie@0 {
+ /* IRQ[0:3] are pulled up on board, set to active-low */
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 0 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ board_pci1: pci1: pcie@ff609000 {
+ reg = <0 0xff609000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ /*
+ * IRQ[4:6] only for PCIe, set to active-high,
+ * IRQ[7] is pulled up on board, set to active-low
+ */
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 4 2 0 0
+ 0000 0 0 2 &mpic 5 2 0 0
+ 0000 0 0 3 &mpic 6 2 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@ff60b000 {
+ reg = <0 0xff60b000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ /*
+ * IRQ[8:10] are pulled up on board, set to active-low
+ * IRQ[11] only for PCIe, set to active-high,
+ */
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 8 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 2 0 0
+ >;
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1023si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi
new file mode 100644
index 0000000..b4d0586
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi
@@ -0,0 +1,228 @@
+/*
+ * P1024 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND Compressed RFS Image";
+ };
+
+ partition@a00000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00f00000>;
+ label = "NAND JFFS2 Root File System";
+ };
+
+ partition@1900000 {
+ /* 7MB for User Writable Area */
+ reg = <0x01900000 0x00700000>;
+ label = "NAND Writable User area";
+ };
+ };
+};
+
+&soc {
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,m25p80", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI U-Boot Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "SPI DTB Image";
+ };
+
+ partition@100000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI Linux Kernel Image";
+ };
+
+ partition@500000 {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "SPI Compressed RFS Image";
+ };
+
+ partition@900000 {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "SPI JFFS2 RFS";
+ };
+ };
+ };
+
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ usb@23000 {
+ status = "disabled";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupts = <1 1 0 0>;
+ reg = <0x2>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ethernet@b0000 {
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts b/arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts
new file mode 100644
index 0000000..8b09b9d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts
@@ -0,0 +1,87 @@
+/*
+ * P1024 RDB 32Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1024RDB";
+ compatible = "fsl,P1024RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0x0 0xffe05000 0 0x1000>;
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xff800000 0x00040000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ reg = <0x0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0x0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1024rdb.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts b/arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts
new file mode 100644
index 0000000..e7093ae
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts
@@ -0,0 +1,87 @@
+/*
+ * P1024 RDB 36Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1020si-pre.dtsi"
+/ {
+ model = "fsl,P1024RDB";
+ compatible = "fsl,P1024RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xff800000 0x00040000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p1024rdb.dtsi"
+/include/ "p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
new file mode 100644
index 0000000..d44bb12
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi
@@ -0,0 +1,326 @@
+/*
+ * P1025 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1025-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND Compressed RFS Image";
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND Writable User area";
+ };
+ };
+
+};
+
+&soc {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+
+ partition@u-boot {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "u-boot";
+ read-only;
+ };
+
+ partition@dtb {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "dtb";
+ };
+
+ partition@kernel {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "kernel";
+ };
+
+ partition@fs {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "file system";
+ };
+
+ partition@jffs-fs {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "file system jffs2";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ /* USB2 is shared with localbus, so it must be disabled
+ by default. We can't put 'status = "disabled";' here
+ since U-Boot doesn't clear the status property when
+ it enables USB2. OTOH, U-Boot does create a new node
+ when there isn't any. So, just comment it out.
+ usb@23000 {
+ phy_type = "ulpi";
+ };
+ */
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <3 1>;
+ reg = <0x0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@25000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@b0000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+
+ };
+
+ enet1: ethernet@b1000 {
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x60>;
+ ranges = <0x0 0xe0100 0x60>;
+ device_type = "par_io";
+ num-ports = <3>;
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
+ 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
+ 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
+ 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
+ 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
+ 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
+ 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
+ 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
+ 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
+ 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
+ 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
+ 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
+ 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
+ };
+
+ pio3: ucc_pin@03 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
+ 0x0 0x12 0x2 0x0 0x2 0x0 /* SER7_CTS_B*/
+ 0x0 0x13 0x1 0x0 0x2 0x0 /* SER7_RTS_B*/
+ 0x0 0x14 0x2 0x0 0x2 0x0 /* SER7_RXD0*/
+ 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
+ };
+
+ pio4: ucc_pin@04 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
+ 0x0 0x1c 0x2 0x0 0x2 0x0 /* SER3_CTS_B*/
+ 0x0 0x1d 0x1 0x0 0x2 0x0 /* SER3_RTS_B*/
+ 0x0 0x1e 0x2 0x0 0x2 0x0 /* SER3_RXD0*/
+ 0x0 0x1f 0x1 0x0 0x2 0x0>; /* SER3_TXD0*/
+ };
+ };
+};
+
+&qe {
+ serial2: ucc@2600 {
+ device_type = "serial";
+ compatible = "ucc_uart";
+ port-number = <0>;
+ rx-clock-name = "brg6";
+ tx-clock-name = "brg6";
+ pio-handle = <&pio3>;
+ };
+
+ serial3: ucc@2200 {
+ device_type = "serial";
+ compatible = "ucc_uart";
+ port-number = <1>;
+ rx-clock-name = "brg2";
+ tx-clock-name = "brg2";
+ pio-handle = <&pio4>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts b/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
new file mode 100644
index 0000000..b15acba
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
@@ -0,0 +1,133 @@
+/*
+ * P1025 RDB Device Tree Source (32-bit address map)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1025RDB";
+ compatible = "fsl,P1025RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xff800000 0x00040000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xe0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0 0xe0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@ffe80000 {
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ status = "disabled"; /* no firmware loaded */
+
+ enet3: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ rx-clock-name = "clk12";
+ tx-clock-name = "clk9";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "mii";
+ };
+
+ mdio@2120 {
+ qe_phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1 0 0>;
+ reg = <0x6>;
+ };
+ qe_phy1: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1 0 0>;
+ reg = <0x3>;
+ };
+ tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ucc@2400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ rx-clock-name = "none";
+ tx-clock-name = "clk13";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rmii";
+ };
+ };
+};
+
+/include/ "p1025rdb.dtsi"
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts b/arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts
new file mode 100644
index 0000000..b0ded5e
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts
@@ -0,0 +1,93 @@
+/*
+ * P1025 RDB Device Tree Source (36-bit address map)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1025RDB";
+ compatible = "fsl,P1025RDB";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ /* NOR, NAND Flashes */
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xff800000 0x00040000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xe 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@fffe80000 {
+ status = "disabled"; /* no firmware loaded */
+ };
+
+};
+
+/include/ "p1025rdb.dtsi"
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1025twr.dts b/arch/powerpc/boot/dts/fsl/p1025twr.dts
new file mode 100644
index 0000000..9b8863b
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1025twr.dts
@@ -0,0 +1,95 @@
+/*
+ * P1025 TWR Device Tree Source (32-bit address map)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p1021si-pre.dtsi"
+/ {
+ model = "fsl,P1025";
+ compatible = "fsl,TWR-P1025";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR Flash and SSD1289 */
+ ranges = <0x0 0x0 0x0 0xec000000 0x04000000
+ 0x2 0x0 0x0 0xe0000000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe: qe@ffe80000 {
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ };
+};
+
+/include/ "p1025twr.dtsi"
+/include/ "p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p1025twr.dtsi b/arch/powerpc/boot/dts/fsl/p1025twr.dtsi
new file mode 100644
index 0000000..08816fb
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1025twr.dtsi
@@ -0,0 +1,292 @@
+/*
+ * P1025 TWR Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+/{
+ aliases {
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ };
+};
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x4000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 5.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00580000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 56.75MB for Root file System */
+ reg = <0x00600000 0x038c0000>;
+ label = "NOR Root File System";
+ };
+
+ partition@ec0000 {
+ /* This location must not be altered */
+ /* 256KB for QE ucode firmware*/
+ reg = <0x03ec0000 0x00040000>;
+ label = "NOR QE microcode firmware";
+ read-only;
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x03f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ /* CS2 for Display */
+ display@2,0 {
+ compatible = "solomon,ssd1289fb";
+ reg = <0x2 0x0000 0x0004>;
+ };
+
+};
+
+&soc {
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1 0 0>;
+ reg = <0x2>;
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@25000 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26000 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ptp_clock@b0e00 {
+ compatible = "fsl,etsec-ptp";
+ reg = <0xb0e00 0xb0>;
+ interrupts = <68 2 0 0 69 2 0 0>;
+ fsl,tclk-period = <10>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xc0000021>;
+ fsl,tmr-fiper1 = <999999990>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <133333332>;
+ };
+
+ enet0: ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+
+ };
+
+ enet1: ethernet@b1000 {
+ status = "disabled";
+ };
+
+ enet2: ethernet@b2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x60>;
+ ranges = <0x0 0xe0100 0x60>;
+ device_type = "par_io";
+ num-ports = <3>;
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
+ 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
+ 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
+ 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
+ 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
+ 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
+ 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
+ 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
+ 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
+ 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
+ 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
+ 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
+ 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
+ };
+
+ pio3: ucc_pin@03 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
+ 0x0 0x12 0x2 0x0 0x2 0x0 /* SER7_CTS_B*/
+ 0x0 0x13 0x1 0x0 0x2 0x0 /* SER7_RTS_B*/
+ 0x0 0x14 0x2 0x0 0x2 0x0 /* SER7_RXD0*/
+ 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
+ };
+
+ pio4: ucc_pin@04 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
+ 0x0 0x1c 0x2 0x0 0x2 0x0 /* SER3_CTS_B*/
+ 0x0 0x1d 0x1 0x0 0x2 0x0 /* SER3_RTS_B*/
+ 0x0 0x1e 0x2 0x0 0x2 0x0 /* SER3_RXD0*/
+ 0x0 0x1f 0x1 0x0 0x2 0x0>; /* SER3_TXD0*/
+ };
+ };
+};
+
+&qe {
+ enet3: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ rx-clock-name = "clk12";
+ tx-clock-name = "clk9";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "mii";
+ };
+
+ mdio@2120 {
+ qe_phy0: ethernet-phy@18 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1 0 0>;
+ reg = <0x18>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy1: ethernet-phy@19 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1 0 0>;
+ reg = <0x19>;
+ device_type = "ethernet-phy";
+ };
+ tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ucc@2400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ rx-clock-name = "none";
+ tx-clock-name = "clk13";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rmii";
+ };
+
+ serial2: ucc@2600 {
+ device_type = "serial";
+ compatible = "ucc_uart";
+ port-number = <0>;
+ rx-clock-name = "brg6";
+ tx-clock-name = "brg6";
+ pio-handle = <&pio3>;
+ };
+
+ serial3: ucc@2200 {
+ device_type = "serial";
+ compatible = "ucc_uart";
+ port-number = <1>;
+ rx-clock-name = "brg2";
+ tx-clock-name = "brg2";
+ pio-handle = <&pio4>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p2020ds.dts b/arch/powerpc/boot/dts/fsl/p2020ds.dts
new file mode 100644
index 0000000..5ba06f7
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2020ds.dts
@@ -0,0 +1,89 @@
+/*
+ * P2020 DS Device Tree Source
+ *
+ * Copyright 2009-2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p2020si-pre.dtsi"
+
+/ {
+ model = "fsl,P2020DS";
+ compatible = "fsl,P2020DS";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+ 0x1 0x0 0x0 0xe0000000 0x08000000
+ 0x2 0x0 0x0 0xffa00000 0x00040000
+ 0x3 0x0 0x0 0xffdf0000 0x00008000
+ 0x4 0x0 0x0 0xffa40000 0x00040000
+ 0x5 0x0 0x0 0xffa80000 0x00040000
+ 0x6 0x0 0x0 0xffac0000 0x00040000>;
+ reg = <0 0xffe05000 0 0x1000>;
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci2: pcie@ffe08000 {
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ reg = <0 0xffe08000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ board_pci1: pci1: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci0: pcie@ffe0a000 {
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
+
+/*
+ * p2020ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
+ * for interrupt-map & interrupt-map-mask
+ */
+
+/include/ "p2020si-post.dtsi"
+/include/ "p2020ds.dtsi"
diff --git a/arch/powerpc/boot/dts/p2020ds.dtsi b/arch/powerpc/boot/dts/fsl/p2020ds.dtsi
index e699cf9..e699cf9 100644
--- a/arch/powerpc/boot/dts/p2020ds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2020ds.dtsi
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
new file mode 100644
index 0000000..03c9afc
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
@@ -0,0 +1,241 @@
+/*
+ * P2020 RDB-PC Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+&lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR DTB Image";
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR Linux Kernel Image";
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND Compressed RFS Image";
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+
+ cpld@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cpld";
+ reg = <0x3 0x0 0x20000>;
+ read-only;
+ };
+};
+
+&soc {
+ i2c@3000 {
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,m25p80", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI U-Boot Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "SPI DTB Image";
+ };
+
+ partition@100000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI Linux Kernel Image";
+ };
+
+ partition@500000 {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "SPI Compressed RFS Image";
+ };
+
+ partition@900000 {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "SPI JFFS2 RFS";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <2 1 0 0>;
+ reg = <0x1>;
+ };
+ };
+
+ mdio@25520 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26520 {
+ status = "disabled";
+ };
+
+ ptp_clock@24e00 {
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <2>;
+ fsl,tmr-add = <0xaaaaaaab>;
+ fsl,tmr-fiper1 = <999999995>;
+ fsl,tmr-fiper2 = <99990>;
+ fsl,max-adj = <299999999>;
+ };
+
+ enet0: ethernet@24000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@26000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts b/arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts
new file mode 100644
index 0000000..d3295c2
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts
@@ -0,0 +1,96 @@
+/*
+ * P2020 RDB-PC 32Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p2020si-pre.dtsi"
+
+/ {
+ model = "fsl,P2020RDB";
+ compatible = "fsl,P2020RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR and NAND Flashes */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xff800000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000
+ 0x3 0x0 0x0 0xffa00000 0x00020000>;
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ };
+
+ pci2: pcie@ffe08000 {
+ reg = <0 0xffe08000 0 0x1000>;
+ status = "disabled";
+ };
+
+ pci1: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci0: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p2020rdb-pc.dtsi"
+/include/ "p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts b/arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts
new file mode 100644
index 0000000..9307a8f4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts
@@ -0,0 +1,96 @@
+/*
+ * P2020 RDB-PC 36Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p2020si-pre.dtsi"
+
+/ {
+ model = "fsl,P2020RDB";
+ compatible = "fsl,P2020RDB-PC";
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@fffe05000 {
+ reg = <0xf 0xffe05000 0 0x1000>;
+
+ /* NOR and NAND Flashes */
+ ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+ 0x1 0x0 0xf 0xff800000 0x00040000
+ 0x2 0x0 0xf 0xffb00000 0x00020000
+ 0x3 0x0 0xf 0xffa00000 0x00020000>;
+ };
+
+ soc: soc@fffe00000 {
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ };
+
+ pci2: pcie@fffe08000 {
+ reg = <0xf 0xffe08000 0 0x1000>;
+ status = "disabled";
+ };
+
+ pci1: pcie@fffe09000 {
+ reg = <0xf 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci0: pcie@fffe0a000 {
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p2020rdb-pc.dtsi"
+/include/ "p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb.dts b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
new file mode 100644
index 0000000..435a319
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
@@ -0,0 +1,291 @@
+/*
+ * P2020 RDB Device Tree Source
+ *
+ * Copyright 2009-2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "p2020si-pre.dtsi"
+
+/ {
+ model = "fsl,P2020RDB";
+ compatible = "fsl,P2020RDB";
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ lbc: localbus@ffe05000 {
+ reg = <0 0xffe05000 0 0x1000>;
+
+ /* NOR and NAND Flashes */
+ ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+ 0x1 0x0 0x0 0xffa00000 0x00040000
+ 0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 256KB for Vitesse 7385 Switch firmware */
+ reg = <0x0 0x00040000>;
+ label = "NOR (RO) Vitesse-7385 Firmware";
+ read-only;
+ };
+
+ partition@40000 {
+ /* 256KB for DTB Image */
+ reg = <0x00040000 0x00040000>;
+ label = "NOR (RO) DTB Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 3.5 MB for Linux Kernel Image */
+ reg = <0x00080000 0x00380000>;
+ label = "NOR (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@400000 {
+ /* 11MB for JFFS2 based Root file System */
+ reg = <0x00400000 0x00b00000>;
+ label = "NOR (RW) JFFS2 Root File System";
+ };
+
+ partition@f00000 {
+ /* This location must not be altered */
+ /* 512KB for u-boot Bootloader Image */
+ /* 512KB for u-boot Environment Variables */
+ reg = <0x00f00000 0x00100000>;
+ label = "NOR (RO) U-Boot Image";
+ read-only;
+ };
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p2020-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 4MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00400000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@a00000 {
+ /* 7MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00700000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 15MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00f00000>;
+ label = "NAND (RW) Writable User area";
+ };
+ };
+
+ L2switch@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "vitesse-7385";
+ reg = <0x2 0x0 0x20000>;
+ };
+
+ };
+
+ soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+
+ i2c@3000 {
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partition@0 {
+ /* 512KB for u-boot Bootloader Image */
+ reg = <0x0 0x00080000>;
+ label = "SPI (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@80000 {
+ /* 512KB for DTB Image */
+ reg = <0x00080000 0x00080000>;
+ label = "SPI (RO) DTB Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00100000 0x00400000>;
+ label = "SPI (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@500000 {
+ /* 4MB for Compressed RFS Image */
+ reg = <0x00500000 0x00400000>;
+ label = "SPI (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@900000 {
+ /* 7MB for JFFS2 based RFS */
+ reg = <0x00900000 0x00700000>;
+ label = "SPI (RW) JFFS2 RFS";
+ };
+ };
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ dr_mode = "host";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <3 1 0 0>;
+ reg = <0x1>;
+ };
+ tbi-phy@2 {
+ device_type = "tbi-phy";
+ reg = <0x2>;
+ };
+ };
+
+ mdio@25520 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ mdio@26520 {
+ status = "disabled";
+ };
+
+ ptp_clock@24e00 {
+ fsl,tclk-period = <5>;
+ fsl,tmr-prsc = <200>;
+ fsl,tmr-add = <0xCCCCCCCD>;
+ fsl,tmr-fiper1 = <0x3B9AC9FB>;
+ fsl,tmr-fiper2 = <0x0001869B>;
+ fsl,max-adj = <249999999>;
+ };
+
+ enet0: ethernet@24000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "sgmii";
+ };
+
+ enet2: ethernet@26000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+ };
+
+ pci0: pcie@ffe08000 {
+ reg = <0 0xffe08000 0 0x1000>;
+ status = "disabled";
+ };
+
+ pci1: pcie@ffe09000 {
+ reg = <0 0xffe09000 0 0x1000>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@ffe0a000 {
+ reg = <0 0xffe0a000 0 0x1000>;
+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0x80000000
+ 0x2000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p2041rdb.dts b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
new file mode 100644
index 0000000..e50fea9
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p2041rdb.dts
@@ -0,0 +1,340 @@
+/*
+ * P2041RDB Device Tree Source
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p2041si-pre.dtsi"
+
+/ {
+ model = "fsl,P2041RDB";
+ compatible = "fsl,P2041RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_2 = &phy_sgmii_2;
+ phy_sgmii_3 = &phy_sgmii_3;
+ phy_sgmii_4 = &phy_sgmii_4;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_2 = &phy_xgmii_2;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118000 {
+ lm75b@48 {
+ compatible = "nxp,lm75a";
+ reg = <0x48>;
+ };
+ eeprom@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ rtc@68 {
+ compatible = "pericom,pt7c4338";
+ reg = <0x68>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c@118100 {
+ eeprom@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+ };
+
+ usb1: usb@211000 {
+ dr_mode = "host";
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_2>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@e1120 {
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ phy_sgmii_2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ phy_sgmii_3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+
+ phy_sgmii_4: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_3>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_4>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xgmii_2>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@f1000 {
+ phy_xgmii_2: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 1 0 0xf 0xffa00000 0x00040000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x1 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x01000000>;
+ };
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p2041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
index 04ad177b..51e975d 100644
--- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
@@ -1,7 +1,7 @@
/*
* P2041/P2040 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2011 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -430,4 +430,31 @@ crypto: crypto@300000 {
/include/ "qoriq-qman1.dtsi"
/include/ "qoriq-bman1.dtsi"
+
+/include/ "qoriq-fman-0.dtsi"
+/include/ "qoriq-fman-0-1g-0.dtsi"
+/include/ "qoriq-fman-0-1g-1.dtsi"
+/include/ "qoriq-fman-0-1g-2.dtsi"
+/include/ "qoriq-fman-0-1g-3.dtsi"
+/include/ "qoriq-fman-0-1g-4.dtsi"
+/include/ "qoriq-fman-0-10g-0.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@f0000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
index b1ea147..941274c 100644
--- a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* P2041 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -72,6 +72,14 @@
rtic_c = &rtic_c;
rtic_d = &rtic_d;
sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/p3041ds.dts b/arch/powerpc/boot/dts/fsl/p3041ds.dts
new file mode 100644
index 0000000..40748e4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p3041ds.dts
@@ -0,0 +1,394 @@
+/*
+ * P3041DS Device Tree Source
+ *
+ * Copyright 2010 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p3041si-pre.dtsi"
+
+/ {
+ model = "fsl,P3041DS";
+ compatible = "fsl,P3041DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases{
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <35000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ ina220@44 {
+ compatible = "ti,ina220";
+ reg = <0x44>;
+ shunt-resistor = <1000>;
+ };
+ ina220@45 {
+ compatible = "ti,ina220";
+ reg = <0x45>;
+ shunt-resistor = <1000>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ fman@400000{
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_1c>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ hydra_mdio_xgmii: mdio@f1000 {
+ status = "disabled";
+
+ phy_xgmii_1: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x4>;
+ };
+
+ phy_xgmii_2: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xffa00000 0x00040000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ ranges = <0 3 0 0x30>;
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ reg = <9 1>;
+ mux-mask = <0x78>;
+
+ hydra_mdio_rgmii: rgmii-mdio@8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <8>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ hydra_mdio_sgmii: sgmii-mdio@28 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x28>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p3041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
index 2cab18a..187676f 100644
--- a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
@@ -1,7 +1,7 @@
/*
* P3041 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2011 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -457,4 +457,31 @@ crypto: crypto@300000 {
/include/ "qoriq-qman1.dtsi"
/include/ "qoriq-bman1.dtsi"
+
+/include/ "qoriq-fman-0.dtsi"
+/include/ "qoriq-fman-0-1g-0.dtsi"
+/include/ "qoriq-fman-0-1g-1.dtsi"
+/include/ "qoriq-fman-0-1g-2.dtsi"
+/include/ "qoriq-fman-0-1g-3.dtsi"
+/include/ "qoriq-fman-0-1g-4.dtsi"
+/include/ "qoriq-fman-0-10g-0.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@f0000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
index dc5f4b3..50b73e8 100644
--- a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* P3041 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -73,6 +73,14 @@
rtic_c = &rtic_c;
rtic_d = &rtic_d;
sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/p4080ds.dts b/arch/powerpc/boot/dts/fsl/p4080ds.dts
new file mode 100644
index 0000000..816b978
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p4080ds.dts
@@ -0,0 +1,400 @@
+/*
+ * P4080DS Device Tree Source
+ *
+ * Copyright 2009 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p4080si-pre.dtsi"
+
+/ {
+ model = "fsl,P4080DS";
+ compatible = "fsl,P4080DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii = &phyrgmii;
+ phy5_slot3 = &phy5slot3;
+ phy6_slot3 = &phy6slot3;
+ phy7_slot3 = &phy7slot3;
+ phy8_slot3 = &phy8slot3;
+ emi1_slot3 = &p4080mdio2;
+ emi1_slot4 = &p4080mdio1;
+ emi1_slot5 = &p4080mdio3;
+ emi1_rgmii = &p4080mdio0;
+ emi2_slot4 = &p4080xmdio1;
+ emi2_slot5 = &p4080xmdio3;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ usb0: usb@210000 {
+ phy_type = "ulpi";
+ };
+
+ usb1: usb@211000 {
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy2>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy3>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy10>;
+ phy-connection-type = "xgmii";
+ };
+ };
+
+ fman@500000 {
+ ethernet@e0000 {
+ phy-handle = <&phy5>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy6>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy7>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy8>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy11>;
+ phy-connection-type = "xgmii";
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,p4080ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-gpio", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ gpios = <&gpio0 1 0>, <&gpio0 0 0>;
+
+ p4080mdio0: mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ phyrgmii: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+
+ p4080mdio1: mdio@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ phy5: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy6: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy7: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy8: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ p4080mdio2: mdio@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "disabled";
+
+ phy5slot3: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy6slot3: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy7slot3: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy8slot3: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ p4080mdio3: mdio@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ phy0: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy1: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy2: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy3: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+
+ mdio-mux-emi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-gpio", "mdio-mux";
+ mdio-parent-bus = <&xmdio0>;
+ gpios = <&gpio0 3 0>, <&gpio0 2 0>;
+
+ p4080xmdio1: mdio@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ phy11: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+
+ p4080xmdio3: mdio@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ phy10: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x4>;
+ };
+ };
+ };
+};
+
+/include/ "p4080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
index dfc76bc..a025208 100644
--- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
@@ -1,7 +1,7 @@
/*
* P4080/P4040 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2011 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -513,4 +513,50 @@ crypto: crypto@300000 {
/include/ "qoriq-qman1.dtsi"
/include/ "qoriq-bman1.dtsi"
+
+/include/ "qoriq-fman-0.dtsi"
+/include/ "qoriq-fman-0-1g-0.dtsi"
+/include/ "qoriq-fman-0-1g-1.dtsi"
+/include/ "qoriq-fman-0-1g-2.dtsi"
+/include/ "qoriq-fman-0-1g-3.dtsi"
+/include/ "qoriq-fman-0-10g-0.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@f0000 {
+ };
+ };
+
+/include/ "qoriq-fman-1.dtsi"
+/include/ "qoriq-fman-1-1g-0.dtsi"
+/include/ "qoriq-fman-1-1g-1.dtsi"
+/include/ "qoriq-fman-1-1g-2.dtsi"
+/include/ "qoriq-fman-1-1g-3.dtsi"
+/include/ "qoriq-fman-1-10g-0.dtsi"
+ fman@500000 {
+ enet5: ethernet@e0000 {
+ };
+
+ enet6: ethernet@e2000 {
+ };
+
+ enet7: ethernet@e4000 {
+ };
+
+ enet8: ethernet@e6000 {
+ };
+
+ enet9: ethernet@f0000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
index 38bde09..d56a546 100644
--- a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* P4080/P4040 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -72,6 +72,19 @@
rtic_c = &rtic_c;
rtic_d = &rtic_d;
sec_mon = &sec_mon;
+
+ fman0 = &fman0;
+ fman1 = &fman1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ ethernet6 = &enet6;
+ ethernet7 = &enet7;
+ ethernet8 = &enet8;
+ ethernet9 = &enet9;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/p5020ds.dts b/arch/powerpc/boot/dts/fsl/p5020ds.dts
new file mode 100644
index 0000000..cd6f373
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p5020ds.dts
@@ -0,0 +1,394 @@
+/*
+ * P5020DS Device Tree Source
+ *
+ * Copyright 2010 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "p5020si-pre.dtsi"
+
+/ {
+ model = "fsl,P5020DS";
+ compatible = "fsl,P5020DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_1c = &phy_sgmii_1c;
+ phy_sgmii_1d = &phy_sgmii_1d;
+ phy_sgmii_1e = &phy_sgmii_1e;
+ phy_sgmii_1f = &phy_sgmii_1f;
+ phy_xgmii_1 = &phy_xgmii_1;
+ phy_xgmii_2 = &phy_xgmii_2;
+ emi1_rgmii = &hydra_mdio_rgmii;
+ emi1_sgmii = &hydra_mdio_sgmii;
+ emi2_xgmii = &hydra_mdio_xgmii;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ ina220@44 {
+ compatible = "ti,ina220";
+ reg = <0x44>;
+ shunt-resistor = <1000>;
+ };
+ ina220@45 {
+ compatible = "ti,ina220";
+ reg = <0x45>;
+ shunt-resistor = <1000>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_1c>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy_sgmii_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xgmii_1>;
+ phy-connection-type = "xgmii";
+ };
+
+ hydra_mdio_xgmii: mdio@f1000 {
+ status = "disabled";
+
+ phy_xgmii_1: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x4>;
+ };
+
+ phy_xgmii_2: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xffa00000 0x00040000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x30>;
+ ranges = <0 3 0 0x30>;
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ reg = <9 1>;
+ mux-mask = <0x78>;
+
+ hydra_mdio_rgmii: rgmii-mdio@8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <8>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ hydra_mdio_sgmii: sgmii-mdio@28 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x28>;
+ status = "disabled";
+
+ phy_sgmii_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe203000 {
+ reg = <0xf 0xfe203000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p5020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
index b77923a..cd008cd 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
@@ -1,7 +1,7 @@
/*
* P5020/5010 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2011 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -448,4 +448,31 @@
raideng@320000 {
fsl,iommu-parent = <&pamu1>;
};
+
+/include/ "qoriq-fman-0.dtsi"
+/include/ "qoriq-fman-0-1g-0.dtsi"
+/include/ "qoriq-fman-0-1g-1.dtsi"
+/include/ "qoriq-fman-0-1g-2.dtsi"
+/include/ "qoriq-fman-0-1g-3.dtsi"
+/include/ "qoriq-fman-0-1g-4.dtsi"
+/include/ "qoriq-fman-0-10g-0.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@f0000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
index 1cc61e1..bfba0b4 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* P5020/P5010 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -79,6 +79,14 @@
raideng_jr1 = &raideng_jr1;
raideng_jr2 = &raideng_jr2;
raideng_jr3 = &raideng_jr3;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/p5040ds.dts b/arch/powerpc/boot/dts/fsl/p5040ds.dts
new file mode 100644
index 0000000..4508473
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p5040ds.dts
@@ -0,0 +1,486 @@
+/*
+ * P5040DS Device Tree Source
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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/ "p5040si-pre.dtsi"
+
+/ {
+ model = "fsl,P5040DS";
+ compatible = "fsl,P5040DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases{
+ phy_sgmii_slot2_1c = &phy_sgmii_slot2_1c;
+ phy_sgmii_slot2_1d = &phy_sgmii_slot2_1d;
+ phy_sgmii_slot2_1e = &phy_sgmii_slot2_1e;
+ phy_sgmii_slot2_1f = &phy_sgmii_slot2_1f;
+ phy_sgmii_slot3_1c = &phy_sgmii_slot3_1c;
+ phy_sgmii_slot3_1d = &phy_sgmii_slot3_1d;
+ phy_sgmii_slot3_1e = &phy_sgmii_slot3_1e;
+ phy_sgmii_slot3_1f = &phy_sgmii_slot3_1f;
+ phy_sgmii_slot5_1c = &phy_sgmii_slot5_1c;
+ phy_sgmii_slot5_1d = &phy_sgmii_slot5_1d;
+ phy_sgmii_slot5_1e = &phy_sgmii_slot5_1e;
+ phy_sgmii_slot5_1f = &phy_sgmii_slot5_1f;
+ phy_sgmii_slot6_1c = &phy_sgmii_slot6_1c;
+ phy_sgmii_slot6_1d = &phy_sgmii_slot6_1d;
+ phy_sgmii_slot6_1e = &phy_sgmii_slot6_1e;
+ phy_sgmii_slot6_1f = &phy_sgmii_slot6_1f;
+ hydra_rg = &hydra_rg;
+ hydra_sg_slot2 = &hydra_sg_slot2;
+ hydra_sg_slot3 = &hydra_sg_slot3;
+ hydra_sg_slot5 = &hydra_sg_slot5;
+ hydra_sg_slot6 = &hydra_sg_slot6;
+ hydra_xg_slot1 = &hydra_xg_slot1;
+ hydra_xg_slot2 = &hydra_xg_slot2;
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x200000>;
+ };
+
+ qportals: qman-portals@ff4200000 {
+ ranges = <0x0 0xf 0xf4200000 0x200000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ ina220@44 {
+ compatible = "ti,ina220";
+ reg = <0x44>;
+ shunt-resistor = <1000>;
+ };
+ ina220@45 {
+ compatible = "ti,ina220";
+ reg = <0x45>;
+ shunt-resistor = <1000>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xgmii_slot_2>;
+ phy-connection-type = "xgmii";
+ };
+ };
+
+ fman@500000 {
+ ethernet@e0000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xgmii_slot_1>;
+ phy-connection-type = "xgmii";
+ };
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xffa00000 0x00040000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x01000000>;
+ };
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x40>;
+ ranges = <0 3 0 0x40>;
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ reg = <9 1>;
+ mux-mask = <0x78>;
+
+ hydra_rg:rgmii-mdio@8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <8>;
+ status = "disabled";
+
+ phy_rgmii_0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy_rgmii_1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ hydra_sg_slot2: sgmii-mdio@28 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x28>;
+ status = "disabled";
+
+ phy_sgmii_slot2_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_slot2_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_slot2_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_slot2_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ hydra_sg_slot3: sgmii-mdio@68 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x68>;
+ status = "disabled";
+
+ phy_sgmii_slot3_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_slot3_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_slot3_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_slot3_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ hydra_sg_slot5: sgmii-mdio@38 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x38>;
+ status = "disabled";
+
+ phy_sgmii_slot5_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_slot5_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_slot5_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_slot5_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ hydra_sg_slot6: sgmii-mdio@48 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x48>;
+ status = "disabled";
+
+ phy_sgmii_slot6_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_slot6_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_slot6_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_slot6_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+
+ mdio-mux-emi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&xmdio0>;
+ reg = <9 1>;
+ mux-mask = <0x06>;
+
+ hydra_xg_slot1: hydra-xg-slot1@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "disabled";
+
+ phy_xgmii_slot_1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <4>;
+ };
+ };
+
+ hydra_xg_slot2: hydra-xg-slot2@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ phy_xgmii_slot_2: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "p5040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
index 6d21452..e2bd931 100644
--- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
@@ -1,7 +1,7 @@
/*
* P5040 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -420,6 +420,61 @@
fsl,iommu-parent = <&pamu4>;
};
+/include/ "qoriq-raid1.0-0.dtsi"
/include/ "qoriq-qman1.dtsi"
/include/ "qoriq-bman1.dtsi"
+
+/include/ "qoriq-fman-0.dtsi"
+/include/ "qoriq-fman-0-1g-0.dtsi"
+/include/ "qoriq-fman-0-1g-1.dtsi"
+/include/ "qoriq-fman-0-1g-2.dtsi"
+/include/ "qoriq-fman-0-1g-3.dtsi"
+/include/ "qoriq-fman-0-1g-4.dtsi"
+/include/ "qoriq-fman-0-10g-0.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@f0000 {
+ };
+ };
+
+/include/ "qoriq-fman-1.dtsi"
+/include/ "qoriq-fman-1-1g-0.dtsi"
+/include/ "qoriq-fman-1-1g-1.dtsi"
+/include/ "qoriq-fman-1-1g-2.dtsi"
+/include/ "qoriq-fman-1-1g-3.dtsi"
+/include/ "qoriq-fman-1-1g-4.dtsi"
+/include/ "qoriq-fman-1-10g-0.dtsi"
+ fman@500000 {
+ enet6: ethernet@e0000 {
+ };
+
+ enet7: ethernet@e2000 {
+ };
+
+ enet8: ethernet@e4000 {
+ };
+
+ enet9: ethernet@e6000 {
+ };
+
+ enet10: ethernet@e8000 {
+ };
+
+ enet11: ethernet@f0000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
index b048a2b..dbd5775 100644
--- a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* P5040 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2012 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -72,6 +72,27 @@
rtic_c = &rtic_c;
rtic_d = &rtic_d;
sec_mon = &sec_mon;
+
+ raideng = &raideng;
+ raideng_jr0 = &raideng_jr0;
+ raideng_jr1 = &raideng_jr1;
+ raideng_jr2 = &raideng_jr2;
+ raideng_jr3 = &raideng_jr3;
+
+ fman0 = &fman0;
+ fman1 = &fman1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ ethernet6 = &enet6;
+ ethernet7 = &enet7;
+ ethernet8 = &enet8;
+ ethernet9 = &enet9;
+ ethernet10 = &enet10;
+ ethernet11 = &enet11;
};
cpus {
diff --git a/arch/powerpc/boot/dts/fsl/ppa8548.dts b/arch/powerpc/boot/dts/fsl/ppa8548.dts
new file mode 100644
index 0000000..8f9ffbe
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/ppa8548.dts
@@ -0,0 +1,164 @@
+/*
+ * PPA8548 Device Tree Source (36-bit address map)
+ * Copyright 2013 Prodrive B.V.
+ *
+ * Based on:
+ * MPC8548 CDS Device Tree Source (36-bit address map)
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc8548si-pre.dtsi"
+
+/ {
+ model = "ppa8548";
+ compatible = "ppa8548";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0x0 0x40000000>;
+ };
+
+ lbc: localbus@fe0005000 {
+ reg = <0xf 0xe0005000 0 0x1000>;
+ ranges = <0x0 0x0 0xf 0xff800000 0x00800000>;
+ };
+
+ soc: soc8548@fe0000000 {
+ ranges = <0 0xf 0xe0000000 0x100000>;
+ };
+
+ pci0: pci@fe0008000 {
+ /* ppa8548 board doesn't support PCI */
+ status = "disabled";
+ };
+
+ pci1: pci@fe0009000 {
+ /* ppa8548 board doesn't support PCI */
+ status = "disabled";
+ };
+
+ pci2: pcie@fe000a000 {
+ /* ppa8548 board doesn't support PCI */
+ status = "disabled";
+ };
+
+ rio: rapidio@fe00c0000 {
+ reg = <0xf 0xe00c0000 0x0 0x11000>;
+ port1 {
+ ranges = <0x0 0x0 0x0 0x80000000 0x0 0x40000000>;
+ };
+ };
+};
+
+&lbc {
+ nor@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x00800000>;
+ bank-width = <2>;
+ device-width = <2>;
+
+ partition@0 {
+ reg = <0x0 0x7A0000>;
+ label = "user";
+ };
+
+ partition@7A0000 {
+ reg = <0x7A0000 0x20000>;
+ label = "env";
+ read-only;
+ };
+
+ partition@7C0000 {
+ reg = <0x7C0000 0x40000>;
+ label = "u-boot";
+ read-only;
+ };
+ };
+};
+
+&soc {
+ i2c@3000 {
+ rtc@6f {
+ compatible = "intersil,isl1208";
+ reg = <0x6f>;
+ };
+ };
+
+ i2c@3100 {
+ };
+
+ /*
+ * Only ethernet controller @25000 and @26000 are used.
+ * Use alias enet2 and enet3 for the remainig controllers,
+ * to stay compatible with mpc8548si-pre.dtsi.
+ */
+ enet2: ethernet@24000 {
+ status = "disabled";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@0 {
+ interrupts = <7 1 0 0>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <8 1 0 0>;
+ reg = <0x1>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy1>;
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@27000 {
+ status = "disabled";
+ };
+
+ mdio@27520 {
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ crypto@30000 {
+ status = "disabled";
+ };
+};
+
+/include/ "mpc8548si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
index 4ece1ed..88cd70d 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
@@ -32,13 +32,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-global-utilities@e1000 {
+clockgen: global-utilities@e1000 {
compatible = "fsl,qoriq-clockgen-1.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>;
clock-frequency = <0>;
#address-cells = <1>;
#size-cells = <1>;
+ #clock-cells = <2>;
sysclk: sysclk {
#clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
index 48e0b6e..6dfd7c5 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
@@ -32,12 +32,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-global-utilities@e1000 {
+clockgen: global-utilities@e1000 {
compatible = "fsl,qoriq-clockgen-2.0";
ranges = <0x0 0xe1000 0x1000>;
reg = <0xe1000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+ #clock-cells = <2>;
sysclk: sysclk {
#clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi
new file mode 100644
index 0000000..eb77675
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi
@@ -0,0 +1,62 @@
+/*
+ * QorIQ FMan 10g port #0 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x10: port@90000 {
+ cell-index = <0x10>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman0_tx_0x30: port@b0000 {
+ cell-index = <0x30>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xb0000 0x1000>;
+ };
+
+ ethernet@f0000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-xgec";
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>;
+ };
+
+ xmdio0: mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ interrupts = <101 2 0 0>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi
new file mode 100644
index 0000000..b965bc2
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi
@@ -0,0 +1,69 @@
+/*
+ * QorIQ FMan 1g port #0 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x08: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x88000 0x1000>;
+ };
+
+ fman0_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa8000 0x1000>;
+ };
+
+ ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
+ tbi-handle = <&tbi0>;
+ ptp-timer = <&ptp_timer0>;
+ };
+
+ mdio0: mdio@e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+ interrupts = <100 2 0 0>;
+
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi
new file mode 100644
index 0000000..9eb6e6d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #1 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x09: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x89000 0x1000>;
+ };
+
+ fman0_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa9000 0x1000>;
+ };
+
+ ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
+ tbi-handle = <&tbi1>;
+ ptp-timer = <&ptp_timer0>;
+ };
+
+ mdio@e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe3120 0xee0>;
+
+ tbi1: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi
new file mode 100644
index 0000000..092b899
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #2 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0a: port@8a000 {
+ cell-index = <0xa>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8a000 0x1000>;
+ };
+
+ fman0_tx_0x2a: port@aa000 {
+ cell-index = <0x2a>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xaa000 0x1000>;
+ };
+
+ ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe4000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>;
+ tbi-handle = <&tbi2>;
+ ptp-timer = <&ptp_timer0>;
+ };
+
+ mdio@e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe5120 0xee0>;
+
+ tbi2: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi
new file mode 100644
index 0000000..2df0dc8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #3 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0b: port@8b000 {
+ cell-index = <0xb>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8b000 0x1000>;
+ };
+
+ fman0_tx_0x2b: port@ab000 {
+ cell-index = <0x2b>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xab000 0x1000>;
+ };
+
+ ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe6000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>;
+ tbi-handle = <&tbi3>;
+ ptp-timer = <&ptp_timer0>;
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe7120 0xee0>;
+
+ tbi3: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi
new file mode 100644
index 0000000..5fceb24
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #4 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0c: port@8c000 {
+ cell-index = <0xc>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8c000 0x1000>;
+ };
+
+ fman0_tx_0x2c: port@ac000 {
+ cell-index = <0x2c>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xac000 0x1000>;
+ };
+
+ ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe8000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>;
+ tbi-handle = <&tbi4>;
+ ptp-timer = <&ptp_timer0>;
+ };
+
+ mdio@e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe9120 0xee0>;
+
+ tbi4: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
new file mode 100644
index 0000000..abd01d4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
@@ -0,0 +1,101 @@
+/*
+ * QorIQ FMan device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,fman";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ interrupts = <96 2 0 0>, <16 2 1 1>;
+ clocks = <&clockgen 3 0>;
+ clock-names = "fmanclk";
+ fsl,qman-channel-range = <0x40 0xc>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ fman0_oh_0x1: port@81000 {
+ cell-index = <0x1>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x81000 0x1000>;
+ };
+
+ fman0_oh_0x2: port@82000 {
+ cell-index = <0x2>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ fman0_oh_0x3: port@83000 {
+ cell-index = <0x3>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ fman0_oh_0x4: port@84000 {
+ cell-index = <0x4>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ fman0_oh_0x5: port@85000 {
+ cell-index = <0x5>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x85000 0x1000>;
+ status = "disabled";
+ };
+
+ fman0_oh_0x6: port@86000 {
+ cell-index = <0x6>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x86000 0x1000>;
+ status = "disabled";
+ };
+
+ fman0_oh_0x7: port@87000 {
+ cell-index = <0x7>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x87000 0x1000>;
+ status = "disabled";
+ };
+
+ ptp_timer0: ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi
new file mode 100644
index 0000000..83ae87b
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi
@@ -0,0 +1,61 @@
+/*
+ * QorIQ FMan 10g port #0 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x10: port@90000 {
+ cell-index = <0x10>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x90000 0x1000>;
+ };
+
+ fman1_tx_0x30: port@b0000 {
+ cell-index = <0x30>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xb0000 0x1000>;
+ };
+
+ ethernet@f0000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-xgec";
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi
new file mode 100644
index 0000000..b0f0e36
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #0 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x08: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x88000 0x1000>;
+ };
+
+ fman1_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa8000 0x1000>;
+ };
+
+ ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>;
+ tbi-handle = <&tbi5>;
+ ptp-timer = <&ptp_timer1>;
+ };
+
+ mdio@e1120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe1120 0xee0>;
+
+ tbi5: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi
new file mode 100644
index 0000000..a3a79f8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #1 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x09: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x89000 0x1000>;
+ };
+
+ fman1_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xa9000 0x1000>;
+ };
+
+ ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>;
+ tbi-handle = <&tbi6>;
+ ptp-timer = <&ptp_timer1>;
+ };
+
+ mdio@e3120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe3120 0xee0>;
+
+ tbi6: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi
new file mode 100644
index 0000000..96a69a8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #2 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0a: port@8a000 {
+ cell-index = <0xa>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8a000 0x1000>;
+ };
+
+ fman1_tx_0x2a: port@aa000 {
+ cell-index = <0x2a>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xaa000 0x1000>;
+ };
+
+ ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe4000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>;
+ tbi-handle = <&tbi7>;
+ ptp-timer = <&ptp_timer1>;
+ };
+
+ mdio@e5120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe5120 0xee0>;
+
+ tbi7: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi
new file mode 100644
index 0000000..7405d19
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #3 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0b: port@8b000 {
+ cell-index = <0xb>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8b000 0x1000>;
+ };
+
+ fman1_tx_0x2b: port@ab000 {
+ cell-index = <0x2b>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xab000 0x1000>;
+ };
+
+ ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe6000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>;
+ tbi-handle = <&tbi8>;
+ ptp-timer = <&ptp_timer1>;
+ };
+
+ mdio@e7120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe7120 0xee0>;
+
+ tbi8: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi
new file mode 100644
index 0000000..f49ad69
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan 1g port #4 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0c: port@8c000 {
+ cell-index = <0xc>;
+ compatible = "fsl,fman-v2-port-rx";
+ reg = <0x8c000 0x1000>;
+ };
+
+ fman1_tx_0x2c: port@ac000 {
+ cell-index = <0x2c>;
+ compatible = "fsl,fman-v2-port-tx";
+ reg = <0xac000 0x1000>;
+ };
+
+ ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,fman-dtsec";
+ reg = <0xe8000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>;
+ tbi-handle = <&tbi9>;
+ ptp-timer = <&ptp_timer1>;
+ };
+
+ mdio@e9120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-mdio";
+ reg = <0xe9120 0xee0>;
+
+ tbi9: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
new file mode 100644
index 0000000..debea75
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
@@ -0,0 +1,101 @@
+/*
+ * QorIQ FMan device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2011 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman1: fman@500000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ compatible = "fsl,fman";
+ ranges = <0 0x500000 0x100000>;
+ reg = <0x500000 0x100000>;
+ interrupts = <97 2 0 0>, <16 2 1 0>;
+ clocks = <&clockgen 3 1>;
+ clock-names = "fmanclk";
+ fsl,qman-channel-range = <0x60 0xc>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x28000>;
+ };
+
+ fman1_oh_0x1: port@81000 {
+ cell-index = <0x1>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x81000 0x1000>;
+ };
+
+ fman1_oh_0x2: port@82000 {
+ cell-index = <0x2>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ fman1_oh_0x3: port@83000 {
+ cell-index = <0x3>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ fman1_oh_0x4: port@84000 {
+ cell-index = <0x4>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ fman1_oh_0x5: port@85000 {
+ cell-index = <0x5>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x85000 0x1000>;
+ status = "disabled";
+ };
+
+ fman1_oh_0x6: port@86000 {
+ cell-index = <0x6>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x86000 0x1000>;
+ status = "disabled";
+ };
+
+ fman1_oh_0x7: port@87000 {
+ cell-index = <0x7>;
+ compatible = "fsl,fman-v2-port-oh";
+ reg = <0x87000 0x1000>;
+ status = "disabled";
+ };
+
+ ptp_timer1: ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi
new file mode 100644
index 0000000..e1a961f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi
@@ -0,0 +1,71 @@
+/*
+ * QorIQ FMan v3 1g port #0 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x08: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x88000 0x1000>;
+ fsl,fman-10g-port;
+ fsl,fman-best-effort-port;
+ };
+
+ fman0_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa8000 0x1000>;
+ fsl,fman-10g-port;
+ fsl,fman-best-effort-port;
+ };
+
+ ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy0>;
+ };
+
+ mdio@e1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe1000 0x1000>;
+
+ pcsphy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi
new file mode 100644
index 0000000..c288f3c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan v3 10g port #0 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x10: port@90000 {
+ cell-index = <0x10>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x90000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ fman0_tx_0x30: port@b0000 {
+ cell-index = <0x30>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ ethernet@f0000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-memac";
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>;
+ pcsphy-handle = <&pcsphy6>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+
+ pcsphy6: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi
new file mode 100644
index 0000000..94f3e71
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi
@@ -0,0 +1,71 @@
+/*
+ * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x09: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x89000 0x1000>;
+ fsl,fman-10g-port;
+ fsl,fman-best-effort-port;
+ };
+
+ fman0_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa9000 0x1000>;
+ fsl,fman-10g-port;
+ fsl,fman-best-effort-port;
+ };
+
+ ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy1>;
+ };
+
+ mdio@e3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe3000 0x1000>;
+
+ pcsphy1: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi
new file mode 100644
index 0000000..94a7698
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan v3 10g port #1 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x11: port@91000 {
+ cell-index = <0x11>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x91000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ fman0_tx_0x31: port@b1000 {
+ cell-index = <0x31>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xb1000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ ethernet@f2000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-memac";
+ reg = <0xf2000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>;
+ pcsphy-handle = <&pcsphy7>;
+ };
+
+ mdio@f3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xf3000 0x1000>;
+
+ pcsphy7: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi
new file mode 100644
index 0000000..b5ff5f7
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #0 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x08: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x88000 0x1000>;
+ };
+
+ fman0_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa8000 0x1000>;
+ };
+
+ ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy0>;
+ };
+
+ mdio@e1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe1000 0x1000>;
+
+ pcsphy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi
new file mode 100644
index 0000000..ee44182
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x09: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x89000 0x1000>;
+ };
+
+ fman0_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa9000 0x1000>;
+ };
+
+ ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy1>;
+ };
+
+ mdio@e3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe3000 0x1000>;
+
+ pcsphy1: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi
new file mode 100644
index 0000000..f05f0d7
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #2 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0a: port@8a000 {
+ cell-index = <0xa>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8a000 0x1000>;
+ };
+
+ fman0_tx_0x2a: port@aa000 {
+ cell-index = <0x2a>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xaa000 0x1000>;
+ };
+
+ ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe4000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy2>;
+ };
+
+ mdio@e5000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe5000 0x1000>;
+
+ pcsphy2: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi
new file mode 100644
index 0000000..a9114ec
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #3 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0b: port@8b000 {
+ cell-index = <0xb>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8b000 0x1000>;
+ };
+
+ fman0_tx_0x2b: port@ab000 {
+ cell-index = <0x2b>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xab000 0x1000>;
+ };
+
+ ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe6000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy3>;
+ };
+
+ mdio@e7000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe7000 0x1000>;
+
+ pcsphy3: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi
new file mode 100644
index 0000000..44dd00a
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #4 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0c: port@8c000 {
+ cell-index = <0xc>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8c000 0x1000>;
+ };
+
+ fman0_tx_0x2c: port@ac000 {
+ cell-index = <0x2c>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xac000 0x1000>;
+ };
+
+ ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe8000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy4>;
+ };
+
+ mdio@e9000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe9000 0x1000>;
+
+ pcsphy4: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi
new file mode 100644
index 0000000..5b1b84b
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #5 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@400000 {
+ fman0_rx_0x0d: port@8d000 {
+ cell-index = <0xd>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8d000 0x1000>;
+ };
+
+ fman0_tx_0x2d: port@ad000 {
+ cell-index = <0x2d>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xad000 0x1000>;
+ };
+
+ ethernet@ea000 {
+ cell-index = <5>;
+ compatible = "fsl,fman-memac";
+ reg = <0xea000 0x1000>;
+ fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>;
+ ptp-timer = <&ptp_timer0>;
+ pcsphy-handle = <&pcsphy5>;
+ };
+
+ mdio@eb000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xeb000 0x1000>;
+
+ pcsphy5: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
new file mode 100644
index 0000000..3a20e0d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
@@ -0,0 +1,106 @@
+/*
+ * QorIQ FMan v3 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,fman";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ interrupts = <96 2 0 0>, <16 2 1 1>;
+ clocks = <&clockgen 3 0>;
+ clock-names = "fmanclk";
+ fsl,qman-channel-range = <0x800 0x10>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x60000>;
+ };
+
+ fman0_oh_0x2: port@82000 {
+ cell-index = <0x2>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ fman0_oh_0x3: port@83000 {
+ cell-index = <0x3>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ fman0_oh_0x4: port@84000 {
+ cell-index = <0x4>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ fman0_oh_0x5: port@85000 {
+ cell-index = <0x5>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x85000 0x1000>;
+ };
+
+ fman0_oh_0x6: port@86000 {
+ cell-index = <0x6>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x86000 0x1000>;
+ };
+
+ fman0_oh_0x7: port@87000 {
+ cell-index = <0x7>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ mdio0: mdio@fc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfc000 0x1000>;
+ };
+
+ xmdio0: mdio@fd000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfd000 0x1000>;
+ };
+
+ ptp_timer0: ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi
new file mode 100644
index 0000000..0e1daae
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan v3 10g port #0 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x10: port@90000 {
+ cell-index = <0x10>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x90000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ fman1_tx_0x30: port@b0000 {
+ cell-index = <0x30>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xb0000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ ethernet@f0000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-memac";
+ reg = <0xf0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>;
+ pcsphy-handle = <&pcsphy14>;
+ };
+
+ mdio@f1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xf1000 0x1000>;
+
+ pcsphy14: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi
new file mode 100644
index 0000000..68c5ef7
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi
@@ -0,0 +1,68 @@
+/*
+ * QorIQ FMan v3 10g port #1 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x11: port@91000 {
+ cell-index = <0x11>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x91000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ fman1_tx_0x31: port@b1000 {
+ cell-index = <0x31>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xb1000 0x1000>;
+ fsl,fman-10g-port;
+ };
+
+ ethernet@f2000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-memac";
+ reg = <0xf2000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>;
+ pcsphy-handle = <&pcsphy15>;
+ };
+
+ mdio@f3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xf3000 0x1000>;
+
+ pcsphy15: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi
new file mode 100644
index 0000000..605363c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #0 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x08: port@88000 {
+ cell-index = <0x8>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x88000 0x1000>;
+ };
+
+ fman1_tx_0x28: port@a8000 {
+ cell-index = <0x28>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa8000 0x1000>;
+ };
+
+ ethernet@e0000 {
+ cell-index = <0>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe0000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy8>;
+ };
+
+ mdio@e1000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe1000 0x1000>;
+
+ pcsphy8: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi
new file mode 100644
index 0000000..1955dfa
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x09: port@89000 {
+ cell-index = <0x9>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x89000 0x1000>;
+ };
+
+ fman1_tx_0x29: port@a9000 {
+ cell-index = <0x29>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xa9000 0x1000>;
+ };
+
+ ethernet@e2000 {
+ cell-index = <1>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe2000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy9>;
+ };
+
+ mdio@e3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe3000 0x1000>;
+
+ pcsphy9: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi
new file mode 100644
index 0000000..2c14764
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #2 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0a: port@8a000 {
+ cell-index = <0xa>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8a000 0x1000>;
+ };
+
+ fman1_tx_0x2a: port@aa000 {
+ cell-index = <0x2a>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xaa000 0x1000>;
+ };
+
+ ethernet@e4000 {
+ cell-index = <2>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe4000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy10>;
+ };
+
+ mdio@e5000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe5000 0x1000>;
+
+ pcsphy10: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi
new file mode 100644
index 0000000..b8b541f
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #3 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0b: port@8b000 {
+ cell-index = <0xb>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8b000 0x1000>;
+ };
+
+ fman1_tx_0x2b: port@ab000 {
+ cell-index = <0x2b>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xab000 0x1000>;
+ };
+
+ ethernet@e6000 {
+ cell-index = <3>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe6000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy11>;
+ };
+
+ mdio@e7000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe7000 0x1000>;
+
+ pcsphy11: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi
new file mode 100644
index 0000000..4b2cfdd
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #4 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0c: port@8c000 {
+ cell-index = <0xc>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8c000 0x1000>;
+ };
+
+ fman1_tx_0x2c: port@ac000 {
+ cell-index = <0x2c>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xac000 0x1000>;
+ };
+
+ ethernet@e8000 {
+ cell-index = <4>;
+ compatible = "fsl,fman-memac";
+ reg = <0xe8000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy12>;
+ };
+
+ mdio@e9000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xe9000 0x1000>;
+
+ pcsphy12: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi
new file mode 100644
index 0000000..0a52ddf
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi
@@ -0,0 +1,67 @@
+/*
+ * QorIQ FMan v3 1g port #5 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman@500000 {
+ fman1_rx_0x0d: port@8d000 {
+ cell-index = <0xd>;
+ compatible = "fsl,fman-v3-port-rx";
+ reg = <0x8d000 0x1000>;
+ };
+
+ fman1_tx_0x2d: port@ad000 {
+ cell-index = <0x2d>;
+ compatible = "fsl,fman-v3-port-tx";
+ reg = <0xad000 0x1000>;
+ };
+
+ ethernet@ea000 {
+ cell-index = <5>;
+ compatible = "fsl,fman-memac";
+ reg = <0xea000 0x1000>;
+ fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>;
+ ptp-timer = <&ptp_timer1>;
+ pcsphy-handle = <&pcsphy13>;
+ };
+
+ mdio@eb000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xeb000 0x1000>;
+
+ pcsphy13: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
new file mode 100644
index 0000000..82750ac
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
@@ -0,0 +1,106 @@
+/*
+ * QorIQ FMan v3 device tree stub [ controller @ offset 0x500000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman1: fman@500000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ compatible = "fsl,fman";
+ ranges = <0 0x500000 0x100000>;
+ reg = <0x500000 0x100000>;
+ interrupts = <97 2 0 0>, <16 2 1 0>;
+ clocks = <&clockgen 3 1>;
+ clock-names = "fmanclk";
+ fsl,qman-channel-range = <0x820 0x10>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x60000>;
+ };
+
+ fman1_oh_0x2: port@82000 {
+ cell-index = <0x2>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ fman1_oh_0x3: port@83000 {
+ cell-index = <0x3>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ fman1_oh_0x4: port@84000 {
+ cell-index = <0x4>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ fman1_oh_0x5: port@85000 {
+ cell-index = <0x5>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x85000 0x1000>;
+ };
+
+ fman1_oh_0x6: port@86000 {
+ cell-index = <0x6>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x86000 0x1000>;
+ };
+
+ fman1_oh_0x7: port@87000 {
+ cell-index = <0x7>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x87000 0x1000>;
+ };
+
+ mdio1: mdio@fc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfc000 0x1000>;
+ };
+
+ mdio@fd000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfd000 0x1000>;
+ };
+
+ ptp_timer1: ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
new file mode 100644
index 0000000..7f60b60
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
@@ -0,0 +1,94 @@
+/*
+ * QorIQ FMan v3 device tree stub [ controller @ offset 0x400000 ]
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
+ */
+
+fman0: fman@400000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ compatible = "fsl,fman";
+ ranges = <0 0x400000 0x100000>;
+ reg = <0x400000 0x100000>;
+ interrupts = <96 2 0 0>, <16 2 1 1>;
+ clocks = <&clockgen 3 0>;
+ clock-names = "fmanclk";
+ fsl,qman-channel-range = <0x800 0x10>;
+
+ muram@0 {
+ compatible = "fsl,fman-muram";
+ reg = <0x0 0x30000>;
+ };
+
+ fman0_oh_0x2: port@82000 {
+ cell-index = <0x2>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x82000 0x1000>;
+ };
+
+ fman0_oh_0x3: port@83000 {
+ cell-index = <0x3>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x83000 0x1000>;
+ };
+
+ fman0_oh_0x4: port@84000 {
+ cell-index = <0x4>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x84000 0x1000>;
+ };
+
+ fman0_oh_0x5: port@85000 {
+ cell-index = <0x5>;
+ compatible = "fsl,fman-v3-port-oh";
+ reg = <0x85000 0x1000>;
+ };
+
+ mdio0: mdio@fc000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfc000 0x1000>;
+ };
+
+ xmdio0: mdio@fd000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+ reg = <0xfd000 0x1000>;
+ };
+
+ ptp_timer0: ptp-timer@fe000 {
+ compatible = "fsl,fman-ptp-timer";
+ reg = <0xfe000 0x1000>;
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/sbc8641d.dts b/arch/powerpc/boot/dts/fsl/sbc8641d.dts
new file mode 100644
index 0000000..0a9733c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/sbc8641d.dts
@@ -0,0 +1,203 @@
+/*
+ * SBC8641D Device Tree Source
+ *
+ * Copyright 2008 Wind River Systems Inc.
+ *
+ * Paul Gortmaker (see MAINTAINERS for contact information)
+ *
+ * Based largely on the mpc8641_hpcn.dts by 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/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "SBC8641D";
+ compatible = "wind,sbc8641";
+
+ aliases {
+ pci1 = &pci1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>; // 512M at 0x0
+ };
+
+ lbc: localbus@f8005000 {
+ reg = <0xf8005000 0x1000>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xf0000000 0x00010000 // 64KB EEPROM
+ 2 0 0xf1000000 0x00100000 // EPLD (1MB)
+ 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3)
+ 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4)
+ 6 0 0xf4000000 0x00100000 // LCD display (1MB)
+ 7 0 0xe8000000 0x04000000>; // 64MB OneNAND
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x01000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "dtb";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@300000 {
+ label = "kernel";
+ reg = <0x00100000 0x00400000>;
+ read-only;
+ };
+ partition@400000 {
+ label = "fs";
+ reg = <0x00500000 0x00a00000>;
+ };
+ partition@700000 {
+ label = "firmware";
+ reg = <0x00f00000 0x00100000>;
+ read-only;
+ };
+ };
+
+ epld@2,0 {
+ compatible = "wrs,epld-localbus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ reg = <2 0 0x100000>;
+ ranges = <0 0 5 0 1 // User switches
+ 1 0 5 1 1 // Board ID/Rev
+ 3 0 5 3 1>; // LEDs
+ };
+ };
+
+ soc: soc@f8000000 {
+ ranges = <0x00000000 0xf8000000 0x00100000>;
+
+ enet0: ethernet@24000 {
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ phy2: ethernet-phy@1 {
+ reg = <1>;
+ };
+ phy3: ethernet-phy@2 {
+ reg = <2>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet1: ethernet@25000 {
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@25520 {
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet2: ethernet@26000 {
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet3: ethernet@27000 {
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@27520 {
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ pci0: pcie@f8008000 {
+ reg = <0xf8008000 0x1000>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+ interrupt-map-mask = <0xff00 0 0 7>;
+
+ pcie@0 {
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00100000>;
+ };
+
+ };
+
+ pci1: pcie@f8009000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf8009000 0x1000>;
+ bus-range = <0 0xff>;
+ ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
+ clock-frequency = <100000000>;
+ interrupts = <25 2 0 0>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0x0000 0 0 1 &mpic 4 1
+ 0x0000 0 0 2 &mpic 5 1
+ 0x0000 0 0 3 &mpic 6 1
+ 0x0000 0 0 4 &mpic 7 1
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0xa0000000
+ 0x02000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00100000>;
+ };
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
new file mode 100644
index 0000000..2975762
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts
@@ -0,0 +1,203 @@
+/*
+ * T1023 RDB Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t102xsi-pre.dtsi"
+
+/ {
+ model = "fsl,T1023RDB";
+ compatible = "fsl,T1023RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 1 0 0xf 0xff800000 0x00010000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x1 0x0 0x10000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>; /* input clk */
+ };
+ };
+
+ i2c@118000 {
+ eeprom@50 {
+ compatible = "st,m24256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ interrupts = <0x5 0x1 0 0>;
+ };
+ };
+
+ i2c@118100 {
+ current-sensor@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ current-sensor@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ fman@400000 {
+ fm1mac1: ethernet@e0000 {
+ phy-handle = <&sgmii_rtk_phy2>;
+ phy-connection-type = "sgmii";
+ sleep = <&rcpm 0x80000000>;
+ };
+
+ fm1mac2: ethernet@e2000 {
+ sleep = <&rcpm 0x40000000>;
+ };
+
+ fm1mac3: ethernet@e4000 {
+ phy-handle = <&sgmii_aqr_phy3>;
+ phy-connection-type = "sgmii-2500";
+ sleep = <&rcpm 0x20000000>;
+ };
+
+ fm1mac4: ethernet@e6000 {
+ phy-handle = <&rgmii_rtk_phy1>;
+ phy-connection-type = "rgmii";
+ sleep = <&rcpm 0x10000000>;
+ };
+
+
+ mdio0: mdio@fc000 {
+ rgmii_rtk_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ sgmii_rtk_phy2: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ };
+
+ xmdio0: mdio@fd000 {
+ sgmii_aqr_phy3: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x2>;
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+#include "t1023si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index df1f068..99e421d 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -32,6 +32,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <dt-bindings/thermal/thermal.h>
+
&ifc {
#address-cells = <2>;
#size-cells = <1>;
@@ -275,6 +277,90 @@
reg = <0xea000 0x4000>;
};
+ tmu: tmu@f0000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0xf0000 0x1000>;
+ interrupts = <18 2 0 0>;
+ fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x30061>;
+ fsl,tmu-calibration = <0x00000000 0x0000000f
+ 0x00000001 0x00000017
+ 0x00000002 0x0000001e
+ 0x00000003 0x00000026
+ 0x00000004 0x0000002e
+ 0x00000005 0x00000035
+ 0x00000006 0x0000003d
+ 0x00000007 0x00000044
+ 0x00000008 0x0000004c
+ 0x00000009 0x00000053
+ 0x0000000a 0x0000005b
+ 0x0000000b 0x00000064
+
+ 0x00010000 0x00000011
+ 0x00010001 0x0000001c
+ 0x00010002 0x00000024
+ 0x00010003 0x0000002b
+ 0x00010004 0x00000034
+ 0x00010005 0x00000039
+ 0x00010006 0x00000042
+ 0x00010007 0x0000004c
+ 0x00010008 0x00000051
+ 0x00010009 0x0000005a
+ 0x0001000a 0x00000063
+
+ 0x00020000 0x00000013
+ 0x00020001 0x00000019
+ 0x00020002 0x00000024
+ 0x00020003 0x0000002c
+ 0x00020004 0x00000035
+ 0x00020005 0x0000003d
+ 0x00020006 0x00000046
+ 0x00020007 0x00000050
+ 0x00020008 0x00000059
+
+ 0x00030000 0x00000002
+ 0x00030001 0x0000000d
+ 0x00030002 0x00000019
+ 0x00030003 0x00000024>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&tmu>;
+
+ trips {
+ cpu_alert: cpu-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit: cpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu1 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
scfg: global-utilities@fc000 {
compatible = "fsl,t1023-scfg";
reg = <0xfc000 0x1000>;
@@ -327,4 +413,23 @@
};
/include/ "qoriq-sec5.0-0.dtsi"
+
+/include/ "qoriq-fman3l-0.dtsi"
+/include/ "qoriq-fman3-0-10g-0-best-effort.dtsi"
+/include/ "qoriq-fman3-0-1g-1.dtsi"
+/include/ "qoriq-fman3-0-1g-2.dtsi"
+/include/ "qoriq-fman3-0-1g-3.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/t1024qds.dts b/arch/powerpc/boot/dts/fsl/t1024qds.dts
new file mode 100644
index 0000000..772143d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1024qds.dts
@@ -0,0 +1,251 @@
+/*
+ * T1024 QDS Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t102xsi-pre.dtsi"
+
+/ {
+ model = "fsl,T1024QDS";
+ compatible = "fsl,T1024QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,tetra-fpga", "fsl,fpga-qixis";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+
+ flash@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040", "jedec,spi-nor"; /* 512KB */
+ reg = <1>;
+ spi-max-frequency = <10000000>;
+ };
+
+ flash@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "eon,en25s64", "jedec,spi-nor"; /* 8MB */
+ reg = <2>;
+ spi-max-frequency = <10000000>;
+ };
+
+ slic@2 {
+ compatible = "maxim,ds26522";
+ reg = <2>;
+ spi-max-frequency = <2000000>;
+ };
+
+ slic@3 {
+ compatible = "maxim,ds26522";
+ reg = <3>;
+ spi-max-frequency = <2000000>;
+ };
+ };
+
+ i2c@118000 {
+ pca9547@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c512";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c02";
+ reg = <0x57>;
+ };
+ };
+
+ 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>;
+
+ adt7461@4c {
+ /* Thermal Monitor */
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ eeprom@55 {
+ compatible = "atmel,24c02";
+ reg = <0x55>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c512";
+ reg = <0x56>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c512";
+ reg = <0x57>;
+ };
+ };
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x5 0x1 0 0>;
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+#include "t1024si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
new file mode 100644
index 0000000..302cdd2
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts
@@ -0,0 +1,236 @@
+/*
+ * T1024 RDB Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t102xsi-pre.dtsi"
+
+/ {
+ model = "fsl,T1024RDB";
+ compatible = "fsl,T1024RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ board-control@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,t1024-cpld";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+ bank-width = <1>;
+ device-width = <1>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q512ax3", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>; /* input clk */
+ };
+
+ slic@1 {
+ compatible = "maxim,ds26522";
+ reg = <1>;
+ spi-max-frequency = <2000000>;
+ };
+
+ slic@2 {
+ compatible = "maxim,ds26522";
+ reg = <2>;
+ spi-max-frequency = <2000000>;
+ };
+ };
+
+ i2c@118000 {
+ adt7461@4c {
+ /* Thermal Monitor */
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ current-sensor@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ i2c@118100 {
+ pca9546@77 {
+ compatible = "nxp,pca9546";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ fman@400000 {
+ fm1mac1: ethernet@e0000 {
+ phy-handle = <&xg_aqr105_phy3>;
+ phy-connection-type = "xgmii";
+ sleep = <&rcpm 0x80000000>;
+ };
+
+ fm1mac2: ethernet@e2000 {
+ sleep = <&rcpm 0x40000000>;
+ };
+
+ fm1mac3: ethernet@e4000 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ sleep = <&rcpm 0x20000000>;
+ };
+
+ fm1mac4: ethernet@e6000 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ sleep = <&rcpm 0x10000000>;
+ };
+
+
+ mdio0: mdio@fc000 {
+ rgmii_phy1: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ rgmii_phy2: ethernet-phy@6 {
+ reg = <0x6>;
+ };
+ };
+
+ xmdio0: mdio@fd000 {
+ xg_aqr105_phy3: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x1>;
+ };
+ sg_2500_aqr105_phy4: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x2>;
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+#include "t1024si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi
index 95e3af8..bb48034 100644
--- a/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1024si-post.dtsi
@@ -32,7 +32,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/include/ "t1023si-post.dtsi"
+#include "t1023si-post.dtsi"
/ {
aliases {
diff --git a/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi
index 1f1a9f8..9d08a36 100644
--- a/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi
@@ -59,6 +59,12 @@
sdhc = &sdhc;
crypto = &crypto;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
};
cpus {
@@ -70,6 +76,7 @@
reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L2_1: l2-cache {
next-level-cache = <&cpc>;
};
@@ -79,6 +86,7 @@
reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_2>;
+ #cooling-cells = <2>;
L2_2: l2-cache {
next-level-cache = <&cpc>;
};
diff --git a/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts b/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts
new file mode 100644
index 0000000..fb6bc02
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1040d4rdb.dts
@@ -0,0 +1,46 @@
+/*
+ * T1040D4RDB Device Tree Source
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xd4rdb.dtsi"
+
+/ {
+ model = "fsl,T1040D4RDB";
+ compatible = "fsl,T1040D4RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+};
+
+#include "t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1040qds.dts b/arch/powerpc/boot/dts/fsl/t1040qds.dts
new file mode 100644
index 0000000..5f76edc
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1040qds.dts
@@ -0,0 +1,46 @@
+/*
+ * T1040QDS Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xqds.dtsi"
+
+/ {
+ model = "fsl,T1040QDS";
+ compatible = "fsl,T1040QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+};
+
+#include "t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
new file mode 100644
index 0000000..621f2c6
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
@@ -0,0 +1,78 @@
+/*
+ * T1040RDB Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xrdb.dtsi"
+
+/ {
+ model = "fsl,T1040RDB";
+ compatible = "fsl,T1040RDB";
+
+ aliases {
+ phy_sgmii_2 = &phy_sgmii_2;
+ };
+
+ soc@ffe000000 {
+ fman@400000 {
+ ethernet@e0000 {
+ fixed-link = <0 1 1000 0 0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_2>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@fc000 {
+ phy_sgmii_2: ethernet-phy@03 {
+ reg = <0x03>;
+ };
+ };
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ cpld@3,0 {
+ compatible = "fsl,t1040rdb-cpld";
+ };
+ };
+};
+
+#include "t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 9770d02..e0f4da5 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -32,6 +32,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <dt-bindings/thermal/thermal.h>
+
&bman_fbpr {
compatible = "fsl,bman-fbpr";
alloc-ranges = <0 0 0x10000 0>;
@@ -484,6 +486,98 @@
reg = <0xea000 0x4000>;
};
+ tmu: tmu@f0000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0xf0000 0x1000>;
+ interrupts = <18 2 0 0>;
+ fsl,tmu-range = <0xa0000 0x90026 0x8004a 0x1006a>;
+ fsl,tmu-calibration = <0x00000000 0x00000025
+ 0x00000001 0x00000028
+ 0x00000002 0x0000002d
+ 0x00000003 0x00000031
+ 0x00000004 0x00000036
+ 0x00000005 0x0000003a
+ 0x00000006 0x00000040
+ 0x00000007 0x00000044
+ 0x00000008 0x0000004a
+ 0x00000009 0x0000004f
+ 0x0000000a 0x00000054
+
+ 0x00010000 0x0000000d
+ 0x00010001 0x00000013
+ 0x00010002 0x00000019
+ 0x00010003 0x0000001f
+ 0x00010004 0x00000025
+ 0x00010005 0x0000002d
+ 0x00010006 0x00000033
+ 0x00010007 0x00000043
+ 0x00010008 0x0000004b
+ 0x00010009 0x00000053
+
+ 0x00020000 0x00000010
+ 0x00020001 0x00000017
+ 0x00020002 0x0000001f
+ 0x00020003 0x00000029
+ 0x00020004 0x00000031
+ 0x00020005 0x0000003c
+ 0x00020006 0x00000042
+ 0x00020007 0x0000004d
+ 0x00020008 0x00000056
+
+ 0x00030000 0x00000012
+ 0x00030001 0x0000001d>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&tmu>;
+
+ trips {
+ cpu_alert: cpu-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit: cpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu1 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map2 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu2 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ map3 {
+ trip = <&cpu_alert>;
+ cooling-device =
+ <&cpu3 THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
scfg: global-utilities@fc000 {
compatible = "fsl,t1040-scfg";
reg = <0xfc000 0x1000>;
@@ -547,4 +641,35 @@
/include/ "qoriq-sec5.0-0.dtsi"
/include/ "qoriq-qman3.dtsi"
/include/ "qoriq-bman1.dtsi"
+
+/include/ "qoriq-fman3l-0.dtsi"
+/include/ "qoriq-fman3-0-1g-0.dtsi"
+/include/ "qoriq-fman3-0-1g-1.dtsi"
+/include/ "qoriq-fman3-0-1g-2.dtsi"
+/include/ "qoriq-fman3-0-1g-3.dtsi"
+/include/ "qoriq-fman3-0-1g-4.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ mdio@fc000 {
+ interrupts = <100 1 0 0>;
+ };
+
+ mdio@fd000 {
+ status = "disabled";
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
new file mode 100644
index 0000000..2a5a90d
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
@@ -0,0 +1,53 @@
+/*
+ * T1042D4RDB Device Tree Source
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xd4rdb.dtsi"
+
+/ {
+ model = "fsl,T1042D4RDB";
+ compatible = "fsl,T1042D4RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ ifc: localbus@ffe124000 {
+ cpld@3,0 {
+ compatible = "fsl,t1040d4rdb-cpld",
+ "fsl,deepsleep-cpld";
+ };
+ };
+};
+
+#include "t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1042qds.dts b/arch/powerpc/boot/dts/fsl/t1042qds.dts
new file mode 100644
index 0000000..90a4a73
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1042qds.dts
@@ -0,0 +1,46 @@
+/*
+ * T1042QDS Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xqds.dtsi"
+
+/ {
+ model = "fsl,T1042QDS";
+ compatible = "fsl,T1042QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+};
+
+#include "t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
new file mode 100644
index 0000000..2c13862
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts
@@ -0,0 +1,76 @@
+/*
+ * T1042RDB Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xrdb.dtsi"
+
+/ {
+ model = "fsl,T1042RDB";
+ compatible = "fsl,T1042RDB";
+
+ aliases {
+ phy_sgmii_2 = &phy_sgmii_2;
+ };
+
+ soc@ffe000000 {
+ fman@400000 {
+ ethernet@e0000 {
+ status = "disabled";
+ };
+
+ ethernet@e2000 {
+ status = "disabled";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_sgmii_2>;
+ phy-connection-type = "sgmii";
+ };
+
+ mdio@fc000 {
+ phy_sgmii_2: ethernet-phy@03 {
+ reg = <0x03>;
+ };
+ };
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ cpld@3,0 {
+ compatible = "fsl,t1042rdb-cpld";
+ };
+ };
+};
+
+#include "t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
new file mode 100644
index 0000000..8ec3ff4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
@@ -0,0 +1,73 @@
+/*
+ * T1042RDB_PI Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t104xsi-pre.dtsi"
+/include/ "t104xrdb.dtsi"
+
+/ {
+ model = "fsl,T1042RDB_PI";
+ compatible = "fsl,T1042RDB_PI";
+
+ ifc: localbus@ffe124000 {
+ cpld@3,0 {
+ compatible = "fsl,t1042rdb_pi-cpld";
+ };
+ };
+
+ soc: soc@ffe000000 {
+ i2c@118000 {
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ interrupts = <0x2 0x1 0 0>;
+ };
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ status = "disabled";
+ };
+
+ ethernet@e2000 {
+ status = "disabled";
+ };
+
+ ethernet@e4000 {
+ status = "disabled";
+ };
+ };
+ };
+};
+
+#include "t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi
index 319b74f..a5544f9 100644
--- a/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi
@@ -32,6 +32,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/include/ "t1040si-post.dtsi"
+#include "t1040si-post.dtsi"
/* Place holder for ethernet related device tree nodes */
diff --git a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
new file mode 100644
index 0000000..8c7ea6c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
@@ -0,0 +1,215 @@
+/*
+ * T1040D4RDB/T1042D4RDB Device Tree Source
+ *
+ * Copyright 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ cpld@3,0 {
+ compatible = "fsl,t1040d4rdb-cpld";
+ reg = <3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q512ax3", "jedec,spi-nor";
+ reg = <0>;
+ /* input clock */
+ spi-max-frequency = <10000000>;
+ };
+ slic@1 {
+ compatible = "maxim,ds26522";
+ reg = <1>;
+ spi-max-frequency = <2000000>; /* input clock */
+ };
+ slic@2 {
+ compatible = "maxim,ds26522";
+ reg = <2>;
+ spi-max-frequency = <2000000>; /* input clock */
+ };
+ };
+ i2c@118000 {
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ interrupts = <0x2 0x1 0 0>;
+ };
+ };
+
+ i2c@118100 {
+ mux@77 {
+ /*
+ * Child nodes of mux depend on which i2c
+ * devices are connected via the mini PCI
+ * connector slot1, the mini PCI connector
+ * slot2, the HDMI connector, and the PEX
+ * slot. Systems with such devices attached
+ * should provide a wrapper .dts file that
+ * includes this one, and adds those nodes
+ */
+ compatible = "nxp,pca9546";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x0 0x0 0x10000000
+ 0x01000000 0 0x0 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
+ 0x01000000 0 0 0xf 0xf8010000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
new file mode 100644
index 0000000..977af35
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
@@ -0,0 +1,369 @@
+/*
+ * T104xQDS Device Tree Source
+ *
+ * Copyright 2013 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ model = "fsl,T1040QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ emi1_rgmii0 = &t1040mdio0;
+ emi1_rgmii1 = &t1040mdio1;
+ emi1_slot3 = &t1040mdio3;
+ emi1_slot5 = &t1040mdio5;
+ emi1_slot6 = &t1040mdio6;
+ emi1_slot7 = &t1040mdio7;
+ rgmii_phy1 = &rgmii_phy1;
+ rgmii_phy2 = &rgmii_phy2;
+ phy_s3_01 = &phy_s3_01;
+ phy_s3_02 = &phy_s3_02;
+ phy_s3_03 = &phy_s3_03;
+ phy_s3_04 = &phy_s3_04;
+ phy_s5_01 = &phy_s5_01;
+ phy_s5_02 = &phy_s5_02;
+ phy_s5_03 = &phy_s5_03;
+ phy_s5_04 = &phy_s5_04;
+ phy_s6_01 = &phy_s6_01;
+ phy_s6_02 = &phy_s6_02;
+ phy_s6_03 = &phy_s6_03;
+ phy_s6_04 = &phy_s6_04;
+ phy_s7_01 = &phy_s7_01;
+ phy_s7_02 = &phy_s7_02;
+ phy_s7_03 = &phy_s7_03;
+ phy_s7_04 = &phy_s7_04;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,fpga-qixis";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ reg = <0x54 1>;
+ mux-mask = <0xe0>;
+
+ t1040mdio0: mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x00>;
+ status = "disabled";
+
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ t1040mdio1: mdio@20 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x20>;
+ status = "disabled";
+
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ t1040mdio3: mdio@60 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60>;
+ status = "disabled";
+
+ phy_s3_01: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_s3_02: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_s3_03: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_s3_04: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t1040mdio5: mdio@a0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xa0>;
+
+ phy_s5_01: ethernet-phy@1c {
+ reg = <0x14>;
+ };
+
+ phy_s5_02: ethernet-phy@1d {
+ reg = <0x15>;
+ };
+
+ phy_s5_03: ethernet-phy@1e {
+ reg = <0x16>;
+ };
+
+ phy_s5_04: ethernet-phy@1f {
+ reg = <0x17>;
+ };
+ };
+
+ t1040mdio6: mdio@c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc0>;
+
+ phy_s6_01: ethernet-phy@1c {
+ reg = <0x18>;
+ };
+
+ phy_s6_02: ethernet-phy@1d {
+ reg = <0x19>;
+ };
+
+ phy_s6_03: ethernet-phy@1e {
+ reg = <0x1a>;
+ };
+
+ phy_s6_04: ethernet-phy@1f {
+ reg = <0x1b>;
+ };
+ };
+
+ t1040mdio7: mdio@e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0>;
+ status = "disabled";
+
+ phy_s7_01: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_s7_02: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_s7_03: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_s7_04: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ pca9547@77 {
+ compatible = "philips,pca9547";
+ reg = <0x77>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ fixed-link = <0 1 1000 0 0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ fixed-link = <1 1 1000 0 0>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy_s7_03>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
new file mode 100644
index 0000000..72691ef
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
@@ -0,0 +1,225 @@
+/*
+ * T1040RDB/T1042RDB Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ aliases {
+ phy_rgmii_0 = &phy_rgmii_0;
+ phy_rgmii_1 = &phy_rgmii_1;
+ phy_sgmii_2 = &phy_sgmii_2;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ cpld@3,0 {
+ reg = <3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q512a", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>; /* input clock */
+ };
+ slic@3 {
+ compatible = "maxim,ds26522";
+ reg = <3>;
+ spi-max-frequency = <2000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c@118100 {
+ pca9546@77 {
+ compatible = "nxp,pca9546";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ fman@400000 {
+ ethernet@e6000 {
+ phy-handle = <&phy_rgmii_0>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_rgmii_1>;
+ phy-connection-type = "rgmii";
+ };
+
+ mdio0: mdio@fc000 {
+ phy_sgmii_2: ethernet-phy@03 {
+ reg = <0x03>;
+ };
+
+ phy_rgmii_0: ethernet-phy@01 {
+ reg = <0x01>;
+ };
+
+ phy_rgmii_1: ethernet-phy@02 {
+ reg = <0x02>;
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x10000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi
index bbb7025..6db0ee8 100644
--- a/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi
@@ -1,7 +1,7 @@
/*
* T1040/T1042 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2013 Freescale Semiconductor Inc.
+ * Copyright 2013-2014 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -58,6 +58,13 @@
sdhc = &sdhc;
crypto = &crypto;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
};
cpus {
@@ -69,6 +76,7 @@
reg = <0>;
clocks = <&mux0>;
next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
L2_1: l2-cache {
next-level-cache = <&cpc>;
};
@@ -78,6 +86,7 @@
reg = <1>;
clocks = <&mux1>;
next-level-cache = <&L2_2>;
+ #cooling-cells = <2>;
L2_2: l2-cache {
next-level-cache = <&cpc>;
};
@@ -87,6 +96,7 @@
reg = <2>;
clocks = <&mux2>;
next-level-cache = <&L2_3>;
+ #cooling-cells = <2>;
L2_3: l2-cache {
next-level-cache = <&cpc>;
};
@@ -96,6 +106,7 @@
reg = <3>;
clocks = <&mux3>;
next-level-cache = <&L2_4>;
+ #cooling-cells = <2>;
L2_4: l2-cache {
next-level-cache = <&cpc>;
};
diff --git a/arch/powerpc/boot/dts/fsl/t2080qds.dts b/arch/powerpc/boot/dts/fsl/t2080qds.dts
new file mode 100644
index 0000000..8d190e8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2080qds.dts
@@ -0,0 +1,213 @@
+/*
+ * T2080QDS Device Tree Source
+ *
+ * Copyright 2013 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t208xsi-pre.dtsi"
+/include/ "t208xqds.dtsi"
+
+/ {
+ model = "fsl,T2080QDS";
+ compatible = "fsl,T2080QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ emi1_slot1 = &t2080mdio2;
+ emi1_slot2 = &t2080mdio3;
+ emi1_slot3 = &t2080mdio4;
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+&soc {
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_s3_1e>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_s3_1f>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_sgmii_s2_1e>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@ea000 {
+ phy-handle = <&phy_sgmii_s2_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_xaui_slot3>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&phy_sgmii_s3_1f>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@fd000 {
+ phy_xaui_slot3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x3>;
+ };
+ };
+ };
+};
+
+&boardctrl {
+ mdio-mux-emi1 {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x54 1>;
+ mux-mask = <0xe0>;
+
+ t2080mdio0: mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ t2080mdio1: mdio@20 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x20>;
+
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ t2080mdio2: mdio@40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40>;
+ status = "disabled";
+
+ phy_sgmii_s1_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s1_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s1_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s1_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2080mdio3: mdio@c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc0>;
+
+ phy_sgmii_s2_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s2_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s2_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s2_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2080mdio4: mdio@60 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60>;
+ status = "disabled";
+
+ phy_sgmii_s3_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s3_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s3_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s3_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+};
+
+/include/ "t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t2080rdb.dts b/arch/powerpc/boot/dts/fsl/t2080rdb.dts
new file mode 100644
index 0000000..836e4c9
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2080rdb.dts
@@ -0,0 +1,122 @@
+/*
+ * T2080PCIe-RDB Board Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t208xsi-pre.dtsi"
+/include/ "t208xrdb.dtsi"
+
+/ {
+ model = "fsl,T2080RDB";
+ compatible = "fsl,T2080RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+&soc {
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&xg_aq1202_phy3>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&xg_aq1202_phy4>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&xg_cs4315_phy1>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&xg_cs4315_phy2>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@fc000 {
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ mdio@fd000 {
+ xg_cs4315_phy1: ethernet-phy@c {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0xc>;
+ };
+
+ xg_cs4315_phy2: ethernet-phy@d {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0xd>;
+ };
+
+ xg_aq1202_phy3: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+
+ xg_aq1202_phy4: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x1>;
+ };
+ };
+ };
+};
+
+/include/ "t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t2081qds.dts b/arch/powerpc/boot/dts/fsl/t2081qds.dts
new file mode 100644
index 0000000..fc5c4a3
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2081qds.dts
@@ -0,0 +1,265 @@
+/*
+ * T2081QDS Device Tree Source
+ *
+ * Copyright 2013 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t208xsi-pre.dtsi"
+/include/ "t208xqds.dtsi"
+
+/ {
+ model = "fsl,T2081QDS";
+ compatible = "fsl,T2081QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ emi1_slot1 = &t2081mdio2;
+ emi1_slot2 = &t2081mdio3;
+ emi1_slot3 = &t2081mdio4;
+ emi1_slot5 = &t2081mdio5;
+ emi1_slot6 = &t2081mdio6;
+ emi1_slot7 = &t2081mdio7;
+ };
+};
+
+&soc {
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&phy_sgmii_s7_1c>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy_sgmii_s7_1d>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&rgmii_phy1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&rgmii_phy2>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phy_sgmii_s3_1c>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@ea000 {
+ phy-handle = <&phy_sgmii_s7_1f>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&phy_sgmii_s2_1c>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&phy_sgmii_s7_1e>;
+ phy-connection-type = "xgmii";
+ };
+ };
+};
+
+&boardctrl {
+ mdio-mux-emi1 {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x54 1>;
+ mux-mask = <0xe0>;
+
+ t2081mdio0: mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ t2081mdio1: mdio@20 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x20>;
+
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ t2081mdio2: mdio@40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40>;
+
+ phy_sgmii_s1_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s1_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s1_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s1_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2081mdio3: mdio@60 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60>;
+
+ phy_sgmii_s2_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s2_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s2_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s2_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2081mdio4: mdio@80 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80>;
+ status = "disabled";
+
+ phy_sgmii_s3_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s3_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s3_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s3_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2081mdio5: mdio@a0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xa0>;
+ status = "disabled";
+
+ phy_sgmii_s5_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s5_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s5_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s5_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2081mdio6: mdio@c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xc0>;
+ status = "disabled";
+
+ phy_sgmii_s6_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s6_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s6_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s6_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t2081mdio7: mdio@e0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xe0>;
+
+ phy_sgmii_s7_1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ phy_sgmii_s7_1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ phy_sgmii_s7_1e: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ phy_sgmii_s7_1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+};
+
+/include/ "t2081si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
index 32c790a..c744569 100644
--- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -630,6 +630,49 @@
/include/ "qoriq-qman3.dtsi"
/include/ "qoriq-bman1.dtsi"
+/include/ "qoriq-fman3-0.dtsi"
+/include/ "qoriq-fman3-0-1g-0.dtsi"
+/include/ "qoriq-fman3-0-1g-1.dtsi"
+/include/ "qoriq-fman3-0-1g-2.dtsi"
+/include/ "qoriq-fman3-0-1g-3.dtsi"
+/include/ "qoriq-fman3-0-1g-4.dtsi"
+/include/ "qoriq-fman3-0-1g-5.dtsi"
+/include/ "qoriq-fman3-0-10g-0.dtsi"
+/include/ "qoriq-fman3-0-10g-1.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@ea000 {
+ };
+
+ enet6: ethernet@f0000 {
+ };
+
+ enet7: ethernet@f2000 {
+ };
+
+ mdio@fc000 {
+ interrupts = <100 1 0 0>;
+ };
+
+ mdio@fd000 {
+ interrupts = <101 1 0 0>;
+ };
+ };
+
L2_1: l2-cache-controller@c20000 {
/* Cluster 0 L2 cache */
compatible = "fsl,t2080-l2-cache-controller";
diff --git a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
new file mode 100644
index 0000000..ec080bd
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi
@@ -0,0 +1,277 @@
+/*
+ * T2080/T2081 QDS Device Tree Source
+ *
+ * Copyright 2013 - 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ model = "fsl,T2080QDS";
+ compatible = "fsl,T2080QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ boardctrl: board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,fpga-qixis";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ };
+
+ flash@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040", "jedec,spi-nor";
+ reg = <1>;
+ spi-max-frequency = <35000000>;
+ };
+
+ flash@2 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "eon,en25s64", "jedec,spi-nor";
+ reg = <2>;
+ spi-max-frequency = <35000000>;
+ };
+ };
+
+ i2c@118000 {
+ pca9547@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ eeprom@50 {
+ compatible = "at24,24c512";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "at24,24c02";
+ reg = <0x51>;
+ };
+
+ eeprom@57 {
+ compatible = "at24,24c02";
+ reg = <0x57>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0xb 0x1 0 0>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+
+ eeprom@55 {
+ compatible = "at24,24c02";
+ reg = <0x55>;
+ };
+ };
+
+ 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>;
+
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+ };
+ };
+
+ sdhc@114000 {
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi
new file mode 100644
index 0000000..dc93268
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi
@@ -0,0 +1,211 @@
+/*
+ * T2080PCIe-RDB Board Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
+ */
+
+/ {
+ model = "fsl,T2080RDB";
+ compatible = "fsl,T2080RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+
+ boardctrl: board-control@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,t2080-cpld";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q512a", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ adt7481@4c {
+ compatible = "adi,adt7481";
+ reg = <0x4c>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@118100 {
+ pca9546@77 {
+ compatible = "nxp,pca9546";
+ reg = <0x77>;
+ };
+ };
+
+ sdhc@114000 {
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
index e71ceb0..c2e5720 100644
--- a/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
@@ -51,6 +51,17 @@
serial3 = &serial3;
crypto = &crypto;
+
+ fman0 = &fman0;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ ethernet6 = &enet6;
+ ethernet7 = &enet7;
+
pci0 = &pci0;
pci1 = &pci1;
pci2 = &pci2;
diff --git a/arch/powerpc/boot/dts/fsl/t4240qds.dts b/arch/powerpc/boot/dts/fsl/t4240qds.dts
new file mode 100644
index 0000000..9573cea
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t4240qds.dts
@@ -0,0 +1,708 @@
+/*
+ * T4240QDS Device Tree Source
+ *
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "t4240si-pre.dtsi"
+
+/ {
+ model = "fsl,T4240QDS";
+ compatible = "fsl,T4240QDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases{
+ phy_rgmii1 = &phyrgmii1;
+ phy_rgmii2 = &phyrgmii2;
+ phy_sgmii3 = &phy3;
+ phy_sgmii4 = &phy4;
+ phy_sgmii11 = &phy11;
+ phy_sgmii12 = &phy12;
+ sgmii_phy11 = &sgmiiphy11;
+ sgmii_phy12 = &sgmiiphy12;
+ sgmii_phy13 = &sgmiiphy13;
+ sgmii_phy14 = &sgmiiphy14;
+ sgmii_phy21 = &sgmiiphy21;
+ sgmii_phy22 = &sgmiiphy22;
+ sgmii_phy23 = &sgmiiphy23;
+ sgmii_phy24 = &sgmiiphy24;
+ sgmii_phy31 = &sgmiiphy31;
+ sgmii_phy32 = &sgmiiphy32;
+ sgmii_phy33 = &sgmiiphy33;
+ sgmii_phy34 = &sgmiiphy34;
+ sgmii_phy41 = &sgmiiphy41;
+ sgmii_phy42 = &sgmiiphy42;
+ sgmii_phy43 = &sgmiiphy43;
+ sgmii_phy44 = &sgmiiphy44;
+ phy_xfi1 = &xfiphy1;
+ phy_xfi2 = &xfiphy2;
+ phy_xfi3 = &xfiphy3;
+ phy_xfi4 = &xfiphy4;
+ xfi_pcs_mdio1 = &xfimdio0;
+ xfi_pcs_mdio2 = &xfimdio1;
+ xfi_pcs_mdio3 = &xfimdio2;
+ xfi_pcs_mdio4 = &xfimdio3;
+ emi1_rgmii = &t4240mdio0;
+ emi1_slot1 = &t4240mdio1;
+ emi1_slot2 = &t4240mdio2;
+ emi1_slot3 = &t4240mdio3;
+ emi1_slot4 = &t4240mdio4;
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND DTB Image";
+ };
+
+ partition@200000 {
+ /* 10MB for Linux Kernel Image */
+ reg = <0x00200000 0x00A00000>;
+ label = "NAND Linux Kernel Image";
+ };
+
+ partition@C00000 {
+ /* 500MB for Root file System Image */
+ reg = <0x00c00000 0x1F400000>;
+ label = "NAND RFS Image";
+ };
+ };
+
+ board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis";
+ reg = <3 0 0x300>;
+ ranges = <0 3 0 0x300>;
+
+ mdio-mux-emi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ mdio-parent-bus = <&mdio1>;
+ reg = <0x54 1>;
+ mux-mask = <0xe0>;
+
+ t4240mdio0: mdio@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ phyrgmii1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ phyrgmii2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ t4240mdio1: mdio@20 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x20>;
+ status = "disabled";
+
+ phy1: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ phy2: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ phy3: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ phy4: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+
+ sgmiiphy11: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ sgmiiphy12: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ sgmiiphy13: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ sgmiiphy14: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t4240mdio2: mdio@40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40>;
+ status = "disabled";
+
+ phy5: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+
+ phy6: ethernet-phy@5 {
+ reg = <0x5>;
+ };
+
+ phy7: ethernet-phy@6 {
+ reg = <0x6>;
+ };
+
+ phy8: ethernet-phy@7 {
+ reg = <0x7>;
+ };
+
+ sgmiiphy21: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ sgmiiphy22: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ sgmiiphy23: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ sgmiiphy24: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t4240mdio3: mdio@60 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x60>;
+ status = "disabled";
+
+ phy9: ethernet-phy@8 {
+ reg = <0x8>;
+ };
+
+ phy10: ethernet-phy@9 {
+ reg = <0x9>;
+ };
+
+ phy11: ethernet-phy@a {
+ reg = <0xa>;
+ };
+
+ phy12: ethernet-phy@b {
+ reg = <0xb>;
+ };
+
+ sgmiiphy31: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ sgmiiphy32: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ sgmiiphy33: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ sgmiiphy34: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+
+ t4240mdio4: mdio@80 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x80>;
+ status = "disabled";
+
+ phy13: ethernet-phy@c {
+ reg = <0xc>;
+ };
+
+ phy14: ethernet-phy@d {
+ reg = <0xd>;
+ };
+
+ phy15: ethernet-phy@e {
+ reg = <0xe>;
+ };
+
+ phy16: ethernet-phy@f {
+ reg = <0xf>;
+ };
+
+ sgmiiphy41: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+
+ sgmiiphy42: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+
+ sgmiiphy43: ethernet-phy@1e {
+ reg = <0x1e>;
+ };
+
+ sgmiiphy44: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+ };
+ };
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ mux@77 {
+ compatible = "nxp,pca9547";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ eeprom@53 {
+ compatible = "at24,24c256";
+ reg = <0x53>;
+ };
+ eeprom@54 {
+ compatible = "at24,24c256";
+ reg = <0x54>;
+ };
+ eeprom@55 {
+ compatible = "at24,24c256";
+ reg = <0x55>;
+ };
+ eeprom@56 {
+ compatible = "at24,24c256";
+ reg = <0x56>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ 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>;
+ };
+
+ ina220@44 {
+ compatible = "ti,ina220";
+ reg = <0x44>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@45 {
+ compatible = "ti,ina220";
+ reg = <0x45>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@46 {
+ compatible = "ti,ina220";
+ reg = <0x46>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@47 {
+ compatible = "ti,ina220";
+ reg = <0x47>;
+ shunt-resistor = <1000>;
+ };
+ };
+ };
+ };
+
+ sdhc@114000 {
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+
+ fman@400000 {
+ port@83000 {
+ status = "disabled";
+ };
+
+ port@84000 {
+ status = "disabled";
+ };
+
+ port@85000 {
+ status = "disabled";
+ };
+
+ port@86000 {
+ status = "disabled";
+ };
+
+ port@87000 {
+ status = "disabled";
+ };
+
+ ethernet@e0000 {
+ phy-handle = <&phy5>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy6>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy7>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy8>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phyrgmii2>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@ea000 {
+ phy-handle = <&phy2>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&xauiphy1>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&xauiphy2>;
+ phy-connection-type = "xgmii";
+ };
+
+ xfimdio0: mdio@f1000 {
+ status = "disabled";
+
+ xfiphy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+
+ xfimdio1: mdio@f3000 {
+ status = "disabled";
+
+ xfiphy2: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+ };
+
+ fman@500000 {
+ port@84000 {
+ status = "disabled";
+ };
+
+ port@85000 {
+ status = "disabled";
+ };
+
+ port@86000 {
+ status = "disabled";
+ };
+
+ port@87000 {
+ status = "disabled";
+ };
+
+ ethernet@e0000 {
+ phy-handle = <&phy13>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&phy14>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&phy15>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&phy16>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ phy-handle = <&phyrgmii1>;
+ phy-connection-type = "rgmii";
+ };
+
+ ethernet@ea000 {
+ phy-handle = <&phy10>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&xauiphy3>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&xauiphy4>;
+ phy-connection-type = "xgmii";
+ };
+
+ xfimdio2: mdio@f1000 {
+ status = "disabled";
+
+ xfiphy3: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+
+ xfimdio3: mdio@f3000 {
+ status = "disabled";
+
+ xfiphy4: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+ };
+
+ mdio@fd000 {
+ xauiphy1: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x0>;
+ };
+
+ xauiphy2: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x1>;
+ };
+
+ xauiphy3: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x2>;
+ };
+
+ xauiphy4: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x3>;
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+/include/ "t4240si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
new file mode 100644
index 0000000..cc0a264
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts
@@ -0,0 +1,360 @@
+/*
+ * T4240RDB Device Tree Source
+ *
+ * Copyright 2014 - 2015 Freescale Semiconductor Inc.
+ *
+ * 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 Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "t4240si-pre.dtsi"
+
+/ {
+ model = "fsl,T4240RDB";
+ compatible = "fsl,T4240RDB";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ sgmii_phy21 = &sgmiiphy21;
+ sgmii_phy22 = &sgmiiphy22;
+ sgmii_phy23 = &sgmiiphy23;
+ sgmii_phy24 = &sgmiiphy24;
+ sgmii_phy41 = &sgmiiphy41;
+ sgmii_phy42 = &sgmiiphy42;
+ sgmii_phy43 = &sgmiiphy43;
+ sgmii_phy44 = &sgmiiphy44;
+ };
+
+ ifc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x2000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xff800000 0x00010000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,ifc-nand";
+ reg = <0x2 0x0 0x10000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ bman_fbpr: bman-fbpr {
+ size = <0 0x1000000>;
+ alignment = <0 0x1000000>;
+ };
+ qman_fqd: qman-fqd {
+ size = <0 0x400000>;
+ alignment = <0 0x400000>;
+ };
+ qman_pfdr: qman-pfdr {
+ size = <0 0x2000000>;
+ alignment = <0 0x2000000>;
+ };
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+ };
+
+ bportals: bman-portals@ff4000000 {
+ ranges = <0x0 0xf 0xf4000000 0x2000000>;
+ };
+
+ qportals: qman-portals@ff6000000 {
+ ranges = <0x0 0xf 0xf6000000 0x2000000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ };
+ };
+
+ i2c@118000 {
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ eeprom@54 {
+ compatible = "at24,24c256";
+ reg = <0x54>;
+ };
+ eeprom@56 {
+ compatible = "at24,24c256";
+ reg = <0x56>;
+ };
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ };
+
+ sdhc@114000 {
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+
+ fman@400000 {
+ ethernet@e0000 {
+ phy-handle = <&sgmiiphy21>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&sgmiiphy22>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&sgmiiphy23>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&sgmiiphy24>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ status = "disabled";
+ };
+
+ ethernet@ea000 {
+ status = "disabled";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&xfiphy1>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&xfiphy2>;
+ phy-connection-type = "xgmii";
+ };
+ };
+
+ fman@500000 {
+ ethernet@e0000 {
+ phy-handle = <&sgmiiphy41>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e2000 {
+ phy-handle = <&sgmiiphy42>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e4000 {
+ phy-handle = <&sgmiiphy43>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e6000 {
+ phy-handle = <&sgmiiphy44>;
+ phy-connection-type = "sgmii";
+ };
+
+ ethernet@e8000 {
+ status = "disabled";
+ };
+
+ ethernet@ea000 {
+ status = "disabled";
+ };
+
+ ethernet@f0000 {
+ phy-handle = <&xfiphy3>;
+ phy-connection-type = "xgmii";
+ };
+
+ ethernet@f2000 {
+ phy-handle = <&xfiphy4>;
+ phy-connection-type = "xgmii";
+ };
+
+ mdio@fc000 {
+ sgmiiphy21: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+
+ sgmiiphy22: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+
+ sgmiiphy23: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+
+ sgmiiphy24: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+
+ sgmiiphy41: ethernet-phy@4 {
+ reg = <0x4>;
+ };
+
+ sgmiiphy42: ethernet-phy@5 {
+ reg = <0x5>;
+ };
+
+ sgmiiphy43: ethernet-phy@6 {
+ reg = <0x6>;
+ };
+
+ sgmiiphy44: ethernet-phy@7 {
+ reg = <0x7>;
+ };
+ };
+
+ mdio@fd000 {
+ xfiphy1: ethernet-phy@10 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x10>;
+ };
+
+ xfiphy2: ethernet-phy@11 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x11>;
+ };
+
+ xfiphy3: ethernet-phy@13 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x13>;
+ };
+
+ xfiphy4: ethernet-phy@12 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0x12>;
+ };
+ };
+ };
+ };
+
+ pci0: pcie@ffe240000 {
+ reg = <0xf 0xfe240000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe250000 {
+ reg = <0xf 0xfe250000 0 0x10000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe260000 {
+ reg = <0xf 0xfe260000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci3: pcie@ffe270000 {
+ reg = <0xf 0xfe270000 0 0x10000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ rio: rapidio@ffe0c0000 {
+ reg = <0xf 0xfe0c0000 0 0x11000>;
+
+ port1 {
+ ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+ };
+ port2 {
+ ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+ };
+ };
+};
+
+/include/ "t4240si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index d806360..68c4ead 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -1,7 +1,7 @@
/*
* T4240 Silicon/SoC Device Tree Source (post include)
*
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -1068,6 +1068,92 @@
/include/ "qoriq-qman3.dtsi"
/include/ "qoriq-bman1.dtsi"
+/include/ "qoriq-fman3-0.dtsi"
+/include/ "qoriq-fman3-0-1g-0.dtsi"
+/include/ "qoriq-fman3-0-1g-1.dtsi"
+/include/ "qoriq-fman3-0-1g-2.dtsi"
+/include/ "qoriq-fman3-0-1g-3.dtsi"
+/include/ "qoriq-fman3-0-1g-4.dtsi"
+/include/ "qoriq-fman3-0-1g-5.dtsi"
+/include/ "qoriq-fman3-0-10g-0.dtsi"
+/include/ "qoriq-fman3-0-10g-1.dtsi"
+ fman@400000 {
+ enet0: ethernet@e0000 {
+ };
+
+ enet1: ethernet@e2000 {
+ };
+
+ enet2: ethernet@e4000 {
+ };
+
+ enet3: ethernet@e6000 {
+ };
+
+ enet4: ethernet@e8000 {
+ };
+
+ enet5: ethernet@ea000 {
+ };
+
+ enet6: ethernet@f0000 {
+ };
+
+ enet7: ethernet@f2000 {
+ };
+
+ mdio@fc000 {
+ status = "disabled";
+ };
+
+ mdio@fd000 {
+ status = "disabled";
+ };
+ };
+
+/include/ "qoriq-fman3-1.dtsi"
+/include/ "qoriq-fman3-1-1g-0.dtsi"
+/include/ "qoriq-fman3-1-1g-1.dtsi"
+/include/ "qoriq-fman3-1-1g-2.dtsi"
+/include/ "qoriq-fman3-1-1g-3.dtsi"
+/include/ "qoriq-fman3-1-1g-4.dtsi"
+/include/ "qoriq-fman3-1-1g-5.dtsi"
+/include/ "qoriq-fman3-1-10g-0.dtsi"
+/include/ "qoriq-fman3-1-10g-1.dtsi"
+ fman@500000 {
+ enet8: ethernet@e0000 {
+ };
+
+ enet9: ethernet@e2000 {
+ };
+
+ enet10: ethernet@e4000 {
+ };
+
+ enet11: ethernet@e6000 {
+ };
+
+ enet12: ethernet@e8000 {
+ };
+
+ enet13: ethernet@ea000 {
+ };
+
+ enet14: ethernet@f0000 {
+ };
+
+ enet15: ethernet@f2000 {
+ };
+
+ mdio@fc000 {
+ interrupts = <100 1 0 0>;
+ };
+
+ mdio@fd000 {
+ interrupts = <101 1 0 0>;
+ };
+ };
+
L2_1: l2-cache-controller@c20000 {
compatible = "fsl,t4240-l2-cache-controller";
reg = <0xc20000 0x40000>;
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
index 261a3abb..1184a74 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
@@ -1,7 +1,7 @@
/*
* T4240 Silicon/SoC Device Tree Source (pre include)
*
- * Copyright 2012 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -51,6 +51,7 @@
serial2 = &serial2;
serial3 = &serial3;
crypto = &crypto;
+
pci0 = &pci0;
pci1 = &pci1;
pci2 = &pci2;
@@ -59,6 +60,25 @@
dma1 = &dma1;
dma2 = &dma2;
sdhc = &sdhc;
+
+ fman0 = &fman0;
+ fman1 = &fman1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ ethernet5 = &enet5;
+ ethernet6 = &enet6;
+ ethernet7 = &enet7;
+ ethernet8 = &enet8;
+ ethernet9 = &enet9;
+ ethernet10 = &enet10;
+ ethernet11 = &enet11;
+ ethernet12 = &enet12;
+ ethernet13 = &enet13;
+ ethernet14 = &enet14;
+ ethernet15 = &enet15;
};
cpus {
diff --git a/arch/powerpc/boot/dts/ge_imp3a.dts b/arch/powerpc/boot/dts/ge_imp3a.dts
deleted file mode 100644
index fefae41..0000000
--- a/arch/powerpc/boot/dts/ge_imp3a.dts
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * GE IMP3A Device Tree Source
- *
- * Copyright 2010-2011 GE Intelligent Platforms Embedded Systems, 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.
- *
- * Based on: P2020 DS Device Tree Source
- * Copyright 2009 Freescale Semiconductor Inc.
- */
-
-/include/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "GE_IMP3A";
- compatible = "ge,imp3a";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fef05000 {
- reg = <0 0xfef05000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xff000000 0x01000000
- 0x1 0x0 0x0 0xe0000000 0x08000000
- 0x2 0x0 0x0 0xe8000000 0x08000000
- 0x3 0x0 0x0 0xfc100000 0x00020000
- 0x4 0x0 0x0 0xfc000000 0x00008000
- 0x5 0x0 0x0 0xfc008000 0x00008000
- 0x6 0x0 0x0 0xfee00000 0x00040000
- 0x7 0x0 0x0 0xfee80000 0x00040000>;
-
- /* nor@0,0 is a mirror of part of the memory in nor@1,0
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "ge,imp3a-firmware-mirror", "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- label = "firmware";
- reg = <0x0 0x1000000>;
- read-only;
- };
- };
- */
-
- nor@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "ge,imp3a-paged-flash", "cfi-flash";
- reg = <0x1 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- label = "user";
- reg = <0x0 0x7800000>;
- };
-
- partition@7800000 {
- label = "firmware";
- reg = <0x7800000 0x800000>;
- read-only;
- };
- };
-
- nvram@3,0 {
- device_type = "nvram";
- compatible = "simtek,stk14ca8";
- reg = <0x3 0x0 0x20000>;
- };
-
- fpga@4,0 {
- compatible = "ge,imp3a-fpga-regs";
- reg = <0x4 0x0 0x20>;
- };
-
- gef_pic: pic@4,20 {
- #interrupt-cells = <1>;
- interrupt-controller;
- device_type = "interrupt-controller";
- compatible = "ge,imp3a-fpga-pic", "gef,fpga-pic-1.00";
- reg = <0x4 0x20 0x20>;
- interrupts = <6 7 0 0>;
- };
-
- gef_gpio: gpio@4,400 {
- #gpio-cells = <2>;
- compatible = "ge,imp3a-gpio";
- reg = <0x4 0x400 0x24>;
- gpio-controller;
- };
-
- wdt@4,800 {
- compatible = "ge,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x800 0x8>;
- interrupts = <10 4>;
- interrupt-parent = <&gef_pic>;
- };
-
- /* Second watchdog available, driver currently supports one.
- wdt@4,808 {
- compatible = "gef,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x808 0x8>;
- interrupts = <9 4>;
- interrupt-parent = <&gef_pic>;
- };
- */
-
- nand@6,0 {
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x6 0x0 0x40000>;
- };
-
- nand@7,0 {
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x7 0x0 0x40000>;
- };
- };
-
- soc: soc@fef00000 {
- ranges = <0x0 0 0xfef00000 0x100000>;
-
- i2c@3000 {
- hwmon@48 {
- compatible = "national,lm92";
- reg = <0x48>;
- };
-
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- rtc@51 {
- compatible = "epson,rx8581";
- reg = <0x51>;
- };
-
- eti@6b {
- compatible = "dallas,ds1682";
- reg = <0x6b>;
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- dr_mode = "host";
- };
-
- mdio@24520 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0xc 0x4>;
- reg = <0x1>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0xb 0x4>;
- reg = <0x2>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- status = "disabled";
- };
-
- enet0: ethernet@24000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "gmii";
- };
-
- enet1: ethernet@25000 {
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
- phy-connection-type = "gmii";
- };
-
- enet2: ethernet@26000 {
- status = "disabled";
- };
- };
-
- pci0: pcie@fef08000 {
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xfe020000 0x0 0x10000>;
- reg = <0 0xfef08000 0 0x1000>;
-
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci1: pcie@fef09000 {
- reg = <0 0xfef09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xfe010000 0x0 0x10000>;
-
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
-
- };
-
- pci2: pcie@fef0a000 {
- reg = <0 0xfef0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xfe000000 0x0 0x10000>;
-
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-};
-
-/include/ "fsl/p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
deleted file mode 100644
index 83eb0fd..0000000
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * GE PPC9A Device Tree Source
- *
- * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
- *
- * Based on: SBS CM6 Device Tree Source
- * Copyright 2007 SBS Technologies GmbH & Co. KG
- * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
- * Copyright 2006 Freescale Semiconductor Inc.
- */
-
-/*
- * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
- */
-
-/dts-v1/;
-
-/ {
- model = "GEF_PPC9A";
- compatible = "gef,ppc9a";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x40000000>; // set by uboot
- };
-
- localbus@fef05000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xfef05000 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
- 1 0 0xe8000000 0x08000000 // Paged Flash 0
- 2 0 0xe0000000 0x08000000 // Paged Flash 1
- 3 0 0xfc100000 0x00020000 // NVRAM
- 4 0 0xfc000000 0x00008000 // FPGA
- 5 0 0xfc008000 0x00008000 // AFIX FPGA
- 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
- 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
-
- /* flash@0,0 is a mirror of part of the memory in flash@1,0
- flash@0,0 {
- compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <4>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "firmware";
- reg = <0x0 0x1000000>;
- read-only;
- };
- };
- */
-
- flash@1,0 {
- compatible = "gef,ppc9a-paged-flash", "cfi-flash";
- reg = <0x1 0x0 0x8000000>;
- bank-width = <4>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "user";
- reg = <0x0 0x7800000>;
- };
- partition@7800000 {
- label = "firmware";
- reg = <0x7800000 0x800000>;
- read-only;
- };
- };
-
- nvram@3,0 {
- device_type = "nvram";
- compatible = "simtek,stk14ca8";
- reg = <0x3 0x0 0x20000>;
- };
-
- fpga@4,0 {
- compatible = "gef,ppc9a-fpga-regs";
- reg = <0x4 0x0 0x40>;
- };
-
- wdt@4,2000 {
- compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x2000 0x8>;
- interrupts = <0x1a 0x4>;
- interrupt-parent = <&gef_pic>;
- };
- /* Second watchdog available, driver currently supports one.
- wdt@4,2010 {
- compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x2010 0x8>;
- interrupts = <0x1b 0x4>;
- interrupt-parent = <&gef_pic>;
- };
- */
- gef_pic: pic@4,4000 {
- #interrupt-cells = <1>;
- interrupt-controller;
- compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
- reg = <0x4 0x4000 0x20>;
- interrupts = <0x8
- 0x9>;
- interrupt-parent = <&mpic>;
-
- };
- gef_gpio: gpio@7,14000 {
- #gpio-cells = <2>;
- compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
- reg = <0x7 0x14000 0x24>;
- gpio-controller;
- };
- };
-
- soc@fef00000 {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <2>;
- device_type = "soc";
- compatible = "fsl,mpc8641-soc", "simple-bus";
- ranges = <0x0 0xfef00000 0x00100000>;
- bus-frequency = <33333333>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c1: i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
-
- hwmon@48 {
- compatible = "national,lm92";
- reg = <0x48>;
- };
-
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- rtc@51 {
- compatible = "epson,rx8581";
- reg = <0x00000051>;
- };
-
- eti@6b {
- compatible = "dallas,ds1682";
- reg = <0x6b>;
- };
- };
-
- i2c2: i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x9 0x4>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x8 0x4>;
- reg = <3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <0x2a 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <0x1c 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- clock-frequency = <0>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- msi@41600 {
- compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
- reg = <0x41600 0x80>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xe0 0
- 0xe1 0
- 0xe2 0
- 0xe3 0
- 0xe4 0
- 0xe5 0
- 0xe6 0
- 0xe7 0>;
- interrupt-parent = <&mpic>;
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@fef08000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xfef08000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
- 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <0x18 0x2>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x40000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00400000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
deleted file mode 100644
index d426dd3d..0000000
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * GE SBC310 Device Tree Source
- *
- * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
- *
- * Based on: SBS CM6 Device Tree Source
- * Copyright 2007 SBS Technologies GmbH & Co. KG
- * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
- * Copyright 2006 Freescale Semiconductor Inc.
- */
-
-/*
- * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
- */
-
-/dts-v1/;
-
-/ {
- model = "GEF_SBC310";
- compatible = "gef,sbc310";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x40000000>; // set by uboot
- };
-
- localbus@fef05000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xfef05000 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
- 1 0 0xe0000000 0x08000000 // Paged Flash 0
- 2 0 0xe8000000 0x08000000 // Paged Flash 1
- 3 0 0xfc100000 0x00020000 // NVRAM
- 4 0 0xfc000000 0x00010000>; // FPGA
-
- /* flash@0,0 is a mirror of part of the memory in flash@1,0
- flash@0,0 {
- compatible = "gef,sbc310-firmware-mirror", "cfi-flash";
- reg = <0x0 0x0 0x01000000>;
- bank-width = <2>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "firmware";
- reg = <0x0 0x01000000>;
- read-only;
- };
- };
- */
-
- flash@1,0 {
- compatible = "gef,sbc310-paged-flash", "cfi-flash";
- reg = <0x1 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "user";
- reg = <0x0 0x7800000>;
- };
- partition@7800000 {
- label = "firmware";
- reg = <0x7800000 0x800000>;
- read-only;
- };
- };
-
- nvram@3,0 {
- device_type = "nvram";
- compatible = "simtek,stk14ca8";
- reg = <0x3 0x0 0x20000>;
- };
-
- fpga@4,0 {
- compatible = "gef,fpga-regs";
- reg = <0x4 0x0 0x40>;
- };
-
- wdt@4,2000 {
- compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x2000 0x8>;
- interrupts = <0x1a 0x4>;
- interrupt-parent = <&gef_pic>;
- };
-/*
- wdt@4,2010 {
- compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
- "gef,fpga-wdt";
- reg = <0x4 0x2010 0x8>;
- interrupts = <0x1b 0x4>;
- interrupt-parent = <&gef_pic>;
- };
-*/
- gef_pic: pic@4,4000 {
- #interrupt-cells = <1>;
- interrupt-controller;
- compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic";
- reg = <0x4 0x4000 0x20>;
- interrupts = <0x8
- 0x9>;
- interrupt-parent = <&mpic>;
-
- };
- gef_gpio: gpio@4,8000 {
- #gpio-cells = <2>;
- compatible = "gef,sbc310-gpio";
- reg = <0x4 0x8000 0x24>;
- gpio-controller;
- };
- };
-
- soc@fef00000 {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <2>;
- device_type = "soc";
- compatible = "fsl,mpc8641-soc", "simple-bus";
- ranges = <0x0 0xfef00000 0x00100000>;
- bus-frequency = <33333333>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c1: i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
-
- rtc@51 {
- compatible = "epson,rx8581";
- reg = <0x00000051>;
- };
- };
-
- i2c2: i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
-
- hwmon@48 {
- compatible = "national,lm92";
- reg = <0x48>;
- };
-
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- eti@6b {
- compatible = "dallas,ds1682";
- reg = <0x6b>;
- };
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x9 0x4>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x8 0x4>;
- reg = <3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <0x2a 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <0x1c 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- clock-frequency = <0>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- msi@41600 {
- compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
- reg = <0x41600 0x80>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xe0 0
- 0xe1 0
- 0xe2 0
- 0xe3 0
- 0xe4 0
- 0xe5 0
- 0xe6 0
- 0xe7 0>;
- interrupt-parent = <&mpic>;
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@fef08000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xfef08000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
- 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <0x18 0x2>;
- interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
- 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
- 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
- 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x40000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00400000>;
- };
- };
-
- pci1: pcie@fef09000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xfef09000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <0x19 0x2>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2
- 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2
- 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2
- 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0xc0000000
- 0x02000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00400000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
deleted file mode 100644
index 5db3399..0000000
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * GE SBC610 Device Tree Source
- *
- * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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.
- *
- * Based on: SBS CM6 Device Tree Source
- * Copyright 2007 SBS Technologies GmbH & Co. KG
- * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
- * Copyright 2006 Freescale Semiconductor Inc.
- */
-
-/*
- * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts
- */
-
-/dts-v1/;
-
-/ {
- model = "GEF_SBC610";
- compatible = "gef,sbc610";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x40000000>; // set by uboot
- };
-
- localbus@fef05000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xfef05000 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
- 1 0 0xe8000000 0x08000000 // Paged Flash 0
- 2 0 0xe0000000 0x08000000 // Paged Flash 1
- 3 0 0xfc100000 0x00020000 // NVRAM
- 4 0 0xfc000000 0x00008000 // FPGA
- 5 0 0xfc008000 0x00008000 // AFIX FPGA
- 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
- 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
-
- /* flash@0,0 is a mirror of part of the memory in flash@1,0
- flash@0,0 {
- compatible = "gef,sbc610-firmware-mirror", "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <4>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "firmware";
- reg = <0x0 0x1000000>;
- read-only;
- };
- };
- */
-
- flash@1,0 {
- compatible = "gef,sbc610-paged-flash", "cfi-flash";
- reg = <0x1 0x0 0x8000000>;
- bank-width = <4>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "user";
- reg = <0x0 0x7800000>;
- };
- partition@7800000 {
- label = "firmware";
- reg = <0x7800000 0x800000>;
- read-only;
- };
- };
-
- nvram@3,0 {
- device_type = "nvram";
- compatible = "simtek,stk14ca8";
- reg = <0x3 0x0 0x20000>;
- };
-
- fpga@4,0 {
- compatible = "gef,fpga-regs";
- reg = <0x4 0x0 0x40>;
- };
-
- wdt@4,2000 {
- compatible = "gef,fpga-wdt";
- reg = <0x4 0x2000 0x8>;
- interrupts = <0x1a 0x4>;
- interrupt-parent = <&gef_pic>;
- };
- /* Second watchdog available, driver currently supports one.
- wdt@4,2010 {
- compatible = "gef,fpga-wdt";
- reg = <0x4 0x2010 0x8>;
- interrupts = <0x1b 0x4>;
- interrupt-parent = <&gef_pic>;
- };
- */
- gef_pic: pic@4,4000 {
- #interrupt-cells = <1>;
- interrupt-controller;
- compatible = "gef,fpga-pic";
- reg = <0x4 0x4000 0x20>;
- interrupts = <0x8
- 0x9>;
- interrupt-parent = <&mpic>;
-
- };
- gef_gpio: gpio@7,14000 {
- #gpio-cells = <2>;
- compatible = "gef,sbc610-gpio";
- reg = <0x7 0x14000 0x24>;
- gpio-controller;
- };
- };
-
- soc@fef00000 {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <2>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0xfef00000 0x00100000>;
- bus-frequency = <33333333>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c1: i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
-
- hwmon@48 {
- compatible = "national,lm92";
- reg = <0x48>;
- };
-
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- rtc@51 {
- compatible = "epson,rx8581";
- reg = <0x00000051>;
- };
-
- eti@6b {
- compatible = "dallas,ds1682";
- reg = <0x6b>;
- };
- };
-
- i2c2: i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <0x2b 0x2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x9 0x4>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x8 0x4>;
- reg = <3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "gmii";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <0x2a 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <0x1c 0x2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- clock-frequency = <0>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- msi@41600 {
- compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
- reg = <0x41600 0x80>;
- msi-available-ranges = <0 0x100>;
- interrupts = <
- 0xe0 0
- 0xe1 0
- 0xe2 0
- 0xe3 0
- 0xe4 0
- 0xe5 0
- 0xe6 0
- 0xe7 0>;
- interrupt-parent = <&mpic>;
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@fef08000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xfef08000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
- 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <0x18 0x2>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x40000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00400000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/kmcoge4.dts b/arch/powerpc/boot/dts/kmcoge4.dts
deleted file mode 100644
index 48dab6a..0000000
--- a/arch/powerpc/boot/dts/kmcoge4.dts
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Keymile kmcoge4 Device Tree Source, based on the P2041RDB DTS
- *
- * (C) Copyright 2014
- * Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p2041si-pre.dtsi"
-
-/ {
- model = "keymile,kmcoge4";
- compatible = "keymile,kmcoge4", "keymile,kmp204x";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25fl256s1";
- reg = <0>;
- spi-max-frequency = <20000000>; /* input clock */
- };
-
- network_clock@1 {
- compatible = "zarlink,zl30343";
- reg = <1>;
- spi-max-frequency = <8000000>;
- };
-
- flash@2 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,m25p32";
- reg = <2>;
- spi-max-frequency = <15000000>;
- };
- };
-
- i2c@119000 {
- status = "disabled";
- };
-
- i2c@119100 {
- status = "disabled";
- };
-
- usb0: usb@210000 {
- status = "disabled";
- };
-
- usb1: usb@211000 {
- status = "disabled";
- };
-
- sata@220000 {
- status = "disabled";
- };
-
- sata@221000 {
- status = "disabled";
- };
- };
-
- rio: rapidio@ffe0c0000 {
- status = "disabled";
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xffa00000 0x00040000 /* LB 0 */
- 1 0 0xf 0xfb000000 0x00010000 /* LB 1 */
- 2 0 0xf 0xd0000000 0x10000000 /* LB 2 */
- 3 0 0xf 0xe0000000 0x10000000>; /* LB 3 */
-
- nand@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0 0 0x40000>;
- };
-
- board-control@1,0 {
- compatible = "keymile,qriox";
- reg = <1 0 0x80>;
- };
-
- chassis-mgmt@3,0 {
- compatible = "keymile,bfticu";
- interrupt-controller;
- #interrupt-cells = <2>;
- reg = <3 0 0x100>;
- interrupt-parent = <&mpic>;
- interrupts = <6 1 0 0>;
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- status = "disabled";
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/p2041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi
index 7f9d14f..a015e45 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -77,7 +77,6 @@
#address-cells = <2>;
#size-cells = <1>;
reg = <0x80000020 0x40>;
- interrupts = <7 0x8>;
ranges = <0x0 0x0 0xfc000000 0x04000000>;
};
@@ -329,7 +328,15 @@
/* LocalPlus controller */
lpc@10000 {
compatible = "fsl,mpc5121-lpc";
- reg = <0x10000 0x200>;
+ reg = <0x10000 0x100>;
+ };
+
+ sclpc@10100 {
+ compatible = "fsl,mpc512x-lpbfifo";
+ reg = <0x10100 0x50>;
+ interrupts = <7 0x8>;
+ dmas = <&dma0 26>;
+ dma-names = "rx-tx";
};
pata@10200 {
diff --git a/arch/powerpc/boot/dts/mpc5125twr.dts b/arch/powerpc/boot/dts/mpc5125twr.dts
index e4f2974..898eb58 100644
--- a/arch/powerpc/boot/dts/mpc5125twr.dts
+++ b/arch/powerpc/boot/dts/mpc5125twr.dts
@@ -246,6 +246,14 @@
status = "disabled";
};
+ sclpc@10100 {
+ compatible = "fsl,mpc512x-lpbfifo";
+ reg = <0x10100 0x50>;
+ interrupts = <7 0x8>;
+ dmas = <&dma0 26>;
+ dma-names = "rx-tx";
+ };
+
// 5125 PSCs are not 52xx or 5121 PSC compatible
// PSC1 uart0 aka ttyPSC0
serial@11100 {
@@ -279,10 +287,11 @@
clock-names = "ipg";
};
- dma@14000 {
+ dma0: dma@14000 {
compatible = "fsl,mpc5121-dma"; // BSP name: "mpc512x-dma2"
reg = <0x14000 0x1800>;
interrupts = <65 0x8>;
+ #dma-cells = <1>;
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
deleted file mode 100644
index 1973622..0000000
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * MPC8536 DS Device Tree Source
- *
- * Copyright 2008, 2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/mpc8536si-pre.dtsi"
-
-/ {
- model = "fsl,mpc8536ds";
- compatible = "fsl,mpc8536ds";
-
- cpus {
- #cpus = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8536@0 {
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0 0 0 0>; // Filled by U-Boot
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
- 0x2 0x0 0x0 0xffa00000 0x00040000
- 0x3 0x0 0x0 0xffdf0000 0x00008000>;
- };
-
- board_soc: soc: soc@ffe00000 {
- ranges = <0x0 0 0xffe00000 0x100000>;
- };
-
- pci0: pci@ffe08000 {
- reg = <0 0xffe08000 0 0x1000>;
- ranges = <0x02000000 0 0x80000000 0 0x80000000 0 0x10000000
- 0x01000000 0 0x00000000 0 0xffc00000 0 0x00010000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x11 J17 Slot 1 */
- 0x8800 0 0 1 &mpic 1 1 0 0
- 0x8800 0 0 2 &mpic 2 1 0 0
- 0x8800 0 0 3 &mpic 3 1 0 0
- 0x8800 0 0 4 &mpic 4 1 0 0>;
- };
-
- pci1: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x02000000 0 0x98000000 0 0x98000000 0 0x08000000
- 0x01000000 0 0x00000000 0 0xffc20000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0x98000000
- 0x02000000 0 0x98000000
- 0 0x08000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x02000000 0 0x90000000 0 0x90000000 0 0x08000000
- 0x01000000 0 0x00000000 0 0xffc10000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0x90000000
- 0x02000000 0 0x90000000
- 0 0x08000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe0b000 {
- reg = <0 0xffe0b000 0 0x1000>;
- ranges = <0x02000000 0 0xa0000000 0 0xa0000000 0 0x20000000
- 0x01000000 0 0x00000000 0 0xffc30000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xa0000000
- 0x02000000 0 0xa0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00100000>;
- };
- };
-};
-
-/include/ "fsl/mpc8536si-post.dtsi"
-/include/ "mpc8536ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dtsi b/arch/powerpc/boot/dts/mpc8536ds.dtsi
deleted file mode 100644
index 937ad7e..0000000
--- a/arch/powerpc/boot/dts/mpc8536ds.dtsi
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * MPC8536DS Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- reg = <0x0 0x03000000>;
- label = "ramdisk-nor";
- };
-
- partition@3000000 {
- reg = <0x03000000 0x00e00000>;
- label = "diagnostic-nor";
- read-only;
- };
-
- partition@3e00000 {
- reg = <0x03e00000 0x00200000>;
- label = "dink-nor";
- read-only;
- };
-
- partition@4000000 {
- reg = <0x04000000 0x00400000>;
- label = "kernel-nor";
- };
-
- partition@4400000 {
- reg = <0x04400000 0x03b00000>;
- label = "fs-nor";
- };
-
- partition@7f00000 {
- reg = <0x07f00000 0x00080000>;
- label = "dtb-nor";
- };
-
- partition@7f80000 {
- reg = <0x07f80000 0x00080000>;
- label = "u-boot-nor";
- read-only;
- };
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8536-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x2 0x0 0x40000>;
-
- partition@0 {
- reg = <0x0 0x02000000>;
- label = "u-boot-nand";
- read-only;
- };
-
- partition@2000000 {
- reg = <0x02000000 0x10000000>;
- label = "fs-nand";
- };
-
- partition@12000000 {
- reg = <0x12000000 0x08000000>;
- label = "ramdisk-nand";
- };
-
- partition@1a000000 {
- reg = <0x1a000000 0x04000000>;
- label = "kernel-nand";
- };
-
- partition@1e000000 {
- reg = <0x1e000000 0x01000000>;
- label = "dtb-nand";
- };
-
- partition@1f000000 {
- reg = <0x1f000000 0x21000000>;
- label = "empty-nand";
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,mpc8536ds-fpga-pixis";
- reg = <0x3 0x0 0x8000>;
- };
-};
-
-&board_soc {
- i2c@3100 {
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0 0x1 0 0>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>;
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- flash@1 {
- compatible = "spansion,s25sl12801";
- reg = <1>;
- spi-max-frequency = <40000000>;
- };
- flash@2 {
- compatible = "spansion,s25sl12801";
- reg = <2>;
- spi-max-frequency = <40000000>;
- };
- flash@3 {
- compatible = "spansion,s25sl12801";
- reg = <3>;
- spi-max-frequency = <40000000>;
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- usb@23000 {
- phy_type = "ulpi";
- };
-
- enet0: ethernet@24000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@24520 {
- phy0: ethernet-phy@0 {
- interrupts = <10 0x1 0 0>;
- reg = <0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <10 0x1 0 0>;
- reg = <1>;
- };
- sgmii_phy0: sgmii-phy@0 {
- interrupts = <6 1 0 0>;
- reg = <0x1d>;
- };
- sgmii_phy1: sgmii-phy@1 {
- interrupts = <6 1 0 0>;
- reg = <0x1c>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet2: ethernet@26000 {
- tbi-handle = <&tbi1>;
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- usb@2b000 {
- dr_mode = "peripheral";
- phy_type = "ulpi";
- };
-};
diff --git a/arch/powerpc/boot/dts/mpc8536ds_36b.dts b/arch/powerpc/boot/dts/mpc8536ds_36b.dts
deleted file mode 100644
index 6c723ee..0000000
--- a/arch/powerpc/boot/dts/mpc8536ds_36b.dts
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * MPC8536DS Device Tree Source (36-bit address map)
- *
- * Copyright 2008-2009, 2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/mpc8536si-pre.dtsi"
-
-/ {
- model = "fsl,mpc8536ds";
- compatible = "fsl,mpc8536ds";
-
- cpus {
- #cpus = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8536@0 {
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0 0 0 0>; // Filled by U-Boot
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
- 0x2 0x0 0xf 0xffa00000 0x00040000
- 0x3 0x0 0xf 0xffdf0000 0x00008000>;
- };
-
- board_soc: soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pci@fffe08000 {
- reg = <0xf 0xffe08000 0 0x1000>;
- ranges = <0x02000000 0 0xf0000000 0xc 0x00000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xffc00000 0 0x00010000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x11 J17 Slot 1 */
- 0x8800 0 0 1 &mpic 1 1 0 0
- 0x8800 0 0 2 &mpic 2 1 0 0
- 0x8800 0 0 3 &mpic 3 1 0 0
- 0x8800 0 0 4 &mpic 4 1 0 0>;
- };
-
- pci1: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x02000000 0 0xf8000000 0xc 0x18000000 0 0x08000000
- 0x01000000 0 0x00000000 0xf 0xffc20000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xf8000000
- 0x02000000 0 0xf8000000
- 0 0x08000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x02000000 0 0xf8000000 0xc 0x10000000 0 0x08000000
- 0x01000000 0 0x00000000 0xf 0xffc10000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xf8000000
- 0x02000000 0 0xf8000000
- 0 0x08000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@fffe0b000 {
- reg = <0xf 0xffe0b000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xffc30000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00100000>;
- };
- };
-};
-
-/include/ "fsl/mpc8536si-post.dtsi"
-/include/ "mpc8536ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
deleted file mode 100644
index 7ce274c..0000000
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * MPC8540 ADS Device Tree Source
- *
- * Copyright 2006, 2008 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/ "fsl/e500v2_power_isa.dtsi"
-
-/ {
- model = "MPC8540ADS";
- compatible = "MPC8540ADS", "MPC85xxADS";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8540@0 {
- device_type = "cpu";
- reg = <0x0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <0x8000>; // L1, 32K
- i-cache-size = <0x8000>; // L1, 32K
- timebase-frequency = <0>; // 33 MHz, from uboot
- bus-frequency = <0>; // 166 MHz
- clock-frequency = <0>; // 825 MHz, from uboot
- next-level-cache = <&L2>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x8000000>; // 128M at 0x0
- };
-
- soc8540@e0000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0xe0000000 0x100000>;
- bus-frequency = <0>;
-
- ecm-law@0 {
- compatible = "fsl,ecm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <8>;
- };
-
- ecm@1000 {
- compatible = "fsl,mpc8540-ecm", "fsl,ecm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- memory-controller@2000 {
- compatible = "fsl,mpc8540-memory-controller";
- reg = <0x2000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <18 2>;
- };
-
- L2: l2-cache-controller@20000 {
- compatible = "fsl,mpc8540-l2-cache-controller";
- reg = <0x20000 0x1000>;
- cache-line-size = <32>; // 32 bytes
- cache-size = <0x40000>; // L2, 256K
- interrupt-parent = <&mpic>;
- interrupts = <16 2>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8540-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8540-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8540-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8540-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet2: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "FEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <41 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy3>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
- };
-
- pci0: pci@e0008000 {
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x02 */
- 0x1000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x1000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x1000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x1000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 0x03 */
- 0x1800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x1800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x1800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x1800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x04 */
- 0x2000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0x2000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0x2000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0x2000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 0x05 */
- 0x2800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0x2800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0x2800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0x2800 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 0x0c */
- 0x6000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x6000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x6000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x6000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 0x0d */
- 0x6800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x6800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x6800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x6800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x0e */
- 0x7000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0x7000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0x7000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0x7000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 0x0f */
- 0x7800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0x7800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0x7800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0x7800 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 0x12 */
- 0x9000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x9000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x9000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 0x13 */
- 0x9800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x9800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x9800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x9800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x14 */
- 0xa000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0xa000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0xa000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0xa000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 0x15 */
- 0xa800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0x1 0x1>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0008000 0x1000>;
- compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci";
- device_type = "pci";
- };
-};
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
deleted file mode 100644
index 4d35a3e..0000000
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * MPC8541 CDS Device Tree Source
- *
- * Copyright 2006, 2008 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/ "fsl/e500v2_power_isa.dtsi"
-
-/ {
- model = "MPC8541CDS";
- compatible = "MPC8541CDS", "MPC85xxCDS";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8541@0 {
- device_type = "cpu";
- reg = <0x0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <0x8000>; // L1, 32K
- i-cache-size = <0x8000>; // L1, 32K
- timebase-frequency = <0>; // 33 MHz, from uboot
- bus-frequency = <0>; // 166 MHz
- clock-frequency = <0>; // 825 MHz, from uboot
- next-level-cache = <&L2>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x8000000>; // 128M at 0x0
- };
-
- soc8541@e0000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0xe0000000 0x100000>;
- bus-frequency = <0>;
-
- ecm-law@0 {
- compatible = "fsl,ecm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <8>;
- };
-
- ecm@1000 {
- compatible = "fsl,mpc8541-ecm", "fsl,ecm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- memory-controller@2000 {
- compatible = "fsl,mpc8541-memory-controller";
- reg = <0x2000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <18 2>;
- };
-
- L2: l2-cache-controller@20000 {
- compatible = "fsl,mpc8541-l2-cache-controller";
- reg = <0x20000 0x1000>;
- cache-line-size = <32>; // 32 bytes
- cache-size = <0x40000>; // L2, 256K
- interrupt-parent = <&mpic>;
- interrupts = <16 2>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8541-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8541-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8541-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8541-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8541-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- crypto@30000 {
- compatible = "fsl,sec2.0";
- reg = <0x30000 0x10000>;
- interrupts = <45 2>;
- interrupt-parent = <&mpic>;
- fsl,num-channels = <4>;
- fsl,channel-fifo-len = <24>;
- fsl,exec-units-mask = <0x7e>;
- fsl,descriptor-types-mask = <0x01010ebf>;
- };
-
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- cpm@919c0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8541-cpm", "fsl,cpm2";
- reg = <0x919c0 0x30>;
- ranges;
-
- muram@80000 {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x0 0x80000 0x10000>;
-
- data@0 {
- compatible = "fsl,cpm-muram-data";
- reg = <0x0 0x2000 0x9000 0x1000>;
- };
- };
-
- brg@919f0 {
- compatible = "fsl,mpc8541-brg",
- "fsl,cpm2-brg",
- "fsl,cpm-brg";
- reg = <0x919f0 0x10 0x915f0 0x10>;
- };
-
- cpmpic: pic@90c00 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <46 2>;
- interrupt-parent = <&mpic>;
- reg = <0x90c00 0x80>;
- compatible = "fsl,mpc8541-cpm-pic", "fsl,cpm2-pic";
- };
- };
- };
-
- pci0: pci@e0008000 {
- interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x10 */
- 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x11 */
- 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x12 (Slot 1) */
- 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x13 (Slot 2) */
- 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1
-
- /* IDSEL 0x14 (Slot 3) */
- 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1
- 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1
- 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1
- 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 0x15 (Slot 4) */
- 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* Bus 1 (Tundra Bridge) */
- /* IDSEL 0x12 (ISA bridge) */
- 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0008000 0x1000>;
- compatible = "fsl,mpc8540-pci";
- device_type = "pci";
-
- i8259@19000 {
- interrupt-controller;
- device_type = "interrupt-controller";
- reg = <0x19000 0x0 0x0 0x0 0x1>;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- compatible = "chrp,iic";
- interrupts = <1>;
- interrupt-parent = <&pci0>;
- };
- };
-
- pci1: pci@e0009000 {
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x15 */
- 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>;
- interrupt-parent = <&mpic>;
- interrupts = <25 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0009000 0x1000>;
- compatible = "fsl,mpc8540-pci";
- device_type = "pci";
- };
-};
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
deleted file mode 100644
index ed38874..0000000
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * MPC8544 DS Device Tree Source
- *
- * Copyright 2007, 2008 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/ "fsl/mpc8544si-pre.dtsi"
-
-/ {
- model = "MPC8544DS";
- compatible = "MPC8544DS", "MPC85xxDS";
-
- memory {
- device_type = "memory";
- reg = <0 0 0 0>; // Filled by U-Boot
- };
-
- board_lbc: lbc: localbus@e0005000 {
- reg = <0 0xe0005000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xff800000 0x800000>;
- };
-
- board_soc: soc: soc8544@e0000000 {
- ranges = <0x0 0x0 0xe0000000 0x100000>;
- };
-
- pci0: pci@e0008000 {
- reg = <0 0xe0008000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xe1000000 0x0 0x10000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x11 J17 Slot 1 */
- 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1 0 0
- 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1 0 0
- 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1 0 0
- 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1 0 0
-
- /* IDSEL 0x12 J16 Slot 2 */
-
- 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1 0 0
- 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1 0 0
- 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
- 0x9000 0x0 0x0 0x4 &mpic 0x1 0x1 0 0>;
- };
-
- pci1: pcie@e0009000 {
- reg = <0x0 0xe0009000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xe1010000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci2: pcie@e000a000 {
- reg = <0x0 0xe000a000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0 0xe1020000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x10000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- board_pci3: pci3: pcie@e000b000 {
- reg = <0x0 0xe000b000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xb0000000 0 0xb0000000 0x0 0x100000
- 0x1000000 0x0 0x00000000 0 0xb0100000 0x0 0x100000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xb0000000
- 0x2000000 0x0 0xb0000000
- 0x0 0x100000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/*
- * mpc8544ds.dtsi must be last to ensure board_pci3 overrides pci3 settings
- * for interrupt-map & interrupt-map-mask
- */
-
-/include/ "fsl/mpc8544si-post.dtsi"
-/include/ "mpc8544ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8548cds_32b.dts b/arch/powerpc/boot/dts/mpc8548cds_32b.dts
deleted file mode 100644
index 6fd6316..0000000
--- a/arch/powerpc/boot/dts/mpc8548cds_32b.dts
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * MPC8548 CDS Device Tree Source (32-bit address map)
- *
- * Copyright 2006, 2008, 2011-2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/mpc8548si-pre.dtsi"
-
-/ {
- model = "MPC8548CDS";
- compatible = "MPC8548CDS", "MPC85xxCDS";
-
- memory {
- device_type = "memory";
- reg = <0 0 0x0 0x8000000>; // 128M at 0x0
- };
-
- board_lbc: lbc: localbus@e0005000 {
- reg = <0 0xe0005000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xff000000 0x01000000
- 0x1 0x0 0x0 0xf8004000 0x00001000>;
-
- };
-
- board_soc: soc: soc8548@e0000000 {
- ranges = <0 0x0 0xe0000000 0x100000>;
- };
-
- board_pci0: pci0: pci@e0008000 {
- reg = <0 0xe0008000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0 0xe2000000 0x0 0x800000>;
- clock-frequency = <66666666>;
- };
-
- pci1: pci@e0009000 {
- reg = <0 0xe0009000 0 0x1000>;
- ranges = <0x2000000 0x0 0x90000000 0 0x90000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0 0xe2800000 0x0 0x800000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x15 */
- 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 0 0
- 0xa800 0x0 0x0 0x2 &mpic 0x1 0x1 0 0
- 0xa800 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
- 0xa800 0x0 0x0 0x4 &mpic 0x3 0x1 0 0>;
- };
-
- pci2: pcie@e000a000 {
- reg = <0 0xe000a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xe3000000 0x0 0x100000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- rio: rapidio@e00c0000 {
- reg = <0x0 0xe00c0000 0x0 0x20000>;
- port1 {
- ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
- };
- };
-};
-
-/*
- * mpc8548cds.dtsi must be last to ensure board_pci0 overrides pci0 settings
- * for interrupt-map & interrupt-map-mask.
- */
-
-/include/ "fsl/mpc8548si-post.dtsi"
-/include/ "mpc8548cds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8548cds_36b.dts b/arch/powerpc/boot/dts/mpc8548cds_36b.dts
deleted file mode 100644
index 10e551b..0000000
--- a/arch/powerpc/boot/dts/mpc8548cds_36b.dts
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * MPC8548 CDS Device Tree Source (36-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/mpc8548si-pre.dtsi"
-
-/ {
- model = "MPC8548CDS";
- compatible = "MPC8548CDS", "MPC85xxCDS";
-
- memory {
- device_type = "memory";
- reg = <0 0 0x0 0x8000000>; // 128M at 0x0
- };
-
- board_lbc: lbc: localbus@fe0005000 {
- reg = <0xf 0xe0005000 0 0x1000>;
-
- ranges = <0x0 0x0 0xf 0xff000000 0x01000000
- 0x1 0x0 0xf 0xf8004000 0x00001000>;
-
- };
-
- board_soc: soc: soc8548@fe0000000 {
- ranges = <0 0xf 0xe0000000 0x100000>;
- };
-
- board_pci0: pci0: pci@fe0008000 {
- reg = <0xf 0xe0008000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0xf 0xe2000000 0x0 0x800000>;
- clock-frequency = <66666666>;
- };
-
- pci1: pci@fe0009000 {
- reg = <0xf 0xe0009000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0xf 0xe2800000 0x0 0x800000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x15 */
- 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1 0 0
- 0xa800 0x0 0x0 0x2 &mpic 0x1 0x1 0 0
- 0xa800 0x0 0x0 0x3 &mpic 0x2 0x1 0 0
- 0xa800 0x0 0x0 0x4 &mpic 0x3 0x1 0 0>;
- };
-
- pci2: pcie@fe000a000 {
- reg = <0xf 0xe000a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xe3000000 0x0 0x100000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- rio: rapidio@fe00c0000 {
- reg = <0xf 0xe00c0000 0x0 0x20000>;
- port1 {
- ranges = <0x0 0x0 0xc 0x40000000 0x0 0x20000000>;
- };
- };
-};
-
-/*
- * mpc8548cds.dtsi must be last to ensure board_pci0 overrides pci0 settings
- * for interrupt-map & interrupt-map-mask.
- */
-
-/include/ "fsl/mpc8548si-post.dtsi"
-/include/ "mpc8548cds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
deleted file mode 100644
index f115f21..0000000
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * MPC8555 CDS Device Tree Source
- *
- * Copyright 2006, 2008 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/ "fsl/e500v2_power_isa.dtsi"
-
-/ {
- model = "MPC8555CDS";
- compatible = "MPC8555CDS", "MPC85xxCDS";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8555@0 {
- device_type = "cpu";
- reg = <0x0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <0x8000>; // L1, 32K
- i-cache-size = <0x8000>; // L1, 32K
- timebase-frequency = <0>; // 33 MHz, from uboot
- bus-frequency = <0>; // 166 MHz
- clock-frequency = <0>; // 825 MHz, from uboot
- next-level-cache = <&L2>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x8000000>; // 128M at 0x0
- };
-
- soc8555@e0000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0xe0000000 0x100000>;
- bus-frequency = <0>;
-
- ecm-law@0 {
- compatible = "fsl,ecm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <8>;
- };
-
- ecm@1000 {
- compatible = "fsl,mpc8555-ecm", "fsl,ecm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- memory-controller@2000 {
- compatible = "fsl,mpc8555-memory-controller";
- reg = <0x2000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <18 2>;
- };
-
- L2: l2-cache-controller@20000 {
- compatible = "fsl,mpc8555-l2-cache-controller";
- reg = <0x20000 0x1000>;
- cache-line-size = <32>; // 32 bytes
- cache-size = <0x40000>; // L2, 256K
- interrupt-parent = <&mpic>;
- interrupts = <16 2>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8555-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8555-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8555-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8555-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8555-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>; // reg base, size
- clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- crypto@30000 {
- compatible = "fsl,sec2.0";
- reg = <0x30000 0x10000>;
- interrupts = <45 2>;
- interrupt-parent = <&mpic>;
- fsl,num-channels = <4>;
- fsl,channel-fifo-len = <24>;
- fsl,exec-units-mask = <0x7e>;
- fsl,descriptor-types-mask = <0x01010ebf>;
- };
-
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- cpm@919c0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8555-cpm", "fsl,cpm2";
- reg = <0x919c0 0x30>;
- ranges;
-
- muram@80000 {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x0 0x80000 0x10000>;
-
- data@0 {
- compatible = "fsl,cpm-muram-data";
- reg = <0x0 0x2000 0x9000 0x1000>;
- };
- };
-
- brg@919f0 {
- compatible = "fsl,mpc8555-brg",
- "fsl,cpm2-brg",
- "fsl,cpm-brg";
- reg = <0x919f0 0x10 0x915f0 0x10>;
- };
-
- cpmpic: pic@90c00 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <46 2>;
- interrupt-parent = <&mpic>;
- reg = <0x90c00 0x80>;
- compatible = "fsl,mpc8555-cpm-pic", "fsl,cpm2-pic";
- };
- };
- };
-
- pci0: pci@e0008000 {
- interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x10 */
- 0x8000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x8000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x8000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x8000 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x11 */
- 0x8800 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x8800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x8800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x8800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x12 (Slot 1) */
- 0x9000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x9000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x9000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x9000 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x13 (Slot 2) */
- 0x9800 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x9800 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x9800 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x9800 0x0 0x0 0x4 &mpic 0x0 0x1
-
- /* IDSEL 0x14 (Slot 3) */
- 0xa000 0x0 0x0 0x1 &mpic 0x2 0x1
- 0xa000 0x0 0x0 0x2 &mpic 0x3 0x1
- 0xa000 0x0 0x0 0x3 &mpic 0x0 0x1
- 0xa000 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 0x15 (Slot 4) */
- 0xa800 0x0 0x0 0x1 &mpic 0x3 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0x0 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0x1 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* Bus 1 (Tundra Bridge) */
- /* IDSEL 0x12 (ISA bridge) */
- 0x19000 0x0 0x0 0x1 &mpic 0x0 0x1
- 0x19000 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x19000 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x19000 0x0 0x0 0x4 &mpic 0x3 0x1>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe2000000 0x0 0x100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0008000 0x1000>;
- compatible = "fsl,mpc8540-pci";
- device_type = "pci";
-
- i8259@19000 {
- interrupt-controller;
- device_type = "interrupt-controller";
- reg = <0x19000 0x0 0x0 0x0 0x1>;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- compatible = "chrp,iic";
- interrupts = <1>;
- interrupt-parent = <&pci0>;
- };
- };
-
- pci1: pci@e0009000 {
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x15 */
- 0xa800 0x0 0x0 0x1 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0xb 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0xb 0x1>;
- interrupt-parent = <&mpic>;
- interrupts = <25 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe3000000 0x0 0x100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0009000 0x1000>;
- compatible = "fsl,mpc8540-pci";
- device_type = "pci";
- };
-};
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
deleted file mode 100644
index 0d70921..0000000
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * MPC8560 ADS Device Tree Source
- *
- * Copyright 2006, 2008 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/ "fsl/e500v2_power_isa.dtsi"
-
-/ {
- model = "MPC8560ADS";
- compatible = "MPC8560ADS", "MPC85xxADS";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- ethernet3 = &enet3;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8560@0 {
- device_type = "cpu";
- reg = <0x0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <0x8000>; // L1, 32K
- i-cache-size = <0x8000>; // L1, 32K
- timebase-frequency = <82500000>;
- bus-frequency = <330000000>;
- clock-frequency = <825000000>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x10000000>;
- };
-
- soc8560@e0000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0xe0000000 0x100000>;
- bus-frequency = <330000000>;
-
- ecm-law@0 {
- compatible = "fsl,ecm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <8>;
- };
-
- ecm@1000 {
- compatible = "fsl,mpc8560-ecm", "fsl,ecm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- memory-controller@2000 {
- compatible = "fsl,mpc8540-memory-controller";
- reg = <0x2000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <18 2>;
- };
-
- L2: l2-cache-controller@20000 {
- compatible = "fsl,mpc8540-l2-cache-controller";
- reg = <0x20000 0x1000>;
- cache-line-size = <32>; // 32 bytes
- cache-size = <0x40000>; // L2, 256K
- interrupt-parent = <&mpic>;
- interrupts = <16 2>;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8560-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8560-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8560-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8560-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8560-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x2>;
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- cpm@919c0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8560-cpm", "fsl,cpm2";
- reg = <0x919c0 0x30>;
- ranges;
-
- muram@80000 {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x0 0x80000 0x10000>;
-
- data@0 {
- compatible = "fsl,cpm-muram-data";
- reg = <0x0 0x4000 0x9000 0x2000>;
- };
- };
-
- brg@919f0 {
- compatible = "fsl,mpc8560-brg",
- "fsl,cpm2-brg",
- "fsl,cpm-brg";
- reg = <0x919f0 0x10 0x915f0 0x10>;
- clock-frequency = <165000000>;
- };
-
- cpmpic: pic@90c00 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- interrupts = <46 2>;
- interrupt-parent = <&mpic>;
- reg = <0x90c00 0x80>;
- compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic";
- };
-
- serial0: serial@91a00 {
- device_type = "serial";
- compatible = "fsl,mpc8560-scc-uart",
- "fsl,cpm2-scc-uart";
- reg = <0x91a00 0x20 0x88000 0x100>;
- fsl,cpm-brg = <1>;
- fsl,cpm-command = <0x800000>;
- current-speed = <115200>;
- interrupts = <40 8>;
- interrupt-parent = <&cpmpic>;
- };
-
- serial1: serial@91a20 {
- device_type = "serial";
- compatible = "fsl,mpc8560-scc-uart",
- "fsl,cpm2-scc-uart";
- reg = <0x91a20 0x20 0x88100 0x100>;
- fsl,cpm-brg = <2>;
- fsl,cpm-command = <0x4a00000>;
- current-speed = <115200>;
- interrupts = <41 8>;
- interrupt-parent = <&cpmpic>;
- };
-
- enet2: ethernet@91320 {
- device_type = "network";
- compatible = "fsl,mpc8560-fcc-enet",
- "fsl,cpm2-fcc-enet";
- reg = <0x91320 0x20 0x88500 0x100 0x913b0 0x1>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- fsl,cpm-command = <0x16200300>;
- interrupts = <33 8>;
- interrupt-parent = <&cpmpic>;
- phy-handle = <&phy2>;
- };
-
- enet3: ethernet@91340 {
- device_type = "network";
- compatible = "fsl,mpc8560-fcc-enet",
- "fsl,cpm2-fcc-enet";
- reg = <0x91340 0x20 0x88600 0x100 0x913d0 0x1>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- fsl,cpm-command = <0x1a400300>;
- interrupts = <34 8>;
- interrupt-parent = <&cpmpic>;
- phy-handle = <&phy3>;
- };
- };
- };
-
- pci0: pci@e0008000 {
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci";
- device_type = "pci";
- reg = <0xe0008000 0x1000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x2 */
- 0x1000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x1000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x1000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x1000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 0x3 */
- 0x1800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x1800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x1800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x1800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 0x4 */
- 0x2000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0x2000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0x2000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0x2000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 0x5 */
- 0x2800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0x2800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0x2800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0x2800 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 12 */
- 0x6000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x6000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x6000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x6000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 13 */
- 0x6800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x6800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x6800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x6800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 14*/
- 0x7000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0x7000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0x7000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0x7000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 15 */
- 0x7800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0x7800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0x7800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0x7800 0x0 0x0 0x4 &mpic 0x1 0x1
-
- /* IDSEL 18 */
- 0x9000 0x0 0x0 0x1 &mpic 0x1 0x1
- 0x9000 0x0 0x0 0x2 &mpic 0x2 0x1
- 0x9000 0x0 0x0 0x3 &mpic 0x3 0x1
- 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1
-
- /* IDSEL 19 */
- 0x9800 0x0 0x0 0x1 &mpic 0x4 0x1
- 0x9800 0x0 0x0 0x2 &mpic 0x1 0x1
- 0x9800 0x0 0x0 0x3 &mpic 0x2 0x1
- 0x9800 0x0 0x0 0x4 &mpic 0x3 0x1
-
- /* IDSEL 20 */
- 0xa000 0x0 0x0 0x1 &mpic 0x3 0x1
- 0xa000 0x0 0x0 0x2 &mpic 0x4 0x1
- 0xa000 0x0 0x0 0x3 &mpic 0x1 0x1
- 0xa000 0x0 0x0 0x4 &mpic 0x2 0x1
-
- /* IDSEL 21 */
- 0xa800 0x0 0x0 0x1 &mpic 0x2 0x1
- 0xa800 0x0 0x0 0x2 &mpic 0x3 0x1
- 0xa800 0x0 0x0 0x3 &mpic 0x4 0x1
- 0xa800 0x0 0x0 0x4 &mpic 0x1 0x1>;
-
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- bus-range = <0 0>;
- ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x0 0xe2000000 0x0 0x1000000>;
- };
-};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
deleted file mode 100644
index bead2b6..0000000
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * MPC8568E MDS Device Tree Source
- *
- * Copyright 2007, 2008 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/ "fsl/mpc8568si-pre.dtsi"
-
-/ {
- model = "MPC8568EMDS";
- compatible = "MPC8568EMDS", "MPC85xxMDS";
-
- aliases {
- pci0 = &pci0;
- pci1 = &pci1;
- rapidio0 = &rio;
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x0 0x0 0x0>;
- };
-
- lbc: localbus@e0005000 {
- reg = <0x0 0xe0005000 0x0 0x1000>;
- ranges = <0x0 0x0 0xfe000000 0x02000000
- 0x1 0x0 0xf8000000 0x00008000
- 0x2 0x0 0xf0000000 0x04000000
- 0x4 0x0 0xf8008000 0x00008000
- 0x5 0x0 0xf8010000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x02000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- bcsr@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8568mds-bcsr";
- reg = <1 0 0x8000>;
- ranges = <0 1 0 0x8000>;
-
- bcsr5: gpio-controller@11 {
- #gpio-cells = <2>;
- compatible = "fsl,mpc8568mds-bcsr-gpio";
- reg = <0x5 0x1>;
- gpio-controller;
- };
- };
-
- pib@4,0 {
- compatible = "fsl,mpc8568mds-pib";
- reg = <4 0 0x8000>;
- };
-
- pib@5,0 {
- compatible = "fsl,mpc8568mds-pib";
- reg = <5 0 0x8000>;
- };
- };
-
- soc: soc8568@e0000000 {
- ranges = <0x0 0x0 0xe0000000 0x100000>;
-
- i2c-sleep-nexus {
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <3 1 0 0>;
- };
- };
- };
-
- enet0: ethernet@24000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy2>;
- };
-
- mdio@24520 {
- phy0: ethernet-phy@7 {
- interrupts = <1 1 0 0>;
- reg = <0x7>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- phy2: ethernet-phy@2 {
- interrupts = <1 1 0 0>;
- reg = <0x2>;
- };
- phy3: ethernet-phy@3 {
- interrupts = <2 1 0 0>;
- reg = <0x3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet1: ethernet@25000 {
- tbi-handle = <&tbi1>;
- phy-handle = <&phy3>;
- sleep = <&pmc 0x00000040>;
- };
-
- mdio@25520 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- par_io@e0100 {
- num-ports = <7>;
-
- pio1: ucc_pin@01 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x4 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
- 0x4 0x9 0x1 0x0 0x2 0x0 /* TxD1 */
- 0x4 0x8 0x1 0x0 0x2 0x0 /* TxD2 */
- 0x4 0x7 0x1 0x0 0x2 0x0 /* TxD3 */
- 0x4 0x17 0x1 0x0 0x2 0x0 /* TxD4 */
- 0x4 0x16 0x1 0x0 0x2 0x0 /* TxD5 */
- 0x4 0x15 0x1 0x0 0x2 0x0 /* TxD6 */
- 0x4 0x14 0x1 0x0 0x2 0x0 /* TxD7 */
- 0x4 0xf 0x2 0x0 0x2 0x0 /* RxD0 */
- 0x4 0xe 0x2 0x0 0x2 0x0 /* RxD1 */
- 0x4 0xd 0x2 0x0 0x2 0x0 /* RxD2 */
- 0x4 0xc 0x2 0x0 0x2 0x0 /* RxD3 */
- 0x4 0x1d 0x2 0x0 0x2 0x0 /* RxD4 */
- 0x4 0x1c 0x2 0x0 0x2 0x0 /* RxD5 */
- 0x4 0x1b 0x2 0x0 0x2 0x0 /* RxD6 */
- 0x4 0x1a 0x2 0x0 0x2 0x0 /* RxD7 */
- 0x4 0xb 0x1 0x0 0x2 0x0 /* TX_EN */
- 0x4 0x18 0x1 0x0 0x2 0x0 /* TX_ER */
- 0x4 0x10 0x2 0x0 0x2 0x0 /* RX_DV */
- 0x4 0x1e 0x2 0x0 0x2 0x0 /* RX_ER */
- 0x4 0x11 0x2 0x0 0x2 0x0 /* RX_CLK */
- 0x4 0x13 0x1 0x0 0x2 0x0 /* GTX_CLK */
- 0x1 0x1f 0x2 0x0 0x3 0x0>; /* GTX125 */
- };
-
- pio2: ucc_pin@02 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x5 0xa 0x1 0x0 0x2 0x0 /* TxD0 */
- 0x5 0x9 0x1 0x0 0x2 0x0 /* TxD1 */
- 0x5 0x8 0x1 0x0 0x2 0x0 /* TxD2 */
- 0x5 0x7 0x1 0x0 0x2 0x0 /* TxD3 */
- 0x5 0x17 0x1 0x0 0x2 0x0 /* TxD4 */
- 0x5 0x16 0x1 0x0 0x2 0x0 /* TxD5 */
- 0x5 0x15 0x1 0x0 0x2 0x0 /* TxD6 */
- 0x5 0x14 0x1 0x0 0x2 0x0 /* TxD7 */
- 0x5 0xf 0x2 0x0 0x2 0x0 /* RxD0 */
- 0x5 0xe 0x2 0x0 0x2 0x0 /* RxD1 */
- 0x5 0xd 0x2 0x0 0x2 0x0 /* RxD2 */
- 0x5 0xc 0x2 0x0 0x2 0x0 /* RxD3 */
- 0x5 0x1d 0x2 0x0 0x2 0x0 /* RxD4 */
- 0x5 0x1c 0x2 0x0 0x2 0x0 /* RxD5 */
- 0x5 0x1b 0x2 0x0 0x2 0x0 /* RxD6 */
- 0x5 0x1a 0x2 0x0 0x2 0x0 /* RxD7 */
- 0x5 0xb 0x1 0x0 0x2 0x0 /* TX_EN */
- 0x5 0x18 0x1 0x0 0x2 0x0 /* TX_ER */
- 0x5 0x10 0x2 0x0 0x2 0x0 /* RX_DV */
- 0x5 0x1e 0x2 0x0 0x2 0x0 /* RX_ER */
- 0x5 0x11 0x2 0x0 0x2 0x0 /* RX_CLK */
- 0x5 0x13 0x1 0x0 0x2 0x0 /* GTX_CLK */
- 0x1 0x1f 0x2 0x0 0x3 0x0 /* GTX125 */
- 0x4 0x6 0x3 0x0 0x2 0x0 /* MDIO */
- 0x4 0x5 0x1 0x0 0x2 0x0>; /* MDC */
- };
- };
- };
-
- qe: qe@e0080000 {
- ranges = <0x0 0x0 0xe0080000 0x40000>;
- reg = <0x0 0xe0080000 0x0 0x480>;
-
- spi@4c0 {
- mode = "cpu";
- };
-
- spi@500 {
- mode = "cpu";
- };
-
- enet2: ucc@2000 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk16";
- pio-handle = <&pio1>;
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet3: ucc@3000 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk16";
- pio-handle = <&pio2>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@2120 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x2120 0x18>;
- compatible = "fsl,ucc-mdio";
-
- /* These are the same PHYs as on
- * gianfar's MDIO bus */
- qe_phy0: ethernet-phy@07 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1 0 0>;
- reg = <0x7>;
- };
- qe_phy1: ethernet-phy@01 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- qe_phy2: ethernet-phy@02 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1 0 0>;
- reg = <0x2>;
- };
- qe_phy3: ethernet-phy@03 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1 0 0>;
- reg = <0x3>;
- };
- };
- };
-
- pci0: pci@e0008000 {
- reg = <0x0 0xe0008000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0x0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xe2000000 0x0 0x800000>;
- clock-frequency = <66666666>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- /* IDSEL 0x12 AD18 */
- 0x9000 0x0 0x0 0x1 &mpic 0x5 0x1 0 0
- 0x9000 0x0 0x0 0x2 &mpic 0x6 0x1 0 0
- 0x9000 0x0 0x0 0x3 &mpic 0x7 0x1 0 0
- 0x9000 0x0 0x0 0x4 &mpic 0x4 0x1 0 0
-
- /* IDSEL 0x13 AD19 */
- 0x9800 0x0 0x0 0x1 &mpic 0x6 0x1 0 0
- 0x9800 0x0 0x0 0x2 &mpic 0x7 0x1 0 0
- 0x9800 0x0 0x0 0x3 &mpic 0x4 0x1 0 0
- 0x9800 0x0 0x0 0x4 &mpic 0x5 0x1 0 0>;
- };
-
- /* PCI Express */
- pci1: pcie@e000a000 {
- ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0x0 0xe2800000 0x0 0x800000>;
- reg = <0x0 0xe000a000 0x0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x10000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x800000>;
- };
- };
-
- rio: rapidio@e00c00000 {
- reg = <0x0 0xe00c0000 0x0 0x20000>;
- port1 {
- ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
-
- green {
- gpios = <&bcsr5 1 0>;
- };
-
- amber {
- gpios = <&bcsr5 2 0>;
- };
-
- red {
- gpios = <&bcsr5 3 0>;
- };
- };
-};
-
-/include/ "fsl/mpc8568si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
deleted file mode 100644
index d0dcdaf..0000000
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * MPC8569E MDS Device Tree Source
- *
- * Copyright (C) 2009 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/ "fsl/mpc8569si-pre.dtsi"
-
-/ {
- model = "MPC8569EMDS";
- compatible = "fsl,MPC8569EMDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- aliases {
- ethernet2 = &enet2;
- ethernet3 = &enet3;
- ethernet5 = &enet5;
- ethernet7 = &enet7;
- rapidio0 = &rio;
- };
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@e0005000 {
- reg = <0x0 0xe0005000 0x0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xfe000000 0x02000000
- 0x1 0x0 0x0 0xf8000000 0x00008000
- 0x2 0x0 0x0 0xf0000000 0x04000000
- 0x3 0x0 0x0 0xfc000000 0x00008000
- 0x4 0x0 0x0 0xf8008000 0x00008000
- 0x5 0x0 0x0 0xf8010000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x02000000>;
- bank-width = <1>;
- device-width = <1>;
- partition@0 {
- label = "ramdisk";
- reg = <0x00000000 0x01c00000>;
- };
- partition@1c00000 {
- label = "kernel";
- reg = <0x01c00000 0x002e0000>;
- };
- partiton@1ee0000 {
- label = "dtb";
- reg = <0x01ee0000 0x00020000>;
- };
- partition@1f00000 {
- label = "firmware";
- reg = <0x01f00000 0x00080000>;
- read-only;
- };
- partition@1f80000 {
- label = "u-boot";
- reg = <0x01f80000 0x00080000>;
- read-only;
- };
- };
-
- bcsr@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8569mds-bcsr";
- reg = <1 0 0x8000>;
- ranges = <0 1 0 0x8000>;
-
- bcsr17: gpio-controller@11 {
- #gpio-cells = <2>;
- compatible = "fsl,mpc8569mds-bcsr-gpio";
- reg = <0x11 0x1>;
- gpio-controller;
- };
- };
-
- nand@3,0 {
- compatible = "fsl,mpc8569-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <3 0 0x8000>;
- };
-
- pib@4,0 {
- compatible = "fsl,mpc8569mds-pib";
- reg = <4 0 0x8000>;
- };
-
- pib@5,0 {
- compatible = "fsl,mpc8569mds-pib";
- reg = <5 0 0x8000>;
- };
- };
-
- soc: soc@e0000000 {
- ranges = <0x0 0x0 0xe0000000 0x100000>;
-
- i2c-sleep-nexus {
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <3 1 0 0>;
- };
- };
- };
-
- sdhc@2e000 {
- status = "disabled";
- sdhci,1-bit-only;
- bus-width = <1>;
- };
-
- par_io@e0100 {
- num-ports = <7>;
-
- qe_pio_e: gpio-controller@80 {
- #gpio-cells = <2>;
- compatible = "fsl,mpc8569-qe-pario-bank",
- "fsl,mpc8323-qe-pario-bank";
- reg = <0x80 0x18>;
- gpio-controller;
- };
-
- qe_pio_f: gpio-controller@a0 {
- #gpio-cells = <2>;
- compatible = "fsl,mpc8569-qe-pario-bank",
- "fsl,mpc8323-qe-pario-bank";
- reg = <0xa0 0x18>;
- gpio-controller;
- };
-
- pio1: ucc_pin@01 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
- 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
- 0x0 0x0 0x1 0x0 0x3 0x0 /* ENET1_TXD0_SER1_TXD0 */
- 0x0 0x1 0x1 0x0 0x3 0x0 /* ENET1_TXD1_SER1_TXD1 */
- 0x0 0x2 0x1 0x0 0x1 0x0 /* ENET1_TXD2_SER1_TXD2 */
- 0x0 0x3 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
- 0x0 0x6 0x2 0x0 0x3 0x0 /* ENET1_RXD0_SER1_RXD0 */
- 0x0 0x7 0x2 0x0 0x1 0x0 /* ENET1_RXD1_SER1_RXD1 */
- 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
- 0x0 0x9 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
- 0x0 0x4 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
- 0x0 0xc 0x2 0x0 0x3 0x0 /* ENET1_RX_DV_SER1_CTS_B */
- 0x2 0x8 0x2 0x0 0x1 0x0 /* ENET1_GRXCLK */
- 0x2 0x14 0x1 0x0 0x2 0x0>; /* ENET1_GTXCLK */
- };
-
- pio2: ucc_pin@02 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
- 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
- 0x0 0xe 0x1 0x0 0x2 0x0 /* ENET2_TXD0_SER2_TXD0 */
- 0x0 0xf 0x1 0x0 0x2 0x0 /* ENET2_TXD1_SER2_TXD1 */
- 0x0 0x10 0x1 0x0 0x1 0x0 /* ENET2_TXD2_SER2_TXD2 */
- 0x0 0x11 0x1 0x0 0x1 0x0 /* ENET2_TXD3_SER2_TXD3 */
- 0x0 0x14 0x2 0x0 0x2 0x0 /* ENET2_RXD0_SER2_RXD0 */
- 0x0 0x15 0x2 0x0 0x1 0x0 /* ENET2_RXD1_SER2_RXD1 */
- 0x0 0x16 0x2 0x0 0x1 0x0 /* ENET2_RXD2_SER2_RXD2 */
- 0x0 0x17 0x2 0x0 0x1 0x0 /* ENET2_RXD3_SER2_RXD3 */
- 0x0 0x12 0x1 0x0 0x2 0x0 /* ENET2_TX_EN_SER2_RTS_B */
- 0x0 0x1a 0x2 0x0 0x3 0x0 /* ENET2_RX_DV_SER2_CTS_B */
- 0x2 0x3 0x2 0x0 0x1 0x0 /* ENET2_GRXCLK */
- 0x2 0x2 0x1 0x0 0x2 0x0>; /* ENET2_GTXCLK */
- };
-
- pio3: ucc_pin@03 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
- 0x2 0x0b 0x2 0x0 0x1 0x0 /* CLK12*/
- 0x0 0x1d 0x1 0x0 0x2 0x0 /* ENET3_TXD0_SER3_TXD0 */
- 0x0 0x1e 0x1 0x0 0x3 0x0 /* ENET3_TXD1_SER3_TXD1 */
- 0x0 0x1f 0x1 0x0 0x2 0x0 /* ENET3_TXD2_SER3_TXD2 */
- 0x1 0x0 0x1 0x0 0x3 0x0 /* ENET3_TXD3_SER3_TXD3 */
- 0x1 0x3 0x2 0x0 0x3 0x0 /* ENET3_RXD0_SER3_RXD0 */
- 0x1 0x4 0x2 0x0 0x1 0x0 /* ENET3_RXD1_SER3_RXD1 */
- 0x1 0x5 0x2 0x0 0x2 0x0 /* ENET3_RXD2_SER3_RXD2 */
- 0x1 0x6 0x2 0x0 0x3 0x0 /* ENET3_RXD3_SER3_RXD3 */
- 0x1 0x1 0x1 0x0 0x1 0x0 /* ENET3_TX_EN_SER3_RTS_B */
- 0x1 0x9 0x2 0x0 0x3 0x0 /* ENET3_RX_DV_SER3_CTS_B */
- 0x2 0x9 0x2 0x0 0x2 0x0 /* ENET3_GRXCLK */
- 0x2 0x19 0x1 0x0 0x2 0x0>; /* ENET3_GTXCLK */
- };
-
- pio4: ucc_pin@04 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x2 0x1f 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x2 0x1e 0x3 0x0 0x2 0x0 /* QE_MUX_MDIO */
- 0x2 0x10 0x2 0x0 0x3 0x0 /* CLK17 */
- 0x1 0xc 0x1 0x0 0x2 0x0 /* ENET4_TXD0_SER4_TXD0 */
- 0x1 0xd 0x1 0x0 0x2 0x0 /* ENET4_TXD1_SER4_TXD1 */
- 0x1 0xe 0x1 0x0 0x1 0x0 /* ENET4_TXD2_SER4_TXD2 */
- 0x1 0xf 0x1 0x0 0x2 0x0 /* ENET4_TXD3_SER4_TXD3 */
- 0x1 0x12 0x2 0x0 0x2 0x0 /* ENET4_RXD0_SER4_RXD0 */
- 0x1 0x13 0x2 0x0 0x1 0x0 /* ENET4_RXD1_SER4_RXD1 */
- 0x1 0x14 0x2 0x0 0x1 0x0 /* ENET4_RXD2_SER4_RXD2 */
- 0x1 0x15 0x2 0x0 0x2 0x0 /* ENET4_RXD3_SER4_RXD3 */
- 0x1 0x10 0x1 0x0 0x2 0x0 /* ENET4_TX_EN_SER4_RTS_B */
- 0x1 0x18 0x2 0x0 0x3 0x0 /* ENET4_RX_DV_SER4_CTS_B */
- 0x2 0x11 0x2 0x0 0x2 0x0 /* ENET4_GRXCLK */
- 0x2 0x18 0x1 0x0 0x2 0x0>; /* ENET4_GTXCLK */
- };
- };
- };
-
- qe: qe@e0080000 {
- ranges = <0x0 0x0 0xe0080000 0x40000>;
- reg = <0x0 0xe0080000 0x0 0x480>;
-
- spi@4c0 {
- gpios = <&qe_pio_e 30 0>;
- mode = "cpu-qe";
-
- serial-flash@0 {
- compatible = "stm,m25p40";
- reg = <0>;
- spi-max-frequency = <25000000>;
- };
- };
-
- spi@500 {
- mode = "cpu";
- };
-
- usb@6c0 {
- fsl,fullspeed-clock = "clk5";
- fsl,lowspeed-clock = "brg10";
- gpios = <&qe_pio_f 3 0 /* USBOE */
- &qe_pio_f 4 0 /* USBTP */
- &qe_pio_f 5 0 /* USBTN */
- &qe_pio_f 6 0 /* USBRP */
- &qe_pio_f 8 0 /* USBRN */
- &bcsr17 1 0 /* SPEED */
- &bcsr17 2 0>; /* POWER */
- };
-
- enet0: ucc@2000 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk12";
- pio-handle = <&pio1>;
- tbi-handle = <&tbi1>;
- phy-handle = <&qe_phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@2120 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x2120 0x18>;
- compatible = "fsl,ucc-mdio";
-
- qe_phy0: ethernet-phy@07 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1 0 0>;
- reg = <0x7>;
- };
- qe_phy1: ethernet-phy@01 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- qe_phy2: ethernet-phy@02 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1 0 0>;
- reg = <0x2>;
- };
- qe_phy3: ethernet-phy@03 {
- interrupt-parent = <&mpic>;
- interrupts = <4 1 0 0>;
- reg = <0x3>;
- };
- qe_phy5: ethernet-phy@04 {
- reg = <0x04>;
- };
- qe_phy7: ethernet-phy@06 {
- reg = <0x6>;
- };
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- mdio@3520 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x3520 0x18>;
- compatible = "fsl,ucc-mdio";
-
- tbi6: tbi-phy@15 {
- reg = <0x15>;
- device_type = "tbi-phy";
- };
- };
- mdio@3720 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x3720 0x38>;
- compatible = "fsl,ucc-mdio";
- tbi8: tbi-phy@17 {
- reg = <0x17>;
- device_type = "tbi-phy";
- };
- };
-
- enet2: ucc@2200 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk12";
- pio-handle = <&pio3>;
- tbi-handle = <&tbi3>;
- phy-handle = <&qe_phy2>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@2320 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x2320 0x18>;
- compatible = "fsl,ucc-mdio";
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet1: ucc@3000 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk17";
- pio-handle = <&pio2>;
- tbi-handle = <&tbi2>;
- phy-handle = <&qe_phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@3120 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x3120 0x18>;
- compatible = "fsl,ucc-mdio";
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet3: ucc@3200 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk17";
- pio-handle = <&pio4>;
- tbi-handle = <&tbi4>;
- phy-handle = <&qe_phy3>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@3320 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x3320 0x18>;
- compatible = "fsl,ucc-mdio";
- tbi4: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet5: ucc@3400 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "none";
- tbi-handle = <&tbi6>;
- phy-handle = <&qe_phy5>;
- phy-connection-type = "sgmii";
- };
-
- enet7: ucc@3600 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "none";
- tbi-handle = <&tbi8>;
- phy-handle = <&qe_phy7>;
- phy-connection-type = "sgmii";
- };
- };
-
- /* PCI Express */
- pci1: pcie@e000a000 {
- reg = <0x0 0xe000a000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000
- 0x1000000 0x0 0x00000000 0 0xe2800000 0x0 0x00800000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x10000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x800000>;
- };
- };
-
- rio: rapidio@e00c00000 {
- reg = <0x0 0xe00c0000 0x0 0x20000>;
- port1 {
- ranges = <0x0 0x0 0x0 0xc0000000 0x0 0x20000000>;
- };
- port2 {
- status = "disabled";
- };
- };
-};
-
-/include/ "fsl/mpc8569si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
deleted file mode 100644
index 0c9f295..0000000
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * MPC8572 DS Device Tree Source
- *
- * Copyright 2007-2009 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/ "fsl/mpc8572si-pre.dtsi"
-
-/ {
- model = "fsl,MPC8572DS";
- compatible = "fsl,MPC8572DS";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
- 0x1 0x0 0x0 0xe0000000 0x08000000
- 0x2 0x0 0x0 0xffa00000 0x00040000
- 0x3 0x0 0x0 0xffdf0000 0x00008000
- 0x4 0x0 0x0 0xffa40000 0x00040000
- 0x5 0x0 0x0 0xffa80000 0x00040000
- 0x6 0x0 0x0 0xffac0000 0x00040000>;
- };
-
- board_soc: soc: soc8572@ffe00000 {
- ranges = <0x0 0 0xffe00000 0x100000>;
- };
-
- board_pci0: pci0: pcie@ffe08000 {
- reg = <0 0xffe08000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci1: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci2: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-};
-
-/*
- * mpc8572ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
- * for interrupt-map & interrupt-map-mask
- */
-
-/include/ "fsl/mpc8572si-post.dtsi"
-/include/ "mpc8572ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8572ds_36b.dts b/arch/powerpc/boot/dts/mpc8572ds_36b.dts
deleted file mode 100644
index 6c3d0b3..0000000
--- a/arch/powerpc/boot/dts/mpc8572ds_36b.dts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * MPC8572DS Device Tree Source (36-bit address map)
- *
- * Copyright 2007-2009 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/ "fsl/mpc8572si-pre.dtsi"
-
-/ {
- model = "fsl,MPC8572DS";
- compatible = "fsl,MPC8572DS";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
- 0x1 0x0 0xf 0xe0000000 0x08000000
- 0x2 0x0 0xf 0xffa00000 0x00040000
- 0x3 0x0 0xf 0xffdf0000 0x00008000
- 0x4 0x0 0xf 0xffa40000 0x00040000
- 0x5 0x0 0xf 0xffa80000 0x00040000
- 0x6 0x0 0xf 0xffac0000 0x00040000>;
- };
-
- board_soc: soc: soc8572@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- board_pci0: pci0: pcie@fffe08000 {
- reg = <0xf 0xffe08000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci1: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci2: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-};
-
-/*
- * mpc8572ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
- * for interrupt-map & interrupt-map-mask
- */
-
-/include/ "fsl/mpc8572si-post.dtsi"
-/include/ "mpc8572ds.dtsi"
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
deleted file mode 100644
index 1c03060..0000000
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * MPC8641 HPCN Device Tree Source
- *
- * Copyright 2006 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/;
-
-/ {
- model = "MPC8641HPCN";
- compatible = "fsl,mpc8641hpcn";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- ethernet3 = &enet3;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>;
- i-cache-line-size = <32>;
- d-cache-size = <32768>; // L1
- i-cache-size = <32768>; // L1
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>;
- i-cache-line-size = <32>;
- d-cache-size = <32768>;
- i-cache-size = <32768>;
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x40000000>; // 1G at 0x0
- };
-
- localbus@ffe05000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xffe05000 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xef800000 0x00800000
- 2 0 0xffdf8000 0x00008000
- 3 0 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x00800000>;
- bank-width = <2>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x00300000>;
- };
- partition@300000 {
- label = "firmware b";
- reg = <0x00300000 0x00100000>;
- read-only;
- };
- partition@400000 {
- label = "fs";
- reg = <0x00400000 0x00300000>;
- };
- partition@700000 {
- label = "firmware a";
- reg = <0x00700000 0x00100000>;
- read-only;
- };
- };
- };
-
- soc8641@ffe00000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x00000000 0xffe00000 0x00100000>;
- bus-frequency = <0>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <2>;
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet2: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet3: ethernet@27000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <3>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x27000 0x1000>;
- ranges = <0x0 0x27000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <37 2 38 2 39 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi3>;
- phy-handle = <&phy3>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <28 2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- rmu: rmu@d3000 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,srio-rmu";
- reg = <0xd3000 0x500>;
- ranges = <0x0 0xd3000 0x500>;
-
- message-unit@0 {
- compatible = "fsl,srio-msg-unit";
- reg = <0x0 0x100>;
- interrupts = <
- 53 2 /* msg1_tx_irq */
- 54 2>;/* msg1_rx_irq */
- };
- message-unit@100 {
- compatible = "fsl,srio-msg-unit";
- reg = <0x100 0x100>;
- interrupts = <
- 55 2 /* msg2_tx_irq */
- 56 2>;/* msg2_rx_irq */
- };
- doorbell-unit@400 {
- compatible = "fsl,srio-dbell-unit";
- reg = <0x400 0x80>;
- interrupts = <
- 49 2 /* bell_outb_irq */
- 50 2>;/* bell_inb_irq */
- };
- port-write-unit@4e0 {
- compatible = "fsl,srio-port-write-unit";
- reg = <0x4e0 0x20>;
- interrupts = <48 2>;
- };
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@ffe08000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xffe08000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- interrupt-map-mask = <0xff00 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x11 func 0 - PCI slot 1 */
- 0x8800 0 0 1 &mpic 2 1
- 0x8800 0 0 2 &mpic 3 1
- 0x8800 0 0 3 &mpic 4 1
- 0x8800 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 1 - PCI slot 1 */
- 0x8900 0 0 1 &mpic 2 1
- 0x8900 0 0 2 &mpic 3 1
- 0x8900 0 0 3 &mpic 4 1
- 0x8900 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 2 - PCI slot 1 */
- 0x8a00 0 0 1 &mpic 2 1
- 0x8a00 0 0 2 &mpic 3 1
- 0x8a00 0 0 3 &mpic 4 1
- 0x8a00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 3 - PCI slot 1 */
- 0x8b00 0 0 1 &mpic 2 1
- 0x8b00 0 0 2 &mpic 3 1
- 0x8b00 0 0 3 &mpic 4 1
- 0x8b00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 4 - PCI slot 1 */
- 0x8c00 0 0 1 &mpic 2 1
- 0x8c00 0 0 2 &mpic 3 1
- 0x8c00 0 0 3 &mpic 4 1
- 0x8c00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 5 - PCI slot 1 */
- 0x8d00 0 0 1 &mpic 2 1
- 0x8d00 0 0 2 &mpic 3 1
- 0x8d00 0 0 3 &mpic 4 1
- 0x8d00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 6 - PCI slot 1 */
- 0x8e00 0 0 1 &mpic 2 1
- 0x8e00 0 0 2 &mpic 3 1
- 0x8e00 0 0 3 &mpic 4 1
- 0x8e00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 7 - PCI slot 1 */
- 0x8f00 0 0 1 &mpic 2 1
- 0x8f00 0 0 2 &mpic 3 1
- 0x8f00 0 0 3 &mpic 4 1
- 0x8f00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x12 func 0 - PCI slot 2 */
- 0x9000 0 0 1 &mpic 3 1
- 0x9000 0 0 2 &mpic 4 1
- 0x9000 0 0 3 &mpic 1 1
- 0x9000 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 1 - PCI slot 2 */
- 0x9100 0 0 1 &mpic 3 1
- 0x9100 0 0 2 &mpic 4 1
- 0x9100 0 0 3 &mpic 1 1
- 0x9100 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 2 - PCI slot 2 */
- 0x9200 0 0 1 &mpic 3 1
- 0x9200 0 0 2 &mpic 4 1
- 0x9200 0 0 3 &mpic 1 1
- 0x9200 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 3 - PCI slot 2 */
- 0x9300 0 0 1 &mpic 3 1
- 0x9300 0 0 2 &mpic 4 1
- 0x9300 0 0 3 &mpic 1 1
- 0x9300 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 4 - PCI slot 2 */
- 0x9400 0 0 1 &mpic 3 1
- 0x9400 0 0 2 &mpic 4 1
- 0x9400 0 0 3 &mpic 1 1
- 0x9400 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 5 - PCI slot 2 */
- 0x9500 0 0 1 &mpic 3 1
- 0x9500 0 0 2 &mpic 4 1
- 0x9500 0 0 3 &mpic 1 1
- 0x9500 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 6 - PCI slot 2 */
- 0x9600 0 0 1 &mpic 3 1
- 0x9600 0 0 2 &mpic 4 1
- 0x9600 0 0 3 &mpic 1 1
- 0x9600 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 7 - PCI slot 2 */
- 0x9700 0 0 1 &mpic 3 1
- 0x9700 0 0 2 &mpic 4 1
- 0x9700 0 0 3 &mpic 1 1
- 0x9700 0 0 4 &mpic 2 1
-
- // IDSEL 0x1c USB
- 0xe000 0 0 1 &i8259 12 2
- 0xe100 0 0 2 &i8259 9 2
- 0xe200 0 0 3 &i8259 10 2
- 0xe300 0 0 4 &i8259 11 2
-
- // IDSEL 0x1d Audio
- 0xe800 0 0 1 &i8259 6 2
-
- // IDSEL 0x1e Legacy
- 0xf000 0 0 1 &i8259 7 2
- 0xf100 0 0 1 &i8259 7 2
-
- // IDSEL 0x1f IDE/SATA
- 0xf800 0 0 1 &i8259 14 2
- 0xf900 0 0 1 &i8259 5 2
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- uli1575@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x20000000
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- isa@1e {
- device_type = "isa";
- #interrupt-cells = <2>;
- #size-cells = <1>;
- #address-cells = <2>;
- reg = <0xf000 0 0 0 0>;
- ranges = <1 0 0x01000000 0 0
- 0x00001000>;
- interrupt-parent = <&i8259>;
-
- i8259: interrupt-controller@20 {
- reg = <1 0x20 2
- 1 0xa0 2
- 1 0x4d0 2>;
- interrupt-controller;
- device_type = "interrupt-controller";
- #address-cells = <0>;
- #interrupt-cells = <2>;
- compatible = "chrp,iic";
- interrupts = <9 2>;
- interrupt-parent = <&mpic>;
- };
-
- i8042@60 {
- #size-cells = <0>;
- #address-cells = <1>;
- reg = <1 0x60 1 1 0x64 1>;
- interrupts = <1 3 12 3>;
- interrupt-parent =
- <&i8259>;
-
- keyboard@0 {
- reg = <0>;
- compatible = "pnpPNP,303";
- };
-
- mouse@1 {
- reg = <1>;
- compatible = "pnpPNP,f03";
- };
- };
-
- rtc@70 {
- compatible =
- "pnpPNP,b00";
- reg = <1 0x70 2>;
- };
-
- gpio@400 {
- reg = <1 0x400 0x80>;
- };
- };
- };
- };
-
- };
-
- pci1: pcie@ffe09000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xffe09000 0x1000>;
- bus-range = <0 0xff>;
- ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <25 2>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0x0000 0 0 1 &mpic 4 1
- 0x0000 0 0 2 &mpic 5 1
- 0x0000 0 0 3 &mpic 6 1
- 0x0000 0 0 4 &mpic 7 1
- >;
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0xa0000000
- 0x02000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- };
- };
-/*
- * Only one of Rapid IO or PCI can be present due to HW limitations and
- * due to the fact that the 2 now share address space in the new memory
- * map. The most likely case is that we have PCI, so comment out the
- * rapidio node. Leave it here for reference.
-
- rapidio@ffec0000 {
- reg = <0xffec0000 0x11000>;
- compatible = "fsl,srio";
- interrupt-parent = <&mpic>;
- interrupts = <48 2>;
- #address-cells = <2>;
- #size-cells = <2>;
- fsl,srio-rmu-handle = <&rmu>;
- ranges;
-
- port1 {
- #address-cells = <2>;
- #size-cells = <2>;
- cell-index = <1>;
- ranges = <0 0 0x80000000 0 0x20000000>;
- };
- };
-*/
-
-};
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
deleted file mode 100644
index bb575e2..0000000
--- a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * MPC8641 HPCN Device Tree Source
- *
- * Copyright 2008-2009 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/;
-
-/ {
- model = "MPC8641HPCN";
- compatible = "fsl,mpc8641hpcn";
- #address-cells = <2>;
- #size-cells = <2>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- ethernet3 = &enet3;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // 33 MHz, from uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <32768>; // L1, 32K
- i-cache-size = <32768>; // L1, 32K
- timebase-frequency = <0>; // 33 MHz, from uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0
- };
-
- localbus@fffe05000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0x0f 0xffe05000 0x0 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xf 0xef800000 0x00800000
- 2 0 0xf 0xffdf8000 0x00008000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x00800000>;
- bank-width = <2>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x00300000>;
- };
- partition@300000 {
- label = "firmware b";
- reg = <0x00300000 0x00100000>;
- read-only;
- };
- partition@400000 {
- label = "fs";
- reg = <0x00400000 0x00300000>;
- };
- partition@700000 {
- label = "firmware a";
- reg = <0x00700000 0x00100000>;
- read-only;
- };
- };
- };
-
- soc8641@fffe00000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
- bus-frequency = <0>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <2>;
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <3>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet2: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet3: ethernet@27000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <3>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x27000 0x1000>;
- ranges = <0x0 0x27000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <37 2 38 2 39 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi3>;
- phy-handle = <&phy3>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <28 2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@fffe08000 {
- cell-index = <0>;
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0x0f 0xffe08000 0x0 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- interrupt-map-mask = <0xff00 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x11 func 0 - PCI slot 1 */
- 0x8800 0 0 1 &mpic 2 1
- 0x8800 0 0 2 &mpic 3 1
- 0x8800 0 0 3 &mpic 4 1
- 0x8800 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 1 - PCI slot 1 */
- 0x8900 0 0 1 &mpic 2 1
- 0x8900 0 0 2 &mpic 3 1
- 0x8900 0 0 3 &mpic 4 1
- 0x8900 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 2 - PCI slot 1 */
- 0x8a00 0 0 1 &mpic 2 1
- 0x8a00 0 0 2 &mpic 3 1
- 0x8a00 0 0 3 &mpic 4 1
- 0x8a00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 3 - PCI slot 1 */
- 0x8b00 0 0 1 &mpic 2 1
- 0x8b00 0 0 2 &mpic 3 1
- 0x8b00 0 0 3 &mpic 4 1
- 0x8b00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 4 - PCI slot 1 */
- 0x8c00 0 0 1 &mpic 2 1
- 0x8c00 0 0 2 &mpic 3 1
- 0x8c00 0 0 3 &mpic 4 1
- 0x8c00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 5 - PCI slot 1 */
- 0x8d00 0 0 1 &mpic 2 1
- 0x8d00 0 0 2 &mpic 3 1
- 0x8d00 0 0 3 &mpic 4 1
- 0x8d00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 6 - PCI slot 1 */
- 0x8e00 0 0 1 &mpic 2 1
- 0x8e00 0 0 2 &mpic 3 1
- 0x8e00 0 0 3 &mpic 4 1
- 0x8e00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x11 func 7 - PCI slot 1 */
- 0x8f00 0 0 1 &mpic 2 1
- 0x8f00 0 0 2 &mpic 3 1
- 0x8f00 0 0 3 &mpic 4 1
- 0x8f00 0 0 4 &mpic 1 1
-
- /* IDSEL 0x12 func 0 - PCI slot 2 */
- 0x9000 0 0 1 &mpic 3 1
- 0x9000 0 0 2 &mpic 4 1
- 0x9000 0 0 3 &mpic 1 1
- 0x9000 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 1 - PCI slot 2 */
- 0x9100 0 0 1 &mpic 3 1
- 0x9100 0 0 2 &mpic 4 1
- 0x9100 0 0 3 &mpic 1 1
- 0x9100 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 2 - PCI slot 2 */
- 0x9200 0 0 1 &mpic 3 1
- 0x9200 0 0 2 &mpic 4 1
- 0x9200 0 0 3 &mpic 1 1
- 0x9200 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 3 - PCI slot 2 */
- 0x9300 0 0 1 &mpic 3 1
- 0x9300 0 0 2 &mpic 4 1
- 0x9300 0 0 3 &mpic 1 1
- 0x9300 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 4 - PCI slot 2 */
- 0x9400 0 0 1 &mpic 3 1
- 0x9400 0 0 2 &mpic 4 1
- 0x9400 0 0 3 &mpic 1 1
- 0x9400 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 5 - PCI slot 2 */
- 0x9500 0 0 1 &mpic 3 1
- 0x9500 0 0 2 &mpic 4 1
- 0x9500 0 0 3 &mpic 1 1
- 0x9500 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 6 - PCI slot 2 */
- 0x9600 0 0 1 &mpic 3 1
- 0x9600 0 0 2 &mpic 4 1
- 0x9600 0 0 3 &mpic 1 1
- 0x9600 0 0 4 &mpic 2 1
-
- /* IDSEL 0x12 func 7 - PCI slot 2 */
- 0x9700 0 0 1 &mpic 3 1
- 0x9700 0 0 2 &mpic 4 1
- 0x9700 0 0 3 &mpic 1 1
- 0x9700 0 0 4 &mpic 2 1
-
- // IDSEL 0x1c USB
- 0xe000 0 0 1 &i8259 12 2
- 0xe100 0 0 2 &i8259 9 2
- 0xe200 0 0 3 &i8259 10 2
- 0xe300 0 0 4 &i8259 11 2
-
- // IDSEL 0x1d Audio
- 0xe800 0 0 1 &i8259 6 2
-
- // IDSEL 0x1e Legacy
- 0xf000 0 0 1 &i8259 7 2
- 0xf100 0 0 1 &i8259 7 2
-
- // IDSEL 0x1f IDE/SATA
- 0xf800 0 0 1 &i8259 14 2
- 0xf900 0 0 1 &i8259 5 2
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0xe0000000
- 0x02000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- uli1575@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- ranges = <0x02000000 0x0 0xe0000000
- 0x02000000 0x0 0xe0000000
- 0x0 0x20000000
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- isa@1e {
- device_type = "isa";
- #interrupt-cells = <2>;
- #size-cells = <1>;
- #address-cells = <2>;
- reg = <0xf000 0 0 0 0>;
- ranges = <1 0 0x01000000 0 0
- 0x00001000>;
- interrupt-parent = <&i8259>;
-
- i8259: interrupt-controller@20 {
- reg = <1 0x20 2
- 1 0xa0 2
- 1 0x4d0 2>;
- interrupt-controller;
- device_type = "interrupt-controller";
- #address-cells = <0>;
- #interrupt-cells = <2>;
- compatible = "chrp,iic";
- interrupts = <9 2>;
- interrupt-parent = <&mpic>;
- };
-
- i8042@60 {
- #size-cells = <0>;
- #address-cells = <1>;
- reg = <1 0x60 1 1 0x64 1>;
- interrupts = <1 3 12 3>;
- interrupt-parent =
- <&i8259>;
-
- keyboard@0 {
- reg = <0>;
- compatible = "pnpPNP,303";
- };
-
- mouse@1 {
- reg = <1>;
- compatible = "pnpPNP,f03";
- };
- };
-
- rtc@70 {
- compatible =
- "pnpPNP,b00";
- reg = <1 0x70 2>;
- };
-
- gpio@400 {
- reg = <1 0x400 0x80>;
- };
- };
- };
- };
-
- };
-
- pci1: pcie@fffe09000 {
- cell-index = <1>;
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0x0f 0xffe09000 0x0 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <25 2>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0x0000 0 0 1 &mpic 4 1
- 0x0000 0 0 2 &mpic 5 1
- 0x0000 0 0 3 &mpic 6 1
- 0x0000 0 0 4 &mpic 7 1
- >;
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0xe0000000
- 0x02000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/mvme2500.dts b/arch/powerpc/boot/dts/mvme2500.dts
deleted file mode 100644
index 67714cf..0000000
--- a/arch/powerpc/boot/dts/mvme2500.dts
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Device tree source for the Emerson/Artesyn MVME2500
- *
- * Copyright 2014 Elettra-Sincrotrone Trieste S.C.p.A.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 on: P2020 DS Device Tree Source
- * Copyright 2009 Freescale Semiconductor Inc.
- */
-
-/include/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "MVME2500";
- compatible = "artesyn,MVME2500";
-
- aliases {
- serial2 = &serial2;
- serial3 = &serial3;
- serial4 = &serial4;
- serial5 = &serial5;
- };
-
- memory {
- device_type = "memory";
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0 0xffe00000 0x100000>;
-
- i2c@3000 {
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- rtc@68 {
- compatible = "dallas,ds1337";
- reg = <0x68>;
- interrupts = <8 1 0 0>;
- };
-
- eeprom@54 {
- compatible = "atmel,24c64";
- reg = <0x54>;
- };
-
- eeprom@52 {
- compatible = "atmel,24c512";
- reg = <0x52>;
- };
-
- eeprom@53 {
- compatible = "atmel,24c512";
- reg = <0x53>;
- };
-
- eeprom@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- };
-
- };
-
- spi0: spi@7000 {
- fsl,espi-num-chipselects = <2>;
-
- flash@0 {
- compatible = "atmel,at25df641";
- reg = <0>;
- spi-max-frequency = <10000000>;
- };
- flash@1 {
- compatible = "atmel,at25df641";
- reg = <1>;
- spi-max-frequency = <10000000>;
- };
- };
-
- usb@22000 {
- dr_mode = "host";
- phy_type = "ulpi";
- };
-
- enet0: ethernet@24000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@24520 {
- phy1: ethernet-phy@1 {
- compatible = "brcm,bcm54616S";
- interrupts = <6 1 0 0>;
- reg = <0x1>;
- };
-
- phy2: ethernet-phy@2 {
- compatible = "brcm,bcm54616S";
- interrupts = <6 1 0 0>;
- reg = <0x2>;
- };
-
- phy3: ethernet-phy@3 {
- compatible = "brcm,bcm54616S";
- interrupts = <5 1 0 0>;
- reg = <0x3>;
- };
-
- phy7: ethernet-phy@7 {
- compatible = "brcm,bcm54616S";
- interrupts = <7 1 0 0>;
- reg = <0x7>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet1: ethernet@25000 {
- tbi-handle = <&tbi1>;
- phy-handle = <&phy7>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@25520 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet2: ethernet@26000 {
- tbi-handle = <&tbi2>;
- phy-handle = <&phy3>;
- phy-connection-type = "rgmii-id";
- };
-
- mdio@26520 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- ranges = <0x0 0x0 0x0 0xfff00000 0x00080000
- 0x1 0x0 0x0 0xffc40000 0x00010000
- 0x2 0x0 0x0 0xffc50000 0x00010000
- 0x3 0x0 0x0 0xffc60000 0x00010000
- 0x4 0x0 0x0 0xffc70000 0x00010000
- 0x6 0x0 0x0 0xffc80000 0x00010000
- 0x5 0x0 0x0 0xffdf0000 0x00008000>;
-
- serial2: serial@1,0 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x1 0x0 0x100>;
- clock-frequency = <1843200>;
- interrupts = <11 2 0 0>;
- };
-
- serial3: serial@2,0 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x2 0x0 0x100>;
- clock-frequency = <1843200>;
- interrupts = <1 2 0 0>;
- };
-
- serial4: serial@3,0 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x3 0x0 0x100>;
- clock-frequency = <1843200>;
- interrupts = <2 2 0 0>;
- };
-
- serial5: serial@4,0 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <0x4 0x0 0x100>;
- clock-frequency = <1843200>;
- interrupts = <3 2 0 0>;
- };
-
- mram@0,0 {
- compatible = "everspin,mram", "mtd-ram";
- reg = <0x0 0x0 0x80000>;
- bank-width = <2>;
- };
-
- board-control@5,0 {
- compatible = "artesyn,mvme2500-fpga";
- reg = <0x5 0x0 0x01000>;
- };
-
- cpld@6,0 {
- compatible = "artesyn,mvme2500-cpld";
- reg = <0x6 0x0 0x10000>;
- interrupts = <9 1 0 0>;
- };
- };
-
- pci0: pcie@ffe08000 {
- reg = <0 0xffe08000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci1: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
-
- };
-
- pci2: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-};
-
-/include/ "fsl/p2020si-post.dtsi"
-
-/ {
- soc@ffe00000 {
- serial@4600 {
- status = "disabled";
- };
-
- i2c@3100 {
- status = "disabled";
- };
-
- sdhc@2e000 {
- compatible = "fsl,p2020-esdhc", "fsl,esdhc";
- non-removable;
- };
-
- };
-
-};
diff --git a/arch/powerpc/boot/dts/oca4080.dts b/arch/powerpc/boot/dts/oca4080.dts
deleted file mode 100644
index 42796c5..0000000
--- a/arch/powerpc/boot/dts/oca4080.dts
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * OCA4080 Device Tree Source
- *
- * Copyright 2014 Prodrive Technologies B.V.
- *
- * Based on:
- * P4080DS Device Tree Source
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p4080si-pre.dtsi"
-
-/ {
- model = "fsl,OCA4080";
- compatible = "fsl,OCA4080";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- i2c@118000 {
- status = "disabled";
- };
-
- i2c@118100 {
- status = "disabled";
- };
-
- i2c@119000 {
- status = "disabled";
- };
-
- i2c@119100 {
- status = "disabled";
- };
-
- usb0: usb@210000 {
- status = "disabled";
- };
-
- usb1: usb@211000 {
- status = "disabled";
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xef800000 0x800000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x00800000>;
- bank-width = <2>;
- device-width = <2>;
- };
- };
-
- pci0: pcie@ffe200000 {
- status = "disabled";
- };
-
- pci1: pcie@ffe201000 {
- status = "disabled";
- };
-
- pci2: pcie@ffe202000 {
- status = "disabled";
- };
-};
-
-/include/ "fsl/p4080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pa.dts b/arch/powerpc/boot/dts/p1010rdb-pa.dts
deleted file mode 100644
index 767d4c0..0000000
--- a/arch/powerpc/boot/dts/p1010rdb-pa.dts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * P1010 RDB Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p1010si-pre.dtsi"
-
-/ {
- model = "fsl,P1010RDB";
- compatible = "fsl,P1010RDB";
-
- /include/ "p1010rdb_32b.dtsi"
-};
-
-/include/ "p1010rdb.dtsi"
-/include/ "p1010rdb-pa.dtsi"
-/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pa_36b.dts b/arch/powerpc/boot/dts/p1010rdb-pa_36b.dts
deleted file mode 100644
index 3033371..0000000
--- a/arch/powerpc/boot/dts/p1010rdb-pa_36b.dts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * P1010 RDB Device Tree Source (36-bit address map)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1010si-pre.dtsi"
-
-/ {
- model = "fsl,P1010RDB";
- compatible = "fsl,P1010RDB";
-
- /include/ "p1010rdb_36b.dtsi"
-};
-
-/include/ "p1010rdb.dtsi"
-/include/ "p1010rdb-pa.dtsi"
-/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb.dts b/arch/powerpc/boot/dts/p1010rdb-pb.dts
deleted file mode 100644
index 6eeb7d3..0000000
--- a/arch/powerpc/boot/dts/p1010rdb-pb.dts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * P1010 RDB Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p1010si-pre.dtsi"
-
-/ {
- model = "fsl,P1010RDB-PB";
- compatible = "fsl,P1010RDB-PB";
-
- /include/ "p1010rdb_32b.dtsi"
-};
-
-/include/ "p1010rdb.dtsi"
-
-&phy0 {
- interrupts = <0 1 0 0>;
-};
-
-&phy1 {
- interrupts = <2 1 0 0>;
-};
-
-&phy2 {
- interrupts = <1 1 0 0>;
-};
-
-/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb-pb_36b.dts b/arch/powerpc/boot/dts/p1010rdb-pb_36b.dts
deleted file mode 100644
index 7ab3c90..0000000
--- a/arch/powerpc/boot/dts/p1010rdb-pb_36b.dts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * P1010 RDB Device Tree Source (36-bit address map)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1010si-pre.dtsi"
-
-/ {
- model = "fsl,P1010RDB-PB";
- compatible = "fsl,P1010RDB-PB";
-
- /include/ "p1010rdb_36b.dtsi"
-};
-
-/include/ "p1010rdb.dtsi"
-
-&phy0 {
- interrupts = <0 1 0 0>;
-};
-
-&phy1 {
- interrupts = <2 1 0 0>;
-};
-
-&phy2 {
- interrupts = <1 1 0 0>;
-};
-
-/include/ "fsl/p1010si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1010rdb.dtsi b/arch/powerpc/boot/dts/p1010rdb.dtsi
deleted file mode 100644
index ea534ef..0000000
--- a/arch/powerpc/boot/dts/p1010rdb.dtsi
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * P1010 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&board_ifc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x2000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 7 MB for Linux Kernel Image */
- reg = <0x00080000 0x00700000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@800000 {
- /* 20MB for JFFS2 based Root file System */
- reg = <0x00800000 0x01400000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@1f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x01f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- ifc_nand: nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x1 0x0 0x10000>;
- };
-
- cpld@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1010rdb-cpld";
- reg = <0x3 0x0 0x0000020>;
- bank-width = <1>;
- device-width = <1>;
- };
-};
-
-&board_soc {
- i2c@3000 {
- eeprom@50 {
- compatible = "st,24c256";
- reg = <0x50>;
- };
-
- rtc@68 {
- compatible = "pericom,pt7c4338";
- reg = <0x68>;
- };
- };
-
- i2c@3100 {
- eeprom@52 {
- compatible = "atmel,24c01";
- reg = <0x52>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 1MB for u-boot Bootloader Image */
- /* 1MB for Environment */
- reg = <0x0 0x00100000>;
- label = "SPI Flash U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 512KB for DTB Image */
- reg = <0x00100000 0x00080000>;
- label = "SPI Flash DTB Image";
- };
-
- partition@180000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00180000 0x00400000>;
- label = "SPI Flash Linux Kernel Image";
- };
-
- partition@580000 {
- /* 4MB for Compressed RFS Image */
- reg = <0x00580000 0x00400000>;
- label = "SPI Flash Compressed RFSImage";
- };
-
- partition@980000 {
- /* 6.5MB for JFFS2 based RFS */
- reg = <0x00980000 0x00680000>;
- label = "SPI Flash JFFS2 RFS";
- };
- };
- };
-
- usb@22000 {
- phy_type = "utmi";
- dr_mode = "host";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- reg = <0x1>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <0x0>;
- };
-
- phy2: ethernet-phy@2 {
- reg = <0x2>;
- };
-
- tbi-phy@3 {
- device_type = "tbi-phy";
- reg = <0x3>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy1>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy2>;
- tbi-handle = <&tbi1>;
- phy-connection-type = "sgmii";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts b/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts
deleted file mode 100644
index ab8f076..0000000
--- a/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P1020 MBG-PC Device Tree Source (32-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020MBG-PC";
- compatible = "fsl,P1020MBG-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0x0 0xffe05000 0x0 0x1000>;
-
- /* NOR and L2 switch */
- ranges = <0x0 0x0 0x0 0xec000000 0x04000000
- 0x1 0x0 0x0 0xffa00000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- reg = <0x0 0xffe09000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0x0 0xffe0a000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020mbg-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts b/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts
deleted file mode 100644
index 9e9f401..0000000
--- a/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P1020 MBG-PC Device Tree Source (36-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020MBG-PC";
- compatible = "fsl,P1020MBG-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0x0 0x1000>;
-
- /* NOR and L2 switch */
- ranges = <0x0 0x0 0xf 0xec000000 0x04000000
- 0x1 0x0 0xf 0xffa00000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00020000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020mbg-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb-pc.dtsi b/arch/powerpc/boot/dts/p1020rdb-pc.dtsi
deleted file mode 100644
index c952cd3..0000000
--- a/arch/powerpc/boot/dts/p1020rdb-pc.dtsi
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * P1020 RDB-PC Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND Compressed RFS Image";
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00f00000>;
- label = "NAND Writable User area";
- };
- };
-
- L2switch@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x2 0x0 0x20000>;
- };
-
- cpld@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cpld";
- reg = <0x3 0x0 0x20000>;
- read-only;
- };
-};
-
-&soc {
- i2c@3000 {
- rtc@68 {
- compatible = "pericom,pt7c4338";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@u-boot {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "u-boot";
- read-only;
- };
-
- partition@dtb {
- /* 512KB for DTB Image*/
- reg = <0x00080000 0x00080000>;
- label = "dtb";
- };
-
- partition@kernel {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "kernel";
- };
-
- partition@fs {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "file system";
- };
-
- partition@jffs-fs {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "file system jffs2";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- /* USB2 is shared with localbus, so it must be disabled
- by default. We can't put 'status = "disabled";' here
- since U-Boot doesn't clear the status property when
- it enables USB2. OTOH, U-Boot does create a new node
- when there isn't any. So, just comment it out.
- usb@23000 {
- phy_type = "ulpi";
- };
- */
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x1>;
- };
-
- tbi0: tbi-phy@11 {
- device_type = "tbi-phy";
- reg = <0x11>;
- };
- };
-
- mdio@25000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
-
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi1>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1020rdb-pc_32b.dts b/arch/powerpc/boot/dts/p1020rdb-pc_32b.dts
deleted file mode 100644
index 4de69b7..0000000
--- a/arch/powerpc/boot/dts/p1020rdb-pc_32b.dts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * P1020 RDB-PC Device Tree Source (32-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020RDB-PC";
- compatible = "fsl,P1020RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xff800000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000
- 0x3 0x0 0x0 0xffa00000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020rdb-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb-pc_36b.dts b/arch/powerpc/boot/dts/p1020rdb-pc_36b.dts
deleted file mode 100644
index 5237da7..0000000
--- a/arch/powerpc/boot/dts/p1020rdb-pc_36b.dts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * P1020 RDB-PC Device Tree Source (36-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020RDB-PC";
- compatible = "fsl,P1020RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xff800000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00040000
- 0x3 0x0 0xf 0xffa00000 0x00020000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020rdb-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb-pd.dts b/arch/powerpc/boot/dts/p1020rdb-pd.dts
deleted file mode 100644
index 987017e..0000000
--- a/arch/powerpc/boot/dts/p1020rdb-pd.dts
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * P1020 RDB-PD Device Tree Source (32-bit address map)
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020RDB-PD";
- compatible = "fsl,P1020RDB-PD";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0x0 0xffe05000 0x0 0x1000>;
-
- /* NOR, NAND flash, L2 switch and CPLD */
- ranges = <0x0 0x0 0x0 0xec000000 0x04000000
- 0x1 0x0 0x0 0xff800000 0x00040000
- 0x2 0x0 0x0 0xffa00000 0x00020000
- 0x3 0x0 0x0 0xffb00000 0x00020000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x4000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* 128KB for DTB Image */
- reg = <0x0 0x00020000>;
- label = "NOR DTB Image";
- };
-
- partition@20000 {
- /* 3.875 MB for Linux Kernel Image */
- reg = <0x00020000 0x003e0000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 58MB for Root file System */
- reg = <0x00400000 0x03a00000>;
- label = "NOR Root File System";
- };
-
- partition@3e00000 {
- /* This location must not be altered */
- /* 1M for Vitesse 7385 Switch firmware */
- reg = <0x3e00000 0x00100000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@3f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x03f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 122MB for File System Image */
- reg = <0x00600000 0x07a00000>;
- label = "NAND File System Image";
- };
- };
-
- cpld@2,0 {
- compatible = "fsl,p1020rdb-pd-cpld";
- reg = <0x2 0x0 0x20000>;
- };
-
- L2switch@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x3 0x0 0x20000>;
- };
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- /* input clock */
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI U-Boot Image";
- read-only;
- };
-
- partition@80000 {
- /* 512KB for DTB Image*/
- reg = <0x00080000 0x00080000>;
- label = "SPI DTB Image";
- };
-
- partition@100000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI Linux Kernel Image";
- };
-
- partition@500000 {
- /* 11MB for FS System Image */
- reg = <0x00500000 0x00b00000>;
- label = "SPI File System Image";
- };
- };
-
- slic@0 {
- compatible = "zarlink,le88266";
- reg = <1>;
- spi-max-frequency = <8000000>;
- };
-
- slic@1 {
- compatible = "zarlink,le88266";
- reg = <2>;
- spi-max-frequency = <8000000>;
- };
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- };
-
- mdio@25000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi1>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
- };
-
- pci0: pcie@ffe09000 {
- reg = <0x0 0xffe09000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0x0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0x0 0xffe0a000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0x0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts
deleted file mode 100644
index 518bf99..0000000
--- a/arch/powerpc/boot/dts/p1020rdb.dts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * P1020 RDB Device Tree Source
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xffa00000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
- };
-
- board_soc: soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020rdb.dtsi b/arch/powerpc/boot/dts/p1020rdb.dtsi
deleted file mode 100644
index 1fb7e0e..0000000
--- a/arch/powerpc/boot/dts/p1020rdb.dtsi
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * P1020 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011-2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&board_lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR (RO) Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR (RO) DTB Image";
- read-only;
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR (RW) JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR (RO) U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND (RO) U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND (RO) DTB Image";
- read-only;
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND (RO) Compressed RFS Image";
- read-only;
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND (RW) JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00f00000>;
- label = "NAND (RW) Writable User area";
- };
- };
-
- L2switch@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x2 0x0 0x20000>;
- };
-};
-
-&board_soc {
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@u-boot {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "u-boot";
- read-only;
- };
-
- partition@dtb {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "dtb";
- read-only;
- };
-
- partition@kernel {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "kernel";
- read-only;
- };
-
- partition@fs {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "file system";
- read-only;
- };
-
- partition@jffs-fs {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "file system jffs2";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- dr_mode = "host";
- };
-
- /* USB2 is shared with localbus. It is used
- only in case of SPI and SD boot after
- appropriate device-tree fixup done by uboot */
- usb@23000 {
- phy_type = "ulpi";
- dr_mode = "host";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x1>;
- };
-
- tbi-phy@2 {
- device_type = "tbi-phy";
- reg = <0x2>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
-
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1020rdb_36b.dts b/arch/powerpc/boot/dts/p1020rdb_36b.dts
deleted file mode 100644
index bdbdb60..0000000
--- a/arch/powerpc/boot/dts/p1020rdb_36b.dts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * P1020 RDB Device Tree Source (36-bit address map)
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xffa00000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00020000>;
- };
-
- board_soc: soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020utm-pc_32b.dts b/arch/powerpc/boot/dts/p1020utm-pc_32b.dts
deleted file mode 100644
index 4bfdd89..0000000
--- a/arch/powerpc/boot/dts/p1020utm-pc_32b.dts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P1020 UTM-PC Device Tree Source (32-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020UTM-PC";
- compatible = "fsl,P1020UTM-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0x0 0xffe05000 0x0 0x1000>;
-
- /* NOR */
- ranges = <0x0 0x0 0x0 0xec000000 0x02000000
- 0x1 0x0 0x0 0xffa00000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- reg = <0x0 0xffe09000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0x0 0xffe0a000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020utm-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1020utm-pc_36b.dts b/arch/powerpc/boot/dts/p1020utm-pc_36b.dts
deleted file mode 100644
index abec535..0000000
--- a/arch/powerpc/boot/dts/p1020utm-pc_36b.dts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P1020 UTM-PC Device Tree Source (36-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1020UTM-PC";
- compatible = "fsl,P1020UTM-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0x0 0x1000>;
-
- /* NOR */
- ranges = <0x0 0x0 0xf 0xec000000 0x02000000
- 0x1 0x0 0xf 0xffa00000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00020000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0x0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1020utm-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
deleted file mode 100644
index 7655904..0000000
--- a/arch/powerpc/boot/dts/p1021mds.dts
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * P1021 MDS Device Tree Source
- *
- * Copyright 2010,2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1021";
- compatible = "fsl,P1021MDS";
-
- aliases {
- ethernet3 = &enet3;
- ethernet4 = &enet4;
- };
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0x0 0xffe05000 0x0 0x1000>;
-
- /* NAND Flash, BCSR, PMC0/1*/
- ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
- 0x1 0x0 0x0 0xf8000000 0x00008000
- 0x2 0x0 0x0 0xf8010000 0x00020000
- 0x3 0x0 0x0 0xf8020000 0x00020000>;
-
- nand@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1021-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x0 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND (RO) U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND (RO) DTB Image";
- read-only;
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@600000 {
- /* 5MB for Compressed Root file System Image */
- reg = <0x00600000 0x00500000>;
- label = "NAND (RO) Compressed RFS Image";
- read-only;
- };
-
- partition@b00000 {
- /* 6MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00600000>;
- label = "NAND (RW) JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 14MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00e00000>;
- label = "NAND (RW) Writable User area";
- };
-
- partition@1f00000 {
- /* 1MB for microcode */
- reg = <0x01f00000 0x00100000>;
- label = "NAND (RO) QE Ucode";
- read-only;
- };
- };
-
- bcsr@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1021mds-bcsr";
- reg = <1 0 0x8000>;
- ranges = <0 1 0 0x8000>;
- };
-
- pib@2,0 {
- compatible = "fsl,p1021mds-pib";
- reg = <2 0 0x10000>;
- };
-
- pib@3,0 {
- compatible = "fsl,p1021mds-pib";
- reg = <3 0 0x10000>;
- };
- };
-
- soc: soc@ffe00000 {
- compatible = "fsl,p1021-immr", "simple-bus";
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
-
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@u-boot {
- label = "u-boot-spi";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel-spi";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb-spi";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system-spi";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- dr_mode = "host";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <1 1 0 0>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- phy4: ethernet-phy@4 {
- reg = <0x4>;
- };
- tbi-phy@5 {
- device_type = "tbi-phy";
- reg = <0x5>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- ethernet@b1000 {
- phy-handle = <&phy4>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- par_io@e0100 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0xe0100 0x60>;
- ranges = <0x0 0xe0100 0x60>;
- device_type = "par_io";
- num-ports = <3>;
- pio1: ucc_pin@01 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
- 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
- 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
- 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
- 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
- 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
- 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
- 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
- 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
- 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
- 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
- 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
- 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
- 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
- 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
- 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
- };
-
- pio2: ucc_pin@02 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
- 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
- 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
- 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
- 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
- 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
- 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
- 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
- };
- };
- };
-
- pci0: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@ffe80000 {
- ranges = <0x0 0x0 0xffe80000 0x40000>;
- reg = <0 0xffe80000 0 0x480>;
- brg-frequency = <0>;
- bus-frequency = <0>;
- status = "disabled"; /* no firmware loaded */
-
- enet3: ucc@2000 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "clk12";
- tx-clock-name = "clk9";
- pio-handle = <&pio1>;
- phy-handle = <&qe_phy0>;
- phy-connection-type = "mii";
- };
-
- mdio@2120 {
- qe_phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <4 1 0 0>;
- reg = <0x0>;
- };
- qe_phy1: ethernet-phy@03 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1 0 0>;
- reg = <0x3>;
- };
- tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet4: ucc@2400 {
- device_type = "network";
- compatible = "ucc_geth";
- local-mac-address = [ 00 00 00 00 00 00 ];
- rx-clock-name = "none";
- tx-clock-name = "clk13";
- pio-handle = <&pio2>;
- phy-handle = <&qe_phy1>;
- phy-connection-type = "rmii";
- };
- };
-};
-
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/p1021rdb-pc.dtsi
deleted file mode 100644
index d6274c5..0000000
--- a/arch/powerpc/boot/dts/p1021rdb-pc.dtsi
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * P1021 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 10.75MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00ac0000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@ec0000 {
- /* This location must not be altered */
- /* 256KB for QE ucode firmware*/
- reg = <0x00ec0000 0x00040000>;
- label = "NOR QE microcode firmware";
- read-only;
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR U-Boot Image";
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1021-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND Compressed RFS Image";
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for User Writable Area */
- reg = <0x01100000 0x00f00000>;
- label = "NAND Writable User area";
- };
- };
-
- L2switch@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x2 0x0 0x20000>;
- };
-};
-
-&soc {
- i2c@3000 {
- rtc@68 {
- compatible = "pericom,pt7c4338";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@u-boot {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI Flash U-Boot Image";
- read-only;
- };
-
- partition@dtb {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "SPI Flash DTB Image";
- };
-
- partition@kernel {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI Flash Linux Kernel Image";
- };
-
- partition@fs {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "SPI Flash Compressed RFSImage";
- };
-
- partition@jffs-fs {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "SPI Flash JFFS2 RFS";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
-
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi1>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- tbi-handle = <&tbi2>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1021rdb-pc_32b.dts b/arch/powerpc/boot/dts/p1021rdb-pc_32b.dts
deleted file mode 100644
index 7cefa12..0000000
--- a/arch/powerpc/boot/dts/p1021rdb-pc_32b.dts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * P1021 RDB Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1021RDB";
- compatible = "fsl,P1021RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xff800000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@ffe80000 {
- ranges = <0x0 0x0 0xffe80000 0x40000>;
- reg = <0 0xffe80000 0 0x480>;
- brg-frequency = <0>;
- bus-frequency = <0>;
- };
-};
-
-/include/ "p1021rdb-pc.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1021rdb-pc_36b.dts b/arch/powerpc/boot/dts/p1021rdb-pc_36b.dts
deleted file mode 100644
index 53d0c88..0000000
--- a/arch/powerpc/boot/dts/p1021rdb-pc_36b.dts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * P1021 RDB Device Tree Source (36-bit address map)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1021RDB";
- compatible = "fsl,P1021RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes and Vitesse 5 port L2 switch */
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xff800000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00020000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- reg = <0xf 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@fffe80000 {
- ranges = <0x0 0xf 0xffe80000 0x40000>;
- reg = <0xf 0xffe80000 0 0x480>;
- brg-frequency = <0>;
- bus-frequency = <0>;
- };
-};
-
-/include/ "p1021rdb-pc.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1022ds.dtsi b/arch/powerpc/boot/dts/p1022ds.dtsi
deleted file mode 100644
index 957e0dc..0000000
--- a/arch/powerpc/boot/dts/p1022ds.dtsi
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * P1022 DS Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-&board_lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- reg = <0x0 0x03000000>;
- label = "ramdisk-nor";
- read-only;
- };
-
- partition@3000000 {
- reg = <0x03000000 0x00e00000>;
- label = "diagnostic-nor";
- read-only;
- };
-
- partition@3e00000 {
- reg = <0x03e00000 0x00200000>;
- label = "dink-nor";
- read-only;
- };
-
- partition@4000000 {
- reg = <0x04000000 0x00400000>;
- label = "kernel-nor";
- read-only;
- };
-
- partition@4400000 {
- reg = <0x04400000 0x03b00000>;
- label = "jffs2-nor";
- };
-
- partition@7f00000 {
- reg = <0x07f00000 0x00080000>;
- label = "dtb-nor";
- read-only;
- };
-
- partition@7f80000 {
- reg = <0x07f80000 0x00080000>;
- label = "u-boot-nor";
- read-only;
- };
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x2 0x0 0x40000>;
-
- partition@0 {
- reg = <0x0 0x02000000>;
- label = "u-boot-nand";
- read-only;
- };
-
- partition@2000000 {
- reg = <0x02000000 0x10000000>;
- label = "jffs2-nand";
- };
-
- partition@12000000 {
- reg = <0x12000000 0x10000000>;
- label = "ramdisk-nand";
- read-only;
- };
-
- partition@22000000 {
- reg = <0x22000000 0x04000000>;
- label = "kernel-nand";
- };
-
- partition@26000000 {
- reg = <0x26000000 0x01000000>;
- label = "dtb-nand";
- read-only;
- };
-
- partition@27000000 {
- reg = <0x27000000 0x19000000>;
- label = "reserved-nand";
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
- reg = <3 0 0x30>;
- interrupt-parent = <&mpic>;
- /*
- * IRQ8 is generated if the "EVENT" switch is pressed
- * and PX_CTL[EVESEL] is set to 00.
- */
- interrupts = <8 0 0 0>;
- };
-};
-
-&board_soc {
- i2c@3100 {
- wm8776:codec@1a {
- compatible = "wlf,wm8776";
- reg = <0x1a>;
- /*
- * clock-frequency will be set by U-Boot if
- * the clock is enabled.
- */
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@0 {
- label = "u-boot-spi";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@100000 {
- label = "kernel-spi";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@600000 {
- label = "dtb-spi";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@700000 {
- label = "file system-spi";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- ssi@15000 {
- fsl,mode = "i2s-slave";
- codec-handle = <&wm8776>;
- fsl,ssi-asynchronous;
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- usb@23000 {
- status = "disabled";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x1>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <9 1 0 0>;
- reg = <0x2>;
- };
- tbi-phy@2 {
- device_type = "tbi-phy";
- reg = <0x2>;
- };
- };
-
- ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- ethernet@b1000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1022ds_32b.dts b/arch/powerpc/boot/dts/p1022ds_32b.dts
deleted file mode 100644
index d96cae0..0000000
--- a/arch/powerpc/boot/dts/p1022ds_32b.dts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * P1022 DS 32-bit Physical Address Map Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p1022si-pre.dtsi"
-/ {
- model = "fsl,P1022DS";
- compatible = "fsl,P1022DS";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@ffe05000 {
- ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
- 0x1 0x0 0x0 0xe0000000 0x08000000
- 0x2 0x0 0x0 0xff800000 0x00040000
- 0x3 0x0 0x0 0xffdf0000 0x00008000>;
- reg = <0x0 0xffe05000 0 0x1000>;
- };
-
- board_soc: soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0x0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- reg = <0 0xffe0a000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci2: pcie@ffe0b000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- reg = <0 0xffe0b000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p1022si-post.dtsi"
-/include/ "p1022ds.dtsi"
diff --git a/arch/powerpc/boot/dts/p1022ds_36b.dts b/arch/powerpc/boot/dts/p1022ds_36b.dts
deleted file mode 100644
index f7aacce..0000000
--- a/arch/powerpc/boot/dts/p1022ds_36b.dts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * P1022 DS 36-bit Physical Address Map Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p1022si-pre.dtsi"
-/ {
- model = "fsl,P1022DS";
- compatible = "fsl,P1022DS";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@fffe05000 {
- ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
- 0x1 0x0 0xf 0xe0000000 0x08000000
- 0x2 0x0 0xf 0xff800000 0x00040000
- 0x3 0x0 0xf 0xffdf0000 0x00008000>;
- reg = <0xf 0xffe05000 0 0x1000>;
- };
-
- board_soc: soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- reg = <0xf 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x10000>;
- reg = <0xf 0xffe0a000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci2: pcie@fffe0b000 {
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- reg = <0xf 0xffe0b000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p1022si-post.dtsi"
-/include/ "p1022ds.dtsi"
diff --git a/arch/powerpc/boot/dts/p1022rdk.dts b/arch/powerpc/boot/dts/p1022rdk.dts
deleted file mode 100644
index 51d82de..0000000
--- a/arch/powerpc/boot/dts/p1022rdk.dts
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * P1022 RDK 32-bit Physical Address Map Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p1022si-pre.dtsi"
-/ {
- model = "fsl,P1022RDK";
- compatible = "fsl,P1022RDK";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@ffe05000 {
- /* The P1022 RDK does not have any localbus devices */
- status = "disabled";
- };
-
- board_soc: soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
- i2c@3100 {
- wm8960:codec@1a {
- compatible = "wlf,wm8960";
- reg = <0x1a>;
- /* MCLK source is a stand-alone oscillator */
- clock-frequency = <12288000>;
- };
- rtc@68 {
- compatible = "stm,m41t62";
- reg = <0x68>;
- };
- adt7461@4c{
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- zl6100@21{
- compatible = "isil,zl6100";
- reg = <0x21>;
- };
- zl6100@24{
- compatible = "isil,zl6100";
- reg = <0x24>;
- };
- zl6100@26{
- compatible = "isil,zl6100";
- reg = <0x26>;
- };
- zl6100@29{
- compatible = "isil,zl6100";
- reg = <0x29>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,m25p80";
- reg = <0>;
- spi-max-frequency = <1000000>;
- partition@0 {
- label = "full-spi-flash";
- reg = <0x00000000 0x00100000>;
- };
- };
- };
-
- ssi@15000 {
- fsl,mode = "i2s-slave";
- codec-handle = <&wm8960>;
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- usb@23000 {
- phy_type = "ulpi";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x1>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <9 1 0 0>;
- reg = <0x2>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
- };
-
- ethernet@b1000 {
- phy-handle = <&phy1>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0x0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- reg = <0 0xffe0a000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci2: pcie@ffe0b000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- reg = <0 0xffe0b000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p1022si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1023rdb.dts b/arch/powerpc/boot/dts/p1023rdb.dts
deleted file mode 100644
index 05a00a4..0000000
--- a/arch/powerpc/boot/dts/p1023rdb.dts
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * P1023 RDB Device Tree Source
- *
- * Copyright 2013 - 2014 Freescale Semiconductor Inc.
- *
- * Author: Chunhe Lan <Chunhe.Lan@freescale.com>
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1023si-pre.dtsi"
-
-/ {
- model = "fsl,P1023";
- compatible = "fsl,P1023RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- qportals: qman-portals@ff000000 {
- ranges = <0x0 0xf 0xff000000 0x200000>;
- };
-
- bportals: bman-portals@ff200000 {
- ranges = <0x0 0xf 0xff200000 0x200000>;
- };
-
- soc: soc@ff600000 {
- ranges = <0x0 0x0 0xff600000 0x200000>;
-
- i2c@3000 {
- eeprom@53 {
- compatible = "at24,24c04";
- reg = <0x53>;
- };
-
- rtc@6f {
- compatible = "microchip,mcp7941x";
- reg = <0x6f>;
- };
- };
-
- usb@22000 {
- dr_mode = "host";
- phy_type = "ulpi";
- };
- };
-
- lbc: localbus@ff605000 {
- reg = <0 0xff605000 0 0x1000>;
-
- /* NOR, NAND Flashes */
- ranges = <0x0 0x0 0x0 0xec000000 0x04000000
- 0x1 0x0 0x0 0xffa00000 0x08000000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x04000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* 48MB for Root File System */
- reg = <0x00000000 0x03000000>;
- label = "NOR Root File System";
- };
-
- partition@3000000 {
- /* 1MB for DTB Image */
- reg = <0x03000000 0x00100000>;
- label = "NOR DTB Image";
- };
-
- partition@3100000 {
- /* 14MB for Linux Kernel Image */
- reg = <0x03100000 0x00e00000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@3f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x03f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 14MB for Linux Kernel Image */
- reg = <0x00200000 0x00e00000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@1000000 {
- /* 96MB for Root File System Image */
- reg = <0x01000000 0x06000000>;
- label = "NAND Root File System";
- };
-
- partition@7000000 {
- /* 16MB for User Writable Area */
- reg = <0x07000000 0x01000000>;
- label = "NAND Writable User area";
- };
- };
- };
-
- pci0: pcie@ff60a000 {
- reg = <0 0xff60a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- pcie@0 {
- /* IRQ[0:3] are pulled up on board, set to active-low */
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 0 1 0 0
- 0000 0 0 2 &mpic 1 1 0 0
- 0000 0 0 3 &mpic 2 1 0 0
- 0000 0 0 4 &mpic 3 1 0 0
- >;
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- board_pci1: pci1: pcie@ff609000 {
- reg = <0 0xff609000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- /*
- * IRQ[4:6] only for PCIe, set to active-high,
- * IRQ[7] is pulled up on board, set to active-low
- */
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 4 2 0 0
- 0000 0 0 2 &mpic 5 2 0 0
- 0000 0 0 3 &mpic 6 2 0 0
- 0000 0 0 4 &mpic 7 1 0 0
- >;
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci2: pcie@ff60b000 {
- reg = <0 0xff60b000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- /*
- * IRQ[8:10] are pulled up on board, set to active-low
- * IRQ[11] only for PCIe, set to active-high,
- */
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0000 0 0 1 &mpic 8 1 0 0
- 0000 0 0 2 &mpic 9 1 0 0
- 0000 0 0 3 &mpic 10 1 0 0
- 0000 0 0 4 &mpic 11 2 0 0
- >;
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p1023si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1024rdb.dtsi b/arch/powerpc/boot/dts/p1024rdb.dtsi
deleted file mode 100644
index b05dcb4..0000000
--- a/arch/powerpc/boot/dts/p1024rdb.dtsi
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * P1024 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND Compressed RFS Image";
- };
-
- partition@a00000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00f00000>;
- label = "NAND JFFS2 Root File System";
- };
-
- partition@1900000 {
- /* 7MB for User Writable Area */
- reg = <0x01900000 0x00700000>;
- label = "NAND Writable User area";
- };
- };
-};
-
-&soc {
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,m25p80";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI U-Boot Image";
- read-only;
- };
-
- partition@80000 {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "SPI DTB Image";
- };
-
- partition@100000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI Linux Kernel Image";
- };
-
- partition@500000 {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "SPI Compressed RFS Image";
- };
-
- partition@900000 {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "SPI JFFS2 RFS";
- };
- };
- };
-
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- usb@23000 {
- status = "disabled";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- phy2: ethernet-phy@2 {
- interrupts = <1 1 0 0>;
- reg = <0x2>;
- };
- };
-
- mdio@25000 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- ethernet@b0000 {
- phy-handle = <&phy2>;
- phy-connection-type = "rgmii-id";
- };
-
- ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi0>;
- phy-connection-type = "sgmii";
- };
-
- ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1024rdb_32b.dts b/arch/powerpc/boot/dts/p1024rdb_32b.dts
deleted file mode 100644
index 90e803e..0000000
--- a/arch/powerpc/boot/dts/p1024rdb_32b.dts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * P1024 RDB 32Bit Physical Address Map Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1024RDB";
- compatible = "fsl,P1024RDB";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0x0 0xffe05000 0 0x1000>;
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xff800000 0x00040000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- reg = <0x0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0x0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- reg = <0x0 0x0 0x0 0x0 0x0>;
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1024rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1024rdb_36b.dts b/arch/powerpc/boot/dts/p1024rdb_36b.dts
deleted file mode 100644
index 3656825..0000000
--- a/arch/powerpc/boot/dts/p1024rdb_36b.dts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * P1024 RDB 36Bit Physical Address Map Device Tree Source
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1020si-pre.dtsi"
-/ {
- model = "fsl,P1024RDB";
- compatible = "fsl,P1024RDB";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xff800000 0x00040000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- reg = <0x0 0x0 0x0 0x0 0x0>;
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p1024rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1025rdb.dtsi b/arch/powerpc/boot/dts/p1025rdb.dtsi
deleted file mode 100644
index f502564..0000000
--- a/arch/powerpc/boot/dts/p1025rdb.dtsi
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * P1025 RDB Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1025-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND Compressed RFS Image";
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00f00000>;
- label = "NAND Writable User area";
- };
- };
-
-};
-
-&soc {
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
-
- partition@u-boot {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "u-boot";
- read-only;
- };
-
- partition@dtb {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "dtb";
- };
-
- partition@kernel {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "kernel";
- };
-
- partition@fs {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "file system";
- };
-
- partition@jffs-fs {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "file system jffs2";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- /* USB2 is shared with localbus, so it must be disabled
- by default. We can't put 'status = "disabled";' here
- since U-Boot doesn't clear the status property when
- it enables USB2. OTOH, U-Boot does create a new node
- when there isn't any. So, just comment it out.
- usb@23000 {
- phy_type = "ulpi";
- };
- */
-
- mdio@24000 {
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <3 1>;
- reg = <0x0>;
- };
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x1>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
-
- };
-
- enet1: ethernet@b1000 {
- phy-handle = <&phy0>;
- tbi-handle = <&tbi1>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- par_io@e0100 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0xe0100 0x60>;
- ranges = <0x0 0xe0100 0x60>;
- device_type = "par_io";
- num-ports = <3>;
- pio1: ucc_pin@01 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
- 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
- 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
- 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
- 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
- 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
- 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
- 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
- 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
- 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
- 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
- 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
- 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
- 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
- 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
- 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
- };
-
- pio2: ucc_pin@02 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
- 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
- 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
- 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
- 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
- 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
- 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
- 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
- };
-
- pio3: ucc_pin@03 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
- 0x0 0x12 0x2 0x0 0x2 0x0 /* SER7_CTS_B*/
- 0x0 0x13 0x1 0x0 0x2 0x0 /* SER7_RTS_B*/
- 0x0 0x14 0x2 0x0 0x2 0x0 /* SER7_RXD0*/
- 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
- };
-
- pio4: ucc_pin@04 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
- 0x0 0x1c 0x2 0x0 0x2 0x0 /* SER3_CTS_B*/
- 0x0 0x1d 0x1 0x0 0x2 0x0 /* SER3_RTS_B*/
- 0x0 0x1e 0x2 0x0 0x2 0x0 /* SER3_RXD0*/
- 0x0 0x1f 0x1 0x0 0x2 0x0>; /* SER3_TXD0*/
- };
- };
-};
-
-&qe {
- serial2: ucc@2600 {
- device_type = "serial";
- compatible = "ucc_uart";
- port-number = <0>;
- rx-clock-name = "brg6";
- tx-clock-name = "brg6";
- pio-handle = <&pio3>;
- };
-
- serial3: ucc@2200 {
- device_type = "serial";
- compatible = "ucc_uart";
- port-number = <1>;
- rx-clock-name = "brg2";
- tx-clock-name = "brg2";
- pio-handle = <&pio4>;
- };
-};
diff --git a/arch/powerpc/boot/dts/p1025rdb_32b.dts b/arch/powerpc/boot/dts/p1025rdb_32b.dts
deleted file mode 100644
index a2ed628..0000000
--- a/arch/powerpc/boot/dts/p1025rdb_32b.dts
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * P1025 RDB Device Tree Source (32-bit address map)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1025RDB";
- compatible = "fsl,P1025RDB";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xff800000 0x00040000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xe0000000 0 0xe0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0 0xe0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@ffe80000 {
- ranges = <0x0 0x0 0xffe80000 0x40000>;
- reg = <0 0xffe80000 0 0x480>;
- brg-frequency = <0>;
- bus-frequency = <0>;
- status = "disabled"; /* no firmware loaded */
-
- enet3: ucc@2000 {
- device_type = "network";
- compatible = "ucc_geth";
- rx-clock-name = "clk12";
- tx-clock-name = "clk9";
- pio-handle = <&pio1>;
- phy-handle = <&qe_phy0>;
- phy-connection-type = "mii";
- };
-
- mdio@2120 {
- qe_phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <4 1 0 0>;
- reg = <0x6>;
- };
- qe_phy1: ethernet-phy@03 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1 0 0>;
- reg = <0x3>;
- };
- tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet4: ucc@2400 {
- device_type = "network";
- compatible = "ucc_geth";
- rx-clock-name = "none";
- tx-clock-name = "clk13";
- pio-handle = <&pio2>;
- phy-handle = <&qe_phy1>;
- phy-connection-type = "rmii";
- };
- };
-};
-
-/include/ "p1025rdb.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1025rdb_36b.dts b/arch/powerpc/boot/dts/p1025rdb_36b.dts
deleted file mode 100644
index 06deb6f..0000000
--- a/arch/powerpc/boot/dts/p1025rdb_36b.dts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * P1025 RDB Device Tree Source (36-bit address map)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1025RDB";
- compatible = "fsl,P1025RDB";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- /* NOR, NAND Flashes */
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xff800000 0x00040000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci0: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xe 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@fffe80000 {
- status = "disabled"; /* no firmware loaded */
- };
-
-};
-
-/include/ "p1025rdb.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1025twr.dts b/arch/powerpc/boot/dts/p1025twr.dts
deleted file mode 100644
index 9036a49..0000000
--- a/arch/powerpc/boot/dts/p1025twr.dts
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * P1025 TWR Device Tree Source (32-bit address map)
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p1021si-pre.dtsi"
-/ {
- model = "fsl,P1025";
- compatible = "fsl,TWR-P1025";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR Flash and SSD1289 */
- ranges = <0x0 0x0 0x0 0xec000000 0x04000000
- 0x2 0x0 0x0 0xe0000000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci0: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci1: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- qe: qe@ffe80000 {
- ranges = <0x0 0x0 0xffe80000 0x40000>;
- reg = <0 0xffe80000 0 0x480>;
- brg-frequency = <0>;
- bus-frequency = <0>;
- };
-};
-
-/include/ "p1025twr.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1025twr.dtsi b/arch/powerpc/boot/dts/p1025twr.dtsi
deleted file mode 100644
index 8453501..0000000
--- a/arch/powerpc/boot/dts/p1025twr.dtsi
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * P1025 TWR Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-/{
- aliases {
- ethernet3 = &enet3;
- ethernet4 = &enet4;
- };
-};
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x4000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 5.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00580000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 56.75MB for Root file System */
- reg = <0x00600000 0x038c0000>;
- label = "NOR Root File System";
- };
-
- partition@ec0000 {
- /* This location must not be altered */
- /* 256KB for QE ucode firmware*/
- reg = <0x03ec0000 0x00040000>;
- label = "NOR QE microcode firmware";
- read-only;
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x03f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- /* CS2 for Display */
- display@2,0 {
- compatible = "solomon,ssd1289fb";
- reg = <0x2 0x0000 0x0004>;
- };
-
-};
-
-&soc {
- usb@22000 {
- phy_type = "ulpi";
- };
-
- mdio@24000 {
- phy0: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1 0 0>;
- reg = <0x2>;
- };
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25000 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26000 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@b0000 {
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
-
- };
-
- enet1: ethernet@b1000 {
- status = "disabled";
- };
-
- enet2: ethernet@b2000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-
- par_io@e0100 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0xe0100 0x60>;
- ranges = <0x0 0xe0100 0x60>;
- device_type = "par_io";
- num-ports = <3>;
- pio1: ucc_pin@01 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
- 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
- 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
- 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
- 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
- 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
- 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
- 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
- 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
- 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
- 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
- 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
- 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
- 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
- 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
- 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
- };
-
- pio2: ucc_pin@02 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
- 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
- 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
- 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
- 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
- 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
- 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
- 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
- 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
- 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
- };
-
- pio3: ucc_pin@03 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
- 0x0 0x12 0x2 0x0 0x2 0x0 /* SER7_CTS_B*/
- 0x0 0x13 0x1 0x0 0x2 0x0 /* SER7_RTS_B*/
- 0x0 0x14 0x2 0x0 0x2 0x0 /* SER7_RXD0*/
- 0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
- };
-
- pio4: ucc_pin@04 {
- pio-map = <
- /* port pin dir open_drain assignment has_irq */
- 0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
- 0x0 0x1c 0x2 0x0 0x2 0x0 /* SER3_CTS_B*/
- 0x0 0x1d 0x1 0x0 0x2 0x0 /* SER3_RTS_B*/
- 0x0 0x1e 0x2 0x0 0x2 0x0 /* SER3_RXD0*/
- 0x0 0x1f 0x1 0x0 0x2 0x0>; /* SER3_TXD0*/
- };
- };
-};
-
-&qe {
- enet3: ucc@2000 {
- device_type = "network";
- compatible = "ucc_geth";
- rx-clock-name = "clk12";
- tx-clock-name = "clk9";
- pio-handle = <&pio1>;
- phy-handle = <&qe_phy0>;
- phy-connection-type = "mii";
- };
-
- mdio@2120 {
- qe_phy0: ethernet-phy@18 {
- interrupt-parent = <&mpic>;
- interrupts = <4 1 0 0>;
- reg = <0x18>;
- device_type = "ethernet-phy";
- };
- qe_phy1: ethernet-phy@19 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1 0 0>;
- reg = <0x19>;
- device_type = "ethernet-phy";
- };
- tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet4: ucc@2400 {
- device_type = "network";
- compatible = "ucc_geth";
- rx-clock-name = "none";
- tx-clock-name = "clk13";
- pio-handle = <&pio2>;
- phy-handle = <&qe_phy1>;
- phy-connection-type = "rmii";
- };
-
- serial2: ucc@2600 {
- device_type = "serial";
- compatible = "ucc_uart";
- port-number = <0>;
- rx-clock-name = "brg6";
- tx-clock-name = "brg6";
- pio-handle = <&pio3>;
- };
-
- serial3: ucc@2200 {
- device_type = "serial";
- compatible = "ucc_uart";
- port-number = <1>;
- rx-clock-name = "brg2";
- tx-clock-name = "brg2";
- pio-handle = <&pio4>;
- };
-};
diff --git a/arch/powerpc/boot/dts/p2020ds.dts b/arch/powerpc/boot/dts/p2020ds.dts
deleted file mode 100644
index 237310c..0000000
--- a/arch/powerpc/boot/dts/p2020ds.dts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P2020 DS Device Tree Source
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "fsl,P2020DS";
- compatible = "fsl,P2020DS";
-
- memory {
- device_type = "memory";
- };
-
- board_lbc: lbc: localbus@ffe05000 {
- ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
- 0x1 0x0 0x0 0xe0000000 0x08000000
- 0x2 0x0 0x0 0xffa00000 0x00040000
- 0x3 0x0 0x0 0xffdf0000 0x00008000
- 0x4 0x0 0x0 0xffa40000 0x00040000
- 0x5 0x0 0x0 0xffa80000 0x00040000
- 0x6 0x0 0x0 0xffac0000 0x00040000>;
- reg = <0 0xffe05000 0 0x1000>;
- };
-
- board_soc: soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci2: pcie@ffe08000 {
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- reg = <0 0xffe08000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- board_pci1: pci1: pcie@ffe09000 {
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- reg = <0 0xffe09000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-
- pci0: pcie@ffe0a000 {
- ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
- reg = <0 0xffe0a000 0 0x1000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xc0000000
- 0x2000000 0x0 0xc0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x10000>;
- };
- };
-};
-
-/*
- * p2020ds.dtsi must be last to ensure board_pci0 overrides pci0 settings
- * for interrupt-map & interrupt-map-mask
- */
-
-/include/ "fsl/p2020si-post.dtsi"
-/include/ "p2020ds.dtsi"
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/p2020rdb-pc.dtsi
deleted file mode 100644
index c21d1c7..0000000
--- a/arch/powerpc/boot/dts/p2020rdb-pc.dtsi
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * P2020 RDB-PC Device Tree Source stub (no addresses or top-level ranges)
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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.
- */
-
-&lbc {
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR DTB Image";
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR Linux Kernel Image";
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p2020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND Compressed RFS Image";
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00f00000>;
- label = "NAND Writable User area";
- };
- };
-
- L2switch@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x2 0x0 0x20000>;
- };
-
- cpld@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cpld";
- reg = <0x3 0x0 0x20000>;
- read-only;
- };
-};
-
-&soc {
- i2c@3000 {
- rtc@68 {
- compatible = "pericom,pt7c4338";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,m25p80";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI U-Boot Image";
- read-only;
- };
-
- partition@80000 {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "SPI DTB Image";
- };
-
- partition@100000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI Linux Kernel Image";
- };
-
- partition@500000 {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "SPI Compressed RFS Image";
- };
-
- partition@900000 {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "SPI JFFS2 RFS";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- };
-
- mdio@24520 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <2 1 0 0>;
- reg = <0x1>;
- };
- };
-
- mdio@25520 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- status = "disabled";
- };
-
- ptp_clock@24e00 {
- fsl,tclk-period = <5>;
- fsl,tmr-prsc = <200>;
- fsl,tmr-add = <0xCCCCCCCD>;
- fsl,tmr-fiper1 = <0x3B9AC9FB>;
- fsl,tmr-fiper2 = <0x0001869B>;
- fsl,max-adj = <249999999>;
- };
-
- enet0: ethernet@24000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@25000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@26000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
deleted file mode 100644
index 57573bd..0000000
--- a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * P2020 RDB-PC 32Bit Physical Address Map Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR and NAND Flashes */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xff800000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000
- 0x3 0x0 0x0 0xffa00000 0x00020000>;
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
- };
-
- pci2: pcie@ffe08000 {
- reg = <0 0xffe08000 0 0x1000>;
- status = "disabled";
- };
-
- pci1: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci0: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p2020rdb-pc.dtsi"
-/include/ "fsl/p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
deleted file mode 100644
index 470247e..0000000
--- a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * P2020 RDB-PC 36Bit Physical Address Map Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB-PC";
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@fffe05000 {
- reg = <0xf 0xffe05000 0 0x1000>;
-
- /* NOR and NAND Flashes */
- ranges = <0x0 0x0 0xf 0xef000000 0x01000000
- 0x1 0x0 0xf 0xff800000 0x00040000
- 0x2 0x0 0xf 0xffb00000 0x00020000
- 0x3 0x0 0xf 0xffa00000 0x00020000>;
- };
-
- soc: soc@fffe00000 {
- ranges = <0x0 0xf 0xffe00000 0x100000>;
- };
-
- pci2: pcie@fffe08000 {
- reg = <0xf 0xffe08000 0 0x1000>;
- status = "disabled";
- };
-
- pci1: pcie@fffe09000 {
- reg = <0xf 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci0: pcie@fffe0a000 {
- reg = <0xf 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xe0000000
- 0x2000000 0x0 0xe0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "p2020rdb-pc.dtsi"
-/include/ "fsl/p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
deleted file mode 100644
index 4d52bce..0000000
--- a/arch/powerpc/boot/dts/p2020rdb.dts
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * P2020 RDB Device Tree Source
- *
- * Copyright 2009-2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/p2020si-pre.dtsi"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB";
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- memory {
- device_type = "memory";
- };
-
- lbc: localbus@ffe05000 {
- reg = <0 0xffe05000 0 0x1000>;
-
- /* NOR and NAND Flashes */
- ranges = <0x0 0x0 0x0 0xef000000 0x01000000
- 0x1 0x0 0x0 0xffa00000 0x00040000
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* This location must not be altered */
- /* 256KB for Vitesse 7385 Switch firmware */
- reg = <0x0 0x00040000>;
- label = "NOR (RO) Vitesse-7385 Firmware";
- read-only;
- };
-
- partition@40000 {
- /* 256KB for DTB Image */
- reg = <0x00040000 0x00040000>;
- label = "NOR (RO) DTB Image";
- read-only;
- };
-
- partition@80000 {
- /* 3.5 MB for Linux Kernel Image */
- reg = <0x00080000 0x00380000>;
- label = "NOR (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@400000 {
- /* 11MB for JFFS2 based Root file System */
- reg = <0x00400000 0x00b00000>;
- label = "NOR (RW) JFFS2 Root File System";
- };
-
- partition@f00000 {
- /* This location must not be altered */
- /* 512KB for u-boot Bootloader Image */
- /* 512KB for u-boot Environment Variables */
- reg = <0x00f00000 0x00100000>;
- label = "NOR (RO) U-Boot Image";
- read-only;
- };
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p2020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND (RO) U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND (RO) DTB Image";
- read-only;
- };
-
- partition@200000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00200000 0x00400000>;
- label = "NAND (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@600000 {
- /* 4MB for Compressed Root file System Image */
- reg = <0x00600000 0x00400000>;
- label = "NAND (RO) Compressed RFS Image";
- read-only;
- };
-
- partition@a00000 {
- /* 7MB for JFFS2 based Root file System */
- reg = <0x00a00000 0x00700000>;
- label = "NAND (RW) JFFS2 Root File System";
- };
-
- partition@1100000 {
- /* 15MB for JFFS2 based Root file System */
- reg = <0x01100000 0x00f00000>;
- label = "NAND (RW) Writable User area";
- };
- };
-
- L2switch@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "vitesse-7385";
- reg = <0x2 0x0 0x20000>;
- };
-
- };
-
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
- i2c@3000 {
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partition@0 {
- /* 512KB for u-boot Bootloader Image */
- reg = <0x0 0x00080000>;
- label = "SPI (RO) U-Boot Image";
- read-only;
- };
-
- partition@80000 {
- /* 512KB for DTB Image */
- reg = <0x00080000 0x00080000>;
- label = "SPI (RO) DTB Image";
- read-only;
- };
-
- partition@100000 {
- /* 4MB for Linux Kernel Image */
- reg = <0x00100000 0x00400000>;
- label = "SPI (RO) Linux Kernel Image";
- read-only;
- };
-
- partition@500000 {
- /* 4MB for Compressed RFS Image */
- reg = <0x00500000 0x00400000>;
- label = "SPI (RO) Compressed RFS Image";
- read-only;
- };
-
- partition@900000 {
- /* 7MB for JFFS2 based RFS */
- reg = <0x00900000 0x00700000>;
- label = "SPI (RW) JFFS2 RFS";
- };
- };
- };
-
- usb@22000 {
- phy_type = "ulpi";
- dr_mode = "host";
- };
-
- mdio@24520 {
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <3 1 0 0>;
- reg = <0x1>;
- };
- tbi-phy@2 {
- device_type = "tbi-phy";
- reg = <0x2>;
- };
- };
-
- mdio@25520 {
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- status = "disabled";
- };
-
- ptp_clock@24e00 {
- fsl,tclk-period = <5>;
- fsl,tmr-prsc = <200>;
- fsl,tmr-add = <0xCCCCCCCD>;
- fsl,tmr-fiper1 = <0x3B9AC9FB>;
- fsl,tmr-fiper2 = <0x0001869B>;
- fsl,max-adj = <249999999>;
- };
-
- enet0: ethernet@24000 {
- fixed-link = <1 1 1000 0 0>;
- phy-connection-type = "rgmii-id";
- };
-
- enet1: ethernet@25000 {
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "sgmii";
- };
-
- enet2: ethernet@26000 {
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
- };
- };
-
- pci0: pcie@ffe08000 {
- reg = <0 0xffe08000 0 0x1000>;
- status = "disabled";
- };
-
- pci1: pcie@ffe09000 {
- reg = <0 0xffe09000 0 0x1000>;
- ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0xa0000000
- 0x2000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-
- pci2: pcie@ffe0a000 {
- reg = <0 0xffe0a000 0 0x1000>;
- ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
- 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
- pcie@0 {
- ranges = <0x2000000 0x0 0x80000000
- 0x2000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x1000000 0x0 0x0
- 0x1000000 0x0 0x0
- 0x0 0x100000>;
- };
- };
-};
-
-/include/ "fsl/p2020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p2041rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts
deleted file mode 100644
index d2bb0765..0000000
--- a/arch/powerpc/boot/dts/p2041rdb.dts
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * P2041RDB Device Tree Source
- *
- * Copyright 2011 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p2041si-pre.dtsi"
-
-/ {
- model = "fsl,P2041RDB";
- compatible = "fsl,P2041RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- i2c@118000 {
- lm75b@48 {
- compatible = "nxp,lm75a";
- reg = <0x48>;
- };
- eeprom@50 {
- compatible = "at24,24c256";
- reg = <0x50>;
- };
- rtc@68 {
- compatible = "pericom,pt7c4338";
- reg = <0x68>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- i2c@118100 {
- eeprom@50 {
- compatible = "at24,24c256";
- reg = <0x50>;
- };
- };
-
- usb1: usb@211000 {
- dr_mode = "host";
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 1 0 0xf 0xffa00000 0x00040000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-
- partition@0 {
- label = "NAND U-Boot Image";
- reg = <0x0 0x02000000>;
- read-only;
- };
-
- partition@2000000 {
- label = "NAND Root File System";
- reg = <0x02000000 0x10000000>;
- };
-
- partition@12000000 {
- label = "NAND Compressed RFS Image";
- reg = <0x12000000 0x08000000>;
- };
-
- partition@1a000000 {
- label = "NAND Linux Kernel Image";
- reg = <0x1a000000 0x04000000>;
- };
-
- partition@1e000000 {
- label = "NAND DTB Image";
- reg = <0x1e000000 0x01000000>;
- };
-
- partition@1f000000 {
- label = "NAND Writable User area";
- reg = <0x1f000000 0x01000000>;
- };
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- reg = <0xf 0xfe201000 0 0x1000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/p2041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts
deleted file mode 100644
index eca6c69..0000000
--- a/arch/powerpc/boot/dts/p3041ds.dts
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * P3041DS Device Tree Source
- *
- * Copyright 2010 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p3041si-pre.dtsi"
-
-/ {
- model = "fsl,P3041DS";
- compatible = "fsl,P3041DS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <35000000>; /* input clock */
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- i2c@118100 {
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- };
-
- i2c@119100 {
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- ina220@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
- ina220@41 {
- compatible = "ti,ina220";
- reg = <0x41>;
- shunt-resistor = <1000>;
- };
- ina220@44 {
- compatible = "ti,ina220";
- reg = <0x44>;
- shunt-resistor = <1000>;
- };
- ina220@45 {
- compatible = "ti,ina220";
- reg = <0x45>;
- shunt-resistor = <1000>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xffa00000 0x00040000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x2 0x0 0x40000>;
-
- partition@0 {
- label = "NAND U-Boot Image";
- reg = <0x0 0x02000000>;
- read-only;
- };
-
- partition@2000000 {
- label = "NAND Root File System";
- reg = <0x02000000 0x10000000>;
- };
-
- partition@12000000 {
- label = "NAND Compressed RFS Image";
- reg = <0x12000000 0x08000000>;
- };
-
- partition@1a000000 {
- label = "NAND Linux Kernel Image";
- reg = <0x1a000000 0x04000000>;
- };
-
- partition@1e000000 {
- label = "NAND DTB Image";
- reg = <0x1e000000 0x01000000>;
- };
-
- partition@1f000000 {
- label = "NAND Writable User area";
- reg = <0x1f000000 0x21000000>;
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
- reg = <3 0 0x30>;
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- reg = <0xf 0xfe201000 0 0x1000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe203000 {
- reg = <0xf 0xfe203000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/p3041si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts
deleted file mode 100644
index 4f80c9d..0000000
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * P4080DS Device Tree Source
- *
- * Copyright 2009 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p4080si-pre.dtsi"
-
-/ {
- model = "fsl,P4080DS";
- compatible = "fsl,P4080DS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- i2c@118100 {
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- usb0: usb@210000 {
- phy_type = "ulpi";
- };
-
- usb1: usb@211000 {
- dr_mode = "host";
- phy_type = "ulpi";
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- board-control@3,0 {
- compatible = "fsl,p4080ds-fpga", "fsl,fpga-ngpixis";
- reg = <3 0 0x30>;
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- reg = <0xf 0xfe201000 0 0x1000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
-};
-
-/include/ "fsl/p4080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts
deleted file mode 100644
index d0309a8..0000000
--- a/arch/powerpc/boot/dts/p5020ds.dts
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * P5020DS Device Tree Source
- *
- * Copyright 2010 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/p5020si-pre.dtsi"
-
-/ {
- model = "fsl,P5020DS";
- compatible = "fsl,P5020DS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- read-only;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- read-only;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- i2c@118100 {
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- };
-
- i2c@119100 {
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- ina220@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
- ina220@41 {
- compatible = "ti,ina220";
- reg = <0x41>;
- shunt-resistor = <1000>;
- };
- ina220@44 {
- compatible = "ti,ina220";
- reg = <0x44>;
- shunt-resistor = <1000>;
- };
- ina220@45 {
- compatible = "ti,ina220";
- reg = <0x45>;
- shunt-resistor = <1000>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xffa00000 0x00040000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x2 0x0 0x40000>;
-
- partition@0 {
- label = "NAND U-Boot Image";
- reg = <0x0 0x02000000>;
- read-only;
- };
-
- partition@2000000 {
- label = "NAND Root File System";
- reg = <0x02000000 0x10000000>;
- };
-
- partition@12000000 {
- label = "NAND Compressed RFS Image";
- reg = <0x12000000 0x08000000>;
- };
-
- partition@1a000000 {
- label = "NAND Linux Kernel Image";
- reg = <0x1a000000 0x04000000>;
- };
-
- partition@1e000000 {
- label = "NAND DTB Image";
- reg = <0x1e000000 0x01000000>;
- };
-
- partition@1f000000 {
- label = "NAND Writable User area";
- reg = <0x1f000000 0x21000000>;
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
- reg = <3 0 0x30>;
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- reg = <0xf 0xfe201000 0 0x1000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe203000 {
- reg = <0xf 0xfe203000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/p5020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p5040ds.dts b/arch/powerpc/boot/dts/p5040ds.dts
deleted file mode 100644
index 0516823..0000000
--- a/arch/powerpc/boot/dts/p5040ds.dts
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * P5040DS Device Tree Source
- *
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * This software is provided by Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/p5040si-pre.dtsi"
-
-/ {
- model = "fsl,P5040DS";
- compatible = "fsl,P5040DS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01008000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x200000>;
- };
-
- qportals: qman-portals@ff4200000 {
- ranges = <0x0 0xf 0xf4200000 0x200000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25sl12801";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- partition@u-boot {
- label = "u-boot";
- reg = <0x00000000 0x00100000>;
- };
- partition@kernel {
- label = "kernel";
- reg = <0x00100000 0x00500000>;
- };
- partition@dtb {
- label = "dtb";
- reg = <0x00600000 0x00100000>;
- };
- partition@fs {
- label = "file system";
- reg = <0x00700000 0x00900000>;
- };
- };
- };
-
- i2c@118100 {
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- };
-
- i2c@119100 {
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- ina220@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
- ina220@41 {
- compatible = "ti,ina220";
- reg = <0x41>;
- shunt-resistor = <1000>;
- };
- ina220@44 {
- compatible = "ti,ina220";
- reg = <0x44>;
- shunt-resistor = <1000>;
- };
- ina220@45 {
- compatible = "ti,ina220";
- reg = <0x45>;
- shunt-resistor = <1000>;
- };
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
- };
-
- lbc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x1000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xffa00000 0x00040000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x08000000>;
- bank-width = <2>;
- device-width = <2>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,elbc-fcm-nand";
- reg = <0x2 0x0 0x40000>;
-
- partition@0 {
- label = "NAND U-Boot Image";
- reg = <0x0 0x02000000>;
- };
-
- partition@2000000 {
- label = "NAND Root File System";
- reg = <0x02000000 0x10000000>;
- };
-
- partition@12000000 {
- label = "NAND Compressed RFS Image";
- reg = <0x12000000 0x08000000>;
- };
-
- partition@1a000000 {
- label = "NAND Linux Kernel Image";
- reg = <0x1a000000 0x04000000>;
- };
-
- partition@1e000000 {
- label = "NAND DTB Image";
- reg = <0x1e000000 0x01000000>;
- };
-
- partition@1f000000 {
- label = "NAND Writable User area";
- reg = <0x1f000000 0x01000000>;
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis";
- reg = <3 0 0x40>;
- };
- };
-
- pci0: pcie@ffe200000 {
- reg = <0xf 0xfe200000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe201000 {
- reg = <0xf 0xfe201000 0 0x1000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe202000 {
- reg = <0xf 0xfe202000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/p5040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/ppa8548.dts b/arch/powerpc/boot/dts/ppa8548.dts
deleted file mode 100644
index 27b0699..0000000
--- a/arch/powerpc/boot/dts/ppa8548.dts
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * PPA8548 Device Tree Source (36-bit address map)
- * Copyright 2013 Prodrive B.V.
- *
- * Based on:
- * MPC8548 CDS Device Tree Source (36-bit address map)
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "fsl/mpc8548si-pre.dtsi"
-
-/ {
- model = "ppa8548";
- compatible = "ppa8548";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- memory {
- device_type = "memory";
- reg = <0 0 0x0 0x40000000>;
- };
-
- lbc: localbus@fe0005000 {
- reg = <0xf 0xe0005000 0 0x1000>;
- ranges = <0x0 0x0 0xf 0xff800000 0x00800000>;
- };
-
- soc: soc8548@fe0000000 {
- ranges = <0 0xf 0xe0000000 0x100000>;
- };
-
- pci0: pci@fe0008000 {
- /* ppa8548 board doesn't support PCI */
- status = "disabled";
- };
-
- pci1: pci@fe0009000 {
- /* ppa8548 board doesn't support PCI */
- status = "disabled";
- };
-
- pci2: pcie@fe000a000 {
- /* ppa8548 board doesn't support PCI */
- status = "disabled";
- };
-
- rio: rapidio@fe00c0000 {
- reg = <0xf 0xe00c0000 0x0 0x11000>;
- port1 {
- ranges = <0x0 0x0 0x0 0x80000000 0x0 0x40000000>;
- };
- };
-};
-
-&lbc {
- nor@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x00800000>;
- bank-width = <2>;
- device-width = <2>;
-
- partition@0 {
- reg = <0x0 0x7A0000>;
- label = "user";
- };
-
- partition@7A0000 {
- reg = <0x7A0000 0x20000>;
- label = "env";
- read-only;
- };
-
- partition@7C0000 {
- reg = <0x7C0000 0x40000>;
- label = "u-boot";
- read-only;
- };
- };
-};
-
-&soc {
- i2c@3000 {
- rtc@6f {
- compatible = "intersil,isl1208";
- reg = <0x6f>;
- };
- };
-
- i2c@3100 {
- };
-
- /*
- * Only ethernet controller @25000 and @26000 are used.
- * Use alias enet2 and enet3 for the remainig controllers,
- * to stay compatible with mpc8548si-pre.dtsi.
- */
- enet2: ethernet@24000 {
- status = "disabled";
- };
-
- mdio@24520 {
- phy0: ethernet-phy@0 {
- interrupts = <7 1 0 0>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <8 1 0 0>;
- reg = <0x1>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet0: ethernet@25000 {
- tbi-handle = <&tbi1>;
- phy-handle = <&phy0>;
- };
-
- mdio@25520 {
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet1: ethernet@26000 {
- tbi-handle = <&tbi2>;
- phy-handle = <&phy1>;
- };
-
- mdio@26520 {
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- enet3: ethernet@27000 {
- status = "disabled";
- };
-
- mdio@27520 {
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- crypto@30000 {
- status = "disabled";
- };
-};
-
-/include/ "fsl/mpc8548si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/prpmc2800.dts b/arch/powerpc/boot/dts/prpmc2800.dts
deleted file mode 100644
index 00afaac..0000000
--- a/arch/powerpc/boot/dts/prpmc2800.dts
+++ /dev/null
@@ -1,297 +0,0 @@
-/* Device Tree Source for Motorola PrPMC2800
- *
- * Author: Mark A. Greer <mgreer@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.
- *
- * Property values that are labeled as "Default" will be updated by bootwrapper
- * if it can determine the exact PrPMC type.
- */
-
-/dts-v1/;
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- model = "PrPMC280/PrPMC2800"; /* Default */
- compatible = "motorola,PrPMC2800";
- coherency-off;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,7447 {
- device_type = "cpu";
- reg = <0>;
- clock-frequency = <733333333>; /* Default */
- bus-frequency = <133333333>;
- timebase-frequency = <33333333>;
- i-cache-line-size = <32>;
- d-cache-line-size = <32>;
- i-cache-size = <32768>;
- d-cache-size = <32768>;
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x20000000>; /* Default (512MB) */
- };
-
- system-controller@f1000000 { /* Marvell Discovery mv64360 */
- #address-cells = <1>;
- #size-cells = <1>;
- model = "mv64360"; /* Default */
- compatible = "marvell,mv64360";
- clock-frequency = <133333333>;
- reg = <0xf1000000 0x10000>;
- virtual-reg = <0xf1000000>;
- ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
- 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
- 0xa0000000 0xa0000000 0x4000000 /* User FLASH */
- 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
- 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
-
- flash@a0000000 {
- device_type = "rom";
- compatible = "direct-mapped";
- reg = <0xa0000000 0x4000000>; /* Default (64MB) */
- probe-type = "CFI";
- bank-width = <4>;
- partitions = <0x00000000 0x00100000 /* RO */
- 0x00100000 0x00040001 /* RW */
- 0x00140000 0x00400000 /* RO */
- 0x00540000 0x039c0000 /* RO */
- 0x03f00000 0x00100000>; /* RO */
- partition-names = "FW Image A", "FW Config Data", "Kernel Image", "Filesystem", "FW Image B";
- };
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,mv64360-mdio";
- PHY0: ethernet-phy@1 {
- compatible = "broadcom,bcm5421";
- interrupts = <76>; /* GPP 12 */
- interrupt-parent = <&PIC>;
- reg = <1>;
- };
- PHY1: ethernet-phy@3 {
- compatible = "broadcom,bcm5421";
- interrupts = <76>; /* GPP 12 */
- interrupt-parent = <&PIC>;
- reg = <3>;
- };
- };
-
- ethernet-group@2000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "marvell,mv64360-eth-group";
- reg = <0x2000 0x2000>;
- ethernet@0 {
- device_type = "network";
- compatible = "marvell,mv64360-eth";
- reg = <0>;
- interrupts = <32>;
- interrupt-parent = <&PIC>;
- phy = <&PHY0>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- };
- ethernet@1 {
- device_type = "network";
- compatible = "marvell,mv64360-eth";
- reg = <1>;
- interrupts = <33>;
- interrupt-parent = <&PIC>;
- phy = <&PHY1>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- };
- };
-
- SDMA0: sdma@4000 {
- compatible = "marvell,mv64360-sdma";
- reg = <0x4000 0xc18>;
- virtual-reg = <0xf1004000>;
- interrupts = <36>;
- interrupt-parent = <&PIC>;
- };
-
- SDMA1: sdma@6000 {
- compatible = "marvell,mv64360-sdma";
- reg = <0x6000 0xc18>;
- virtual-reg = <0xf1006000>;
- interrupts = <38>;
- interrupt-parent = <&PIC>;
- };
-
- BRG0: brg@b200 {
- compatible = "marvell,mv64360-brg";
- reg = <0xb200 0x8>;
- clock-src = <8>;
- clock-frequency = <133333333>;
- current-speed = <9600>;
- };
-
- BRG1: brg@b208 {
- compatible = "marvell,mv64360-brg";
- reg = <0xb208 0x8>;
- clock-src = <8>;
- clock-frequency = <133333333>;
- current-speed = <9600>;
- };
-
- CUNIT: cunit@f200 {
- reg = <0xf200 0x200>;
- };
-
- MPSCROUTING: mpscrouting@b400 {
- reg = <0xb400 0xc>;
- };
-
- MPSCINTR: mpscintr@b800 {
- reg = <0xb800 0x100>;
- virtual-reg = <0xf100b800>;
- };
-
- MPSC0: mpsc@8000 {
- compatible = "marvell,mv64360-mpsc";
- reg = <0x8000 0x38>;
- virtual-reg = <0xf1008000>;
- sdma = <&SDMA0>;
- brg = <&BRG0>;
- cunit = <&CUNIT>;
- mpscrouting = <&MPSCROUTING>;
- mpscintr = <&MPSCINTR>;
- cell-index = <0>;
- interrupts = <40>;
- interrupt-parent = <&PIC>;
- };
-
- MPSC1: mpsc@9000 {
- compatible = "marvell,mv64360-mpsc";
- reg = <0x9000 0x38>;
- virtual-reg = <0xf1009000>;
- sdma = <&SDMA1>;
- brg = <&BRG1>;
- cunit = <&CUNIT>;
- mpscrouting = <&MPSCROUTING>;
- mpscintr = <&MPSCINTR>;
- cell-index = <1>;
- interrupts = <42>;
- interrupt-parent = <&PIC>;
- };
-
- wdt@b410 { /* watchdog timer */
- compatible = "marvell,mv64360-wdt";
- reg = <0xb410 0x8>;
- };
-
- i2c@c000 {
- device_type = "i2c";
- compatible = "marvell,mv64360-i2c";
- reg = <0xc000 0x20>;
- virtual-reg = <0xf100c000>;
- interrupts = <37>;
- interrupt-parent = <&PIC>;
- };
-
- PIC: pic {
- #interrupt-cells = <1>;
- #address-cells = <0>;
- compatible = "marvell,mv64360-pic";
- reg = <0x0 0x88>;
- interrupt-controller;
- };
-
- mpp@f000 {
- compatible = "marvell,mv64360-mpp";
- reg = <0xf000 0x10>;
- };
-
- gpp@f100 {
- compatible = "marvell,mv64360-gpp";
- reg = <0xf100 0x20>;
- };
-
- pci@80000000 {
- #address-cells = <3>;
- #size-cells = <2>;
- #interrupt-cells = <1>;
- device_type = "pci";
- compatible = "marvell,mv64360-pci";
- reg = <0xcf8 0x8>;
- ranges = <0x01000000 0x0 0x0
- 0x88000000 0x0 0x01000000
- 0x02000000 0x0 0x80000000
- 0x80000000 0x0 0x08000000>;
- bus-range = <0 255>;
- clock-frequency = <66000000>;
- interrupt-pci-iack = <0xc34>;
- interrupt-parent = <&PIC>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
- /* IDSEL 0x0a */
- 0x5000 0 0 1 &PIC 80
- 0x5000 0 0 2 &PIC 81
- 0x5000 0 0 3 &PIC 91
- 0x5000 0 0 4 &PIC 93
-
- /* IDSEL 0x0b */
- 0x5800 0 0 1 &PIC 91
- 0x5800 0 0 2 &PIC 93
- 0x5800 0 0 3 &PIC 80
- 0x5800 0 0 4 &PIC 81
-
- /* IDSEL 0x0c */
- 0x6000 0 0 1 &PIC 91
- 0x6000 0 0 2 &PIC 93
- 0x6000 0 0 3 &PIC 80
- 0x6000 0 0 4 &PIC 81
-
- /* IDSEL 0x0d */
- 0x6800 0 0 1 &PIC 93
- 0x6800 0 0 2 &PIC 80
- 0x6800 0 0 3 &PIC 81
- 0x6800 0 0 4 &PIC 91
- >;
- };
-
- cpu-error@0070 {
- compatible = "marvell,mv64360-cpu-error";
- reg = <0x70 0x10 0x128 0x28>;
- interrupts = <3>;
- interrupt-parent = <&PIC>;
- };
-
- sram-ctrl@0380 {
- compatible = "marvell,mv64360-sram-ctrl";
- reg = <0x380 0x80>;
- interrupts = <13>;
- interrupt-parent = <&PIC>;
- };
-
- pci-error@1d40 {
- compatible = "marvell,mv64360-pci-error";
- reg = <0x1d40 0x40 0xc28 0x4>;
- interrupts = <12>;
- interrupt-parent = <&PIC>;
- };
-
- mem-ctrl@1400 {
- compatible = "marvell,mv64360-mem-ctrl";
- reg = <0x1400 0x60>;
- interrupts = <17>;
- interrupt-parent = <&PIC>;
- };
- };
-
- chosen {
- bootargs = "ip=on";
- linux,stdout-path = &MPSC0;
- };
-};
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts
deleted file mode 100644
index 631ede7..0000000
--- a/arch/powerpc/boot/dts/sbc8641d.dts
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * SBC8641D Device Tree Source
- *
- * Copyright 2008 Wind River Systems Inc.
- *
- * Paul Gortmaker (see MAINTAINERS for contact information)
- *
- * Based largely on the mpc8641_hpcn.dts by 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/;
-
-/ {
- model = "SBC8641D";
- compatible = "wind,sbc8641";
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- ethernet0 = &enet0;
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- ethernet3 = &enet3;
- serial0 = &serial0;
- serial1 = &serial1;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- PowerPC,8641@0 {
- device_type = "cpu";
- reg = <0>;
- d-cache-line-size = <32>;
- i-cache-line-size = <32>;
- d-cache-size = <32768>; // L1
- i-cache-size = <32768>; // L1
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- PowerPC,8641@1 {
- device_type = "cpu";
- reg = <1>;
- d-cache-line-size = <32>;
- i-cache-line-size = <32>;
- d-cache-size = <32768>;
- i-cache-size = <32768>;
- timebase-frequency = <0>; // From uboot
- bus-frequency = <0>; // From uboot
- clock-frequency = <0>; // From uboot
- };
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>; // 512M at 0x0
- };
-
- localbus@f8005000 {
- #address-cells = <2>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xf8005000 0x1000>;
- interrupts = <19 2>;
- interrupt-parent = <&mpic>;
-
- ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
- 1 0 0xf0000000 0x00010000 // 64KB EEPROM
- 2 0 0xf1000000 0x00100000 // EPLD (1MB)
- 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3)
- 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4)
- 6 0 0xf4000000 0x00100000 // LCD display (1MB)
- 7 0 0xe8000000 0x04000000>; // 64MB OneNAND
-
- flash@0,0 {
- compatible = "cfi-flash";
- reg = <0 0 0x01000000>;
- bank-width = <2>;
- device-width = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "dtb";
- reg = <0x00000000 0x00100000>;
- read-only;
- };
- partition@300000 {
- label = "kernel";
- reg = <0x00100000 0x00400000>;
- read-only;
- };
- partition@400000 {
- label = "fs";
- reg = <0x00500000 0x00a00000>;
- };
- partition@700000 {
- label = "firmware";
- reg = <0x00f00000 0x00100000>;
- read-only;
- };
- };
-
- epld@2,0 {
- compatible = "wrs,epld-localbus";
- #address-cells = <2>;
- #size-cells = <1>;
- reg = <2 0 0x100000>;
- ranges = <0 0 5 0 1 // User switches
- 1 0 5 1 1 // Board ID/Rev
- 3 0 5 3 1>; // LEDs
- };
- };
-
- soc@f8000000 {
- #address-cells = <1>;
- #size-cells = <1>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x00000000 0xf8000000 0x00100000>;
- bus-frequency = <0>;
-
- mcm-law@0 {
- compatible = "fsl,mcm-law";
- reg = <0x0 0x1000>;
- fsl,num-laws = <10>;
- };
-
- mcm@1000 {
- compatible = "fsl,mpc8641-mcm", "fsl,mcm";
- reg = <0x1000 0x1000>;
- interrupts = <17 2>;
- interrupt-parent = <&mpic>;
- };
-
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- i2c@3100 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- compatible = "fsl-i2c";
- reg = <0x3100 0x100>;
- interrupts = <43 2>;
- interrupt-parent = <&mpic>;
- dfsrr;
- };
-
- dma@21300 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
- reg = <0x21300 0x4>;
- ranges = <0x0 0x21100 0x200>;
- cell-index = <0>;
- dma-channel@0 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x0 0x80>;
- cell-index = <0>;
- interrupt-parent = <&mpic>;
- interrupts = <20 2>;
- };
- dma-channel@80 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x80 0x80>;
- cell-index = <1>;
- interrupt-parent = <&mpic>;
- interrupts = <21 2>;
- };
- dma-channel@100 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x100 0x80>;
- cell-index = <2>;
- interrupt-parent = <&mpic>;
- interrupts = <22 2>;
- };
- dma-channel@180 {
- compatible = "fsl,mpc8641-dma-channel",
- "fsl,eloplus-dma-channel";
- reg = <0x180 0x80>;
- cell-index = <3>;
- interrupt-parent = <&mpic>;
- interrupts = <23 2>;
- };
- };
-
- enet0: ethernet@24000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <0>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x24000 0x1000>;
- ranges = <0x0 0x24000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <29 2 30 2 34 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi0>;
- phy-handle = <&phy0>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x520 0x20>;
-
- phy0: ethernet-phy@1f {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x1f>;
- };
- phy1: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0>;
- };
- phy2: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <1>;
- };
- phy3: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <2>;
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet1: ethernet@25000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <1>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x25000 0x1000>;
- ranges = <0x0 0x25000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <35 2 36 2 40 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi1>;
- phy-handle = <&phy1>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet2: ethernet@26000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <2>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x26000 0x1000>;
- ranges = <0x0 0x26000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <31 2 32 2 33 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi2>;
- phy-handle = <&phy2>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- enet3: ethernet@27000 {
- #address-cells = <1>;
- #size-cells = <1>;
- cell-index = <3>;
- device_type = "network";
- model = "TSEC";
- compatible = "gianfar";
- reg = <0x27000 0x1000>;
- ranges = <0x0 0x27000 0x1000>;
- local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <37 2 38 2 39 2>;
- interrupt-parent = <&mpic>;
- tbi-handle = <&tbi3>;
- phy-handle = <&phy3>;
- phy-connection-type = "rgmii-id";
-
- mdio@520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
- };
-
- serial0: serial@4500 {
- cell-index = <0>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4500 0x100>;
- clock-frequency = <0>;
- interrupts = <42 2>;
- interrupt-parent = <&mpic>;
- };
-
- serial1: serial@4600 {
- cell-index = <1>;
- device_type = "serial";
- compatible = "fsl,ns16550", "ns16550";
- reg = <0x4600 0x100>;
- clock-frequency = <0>;
- interrupts = <28 2>;
- interrupt-parent = <&mpic>;
- };
-
- mpic: pic@40000 {
- clock-frequency = <0>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <2>;
- reg = <0x40000 0x40000>;
- compatible = "chrp,open-pic";
- device_type = "open-pic";
- big-endian;
- };
-
- global-utilities@e0000 {
- compatible = "fsl,mpc8641-guts";
- reg = <0xe0000 0x1000>;
- fsl,has-rstcr;
- };
- };
-
- pci0: pcie@f8008000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xf8008000 0x1000>;
- bus-range = <0x0 0xff>;
- ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <24 2>;
- interrupt-map-mask = <0xff00 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0x0000 0 0 1 &mpic 0 1
- 0x0000 0 0 2 &mpic 1 1
- 0x0000 0 0 3 &mpic 2 1
- 0x0000 0 0 4 &mpic 3 1
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0x80000000
- 0x02000000 0x0 0x80000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00100000>;
- };
-
- };
-
- pci1: pcie@f8009000 {
- compatible = "fsl,mpc8641-pcie";
- device_type = "pci";
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xf8009000 0x1000>;
- bus-range = <0 0xff>;
- ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
- clock-frequency = <33333333>;
- interrupt-parent = <&mpic>;
- interrupts = <25 2>;
- interrupt-map-mask = <0xf800 0 0 7>;
- interrupt-map = <
- /* IDSEL 0x0 */
- 0x0000 0 0 1 &mpic 4 1
- 0x0000 0 0 2 &mpic 5 1
- 0x0000 0 0 3 &mpic 6 1
- 0x0000 0 0 4 &mpic 7 1
- >;
-
- pcie@0 {
- reg = <0 0 0 0 0>;
- #size-cells = <2>;
- #address-cells = <3>;
- device_type = "pci";
- ranges = <0x02000000 0x0 0xa0000000
- 0x02000000 0x0 0xa0000000
- 0x0 0x20000000
-
- 0x01000000 0x0 0x00000000
- 0x01000000 0x0 0x00000000
- 0x0 0x00100000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t1023rdb.dts b/arch/powerpc/boot/dts/t1023rdb.dts
deleted file mode 100644
index d3fa829..0000000
--- a/arch/powerpc/boot/dts/t1023rdb.dts
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * T1023 RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t102xsi-pre.dtsi"
-
-/ {
- model = "fsl,T1023RDB";
- compatible = "fsl,T1023RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 1 0 0xf 0xff800000 0x00010000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- status = "disabled";
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x1 0x0 0x10000>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spansion,s25fl512s";
- reg = <0>;
- spi-max-frequency = <10000000>; /* input clk */
- };
- };
-
- i2c@118000 {
- eeprom@50 {
- compatible = "st,m24256";
- reg = <0x50>;
- };
-
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- interrupts = <0x5 0x1 0 0>;
- };
- };
-
- i2c@118100 {
- current-sensor@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
-
- current-sensor@41 {
- compatible = "ti,ina220";
- reg = <0x41>;
- shunt-resistor = <1000>;
- };
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/t1023si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1024qds.dts b/arch/powerpc/boot/dts/t1024qds.dts
deleted file mode 100644
index f31fabb..0000000
--- a/arch/powerpc/boot/dts/t1024qds.dts
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * T1024 QDS Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t102xsi-pre.dtsi"
-
-/ {
- model = "fsl,T1024QDS";
- compatible = "fsl,T1024QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- board-control@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,tetra-fpga", "fsl,fpga-qixis";
- reg = <3 0 0x300>;
- ranges = <0 3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q128a11"; /* 16MB */
- reg = <0>;
- spi-max-frequency = <10000000>;
- };
-
- flash@1 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sst,sst25wf040"; /* 512KB */
- reg = <1>;
- spi-max-frequency = <10000000>;
- };
-
- flash@2 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "eon,en25s64"; /* 8MB */
- reg = <2>;
- spi-max-frequency = <10000000>;
- };
-
- slic@2 {
- compatible = "maxim,ds26522";
- reg = <2>;
- spi-max-frequency = <2000000>;
- };
-
- slic@3 {
- compatible = "maxim,ds26522";
- reg = <3>;
- spi-max-frequency = <2000000>;
- };
- };
-
- i2c@118000 {
- pca9547@77 {
- compatible = "nxp,pca9547";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0>;
-
- eeprom@50 {
- compatible = "atmel,24c512";
- reg = <0x50>;
- };
-
- eeprom@51 {
- compatible = "atmel,24c02";
- reg = <0x51>;
- };
-
- eeprom@57 {
- compatible = "atmel,24c02";
- reg = <0x57>;
- };
- };
-
- 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>;
-
- adt7461@4c {
- /* Thermal Monitor */
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- eeprom@55 {
- compatible = "atmel,24c02";
- reg = <0x55>;
- };
-
- eeprom@56 {
- compatible = "atmel,24c512";
- reg = <0x56>;
- };
-
- eeprom@57 {
- compatible = "atmel,24c512";
- reg = <0x57>;
- };
- };
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x5 0x1 0 0>;
- };
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/t1024si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1024rdb.dts b/arch/powerpc/boot/dts/t1024rdb.dts
deleted file mode 100644
index bf05e32..0000000
--- a/arch/powerpc/boot/dts/t1024rdb.dts
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * T1024 RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t102xsi-pre.dtsi"
-
-/ {
- model = "fsl,T1024RDB";
- compatible = "fsl,T1024RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- board-control@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,t1024-cpld";
- reg = <3 0 0x300>;
- ranges = <0 3 0 0x300>;
- bank-width = <1>;
- device-width = <1>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q512ax3";
- reg = <0>;
- spi-max-frequency = <10000000>; /* input clk */
- };
-
- slic@1 {
- compatible = "maxim,ds26522";
- reg = <1>;
- spi-max-frequency = <2000000>;
- };
-
- slic@2 {
- compatible = "maxim,ds26522";
- reg = <2>;
- spi-max-frequency = <2000000>;
- };
- };
-
- i2c@118000 {
- adt7461@4c {
- /* Thermal Monitor */
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- current-sensor@40 {
- compatible = "ti,ina220";
- reg = <0x40>;
- shunt-resistor = <1000>;
- };
-
- eeprom@50 {
- compatible = "atmel,24c256";
- reg = <0x50>;
- };
-
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- };
-
- i2c@118100 {
- pca9546@77 {
- compatible = "nxp,pca9546";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
-
-/include/ "fsl/t1024si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1040d4rdb.dts b/arch/powerpc/boot/dts/t1040d4rdb.dts
deleted file mode 100644
index 2d1315a..0000000
--- a/arch/powerpc/boot/dts/t1040d4rdb.dts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * T1040D4RDB Device Tree Source
- *
- * Copyright 2015 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xd4rdb.dtsi"
-
-/ {
- model = "fsl,T1040D4RDB";
- compatible = "fsl,T1040D4RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-};
-
-/include/ "fsl/t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1040qds.dts b/arch/powerpc/boot/dts/t1040qds.dts
deleted file mode 100644
index 973c29c..0000000
--- a/arch/powerpc/boot/dts/t1040qds.dts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * T1040QDS Device Tree Source
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xqds.dtsi"
-
-/ {
- model = "fsl,T1040QDS";
- compatible = "fsl,T1040QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-};
-
-/include/ "fsl/t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1040rdb.dts b/arch/powerpc/boot/dts/t1040rdb.dts
deleted file mode 100644
index 79a0bed..0000000
--- a/arch/powerpc/boot/dts/t1040rdb.dts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * T1040RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xrdb.dtsi"
-
-/ {
- model = "fsl,T1040RDB";
- compatible = "fsl,T1040RDB";
- ifc: localbus@ffe124000 {
- cpld@3,0 {
- compatible = "fsl,t1040rdb-cpld";
- };
- };
-};
-
-/include/ "fsl/t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1042d4rdb.dts b/arch/powerpc/boot/dts/t1042d4rdb.dts
deleted file mode 100644
index 846f8c8..0000000
--- a/arch/powerpc/boot/dts/t1042d4rdb.dts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * T1042D4RDB Device Tree Source
- *
- * Copyright 2015 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xd4rdb.dtsi"
-
-/ {
- model = "fsl,T1042D4RDB";
- compatible = "fsl,T1042D4RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- cpld@3,0 {
- compatible = "fsl,t1040d4rdb-cpld",
- "fsl,deepsleep-cpld";
- };
- };
-};
-
-/include/ "fsl/t1040si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1042qds.dts b/arch/powerpc/boot/dts/t1042qds.dts
deleted file mode 100644
index 45bd037..0000000
--- a/arch/powerpc/boot/dts/t1042qds.dts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * T1042QDS Device Tree Source
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xqds.dtsi"
-
-/ {
- model = "fsl,T1042QDS";
- compatible = "fsl,T1042QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-};
-
-/include/ "fsl/t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1042rdb.dts b/arch/powerpc/boot/dts/t1042rdb.dts
deleted file mode 100644
index 738c237..0000000
--- a/arch/powerpc/boot/dts/t1042rdb.dts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * T1042RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xrdb.dtsi"
-
-/ {
- model = "fsl,T1042RDB";
- compatible = "fsl,T1042RDB";
- ifc: localbus@ffe124000 {
- cpld@3,0 {
- compatible = "fsl,t1042rdb-cpld";
- };
- };
-};
-
-/include/ "fsl/t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t1042rdb_pi.dts b/arch/powerpc/boot/dts/t1042rdb_pi.dts
deleted file mode 100644
index 634f751..0000000
--- a/arch/powerpc/boot/dts/t1042rdb_pi.dts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * T1042RDB_PI Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t104xsi-pre.dtsi"
-/include/ "t104xrdb.dtsi"
-
-/ {
- model = "fsl,T1042RDB_PI";
- compatible = "fsl,T1042RDB_PI";
- ifc: localbus@ffe124000 {
- cpld@3,0 {
- compatible = "fsl,t1042rdb_pi-cpld";
- };
- };
- soc: soc@ffe000000 {
- i2c@118000 {
- rtc@68 {
- compatible = "dallas,ds1337";
- reg = <0x68>;
- interrupts = <0x2 0x1 0 0>;
- };
- };
- };
-};
-
-/include/ "fsl/t1042si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/t104xd4rdb.dtsi
deleted file mode 100644
index 491367b..0000000
--- a/arch/powerpc/boot/dts/t104xd4rdb.dtsi
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * T1040D4RDB/T1042D4RDB Device Tree Source
- *
- * Copyright 2015 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- cpld@3,0 {
- compatible = "fsl,t1040d4rdb-cpld";
- reg = <3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q512ax3";
- reg = <0>;
- /* input clock */
- spi-max-frequency = <10000000>;
- };
- };
- i2c@118000 {
- hwmon@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
-
- rtc@68 {
- compatible = "dallas,ds1337";
- reg = <0x68>;
- interrupts = <0x2 0x1 0 0>;
- };
- };
-
- i2c@118100 {
- mux@77 {
- /*
- * Child nodes of mux depend on which i2c
- * devices are connected via the mini PCI
- * connector slot1, the mini PCI connector
- * slot2, the HDMI connector, and the PEX
- * slot. Systems with such devices attached
- * should provide a wrapper .dts file that
- * includes this one, and adds those nodes
- */
- compatible = "nxp,pca9546";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x0 0x0 0x10000000
- 0x01000000 0 0x0 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000
- 0x01000000 0 0 0xf 0xf8010000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t104xqds.dtsi b/arch/powerpc/boot/dts/t104xqds.dtsi
deleted file mode 100644
index 1498d1e..0000000
--- a/arch/powerpc/boot/dts/t104xqds.dtsi
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * T104xQDS Device Tree Source
- *
- * Copyright 2013 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- model = "fsl,T1040QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
-
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- board-control@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,fpga-qixis";
- reg = <3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q128a11";
- reg = <0>;
- spi-max-frequency = <10000000>; /* input clock */
- };
- };
-
- i2c@118000 {
- pca9547@77 {
- compatible = "philips,pca9547";
- reg = <0x77>;
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t104xrdb.dtsi b/arch/powerpc/boot/dts/t104xrdb.dtsi
deleted file mode 100644
index 830ea48..0000000
--- a/arch/powerpc/boot/dts/t104xrdb.dtsi
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * T1040RDB/T1042RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- cpld@3,0 {
- reg = <3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
-
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q512a";
- reg = <0>;
- spi-max-frequency = <10000000>; /* input clock */
- };
- };
-
- i2c@118000 {
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
-
- i2c@118100 {
- pca9546@77 {
- compatible = "nxp,pca9546";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x10000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t2080qds.dts b/arch/powerpc/boot/dts/t2080qds.dts
deleted file mode 100644
index aa1d6d8..0000000
--- a/arch/powerpc/boot/dts/t2080qds.dts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * T2080QDS Device Tree Source
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t208xsi-pre.dtsi"
-/include/ "t208xqds.dtsi"
-
-/ {
- model = "fsl,T2080QDS";
- compatible = "fsl,T2080QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-};
-
-/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t2080rdb.dts b/arch/powerpc/boot/dts/t2080rdb.dts
deleted file mode 100644
index e889104..0000000
--- a/arch/powerpc/boot/dts/t2080rdb.dts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * T2080PCIe-RDB Board Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t208xsi-pre.dtsi"
-/include/ "t208xrdb.dtsi"
-
-/ {
- model = "fsl,T2080RDB";
- compatible = "fsl,T2080RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-};
-
-/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t2081qds.dts b/arch/powerpc/boot/dts/t2081qds.dts
deleted file mode 100644
index 8ec80a7..0000000
--- a/arch/powerpc/boot/dts/t2081qds.dts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * T2081QDS Device Tree Source
- *
- * Copyright 2013 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t208xsi-pre.dtsi"
-/include/ "t208xqds.dtsi"
-
-/ {
- model = "fsl,T2081QDS";
- compatible = "fsl,T2081QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-};
-
-/include/ "fsl/t2081si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t208xqds.dtsi b/arch/powerpc/boot/dts/t208xqds.dtsi
deleted file mode 100644
index 869f915..0000000
--- a/arch/powerpc/boot/dts/t208xqds.dtsi
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * T2080/T2081 QDS Device Tree Source
- *
- * Copyright 2013 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- model = "fsl,T2080QDS";
- compatible = "fsl,T2080QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- boardctrl: board-control@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,fpga-qixis";
- reg = <3 0 0x300>;
- ranges = <0 3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q128a11"; /* 16MB */
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- };
-
- flash@1 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sst,sst25wf040";
- reg = <1>;
- spi-max-frequency = <35000000>;
- };
-
- flash@2 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "eon,en25s64";
- reg = <2>;
- spi-max-frequency = <35000000>;
- };
- };
-
- i2c@118000 {
- pca9547@77 {
- compatible = "nxp,pca9547";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0>;
-
- eeprom@50 {
- compatible = "at24,24c512";
- reg = <0x50>;
- };
-
- eeprom@51 {
- compatible = "at24,24c02";
- reg = <0x51>;
- };
-
- eeprom@57 {
- compatible = "at24,24c02";
- reg = <0x57>;
- };
-
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0xb 0x1 0 0>;
- };
- };
-
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x1>;
-
- eeprom@55 {
- compatible = "at24,24c02";
- reg = <0x55>;
- };
- };
-
- 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>;
-
- adt7461@4c {
- compatible = "adi,adt7461";
- reg = <0x4c>;
- };
- };
- };
- };
-
- sdhc@114000 {
- voltage-ranges = <1800 1800 3300 3300>;
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t208xrdb.dtsi b/arch/powerpc/boot/dts/t208xrdb.dtsi
deleted file mode 100644
index 693d2a8..0000000
--- a/arch/powerpc/boot/dts/t208xrdb.dtsi
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * T2080PCIe-RDB Board Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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.
- */
-
-/ {
- model = "fsl,T2080RDB";
- compatible = "fsl,T2080RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
-
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
-
- boardctrl: board-control@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,t2080-cpld";
- reg = <3 0 0x300>;
- ranges = <0 3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q512a";
- reg = <0>;
- spi-max-frequency = <10000000>; /* input clock */
- };
- };
-
- i2c@118000 {
- adt7481@4c {
- compatible = "adi,adt7481";
- reg = <0x4c>;
- };
-
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
-
- eeprom@50 {
- compatible = "atmel,24c256";
- reg = <0x50>;
- };
- };
-
- i2c@118100 {
- pca9546@77 {
- compatible = "nxp,pca9546";
- reg = <0x77>;
- };
- };
-
- sdhc@114000 {
- voltage-ranges = <1800 1800 3300 3300>;
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/t4240qds.dts b/arch/powerpc/boot/dts/t4240qds.dts
deleted file mode 100644
index 93722da..0000000
--- a/arch/powerpc/boot/dts/t4240qds.dts
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * T4240QDS Device Tree Source
- *
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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/ "fsl/t4240si-pre.dtsi"
-
-/ {
- model = "fsl,T4240QDS";
- compatible = "fsl,T4240QDS";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
-
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
-
- partition@100000 {
- /* 1MB for DTB Image */
- reg = <0x00100000 0x00100000>;
- label = "NAND DTB Image";
- };
-
- partition@200000 {
- /* 10MB for Linux Kernel Image */
- reg = <0x00200000 0x00A00000>;
- label = "NAND Linux Kernel Image";
- };
-
- partition@C00000 {
- /* 500MB for Root file System Image */
- reg = <0x00c00000 0x1F400000>;
- label = "NAND RFS Image";
- };
- };
-
- board-control@3,0 {
- compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis";
- reg = <3 0 0x300>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sst,sst25wf040";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- };
- };
-
- i2c@118000 {
- mux@77 {
- compatible = "nxp,pca9547";
- reg = <0x77>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- eeprom@51 {
- compatible = "at24,24c256";
- reg = <0x51>;
- };
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- eeprom@53 {
- compatible = "at24,24c256";
- reg = <0x53>;
- };
- eeprom@54 {
- compatible = "at24,24c256";
- reg = <0x54>;
- };
- eeprom@55 {
- compatible = "at24,24c256";
- reg = <0x55>;
- };
- eeprom@56 {
- compatible = "at24,24c256";
- reg = <0x56>;
- };
- rtc@68 {
- compatible = "dallas,ds3232";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- };
-
- 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>;
- };
-
- ina220@44 {
- compatible = "ti,ina220";
- reg = <0x44>;
- shunt-resistor = <1000>;
- };
-
- ina220@45 {
- compatible = "ti,ina220";
- reg = <0x45>;
- shunt-resistor = <1000>;
- };
-
- ina220@46 {
- compatible = "ti,ina220";
- reg = <0x46>;
- shunt-resistor = <1000>;
- };
-
- ina220@47 {
- compatible = "ti,ina220";
- reg = <0x47>;
- shunt-resistor = <1000>;
- };
- };
- };
- };
-
- sdhc@114000 {
- voltage-ranges = <1800 1800 3300 3300>;
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-};
-
-/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t4240rdb.dts b/arch/powerpc/boot/dts/t4240rdb.dts
deleted file mode 100644
index 993eb4b..0000000
--- a/arch/powerpc/boot/dts/t4240rdb.dts
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * T4240RDB Device Tree Source
- *
- * Copyright 2014 Freescale Semiconductor Inc.
- *
- * 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 Freescale Semiconductor nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "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 Freescale Semiconductor 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/ "fsl/t4240si-pre.dtsi"
-
-/ {
- model = "fsl,T4240RDB";
- compatible = "fsl,T4240RDB";
- #address-cells = <2>;
- #size-cells = <2>;
- interrupt-parent = <&mpic>;
-
- ifc: localbus@ffe124000 {
- reg = <0xf 0xfe124000 0 0x2000>;
- ranges = <0 0 0xf 0xe8000000 0x08000000
- 2 0 0xf 0xff800000 0x00010000
- 3 0 0xf 0xffdf0000 0x00008000>;
-
- nor@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x8000000>;
-
- bank-width = <2>;
- device-width = <1>;
- };
-
- nand@2,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x2 0x0 0x10000>;
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- bman_fbpr: bman-fbpr {
- size = <0 0x1000000>;
- alignment = <0 0x1000000>;
- };
- qman_fqd: qman-fqd {
- size = <0 0x400000>;
- alignment = <0 0x400000>;
- };
- qman_pfdr: qman-pfdr {
- size = <0 0x2000000>;
- alignment = <0 0x2000000>;
- };
- };
-
- dcsr: dcsr@f00000000 {
- ranges = <0x00000000 0xf 0x00000000 0x01072000>;
- };
-
- bportals: bman-portals@ff4000000 {
- ranges = <0x0 0xf 0xf4000000 0x2000000>;
- };
-
- qportals: qman-portals@ff6000000 {
- ranges = <0x0 0xf 0xf6000000 0x2000000>;
- };
-
- soc: soc@ffe000000 {
- ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
- reg = <0xf 0xfe000000 0 0x00001000>;
- spi@110000 {
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sst,sst25wf040";
- reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
- };
- };
-
- i2c@118000 {
- eeprom@52 {
- compatible = "at24,24c256";
- reg = <0x52>;
- };
- eeprom@54 {
- compatible = "at24,24c256";
- reg = <0x54>;
- };
- eeprom@56 {
- compatible = "at24,24c256";
- reg = <0x56>;
- };
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <0x1 0x1 0 0>;
- };
- };
-
- sdhc@114000 {
- voltage-ranges = <1800 1800 3300 3300>;
- };
- };
-
- pci0: pcie@ffe240000 {
- reg = <0xf 0xfe240000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci1: pcie@ffe250000 {
- reg = <0xf 0xfe250000 0 0x10000>;
- ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
- 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci2: pcie@ffe260000 {
- reg = <0xf 0xfe260000 0 0x1000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- pci3: pcie@ffe270000 {
- reg = <0xf 0xfe270000 0 0x10000>;
- ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000
- 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
- pcie@0 {
- ranges = <0x02000000 0 0xe0000000
- 0x02000000 0 0xe0000000
- 0 0x20000000
-
- 0x01000000 0 0x00000000
- 0x01000000 0 0x00000000
- 0 0x00010000>;
- };
- };
-
- rio: rapidio@ffe0c0000 {
- reg = <0xf 0xfe0c0000 0 0x11000>;
-
- port1 {
- ranges = <0 0 0xc 0x20000000 0 0x10000000>;
- };
- port2 {
- ranges = <0 0 0xc 0x30000000 0 0x10000000>;
- };
- };
-};
-
-/include/ "fsl/t4240si-post.dtsi"
diff --git a/arch/powerpc/boot/page.h b/arch/powerpc/boot/page.h
index 14eca30f..87c42d7d 100644
--- a/arch/powerpc/boot/page.h
+++ b/arch/powerpc/boot/page.h
@@ -22,8 +22,8 @@
#define PAGE_MASK (~(PAGE_SIZE-1))
/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
+#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((typeof(addr))(size)-1)))
+#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
diff --git a/arch/powerpc/boot/prpmc2800.c b/arch/powerpc/boot/prpmc2800.c
deleted file mode 100644
index da31d60..0000000
--- a/arch/powerpc/boot/prpmc2800.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
- *
- * Author: Mark A. Greer <mgreer@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 <stdarg.h>
-#include <stddef.h>
-#include "types.h"
-#include "elf.h"
-#include "page.h"
-#include "string.h"
-#include "stdio.h"
-#include "io.h"
-#include "ops.h"
-#include "gunzip_util.h"
-#include "mv64x60.h"
-
-#define KB 1024U
-#define MB (KB*KB)
-#define GB (KB*MB)
-#define MHz (1000U*1000U)
-#define GHz (1000U*MHz)
-
-#define BOARD_MODEL "PrPMC2800"
-#define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
-
-#define EEPROM2_ADDR 0xa4
-#define EEPROM3_ADDR 0xa8
-
-BSS_STACK(16*KB);
-
-static u8 *bridge_base;
-
-typedef enum {
- BOARD_MODEL_PRPMC280,
- BOARD_MODEL_PRPMC2800,
-} prpmc2800_board_model;
-
-typedef enum {
- BRIDGE_TYPE_MV64360,
- BRIDGE_TYPE_MV64362,
-} prpmc2800_bridge_type;
-
-struct prpmc2800_board_info {
- prpmc2800_board_model model;
- char variant;
- prpmc2800_bridge_type bridge_type;
- u8 subsys0;
- u8 subsys1;
- u8 vpd4;
- u8 vpd4_mask;
- u32 core_speed;
- u32 mem_size;
- u32 boot_flash;
- u32 user_flash;
-};
-
-static struct prpmc2800_board_info prpmc2800_board_info[] = {
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'a',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x00,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 1*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'b',
- .bridge_type = BRIDGE_TYPE_MV64362,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x01,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 0,
- .user_flash = 0,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'c',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x02,
- .vpd4_mask = 0x0f,
- .core_speed = 733*MHz,
- .mem_size = 512*MB,
- .boot_flash = 1*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'd',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x03,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 1*GB,
- .boot_flash = 1*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'e',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x04,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 1*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'f',
- .bridge_type = BRIDGE_TYPE_MV64362,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x05,
- .vpd4_mask = 0x0f,
- .core_speed = 733*MHz,
- .mem_size = 128*MB,
- .boot_flash = 1*MB,
- .user_flash = 0,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'g',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x06,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 256*MB,
- .boot_flash = 1*MB,
- .user_flash = 0,
- },
- {
- .model = BOARD_MODEL_PRPMC280,
- .variant = 'h',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xff,
- .subsys1 = 0xff,
- .vpd4 = 0x07,
- .vpd4_mask = 0x0f,
- .core_speed = 1*GHz,
- .mem_size = 1*GB,
- .boot_flash = 1*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'a',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xb2,
- .subsys1 = 0x8c,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'b',
- .bridge_type = BRIDGE_TYPE_MV64362,
- .subsys0 = 0xb2,
- .subsys1 = 0x8d,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 0,
- .user_flash = 0,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'c',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xb2,
- .subsys1 = 0x8e,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 733*MHz,
- .mem_size = 512*MB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'd',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xb2,
- .subsys1 = 0x8f,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 1*GHz,
- .mem_size = 1*GB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'e',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xa2,
- .subsys1 = 0x8a,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 1*GHz,
- .mem_size = 512*MB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'f',
- .bridge_type = BRIDGE_TYPE_MV64362,
- .subsys0 = 0xa2,
- .subsys1 = 0x8b,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 733*MHz,
- .mem_size = 128*MB,
- .boot_flash = 2*MB,
- .user_flash = 0,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'g',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xa2,
- .subsys1 = 0x8c,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 1*GHz,
- .mem_size = 2*GB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
- {
- .model = BOARD_MODEL_PRPMC2800,
- .variant = 'h',
- .bridge_type = BRIDGE_TYPE_MV64360,
- .subsys0 = 0xa2,
- .subsys1 = 0x8d,
- .vpd4 = 0x00,
- .vpd4_mask = 0x00,
- .core_speed = 733*MHz,
- .mem_size = 1*GB,
- .boot_flash = 2*MB,
- .user_flash = 64*MB,
- },
-};
-
-static struct prpmc2800_board_info *prpmc2800_get_board_info(u8 *vpd)
-{
- struct prpmc2800_board_info *bip;
- int i;
-
- for (i=0,bip=prpmc2800_board_info; i<ARRAY_SIZE(prpmc2800_board_info);
- i++,bip++)
- if ((vpd[0] == bip->subsys0) && (vpd[1] == bip->subsys1)
- && ((vpd[4] & bip->vpd4_mask) == bip->vpd4))
- return bip;
-
- return NULL;
-}
-
-/* Get VPD from i2c eeprom 2, then match it to a board info entry */
-static struct prpmc2800_board_info *prpmc2800_get_bip(void)
-{
- struct prpmc2800_board_info *bip;
- u8 vpd[5];
- int rc;
-
- if (mv64x60_i2c_open())
- fatal("Error: Can't open i2c device\n\r");
-
- /* Get VPD from i2c eeprom-2 */
- memset(vpd, 0, sizeof(vpd));
- rc = mv64x60_i2c_read(EEPROM2_ADDR, vpd, 0x1fde, 2, sizeof(vpd));
- if (rc < 0)
- fatal("Error: Couldn't read eeprom2\n\r");
- mv64x60_i2c_close();
-
- /* Get board type & related info */
- bip = prpmc2800_get_board_info(vpd);
- if (bip == NULL) {
- printf("Error: Unsupported board or corrupted VPD:\n\r");
- printf(" 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
- vpd[0], vpd[1], vpd[2], vpd[3], vpd[4]);
- printf("Using device tree defaults...\n\r");
- }
-
- return bip;
-}
-
-static void prpmc2800_bridge_setup(u32 mem_size)
-{
- u32 i, v[12], enables, acc_bits;
- u32 pci_base_hi, pci_base_lo, size, buf[2];
- unsigned long cpu_base;
- int rc;
- void *devp;
- u8 *bridge_pbase, is_coherent;
- struct mv64x60_cpu2pci_win *tbl;
-
- bridge_pbase = mv64x60_get_bridge_pbase();
- is_coherent = mv64x60_is_coherent();
-
- if (is_coherent)
- acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
- | MV64x60_PCI_ACC_CNTL_SWAP_NONE
- | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
- | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
- else
- acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
- | MV64x60_PCI_ACC_CNTL_SWAP_NONE
- | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
- | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
-
- mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
- mv64x60_config_pci_windows(bridge_base, bridge_pbase, 0, 0, mem_size,
- acc_bits);
-
- /* Get the cpu -> pci i/o & mem mappings from the device tree */
- devp = find_node_by_compatible(NULL, "marvell,mv64360-pci");
- if (devp == NULL)
- fatal("Error: Missing marvell,mv64360-pci"
- " device tree node\n\r");
-
- rc = getprop(devp, "ranges", v, sizeof(v));
- if (rc != sizeof(v))
- fatal("Error: Can't find marvell,mv64360-pci ranges"
- " property\n\r");
-
- /* Get the cpu -> pci i/o & mem mappings from the device tree */
- devp = find_node_by_compatible(NULL, "marvell,mv64360");
- if (devp == NULL)
- fatal("Error: Missing marvell,mv64360 device tree node\n\r");
-
- enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
- enables |= 0x0007fe00; /* Disable all cpu->pci windows */
- out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
-
- for (i=0; i<12; i+=6) {
- switch (v[i] & 0xff000000) {
- case 0x01000000: /* PCI I/O Space */
- tbl = mv64x60_cpu2pci_io;
- break;
- case 0x02000000: /* PCI MEM Space */
- tbl = mv64x60_cpu2pci_mem;
- break;
- default:
- continue;
- }
-
- pci_base_hi = v[i+1];
- pci_base_lo = v[i+2];
- cpu_base = v[i+3];
- size = v[i+5];
-
- buf[0] = cpu_base;
- buf[1] = size;
-
- if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
- fatal("Error: Can't translate PCI address 0x%x\n\r",
- (u32)cpu_base);
-
- mv64x60_config_cpu2pci_window(bridge_base, 0, pci_base_hi,
- pci_base_lo, cpu_base, size, tbl);
- }
-
- enables &= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
- out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
-}
-
-static void prpmc2800_fixups(void)
-{
- u32 v[2], l, mem_size;
- int rc;
- void *devp;
- char model[BOARD_MODEL_MAX];
- struct prpmc2800_board_info *bip;
-
- bip = prpmc2800_get_bip(); /* Get board info based on VPD */
-
- mem_size = (bip) ? bip->mem_size : mv64x60_get_mem_size(bridge_base);
- prpmc2800_bridge_setup(mem_size); /* Do necessary bridge setup */
-
- /* If the VPD doesn't match what we know about, just use the
- * defaults already in the device tree.
- */
- if (!bip)
- return;
-
- /* Know the board type so override device tree defaults */
- /* Set /model appropriately */
- devp = finddevice("/");
- if (devp == NULL)
- fatal("Error: Missing '/' device tree node\n\r");
- memset(model, 0, BOARD_MODEL_MAX);
- strncpy(model, BOARD_MODEL, BOARD_MODEL_MAX - 2);
- l = strlen(model);
- if (bip->model == BOARD_MODEL_PRPMC280)
- l--;
- model[l++] = bip->variant;
- model[l++] = '\0';
- setprop(devp, "model", model, l);
-
- /* Set /cpus/PowerPC,7447/clock-frequency */
- devp = find_node_by_prop_value_str(NULL, "device_type", "cpu");
- if (devp == NULL)
- fatal("Error: Missing proper cpu device tree node\n\r");
- v[0] = bip->core_speed;
- setprop(devp, "clock-frequency", &v[0], sizeof(v[0]));
-
- /* Set /memory/reg size */
- devp = finddevice("/memory");
- if (devp == NULL)
- fatal("Error: Missing /memory device tree node\n\r");
- v[0] = 0;
- v[1] = bip->mem_size;
- setprop(devp, "reg", v, sizeof(v));
-
- /* Update model, if this is a mv64362 */
- if (bip->bridge_type == BRIDGE_TYPE_MV64362) {
- devp = find_node_by_compatible(NULL, "marvell,mv64360");
- if (devp == NULL)
- fatal("Error: Missing marvell,mv64360"
- " device tree node\n\r");
- setprop(devp, "model", "mv64362", strlen("mv64362") + 1);
- }
-
- /* Set User FLASH size */
- devp = find_node_by_compatible(NULL, "direct-mapped");
- if (devp == NULL)
- fatal("Error: Missing User FLASH device tree node\n\r");
- rc = getprop(devp, "reg", v, sizeof(v));
- if (rc != sizeof(v))
- fatal("Error: Can't find User FLASH reg property\n\r");
- v[1] = bip->user_flash;
- setprop(devp, "reg", v, sizeof(v));
-}
-
-#define MV64x60_MPP_CNTL_0 0xf000
-#define MV64x60_MPP_CNTL_2 0xf008
-#define MV64x60_GPP_IO_CNTL 0xf100
-#define MV64x60_GPP_LEVEL_CNTL 0xf110
-#define MV64x60_GPP_VALUE_SET 0xf118
-
-static void prpmc2800_reset(void)
-{
- u32 temp;
-
- udelay(5000000);
-
- if (bridge_base != 0) {
- temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
- temp &= 0xFFFF0FFF;
- out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
-
- temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
- temp |= 0x00000004;
- out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
-
- temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
- temp |= 0x00000004;
- out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
-
- temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
- temp &= 0xFFFF0FFF;
- out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
-
- temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
- temp |= 0x00080000;
- out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
-
- temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
- temp |= 0x00080000;
- out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
-
- out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
- 0x00080004);
- }
-
- for (;;);
-}
-
-#define HEAP_SIZE (16*MB)
-static struct gunzip_state gzstate;
-
-void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- struct elf_info ei;
- char *heap_start, *dtb;
- int dt_size = _dtb_end - _dtb_start;
- void *vmlinuz_addr = _vmlinux_start;
- unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
- char elfheader[256];
-
- if (dt_size <= 0) /* No fdt */
- exit();
-
- /*
- * Start heap after end of the kernel (after decompressed to
- * address 0) or the end of the zImage, whichever is higher.
- * That's so things allocated by simple_alloc won't overwrite
- * any part of the zImage and the kernel won't overwrite the dtb
- * when decompressed & relocated.
- */
- gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
- gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
-
- if (!parse_elf32(elfheader, &ei))
- exit();
-
- heap_start = (char *)(ei.memsize + ei.elfoffset); /* end of kernel*/
- heap_start = max(heap_start, (char *)_end); /* end of zImage */
-
- if ((unsigned)simple_alloc_init(heap_start, HEAP_SIZE, 2*KB, 16)
- > (128*MB))
- exit();
-
- /* Relocate dtb to safe area past end of zImage & kernel */
- dtb = malloc(dt_size);
- if (!dtb)
- exit();
- memmove(dtb, _dtb_start, dt_size);
- fdt_init(dtb);
-
- bridge_base = mv64x60_get_bridge_base();
-
- platform_ops.fixups = prpmc2800_fixups;
- platform_ops.exit = prpmc2800_reset;
-
- if (serial_console_init() < 0)
- exit();
-}
-
-/* _zimage_start called very early--need to turn off external interrupts */
-asm (" .globl _zimage_start\n\
- _zimage_start:\n\
- mfmsr 10\n\
- rlwinm 10,10,0,~(1<<15) /* Clear MSR_EE */\n\
- sync\n\
- mtmsr 10\n\
- isync\n\
- b _zimage_start_lib\n\
-");
diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h
index 433f450..d70517c 100644
--- a/arch/powerpc/boot/rs6000.h
+++ b/arch/powerpc/boot/rs6000.h
@@ -239,5 +239,5 @@ struct external_reloc {
#define DEFAULT_DATA_SECTION_ALIGNMENT 4
#define DEFAULT_BSS_SECTION_ALIGNMENT 4
#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
-/* For new sections we havn't heard of before */
+/* For new sections we haven't heard of before */
#define DEFAULT_SECTION_ALIGNMENT 4
diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c
index b73174c..bcc5902 100644
--- a/arch/powerpc/boot/treeboot-akebono.c
+++ b/arch/powerpc/boot/treeboot-akebono.c
@@ -38,7 +38,7 @@
BSS_STACK(4096);
-#define SPRN_PIR 0x11E /* Processor Indentification Register */
+#define SPRN_PIR 0x11E /* Processor Identification Register */
#define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */
#define MAX_RANKS 0x4
#define DDR3_MR0CF 0x80010011U
diff --git a/arch/powerpc/boot/treeboot-currituck.c b/arch/powerpc/boot/treeboot-currituck.c
index 925ae43..303d207 100644
--- a/arch/powerpc/boot/treeboot-currituck.c
+++ b/arch/powerpc/boot/treeboot-currituck.c
@@ -80,7 +80,7 @@ static void ibm_currituck_fixups(void)
}
}
-#define SPRN_PIR 0x11E /* Processor Indentification Register */
+#define SPRN_PIR 0x11E /* Processor Identification Register */
void platform_init(void)
{
unsigned long end_of_ram, avail_ram;
diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c
index 329e710..733f8bf 100644
--- a/arch/powerpc/boot/treeboot-iss4xx.c
+++ b/arch/powerpc/boot/treeboot-iss4xx.c
@@ -59,7 +59,7 @@ static void *iss_4xx_vmlinux_alloc(unsigned long size)
return (void *)ibm4xx_memstart;
}
-#define SPRN_PIR 0x11E /* Processor Indentification Register */
+#define SPRN_PIR 0x11E /* Processor Identification Register */
void platform_init(void)
{
unsigned long end_of_ram = 0x08000000;
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 3f50c27..6a19fce 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -63,6 +63,23 @@ usage() {
exit 1
}
+run_cmd() {
+ if [ "$V" = 1 ]; then
+ $* 2>&1
+ else
+ local msg
+
+ set +e
+ msg=$($* 2>&1)
+
+ if [ $? -ne "0" ]; then
+ echo $msg
+ exit 1
+ fi
+ set -e
+ fi
+}
+
while [ "$#" -gt 0 ]; do
case "$1" in
-o)
@@ -137,7 +154,7 @@ if [ -z "$kernel" ]; then
kernel=vmlinux
fi
-elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`"
+LANG=C elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`"
case "$elfformat" in
elf64-powerpcle) format=elf64lppc ;;
elf64-powerpc) format=elf32ppc ;;
@@ -456,12 +473,12 @@ ps3)
${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
- dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
- skip=$overlay_dest seek=$system_reset_kernel \
+ run_cmd dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+ skip=$overlay_dest seek=$system_reset_kernel \
count=$overlay_size bs=1
- dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
- skip=$system_reset_overlay seek=$overlay_dest \
+ run_cmd dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+ skip=$system_reset_overlay seek=$overlay_dest \
count=$overlay_size bs=1
odir="$(dirname "$ofile.bin")"
diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
index 2a5fdcb..87fc15b 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
@@ -35,7 +35,6 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_IDE=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_SPI_ATTRS=y
diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig
index 3be85c5..6f753a7 100644
--- a/arch/powerpc/configs/85xx/ksi8560_defconfig
+++ b/arch/powerpc/configs/85xx/ksi8560_defconfig
@@ -34,7 +34,6 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_IDE=y
CONFIG_NETDEVICES=y
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_SCC is not set
diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig
index f66d16b..b451905 100644
--- a/arch/powerpc/configs/85xx/stx_gp3_defconfig
+++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig
@@ -31,8 +31,6 @@ CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=m
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
CONFIG_CHR_DEV_ST=m
diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config
new file mode 100644
index 0000000..f91f889
--- /dev/null
+++ b/arch/powerpc/configs/86xx-hw.config
@@ -0,0 +1,104 @@
+CONFIG_ATA=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BROADCOM_PHY=y
+# CONFIG_CARDBUS is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_DS1682=y
+CONFIG_EEPROM_LEGACY=y
+CONFIG_GEF_WDT=y
+CONFIG_GIANFAR=y
+CONFIG_GPIO_GE_FPGA=y
+CONFIG_GPIO_SYSFS=y
+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_SUNPLUS=y
+CONFIG_HW_RANDOM=y
+CONFIG_HZ_1000=y
+CONFIG_I2C_MPC=y
+CONFIG_I2C=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_NAND_FSL_ELBC=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_TULIP=y
+CONFIG_NVRAM=y
+CONFIG_PATA_ALI=y
+CONFIG_PCCARD=y
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCIEASPM is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCI=y
+# CONFIG_PCMCIA_LOAD_CIS is not set
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_RTC_DRV_RX8581=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SIL24=y
+CONFIG_SATA_SIL=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM92=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SND_INTEL8X0=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND=y
+CONFIG_SOUND=y
+CONFIG_ULI526X=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB=y
+CONFIG_VITESSE_PHY=y
+CONFIG_VME_BUS=y
+CONFIG_VME_TSI148=y
+CONFIG_WATCHDOG=y
+# CONFIG_YENTA_O2 is not set
+# CONFIG_YENTA_RICOH is not set
+# CONFIG_YENTA_TOSHIBA is not set
+CONFIG_YENTA=y
diff --git a/arch/powerpc/configs/86xx-smp.config b/arch/powerpc/configs/86xx-smp.config
new file mode 100644
index 0000000..40ac38d
--- /dev/null
+++ b/arch/powerpc/configs/86xx-smp.config
@@ -0,0 +1,2 @@
+CONFIG_NR_CPUS=2
+CONFIG_SMP=y
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
deleted file mode 100644
index 9792a2c..0000000
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ /dev/null
@@ -1,216 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_GEF_PPC9A=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_PREEMPT=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIEASPM is not set
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_CARDBUS is not set
-CONFIG_YENTA=y
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TOSHIBA is not set
-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_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-# CONFIG_INET_XFRM_MODE_BEET is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NET_PKTGEN=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=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_PHYSMAP_OF=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_DS1682=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_ATA=y
-CONFIG_SATA_SIL=y
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TUN=m
-CONFIG_GIANFAR=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_HW_RANDOM=y
-CONFIG_NVRAM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MPC=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_GE_FPGA=y
-CONFIG_SENSORS_LM90=y
-CONFIG_SENSORS_LM92=y
-CONFIG_WATCHDOG=y
-CONFIG_GEF_WDT=y
-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_SUNPLUS=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_INTF_PROC is not set
-CONFIG_RTC_DRV_RX8581=y
-CONFIG_STAGING=y
-CONFIG_VME_BUS=y
-CONFIG_VME_TSI148=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=850
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_CIFS=m
-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_CRC_CCITT=y
-CONFIG_CRC_T10DIF=y
-CONFIG_LIBCRC32C=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
deleted file mode 100644
index cadc366..0000000
--- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig
+++ /dev/null
@@ -1,214 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_GEF_SBC310=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_PREEMPT=y
-CONFIG_BINFMT_MISC=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIEASPM is not set
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_CARDBUS is not set
-CONFIG_YENTA=y
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TOSHIBA is not set
-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_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-# CONFIG_INET_XFRM_MODE_BEET is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NET_PKTGEN=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=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_PHYSMAP_OF=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_DS1682=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_ATA=y
-CONFIG_SATA_SIL24=y
-# CONFIG_ATA_SFF is not set
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TUN=m
-CONFIG_GIANFAR=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_HW_RANDOM=y
-CONFIG_NVRAM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MPC=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_GE_FPGA=y
-CONFIG_SENSORS_LM90=y
-CONFIG_SENSORS_LM92=y
-CONFIG_WATCHDOG=y
-CONFIG_GEF_WDT=y
-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_SUNPLUS=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_INTF_PROC is not set
-CONFIG_RTC_DRV_RX8581=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=850
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_CIFS=m
-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_CRC_CCITT=y
-CONFIG_CRC_T10DIF=y
-CONFIG_LIBCRC32C=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
deleted file mode 100644
index 2aa7d97..0000000
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ /dev/null
@@ -1,273 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_GEF_SBC610=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_PREEMPT=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIEASPM is not set
-CONFIG_PCI_DEBUG=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_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-# CONFIG_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_NETFILTER_XT_MATCH_SCTP is not set
-CONFIG_IP_NF_IPTABLES=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_MANGLE=m
-CONFIG_IP_NF_TARGET_ECN=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_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_IP_SCTP=m
-CONFIG_TIPC=m
-CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_PKTGEN=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FW_LOADER is not set
-CONFIG_MTD=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_PHYSMAP_OF=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_DS1682=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_ATA=y
-CONFIG_SATA_SIL=y
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TUN=m
-CONFIG_GIANFAR=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOATM=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_INPUT_FF_MEMLESS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_HW_RANDOM=y
-CONFIG_NVRAM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MPC=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_GE_FPGA=y
-CONFIG_SENSORS_LM90=y
-CONFIG_SENSORS_LM92=y
-CONFIG_WATCHDOG=y
-CONFIG_GEF_WDT=y
-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_SUNPLUS=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_INTF_PROC is not set
-CONFIG_RTC_DRV_RX8581=y
-CONFIG_STAGING=y
-CONFIG_VME_BUS=y
-CONFIG_VME_TSI148=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_CIFS=m
-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_DEBUG_INFO=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=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_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
deleted file mode 100644
index e32207d..0000000
--- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
+++ /dev/null
@@ -1,110 +0,0 @@
-# CONFIG_SWAP is not set
-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_EXPERT=y
-# CONFIG_ELF_CORE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_LDM_PARTITION=y
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_MPC8610_HPCD=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_FORCE_MAX_ZONEORDER=12
-# CONFIG_SECCOMP is not set
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIEASPM is not set
-CONFIG_PCI_DEBUG=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=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_LRO is not set
-CONFIG_IPV6=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_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_FSL_ELBC=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_IDE=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_ATA=y
-CONFIG_SATA_AHCI=y
-CONFIG_PATA_ALI=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_NET_TULIP=y
-CONFIG_ULI526X=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_MPC=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_FSL_DIU=y
-CONFIG_VGACON_SOFT_SCROLLBACK=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-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_SOC=y
-CONFIG_SND_POWERPC_SOC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_CMOS=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NLS=y
-CONFIG_CRC_T10DIF=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
deleted file mode 100644
index a36e11d..0000000
--- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
+++ /dev/null
@@ -1,156 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_MPC8641_HPCN=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=y
-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_NET_IPIP=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_IP_SCTP=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_EEPROM_LEGACY=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_ATA=y
-CONFIG_SATA_AHCI=y
-CONFIG_PATA_ALI=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_GIANFAR=y
-CONFIG_VITESSE_PHY=y
-CONFIG_INPUT_FF_MEMLESS=m
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_NVRAM=y
-CONFIG_I2C=y
-CONFIG_I2C_MPC=y
-# CONFIG_HWMON 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_INTEL8X0=y
-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_SUNPLUS=y
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
-CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_CMOS=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_ADFS_FS=m
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=y
-CONFIG_VXFS_FS=m
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_CRC_T10DIF=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig
deleted file mode 100644
index db79bde..0000000
--- a/arch/powerpc/configs/86xx/sbc8641d_defconfig
+++ /dev/null
@@ -1,246 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_SBC8641D=y
-CONFIG_PREEMPT=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIEASPM is not set
-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_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-# CONFIG_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_NETFILTER_XT_MATCH_SCTP is not set
-CONFIG_IP_NF_IPTABLES=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_MANGLE=m
-CONFIG_IP_NF_TARGET_ECN=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_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_IP_SCTP=m
-CONFIG_TIPC=m
-CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_PKTGEN=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# 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_LE_BYTE_SWAP=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID10=y
-CONFIG_MD_MULTIPATH=y
-CONFIG_MD_FAULTY=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_CRYPT=y
-CONFIG_DM_SNAPSHOT=y
-CONFIG_DM_MIRROR=y
-CONFIG_DM_ZERO=y
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=y
-CONFIG_TUN=m
-CONFIG_GIANFAR=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOATM=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MPC=y
-CONFIG_WATCHDOG=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS=m
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_MINIX_FS=m
-CONFIG_ROMFS_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_CIFS=m
-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_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=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
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig
index 9186229..340685c 100644
--- a/arch/powerpc/configs/c2k_defconfig
+++ b/arch/powerpc/configs/c2k_defconfig
@@ -387,7 +387,6 @@ CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_BOOTX_TEXT=y
CONFIG_PPC_EARLY_DEBUG=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SELINUX=y
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 9227b51..db328e6 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,5 +1,5 @@
CONFIG_PPC64=y
-CONFIG_TUNE_CELL=y
+CONFIG_CELL_CPU=y
CONFIG_ALTIVEC=y
CONFIG_SMP=y
CONFIG_NR_CPUS=4
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
index 59b85cb..d16d6c5 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -112,6 +112,7 @@ CONFIG_RTC_DRV_M41T80=y
CONFIG_RTC_DRV_MPC5121=y
CONFIG_DMADEVICES=y
CONFIG_MPC512X_DMA=y
+CONFIG_MPC512x_LPBFIFO=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XIP=y
CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/configs/mpc85xx_basic_defconfig b/arch/powerpc/configs/mpc85xx_basic_defconfig
index 850bd19..b1593fe 100644
--- a/arch/powerpc/configs/mpc85xx_basic_defconfig
+++ b/arch/powerpc/configs/mpc85xx_basic_defconfig
@@ -12,6 +12,7 @@ CONFIG_P1010_RDB=y
CONFIG_P1022_DS=y
CONFIG_P1022_RDK=y
CONFIG_P1023_RDB=y
+CONFIG_TWR_P102x=y
CONFIG_SBC8548=y
CONFIG_SOCRATES=y
CONFIG_STX_GP3=y
diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig
new file mode 100644
index 0000000..33af5c5
--- /dev/null
+++ b/arch/powerpc/configs/mpc86xx_basic_defconfig
@@ -0,0 +1,10 @@
+CONFIG_HIGHMEM=y
+CONFIG_KEXEC=y
+CONFIG_PPC_86xx=y
+CONFIG_PROC_KCORE=y
+CONFIG_GEF_PPC9A=y
+CONFIG_GEF_SBC310=y
+CONFIG_GEF_SBC610=y
+CONFIG_MPC8610_HPCD=y
+CONFIG_MPC8641_HPCN=y
+CONFIG_SBC8641D=y
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
deleted file mode 100644
index a457256..0000000
--- a/arch/powerpc/configs/mpc86xx_defconfig
+++ /dev/null
@@ -1,162 +0,0 @@
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=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=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_PPC_86xx=y
-CONFIG_MPC8641_HPCN=y
-CONFIG_SBC8641D=y
-CONFIG_MPC8610_HPCD=y
-CONFIG_GEF_SBC610=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_1000=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=y
-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_NET_IPIP=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_IP_SCTP=m
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_EEPROM_LEGACY=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_ATA=y
-CONFIG_SATA_AHCI=y
-CONFIG_PATA_ALI=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_GIANFAR=y
-CONFIG_VITESSE_PHY=y
-CONFIG_INPUT_FF_MEMLESS=m
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_NVRAM=y
-CONFIG_I2C=y
-CONFIG_I2C_MPC=y
-# CONFIG_HWMON 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_INTEL8X0=y
-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_SUNPLUS=y
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
-CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_CMOS=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_ADFS_FS=m
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=y
-CONFIG_VXFS_FS=m
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_CRC_T10DIF=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
new file mode 100644
index 0000000..0450310
--- /dev/null
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -0,0 +1,313 @@
+CONFIG_PPC64=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2048
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
+CONFIG_IRQ_DOMAIN_DEBUG=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_NUMA_BALANCING=y
+CONFIG_CGROUPS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_OPAL_PRD=y
+# CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_HZ_100=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PPC_TRANSACTIONAL_MEM=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_KEXEC=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_NUMA=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_PPC_64K_PAGES=y
+CONFIG_PPC_SUBPAGE_PROT=y
+CONFIG_SCHED_SMT=y
+CONFIG_PM=y
+CONFIG_PCI_MSI=y
+CONFIG_HOTPLUG_PCI=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_NET_IPIP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_POWERNV_FLASH=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_BLK_DEV_FD=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SRP_ATTRS=y
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_CXGB4_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
+CONFIG_SCSI_MPT2SAS=m
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_IPR=y
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+# CONFIG_ATA_SFF is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_VHOST_NET=m
+CONFIG_VORTEX=y
+CONFIG_ACENIC=m
+CONFIG_ACENIC_OMIT_TIGON_I=y
+CONFIG_PCNET32=y
+CONFIG_TIGON3=y
+CONFIG_BNX2X=m
+CONFIG_CHELSIO_T1=m
+CONFIG_BE2NET=m
+CONFIG_S2IO=m
+CONFIG_E100=y
+CONFIG_E1000=y
+CONFIG_E1000E=y
+CONFIG_IXGB=m
+CONFIG_IXGBE=m
+CONFIG_MLX4_EN=m
+CONFIG_MYRI10GE=m
+CONFIG_QLGE=m
+CONFIG_NETXEN_NIC=m
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_VIRTIO_CONSOLE=m
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_DEVICE_INTERFACE=y
+CONFIG_IPMI_POWERNV=y
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=1024
+CONFIG_DRM=y
+CONFIG_DRM_AST=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_OF=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_IBM_GXT4500=y
+CONFIG_LCD_PLATFORM=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_LOGO=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_MON=m
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_POWERNV=m
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_CXGB3=m
+CONFIG_INFINIBAND_CXGB4=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_CM=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=y
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
+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_REISERFS_FS=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_OVERLAY_FS=m
+CONFIG_ISO9660_FS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_PSTORE=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LATENCYTOP=y
+CONFIG_SCHED_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
+CONFIG_XMON=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_DEV_NX=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=m
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 2c041b5..b041fb6 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -36,7 +36,6 @@ CONFIG_PS3_ROM=m
CONFIG_PS3_FLASH=m
CONFIG_PS3_LPM=m
CONFIG_PPC_IBM_CELL_BLADE=y
-CONFIG_PPC_CELL_QPACE=y
CONFIG_RTAS_FLASH=m
CONFIG_IBMEBUS=y
CONFIG_CPU_FREQ_PMAC64=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index e5d2c3d..99ccbeba 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -1175,7 +1175,6 @@ CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_XMON=y
CONFIG_BOOTX_TEXT=y
CONFIG_PPC_EARLY_DEBUG=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index adc14e8..c400460 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,5 +1,5 @@
CONFIG_PPC64=y
-CONFIG_TUNE_CELL=y
+CONFIG_CELL_CPU=y
CONFIG_ALTIVEC=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
@@ -53,7 +53,6 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
CONFIG_BT=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
@@ -141,8 +140,6 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_PS3=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT4_FS=y
CONFIG_QUOTA=y
CONFIG_QFMT_V2=y
@@ -175,9 +172,7 @@ CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_LIST=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_FTRACE is not set
-CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SALSA20=m
CONFIG_CRYPTO_LZO=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/crypto/aes-spe-core.S b/arch/powerpc/crypto/aes-spe-core.S
index 5dc6bce..bc6ff43 100644
--- a/arch/powerpc/crypto/aes-spe-core.S
+++ b/arch/powerpc/crypto/aes-spe-core.S
@@ -61,7 +61,7 @@
* via bl/blr. It expects that caller has pre-xored input data with first
* 4 words of encryption key into rD0-rD3. Pointer/counter registers must
* have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3
- * and rW0-rW3 and caller must execute a final xor on the ouput registers.
+ * and rW0-rW3 and caller must execute a final xor on the output registers.
* All working registers rD0-rD3 & rW0-rW7 are overwritten during processing.
*
*/
@@ -209,7 +209,7 @@ ppc_encrypt_block_loop:
* via bl/blr. It expects that caller has pre-xored input data with first
* 4 words of encryption key into rD0-rD3. Pointer/counter registers must
* have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3
- * and rW0-rW3 and caller must execute a final xor on the ouput registers.
+ * and rW0-rW3 and caller must execute a final xor on the output registers.
* All working registers rD0-rD3 & rW0-rW7 are overwritten during processing.
*
*/
diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c
index bd5e63f..748fc00 100644
--- a/arch/powerpc/crypto/aes-spe-glue.c
+++ b/arch/powerpc/crypto/aes-spe-glue.c
@@ -22,6 +22,7 @@
#include <asm/byteorder.h>
#include <asm/switch_to.h>
#include <crypto/algapi.h>
+#include <crypto/xts.h>
/*
* MAX_BYTES defines the number of bytes that are allowed to be processed
@@ -32,7 +33,7 @@
* 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data
* will need an estimated maximum of 20,000 cycles. Headroom for cache misses
* included. Even with the low end model clocked at 667 MHz this equals to a
- * critical time window of less than 30us. The value has been choosen to
+ * critical time window of less than 30us. The value has been chosen to
* process a 512 byte disk block in one or a large 1400 bytes IPsec network
* packet in two runs.
*
@@ -85,6 +86,7 @@ static void spe_begin(void)
static void spe_end(void)
{
+ disable_kernel_spe();
/* reenable preemption */
preempt_enable();
}
@@ -125,6 +127,11 @@ static int ppc_xts_setkey(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
{
struct ppc_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ int err;
+
+ err = xts_check_key(tfm, in_key, key_len);
+ if (err)
+ return err;
key_len >>= 1;
diff --git a/arch/powerpc/crypto/sha1-spe-glue.c b/arch/powerpc/crypto/sha1-spe-glue.c
index 3e1d222..f9ebc38 100644
--- a/arch/powerpc/crypto/sha1-spe-glue.c
+++ b/arch/powerpc/crypto/sha1-spe-glue.c
@@ -46,6 +46,7 @@ static void spe_begin(void)
static void spe_end(void)
{
+ disable_kernel_spe();
/* reenable preemption */
preempt_enable();
}
diff --git a/arch/powerpc/crypto/sha256-spe-glue.c b/arch/powerpc/crypto/sha256-spe-glue.c
index f4a616f..718a079 100644
--- a/arch/powerpc/crypto/sha256-spe-glue.c
+++ b/arch/powerpc/crypto/sha256-spe-glue.c
@@ -47,6 +47,7 @@ static void spe_begin(void)
static void spe_end(void)
{
+ disable_kernel_spe();
/* reenable preemption */
preempt_enable();
}
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 55f106e..ae0751e 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -12,6 +12,24 @@
#define ATOMIC_INIT(i) { (i) }
+/*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+ * on the platform without lwsync.
+ */
+#define __atomic_op_acquire(op, args...) \
+({ \
+ typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
+ __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \
+ __ret; \
+})
+
+#define __atomic_op_release(op, args...) \
+({ \
+ __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \
+ op##_relaxed(args); \
+})
+
static __inline__ int atomic_read(const atomic_t *v)
{
int t;
@@ -42,27 +60,27 @@ static __inline__ void atomic_##op(int a, atomic_t *v) \
: "cc"); \
} \
-#define ATOMIC_OP_RETURN(op, asm_op) \
-static __inline__ int atomic_##op##_return(int a, atomic_t *v) \
+#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \
+static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
{ \
int t; \
\
__asm__ __volatile__( \
- PPC_ATOMIC_ENTRY_BARRIER \
-"1: lwarx %0,0,%2 # atomic_" #op "_return\n" \
- #asm_op " %0,%1,%0\n" \
- PPC405_ERR77(0,%2) \
-" stwcx. %0,0,%2 \n" \
+"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \
+ #asm_op " %0,%2,%0\n" \
+ PPC405_ERR77(0, %3) \
+" stwcx. %0,0,%3\n" \
" bne- 1b\n" \
- PPC_ATOMIC_EXIT_BARRIER \
- : "=&r" (t) \
+ : "=&r" (t), "+m" (v->counter) \
: "r" (a), "r" (&v->counter) \
- : "cc", "memory"); \
+ : "cc"); \
\
return t; \
}
-#define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op)
+#define ATOMIC_OPS(op, asm_op) \
+ ATOMIC_OP(op, asm_op) \
+ ATOMIC_OP_RETURN_RELAXED(op, asm_op)
ATOMIC_OPS(add, add)
ATOMIC_OPS(sub, subf)
@@ -71,8 +89,11 @@ ATOMIC_OP(and, and)
ATOMIC_OP(or, or)
ATOMIC_OP(xor, xor)
+#define atomic_add_return_relaxed atomic_add_return_relaxed
+#define atomic_sub_return_relaxed atomic_sub_return_relaxed
+
#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP_RETURN_RELAXED
#undef ATOMIC_OP
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
@@ -92,21 +113,19 @@ static __inline__ void atomic_inc(atomic_t *v)
: "cc", "xer");
}
-static __inline__ int atomic_inc_return(atomic_t *v)
+static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
{
int t;
__asm__ __volatile__(
- PPC_ATOMIC_ENTRY_BARRIER
-"1: lwarx %0,0,%1 # atomic_inc_return\n\
- addic %0,%0,1\n"
- PPC405_ERR77(0,%1)
-" stwcx. %0,0,%1 \n\
- bne- 1b"
- PPC_ATOMIC_EXIT_BARRIER
- : "=&r" (t)
+"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n"
+" addic %0,%0,1\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %0,0,%2\n"
+" bne- 1b"
+ : "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
- : "cc", "xer", "memory");
+ : "cc", "xer");
return t;
}
@@ -136,27 +155,34 @@ static __inline__ void atomic_dec(atomic_t *v)
: "cc", "xer");
}
-static __inline__ int atomic_dec_return(atomic_t *v)
+static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
{
int t;
__asm__ __volatile__(
- PPC_ATOMIC_ENTRY_BARRIER
-"1: lwarx %0,0,%1 # atomic_dec_return\n\
- addic %0,%0,-1\n"
- PPC405_ERR77(0,%1)
-" stwcx. %0,0,%1\n\
- bne- 1b"
- PPC_ATOMIC_EXIT_BARRIER
- : "=&r" (t)
+"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n"
+" addic %0,%0,-1\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %0,0,%2\n"
+" bne- 1b"
+ : "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
- : "cc", "xer", "memory");
+ : "cc", "xer");
return t;
}
+#define atomic_inc_return_relaxed atomic_inc_return_relaxed
+#define atomic_dec_return_relaxed atomic_dec_return_relaxed
+
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg_relaxed(v, o, n) \
+ cmpxchg_relaxed(&((v)->counter), (o), (n))
+#define atomic_cmpxchg_acquire(v, o, n) \
+ cmpxchg_acquire(&((v)->counter), (o), (n))
+
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
/**
* __atomic_add_unless - add unless the number is a given value
@@ -285,26 +311,27 @@ static __inline__ void atomic64_##op(long a, atomic64_t *v) \
: "cc"); \
}
-#define ATOMIC64_OP_RETURN(op, asm_op) \
-static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \
+#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) \
+static inline long \
+atomic64_##op##_return_relaxed(long a, atomic64_t *v) \
{ \
long t; \
\
__asm__ __volatile__( \
- PPC_ATOMIC_ENTRY_BARRIER \
-"1: ldarx %0,0,%2 # atomic64_" #op "_return\n" \
- #asm_op " %0,%1,%0\n" \
-" stdcx. %0,0,%2 \n" \
+"1: ldarx %0,0,%3 # atomic64_" #op "_return_relaxed\n" \
+ #asm_op " %0,%2,%0\n" \
+" stdcx. %0,0,%3\n" \
" bne- 1b\n" \
- PPC_ATOMIC_EXIT_BARRIER \
- : "=&r" (t) \
+ : "=&r" (t), "+m" (v->counter) \
: "r" (a), "r" (&v->counter) \
- : "cc", "memory"); \
+ : "cc"); \
\
return t; \
}
-#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op)
+#define ATOMIC64_OPS(op, asm_op) \
+ ATOMIC64_OP(op, asm_op) \
+ ATOMIC64_OP_RETURN_RELAXED(op, asm_op)
ATOMIC64_OPS(add, add)
ATOMIC64_OPS(sub, subf)
@@ -312,8 +339,11 @@ ATOMIC64_OP(and, and)
ATOMIC64_OP(or, or)
ATOMIC64_OP(xor, xor)
-#undef ATOMIC64_OPS
-#undef ATOMIC64_OP_RETURN
+#define atomic64_add_return_relaxed atomic64_add_return_relaxed
+#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+
+#undef ATOPIC64_OPS
+#undef ATOMIC64_OP_RETURN_RELAXED
#undef ATOMIC64_OP
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
@@ -332,20 +362,18 @@ static __inline__ void atomic64_inc(atomic64_t *v)
: "cc", "xer");
}
-static __inline__ long atomic64_inc_return(atomic64_t *v)
+static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v)
{
long t;
__asm__ __volatile__(
- PPC_ATOMIC_ENTRY_BARRIER
-"1: ldarx %0,0,%1 # atomic64_inc_return\n\
- addic %0,%0,1\n\
- stdcx. %0,0,%1 \n\
- bne- 1b"
- PPC_ATOMIC_EXIT_BARRIER
- : "=&r" (t)
+"1: ldarx %0,0,%2 # atomic64_inc_return_relaxed\n"
+" addic %0,%0,1\n"
+" stdcx. %0,0,%2\n"
+" bne- 1b"
+ : "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
- : "cc", "xer", "memory");
+ : "cc", "xer");
return t;
}
@@ -374,24 +402,25 @@ static __inline__ void atomic64_dec(atomic64_t *v)
: "cc", "xer");
}
-static __inline__ long atomic64_dec_return(atomic64_t *v)
+static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v)
{
long t;
__asm__ __volatile__(
- PPC_ATOMIC_ENTRY_BARRIER
-"1: ldarx %0,0,%1 # atomic64_dec_return\n\
- addic %0,%0,-1\n\
- stdcx. %0,0,%1\n\
- bne- 1b"
- PPC_ATOMIC_EXIT_BARRIER
- : "=&r" (t)
+"1: ldarx %0,0,%2 # atomic64_dec_return_relaxed\n"
+" addic %0,%0,-1\n"
+" stdcx. %0,0,%2\n"
+" bne- 1b"
+ : "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
- : "cc", "xer", "memory");
+ : "cc", "xer");
return t;
}
+#define atomic64_inc_return_relaxed atomic64_inc_return_relaxed
+#define atomic64_dec_return_relaxed atomic64_dec_return_relaxed
+
#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
@@ -420,7 +449,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
}
#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg_relaxed(v, o, n) \
+ cmpxchg_relaxed(&((v)->counter), (o), (n))
+#define atomic64_cmpxchg_acquire(v, o, n) \
+ cmpxchg_acquire(&((v)->counter), (o), (n))
+
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
/**
* atomic64_add_unless - add unless the number is a given value
diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
index 0eca6ef..c0deafc 100644
--- a/arch/powerpc/include/asm/barrier.h
+++ b/arch/powerpc/include/asm/barrier.h
@@ -34,8 +34,6 @@
#define rmb() __asm__ __volatile__ ("sync" : : : "memory")
#define wmb() __asm__ __volatile__ ("sync" : : : "memory")
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); mb(); } while (0)
-
#ifdef __SUBARCH_HAS_LWSYNC
# define SMPWMB LWSYNC
#else
@@ -46,22 +44,11 @@
#define dma_rmb() __lwsync()
#define dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
-#ifdef CONFIG_SMP
-#define smp_lwsync() __lwsync()
-
-#define smp_mb() mb()
-#define smp_rmb() __lwsync()
-#define smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
-#else
-#define smp_lwsync() barrier()
+#define __smp_lwsync() __lwsync()
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#endif /* CONFIG_SMP */
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
+#define __smp_mb() mb()
+#define __smp_rmb() __lwsync()
+#define __smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
/*
* This is a barrier which prevents following instructions from being
@@ -72,23 +59,23 @@
#define data_barrier(x) \
asm volatile("twi 0,%0,0; isync" : : "r" (x) : "memory");
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
- smp_lwsync(); \
+ __smp_lwsync(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
- smp_lwsync(); \
+ __smp_lwsync(); \
___p1; \
})
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() smp_mb()
#define smp_mb__before_spinlock() smp_mb()
+#include <asm-generic/barrier.h>
+
#endif /* _ASM_POWERPC_BARRIER_H */
diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h
new file mode 100644
index 0000000..264b754
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/32/hash.h
@@ -0,0 +1,46 @@
+#ifndef _ASM_POWERPC_BOOK3S_32_HASH_H
+#define _ASM_POWERPC_BOOK3S_32_HASH_H
+#ifdef __KERNEL__
+
+/*
+ * The "classic" 32-bit implementation of the PowerPC MMU uses a hash
+ * table containing PTEs, together with a set of 16 segment registers,
+ * to define the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings. We maintain a two-level page table tree, much
+ * like that used by the i386, for the sake of the Linux memory
+ * management code. Low-level assembler code in hash_low_32.S
+ * (procedure hash_page) is responsible for extracting ptes from the
+ * tree and putting them into the hash table when necessary, and
+ * updating the accessed and modified bits in the page table tree.
+ */
+
+#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
+#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
+#define _PAGE_USER 0x004 /* usermode access allowed */
+#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
+#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x080 /* C: page changed */
+#define _PAGE_ACCESSED 0x100 /* R: page referenced */
+#define _PAGE_RW 0x400 /* software: user write access allowed */
+#define _PAGE_SPECIAL 0x800 /* software: Special page */
+
+#ifdef CONFIG_PTE_64BIT
+/* We never clear the high word of the pte */
+#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
+#else
+#define _PTE_NONE_MASK _PAGE_HASHPTE
+#endif
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES 1
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_BOOK3S_32_HASH_H */
diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
index 16f513e..16f513e 100644
--- a/arch/powerpc/include/asm/mmu-hash32.h
+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
new file mode 100644
index 0000000..38b33dc
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -0,0 +1,482 @@
+#ifndef _ASM_POWERPC_BOOK3S_32_PGTABLE_H
+#define _ASM_POWERPC_BOOK3S_32_PGTABLE_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#include <asm/book3s/32/hash.h>
+
+/* And here we include common definitions */
+#include <asm/pte-common.h>
+
+/*
+ * The normal case is that PTEs are 32-bits and we have a 1-page
+ * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
+ *
+ * For any >32-bit physical address platform, we can use the following
+ * two level page table layout where the pgdir is 8KB and the MS 13 bits
+ * are an index to the second level table. The combined pgdir/pmd first
+ * level has 2048 entries and the second level has 512 64-bit PTE entries.
+ * -Matt
+ */
+/* PGDIR_SHIFT determines what a top-level page table entry can map */
+#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+#define PTRS_PER_PTE (1 << PTE_SHIFT)
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+/*
+ * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
+ * value (for now) on others, from where we can start layout kernel
+ * virtual space that goes below PKMAP and FIXMAP
+ */
+#ifdef CONFIG_HIGHMEM
+#define KVIRT_TOP PKMAP_BASE
+#else
+#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
+#endif
+
+/*
+ * ioremap_bot starts at that address. Early ioremaps move down from there,
+ * until mem_init() at which point this becomes the top of the vmalloc
+ * and ioremap space
+ */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK)
+#else
+#define IOREMAP_TOP KVIRT_TOP
+#endif
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 16MB value just means that there will be a 64MB "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. ;)
+ *
+ * We no longer map larger than phys RAM with the BATs so we don't have
+ * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
+ * about clashes between our early calls to ioremap() that start growing down
+ * from ioremap_base being run into the VM area allocations (growing upwards
+ * from VMALLOC_START). For this reason we have ioremap_bot to check when
+ * we actually run into our mappings setup in the early boot with the VM
+ * system. This really does become a problem for machines with good amounts
+ * of RAM. -- Cort
+ */
+#define VMALLOC_OFFSET (0x1000000) /* 16M */
+#ifdef PPC_PIN_SIZE
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#else
+#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
+#define VMALLOC_END ioremap_bot
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
+
+extern unsigned long ioremap_bot;
+
+/*
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT))
+
+#define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \
+ (unsigned long long)pte_val(e))
+#define pgd_ERROR(e) \
+ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+/*
+ * Bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+
+#define pte_clear(mm, addr, ptep) \
+ do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
+#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ *pmdp = __pmd(0);
+}
+
+
+/*
+ * When flushing the tlb entry for a page, we also need to flush the hash
+ * table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
+ */
+extern int flush_hash_pages(unsigned context, unsigned long va,
+ unsigned long pmdval, int count);
+
+/* Add an HPTE to the hash table */
+extern void add_hash_page(unsigned context, unsigned long va,
+ unsigned long pmdval);
+
+/* Flush an entry from the TLB/hash table */
+extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
+ unsigned long address);
+
+/*
+ * PTE updates. This function is called whenever an existing
+ * valid PTE is updated. This does -not- include set_pte_at()
+ * which nowadays only sets a new PTE.
+ *
+ * Depending on the type of MMU, we may need to use atomic updates
+ * and the PTE may be either 32 or 64 bit wide. In the later case,
+ * when using atomic updates, only the low part of the PTE is
+ * accessed atomically.
+ *
+ * In addition, on 44x, we also maintain a global flag indicating
+ * that an executable user mapping was modified, which is needed
+ * to properly flush the virtually tagged instruction cache of
+ * those implementations.
+ */
+#ifndef CONFIG_PTE_64BIT
+static inline unsigned long pte_update(pte_t *p,
+ unsigned long clr,
+ unsigned long set)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %0,0,%3\n\
+ andc %1,%0,%4\n\
+ or %1,%1,%5\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+
+ return old;
+}
+#else /* CONFIG_PTE_64BIT */
+static inline unsigned long long pte_update(pte_t *p,
+ unsigned long clr,
+ unsigned long set)
+{
+ unsigned long long old;
+ unsigned long tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %L0,0,%4\n\
+ lwzx %0,0,%3\n\
+ andc %1,%L0,%5\n\
+ or %1,%1,%6\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%4\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+
+ return old;
+}
+#endif /* CONFIG_PTE_64BIT */
+
+/*
+ * 2.6 calls this without flushing the TLB entry; this is wrong
+ * for our hash-based implementation, we fix that up here.
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+ old = pte_update(ptep, _PAGE_ACCESSED, 0);
+ if (old & _PAGE_HASHPTE) {
+ unsigned long ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(context, addr, ptephys, 1);
+ }
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+ __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
+}
+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 void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+{
+ unsigned long set = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+ unsigned long clr = ~pte_val(entry) & _PAGE_RO;
+
+ pte_update(ptep, clr, set);
+}
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+
+/*
+ * Note that on Book E processors, the pmd contains the kernel virtual
+ * (lowmem) address of the pte page. The physical address is less useful
+ * because everything runs with translation enabled (even the TLB miss
+ * handler). On everything else the pmd contains the physical address
+ * of the pte page. -- paulus
+ */
+#ifndef CONFIG_BOOKE
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#else
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#endif
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, addr) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
+#define pte_offset_map(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
+#define pte_unmap(pte) kunmap_atomic(pte)
+
+/*
+ * Encode and decode a swap entry.
+ * Note that the bits we use in a PTE for representing a swap entry
+ * must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used).
+ * -- paulus
+ */
+#define __swp_type(entry) ((entry).val & 0x1f)
+#define __swp_offset(entry) ((entry).val >> 5)
+#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
+
+#ifndef CONFIG_PPC_4K_PAGES
+void pgtable_cache_init(void);
+#else
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+#endif
+
+extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
+ pmd_t **pmdp);
+
+/* Generic accessors to PTE bits */
+static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);}
+static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); }
+static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); }
+static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); }
+static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
+static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
+
+static inline int pte_present(pte_t pte)
+{
+ return pte_val(pte) & _PAGE_PRESENT;
+}
+
+/* Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * Even if PTEs can be unsigned long long, a PFN is always an unsigned
+ * long for now.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+ return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) |
+ pgprot_val(pgprot));
+}
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ return pte_val(pte) >> PTE_RPN_SHIFT;
+}
+
+/* Generic modifiers for PTE bits */
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_RW);
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_RW);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SPECIAL);
+}
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+ return pte;
+}
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int percpu)
+{
+#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
+ /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
+ * helper pte_update() which does an atomic update. We need to do that
+ * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
+ * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
+ * the hash bits instead (ie, same as the non-SMP case)
+ */
+ if (percpu)
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ else
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
+
+#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+ /* Second case is 32-bit with 64-bit PTE. In this case, we
+ * can just store as long as we do the two halves in the right order
+ * with a barrier in between. This is possible because we take care,
+ * in the hash code, to pre-invalidate if the PTE was already hashed,
+ * which synchronizes us with any concurrent invalidation.
+ * In the percpu case, we also fallback to the simple update preserving
+ * the hash bits
+ */
+ if (percpu) {
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ return;
+ }
+ if (pte_val(*ptep) & _PAGE_HASHPTE)
+ flush_hash_entry(mm, ptep, addr);
+ __asm__ __volatile__("\
+ stw%U0%X0 %2,%0\n\
+ eieio\n\
+ stw%U0%X0 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+
+#elif defined(CONFIG_PPC_STD_MMU_32)
+ /* Third case is 32-bit hash table in UP mode, we need to preserve
+ * the _PAGE_HASHPTE bit since we may not have invalidated the previous
+ * translation in the hash yet (done in a subsequent flush_tlb_xxx())
+ * and see we need to keep track that this PTE needs invalidating
+ */
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+
+#else
+#error "Not supported "
+#endif
+}
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU)
+
+#define pgprot_noncached pgprot_noncached
+static inline pgprot_t pgprot_noncached(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_NO_CACHE | _PAGE_GUARDED);
+}
+
+#define pgprot_noncached_wc pgprot_noncached_wc
+static inline pgprot_t pgprot_noncached_wc(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_NO_CACHE);
+}
+
+#define pgprot_cached pgprot_cached
+static inline pgprot_t pgprot_cached(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_COHERENT);
+}
+
+#define pgprot_cached_wthru pgprot_cached_wthru
+static inline pgprot_t pgprot_cached_wthru(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_COHERENT | _PAGE_WRITETHRU);
+}
+
+#define pgprot_cached_noncoherent pgprot_cached_noncoherent
+static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot)
+{
+ return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL);
+}
+
+#define pgprot_writecombine pgprot_writecombine
+static inline pgprot_t pgprot_writecombine(pgprot_t prot)
+{
+ return pgprot_noncached_wc(prot);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_BOOK3S_32_PGTABLE_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
new file mode 100644
index 0000000..5f08a08
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -0,0 +1,102 @@
+#ifndef _ASM_POWERPC_BOOK3S_64_HASH_4K_H
+#define _ASM_POWERPC_BOOK3S_64_HASH_4K_H
+/*
+ * Entries per page directory level. The PTE level must use a 64b record
+ * for each page table entry. The PMD and PGD level use a 32b record for
+ * each entry by assuming that each entry is page aligned.
+ */
+#define PTE_INDEX_SIZE 9
+#define PMD_INDEX_SIZE 7
+#define PUD_INDEX_SIZE 9
+#define PGD_INDEX_SIZE 9
+
+#ifndef __ASSEMBLY__
+#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+#endif /* __ASSEMBLY__ */
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PMD_SHIFT
+
+/* PUD_SHIFT determines what a third-level page table entry can map */
+#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
+#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0
+/* Bits to mask out from a PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0
+/* Bits to mask out from a PGD to get to the PUD page */
+#define PGD_MASKED_BITS 0
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
+ _PAGE_F_SECOND | _PAGE_F_GIX)
+
+/* shift to put page number into pte */
+#define PTE_RPN_SHIFT (12)
+#define PTE_RPN_SIZE (45) /* gives 57-bit real addresses */
+
+#define _PAGE_4K_PFN 0
+#ifndef __ASSEMBLY__
+/*
+ * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range()
+ */
+#define remap_4k_pfn(vma, addr, pfn, prot) \
+ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
+
+#ifdef CONFIG_HUGETLB_PAGE
+/*
+ * For 4k page size, we support explicit hugepage via hugepd
+ */
+static inline int pmd_huge(pmd_t pmd)
+{
+ return 0;
+}
+
+static inline int pud_huge(pud_t pud)
+{
+ return 0;
+}
+
+static inline int pgd_huge(pgd_t pgd)
+{
+ return 0;
+}
+#define pgd_huge pgd_huge
+
+static inline int hugepd_ok(hugepd_t hpd)
+{
+ /*
+ * if it is not a pte and have hugepd shift mask
+ * set, then it is a hugepd directory pointer
+ */
+ if (!(hpd.pd & _PAGE_PTE) &&
+ ((hpd.pd & HUGEPD_SHIFT_MASK) != 0))
+ return true;
+ return false;
+}
+#define is_hugepd(hpd) (hugepd_ok(hpd))
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
new file mode 100644
index 0000000..0a7956a
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -0,0 +1,303 @@
+#ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H
+#define _ASM_POWERPC_BOOK3S_64_HASH_64K_H
+
+#define PTE_INDEX_SIZE 8
+#define PMD_INDEX_SIZE 5
+#define PUD_INDEX_SIZE 5
+#define PGD_INDEX_SIZE 12
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* PUD_SHIFT determines what a third-level page table entry can map */
+#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
+#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+#define _PAGE_COMBO 0x00001000 /* this is a combo 4k page */
+#define _PAGE_4K_PFN 0x00002000 /* PFN is for a single 4k page */
+/*
+ * Used to track subpage group valid if _PAGE_COMBO is set
+ * This overloads _PAGE_F_GIX and _PAGE_F_SECOND
+ */
+#define _PAGE_COMBO_VALID (_PAGE_F_GIX | _PAGE_F_SECOND)
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_F_SECOND | \
+ _PAGE_F_GIX | _PAGE_HASHPTE | _PAGE_COMBO)
+
+/* Shift to put page number into pte.
+ *
+ * That gives us a max RPN of 41 bits, which means a max of 57 bits
+ * of addressable physical space, or 53 bits for the special 4k PFNs.
+ */
+#define PTE_RPN_SHIFT (16)
+#define PTE_RPN_SIZE (41)
+
+/*
+ * we support 16 fragments per PTE page of 64K size.
+ */
+#define PTE_FRAG_NR 16
+/*
+ * We use a 2K PTE page fragment and another 2K for storing
+ * real_pte_t hash index
+ */
+#define PTE_FRAG_SIZE_SHIFT 12
+#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0xc0000000000000ffUL
+/* Bits to mask out from a PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0xc0000000000000ffUL
+/* Bits to mask out from a PGD to get to the PUD page */
+#define PGD_MASKED_BITS 0xc0000000000000ffUL
+
+#ifndef __ASSEMBLY__
+
+/*
+ * With 64K pages on hash table, we have a special PTE format that
+ * uses a second "half" of the page table to encode sub-page information
+ * in order to deal with 64K made of 4K HW pages. Thus we override the
+ * generic accessors and iterators here
+ */
+#define __real_pte __real_pte
+static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
+{
+ real_pte_t rpte;
+ unsigned long *hidxp;
+
+ rpte.pte = pte;
+ rpte.hidx = 0;
+ if (pte_val(pte) & _PAGE_COMBO) {
+ /*
+ * Make sure we order the hidx load against the _PAGE_COMBO
+ * check. The store side ordering is done in __hash_page_4K
+ */
+ smp_rmb();
+ hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
+ rpte.hidx = *hidxp;
+ }
+ return rpte;
+}
+
+static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
+{
+ if ((pte_val(rpte.pte) & _PAGE_COMBO))
+ return (rpte.hidx >> (index<<2)) & 0xf;
+ return (pte_val(rpte.pte) >> _PAGE_F_GIX_SHIFT) & 0xf;
+}
+
+#define __rpte_to_pte(r) ((r).pte)
+extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index);
+/*
+ * Trick: we set __end to va + 64k, which happens works for
+ * a 16M page as well as we want only one iteration
+ */
+#define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \
+ do { \
+ unsigned long __end = vpn + (1UL << (PAGE_SHIFT - VPN_SHIFT)); \
+ unsigned __split = (psize == MMU_PAGE_4K || \
+ psize == MMU_PAGE_64K_AP); \
+ shift = mmu_psize_defs[psize].shift; \
+ for (index = 0; vpn < __end; index++, \
+ vpn += (1L << (shift - VPN_SHIFT))) { \
+ if (!__split || __rpte_sub_valid(rpte, index)) \
+ do {
+
+#define pte_iterate_hashed_end() } while(0); } } while(0)
+
+#define pte_pagesize_index(mm, addr, pte) \
+ (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
+
+#define remap_4k_pfn(vma, addr, pfn, prot) \
+ (WARN_ON(((pfn) >= (1UL << PTE_RPN_SIZE))) ? -EINVAL : \
+ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
+ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))
+
+#define PTE_TABLE_SIZE PTE_FRAG_SIZE
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_TABLE_SIZE ((sizeof(pmd_t) << PMD_INDEX_SIZE) + (sizeof(unsigned long) << PMD_INDEX_SIZE))
+#else
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#endif
+#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+
+#ifdef CONFIG_HUGETLB_PAGE
+/*
+ * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have
+ * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD;
+ *
+ * Defined in such a way that we can optimize away code block at build time
+ * if CONFIG_HUGETLB_PAGE=n.
+ */
+static inline int pmd_huge(pmd_t pmd)
+{
+ /*
+ * leaf pte for huge page
+ */
+ return !!(pmd_val(pmd) & _PAGE_PTE);
+}
+
+static inline int pud_huge(pud_t pud)
+{
+ /*
+ * leaf pte for huge page
+ */
+ return !!(pud_val(pud) & _PAGE_PTE);
+}
+
+static inline int pgd_huge(pgd_t pgd)
+{
+ /*
+ * leaf pte for huge page
+ */
+ return !!(pgd_val(pgd) & _PAGE_PTE);
+}
+#define pgd_huge pgd_huge
+
+#ifdef CONFIG_DEBUG_VM
+extern int hugepd_ok(hugepd_t hpd);
+#define is_hugepd(hpd) (hugepd_ok(hpd))
+#else
+/*
+ * With 64k page size, we have hugepage ptes in the pgd and pmd entries. We don't
+ * need to setup hugepage directory for them. Our pte and page directory format
+ * enable us to have this enabled.
+ */
+static inline int hugepd_ok(hugepd_t hpd)
+{
+ return 0;
+}
+#define is_hugepd(pdep) 0
+#endif /* CONFIG_DEBUG_VM */
+
+#endif /* CONFIG_HUGETLB_PAGE */
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern unsigned long pmd_hugepage_update(struct mm_struct *mm,
+ unsigned long addr,
+ pmd_t *pmdp,
+ unsigned long clr,
+ unsigned long set);
+static inline char *get_hpte_slot_array(pmd_t *pmdp)
+{
+ /*
+ * The hpte hindex is stored in the pgtable whose address is in the
+ * second half of the PMD
+ *
+ * Order this load with the test for pmd_trans_huge in the caller
+ */
+ smp_rmb();
+ return *(char **)(pmdp + PTRS_PER_PMD);
+
+
+}
+/*
+ * The linux hugepage PMD now include the pmd entries followed by the address
+ * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits.
+ * [ 000 | 1 bit secondary | 3 bit hidx | 1 bit valid]. We use one byte per
+ * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and
+ * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t.
+ *
+ * The top three bits are intentionally left as zero. This memory location
+ * are also used as normal page PTE pointers. So if we have any pointers
+ * left around while we collapse a hugepage, we need to make sure
+ * _PAGE_PRESENT bit of that is zero when we look at them
+ */
+static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
+{
+ return hpte_slot_array[index] & 0x1;
+}
+
+static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
+ int index)
+{
+ return hpte_slot_array[index] >> 1;
+}
+
+static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
+ unsigned int index, unsigned int hidx)
+{
+ hpte_slot_array[index] = (hidx << 1) | 0x1;
+}
+
+/*
+ *
+ * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs
+ * page. The hugetlbfs page table walking and mangling paths are totally
+ * separated form the core VM paths and they're differentiated by
+ * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run.
+ *
+ * pmd_trans_huge() is defined as false at build time if
+ * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build
+ * time in such case.
+ *
+ * For ppc64 we need to differntiate from explicit hugepages from THP, because
+ * for THP we also track the subpage details at the pmd level. We don't do
+ * that for explicit huge pages.
+ *
+ */
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+ return !!((pmd_val(pmd) & (_PAGE_PTE | _PAGE_THP_HUGE)) ==
+ (_PAGE_PTE | _PAGE_THP_HUGE));
+}
+
+static inline int pmd_large(pmd_t pmd)
+{
+ return !!(pmd_val(pmd) & _PAGE_PTE);
+}
+
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+ return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT);
+}
+
+#define __HAVE_ARCH_PMD_SAME
+static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
+{
+ return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0);
+}
+
+static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pmd_t *pmdp)
+{
+ unsigned long old;
+
+ if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+ return 0;
+ old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0);
+ return ((old & _PAGE_ACCESSED) != 0);
+}
+
+#define __HAVE_ARCH_PMDP_SET_WRPROTECT
+static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp)
+{
+
+ if ((pmd_val(*pmdp) & _PAGE_RW) == 0)
+ return;
+
+ pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0);
+}
+
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
new file mode 100644
index 0000000..d0ee6fc
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -0,0 +1,561 @@
+#ifndef _ASM_POWERPC_BOOK3S_64_HASH_H
+#define _ASM_POWERPC_BOOK3S_64_HASH_H
+#ifdef __KERNEL__
+
+/*
+ * Common bits between 4K and 64K pages in a linux-style PTE.
+ * Additional bits may be defined in pgtable-hash64-*.h
+ *
+ * Note: We only support user read/write permissions. Supervisor always
+ * have full read/write to pages above PAGE_OFFSET (pages below that
+ * always use the user access permissions).
+ *
+ * We could create separate kernel read-only if we used the 3 PP bits
+ * combinations that newer processors provide but we currently don't.
+ */
+#define _PAGE_BIT_SWAP_TYPE 0
+
+#define _PAGE_EXEC 0x00001 /* execute permission */
+#define _PAGE_RW 0x00002 /* read & write access allowed */
+#define _PAGE_READ 0x00004 /* read access allowed */
+#define _PAGE_USER 0x00008 /* page may be accessed by userspace */
+#define _PAGE_GUARDED 0x00010 /* G: guarded (side-effect) page */
+/* M (memory coherence) is always set in the HPTE, so we don't need it here */
+#define _PAGE_COHERENT 0x0
+#define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x00080 /* C: page changed */
+#define _PAGE_ACCESSED 0x00100 /* R: page referenced */
+#define _PAGE_SPECIAL 0x00400 /* software: special page */
+#define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */
+
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SOFT_DIRTY 0x200 /* software: software dirty tracking */
+#else
+#define _PAGE_SOFT_DIRTY 0x000
+#endif
+
+#define _PAGE_F_GIX_SHIFT 57
+#define _PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */
+#define _PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */
+#define _PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */
+#define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */
+#define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */
+
+/*
+ * We need to differentiate between explicit huge page and THP huge
+ * page, since THP huge page also need to track real subpage details
+ */
+#define _PAGE_THP_HUGE _PAGE_4K_PFN
+
+/*
+ * set of bits not changed in pmd_modify.
+ */
+#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
+ _PAGE_ACCESSED | _PAGE_THP_HUGE | _PAGE_PTE | \
+ _PAGE_SOFT_DIRTY)
+
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/book3s/64/hash-64k.h>
+#else
+#include <asm/book3s/64/hash-4k.h>
+#endif
+
+/*
+ * Size of EA range mapped by our pagetables.
+ */
+#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+ PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
+#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1)
+#else
+#define PMD_CACHE_INDEX PMD_INDEX_SIZE
+#endif
+/*
+ * Define the address range of the kernel non-linear virtual area
+ */
+#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
+#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000)
+
+/*
+ * The vmalloc space starts at the beginning of that region, and
+ * occupies half of it on hash CPUs and a quarter of it on Book3E
+ * (we keep a quarter for the virtual memmap)
+ */
+#define VMALLOC_START KERN_VIRT_START
+#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
+#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
+
+/*
+ * Region IDs
+ */
+#define REGION_SHIFT 60UL
+#define REGION_MASK (0xfUL << REGION_SHIFT)
+#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
+
+#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
+#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
+#define VMEMMAP_REGION_ID (0xfUL) /* Server only */
+#define USER_REGION_ID (0UL)
+
+/*
+ * Defines the address of the vmemap area, in its own region on
+ * hash table CPUs.
+ */
+#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT)
+
+#ifdef CONFIG_PPC_MM_SLICES
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#endif /* CONFIG_PPC_MM_SLICES */
+
+/* No separate kernel read-only */
+#define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
+#define _PAGE_KERNEL_RO _PAGE_KERNEL_RW
+#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
+
+/* Strong Access Ordering */
+#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
+
+/* No page size encoding in the linux PTE */
+#define _PAGE_PSIZE 0
+
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY 0x8
+#define _PTEIDX_GROUP_IX 0x7
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES 1
+#define _PTE_NONE_MASK _PAGE_HPTEFLAGS
+/*
+ * The mask convered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs
+ */
+#define PTE_RPN_MASK (((1UL << PTE_RPN_SIZE) - 1) << PTE_RPN_SHIFT)
+/*
+ * _PAGE_CHG_MASK masks of bits that are to be preserved across
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
+ _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE | \
+ _PAGE_SOFT_DIRTY)
+/*
+ * Mask of bits returned by pte_pgprot()
+ */
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU | _PAGE_4K_PFN | \
+ _PAGE_USER | _PAGE_ACCESSED | \
+ _PAGE_RW | _PAGE_DIRTY | _PAGE_EXEC | \
+ _PAGE_SOFT_DIRTY)
+/*
+ * We define 2 sets of base prot bits, one for basic pages (ie,
+ * cacheable kernel and user pages) and one for non cacheable
+ * pages. We always set _PAGE_COHERENT when SMP is enabled or
+ * the processor might need it for DMA coherency.
+ */
+#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
+#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT)
+
+/* Permission masks used to generate the __P and __S table,
+ *
+ * Note:__pgprot is defined in arch/powerpc/include/asm/page.h
+ *
+ * Write permissions imply read permissions for now (we could make write-only
+ * pages on BookE but we don't bother for now). Execute permission control is
+ * possible on platforms that define _PAGE_EXEC
+ *
+ * Note due to the way vm flags are laid out, the bits are XWR
+ */
+#define PAGE_NONE __pgprot(_PAGE_BASE)
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \
+ _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER )
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER )
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_X
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY_X
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_X
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED_X
+#define __S111 PAGE_SHARED_X
+
+/* Permission masks used for kernel mappings */
+#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+ _PAGE_NO_CACHE)
+#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+ _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
+
+/* Protection used for kernel text. We want the debuggers to be able to
+ * set breakpoints anywhere, so don't write protect the kernel text
+ * on platforms where such control is possible.
+ */
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
+ defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE)
+#define PAGE_KERNEL_TEXT PAGE_KERNEL_X
+#else
+#define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX
+#endif
+
+/* Make modules code happy. We don't set RO yet */
+#define PAGE_KERNEL_EXEC PAGE_KERNEL_X
+#define PAGE_AGP (PAGE_KERNEL_NC)
+
+#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
+#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
+
+#ifndef __ASSEMBLY__
+#define pmd_bad(pmd) (pmd_val(pmd) & PMD_BAD_BITS)
+#define pmd_page_vaddr(pmd) __va(pmd_val(pmd) & ~PMD_MASKED_BITS)
+
+#define pud_bad(pud) (pud_val(pud) & PUD_BAD_BITS)
+#define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS)
+
+/* Pointers in the page table tree are physical addresses */
+#define __pgtable_ptr_val(ptr) __pa(ptr)
+
+#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
+#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1))
+#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1))
+#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1))
+
+extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned long pte, int huge);
+extern unsigned long htab_convert_pte_flags(unsigned long pteflags);
+/* Atomic PTE updates */
+static inline unsigned long pte_update(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, unsigned long clr,
+ unsigned long set,
+ int huge)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%3 # pte_update\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ andc %1,%0,%4 \n\
+ or %1,%1,%7\n\
+ stdcx. %1,0,%3 \n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set)
+ : "cc" );
+ /* huge pages use the old page table lock */
+ if (!huge)
+ assert_pte_locked(mm, addr);
+
+ if (old & _PAGE_HASHPTE)
+ hpte_need_flush(mm, addr, ptep, old, huge);
+
+ return old;
+}
+
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+
+ pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+
+ pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
+}
+
+/*
+ * We currently remove entries from the hashtable regardless of whether
+ * the entry was young or dirty. The generic routines only flush if the
+ * entry was young or dirty which is not good enough.
+ *
+ * We should be more intelligent about this but for the moment we override
+ * these functions and force a tlb flush unconditionally
+ */
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(__vma, __address, __ptep) \
+({ \
+ int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
+ __ptep); \
+ __young; \
+})
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
+ return __pte(old);
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t * ptep)
+{
+ pte_update(mm, addr, ptep, ~0UL, 0, 0);
+}
+
+
+/* Set the dirty and/or accessed bits atomically in a linux PTE, this
+ * function doesn't need to flush the hash entry
+ */
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC |
+ _PAGE_SOFT_DIRTY);
+
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%4\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ or %0,%3,%0\n\
+ stdcx. %0,0,%4\n\
+ bne- 1b"
+ :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
+ :"cc");
+}
+
+static inline int pgd_bad(pgd_t pgd)
+{
+ return (pgd_val(pgd) == 0);
+}
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+{
+ return (unsigned long)__va(pgd_val(pgd) & ~PGD_MASKED_BITS);
+}
+
+
+/* Generic accessors to PTE bits */
+static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);}
+static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); }
+static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); }
+static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); }
+static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
+static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
+
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+static inline bool pte_soft_dirty(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_SOFT_DIRTY);
+}
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_SOFT_DIRTY);
+}
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
+#ifdef CONFIG_NUMA_BALANCING
+/*
+ * These work without NUMA balancing but the kernel does not care. See the
+ * comment in include/asm-generic/pgtable.h . On powerpc, this will only
+ * work for user pages and always return true for kernel pages.
+ */
+static inline int pte_protnone(pte_t pte)
+{
+ return (pte_val(pte) &
+ (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
+}
+#endif /* CONFIG_NUMA_BALANCING */
+
+static inline int pte_present(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_PRESENT);
+}
+
+/* Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * Even if PTEs can be unsigned long long, a PFN is always an unsigned
+ * long for now.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+ return __pte((((pte_basic_t)(pfn) << PTE_RPN_SHIFT) & PTE_RPN_MASK) |
+ pgprot_val(pgprot));
+}
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ return (pte_val(pte) & PTE_RPN_MASK) >> PTE_RPN_SHIFT;
+}
+
+/* Generic modifiers for PTE bits */
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_RW);
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_RW);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SPECIAL);
+}
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+ return pte;
+}
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int percpu)
+{
+ /*
+ * Anything else just stores the PTE normally. That covers all 64-bit
+ * cases, and 32-bit non-hash with 32-bit PTEs.
+ */
+ *ptep = pte;
+}
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU)
+
+#define pgprot_noncached pgprot_noncached
+static inline pgprot_t pgprot_noncached(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_NO_CACHE | _PAGE_GUARDED);
+}
+
+#define pgprot_noncached_wc pgprot_noncached_wc
+static inline pgprot_t pgprot_noncached_wc(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_NO_CACHE);
+}
+
+#define pgprot_cached pgprot_cached
+static inline pgprot_t pgprot_cached(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_COHERENT);
+}
+
+#define pgprot_cached_wthru pgprot_cached_wthru
+static inline pgprot_t pgprot_cached_wthru(pgprot_t prot)
+{
+ return __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) |
+ _PAGE_COHERENT | _PAGE_WRITETHRU);
+}
+
+#define pgprot_cached_noncoherent pgprot_cached_noncoherent
+static inline pgprot_t pgprot_cached_noncoherent(pgprot_t prot)
+{
+ return __pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL);
+}
+
+#define pgprot_writecombine pgprot_writecombine
+static inline pgprot_t pgprot_writecombine(pgprot_t prot)
+{
+ return pgprot_noncached_wc(prot);
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, unsigned long old_pmd);
+#else
+static inline void hpte_do_hugepage_flush(struct mm_struct *mm,
+ unsigned long addr, pmd_t *pmdp,
+ unsigned long old_pmd)
+{
+ WARN(1, "%s called with THP disabled\n", __func__);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */
diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
new file mode 100644
index 0000000..0cea480
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
@@ -0,0 +1,616 @@
+#ifndef _ASM_POWERPC_MMU_HASH64_H_
+#define _ASM_POWERPC_MMU_HASH64_H_
+/*
+ * PowerPC64 memory management structures
+ *
+ * Dave Engebretsen & Mike Corrigan <{engebret|mikejc}@us.ibm.com>
+ * PPC64 rework.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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/asm-compat.h>
+#include <asm/page.h>
+#include <asm/bug.h>
+
+/*
+ * This is necessary to get the definition of PGTABLE_RANGE which we
+ * need for various slices related matters. Note that this isn't the
+ * complete pgtable.h but only a portion of it.
+ */
+#include <asm/book3s/64/pgtable.h>
+#include <asm/bug.h>
+#include <asm/processor.h>
+
+/*
+ * SLB
+ */
+
+#define SLB_NUM_BOLTED 3
+#define SLB_CACHE_ENTRIES 8
+#define SLB_MIN_SIZE 32
+
+/* Bits in the SLB ESID word */
+#define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */
+
+/* Bits in the SLB VSID word */
+#define SLB_VSID_SHIFT 12
+#define SLB_VSID_SHIFT_1T 24
+#define SLB_VSID_SSIZE_SHIFT 62
+#define SLB_VSID_B ASM_CONST(0xc000000000000000)
+#define SLB_VSID_B_256M ASM_CONST(0x0000000000000000)
+#define SLB_VSID_B_1T ASM_CONST(0x4000000000000000)
+#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
+#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
+#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
+#define SLB_VSID_L ASM_CONST(0x0000000000000100)
+#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
+#define SLB_VSID_LP ASM_CONST(0x0000000000000030)
+#define SLB_VSID_LP_00 ASM_CONST(0x0000000000000000)
+#define SLB_VSID_LP_01 ASM_CONST(0x0000000000000010)
+#define SLB_VSID_LP_10 ASM_CONST(0x0000000000000020)
+#define SLB_VSID_LP_11 ASM_CONST(0x0000000000000030)
+#define SLB_VSID_LLP (SLB_VSID_L|SLB_VSID_LP)
+
+#define SLB_VSID_KERNEL (SLB_VSID_KP)
+#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS|SLB_VSID_C)
+
+#define SLBIE_C (0x08000000)
+#define SLBIE_SSIZE_SHIFT 25
+
+/*
+ * Hash table
+ */
+
+#define HPTES_PER_GROUP 8
+
+#define HPTE_V_SSIZE_SHIFT 62
+#define HPTE_V_AVPN_SHIFT 7
+#define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80)
+#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
+#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL))
+#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)
+#define HPTE_V_LOCK ASM_CONST(0x0000000000000008)
+#define HPTE_V_LARGE ASM_CONST(0x0000000000000004)
+#define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002)
+#define HPTE_V_VALID ASM_CONST(0x0000000000000001)
+
+#define HPTE_R_PP0 ASM_CONST(0x8000000000000000)
+#define HPTE_R_TS ASM_CONST(0x4000000000000000)
+#define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000)
+#define HPTE_R_RPN_SHIFT 12
+#define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000)
+#define HPTE_R_PP ASM_CONST(0x0000000000000003)
+#define HPTE_R_N ASM_CONST(0x0000000000000004)
+#define HPTE_R_G ASM_CONST(0x0000000000000008)
+#define HPTE_R_M ASM_CONST(0x0000000000000010)
+#define HPTE_R_I ASM_CONST(0x0000000000000020)
+#define HPTE_R_W ASM_CONST(0x0000000000000040)
+#define HPTE_R_WIMG ASM_CONST(0x0000000000000078)
+#define HPTE_R_C ASM_CONST(0x0000000000000080)
+#define HPTE_R_R ASM_CONST(0x0000000000000100)
+#define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00)
+
+#define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000)
+#define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000)
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX 0 /* Supervisor read/write, User none */
+#define PP_RWRX 1 /* Supervisor read/write, User read */
+#define PP_RWRW 2 /* Supervisor read/write, User read/write */
+#define PP_RXRX 3 /* Supervisor read, User read */
+#define PP_RXXX (HPTE_R_PP0 | 2) /* Supervisor read, user none */
+
+/* Fields for tlbiel instruction in architecture 2.06 */
+#define TLBIEL_INVAL_SEL_MASK 0xc00 /* invalidation selector */
+#define TLBIEL_INVAL_PAGE 0x000 /* invalidate a single page */
+#define TLBIEL_INVAL_SET_LPID 0x800 /* invalidate a set for current LPID */
+#define TLBIEL_INVAL_SET 0xc00 /* invalidate a set for all LPIDs */
+#define TLBIEL_INVAL_SET_MASK 0xfff000 /* set number to inval. */
+#define TLBIEL_INVAL_SET_SHIFT 12
+
+#define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */
+#define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */
+#define POWER9_TLB_SETS_HASH 256 /* # sets in POWER9 TLB Hash mode */
+
+#ifndef __ASSEMBLY__
+
+struct hash_pte {
+ __be64 v;
+ __be64 r;
+};
+
+extern struct hash_pte *htab_address;
+extern unsigned long htab_size_bytes;
+extern unsigned long htab_hash_mask;
+
+/*
+ * Page size definition
+ *
+ * shift : is the "PAGE_SHIFT" value for that page size
+ * sllp : is a bit mask with the value of SLB L || LP to be or'ed
+ * directly to a slbmte "vsid" value
+ * penc : is the HPTE encoding mask for the "LP" field:
+ *
+ */
+struct mmu_psize_def
+{
+ unsigned int shift; /* number of bits */
+ int penc[MMU_PAGE_COUNT]; /* HPTE encoding */
+ unsigned int tlbiel; /* tlbiel supported for that page size */
+ unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */
+ unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */
+};
+extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+
+static inline int shift_to_mmu_psize(unsigned int shift)
+{
+ int psize;
+
+ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize)
+ if (mmu_psize_defs[psize].shift == shift)
+ return psize;
+ return -1;
+}
+
+static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
+{
+ if (mmu_psize_defs[mmu_psize].shift)
+ return mmu_psize_defs[mmu_psize].shift;
+ BUG();
+}
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Segment sizes.
+ * These are the values used by hardware in the B field of
+ * SLB entries and the first dword of MMU hashtable entries.
+ * The B field is 2 bits; the values 2 and 3 are unused and reserved.
+ */
+#define MMU_SEGSIZE_256M 0
+#define MMU_SEGSIZE_1T 1
+
+/*
+ * encode page number shift.
+ * in order to fit the 78 bit va in a 64 bit variable we shift the va by
+ * 12 bits. This enable us to address upto 76 bit va.
+ * For hpt hash from a va we can ignore the page size bits of va and for
+ * hpte encoding we ignore up to 23 bits of va. So ignoring lower 12 bits ensure
+ * we work in all cases including 4k page size.
+ */
+#define VPN_SHIFT 12
+
+/*
+ * HPTE Large Page (LP) details
+ */
+#define LP_SHIFT 12
+#define LP_BITS 8
+#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+static inline int slb_vsid_shift(int ssize)
+{
+ if (ssize == MMU_SEGSIZE_256M)
+ return SLB_VSID_SHIFT;
+ return SLB_VSID_SHIFT_1T;
+}
+
+static inline int segment_shift(int ssize)
+{
+ if (ssize == MMU_SEGSIZE_256M)
+ return SID_SHIFT;
+ return SID_SHIFT_1T;
+}
+
+/*
+ * The current system page and segment sizes
+ */
+extern int mmu_linear_psize;
+extern int mmu_virtual_psize;
+extern int mmu_vmalloc_psize;
+extern int mmu_vmemmap_psize;
+extern int mmu_io_psize;
+extern int mmu_kernel_ssize;
+extern int mmu_highuser_ssize;
+extern u16 mmu_slb_size;
+extern unsigned long tce_alloc_start, tce_alloc_end;
+
+/*
+ * If the processor supports 64k normal pages but not 64k cache
+ * inhibited pages, we have to be prepared to switch processes
+ * to use 4k pages when they create cache-inhibited mappings.
+ * If this is the case, mmu_ci_restrictions will be set to 1.
+ */
+extern int mmu_ci_restrictions;
+
+/*
+ * This computes the AVPN and B fields of the first dword of a HPTE,
+ * for use when we want to match an existing PTE. The bottom 7 bits
+ * of the returned value are zero.
+ */
+static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize,
+ int ssize)
+{
+ unsigned long v;
+ /*
+ * The AVA field omits the low-order 23 bits of the 78 bits VA.
+ * These bits are not needed in the PTE, because the
+ * low-order b of these bits are part of the byte offset
+ * into the virtual page and, if b < 23, the high-order
+ * 23-b of these bits are always used in selecting the
+ * PTEGs to be searched
+ */
+ v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm);
+ v <<= HPTE_V_AVPN_SHIFT;
+ v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
+ return v;
+}
+
+/*
+ * This function sets the AVPN and L fields of the HPTE appropriately
+ * using the base page size and actual page size.
+ */
+static inline unsigned long hpte_encode_v(unsigned long vpn, int base_psize,
+ int actual_psize, int ssize)
+{
+ unsigned long v;
+ v = hpte_encode_avpn(vpn, base_psize, ssize);
+ if (actual_psize != MMU_PAGE_4K)
+ v |= HPTE_V_LARGE;
+ return v;
+}
+
+/*
+ * This function sets the ARPN, and LP fields of the HPTE appropriately
+ * for the page size. We assume the pa is already "clean" that is properly
+ * aligned for the requested page size
+ */
+static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize,
+ int actual_psize)
+{
+ /* A 4K page needs no special encoding */
+ if (actual_psize == MMU_PAGE_4K)
+ return pa & HPTE_R_RPN;
+ else {
+ unsigned int penc = mmu_psize_defs[base_psize].penc[actual_psize];
+ unsigned int shift = mmu_psize_defs[actual_psize].shift;
+ return (pa & ~((1ul << shift) - 1)) | (penc << LP_SHIFT);
+ }
+}
+
+/*
+ * Build a VPN_SHIFT bit shifted va given VSID, EA and segment size.
+ */
+static inline unsigned long hpt_vpn(unsigned long ea,
+ unsigned long vsid, int ssize)
+{
+ unsigned long mask;
+ int s_shift = segment_shift(ssize);
+
+ mask = (1ul << (s_shift - VPN_SHIFT)) - 1;
+ return (vsid << (s_shift - VPN_SHIFT)) | ((ea >> VPN_SHIFT) & mask);
+}
+
+/*
+ * This hashes a virtual address
+ */
+static inline unsigned long hpt_hash(unsigned long vpn,
+ unsigned int shift, int ssize)
+{
+ int mask;
+ unsigned long hash, vsid;
+
+ /* VPN_SHIFT can be atmost 12 */
+ if (ssize == MMU_SEGSIZE_256M) {
+ mask = (1ul << (SID_SHIFT - VPN_SHIFT)) - 1;
+ hash = (vpn >> (SID_SHIFT - VPN_SHIFT)) ^
+ ((vpn & mask) >> (shift - VPN_SHIFT));
+ } else {
+ mask = (1ul << (SID_SHIFT_1T - VPN_SHIFT)) - 1;
+ vsid = vpn >> (SID_SHIFT_1T - VPN_SHIFT);
+ hash = vsid ^ (vsid << 25) ^
+ ((vpn & mask) >> (shift - VPN_SHIFT)) ;
+ }
+ return hash & 0x7fffffffffUL;
+}
+
+#define HPTE_LOCAL_UPDATE 0x1
+#define HPTE_NOHPTE_UPDATE 0x2
+
+extern int __hash_page_4K(unsigned long ea, unsigned long access,
+ unsigned long vsid, pte_t *ptep, unsigned long trap,
+ unsigned long flags, int ssize, int subpage_prot);
+extern int __hash_page_64K(unsigned long ea, unsigned long access,
+ unsigned long vsid, pte_t *ptep, unsigned long trap,
+ unsigned long flags, int ssize);
+struct mm_struct;
+unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
+extern int hash_page_mm(struct mm_struct *mm, unsigned long ea,
+ unsigned long access, unsigned long trap,
+ unsigned long flags);
+extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
+ unsigned long dsisr);
+int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
+ pte_t *ptep, unsigned long trap, unsigned long flags,
+ int ssize, unsigned int shift, unsigned int mmu_psize);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern int __hash_page_thp(unsigned long ea, unsigned long access,
+ unsigned long vsid, pmd_t *pmdp, unsigned long trap,
+ unsigned long flags, int ssize, unsigned int psize);
+#else
+static inline int __hash_page_thp(unsigned long ea, unsigned long access,
+ unsigned long vsid, pmd_t *pmdp,
+ unsigned long trap, unsigned long flags,
+ int ssize, unsigned int psize)
+{
+ BUG();
+ return -1;
+}
+#endif
+extern void hash_failure_debug(unsigned long ea, unsigned long access,
+ unsigned long vsid, unsigned long trap,
+ int ssize, int psize, int lpsize,
+ unsigned long pte);
+extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
+ unsigned long pstart, unsigned long prot,
+ int psize, int ssize);
+int htab_remove_mapping(unsigned long vstart, unsigned long vend,
+ int psize, int ssize);
+extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages);
+extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
+
+extern void hpte_init_native(void);
+extern void hpte_init_lpar(void);
+extern void hpte_init_beat(void);
+extern void hpte_init_beat_v3(void);
+
+extern void slb_initialize(void);
+extern void slb_flush_and_rebolt(void);
+
+extern void slb_vmalloc_update(void);
+extern void slb_set_size(u16 size);
+#endif /* __ASSEMBLY__ */
+
+/*
+ * VSID allocation (256MB segment)
+ *
+ * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
+ * from mmu context id and effective segment id of the address.
+ *
+ * For user processes max context id is limited to ((1ul << 19) - 5)
+ * for kernel space, we use the top 4 context ids to map address as below
+ * NOTE: each context only support 64TB now.
+ * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
+ * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
+ * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
+ * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
+ *
+ * The proto-VSIDs are then scrambled into real VSIDs with the
+ * multiplicative hash:
+ *
+ * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
+ *
+ * VSID_MULTIPLIER is prime, so in particular it is
+ * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
+ * Because the modulus is 2^n-1 we can compute it efficiently without
+ * a divide or extra multiply (see below). The scramble function gives
+ * robust scattering in the hash table (at least based on some initial
+ * results).
+ *
+ * We also consider VSID 0 special. We use VSID 0 for slb entries mapping
+ * bad address. This enables us to consolidate bad address handling in
+ * hash_page.
+ *
+ * We also need to avoid the last segment of the last context, because that
+ * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
+ * because of the modulo operation in vsid scramble. But the vmemmap
+ * (which is what uses region 0xf) will never be close to 64TB in size
+ * (it's 56 bytes per page of system memory).
+ */
+
+#define CONTEXT_BITS 19
+#define ESID_BITS 18
+#define ESID_BITS_1T 6
+
+/*
+ * 256MB segment
+ * The proto-VSID space has 2^(CONTEX_BITS + ESID_BITS) - 1 segments
+ * available for user + kernel mapping. The top 4 contexts are used for
+ * kernel mapping. Each segment contains 2^28 bytes. Each
+ * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
+ * (19 == 37 + 28 - 46).
+ */
+#define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 5)
+
+/*
+ * This should be computed such that protovosid * vsid_mulitplier
+ * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
+ */
+#define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
+#define VSID_BITS_256M (CONTEXT_BITS + ESID_BITS)
+#define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
+
+#define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
+#define VSID_BITS_1T (CONTEXT_BITS + ESID_BITS_1T)
+#define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
+
+
+#define USER_VSID_RANGE (1UL << (ESID_BITS + SID_SHIFT))
+
+/*
+ * This macro generates asm code to compute the VSID scramble
+ * function. Used in slb_allocate() and do_stab_bolted. The function
+ * computed is: (protovsid*VSID_MULTIPLIER) % VSID_MODULUS
+ *
+ * rt = register continaing the proto-VSID and into which the
+ * VSID will be stored
+ * rx = scratch register (clobbered)
+ *
+ * - rt and rx must be different registers
+ * - The answer will end up in the low VSID_BITS bits of rt. The higher
+ * bits may contain other garbage, so you may need to mask the
+ * result.
+ */
+#define ASM_VSID_SCRAMBLE(rt, rx, size) \
+ lis rx,VSID_MULTIPLIER_##size@h; \
+ ori rx,rx,VSID_MULTIPLIER_##size@l; \
+ mulld rt,rt,rx; /* rt = rt * MULTIPLIER */ \
+ \
+ srdi rx,rt,VSID_BITS_##size; \
+ clrldi rt,rt,(64-VSID_BITS_##size); \
+ add rt,rt,rx; /* add high and low bits */ \
+ /* NOTE: explanation based on VSID_BITS_##size = 36 \
+ * Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
+ * 2^36-1+2^28-1. That in particular means that if r3 >= \
+ * 2^36-1, then r3+1 has the 2^36 bit set. So, if r3+1 has \
+ * the bit clear, r3 already has the answer we want, if it \
+ * doesn't, the answer is the low 36 bits of r3+1. So in all \
+ * cases the answer is the low 36 bits of (r3 + ((r3+1) >> 36))*/\
+ addi rx,rt,1; \
+ srdi rx,rx,VSID_BITS_##size; /* extract 2^VSID_BITS bit */ \
+ add rt,rt,rx
+
+/* 4 bits per slice and we have one slice per 1TB */
+#define SLICE_ARRAY_SIZE (PGTABLE_RANGE >> 41)
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * For the sub-page protection option, we extend the PGD with one of
+ * these. Basically we have a 3-level tree, with the top level being
+ * the protptrs array. To optimize speed and memory consumption when
+ * only addresses < 4GB are being protected, pointers to the first
+ * four pages of sub-page protection words are stored in the low_prot
+ * array.
+ * Each page of sub-page protection words protects 1GB (4 bytes
+ * protects 64k). For the 3-level tree, each page of pointers then
+ * protects 8TB.
+ */
+struct subpage_prot_table {
+ unsigned long maxaddr; /* only addresses < this are protected */
+ unsigned int **protptrs[(TASK_SIZE_USER64 >> 43)];
+ unsigned int *low_prot[4];
+};
+
+#define SBP_L1_BITS (PAGE_SHIFT - 2)
+#define SBP_L2_BITS (PAGE_SHIFT - 3)
+#define SBP_L1_COUNT (1 << SBP_L1_BITS)
+#define SBP_L2_COUNT (1 << SBP_L2_BITS)
+#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
+#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
+
+extern void subpage_prot_free(struct mm_struct *mm);
+extern void subpage_prot_init_new_context(struct mm_struct *mm);
+#else
+static inline void subpage_prot_free(struct mm_struct *mm) {}
+static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+
+typedef unsigned long mm_context_id_t;
+struct spinlock;
+
+typedef struct {
+ mm_context_id_t id;
+ u16 user_psize; /* page size index */
+
+#ifdef CONFIG_PPC_MM_SLICES
+ u64 low_slices_psize; /* SLB page size encodings */
+ unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
+#else
+ u16 sllp; /* SLB page size encoding */
+#endif
+ unsigned long vdso_base;
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+ struct subpage_prot_table spt;
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_PPC_ICSWX
+ struct spinlock *cop_lockp; /* guard acop and cop_pid */
+ unsigned long acop; /* mask of enabled coprocessor types */
+ unsigned int cop_pid; /* pid value used with coprocessors */
+#endif /* CONFIG_PPC_ICSWX */
+#ifdef CONFIG_PPC_64K_PAGES
+ /* for 4K PTE fragment support */
+ void *pte_frag;
+#endif
+#ifdef CONFIG_SPAPR_TCE_IOMMU
+ struct list_head iommu_group_mem_list;
+#endif
+} mm_context_t;
+
+
+#if 0
+/*
+ * The code below is equivalent to this function for arguments
+ * < 2^VSID_BITS, which is all this should ever be called
+ * with. However gcc is not clever enough to compute the
+ * modulus (2^n-1) without a second multiply.
+ */
+#define vsid_scramble(protovsid, size) \
+ ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
+
+#else /* 1 */
+#define vsid_scramble(protovsid, size) \
+ ({ \
+ unsigned long x; \
+ x = (protovsid) * VSID_MULTIPLIER_##size; \
+ x = (x >> VSID_BITS_##size) + (x & VSID_MODULUS_##size); \
+ (x + ((x+1) >> VSID_BITS_##size)) & VSID_MODULUS_##size; \
+ })
+#endif /* 1 */
+
+/* Returns the segment size indicator for a user address */
+static inline int user_segment_size(unsigned long addr)
+{
+ /* Use 1T segments if possible for addresses >= 1T */
+ if (addr >= (1UL << SID_SHIFT_1T))
+ return mmu_highuser_ssize;
+ return MMU_SEGSIZE_256M;
+}
+
+static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
+ int ssize)
+{
+ /*
+ * Bad address. We return VSID 0 for that
+ */
+ if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
+ return 0;
+
+ if (ssize == MMU_SEGSIZE_256M)
+ return vsid_scramble((context << ESID_BITS)
+ | (ea >> SID_SHIFT), 256M);
+ return vsid_scramble((context << ESID_BITS_1T)
+ | (ea >> SID_SHIFT_1T), 1T);
+}
+
+/*
+ * This is only valid for addresses >= PAGE_OFFSET
+ *
+ * For kernel space, we use the top 4 context ids to map address as below
+ * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
+ * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
+ * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
+ * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
+ */
+static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
+{
+ unsigned long context;
+
+ /*
+ * kernel take the top 4 context from the available range
+ */
+ context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1;
+ return get_vsid(context, ea, ssize);
+}
+
+unsigned htab_shift_for_mem_size(unsigned long mem_size);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_MMU_HASH64_H_ */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
new file mode 100644
index 0000000..77d3ce0
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -0,0 +1,319 @@
+#ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_H_
+#define _ASM_POWERPC_BOOK3S_64_PGTABLE_H_
+/*
+ * This file contains the functions and defines necessary to modify and use
+ * the ppc64 hashed page table.
+ */
+
+#include <asm/book3s/64/hash.h>
+#include <asm/barrier.h>
+
+/*
+ * The second half of the kernel virtual space is used for IO mappings,
+ * it's itself carved into the PIO region (ISA and PHB IO space) and
+ * the ioremap space
+ *
+ * ISA_IO_BASE = KERN_IO_START, 64K reserved area
+ * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
+ * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
+ */
+#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1))
+#define FULL_IO_SIZE 0x80000000ul
+#define ISA_IO_BASE (KERN_IO_START)
+#define ISA_IO_END (KERN_IO_START + 0x10000ul)
+#define PHB_IO_BASE (ISA_IO_END)
+#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE)
+#define IOREMAP_BASE (PHB_IO_END)
+#define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE)
+
+#define vmemmap ((struct page *)VMEMMAP_BASE)
+
+/* Advertise special mapping type for AGP */
+#define HAVE_PAGE_AGP
+
+/* Advertise support for _PAGE_SPECIAL */
+#define __HAVE_ARCH_PTE_SPECIAL
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This is the default implementation of various PTE accessors, it's
+ * used in all cases except Book3S with 64K pages where we have a
+ * concept of sub-pages
+ */
+#ifndef __real_pte
+
+#define __real_pte(e,p) ((real_pte_t){(e)})
+#define __rpte_to_pte(r) ((r).pte)
+#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT)
+
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
+ do { \
+ index = 0; \
+ shift = mmu_psize_defs[psize].shift; \
+
+#define pte_iterate_hashed_end() } while(0)
+
+/*
+ * We expect this to be called only for user addresses or kernel virtual
+ * addresses other than the linear mapping.
+ */
+#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K
+
+#endif /* __real_pte */
+
+static inline void pmd_set(pmd_t *pmdp, unsigned long val)
+{
+ *pmdp = __pmd(val);
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ *pmdp = __pmd(0);
+}
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_present(pmd) (!pmd_none(pmd))
+
+static inline void pud_set(pud_t *pudp, unsigned long val)
+{
+ *pudp = __pud(val);
+}
+
+static inline void pud_clear(pud_t *pudp)
+{
+ *pudp = __pud(0);
+}
+
+#define pud_none(pud) (!pud_val(pud))
+#define pud_present(pud) (pud_val(pud) != 0)
+
+extern struct page *pud_page(pud_t pud);
+extern struct page *pmd_page(pmd_t pmd);
+static inline pte_t pud_pte(pud_t pud)
+{
+ return __pte(pud_val(pud));
+}
+
+static inline pud_t pte_pud(pte_t pte)
+{
+ return __pud(pte_val(pte));
+}
+#define pud_write(pud) pte_write(pud_pte(pud))
+#define pgd_write(pgd) pte_write(pgd_pte(pgd))
+static inline void pgd_set(pgd_t *pgdp, unsigned long val)
+{
+ *pgdp = __pgd(val);
+}
+
+static inline void pgd_clear(pgd_t *pgdp)
+{
+ *pgdp = __pgd(0);
+}
+
+#define pgd_none(pgd) (!pgd_val(pgd))
+#define pgd_present(pgd) (!pgd_none(pgd))
+
+static inline pte_t pgd_pte(pgd_t pgd)
+{
+ return __pte(pgd_val(pgd));
+}
+
+static inline pgd_t pte_pgd(pte_t pte)
+{
+ return __pgd(pte_val(pte));
+}
+
+extern struct page *pgd_page(pgd_t pgd);
+
+/*
+ * Find an entry in a page-table-directory. We combine the address region
+ * (the high order N bits) and the pgd portion of the address.
+ */
+
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+#define pud_offset(pgdp, addr) \
+ (((pud_t *) pgd_page_vaddr(*(pgdp))) + pud_index(addr))
+#define pmd_offset(pudp,addr) \
+ (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr))
+#define pte_offset_kernel(dir,addr) \
+ (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr))
+
+#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_unmap(pte) do { } while(0)
+
+/* to find an entry in a kernel page-table-directory */
+/* This now only contains the vmalloc pages */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+ pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pud_ERROR(e) \
+ pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+#define pgd_ERROR(e) \
+ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/* Encode and de-code a swap entry */
+#define MAX_SWAPFILES_CHECK() do { \
+ BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \
+ /* \
+ * Don't have overlapping bits with _PAGE_HPTEFLAGS \
+ * We filter HPTEFLAGS on set_pte. \
+ */ \
+ BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \
+ BUILD_BUG_ON(_PAGE_HPTEFLAGS & _PAGE_SWP_SOFT_DIRTY); \
+ } while (0)
+/*
+ * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT;
+ */
+#define SWP_TYPE_BITS 5
+#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \
+ & ((1UL << SWP_TYPE_BITS) - 1))
+#define __swp_offset(x) (((x).val & PTE_RPN_MASK) >> PTE_RPN_SHIFT)
+#define __swp_entry(type, offset) ((swp_entry_t) { \
+ ((type) << _PAGE_BIT_SWAP_TYPE) \
+ | (((offset) << PTE_RPN_SHIFT) & PTE_RPN_MASK)})
+/*
+ * swp_entry_t must be independent of pte bits. We build a swp_entry_t from
+ * swap type and offset we get from swap and convert that to pte to find a
+ * matching pte in linux page table.
+ * Clear bits not found in swap entries here.
+ */
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) & ~_PAGE_PTE })
+#define __swp_entry_to_pte(x) __pte((x).val | _PAGE_PTE)
+
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SWP_SOFT_DIRTY (1UL << (SWP_TYPE_BITS + _PAGE_BIT_SWAP_TYPE))
+#else
+#define _PAGE_SWP_SOFT_DIRTY 0UL
+#endif /* CONFIG_MEM_SOFT_DIRTY */
+
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
+}
+static inline bool pte_swp_soft_dirty(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_SWP_SOFT_DIRTY);
+}
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_SWP_SOFT_DIRTY);
+}
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
+void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
+void pgtable_cache_init(void);
+
+struct page *realmode_pfn_to_page(unsigned long pfn);
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
+extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
+extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
+extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd);
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd);
+extern int has_transparent_hugepage(void);
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+
+static inline pte_t pmd_pte(pmd_t pmd)
+{
+ return __pte(pmd_val(pmd));
+}
+
+static inline pmd_t pte_pmd(pte_t pte)
+{
+ return __pmd(pte_val(pte));
+}
+
+static inline pte_t *pmdp_ptep(pmd_t *pmd)
+{
+ return (pte_t *)pmd;
+}
+
+#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
+#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
+#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
+#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
+#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+#define pmd_soft_dirty(pmd) pte_soft_dirty(pmd_pte(pmd))
+#define pmd_mksoft_dirty(pmd) pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)))
+#define pmd_clear_soft_dirty(pmd) pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)))
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
+#ifdef CONFIG_NUMA_BALANCING
+static inline int pmd_protnone(pmd_t pmd)
+{
+ return pte_protnone(pmd_pte(pmd));
+}
+#endif /* CONFIG_NUMA_BALANCING */
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd) pte_write(pmd_pte(pmd))
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+ return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_THP_HUGE));
+}
+
+#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+extern int pmdp_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp,
+ pmd_t entry, int dirty);
+
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+extern int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp);
+#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
+extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
+extern pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pmd_t *pmdp);
+
+extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp);
+#define pmdp_collapse_flush pmdp_collapse_flush
+
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable);
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_INVALIDATE
+extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE
+extern void pmdp_huge_split_prepare(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp);
+
+#define pmd_move_must_withdraw pmd_move_must_withdraw
+struct spinlock;
+static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
+ struct spinlock *old_pmd_ptl)
+{
+ /*
+ * Archs like ppc64 use pgtable to store per pmd
+ * specific information. So when we switch the pmd,
+ * we should also withdraw and deposit the pgtable
+ */
+ return true;
+}
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
new file mode 100644
index 0000000..1b753f9
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -0,0 +1,94 @@
+#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
+#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H
+
+#define MMU_NO_CONTEXT 0
+
+/*
+ * TLB flushing for 64-bit hash-MMU CPUs
+ */
+
+#include <linux/percpu.h>
+#include <asm/page.h>
+
+#define PPC64_TLB_BATCH_NR 192
+
+struct ppc64_tlb_batch {
+ int active;
+ unsigned long index;
+ struct mm_struct *mm;
+ real_pte_t pte[PPC64_TLB_BATCH_NR];
+ unsigned long vpn[PPC64_TLB_BATCH_NR];
+ unsigned int psize;
+ int ssize;
+};
+DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+
+extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
+
+#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+
+static inline void arch_enter_lazy_mmu_mode(void)
+{
+ struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
+
+ batch->active = 1;
+}
+
+static inline void arch_leave_lazy_mmu_mode(void)
+{
+ struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
+
+ if (batch->index)
+ __flush_tlb_pending(batch);
+ batch->active = 0;
+}
+
+#define arch_flush_lazy_mmu_mode() do {} while (0)
+
+
+extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
+ int ssize, unsigned long flags);
+extern void flush_hash_range(unsigned long number, int local);
+extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
+ pmd_t *pmdp, unsigned int psize, int ssize,
+ unsigned long flags);
+
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
+{
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+}
+
+static inline void local_flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+}
+
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start,
+ unsigned long end)
+{
+}
+
+/* Private function for use by PCI IO mapping code */
+extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr);
+#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h
new file mode 100644
index 0000000..8b0f4a2
--- /dev/null
+++ b/arch/powerpc/include/asm/book3s/pgtable.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_POWERPC_BOOK3S_PGTABLE_H
+#define _ASM_POWERPC_BOOK3S_PGTABLE_H
+
+#ifdef CONFIG_PPC64
+#include <asm/book3s/64/pgtable.h>
+#else
+#include <asm/book3s/32/pgtable.h>
+#endif
+
+#define FIRST_USER_ADDRESS 0UL
+#ifndef __ASSEMBLY__
+/* Insert a PTE, top-level function is out of line. It uses an inline
+ * low level function in the respective pgtable-* files
+ */
+extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte);
+
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty);
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 5f8229e..ffbafbf 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -69,6 +69,25 @@ extern void _set_L3CR(unsigned long);
#define _set_L3CR(val) do { } while(0)
#endif
+static inline void dcbz(void *addr)
+{
+ __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory");
+}
+
+static inline void dcbi(void *addr)
+{
+ __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory");
+}
+
+static inline void dcbf(void *addr)
+{
+ __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory");
+}
+
+static inline void dcbst(void *addr)
+{
+ __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory");
+}
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_CACHE_H */
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h
index 6229e6b..69fb16d 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page);
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-extern void __flush_disable_L1(void);
-
extern void flush_icache_range(unsigned long, unsigned long);
extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr,
@@ -47,12 +45,58 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr)
}
#endif
-extern void flush_dcache_range(unsigned long start, unsigned long stop);
#ifdef CONFIG_PPC32
-extern void clean_dcache_range(unsigned long start, unsigned long stop);
-extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ */
+static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
+ unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+ unsigned long i;
+
+ for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+ dcbf(addr);
+ mb(); /* sync */
+}
+
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ */
+static inline void clean_dcache_range(unsigned long start, unsigned long stop)
+{
+ void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
+ unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+ unsigned long i;
+
+ for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+ dcbst(addr);
+ mb(); /* sync */
+}
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ */
+static inline void invalidate_dcache_range(unsigned long start,
+ unsigned long stop)
+{
+ void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
+ unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+ unsigned long i;
+
+ for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+ dcbi(addr);
+ mb(); /* sync */
+}
+
#endif /* CONFIG_PPC32 */
#ifdef CONFIG_PPC64
+extern void flush_dcache_range(unsigned long start, unsigned long stop);
extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
#endif
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index e8d9ef4..ee655ed 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -9,30 +9,9 @@
* 2 of the License, or (at your option) any later version.
*/
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries. ihl is the number
- * of 32-bit words and is always >= 5.
- */
#ifdef CONFIG_GENERIC_CSUM
#include <asm-generic/checksum.h>
#else
-extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- * 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
- */
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
/*
* Computes the checksum of a memory block at src, length len,
* and adds in "sum" (32-bit), while copying the block to dst.
@@ -47,21 +26,12 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst,
int len, __wsum sum,
int *src_err, int *dst_err);
-#ifdef __powerpc64__
#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum, int *err_ptr);
#define HAVE_CSUM_COPY_USER
extern __wsum csum_and_copy_to_user(const void *src, void __user *dst,
int len, __wsum sum, int *err_ptr);
-#else
-/*
- * the same as csum_partial, but copies from src to dst while it
- * checksums.
- */
-#define csum_partial_copy_from_user(src, dst, len, sum, errp) \
- csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL)
-#endif
#define csum_partial_copy_nocheck(src, dst, len, sum) \
csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)
@@ -83,15 +53,6 @@ static inline __sum16 csum_fold(__wsum sum)
return (__force __sum16)(~((__force u32)sum + tmp) >> 16);
}
-/*
- * 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));
-}
-
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
@@ -135,17 +96,117 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
{
#ifdef __powerpc64__
u64 res = (__force u64)csum;
+#endif
+ if (__builtin_constant_p(csum) && csum == 0)
+ return addend;
+ if (__builtin_constant_p(addend) && addend == 0)
+ return csum;
+#ifdef __powerpc64__
res += (__force u64)addend;
return (__force __wsum)((u32)res + (res >> 32));
#else
asm("addc %0,%0,%1;"
"addze %0,%0;"
- : "+r" (csum) : "r" (addend));
+ : "+r" (csum) : "r" (addend) : "xer");
return csum;
#endif
}
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries. ihl is the number
+ * of 32-bit words and is always >= 5.
+ */
+static inline __wsum ip_fast_csum_nofold(const void *iph, unsigned int ihl)
+{
+ const u32 *ptr = (const u32 *)iph + 1;
+#ifdef __powerpc64__
+ unsigned int i;
+ u64 s = *(const u32 *)iph;
+
+ for (i = 0; i < ihl - 1; i++, ptr++)
+ s += *ptr;
+ s += (s >> 32);
+ return (__force __wsum)s;
+#else
+ __wsum sum, tmp;
+
+ asm("mtctr %3;"
+ "addc %0,%4,%5;"
+ "1: lwzu %1, 4(%2);"
+ "adde %0,%0,%1;"
+ "bdnz 1b;"
+ "addze %0,%0;"
+ : "=r" (sum), "=r" (tmp), "+b" (ptr)
+ : "r" (ihl - 2), "r" (*(const u32 *)iph), "r" (*ptr)
+ : "ctr", "xer", "memory");
+
+ return sum;
+#endif
+}
+
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ return csum_fold(ip_fast_csum_nofold(iph, ihl));
+}
+
+/*
+ * 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);
+
+static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
+{
+ if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) {
+ if (len == 2)
+ sum = csum_add(sum, (__force __wsum)*(const u16 *)buff);
+ if (len >= 4)
+ sum = csum_add(sum, (__force __wsum)*(const u32 *)buff);
+ if (len == 6)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u16 *)(buff + 4));
+ if (len >= 8)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u32 *)(buff + 4));
+ if (len == 10)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u16 *)(buff + 8));
+ if (len >= 12)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u32 *)(buff + 8));
+ if (len == 14)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u16 *)(buff + 12));
+ if (len >= 16)
+ sum = csum_add(sum, (__force __wsum)
+ *(const u32 *)(buff + 12));
+ } else if (__builtin_constant_p(len) && (len & 3) == 0) {
+ sum = csum_add(sum, ip_fast_csum_nofold(buff, len >> 2));
+ } else {
+ sum = __csum_partial(buff, len, sum);
+ }
+ return 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));
+}
+
#endif
#endif /* __KERNEL__ */
#endif
diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h
index ad6263c..44efe73 100644
--- a/arch/powerpc/include/asm/cmpxchg.h
+++ b/arch/powerpc/include/asm/cmpxchg.h
@@ -5,25 +5,25 @@
#include <linux/compiler.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
+#include <linux/bug.h>
/*
* Atomic exchange
*
- * Changes the memory location '*ptr' to be val and returns
+ * Changes the memory location '*p' to be val and returns
* the previous value stored there.
*/
+
static __always_inline unsigned long
-__xchg_u32(volatile void *p, unsigned long val)
+__xchg_u32_local(volatile void *p, unsigned long val)
{
unsigned long prev;
__asm__ __volatile__(
- PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stwcx. %3,0,%2 \n\
bne- 1b"
- PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -31,42 +31,34 @@ __xchg_u32(volatile void *p, unsigned long val)
return prev;
}
-/*
- * Atomic exchange
- *
- * Changes the memory location '*ptr' to be val and returns
- * the previous value stored there.
- */
static __always_inline unsigned long
-__xchg_u32_local(volatile void *p, unsigned long val)
+__xchg_u32_relaxed(u32 *p, unsigned long val)
{
unsigned long prev;
__asm__ __volatile__(
-"1: lwarx %0,0,%2 \n"
- PPC405_ERR77(0,%2)
-" stwcx. %3,0,%2 \n\
- bne- 1b"
- : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
+"1: lwarx %0,0,%2\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %3,0,%2\n"
+" bne- 1b"
+ : "=&r" (prev), "+m" (*p)
: "r" (p), "r" (val)
- : "cc", "memory");
+ : "cc");
return prev;
}
#ifdef CONFIG_PPC64
static __always_inline unsigned long
-__xchg_u64(volatile void *p, unsigned long val)
+__xchg_u64_local(volatile void *p, unsigned long val)
{
unsigned long prev;
__asm__ __volatile__(
- PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stdcx. %3,0,%2 \n\
bne- 1b"
- PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -75,64 +67,52 @@ __xchg_u64(volatile void *p, unsigned long val)
}
static __always_inline unsigned long
-__xchg_u64_local(volatile void *p, unsigned long val)
+__xchg_u64_relaxed(u64 *p, unsigned long val)
{
unsigned long prev;
__asm__ __volatile__(
-"1: ldarx %0,0,%2 \n"
- PPC405_ERR77(0,%2)
-" stdcx. %3,0,%2 \n\
- bne- 1b"
- : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
+"1: ldarx %0,0,%2\n"
+ PPC405_ERR77(0, %2)
+" stdcx. %3,0,%2\n"
+" bne- 1b"
+ : "=&r" (prev), "+m" (*p)
: "r" (p), "r" (val)
- : "cc", "memory");
+ : "cc");
return prev;
}
#endif
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid xchg().
- */
-extern void __xchg_called_with_bad_pointer(void);
-
static __always_inline unsigned long
-__xchg(volatile void *ptr, unsigned long x, unsigned int size)
+__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
{
switch (size) {
case 4:
- return __xchg_u32(ptr, x);
+ return __xchg_u32_local(ptr, x);
#ifdef CONFIG_PPC64
case 8:
- return __xchg_u64(ptr, x);
+ return __xchg_u64_local(ptr, x);
#endif
}
- __xchg_called_with_bad_pointer();
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg");
return x;
}
static __always_inline unsigned long
-__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
+__xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
{
switch (size) {
case 4:
- return __xchg_u32_local(ptr, x);
+ return __xchg_u32_relaxed(ptr, x);
#ifdef CONFIG_PPC64
case 8:
- return __xchg_u64_local(ptr, x);
+ return __xchg_u64_relaxed(ptr, x);
#endif
}
- __xchg_called_with_bad_pointer();
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local");
return x;
}
-#define xchg(ptr,x) \
- ({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
- })
-
#define xchg_local(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
@@ -140,6 +120,12 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
(unsigned long)_x_, sizeof(*(ptr))); \
})
+#define xchg_relaxed(ptr, x) \
+({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_relaxed((ptr), \
+ (unsigned long)_x_, sizeof(*(ptr))); \
+})
/*
* Compare and exchange - if *p == old, set it to new,
* and return the old value of *p.
@@ -151,14 +137,14 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
unsigned int prev;
__asm__ __volatile__ (
- PPC_RELEASE_BARRIER
+ PPC_ATOMIC_ENTRY_BARRIER
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
cmpw 0,%0,%3\n\
bne- 2f\n"
PPC405_ERR77(0,%2)
" stwcx. %4,0,%2\n\
bne- 1b"
- PPC_ACQUIRE_BARRIER
+ PPC_ATOMIC_EXIT_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
@@ -190,6 +176,56 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
return prev;
}
+static __always_inline unsigned long
+__cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n"
+" cmpw 0,%0,%3\n"
+" bne- 2f\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %4,0,%2\n"
+" bne- 1b\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc");
+
+ return prev;
+}
+
+/*
+ * cmpxchg family don't have order guarantee if cmp part fails, therefore we
+ * can avoid superfluous barriers if we use assembly code to implement
+ * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
+ * cmpxchg_release() because that will result in putting a barrier in the
+ * middle of a ll/sc loop, which is probably a bad idea. For example, this
+ * might cause the conditional store more likely to fail.
+ */
+static __always_inline unsigned long
+__cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n"
+" cmpw 0,%0,%3\n"
+" bne- 2f\n"
+ PPC405_ERR77(0, %2)
+" stwcx. %4,0,%2\n"
+" bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+ "\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
+
#ifdef CONFIG_PPC64
static __always_inline unsigned long
__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -197,13 +233,13 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
unsigned long prev;
__asm__ __volatile__ (
- PPC_RELEASE_BARRIER
+ PPC_ATOMIC_ENTRY_BARRIER
"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
cmpd 0,%0,%3\n\
bne- 2f\n\
stdcx. %4,0,%2\n\
bne- 1b"
- PPC_ACQUIRE_BARRIER
+ PPC_ATOMIC_EXIT_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
@@ -233,11 +269,47 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
return prev;
}
-#endif
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid cmpxchg(). */
-extern void __cmpxchg_called_with_bad_pointer(void);
+static __always_inline unsigned long
+__cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: ldarx %0,0,%2 # __cmpxchg_u64_relaxed\n"
+" cmpd 0,%0,%3\n"
+" bne- 2f\n"
+" stdcx. %4,0,%2\n"
+" bne- 1b\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc");
+
+ return prev;
+}
+
+static __always_inline unsigned long
+__cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: ldarx %0,0,%2 # __cmpxchg_u64_acquire\n"
+" cmpd 0,%0,%3\n"
+" bne- 2f\n"
+" stdcx. %4,0,%2\n"
+" bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+ "\n"
+"2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
+#endif
static __always_inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
@@ -251,7 +323,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
return __cmpxchg_u64(ptr, old, new);
#endif
}
- __cmpxchg_called_with_bad_pointer();
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg");
return old;
}
@@ -267,10 +339,41 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
return __cmpxchg_u64_local(ptr, old, new);
#endif
}
- __cmpxchg_called_with_bad_pointer();
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local");
+ return old;
+}
+
+static __always_inline unsigned long
+__cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_relaxed(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64_relaxed(ptr, old, new);
+#endif
+ }
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed");
return old;
}
+static __always_inline unsigned long
+__cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_acquire(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64_acquire(ptr, old, new);
+#endif
+ }
+ BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
+ return old;
+}
#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
@@ -288,6 +391,23 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
(unsigned long)_n_, sizeof(*(ptr))); \
})
+#define cmpxchg_relaxed(ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \
+ (unsigned long)_o_, (unsigned long)_n_, \
+ sizeof(*(ptr))); \
+})
+
+#define cmpxchg_acquire(ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \
+ (unsigned long)_o_, (unsigned long)_n_, \
+ sizeof(*(ptr))); \
+})
#ifdef CONFIG_PPC64
#define cmpxchg64(ptr, o, n) \
({ \
@@ -299,7 +419,16 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg_local((ptr), (o), (n)); \
})
-#define cmpxchg64_relaxed cmpxchg64_local
+#define cmpxchg64_relaxed(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_relaxed((ptr), (o), (n)); \
+})
+#define cmpxchg64_acquire(ptr, o, n) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_acquire((ptr), (o), (n)); \
+})
#else
#include <asm-generic/cmpxchg-local.h>
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 840a550..994c60a 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -99,4 +99,25 @@ static inline unsigned long ppc_global_function_entry(void *func)
#endif
}
+#ifdef CONFIG_PPC64
+/*
+ * Some instruction encodings commonly used in dynamic ftracing
+ * and function live patching.
+ */
+
+/* This must match the definition of STK_GOT in <asm/ppc_asm.h> */
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define R2_STACK_OFFSET 24
+#else
+#define R2_STACK_OFFSET 40
+#endif
+
+#define PPC_INST_LD_TOC (PPC_INST_LD | ___PPC_RT(__REG_R2) | \
+ ___PPC_RA(__REG_R1) | R2_STACK_OFFSET)
+
+/* usually preceded by a mflr r0 */
+#define PPC_INST_STD_LR (PPC_INST_STD | ___PPC_RS(__REG_R0) | \
+ ___PPC_RA(__REG_R1) | PPC_LR_STKOFF)
+#endif /* CONFIG_PPC64 */
+
#endif /* _ASM_POWERPC_CODE_PATCHING_H */
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index 4398a6c..2c5c5b4 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
+#include <soc/fsl/qe/qe.h>
/*
* SPI Parameter RAM common to QE and CPM.
@@ -155,49 +156,6 @@ typedef struct cpm_buf_desc {
*/
#define BD_I2C_START (0x0400)
-int cpm_muram_init(void);
-
-#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE)
-unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
-int cpm_muram_free(unsigned long offset);
-unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
-void __iomem *cpm_muram_addr(unsigned long offset);
-unsigned long cpm_muram_offset(void __iomem *addr);
-dma_addr_t cpm_muram_dma(void __iomem *addr);
-#else
-static inline unsigned long cpm_muram_alloc(unsigned long size,
- unsigned long align)
-{
- return -ENOSYS;
-}
-
-static inline int cpm_muram_free(unsigned long offset)
-{
- return -ENOSYS;
-}
-
-static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset,
- unsigned long size)
-{
- return -ENOSYS;
-}
-
-static inline void __iomem *cpm_muram_addr(unsigned long offset)
-{
- return NULL;
-}
-
-static inline unsigned long cpm_muram_offset(void __iomem *addr)
-{
- return -ENOSYS;
-}
-
-static inline dma_addr_t cpm_muram_dma(void __iomem *addr)
-{
- return 0;
-}
-#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */
-
#ifdef CONFIG_CPM
int cpm_command(u32 command, u8 opcode);
#else
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index b118072..df4fb5f 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -43,6 +43,11 @@ extern int machine_check_e500(struct pt_regs *regs);
extern int machine_check_e200(struct pt_regs *regs);
extern int machine_check_47x(struct pt_regs *regs);
+extern void cpu_down_flush_e500v2(void);
+extern void cpu_down_flush_e500mc(void);
+extern void cpu_down_flush_e5500(void);
+extern void cpu_down_flush_e6500(void);
+
/* NOTE WELL: Update identify_cpu() if fields are added or removed! */
struct cpu_spec {
/* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -59,6 +64,9 @@ struct cpu_spec {
unsigned int icache_bsize;
unsigned int dcache_bsize;
+ /* flush caches inside the current cpu */
+ void (*cpu_down_flush)(void);
+
/* number of performance monitor counters */
unsigned int num_pmcs;
enum powerpc_pmc_type pmc_type;
@@ -171,7 +179,7 @@ enum {
#define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000)
#define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000)
#define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000)
-/* Free LONG_ASM_CONST(0x0000001000000000) */
+#define CPU_FTR_ARCH_300 LONG_ASM_CONST(0x0000001000000000)
#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000)
#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000)
#define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000)
@@ -196,6 +204,7 @@ enum {
#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000)
#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000)
#define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000)
+#define CPU_FTR_SUBCORE LONG_ASM_CONST(0x2000000000000000)
#ifndef __ASSEMBLY__
@@ -443,9 +452,19 @@ enum {
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
- CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
+ CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_SUBCORE)
#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
+#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
+ CPU_FTR_MMCRA | CPU_FTR_SMT | \
+ CPU_FTR_COHERENT_ICACHE | \
+ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
+ CPU_FTR_DSCR | CPU_FTR_SAO | \
+ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
+ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
+ CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -464,7 +483,7 @@ enum {
(CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \
- CPU_FTRS_PA6T | CPU_FTR_VSX)
+ CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9)
#endif
#else
enum {
@@ -515,7 +534,8 @@ enum {
(CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \
CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \
- CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE)
+ CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & \
+ CPU_FTRS_POWER9)
#endif
#else
enum {
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h
index ba42e46..666bef4e 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -1,6 +1,7 @@
#ifndef _ASM_POWERPC_CPUTHREADS_H
#define _ASM_POWERPC_CPUTHREADS_H
+#ifndef __ASSEMBLY__
#include <linux/cpumask.h>
/*
@@ -94,7 +95,21 @@ static inline int cpu_last_thread_sibling(int cpu)
return cpu | (threads_per_core - 1);
}
+static inline u32 get_tensr(void)
+{
+#ifdef CONFIG_BOOKE
+ if (cpu_has_feature(CPU_FTR_SMT))
+ return mfspr(SPRN_TENSR);
+#endif
+ return 1;
+}
+
+void book3e_start_thread(int thread, unsigned long addr);
+void book3e_stop_thread(int thread);
+
+#endif /* __ASSEMBLY__ */
+#define INVALID_THREAD_HWID 0x0fff
#endif /* _ASM_POWERPC_CPUTHREADS_H */
diff --git a/arch/powerpc/include/asm/disassemble.h b/arch/powerpc/include/asm/disassemble.h
index 6330a61..4852e84 100644
--- a/arch/powerpc/include/asm/disassemble.h
+++ b/arch/powerpc/include/asm/disassemble.h
@@ -42,6 +42,11 @@ static inline unsigned int get_dcrn(u32 inst)
return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
}
+static inline unsigned int get_tmrn(u32 inst)
+{
+ return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
+}
+
static inline unsigned int get_rt(u32 inst)
{
return (inst >> 21) & 0x1f;
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 7f522c0..77816ac 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -125,8 +125,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
#define HAVE_ARCH_DMA_SET_MASK 1
extern int dma_set_mask(struct device *dev, u64 dma_mask);
-#include <asm-generic/dma-mapping-common.h>
-
extern int __dma_set_mask(struct device *dev, u64 dma_mask);
extern u64 __dma_get_required_mask(struct device *dev);
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index c5eb86f..fb9f376 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -72,6 +72,7 @@ struct pci_dn;
#define EEH_PE_PHB (1 << 1) /* PHB PE */
#define EEH_PE_DEVICE (1 << 2) /* Device PE */
#define EEH_PE_BUS (1 << 3) /* Bus PE */
+#define EEH_PE_VF (1 << 4) /* VF PE */
#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */
@@ -81,6 +82,7 @@ struct pci_dn;
#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */
#define EEH_PE_REMOVED (1 << 10) /* Removed permanently */
+#define EEH_PE_PRI_BUS (1 << 11) /* Cached primary bus */
struct eeh_pe {
int type; /* PE type: PHB/Bus/Device */
@@ -135,11 +137,15 @@ struct eeh_dev {
int pcix_cap; /* Saved PCIx capability */
int pcie_cap; /* Saved PCIe capability */
int aer_cap; /* Saved AER capability */
+ int af_cap; /* Saved AF capability */
struct eeh_pe *pe; /* Associated PE */
struct list_head list; /* Form link list in the PE */
+ struct list_head rmv_list; /* Record the removed edevs */
struct pci_controller *phb; /* Associated PHB */
struct pci_dn *pdn; /* Associated PCI device node */
struct pci_dev *pdev; /* Associated PCI device */
+ bool in_error; /* Error flag for edev */
+ struct pci_dev *physfn; /* Associated SRIOV PF */
struct pci_bus *bus; /* PCI bus for partial hotplug */
};
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index a8b52b6..a703452 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -69,13 +69,14 @@
#define EX_TLB_ESR ( 9 * 8) /* Level 0 and 2 only */
#define EX_TLB_SRR0 (10 * 8)
#define EX_TLB_SRR1 (11 * 8)
+#define EX_TLB_R7 (12 * 8)
#ifdef CONFIG_BOOK3E_MMU_TLB_STATS
-#define EX_TLB_R8 (12 * 8)
-#define EX_TLB_R9 (13 * 8)
-#define EX_TLB_LR (14 * 8)
-#define EX_TLB_SIZE (15 * 8)
+#define EX_TLB_R8 (13 * 8)
+#define EX_TLB_R9 (14 * 8)
+#define EX_TLB_LR (15 * 8)
+#define EX_TLB_SIZE (16 * 8)
#else
-#define EX_TLB_SIZE (12 * 8)
+#define EX_TLB_SIZE (13 * 8)
#endif
#define START_EXCEPTION(label) \
@@ -204,8 +205,8 @@ exc_##label##_book3e:
#endif
#define SET_IVOR(vector_number, vector_offset) \
- li r3,vector_offset@l; \
- ori r3,r3,interrupt_base_book3e@l; \
+ LOAD_REG_ADDR(r3,interrupt_base_book3e);\
+ ori r3,r3,vector_offset@l; \
mtspr SPRN_IVOR##vector_number,r3;
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 77f52b2..93ae809 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -130,15 +130,6 @@ BEGIN_FTR_SECTION_NESTED(941) \
END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
/*
- * Increase the priority on systems where PPR save/restore is not
- * implemented/ supported.
- */
-#define HMT_MEDIUM_PPR_DISCARD \
-BEGIN_FTR_SECTION_NESTED(942) \
- HMT_MEDIUM; \
-END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,942) /*non P7*/
-
-/*
* Get an SPR into a register if the CPU has the given feature
*/
#define OPT_GET_SPR(ra, spr, ftr) \
@@ -263,17 +254,6 @@ do_kvm_##n: \
#define KVM_HANDLER_SKIP(area, h, n)
#endif
-#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
-#define KVMTEST_PR(n) __KVMTEST(n)
-#define KVM_HANDLER_PR(area, h, n) __KVM_HANDLER(area, h, n)
-#define KVM_HANDLER_PR_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n)
-
-#else
-#define KVMTEST_PR(n)
-#define KVM_HANDLER_PR(area, h, n)
-#define KVM_HANDLER_PR_SKIP(area, h, n)
-#endif
-
#define NOTEST(n)
/*
@@ -353,27 +333,25 @@ do_kvm_##n: \
/*
* Exception vectors.
*/
-#define STD_EXCEPTION_PSERIES(loc, vec, label) \
- . = loc; \
+#define STD_EXCEPTION_PSERIES(vec, label) \
+ . = vec; \
.globl label##_pSeries; \
label##_pSeries: \
- HMT_MEDIUM_PPR_DISCARD; \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
- EXC_STD, KVMTEST_PR, vec)
+ EXC_STD, KVMTEST, vec)
/* Version of above for when we have to branch out-of-line */
#define STD_EXCEPTION_PSERIES_OOL(vec, label) \
.globl label##_pSeries; \
label##_pSeries: \
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \
EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD)
#define STD_EXCEPTION_HV(loc, vec, label) \
. = loc; \
.globl label##_hv; \
label##_hv: \
- HMT_MEDIUM_PPR_DISCARD; \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
EXC_HV, KVMTEST, vec)
@@ -389,7 +367,6 @@ label##_hv: \
. = loc; \
.globl label##_relon_pSeries; \
label##_relon_pSeries: \
- HMT_MEDIUM_PPR_DISCARD; \
/* No guest interrupts come through here */ \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
@@ -405,7 +382,6 @@ label##_relon_pSeries: \
. = loc; \
.globl label##_relon_hv; \
label##_relon_hv: \
- HMT_MEDIUM_PPR_DISCARD; \
/* No guest interrupts come through here */ \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
@@ -436,17 +412,13 @@ label##_relon_hv: \
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
#define SOFTEN_TEST_PR(vec) \
- KVMTEST_PR(vec); \
+ KVMTEST(vec); \
_SOFTEN_TEST(EXC_STD, vec)
#define SOFTEN_TEST_HV(vec) \
KVMTEST(vec); \
_SOFTEN_TEST(EXC_HV, vec)
-#define SOFTEN_TEST_HV_201(vec) \
- KVMTEST(vec); \
- _SOFTEN_TEST(EXC_STD, vec)
-
#define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec)
#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec)
@@ -463,7 +435,6 @@ label##_relon_hv: \
. = loc; \
.globl label##_pSeries; \
label##_pSeries: \
- HMT_MEDIUM_PPR_DISCARD; \
_MASKABLE_EXCEPTION_PSERIES(vec, label, \
EXC_STD, SOFTEN_TEST_PR)
@@ -481,7 +452,6 @@ label##_hv: \
EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV);
#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
- HMT_MEDIUM_PPR_DISCARD; \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_0(PACA_EXGEN); \
__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
index 493e72f..b4407d0 100644
--- a/arch/powerpc/include/asm/fadump.h
+++ b/arch/powerpc/include/asm/fadump.h
@@ -191,7 +191,7 @@ struct fadump_crash_info_header {
u64 elfcorehdr_addr;
u32 crashing_cpu;
struct pt_regs regs;
- struct cpumask cpu_online_mask;
+ struct cpumask online_mask;
};
/* Crash memory ranges */
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index e05808a..b062924 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -47,12 +47,10 @@
#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
#define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000)
-#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000)
#define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000)
#define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000)
#define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
#define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000)
-#define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000)
#ifndef __ASSEMBLY__
@@ -70,8 +68,7 @@ enum {
FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN,
FW_FEATURE_PSERIES_ALWAYS = 0,
- FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 |
- FW_FEATURE_OPALv3,
+ FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h
deleted file mode 100644
index 43b6bb1..0000000
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * Freecale 85xx and 86xx Global Utilties register set
- *
- * Authors: Jeff Brown
- * Timur Tabi <timur@freescale.com>
- *
- * Copyright 2004,2007,2012 Freescale Semiconductor, Inc
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef __ASM_POWERPC_FSL_GUTS_H__
-#define __ASM_POWERPC_FSL_GUTS_H__
-#ifdef __KERNEL__
-
-/**
- * Global Utility Registers.
- *
- * Not all registers defined in this structure are available on all chips, so
- * you are expected to know whether a given register actually exists on your
- * chip before you access it.
- *
- * Also, some registers are similar on different chips but have slightly
- * different names. In these cases, one name is chosen to avoid extraneous
- * #ifdefs.
- */
-struct ccsr_guts {
- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
- u8 res018[0x20 - 0x18];
- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */
- u8 res024[0x30 - 0x24];
- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */
- u8 res034[0x40 - 0x34];
- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
- u8 res044[0x50 - 0x44];
- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
- u8 res054[0x60 - 0x54];
- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
- u8 res06c[0x70 - 0x6c];
- __be32 devdisr; /* 0x.0070 - Device Disable Control */
-#define CCSR_GUTS_DEVDISR_TB1 0x00001000
-#define CCSR_GUTS_DEVDISR_TB0 0x00004000
- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
- u8 res078[0x7c - 0x78];
- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */
- __be32 autorstsr; /* 0x.009c - Automatic reset status register */
- __be32 pvr; /* 0x.00a0 - Processor Version Register */
- __be32 svr; /* 0x.00a4 - System Version Register */
- u8 res0a8[0xb0 - 0xa8];
- __be32 rstcr; /* 0x.00b0 - Reset Control Register */
- u8 res0b4[0xc0 - 0xb4];
- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register
- Called 'elbcvselcr' on 86xx SOCs */
- u8 res0c4[0x100 - 0xc4];
- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
- There are 16 registers */
- u8 res140[0x224 - 0x140];
- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
- u8 res22c[0x604 - 0x22c];
- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
- u8 res608[0x800 - 0x608];
- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
- u8 res804[0x900 - 0x804];
- __be32 ircr; /* 0x.0900 - Infrared Control Register */
- u8 res904[0x908 - 0x904];
- __be32 dmacr; /* 0x.0908 - DMA Control Register */
- u8 res90c[0x914 - 0x90c];
- __be32 elbccr; /* 0x.0914 - eLBC Control Register */
- u8 res918[0xb20 - 0x918];
- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
- u8 resb2c[0xe00 - 0xb2c];
- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
- u8 rese04[0xe10 - 0xe04];
- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
- u8 rese14[0xe20 - 0xe14];
- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
- u8 rese28[0xf04 - 0xe28];
- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
- u8 resf0c[0xf2c - 0xf0c];
- __be32 itcr; /* 0x.0f2c - Internal transaction control register */
- u8 resf30[0xf40 - 0xf30];
- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
-} __attribute__ ((packed));
-
-
-/* Alternate function signal multiplex control */
-#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
-
-#ifdef CONFIG_PPC_86xx
-
-#define CCSR_GUTS_DMACR_DEV_SSI 0 /* DMA controller/channel set to SSI */
-#define CCSR_GUTS_DMACR_DEV_IR 1 /* DMA controller/channel set to IR */
-
-/*
- * Set the DMACR register in the GUTS
- *
- * The DMACR register determines the source of initiated transfers for each
- * channel on each DMA controller. Rather than have a bunch of repetitive
- * macros for the bit patterns, we just have a function that calculates
- * them.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
- */
-static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
- unsigned int co, unsigned int ch, unsigned int device)
-{
- unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
-
- clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift);
-}
-
-#define CCSR_GUTS_PMUXCR_LDPSEL 0x00010000
-#define CCSR_GUTS_PMUXCR_SSI1_MASK 0x0000C000 /* Bitmask for SSI1 */
-#define CCSR_GUTS_PMUXCR_SSI1_LA 0x00000000 /* Latched address */
-#define CCSR_GUTS_PMUXCR_SSI1_HI 0x00004000 /* High impedance */
-#define CCSR_GUTS_PMUXCR_SSI1_SSI 0x00008000 /* Used for SSI1 */
-#define CCSR_GUTS_PMUXCR_SSI2_MASK 0x00003000 /* Bitmask for SSI2 */
-#define CCSR_GUTS_PMUXCR_SSI2_LA 0x00000000 /* Latched address */
-#define CCSR_GUTS_PMUXCR_SSI2_HI 0x00001000 /* High impedance */
-#define CCSR_GUTS_PMUXCR_SSI2_SSI 0x00002000 /* Used for SSI2 */
-#define CCSR_GUTS_PMUXCR_LA_22_25_LA 0x00000000 /* Latched Address */
-#define CCSR_GUTS_PMUXCR_LA_22_25_HI 0x00000400 /* High impedance */
-#define CCSR_GUTS_PMUXCR_DBGDRV 0x00000200 /* Signals not driven */
-#define CCSR_GUTS_PMUXCR_DMA2_0 0x00000008
-#define CCSR_GUTS_PMUXCR_DMA2_3 0x00000004
-#define CCSR_GUTS_PMUXCR_DMA1_0 0x00000002
-#define CCSR_GUTS_PMUXCR_DMA1_3 0x00000001
-
-/*
- * Set the DMA external control bits in the GUTS
- *
- * The DMA external control bits in the PMUXCR are only meaningful for
- * channels 0 and 3. Any other channels are ignored.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * value: the new value for the bit (0 or 1)
- */
-static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
- unsigned int co, unsigned int ch, unsigned int value)
-{
- if ((ch == 0) || (ch == 3)) {
- unsigned int shift = 2 * (co + 1) - (ch & 1) - 1;
-
- clrsetbits_be32(&guts->pmuxcr, 1 << shift, value << shift);
- }
-}
-
-#define CCSR_GUTS_CLKDVDR_PXCKEN 0x80000000
-#define CCSR_GUTS_CLKDVDR_SSICKEN 0x20000000
-#define CCSR_GUTS_CLKDVDR_PXCKINV 0x10000000
-#define CCSR_GUTS_CLKDVDR_PXCKDLY_SHIFT 25
-#define CCSR_GUTS_CLKDVDR_PXCKDLY_MASK 0x06000000
-#define CCSR_GUTS_CLKDVDR_PXCKDLY(x) \
- (((x) & 3) << CCSR_GUTS_CLKDVDR_PXCKDLY_SHIFT)
-#define CCSR_GUTS_CLKDVDR_PXCLK_SHIFT 16
-#define CCSR_GUTS_CLKDVDR_PXCLK_MASK 0x001F0000
-#define CCSR_GUTS_CLKDVDR_PXCLK(x) (((x) & 31) << CCSR_GUTS_CLKDVDR_PXCLK_SHIFT)
-#define CCSR_GUTS_CLKDVDR_SSICLK_MASK 0x000000FF
-#define CCSR_GUTS_CLKDVDR_SSICLK(x) ((x) & CCSR_GUTS_CLKDVDR_SSICLK_MASK)
-
-#endif
-
-#endif
-#endif
diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h
new file mode 100644
index 0000000..47df55e
--- /dev/null
+++ b/arch/powerpc/include/asm/fsl_pm.h
@@ -0,0 +1,51 @@
+/*
+ * Support Power Management
+ *
+ * Copyright 2014-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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef __PPC_FSL_PM_H
+#define __PPC_FSL_PM_H
+
+#define E500_PM_PH10 1
+#define E500_PM_PH15 2
+#define E500_PM_PH20 3
+#define E500_PM_PH30 4
+#define E500_PM_DOZE E500_PM_PH10
+#define E500_PM_NAP E500_PM_PH15
+
+#define PLAT_PM_SLEEP 20
+#define PLAT_PM_LPM20 30
+
+#define FSL_PM_SLEEP (1 << 0)
+#define FSL_PM_DEEP_SLEEP (1 << 1)
+
+struct fsl_pm_ops {
+ /* mask pending interrupts to the RCPM from MPIC */
+ void (*irq_mask)(int cpu);
+
+ /* unmask pending interrupts to the RCPM from MPIC */
+ void (*irq_unmask)(int cpu);
+ void (*cpu_enter_state)(int cpu, int state);
+ void (*cpu_exit_state)(int cpu, int state);
+ void (*cpu_up_prepare)(int cpu);
+ void (*cpu_die)(int cpu);
+ int (*plat_enter_sleep)(void);
+ void (*freeze_time_base)(bool freeze);
+
+ /* keep the power of IP blocks during sleep/deep sleep */
+ void (*set_ip_power)(bool enable, u32 mask);
+
+ /* get platform supported power management modes */
+ unsigned int (*get_pm_modes)(void);
+};
+
+extern const struct fsl_pm_ops *qoriq_pm_ops;
+
+int __init fsl_rcpm_init(void);
+
+#endif /* __PPC_FSL_PM_H */
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index ef89b14..50ca758 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -46,6 +46,8 @@
extern void _mcount(void);
#ifdef CONFIG_DYNAMIC_FTRACE
+# define FTRACE_ADDR ((unsigned long)ftrace_caller)
+# define FTRACE_REGS_ADDR FTRACE_ADDR
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
/* reloction of mcount call site is the same as the address */
@@ -58,6 +60,9 @@ struct dyn_arch_ftrace {
#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* __ASSEMBLY__ */
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+#define ARCH_SUPPORTS_FTRACE_OPS 1
+#endif
#endif
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__)
diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/powerpc/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index caaf6e0..01c2c23b 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -84,19 +84,6 @@ static inline void *kmap_atomic(struct page *page)
return kmap_atomic_prot(page, kmap_prot);
}
-static inline struct page *kmap_atomic_to_page(void *ptr)
-{
- unsigned long idx, vaddr = (unsigned long) ptr;
- pte_t *pte;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- idx = virt_to_fix(vaddr);
- pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
- return pte_page(*pte);
-}
-
#define flush_cache_kmaps() flush_cache_all()
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 7eac89b..42814f0 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -19,7 +19,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd)
* We have only four bits to encode, MMU page size
*/
BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
- return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK);
+ return __va(hpd.pd & HUGEPD_ADDR_MASK);
}
static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 85bc8c0..0bc9c28 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -94,6 +94,7 @@
#define H_SG_LIST -72
#define H_OP_MODE -73
#define H_COP_HW -74
+#define H_STATE -75
#define H_UNSUPPORTED_FLAG_START -256
#define H_UNSUPPORTED_FLAG_END -511
#define H_MULTI_THREADS_ACTIVE -9005
@@ -258,11 +259,16 @@
#define H_DEL_CONN 0x288
#define H_JOIN 0x298
#define H_VASI_STATE 0x2A4
+#define H_VIOCTL 0x2A8
#define H_ENABLE_CRQ 0x2B0
#define H_GET_EM_PARMS 0x2B8
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
+#define H_REG_SUB_CRQ 0x2DC
#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
+#define H_FREE_SUB_CRQ 0x2E0
+#define H_SEND_SUB_CRQ 0x2E4
+#define H_SEND_SUB_CRQ_INDIRECT 0x2E8
#define H_BEST_ENERGY 0x2F4
#define H_XIRR_X 0x2FC
#define H_RANDOM 0x300
@@ -271,6 +277,21 @@
#define H_SET_MODE 0x31C
#define MAX_HCALL_OPCODE H_SET_MODE
+/* H_VIOCTL functions */
+#define H_GET_VIOA_DUMP_SIZE 0x01
+#define H_GET_VIOA_DUMP 0x02
+#define H_GET_ILLAN_NUM_VLAN_IDS 0x03
+#define H_GET_ILLAN_VLAN_ID_LIST 0x04
+#define H_GET_ILLAN_SWITCH_ID 0x05
+#define H_DISABLE_MIGRATION 0x06
+#define H_ENABLE_MIGRATION 0x07
+#define H_GET_PARTNER_INFO 0x08
+#define H_GET_PARTNER_WWPN_LIST 0x09
+#define H_DISABLE_ALL_VIO_INTS 0x0A
+#define H_DISABLE_VIO_INTERRUPT 0x0B
+#define H_ENABLE_VIO_INTERRUPT 0x0C
+
+
/* Platform specific hcalls, used by KVM */
#define H_RTAS 0xf000
diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h
index 1cb39c9..b3b0f2d 100644
--- a/arch/powerpc/include/asm/hydra.h
+++ b/arch/powerpc/include/asm/hydra.h
@@ -89,7 +89,7 @@ extern volatile struct Hydra __iomem *Hydra;
#define HYDRA_INT_EXT2 13 /* PCI IRQX */
#define HYDRA_INT_EXT3 14 /* PCI IRQY */
#define HYDRA_INT_EXT4 15 /* PCI IRQZ */
-#define HYDRA_INT_EXT5 16 /* IDE Primay/Secondary */
+#define HYDRA_INT_EXT5 16 /* IDE Primary/Secondary */
#define HYDRA_INT_EXT6 17 /* IDE Secondary */
#define HYDRA_INT_EXT7 18 /* Power Off Request */
#define HYDRA_INT_SPARE 19
diff --git a/arch/powerpc/include/asm/icswx.h b/arch/powerpc/include/asm/icswx.h
index 9f8402b..27e588f 100644
--- a/arch/powerpc/include/asm/icswx.h
+++ b/arch/powerpc/include/asm/icswx.h
@@ -164,6 +164,7 @@ struct coprocessor_request_block {
#define ICSWX_INITIATED (0x8)
#define ICSWX_BUSY (0x4)
#define ICSWX_REJECTED (0x2)
+#define ICSWX_XERS0 (0x1) /* undefined or set from XERSO. */
static inline int icswx(__be32 ccw, struct coprocessor_request_block *crb)
{
diff --git a/arch/powerpc/include/asm/immap_qe.h b/arch/powerpc/include/asm/immap_qe.h
deleted file mode 100644
index bedbff8..0000000
--- a/arch/powerpc/include/asm/immap_qe.h
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * QUICC Engine (QE) Internal Memory Map.
- * The Internal Memory Map for devices with QE on them. This
- * is the superset of all QE devices (8360, etc.).
-
- * Copyright (C) 2006. Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@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.
- */
-#ifndef _ASM_POWERPC_IMMAP_QE_H
-#define _ASM_POWERPC_IMMAP_QE_H
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-#include <asm/io.h>
-
-#define QE_IMMAP_SIZE (1024 * 1024) /* 1MB from 1MB+IMMR */
-
-/* QE I-RAM */
-struct qe_iram {
- __be32 iadd; /* I-RAM Address Register */
- __be32 idata; /* I-RAM Data Register */
- u8 res0[0x04];
- __be32 iready; /* I-RAM Ready Register */
- u8 res1[0x70];
-} __attribute__ ((packed));
-
-/* QE Interrupt Controller */
-struct qe_ic_regs {
- __be32 qicr;
- __be32 qivec;
- __be32 qripnr;
- __be32 qipnr;
- __be32 qipxcc;
- __be32 qipycc;
- __be32 qipwcc;
- __be32 qipzcc;
- __be32 qimr;
- __be32 qrimr;
- __be32 qicnr;
- u8 res0[0x4];
- __be32 qiprta;
- __be32 qiprtb;
- u8 res1[0x4];
- __be32 qricr;
- u8 res2[0x20];
- __be32 qhivec;
- u8 res3[0x1C];
-} __attribute__ ((packed));
-
-/* Communications Processor */
-struct cp_qe {
- __be32 cecr; /* QE command register */
- __be32 ceccr; /* QE controller configuration register */
- __be32 cecdr; /* QE command data register */
- u8 res0[0xA];
- __be16 ceter; /* QE timer event register */
- u8 res1[0x2];
- __be16 cetmr; /* QE timers mask register */
- __be32 cetscr; /* QE time-stamp timer control register */
- __be32 cetsr1; /* QE time-stamp register 1 */
- __be32 cetsr2; /* QE time-stamp register 2 */
- u8 res2[0x8];
- __be32 cevter; /* QE virtual tasks event register */
- __be32 cevtmr; /* QE virtual tasks mask register */
- __be16 cercr; /* QE RAM control register */
- u8 res3[0x2];
- u8 res4[0x24];
- __be16 ceexe1; /* QE external request 1 event register */
- u8 res5[0x2];
- __be16 ceexm1; /* QE external request 1 mask register */
- u8 res6[0x2];
- __be16 ceexe2; /* QE external request 2 event register */
- u8 res7[0x2];
- __be16 ceexm2; /* QE external request 2 mask register */
- u8 res8[0x2];
- __be16 ceexe3; /* QE external request 3 event register */
- u8 res9[0x2];
- __be16 ceexm3; /* QE external request 3 mask register */
- u8 res10[0x2];
- __be16 ceexe4; /* QE external request 4 event register */
- u8 res11[0x2];
- __be16 ceexm4; /* QE external request 4 mask register */
- u8 res12[0x3A];
- __be32 ceurnr; /* QE microcode revision number register */
- u8 res13[0x244];
-} __attribute__ ((packed));
-
-/* QE Multiplexer */
-struct qe_mux {
- __be32 cmxgcr; /* CMX general clock route register */
- __be32 cmxsi1cr_l; /* CMX SI1 clock route low register */
- __be32 cmxsi1cr_h; /* CMX SI1 clock route high register */
- __be32 cmxsi1syr; /* CMX SI1 SYNC route register */
- __be32 cmxucr[4]; /* CMX UCCx clock route registers */
- __be32 cmxupcr; /* CMX UPC clock route register */
- u8 res0[0x1C];
-} __attribute__ ((packed));
-
-/* QE Timers */
-struct qe_timers {
- u8 gtcfr1; /* Timer 1 and Timer 2 global config register*/
- u8 res0[0x3];
- u8 gtcfr2; /* Timer 3 and timer 4 global config register*/
- u8 res1[0xB];
- __be16 gtmdr1; /* Timer 1 mode register */
- __be16 gtmdr2; /* Timer 2 mode register */
- __be16 gtrfr1; /* Timer 1 reference register */
- __be16 gtrfr2; /* Timer 2 reference register */
- __be16 gtcpr1; /* Timer 1 capture register */
- __be16 gtcpr2; /* Timer 2 capture register */
- __be16 gtcnr1; /* Timer 1 counter */
- __be16 gtcnr2; /* Timer 2 counter */
- __be16 gtmdr3; /* Timer 3 mode register */
- __be16 gtmdr4; /* Timer 4 mode register */
- __be16 gtrfr3; /* Timer 3 reference register */
- __be16 gtrfr4; /* Timer 4 reference register */
- __be16 gtcpr3; /* Timer 3 capture register */
- __be16 gtcpr4; /* Timer 4 capture register */
- __be16 gtcnr3; /* Timer 3 counter */
- __be16 gtcnr4; /* Timer 4 counter */
- __be16 gtevr1; /* Timer 1 event register */
- __be16 gtevr2; /* Timer 2 event register */
- __be16 gtevr3; /* Timer 3 event register */
- __be16 gtevr4; /* Timer 4 event register */
- __be16 gtps; /* Timer 1 prescale register */
- u8 res2[0x46];
-} __attribute__ ((packed));
-
-/* BRG */
-struct qe_brg {
- __be32 brgc[16]; /* BRG configuration registers */
- u8 res0[0x40];
-} __attribute__ ((packed));
-
-/* SPI */
-struct spi {
- u8 res0[0x20];
- __be32 spmode; /* SPI mode register */
- u8 res1[0x2];
- u8 spie; /* SPI event register */
- u8 res2[0x1];
- u8 res3[0x2];
- u8 spim; /* SPI mask register */
- u8 res4[0x1];
- u8 res5[0x1];
- u8 spcom; /* SPI command register */
- u8 res6[0x2];
- __be32 spitd; /* SPI transmit data register (cpu mode) */
- __be32 spird; /* SPI receive data register (cpu mode) */
- u8 res7[0x8];
-} __attribute__ ((packed));
-
-/* SI */
-struct si1 {
- __be16 siamr1; /* SI1 TDMA mode register */
- __be16 sibmr1; /* SI1 TDMB mode register */
- __be16 sicmr1; /* SI1 TDMC mode register */
- __be16 sidmr1; /* SI1 TDMD mode register */
- u8 siglmr1_h; /* SI1 global mode register high */
- u8 res0[0x1];
- u8 sicmdr1_h; /* SI1 command register high */
- u8 res2[0x1];
- u8 sistr1_h; /* SI1 status register high */
- u8 res3[0x1];
- __be16 sirsr1_h; /* SI1 RAM shadow address register high */
- u8 sitarc1; /* SI1 RAM counter Tx TDMA */
- u8 sitbrc1; /* SI1 RAM counter Tx TDMB */
- u8 sitcrc1; /* SI1 RAM counter Tx TDMC */
- u8 sitdrc1; /* SI1 RAM counter Tx TDMD */
- u8 sirarc1; /* SI1 RAM counter Rx TDMA */
- u8 sirbrc1; /* SI1 RAM counter Rx TDMB */
- u8 sircrc1; /* SI1 RAM counter Rx TDMC */
- u8 sirdrc1; /* SI1 RAM counter Rx TDMD */
- u8 res4[0x8];
- __be16 siemr1; /* SI1 TDME mode register 16 bits */
- __be16 sifmr1; /* SI1 TDMF mode register 16 bits */
- __be16 sigmr1; /* SI1 TDMG mode register 16 bits */
- __be16 sihmr1; /* SI1 TDMH mode register 16 bits */
- u8 siglmg1_l; /* SI1 global mode register low 8 bits */
- u8 res5[0x1];
- u8 sicmdr1_l; /* SI1 command register low 8 bits */
- u8 res6[0x1];
- u8 sistr1_l; /* SI1 status register low 8 bits */
- u8 res7[0x1];
- __be16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits*/
- u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */
- u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */
- u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */
- u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */
- u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */
- u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */
- u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */
- u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */
- u8 res8[0x8];
- __be32 siml1; /* SI1 multiframe limit register */
- u8 siedm1; /* SI1 extended diagnostic mode register */
- u8 res9[0xBB];
-} __attribute__ ((packed));
-
-/* SI Routing Tables */
-struct sir {
- u8 tx[0x400];
- u8 rx[0x400];
- u8 res0[0x800];
-} __attribute__ ((packed));
-
-/* USB Controller */
-struct qe_usb_ctlr {
- u8 usb_usmod;
- u8 usb_usadr;
- u8 usb_uscom;
- u8 res1[1];
- __be16 usb_usep[4];
- u8 res2[4];
- __be16 usb_usber;
- u8 res3[2];
- __be16 usb_usbmr;
- u8 res4[1];
- u8 usb_usbs;
- __be16 usb_ussft;
- u8 res5[2];
- __be16 usb_usfrn;
- u8 res6[0x22];
-} __attribute__ ((packed));
-
-/* MCC */
-struct qe_mcc {
- __be32 mcce; /* MCC event register */
- __be32 mccm; /* MCC mask register */
- __be32 mccf; /* MCC configuration register */
- __be32 merl; /* MCC emergency request level register */
- u8 res0[0xF0];
-} __attribute__ ((packed));
-
-/* QE UCC Slow */
-struct ucc_slow {
- __be32 gumr_l; /* UCCx general mode register (low) */
- __be32 gumr_h; /* UCCx general mode register (high) */
- __be16 upsmr; /* UCCx protocol-specific mode register */
- u8 res0[0x2];
- __be16 utodr; /* UCCx transmit on demand register */
- __be16 udsr; /* UCCx data synchronization register */
- __be16 ucce; /* UCCx event register */
- u8 res1[0x2];
- __be16 uccm; /* UCCx mask register */
- u8 res2[0x1];
- u8 uccs; /* UCCx status register */
- u8 res3[0x24];
- __be16 utpt;
- u8 res4[0x52];
- u8 guemr; /* UCC general extended mode register */
-} __attribute__ ((packed));
-
-/* QE UCC Fast */
-struct ucc_fast {
- __be32 gumr; /* UCCx general mode register */
- __be32 upsmr; /* UCCx protocol-specific mode register */
- __be16 utodr; /* UCCx transmit on demand register */
- u8 res0[0x2];
- __be16 udsr; /* UCCx data synchronization register */
- u8 res1[0x2];
- __be32 ucce; /* UCCx event register */
- __be32 uccm; /* UCCx mask register */
- u8 uccs; /* UCCx status register */
- u8 res2[0x7];
- __be32 urfb; /* UCC receive FIFO base */
- __be16 urfs; /* UCC receive FIFO size */
- u8 res3[0x2];
- __be16 urfet; /* UCC receive FIFO emergency threshold */
- __be16 urfset; /* UCC receive FIFO special emergency
- threshold */
- __be32 utfb; /* UCC transmit FIFO base */
- __be16 utfs; /* UCC transmit FIFO size */
- u8 res4[0x2];
- __be16 utfet; /* UCC transmit FIFO emergency threshold */
- u8 res5[0x2];
- __be16 utftt; /* UCC transmit FIFO transmit threshold */
- u8 res6[0x2];
- __be16 utpt; /* UCC transmit polling timer */
- u8 res7[0x2];
- __be32 urtry; /* UCC retry counter register */
- u8 res8[0x4C];
- u8 guemr; /* UCC general extended mode register */
-} __attribute__ ((packed));
-
-struct ucc {
- union {
- struct ucc_slow slow;
- struct ucc_fast fast;
- u8 res[0x200]; /* UCC blocks are 512 bytes each */
- };
-} __attribute__ ((packed));
-
-/* MultiPHY UTOPIA POS Controllers (UPC) */
-struct upc {
- __be32 upgcr; /* UTOPIA/POS general configuration register */
- __be32 uplpa; /* UTOPIA/POS last PHY address */
- __be32 uphec; /* ATM HEC register */
- __be32 upuc; /* UTOPIA/POS UCC configuration */
- __be32 updc1; /* UTOPIA/POS device 1 configuration */
- __be32 updc2; /* UTOPIA/POS device 2 configuration */
- __be32 updc3; /* UTOPIA/POS device 3 configuration */
- __be32 updc4; /* UTOPIA/POS device 4 configuration */
- __be32 upstpa; /* UTOPIA/POS STPA threshold */
- u8 res0[0xC];
- __be32 updrs1_h; /* UTOPIA/POS device 1 rate select */
- __be32 updrs1_l; /* UTOPIA/POS device 1 rate select */
- __be32 updrs2_h; /* UTOPIA/POS device 2 rate select */
- __be32 updrs2_l; /* UTOPIA/POS device 2 rate select */
- __be32 updrs3_h; /* UTOPIA/POS device 3 rate select */
- __be32 updrs3_l; /* UTOPIA/POS device 3 rate select */
- __be32 updrs4_h; /* UTOPIA/POS device 4 rate select */
- __be32 updrs4_l; /* UTOPIA/POS device 4 rate select */
- __be32 updrp1; /* UTOPIA/POS device 1 receive priority low */
- __be32 updrp2; /* UTOPIA/POS device 2 receive priority low */
- __be32 updrp3; /* UTOPIA/POS device 3 receive priority low */
- __be32 updrp4; /* UTOPIA/POS device 4 receive priority low */
- __be32 upde1; /* UTOPIA/POS device 1 event */
- __be32 upde2; /* UTOPIA/POS device 2 event */
- __be32 upde3; /* UTOPIA/POS device 3 event */
- __be32 upde4; /* UTOPIA/POS device 4 event */
- __be16 uprp1;
- __be16 uprp2;
- __be16 uprp3;
- __be16 uprp4;
- u8 res1[0x8];
- __be16 uptirr1_0; /* Device 1 transmit internal rate 0 */
- __be16 uptirr1_1; /* Device 1 transmit internal rate 1 */
- __be16 uptirr1_2; /* Device 1 transmit internal rate 2 */
- __be16 uptirr1_3; /* Device 1 transmit internal rate 3 */
- __be16 uptirr2_0; /* Device 2 transmit internal rate 0 */
- __be16 uptirr2_1; /* Device 2 transmit internal rate 1 */
- __be16 uptirr2_2; /* Device 2 transmit internal rate 2 */
- __be16 uptirr2_3; /* Device 2 transmit internal rate 3 */
- __be16 uptirr3_0; /* Device 3 transmit internal rate 0 */
- __be16 uptirr3_1; /* Device 3 transmit internal rate 1 */
- __be16 uptirr3_2; /* Device 3 transmit internal rate 2 */
- __be16 uptirr3_3; /* Device 3 transmit internal rate 3 */
- __be16 uptirr4_0; /* Device 4 transmit internal rate 0 */
- __be16 uptirr4_1; /* Device 4 transmit internal rate 1 */
- __be16 uptirr4_2; /* Device 4 transmit internal rate 2 */
- __be16 uptirr4_3; /* Device 4 transmit internal rate 3 */
- __be32 uper1; /* Device 1 port enable register */
- __be32 uper2; /* Device 2 port enable register */
- __be32 uper3; /* Device 3 port enable register */
- __be32 uper4; /* Device 4 port enable register */
- u8 res2[0x150];
-} __attribute__ ((packed));
-
-/* SDMA */
-struct sdma {
- __be32 sdsr; /* Serial DMA status register */
- __be32 sdmr; /* Serial DMA mode register */
- __be32 sdtr1; /* SDMA system bus threshold register */
- __be32 sdtr2; /* SDMA secondary bus threshold register */
- __be32 sdhy1; /* SDMA system bus hysteresis register */
- __be32 sdhy2; /* SDMA secondary bus hysteresis register */
- __be32 sdta1; /* SDMA system bus address register */
- __be32 sdta2; /* SDMA secondary bus address register */
- __be32 sdtm1; /* SDMA system bus MSNUM register */
- __be32 sdtm2; /* SDMA secondary bus MSNUM register */
- u8 res0[0x10];
- __be32 sdaqr; /* SDMA address bus qualify register */
- __be32 sdaqmr; /* SDMA address bus qualify mask register */
- u8 res1[0x4];
- __be32 sdebcr; /* SDMA CAM entries base register */
- u8 res2[0x38];
-} __attribute__ ((packed));
-
-/* Debug Space */
-struct dbg {
- __be32 bpdcr; /* Breakpoint debug command register */
- __be32 bpdsr; /* Breakpoint debug status register */
- __be32 bpdmr; /* Breakpoint debug mask register */
- __be32 bprmrr0; /* Breakpoint request mode risc register 0 */
- __be32 bprmrr1; /* Breakpoint request mode risc register 1 */
- u8 res0[0x8];
- __be32 bprmtr0; /* Breakpoint request mode trb register 0 */
- __be32 bprmtr1; /* Breakpoint request mode trb register 1 */
- u8 res1[0x8];
- __be32 bprmir; /* Breakpoint request mode immediate register */
- __be32 bprmsr; /* Breakpoint request mode serial register */
- __be32 bpemr; /* Breakpoint exit mode register */
- u8 res2[0x48];
-} __attribute__ ((packed));
-
-/*
- * RISC Special Registers (Trap and Breakpoint). These are described in
- * the QE Developer's Handbook.
- */
-struct rsp {
- __be32 tibcr[16]; /* Trap/instruction breakpoint control regs */
- u8 res0[64];
- __be32 ibcr0;
- __be32 ibs0;
- __be32 ibcnr0;
- u8 res1[4];
- __be32 ibcr1;
- __be32 ibs1;
- __be32 ibcnr1;
- __be32 npcr;
- __be32 dbcr;
- __be32 dbar;
- __be32 dbamr;
- __be32 dbsr;
- __be32 dbcnr;
- u8 res2[12];
- __be32 dbdr_h;
- __be32 dbdr_l;
- __be32 dbdmr_h;
- __be32 dbdmr_l;
- __be32 bsr;
- __be32 bor;
- __be32 bior;
- u8 res3[4];
- __be32 iatr[4];
- __be32 eccr; /* Exception control configuration register */
- __be32 eicr;
- u8 res4[0x100-0xf8];
-} __attribute__ ((packed));
-
-struct qe_immap {
- struct qe_iram iram; /* I-RAM */
- struct qe_ic_regs ic; /* Interrupt Controller */
- struct cp_qe cp; /* Communications Processor */
- struct qe_mux qmx; /* QE Multiplexer */
- struct qe_timers qet; /* QE Timers */
- struct spi spi[0x2]; /* spi */
- struct qe_mcc mcc; /* mcc */
- struct qe_brg brg; /* brg */
- struct qe_usb_ctlr usb; /* USB */
- struct si1 si1; /* SI */
- u8 res11[0x800];
- struct sir sir; /* SI Routing Tables */
- struct ucc ucc1; /* ucc1 */
- struct ucc ucc3; /* ucc3 */
- struct ucc ucc5; /* ucc5 */
- struct ucc ucc7; /* ucc7 */
- u8 res12[0x600];
- struct upc upc1; /* MultiPHY UTOPIA POS Ctrlr 1*/
- struct ucc ucc2; /* ucc2 */
- struct ucc ucc4; /* ucc4 */
- struct ucc ucc6; /* ucc6 */
- struct ucc ucc8; /* ucc8 */
- u8 res13[0x600];
- struct upc upc2; /* MultiPHY UTOPIA POS Ctrlr 2*/
- struct sdma sdma; /* SDMA */
- struct dbg dbg; /* 0x104080 - 0x1040FF
- Debug Space */
- struct rsp rsp[0x2]; /* 0x104100 - 0x1042FF
- RISC Special Registers
- (Trap and Breakpoint) */
- u8 res14[0x300]; /* 0x104300 - 0x1045FF */
- u8 res15[0x3A00]; /* 0x104600 - 0x107FFF */
- u8 res16[0x8000]; /* 0x108000 - 0x110000 */
- u8 muram[0xC000]; /* 0x110000 - 0x11C000
- Multi-user RAM */
- u8 res17[0x24000]; /* 0x11C000 - 0x140000 */
- u8 res18[0xC0000]; /* 0x140000 - 0x200000 */
-} __attribute__ ((packed));
-
-extern struct qe_immap __iomem *qe_immr;
-extern phys_addr_t get_qe_base(void);
-
-/*
- * Returns the offset within the QE address space of the given pointer.
- *
- * Note that the QE does not support 36-bit physical addresses, so if
- * get_qe_base() returns a number above 4GB, the caller will probably fail.
- */
-static inline phys_addr_t immrbar_virt_to_phys(void *address)
-{
- void *q = (void *)qe_immr;
-
- /* Is it a MURAM address? */
- if ((address >= q) && (address < (q + QE_IMMAP_SIZE)))
- return get_qe_base() + (address - q);
-
- /* It's an address returned by kmalloc */
- return virt_to_phys(address);
-}
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_IMMAP_QE_H */
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 5879fde..2fd1690 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -300,7 +300,7 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
* When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks
* on all MMIOs. (Note that this is all 64 bits only for now)
*
- * To help platforms who may need to differenciate MMIO addresses in
+ * To help platforms who may need to differentiate MMIO addresses in
* their hooks, a bitfield is reserved for use by the platform near the
* top of MMIO addresses (not PIO, those have to cope the hard way).
*
@@ -385,6 +385,17 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
{
*(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v;
}
+
+/*
+ * Real mode version of the above. stdcix is only supposed to be used
+ * in hypervisor real mode as per the architecture spec.
+ */
+static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
+{
+ __asm__ __volatile__("stdcix %0,0,%1"
+ : : "r" (val), "r" (paddr) : "memory");
+}
+
#endif /* __powerpc64__ */
/*
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 9fac01c..8f39796 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -154,8 +154,8 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
bool upper, u32 val);
extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu);
-extern pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
- bool *writable);
+extern kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa,
+ bool writing, bool *writable);
extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,
unsigned long *rmap, long pte_index, int realmode);
extern void kvmppc_update_rmap_change(unsigned long *rmap, unsigned long psize);
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index 2aa79c8..7529aab 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -33,8 +33,6 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
}
#endif
-#define SPAPR_TCE_SHIFT 12
-
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
#define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */
#endif
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 887c259..d7b3431 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -38,8 +38,7 @@
#define KVM_MAX_VCPUS NR_CPUS
#define KVM_MAX_VCORES NR_CPUS
-#define KVM_USER_MEM_SLOTS 32
-#define KVM_MEM_SLOTS_NUM KVM_USER_MEM_SLOTS
+#define KVM_USER_MEM_SLOTS 512
#ifdef CONFIG_KVM_MMIO
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -50,6 +49,10 @@
#define KVM_NR_IRQCHIPS 1
#define KVM_IRQCHIP_NUM_PINS 256
+/* PPC-specific vcpu->requests bit members */
+#define KVM_REQ_WATCHDOG 8
+#define KVM_REQ_EPR_EXIT 9
+
#include <linux/mmu_notifier.h>
#define KVM_ARCH_WANT_MMU_NOTIFIER
@@ -179,7 +182,10 @@ struct kvmppc_spapr_tce_table {
struct list_head list;
struct kvm *kvm;
u64 liobn;
- u32 window_size;
+ struct rcu_head rcu;
+ u32 page_shift;
+ u64 offset; /* in pages */
+ u64 size; /* window size in pages */
struct page *pages[0];
};
@@ -286,7 +292,7 @@ struct kvmppc_vcore {
struct list_head runnable_threads;
struct list_head preempt_list;
spinlock_t lock;
- wait_queue_head_t wq;
+ struct swait_queue_head wq;
spinlock_t stoltb_lock; /* protects stolen_tb and preempt_tb */
u64 stolen_tb;
u64 preempt_tb;
@@ -626,7 +632,7 @@ struct kvm_vcpu_arch {
u8 prodded;
u32 last_inst;
- wait_queue_head_t *wqp;
+ struct swait_queue_head *wqp;
struct kvmppc_vcore *vcore;
int ret;
int trap;
@@ -716,5 +722,7 @@ static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslot
static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
static inline void kvm_arch_exit(void) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index c6ef05b..2544eda 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -165,9 +165,25 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
- struct kvm_create_spapr_tce *args);
+ struct kvm_create_spapr_tce_64 *args);
+extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
+ struct kvm_vcpu *vcpu, unsigned long liobn);
+extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
+ unsigned long ioba, unsigned long npages);
+extern long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *tt,
+ unsigned long tce);
+extern long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
+ unsigned long *ua, unsigned long **prmap);
+extern void kvmppc_tce_put(struct kvmppc_spapr_tce_table *tt,
+ unsigned long idx, unsigned long tce);
extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
unsigned long ioba, unsigned long tce);
+extern long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
+ unsigned long liobn, unsigned long ioba,
+ unsigned long tce_list, unsigned long npages);
+extern long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
+ unsigned long liobn, unsigned long ioba,
+ unsigned long tce_value, unsigned long npages);
extern long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
unsigned long ioba);
extern struct page *kvm_alloc_hpt(unsigned long nr_pages);
@@ -437,6 +453,8 @@ static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
{
return vcpu->arch.irq_type == KVMPPC_IRQ_XICS;
}
+extern void kvmppc_alloc_host_rm_ops(void);
+extern void kvmppc_free_host_rm_ops(void);
extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server);
extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args);
@@ -445,7 +463,11 @@ extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu);
extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
extern int kvmppc_xics_connect_vcpu(struct kvm_device *dev,
struct kvm_vcpu *vcpu, u32 cpu);
+extern void kvmppc_xics_ipi_action(void);
+extern int h_ipi_redirect;
#else
+static inline void kvmppc_alloc_host_rm_ops(void) {};
+static inline void kvmppc_free_host_rm_ops(void) {};
static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
{ return 0; }
static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
@@ -459,6 +481,33 @@ static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
{ return 0; }
#endif
+/*
+ * Host-side operations we want to set up while running in real
+ * mode in the guest operating on the xics.
+ * Currently only VCPU wakeup is supported.
+ */
+
+union kvmppc_rm_state {
+ unsigned long raw;
+ struct {
+ u32 in_host;
+ u32 rm_action;
+ };
+};
+
+struct kvmppc_host_rm_core {
+ union kvmppc_rm_state rm_state;
+ void *rm_data;
+ char pad[112];
+};
+
+struct kvmppc_host_rm_ops {
+ struct kvmppc_host_rm_core *rm_core;
+ void (*vcpu_kick)(struct kvm_vcpu *vcpu);
+};
+
+extern struct kvmppc_host_rm_ops *kvmppc_host_rm_ops_hv;
+
static inline unsigned long kvmppc_get_epr(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_KVM_BOOKE_HV
@@ -515,7 +564,7 @@ void kvmppc_claim_lpid(long lpid);
void kvmppc_free_lpid(long lpid);
void kvmppc_init_lpid(unsigned long nr_lpids);
-static inline void kvmppc_mmu_flush_icache(pfn_t pfn)
+static inline void kvmppc_mmu_flush_icache(kvm_pfn_t pfn)
{
struct page *page;
/*
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 3f191f5..fd22442 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -54,7 +54,7 @@ struct machdep_calls {
int psize, int apsize,
int ssize);
long (*hpte_remove)(unsigned long hpte_group);
- void (*hpte_removebolted)(unsigned long ea,
+ int (*hpte_removebolted)(unsigned long ea,
int psize, int ssize);
void (*flush_hash_range)(unsigned long number, int local);
void (*hugepage_invalidate)(unsigned long vsid,
@@ -174,11 +174,11 @@ struct machdep_calls {
platform, called once per cpu. */
void (*enable_pmcs)(void);
- /* Set DABR for this platform, leave empty for default implemenation */
+ /* Set DABR for this platform, leave empty for default implementation */
int (*set_dabr)(unsigned long dabr,
unsigned long dabrx);
- /* Set DAWR for this platform, leave empty for default implemenation */
+ /* Set DAWR for this platform, leave empty for default implementation */
int (*set_dawr)(unsigned long dawr,
unsigned long dawrx);
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index f05500a..0a566f1 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -171,9 +171,9 @@ typedef struct {
} mm_context_t;
#endif /* !__ASSEMBLY__ */
-#if (PAGE_SHIFT == 12)
+#if defined(CONFIG_PPC_4K_PAGES)
#define mmu_virtual_psize MMU_PAGE_4K
-#elif (PAGE_SHIFT == 14)
+#elif defined(CONFIG_PPC_16K_PAGES)
#define mmu_virtual_psize MMU_PAGE_16K
#else
#error "Unsupported PAGE_SIZE"
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
deleted file mode 100644
index a82f534..0000000
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ /dev/null
@@ -1,611 +0,0 @@
-#ifndef _ASM_POWERPC_MMU_HASH64_H_
-#define _ASM_POWERPC_MMU_HASH64_H_
-/*
- * PowerPC64 memory management structures
- *
- * Dave Engebretsen & Mike Corrigan <{engebret|mikejc}@us.ibm.com>
- * PPC64 rework.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the 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/asm-compat.h>
-#include <asm/page.h>
-
-/*
- * This is necessary to get the definition of PGTABLE_RANGE which we
- * need for various slices related matters. Note that this isn't the
- * complete pgtable.h but only a portion of it.
- */
-#include <asm/pgtable-ppc64.h>
-#include <asm/bug.h>
-#include <asm/processor.h>
-
-/*
- * SLB
- */
-
-#define SLB_NUM_BOLTED 3
-#define SLB_CACHE_ENTRIES 8
-#define SLB_MIN_SIZE 32
-
-/* Bits in the SLB ESID word */
-#define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */
-
-/* Bits in the SLB VSID word */
-#define SLB_VSID_SHIFT 12
-#define SLB_VSID_SHIFT_1T 24
-#define SLB_VSID_SSIZE_SHIFT 62
-#define SLB_VSID_B ASM_CONST(0xc000000000000000)
-#define SLB_VSID_B_256M ASM_CONST(0x0000000000000000)
-#define SLB_VSID_B_1T ASM_CONST(0x4000000000000000)
-#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
-#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
-#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
-#define SLB_VSID_L ASM_CONST(0x0000000000000100)
-#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
-#define SLB_VSID_LP ASM_CONST(0x0000000000000030)
-#define SLB_VSID_LP_00 ASM_CONST(0x0000000000000000)
-#define SLB_VSID_LP_01 ASM_CONST(0x0000000000000010)
-#define SLB_VSID_LP_10 ASM_CONST(0x0000000000000020)
-#define SLB_VSID_LP_11 ASM_CONST(0x0000000000000030)
-#define SLB_VSID_LLP (SLB_VSID_L|SLB_VSID_LP)
-
-#define SLB_VSID_KERNEL (SLB_VSID_KP)
-#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS|SLB_VSID_C)
-
-#define SLBIE_C (0x08000000)
-#define SLBIE_SSIZE_SHIFT 25
-
-/*
- * Hash table
- */
-
-#define HPTES_PER_GROUP 8
-
-#define HPTE_V_SSIZE_SHIFT 62
-#define HPTE_V_AVPN_SHIFT 7
-#define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80)
-#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
-#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL))
-#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)
-#define HPTE_V_LOCK ASM_CONST(0x0000000000000008)
-#define HPTE_V_LARGE ASM_CONST(0x0000000000000004)
-#define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002)
-#define HPTE_V_VALID ASM_CONST(0x0000000000000001)
-
-#define HPTE_R_PP0 ASM_CONST(0x8000000000000000)
-#define HPTE_R_TS ASM_CONST(0x4000000000000000)
-#define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000)
-#define HPTE_R_RPN_SHIFT 12
-#define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000)
-#define HPTE_R_PP ASM_CONST(0x0000000000000003)
-#define HPTE_R_N ASM_CONST(0x0000000000000004)
-#define HPTE_R_G ASM_CONST(0x0000000000000008)
-#define HPTE_R_M ASM_CONST(0x0000000000000010)
-#define HPTE_R_I ASM_CONST(0x0000000000000020)
-#define HPTE_R_W ASM_CONST(0x0000000000000040)
-#define HPTE_R_WIMG ASM_CONST(0x0000000000000078)
-#define HPTE_R_C ASM_CONST(0x0000000000000080)
-#define HPTE_R_R ASM_CONST(0x0000000000000100)
-#define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00)
-
-#define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000)
-#define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000)
-
-/* Values for PP (assumes Ks=0, Kp=1) */
-#define PP_RWXX 0 /* Supervisor read/write, User none */
-#define PP_RWRX 1 /* Supervisor read/write, User read */
-#define PP_RWRW 2 /* Supervisor read/write, User read/write */
-#define PP_RXRX 3 /* Supervisor read, User read */
-#define PP_RXXX (HPTE_R_PP0 | 2) /* Supervisor read, user none */
-
-/* Fields for tlbiel instruction in architecture 2.06 */
-#define TLBIEL_INVAL_SEL_MASK 0xc00 /* invalidation selector */
-#define TLBIEL_INVAL_PAGE 0x000 /* invalidate a single page */
-#define TLBIEL_INVAL_SET_LPID 0x800 /* invalidate a set for current LPID */
-#define TLBIEL_INVAL_SET 0xc00 /* invalidate a set for all LPIDs */
-#define TLBIEL_INVAL_SET_MASK 0xfff000 /* set number to inval. */
-#define TLBIEL_INVAL_SET_SHIFT 12
-
-#define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */
-#define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */
-
-#ifndef __ASSEMBLY__
-
-struct hash_pte {
- __be64 v;
- __be64 r;
-};
-
-extern struct hash_pte *htab_address;
-extern unsigned long htab_size_bytes;
-extern unsigned long htab_hash_mask;
-
-/*
- * Page size definition
- *
- * shift : is the "PAGE_SHIFT" value for that page size
- * sllp : is a bit mask with the value of SLB L || LP to be or'ed
- * directly to a slbmte "vsid" value
- * penc : is the HPTE encoding mask for the "LP" field:
- *
- */
-struct mmu_psize_def
-{
- unsigned int shift; /* number of bits */
- int penc[MMU_PAGE_COUNT]; /* HPTE encoding */
- unsigned int tlbiel; /* tlbiel supported for that page size */
- unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */
- unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */
-};
-extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
-
-static inline int shift_to_mmu_psize(unsigned int shift)
-{
- int psize;
-
- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize)
- if (mmu_psize_defs[psize].shift == shift)
- return psize;
- return -1;
-}
-
-static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
-{
- if (mmu_psize_defs[mmu_psize].shift)
- return mmu_psize_defs[mmu_psize].shift;
- BUG();
-}
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Segment sizes.
- * These are the values used by hardware in the B field of
- * SLB entries and the first dword of MMU hashtable entries.
- * The B field is 2 bits; the values 2 and 3 are unused and reserved.
- */
-#define MMU_SEGSIZE_256M 0
-#define MMU_SEGSIZE_1T 1
-
-/*
- * encode page number shift.
- * in order to fit the 78 bit va in a 64 bit variable we shift the va by
- * 12 bits. This enable us to address upto 76 bit va.
- * For hpt hash from a va we can ignore the page size bits of va and for
- * hpte encoding we ignore up to 23 bits of va. So ignoring lower 12 bits ensure
- * we work in all cases including 4k page size.
- */
-#define VPN_SHIFT 12
-
-/*
- * HPTE Large Page (LP) details
- */
-#define LP_SHIFT 12
-#define LP_BITS 8
-#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
-
-#ifndef __ASSEMBLY__
-
-static inline int slb_vsid_shift(int ssize)
-{
- if (ssize == MMU_SEGSIZE_256M)
- return SLB_VSID_SHIFT;
- return SLB_VSID_SHIFT_1T;
-}
-
-static inline int segment_shift(int ssize)
-{
- if (ssize == MMU_SEGSIZE_256M)
- return SID_SHIFT;
- return SID_SHIFT_1T;
-}
-
-/*
- * The current system page and segment sizes
- */
-extern int mmu_linear_psize;
-extern int mmu_virtual_psize;
-extern int mmu_vmalloc_psize;
-extern int mmu_vmemmap_psize;
-extern int mmu_io_psize;
-extern int mmu_kernel_ssize;
-extern int mmu_highuser_ssize;
-extern u16 mmu_slb_size;
-extern unsigned long tce_alloc_start, tce_alloc_end;
-
-/*
- * If the processor supports 64k normal pages but not 64k cache
- * inhibited pages, we have to be prepared to switch processes
- * to use 4k pages when they create cache-inhibited mappings.
- * If this is the case, mmu_ci_restrictions will be set to 1.
- */
-extern int mmu_ci_restrictions;
-
-/*
- * This computes the AVPN and B fields of the first dword of a HPTE,
- * for use when we want to match an existing PTE. The bottom 7 bits
- * of the returned value are zero.
- */
-static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize,
- int ssize)
-{
- unsigned long v;
- /*
- * The AVA field omits the low-order 23 bits of the 78 bits VA.
- * These bits are not needed in the PTE, because the
- * low-order b of these bits are part of the byte offset
- * into the virtual page and, if b < 23, the high-order
- * 23-b of these bits are always used in selecting the
- * PTEGs to be searched
- */
- v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm);
- v <<= HPTE_V_AVPN_SHIFT;
- v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
- return v;
-}
-
-/*
- * This function sets the AVPN and L fields of the HPTE appropriately
- * using the base page size and actual page size.
- */
-static inline unsigned long hpte_encode_v(unsigned long vpn, int base_psize,
- int actual_psize, int ssize)
-{
- unsigned long v;
- v = hpte_encode_avpn(vpn, base_psize, ssize);
- if (actual_psize != MMU_PAGE_4K)
- v |= HPTE_V_LARGE;
- return v;
-}
-
-/*
- * This function sets the ARPN, and LP fields of the HPTE appropriately
- * for the page size. We assume the pa is already "clean" that is properly
- * aligned for the requested page size
- */
-static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize,
- int actual_psize)
-{
- /* A 4K page needs no special encoding */
- if (actual_psize == MMU_PAGE_4K)
- return pa & HPTE_R_RPN;
- else {
- unsigned int penc = mmu_psize_defs[base_psize].penc[actual_psize];
- unsigned int shift = mmu_psize_defs[actual_psize].shift;
- return (pa & ~((1ul << shift) - 1)) | (penc << LP_SHIFT);
- }
-}
-
-/*
- * Build a VPN_SHIFT bit shifted va given VSID, EA and segment size.
- */
-static inline unsigned long hpt_vpn(unsigned long ea,
- unsigned long vsid, int ssize)
-{
- unsigned long mask;
- int s_shift = segment_shift(ssize);
-
- mask = (1ul << (s_shift - VPN_SHIFT)) - 1;
- return (vsid << (s_shift - VPN_SHIFT)) | ((ea >> VPN_SHIFT) & mask);
-}
-
-/*
- * This hashes a virtual address
- */
-static inline unsigned long hpt_hash(unsigned long vpn,
- unsigned int shift, int ssize)
-{
- int mask;
- unsigned long hash, vsid;
-
- /* VPN_SHIFT can be atmost 12 */
- if (ssize == MMU_SEGSIZE_256M) {
- mask = (1ul << (SID_SHIFT - VPN_SHIFT)) - 1;
- hash = (vpn >> (SID_SHIFT - VPN_SHIFT)) ^
- ((vpn & mask) >> (shift - VPN_SHIFT));
- } else {
- mask = (1ul << (SID_SHIFT_1T - VPN_SHIFT)) - 1;
- vsid = vpn >> (SID_SHIFT_1T - VPN_SHIFT);
- hash = vsid ^ (vsid << 25) ^
- ((vpn & mask) >> (shift - VPN_SHIFT)) ;
- }
- return hash & 0x7fffffffffUL;
-}
-
-#define HPTE_LOCAL_UPDATE 0x1
-#define HPTE_NOHPTE_UPDATE 0x2
-
-extern int __hash_page_4K(unsigned long ea, unsigned long access,
- unsigned long vsid, pte_t *ptep, unsigned long trap,
- unsigned long flags, int ssize, int subpage_prot);
-extern int __hash_page_64K(unsigned long ea, unsigned long access,
- unsigned long vsid, pte_t *ptep, unsigned long trap,
- unsigned long flags, int ssize);
-struct mm_struct;
-unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
-extern int hash_page_mm(struct mm_struct *mm, unsigned long ea,
- unsigned long access, unsigned long trap,
- unsigned long flags);
-extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
- unsigned long dsisr);
-int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
- pte_t *ptep, unsigned long trap, unsigned long flags,
- int ssize, unsigned int shift, unsigned int mmu_psize);
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-extern int __hash_page_thp(unsigned long ea, unsigned long access,
- unsigned long vsid, pmd_t *pmdp, unsigned long trap,
- unsigned long flags, int ssize, unsigned int psize);
-#else
-static inline int __hash_page_thp(unsigned long ea, unsigned long access,
- unsigned long vsid, pmd_t *pmdp,
- unsigned long trap, unsigned long flags,
- int ssize, unsigned int psize)
-{
- BUG();
- return -1;
-}
-#endif
-extern void hash_failure_debug(unsigned long ea, unsigned long access,
- unsigned long vsid, unsigned long trap,
- int ssize, int psize, int lpsize,
- unsigned long pte);
-extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
- unsigned long pstart, unsigned long prot,
- int psize, int ssize);
-int htab_remove_mapping(unsigned long vstart, unsigned long vend,
- int psize, int ssize);
-extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages);
-extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
-
-extern void hpte_init_native(void);
-extern void hpte_init_lpar(void);
-extern void hpte_init_beat(void);
-extern void hpte_init_beat_v3(void);
-
-extern void slb_initialize(void);
-extern void slb_flush_and_rebolt(void);
-
-extern void slb_vmalloc_update(void);
-extern void slb_set_size(u16 size);
-#endif /* __ASSEMBLY__ */
-
-/*
- * VSID allocation (256MB segment)
- *
- * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
- * from mmu context id and effective segment id of the address.
- *
- * For user processes max context id is limited to ((1ul << 19) - 5)
- * for kernel space, we use the top 4 context ids to map address as below
- * NOTE: each context only support 64TB now.
- * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
- * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
- * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
- * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
- *
- * The proto-VSIDs are then scrambled into real VSIDs with the
- * multiplicative hash:
- *
- * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
- *
- * VSID_MULTIPLIER is prime, so in particular it is
- * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
- * Because the modulus is 2^n-1 we can compute it efficiently without
- * a divide or extra multiply (see below). The scramble function gives
- * robust scattering in the hash table (at least based on some initial
- * results).
- *
- * We also consider VSID 0 special. We use VSID 0 for slb entries mapping
- * bad address. This enables us to consolidate bad address handling in
- * hash_page.
- *
- * We also need to avoid the last segment of the last context, because that
- * would give a protovsid of 0x1fffffffff. That will result in a VSID 0
- * because of the modulo operation in vsid scramble. But the vmemmap
- * (which is what uses region 0xf) will never be close to 64TB in size
- * (it's 56 bytes per page of system memory).
- */
-
-#define CONTEXT_BITS 19
-#define ESID_BITS 18
-#define ESID_BITS_1T 6
-
-/*
- * 256MB segment
- * The proto-VSID space has 2^(CONTEX_BITS + ESID_BITS) - 1 segments
- * available for user + kernel mapping. The top 4 contexts are used for
- * kernel mapping. Each segment contains 2^28 bytes. Each
- * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
- * (19 == 37 + 28 - 46).
- */
-#define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 5)
-
-/*
- * This should be computed such that protovosid * vsid_mulitplier
- * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
- */
-#define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
-#define VSID_BITS_256M (CONTEXT_BITS + ESID_BITS)
-#define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
-
-#define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
-#define VSID_BITS_1T (CONTEXT_BITS + ESID_BITS_1T)
-#define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
-
-
-#define USER_VSID_RANGE (1UL << (ESID_BITS + SID_SHIFT))
-
-/*
- * This macro generates asm code to compute the VSID scramble
- * function. Used in slb_allocate() and do_stab_bolted. The function
- * computed is: (protovsid*VSID_MULTIPLIER) % VSID_MODULUS
- *
- * rt = register continaing the proto-VSID and into which the
- * VSID will be stored
- * rx = scratch register (clobbered)
- *
- * - rt and rx must be different registers
- * - The answer will end up in the low VSID_BITS bits of rt. The higher
- * bits may contain other garbage, so you may need to mask the
- * result.
- */
-#define ASM_VSID_SCRAMBLE(rt, rx, size) \
- lis rx,VSID_MULTIPLIER_##size@h; \
- ori rx,rx,VSID_MULTIPLIER_##size@l; \
- mulld rt,rt,rx; /* rt = rt * MULTIPLIER */ \
- \
- srdi rx,rt,VSID_BITS_##size; \
- clrldi rt,rt,(64-VSID_BITS_##size); \
- add rt,rt,rx; /* add high and low bits */ \
- /* NOTE: explanation based on VSID_BITS_##size = 36 \
- * Now, r3 == VSID (mod 2^36-1), and lies between 0 and \
- * 2^36-1+2^28-1. That in particular means that if r3 >= \
- * 2^36-1, then r3+1 has the 2^36 bit set. So, if r3+1 has \
- * the bit clear, r3 already has the answer we want, if it \
- * doesn't, the answer is the low 36 bits of r3+1. So in all \
- * cases the answer is the low 36 bits of (r3 + ((r3+1) >> 36))*/\
- addi rx,rt,1; \
- srdi rx,rx,VSID_BITS_##size; /* extract 2^VSID_BITS bit */ \
- add rt,rt,rx
-
-/* 4 bits per slice and we have one slice per 1TB */
-#define SLICE_ARRAY_SIZE (PGTABLE_RANGE >> 41)
-
-#ifndef __ASSEMBLY__
-
-#ifdef CONFIG_PPC_SUBPAGE_PROT
-/*
- * For the sub-page protection option, we extend the PGD with one of
- * these. Basically we have a 3-level tree, with the top level being
- * the protptrs array. To optimize speed and memory consumption when
- * only addresses < 4GB are being protected, pointers to the first
- * four pages of sub-page protection words are stored in the low_prot
- * array.
- * Each page of sub-page protection words protects 1GB (4 bytes
- * protects 64k). For the 3-level tree, each page of pointers then
- * protects 8TB.
- */
-struct subpage_prot_table {
- unsigned long maxaddr; /* only addresses < this are protected */
- unsigned int **protptrs[(TASK_SIZE_USER64 >> 43)];
- unsigned int *low_prot[4];
-};
-
-#define SBP_L1_BITS (PAGE_SHIFT - 2)
-#define SBP_L2_BITS (PAGE_SHIFT - 3)
-#define SBP_L1_COUNT (1 << SBP_L1_BITS)
-#define SBP_L2_COUNT (1 << SBP_L2_BITS)
-#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
-#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
-
-extern void subpage_prot_free(struct mm_struct *mm);
-extern void subpage_prot_init_new_context(struct mm_struct *mm);
-#else
-static inline void subpage_prot_free(struct mm_struct *mm) {}
-static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
-#endif /* CONFIG_PPC_SUBPAGE_PROT */
-
-typedef unsigned long mm_context_id_t;
-struct spinlock;
-
-typedef struct {
- mm_context_id_t id;
- u16 user_psize; /* page size index */
-
-#ifdef CONFIG_PPC_MM_SLICES
- u64 low_slices_psize; /* SLB page size encodings */
- unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
-#else
- u16 sllp; /* SLB page size encoding */
-#endif
- unsigned long vdso_base;
-#ifdef CONFIG_PPC_SUBPAGE_PROT
- struct subpage_prot_table spt;
-#endif /* CONFIG_PPC_SUBPAGE_PROT */
-#ifdef CONFIG_PPC_ICSWX
- struct spinlock *cop_lockp; /* guard acop and cop_pid */
- unsigned long acop; /* mask of enabled coprocessor types */
- unsigned int cop_pid; /* pid value used with coprocessors */
-#endif /* CONFIG_PPC_ICSWX */
-#ifdef CONFIG_PPC_64K_PAGES
- /* for 4K PTE fragment support */
- void *pte_frag;
-#endif
-#ifdef CONFIG_SPAPR_TCE_IOMMU
- struct list_head iommu_group_mem_list;
-#endif
-} mm_context_t;
-
-
-#if 0
-/*
- * The code below is equivalent to this function for arguments
- * < 2^VSID_BITS, which is all this should ever be called
- * with. However gcc is not clever enough to compute the
- * modulus (2^n-1) without a second multiply.
- */
-#define vsid_scramble(protovsid, size) \
- ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
-
-#else /* 1 */
-#define vsid_scramble(protovsid, size) \
- ({ \
- unsigned long x; \
- x = (protovsid) * VSID_MULTIPLIER_##size; \
- x = (x >> VSID_BITS_##size) + (x & VSID_MODULUS_##size); \
- (x + ((x+1) >> VSID_BITS_##size)) & VSID_MODULUS_##size; \
- })
-#endif /* 1 */
-
-/* Returns the segment size indicator for a user address */
-static inline int user_segment_size(unsigned long addr)
-{
- /* Use 1T segments if possible for addresses >= 1T */
- if (addr >= (1UL << SID_SHIFT_1T))
- return mmu_highuser_ssize;
- return MMU_SEGSIZE_256M;
-}
-
-static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
- int ssize)
-{
- /*
- * Bad address. We return VSID 0 for that
- */
- if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
- return 0;
-
- if (ssize == MMU_SEGSIZE_256M)
- return vsid_scramble((context << ESID_BITS)
- | (ea >> SID_SHIFT), 256M);
- return vsid_scramble((context << ESID_BITS_1T)
- | (ea >> SID_SHIFT_1T), 1T);
-}
-
-/*
- * This is only valid for addresses >= PAGE_OFFSET
- *
- * For kernel space, we use the top 4 context ids to map address as below
- * 0x7fffc - [ 0xc000000000000000 - 0xc0003fffffffffff ]
- * 0x7fffd - [ 0xd000000000000000 - 0xd0003fffffffffff ]
- * 0x7fffe - [ 0xe000000000000000 - 0xe0003fffffffffff ]
- * 0x7ffff - [ 0xf000000000000000 - 0xf0003fffffffffff ]
- */
-static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
-{
- unsigned long context;
-
- /*
- * kernel take the top 4 context from the available range
- */
- context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1;
- return get_vsid(context, ea, ssize);
-}
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_POWERPC_MMU_HASH64_H_ */
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 3d5abfe..8ca1c98 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -97,6 +97,7 @@
#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
@@ -182,10 +183,10 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
#if defined(CONFIG_PPC_STD_MMU_64)
/* 64-bit classic hash table MMU */
-# include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#elif defined(CONFIG_PPC_STD_MMU_32)
/* 32-bit classic hash table MMU */
-# include <asm/mmu-hash32.h>
+#include <asm/book3s/32/mmu-hash.h>
#elif defined(CONFIG_40x)
/* 40x-style software loaded TLB */
# include <asm/mmu-40x.h>
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index dcfcad1..cd4ffd8 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -19,7 +19,7 @@
* Thanks to Paul M for explaining this.
*
* PPC can only do rel jumps += 32MB, and often the kernel and other
- * modules are furthur away than this. So, we jump to a table of
+ * modules are further away than this. So, we jump to a table of
* trampolines attached to the module (the Procedure Linkage Table)
* whenever that happens.
*/
@@ -78,10 +78,18 @@ struct mod_arch_specific {
# endif /* MODULE */
#endif
-bool is_module_trampoline(u32 *insns);
-int module_trampoline_target(struct module *mod, u32 *trampoline,
+int module_trampoline_target(struct module *mod, unsigned long trampoline,
unsigned long *target);
+#ifdef CONFIG_DYNAMIC_FTRACE
+int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs);
+#else
+static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
+{
+ return 0;
+}
+#endif
+
struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
struct exception_table_entry *finish);
diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h
index 4a69cd1..deaeb0b 100644
--- a/arch/powerpc/include/asm/mpc5121.h
+++ b/arch/powerpc/include/asm/mpc5121.h
@@ -60,4 +60,63 @@ struct mpc512x_lpc {
int mpc512x_cs_config(unsigned int cs, u32 val);
+/*
+ * SCLPC Module (LPB FIFO)
+ */
+struct mpc512x_lpbfifo {
+ u32 pkt_size; /* SCLPC Packet Size Register */
+ u32 start_addr; /* SCLPC Start Address Register */
+ u32 ctrl; /* SCLPC Control Register */
+ u32 enable; /* SCLPC Enable Register */
+ u32 reserved1;
+ u32 status; /* SCLPC Status Register */
+ u32 bytes_done; /* SCLPC Bytes Done Register */
+ u32 emb_sc; /* EMB Share Counter Register */
+ u32 emb_pc; /* EMB Pause Control Register */
+ u32 reserved2[7];
+ u32 data_word; /* LPC RX/TX FIFO Data Word Register */
+ u32 fifo_status; /* LPC RX/TX FIFO Status Register */
+ u32 fifo_ctrl; /* LPC RX/TX FIFO Control Register */
+ u32 fifo_alarm; /* LPC RX/TX FIFO Alarm Register */
+};
+
+#define MPC512X_SCLPC_START (1 << 31)
+#define MPC512X_SCLPC_CS(x) (((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FLUSH (1 << 17)
+#define MPC512X_SCLPC_READ (1 << 16)
+#define MPC512X_SCLPC_DAI (1 << 8)
+#define MPC512X_SCLPC_BPT(x) ((x) & 0x3f)
+#define MPC512X_SCLPC_RESET (1 << 24)
+#define MPC512X_SCLPC_FIFO_RESET (1 << 16)
+#define MPC512X_SCLPC_ABORT_INT_ENABLE (1 << 9)
+#define MPC512X_SCLPC_NORM_INT_ENABLE (1 << 8)
+#define MPC512X_SCLPC_ENABLE (1 << 0)
+#define MPC512X_SCLPC_SUCCESS (1 << 24)
+#define MPC512X_SCLPC_FIFO_CTRL(x) (((x) & 0x7) << 24)
+#define MPC512X_SCLPC_FIFO_ALARM(x) ((x) & 0x3ff)
+
+enum lpb_dev_portsize {
+ LPB_DEV_PORTSIZE_UNDEFINED = 0,
+ LPB_DEV_PORTSIZE_1_BYTE = 1,
+ LPB_DEV_PORTSIZE_2_BYTES = 2,
+ LPB_DEV_PORTSIZE_4_BYTES = 4,
+ LPB_DEV_PORTSIZE_8_BYTES = 8
+};
+
+enum mpc512x_lpbfifo_req_dir {
+ MPC512X_LPBFIFO_REQ_DIR_READ,
+ MPC512X_LPBFIFO_REQ_DIR_WRITE
+};
+
+struct mpc512x_lpbfifo_request {
+ phys_addr_t dev_phys_addr; /* physical address of some device on LPB */
+ void *ram_virt_addr; /* virtual address of some region in RAM */
+ u32 size;
+ enum lpb_dev_portsize portsize;
+ enum mpc512x_lpbfifo_req_dir dir;
+ void (*callback)(struct mpc512x_lpbfifo_request *);
+};
+
+int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req);
+
#endif /* __ASM_POWERPC_MPC5121_H__ */
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index 04c7e8f..ec995b2 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -261,8 +261,6 @@ struct mpc52xx_psc_fifo {
#define MPC512x_PSC_FIFO_FULL 0x2
#define MPC512x_PSC_FIFO_ALARM 0x4
#define MPC512x_PSC_FIFO_URERR 0x8
-#define MPC512x_PSC_FIFO_ORERR 0x01
-#define MPC512x_PSC_FIFO_MEMERROR 0x02
struct mpc512x_psc_fifo {
u32 reserved1[10];
diff --git a/arch/powerpc/include/asm/msi_bitmap.h b/arch/powerpc/include/asm/msi_bitmap.h
index 97ac3f4..1ec7125 100644
--- a/arch/powerpc/include/asm/msi_bitmap.h
+++ b/arch/powerpc/include/asm/msi_bitmap.h
@@ -19,6 +19,7 @@ struct msi_bitmap {
unsigned long *bitmap;
spinlock_t lock;
unsigned int irq_count;
+ bool bitmap_from_slab;
};
int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num);
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
new file mode 100644
index 0000000..7808475
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -0,0 +1,344 @@
+#ifndef _ASM_POWERPC_NOHASH_32_PGTABLE_H
+#define _ASM_POWERPC_NOHASH_32_PGTABLE_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
+
+extern unsigned long ioremap_bot;
+
+#ifdef CONFIG_44x
+extern int icache_44x_need_flush;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The normal case is that PTEs are 32-bits and we have a 1-page
+ * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
+ *
+ * For any >32-bit physical address platform, we can use the following
+ * two level page table layout where the pgdir is 8KB and the MS 13 bits
+ * are an index to the second level table. The combined pgdir/pmd first
+ * level has 2048 entries and the second level has 512 64-bit PTE entries.
+ * -Matt
+ */
+/* PGDIR_SHIFT determines what a top-level page table entry can map */
+#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
+ */
+#ifndef __ASSEMBLY__
+#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT))
+#endif /* __ASSEMBLY__ */
+
+#define PTRS_PER_PTE (1 << PTE_SHIFT)
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0UL
+
+#define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \
+ (unsigned long long)pte_val(e))
+#define pgd_ERROR(e) \
+ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
+ * value (for now) on others, from where we can start layout kernel
+ * virtual space that goes below PKMAP and FIXMAP
+ */
+#ifdef CONFIG_HIGHMEM
+#define KVIRT_TOP PKMAP_BASE
+#else
+#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
+#endif
+
+/*
+ * ioremap_bot starts at that address. Early ioremaps move down from there,
+ * until mem_init() at which point this becomes the top of the vmalloc
+ * and ioremap space
+ */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK)
+#else
+#define IOREMAP_TOP KVIRT_TOP
+#endif
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 16MB value just means that there will be a 64MB "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. ;)
+ *
+ * We no longer map larger than phys RAM with the BATs so we don't have
+ * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
+ * about clashes between our early calls to ioremap() that start growing down
+ * from IOREMAP_TOP being run into the VM area allocations (growing upwards
+ * from VMALLOC_START). For this reason we have ioremap_bot to check when
+ * we actually run into our mappings setup in the early boot with the VM
+ * system. This really does become a problem for machines with good amounts
+ * of RAM. -- Cort
+ */
+#define VMALLOC_OFFSET (0x1000000) /* 16M */
+#ifdef PPC_PIN_SIZE
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#else
+#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
+#define VMALLOC_END ioremap_bot
+
+/*
+ * Bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+
+#if defined(CONFIG_40x)
+#include <asm/nohash/32/pte-40x.h>
+#elif defined(CONFIG_44x)
+#include <asm/nohash/32/pte-44x.h>
+#elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
+#include <asm/nohash/pte-book3e.h>
+#elif defined(CONFIG_FSL_BOOKE)
+#include <asm/nohash/32/pte-fsl-booke.h>
+#elif defined(CONFIG_8xx)
+#include <asm/nohash/32/pte-8xx.h>
+#endif
+
+/* And here we include common definitions */
+#include <asm/pte-common.h>
+
+#ifndef __ASSEMBLY__
+
+#define pte_clear(mm, addr, ptep) \
+ do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
+#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ *pmdp = __pmd(0);
+}
+
+
+
+/*
+ * When flushing the tlb entry for a page, we also need to flush the hash
+ * table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
+ */
+extern int flush_hash_pages(unsigned context, unsigned long va,
+ unsigned long pmdval, int count);
+
+/* Add an HPTE to the hash table */
+extern void add_hash_page(unsigned context, unsigned long va,
+ unsigned long pmdval);
+
+/* Flush an entry from the TLB/hash table */
+extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
+ unsigned long address);
+
+/*
+ * PTE updates. This function is called whenever an existing
+ * valid PTE is updated. This does -not- include set_pte_at()
+ * which nowadays only sets a new PTE.
+ *
+ * Depending on the type of MMU, we may need to use atomic updates
+ * and the PTE may be either 32 or 64 bit wide. In the later case,
+ * when using atomic updates, only the low part of the PTE is
+ * accessed atomically.
+ *
+ * In addition, on 44x, we also maintain a global flag indicating
+ * that an executable user mapping was modified, which is needed
+ * to properly flush the virtually tagged instruction cache of
+ * those implementations.
+ */
+#ifndef CONFIG_PTE_64BIT
+static inline unsigned long pte_update(pte_t *p,
+ unsigned long clr,
+ unsigned long set)
+{
+#ifdef PTE_ATOMIC_UPDATES
+ unsigned long old, tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %0,0,%3\n\
+ andc %1,%0,%4\n\
+ or %1,%1,%5\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+#else /* PTE_ATOMIC_UPDATES */
+ unsigned long old = pte_val(*p);
+ *p = __pte((old & ~clr) | set);
+#endif /* !PTE_ATOMIC_UPDATES */
+
+#ifdef CONFIG_44x
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
+ icache_44x_need_flush = 1;
+#endif
+ return old;
+}
+#else /* CONFIG_PTE_64BIT */
+static inline unsigned long long pte_update(pte_t *p,
+ unsigned long clr,
+ unsigned long set)
+{
+#ifdef PTE_ATOMIC_UPDATES
+ unsigned long long old;
+ unsigned long tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %L0,0,%4\n\
+ lwzx %0,0,%3\n\
+ andc %1,%L0,%5\n\
+ or %1,%1,%6\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%4\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+#else /* PTE_ATOMIC_UPDATES */
+ unsigned long long old = pte_val(*p);
+ *p = __pte((old & ~(unsigned long long)clr) | set);
+#endif /* !PTE_ATOMIC_UPDATES */
+
+#ifdef CONFIG_44x
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
+ icache_44x_need_flush = 1;
+#endif
+ return old;
+}
+#endif /* CONFIG_PTE_64BIT */
+
+/*
+ * 2.6 calls this without flushing the TLB entry; this is wrong
+ * for our hash-based implementation, we fix that up here.
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+ old = pte_update(ptep, _PAGE_ACCESSED, 0);
+#if _PAGE_HASHPTE != 0
+ if (old & _PAGE_HASHPTE) {
+ unsigned long ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(context, addr, ptephys, 1);
+ }
+#endif
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+ __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
+}
+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 void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+{
+ unsigned long set = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+ unsigned long clr = ~pte_val(entry) & _PAGE_RO;
+
+ pte_update(ptep, clr, set);
+}
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+
+/*
+ * Note that on Book E processors, the pmd contains the kernel virtual
+ * (lowmem) address of the pte page. The physical address is less useful
+ * because everything runs with translation enabled (even the TLB miss
+ * handler). On everything else the pmd contains the physical address
+ * of the pte page. -- paulus
+ */
+#ifndef CONFIG_BOOKE
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#else
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#endif
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, addr) \
+ (pmd_bad(*(dir)) ? NULL : (pte_t *)pmd_page_vaddr(*(dir)) + \
+ pte_index(addr))
+#define pte_offset_map(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
+#define pte_unmap(pte) kunmap_atomic(pte)
+
+/*
+ * Encode and decode a swap entry.
+ * Note that the bits we use in a PTE for representing a swap entry
+ * must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used).
+ * -- paulus
+ */
+#define __swp_type(entry) ((entry).val & 0x1f)
+#define __swp_offset(entry) ((entry).val >> 5)
+#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
+
+#ifndef CONFIG_PPC_4K_PAGES
+void pgtable_cache_init(void);
+#else
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+#endif
+
+extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
+ pmd_t **pmdp);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_POWERPC_NOHASH_32_PGTABLE_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h
new file mode 100644
index 0000000..9624ebd
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h
@@ -0,0 +1,64 @@
+#ifndef _ASM_POWERPC_NOHASH_32_PTE_40x_H
+#define _ASM_POWERPC_NOHASH_32_PTE_40x_H
+#ifdef __KERNEL__
+
+/*
+ * At present, all PowerPC 400-class processors share a similar TLB
+ * architecture. The instruction and data sides share a unified,
+ * 64-entry, fully-associative TLB which is maintained totally under
+ * software control. In addition, the instruction side has a
+ * hardware-managed, 4-entry, fully-associative TLB which serves as a
+ * first level to the shared TLB. These two TLBs are known as the UTLB
+ * and ITLB, respectively (see "mmu.h" for definitions).
+ *
+ * There are several potential gotchas here. The 40x hardware TLBLO
+ * field looks like this:
+ *
+ * 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN..................... 0 0 EX WR ZSEL....... W I M G
+ *
+ * Where possible we make the Linux PTE bits match up with this
+ *
+ * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
+ * support down to 1k pages), this is done in the TLBMiss exception
+ * handler.
+ * - We use only zones 0 (for kernel pages) and 1 (for user pages)
+ * of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
+ * miss handler. Bit 27 is PAGE_USER, thus selecting the correct
+ * zone.
+ * - PRESENT *must* be in the bottom two bits because swap cache
+ * entries use the top 30 bits. Because 40x doesn't support SMP
+ * anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
+ * is cleared in the TLB miss handler before the TLB entry is loaded.
+ * - All other bits of the PTE are loaded into TLBLO without
+ * modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
+ * software PTE bits. We actually use use bits 21, 24, 25, and
+ * 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
+ * PRESENT.
+ */
+
+#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
+#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
+#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
+#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
+#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
+#define _PAGE_SPECIAL 0x020 /* software: Special page */
+#define _PAGE_RW 0x040 /* software: Writes permitted */
+#define _PAGE_DIRTY 0x080 /* software: dirty page */
+#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
+#define _PAGE_EXEC 0x200 /* hardware: EX permission */
+#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
+
+#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
+#define _PMD_BAD 0x802
+#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M 0x0c0
+#define _PMD_SIZE_16M 0x0e0
+
+#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES 1
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NOHASH_32_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-44x.h b/arch/powerpc/include/asm/nohash/32/pte-44x.h
new file mode 100644
index 0000000..fdab41c
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h
@@ -0,0 +1,97 @@
+#ifndef _ASM_POWERPC_NOHASH_32_PTE_44x_H
+#define _ASM_POWERPC_NOHASH_32_PTE_44x_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing. I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN. This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * This isn't entirely true anymore, at least some bits are now
+ * easier to move into the TLB from the PTE. -BenH.
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ * TLB1:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN................................. - - - - - - ERPN.......
+ *
+ * TLB2:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
+ *
+ * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
+ * TLB2 storage attibute fields. Those are:
+ *
+ * TLB2:
+ * 0...10 11 12 13 14 15 16...31
+ * no change WL1 IL1I IL1D IL2I IL2D no change
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ * - PRESENT *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
+ * because it doesn't support SMP. However, some later 460 variants
+ * have -some- form of SMP support and so I keep the bit there for
+ * future use
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
+ * above bits. Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ * _PAGE_PRESENT
+ * _PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
+ */
+
+#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
+#define _PAGE_RW 0x00000002 /* S: Write permission */
+#define _PAGE_EXEC 0x00000004 /* H: Execute permission */
+#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
+#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
+#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
+#define _PAGE_USER 0x00000040 /* S: User page */
+#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
+#define _PAGE_GUARDED 0x00000100 /* H: G bit */
+#define _PAGE_COHERENT 0x00000200 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NOHASH_32_PTE_44x_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
new file mode 100644
index 0000000..3742b19
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -0,0 +1,65 @@
+#ifndef _ASM_POWERPC_NOHASH_32_PTE_8xx_H
+#define _ASM_POWERPC_NOHASH_32_PTE_8xx_H
+#ifdef __KERNEL__
+
+/*
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access. The TLB does not have accessed nor write
+ * protect. We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect. We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators. Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded. We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ * Large page sizes added. We currently support two sizes, 4K and 8M.
+ * This also allows a TLB hander optimization because we can directly
+ * load the PMD into MD_TWC. The 8M pages are only used for kernel
+ * mapping of well known areas. The PMD (PGD) entries contain control
+ * flags in addition to the address, so care must be taken that the
+ * software no longer assumes these are only pointers.
+ */
+
+/* Definitions for 8xx embedded chips. */
+#define _PAGE_PRESENT 0x0001 /* Page is valid */
+#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
+#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
+#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */
+#define _PAGE_DIRTY 0x0100 /* C: page changed */
+
+/* These 4 software bits must be masked out when the L2 entry is loaded
+ * into the TLB.
+ */
+#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
+#define _PAGE_USER 0x0020 /* Copied to L1 APG lsb */
+#define _PAGE_EXEC 0x0040 /* Copied to L1 APG */
+#define _PAGE_WRITETHRU 0x0080 /* software: caching is write through */
+#define _PAGE_ACCESSED 0x0800 /* software: page referenced */
+
+#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
+
+#define _PMD_PRESENT 0x0001
+#define _PMD_BAD 0x0ff0
+#define _PMD_PAGE_MASK 0x000c
+#define _PMD_PAGE_8M 0x000c
+
+/* Until my rework is finished, 8xx still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES 1
+
+/* We need to add _PAGE_SHARED to kernel pages */
+#define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_RO)
+#define _PAGE_KERNEL_ROX (_PAGE_SHARED | _PAGE_RO | _PAGE_EXEC)
+#define _PAGE_KERNEL_RW (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
+ _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RWX (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
+ _PAGE_HWWRITE | _PAGE_EXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NOHASH_32_PTE_8xx_H */
diff --git a/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h
new file mode 100644
index 0000000..5422d00
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H
+#define _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H
+#ifdef __KERNEL__
+
+/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based
+ * processors
+ *
+ MMU Assist Register 3:
+
+ 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+ RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+ - PRESENT *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+
+*/
+
+/* Definitions for FSL Book-E Cores */
+#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
+#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
+#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
+#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
+#define _PAGE_EXEC 0x00010 /* H: SX permission */
+#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
+
+#define _PAGE_ENDIAN 0x00040 /* H: E bit */
+#define _PAGE_GUARDED 0x00080 /* H: G bit */
+#define _PAGE_COHERENT 0x00100 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
+#define _PAGE_SPECIAL 0x00800 /* S: Special page */
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+#define PTE_WIMGE_SHIFT (6)
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
new file mode 100644
index 0000000..fc7d517
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
@@ -0,0 +1,92 @@
+#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H
+#define _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H
+/*
+ * Entries per page directory level. The PTE level must use a 64b record
+ * for each page table entry. The PMD and PGD level use a 32b record for
+ * each entry by assuming that each entry is page aligned.
+ */
+#define PTE_INDEX_SIZE 9
+#define PMD_INDEX_SIZE 7
+#define PUD_INDEX_SIZE 9
+#define PGD_INDEX_SIZE 9
+
+#ifndef __ASSEMBLY__
+#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+#endif /* __ASSEMBLY__ */
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PMD_SHIFT
+
+/* PUD_SHIFT determines what a third-level page table entry can map */
+#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
+#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0
+/* Bits to mask out from a PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0
+/* Bits to mask out from a PGD to get to the PUD page */
+#define PGD_MASKED_BITS 0
+
+
+/*
+ * 4-level page tables related bits
+ */
+
+#define pgd_none(pgd) (!pgd_val(pgd))
+#define pgd_bad(pgd) (pgd_val(pgd) == 0)
+#define pgd_present(pgd) (pgd_val(pgd) != 0)
+#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS)
+
+#ifndef __ASSEMBLY__
+
+static inline void pgd_clear(pgd_t *pgdp)
+{
+ *pgdp = __pgd(0);
+}
+
+static inline pte_t pgd_pte(pgd_t pgd)
+{
+ return __pte(pgd_val(pgd));
+}
+
+static inline pgd_t pte_pgd(pte_t pte)
+{
+ return __pgd(pte_val(pte));
+}
+extern struct page *pgd_page(pgd_t pgd);
+
+#endif /* !__ASSEMBLY__ */
+
+#define pud_offset(pgdp, addr) \
+ (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
+ (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
+
+#define pud_ERROR(e) \
+ pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+
+/*
+ * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */
+#define remap_4k_pfn(vma, addr, pfn, prot) \
+ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
+
+#endif /* _ _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H */
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h
new file mode 100644
index 0000000..570fb30
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h
@@ -0,0 +1,57 @@
+#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H
+#define _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+
+#define PTE_INDEX_SIZE 8
+#define PMD_INDEX_SIZE 10
+#define PUD_INDEX_SIZE 0
+#define PGD_INDEX_SIZE 12
+
+/*
+ * we support 32 fragments per PTE page of 64K size
+ */
+#define PTE_FRAG_NR 32
+/*
+ * We use a 2K PTE page fragment and another 2K for storing
+ * real_pte_t hash index
+ */
+#define PTE_FRAG_SIZE_SHIFT 11
+#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
+
+#ifndef __ASSEMBLY__
+#define PTE_TABLE_SIZE PTE_FRAG_SIZE
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+#endif /* __ASSEMBLY__ */
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * Bits to mask out from a PMD to get to the PTE page
+ * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned.
+ */
+#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1)
+/* Bits to mask out from a PGD/PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0x1ff
+
+#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd })))
+#define pte_pgd(pte) ((pgd_t)pte_pud(pte))
+
+#endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H */
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
new file mode 100644
index 0000000..10debb9
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -0,0 +1,367 @@
+#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_H
+#define _ASM_POWERPC_NOHASH_64_PGTABLE_H
+/*
+ * This file contains the functions and defines necessary to modify and use
+ * the ppc64 hashed page table.
+ */
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/nohash/64/pgtable-64k.h>
+#else
+#include <asm/nohash/64/pgtable-4k.h>
+#endif
+#include <asm/barrier.h>
+
+#define FIRST_USER_ADDRESS 0UL
+
+/*
+ * Size of EA range mapped by our pagetables.
+ */
+#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+ PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
+#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1)
+#else
+#define PMD_CACHE_INDEX PMD_INDEX_SIZE
+#endif
+/*
+ * Define the address range of the kernel non-linear virtual area
+ */
+
+#ifdef CONFIG_PPC_BOOK3E
+#define KERN_VIRT_START ASM_CONST(0x8000000000000000)
+#else
+#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
+#endif
+#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000)
+
+/*
+ * The vmalloc space starts at the beginning of that region, and
+ * occupies half of it on hash CPUs and a quarter of it on Book3E
+ * (we keep a quarter for the virtual memmap)
+ */
+#define VMALLOC_START KERN_VIRT_START
+#ifdef CONFIG_PPC_BOOK3E
+#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 2)
+#else
+#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
+#endif
+#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
+
+/*
+ * The second half of the kernel virtual space is used for IO mappings,
+ * it's itself carved into the PIO region (ISA and PHB IO space) and
+ * the ioremap space
+ *
+ * ISA_IO_BASE = KERN_IO_START, 64K reserved area
+ * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
+ * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
+ */
+#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1))
+#define FULL_IO_SIZE 0x80000000ul
+#define ISA_IO_BASE (KERN_IO_START)
+#define ISA_IO_END (KERN_IO_START + 0x10000ul)
+#define PHB_IO_BASE (ISA_IO_END)
+#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE)
+#define IOREMAP_BASE (PHB_IO_END)
+#define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE)
+
+
+/*
+ * Region IDs
+ */
+#define REGION_SHIFT 60UL
+#define REGION_MASK (0xfUL << REGION_SHIFT)
+#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
+
+#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
+#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
+#define VMEMMAP_REGION_ID (0xfUL) /* Server only */
+#define USER_REGION_ID (0UL)
+
+/*
+ * Defines the address of the vmemap area, in its own region on
+ * hash table CPUs and after the vmalloc space on Book3E
+ */
+#ifdef CONFIG_PPC_BOOK3E
+#define VMEMMAP_BASE VMALLOC_END
+#define VMEMMAP_END KERN_IO_START
+#else
+#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT)
+#endif
+#define vmemmap ((struct page *)VMEMMAP_BASE)
+
+
+/*
+ * Include the PTE bits definitions
+ */
+#include <asm/nohash/pte-book3e.h>
+#include <asm/pte-common.h>
+
+#ifdef CONFIG_PPC_MM_SLICES
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#endif /* CONFIG_PPC_MM_SLICES */
+
+#ifndef __ASSEMBLY__
+/* pte_clear moved to later in this file */
+
+/* Pointers in the page table tree are virtual addresses */
+#define __pgtable_ptr_val(ptr) ((unsigned long)(ptr))
+
+#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
+#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
+
+static inline void pmd_set(pmd_t *pmdp, unsigned long val)
+{
+ *pmdp = __pmd(val);
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ *pmdp = __pmd(0);
+}
+
+static inline pte_t pmd_pte(pmd_t pmd)
+{
+ return __pte(pmd_val(pmd));
+}
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
+ || (pmd_val(pmd) & PMD_BAD_BITS))
+#define pmd_present(pmd) (!pmd_none(pmd))
+#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
+extern struct page *pmd_page(pmd_t pmd);
+
+static inline void pud_set(pud_t *pudp, unsigned long val)
+{
+ *pudp = __pud(val);
+}
+
+static inline void pud_clear(pud_t *pudp)
+{
+ *pudp = __pud(0);
+}
+
+#define pud_none(pud) (!pud_val(pud))
+#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
+ || (pud_val(pud) & PUD_BAD_BITS))
+#define pud_present(pud) (pud_val(pud) != 0)
+#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
+
+extern struct page *pud_page(pud_t pud);
+
+static inline pte_t pud_pte(pud_t pud)
+{
+ return __pte(pud_val(pud));
+}
+
+static inline pud_t pte_pud(pte_t pte)
+{
+ return __pud(pte_val(pte));
+}
+#define pud_write(pud) pte_write(pud_pte(pud))
+#define pgd_write(pgd) pte_write(pgd_pte(pgd))
+
+static inline void pgd_set(pgd_t *pgdp, unsigned long val)
+{
+ *pgdp = __pgd(val);
+}
+
+/*
+ * Find an entry in a page-table-directory. We combine the address region
+ * (the high order N bits) and the pgd portion of the address.
+ */
+#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
+
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+#define pmd_offset(pudp,addr) \
+ (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
+
+#define pte_offset_kernel(dir,addr) \
+ (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+
+#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_unmap(pte) do { } while(0)
+
+/* to find an entry in a kernel page-table-directory */
+/* This now only contains the vmalloc pages */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned long pte, int huge);
+
+/* Atomic PTE updates */
+static inline unsigned long pte_update(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, unsigned long clr,
+ unsigned long set,
+ int huge)
+{
+#ifdef PTE_ATOMIC_UPDATES
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%3 # pte_update\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ andc %1,%0,%4 \n\
+ or %1,%1,%7\n\
+ stdcx. %1,0,%3 \n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set)
+ : "cc" );
+#else
+ unsigned long old = pte_val(*ptep);
+ *ptep = __pte((old & ~clr) | set);
+#endif
+ /* huge pages use the old page table lock */
+ if (!huge)
+ assert_pte_locked(mm, addr);
+
+#ifdef CONFIG_PPC_STD_MMU_64
+ if (old & _PAGE_HASHPTE)
+ hpte_need_flush(mm, addr, ptep, old, huge);
+#endif
+
+ return old;
+}
+
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+
+ pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+
+ pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
+}
+
+/*
+ * We currently remove entries from the hashtable regardless of whether
+ * the entry was young or dirty. The generic routines only flush if the
+ * entry was young or dirty which is not good enough.
+ *
+ * We should be more intelligent about this but for the moment we override
+ * these functions and force a tlb flush unconditionally
+ */
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(__vma, __address, __ptep) \
+({ \
+ int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
+ __ptep); \
+ __young; \
+})
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
+ return __pte(old);
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t * ptep)
+{
+ pte_update(mm, addr, ptep, ~0UL, 0, 0);
+}
+
+
+/* Set the dirty and/or accessed bits atomically in a linux PTE, this
+ * function doesn't need to flush the hash entry
+ */
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+
+#ifdef PTE_ATOMIC_UPDATES
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%4\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ or %0,%3,%0\n\
+ stdcx. %0,0,%4\n\
+ bne- 1b"
+ :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
+ :"cc");
+#else
+ unsigned long old = pte_val(*ptep);
+ *ptep = __pte(old | bits);
+#endif
+}
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+
+#define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+ pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/* Encode and de-code a swap entry */
+#define MAX_SWAPFILES_CHECK() do { \
+ BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \
+ /* \
+ * Don't have overlapping bits with _PAGE_HPTEFLAGS \
+ * We filter HPTEFLAGS on set_pte. \
+ */ \
+ BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \
+ } while (0)
+/*
+ * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT;
+ */
+#define SWP_TYPE_BITS 5
+#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \
+ & ((1UL << SWP_TYPE_BITS) - 1))
+#define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT)
+#define __swp_entry(type, offset) ((swp_entry_t) { \
+ ((type) << _PAGE_BIT_SWAP_TYPE) \
+ | ((offset) << PTE_RPN_SHIFT) })
+
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
+#define __swp_entry_to_pte(x) __pte((x).val)
+
+void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
+void pgtable_cache_init(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_H */
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h
new file mode 100644
index 0000000..1263c22
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -0,0 +1,252 @@
+#ifndef _ASM_POWERPC_NOHASH_PGTABLE_H
+#define _ASM_POWERPC_NOHASH_PGTABLE_H
+
+#if defined(CONFIG_PPC64)
+#include <asm/nohash/64/pgtable.h>
+#else
+#include <asm/nohash/32/pgtable.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* Generic accessors to PTE bits */
+static inline int pte_write(pte_t pte)
+{
+ return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO;
+}
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
+static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
+static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
+
+#ifdef CONFIG_NUMA_BALANCING
+/*
+ * These work without NUMA balancing but the kernel does not care. See the
+ * comment in include/asm-generic/pgtable.h . On powerpc, this will only
+ * work for user pages and always return true for kernel pages.
+ */
+static inline int pte_protnone(pte_t pte)
+{
+ return (pte_val(pte) &
+ (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
+}
+
+static inline int pmd_protnone(pmd_t pmd)
+{
+ return pte_protnone(pmd_pte(pmd));
+}
+#endif /* CONFIG_NUMA_BALANCING */
+
+static inline int pte_present(pte_t pte)
+{
+ return pte_val(pte) & _PAGE_PRESENT;
+}
+
+/* Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * Even if PTEs can be unsigned long long, a PFN is always an unsigned
+ * long for now.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) {
+ return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) |
+ pgprot_val(pgprot)); }
+static inline unsigned long pte_pfn(pte_t pte) {
+ return pte_val(pte) >> PTE_RPN_SHIFT; }
+
+/* Generic modifiers for PTE bits */
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ pte_basic_t ptev;
+
+ ptev = pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE);
+ ptev |= _PAGE_RO;
+ return __pte(ptev);
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE));
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ pte_basic_t ptev;
+
+ ptev = pte_val(pte) & ~_PAGE_RO;
+ ptev |= _PAGE_RW;
+ return __pte(ptev);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SPECIAL);
+}
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+ return pte;
+}
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+/* Insert a PTE, top-level function is out of line. It uses an inline
+ * low level function in the respective pgtable-* files
+ */
+extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte);
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int percpu)
+{
+#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
+ /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
+ * helper pte_update() which does an atomic update. We need to do that
+ * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
+ * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
+ * the hash bits instead (ie, same as the non-SMP case)
+ */
+ if (percpu)
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ else
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
+
+#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+ /* Second case is 32-bit with 64-bit PTE. In this case, we
+ * can just store as long as we do the two halves in the right order
+ * with a barrier in between. This is possible because we take care,
+ * in the hash code, to pre-invalidate if the PTE was already hashed,
+ * which synchronizes us with any concurrent invalidation.
+ * In the percpu case, we also fallback to the simple update preserving
+ * the hash bits
+ */
+ if (percpu) {
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ return;
+ }
+#if _PAGE_HASHPTE != 0
+ if (pte_val(*ptep) & _PAGE_HASHPTE)
+ flush_hash_entry(mm, ptep, addr);
+#endif
+ __asm__ __volatile__("\
+ stw%U0%X0 %2,%0\n\
+ eieio\n\
+ stw%U0%X0 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+
+#elif defined(CONFIG_PPC_STD_MMU_32)
+ /* Third case is 32-bit hash table in UP mode, we need to preserve
+ * the _PAGE_HASHPTE bit since we may not have invalidated the previous
+ * translation in the hash yet (done in a subsequent flush_tlb_xxx())
+ * and see we need to keep track that this PTE needs invalidating
+ */
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+
+#else
+ /* Anything else just stores the PTE normally. That covers all 64-bit
+ * cases, and 32-bit non-hash with 32-bit PTEs.
+ */
+ *ptep = pte;
+
+#ifdef CONFIG_PPC_BOOK3E_64
+ /*
+ * With hardware tablewalk, a sync is needed to ensure that
+ * subsequent accesses see the PTE we just wrote. Unlike userspace
+ * mappings, we can't tolerate spurious faults, so make sure
+ * the new PTE will be seen the first time.
+ */
+ if (is_kernel_addr(addr))
+ mb();
+#endif
+#endif
+}
+
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty);
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU)
+
+#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_NO_CACHE))
+
+#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_COHERENT))
+
+#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_COHERENT | _PAGE_WRITETHRU))
+
+#define pgprot_cached_noncoherent(prot) \
+ (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL))
+
+#define pgprot_writecombine pgprot_noncached_wc
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#ifdef CONFIG_HUGETLB_PAGE
+static inline int hugepd_ok(hugepd_t hpd)
+{
+ return (hpd.pd > 0);
+}
+
+static inline int pmd_huge(pmd_t pmd)
+{
+ return 0;
+}
+
+static inline int pud_huge(pud_t pud)
+{
+ return 0;
+}
+
+static inline int pgd_huge(pgd_t pgd)
+{
+ return 0;
+}
+#define pgd_huge pgd_huge
+
+#define is_hugepd(hpd) (hugepd_ok(hpd))
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h
new file mode 100644
index 0000000..e16807b
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/pte-book3e.h
@@ -0,0 +1,87 @@
+#ifndef _ASM_POWERPC_NOHASH_PTE_BOOK3E_H
+#define _ASM_POWERPC_NOHASH_PTE_BOOK3E_H
+#ifdef __KERNEL__
+
+/* PTE bit definitions for processors compliant to the Book3E
+ * architecture 2.06 or later. The position of the PTE bits
+ * matches the HW definition of the optional Embedded Page Table
+ * category.
+ */
+
+/* Architected bits */
+#define _PAGE_PRESENT 0x000001 /* software: pte contains a translation */
+#define _PAGE_SW1 0x000002
+#define _PAGE_BIT_SWAP_TYPE 2
+#define _PAGE_BAP_SR 0x000004
+#define _PAGE_BAP_UR 0x000008
+#define _PAGE_BAP_SW 0x000010
+#define _PAGE_BAP_UW 0x000020
+#define _PAGE_BAP_SX 0x000040
+#define _PAGE_BAP_UX 0x000080
+#define _PAGE_PSIZE_MSK 0x000f00
+#define _PAGE_PSIZE_4K 0x000200
+#define _PAGE_PSIZE_8K 0x000300
+#define _PAGE_PSIZE_16K 0x000400
+#define _PAGE_PSIZE_32K 0x000500
+#define _PAGE_PSIZE_64K 0x000600
+#define _PAGE_PSIZE_128K 0x000700
+#define _PAGE_PSIZE_256K 0x000800
+#define _PAGE_PSIZE_512K 0x000900
+#define _PAGE_PSIZE_1M 0x000a00
+#define _PAGE_PSIZE_2M 0x000b00
+#define _PAGE_PSIZE_4M 0x000c00
+#define _PAGE_PSIZE_8M 0x000d00
+#define _PAGE_PSIZE_16M 0x000e00
+#define _PAGE_PSIZE_32M 0x000f00
+#define _PAGE_DIRTY 0x001000 /* C: page changed */
+#define _PAGE_SW0 0x002000
+#define _PAGE_U3 0x004000
+#define _PAGE_U2 0x008000
+#define _PAGE_U1 0x010000
+#define _PAGE_U0 0x020000
+#define _PAGE_ACCESSED 0x040000
+#define _PAGE_ENDIAN 0x080000
+#define _PAGE_GUARDED 0x100000
+#define _PAGE_COHERENT 0x200000 /* M: enforce memory coherence */
+#define _PAGE_NO_CACHE 0x400000 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
+
+/* "Higher level" linux bit combinations */
+#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */
+#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
+#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
+#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
+#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX)
+#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
+
+#define _PAGE_HASHPTE 0
+#define _PAGE_BUSY 0
+
+#define _PAGE_SPECIAL _PAGE_SW0
+
+/* Flags to be preserved on PTE modifications */
+#define _PAGE_HPTEFLAGS _PAGE_BUSY
+
+/* Base page size */
+#ifdef CONFIG_PPC_64K_PAGES
+#define _PAGE_PSIZE _PAGE_PSIZE_64K
+#define PTE_RPN_SHIFT (28)
+#else
+#define _PAGE_PSIZE _PAGE_PSIZE_4K
+#define PTE_RPN_SHIFT (24)
+#endif
+
+#define PTE_WIMGE_SHIFT (19)
+#define PTE_BAP_SHIFT (2)
+
+/* On 32-bit, we never clear the top part of the PTE */
+#ifdef CONFIG_PPC32
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NOHASH_PTE_BOOK3E_H */
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 8374afe..f8faaae 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -157,7 +157,8 @@
#define OPAL_LEDS_GET_INDICATOR 114
#define OPAL_LEDS_SET_INDICATOR 115
#define OPAL_CEC_REBOOT2 116
-#define OPAL_LAST 116
+#define OPAL_CONSOLE_FLUSH 117
+#define OPAL_LAST 117
/* Device tree flags */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 8001159..9d86c66 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -35,6 +35,7 @@ int64_t opal_console_read(int64_t term_number, __be64 *length,
uint8_t *buffer);
int64_t opal_console_write_buffer_space(int64_t term_number,
__be64 *length);
+int64_t opal_console_flush(int64_t term_number);
int64_t opal_rtc_read(__be32 *year_month_day,
__be64 *hour_minute_second_millisecond);
int64_t opal_rtc_write(uint32_t year_month_day,
@@ -247,6 +248,7 @@ extern int opal_elog_init(void);
extern void opal_platform_dump_init(void);
extern void opal_sys_param_init(void);
extern void opal_msglog_init(void);
+extern void opal_msglog_sysfs_init(void);
extern int opal_async_comp_init(void);
extern int opal_sensor_init(void);
extern int opal_hmi_handler_init(void);
@@ -262,6 +264,8 @@ extern int opal_resync_timebase(void);
extern void opal_lpc_init(void);
+extern void opal_kmsg_init(void);
+
extern int opal_event_request(unsigned int opal_event_nr);
struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
@@ -270,6 +274,8 @@ void opal_free_sg_list(struct opal_sg_list *sg);
extern int opal_error_code(int rc);
+ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_OPAL_H */
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 70bd438..546540b 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -16,6 +16,7 @@
#ifdef CONFIG_PPC64
+#include <linux/string.h>
#include <asm/types.h>
#include <asm/lppaca.h>
#include <asm/mmu.h>
@@ -131,7 +132,16 @@ struct paca_struct {
struct tlb_core_data tcd;
#endif /* CONFIG_PPC_BOOK3E */
- mm_context_t context;
+#ifdef CONFIG_PPC_BOOK3S
+ mm_context_id_t mm_ctx_id;
+#ifdef CONFIG_PPC_MM_SLICES
+ u64 mm_ctx_low_slices_psize;
+ unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
+#else
+ u16 mm_ctx_user_psize;
+ u16 mm_ctx_sllp;
+#endif
+#endif
/*
* then miscellaneous read-write fields
@@ -194,6 +204,23 @@ struct paca_struct {
#endif
};
+#ifdef CONFIG_PPC_BOOK3S
+static inline void copy_mm_to_paca(mm_context_t *context)
+{
+ get_paca()->mm_ctx_id = context->id;
+#ifdef CONFIG_PPC_MM_SLICES
+ get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize;
+ memcpy(&get_paca()->mm_ctx_high_slices_psize,
+ &context->high_slices_psize, SLICE_ARRAY_SIZE);
+#else
+ get_paca()->mm_ctx_user_psize = context->user_psize;
+ get_paca()->mm_ctx_sllp = context->sllp;
+#endif
+}
+#else
+static inline void copy_mm_to_paca(mm_context_t *context){}
+#endif
+
extern struct paca_struct *paca;
extern void initialise_paca(struct paca_struct *new_paca, int cpu);
extern void setup_paca(struct paca_struct *new_paca);
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 71294a6..ab3d897 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -12,6 +12,7 @@
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#include <linux/kernel.h>
#else
#include <asm/types.h>
#endif
@@ -107,12 +108,13 @@ extern long long virt_phys_offset;
#endif
/* See Description below for VIRT_PHYS_OFFSET */
-#ifdef CONFIG_RELOCATABLE_PPC32
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+#ifdef CONFIG_RELOCATABLE
#define VIRT_PHYS_OFFSET virt_phys_offset
#else
#define VIRT_PHYS_OFFSET (KERNELBASE - PHYSICAL_START)
#endif
-
+#endif
#ifdef CONFIG_PPC64
#define MEMORY_START 0UL
@@ -127,9 +129,10 @@ extern long long virt_phys_offset;
#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr)
#endif
-#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
-#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr))
/*
* On Book-E parts we need __va to parse the device tree and we can't
@@ -204,7 +207,7 @@ extern long long virt_phys_offset;
* On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
* the other definitions for __va & __pa.
*/
-#ifdef CONFIG_BOOKE
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET))
#define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET)
#else
@@ -240,8 +243,8 @@ extern long long virt_phys_offset;
#endif
/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
+#define _ALIGN_UP(addr, size) __ALIGN_KERNEL(addr, size)
+#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
@@ -268,6 +271,13 @@ extern long long virt_phys_offset;
#else
#define PD_HUGE 0x80000000
#endif
+
+#else /* CONFIG_PPC_BOOK3S_64 */
+/*
+ * Book3S 64 stores real addresses in the hugepd entries to
+ * avoid overlaps with _PAGE_PRESENT and _PAGE_PTE.
+ */
+#define HUGEPD_ADDR_MASK (0x0ffffffffffffffful & ~HUGEPD_SHIFT_MASK)
#endif /* CONFIG_PPC_BOOK3S_64 */
/*
@@ -278,112 +288,15 @@ extern long long virt_phys_offset;
#ifndef __ASSEMBLY__
-#ifdef CONFIG_STRICT_MM_TYPECHECKS
-/* These are used to make use of C type-checking. */
-
-/* PTE level */
-typedef struct { pte_basic_t pte; } pte_t;
-#define pte_val(x) ((x).pte)
-#define __pte(x) ((pte_t) { (x) })
-
-/* 64k pages additionally define a bigger "real PTE" type that gathers
- * the "second half" part of the PTE for pseudo 64k pages
- */
-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
-typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
-#else
-typedef struct { pte_t pte; } real_pte_t;
-#endif
-
-/* PMD level */
-#ifdef CONFIG_PPC64
-typedef struct { unsigned long pmd; } pmd_t;
-#define pmd_val(x) ((x).pmd)
-#define __pmd(x) ((pmd_t) { (x) })
-
-/* PUD level exusts only on 4k pages */
-#ifndef CONFIG_PPC_64K_PAGES
-typedef struct { unsigned long pud; } pud_t;
-#define pud_val(x) ((x).pud)
-#define __pud(x) ((pud_t) { (x) })
-#endif /* !CONFIG_PPC_64K_PAGES */
-#endif /* CONFIG_PPC64 */
-
-/* PGD level */
-typedef struct { unsigned long pgd; } pgd_t;
-#define pgd_val(x) ((x).pgd)
-#define __pgd(x) ((pgd_t) { (x) })
-
-/* Page protection bits */
-typedef struct { unsigned long pgprot; } pgprot_t;
-#define pgprot_val(x) ((x).pgprot)
-#define __pgprot(x) ((pgprot_t) { (x) })
-
-#else
-
-/*
- * .. while these make it easier on the compiler
- */
-
-typedef pte_basic_t pte_t;
-#define pte_val(x) (x)
-#define __pte(x) (x)
-
-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
-typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
-#else
-typedef pte_t real_pte_t;
-#endif
-
-
-#ifdef CONFIG_PPC64
-typedef unsigned long pmd_t;
-#define pmd_val(x) (x)
-#define __pmd(x) (x)
-
-#ifndef CONFIG_PPC_64K_PAGES
-typedef unsigned long pud_t;
-#define pud_val(x) (x)
-#define __pud(x) (x)
-#endif /* !CONFIG_PPC_64K_PAGES */
-#endif /* CONFIG_PPC64 */
-
-typedef unsigned long pgd_t;
-#define pgd_val(x) (x)
-#define pgprot_val(x) (x)
-
-typedef unsigned long pgprot_t;
-#define __pgd(x) (x)
-#define __pgprot(x) (x)
-
-#endif
+#include <asm/pgtable-types.h>
typedef struct { signed long pd; } hugepd_t;
-#ifdef CONFIG_HUGETLB_PAGE
-#ifdef CONFIG_PPC_BOOK3S_64
-static inline int hugepd_ok(hugepd_t hpd)
-{
- /*
- * hugepd pointer, bottom two bits == 00 and next 4 bits
- * indicate size of table
- */
- return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0));
-}
-#else
-static inline int hugepd_ok(hugepd_t hpd)
-{
- return (hpd.pd > 0);
-}
-#endif
-
-#define is_hugepd(hpd) (hugepd_ok(hpd))
-#define pgd_huge pgd_huge
-int pgd_huge(pgd_t pgd);
-#else /* CONFIG_HUGETLB_PAGE */
-#define is_hugepd(pdep) 0
-#define pgd_huge(pgd) 0
+#ifndef CONFIG_HUGETLB_PAGE
+#define is_hugepd(pdep) (0)
+#define pgd_huge(pgd) (0)
#endif /* CONFIG_HUGETLB_PAGE */
+
#define __hugepd(x) ((hugepd_t) { (x) })
struct page;
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
index 68d73b2..6a8e179 100644
--- a/arch/powerpc/include/asm/page_32.h
+++ b/arch/powerpc/include/asm/page_32.h
@@ -1,6 +1,8 @@
#ifndef _ASM_POWERPC_PAGE_32_H
#define _ASM_POWERPC_PAGE_32_H
+#include <asm/cache.h>
+
#if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0)
#if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0
#error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN"
@@ -36,9 +38,18 @@ typedef unsigned long long pte_basic_t;
typedef unsigned long pte_basic_t;
#endif
-struct page;
-extern void clear_pages(void *page, int order);
-static inline void clear_page(void *page) { clear_pages(page, 0); }
+/*
+ * Clear page using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced). This only works on cacheable memory.
+ */
+static inline void clear_page(void *addr)
+{
+ unsigned int i;
+
+ for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES)
+ dcbz(addr);
+}
extern void copy_page(void *to, void *from);
#include <asm-generic/getorder.h>
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 37fc535..f5056e3 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -10,7 +10,6 @@
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/ioport.h>
-#include <asm-generic/pci-bridge.h>
struct device_node;
@@ -205,21 +204,23 @@ struct pci_dn {
int pci_ext_config_space; /* for pci devices */
+ struct pci_dev *pcidev; /* back-pointer to the pci device */
#ifdef CONFIG_EEH
struct eeh_dev *edev; /* eeh device */
#endif
#define IODA_INVALID_PE (-1)
#ifdef CONFIG_PPC_POWERNV
int pe_number;
+ int vf_index; /* VF index in the PF */
#ifdef CONFIG_PCI_IOV
u16 vfs_expanded; /* number of VFs IOV BAR expanded */
u16 num_vfs; /* number of VFs enabled*/
- int offset; /* PE# for the first VF PE */
-#define M64_PER_IOV 4
- int m64_per_iov;
+ int *pe_num_map; /* PE# for the first VF PE or array */
+ bool m64_single_mode; /* Use M64 BAR in Single Mode */
#define IODA_INVALID_M64 (-1)
- int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+ int (*m64_map)[PCI_SRIOV_NUM_BARS];
#endif /* CONFIG_PCI_IOV */
+ int mps; /* Maximum Payload Size */
#endif
struct list_head child_list;
struct list_head list;
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 3453bd8..a6f3ac0 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -20,8 +20,6 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
-#include <asm-generic/pci-dma-compat.h>
-
/* Return values for pci_controller_ops.probe_mode function */
#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
@@ -149,4 +147,8 @@ extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
extern void pcibios_scan_phb(struct pci_controller *hose);
#endif /* __KERNEL__ */
+
+extern struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev);
+extern struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index);
+
#endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 8146221..e157489 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -136,16 +136,24 @@ extern ssize_t power_events_sysfs_show(struct device *dev,
* event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and
* 'PM_CYC' where the latter is the name by which the event is known in
* POWER CPU specification.
+ *
+ * Similarly, some hardware and cache events use the same event code. Eg.
+ * on POWER8, both "cache-references" and "L1-dcache-loads" events refer
+ * to the same event, PM_LD_REF_L1. The suffix, allows us to have two
+ * sysfs objects for the same event and thus two entries/aliases in sysfs.
*/
#define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix
#define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr
#define EVENT_ATTR(_name, _id, _suffix) \
- PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \
+ PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), _id, \
power_events_sysfs_show)
#define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g)
#define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g)
+#define CACHE_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _c)
+#define CACHE_EVENT_PTR(_id) EVENT_PTR(_id, _c)
+
#define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p)
#define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p)
diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h
index 842846c..76d6b9e 100644
--- a/arch/powerpc/include/asm/pgalloc-32.h
+++ b/arch/powerpc/include/asm/pgalloc-32.h
@@ -21,16 +21,34 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
/* #define pgd_populate(mm, pmd, pte) BUG() */
#ifndef CONFIG_BOOKE
-#define pmd_populate_kernel(mm, pmd, pte) \
- (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
-#define pmd_populate(mm, pmd, pte) \
- (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
+ pte_t *pte)
+{
+ *pmdp = __pmd(__pa(pte) | _PMD_PRESENT);
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pte_page)
+{
+ *pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT);
+}
+
#define pmd_pgtable(pmd) pmd_page(pmd)
#else
-#define pmd_populate_kernel(mm, pmd, pte) \
- (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
-#define pmd_populate(mm, pmd, pte) \
- (pmd_val(*(pmd)) = (unsigned long)lowmem_page_address(pte) | _PMD_PRESENT)
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
+ pte_t *pte)
+{
+ *pmdp = __pmd((unsigned long)pte | _PMD_PRESENT);
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pte_page)
+{
+ *pmdp = __pmd((unsigned long)lowmem_page_address(pte_page) | _PMD_PRESENT);
+}
+
#define pmd_pgtable(pmd) pmd_page(pmd)
#endif
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index 4b0be20..8d5fc3a 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -53,7 +53,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
#ifndef CONFIG_PPC_64K_PAGES
-#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
+#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, __pgtable_ptr_val(PUD))
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
{
@@ -68,12 +68,21 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
{
- pud_set(pud, (unsigned long)pmd);
+ pud_set(pud, __pgtable_ptr_val(pmd));
+}
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ pmd_set(pmd, __pgtable_ptr_val(pte));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+ pgtable_t pte_page)
+{
+ pmd_set(pmd, __pgtable_ptr_val(page_address(pte_page)));
}
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
#define pmd_pgtable(pmd) pmd_page(pmd)
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
@@ -154,16 +163,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
}
#else /* if CONFIG_PPC_64K_PAGES */
-/*
- * we support 16 fragments per PTE page.
- */
-#define PTE_FRAG_NR 16
-/*
- * We use a 2K PTE page fragment and another 2K for storing
- * real_pte_t hash index
- */
-#define PTE_FRAG_SIZE_SHIFT 12
-#define PTE_FRAG_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t))
extern pte_t *page_table_alloc(struct mm_struct *, unsigned long, int);
extern void page_table_free(struct mm_struct *, unsigned long *, int);
@@ -172,23 +171,45 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
extern void __tlb_remove_table(void *_table);
#endif
-#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
+#ifndef __PAGETABLE_PUD_FOLDED
+/* book3s 64 is 4 level page table */
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+{
+ pgd_set(pgd, __pgtable_ptr_val(pud));
+}
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+ kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
+}
+#endif
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ pud_set(pud, __pgtable_ptr_val(pmd));
+}
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
{
- pmd_set(pmd, (unsigned long)pte);
+ pmd_set(pmd, __pgtable_ptr_val(pte));
}
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
pgtable_t pte_page)
{
- pmd_set(pmd, (unsigned long)pte_page);
+ pmd_set(pmd, __pgtable_ptr_val(pte_page));
}
static inline pgtable_t pmd_pgtable(pmd_t pmd)
{
- return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS);
+ return (pgtable_t)pmd_page_vaddr(pmd);
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
@@ -234,11 +255,11 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
#define __pmd_free_tlb(tlb, pmd, addr) \
pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX)
-#ifndef CONFIG_PPC_64K_PAGES
+#ifndef __PAGETABLE_PUD_FOLDED
#define __pud_free_tlb(tlb, pud, addr) \
pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
-#endif /* CONFIG_PPC_64K_PAGES */
+#endif /* __PAGETABLE_PUD_FOLDED */
#define check_pgt_cache() do { } while (0)
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
deleted file mode 100644
index 9c32656..0000000
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ /dev/null
@@ -1,340 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_PPC32_H
-#define _ASM_POWERPC_PGTABLE_PPC32_H
-
-#include <asm-generic/pgtable-nopmd.h>
-
-#ifndef __ASSEMBLY__
-#include <linux/sched.h>
-#include <linux/threads.h>
-#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
-
-extern unsigned long ioremap_bot;
-
-#ifdef CONFIG_44x
-extern int icache_44x_need_flush;
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * The normal case is that PTEs are 32-bits and we have a 1-page
- * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
- *
- * For any >32-bit physical address platform, we can use the following
- * two level page table layout where the pgdir is 8KB and the MS 13 bits
- * are an index to the second level table. The combined pgdir/pmd first
- * level has 2048 entries and the second level has 512 64-bit PTE entries.
- * -Matt
- */
-/* PGDIR_SHIFT determines what a top-level page table entry can map */
-#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-
-/*
- * entries per page directory level: our page-table tree is two-level, so
- * we don't really have any PMD directory.
- */
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_SHIFT)
-#define PGD_TABLE_SIZE (sizeof(pgd_t) << (32 - PGDIR_SHIFT))
-#endif /* __ASSEMBLY__ */
-
-#define PTRS_PER_PTE (1 << PTE_SHIFT)
-#define PTRS_PER_PMD 1
-#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
-
-#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
-#define FIRST_USER_ADDRESS 0UL
-
-#define pte_ERROR(e) \
- pr_err("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \
- (unsigned long long)pte_val(e))
-#define pgd_ERROR(e) \
- pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-/*
- * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
- * value (for now) on others, from where we can start layout kernel
- * virtual space that goes below PKMAP and FIXMAP
- */
-#ifdef CONFIG_HIGHMEM
-#define KVIRT_TOP PKMAP_BASE
-#else
-#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
-#endif
-
-/*
- * ioremap_bot starts at that address. Early ioremaps move down from there,
- * until mem_init() at which point this becomes the top of the vmalloc
- * and ioremap space
- */
-#ifdef CONFIG_NOT_COHERENT_CACHE
-#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK)
-#else
-#define IOREMAP_TOP KVIRT_TOP
-#endif
-
-/*
- * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 16MB value just means that there will be a 64MB "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. ;)
- *
- * We no longer map larger than phys RAM with the BATs so we don't have
- * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
- * about clashes between our early calls to ioremap() that start growing down
- * from ioremap_base being run into the VM area allocations (growing upwards
- * from VMALLOC_START). For this reason we have ioremap_bot to check when
- * we actually run into our mappings setup in the early boot with the VM
- * system. This really does become a problem for machines with good amounts
- * of RAM. -- Cort
- */
-#define VMALLOC_OFFSET (0x1000000) /* 16M */
-#ifdef PPC_PIN_SIZE
-#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
-#else
-#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
-#endif
-#define VMALLOC_END ioremap_bot
-
-/*
- * Bits in a linux-style PTE. These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible.
- */
-
-#if defined(CONFIG_40x)
-#include <asm/pte-40x.h>
-#elif defined(CONFIG_44x)
-#include <asm/pte-44x.h>
-#elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
-#include <asm/pte-book3e.h>
-#elif defined(CONFIG_FSL_BOOKE)
-#include <asm/pte-fsl-booke.h>
-#elif defined(CONFIG_8xx)
-#include <asm/pte-8xx.h>
-#else /* CONFIG_6xx */
-#include <asm/pte-hash32.h>
-#endif
-
-/* And here we include common definitions */
-#include <asm/pte-common.h>
-
-#ifndef __ASSEMBLY__
-
-#define pte_clear(mm, addr, ptep) \
- do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
-
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
-#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
-#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0)
-
-/*
- * When flushing the tlb entry for a page, we also need to flush the hash
- * table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
- */
-extern int flush_hash_pages(unsigned context, unsigned long va,
- unsigned long pmdval, int count);
-
-/* Add an HPTE to the hash table */
-extern void add_hash_page(unsigned context, unsigned long va,
- unsigned long pmdval);
-
-/* Flush an entry from the TLB/hash table */
-extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
- unsigned long address);
-
-/*
- * PTE updates. This function is called whenever an existing
- * valid PTE is updated. This does -not- include set_pte_at()
- * which nowadays only sets a new PTE.
- *
- * Depending on the type of MMU, we may need to use atomic updates
- * and the PTE may be either 32 or 64 bit wide. In the later case,
- * when using atomic updates, only the low part of the PTE is
- * accessed atomically.
- *
- * In addition, on 44x, we also maintain a global flag indicating
- * that an executable user mapping was modified, which is needed
- * to properly flush the virtually tagged instruction cache of
- * those implementations.
- */
-#ifndef CONFIG_PTE_64BIT
-static inline unsigned long pte_update(pte_t *p,
- unsigned long clr,
- unsigned long set)
-{
-#ifdef PTE_ATOMIC_UPDATES
- unsigned long old, tmp;
-
- __asm__ __volatile__("\
-1: lwarx %0,0,%3\n\
- andc %1,%0,%4\n\
- or %1,%1,%5\n"
- PPC405_ERR77(0,%3)
-" stwcx. %1,0,%3\n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*p)
- : "r" (p), "r" (clr), "r" (set), "m" (*p)
- : "cc" );
-#else /* PTE_ATOMIC_UPDATES */
- unsigned long old = pte_val(*p);
- *p = __pte((old & ~clr) | set);
-#endif /* !PTE_ATOMIC_UPDATES */
-
-#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
- icache_44x_need_flush = 1;
-#endif
- return old;
-}
-#else /* CONFIG_PTE_64BIT */
-static inline unsigned long long pte_update(pte_t *p,
- unsigned long clr,
- unsigned long set)
-{
-#ifdef PTE_ATOMIC_UPDATES
- unsigned long long old;
- unsigned long tmp;
-
- __asm__ __volatile__("\
-1: lwarx %L0,0,%4\n\
- lwzx %0,0,%3\n\
- andc %1,%L0,%5\n\
- or %1,%1,%6\n"
- PPC405_ERR77(0,%3)
-" stwcx. %1,0,%4\n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*p)
- : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
- : "cc" );
-#else /* PTE_ATOMIC_UPDATES */
- unsigned long long old = pte_val(*p);
- *p = __pte((old & ~(unsigned long long)clr) | set);
-#endif /* !PTE_ATOMIC_UPDATES */
-
-#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
- icache_44x_need_flush = 1;
-#endif
- return old;
-}
-#endif /* CONFIG_PTE_64BIT */
-
-/*
- * 2.6 calls this without flushing the TLB entry; this is wrong
- * for our hash-based implementation, we fix that up here.
- */
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
- old = pte_update(ptep, _PAGE_ACCESSED, 0);
-#if _PAGE_HASHPTE != 0
- if (old & _PAGE_HASHPTE) {
- unsigned long ptephys = __pa(ptep) & PAGE_MASK;
- flush_hash_pages(context, addr, ptephys, 1);
- }
-#endif
- return (old & _PAGE_ACCESSED) != 0;
-}
-#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
- __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
-
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
- return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
-}
-
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
- pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
-}
-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 void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
-{
- unsigned long set = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
- unsigned long clr = ~pte_val(entry) & _PAGE_RO;
-
- pte_update(ptep, clr, set);
-}
-
-#define __HAVE_ARCH_PTE_SAME
-#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
-
-/*
- * Note that on Book E processors, the pmd contains the kernel virtual
- * (lowmem) address of the pte page. The physical address is less useful
- * because everything runs with translation enabled (even the TLB miss
- * handler). On everything else the pmd contains the physical address
- * of the pte page. -- paulus
- */
-#ifndef CONFIG_BOOKE
-#define pmd_page_vaddr(pmd) \
- ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-#define pmd_page(pmd) \
- pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
-#else
-#define pmd_page_vaddr(pmd) \
- ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
-#define pmd_page(pmd) \
- pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT))
-#endif
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
-/* to find an entry in a page-table-directory */
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-
-/* Find an entry in the third-level page table.. */
-#define pte_index(address) \
- (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-#define pte_offset_kernel(dir, addr) \
- ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
-#define pte_offset_map(dir, addr) \
- ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
-#define pte_unmap(pte) kunmap_atomic(pte)
-
-/*
- * Encode and decode a swap entry.
- * Note that the bits we use in a PTE for representing a swap entry
- * must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used).
- * -- paulus
- */
-#define __swp_type(entry) ((entry).val & 0x1f)
-#define __swp_offset(entry) ((entry).val >> 5)
-#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
-
-#ifndef CONFIG_PPC_4K_PAGES
-void pgtable_cache_init(void);
-#else
-/*
- * No page table caches to initialise
- */
-#define pgtable_cache_init() do { } while (0)
-#endif
-
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
- pmd_t **pmdp);
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_POWERPC_PGTABLE_PPC32_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
deleted file mode 100644
index 132ee1d..0000000
--- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_PPC64_4K_H
-#define _ASM_POWERPC_PGTABLE_PPC64_4K_H
-/*
- * Entries per page directory level. The PTE level must use a 64b record
- * for each page table entry. The PMD and PGD level use a 32b record for
- * each entry by assuming that each entry is page aligned.
- */
-#define PTE_INDEX_SIZE 9
-#define PMD_INDEX_SIZE 7
-#define PUD_INDEX_SIZE 9
-#define PGD_INDEX_SIZE 9
-
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
-#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
-#endif /* __ASSEMBLY__ */
-
-#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
-#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT PMD_SHIFT
-
-/* PUD_SHIFT determines what a third-level page table entry can map */
-#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
-#define PUD_SIZE (1UL << PUD_SHIFT)
-#define PUD_MASK (~(PUD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
-#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-
-/* Bits to mask out from a PMD to get to the PTE page */
-#define PMD_MASKED_BITS 0
-/* Bits to mask out from a PUD to get to the PMD page */
-#define PUD_MASKED_BITS 0
-/* Bits to mask out from a PGD to get to the PUD page */
-#define PGD_MASKED_BITS 0
-
-
-/*
- * 4-level page tables related bits
- */
-
-#define pgd_none(pgd) (!pgd_val(pgd))
-#define pgd_bad(pgd) (pgd_val(pgd) == 0)
-#define pgd_present(pgd) (pgd_val(pgd) != 0)
-#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0)
-#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS)
-
-#ifndef __ASSEMBLY__
-
-static inline pte_t pgd_pte(pgd_t pgd)
-{
- return __pte(pgd_val(pgd));
-}
-
-static inline pgd_t pte_pgd(pte_t pte)
-{
- return __pgd(pte_val(pte));
-}
-extern struct page *pgd_page(pgd_t pgd);
-
-#endif /* !__ASSEMBLY__ */
-
-#define pud_offset(pgdp, addr) \
- (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
- (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
-
-#define pud_ERROR(e) \
- pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
-
-/*
- * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */
-#define remap_4k_pfn(vma, addr, pfn, prot) \
- remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
-
-#endif /* _ASM_POWERPC_PGTABLE_PPC64_4K_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
deleted file mode 100644
index 1de35bbd..0000000
--- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_PPC64_64K_H
-#define _ASM_POWERPC_PGTABLE_PPC64_64K_H
-
-#include <asm-generic/pgtable-nopud.h>
-
-
-#define PTE_INDEX_SIZE 8
-#define PMD_INDEX_SIZE 10
-#define PUD_INDEX_SIZE 0
-#define PGD_INDEX_SIZE 12
-
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
-#endif /* __ASSEMBLY__ */
-
-#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
-
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-
-/* Bits to mask out from a PMD to get to the PTE page */
-/* PMDs point to PTE table fragments which are 4K aligned. */
-#define PMD_MASKED_BITS 0xfff
-/* Bits to mask out from a PGD/PUD to get to the PMD page */
-#define PUD_MASKED_BITS 0x1ff
-
-#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd })))
-#define pte_pgd(pte) ((pgd_t)pte_pud(pte))
-
-#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
deleted file mode 100644
index fa1dfb7..0000000
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ /dev/null
@@ -1,618 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_PPC64_H_
-#define _ASM_POWERPC_PGTABLE_PPC64_H_
-/*
- * This file contains the functions and defines necessary to modify and use
- * the ppc64 hashed page table.
- */
-
-#ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pgtable-ppc64-64k.h>
-#else
-#include <asm/pgtable-ppc64-4k.h>
-#endif
-#include <asm/barrier.h>
-
-#define FIRST_USER_ADDRESS 0UL
-
-/*
- * Size of EA range mapped by our pagetables.
- */
-#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
- PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
-#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#define PMD_CACHE_INDEX (PMD_INDEX_SIZE + 1)
-#else
-#define PMD_CACHE_INDEX PMD_INDEX_SIZE
-#endif
-/*
- * Define the address range of the kernel non-linear virtual area
- */
-
-#ifdef CONFIG_PPC_BOOK3E
-#define KERN_VIRT_START ASM_CONST(0x8000000000000000)
-#else
-#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
-#endif
-#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000)
-
-/*
- * The vmalloc space starts at the beginning of that region, and
- * occupies half of it on hash CPUs and a quarter of it on Book3E
- * (we keep a quarter for the virtual memmap)
- */
-#define VMALLOC_START KERN_VIRT_START
-#ifdef CONFIG_PPC_BOOK3E
-#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 2)
-#else
-#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
-#endif
-#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
-
-/*
- * The second half of the kernel virtual space is used for IO mappings,
- * it's itself carved into the PIO region (ISA and PHB IO space) and
- * the ioremap space
- *
- * ISA_IO_BASE = KERN_IO_START, 64K reserved area
- * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
- * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
- */
-#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1))
-#define FULL_IO_SIZE 0x80000000ul
-#define ISA_IO_BASE (KERN_IO_START)
-#define ISA_IO_END (KERN_IO_START + 0x10000ul)
-#define PHB_IO_BASE (ISA_IO_END)
-#define PHB_IO_END (KERN_IO_START + FULL_IO_SIZE)
-#define IOREMAP_BASE (PHB_IO_END)
-#define IOREMAP_END (KERN_VIRT_START + KERN_VIRT_SIZE)
-
-
-/*
- * Region IDs
- */
-#define REGION_SHIFT 60UL
-#define REGION_MASK (0xfUL << REGION_SHIFT)
-#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
-
-#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
-#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
-#define VMEMMAP_REGION_ID (0xfUL) /* Server only */
-#define USER_REGION_ID (0UL)
-
-/*
- * Defines the address of the vmemap area, in its own region on
- * hash table CPUs and after the vmalloc space on Book3E
- */
-#ifdef CONFIG_PPC_BOOK3E
-#define VMEMMAP_BASE VMALLOC_END
-#define VMEMMAP_END KERN_IO_START
-#else
-#define VMEMMAP_BASE (VMEMMAP_REGION_ID << REGION_SHIFT)
-#endif
-#define vmemmap ((struct page *)VMEMMAP_BASE)
-
-
-/*
- * Include the PTE bits definitions
- */
-#ifdef CONFIG_PPC_BOOK3S
-#include <asm/pte-hash64.h>
-#else
-#include <asm/pte-book3e.h>
-#endif
-#include <asm/pte-common.h>
-
-#ifdef CONFIG_PPC_MM_SLICES
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-#endif /* CONFIG_PPC_MM_SLICES */
-
-#ifndef __ASSEMBLY__
-
-/*
- * This is the default implementation of various PTE accessors, it's
- * used in all cases except Book3S with 64K pages where we have a
- * concept of sub-pages
- */
-#ifndef __real_pte
-
-#ifdef CONFIG_STRICT_MM_TYPECHECKS
-#define __real_pte(e,p) ((real_pte_t){(e)})
-#define __rpte_to_pte(r) ((r).pte)
-#else
-#define __real_pte(e,p) (e)
-#define __rpte_to_pte(r) (__pte(r))
-#endif
-#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12)
-
-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
- do { \
- index = 0; \
- shift = mmu_psize_defs[psize].shift; \
-
-#define pte_iterate_hashed_end() } while(0)
-
-/*
- * We expect this to be called only for user addresses or kernel virtual
- * addresses other than the linear mapping.
- */
-#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K
-
-#endif /* __real_pte */
-
-
-/* pte_clear moved to later in this file */
-
-#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
-#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
-
-#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
- || (pmd_val(pmd) & PMD_BAD_BITS))
-#define pmd_present(pmd) (!pmd_none(pmd))
-#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
-extern struct page *pmd_page(pmd_t pmd);
-
-#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
-#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
- || (pud_val(pud) & PUD_BAD_BITS))
-#define pud_present(pud) (pud_val(pud) != 0)
-#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
-#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
-
-extern struct page *pud_page(pud_t pud);
-
-static inline pte_t pud_pte(pud_t pud)
-{
- return __pte(pud_val(pud));
-}
-
-static inline pud_t pte_pud(pte_t pte)
-{
- return __pud(pte_val(pte));
-}
-#define pud_write(pud) pte_write(pud_pte(pud))
-#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
-#define pgd_write(pgd) pte_write(pgd_pte(pgd))
-
-/*
- * Find an entry in a page-table-directory. We combine the address region
- * (the high order N bits) and the pgd portion of the address.
- */
-#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
-
-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-
-#define pmd_offset(pudp,addr) \
- (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-
-#define pte_offset_kernel(dir,addr) \
- (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-
-#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_unmap(pte) do { } while(0)
-
-/* to find an entry in a kernel page-table-directory */
-/* This now only contains the vmalloc pages */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, unsigned long pte, int huge);
-
-/* Atomic PTE updates */
-static inline unsigned long pte_update(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, unsigned long clr,
- unsigned long set,
- int huge)
-{
-#ifdef PTE_ATOMIC_UPDATES
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%3 # pte_update\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- andc %1,%0,%4 \n\
- or %1,%1,%7\n\
- stdcx. %1,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
- : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set)
- : "cc" );
-#else
- unsigned long old = pte_val(*ptep);
- *ptep = __pte((old & ~clr) | set);
-#endif
- /* huge pages use the old page table lock */
- if (!huge)
- assert_pte_locked(mm, addr);
-
-#ifdef CONFIG_PPC_STD_MMU_64
- if (old & _PAGE_HASHPTE)
- hpte_need_flush(mm, addr, ptep, old, huge);
-#endif
-
- return old;
-}
-
-static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
- return 0;
- old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
- return (old & _PAGE_ACCESSED) != 0;
-}
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
-({ \
- int __r; \
- __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
- __r; \
-})
-
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
-
- if ((pte_val(*ptep) & _PAGE_RW) == 0)
- return;
-
- pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
-}
-
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- if ((pte_val(*ptep) & _PAGE_RW) == 0)
- return;
-
- pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
-}
-
-/*
- * We currently remove entries from the hashtable regardless of whether
- * the entry was young or dirty. The generic routines only flush if the
- * entry was young or dirty which is not good enough.
- *
- * We should be more intelligent about this but for the moment we override
- * these functions and force a tlb flush unconditionally
- */
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define ptep_clear_flush_young(__vma, __address, __ptep) \
-({ \
- int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
- __ptep); \
- __young; \
-})
-
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
- return __pte(old);
-}
-
-static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
- pte_t * ptep)
-{
- pte_update(mm, addr, ptep, ~0UL, 0, 0);
-}
-
-
-/* Set the dirty and/or accessed bits atomically in a linux PTE, this
- * function doesn't need to flush the hash entry
- */
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
-{
- unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
-
-#ifdef PTE_ATOMIC_UPDATES
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%4\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- or %0,%3,%0\n\
- stdcx. %0,0,%4\n\
- bne- 1b"
- :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
- :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
- :"cc");
-#else
- unsigned long old = pte_val(*ptep);
- *ptep = __pte(old | bits);
-#endif
-}
-
-#define __HAVE_ARCH_PTE_SAME
-#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
-
-#define pte_ERROR(e) \
- pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
- pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
- pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-/* Encode and de-code a swap entry */
-#define MAX_SWAPFILES_CHECK() do { \
- BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \
- /* \
- * Don't have overlapping bits with _PAGE_HPTEFLAGS \
- * We filter HPTEFLAGS on set_pte. \
- */ \
- BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \
- } while (0)
-/*
- * on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT;
- */
-#define SWP_TYPE_BITS 5
-#define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \
- & ((1UL << SWP_TYPE_BITS) - 1))
-#define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT)
-#define __swp_entry(type, offset) ((swp_entry_t) { \
- ((type) << _PAGE_BIT_SWAP_TYPE) \
- | ((offset) << PTE_RPN_SHIFT) })
-
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
-#define __swp_entry_to_pte(x) __pte((x).val)
-
-void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
-void pgtable_cache_init(void);
-#endif /* __ASSEMBLY__ */
-
-/*
- * THP pages can't be special. So use the _PAGE_SPECIAL
- */
-#define _PAGE_SPLITTING _PAGE_SPECIAL
-
-/*
- * We need to differentiate between explicit huge page and THP huge
- * page, since THP huge page also need to track real subpage details
- */
-#define _PAGE_THP_HUGE _PAGE_4K_PFN
-
-/*
- * set of bits not changed in pmd_modify.
- */
-#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | \
- _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \
- _PAGE_THP_HUGE)
-
-#ifndef __ASSEMBLY__
-/*
- * The linux hugepage PMD now include the pmd entries followed by the address
- * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits.
- * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per
- * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and
- * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t.
- *
- * The last three bits are intentionally left to zero. This memory location
- * are also used as normal page PTE pointers. So if we have any pointers
- * left around while we collapse a hugepage, we need to make sure
- * _PAGE_PRESENT bit of that is zero when we look at them
- */
-static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
-{
- return (hpte_slot_array[index] >> 3) & 0x1;
-}
-
-static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
- int index)
-{
- return hpte_slot_array[index] >> 4;
-}
-
-static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
- unsigned int index, unsigned int hidx)
-{
- hpte_slot_array[index] = hidx << 4 | 0x1 << 3;
-}
-
-struct page *realmode_pfn_to_page(unsigned long pfn);
-
-static inline char *get_hpte_slot_array(pmd_t *pmdp)
-{
- /*
- * The hpte hindex is stored in the pgtable whose address is in the
- * second half of the PMD
- *
- * Order this load with the test for pmd_trans_huge in the caller
- */
- smp_rmb();
- return *(char **)(pmdp + PTRS_PER_PMD);
-
-
-}
-
-extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp, unsigned long old_pmd);
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
-extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
-extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
-extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp, pmd_t pmd);
-extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
- pmd_t *pmd);
-/*
- *
- * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs
- * page. The hugetlbfs page table walking and mangling paths are totally
- * separated form the core VM paths and they're differentiated by
- * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run.
- *
- * pmd_trans_huge() is defined as false at build time if
- * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build
- * time in such case.
- *
- * For ppc64 we need to differntiate from explicit hugepages from THP, because
- * for THP we also track the subpage details at the pmd level. We don't do
- * that for explicit huge pages.
- *
- */
-static inline int pmd_trans_huge(pmd_t pmd)
-{
- /*
- * leaf pte for huge page, bottom two bits != 00
- */
- return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE);
-}
-
-static inline int pmd_trans_splitting(pmd_t pmd)
-{
- if (pmd_trans_huge(pmd))
- return pmd_val(pmd) & _PAGE_SPLITTING;
- return 0;
-}
-
-extern int has_transparent_hugepage(void);
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-
-static inline int pmd_large(pmd_t pmd)
-{
- /*
- * leaf pte for huge page, bottom two bits != 00
- */
- return ((pmd_val(pmd) & 0x3) != 0x0);
-}
-
-static inline pte_t pmd_pte(pmd_t pmd)
-{
- return __pte(pmd_val(pmd));
-}
-
-static inline pmd_t pte_pmd(pte_t pte)
-{
- return __pmd(pte_val(pte));
-}
-
-static inline pte_t *pmdp_ptep(pmd_t *pmd)
-{
- return (pte_t *)pmd;
-}
-
-#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
-#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
-#define pmd_young(pmd) pte_young(pmd_pte(pmd))
-#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
-#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
-#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
-#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
-#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
-
-#define __HAVE_ARCH_PMD_WRITE
-#define pmd_write(pmd) pte_write(pmd_pte(pmd))
-
-static inline pmd_t pmd_mkhuge(pmd_t pmd)
-{
- /* Do nothing, mk_pmd() does this part. */
- return pmd;
-}
-
-static inline pmd_t pmd_mknotpresent(pmd_t pmd)
-{
- pmd_val(pmd) &= ~_PAGE_PRESENT;
- return pmd;
-}
-
-static inline pmd_t pmd_mksplitting(pmd_t pmd)
-{
- pmd_val(pmd) |= _PAGE_SPLITTING;
- return pmd;
-}
-
-#define __HAVE_ARCH_PMD_SAME
-static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
-{
- return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0);
-}
-
-#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
-extern int pmdp_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp,
- pmd_t entry, int dirty);
-
-extern unsigned long pmd_hugepage_update(struct mm_struct *mm,
- unsigned long addr,
- pmd_t *pmdp,
- unsigned long clr,
- unsigned long set);
-
-static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
- unsigned long addr, pmd_t *pmdp)
-{
- unsigned long old;
-
- if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
- return 0;
- old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0);
- return ((old & _PAGE_ACCESSED) != 0);
-}
-
-#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
-extern int pmdp_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp);
-#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
-extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp);
-
-#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
-extern pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
- unsigned long addr, pmd_t *pmdp);
-
-#define __HAVE_ARCH_PMDP_SET_WRPROTECT
-static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp)
-{
-
- if ((pmd_val(*pmdp) & _PAGE_RW) == 0)
- return;
-
- pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0);
-}
-
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-extern void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp);
-
-extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp);
-#define pmdp_collapse_flush pmdp_collapse_flush
-
-#define __HAVE_ARCH_PGTABLE_DEPOSIT
-extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
- pgtable_t pgtable);
-#define __HAVE_ARCH_PGTABLE_WITHDRAW
-extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
-
-#define __HAVE_ARCH_PMDP_INVALIDATE
-extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp);
-
-#define pmd_move_must_withdraw pmd_move_must_withdraw
-struct spinlock;
-static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
- struct spinlock *old_pmd_ptl)
-{
- /*
- * Archs like ppc64 use pgtable to store per pmd
- * specific information. So when we switch the pmd,
- * we should also withdraw and deposit the pgtable
- */
- return true;
-}
-#endif /* __ASSEMBLY__ */
-#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
new file mode 100644
index 0000000..43140f8
--- /dev/null
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -0,0 +1,103 @@
+#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
+#define _ASM_POWERPC_PGTABLE_TYPES_H
+
+#ifdef CONFIG_STRICT_MM_TYPECHECKS
+/* These are used to make use of C type-checking. */
+
+/* PTE level */
+typedef struct { pte_basic_t pte; } pte_t;
+#define __pte(x) ((pte_t) { (x) })
+static inline pte_basic_t pte_val(pte_t x)
+{
+ return x.pte;
+}
+
+/* PMD level */
+#ifdef CONFIG_PPC64
+typedef struct { unsigned long pmd; } pmd_t;
+#define __pmd(x) ((pmd_t) { (x) })
+static inline unsigned long pmd_val(pmd_t x)
+{
+ return x.pmd;
+}
+
+/*
+ * 64 bit hash always use 4 level table. Everybody else use 4 level
+ * only for 4K page size.
+ */
+#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
+typedef struct { unsigned long pud; } pud_t;
+#define __pud(x) ((pud_t) { (x) })
+static inline unsigned long pud_val(pud_t x)
+{
+ return x.pud;
+}
+#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
+
+/* PGD level */
+typedef struct { unsigned long pgd; } pgd_t;
+#define __pgd(x) ((pgd_t) { (x) })
+static inline unsigned long pgd_val(pgd_t x)
+{
+ return x.pgd;
+}
+
+/* Page protection bits */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x) ((x).pgprot)
+#define __pgprot(x) ((pgprot_t) { (x) })
+
+#else
+
+/*
+ * .. while these make it easier on the compiler
+ */
+
+typedef pte_basic_t pte_t;
+#define __pte(x) (x)
+static inline pte_basic_t pte_val(pte_t pte)
+{
+ return pte;
+}
+
+#ifdef CONFIG_PPC64
+typedef unsigned long pmd_t;
+#define __pmd(x) (x)
+static inline unsigned long pmd_val(pmd_t pmd)
+{
+ return pmd;
+}
+
+#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
+typedef unsigned long pud_t;
+#define __pud(x) (x)
+static inline unsigned long pud_val(pud_t pud)
+{
+ return pud;
+}
+#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
+
+typedef unsigned long pgd_t;
+#define __pgd(x) (x)
+static inline unsigned long pgd_val(pgd_t pgd)
+{
+ return pgd;
+}
+
+typedef unsigned long pgprot_t;
+#define pgprot_val(x) (x)
+#define __pgprot(x) (x)
+
+#endif /* CONFIG_STRICT_MM_TYPECHECKS */
+/*
+ * With hash config 64k pages additionally define a bigger "real PTE" type that
+ * gathers the "second half" part of the PTE for pseudo 64k pages
+ */
+#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
+typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
+#else
+typedef struct { pte_t pte; } real_pte_t;
+#endif
+#endif /* _ASM_POWERPC_PGTABLE_TYPES_H */
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 0717693..47897a3 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -1,6 +1,5 @@
#ifndef _ASM_POWERPC_PGTABLE_H
#define _ASM_POWERPC_PGTABLE_H
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/mmdebug.h>
@@ -13,210 +12,20 @@ struct mm_struct;
#endif /* !__ASSEMBLY__ */
-#if defined(CONFIG_PPC64)
-# include <asm/pgtable-ppc64.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/book3s/pgtable.h>
#else
-# include <asm/pgtable-ppc32.h>
-#endif
-
-/*
- * We save the slot number & secondary bit in the second half of the
- * PTE page. We use the 8 bytes per each pte entry.
- */
-#define PTE_PAGE_HIDX_OFFSET (PTRS_PER_PTE * 8)
+#include <asm/nohash/pgtable.h>
+#endif /* !CONFIG_PPC_BOOK3S */
#ifndef __ASSEMBLY__
#include <asm/tlbflush.h>
-/* Generic accessors to PTE bits */
-static inline int pte_write(pte_t pte)
-{ return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; }
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
-static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
-static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
-
-#ifdef CONFIG_NUMA_BALANCING
-/*
- * These work without NUMA balancing but the kernel does not care. See the
- * comment in include/asm-generic/pgtable.h . On powerpc, this will only
- * work for user pages and always return true for kernel pages.
- */
-static inline int pte_protnone(pte_t pte)
-{
- return (pte_val(pte) &
- (_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
-}
-
-static inline int pmd_protnone(pmd_t pmd)
-{
- return pte_protnone(pmd_pte(pmd));
-}
-#endif /* CONFIG_NUMA_BALANCING */
-
-static inline int pte_present(pte_t pte)
-{
- return pte_val(pte) & _PAGE_PRESENT;
-}
-
-/* Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- *
- * Even if PTEs can be unsigned long long, a PFN is always an unsigned
- * long for now.
- */
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) {
- return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) |
- pgprot_val(pgprot)); }
-static inline unsigned long pte_pfn(pte_t pte) {
- return pte_val(pte) >> PTE_RPN_SHIFT; }
-
/* Keep these as a macros to avoid include dependency mess */
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-/* Generic modifiers for PTE bits */
-static inline pte_t pte_wrprotect(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE);
- pte_val(pte) |= _PAGE_RO; return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
- pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkwrite(pte_t pte) {
- pte_val(pte) &= ~_PAGE_RO;
- pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
- pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
- pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) {
- pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline pte_t pte_mkhuge(pte_t pte) {
- return pte; }
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
- pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
- return pte;
-}
-
-
-/* Insert a PTE, top-level function is out of line. It uses an inline
- * low level function in the respective pgtable-* files
- */
-extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
- pte_t pte);
-
-/* This low level function performs the actual PTE insertion
- * Setting the PTE depends on the MMU type and other factors. It's
- * an horrible mess that I'm not going to try to clean up now but
- * I'm keeping it in one place rather than spread around
- */
-static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte, int percpu)
-{
-#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
- /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
- * helper pte_update() which does an atomic update. We need to do that
- * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
- * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
- * the hash bits instead (ie, same as the non-SMP case)
- */
- if (percpu)
- *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
- | (pte_val(pte) & ~_PAGE_HASHPTE));
- else
- pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
-
-#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
- /* Second case is 32-bit with 64-bit PTE. In this case, we
- * can just store as long as we do the two halves in the right order
- * with a barrier in between. This is possible because we take care,
- * in the hash code, to pre-invalidate if the PTE was already hashed,
- * which synchronizes us with any concurrent invalidation.
- * In the percpu case, we also fallback to the simple update preserving
- * the hash bits
- */
- if (percpu) {
- *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
- | (pte_val(pte) & ~_PAGE_HASHPTE));
- return;
- }
-#if _PAGE_HASHPTE != 0
- if (pte_val(*ptep) & _PAGE_HASHPTE)
- flush_hash_entry(mm, ptep, addr);
-#endif
- __asm__ __volatile__("\
- stw%U0%X0 %2,%0\n\
- eieio\n\
- stw%U0%X0 %L2,%1"
- : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
- : "r" (pte) : "memory");
-
-#elif defined(CONFIG_PPC_STD_MMU_32)
- /* Third case is 32-bit hash table in UP mode, we need to preserve
- * the _PAGE_HASHPTE bit since we may not have invalidated the previous
- * translation in the hash yet (done in a subsequent flush_tlb_xxx())
- * and see we need to keep track that this PTE needs invalidating
- */
- *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
- | (pte_val(pte) & ~_PAGE_HASHPTE));
-
-#else
- /* Anything else just stores the PTE normally. That covers all 64-bit
- * cases, and 32-bit non-hash with 32-bit PTEs.
- */
- *ptep = pte;
-
-#ifdef CONFIG_PPC_BOOK3E_64
- /*
- * With hardware tablewalk, a sync is needed to ensure that
- * subsequent accesses see the PTE we just wrote. Unlike userspace
- * mappings, we can't tolerate spurious faults, so make sure
- * the new PTE will be seen the first time.
- */
- if (is_kernel_addr(addr))
- mb();
-#endif
-#endif
-}
-
-
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
- pte_t *ptep, pte_t entry, int dirty);
-
-/*
- * Macro to mark a page protection value as "uncacheable".
- */
-
-#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \
- _PAGE_WRITETHRU)
-
-#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
- _PAGE_NO_CACHE | _PAGE_GUARDED))
-
-#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
- _PAGE_NO_CACHE))
-
-#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
- _PAGE_COHERENT))
-
-#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
- _PAGE_COHERENT | _PAGE_WRITETHRU))
-
-#define pgprot_cached_noncoherent(prot) \
- (__pgprot(pgprot_val(prot) & ~_PAGE_CACHE_CTL))
-
-#define pgprot_writecombine pgprot_noncached_wc
-
-struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
- unsigned long size, pgprot_t vma_prot);
-#define __HAVE_PHYS_MEM_ACCESS_PROT
-
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
@@ -259,17 +68,19 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
#define has_transparent_hugepage() 0
#endif
pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
- unsigned *shift);
+ bool *is_thp, unsigned *shift);
static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
- unsigned *shift)
+ bool *is_thp, unsigned *shift)
{
if (!arch_irqs_disabled()) {
pr_info("%s called with irq enabled\n", __func__);
dump_stack();
}
- return __find_linux_pte_or_hugepte(pgdir, ea, shift);
+ return __find_linux_pte_or_hugepte(pgdir, ea, is_thp, shift);
}
+
+unsigned long vmalloc_to_phys(void *vmalloc_addr);
+
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
index 67859ed..1b39424 100644
--- a/arch/powerpc/include/asm/plpar_wrappers.h
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -202,6 +202,23 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
}
/*
+ * ptes must be 8*sizeof(unsigned long)
+ */
+static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
+ unsigned long *ptes)
+
+{
+ long rc;
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+
+ rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex);
+
+ memcpy(ptes, retbuf, 8*sizeof(unsigned long));
+
+ return rc;
+}
+
+/*
* plpar_pte_read_4_raw can be called in real mode.
* ptes must be 8*sizeof(unsigned long)
*/
diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h
index 10902c937..9256979 100644
--- a/arch/powerpc/include/asm/pmac_feature.h
+++ b/arch/powerpc/include/asm/pmac_feature.h
@@ -46,7 +46,7 @@
/* PowerSurge are the first generation of PCI Pmacs. This include
* all of the Grand-Central based machines. We currently don't
- * differenciate most of them.
+ * differentiate most of them.
*/
#define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */
#define PMAC_TYPE_ANS 0x11 /* Apple Network Server */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index dd0fc18..499d9f8 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -413,24 +413,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
FTR_SECTION_ELSE_NESTED(848); \
mtocrf (FXM), RS; \
ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848)
-
-/*
- * PPR restore macros used in entry_64.S
- * Used for P7 or later processors
- */
-#define HMT_MEDIUM_LOW_HAS_PPR \
-BEGIN_FTR_SECTION_NESTED(944) \
- HMT_MEDIUM_LOW; \
-END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,944)
-
-#define SET_DEFAULT_THREAD_PPR(ra, rb) \
-BEGIN_FTR_SECTION_NESTED(945) \
- lis ra,INIT_PPR@highest; /* default ppr=3 */ \
- ld rb,PACACURRENT(r13); \
- sldi ra,ra,32; /* 11- 13 bits are used for ppr */ \
- std ra,TASKTHREADPPR(rb); \
-END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
-
#endif
/*
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 5afea36..8ab8a1a 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -88,12 +88,6 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
-/* Lazy FPU handling on uni-processor */
-extern struct task_struct *last_task_used_math;
-extern struct task_struct *last_task_used_altivec;
-extern struct task_struct *last_task_used_vsx;
-extern struct task_struct *last_task_used_spe;
-
#ifdef CONFIG_PPC32
#if CONFIG_TASK_SIZE > CONFIG_KERNEL_START
@@ -242,7 +236,9 @@ struct thread_struct {
#endif
struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
unsigned long trap_nr; /* last trap # on this thread */
+ u8 load_fp;
#ifdef CONFIG_ALTIVEC
+ u8 load_vec;
struct thread_vr_state vr_state;
struct thread_vr_state *vr_save_area;
unsigned long vrsave;
@@ -294,6 +290,7 @@ struct thread_struct {
#endif
#ifdef CONFIG_PPC64
unsigned long dscr;
+ unsigned long fscr;
/*
* This member element dscr_inherit indicates that the process
* has explicitly attempted and changed the DSCR register value
@@ -385,8 +382,6 @@ extern int set_endian(struct task_struct *tsk, unsigned int val);
extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
-extern void fp_enable(void);
-extern void vec_enable(void);
extern void load_fp_state(struct thread_fp_state *fp);
extern void store_fp_state(struct thread_fp_state *fp);
extern void load_vr_state(struct thread_vr_state *vr);
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
deleted file mode 100644
index 486b1ef..0000000
--- a/arch/powerpc/include/asm/pte-40x.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_40x_H
-#define _ASM_POWERPC_PTE_40x_H
-#ifdef __KERNEL__
-
-/*
- * At present, all PowerPC 400-class processors share a similar TLB
- * architecture. The instruction and data sides share a unified,
- * 64-entry, fully-associative TLB which is maintained totally under
- * software control. In addition, the instruction side has a
- * hardware-managed, 4-entry, fully-associative TLB which serves as a
- * first level to the shared TLB. These two TLBs are known as the UTLB
- * and ITLB, respectively (see "mmu.h" for definitions).
- *
- * There are several potential gotchas here. The 40x hardware TLBLO
- * field looks like this:
- *
- * 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * RPN..................... 0 0 EX WR ZSEL....... W I M G
- *
- * Where possible we make the Linux PTE bits match up with this
- *
- * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
- * support down to 1k pages), this is done in the TLBMiss exception
- * handler.
- * - We use only zones 0 (for kernel pages) and 1 (for user pages)
- * of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
- * miss handler. Bit 27 is PAGE_USER, thus selecting the correct
- * zone.
- * - PRESENT *must* be in the bottom two bits because swap cache
- * entries use the top 30 bits. Because 40x doesn't support SMP
- * anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
- * is cleared in the TLB miss handler before the TLB entry is loaded.
- * - All other bits of the PTE are loaded into TLBLO without
- * modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
- * software PTE bits. We actually use use bits 21, 24, 25, and
- * 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
- * PRESENT.
- */
-
-#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
-#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
-#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
-#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
-#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
-#define _PAGE_SPECIAL 0x020 /* software: Special page */
-#define _PAGE_RW 0x040 /* software: Writes permitted */
-#define _PAGE_DIRTY 0x080 /* software: dirty page */
-#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
-#define _PAGE_EXEC 0x200 /* hardware: EX permission */
-#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
-
-#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
-#define _PMD_BAD 0x802
-#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
-#define _PMD_SIZE_4M 0x0c0
-#define _PMD_SIZE_16M 0x0e0
-
-#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
-
-/* Until my rework is finished, 40x still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES 1
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
deleted file mode 100644
index 36f75fa..0000000
--- a/arch/powerpc/include/asm/pte-44x.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_44x_H
-#define _ASM_POWERPC_PTE_44x_H
-#ifdef __KERNEL__
-
-/*
- * Definitions for PPC440
- *
- * Because of the 3 word TLB entries to support 36-bit addressing,
- * the attribute are difficult to map in such a fashion that they
- * are easily loaded during exception processing. I decided to
- * organize the entry so the ERPN is the only portion in the
- * upper word of the PTE and the attribute bits below are packed
- * in as sensibly as they can be in the area below a 4KB page size
- * oriented RPN. This at least makes it easy to load the RPN and
- * ERPN fields in the TLB. -Matt
- *
- * This isn't entirely true anymore, at least some bits are now
- * easier to move into the TLB from the PTE. -BenH.
- *
- * Note that these bits preclude future use of a page size
- * less than 4KB.
- *
- *
- * PPC 440 core has following TLB attribute fields;
- *
- * TLB1:
- * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * RPN................................. - - - - - - ERPN.......
- *
- * TLB2:
- * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
- *
- * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
- * TLB2 storage attibute fields. Those are:
- *
- * TLB2:
- * 0...10 11 12 13 14 15 16...31
- * no change WL1 IL1I IL1D IL2I IL2D no change
- *
- * There are some constrains and options, to decide mapping software bits
- * into TLB entry.
- *
- * - PRESENT *must* be in the bottom three bits because swap cache
- * entries use the top 29 bits for TLB2.
- *
- * - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
- * because it doesn't support SMP. However, some later 460 variants
- * have -some- form of SMP support and so I keep the bit there for
- * future use
- *
- * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
- * for memory protection related functions (see PTE structure in
- * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
- * above bits. Note that the bit values are CPU specific, not architecture
- * specific.
- *
- * The kernel PTE entry holds an arch-dependent swp_entry structure under
- * certain situations. In other words, in such situations some portion of
- * the PTE bits are used as a swp_entry. In the PPC implementation, the
- * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
- * hold protection values. That means the three protection bits are
- * reserved for both PTE and SWAP entry at the most significant three
- * LSBs.
- *
- * There are three protection bits available for SWAP entry:
- * _PAGE_PRESENT
- * _PAGE_HASHPTE (if HW has)
- *
- * So those three bits have to be inside of 0-2nd LSB of PTE.
- *
- */
-
-#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
-#define _PAGE_RW 0x00000002 /* S: Write permission */
-#define _PAGE_EXEC 0x00000004 /* H: Execute permission */
-#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
-#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
-#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
-#define _PAGE_USER 0x00000040 /* S: User page */
-#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
-#define _PAGE_GUARDED 0x00000100 /* H: G bit */
-#define _PAGE_COHERENT 0x00000200 /* H: M bit */
-#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
-#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
-
-/* TODO: Add large page lowmem mapping support */
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK 0xffffffff00000000ULL
-
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_44x_H */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
deleted file mode 100644
index a0e2ba9..0000000
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_8xx_H
-#define _ASM_POWERPC_PTE_8xx_H
-#ifdef __KERNEL__
-
-/*
- * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
- * We also use the two level tables, but we can put the real bits in them
- * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
- * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
- * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
- * based upon user/super access. The TLB does not have accessed nor write
- * protect. We assume that if the TLB get loaded with an entry it is
- * accessed, and overload the changed bit for write protect. We use
- * two bits in the software pte that are supposed to be set to zero in
- * the TLB entry (24 and 25) for these indicators. Although the level 1
- * descriptor contains the guarded and writethrough/copyback bits, we can
- * set these at the page level since they get copied from the Mx_TWC
- * register when the TLB entry is loaded. We will use bit 27 for guard, since
- * that is where it exists in the MD_TWC, and bit 26 for writethrough.
- * These will get masked from the level 2 descriptor at TLB load time, and
- * copied to the MD_TWC before it gets loaded.
- * Large page sizes added. We currently support two sizes, 4K and 8M.
- * This also allows a TLB hander optimization because we can directly
- * load the PMD into MD_TWC. The 8M pages are only used for kernel
- * mapping of well known areas. The PMD (PGD) entries contain control
- * flags in addition to the address, so care must be taken that the
- * software no longer assumes these are only pointers.
- */
-
-/* Definitions for 8xx embedded chips. */
-#define _PAGE_PRESENT 0x0001 /* Page is valid */
-#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
-#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
-#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */
-#define _PAGE_DIRTY 0x0100 /* C: page changed */
-
-/* These 4 software bits must be masked out when the L2 entry is loaded
- * into the TLB.
- */
-#define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */
-#define _PAGE_USER 0x0020 /* Copied to L1 APG lsb */
-#define _PAGE_EXEC 0x0040 /* Copied to L1 APG */
-#define _PAGE_WRITETHRU 0x0080 /* software: caching is write through */
-#define _PAGE_ACCESSED 0x0800 /* software: page referenced */
-
-#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
-
-#define _PMD_PRESENT 0x0001
-#define _PMD_BAD 0x0ff0
-#define _PMD_PAGE_MASK 0x000c
-#define _PMD_PAGE_8M 0x000c
-
-/* Until my rework is finished, 8xx still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES 1
-
-/* We need to add _PAGE_SHARED to kernel pages */
-#define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_RO)
-#define _PAGE_KERNEL_ROX (_PAGE_SHARED | _PAGE_RO | _PAGE_EXEC)
-#define _PAGE_KERNEL_RW (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
- _PAGE_HWWRITE)
-#define _PAGE_KERNEL_RWX (_PAGE_SHARED | _PAGE_DIRTY | _PAGE_RW | \
- _PAGE_HWWRITE | _PAGE_EXEC)
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_8xx_H */
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
deleted file mode 100644
index 8d84732..0000000
--- a/arch/powerpc/include/asm/pte-book3e.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_BOOK3E_H
-#define _ASM_POWERPC_PTE_BOOK3E_H
-#ifdef __KERNEL__
-
-/* PTE bit definitions for processors compliant to the Book3E
- * architecture 2.06 or later. The position of the PTE bits
- * matches the HW definition of the optional Embedded Page Table
- * category.
- */
-
-/* Architected bits */
-#define _PAGE_PRESENT 0x000001 /* software: pte contains a translation */
-#define _PAGE_SW1 0x000002
-#define _PAGE_BIT_SWAP_TYPE 2
-#define _PAGE_BAP_SR 0x000004
-#define _PAGE_BAP_UR 0x000008
-#define _PAGE_BAP_SW 0x000010
-#define _PAGE_BAP_UW 0x000020
-#define _PAGE_BAP_SX 0x000040
-#define _PAGE_BAP_UX 0x000080
-#define _PAGE_PSIZE_MSK 0x000f00
-#define _PAGE_PSIZE_4K 0x000200
-#define _PAGE_PSIZE_8K 0x000300
-#define _PAGE_PSIZE_16K 0x000400
-#define _PAGE_PSIZE_32K 0x000500
-#define _PAGE_PSIZE_64K 0x000600
-#define _PAGE_PSIZE_128K 0x000700
-#define _PAGE_PSIZE_256K 0x000800
-#define _PAGE_PSIZE_512K 0x000900
-#define _PAGE_PSIZE_1M 0x000a00
-#define _PAGE_PSIZE_2M 0x000b00
-#define _PAGE_PSIZE_4M 0x000c00
-#define _PAGE_PSIZE_8M 0x000d00
-#define _PAGE_PSIZE_16M 0x000e00
-#define _PAGE_PSIZE_32M 0x000f00
-#define _PAGE_DIRTY 0x001000 /* C: page changed */
-#define _PAGE_SW0 0x002000
-#define _PAGE_U3 0x004000
-#define _PAGE_U2 0x008000
-#define _PAGE_U1 0x010000
-#define _PAGE_U0 0x020000
-#define _PAGE_ACCESSED 0x040000
-#define _PAGE_ENDIAN 0x080000
-#define _PAGE_GUARDED 0x100000
-#define _PAGE_COHERENT 0x200000 /* M: enforce memory coherence */
-#define _PAGE_NO_CACHE 0x400000 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
-
-/* "Higher level" linux bit combinations */
-#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */
-#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
-#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
-#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
-#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX)
-#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
-
-#define _PAGE_HASHPTE 0
-#define _PAGE_BUSY 0
-
-#define _PAGE_SPECIAL _PAGE_SW0
-
-/* Flags to be preserved on PTE modifications */
-#define _PAGE_HPTEFLAGS _PAGE_BUSY
-
-/* Base page size */
-#ifdef CONFIG_PPC_64K_PAGES
-#define _PAGE_PSIZE _PAGE_PSIZE_64K
-#define PTE_RPN_SHIFT (28)
-#else
-#define _PAGE_PSIZE _PAGE_PSIZE_4K
-#define PTE_RPN_SHIFT (24)
-#endif
-
-#define PTE_WIMGE_SHIFT (19)
-#define PTE_BAP_SHIFT (2)
-
-/* On 32-bit, we never clear the top part of the PTE */
-#ifdef CONFIG_PPC32
-#define _PTE_NONE_MASK 0xffffffff00000000ULL
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-#endif
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index 71537a3..1ec67b0 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -40,6 +40,11 @@
#else
#define _PAGE_RW 0
#endif
+
+#ifndef _PAGE_PTE
+#define _PAGE_PTE 0
+#endif
+
#ifndef _PMD_PRESENT_MASK
#define _PMD_PRESENT_MASK _PMD_PRESENT
#endif
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
deleted file mode 100644
index 9f5c3d0..0000000
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_FSL_BOOKE_H
-#define _ASM_POWERPC_PTE_FSL_BOOKE_H
-#ifdef __KERNEL__
-
-/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based
- * processors
- *
- MMU Assist Register 3:
-
- 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
- RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
-
- - PRESENT *must* be in the bottom three bits because swap cache
- entries use the top 29 bits.
-
-*/
-
-/* Definitions for FSL Book-E Cores */
-#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
-#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
-#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
-#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
-#define _PAGE_EXEC 0x00010 /* H: SX permission */
-#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
-
-#define _PAGE_ENDIAN 0x00040 /* H: E bit */
-#define _PAGE_GUARDED 0x00080 /* H: G bit */
-#define _PAGE_COHERENT 0x00100 /* H: M bit */
-#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
-#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
-#define _PAGE_SPECIAL 0x00800 /* S: Special page */
-
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-#define PTE_WIMGE_SHIFT (6)
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
deleted file mode 100644
index 62cfb0c..0000000
--- a/arch/powerpc/include/asm/pte-hash32.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_HASH32_H
-#define _ASM_POWERPC_PTE_HASH32_H
-#ifdef __KERNEL__
-
-/*
- * The "classic" 32-bit implementation of the PowerPC MMU uses a hash
- * table containing PTEs, together with a set of 16 segment registers,
- * to define the virtual to physical address mapping.
- *
- * We use the hash table as an extended TLB, i.e. a cache of currently
- * active mappings. We maintain a two-level page table tree, much
- * like that used by the i386, for the sake of the Linux memory
- * management code. Low-level assembler code in hash_low_32.S
- * (procedure hash_page) is responsible for extracting ptes from the
- * tree and putting them into the hash table when necessary, and
- * updating the accessed and modified bits in the page table tree.
- */
-
-#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
-#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
-#define _PAGE_USER 0x004 /* usermode access allowed */
-#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
-#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x080 /* C: page changed */
-#define _PAGE_ACCESSED 0x100 /* R: page referenced */
-#define _PAGE_RW 0x400 /* software: user write access allowed */
-#define _PAGE_SPECIAL 0x800 /* software: Special page */
-
-#ifdef CONFIG_PTE_64BIT
-/* We never clear the high word of the pte */
-#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
-#else
-#define _PTE_NONE_MASK _PAGE_HASHPTE
-#endif
-
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-/* Hash table based platforms need atomic updates of the linux PTE */
-#define PTE_ATOMIC_UPDATES 1
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_HASH32_H */
diff --git a/arch/powerpc/include/asm/pte-hash64-4k.h b/arch/powerpc/include/asm/pte-hash64-4k.h
deleted file mode 100644
index c134e809..0000000
--- a/arch/powerpc/include/asm/pte-hash64-4k.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* To be include by pgtable-hash64.h only */
-
-/* PTE bits */
-#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
-#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
-#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
-#define _PAGE_F_SECOND _PAGE_SECONDARY
-#define _PAGE_F_GIX _PAGE_GROUP_IX
-#define _PAGE_SPECIAL 0x10000 /* software: special page */
-
-/* PTE flags to conserve for HPTE identification */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
- _PAGE_SECONDARY | _PAGE_GROUP_IX)
-
-/* shift to put page number into pte */
-#define PTE_RPN_SHIFT (17)
-
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h
deleted file mode 100644
index 4f4ec2a..0000000
--- a/arch/powerpc/include/asm/pte-hash64-64k.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* To be include by pgtable-hash64.h only */
-
-/* Additional PTE bits (don't change without checking asm in hash_low.S) */
-#define _PAGE_SPECIAL 0x00000400 /* software: special page */
-#define _PAGE_HPTE_SUB 0x0ffff000 /* combo only: sub pages HPTE bits */
-#define _PAGE_HPTE_SUB0 0x08000000 /* combo only: first sub page */
-#define _PAGE_COMBO 0x10000000 /* this is a combo 4k page */
-#define _PAGE_4K_PFN 0x20000000 /* PFN is for a single 4k page */
-
-/* For 64K page, we don't have a separate _PAGE_HASHPTE bit. Instead,
- * we set that to be the whole sub-bits mask. The C code will only
- * test this, so a multi-bit mask will work. For combo pages, this
- * is equivalent as effectively, the old _PAGE_HASHPTE was an OR of
- * all the sub bits. For real 64k pages, we now have the assembly set
- * _PAGE_HPTE_SUB0 in addition to setting the HIDX bits which overlap
- * that mask. This is fine as long as the HIDX bits are never set on
- * a PTE that isn't hashed, which is the case today.
- *
- * A little nit is for the huge page C code, which does the hashing
- * in C, we need to provide which bit to use.
- */
-#define _PAGE_HASHPTE _PAGE_HPTE_SUB
-
-/* Note the full page bits must be in the same location as for normal
- * 4k pages as the same assembly will be used to insert 64K pages
- * whether the kernel has CONFIG_PPC_64K_PAGES or not
- */
-#define _PAGE_F_SECOND 0x00008000 /* full page: hidx bits */
-#define _PAGE_F_GIX 0x00007000 /* full page: hidx bits */
-
-/* PTE flags to conserve for HPTE identification */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO)
-
-/* Shift to put page number into pte.
- *
- * That gives us a max RPN of 34 bits, which means a max of 50 bits
- * of addressable physical space, or 46 bits for the special 4k PFNs.
- */
-#define PTE_RPN_SHIFT (30)
-
-#ifndef __ASSEMBLY__
-
-/*
- * With 64K pages on hash table, we have a special PTE format that
- * uses a second "half" of the page table to encode sub-page information
- * in order to deal with 64K made of 4K HW pages. Thus we override the
- * generic accessors and iterators here
- */
-#define __real_pte __real_pte
-static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
-{
- real_pte_t rpte;
-
- rpte.pte = pte;
- rpte.hidx = 0;
- if (pte_val(pte) & _PAGE_COMBO) {
- /*
- * Make sure we order the hidx load against the _PAGE_COMBO
- * check. The store side ordering is done in __hash_page_4K
- */
- smp_rmb();
- rpte.hidx = pte_val(*((ptep) + PTRS_PER_PTE));
- }
- return rpte;
-}
-
-static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
-{
- if ((pte_val(rpte.pte) & _PAGE_COMBO))
- return (rpte.hidx >> (index<<2)) & 0xf;
- return (pte_val(rpte.pte) >> 12) & 0xf;
-}
-
-#define __rpte_to_pte(r) ((r).pte)
-#define __rpte_sub_valid(rpte, index) \
- (pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))
-
-/* Trick: we set __end to va + 64k, which happens works for
- * a 16M page as well as we want only one iteration
- */
-#define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \
- do { \
- unsigned long __end = vpn + (1UL << (PAGE_SHIFT - VPN_SHIFT)); \
- unsigned __split = (psize == MMU_PAGE_4K || \
- psize == MMU_PAGE_64K_AP); \
- shift = mmu_psize_defs[psize].shift; \
- for (index = 0; vpn < __end; index++, \
- vpn += (1L << (shift - VPN_SHIFT))) { \
- if (!__split || __rpte_sub_valid(rpte, index)) \
- do {
-
-#define pte_iterate_hashed_end() } while(0); } } while(0)
-
-#define pte_pagesize_index(mm, addr, pte) \
- (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
-
-#define remap_4k_pfn(vma, addr, pfn, prot) \
- (WARN_ON(((pfn) >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \
- remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
- __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))
-
-#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/pte-hash64.h b/arch/powerpc/include/asm/pte-hash64.h
deleted file mode 100644
index ef612c1..0000000
--- a/arch/powerpc/include/asm/pte-hash64.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef _ASM_POWERPC_PTE_HASH64_H
-#define _ASM_POWERPC_PTE_HASH64_H
-#ifdef __KERNEL__
-
-/*
- * Common bits between 4K and 64K pages in a linux-style PTE.
- * These match the bits in the (hardware-defined) PowerPC PTE as closely
- * as possible. Additional bits may be defined in pgtable-hash64-*.h
- *
- * Note: We only support user read/write permissions. Supervisor always
- * have full read/write to pages above PAGE_OFFSET (pages below that
- * always use the user access permissions).
- *
- * We could create separate kernel read-only if we used the 3 PP bits
- * combinations that newer processors provide but we currently don't.
- */
-#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
-#define _PAGE_USER 0x0002 /* matches one of the PP bits */
-#define _PAGE_BIT_SWAP_TYPE 2
-#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
-#define _PAGE_GUARDED 0x0008
-/* We can derive Memory coherence from _PAGE_NO_CACHE */
-#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x0080 /* C: page changed */
-#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
-#define _PAGE_RW 0x0200 /* software: user write access allowed */
-#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
-
-/* No separate kernel read-only */
-#define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
-#define _PAGE_KERNEL_RO _PAGE_KERNEL_RW
-
-/* Strong Access Ordering */
-#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
-
-/* No page size encoding in the linux PTE */
-#define _PAGE_PSIZE 0
-
-/* PTEIDX nibble */
-#define _PTEIDX_SECONDARY 0x8
-#define _PTEIDX_GROUP_IX 0x7
-
-/* Hash table based platforms need atomic updates of the linux PTE */
-#define PTE_ATOMIC_UPDATES 1
-
-#ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pte-hash64-64k.h>
-#else
-#include <asm/pte-hash64-4k.h>
-#endif
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_PTE_HASH64_H */
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
deleted file mode 100644
index 32b9bfa..0000000
--- a/arch/powerpc/include/asm/qe.h
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * QUICC Engine (QE) external definitions and structure.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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_POWERPC_QE_H
-#define _ASM_POWERPC_QE_H
-#ifdef __KERNEL__
-
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <asm/cpm.h>
-#include <asm/immap_qe.h>
-
-#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */
-#define QE_NUM_OF_BRGS 16
-#define QE_NUM_OF_PORTS 1024
-
-/* Memory partitions
-*/
-#define MEM_PART_SYSTEM 0
-#define MEM_PART_SECONDARY 1
-#define MEM_PART_MURAM 2
-
-/* Clocks and BRGs */
-enum qe_clock {
- QE_CLK_NONE = 0,
- QE_BRG1, /* Baud Rate Generator 1 */
- QE_BRG2, /* Baud Rate Generator 2 */
- QE_BRG3, /* Baud Rate Generator 3 */
- QE_BRG4, /* Baud Rate Generator 4 */
- QE_BRG5, /* Baud Rate Generator 5 */
- QE_BRG6, /* Baud Rate Generator 6 */
- QE_BRG7, /* Baud Rate Generator 7 */
- QE_BRG8, /* Baud Rate Generator 8 */
- QE_BRG9, /* Baud Rate Generator 9 */
- QE_BRG10, /* Baud Rate Generator 10 */
- QE_BRG11, /* Baud Rate Generator 11 */
- QE_BRG12, /* Baud Rate Generator 12 */
- QE_BRG13, /* Baud Rate Generator 13 */
- QE_BRG14, /* Baud Rate Generator 14 */
- QE_BRG15, /* Baud Rate Generator 15 */
- QE_BRG16, /* Baud Rate Generator 16 */
- QE_CLK1, /* Clock 1 */
- QE_CLK2, /* Clock 2 */
- QE_CLK3, /* Clock 3 */
- QE_CLK4, /* Clock 4 */
- QE_CLK5, /* Clock 5 */
- QE_CLK6, /* Clock 6 */
- QE_CLK7, /* Clock 7 */
- QE_CLK8, /* Clock 8 */
- QE_CLK9, /* Clock 9 */
- QE_CLK10, /* Clock 10 */
- QE_CLK11, /* Clock 11 */
- QE_CLK12, /* Clock 12 */
- QE_CLK13, /* Clock 13 */
- QE_CLK14, /* Clock 14 */
- QE_CLK15, /* Clock 15 */
- QE_CLK16, /* Clock 16 */
- QE_CLK17, /* Clock 17 */
- QE_CLK18, /* Clock 18 */
- QE_CLK19, /* Clock 19 */
- QE_CLK20, /* Clock 20 */
- QE_CLK21, /* Clock 21 */
- QE_CLK22, /* Clock 22 */
- QE_CLK23, /* Clock 23 */
- QE_CLK24, /* Clock 24 */
- QE_CLK_DUMMY
-};
-
-static inline bool qe_clock_is_brg(enum qe_clock clk)
-{
- return clk >= QE_BRG1 && clk <= QE_BRG16;
-}
-
-extern spinlock_t cmxgcr_lock;
-
-/* Export QE common operations */
-#ifdef CONFIG_QUICC_ENGINE
-extern void qe_reset(void);
-#else
-static inline void qe_reset(void) {}
-#endif
-
-/* QE PIO */
-#define QE_PIO_PINS 32
-
-struct qe_pio_regs {
- __be32 cpodr; /* Open drain register */
- __be32 cpdata; /* Data register */
- __be32 cpdir1; /* Direction register */
- __be32 cpdir2; /* Direction register */
- __be32 cppar1; /* Pin assignment register */
- __be32 cppar2; /* Pin assignment register */
-#ifdef CONFIG_PPC_85xx
- u8 pad[8];
-#endif
-};
-
-#define QE_PIO_DIR_IN 2
-#define QE_PIO_DIR_OUT 1
-extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin,
- int dir, int open_drain, int assignment,
- int has_irq);
-#ifdef CONFIG_QUICC_ENGINE
-extern int par_io_init(struct device_node *np);
-extern int par_io_of_config(struct device_node *np);
-extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
- int assignment, int has_irq);
-extern int par_io_data_set(u8 port, u8 pin, u8 val);
-#else
-static inline int par_io_init(struct device_node *np) { return -ENOSYS; }
-static inline int par_io_of_config(struct device_node *np) { return -ENOSYS; }
-static inline int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
- int assignment, int has_irq) { return -ENOSYS; }
-static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; }
-#endif /* CONFIG_QUICC_ENGINE */
-
-/*
- * Pin multiplexing functions.
- */
-struct qe_pin;
-#ifdef CONFIG_QE_GPIO
-extern struct qe_pin *qe_pin_request(struct device_node *np, int index);
-extern void qe_pin_free(struct qe_pin *qe_pin);
-extern void qe_pin_set_gpio(struct qe_pin *qe_pin);
-extern void qe_pin_set_dedicated(struct qe_pin *pin);
-#else
-static inline struct qe_pin *qe_pin_request(struct device_node *np, int index)
-{
- return ERR_PTR(-ENOSYS);
-}
-static inline void qe_pin_free(struct qe_pin *qe_pin) {}
-static inline void qe_pin_set_gpio(struct qe_pin *qe_pin) {}
-static inline void qe_pin_set_dedicated(struct qe_pin *pin) {}
-#endif /* CONFIG_QE_GPIO */
-
-#ifdef CONFIG_QUICC_ENGINE
-int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
-#else
-static inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
- u32 cmd_input)
-{
- return -ENOSYS;
-}
-#endif /* CONFIG_QUICC_ENGINE */
-
-/* QE internal API */
-enum qe_clock qe_clock_source(const char *source);
-unsigned int qe_get_brg_clk(void);
-int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
-int qe_get_snum(void);
-void qe_put_snum(u8 snum);
-unsigned int qe_get_num_of_risc(void);
-unsigned int qe_get_num_of_snums(void);
-
-static inline int qe_alive_during_sleep(void)
-{
- /*
- * MPC8568E reference manual says:
- *
- * "...power down sequence waits for all I/O interfaces to become idle.
- * In some applications this may happen eventually without actively
- * shutting down interfaces, but most likely, software will have to
- * take steps to shut down the eTSEC, QUICC Engine Block, and PCI
- * interfaces before issuing the command (either the write to the core
- * MSR[WE] as described above or writing to POWMGTCSR) to put the
- * device into sleep state."
- *
- * MPC8569E reference manual has a similar paragraph.
- */
-#ifdef CONFIG_PPC_85xx
- return 0;
-#else
- return 1;
-#endif
-}
-
-/* we actually use cpm_muram implementation, define this for convenience */
-#define qe_muram_init cpm_muram_init
-#define qe_muram_alloc cpm_muram_alloc
-#define qe_muram_alloc_fixed cpm_muram_alloc_fixed
-#define qe_muram_free cpm_muram_free
-#define qe_muram_addr cpm_muram_addr
-#define qe_muram_offset cpm_muram_offset
-
-/* Structure that defines QE firmware binary files.
- *
- * See Documentation/powerpc/qe_firmware.txt for a description of these
- * fields.
- */
-struct qe_firmware {
- struct qe_header {
- __be32 length; /* Length of the entire structure, in bytes */
- u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
- u8 version; /* Version of this layout. First ver is '1' */
- } header;
- u8 id[62]; /* Null-terminated identifier string */
- u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
- u8 count; /* Number of microcode[] structures */
- struct {
- __be16 model; /* The SOC model */
- u8 major; /* The SOC revision major */
- u8 minor; /* The SOC revision minor */
- } __attribute__ ((packed)) soc;
- u8 padding[4]; /* Reserved, for alignment */
- __be64 extended_modes; /* Extended modes */
- __be32 vtraps[8]; /* Virtual trap addresses */
- u8 reserved[4]; /* Reserved, for future expansion */
- struct qe_microcode {
- u8 id[32]; /* Null-terminated identifier */
- __be32 traps[16]; /* Trap addresses, 0 == ignore */
- __be32 eccr; /* The value for the ECCR register */
- __be32 iram_offset; /* Offset into I-RAM for the code */
- __be32 count; /* Number of 32-bit words of the code */
- __be32 code_offset; /* Offset of the actual microcode */
- u8 major; /* The microcode version major */
- u8 minor; /* The microcode version minor */
- u8 revision; /* The microcode version revision */
- u8 padding; /* Reserved, for alignment */
- u8 reserved[4]; /* Reserved, for future expansion */
- } __attribute__ ((packed)) microcode[1];
- /* All microcode binaries should be located here */
- /* CRC32 should be located here, after the microcode binaries */
-} __attribute__ ((packed));
-
-struct qe_firmware_info {
- char id[64]; /* Firmware name */
- u32 vtraps[8]; /* Virtual trap addresses */
- u64 extended_modes; /* Extended modes */
-};
-
-#ifdef CONFIG_QUICC_ENGINE
-/* Upload a firmware to the QE */
-int qe_upload_firmware(const struct qe_firmware *firmware);
-#else
-static inline int qe_upload_firmware(const struct qe_firmware *firmware)
-{
- return -ENOSYS;
-}
-#endif /* CONFIG_QUICC_ENGINE */
-
-/* Obtain information on the uploaded firmware */
-struct qe_firmware_info *qe_get_firmware_info(void);
-
-/* QE USB */
-int qe_usb_clock_set(enum qe_clock clk, int rate);
-
-/* Buffer descriptors */
-struct qe_bd {
- __be16 status;
- __be16 length;
- __be32 buf;
-} __attribute__ ((packed));
-
-#define BD_STATUS_MASK 0xffff0000
-#define BD_LENGTH_MASK 0x0000ffff
-
-/* Alignment */
-#define QE_INTR_TABLE_ALIGN 16 /* ??? */
-#define QE_ALIGNMENT_OF_BD 8
-#define QE_ALIGNMENT_OF_PRAM 64
-
-/* RISC allocation */
-#define QE_RISC_ALLOCATION_RISC1 0x1 /* RISC 1 */
-#define QE_RISC_ALLOCATION_RISC2 0x2 /* RISC 2 */
-#define QE_RISC_ALLOCATION_RISC3 0x4 /* RISC 3 */
-#define QE_RISC_ALLOCATION_RISC4 0x8 /* RISC 4 */
-#define QE_RISC_ALLOCATION_RISC1_AND_RISC2 (QE_RISC_ALLOCATION_RISC1 | \
- QE_RISC_ALLOCATION_RISC2)
-#define QE_RISC_ALLOCATION_FOUR_RISCS (QE_RISC_ALLOCATION_RISC1 | \
- QE_RISC_ALLOCATION_RISC2 | \
- QE_RISC_ALLOCATION_RISC3 | \
- QE_RISC_ALLOCATION_RISC4)
-
-/* QE extended filtering Table Lookup Key Size */
-enum qe_fltr_tbl_lookup_key_size {
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES
- = 0x3f, /* LookupKey parsed by the Generate LookupKey
- CMD is truncated to 8 bytes */
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES
- = 0x5f, /* LookupKey parsed by the Generate LookupKey
- CMD is truncated to 16 bytes */
-};
-
-/* QE FLTR extended filtering Largest External Table Lookup Key Size */
-enum qe_fltr_largest_external_tbl_lookup_key_size {
- QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE
- = 0x0,/* not used */
- QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES
- = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES, /* 8 bytes */
- QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES
- = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES, /* 16 bytes */
-};
-
-/* structure representing QE parameter RAM */
-struct qe_timer_tables {
- u16 tm_base; /* QE timer table base adr */
- u16 tm_ptr; /* QE timer table pointer */
- u16 r_tmr; /* QE timer mode register */
- u16 r_tmv; /* QE timer valid register */
- u32 tm_cmd; /* QE timer cmd register */
- u32 tm_cnt; /* QE timer internal cnt */
-} __attribute__ ((packed));
-
-#define QE_FLTR_TAD_SIZE 8
-
-/* QE extended filtering Termination Action Descriptor (TAD) */
-struct qe_fltr_tad {
- u8 serialized[QE_FLTR_TAD_SIZE];
-} __attribute__ ((packed));
-
-/* Communication Direction */
-enum comm_dir {
- COMM_DIR_NONE = 0,
- COMM_DIR_RX = 1,
- COMM_DIR_TX = 2,
- COMM_DIR_RX_AND_TX = 3
-};
-
-/* QE CMXUCR Registers.
- * There are two UCCs represented in each of the four CMXUCR registers.
- * These values are for the UCC in the LSBs
- */
-#define QE_CMXUCR_MII_ENET_MNG 0x00007000
-#define QE_CMXUCR_MII_ENET_MNG_SHIFT 12
-#define QE_CMXUCR_GRANT 0x00008000
-#define QE_CMXUCR_TSA 0x00004000
-#define QE_CMXUCR_BKPT 0x00000100
-#define QE_CMXUCR_TX_CLK_SRC_MASK 0x0000000F
-
-/* QE CMXGCR Registers.
-*/
-#define QE_CMXGCR_MII_ENET_MNG 0x00007000
-#define QE_CMXGCR_MII_ENET_MNG_SHIFT 12
-#define QE_CMXGCR_USBCS 0x0000000f
-#define QE_CMXGCR_USBCS_CLK3 0x1
-#define QE_CMXGCR_USBCS_CLK5 0x2
-#define QE_CMXGCR_USBCS_CLK7 0x3
-#define QE_CMXGCR_USBCS_CLK9 0x4
-#define QE_CMXGCR_USBCS_CLK13 0x5
-#define QE_CMXGCR_USBCS_CLK17 0x6
-#define QE_CMXGCR_USBCS_CLK19 0x7
-#define QE_CMXGCR_USBCS_CLK21 0x8
-#define QE_CMXGCR_USBCS_BRG9 0x9
-#define QE_CMXGCR_USBCS_BRG10 0xa
-
-/* QE CECR Commands.
-*/
-#define QE_CR_FLG 0x00010000
-#define QE_RESET 0x80000000
-#define QE_INIT_TX_RX 0x00000000
-#define QE_INIT_RX 0x00000001
-#define QE_INIT_TX 0x00000002
-#define QE_ENTER_HUNT_MODE 0x00000003
-#define QE_STOP_TX 0x00000004
-#define QE_GRACEFUL_STOP_TX 0x00000005
-#define QE_RESTART_TX 0x00000006
-#define QE_CLOSE_RX_BD 0x00000007
-#define QE_SWITCH_COMMAND 0x00000007
-#define QE_SET_GROUP_ADDRESS 0x00000008
-#define QE_START_IDMA 0x00000009
-#define QE_MCC_STOP_RX 0x00000009
-#define QE_ATM_TRANSMIT 0x0000000a
-#define QE_HPAC_CLEAR_ALL 0x0000000b
-#define QE_GRACEFUL_STOP_RX 0x0000001a
-#define QE_RESTART_RX 0x0000001b
-#define QE_HPAC_SET_PRIORITY 0x0000010b
-#define QE_HPAC_STOP_TX 0x0000020b
-#define QE_HPAC_STOP_RX 0x0000030b
-#define QE_HPAC_GRACEFUL_STOP_TX 0x0000040b
-#define QE_HPAC_GRACEFUL_STOP_RX 0x0000050b
-#define QE_HPAC_START_TX 0x0000060b
-#define QE_HPAC_START_RX 0x0000070b
-#define QE_USB_STOP_TX 0x0000000a
-#define QE_USB_RESTART_TX 0x0000000c
-#define QE_QMC_STOP_TX 0x0000000c
-#define QE_QMC_STOP_RX 0x0000000d
-#define QE_SS7_SU_FIL_RESET 0x0000000e
-/* jonathbr added from here down for 83xx */
-#define QE_RESET_BCS 0x0000000a
-#define QE_MCC_INIT_TX_RX_16 0x00000003
-#define QE_MCC_STOP_TX 0x00000004
-#define QE_MCC_INIT_TX_1 0x00000005
-#define QE_MCC_INIT_RX_1 0x00000006
-#define QE_MCC_RESET 0x00000007
-#define QE_SET_TIMER 0x00000008
-#define QE_RANDOM_NUMBER 0x0000000c
-#define QE_ATM_MULTI_THREAD_INIT 0x00000011
-#define QE_ASSIGN_PAGE 0x00000012
-#define QE_ADD_REMOVE_HASH_ENTRY 0x00000013
-#define QE_START_FLOW_CONTROL 0x00000014
-#define QE_STOP_FLOW_CONTROL 0x00000015
-#define QE_ASSIGN_PAGE_TO_DEVICE 0x00000016
-
-#define QE_ASSIGN_RISC 0x00000010
-#define QE_CR_MCN_NORMAL_SHIFT 6
-#define QE_CR_MCN_USB_SHIFT 4
-#define QE_CR_MCN_RISC_ASSIGN_SHIFT 8
-#define QE_CR_SNUM_SHIFT 17
-
-/* QE CECR Sub Block - sub block of QE command.
-*/
-#define QE_CR_SUBBLOCK_INVALID 0x00000000
-#define QE_CR_SUBBLOCK_USB 0x03200000
-#define QE_CR_SUBBLOCK_UCCFAST1 0x02000000
-#define QE_CR_SUBBLOCK_UCCFAST2 0x02200000
-#define QE_CR_SUBBLOCK_UCCFAST3 0x02400000
-#define QE_CR_SUBBLOCK_UCCFAST4 0x02600000
-#define QE_CR_SUBBLOCK_UCCFAST5 0x02800000
-#define QE_CR_SUBBLOCK_UCCFAST6 0x02a00000
-#define QE_CR_SUBBLOCK_UCCFAST7 0x02c00000
-#define QE_CR_SUBBLOCK_UCCFAST8 0x02e00000
-#define QE_CR_SUBBLOCK_UCCSLOW1 0x00000000
-#define QE_CR_SUBBLOCK_UCCSLOW2 0x00200000
-#define QE_CR_SUBBLOCK_UCCSLOW3 0x00400000
-#define QE_CR_SUBBLOCK_UCCSLOW4 0x00600000
-#define QE_CR_SUBBLOCK_UCCSLOW5 0x00800000
-#define QE_CR_SUBBLOCK_UCCSLOW6 0x00a00000
-#define QE_CR_SUBBLOCK_UCCSLOW7 0x00c00000
-#define QE_CR_SUBBLOCK_UCCSLOW8 0x00e00000
-#define QE_CR_SUBBLOCK_MCC1 0x03800000
-#define QE_CR_SUBBLOCK_MCC2 0x03a00000
-#define QE_CR_SUBBLOCK_MCC3 0x03000000
-#define QE_CR_SUBBLOCK_IDMA1 0x02800000
-#define QE_CR_SUBBLOCK_IDMA2 0x02a00000
-#define QE_CR_SUBBLOCK_IDMA3 0x02c00000
-#define QE_CR_SUBBLOCK_IDMA4 0x02e00000
-#define QE_CR_SUBBLOCK_HPAC 0x01e00000
-#define QE_CR_SUBBLOCK_SPI1 0x01400000
-#define QE_CR_SUBBLOCK_SPI2 0x01600000
-#define QE_CR_SUBBLOCK_RAND 0x01c00000
-#define QE_CR_SUBBLOCK_TIMER 0x01e00000
-#define QE_CR_SUBBLOCK_GENERAL 0x03c00000
-
-/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */
-#define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */
-#define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00
-#define QE_CR_PROTOCOL_QMC 0x02
-#define QE_CR_PROTOCOL_UART 0x04
-#define QE_CR_PROTOCOL_ATM_POS 0x0A
-#define QE_CR_PROTOCOL_ETHERNET 0x0C
-#define QE_CR_PROTOCOL_L2_SWITCH 0x0D
-
-/* BRG configuration register */
-#define QE_BRGC_ENABLE 0x00010000
-#define QE_BRGC_DIVISOR_SHIFT 1
-#define QE_BRGC_DIVISOR_MAX 0xFFF
-#define QE_BRGC_DIV16 1
-
-/* QE Timers registers */
-#define QE_GTCFR1_PCAS 0x80
-#define QE_GTCFR1_STP2 0x20
-#define QE_GTCFR1_RST2 0x10
-#define QE_GTCFR1_GM2 0x08
-#define QE_GTCFR1_GM1 0x04
-#define QE_GTCFR1_STP1 0x02
-#define QE_GTCFR1_RST1 0x01
-
-/* SDMA registers */
-#define QE_SDSR_BER1 0x02000000
-#define QE_SDSR_BER2 0x01000000
-
-#define QE_SDMR_GLB_1_MSK 0x80000000
-#define QE_SDMR_ADR_SEL 0x20000000
-#define QE_SDMR_BER1_MSK 0x02000000
-#define QE_SDMR_BER2_MSK 0x01000000
-#define QE_SDMR_EB1_MSK 0x00800000
-#define QE_SDMR_ER1_MSK 0x00080000
-#define QE_SDMR_ER2_MSK 0x00040000
-#define QE_SDMR_CEN_MASK 0x0000E000
-#define QE_SDMR_SBER_1 0x00000200
-#define QE_SDMR_SBER_2 0x00000200
-#define QE_SDMR_EB1_PR_MASK 0x000000C0
-#define QE_SDMR_ER1_PR 0x00000008
-
-#define QE_SDMR_CEN_SHIFT 13
-#define QE_SDMR_EB1_PR_SHIFT 6
-
-#define QE_SDTM_MSNUM_SHIFT 24
-
-#define QE_SDEBCR_BA_MASK 0x01FFFFFF
-
-/* Communication Processor */
-#define QE_CP_CERCR_MEE 0x8000 /* Multi-user RAM ECC enable */
-#define QE_CP_CERCR_IEE 0x4000 /* Instruction RAM ECC enable */
-#define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */
-
-/* I-RAM */
-#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */
-#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */
-#define QE_IRAM_READY 0x80000000 /* Ready */
-
-/* UPC */
-#define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */
-#define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */
-#define UPGCR_RMS 0x20000000 /* Receive master/slave mode */
-#define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing */
-#define UPGCR_DIAG 0x01000000 /* Diagnostic mode */
-
-/* UCC GUEMR register */
-#define UCC_GUEMR_MODE_MASK_RX 0x02
-#define UCC_GUEMR_MODE_FAST_RX 0x02
-#define UCC_GUEMR_MODE_SLOW_RX 0x00
-#define UCC_GUEMR_MODE_MASK_TX 0x01
-#define UCC_GUEMR_MODE_FAST_TX 0x01
-#define UCC_GUEMR_MODE_SLOW_TX 0x00
-#define UCC_GUEMR_MODE_MASK (UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX)
-#define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 in the guemr is reserved but
- must be set 1 */
-
-/* structure representing UCC SLOW parameter RAM */
-struct ucc_slow_pram {
- __be16 rbase; /* RX BD base address */
- __be16 tbase; /* TX BD base address */
- u8 rbmr; /* RX bus mode register (same as CPM's RFCR) */
- u8 tbmr; /* TX bus mode register (same as CPM's TFCR) */
- __be16 mrblr; /* Rx buffer length */
- __be32 rstate; /* Rx internal state */
- __be32 rptr; /* Rx internal data pointer */
- __be16 rbptr; /* rb BD Pointer */
- __be16 rcount; /* Rx internal byte count */
- __be32 rtemp; /* Rx temp */
- __be32 tstate; /* Tx internal state */
- __be32 tptr; /* Tx internal data pointer */
- __be16 tbptr; /* Tx BD pointer */
- __be16 tcount; /* Tx byte count */
- __be32 ttemp; /* Tx temp */
- __be32 rcrc; /* temp receive CRC */
- __be32 tcrc; /* temp transmit CRC */
-} __attribute__ ((packed));
-
-/* General UCC SLOW Mode Register (GUMRH & GUMRL) */
-#define UCC_SLOW_GUMR_H_SAM_QMC 0x00000000
-#define UCC_SLOW_GUMR_H_SAM_SATM 0x00008000
-#define UCC_SLOW_GUMR_H_REVD 0x00002000
-#define UCC_SLOW_GUMR_H_TRX 0x00001000
-#define UCC_SLOW_GUMR_H_TTX 0x00000800
-#define UCC_SLOW_GUMR_H_CDP 0x00000400
-#define UCC_SLOW_GUMR_H_CTSP 0x00000200
-#define UCC_SLOW_GUMR_H_CDS 0x00000100
-#define UCC_SLOW_GUMR_H_CTSS 0x00000080
-#define UCC_SLOW_GUMR_H_TFL 0x00000040
-#define UCC_SLOW_GUMR_H_RFW 0x00000020
-#define UCC_SLOW_GUMR_H_TXSY 0x00000010
-#define UCC_SLOW_GUMR_H_4SYNC 0x00000004
-#define UCC_SLOW_GUMR_H_8SYNC 0x00000008
-#define UCC_SLOW_GUMR_H_16SYNC 0x0000000c
-#define UCC_SLOW_GUMR_H_RTSM 0x00000002
-#define UCC_SLOW_GUMR_H_RSYN 0x00000001
-
-#define UCC_SLOW_GUMR_L_TCI 0x10000000
-#define UCC_SLOW_GUMR_L_RINV 0x02000000
-#define UCC_SLOW_GUMR_L_TINV 0x01000000
-#define UCC_SLOW_GUMR_L_TEND 0x00040000
-#define UCC_SLOW_GUMR_L_TDCR_MASK 0x00030000
-#define UCC_SLOW_GUMR_L_TDCR_32 0x00030000
-#define UCC_SLOW_GUMR_L_TDCR_16 0x00020000
-#define UCC_SLOW_GUMR_L_TDCR_8 0x00010000
-#define UCC_SLOW_GUMR_L_TDCR_1 0x00000000
-#define UCC_SLOW_GUMR_L_RDCR_MASK 0x0000c000
-#define UCC_SLOW_GUMR_L_RDCR_32 0x0000c000
-#define UCC_SLOW_GUMR_L_RDCR_16 0x00008000
-#define UCC_SLOW_GUMR_L_RDCR_8 0x00004000
-#define UCC_SLOW_GUMR_L_RDCR_1 0x00000000
-#define UCC_SLOW_GUMR_L_RENC_NRZI 0x00000800
-#define UCC_SLOW_GUMR_L_RENC_NRZ 0x00000000
-#define UCC_SLOW_GUMR_L_TENC_NRZI 0x00000100
-#define UCC_SLOW_GUMR_L_TENC_NRZ 0x00000000
-#define UCC_SLOW_GUMR_L_DIAG_MASK 0x000000c0
-#define UCC_SLOW_GUMR_L_DIAG_LE 0x000000c0
-#define UCC_SLOW_GUMR_L_DIAG_ECHO 0x00000080
-#define UCC_SLOW_GUMR_L_DIAG_LOOP 0x00000040
-#define UCC_SLOW_GUMR_L_DIAG_NORM 0x00000000
-#define UCC_SLOW_GUMR_L_ENR 0x00000020
-#define UCC_SLOW_GUMR_L_ENT 0x00000010
-#define UCC_SLOW_GUMR_L_MODE_MASK 0x0000000F
-#define UCC_SLOW_GUMR_L_MODE_BISYNC 0x00000008
-#define UCC_SLOW_GUMR_L_MODE_AHDLC 0x00000006
-#define UCC_SLOW_GUMR_L_MODE_UART 0x00000004
-#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002
-
-/* General UCC FAST Mode Register */
-#define UCC_FAST_GUMR_TCI 0x20000000
-#define UCC_FAST_GUMR_TRX 0x10000000
-#define UCC_FAST_GUMR_TTX 0x08000000
-#define UCC_FAST_GUMR_CDP 0x04000000
-#define UCC_FAST_GUMR_CTSP 0x02000000
-#define UCC_FAST_GUMR_CDS 0x01000000
-#define UCC_FAST_GUMR_CTSS 0x00800000
-#define UCC_FAST_GUMR_TXSY 0x00020000
-#define UCC_FAST_GUMR_RSYN 0x00010000
-#define UCC_FAST_GUMR_RTSM 0x00002000
-#define UCC_FAST_GUMR_REVD 0x00000400
-#define UCC_FAST_GUMR_ENR 0x00000020
-#define UCC_FAST_GUMR_ENT 0x00000010
-
-/* UART Slow UCC Event Register (UCCE) */
-#define UCC_UART_UCCE_AB 0x0200
-#define UCC_UART_UCCE_IDLE 0x0100
-#define UCC_UART_UCCE_GRA 0x0080
-#define UCC_UART_UCCE_BRKE 0x0040
-#define UCC_UART_UCCE_BRKS 0x0020
-#define UCC_UART_UCCE_CCR 0x0008
-#define UCC_UART_UCCE_BSY 0x0004
-#define UCC_UART_UCCE_TX 0x0002
-#define UCC_UART_UCCE_RX 0x0001
-
-/* HDLC Slow UCC Event Register (UCCE) */
-#define UCC_HDLC_UCCE_GLR 0x1000
-#define UCC_HDLC_UCCE_GLT 0x0800
-#define UCC_HDLC_UCCE_IDLE 0x0100
-#define UCC_HDLC_UCCE_BRKE 0x0040
-#define UCC_HDLC_UCCE_BRKS 0x0020
-#define UCC_HDLC_UCCE_TXE 0x0010
-#define UCC_HDLC_UCCE_RXF 0x0008
-#define UCC_HDLC_UCCE_BSY 0x0004
-#define UCC_HDLC_UCCE_TXB 0x0002
-#define UCC_HDLC_UCCE_RXB 0x0001
-
-/* BISYNC Slow UCC Event Register (UCCE) */
-#define UCC_BISYNC_UCCE_GRA 0x0080
-#define UCC_BISYNC_UCCE_TXE 0x0010
-#define UCC_BISYNC_UCCE_RCH 0x0008
-#define UCC_BISYNC_UCCE_BSY 0x0004
-#define UCC_BISYNC_UCCE_TXB 0x0002
-#define UCC_BISYNC_UCCE_RXB 0x0001
-
-/* Gigabit Ethernet Fast UCC Event Register (UCCE) */
-#define UCC_GETH_UCCE_MPD 0x80000000
-#define UCC_GETH_UCCE_SCAR 0x40000000
-#define UCC_GETH_UCCE_GRA 0x20000000
-#define UCC_GETH_UCCE_CBPR 0x10000000
-#define UCC_GETH_UCCE_BSY 0x08000000
-#define UCC_GETH_UCCE_RXC 0x04000000
-#define UCC_GETH_UCCE_TXC 0x02000000
-#define UCC_GETH_UCCE_TXE 0x01000000
-#define UCC_GETH_UCCE_TXB7 0x00800000
-#define UCC_GETH_UCCE_TXB6 0x00400000
-#define UCC_GETH_UCCE_TXB5 0x00200000
-#define UCC_GETH_UCCE_TXB4 0x00100000
-#define UCC_GETH_UCCE_TXB3 0x00080000
-#define UCC_GETH_UCCE_TXB2 0x00040000
-#define UCC_GETH_UCCE_TXB1 0x00020000
-#define UCC_GETH_UCCE_TXB0 0x00010000
-#define UCC_GETH_UCCE_RXB7 0x00008000
-#define UCC_GETH_UCCE_RXB6 0x00004000
-#define UCC_GETH_UCCE_RXB5 0x00002000
-#define UCC_GETH_UCCE_RXB4 0x00001000
-#define UCC_GETH_UCCE_RXB3 0x00000800
-#define UCC_GETH_UCCE_RXB2 0x00000400
-#define UCC_GETH_UCCE_RXB1 0x00000200
-#define UCC_GETH_UCCE_RXB0 0x00000100
-#define UCC_GETH_UCCE_RXF7 0x00000080
-#define UCC_GETH_UCCE_RXF6 0x00000040
-#define UCC_GETH_UCCE_RXF5 0x00000020
-#define UCC_GETH_UCCE_RXF4 0x00000010
-#define UCC_GETH_UCCE_RXF3 0x00000008
-#define UCC_GETH_UCCE_RXF2 0x00000004
-#define UCC_GETH_UCCE_RXF1 0x00000002
-#define UCC_GETH_UCCE_RXF0 0x00000001
-
-/* UCC Protocol Specific Mode Register (UPSMR), when used for UART */
-#define UCC_UART_UPSMR_FLC 0x8000
-#define UCC_UART_UPSMR_SL 0x4000
-#define UCC_UART_UPSMR_CL_MASK 0x3000
-#define UCC_UART_UPSMR_CL_8 0x3000
-#define UCC_UART_UPSMR_CL_7 0x2000
-#define UCC_UART_UPSMR_CL_6 0x1000
-#define UCC_UART_UPSMR_CL_5 0x0000
-#define UCC_UART_UPSMR_UM_MASK 0x0c00
-#define UCC_UART_UPSMR_UM_NORMAL 0x0000
-#define UCC_UART_UPSMR_UM_MAN_MULTI 0x0400
-#define UCC_UART_UPSMR_UM_AUTO_MULTI 0x0c00
-#define UCC_UART_UPSMR_FRZ 0x0200
-#define UCC_UART_UPSMR_RZS 0x0100
-#define UCC_UART_UPSMR_SYN 0x0080
-#define UCC_UART_UPSMR_DRT 0x0040
-#define UCC_UART_UPSMR_PEN 0x0010
-#define UCC_UART_UPSMR_RPM_MASK 0x000c
-#define UCC_UART_UPSMR_RPM_ODD 0x0000
-#define UCC_UART_UPSMR_RPM_LOW 0x0004
-#define UCC_UART_UPSMR_RPM_EVEN 0x0008
-#define UCC_UART_UPSMR_RPM_HIGH 0x000C
-#define UCC_UART_UPSMR_TPM_MASK 0x0003
-#define UCC_UART_UPSMR_TPM_ODD 0x0000
-#define UCC_UART_UPSMR_TPM_LOW 0x0001
-#define UCC_UART_UPSMR_TPM_EVEN 0x0002
-#define UCC_UART_UPSMR_TPM_HIGH 0x0003
-
-/* UCC Protocol Specific Mode Register (UPSMR), when used for Ethernet */
-#define UCC_GETH_UPSMR_FTFE 0x80000000
-#define UCC_GETH_UPSMR_PTPE 0x40000000
-#define UCC_GETH_UPSMR_ECM 0x04000000
-#define UCC_GETH_UPSMR_HSE 0x02000000
-#define UCC_GETH_UPSMR_PRO 0x00400000
-#define UCC_GETH_UPSMR_CAP 0x00200000
-#define UCC_GETH_UPSMR_RSH 0x00100000
-#define UCC_GETH_UPSMR_RPM 0x00080000
-#define UCC_GETH_UPSMR_R10M 0x00040000
-#define UCC_GETH_UPSMR_RLPB 0x00020000
-#define UCC_GETH_UPSMR_TBIM 0x00010000
-#define UCC_GETH_UPSMR_RES1 0x00002000
-#define UCC_GETH_UPSMR_RMM 0x00001000
-#define UCC_GETH_UPSMR_CAM 0x00000400
-#define UCC_GETH_UPSMR_BRO 0x00000200
-#define UCC_GETH_UPSMR_SMM 0x00000080
-#define UCC_GETH_UPSMR_SGMM 0x00000020
-
-/* UCC Transmit On Demand Register (UTODR) */
-#define UCC_SLOW_TOD 0x8000
-#define UCC_FAST_TOD 0x8000
-
-/* UCC Bus Mode Register masks */
-/* Not to be confused with the Bundle Mode Register */
-#define UCC_BMR_GBL 0x20
-#define UCC_BMR_BO_BE 0x10
-#define UCC_BMR_CETM 0x04
-#define UCC_BMR_DTB 0x02
-#define UCC_BMR_BDB 0x01
-
-/* Function code masks */
-#define FC_GBL 0x20
-#define FC_DTB_LCL 0x02
-#define UCC_FAST_FUNCTION_CODE_GBL 0x20
-#define UCC_FAST_FUNCTION_CODE_DTB_LCL 0x02
-#define UCC_FAST_FUNCTION_CODE_BDB_LCL 0x01
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_QE_H */
diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h
deleted file mode 100644
index 1e155ca..0000000
--- a/arch/powerpc/include/asm/qe_ic.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * QE IC external definitions and structure.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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_POWERPC_QE_IC_H
-#define _ASM_POWERPC_QE_IC_H
-
-#include <linux/irq.h>
-
-struct device_node;
-struct qe_ic;
-
-#define NUM_OF_QE_IC_GROUPS 6
-
-/* Flags when we init the QE IC */
-#define QE_IC_SPREADMODE_GRP_W 0x00000001
-#define QE_IC_SPREADMODE_GRP_X 0x00000002
-#define QE_IC_SPREADMODE_GRP_Y 0x00000004
-#define QE_IC_SPREADMODE_GRP_Z 0x00000008
-#define QE_IC_SPREADMODE_GRP_RISCA 0x00000010
-#define QE_IC_SPREADMODE_GRP_RISCB 0x00000020
-
-#define QE_IC_LOW_SIGNAL 0x00000100
-#define QE_IC_HIGH_SIGNAL 0x00000200
-
-#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH 0x00001000
-#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH 0x00002000
-#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH 0x00004000
-#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH 0x00008000
-#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH 0x00010000
-#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH 0x00020000
-#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH 0x00040000
-#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH 0x00080000
-#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH 0x00100000
-#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH 0x00200000
-#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH 0x00400000
-#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH 0x00800000
-#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT (12)
-
-/* QE interrupt sources groups */
-enum qe_ic_grp_id {
- QE_IC_GRP_W = 0, /* QE interrupt controller group W */
- QE_IC_GRP_X, /* QE interrupt controller group X */
- QE_IC_GRP_Y, /* QE interrupt controller group Y */
- QE_IC_GRP_Z, /* QE interrupt controller group Z */
- QE_IC_GRP_RISCA, /* QE interrupt controller RISC group A */
- QE_IC_GRP_RISCB /* QE interrupt controller RISC group B */
-};
-
-#ifdef CONFIG_QUICC_ENGINE
-void qe_ic_init(struct device_node *node, unsigned int flags,
- void (*low_handler)(struct irq_desc *desc),
- void (*high_handler)(struct irq_desc *desc));
-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic);
-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic);
-#else
-static inline void qe_ic_init(struct device_node *node, unsigned int flags,
- void (*low_handler)(struct irq_desc *desc),
- void (*high_handler)(struct irq_desc *desc))
-{}
-static inline unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
-{ return 0; }
-static inline unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
-{ return 0; }
-#endif /* CONFIG_QUICC_ENGINE */
-
-void qe_ic_set_highest_priority(unsigned int virq, int high);
-int qe_ic_set_priority(unsigned int virq, unsigned int priority);
-int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
-
-static inline void qe_ic_cascade_low_ipic(struct irq_desc *desc)
-{
- struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
- unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
-
- if (cascade_irq != NO_IRQ)
- generic_handle_irq(cascade_irq);
-}
-
-static inline void qe_ic_cascade_high_ipic(struct irq_desc *desc)
-{
- struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
- unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
-
- if (cascade_irq != NO_IRQ)
- generic_handle_irq(cascade_irq);
-}
-
-static inline void qe_ic_cascade_low_mpic(struct irq_desc *desc)
-{
- struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
- unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- if (cascade_irq != NO_IRQ)
- generic_handle_irq(cascade_irq);
-
- chip->irq_eoi(&desc->irq_data);
-}
-
-static inline void qe_ic_cascade_high_mpic(struct irq_desc *desc)
-{
- struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
- unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- if (cascade_irq != NO_IRQ)
- generic_handle_irq(cascade_irq);
-
- chip->irq_eoi(&desc->irq_data);
-}
-
-static inline void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
-{
- struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
- unsigned int cascade_irq;
- struct irq_chip *chip = irq_desc_get_chip(desc);
-
- cascade_irq = qe_ic_get_high_irq(qe_ic);
- if (cascade_irq == NO_IRQ)
- cascade_irq = qe_ic_get_low_irq(qe_ic);
-
- if (cascade_irq != NO_IRQ)
- generic_handle_irq(cascade_irq);
-
- chip->irq_eoi(&desc->irq_data);
-}
-
-#endif /* _ASM_POWERPC_QE_IC_H */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index a908ada..f5f4c66 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -75,6 +75,14 @@
#define MSR_HV 0
#endif
+/*
+ * To be used in shared book E/book S, this avoids needing to worry about
+ * book S/book E in shared code
+ */
+#ifndef MSR_SPE
+#define MSR_SPE 0
+#endif
+
#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
#define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */
#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
@@ -108,6 +116,7 @@
#define MSR_TS_T __MASK(MSR_TS_T_LG) /* Transaction Transactional */
#define MSR_TS_MASK (MSR_TS_T | MSR_TS_S) /* Transaction State bits */
#define MSR_TM_ACTIVE(x) (((x) & MSR_TS_MASK) != 0) /* Transaction active? */
+#define MSR_TM_RESV(x) (((x) & MSR_TS_MASK) == MSR_TS_MASK) /* Reserved */
#define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T)
#define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S)
@@ -375,7 +384,7 @@
#define SPRN_TSCR 0x399 /* Thread Switch Control Register */
#define SPRN_DEC 0x016 /* Decrement Register */
-#define SPRN_DER 0x095 /* Debug Enable Regsiter */
+#define SPRN_DER 0x095 /* Debug Enable Register */
#define DER_RSTE 0x40000000 /* Reset Interrupt */
#define DER_CHSTPE 0x20000000 /* Check Stop */
#define DER_MCIE 0x10000000 /* Machine Check Interrupt */
@@ -400,7 +409,7 @@
#define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */
#define SPRN_EAR 0x11A /* External Address Register */
#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */
-#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */
+#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Register */
#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */
#define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */
#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
@@ -513,7 +522,7 @@
#define ICTRL_EICP 0x00000100 /* enable icache par. check */
#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */
#define SPRN_IMMR 0x27E /* Internal Memory Map Register */
-#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */
+#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Register */
#define SPRN_L2CR2 0x3f8
#define L2CR_L2E 0x80000000 /* L2 enable */
#define L2CR_L2PE 0x40000000 /* L2 parity enable */
@@ -548,7 +557,7 @@
#define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */
#define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */
#define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */
-#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */
+#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Register */
#define L3CR_L3E 0x80000000 /* L3 enable */
#define L3CR_L3PE 0x40000000 /* L3 data parity enable */
#define L3CR_L3APE 0x20000000 /* L3 addr parity enable */
@@ -1193,18 +1202,37 @@
#define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
: : "r" (v) : "memory")
#define mtmsr(v) __mtmsrd((v), 0)
+#define __MTMSR "mtmsrd"
#else
#define mtmsr(v) asm volatile("mtmsr %0" : \
: "r" ((unsigned long)(v)) \
: "memory")
+#define __MTMSR "mtmsr"
#endif
+static inline void mtmsr_isync(unsigned long val)
+{
+ asm volatile(__MTMSR " %0; " ASM_FTR_IFCLR("isync", "nop", %1) : :
+ "r" (val), "i" (CPU_FTR_ARCH_206) : "memory");
+}
+
#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
: "=r" (rval)); rval;})
+#ifndef mtspr
#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
: "r" ((unsigned long)(v)) \
: "memory")
+#endif
+
+extern void msr_check_and_set(unsigned long bits);
+extern bool strict_msr_control;
+extern void __msr_check_and_clear(unsigned long bits);
+static inline void msr_check_and_clear(unsigned long bits)
+{
+ if (strict_msr_control)
+ __msr_check_and_clear(bits);
+}
static inline unsigned long mfvtb (void)
{
diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h
index e8ea346..94d01f8 100644
--- a/arch/powerpc/include/asm/reg_8xx.h
+++ b/arch/powerpc/include/asm/reg_8xx.h
@@ -4,6 +4,8 @@
#ifndef _ASM_POWERPC_REG_8xx_H
#define _ASM_POWERPC_REG_8xx_H
+#include <asm/mmu-8xx.h>
+
/* Cache control on the MPC8xx is provided through some additional
* special purpose registers.
*/
@@ -14,6 +16,15 @@
#define SPRN_DC_ADR 569 /* Address needed for some commands */
#define SPRN_DC_DAT 570 /* Read-only data register */
+/* Misc Debug */
+#define SPRN_DPDR 630
+#define SPRN_MI_CAM 816
+#define SPRN_MI_RAM0 817
+#define SPRN_MI_RAM1 818
+#define SPRN_MD_CAM 824
+#define SPRN_MD_RAM0 825
+#define SPRN_MD_RAM1 826
+
/* Commands. Only the first few are available to the instruction cache.
*/
#define IDC_ENABLE 0x02000000 /* Cache enable */
@@ -39,4 +50,86 @@
#define DC_DFWT 0x40000000 /* Data cache is forced write through */
#define DC_LES 0x20000000 /* Caches are little endian mode */
+#ifdef CONFIG_8xx_CPU6
+#define do_mtspr_cpu6(rn, rn_addr, v) \
+ do { \
+ int _reg_cpu6 = rn_addr, _tmp_cpu6; \
+ asm volatile("stw %0, %1;" \
+ "lwz %0, %1;" \
+ "mtspr " __stringify(rn) ",%2" : \
+ : "r" (_reg_cpu6), "m"(_tmp_cpu6), \
+ "r" ((unsigned long)(v)) \
+ : "memory"); \
+ } while (0)
+
+#define do_mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
+ : "r" ((unsigned long)(v)) \
+ : "memory")
+#define mtspr(rn, v) \
+ do { \
+ if (rn == SPRN_IMMR) \
+ do_mtspr_cpu6(rn, 0x3d30, v); \
+ else if (rn == SPRN_IC_CST) \
+ do_mtspr_cpu6(rn, 0x2110, v); \
+ else if (rn == SPRN_IC_ADR) \
+ do_mtspr_cpu6(rn, 0x2310, v); \
+ else if (rn == SPRN_IC_DAT) \
+ do_mtspr_cpu6(rn, 0x2510, v); \
+ else if (rn == SPRN_DC_CST) \
+ do_mtspr_cpu6(rn, 0x3110, v); \
+ else if (rn == SPRN_DC_ADR) \
+ do_mtspr_cpu6(rn, 0x3310, v); \
+ else if (rn == SPRN_DC_DAT) \
+ do_mtspr_cpu6(rn, 0x3510, v); \
+ else if (rn == SPRN_MI_CTR) \
+ do_mtspr_cpu6(rn, 0x2180, v); \
+ else if (rn == SPRN_MI_AP) \
+ do_mtspr_cpu6(rn, 0x2580, v); \
+ else if (rn == SPRN_MI_EPN) \
+ do_mtspr_cpu6(rn, 0x2780, v); \
+ else if (rn == SPRN_MI_TWC) \
+ do_mtspr_cpu6(rn, 0x2b80, v); \
+ else if (rn == SPRN_MI_RPN) \
+ do_mtspr_cpu6(rn, 0x2d80, v); \
+ else if (rn == SPRN_MI_CAM) \
+ do_mtspr_cpu6(rn, 0x2190, v); \
+ else if (rn == SPRN_MI_RAM0) \
+ do_mtspr_cpu6(rn, 0x2390, v); \
+ else if (rn == SPRN_MI_RAM1) \
+ do_mtspr_cpu6(rn, 0x2590, v); \
+ else if (rn == SPRN_MD_CTR) \
+ do_mtspr_cpu6(rn, 0x3180, v); \
+ else if (rn == SPRN_M_CASID) \
+ do_mtspr_cpu6(rn, 0x3380, v); \
+ else if (rn == SPRN_MD_AP) \
+ do_mtspr_cpu6(rn, 0x3580, v); \
+ else if (rn == SPRN_MD_EPN) \
+ do_mtspr_cpu6(rn, 0x3780, v); \
+ else if (rn == SPRN_M_TWB) \
+ do_mtspr_cpu6(rn, 0x3980, v); \
+ else if (rn == SPRN_MD_TWC) \
+ do_mtspr_cpu6(rn, 0x3b80, v); \
+ else if (rn == SPRN_MD_RPN) \
+ do_mtspr_cpu6(rn, 0x3d80, v); \
+ else if (rn == SPRN_M_TW) \
+ do_mtspr_cpu6(rn, 0x3f80, v); \
+ else if (rn == SPRN_MD_CAM) \
+ do_mtspr_cpu6(rn, 0x3190, v); \
+ else if (rn == SPRN_MD_RAM0) \
+ do_mtspr_cpu6(rn, 0x3390, v); \
+ else if (rn == SPRN_MD_RAM1) \
+ do_mtspr_cpu6(rn, 0x3590, v); \
+ else if (rn == SPRN_DEC) \
+ do_mtspr_cpu6(rn, 0x2c00, v); \
+ else if (rn == SPRN_TBWL) \
+ do_mtspr_cpu6(rn, 0x3880, v); \
+ else if (rn == SPRN_TBWU) \
+ do_mtspr_cpu6(rn, 0x3a80, v); \
+ else if (rn == SPRN_DPDR) \
+ do_mtspr_cpu6(rn, 0x2d30, v); \
+ else \
+ do_mtspr(rn, v); \
+ } while (0)
+#endif
+
#endif /* _ASM_POWERPC_REG_8xx_H */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 16547ef..737e012 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -681,7 +681,7 @@
#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */
#define SPRN_TBHI 0x3DC /* Time Base High */
#define SPRN_TBLO 0x3DD /* Time Base Low */
-#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */
+#define SPRN_DBCR 0x3F2 /* Debug Control Register */
#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */
#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */
#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */
@@ -742,6 +742,12 @@
#define MMUBE1_VBE4 0x00000002
#define MMUBE1_VBE5 0x00000001
+#define TMRN_TMCFG0 16 /* Thread Management Configuration Register 0 */
+#define TMRN_TMCFG0_NPRIBITS 0x003f0000 /* Bits of thread priority */
+#define TMRN_TMCFG0_NPRIBITS_SHIFT 16
+#define TMRN_TMCFG0_NATHRD 0x00003f00 /* Number of active threads */
+#define TMRN_TMCFG0_NATHRD_SHIFT 8
+#define TMRN_TMCFG0_NTHRD 0x0000003f /* Number of threads */
#define TMRN_IMSR0 0x120 /* Initial MSR Register 0 (e6500) */
#define TMRN_IMSR1 0x121 /* Initial MSR Register 1 (e6500) */
#define TMRN_INIA0 0x140 /* Next Instruction Address Register 0 */
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index b77ef36..51400ba 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -334,10 +334,11 @@ extern void (*rtas_flash_term_hook)(int);
extern struct rtas_t rtas;
-extern void enter_rtas(unsigned long);
extern int rtas_token(const char *service);
extern int rtas_service_present(const char *service);
extern int rtas_call(int token, int, int, int *, ...);
+void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
+ int nret, ...);
extern void rtas_restart(char *cmd);
extern void rtas_power_off(void);
extern void rtas_halt(void);
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index a5e930a..abf5866 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -22,6 +22,18 @@ static inline int in_kernel_text(unsigned long addr)
return 0;
}
+static inline unsigned long kernel_toc_addr(void)
+{
+ /* Defined by the linker, see vmlinux.lds.S */
+ extern unsigned long __toc_start;
+
+ /*
+ * The TOC register (r2) points 32kB into the TOC, so that 64kB of
+ * the TOC can be addressed using a single machine instruction.
+ */
+ return (unsigned long)(&__toc_start) + 0x8000UL;
+}
+
static inline int overlaps_interrupt_vector_text(unsigned long start,
unsigned long end)
{
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 825663c..e1afd4c 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu);
void generic_set_cpu_dead(unsigned int cpu);
void generic_set_cpu_up(unsigned int cpu);
int generic_check_cpu_restart(unsigned int cpu);
+int is_cpu_dead(unsigned int cpu);
+#else
+#define generic_set_cpu_up(i) do { } while (0)
#endif
#ifdef CONFIG_PPC64
@@ -114,6 +117,9 @@ extern int cpu_to_core_id(int cpu);
#define PPC_MSG_TICK_BROADCAST 2
#define PPC_MSG_DEBUGGER_BREAK 3
+/* This is only used by the powernv kernel */
+#define PPC_MSG_RM_HOST_ACTION 4
+
/* for irq controllers that have dedicated ipis per message (4) */
extern int smp_request_message_ipi(int virq, int message);
extern const char *smp_ipi_name[];
@@ -121,6 +127,7 @@ extern const char *smp_ipi_name[];
/* for irq controllers with only a single ipi */
extern void smp_muxed_ipi_set_data(int cpu, unsigned long data);
extern void smp_muxed_ipi_message_pass(int cpu, int msg);
+extern void smp_muxed_ipi_set_message(int cpu, int msg);
extern irqreturn_t smp_ipi_demux(void);
void smp_init_pSeries(void);
@@ -197,6 +204,7 @@ extern void generic_secondary_thread_init(void);
extern unsigned long __secondary_hold_spinloop;
extern unsigned long __secondary_hold_acknowledge;
extern char __secondary_hold;
+extern unsigned int booting_thread_hwid;
extern void __early_start(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h
index 37d2da6..f280dd1 100644
--- a/arch/powerpc/include/asm/smu.h
+++ b/arch/powerpc/include/asm/smu.h
@@ -154,7 +154,7 @@
*
* The Darwin I2C driver is less subtle though. On any non-success status
* from the response command, it waits 5ms and tries again up to 20 times,
- * it doesn't differenciate between fatal errors or "busy" status.
+ * it doesn't differentiate between fatal errors or "busy" status.
*
* This driver provides an asynchronous paramblock based i2c command
* interface to be used either directly by low level code or by a higher
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 15cca17..17c8380 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -4,6 +4,8 @@
#ifndef _ASM_POWERPC_SWITCH_TO_H
#define _ASM_POWERPC_SWITCH_TO_H
+#include <asm/reg.h>
+
struct thread_struct;
struct task_struct;
struct pt_regs;
@@ -12,75 +14,65 @@ extern struct task_struct *__switch_to(struct task_struct *,
struct task_struct *);
#define switch_to(prev, next, last) ((last) = __switch_to((prev), (next)))
-struct thread_struct;
extern struct task_struct *_switch(struct thread_struct *prev,
struct thread_struct *next);
-#ifdef CONFIG_PPC_BOOK3S_64
-static inline void save_early_sprs(struct thread_struct *prev)
-{
- if (cpu_has_feature(CPU_FTR_ARCH_207S))
- prev->tar = mfspr(SPRN_TAR);
- if (cpu_has_feature(CPU_FTR_DSCR))
- prev->dscr = mfspr(SPRN_DSCR);
-}
-#else
-static inline void save_early_sprs(struct thread_struct *prev) {}
-#endif
-extern void enable_kernel_fp(void);
-extern void enable_kernel_altivec(void);
-extern void enable_kernel_vsx(void);
-extern int emulate_altivec(struct pt_regs *);
-extern void __giveup_vsx(struct task_struct *);
-extern void giveup_vsx(struct task_struct *);
-extern void enable_kernel_spe(void);
-extern void giveup_spe(struct task_struct *);
-extern void load_up_spe(struct task_struct *);
extern void switch_booke_debug_regs(struct debug_reg *new_debug);
-#ifndef CONFIG_SMP
-extern void discard_lazy_cpu_state(void);
-#else
-static inline void discard_lazy_cpu_state(void)
-{
-}
-#endif
+extern int emulate_altivec(struct pt_regs *);
+
+extern void flush_all_to_thread(struct task_struct *);
+extern void giveup_all(struct task_struct *);
#ifdef CONFIG_PPC_FPU
+extern void enable_kernel_fp(void);
extern void flush_fp_to_thread(struct task_struct *);
extern void giveup_fpu(struct task_struct *);
+extern void save_fpu(struct task_struct *);
+static inline void disable_kernel_fp(void)
+{
+ msr_check_and_clear(MSR_FP);
+}
#else
+static inline void __giveup_fpu(struct task_struct *t) { }
+static inline void save_fpu(struct task_struct *t) { }
static inline void flush_fp_to_thread(struct task_struct *t) { }
-static inline void giveup_fpu(struct task_struct *t) { }
#endif
#ifdef CONFIG_ALTIVEC
+extern void enable_kernel_altivec(void);
extern void flush_altivec_to_thread(struct task_struct *);
extern void giveup_altivec(struct task_struct *);
-extern void giveup_altivec_notask(void);
-#else
-static inline void flush_altivec_to_thread(struct task_struct *t)
-{
-}
-static inline void giveup_altivec(struct task_struct *t)
+extern void save_altivec(struct task_struct *);
+static inline void disable_kernel_altivec(void)
{
+ msr_check_and_clear(MSR_VEC);
}
+#else
+static inline void save_altivec(struct task_struct *t) { }
+static inline void __giveup_altivec(struct task_struct *t) { }
#endif
#ifdef CONFIG_VSX
+extern void enable_kernel_vsx(void);
extern void flush_vsx_to_thread(struct task_struct *);
-#else
-static inline void flush_vsx_to_thread(struct task_struct *t)
+static inline void disable_kernel_vsx(void)
{
+ msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
}
#endif
#ifdef CONFIG_SPE
+extern void enable_kernel_spe(void);
extern void flush_spe_to_thread(struct task_struct *);
-#else
-static inline void flush_spe_to_thread(struct task_struct *t)
+extern void giveup_spe(struct task_struct *);
+extern void __giveup_spe(struct task_struct *);
+static inline void disable_kernel_spe(void)
{
+ msr_check_and_clear(MSR_SPE);
}
+#else
+static inline void __giveup_spe(struct task_struct *t) { }
#endif
static inline void clear_task_ebb(struct task_struct *t)
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
index e682a71..c508686 100644
--- a/arch/powerpc/include/asm/synch.h
+++ b/arch/powerpc/include/asm/synch.h
@@ -44,7 +44,7 @@ static inline void isync(void)
MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
#define PPC_ACQUIRE_BARRIER "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
#define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n"
-#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(sync) "\n"
#define PPC_ATOMIC_EXIT_BARRIER "\n" stringify_in_c(sync) "\n"
#else
#define PPC_ACQUIRE_BARRIER
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 126d0c4..3fa9df7 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -370,3 +370,17 @@ COMPAT_SYS(execveat)
PPC64ONLY(switch_endian)
SYSCALL_SPU(userfaultfd)
SYSCALL_SPU(membarrier)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYSCALL(mlock2)
+SYSCALL(copy_file_range)
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 10fc784..1092fdd 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -27,13 +27,10 @@ extern struct clock_event_device decrementer_clockevent;
struct rtc_time;
extern void to_tm(int tim, struct rtc_time * tm);
-extern void GregorianDay(struct rtc_time *tm);
extern void tick_broadcast_ipi_handler(void);
extern void generic_calibrate_decr(void);
-extern void set_dec_cpu6(unsigned int val);
-
/* Some sane defaults: 125 MHz timebase, 1GHz processor */
extern unsigned long ppc_proc_freq;
#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
@@ -167,14 +164,12 @@ static inline void set_dec(int val)
{
#if defined(CONFIG_40x)
mtspr(SPRN_PIT, val);
-#elif defined(CONFIG_8xx_CPU6)
- set_dec_cpu6(val - 1);
#else
#ifndef CONFIG_BOOKE
--val;
#endif
mtspr(SPRN_DEC, val);
-#endif /* not 40x or 8xx_CPU6 */
+#endif /* not 40x */
}
static inline unsigned long tb_ticks_since(unsigned long tstamp)
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index 23d351c..9f77f85 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -78,97 +78,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
}
#elif defined(CONFIG_PPC_STD_MMU_64)
-
-#define MMU_NO_CONTEXT 0
-
-/*
- * TLB flushing for 64-bit hash-MMU CPUs
- */
-
-#include <linux/percpu.h>
-#include <asm/page.h>
-
-#define PPC64_TLB_BATCH_NR 192
-
-struct ppc64_tlb_batch {
- int active;
- unsigned long index;
- struct mm_struct *mm;
- real_pte_t pte[PPC64_TLB_BATCH_NR];
- unsigned long vpn[PPC64_TLB_BATCH_NR];
- unsigned int psize;
- int ssize;
-};
-DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
-
-extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
-
-#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
-
-static inline void arch_enter_lazy_mmu_mode(void)
-{
- struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
-
- batch->active = 1;
-}
-
-static inline void arch_leave_lazy_mmu_mode(void)
-{
- struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
-
- if (batch->index)
- __flush_tlb_pending(batch);
- batch->active = 0;
-}
-
-#define arch_flush_lazy_mmu_mode() do {} while (0)
-
-
-extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
- int ssize, unsigned long flags);
-extern void flush_hash_range(unsigned long number, int local);
-extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
- pmd_t *pmdp, unsigned int psize, int ssize,
- unsigned long flags);
-
-static inline void local_flush_tlb_mm(struct mm_struct *mm)
-{
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-}
-
-static inline void local_flush_tlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
-}
-
-static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
-}
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
-{
-}
-
-/* Private function for use by PCI IO mapping code */
-extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
- unsigned long end);
-extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr);
+#include <asm/book3s/64/tlbflush-hash.h>
#else
#error Unsupported MMU type
#endif
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index 8e86b48..32e36b1 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -57,12 +57,14 @@ DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_exit,
extern void hcall_tracepoint_regfunc(void);
extern void hcall_tracepoint_unregfunc(void);
-TRACE_EVENT_FN(hcall_entry,
+TRACE_EVENT_FN_COND(hcall_entry,
TP_PROTO(unsigned long opcode, unsigned long *args),
TP_ARGS(opcode, args),
+ TP_CONDITION(cpu_online(raw_smp_processor_id())),
+
TP_STRUCT__entry(
__field(unsigned long, opcode)
),
@@ -76,13 +78,15 @@ TRACE_EVENT_FN(hcall_entry,
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
);
-TRACE_EVENT_FN(hcall_exit,
+TRACE_EVENT_FN_COND(hcall_exit,
TP_PROTO(unsigned long opcode, unsigned long retval,
unsigned long *retbuf),
TP_ARGS(opcode, retval, retbuf),
+ TP_CONDITION(cpu_online(raw_smp_processor_id())),
+
TP_STRUCT__entry(
__field(unsigned long, opcode)
__field(unsigned long, retval)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 2a8ebae..b7c20f0 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -274,21 +274,6 @@ do { \
__gu_err; \
})
-#ifndef __powerpc64__
-#define __get_user64_nocheck(x, ptr, size) \
-({ \
- long __gu_err; \
- long long __gu_val; \
- __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- __chk_user_ptr(ptr); \
- if (!is_kernel_addr((unsigned long)__gu_addr)) \
- might_fault(); \
- __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__force __typeof__(*(ptr)))__gu_val; \
- __gu_err; \
-})
-#endif /* __powerpc64__ */
-
#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
diff --git a/arch/powerpc/include/asm/ucc.h b/arch/powerpc/include/asm/ucc.h
deleted file mode 100644
index 6927ac2..0000000
--- a/arch/powerpc/include/asm/ucc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * Internal header file for UCC unit routines.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 __UCC_H__
-#define __UCC_H__
-
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-#define STATISTICS
-
-#define UCC_MAX_NUM 8
-
-/* Slow or fast type for UCCs.
-*/
-enum ucc_speed_type {
- UCC_SPEED_TYPE_FAST = UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX,
- UCC_SPEED_TYPE_SLOW = UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX
-};
-
-/* ucc_set_type
- * Sets UCC to slow or fast mode.
- *
- * ucc_num - (In) number of UCC (0-7).
- * speed - (In) slow or fast mode for UCC.
- */
-int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed);
-
-int ucc_set_qe_mux_mii_mng(unsigned int ucc_num);
-
-int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
- enum comm_dir mode);
-
-int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask);
-
-/* QE MUX clock routing for UCC
-*/
-static inline int ucc_set_qe_mux_grant(unsigned int ucc_num, int set)
-{
- return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT);
-}
-
-static inline int ucc_set_qe_mux_tsa(unsigned int ucc_num, int set)
-{
- return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA);
-}
-
-static inline int ucc_set_qe_mux_bkpt(unsigned int ucc_num, int set)
-{
- return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT);
-}
-
-#endif /* __UCC_H__ */
diff --git a/arch/powerpc/include/asm/ucc_fast.h b/arch/powerpc/include/asm/ucc_fast.h
deleted file mode 100644
index 72ea9ba..0000000
--- a/arch/powerpc/include/asm/ucc_fast.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Internal header file for UCC FAST unit routines.
- *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@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.
- */
-#ifndef __UCC_FAST_H__
-#define __UCC_FAST_H__
-
-#include <linux/kernel.h>
-
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-#include <asm/ucc.h>
-
-/* Receive BD's status */
-#define R_E 0x80000000 /* buffer empty */
-#define R_W 0x20000000 /* wrap bit */
-#define R_I 0x10000000 /* interrupt on reception */
-#define R_L 0x08000000 /* last */
-#define R_F 0x04000000 /* first */
-
-/* transmit BD's status */
-#define T_R 0x80000000 /* ready bit */
-#define T_W 0x20000000 /* wrap bit */
-#define T_I 0x10000000 /* interrupt on completion */
-#define T_L 0x08000000 /* last */
-
-/* Rx Data buffer must be 4 bytes aligned in most cases */
-#define UCC_FAST_RX_ALIGN 4
-#define UCC_FAST_MRBLR_ALIGNMENT 4
-#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT 8
-
-/* Sizes */
-#define UCC_FAST_URFS_MIN_VAL 0x88
-#define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR 8
-
-/* ucc_fast_channel_protocol_mode - UCC FAST mode */
-enum ucc_fast_channel_protocol_mode {
- UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000,
- UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001,
- UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002,
- UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003,
- UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004,
- UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005,
- UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006,
- UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007,
- UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008,
- UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009,
- UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A,
- UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B,
- UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C,
- UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D,
- UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E,
- UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F
-};
-
-/* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */
-enum ucc_fast_transparent_txrx {
- UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000,
- UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000
-};
-
-/* UCC fast diagnostic mode */
-enum ucc_fast_diag_mode {
- UCC_FAST_DIAGNOSTIC_NORMAL = 0x0,
- UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000,
- UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000,
- UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000
-};
-
-/* UCC fast Sync length (transparent mode only) */
-enum ucc_fast_sync_len {
- UCC_FAST_SYNC_LEN_NOT_USED = 0x0,
- UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000,
- UCC_FAST_SYNC_LEN_8_BIT = 0x00008000,
- UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000
-};
-
-/* UCC fast RTS mode */
-enum ucc_fast_ready_to_send {
- UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000,
- UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000
-};
-
-/* UCC fast receiver decoding mode */
-enum ucc_fast_rx_decoding_method {
- UCC_FAST_RX_ENCODING_NRZ = 0x00000000,
- UCC_FAST_RX_ENCODING_NRZI = 0x00000800,
- UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000,
- UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800
-};
-
-/* UCC fast transmitter encoding mode */
-enum ucc_fast_tx_encoding_method {
- UCC_FAST_TX_ENCODING_NRZ = 0x00000000,
- UCC_FAST_TX_ENCODING_NRZI = 0x00000100,
- UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200,
- UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300
-};
-
-/* UCC fast CRC length */
-enum ucc_fast_transparent_tcrc {
- UCC_FAST_16_BIT_CRC = 0x00000000,
- UCC_FAST_CRC_RESERVED0 = 0x00000040,
- UCC_FAST_32_BIT_CRC = 0x00000080,
- UCC_FAST_CRC_RESERVED1 = 0x000000C0
-};
-
-/* Fast UCC initialization structure */
-struct ucc_fast_info {
- int ucc_num;
- enum qe_clock rx_clock;
- enum qe_clock tx_clock;
- u32 regs;
- int irq;
- u32 uccm_mask;
- int bd_mem_part;
- int brkpt_support;
- int grant_support;
- int tsa;
- int cdp;
- int cds;
- int ctsp;
- int ctss;
- int tci;
- int txsy;
- int rtsm;
- int revd;
- int rsyn;
- u16 max_rx_buf_length;
- u16 urfs;
- u16 urfet;
- u16 urfset;
- u16 utfs;
- u16 utfet;
- u16 utftt;
- u16 ufpt;
- enum ucc_fast_channel_protocol_mode mode;
- enum ucc_fast_transparent_txrx ttx_trx;
- enum ucc_fast_tx_encoding_method tenc;
- enum ucc_fast_rx_decoding_method renc;
- enum ucc_fast_transparent_tcrc tcrc;
- enum ucc_fast_sync_len synl;
-};
-
-struct ucc_fast_private {
- struct ucc_fast_info *uf_info;
- struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */
- u32 __iomem *p_ucce; /* a pointer to the event register in memory. */
- u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */
-#ifdef CONFIG_UGETH_TX_ON_DEMAND
- u16 __iomem *p_utodr; /* pointer to the transmit on demand register */
-#endif
- int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
- int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
- int stopped_tx; /* Whether channel has been stopped for Tx
- (STOP_TX, etc.) */
- int stopped_rx; /* Whether channel has been stopped for Rx */
- u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
- virtual fifo */
- u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
- virtual fifo */
-#ifdef STATISTICS
- u32 tx_frames; /* Transmitted frames counter. */
- u32 rx_frames; /* Received frames counter (only frames
- passed to application). */
- u32 tx_discarded; /* Discarded tx frames counter (frames that
- were discarded by the driver due to errors).
- */
- u32 rx_discarded; /* Discarded rx frames counter (frames that
- were discarded by the driver due to errors).
- */
-#endif /* STATISTICS */
- u16 mrblr; /* maximum receive buffer length */
-};
-
-/* ucc_fast_init
- * Initializes Fast UCC according to user provided parameters.
- *
- * uf_info - (In) pointer to the fast UCC info structure.
- * uccf_ret - (Out) pointer to the fast UCC structure.
- */
-int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret);
-
-/* ucc_fast_free
- * Frees all resources for fast UCC.
- *
- * uccf - (In) pointer to the fast UCC structure.
- */
-void ucc_fast_free(struct ucc_fast_private * uccf);
-
-/* ucc_fast_enable
- * Enables a fast UCC port.
- * This routine enables Tx and/or Rx through the General UCC Mode Register.
- *
- * uccf - (In) pointer to the fast UCC structure.
- * mode - (In) TX, RX, or both.
- */
-void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode);
-
-/* ucc_fast_disable
- * Disables a fast UCC port.
- * This routine disables Tx and/or Rx through the General UCC Mode Register.
- *
- * uccf - (In) pointer to the fast UCC structure.
- * mode - (In) TX, RX, or both.
- */
-void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode);
-
-/* ucc_fast_irq
- * Handles interrupts on fast UCC.
- * Called from the general interrupt routine to handle interrupts on fast UCC.
- *
- * uccf - (In) pointer to the fast UCC structure.
- */
-void ucc_fast_irq(struct ucc_fast_private * uccf);
-
-/* ucc_fast_transmit_on_demand
- * Immediately forces a poll of the transmitter for data to be sent.
- * Typically, the hardware performs a periodic poll for data that the
- * transmit routine has set up to be transmitted. In cases where
- * this polling cycle is not soon enough, this optional routine can
- * be invoked to force a poll right away, instead. Proper use for
- * each transmission for which this functionality is desired is to
- * call the transmit routine and then this routine right after.
- *
- * uccf - (In) pointer to the fast UCC structure.
- */
-void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf);
-
-u32 ucc_fast_get_qe_cr_subblock(int uccf_num);
-
-void ucc_fast_dump_regs(struct ucc_fast_private * uccf);
-
-#endif /* __UCC_FAST_H__ */
diff --git a/arch/powerpc/include/asm/ucc_slow.h b/arch/powerpc/include/asm/ucc_slow.h
deleted file mode 100644
index 233ef5f..0000000
--- a/arch/powerpc/include/asm/ucc_slow.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * Internal header file for UCC SLOW unit routines.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 __UCC_SLOW_H__
-#define __UCC_SLOW_H__
-
-#include <linux/kernel.h>
-
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-#include <asm/ucc.h>
-
-/* transmit BD's status */
-#define T_R 0x80000000 /* ready bit */
-#define T_PAD 0x40000000 /* add pads to short frames */
-#define T_W 0x20000000 /* wrap bit */
-#define T_I 0x10000000 /* interrupt on completion */
-#define T_L 0x08000000 /* last */
-
-#define T_A 0x04000000 /* Address - the data transmitted as address
- chars */
-#define T_TC 0x04000000 /* transmit CRC */
-#define T_CM 0x02000000 /* continuous mode */
-#define T_DEF 0x02000000 /* collision on previous attempt to transmit */
-#define T_P 0x01000000 /* Preamble - send Preamble sequence before
- data */
-#define T_HB 0x01000000 /* heartbeat */
-#define T_NS 0x00800000 /* No Stop */
-#define T_LC 0x00800000 /* late collision */
-#define T_RL 0x00400000 /* retransmission limit */
-#define T_UN 0x00020000 /* underrun */
-#define T_CT 0x00010000 /* CTS lost */
-#define T_CSL 0x00010000 /* carrier sense lost */
-#define T_RC 0x003c0000 /* retry count */
-
-/* Receive BD's status */
-#define R_E 0x80000000 /* buffer empty */
-#define R_W 0x20000000 /* wrap bit */
-#define R_I 0x10000000 /* interrupt on reception */
-#define R_L 0x08000000 /* last */
-#define R_C 0x08000000 /* the last byte in this buffer is a cntl
- char */
-#define R_F 0x04000000 /* first */
-#define R_A 0x04000000 /* the first byte in this buffer is address
- byte */
-#define R_CM 0x02000000 /* continuous mode */
-#define R_ID 0x01000000 /* buffer close on reception of idles */
-#define R_M 0x01000000 /* Frame received because of promiscuous
- mode */
-#define R_AM 0x00800000 /* Address match */
-#define R_DE 0x00800000 /* Address match */
-#define R_LG 0x00200000 /* Break received */
-#define R_BR 0x00200000 /* Frame length violation */
-#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */
-#define R_FR 0x00100000 /* Framing Error (no stop bit) character
- received */
-#define R_PR 0x00080000 /* Parity Error character received */
-#define R_AB 0x00080000 /* Frame Aborted */
-#define R_SH 0x00080000 /* frame is too short */
-#define R_CR 0x00040000 /* CRC Error */
-#define R_OV 0x00020000 /* Overrun */
-#define R_CD 0x00010000 /* CD lost */
-#define R_CL 0x00010000 /* this frame is closed because of a
- collision */
-
-/* Rx Data buffer must be 4 bytes aligned in most cases.*/
-#define UCC_SLOW_RX_ALIGN 4
-#define UCC_SLOW_MRBLR_ALIGNMENT 4
-#define UCC_SLOW_PRAM_SIZE 0x100
-#define ALIGNMENT_OF_UCC_SLOW_PRAM 64
-
-/* UCC Slow Channel Protocol Mode */
-enum ucc_slow_channel_protocol_mode {
- UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002,
- UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004,
- UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008,
-};
-
-/* UCC Slow Transparent Transmit CRC (TCRC) */
-enum ucc_slow_transparent_tcrc {
- /* 16-bit CCITT CRC (HDLC). (X16 + X12 + X5 + 1) */
- UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000,
- /* CRC16 (BISYNC). (X16 + X15 + X2 + 1) */
- UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000,
- /* 32-bit CCITT CRC (Ethernet and HDLC) */
- UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000,
-};
-
-/* UCC Slow oversampling rate for transmitter (TDCR) */
-enum ucc_slow_tx_oversampling_rate {
- /* 1x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000,
- /* 8x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000,
- /* 16x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000,
- /* 32x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000,
-};
-
-/* UCC Slow Oversampling rate for receiver (RDCR)
-*/
-enum ucc_slow_rx_oversampling_rate {
- /* 1x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000,
- /* 8x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000,
- /* 16x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000,
- /* 32x clock mode */
- UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000,
-};
-
-/* UCC Slow Transmitter encoding method (TENC)
-*/
-enum ucc_slow_tx_encoding_method {
- UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000,
- UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100
-};
-
-/* UCC Slow Receiver decoding method (RENC)
-*/
-enum ucc_slow_rx_decoding_method {
- UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000,
- UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800
-};
-
-/* UCC Slow Diagnostic mode (DIAG)
-*/
-enum ucc_slow_diag_mode {
- UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000,
- UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040,
- UCC_SLOW_DIAG_MODE_ECHO = 0x00000080,
- UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0
-};
-
-struct ucc_slow_info {
- int ucc_num;
- int protocol; /* QE_CR_PROTOCOL_xxx */
- enum qe_clock rx_clock;
- enum qe_clock tx_clock;
- phys_addr_t regs;
- int irq;
- u16 uccm_mask;
- int data_mem_part;
- int init_tx;
- int init_rx;
- u32 tx_bd_ring_len;
- u32 rx_bd_ring_len;
- int rx_interrupts;
- int brkpt_support;
- int grant_support;
- int tsa;
- int cdp;
- int cds;
- int ctsp;
- int ctss;
- int rinv;
- int tinv;
- int rtsm;
- int rfw;
- int tci;
- int tend;
- int tfl;
- int txsy;
- u16 max_rx_buf_length;
- enum ucc_slow_transparent_tcrc tcrc;
- enum ucc_slow_channel_protocol_mode mode;
- enum ucc_slow_diag_mode diag;
- enum ucc_slow_tx_oversampling_rate tdcr;
- enum ucc_slow_rx_oversampling_rate rdcr;
- enum ucc_slow_tx_encoding_method tenc;
- enum ucc_slow_rx_decoding_method renc;
-};
-
-struct ucc_slow_private {
- struct ucc_slow_info *us_info;
- struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
- struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */
- u32 us_pram_offset;
- int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
- int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
- int stopped_tx; /* Whether channel has been stopped for Tx
- (STOP_TX, etc.) */
- int stopped_rx; /* Whether channel has been stopped for Rx */
- struct list_head confQ; /* frames passed to chip waiting for tx */
- u32 first_tx_bd_mask; /* mask is used in Tx routine to save status
- and length for first BD in a frame */
- u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */
- u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */
- struct qe_bd *confBd; /* next BD for confirm after Tx */
- struct qe_bd *tx_bd; /* next BD for new Tx request */
- struct qe_bd *rx_bd; /* next BD to collect after Rx */
- void *p_rx_frame; /* accumulating receive frame */
- u16 *p_ucce; /* a pointer to the event register in memory.
- */
- u16 *p_uccm; /* a pointer to the mask register in memory */
- u16 saved_uccm; /* a saved mask for the RX Interrupt bits */
-#ifdef STATISTICS
- u32 tx_frames; /* Transmitted frames counters */
- u32 rx_frames; /* Received frames counters (only frames
- passed to application) */
- u32 rx_discarded; /* Discarded frames counters (frames that
- were discarded by the driver due to
- errors) */
-#endif /* STATISTICS */
-};
-
-/* ucc_slow_init
- * Initializes Slow UCC according to provided parameters.
- *
- * us_info - (In) pointer to the slow UCC info structure.
- * uccs_ret - (Out) pointer to the slow UCC structure.
- */
-int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret);
-
-/* ucc_slow_free
- * Frees all resources for slow UCC.
- *
- * uccs - (In) pointer to the slow UCC structure.
- */
-void ucc_slow_free(struct ucc_slow_private * uccs);
-
-/* ucc_slow_enable
- * Enables a fast UCC port.
- * This routine enables Tx and/or Rx through the General UCC Mode Register.
- *
- * uccs - (In) pointer to the slow UCC structure.
- * mode - (In) TX, RX, or both.
- */
-void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode);
-
-/* ucc_slow_disable
- * Disables a fast UCC port.
- * This routine disables Tx and/or Rx through the General UCC Mode Register.
- *
- * uccs - (In) pointer to the slow UCC structure.
- * mode - (In) TX, RX, or both.
- */
-void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode);
-
-/* ucc_slow_graceful_stop_tx
- * Smoothly stops transmission on a specified slow UCC.
- *
- * uccs - (In) pointer to the slow UCC structure.
- */
-void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);
-
-/* ucc_slow_stop_tx
- * Stops transmission on a specified slow UCC.
- *
- * uccs - (In) pointer to the slow UCC structure.
- */
-void ucc_slow_stop_tx(struct ucc_slow_private * uccs);
-
-/* ucc_slow_restart_tx
- * Restarts transmitting on a specified slow UCC.
- *
- * uccs - (In) pointer to the slow UCC structure.
- */
-void ucc_slow_restart_tx(struct ucc_slow_private *uccs);
-
-u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
-
-#endif /* __UCC_SLOW_H__ */
diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h
index d12b11d..a1d1129 100644
--- a/arch/powerpc/include/asm/uninorth.h
+++ b/arch/powerpc/include/asm/uninorth.h
@@ -132,7 +132,7 @@
/* This one _might_ return the CPU number of the CPU reading it;
* the bootROM decides whether to boot or to sleep/spinloop depending
- * on this register beeing 0 or not
+ * on this register being 0 or not
*/
#define UNI_N_CPU_NUMBER 0x0050
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 13411be..1f2594d 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,10 +12,9 @@
#include <uapi/asm/unistd.h>
-#define __NR_syscalls 366
+#define NR_syscalls 380
#define __NR__exit __NR_exit
-#define NR_syscalls __NR_syscalls
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index b73a819..1afe90a 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -41,7 +41,7 @@
#include <linux/unistd.h>
#include <linux/time.h>
-#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32)
+#define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32)
/*
* So here is the ppc64 backward compatible version
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index 0e25bdb..04ef3ae 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -1,5 +1,5 @@
/*
- * Common definitions accross all variants of ICP and ICS interrupt
+ * Common definitions across all variants of ICP and ICS interrupt
* controllers.
*/
@@ -30,6 +30,7 @@
#ifdef CONFIG_PPC_ICP_NATIVE
extern int icp_native_init(void);
extern void icp_native_flush_interrupt(void);
+extern void icp_native_cause_ipi_rm(int cpu);
#else
static inline int icp_native_init(void) { return -ENODEV; }
#endif
diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h
index 4368604..8dde199 100644
--- a/arch/powerpc/include/uapi/asm/cputable.h
+++ b/arch/powerpc/include/uapi/asm/cputable.h
@@ -43,5 +43,7 @@
#define PPC_FEATURE2_TAR 0x04000000
#define PPC_FEATURE2_VEC_CRYPTO 0x02000000
#define PPC_FEATURE2_HTM_NOSC 0x01000000
+#define PPC_FEATURE2_ARCH_3_00 0x00800000 /* ISA 3.00 */
+#define PPC_FEATURE2_HAS_IEEE128 0x00400000 /* VSX IEEE Binary Float 128-bit */
#endif /* _UAPI__ASM_POWERPC_CPUTABLE_H */
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 59dad11..c2d21d1 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -295,6 +295,8 @@ do { \
#define R_PPC64_TLSLD 108
#define R_PPC64_TOCSAVE 109
+#define R_PPC64_ENTRY 118
+
#define R_PPC64_REL16 249
#define R_PPC64_REL16_LO 250
#define R_PPC64_REL16_HI 251
diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
index 7f9c74b..b4504f3 100644
--- a/arch/powerpc/include/uapi/asm/epapr_hcalls.h
+++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h
@@ -78,7 +78,7 @@
#define EV_SUCCESS 0
#define EV_EPERM 1 /* Operation not permitted */
#define EV_ENOENT 2 /* Entry Not Found */
-#define EV_EIO 3 /* I/O error occured */
+#define EV_EIO 3 /* I/O error occurred */
#define EV_EAGAIN 4 /* The operation had insufficient
* resources to complete and should be
* retried
@@ -89,7 +89,7 @@
#define EV_ENODEV 7 /* No such device */
#define EV_EINVAL 8 /* An argument supplied to the hcall
was out of range or invalid */
-#define EV_INTERNAL 9 /* An internal error occured */
+#define EV_INTERNAL 9 /* An internal error occurred */
#define EV_CONFIG 10 /* A configuration error was detected */
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d473..c93cf35 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
__u32 window_size;
};
+/* for KVM_CAP_SPAPR_TCE_64 */
+struct kvm_create_spapr_tce_64 {
+ __u64 liobn;
+ __u32 page_shift;
+ __u32 flags;
+ __u64 offset; /* in pages */
+ __u64 size; /* in pages */
+};
+
/* for KVM_ALLOCATE_RMA */
struct kvm_allocate_rma {
__u64 rma_size;
diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h
index 6ea26df..03c06ba 100644
--- a/arch/powerpc/include/uapi/asm/mman.h
+++ b/arch/powerpc/include/uapi/asm/mman.h
@@ -22,6 +22,7 @@
#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
#define MCL_FUTURE 0x4000 /* lock all additions to address space */
+#define MCL_ONFAULT 0x8000 /* lock all pages that are faulted in */
#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x10000 /* do not block on IO */
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h
index c046666..1672e33 100644
--- a/arch/powerpc/include/uapi/asm/socket.h
+++ b/arch/powerpc/include/uapi/asm/socket.h
@@ -92,4 +92,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index 6337738..940290d 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -388,5 +388,7 @@
#define __NR_switch_endian 363
#define __NR_userfaultfd 364
#define __NR_membarrier 365
+#define __NR_mlock2 378
+#define __NR_copy_file_range 379
#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ba33693..2da380f 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,14 +16,14 @@ endif
ifdef CONFIG_FUNCTION_TRACER
# Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
-CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
# do not trace tracer code
-CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
# timers used by tracing
-CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
endif
obj-y := cputable.o ptrace.o syscalls.o \
@@ -136,12 +136,18 @@ endif
obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o
obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
-# Disable GCOV in odd or sensitive code
+# Disable GCOV & sanitizers in odd or sensitive code
GCOV_PROFILE_prom_init.o := n
+UBSAN_SANITIZE_prom_init.o := n
GCOV_PROFILE_ftrace.o := n
+UBSAN_SANITIZE_ftrace.o := n
GCOV_PROFILE_machine_kexec_64.o := n
+UBSAN_SANITIZE_machine_kexec_64.o := n
GCOV_PROFILE_machine_kexec_32.o := n
+UBSAN_SANITIZE_machine_kexec_32.o := n
GCOV_PROFILE_kprobes.o := n
+UBSAN_SANITIZE_kprobes.o := n
+UBSAN_SANITIZE_vdso.o := n
extra-$(CONFIG_PPC_FPU) += fpu.o
extra-$(CONFIG_ALTIVEC) += vector.o
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 86150fb..8e7cb8e 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -960,6 +960,7 @@ int fix_alignment(struct pt_regs *regs)
preempt_disable();
enable_kernel_fp();
cvt_df(&data.dd, (float *)&data.x32.low32);
+ disable_kernel_fp();
preempt_enable();
#else
return 0;
@@ -1000,6 +1001,7 @@ int fix_alignment(struct pt_regs *regs)
preempt_disable();
enable_kernel_fp();
cvt_fd((float *)&data.x32.low32, &data.dd);
+ disable_kernel_fp();
preempt_enable();
#else
return 0;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 221d584..0d0183d 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -95,12 +95,14 @@ int main(void)
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state));
DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area));
DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr));
+ DEFINE(THREAD_LOAD_FP, offsetof(struct thread_struct, load_fp));
#ifdef CONFIG_ALTIVEC
DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state));
DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area));
DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr));
+ DEFINE(THREAD_LOAD_VEC, offsetof(struct thread_struct, load_vec));
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_VSX
DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr));
@@ -185,14 +187,16 @@ int main(void)
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
- DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
+#ifdef CONFIG_PPC_BOOK3S
+ DEFINE(PACACONTEXTID, offsetof(struct paca_struct, mm_ctx_id));
#ifdef CONFIG_PPC_MM_SLICES
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
- context.low_slices_psize));
+ mm_ctx_low_slices_psize));
DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
- context.high_slices_psize));
+ mm_ctx_high_slices_psize));
DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
#endif /* CONFIG_PPC_MM_SLICES */
+#endif
#ifdef CONFIG_PPC_BOOK3E
DEFINE(PACAPGD, offsetof(struct paca_struct, pgd));
@@ -222,7 +226,7 @@ int main(void)
#ifdef CONFIG_PPC_MM_SLICES
DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
#else
- DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp));
+ DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, mm_ctx_sllp));
#endif /* CONFIG_PPC_MM_SLICES */
DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
@@ -372,6 +376,7 @@ int main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
+ DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush));
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index dddba3e..462aed9 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -13,11 +13,13 @@
*
*/
+#include <asm/page.h>
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/mmu-book3e.h>
#include <asm/asm-offsets.h>
+#include <asm/mpc85xx.h>
_GLOBAL(__e500_icache_setup)
mfspr r0, SPRN_L1CSR1
@@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500)
mtlr r5
blr
#endif
+
+/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */
+_GLOBAL(flush_dcache_L1)
+ mfmsr r10
+ wrteei 0
+
+ mfspr r3,SPRN_L1CFG0
+ rlwinm r5,r3,9,3 /* Extract cache block size */
+ twlgti r5,1 /* Only 32 and 64 byte cache blocks
+ * are currently defined.
+ */
+ li r4,32
+ subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
+ * log2(number of ways)
+ */
+ slw r5,r4,r5 /* r5 = cache block size */
+
+ rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
+ mulli r7,r7,13 /* An 8-way cache will require 13
+ * loads per set.
+ */
+ slw r7,r7,r6
+
+ /* save off HID0 and set DCFA */
+ mfspr r8,SPRN_HID0
+ ori r9,r8,HID0_DCFA@l
+ mtspr SPRN_HID0,r9
+ isync
+
+ LOAD_REG_IMMEDIATE(r6, KERNELBASE)
+ mr r4, r6
+ mtctr r7
+
+1: lwz r3,0(r4) /* Load... */
+ add r4,r4,r5
+ bdnz 1b
+
+ msync
+ mr r4, r6
+ mtctr r7
+
+1: dcbf 0,r4 /* ...and flush. */
+ add r4,r4,r5
+ bdnz 1b
+
+ /* restore HID0 */
+ mtspr SPRN_HID0,r8
+ isync
+
+ wrtee r10
+
+ blr
+
+has_L2_cache:
+ /* skip L2 cache on P2040/P2040E as they have no L2 cache */
+ mfspr r3, SPRN_SVR
+ /* shift right by 8 bits and clear E bit of SVR */
+ rlwinm r4, r3, 24, ~0x800
+
+ lis r3, SVR_P2040@h
+ ori r3, r3, SVR_P2040@l
+ cmpw r4, r3
+ beq 1f
+
+ li r3, 1
+ blr
+1:
+ li r3, 0
+ blr
+
+/* flush backside L2 cache */
+flush_backside_L2_cache:
+ mflr r10
+ bl has_L2_cache
+ mtlr r10
+ cmpwi r3, 0
+ beq 2f
+
+ /* Flush the L2 cache */
+ mfspr r3, SPRN_L2CSR0
+ ori r3, r3, L2CSR0_L2FL@l
+ msync
+ isync
+ mtspr SPRN_L2CSR0,r3
+ isync
+
+ /* check if it is complete */
+1: mfspr r3,SPRN_L2CSR0
+ andi. r3, r3, L2CSR0_L2FL@l
+ bne 1b
+2:
+ blr
+
+_GLOBAL(cpu_down_flush_e500v2)
+ mflr r0
+ bl flush_dcache_L1
+ mtlr r0
+ blr
+
+_GLOBAL(cpu_down_flush_e500mc)
+_GLOBAL(cpu_down_flush_e5500)
+ mflr r0
+ bl flush_dcache_L1
+ bl flush_backside_L2_cache
+ mtlr r0
+ blr
+
+/* L1 Data Cache of e6500 contains no modified data, no flush is required */
+_GLOBAL(cpu_down_flush_e6500)
+ blr
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 9c9b741..584e119 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -15,6 +15,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
+#include <asm/book3s/64/mmu-hash.h>
/* Entry: r3 = crap, r4 = ptr to cputable entry
*
@@ -83,6 +84,39 @@ _GLOBAL(__restore_cpu_power8)
mtlr r11
blr
+_GLOBAL(__setup_cpu_power9)
+ mflr r11
+ bl __init_FSCR
+ bl __init_hvmode_206
+ mtlr r11
+ beqlr
+ li r0,0
+ mtspr SPRN_LPID,r0
+ mfspr r3,SPRN_LPCR
+ ori r3, r3, LPCR_PECEDH
+ bl __init_LPCR
+ bl __init_HFSCR
+ bl __init_tlb_power9
+ mtlr r11
+ blr
+
+_GLOBAL(__restore_cpu_power9)
+ mflr r11
+ bl __init_FSCR
+ mfmsr r3
+ rldicl. r0,r3,4,63
+ mtlr r11
+ beqlr
+ li r0,0
+ mtspr SPRN_LPID,r0
+ mfspr r3,SPRN_LPCR
+ ori r3, r3, LPCR_PECEDH
+ bl __init_LPCR
+ bl __init_HFSCR
+ bl __init_tlb_power9
+ mtlr r11
+ blr
+
__init_hvmode_206:
/* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
mfmsr r3
@@ -139,7 +173,7 @@ __init_HFSCR:
* (invalidate by congruence class). P7 has 128 CCs., P8 has 512.
*/
__init_tlb_power7:
- li r6,128
+ li r6,POWER7_TLB_SETS
mtctr r6
li r7,0xc00 /* IS field = 0b11 */
ptesync
@@ -150,7 +184,18 @@ __init_tlb_power7:
1: blr
__init_tlb_power8:
- li r6,512
+ li r6,POWER8_TLB_SETS
+ mtctr r6
+ li r7,0xc00 /* IS field = 0b11 */
+ ptesync
+2: tlbiel r7
+ addi r7,r7,0x1000
+ bdnz 2b
+ ptesync
+1: blr
+
+__init_tlb_power9:
+ li r6,POWER9_TLB_SETS_HASH
mtctr r6
li r7,0xc00 /* IS field = 0b11 */
ptesync
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 7d80bfd..6c662b8 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -70,9 +70,12 @@ extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
extern void __restore_cpu_power7(void);
extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
extern void __restore_cpu_power8(void);
+extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec);
+extern void __restore_cpu_power9(void);
extern void __restore_cpu_a2(void);
extern void __flush_tlb_power7(unsigned int action);
extern void __flush_tlb_power8(unsigned int action);
+extern void __flush_tlb_power9(unsigned int action);
extern long __machine_check_early_realmode_p7(struct pt_regs *regs);
extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
#endif /* CONFIG_PPC64 */
@@ -116,6 +119,11 @@ extern void __restore_cpu_e6500(void);
#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
PPC_FEATURE_TRUE_LE | \
PPC_FEATURE_HAS_ALTIVEC_COMP)
+#define COMMON_USER_POWER9 COMMON_USER_POWER8
+#define COMMON_USER2_POWER9 (COMMON_USER2_POWER8 | \
+ PPC_FEATURE2_ARCH_3_00 | \
+ PPC_FEATURE2_HAS_IEEE128)
+
#ifdef CONFIG_PPC_BOOK3E_64
#define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
#else
@@ -499,6 +507,25 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check_early = __machine_check_early_realmode_p8,
.platform = "power8",
},
+ { /* Power9 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x004e0000,
+ .cpu_name = "POWER9 (raw)",
+ .cpu_features = CPU_FTRS_POWER9,
+ .cpu_user_features = COMMON_USER_POWER9,
+ .cpu_user_features2 = COMMON_USER2_POWER9,
+ .mmu_features = MMU_FTRS_POWER9,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .pmc_type = PPC_PMC_IBM,
+ .oprofile_cpu_type = "ppc64/power9",
+ .oprofile_type = PPC_OPROFILE_INVALID,
+ .cpu_setup = __setup_cpu_power9,
+ .cpu_restore = __restore_cpu_power9,
+ .flush_tlb = __flush_tlb_power9,
+ .platform = "power9",
+ },
{ /* Cell Broadband Engine */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00700000,
@@ -2023,6 +2050,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_e500v2,
.machine_check = machine_check_e500,
.platform = "ppc8548",
+ .cpu_down_flush = cpu_down_flush_e500v2,
},
#else
{ /* e500mc */
@@ -2042,6 +2070,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_e500mc,
.machine_check = machine_check_e500mc,
.platform = "ppce500mc",
+ .cpu_down_flush = cpu_down_flush_e500mc,
},
#endif /* CONFIG_PPC_E500MC */
#endif /* CONFIG_PPC32 */
@@ -2066,6 +2095,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
#endif
.machine_check = machine_check_e500mc,
.platform = "ppce5500",
+ .cpu_down_flush = cpu_down_flush_e5500,
},
{ /* e6500 */
.pvr_mask = 0xffff0000,
@@ -2088,6 +2118,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
#endif
.machine_check = machine_check_e500mc,
.platform = "ppce6500",
+ .cpu_down_flush = cpu_down_flush_e6500,
},
#endif /* CONFIG_PPC_E500MC */
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 51dbace..2bb252c 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -221,8 +221,8 @@ void crash_kexec_secondary(struct pt_regs *regs)
#endif /* CONFIG_SMP */
/* wait for all the CPUs to hit real mode but timeout if they don't come in */
-#if defined(CONFIG_SMP) && defined(CONFIG_PPC_STD_MMU_64)
-static void crash_kexec_wait_realmode(int cpu)
+#if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
+static void __maybe_unused crash_kexec_wait_realmode(int cpu)
{
unsigned int msecs;
int i;
@@ -244,7 +244,7 @@ static void crash_kexec_wait_realmode(int cpu)
}
#else
static inline void crash_kexec_wait_realmode(int cpu) {}
-#endif /* CONFIG_SMP && CONFIG_PPC_STD_MMU_64 */
+#endif /* CONFIG_SMP && CONFIG_PPC64 */
/*
* Register a function to be called on shutdown. Only use this if you
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index e968533..6544017 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -268,13 +268,6 @@ static void *eeh_dump_pe_log(void *data, void *flag)
struct eeh_dev *edev, *tmp;
size_t *plen = flag;
- /* If the PE's config space is blocked, 0xFF's will be
- * returned. It's pointless to collect the log in this
- * case.
- */
- if (pe->state & EEH_PE_CFG_BLOCKED)
- return NULL;
-
eeh_pe_for_each_dev(pe, edev, tmp)
*plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen,
EEH_PCI_REGS_LOG_LEN - *plen);
@@ -351,7 +344,8 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
* worried about _PAGE_SPLITTING/collapse. Also we will not hit
* page table free, because of init_mm.
*/
- ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token, &hugepage_shift);
+ ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token,
+ NULL, &hugepage_shift);
if (!ptep)
return token;
WARN_ON(hugepage_shift);
@@ -630,7 +624,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function)
*/
switch (function) {
case EEH_OPT_THAW_MMIO:
- active_flag = EEH_STATE_MMIO_ACTIVE;
+ active_flag = EEH_STATE_MMIO_ACTIVE | EEH_STATE_MMIO_ENABLED;
break;
case EEH_OPT_THAW_DMA:
active_flag = EEH_STATE_DMA_ACTIVE;
@@ -676,7 +670,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function)
/* Check if the request is finished successfully */
if (active_flag) {
rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
- if (rc <= 0)
+ if (rc < 0)
return rc;
if (rc & active_flag)
@@ -738,7 +732,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata)
}
/**
- * pcibios_set_pcie_slot_reset - Set PCI-E reset state
+ * pcibios_set_pcie_reset_state - Set PCI-E reset state
* @dev: pci device struct
* @state: reset state to enter
*
@@ -760,7 +754,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
case pcie_deassert_reset:
eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
eeh_unfreeze_pe(pe, false);
- eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
+ if (!(pe->type & EEH_PE_VF))
+ eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev);
eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
break;
@@ -768,14 +763,16 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
- eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
+ if (!(pe->type & EEH_PE_VF))
+ eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
eeh_ops->reset(pe, EEH_RESET_HOT);
break;
case pcie_warm_reset:
eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);
eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
- eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
+ if (!(pe->type & EEH_PE_VF))
+ eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
break;
default:
@@ -1242,6 +1239,14 @@ void eeh_remove_device(struct pci_dev *dev)
* from the parent PE during the BAR resotre.
*/
edev->pdev = NULL;
+
+ /*
+ * The flag "in_error" is used to trace EEH devices for VFs
+ * in error state or not. It's set in eeh_report_error(). If
+ * it's not set, eeh_report_{reset,resume}() won't be called
+ * for the VF EEH device.
+ */
+ edev->in_error = false;
dev->dev.archdata.edev = NULL;
if (!(edev->pe->state & EEH_PE_KEEP))
eeh_rmv_from_parent_pe(edev);
@@ -1411,8 +1416,7 @@ void eeh_dev_release(struct pci_dev *pdev)
goto out;
/* Decrease PE's pass through count */
- atomic_dec(&edev->pe->pass_dev_cnt);
- WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0);
+ WARN_ON(atomic_dec_if_positive(&edev->pe->pass_dev_cnt) < 0);
eeh_pe_change_owner(edev->pe);
out:
mutex_unlock(&eeh_dev_mutex);
@@ -1537,6 +1541,17 @@ int eeh_pe_get_state(struct eeh_pe *pe)
if (!eeh_ops || !eeh_ops->get_state)
return -ENOENT;
+ /*
+ * If the parent PE is owned by the host kernel and is undergoing
+ * error recovery, we should return the PE state as temporarily
+ * unavailable so that the error recovery on the guest is suspended
+ * until the recovery completes on the host.
+ */
+ if (pe->parent &&
+ !(pe->state & EEH_PE_REMOVED) &&
+ (pe->parent->state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING)))
+ return EEH_PE_STATE_UNAVAIL;
+
result = eeh_ops->get_state(pe, NULL);
rst_active = !!(result & EEH_STATE_RESET_ACTIVE);
dma_en = !!(result & EEH_STATE_DMA_ENABLED);
diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
index a1e86e1..ddbcfab 100644
--- a/arch/powerpc/kernel/eeh_cache.c
+++ b/arch/powerpc/kernel/eeh_cache.c
@@ -195,8 +195,11 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
return;
}
- /* Walk resources on this device, poke them into the tree */
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ /*
+ * Walk resources on this device, poke the first 7 (6 normal BAR and 1
+ * ROM BAR) into the tree.
+ */
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
resource_size_t start = pci_resource_start(dev,i);
resource_size_t end = pci_resource_end(dev,i);
unsigned long flags = pci_resource_flags(dev,i);
@@ -222,10 +225,6 @@ void eeh_addr_cache_insert_dev(struct pci_dev *dev)
{
unsigned long flags;
- /* Ignore PCI bridges */
- if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
- return;
-
spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
__eeh_addr_cache_insert_dev(dev);
spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c
index aabba94..7815095 100644
--- a/arch/powerpc/kernel/eeh_dev.c
+++ b/arch/powerpc/kernel/eeh_dev.c
@@ -67,6 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data)
edev->pdn = pdn;
edev->phb = phb;
INIT_LIST_HEAD(&edev->list);
+ INIT_LIST_HEAD(&edev->rmv_list);
return NULL;
}
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 89eb4bc..fb6207d 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -34,6 +34,11 @@
#include <asm/prom.h>
#include <asm/rtas.h>
+struct eeh_rmv_data {
+ struct list_head edev_list;
+ int removed;
+};
+
/**
* eeh_pcid_name - Retrieve name of PCI device driver
* @pdev: PCI device
@@ -190,7 +195,7 @@ static void *eeh_report_error(void *data, void *userdata)
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver;
- if (!dev || eeh_dev_removed(edev))
+ if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
return NULL;
dev->error_state = pci_channel_io_frozen;
@@ -211,6 +216,7 @@ static void *eeh_report_error(void *data, void *userdata)
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+ edev->in_error = true;
eeh_pcid_put(dev);
return NULL;
}
@@ -231,7 +237,7 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata)
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver;
- if (!dev || eeh_dev_removed(edev))
+ if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
return NULL;
driver = eeh_pcid_get(dev);
@@ -271,7 +277,7 @@ static void *eeh_report_reset(void *data, void *userdata)
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver;
- if (!dev || eeh_dev_removed(edev))
+ if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
return NULL;
dev->error_state = pci_channel_io_normal;
@@ -282,7 +288,8 @@ static void *eeh_report_reset(void *data, void *userdata)
if (!driver->err_handler ||
!driver->err_handler->slot_reset ||
- (edev->mode & EEH_DEV_NO_HANDLER)) {
+ (edev->mode & EEH_DEV_NO_HANDLER) ||
+ (!edev->in_error)) {
eeh_pcid_put(dev);
return NULL;
}
@@ -326,20 +333,23 @@ static void *eeh_report_resume(void *data, void *userdata)
{
struct eeh_dev *edev = (struct eeh_dev *)data;
struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+ bool was_in_error;
struct pci_driver *driver;
- if (!dev || eeh_dev_removed(edev))
+ if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
return NULL;
dev->error_state = pci_channel_io_normal;
driver = eeh_pcid_get(dev);
if (!driver) return NULL;
+ was_in_error = edev->in_error;
+ edev->in_error = false;
eeh_enable_irq(dev);
if (!driver->err_handler ||
!driver->err_handler->resume ||
- (edev->mode & EEH_DEV_NO_HANDLER)) {
+ (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) {
edev->mode &= ~EEH_DEV_NO_HANDLER;
eeh_pcid_put(dev);
return NULL;
@@ -365,7 +375,7 @@ static void *eeh_report_failure(void *data, void *userdata)
struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
struct pci_driver *driver;
- if (!dev || eeh_dev_removed(edev))
+ if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe))
return NULL;
dev->error_state = pci_channel_io_perm_failure;
@@ -386,12 +396,40 @@ static void *eeh_report_failure(void *data, void *userdata)
return NULL;
}
+static void *eeh_add_virt_device(void *data, void *userdata)
+{
+ struct pci_driver *driver;
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+ struct pci_dn *pdn = eeh_dev_to_pdn(edev);
+
+ if (!(edev->physfn)) {
+ pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n",
+ __func__, edev->phb->global_number, pdn->busno,
+ PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
+ return NULL;
+ }
+
+ driver = eeh_pcid_get(dev);
+ if (driver) {
+ eeh_pcid_put(dev);
+ if (driver->err_handler)
+ return NULL;
+ }
+
+#ifdef CONFIG_PPC_POWERNV
+ pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0);
+#endif
+ return NULL;
+}
+
static void *eeh_rmv_device(void *data, void *userdata)
{
struct pci_driver *driver;
struct eeh_dev *edev = (struct eeh_dev *)data;
struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
- int *removed = (int *)userdata;
+ struct eeh_rmv_data *rmv_data = (struct eeh_rmv_data *)userdata;
+ int *removed = rmv_data ? &rmv_data->removed : NULL;
/*
* Actually, we should remove the PCI bridges as well.
@@ -400,7 +438,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
* support EEH. So we just care about PCI devices for
* simplicity here.
*/
- if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
+ if (!dev || (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE))
return NULL;
/*
@@ -416,7 +454,13 @@ static void *eeh_rmv_device(void *data, void *userdata)
driver = eeh_pcid_get(dev);
if (driver) {
eeh_pcid_put(dev);
- if (driver->err_handler)
+ if (removed &&
+ eeh_pe_passed(edev->pe))
+ return NULL;
+ if (removed &&
+ driver->err_handler &&
+ driver->err_handler->error_detected &&
+ driver->err_handler->slot_reset)
return NULL;
}
@@ -425,11 +469,29 @@ static void *eeh_rmv_device(void *data, void *userdata)
pci_name(dev));
edev->bus = dev->bus;
edev->mode |= EEH_DEV_DISCONNECTED;
- (*removed)++;
+ if (removed)
+ (*removed)++;
- pci_lock_rescan_remove();
- pci_stop_and_remove_bus_device(dev);
- pci_unlock_rescan_remove();
+ if (edev->physfn) {
+#ifdef CONFIG_PPC_POWERNV
+ struct pci_dn *pdn = eeh_dev_to_pdn(edev);
+
+ pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0);
+ edev->pdev = NULL;
+
+ /*
+ * We have to set the VF PE number to invalid one, which is
+ * required to plug the VF successfully.
+ */
+ pdn->pe_number = IODA_INVALID_PE;
+#endif
+ if (rmv_data)
+ list_add(&edev->rmv_list, &rmv_data->edev_list);
+ } else {
+ pci_lock_rescan_remove();
+ pci_stop_and_remove_bus_device(dev);
+ pci_unlock_rescan_remove();
+ }
return NULL;
}
@@ -543,11 +605,13 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe)
* During the reset, udev might be invoked because those affected
* PCI devices will be removed and then added.
*/
-static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
+static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
+ struct eeh_rmv_data *rmv_data)
{
struct pci_bus *frozen_bus = eeh_pe_bus_get(pe);
struct timeval tstamp;
- int cnt, rc, removed = 0;
+ int cnt, rc;
+ struct eeh_dev *edev;
/* pcibios will clear the counter; save the value */
cnt = pe->freeze_count;
@@ -561,11 +625,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
*/
eeh_pe_state_mark(pe, EEH_PE_KEEP);
if (bus) {
- pci_lock_rescan_remove();
- pcibios_remove_pci_devices(bus);
- pci_unlock_rescan_remove();
+ if (pe->type & EEH_PE_VF) {
+ eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
+ } else {
+ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ pci_lock_rescan_remove();
+ pcibios_remove_pci_devices(bus);
+ pci_unlock_rescan_remove();
+ }
} else if (frozen_bus) {
- eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
+ eeh_pe_dev_traverse(pe, eeh_rmv_device, &rmv_data);
}
/*
@@ -607,14 +676,22 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
* PE. We should disconnect it so the binding can be
* rebuilt when adding PCI devices.
*/
+ edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
- pcibios_add_pci_devices(bus);
- } else if (frozen_bus && removed) {
+ if (pe->type & EEH_PE_VF)
+ eeh_add_virt_device(edev, NULL);
+ else
+ pcibios_add_pci_devices(bus);
+ } else if (frozen_bus && rmv_data->removed) {
pr_info("EEH: Sleep 5s ahead of partial hotplug\n");
ssleep(5);
+ edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
- pcibios_add_pci_devices(frozen_bus);
+ if (pe->type & EEH_PE_VF)
+ eeh_add_virt_device(edev, NULL);
+ else
+ pcibios_add_pci_devices(frozen_bus);
}
eeh_pe_state_clear(pe, EEH_PE_KEEP);
@@ -633,8 +710,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
static void eeh_handle_normal_event(struct eeh_pe *pe)
{
struct pci_bus *frozen_bus;
+ struct eeh_dev *edev, *tmp;
int rc = 0;
enum pci_ers_result result = PCI_ERS_RESULT_NONE;
+ struct eeh_rmv_data rmv_data = {LIST_HEAD_INIT(rmv_data.edev_list), 0};
frozen_bus = eeh_pe_bus_get(pe);
if (!frozen_bus) {
@@ -655,9 +734,17 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
* to accomplish the reset. Each child gets a report of the
* status ... if any child can't handle the reset, then the entire
* slot is dlpar removed and added.
+ *
+ * When the PHB is fenced, we have to issue a reset to recover from
+ * the error. Override the result if necessary to have partially
+ * hotplug for this case.
*/
pr_info("EEH: Notify device drivers to shutdown\n");
eeh_pe_dev_traverse(pe, eeh_report_error, &result);
+ if ((pe->type & EEH_PE_PHB) &&
+ result != PCI_ERS_RESULT_NONE &&
+ result != PCI_ERS_RESULT_NEED_RESET)
+ result = PCI_ERS_RESULT_NEED_RESET;
/* Get the current PCI slot state. This can take a long time,
* sometimes over 300 seconds for certain systems.
@@ -681,7 +768,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
*/
if (result == PCI_ERS_RESULT_NONE) {
pr_info("EEH: Reset with hotplug activity\n");
- rc = eeh_reset_device(pe, frozen_bus);
+ rc = eeh_reset_device(pe, frozen_bus, NULL);
if (rc) {
pr_warn("%s: Unable to reset, err=%d\n",
__func__, rc);
@@ -733,7 +820,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
/* If any device called out for a reset, then reset the slot */
if (result == PCI_ERS_RESULT_NEED_RESET) {
pr_info("EEH: Reset without hotplug activity\n");
- rc = eeh_reset_device(pe, NULL);
+ rc = eeh_reset_device(pe, NULL, &rmv_data);
if (rc) {
pr_warn("%s: Cannot reset, err=%d\n",
__func__, rc);
@@ -753,6 +840,15 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
goto hard_fail;
}
+ /*
+ * For those hot removed VFs, we should add back them after PF get
+ * recovered properly.
+ */
+ list_for_each_entry_safe(edev, tmp, &rmv_data.edev_list, rmv_list) {
+ eeh_add_virt_device(edev, NULL);
+ list_del(&edev->rmv_list);
+ }
+
/* Tell all device drivers that they can resume operations */
pr_info("EEH: Notify device driver to resume\n");
eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
@@ -792,11 +888,17 @@ perm_error:
* the their PCI config any more.
*/
if (frozen_bus) {
- eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+ if (pe->type & EEH_PE_VF) {
+ eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
+ eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+ } else {
+ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
- pci_lock_rescan_remove();
- pcibios_remove_pci_devices(frozen_bus);
- pci_unlock_rescan_remove();
+ pci_lock_rescan_remove();
+ pcibios_remove_pci_devices(frozen_bus);
+ pci_unlock_rescan_remove();
+ }
}
}
@@ -875,6 +977,7 @@ static void eeh_handle_special_event(void)
continue;
/* Notify all devices to be down */
+ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
bus = eeh_pe_bus_get(phb_pe);
eeh_pe_dev_traverse(pe,
eeh_report_failure, NULL);
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 8654cb1..eea48d8 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -299,7 +299,10 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
* EEH device already having associated PE, but
* the direct parent EEH device doesn't have yet.
*/
- pdn = pdn ? pdn->parent : NULL;
+ if (edev->physfn)
+ pdn = pci_get_pdn(edev->physfn);
+ else
+ pdn = pdn ? pdn->parent : NULL;
while (pdn) {
/* We're poking out of PCI territory */
parent = pdn_to_eeh_dev(pdn);
@@ -382,7 +385,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
}
/* Create a new EEH PE */
- pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
+ if (edev->physfn)
+ pe = eeh_pe_alloc(edev->phb, EEH_PE_VF);
+ else
+ pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
if (!pe) {
pr_err("%s: out of memory!\n", __func__);
return -ENOMEM;
@@ -883,32 +889,29 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
const char *eeh_pe_loc_get(struct eeh_pe *pe)
{
struct pci_bus *bus = eeh_pe_bus_get(pe);
- struct device_node *dn = pci_bus_to_OF_node(bus);
+ struct device_node *dn;
const char *loc = NULL;
- if (!dn)
- goto out;
+ while (bus) {
+ dn = pci_bus_to_OF_node(bus);
+ if (!dn) {
+ bus = bus->parent;
+ continue;
+ }
- /* PHB PE or root PE ? */
- if (pci_is_root_bus(bus)) {
- loc = of_get_property(dn, "ibm,loc-code", NULL);
- if (!loc)
+ if (pci_is_root_bus(bus))
loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
+ else
+ loc = of_get_property(dn, "ibm,slot-location-code",
+ NULL);
+
if (loc)
- goto out;
+ return loc;
- /* Check the root port */
- dn = dn->child;
- if (!dn)
- goto out;
+ bus = bus->parent;
}
- loc = of_get_property(dn, "ibm,loc-code", NULL);
- if (!loc)
- loc = of_get_property(dn, "ibm,slot-location-code", NULL);
-
-out:
- return loc ? loc : "N/A";
+ return "N/A";
}
/**
@@ -923,25 +926,21 @@ out:
*/
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
{
- struct pci_bus *bus = NULL;
struct eeh_dev *edev;
struct pci_dev *pdev;
- if (pe->type & EEH_PE_PHB) {
- bus = pe->phb->bus;
- } else if (pe->type & EEH_PE_BUS ||
- pe->type & EEH_PE_DEVICE) {
- if (pe->bus) {
- bus = pe->bus;
- goto out;
- }
+ if (pe->type & EEH_PE_PHB)
+ return pe->phb->bus;
- edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
- pdev = eeh_dev_to_pci_dev(edev);
- if (pdev)
- bus = pdev->bus;
- }
+ /* The primary bus might be cached during probe time */
+ if (pe->state & EEH_PE_PRI_BUS)
+ return pe->bus;
+
+ /* Retrieve the parent PCI bus of first (top) PCI device */
+ edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list);
+ pdev = eeh_dev_to_pci_dev(edev);
+ if (pdev)
+ return pdev->bus;
-out:
- return bus;
+ return NULL;
}
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index a94f155..9916d15 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -210,7 +210,29 @@ system_call: /* label this so stack traces look sane */
li r11,-MAX_ERRNO
andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
bne- syscall_exit_work
- cmpld r3,r11
+
+ andi. r0,r8,MSR_FP
+ beq 2f
+#ifdef CONFIG_ALTIVEC
+ andis. r0,r8,MSR_VEC@h
+ bne 3f
+#endif
+2: addi r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_BOOK3S
+ mtmsrd r10,1 /* Restore RI */
+#endif
+ bl restore_math
+#ifdef CONFIG_PPC_BOOK3S
+ ld r10,PACAKMSR(r13)
+ li r9,MSR_RI
+ andc r11,r10,r9 /* Re-clear RI */
+ mtmsrd r11,1
+#endif
+ ld r8,_MSR(r1)
+ ld r3,RESULT(r1)
+ li r11,-MAX_ERRNO
+
+3: cmpld r3,r11
ld r5,_CCR(r1)
bge- syscall_error
.Lsyscall_error_cont:
@@ -223,7 +245,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
beq- 1f
ACCOUNT_CPU_USER_EXIT(r11, r12)
- HMT_MEDIUM_LOW_HAS_PPR
+
+BEGIN_FTR_SECTION
+ HMT_MEDIUM_LOW
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+
ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1: ld r2,GPR2(r1)
ld r1,GPR1(r1)
@@ -312,7 +338,13 @@ syscall_exit_work:
subi r12,r12,TI_FLAGS
4: /* Anything else left to do? */
- SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */
+BEGIN_FTR_SECTION
+ lis r3,INIT_PPR@highest /* Set thread.ppr = 3 */
+ ld r10,PACACURRENT(r13)
+ sldi r3,r3,32 /* bits 11-13 are used for ppr */
+ std r3,TASKTHREADPPR(r10)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+
andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP)
beq ret_from_except_lite
@@ -452,43 +484,11 @@ _GLOBAL(_switch)
/* r3-r13 are caller saved -- Cort */
SAVE_8GPRS(14, r1)
SAVE_10GPRS(22, r1)
- mflr r20 /* Return to switch caller */
- mfmsr r22
- li r0, MSR_FP
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
- oris r0,r0,MSR_VSX@h /* Disable VSX */
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif /* CONFIG_VSX */
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
- oris r0,r0,MSR_VEC@h /* Disable altivec */
- mfspr r24,SPRN_VRSAVE /* save vrsave register value */
- std r24,THREAD_VRSAVE(r3)
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif /* CONFIG_ALTIVEC */
- and. r0,r0,r22
- beq+ 1f
- andc r22,r22,r0
- MTMSRD(r22)
- isync
-1: std r20,_NIP(r1)
+ std r0,_NIP(r1) /* Return to switch caller */
mfcr r23
std r23,_CCR(r1)
std r1,KSP(r3) /* Set old stack pointer */
-#ifdef CONFIG_PPC_BOOK3S_64
-BEGIN_FTR_SECTION
- /* Event based branch registers */
- mfspr r0, SPRN_BESCR
- std r0, THREAD_BESCR(r3)
- mfspr r0, SPRN_EBBHR
- std r0, THREAD_EBBHR(r3)
- mfspr r0, SPRN_EBBRR
- std r0, THREAD_EBBRR(r3)
-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
-#endif
-
#ifdef CONFIG_SMP
/* We need a sync somewhere here to make sure that if the
* previous task gets rescheduled on another CPU, it sees all
@@ -576,47 +576,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
mr r1,r8 /* start using new stack pointer */
std r7,PACAKSAVE(r13)
-#ifdef CONFIG_PPC_BOOK3S_64
-BEGIN_FTR_SECTION
- /* Event based branch registers */
- ld r0, THREAD_BESCR(r4)
- mtspr SPRN_BESCR, r0
- ld r0, THREAD_EBBHR(r4)
- mtspr SPRN_EBBHR, r0
- ld r0, THREAD_EBBRR(r4)
- mtspr SPRN_EBBRR, r0
-
- ld r0,THREAD_TAR(r4)
- mtspr SPRN_TAR,r0
-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
-#endif
-
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
- ld r0,THREAD_VRSAVE(r4)
- mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_PPC64
-BEGIN_FTR_SECTION
- lwz r6,THREAD_DSCR_INHERIT(r4)
- ld r0,THREAD_DSCR(r4)
- cmpwi r6,0
- bne 1f
- ld r0,PACA_DSCR_DEFAULT(r13)
-1:
-BEGIN_FTR_SECTION_NESTED(70)
- mfspr r8, SPRN_FSCR
- rldimi r8, r6, FSCR_DSCR_LG, (63 - FSCR_DSCR_LG)
- mtspr SPRN_FSCR, r8
-END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70)
- cmpd r0,r25
- beq 2f
- mtspr SPRN_DSCR,r0
-2:
-END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
-#endif
-
ld r6,_CCR(r1)
mtcrf 0xFF,r6
@@ -665,8 +624,8 @@ _GLOBAL(ret_from_except_lite)
/* Check current_thread_info()->flags */
andi. r0,r4,_TIF_USER_WORK_MASK
-#ifdef CONFIG_PPC_BOOK3E
bne 1f
+#ifdef CONFIG_PPC_BOOK3E
/*
* Check to see if the dbcr0 register is set up to debug.
* Use the internal debug mode bit to do this.
@@ -681,7 +640,9 @@ _GLOBAL(ret_from_except_lite)
mtspr SPRN_DBSR,r10
b restore
#else
- beq restore
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl restore_math
+ b restore
#endif
1: andi. r0,r4,_TIF_NEED_RESCHED
beq 2f
@@ -1206,8 +1167,12 @@ _GLOBAL(enter_prom)
#ifdef CONFIG_DYNAMIC_FTRACE
_GLOBAL(mcount)
_GLOBAL(_mcount)
- blr
+ mflr r12
+ mtctr r12
+ mtlr r0
+ bctr
+#ifndef CC_USING_MPROFILE_KERNEL
_GLOBAL_TOC(ftrace_caller)
/* Taken from output of objdump from lib64/glibc */
mflr r3
@@ -1229,6 +1194,115 @@ _GLOBAL(ftrace_graph_stub)
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
+
+#else /* CC_USING_MPROFILE_KERNEL */
+/*
+ *
+ * ftrace_caller() is the function that replaces _mcount() when ftrace is
+ * active.
+ *
+ * We arrive here after a function A calls function B, and we are the trace
+ * function for B. When we enter r1 points to A's stack frame, B has not yet
+ * had a chance to allocate one yet.
+ *
+ * Additionally r2 may point either to the TOC for A, or B, depending on
+ * whether B did a TOC setup sequence before calling us.
+ *
+ * On entry the LR points back to the _mcount() call site, and r0 holds the
+ * saved LR as it was on entry to B, ie. the original return address at the
+ * call site in A.
+ *
+ * Our job is to save the register state into a struct pt_regs (on the stack)
+ * and then arrange for the ftrace function to be called.
+ */
+_GLOBAL(ftrace_caller)
+ /* Save the original return address in A's stack frame */
+ std r0,LRSAVE(r1)
+
+ /* Create our stack frame + pt_regs */
+ stdu r1,-SWITCH_FRAME_SIZE(r1)
+
+ /* Save all gprs to pt_regs */
+ SAVE_8GPRS(0,r1)
+ SAVE_8GPRS(8,r1)
+ SAVE_8GPRS(16,r1)
+ SAVE_8GPRS(24,r1)
+
+ /* Load special regs for save below */
+ mfmsr r8
+ mfctr r9
+ mfxer r10
+ mfcr r11
+
+ /* Get the _mcount() call site out of LR */
+ mflr r7
+ /* Save it as pt_regs->nip & pt_regs->link */
+ std r7, _NIP(r1)
+ std r7, _LINK(r1)
+
+ /* Save callee's TOC in the ABI compliant location */
+ std r2, 24(r1)
+ ld r2,PACATOC(r13) /* get kernel TOC in r2 */
+
+ addis r3,r2,function_trace_op@toc@ha
+ addi r3,r3,function_trace_op@toc@l
+ ld r5,0(r3)
+
+ /* Calculate ip from nip-4 into r3 for call below */
+ subi r3, r7, MCOUNT_INSN_SIZE
+
+ /* Put the original return address in r4 as parent_ip */
+ mr r4, r0
+
+ /* Save special regs */
+ std r8, _MSR(r1)
+ std r9, _CTR(r1)
+ std r10, _XER(r1)
+ std r11, _CCR(r1)
+
+ /* Load &pt_regs in r6 for call below */
+ addi r6, r1 ,STACK_FRAME_OVERHEAD
+
+ /* ftrace_call(r3, r4, r5, r6) */
+.globl ftrace_call
+ftrace_call:
+ bl ftrace_stub
+ nop
+
+ /* Load ctr with the possibly modified NIP */
+ ld r3, _NIP(r1)
+ mtctr r3
+
+ /* Restore gprs */
+ REST_8GPRS(0,r1)
+ REST_8GPRS(8,r1)
+ REST_8GPRS(16,r1)
+ REST_8GPRS(24,r1)
+
+ /* Restore callee's TOC */
+ ld r2, 24(r1)
+
+ /* Pop our stack frame */
+ addi r1, r1, SWITCH_FRAME_SIZE
+
+ /* Restore original LR for return to B */
+ ld r0, LRSAVE(r1)
+ mtlr r0
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ stdu r1, -112(r1)
+.globl ftrace_graph_call
+ftrace_graph_call:
+ b ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+ addi r1, r1, 112
+#endif
+
+ ld r0,LRSAVE(r1) /* restore callee's lr at _mcount site */
+ mtlr r0
+ bctr /* jump after _mcount site */
+#endif /* CC_USING_MPROFILE_KERNEL */
+
_GLOBAL(ftrace_stub)
blr
#else
@@ -1261,6 +1335,7 @@ _GLOBAL(ftrace_stub)
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#ifndef CC_USING_MPROFILE_KERNEL
_GLOBAL(ftrace_graph_caller)
/* load r4 with local address */
ld r4, 128(r1)
@@ -1285,6 +1360,56 @@ _GLOBAL(ftrace_graph_caller)
addi r1, r1, 112
blr
+#else /* CC_USING_MPROFILE_KERNEL */
+_GLOBAL(ftrace_graph_caller)
+ /* with -mprofile-kernel, parameter regs are still alive at _mcount */
+ std r10, 104(r1)
+ std r9, 96(r1)
+ std r8, 88(r1)
+ std r7, 80(r1)
+ std r6, 72(r1)
+ std r5, 64(r1)
+ std r4, 56(r1)
+ std r3, 48(r1)
+
+ /* Save callee's TOC in the ABI compliant location */
+ std r2, 24(r1)
+ ld r2, PACATOC(r13) /* get kernel TOC in r2 */
+
+ mfctr r4 /* ftrace_caller has moved local addr here */
+ std r4, 40(r1)
+ mflr r3 /* ftrace_caller has restored LR from stack */
+ subi r4, r4, MCOUNT_INSN_SIZE
+
+ bl prepare_ftrace_return
+ nop
+
+ /*
+ * prepare_ftrace_return gives us the address we divert to.
+ * Change the LR to this.
+ */
+ mtlr r3
+
+ ld r0, 40(r1)
+ mtctr r0
+ ld r10, 104(r1)
+ ld r9, 96(r1)
+ ld r8, 88(r1)
+ ld r7, 80(r1)
+ ld r6, 72(r1)
+ ld r5, 64(r1)
+ ld r4, 56(r1)
+ ld r3, 48(r1)
+
+ /* Restore callee's TOC */
+ ld r2, 24(r1)
+
+ addi r1, r1, 112
+ mflr r0
+ std r0, LRSAVE(r1)
+ bctr
+#endif /* CC_USING_MPROFILE_KERNEL */
+
_GLOBAL(return_to_handler)
/* need to save return values */
std r4, -32(r1)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index f3bd5e7..488e631 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -542,8 +542,8 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x320, ehpriv)
EXCEPTION_STUB(0x340, lrat_error)
- .globl interrupt_end_book3e
-interrupt_end_book3e:
+ .globl __end_interrupts
+__end_interrupts:
/* Critical Input Interrupt */
START_EXCEPTION(critical_input);
@@ -736,7 +736,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
beq+ 1f
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
- LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
cmpld cr0,r10,r14
cmpld cr1,r10,r15
blt+ cr0,1f
@@ -800,7 +800,7 @@ kernel_dbg_exc:
beq+ 1f
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
- LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
cmpld cr0,r10,r14
cmpld cr1,r10,r15
blt+ cr0,1f
@@ -1351,7 +1351,10 @@ skpinv: addi r6,r6,1 /* Increment */
* r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
*/
/* Now we branch the new virtual address mapped by this entry */
- LOAD_REG_IMMEDIATE(r6,2f)
+ bl 1f /* Find our address */
+1: mflr r6
+ addi r6,r6,(2f - 1b)
+ tovirt(r6,r6)
lis r7,MSR_KERNEL@h
ori r7,r7,MSR_KERNEL@l
mtspr SPRN_SRR0,r6
@@ -1583,9 +1586,11 @@ _GLOBAL(book3e_secondary_thread_init)
mflr r28
b 3b
+ .globl init_core_book3e
init_core_book3e:
/* Establish the interrupt vector base */
- LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
+ tovirt(r2,r2)
+ LOAD_REG_ADDR(r3, interrupt_base_book3e)
mtspr SPRN_IVPR,r3
sync
blr
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 0a0399c2..7716ceb 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -96,7 +96,6 @@ __start_interrupts:
.globl system_reset_pSeries;
system_reset_pSeries:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13)
#ifdef CONFIG_PPC_P7_NAP
BEGIN_FTR_SECTION
@@ -164,7 +163,6 @@ machine_check_pSeries_1:
* some code path might still want to branch into the original
* vector
*/
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13) /* save r13 */
#ifdef CONFIG_PPC_P7_NAP
BEGIN_FTR_SECTION
@@ -199,7 +197,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
. = 0x300
.globl data_access_pSeries
data_access_pSeries:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
KVMTEST, 0x300)
@@ -207,7 +204,6 @@ data_access_pSeries:
. = 0x380
.globl data_access_slb_pSeries
data_access_slb_pSeries:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
@@ -234,15 +230,14 @@ data_access_slb_pSeries:
bctr
#endif
- STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access)
+ STD_EXCEPTION_PSERIES(0x400, instruction_access)
. = 0x480
.globl instruction_access_slb_pSeries
instruction_access_slb_pSeries:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
+ EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x480)
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
#ifdef __DISABLED__
@@ -269,25 +264,24 @@ instruction_access_slb_pSeries:
.globl hardware_interrupt_hv;
hardware_interrupt_pSeries:
hardware_interrupt_hv:
- HMT_MEDIUM_PPR_DISCARD
BEGIN_FTR_SECTION
_MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt,
EXC_HV, SOFTEN_TEST_HV)
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502)
FTR_SECTION_ELSE
_MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt,
- EXC_STD, SOFTEN_TEST_HV_201)
+ EXC_STD, SOFTEN_TEST_PR)
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500)
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
- STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x600)
+ STD_EXCEPTION_PSERIES(0x600, alignment)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x600)
- STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x700)
+ STD_EXCEPTION_PSERIES(0x700, program_check)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x700)
- STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800)
+ STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x800)
. = 0x900
.globl decrementer_pSeries
@@ -297,10 +291,10 @@ decrementer_pSeries:
STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xa00)
- STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xb00)
+ STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xb00)
. = 0xc00
.globl system_call_pSeries
@@ -331,8 +325,8 @@ system_call_pSeries:
SYSCALL_PSERIES_3
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
- STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00)
+ STD_EXCEPTION_PSERIES(0xd00, single_step)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xd00)
/* At 0xe??? we have a bunch of hypervisor exceptions, we branch
* out of line to handle them
@@ -407,13 +401,12 @@ hv_facility_unavailable_trampoline:
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
#endif /* CONFIG_CBE_RAS */
- STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
- KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
+ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+ KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
. = 0x1500
.global denorm_exception_hv
denorm_exception_hv:
- HMT_MEDIUM_PPR_DISCARD
mtspr SPRN_SPRG_HSCRATCH0,r13
EXCEPTION_PROLOG_0(PACA_EXGEN)
EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500)
@@ -435,8 +428,8 @@ denorm_exception_hv:
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
#endif /* CONFIG_CBE_RAS */
- STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x1700)
+ STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x1700)
#ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
@@ -527,7 +520,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
machine_check_pSeries:
.globl machine_check_fwnmi
machine_check_fwnmi:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_0(PACA_EXMC)
machine_check_pSeries_0:
@@ -536,9 +528,9 @@ machine_check_pSeries_0:
KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400)
- KVM_HANDLER_PR(PACA_EXSLB, EXC_STD, 0x480)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x400)
+ KVM_HANDLER(PACA_EXSLB, EXC_STD, 0x480)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x900)
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
#ifdef CONFIG_PPC_DENORMALISATION
@@ -621,13 +613,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
/* moved from 0xf00 */
STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf00)
STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf20)
STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf40)
STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
- KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60)
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf60)
STD_EXCEPTION_HV_OOL(0xf82, facility_unavailable)
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf82)
@@ -711,7 +703,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
.globl system_reset_fwnmi
.align 7
system_reset_fwnmi:
- HMT_MEDIUM_PPR_DISCARD
SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
NOTEST, 0x100)
@@ -1556,29 +1547,19 @@ do_hash_page:
lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */
andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */
bne 77f /* then don't call hash_page now */
- /*
- * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
- * accessing a userspace segment (even from the kernel). We assume
- * kernel addresses always have the high bit set.
- */
- rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
- rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
- orc r0,r12,r0 /* MSR_PR | ~high_bit */
- rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
- ori r4,r4,1 /* add _PAGE_PRESENT */
- rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
/*
* r3 contains the faulting address
- * r4 contains the required access permissions
+ * r4 msr
* r5 contains the trap number
* r6 contains dsisr
*
* at return r3 = 0 for success, 1 for page fault, negative for error
*/
+ mr r4,r12
ld r6,_DSISR(r1)
- bl hash_page /* build HPTE if possible */
- cmpdi r3,0 /* see if hash_page succeeded */
+ bl __hash_page /* build HPTE if possible */
+ cmpdi r3,0 /* see if __hash_page succeeded */
/* Success */
beq fast_exc_return_irq /* Return from exception on success */
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 26d091a..3cb3b02a 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -415,7 +415,7 @@ void crash_fadump(struct pt_regs *regs, const char *str)
else
ppc_save_regs(&fdh->regs);
- fdh->cpu_online_mask = *cpu_online_mask;
+ fdh->online_mask = *cpu_online_mask;
/* Call ibm,os-term rtas call to trigger firmware assisted dump */
rtas_os_term((char *)str);
@@ -646,7 +646,7 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
}
/* Lower 4 bytes of reg_value contains logical cpu id */
cpu = be64_to_cpu(reg_entry->reg_value) & FADUMP_CPU_ID_MASK;
- if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) {
+ if (fdh && !cpumask_test_cpu(cpu, &fdh->online_mask)) {
SKIP_TO_NEXT_CPU(reg_entry);
continue;
}
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 9ad236e..15da2b5 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -73,30 +73,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
MTFSF_L(fr0)
REST_32FPVSRS(0, R4, R7)
- /* FP/VSX off again */
- MTMSRD(r6)
- SYNC
-
blr
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
/*
- * Enable use of the FPU, and VSX if possible, for the caller.
- */
-_GLOBAL(fp_enable)
- mfmsr r3
- ori r3,r3,MSR_FP
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
- oris r3,r3,MSR_VSX@h
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
- SYNC
- MTMSRD(r3)
- isync /* (not necessary for arch 2.02 and later) */
- blr
-
-/*
* Load state from memory into FP registers including FPSCR.
* Assumes the caller has enabled FP in the MSR.
*/
@@ -136,31 +116,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
SYNC
MTMSRD(r5) /* enable use of fpu now */
isync
-/*
- * For SMP, we don't do lazy FPU switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_fpu in switch_to.
- */
-#ifndef CONFIG_SMP
- LOAD_REG_ADDRBASE(r3, last_task_used_math)
- toreal(r3)
- PPC_LL r4,ADDROFF(last_task_used_math)(r3)
- PPC_LCMPI 0,r4,0
- beq 1f
- toreal(r4)
- addi r4,r4,THREAD /* want last_task_used_math->thread */
- addi r10,r4,THREAD_FPSTATE
- SAVE_32FPVSRS(0, R5, R10)
- mffs fr0
- stfd fr0,FPSTATE_FPSCR(r10)
- PPC_LL r5,PT_REGS(r4)
- toreal(r5)
- PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r10,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r10 /* disable FP for previous task */
- PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
/* enable use of FP after return */
#ifdef CONFIG_PPC32
mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
@@ -175,66 +130,33 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
or r12,r12,r4
std r12,_MSR(r1)
#endif
+ /* Don't care if r4 overflows, this is desired behaviour */
+ lbz r4,THREAD_LOAD_FP(r5)
+ addi r4,r4,1
+ stb r4,THREAD_LOAD_FP(r5)
addi r10,r5,THREAD_FPSTATE
lfd fr0,FPSTATE_FPSCR(r10)
MTFSF_L(fr0)
REST_32FPVSRS(0, R4, R10)
-#ifndef CONFIG_SMP
- subi r4,r5,THREAD
- fromreal(r4)
- PPC_STL r4,ADDROFF(last_task_used_math)(r3)
-#endif /* CONFIG_SMP */
/* restore registers and return */
/* we haven't used ctr or xer or lr */
blr
/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
+ * save_fpu(tsk)
+ * Save the floating-point registers in its thread_struct.
* Enables the FPU for use in the kernel on return.
*/
-_GLOBAL(giveup_fpu)
- mfmsr r5
- ori r5,r5,MSR_FP
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
- oris r5,r5,MSR_VSX@h
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
- SYNC_601
- ISYNC_601
- MTMSRD(r5) /* enable use of fpu now */
- SYNC_601
- isync
- PPC_LCMPI 0,r3,0
- beqlr- /* if no previous owner, done */
+_GLOBAL(save_fpu)
addi r3,r3,THREAD /* want THREAD of task */
PPC_LL r6,THREAD_FPSAVEAREA(r3)
PPC_LL r5,PT_REGS(r3)
PPC_LCMPI 0,r6,0
bne 2f
addi r6,r3,THREAD_FPSTATE
-2: PPC_LCMPI 0,r5,0
- SAVE_32FPVSRS(0, R4, R6)
+2: SAVE_32FPVSRS(0, R4, R6)
mffs fr0
stfd fr0,FPSTATE_FPSCR(r6)
- beq 1f
- PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r3,MSR_FP|MSR_FE0|MSR_FE1
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
- oris r3,r3,MSR_VSX@h
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
- andc r4,r4,r3 /* disable FP for previous task */
- PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- LOAD_REG_ADDRBASE(r4,last_task_used_math)
- PPC_STL r5,ADDROFF(last_task_used_math)(r4)
-#endif /* CONFIG_SMP */
blr
/*
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 44d4d8e..9dac18da 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -61,8 +61,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
return -EFAULT;
/* Make sure it is what we expect it to be */
- if (replaced != old)
+ if (replaced != old) {
+ pr_err("%p: replaced (%#x) != old (%#x)",
+ (void *)ip, replaced, old);
return -EINVAL;
+ }
/* replace the text with the new text */
if (patch_instruction((unsigned int *)ip, new))
@@ -106,14 +109,15 @@ static int
__ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr)
{
- unsigned int op;
- unsigned long entry, ptr;
+ unsigned long entry, ptr, tramp;
unsigned long ip = rec->ip;
- void *tramp;
+ unsigned int op, pop;
/* read where this goes */
- if (probe_kernel_read(&op, (void *)ip, sizeof(int)))
+ if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+ pr_err("Fetching opcode failed.\n");
return -EFAULT;
+ }
/* Make sure that that this is still a 24bit jump */
if (!is_bl_op(op)) {
@@ -122,14 +126,9 @@ __ftrace_make_nop(struct module *mod,
}
/* lets find where the pointer goes */
- tramp = (void *)find_bl_target(ip, op);
-
- pr_devel("ip:%lx jumps to %p", ip, tramp);
+ tramp = find_bl_target(ip, op);
- if (!is_module_trampoline(tramp)) {
- pr_err("Not a trampoline\n");
- return -EINVAL;
- }
+ pr_devel("ip:%lx jumps to %lx", ip, tramp);
if (module_trampoline_target(mod, tramp, &ptr)) {
pr_err("Failed to get trampoline target\n");
@@ -158,10 +157,42 @@ __ftrace_make_nop(struct module *mod,
*
* Use a b +8 to jump over the load.
*/
- op = 0x48000008; /* b +8 */
- if (patch_instruction((unsigned int *)ip, op))
+ pop = PPC_INST_BRANCH | 8; /* b +8 */
+
+ /*
+ * Check what is in the next instruction. We can see ld r2,40(r1), but
+ * on first pass after boot we will see mflr r0.
+ */
+ if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) {
+ pr_err("Fetching op failed.\n");
+ return -EFAULT;
+ }
+
+ if (op != PPC_INST_LD_TOC) {
+ unsigned int inst;
+
+ if (probe_kernel_read(&inst, (void *)(ip - 4), 4)) {
+ pr_err("Fetching instruction at %lx failed.\n", ip - 4);
+ return -EFAULT;
+ }
+
+ /* We expect either a mlfr r0, or a std r0, LRSAVE(r1) */
+ if (inst != PPC_INST_MFLR && inst != PPC_INST_STD_LR) {
+ pr_err("Unexpected instructions around bl _mcount\n"
+ "when enabling dynamic ftrace!\t"
+ "(%08x,bl,%08x)\n", inst, op);
+ return -EINVAL;
+ }
+
+ /* When using -mkernel_profile there is no load to jump over */
+ pop = PPC_INST_NOP;
+ }
+
+ if (patch_instruction((unsigned int *)ip, pop)) {
+ pr_err("Patching NOP failed.\n");
return -EPERM;
+ }
return 0;
}
@@ -287,16 +318,15 @@ int ftrace_make_nop(struct module *mod,
#ifdef CONFIG_MODULES
#ifdef CONFIG_PPC64
+/*
+ * Examine the existing instructions for __ftrace_make_call.
+ * They should effectively be a NOP, and follow formal constraints,
+ * depending on the ABI. Return false if they don't.
+ */
+#ifndef CC_USING_MPROFILE_KERNEL
static int
-__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
{
- unsigned int op[2];
- void *ip = (void *)rec->ip;
-
- /* read where this goes */
- if (probe_kernel_read(op, ip, sizeof(op)))
- return -EFAULT;
-
/*
* We expect to see:
*
@@ -306,8 +336,34 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
* The load offset is different depending on the ABI. For simplicity
* just mask it out when doing the compare.
*/
- if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) {
- pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]);
+ if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000))
+ return 0;
+ return 1;
+}
+#else
+static int
+expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
+{
+ /* look for patched "NOP" on ppc64 with -mprofile-kernel */
+ if (op0 != PPC_INST_NOP)
+ return 0;
+ return 1;
+}
+#endif
+
+static int
+__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned int op[2];
+ void *ip = (void *)rec->ip;
+
+ /* read where this goes */
+ if (probe_kernel_read(op, ip, sizeof(op)))
+ return -EFAULT;
+
+ if (!expected_nop_sequence(ip, op[0], op[1])) {
+ pr_err("Unexpected call sequence at %p: %x %x\n",
+ ip, op[0], op[1]);
return -EINVAL;
}
@@ -330,7 +386,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return 0;
}
-#else
+
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
+ unsigned long addr)
+{
+ return ftrace_make_call(rec, addr);
+}
+#endif
+
+#else /* !CONFIG_PPC64: */
static int
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
@@ -455,20 +520,13 @@ void ftrace_replace_code(int enable)
}
}
+/*
+ * Use the default ftrace_modify_all_code, but without
+ * stop_machine().
+ */
void arch_ftrace_update_code(int command)
{
- if (command & FTRACE_UPDATE_CALLS)
- ftrace_replace_code(1);
- else if (command & FTRACE_DISABLE_CALLS)
- ftrace_replace_code(0);
-
- if (command & FTRACE_UPDATE_TRACE_FUNC)
- ftrace_update_ftrace_func(ftrace_trace_function);
-
- if (command & FTRACE_START_FUNC_RET)
- ftrace_enable_ftrace_graph_caller();
- else if (command & FTRACE_STOP_FUNC_RET)
- ftrace_disable_ftrace_graph_caller();
+ ftrace_modify_all_code(command);
}
int __init ftrace_dyn_arch_init(void)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b5061ab..9cdf5c7 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -806,7 +806,7 @@ _GLOBAL(set_context)
_GLOBAL(init_cpu_state)
mflr r22
#ifdef CONFIG_PPC_47x
- /* We use the PVR to differenciate 44x cores from 476 */
+ /* We use the PVR to differentiate 44x cores from 476 */
mfspr r3,SPRN_PVR
srwi r3,r3,16
cmplwi cr0,r3,PVR_476FPE@h
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d48125d..4286775 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -40,6 +40,8 @@
#include <asm/kvm_book3s_asm.h>
#include <asm/ptrace.h>
#include <asm/hw_irq.h>
+#include <asm/cputhreads.h>
+#include <asm/ppc-opcode.h>
/* The physical memory is laid out such that the secondary processor
* spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -181,7 +183,67 @@ exception_marker:
#endif
#ifdef CONFIG_PPC_BOOK3E
+/*
+ * The booting_thread_hwid holds the thread id we want to boot in cpu
+ * hotplug case. It is set by cpu hotplug code, and is invalid by default.
+ * The thread id is the same as the initial value of SPRN_PIR[THREAD_ID]
+ * bit field.
+ */
+ .globl booting_thread_hwid
+booting_thread_hwid:
+ .long INVALID_THREAD_HWID
+ .align 3
+/*
+ * start a thread in the same core
+ * input parameters:
+ * r3 = the thread physical id
+ * r4 = the entry point where thread starts
+ */
+_GLOBAL(book3e_start_thread)
+ LOAD_REG_IMMEDIATE(r5, MSR_KERNEL)
+ cmpi 0, r3, 0
+ beq 10f
+ cmpi 0, r3, 1
+ beq 11f
+ /* If the thread id is invalid, just exit. */
+ b 13f
+10:
+ MTTMR(TMRN_IMSR0, 5)
+ MTTMR(TMRN_INIA0, 4)
+ b 12f
+11:
+ MTTMR(TMRN_IMSR1, 5)
+ MTTMR(TMRN_INIA1, 4)
+12:
+ isync
+ li r6, 1
+ sld r6, r6, r3
+ mtspr SPRN_TENS, r6
+13:
+ blr
+
+/*
+ * stop a thread in the same core
+ * input parameter:
+ * r3 = the thread physical id
+ */
+_GLOBAL(book3e_stop_thread)
+ cmpi 0, r3, 0
+ beq 10f
+ cmpi 0, r3, 1
+ beq 10f
+ /* If the thread id is invalid, just exit. */
+ b 13f
+10:
+ li r4, 1
+ sld r4, r4, r3
+ mtspr SPRN_TENC, r4
+13:
+ blr
+
_GLOBAL(fsl_secondary_thread_init)
+ mfspr r4,SPRN_BUCSR
+
/* Enable branch prediction */
lis r3,BUCSR_INIT@h
ori r3,r3,BUCSR_INIT@l
@@ -196,10 +258,24 @@ _GLOBAL(fsl_secondary_thread_init)
* number. There are two threads per core, so shift everything
* but the low bit right by two bits so that the cpu numbering is
* continuous.
+ *
+ * If the old value of BUCSR is non-zero, this thread has run
+ * before. Thus, we assume we are coming from kexec or a similar
+ * scenario, and PIR is already set to the correct value. This
+ * is a bit of a hack, but there are limited opportunities for
+ * getting information into the thread and the alternatives
+ * seemed like they'd be overkill. We can't tell just by looking
+ * at the old PIR value which state it's in, since the same value
+ * could be valid for one thread out of reset and for a different
+ * thread in Linux.
*/
+
mfspr r3, SPRN_PIR
+ cmpwi r4,0
+ bne 1f
rlwimi r3, r3, 30, 2, 30
mtspr SPRN_PIR, r3
+1:
#endif
_GLOBAL(generic_secondary_thread_init)
@@ -245,6 +321,44 @@ _GLOBAL(generic_secondary_smp_init)
mr r3,r24
mr r4,r25
bl book3e_secondary_core_init
+
+/*
+ * After common core init has finished, check if the current thread is the
+ * one we wanted to boot. If not, start the specified thread and stop the
+ * current thread.
+ */
+ LOAD_REG_ADDR(r4, booting_thread_hwid)
+ lwz r3, 0(r4)
+ li r5, INVALID_THREAD_HWID
+ cmpw r3, r5
+ beq 20f
+
+ /*
+ * The value of booting_thread_hwid has been stored in r3,
+ * so make it invalid.
+ */
+ stw r5, 0(r4)
+
+ /*
+ * Get the current thread id and check if it is the one we wanted.
+ * If not, start the one specified in booting_thread_hwid and stop
+ * the current thread.
+ */
+ mfspr r8, SPRN_TIR
+ cmpw r3, r8
+ beq 20f
+
+ /* start the specified thread */
+ LOAD_REG_ADDR(r5, fsl_secondary_thread_init)
+ ld r4, 0(r5)
+ bl book3e_start_thread
+
+ /* stop the current thread */
+ mr r3, r8
+ bl book3e_stop_thread
+10:
+ b 10b
+20:
#endif
generic_secondary_common_init:
@@ -441,12 +555,22 @@ __after_prom_start:
/* process relocations for the final address of the kernel */
lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
sldi r25,r25,32
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */
+#endif
lwz r7,__run_at_load-_stext(r26)
+#if defined(CONFIG_PPC_BOOK3E)
+ tophys(r26,r26)
+#endif
cmplwi cr0,r7,1 /* flagged to stay where we are ? */
bne 1f
add r25,r25,r26
1: mr r3,r25
bl relocate
+#if defined(CONFIG_PPC_BOOK3E)
+ /* IVPR needs to be set after relocation. */
+ bl init_core_book3e
+#endif
#endif
/*
@@ -458,15 +582,15 @@ __after_prom_start:
*/
li r3,0 /* target addr */
#ifdef CONFIG_PPC_BOOK3E
- tovirt(r3,r3) /* on booke, we already run at PAGE_OFFSET */
+ tovirt(r3,r3) /* on booke, we already run at PAGE_OFFSET */
#endif
mr. r4,r26 /* In some cases the loader may */
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r4,r4)
+#endif
beq 9f /* have already put us at zero */
li r6,0x100 /* Start offset, the first 0x100 */
/* bytes were copied earlier. */
-#ifdef CONFIG_PPC_BOOK3E
- tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */
-#endif
#ifdef CONFIG_RELOCATABLE
/*
@@ -474,12 +598,21 @@ __after_prom_start:
* variable __run_at_load, if it is set the kernel is treated as relocatable
* kernel, otherwise it will be moved to PHYSICAL_START
*/
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */
+#endif
lwz r7,__run_at_load-_stext(r26)
cmplwi cr0,r7,1
bne 3f
+#ifdef CONFIG_PPC_BOOK3E
+ LOAD_REG_ADDR(r5, __end_interrupts)
+ LOAD_REG_ADDR(r11, _stext)
+ sub r5,r5,r11
+#else
/* just copy interrupts */
LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
+#endif
b 5f
3:
#endif
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 78c1eba..80c6947 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -329,7 +329,7 @@ InstructionTLBMiss:
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
-#ifdef CONFIG_MODULES
+#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
/* Only modules will cause ITLB Misses as we always
* pin the first 8MB of kernel memory */
mfspr r11, SPRN_SRR0 /* Get effective address of fault */
@@ -385,27 +385,26 @@ InstructionTLBMiss:
. = 0x1200
DataStoreTLBMiss:
-#ifdef CONFIG_8xx_CPU6
mtspr SPRN_SPRG_SCRATCH2, r3
-#endif
EXCEPTION_PROLOG_0
- mfcr r10
+ mfcr r3
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
- mfspr r11, SPRN_MD_EPN
- IS_KERNEL(r11, r11)
+ mfspr r10, SPRN_MD_EPN
+ IS_KERNEL(r11, r10)
mfspr r11, SPRN_M_TW /* Get level 1 table */
BRANCH_UNLESS_KERNEL(3f)
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
3:
- mtcr r10
- mfspr r10, SPRN_MD_EPN
/* Insert level 1 index */
rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
+ mtcr r11
+ bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */
+ mtcr r3
/* We have a pte table, so load fetch the pte from the table.
*/
@@ -453,13 +452,34 @@ DataStoreTLBMiss:
MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
/* Restore registers */
-#ifdef CONFIG_8xx_CPU6
mfspr r3, SPRN_SPRG_SCRATCH2
+ mtspr SPRN_DAR, r11 /* Tag DAR */
+ EXCEPTION_EPILOG_0
+ rfi
+
+DTLBMiss8M:
+ mtcr r3
+ ori r11, r11, MD_SVALID
+ MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
+#ifdef CONFIG_PPC_16K_PAGES
+ /*
+ * In 16k pages mode, each PGD entry defines a 64M block.
+ * Here we select the 8M page within the block.
+ */
+ rlwimi r11, r10, 0, 0x03800000
#endif
+ rlwinm r10, r11, 0, 0xff800000
+ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
+ _PAGE_PRESENT
+ MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
+
+ li r11, RPN_PATTERN
+ mfspr r3, SPRN_SPRG_SCRATCH2
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
+
/* This is an instruction TLB error on the MPC8xx. This could be due
* to many reasons, such as executing guarded memory or illegal instruction
* addresses. There is nothing to do but handle a big time error fault.
@@ -537,13 +557,15 @@ FixupDAR:/* Entry point for dcbx workaround. */
/* Insert level 1 index */
3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
+ mtcr r11
+ bt 28,200f /* bit 28 = Large page (8M) */
rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
/* Insert level 2 index */
rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
lwz r11, 0(r11) /* Get the pte */
/* concat physical page address(r11) and page offset(r10) */
rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
- lwz r11,0(r11)
+201: lwz r11,0(r11)
/* Check if it really is a dcbx instruction. */
/* dcbt and dcbtst does not generate DTLB Misses/Errors,
* no need to include them here */
@@ -562,6 +584,10 @@ FixupDAR:/* Entry point for dcbx workaround. */
141: mfspr r10,SPRN_SPRG_SCRATCH2
b DARFixed /* Nope, go back to normal TLB processing */
+ /* concat physical page address(r11) and page offset(r10) */
+200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31
+ b 201b
+
144: mfspr r10, SPRN_DSISR
rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
mtspr SPRN_DSISR, r10
@@ -857,68 +883,6 @@ initial_mmu:
/*
- * Set up to use a given MMU context.
- * r3 is context number, r4 is PGD pointer.
- *
- * We place the physical address of the new task page directory loaded
- * into the MMU base register, and set the ASID compare register with
- * the new "context."
- */
-_GLOBAL(set_context)
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is passed as second argument.
- */
- lis r5, KERNELBASE@h
- lwz r5, 0xf0(r5)
- stw r4, 0x4(r5)
-#endif
-
- /* Register M_TW will contain base address of level 1 table minus the
- * lower part of the kernel PGDIR base address, so that all accesses to
- * level 1 table are done relative to lower part of kernel PGDIR base
- * address.
- */
- li r5, (swapper_pg_dir-PAGE_OFFSET)@l
- sub r4, r4, r5
- tophys (r4, r4)
-#ifdef CONFIG_8xx_CPU6
- lis r6, cpu6_errata_word@h
- ori r6, r6, cpu6_errata_word@l
- li r7, 0x3f80
- stw r7, 12(r6)
- lwz r7, 12(r6)
-#endif
- mtspr SPRN_M_TW, r4 /* Update pointeur to level 1 table */
-#ifdef CONFIG_8xx_CPU6
- li r7, 0x3380
- stw r7, 12(r6)
- lwz r7, 12(r6)
-#endif
- mtspr SPRN_M_CASID, r3 /* Update context */
- SYNC
- blr
-
-#ifdef CONFIG_8xx_CPU6
-/* It's here because it is unique to the 8xx.
- * It is important we get called with interrupts disabled. I used to
- * do that, but it appears that all code that calls this already had
- * interrupt disabled.
- */
- .globl set_dec_cpu6
-set_dec_cpu6:
- lis r7, cpu6_errata_word@h
- ori r7, r7, cpu6_errata_word@l
- li r4, 0x2c00
- stw r4, 8(r7)
- lwz r4, 8(r7)
- mtspr 22, r3 /* Update Decrementer */
- SYNC
- blr
-#endif
-
-/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the data segment,
* which is page-aligned.
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index fffd1f9..3bfa315 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -857,29 +857,6 @@ _GLOBAL(load_up_spe)
oris r5,r5,MSR_SPE@h
mtmsr r5 /* enable use of SPE now */
isync
-/*
- * For SMP, we don't do lazy SPE switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_spe in switch_to.
- */
-#ifndef CONFIG_SMP
- lis r3,last_task_used_spe@ha
- lwz r4,last_task_used_spe@l(r3)
- cmpi 0,r4,0
- beq 1f
- addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
- SAVE_32EVRS(0,r10,r4,THREAD_EVR0)
- evxor evr10, evr10, evr10 /* clear out evr10 */
- evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
- li r5,THREAD_ACC
- evstddx evr10, r4, r5 /* save off accumulator */
- lwz r5,PT_REGS(r4)
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r10,MSR_SPE@h
- andc r4,r4,r10 /* disable SPE for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* !CONFIG_SMP */
/* enable use of SPE after return */
oris r9,r9,MSR_SPE@h
mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
@@ -889,10 +866,6 @@ _GLOBAL(load_up_spe)
evlddx evr4,r10,r5
evmra evr4,evr4
REST_32EVRS(0,r10,r5,THREAD_EVR0)
-#ifndef CONFIG_SMP
- subi r4,r5,THREAD
- stw r4,last_task_used_spe@l(r3)
-#endif /* !CONFIG_SMP */
blr
/*
@@ -1011,16 +984,10 @@ _GLOBAL(__setup_ehv_ivors)
#ifdef CONFIG_SPE
/*
- * extern void giveup_spe(struct task_struct *prev)
+ * extern void __giveup_spe(struct task_struct *prev)
*
*/
-_GLOBAL(giveup_spe)
- mfmsr r5
- oris r5,r5,MSR_SPE@h
- mtmsr r5 /* enable use of SPE now */
- isync
- cmpi 0,r3,0
- beqlr- /* if no previous owner, done */
+_GLOBAL(__giveup_spe)
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpi 0,r5,0
@@ -1035,11 +1002,6 @@ _GLOBAL(giveup_spe)
andc r4,r4,r3 /* disable SPE for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
-#ifndef CONFIG_SMP
- li r5,0
- lis r4,last_task_used_spe@ha
- stw r5,last_task_used_spe@l(r4)
-#endif /* !CONFIG_SMP */
blr
#endif /* CONFIG_SPE */
@@ -1075,80 +1037,6 @@ _GLOBAL(set_context)
isync /* Force context change */
blr
-_GLOBAL(flush_dcache_L1)
- mfspr r3,SPRN_L1CFG0
-
- rlwinm r5,r3,9,3 /* Extract cache block size */
- twlgti r5,1 /* Only 32 and 64 byte cache blocks
- * are currently defined.
- */
- li r4,32
- subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
- * log2(number of ways)
- */
- slw r5,r4,r5 /* r5 = cache block size */
-
- rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
- mulli r7,r7,13 /* An 8-way cache will require 13
- * loads per set.
- */
- slw r7,r7,r6
-
- /* save off HID0 and set DCFA */
- mfspr r8,SPRN_HID0
- ori r9,r8,HID0_DCFA@l
- mtspr SPRN_HID0,r9
- isync
-
- lis r4,KERNELBASE@h
- mtctr r7
-
-1: lwz r3,0(r4) /* Load... */
- add r4,r4,r5
- bdnz 1b
-
- msync
- lis r4,KERNELBASE@h
- mtctr r7
-
-1: dcbf 0,r4 /* ...and flush. */
- add r4,r4,r5
- bdnz 1b
-
- /* restore HID0 */
- mtspr SPRN_HID0,r8
- isync
-
- blr
-
-/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */
-_GLOBAL(__flush_disable_L1)
- mflr r10
- bl flush_dcache_L1 /* Flush L1 d-cache */
- mtlr r10
-
- mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */
- li r5, 2
- rlwimi r4, r5, 0, 3
-
- msync
- isync
- mtspr SPRN_L1CSR0, r4
- isync
-
-1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
- andi. r4, r4, 2
- bne 1b
-
- mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */
- li r5, 2
- rlwimi r4, r5, 0, 3
-
- mtspr SPRN_L1CSR1, r4
- isync
-
- blr
-
#ifdef CONFIG_SMP
/* When we get here, r24 needs to hold the CPU # */
.globl __secondary_start
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 05e804c..aec9a1b 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -109,8 +109,9 @@ void arch_unregister_hw_breakpoint(struct perf_event *bp)
* If the breakpoint is unregistered between a hw_breakpoint_handler()
* and the single_step_dabr_instruction(), then cleanup the breakpoint
* restoration variables to prevent dangling pointers.
+ * FIXME, this should not be using bp->ctx at all! Sayeth peterz.
*/
- if (bp->ctx && bp->ctx->task)
+ if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L))
bp->ctx->task->thread.last_hit_ubp = NULL;
}
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 112ccf4..470ceeb 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -19,7 +19,7 @@
#include <asm/kvm_book3s_asm.h>
#include <asm/opal.h>
#include <asm/cpuidle.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#undef DEBUG
@@ -89,13 +89,6 @@ _GLOBAL(power7_powersave_common)
std r0,_LINK(r1)
std r0,_NIP(r1)
-#ifndef CONFIG_SMP
- /* Make sure FPU, VSX etc... are flushed as we may lose
- * state when going to nap mode
- */
- bl discard_lazy_cpu_state
-#endif /* CONFIG_SMP */
-
/* Hard disable interrupts */
mfmsr r9
rldicl r9,r9,48,1
diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c
index 63d9cc4..5f8613c 100644
--- a/arch/powerpc/kernel/io-workarounds.c
+++ b/arch/powerpc/kernel/io-workarounds.c
@@ -76,7 +76,7 @@ struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
* a page table free due to init_mm
*/
ptep = __find_linux_pte_or_hugepte(init_mm.pgd, vaddr,
- &hugepage_shift);
+ NULL, &hugepage_shift);
if (ptep == NULL)
paddr = 0;
else {
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index e77c3cc..dbf0981 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -445,7 +445,11 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
* Global data
*/
struct kgdb_arch arch_kgdb_ops = {
+#ifdef __LITTLE_ENDIAN__
+ .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d},
+#else
.gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
+#endif
};
static int kgdb_not_implemented(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 1a74446..0fbd75d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -30,6 +30,21 @@
#include <asm/smp.h>
#include <asm/hw_breakpoint.h>
+#ifdef CONFIG_PPC_BOOK3E
+int default_machine_kexec_prepare(struct kimage *image)
+{
+ int i;
+ /*
+ * Since we use the kernel fault handlers and paging code to
+ * handle the virtual mode, we must make sure no destination
+ * overlaps kernel static data or bss.
+ */
+ for (i = 0; i < image->nr_segments; i++)
+ if (image->segment[i].mem < __pa(_end))
+ return -ETXTBSY;
+ return 0;
+}
+#else
int default_machine_kexec_prepare(struct kimage *image)
{
int i;
@@ -95,6 +110,7 @@ int default_machine_kexec_prepare(struct kimage *image)
return 0;
}
+#endif /* !CONFIG_PPC_BOOK3E */
static void copy_segments(unsigned long ind)
{
@@ -365,6 +381,7 @@ void default_machine_kexec(struct kimage *image)
/* NOTREACHED */
}
+#ifndef CONFIG_PPC_BOOK3E
/* Values we need to export to the second kernel via the device tree. */
static unsigned long htab_base;
static unsigned long htab_size;
@@ -411,3 +428,4 @@ static int __init export_htab_values(void)
return 0;
}
late_initcall(export_htab_values);
+#endif /* !CONFIG_PPC_BOOK3E */
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index 2c647b1..ee62b19 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -54,8 +54,8 @@ static void flush_tlb_206(unsigned int num_sets, unsigned int action)
}
/*
- * Generic routine to flush TLB on power7. This routine is used as
- * flush_tlb hook in cpu_spec for Power7 processor.
+ * Generic routines to flush TLB on POWER processors. These routines
+ * are used as flush_tlb hook in the cpu_spec.
*
* action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs.
* TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID.
@@ -65,18 +65,17 @@ void __flush_tlb_power7(unsigned int action)
flush_tlb_206(POWER7_TLB_SETS, action);
}
-/*
- * Generic routine to flush TLB on power8. This routine is used as
- * flush_tlb hook in cpu_spec for power8 processor.
- *
- * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs.
- * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID.
- */
void __flush_tlb_power8(unsigned int action)
{
flush_tlb_206(POWER8_TLB_SETS, action);
}
+void __flush_tlb_power9(unsigned int action)
+{
+ flush_tlb_206(POWER9_TLB_SETS_HASH, action);
+}
+
+
/* flush SLBs and reload */
static void flush_and_reload_slb(void)
{
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index ed3ab50..bf5160f 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -91,17 +91,16 @@ _GLOBAL(mulhdu)
addc r7,r0,r7
addze r4,r4
1: beqlr cr1 /* all done if high part of A is 0 */
- mr r10,r3
mullw r9,r3,r5
- mulhwu r3,r3,r5
+ mulhwu r10,r3,r5
beq 2f
- mullw r0,r10,r6
- mulhwu r8,r10,r6
+ mullw r0,r3,r6
+ mulhwu r8,r3,r6
addc r7,r0,r7
adde r4,r4,r8
- addze r3,r3
+ addze r10,r10
2: addc r4,r4,r9
- addze r3,r3
+ addze r3,r10
blr
/*
@@ -296,12 +295,9 @@ _GLOBAL(real_writeb)
* Flush instruction cache.
* This is a no-op on the 601.
*/
+#ifndef CONFIG_PPC_8xx
_GLOBAL(flush_instruction_cache)
-#if defined(CONFIG_8xx)
- isync
- lis r5, IDC_INVALL@h
- mtspr SPRN_IC_CST, r5
-#elif defined(CONFIG_4xx)
+#if defined(CONFIG_4xx)
#ifdef CONFIG_403GCX
li r3, 512
mtctr r3
@@ -334,9 +330,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
mfspr r3,SPRN_HID0
ori r3,r3,HID0_ICFI
mtspr SPRN_HID0,r3
-#endif /* CONFIG_8xx/4xx */
+#endif /* CONFIG_4xx */
isync
blr
+#endif /* CONFIG_PPC_8xx */
/*
* Write any modified data cache blocks out to memory
@@ -350,10 +347,9 @@ BEGIN_FTR_SECTION
PURGE_PREFETCHED_INS
blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
- li r5,L1_CACHE_BYTES-1
- andc r3,r3,r5
+ rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT
subf r4,r3,r4
- add r4,r4,r5
+ addi r4,r4,L1_CACHE_BYTES - 1
srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
@@ -377,71 +373,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
isync
blr
/*
- * Write any modified data cache blocks out to memory.
- * Does not invalidate the corresponding cache lines (especially for
- * any corresponding instruction cache).
- *
- * clean_dcache_range(unsigned long start, unsigned long stop)
- */
-_GLOBAL(clean_dcache_range)
- li r5,L1_CACHE_BYTES-1
- andc r3,r3,r5
- subf r4,r3,r4
- add r4,r4,r5
- srwi. r4,r4,L1_CACHE_SHIFT
- beqlr
- mtctr r4
-
-1: dcbst 0,r3
- addi r3,r3,L1_CACHE_BYTES
- bdnz 1b
- sync /* wait for dcbst's to get to ram */
- blr
-
-/*
- * Write any modified data cache blocks out to memory and invalidate them.
- * Does not invalidate the corresponding instruction cache blocks.
- *
- * flush_dcache_range(unsigned long start, unsigned long stop)
- */
-_GLOBAL(flush_dcache_range)
- li r5,L1_CACHE_BYTES-1
- andc r3,r3,r5
- subf r4,r3,r4
- add r4,r4,r5
- srwi. r4,r4,L1_CACHE_SHIFT
- beqlr
- mtctr r4
-
-1: dcbf 0,r3
- addi r3,r3,L1_CACHE_BYTES
- bdnz 1b
- sync /* wait for dcbst's to get to ram */
- blr
-
-/*
- * Like above, but invalidate the D-cache. This is used by the 8xx
- * to invalidate the cache so the PPC core doesn't get stale data
- * from the CPM (no cache snooping here :-).
- *
- * invalidate_dcache_range(unsigned long start, unsigned long stop)
- */
-_GLOBAL(invalidate_dcache_range)
- li r5,L1_CACHE_BYTES-1
- andc r3,r3,r5
- subf r4,r3,r4
- add r4,r4,r5
- srwi. r4,r4,L1_CACHE_SHIFT
- beqlr
- mtctr r4
-
-1: dcbi 0,r3
- addi r3,r3,L1_CACHE_BYTES
- bdnz 1b
- sync /* wait for dcbi's to get to ram */
- blr
-
-/*
* Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
@@ -519,22 +450,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
#endif /* CONFIG_BOOKE */
/*
- * Clear pages using the dcbz instruction, which doesn't cause any
- * memory traffic (except to write out any cache lines which get
- * displaced). This only works on cacheable memory.
- *
- * void clear_pages(void *page, int order) ;
- */
-_GLOBAL(clear_pages)
- li r0,PAGE_SIZE/L1_CACHE_BYTES
- slw r0,r0,r4
- mtctr r0
-1: dcbz 0,r3
- addi r3,r3,L1_CACHE_BYTES
- bdnz 1b
- blr
-
-/*
* Copy a whole page. We use the dcbz instruction on the destination
* to reduce memory traffic (it eliminates the unnecessary reads of
* the destination into cache). This requires that the destination
@@ -743,6 +658,8 @@ relocate_new_kernel:
/* Check for 47x cores */
mfspr r3,SPRN_PVR
srwi r3,r3,16
+ cmplwi cr0,r3,PVR_476FPE@h
+ beq setup_map_47x
cmplwi cr0,r3,PVR_476@h
beq setup_map_47x
cmplwi cr0,r3,PVR_476_ISS@h
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 6e4168c..f28754c 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -26,6 +26,7 @@
#include <asm/thread_info.h>
#include <asm/kexec.h>
#include <asm/ptrace.h>
+#include <asm/mmu.h>
.text
@@ -484,6 +485,8 @@ _GLOBAL(kexec_wait)
mtsrr1 r11
rfid
#else
+ /* Create TLB entry in book3e_secondary_core_init */
+ li r4,0
ba 0x60
#endif
#endif
@@ -496,6 +499,51 @@ kexec_flag:
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_PPC_BOOK3E
+/*
+ * BOOK3E has no real MMU mode, so we have to setup the initial TLB
+ * for a core to identity map v:0 to p:0. This current implementation
+ * assumes that 1G is enough for kexec.
+ */
+kexec_create_tlb:
+ /*
+ * Invalidate all non-IPROT TLB entries to avoid any TLB conflict.
+ * IPROT TLB entries should be >= PAGE_OFFSET and thus not conflict.
+ */
+ PPC_TLBILX_ALL(0,R0)
+ sync
+ isync
+
+ mfspr r10,SPRN_TLB1CFG
+ andi. r10,r10,TLBnCFG_N_ENTRY /* Extract # entries */
+ subi r10,r10,1 /* Last entry: no conflict with kernel text */
+ lis r9,MAS0_TLBSEL(1)@h
+ rlwimi r9,r10,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r9) */
+
+/* Set up a temp identity mapping v:0 to p:0 and return to it. */
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
+#define M_IF_NEEDED MAS2_M
+#else
+#define M_IF_NEEDED 0
+#endif
+ mtspr SPRN_MAS0,r9
+
+ lis r9,(MAS1_VALID|MAS1_IPROT)@h
+ ori r9,r9,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
+ mtspr SPRN_MAS1,r9
+
+ LOAD_REG_IMMEDIATE(r9, 0x0 | M_IF_NEEDED)
+ mtspr SPRN_MAS2,r9
+
+ LOAD_REG_IMMEDIATE(r9, 0x0 | MAS3_SR | MAS3_SW | MAS3_SX)
+ mtspr SPRN_MAS3,r9
+ li r9,0
+ mtspr SPRN_MAS7,r9
+
+ tlbwe
+ isync
+ blr
+#endif
/* kexec_smp_wait(void)
*
@@ -525,6 +573,10 @@ _GLOBAL(kexec_smp_wait)
* don't overwrite r3 here, it is live for kexec_wait above.
*/
real_mode: /* assume normal blr return */
+#ifdef CONFIG_PPC_BOOK3E
+ /* Create an identity mapping. */
+ b kexec_create_tlb
+#else
1: li r9,MSR_RI
li r10,MSR_DR|MSR_IR
mflr r11 /* return address to SRR0 */
@@ -536,7 +588,7 @@ real_mode: /* assume normal blr return */
mtspr SPRN_SRR1,r10
mtspr SPRN_SRR0,r11
rfid
-
+#endif
/*
* kexec_sequence(newstack, start, image, control, clear_all())
@@ -579,9 +631,13 @@ _GLOBAL(kexec_sequence)
lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */
/* disable interrupts, we are overwriting kernel data next */
+#ifdef CONFIG_PPC_BOOK3E
+ wrteei 0
+#else
mfmsr r3
rlwinm r3,r3,0,17,15
mtmsrd r3,1
+#endif
/* copy dest pages, flush whole dest image */
mr r3,r29
@@ -603,6 +659,7 @@ _GLOBAL(kexec_sequence)
li r6,1
stw r6,kexec_flag-1b(5)
+#ifndef CONFIG_PPC_BOOK3E
/* clear out hardware hash page table and tlb */
#if !defined(_CALL_ELF) || _CALL_ELF != 2
ld r12,0(r27) /* deref function descriptor */
@@ -611,6 +668,7 @@ _GLOBAL(kexec_sequence)
#endif
mtctr r12
bctrl /* ppc_md.hpte_clear_all(void); */
+#endif /* !CONFIG_PPC_BOOK3E */
/*
* kexec image calling is:
@@ -643,31 +701,3 @@ _GLOBAL(kexec_sequence)
li r5,0
blr /* image->start(physid, image->start, 0); */
#endif /* CONFIG_KEXEC */
-
-#ifdef CONFIG_MODULES
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-
-#ifdef CONFIG_MODVERSIONS
-.weak __crc_TOC.
-.section "___kcrctab+TOC.","a"
-.globl __kcrctab_TOC.
-__kcrctab_TOC.:
- .llong __crc_TOC.
-#endif
-
-/*
- * Export a fake .TOC. since both modpost and depmod will complain otherwise.
- * Both modpost and depmod strip the leading . so we do the same here.
- */
-.section "__ksymtab_strings","a"
-__kstrtab_TOC.:
- .asciz "TOC."
-
-.section "___ksymtab+TOC.","a"
-/* This symbol name is important: it's used by modpost to find exported syms */
-.globl __ksymtab_TOC.
-__ksymtab_TOC.:
- .llong 0 /* .value */
- .llong __kstrtab_TOC.
-#endif /* ELFv2 */
-#endif /* MODULES */
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 9547381..d1f1b35 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -47,6 +47,11 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *me)
{
const Elf_Shdr *sect;
+ int rc;
+
+ rc = module_finalize_ftrace(me, sechdrs);
+ if (rc)
+ return rc;
/* Apply feature fixups */
sect = find_section(hdr, sechdrs, "__ftr_fixup");
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index c94d2e0..5a7a78f 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -181,15 +181,15 @@ static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val)
/* Set up a trampoline in the PLT to bounce us to the distant function */
static uint32_t do_plt_call(void *location,
Elf32_Addr val,
- Elf32_Shdr *sechdrs,
+ const Elf32_Shdr *sechdrs,
struct module *mod)
{
struct ppc_plt_entry *entry;
pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
/* Init, or core PLT? */
- if (location >= mod->module_core
- && location < mod->module_core + mod->core_size)
+ if (location >= mod->core_layout.base
+ && location < mod->core_layout.base + mod->core_layout.size)
entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
else
entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
@@ -294,11 +294,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
return -ENOEXEC;
}
}
+
+ return 0;
+}
+
#ifdef CONFIG_DYNAMIC_FTRACE
- module->arch.tramp =
- do_plt_call(module->module_core,
- (unsigned long)ftrace_caller,
- sechdrs, module);
-#endif
+int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs)
+{
+ module->arch.tramp = do_plt_call(module->core_layout.base,
+ (unsigned long)ftrace_caller,
+ sechdrs, module);
+ if (!module->arch.tramp)
+ return -ENOENT;
+
return 0;
}
+#endif
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 6838451..9ce9a25 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -31,6 +31,7 @@
#include <asm/code-patching.h>
#include <linux/sort.h>
#include <asm/setup.h>
+#include <asm/sections.h>
/* FIXME: We don't do .init separately. To do this, we'd need to have
a separate r2 value in the init and core section, and stub between
@@ -41,7 +42,6 @@
--RR. */
#if defined(_CALL_ELF) && _CALL_ELF == 2
-#define R2_STACK_OFFSET 24
/* An address is simply the address of the function. */
typedef unsigned long func_desc_t;
@@ -73,7 +73,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
}
#else
-#define R2_STACK_OFFSET 40
/* An address is address of the OPD entry, which contains address of fn. */
typedef struct ppc64_opd_entry func_desc_t;
@@ -96,6 +95,8 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
}
#endif
+#define STUB_MAGIC 0x73747562 /* stub */
+
/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
the kernel itself). But on PPC64, these need to be used for every
jump, actually, to reset r2 (TOC+0x8000). */
@@ -105,7 +106,8 @@ struct ppc64_stub_entry
* need 6 instructions on ABIv2 but we always allocate 7 so
* so we don't have to modify the trampoline load instruction. */
u32 jump[7];
- u32 unused;
+ /* Used by ftrace to identify stubs */
+ u32 magic;
/* Data for the above code */
func_desc_t funcdata;
};
@@ -139,70 +141,39 @@ static u32 ppc64_stub_insns[] = {
};
#ifdef CONFIG_DYNAMIC_FTRACE
-
-static u32 ppc64_stub_mask[] = {
- 0xffff0000,
- 0xffff0000,
- 0xffffffff,
- 0xffffffff,
-#if !defined(_CALL_ELF) || _CALL_ELF != 2
- 0xffffffff,
-#endif
- 0xffffffff,
- 0xffffffff
-};
-
-bool is_module_trampoline(u32 *p)
+int module_trampoline_target(struct module *mod, unsigned long addr,
+ unsigned long *target)
{
- unsigned int i;
- u32 insns[ARRAY_SIZE(ppc64_stub_insns)];
-
- BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask));
+ struct ppc64_stub_entry *stub;
+ func_desc_t funcdata;
+ u32 magic;
- if (probe_kernel_read(insns, p, sizeof(insns)))
+ if (!within_module_core(addr, mod)) {
+ pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name);
return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) {
- u32 insna = insns[i];
- u32 insnb = ppc64_stub_insns[i];
- u32 mask = ppc64_stub_mask[i];
-
- if ((insna & mask) != (insnb & mask))
- return false;
}
- return true;
-}
-
-int module_trampoline_target(struct module *mod, u32 *trampoline,
- unsigned long *target)
-{
- u32 buf[2];
- u16 upper, lower;
- long offset;
- void *toc_entry;
+ stub = (struct ppc64_stub_entry *)addr;
- if (probe_kernel_read(buf, trampoline, sizeof(buf)))
+ if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) {
+ pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name);
return -EFAULT;
+ }
- upper = buf[0] & 0xffff;
- lower = buf[1] & 0xffff;
-
- /* perform the addis/addi, both signed */
- offset = ((short)upper << 16) + (short)lower;
+ if (magic != STUB_MAGIC) {
+ pr_err("%s: bad magic for stub %lx for %s\n", __func__, addr, mod->name);
+ return -EFAULT;
+ }
- /*
- * Now get the address this trampoline jumps to. This
- * is always 32 bytes into our trampoline stub.
- */
- toc_entry = (void *)mod->arch.toc + offset + 32;
+ if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) {
+ pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name);
+ return -EFAULT;
+ }
- if (probe_kernel_read(target, toc_entry, sizeof(*target)))
- return -EFAULT;
+ *target = stub_func_addr(funcdata);
return 0;
}
-
#endif
/* Count how many different 24-bit relocations (different symbol,
@@ -326,7 +297,10 @@ static void dedotify_versions(struct modversion_info *vers,
}
}
-/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */
+/*
+ * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC.
+ * seem to be defined (value set later).
+ */
static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
{
unsigned int i;
@@ -334,8 +308,11 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
for (i = 1; i < numsyms; i++) {
if (syms[i].st_shndx == SHN_UNDEF) {
char *name = strtab + syms[i].st_name;
- if (name[0] == '.')
- memmove(name, name+1, strlen(name));
+ if (name[0] == '.') {
+ if (strcmp(name+1, "TOC.") == 0)
+ syms[i].st_shndx = SHN_ABS;
+ syms[i].st_name++;
+ }
}
}
}
@@ -351,7 +328,7 @@ static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs,
numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym);
for (i = 1; i < numsyms; i++) {
- if (syms[i].st_shndx == SHN_UNDEF
+ if (syms[i].st_shndx == SHN_ABS
&& strcmp(strtab + syms[i].st_name, "TOC.") == 0)
return &syms[i];
}
@@ -407,7 +384,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
gives the value maximum span in an instruction which uses a signed
offset) */
-static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
+static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me)
{
return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
}
@@ -420,7 +397,7 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
/* Patch stub to reference function and correct r2 value. */
-static inline int create_stub(Elf64_Shdr *sechdrs,
+static inline int create_stub(const Elf64_Shdr *sechdrs,
struct ppc64_stub_entry *entry,
unsigned long addr,
struct module *me)
@@ -441,12 +418,14 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
entry->jump[0] |= PPC_HA(reladdr);
entry->jump[1] |= PPC_LO(reladdr);
entry->funcdata = func_desc(addr);
+ entry->magic = STUB_MAGIC;
+
return 1;
}
/* Create stub to jump to function described in this OPD/ptr: we need the
stub to set up the TOC ptr (r2) for the function. */
-static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
+static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
unsigned long addr,
struct module *me)
{
@@ -470,17 +449,60 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
return (unsigned long)&stubs[i];
}
+#ifdef CC_USING_MPROFILE_KERNEL
+static bool is_early_mcount_callsite(u32 *instruction)
+{
+ /*
+ * Check if this is one of the -mprofile-kernel sequences.
+ */
+ if (instruction[-1] == PPC_INST_STD_LR &&
+ instruction[-2] == PPC_INST_MFLR)
+ return true;
+
+ if (instruction[-1] == PPC_INST_MFLR)
+ return true;
+
+ return false;
+}
+
+/*
+ * In case of _mcount calls, do not save the current callee's TOC (in r2) into
+ * the original caller's stack frame. If we did we would clobber the saved TOC
+ * value of the original caller.
+ */
+static void squash_toc_save_inst(const char *name, unsigned long addr)
+{
+ struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr;
+
+ /* Only for calls to _mcount */
+ if (strcmp("_mcount", name) != 0)
+ return;
+
+ stub->jump[2] = PPC_INST_NOP;
+}
+#else
+static void squash_toc_save_inst(const char *name, unsigned long addr) { }
+
+/* without -mprofile-kernel, mcount calls are never early */
+static bool is_early_mcount_callsite(u32 *instruction)
+{
+ return false;
+}
+#endif
+
/* We expect a noop next: if it is, replace it with instruction to
restore r2. */
static int restore_r2(u32 *instruction, struct module *me)
{
if (*instruction != PPC_INST_NOP) {
+ if (is_early_mcount_callsite(instruction - 1))
+ return 1;
pr_err("%s: Expect noop after relocate, got %08x\n",
me->name, *instruction);
return 0;
}
/* ld r2,R2_STACK_OFFSET(r1) */
- *instruction = 0xe8410000 | R2_STACK_OFFSET;
+ *instruction = PPC_INST_LD_TOC;
return 1;
}
@@ -605,6 +627,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
return -ENOENT;
if (!restore_r2((u32 *)location + 1, me))
return -ENOEXEC;
+
+ squash_toc_save_inst(strtab + sym->st_name, value);
} else
value += local_entry_offset(sym);
@@ -635,6 +659,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
*/
break;
+ case R_PPC64_ENTRY:
+ /*
+ * Optimize ELFv2 large code model entry point if
+ * the TOC is within 2GB range of current location.
+ */
+ value = my_r2(sechdrs, me) - (unsigned long)location;
+ if (value + 0x80008000 > 0xffffffff)
+ break;
+ /*
+ * Check for the large code model prolog sequence:
+ * ld r2, ...(r12)
+ * add r2, r2, r12
+ */
+ if ((((uint32_t *)location)[0] & ~0xfffc)
+ != 0xe84c0000)
+ break;
+ if (((uint32_t *)location)[1] != 0x7c426214)
+ break;
+ /*
+ * If found, replace it with:
+ * addis r2, r12, (.TOC.-func)@ha
+ * addi r2, r12, (.TOC.-func)@l
+ */
+ ((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
+ ((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
+ break;
+
case R_PPC64_REL16_HA:
/* Subtract location pointer */
value -= (unsigned long)location;
@@ -660,12 +711,84 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
}
}
+ return 0;
+}
+
#ifdef CONFIG_DYNAMIC_FTRACE
- me->arch.toc = my_r2(sechdrs, me);
- me->arch.tramp = stub_for_addr(sechdrs,
- (unsigned long)ftrace_caller,
- me);
+
+#ifdef CC_USING_MPROFILE_KERNEL
+
+#define PACATOC offsetof(struct paca_struct, kernel_toc)
+
+/*
+ * For mprofile-kernel we use a special stub for ftrace_caller() because we
+ * can't rely on r2 containing this module's TOC when we enter the stub.
+ *
+ * That can happen if the function calling us didn't need to use the toc. In
+ * that case it won't have setup r2, and the r2 value will be either the
+ * kernel's toc, or possibly another modules toc.
+ *
+ * To deal with that this stub uses the kernel toc, which is always accessible
+ * via the paca (in r13). The target (ftrace_caller()) is responsible for
+ * saving and restoring the toc before returning.
+ */
+static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
+{
+ struct ppc64_stub_entry *entry;
+ unsigned int i, num_stubs;
+ static u32 stub_insns[] = {
+ 0xe98d0000 | PACATOC, /* ld r12,PACATOC(r13) */
+ 0x3d8c0000, /* addis r12,r12,<high> */
+ 0x398c0000, /* addi r12,r12,<low> */
+ 0x7d8903a6, /* mtctr r12 */
+ 0x4e800420, /* bctr */
+ };
+ long reladdr;
+
+ num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry);
+
+ /* Find the next available stub entry */
+ entry = (void *)sechdrs[me->arch.stubs_section].sh_addr;
+ for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++);
+
+ if (i >= num_stubs) {
+ pr_err("%s: Unable to find a free slot for ftrace stub.\n", me->name);
+ return 0;
+ }
+
+ memcpy(entry->jump, stub_insns, sizeof(stub_insns));
+
+ /* Stub uses address relative to kernel toc (from the paca) */
+ reladdr = (unsigned long)ftrace_caller - kernel_toc_addr();
+ if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
+ pr_err("%s: Address of ftrace_caller out of range of kernel_toc.\n", me->name);
+ return 0;
+ }
+
+ entry->jump[1] |= PPC_HA(reladdr);
+ entry->jump[2] |= PPC_LO(reladdr);
+
+ /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */
+ entry->funcdata = func_desc((unsigned long)ftrace_caller);
+ entry->magic = STUB_MAGIC;
+
+ return (unsigned long)entry;
+}
+#else
+static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
+{
+ return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me);
+}
#endif
+int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
+{
+ mod->arch.toc = my_r2(sechdrs, mod);
+ mod->arch.tramp = create_ftrace_stub(sechdrs, mod);
+
+ if (!mod->arch.tramp)
+ return -ENOENT;
+
return 0;
}
+#endif
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 98ba106..0cab9e8 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/kmsg_dump.h>
+#include <linux/pagemap.h>
#include <linux/pstore.h>
#include <linux/zlib.h>
#include <asm/uaccess.h>
@@ -733,24 +734,10 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
{
- int size;
-
if (ppc_md.nvram_size == NULL)
return -ENODEV;
- size = ppc_md.nvram_size();
-
- switch (origin) {
- case 1:
- offset += file->f_pos;
- break;
- case 2:
- offset += size;
- break;
- }
- if (offset < 0)
- return -EINVAL;
- file->f_pos = offset;
- return file->f_pos;
+ return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
+ ppc_md.nvram_size());
}
@@ -1065,7 +1052,7 @@ loff_t __init nvram_create_partition(const char *name, int sig,
/* Create our OS partition */
new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
if (!new_part) {
- pr_err("nvram_create_os_partition: kmalloc failed\n");
+ pr_err("%s: kmalloc failed\n", __func__);
return -ENOMEM;
}
@@ -1077,8 +1064,8 @@ loff_t __init nvram_create_partition(const char *name, int sig,
rc = nvram_write_header(new_part);
if (rc <= 0) {
- pr_err("nvram_create_os_partition: nvram_write_header "
- "failed (%d)\n", rc);
+ pr_err("%s: nvram_write_header failed (%d)\n", __func__, rc);
+ kfree(new_part);
return rc;
}
list_add_tail(&new_part->partition, &free_part->partition);
@@ -1090,8 +1077,8 @@ loff_t __init nvram_create_partition(const char *name, int sig,
free_part->header.checksum = nvram_checksum(&free_part->header);
rc = nvram_write_header(free_part);
if (rc <= 0) {
- pr_err("nvram_create_os_partition: nvram_write_header "
- "failed (%d)\n", rc);
+ pr_err("%s: nvram_write_header failed (%d)\n",
+ __func__, rc);
return rc;
}
} else {
@@ -1105,11 +1092,12 @@ loff_t __init nvram_create_partition(const char *name, int sig,
tmp_index += NVRAM_BLOCK_LEN) {
rc = ppc_md.nvram_write(nv_init_vals, NVRAM_BLOCK_LEN, &tmp_index);
if (rc <= 0) {
- pr_err("nvram_create_partition: nvram_write failed (%d)\n", rc);
+ pr_err("%s: nvram_write failed (%d)\n",
+ __func__, rc);
return rc;
}
}
-
+
return new_part->index + NVRAM_HEADER_LEN;
}
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5a23b69..93dae29 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,10 +17,6 @@
#include <asm/pgtable.h>
#include <asm/kexec.h>
-/* This symbol is provided by the linker - let it fill in the paca
- * field correctly */
-extern unsigned long __toc_start;
-
#ifdef CONFIG_PPC_BOOK3S
/*
@@ -149,11 +145,6 @@ EXPORT_SYMBOL(paca);
void __init initialise_paca(struct paca_struct *new_paca, int cpu)
{
- /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
- * of the TOC can be addressed using a single machine instruction.
- */
- unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
-
#ifdef CONFIG_PPC_BOOK3S
new_paca->lppaca_ptr = new_lppaca(cpu);
#else
@@ -161,7 +152,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
#endif
new_paca->lock_token = 0x8000;
new_paca->paca_index = cpu;
- new_paca->kernel_toc = kernel_toc;
+ new_paca->kernel_toc = kernel_toc_addr();
new_paca->kernelbase = (unsigned long) _stext;
/* Only set MSR:IR/DR when MMU is initialized */
new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR);
@@ -204,14 +195,19 @@ static int __initdata paca_size;
void __init allocate_pacas(void)
{
- int cpu, limit;
+ u64 limit;
+ int cpu;
+ limit = ppc64_rma_size;
+
+#ifdef CONFIG_PPC_BOOK3S_64
/*
* We can't take SLB misses on the paca, and we want to access them
* in real mode, so allocate them within the RMA and also within
* the first segment.
*/
- limit = min(0x10000000ULL, ppc64_rma_size);
+ limit = min(0x10000000ULL, limit);
+#endif
paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 7587b2a..0f7a60f 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -100,6 +100,7 @@ void pcibios_free_controller(struct pci_controller *phb)
if (phb->is_dynamic)
kfree(phb);
}
+EXPORT_SYMBOL_GPL(pcibios_free_controller);
/*
* The function is used to return the minimal alignment
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 7f9ed0c..59c4361 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -55,7 +55,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus)
pr_debug("PCI: Removing devices on bus %04x:%02x\n",
pci_domain_nr(bus), bus->number);
- list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+ list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
pr_debug(" Removing %s...\n", pci_name(dev));
pci_stop_and_remove_bus_device(dev);
}
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index b3b4df9..38102cb 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
#ifdef CONFIG_PCI_IOV
static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
struct pci_dev *pdev,
+ int vf_index,
int busno, int devfn)
{
struct pci_dn *pdn;
@@ -158,6 +159,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
pdn->busno = busno;
pdn->devfn = devfn;
#ifdef CONFIG_PPC_POWERNV
+ pdn->vf_index = vf_index;
pdn->pe_number = IODA_INVALID_PE;
#endif
INIT_LIST_HEAD(&pdn->child_list);
@@ -179,6 +181,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
{
#ifdef CONFIG_PCI_IOV
struct pci_dn *parent, *pdn;
+ struct eeh_dev *edev;
int i;
/* Only support IOV for now */
@@ -196,7 +199,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
return NULL;
for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
- pdn = add_one_dev_pci_data(parent, NULL,
+ pdn = add_one_dev_pci_data(parent, NULL, i,
pci_iov_virtfn_bus(pdev, i),
pci_iov_virtfn_devfn(pdev, i));
if (!pdn) {
@@ -204,6 +207,12 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
__func__, i);
return NULL;
}
+
+ /* Create the EEH device for the VF */
+ eeh_dev_init(pdn, pci_bus_to_host(pdev->bus));
+ edev = pdn_to_eeh_dev(pdn);
+ BUG_ON(!edev);
+ edev->physfn = pdev;
}
#endif /* CONFIG_PCI_IOV */
@@ -215,6 +224,7 @@ void remove_dev_pci_data(struct pci_dev *pdev)
#ifdef CONFIG_PCI_IOV
struct pci_dn *parent;
struct pci_dn *pdn, *tmp;
+ struct eeh_dev *edev;
int i;
/*
@@ -256,6 +266,13 @@ void remove_dev_pci_data(struct pci_dev *pdev)
pdn->devfn != pci_iov_virtfn_devfn(pdev, i))
continue;
+ /* Release EEH device for the VF */
+ edev = pdn_to_eeh_dev(pdn);
+ if (edev) {
+ pdn->edev = NULL;
+ kfree(edev);
+ }
+
if (!list_empty(&pdn->list))
list_del(&pdn->list);
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 2e710c1..526ac67 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -187,9 +187,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pci_device_add(dev, bus);
- /* Setup MSI caps & disable MSI/MSI-X interrupts */
- pci_msi_setup_pci_dev(dev);
-
return dev;
}
EXPORT_SYMBOL(of_create_pci_dev);
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 202963e..9f01e28 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -6,7 +6,9 @@
#include <asm/cacheflush.h>
#include <asm/epapr_hcalls.h>
+#ifdef CONFIG_PPC64
EXPORT_SYMBOL(flush_dcache_range);
+#endif
EXPORT_SYMBOL(flush_icache_range);
EXPORT_SYMBOL(empty_zero_page);
@@ -19,25 +21,15 @@ EXPORT_SYMBOL(_mcount);
#endif
#ifdef CONFIG_PPC_FPU
-EXPORT_SYMBOL(giveup_fpu);
EXPORT_SYMBOL(load_fp_state);
EXPORT_SYMBOL(store_fp_state);
#endif
#ifdef CONFIG_ALTIVEC
-EXPORT_SYMBOL(giveup_altivec);
EXPORT_SYMBOL(load_vr_state);
EXPORT_SYMBOL(store_vr_state);
#endif
-#ifdef CONFIG_VSX
-EXPORT_SYMBOL_GPL(__giveup_vsx);
-#endif
-
-#ifdef CONFIG_SPE
-EXPORT_SYMBOL(giveup_spe);
-#endif
-
#ifdef CONFIG_EPAPR_PARAVIRT
EXPORT_SYMBOL(epapr_hypercall_start);
#endif
diff --git a/arch/powerpc/kernel/ppc_ksyms_32.c b/arch/powerpc/kernel/ppc_ksyms_32.c
index 30ddd8a..2bfaafe 100644
--- a/arch/powerpc/kernel/ppc_ksyms_32.c
+++ b/arch/powerpc/kernel/ppc_ksyms_32.c
@@ -10,7 +10,6 @@
#include <asm/pgtable.h>
#include <asm/dcr.h>
-EXPORT_SYMBOL(clear_pages);
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
EXPORT_SYMBOL(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 75b6676..612df30 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -67,15 +67,8 @@
extern unsigned long _get_SP(void);
-#ifndef CONFIG_SMP
-struct task_struct *last_task_used_math = NULL;
-struct task_struct *last_task_used_altivec = NULL;
-struct task_struct *last_task_used_vsx = NULL;
-struct task_struct *last_task_used_spe = NULL;
-#endif
-
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-void giveup_fpu_maybe_transactional(struct task_struct *tsk)
+static void check_if_tm_restore_required(struct task_struct *tsk)
{
/*
* If we are saving the current thread's registers, and the
@@ -89,34 +82,77 @@ void giveup_fpu_maybe_transactional(struct task_struct *tsk)
tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr;
set_thread_flag(TIF_RESTORE_TM);
}
+}
+#else
+static inline void check_if_tm_restore_required(struct task_struct *tsk) { }
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
- giveup_fpu(tsk);
+bool strict_msr_control;
+EXPORT_SYMBOL(strict_msr_control);
+
+static int __init enable_strict_msr_control(char *str)
+{
+ strict_msr_control = true;
+ pr_info("Enabling strict facility control\n");
+
+ return 0;
}
+early_param("ppc_strict_facility_enable", enable_strict_msr_control);
-void giveup_altivec_maybe_transactional(struct task_struct *tsk)
+void msr_check_and_set(unsigned long bits)
{
- /*
- * If we are saving the current thread's registers, and the
- * thread is in a transactional state, set the TIF_RESTORE_TM
- * bit so that we know to restore the registers before
- * returning to userspace.
- */
- if (tsk == current && tsk->thread.regs &&
- MSR_TM_ACTIVE(tsk->thread.regs->msr) &&
- !test_thread_flag(TIF_RESTORE_TM)) {
- tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr;
- set_thread_flag(TIF_RESTORE_TM);
- }
+ unsigned long oldmsr = mfmsr();
+ unsigned long newmsr;
+
+ newmsr = oldmsr | bits;
+
+#ifdef CONFIG_VSX
+ if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP))
+ newmsr |= MSR_VSX;
+#endif
- giveup_altivec(tsk);
+ if (oldmsr != newmsr)
+ mtmsr_isync(newmsr);
}
-#else
-#define giveup_fpu_maybe_transactional(tsk) giveup_fpu(tsk)
-#define giveup_altivec_maybe_transactional(tsk) giveup_altivec(tsk)
-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+void __msr_check_and_clear(unsigned long bits)
+{
+ unsigned long oldmsr = mfmsr();
+ unsigned long newmsr;
+
+ newmsr = oldmsr & ~bits;
+
+#ifdef CONFIG_VSX
+ if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP))
+ newmsr &= ~MSR_VSX;
+#endif
+
+ if (oldmsr != newmsr)
+ mtmsr_isync(newmsr);
+}
+EXPORT_SYMBOL(__msr_check_and_clear);
#ifdef CONFIG_PPC_FPU
+void __giveup_fpu(struct task_struct *tsk)
+{
+ save_fpu(tsk);
+ tsk->thread.regs->msr &= ~MSR_FP;
+#ifdef CONFIG_VSX
+ if (cpu_has_feature(CPU_FTR_VSX))
+ tsk->thread.regs->msr &= ~MSR_VSX;
+#endif
+}
+
+void giveup_fpu(struct task_struct *tsk)
+{
+ check_if_tm_restore_required(tsk);
+
+ msr_check_and_set(MSR_FP);
+ __giveup_fpu(tsk);
+ msr_check_and_clear(MSR_FP);
+}
+EXPORT_SYMBOL(giveup_fpu);
+
/*
* Make sure the floating-point register state in the
* the thread_struct is up to date for task tsk.
@@ -134,52 +170,79 @@ void flush_fp_to_thread(struct task_struct *tsk)
*/
preempt_disable();
if (tsk->thread.regs->msr & MSR_FP) {
-#ifdef CONFIG_SMP
/*
* This should only ever be called for current or
* for a stopped child process. Since we save away
- * the FP register state on context switch on SMP,
+ * the FP register state on context switch,
* there is something wrong if a stopped child appears
* to still have its FP state in the CPU registers.
*/
BUG_ON(tsk != current);
-#endif
- giveup_fpu_maybe_transactional(tsk);
+ giveup_fpu(tsk);
}
preempt_enable();
}
}
EXPORT_SYMBOL_GPL(flush_fp_to_thread);
-#endif /* CONFIG_PPC_FPU */
void enable_kernel_fp(void)
{
WARN_ON(preemptible());
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu_maybe_transactional(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu_maybe_transactional(last_task_used_math);
-#endif /* CONFIG_SMP */
+ msr_check_and_set(MSR_FP);
+
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP)) {
+ check_if_tm_restore_required(current);
+ __giveup_fpu(current);
+ }
}
EXPORT_SYMBOL(enable_kernel_fp);
+static int restore_fp(struct task_struct *tsk) {
+ if (tsk->thread.load_fp) {
+ load_fp_state(&current->thread.fp_state);
+ current->thread.load_fp++;
+ return 1;
+ }
+ return 0;
+}
+#else
+static int restore_fp(struct task_struct *tsk) { return 0; }
+#endif /* CONFIG_PPC_FPU */
+
#ifdef CONFIG_ALTIVEC
+#define loadvec(thr) ((thr).load_vec)
+
+static void __giveup_altivec(struct task_struct *tsk)
+{
+ save_altivec(tsk);
+ tsk->thread.regs->msr &= ~MSR_VEC;
+#ifdef CONFIG_VSX
+ if (cpu_has_feature(CPU_FTR_VSX))
+ tsk->thread.regs->msr &= ~MSR_VSX;
+#endif
+}
+
+void giveup_altivec(struct task_struct *tsk)
+{
+ check_if_tm_restore_required(tsk);
+
+ msr_check_and_set(MSR_VEC);
+ __giveup_altivec(tsk);
+ msr_check_and_clear(MSR_VEC);
+}
+EXPORT_SYMBOL(giveup_altivec);
+
void enable_kernel_altivec(void)
{
WARN_ON(preemptible());
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
- giveup_altivec_maybe_transactional(current);
- else
- giveup_altivec_notask();
-#else
- giveup_altivec_maybe_transactional(last_task_used_altivec);
-#endif /* CONFIG_SMP */
+ msr_check_and_set(MSR_VEC);
+
+ if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) {
+ check_if_tm_restore_required(current);
+ __giveup_altivec(current);
+ }
}
EXPORT_SYMBOL(enable_kernel_altivec);
@@ -192,71 +255,122 @@ void flush_altivec_to_thread(struct task_struct *tsk)
if (tsk->thread.regs) {
preempt_disable();
if (tsk->thread.regs->msr & MSR_VEC) {
-#ifdef CONFIG_SMP
BUG_ON(tsk != current);
-#endif
- giveup_altivec_maybe_transactional(tsk);
+ giveup_altivec(tsk);
}
preempt_enable();
}
}
EXPORT_SYMBOL_GPL(flush_altivec_to_thread);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_VSX
-void enable_kernel_vsx(void)
+static int restore_altivec(struct task_struct *tsk)
{
- WARN_ON(preemptible());
+ if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) {
+ load_vr_state(&tsk->thread.vr_state);
+ tsk->thread.used_vr = 1;
+ tsk->thread.load_vec++;
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_VSX))
- giveup_vsx(current);
- else
- giveup_vsx(NULL); /* just enable vsx for kernel - force */
+ return 1;
+ }
+ return 0;
+}
#else
- giveup_vsx(last_task_used_vsx);
-#endif /* CONFIG_SMP */
+#define loadvec(thr) 0
+static inline int restore_altivec(struct task_struct *tsk) { return 0; }
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_VSX
+static void __giveup_vsx(struct task_struct *tsk)
+{
+ if (tsk->thread.regs->msr & MSR_FP)
+ __giveup_fpu(tsk);
+ if (tsk->thread.regs->msr & MSR_VEC)
+ __giveup_altivec(tsk);
+ tsk->thread.regs->msr &= ~MSR_VSX;
}
-EXPORT_SYMBOL(enable_kernel_vsx);
-void giveup_vsx(struct task_struct *tsk)
+static void giveup_vsx(struct task_struct *tsk)
{
- giveup_fpu_maybe_transactional(tsk);
- giveup_altivec_maybe_transactional(tsk);
+ check_if_tm_restore_required(tsk);
+
+ msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX);
__giveup_vsx(tsk);
+ msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
+}
+
+static void save_vsx(struct task_struct *tsk)
+{
+ if (tsk->thread.regs->msr & MSR_FP)
+ save_fpu(tsk);
+ if (tsk->thread.regs->msr & MSR_VEC)
+ save_altivec(tsk);
+}
+
+void enable_kernel_vsx(void)
+{
+ WARN_ON(preemptible());
+
+ msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX);
+
+ if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) {
+ check_if_tm_restore_required(current);
+ if (current->thread.regs->msr & MSR_FP)
+ __giveup_fpu(current);
+ if (current->thread.regs->msr & MSR_VEC)
+ __giveup_altivec(current);
+ __giveup_vsx(current);
+ }
}
-EXPORT_SYMBOL(giveup_vsx);
+EXPORT_SYMBOL(enable_kernel_vsx);
void flush_vsx_to_thread(struct task_struct *tsk)
{
if (tsk->thread.regs) {
preempt_disable();
if (tsk->thread.regs->msr & MSR_VSX) {
-#ifdef CONFIG_SMP
BUG_ON(tsk != current);
-#endif
giveup_vsx(tsk);
}
preempt_enable();
}
}
EXPORT_SYMBOL_GPL(flush_vsx_to_thread);
+
+static int restore_vsx(struct task_struct *tsk)
+{
+ if (cpu_has_feature(CPU_FTR_VSX)) {
+ tsk->thread.used_vsr = 1;
+ return 1;
+ }
+
+ return 0;
+}
+#else
+static inline int restore_vsx(struct task_struct *tsk) { return 0; }
+static inline void save_vsx(struct task_struct *tsk) { }
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
+void giveup_spe(struct task_struct *tsk)
+{
+ check_if_tm_restore_required(tsk);
+
+ msr_check_and_set(MSR_SPE);
+ __giveup_spe(tsk);
+ msr_check_and_clear(MSR_SPE);
+}
+EXPORT_SYMBOL(giveup_spe);
void enable_kernel_spe(void)
{
WARN_ON(preemptible());
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
- giveup_spe(current);
- else
- giveup_spe(NULL); /* just enable SPE for kernel - force */
-#else
- giveup_spe(last_task_used_spe);
-#endif /* __SMP __ */
+ msr_check_and_set(MSR_SPE);
+
+ if (current->thread.regs && (current->thread.regs->msr & MSR_SPE)) {
+ check_if_tm_restore_required(current);
+ __giveup_spe(current);
+ }
}
EXPORT_SYMBOL(enable_kernel_spe);
@@ -265,9 +379,7 @@ void flush_spe_to_thread(struct task_struct *tsk)
if (tsk->thread.regs) {
preempt_disable();
if (tsk->thread.regs->msr & MSR_SPE) {
-#ifdef CONFIG_SMP
BUG_ON(tsk != current);
-#endif
tsk->thread.spefscr = mfspr(SPRN_SPEFSCR);
giveup_spe(tsk);
}
@@ -276,31 +388,145 @@ void flush_spe_to_thread(struct task_struct *tsk)
}
#endif /* CONFIG_SPE */
-#ifndef CONFIG_SMP
-/*
- * If we are doing lazy switching of CPU state (FP, altivec or SPE),
- * and the current task has some state, discard it.
- */
-void discard_lazy_cpu_state(void)
+static unsigned long msr_all_available;
+
+static int __init init_msr_all_available(void)
{
- preempt_disable();
- if (last_task_used_math == current)
- last_task_used_math = NULL;
+#ifdef CONFIG_PPC_FPU
+ msr_all_available |= MSR_FP;
+#endif
#ifdef CONFIG_ALTIVEC
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#endif /* CONFIG_ALTIVEC */
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ msr_all_available |= MSR_VEC;
+#endif
#ifdef CONFIG_VSX
- if (last_task_used_vsx == current)
- last_task_used_vsx = NULL;
-#endif /* CONFIG_VSX */
+ if (cpu_has_feature(CPU_FTR_VSX))
+ msr_all_available |= MSR_VSX;
+#endif
#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
+ if (cpu_has_feature(CPU_FTR_SPE))
+ msr_all_available |= MSR_SPE;
#endif
- preempt_enable();
+
+ return 0;
}
-#endif /* CONFIG_SMP */
+early_initcall(init_msr_all_available);
+
+void giveup_all(struct task_struct *tsk)
+{
+ unsigned long usermsr;
+
+ if (!tsk->thread.regs)
+ return;
+
+ usermsr = tsk->thread.regs->msr;
+
+ if ((usermsr & msr_all_available) == 0)
+ return;
+
+ msr_check_and_set(msr_all_available);
+
+#ifdef CONFIG_PPC_FPU
+ if (usermsr & MSR_FP)
+ __giveup_fpu(tsk);
+#endif
+#ifdef CONFIG_ALTIVEC
+ if (usermsr & MSR_VEC)
+ __giveup_altivec(tsk);
+#endif
+#ifdef CONFIG_VSX
+ if (usermsr & MSR_VSX)
+ __giveup_vsx(tsk);
+#endif
+#ifdef CONFIG_SPE
+ if (usermsr & MSR_SPE)
+ __giveup_spe(tsk);
+#endif
+
+ msr_check_and_clear(msr_all_available);
+}
+EXPORT_SYMBOL(giveup_all);
+
+void restore_math(struct pt_regs *regs)
+{
+ unsigned long msr;
+
+ if (!current->thread.load_fp && !loadvec(current->thread))
+ return;
+
+ msr = regs->msr;
+ msr_check_and_set(msr_all_available);
+
+ /*
+ * Only reload if the bit is not set in the user MSR, the bit BEING set
+ * indicates that the registers are hot
+ */
+ if ((!(msr & MSR_FP)) && restore_fp(current))
+ msr |= MSR_FP | current->thread.fpexc_mode;
+
+ if ((!(msr & MSR_VEC)) && restore_altivec(current))
+ msr |= MSR_VEC;
+
+ if ((msr & (MSR_FP | MSR_VEC)) == (MSR_FP | MSR_VEC) &&
+ restore_vsx(current)) {
+ msr |= MSR_VSX;
+ }
+
+ msr_check_and_clear(msr_all_available);
+
+ regs->msr = msr;
+}
+
+void save_all(struct task_struct *tsk)
+{
+ unsigned long usermsr;
+
+ if (!tsk->thread.regs)
+ return;
+
+ usermsr = tsk->thread.regs->msr;
+
+ if ((usermsr & msr_all_available) == 0)
+ return;
+
+ msr_check_and_set(msr_all_available);
+
+ /*
+ * Saving the way the register space is in hardware, save_vsx boils
+ * down to a save_fpu() and save_altivec()
+ */
+ if (usermsr & MSR_VSX) {
+ save_vsx(tsk);
+ } else {
+ if (usermsr & MSR_FP)
+ save_fpu(tsk);
+
+ if (usermsr & MSR_VEC)
+ save_altivec(tsk);
+ }
+
+ if (usermsr & MSR_SPE)
+ __giveup_spe(tsk);
+
+ msr_check_and_clear(msr_all_available);
+}
+
+void flush_all_to_thread(struct task_struct *tsk)
+{
+ if (tsk->thread.regs) {
+ preempt_disable();
+ BUG_ON(tsk != current);
+ save_all(tsk);
+
+#ifdef CONFIG_SPE
+ if (tsk->thread.regs->msr & MSR_SPE)
+ tsk->thread.spefscr = mfspr(SPRN_SPEFSCR);
+#endif
+
+ preempt_enable();
+ }
+}
+EXPORT_SYMBOL(flush_all_to_thread);
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
void do_send_trap(struct pt_regs *regs, unsigned long address,
@@ -551,6 +777,24 @@ static void tm_reclaim_thread(struct thread_struct *thr,
msr_diff &= MSR_FP | MSR_VEC | MSR_VSX | MSR_FE0 | MSR_FE1;
}
+ /*
+ * Use the current MSR TM suspended bit to track if we have
+ * checkpointed state outstanding.
+ * On signal delivery, we'd normally reclaim the checkpointed
+ * state to obtain stack pointer (see:get_tm_stackpointer()).
+ * This will then directly return to userspace without going
+ * through __switch_to(). However, if the stack frame is bad,
+ * we need to exit this thread which calls __switch_to() which
+ * will again attempt to reclaim the already saved tm state.
+ * Hence we need to check that we've not already reclaimed
+ * this state.
+ * We do this using the current MSR, rather tracking it in
+ * some specific thread_struct bit, as it has the additional
+ * benifit of checking for a potential TM bad thing exception.
+ */
+ if (!MSR_TM_SUSPENDED(mfmsr()))
+ return;
+
tm_reclaim(thr, thr->regs->msr, cause);
/* Having done the reclaim, we now have the checkpointed
@@ -725,15 +969,9 @@ void restore_tm_state(struct pt_regs *regs)
msr_diff = current->thread.ckpt_regs.msr & ~regs->msr;
msr_diff &= MSR_FP | MSR_VEC | MSR_VSX;
- if (msr_diff & MSR_FP) {
- fp_enable();
- load_fp_state(&current->thread.fp_state);
- regs->msr |= current->thread.fpexc_mode;
- }
- if (msr_diff & MSR_VEC) {
- vec_enable();
- load_vr_state(&current->thread.vr_state);
- }
+
+ restore_math(regs);
+
regs->msr |= msr_diff;
}
@@ -742,112 +980,87 @@ void restore_tm_state(struct pt_regs *regs)
#define __switch_to_tm(prev)
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
-struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *new)
+static inline void save_sprs(struct thread_struct *t)
{
- struct thread_struct *new_thread, *old_thread;
- struct task_struct *last;
-#ifdef CONFIG_PPC_BOOK3S_64
- struct ppc64_tlb_batch *batch;
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(cpu_has_feature(CPU_FTR_ALTIVEC)))
+ t->vrsave = mfspr(SPRN_VRSAVE);
#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+ if (cpu_has_feature(CPU_FTR_DSCR))
+ t->dscr = mfspr(SPRN_DSCR);
- WARN_ON(!irqs_disabled());
+ if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
+ t->bescr = mfspr(SPRN_BESCR);
+ t->ebbhr = mfspr(SPRN_EBBHR);
+ t->ebbrr = mfspr(SPRN_EBBRR);
- /* Back up the TAR and DSCR across context switches.
- * Note that the TAR is not available for use in the kernel. (To
- * provide this, the TAR should be backed up/restored on exception
- * entry/exit instead, and be in pt_regs. FIXME, this should be in
- * pt_regs anyway (for debug).)
- * Save the TAR and DSCR here before we do treclaim/trecheckpoint as
- * these will change them.
- */
- save_early_sprs(&prev->thread);
+ t->fscr = mfspr(SPRN_FSCR);
- __switch_to_tm(prev);
+ /*
+ * Note that the TAR is not available for use in the kernel.
+ * (To provide this, the TAR should be backed up/restored on
+ * exception entry/exit instead, and be in pt_regs. FIXME,
+ * this should be in pt_regs anyway (for debug).)
+ */
+ t->tar = mfspr(SPRN_TAR);
+ }
+#endif
+}
-#ifdef CONFIG_SMP
- /* avoid complexity of lazy save/restore of fpu
- * by just saving it every time we switch out if
- * this task used the fpu during the last quantum.
- *
- * If it tries to use the fpu again, it'll trap and
- * reload its fp regs. So we don't have to do a restore
- * every switch, just a save.
- * -- Cort
- */
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
- giveup_fpu(prev);
+static inline void restore_sprs(struct thread_struct *old_thread,
+ struct thread_struct *new_thread)
+{
#ifdef CONFIG_ALTIVEC
- /*
- * If the previous thread used altivec in the last quantum
- * (thus changing altivec regs) then save them.
- * We used to check the VRSAVE register but not all apps
- * set it, so we don't rely on it now (and in fact we need
- * to save & restore VSCR even if VRSAVE == 0). -- paulus
- *
- * On SMP we always save/restore altivec regs just to avoid the
- * complexity of changing processors.
- * -- Cort
- */
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
- giveup_altivec(prev);
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_VSX
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_VSX))
- /* VMX and FPU registers are already save here */
- __giveup_vsx(prev);
-#endif /* CONFIG_VSX */
-#ifdef CONFIG_SPE
- /*
- * If the previous thread used spe in the last quantum
- * (thus changing spe regs) then save them.
- *
- * On SMP we always save/restore spe regs just to avoid the
- * complexity of changing processors.
- */
- if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
- giveup_spe(prev);
-#endif /* CONFIG_SPE */
+ if (cpu_has_feature(CPU_FTR_ALTIVEC) &&
+ old_thread->vrsave != new_thread->vrsave)
+ mtspr(SPRN_VRSAVE, new_thread->vrsave);
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+ if (cpu_has_feature(CPU_FTR_DSCR)) {
+ u64 dscr = get_paca()->dscr_default;
+ u64 fscr = old_thread->fscr & ~FSCR_DSCR;
-#else /* CONFIG_SMP */
-#ifdef CONFIG_ALTIVEC
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_altivec -- Cort
- */
- if (new->thread.regs && last_task_used_altivec == new)
- new->thread.regs->msr |= MSR_VEC;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_VSX
- if (new->thread.regs && last_task_used_vsx == new)
- new->thread.regs->msr |= MSR_VSX;
-#endif /* CONFIG_VSX */
-#ifdef CONFIG_SPE
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_spe
- */
- if (new->thread.regs && last_task_used_spe == new)
- new->thread.regs->msr |= MSR_SPE;
-#endif /* CONFIG_SPE */
+ if (new_thread->dscr_inherit) {
+ dscr = new_thread->dscr;
+ fscr |= FSCR_DSCR;
+ }
-#endif /* CONFIG_SMP */
+ if (old_thread->dscr != dscr)
+ mtspr(SPRN_DSCR, dscr);
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
- switch_booke_debug_regs(&new->thread.debug);
-#else
-/*
- * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
- * schedule DABR
- */
-#ifndef CONFIG_HAVE_HW_BREAKPOINT
- if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk), &new->thread.hw_brk)))
- __set_breakpoint(&new->thread.hw_brk);
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+ if (old_thread->fscr != fscr)
+ mtspr(SPRN_FSCR, fscr);
+ }
+
+ if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
+ if (old_thread->bescr != new_thread->bescr)
+ mtspr(SPRN_BESCR, new_thread->bescr);
+ if (old_thread->ebbhr != new_thread->ebbhr)
+ mtspr(SPRN_EBBHR, new_thread->ebbhr);
+ if (old_thread->ebbrr != new_thread->ebbrr)
+ mtspr(SPRN_EBBRR, new_thread->ebbrr);
+
+ if (old_thread->tar != new_thread->tar)
+ mtspr(SPRN_TAR, new_thread->tar);
+ }
#endif
+}
+struct task_struct *__switch_to(struct task_struct *prev,
+ struct task_struct *new)
+{
+ struct thread_struct *new_thread, *old_thread;
+ struct task_struct *last;
+#ifdef CONFIG_PPC_BOOK3S_64
+ struct ppc64_tlb_batch *batch;
+#endif
new_thread = &new->thread;
old_thread = &current->thread;
+ WARN_ON(!irqs_disabled());
+
#ifdef CONFIG_PPC64
/*
* Collect processor utilization data per process
@@ -872,6 +1085,30 @@ struct task_struct *__switch_to(struct task_struct *prev,
}
#endif /* CONFIG_PPC_BOOK3S_64 */
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ switch_booke_debug_regs(&new->thread.debug);
+#else
+/*
+ * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
+ * schedule DABR
+ */
+#ifndef CONFIG_HAVE_HW_BREAKPOINT
+ if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk), &new->thread.hw_brk)))
+ __set_breakpoint(&new->thread.hw_brk);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif
+
+ /*
+ * We need to save SPRs before treclaim/trecheckpoint as these will
+ * change a number of them.
+ */
+ save_sprs(&prev->thread);
+
+ __switch_to_tm(prev);
+
+ /* Save FPU, Altivec, VSX and SPE state */
+ giveup_all(prev);
+
/*
* We can't take a PMU exception inside _switch() since there is a
* window where the kernel stack SLB and the kernel stack are out
@@ -881,6 +1118,15 @@ struct task_struct *__switch_to(struct task_struct *prev,
tm_recheckpoint_new_task(new);
+ /*
+ * Call restore_sprs() before calling _switch(). If we move it after
+ * _switch() then we miss out on calling it for new tasks. The reason
+ * for this is we manually create a stack frame for new tasks that
+ * directly returns through ret_from_fork() or
+ * ret_from_kernel_thread(). See copy_thread() for details.
+ */
+ restore_sprs(old_thread, new_thread);
+
last = _switch(old_thread, new_thread);
#ifdef CONFIG_PPC_BOOK3S_64
@@ -889,6 +1135,10 @@ struct task_struct *__switch_to(struct task_struct *prev,
batch = this_cpu_ptr(&ppc64_tlb_batch);
batch->active = 1;
}
+
+ if (current_thread_info()->task->thread.regs)
+ restore_math(current_thread_info()->task->thread.regs);
+
#endif /* CONFIG_PPC_BOOK3S_64 */
return last;
@@ -934,10 +1184,12 @@ static void show_instructions(struct pt_regs *regs)
printk("\n");
}
-static struct regbit {
+struct regbit {
unsigned long bit;
const char *name;
-} msr_bits[] = {
+};
+
+static struct regbit msr_bits[] = {
#if defined(CONFIG_PPC64) && !defined(CONFIG_BOOKE)
{MSR_SF, "SF"},
{MSR_HV, "HV"},
@@ -967,16 +1219,49 @@ static struct regbit {
{0, NULL}
};
-static void printbits(unsigned long val, struct regbit *bits)
+static void print_bits(unsigned long val, struct regbit *bits, const char *sep)
{
- const char *sep = "";
+ const char *s = "";
- printk("<");
for (; bits->bit; ++bits)
if (val & bits->bit) {
- printk("%s%s", sep, bits->name);
- sep = ",";
+ printk("%s%s", s, bits->name);
+ s = sep;
}
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+static struct regbit msr_tm_bits[] = {
+ {MSR_TS_T, "T"},
+ {MSR_TS_S, "S"},
+ {MSR_TM, "E"},
+ {0, NULL}
+};
+
+static void print_tm_bits(unsigned long val)
+{
+/*
+ * This only prints something if at least one of the TM bit is set.
+ * Inside the TM[], the output means:
+ * E: Enabled (bit 32)
+ * S: Suspended (bit 33)
+ * T: Transactional (bit 34)
+ */
+ if (val & (MSR_TM | MSR_TS_S | MSR_TS_T)) {
+ printk(",TM[");
+ print_bits(val, msr_tm_bits, "");
+ printk("]");
+ }
+}
+#else
+static void print_tm_bits(unsigned long val) {}
+#endif
+
+static void print_msr_bits(unsigned long val)
+{
+ printk("<");
+ print_bits(val, msr_bits, ",");
+ print_tm_bits(val);
printk(">");
}
@@ -1001,7 +1286,7 @@ void show_regs(struct pt_regs * regs)
printk("REGS: %p TRAP: %04lx %s (%s)\n",
regs, regs->trap, print_tainted(), init_utsname()->release);
printk("MSR: "REG" ", regs->msr);
- printbits(regs->msr, msr_bits);
+ print_msr_bits(regs->msr);
printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
trap = TRAP(regs);
if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
@@ -1043,13 +1328,10 @@ void show_regs(struct pt_regs * regs)
void exit_thread(void)
{
- discard_lazy_cpu_state();
}
void flush_thread(void)
{
- discard_lazy_cpu_state();
-
#ifdef CONFIG_HAVE_HW_BREAKPOINT
flush_ptrace_hw_breakpoint(current);
#else /* CONFIG_HAVE_HW_BREAKPOINT */
@@ -1068,10 +1350,7 @@ release_thread(struct task_struct *t)
*/
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
- flush_fp_to_thread(src);
- flush_altivec_to_thread(src);
- flush_vsx_to_thread(src);
- flush_spe_to_thread(src);
+ flush_all_to_thread(src);
/*
* Flush TM state out so we can copy it. __switch_to_tm() does this
* flush but it removes the checkpointed state from the current CPU and
@@ -1161,6 +1440,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
f = ret_from_fork;
}
+ childregs->msr &= ~(MSR_FP|MSR_VEC|MSR_VSX);
sp -= STACK_FRAME_OVERHEAD;
/*
@@ -1194,7 +1474,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_DSCR)) {
p->thread.dscr_inherit = current->thread.dscr_inherit;
- p->thread.dscr = current->thread.dscr;
+ p->thread.dscr = mfspr(SPRN_DSCR);
}
if (cpu_has_feature(CPU_FTR_HAS_PPR))
p->thread.ppr = INIT_PPR;
@@ -1287,7 +1567,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
regs->msr = MSR_USER32;
}
#endif
- discard_lazy_cpu_state();
#ifdef CONFIG_VSX
current->thread.used_vsr = 0;
#endif
@@ -1623,9 +1902,9 @@ static inline unsigned long brk_rnd(void)
/* 8MB for 32bit, 1GB for 64bit */
if (is_32bit_task())
- rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+ rnd = (get_random_long() % (1UL<<(23-PAGE_SHIFT)));
else
- rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+ rnd = (get_random_long() % (1UL<<(30-PAGE_SHIFT)));
return rnd << PAGE_SHIFT;
}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index bef76c5..7030b03 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -783,17 +783,19 @@ void __init early_get_first_memblock_info(void *params, phys_addr_t *size)
int of_get_ibm_chip_id(struct device_node *np)
{
of_node_get(np);
- while(np) {
- struct device_node *old = np;
- const __be32 *prop;
+ while (np) {
+ u32 chip_id;
- prop = of_get_property(np, "ibm,chip-id", NULL);
- if (prop) {
+ /*
+ * Skiboot may produce memory nodes that contain more than one
+ * cell in chip-id, we only read the first one here.
+ */
+ if (!of_property_read_u32(np, "ibm,chip-id", &chip_id)) {
of_node_put(np);
- return be32_to_cpup(prop);
+ return chip_id;
}
- np = of_get_parent(np);
- of_node_put(old);
+
+ np = of_get_next_parent(np);
}
return -1;
}
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 15099c4..da51925 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -389,6 +389,7 @@ static void __init prom_printf(const char *format, ...)
break;
}
}
+ va_end(args);
}
@@ -1425,27 +1426,45 @@ static void __init prom_instantiate_sml(void)
{
phandle ibmvtpm_node;
ihandle ibmvtpm_inst;
- u32 entry = 0, size = 0;
+ u32 entry = 0, size = 0, succ = 0;
u64 base;
+ __be32 val;
prom_debug("prom_instantiate_sml: start...\n");
- ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/ibm,vtpm"));
+ ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/vdevice/vtpm"));
prom_debug("ibmvtpm_node: %x\n", ibmvtpm_node);
if (!PHANDLE_VALID(ibmvtpm_node))
return;
- ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/ibm,vtpm"));
+ ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/vdevice/vtpm"));
if (!IHANDLE_VALID(ibmvtpm_inst)) {
prom_printf("opening vtpm package failed (%x)\n", ibmvtpm_inst);
return;
}
- if (call_prom_ret("call-method", 2, 2, &size,
- ADDR("sml-get-handover-size"),
- ibmvtpm_inst) != 0 || size == 0) {
- prom_printf("SML get handover size failed\n");
- return;
+ if (prom_getprop(ibmvtpm_node, "ibm,sml-efi-reformat-supported",
+ &val, sizeof(val)) != PROM_ERROR) {
+ if (call_prom_ret("call-method", 2, 2, &succ,
+ ADDR("reformat-sml-to-efi-alignment"),
+ ibmvtpm_inst) != 0 || succ == 0) {
+ prom_printf("Reformat SML to EFI alignment failed\n");
+ return;
+ }
+
+ if (call_prom_ret("call-method", 2, 2, &size,
+ ADDR("sml-get-allocated-size"),
+ ibmvtpm_inst) != 0 || size == 0) {
+ prom_printf("SML get allocated size failed\n");
+ return;
+ }
+ } else {
+ if (call_prom_ret("call-method", 2, 2, &size,
+ ADDR("sml-get-handover-size"),
+ ibmvtpm_inst) != 0 || size == 0) {
+ prom_printf("SML get handover size failed\n");
+ return;
+ }
}
base = alloc_down(size, PAGE_SIZE, 0);
@@ -1454,6 +1473,8 @@ static void __init prom_instantiate_sml(void)
prom_printf("instantiating sml at 0x%x...", base);
+ memset((void *)base, 0, size);
+
if (call_prom_ret("call-method", 4, 2, &entry,
ADDR("sml-handover"),
ibmvtpm_inst, size, base) != 0 || entry == 0) {
@@ -1464,9 +1485,9 @@ static void __init prom_instantiate_sml(void)
reserve_mem(base, size);
- prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-base",
+ prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
&base, sizeof(base));
- prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-size",
+ prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
&size, sizeof(size));
prom_debug("sml base = 0x%x\n", base);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 737c0d0..30a03c0 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -60,6 +60,7 @@ struct pt_regs_offset {
#define STR(s) #s /* convert to string */
#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
#define GPR_OFFSET_NAME(num) \
+ {.name = STR(r##num), .offset = offsetof(struct pt_regs, gpr[num])}, \
{.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])}
#define REG_OFFSET_END {.name = NULL, .offset = 0}
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 5a753fa..28736ff 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -44,6 +44,9 @@
#include <asm/mmu.h>
#include <asm/topology.h>
+/* This is here deliberately so it's only used in this file */
+void enter_rtas(unsigned long);
+
struct rtas_t rtas = {
.lock = __ARCH_SPIN_LOCK_UNLOCKED
};
@@ -93,21 +96,13 @@ static void unlock_rtas(unsigned long flags)
*/
static void call_rtas_display_status(unsigned char c)
{
- struct rtas_args *args = &rtas.args;
unsigned long s;
if (!rtas.base)
return;
- s = lock_rtas();
-
- args->token = cpu_to_be32(10);
- args->nargs = cpu_to_be32(1);
- args->nret = cpu_to_be32(1);
- args->rets = &(args->args[1]);
- args->args[0] = cpu_to_be32(c);
-
- enter_rtas(__pa(args));
+ s = lock_rtas();
+ rtas_call_unlocked(&rtas.args, 10, 1, 1, NULL, c);
unlock_rtas(s);
}
@@ -418,6 +413,36 @@ static char *__fetch_rtas_last_error(char *altbuf)
#define get_errorlog_buffer() NULL
#endif
+
+static void
+va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret,
+ va_list list)
+{
+ int i;
+
+ args->token = cpu_to_be32(token);
+ args->nargs = cpu_to_be32(nargs);
+ args->nret = cpu_to_be32(nret);
+ args->rets = &(args->args[nargs]);
+
+ for (i = 0; i < nargs; ++i)
+ args->args[i] = cpu_to_be32(va_arg(list, __u32));
+
+ for (i = 0; i < nret; ++i)
+ args->rets[i] = 0;
+
+ enter_rtas(__pa(args));
+}
+
+void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...)
+{
+ va_list list;
+
+ va_start(list, nret);
+ va_rtas_call_unlocked(args, token, nargs, nret, list);
+ va_end(list);
+}
+
int rtas_call(int token, int nargs, int nret, int *outputs, ...)
{
va_list list;
@@ -431,22 +456,14 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
return -1;
s = lock_rtas();
+
+ /* We use the global rtas args buffer */
rtas_args = &rtas.args;
- rtas_args->token = cpu_to_be32(token);
- rtas_args->nargs = cpu_to_be32(nargs);
- rtas_args->nret = cpu_to_be32(nret);
- rtas_args->rets = &(rtas_args->args[nargs]);
va_start(list, outputs);
- for (i = 0; i < nargs; ++i)
- rtas_args->args[i] = cpu_to_be32(va_arg(list, __u32));
+ va_rtas_call_unlocked(rtas_args, token, nargs, nret, list);
va_end(list);
- for (i = 0; i < nret; ++i)
- rtas_args->rets[i] = 0;
-
- enter_rtas(__pa(rtas_args));
-
/* A -1 return code indicates that the last command couldn't
be completed due to a hardware error. */
if (be32_to_cpu(rtas_args->rets[0]) == -1)
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 5a2c049..aa610ce 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max;
static unsigned int event_scan;
static unsigned int rtas_event_scan_rate;
-static int full_rtas_msgs = 0;
+static bool full_rtas_msgs;
/* Stop logging to nvram after first fatal error */
static int logging_enabled; /* Until we initialize everything,
@@ -592,11 +592,6 @@ __setup("surveillance=", surveillance_setup);
static int __init rtasmsgs_setup(char *str)
{
- if (strcmp(str, "on") == 0)
- full_rtas_msgs = 1;
- else if (strcmp(str, "off") == 0)
- full_rtas_msgs = 0;
-
- return 1;
+ return (kstrtobool(str, &full_rtas_msgs) == 0);
}
__setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index ad8c9db..d544fa3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -114,8 +114,6 @@ extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */
notrace void __init machine_init(u64 dt_ptr)
{
- lockdep_init();
-
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index bdcbb71..f98be83 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -108,6 +108,14 @@ static void setup_tlb_core_data(void)
for_each_possible_cpu(cpu) {
int first = cpu_first_thread_sibling(cpu);
+ /*
+ * If we boot via kdump on a non-primary thread,
+ * make sure we point at the thread that actually
+ * set up this TLB.
+ */
+ if (cpu_first_thread_sibling(boot_cpuid) == first)
+ first = boot_cpuid;
+
paca[cpu].tcd_ptr = &paca[first].tcd;
/*
@@ -247,9 +255,6 @@ void __init early_setup(unsigned long dt_ptr)
setup_paca(&boot_paca);
fixup_boot_paca();
- /* Initialize lockdep early or else spinlocks will blow */
- lockdep_init();
-
/* -------- printk is now safe to use ------- */
/* Enable early debugging if any specified (see udbg.h) */
@@ -332,11 +337,26 @@ void early_setup_secondary(void)
#endif /* CONFIG_SMP */
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+static bool use_spinloop(void)
+{
+ if (!IS_ENABLED(CONFIG_PPC_BOOK3E))
+ return true;
+
+ /*
+ * When book3e boots from kexec, the ePAPR spin table does
+ * not get used.
+ */
+ return of_property_read_bool(of_chosen, "linux,booted-from-kexec");
+}
+
void smp_release_cpus(void)
{
unsigned long *ptr;
int i;
+ if (!use_spinloop())
+ return;
+
DBG(" -> smp_release_cpus()\n");
/* All secondary cpus are spinning on a common spinloop, release them
@@ -516,7 +536,7 @@ void __init setup_system(void)
* Freescale Book3e parts spin in a loop provided by firmware,
* so smp_release_cpus() does nothing for them
*/
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_FSL_BOOK3E)
+#if defined(CONFIG_SMP)
/* Release secondary cpus out of their spinloops at 0x60 now that
* we can map physical -> logical CPU ids
*/
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index cf8c7e4..cb64d6f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -1,7 +1,7 @@
/*
* Common signal handling code for both 32 and 64 bits
*
- * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
+ * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
* Extracted from signal_32.c and signal_64.c
*
* This file is subject to the terms and conditions of the GNU General
@@ -178,7 +178,7 @@ unsigned long get_tm_stackpointer(struct pt_regs *regs)
* need to use the stack pointer from the checkpointed state, rather
* than the speculated state. This ensures that the signal context
* (written tm suspended) will be written below the stack required for
- * the rollback. The transaction is aborted becuase of the treclaim,
+ * the rollback. The transaction is aborted because of the treclaim,
* so any memory written between the tbegin and the signal will be
* rolled back anyway.
*
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 51b2741..be305c8 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
+ * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
* Extracted from signal_32.c and signal_64.c
*
* This file is subject to the terms and conditions of the GNU General
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 0dbee46..b6aa378 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -458,7 +458,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* contains valid data
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- __giveup_vsx(current);
+ flush_vsx_to_thread(current);
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
msr |= MSR_VSX;
@@ -606,7 +606,7 @@ static int save_tm_user_regs(struct pt_regs *regs,
* contains valid data
*/
if (current->thread.used_vsr) {
- __giveup_vsx(current);
+ flush_vsx_to_thread(current);
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
if (msr & MSR_VSX) {
@@ -687,15 +687,6 @@ static long restore_user_regs(struct pt_regs *regs,
if (sig)
regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
- /*
- * Do this before updating the thread state in
- * current->thread.fpr/vr/evr. That way, if we get preempted
- * and another task grabs the FPU/Altivec/SPE, it won't be
- * tempted to save the current CPU state into the thread_struct
- * and corrupt what we are writing there.
- */
- discard_lazy_cpu_state();
-
#ifdef CONFIG_ALTIVEC
/*
* Force the process to reload the altivec registers from
@@ -798,15 +789,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
/* Restore the previous little-endian mode */
regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
- /*
- * Do this before updating the thread state in
- * current->thread.fpr/vr/evr. That way, if we get preempted
- * and another task grabs the FPU/Altivec/SPE, it won't be
- * tempted to save the current CPU state into the thread_struct
- * and corrupt what we are writing there.
- */
- discard_lazy_cpu_state();
-
#ifdef CONFIG_ALTIVEC
regs->msr &= ~MSR_VEC;
if (msr & MSR_VEC) {
@@ -875,6 +857,15 @@ static long restore_tm_user_regs(struct pt_regs *regs,
return 1;
#endif /* CONFIG_SPE */
+ /* Get the top half of the MSR from the user context */
+ if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
+ return 1;
+ msr_hi <<= 32;
+ /* If TM bits are set to the reserved value, it's an invalid context */
+ if (MSR_TM_RESV(msr_hi))
+ return 1;
+ /* Pull in the MSR TM bits from the user context */
+ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
/* Now, recheckpoint. This loads up all of the checkpointed (older)
* registers, including FP and V[S]Rs. After recheckpointing, the
* transactional versions should be loaded.
@@ -884,11 +875,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
current->thread.tm_texasr |= TEXASR_FS;
/* This loads the checkpointed FP/VEC state, if used */
tm_recheckpoint(&current->thread, msr);
- /* Get the top half of the MSR */
- if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
- return 1;
- /* Pull in MSR TM from user context */
- regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
/* This loads the speculative FP/VEC state, if used */
if (msr & MSR_FP) {
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 20756df..2552079 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -147,7 +147,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
* VMX data.
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- __giveup_vsx(current);
+ flush_vsx_to_thread(current);
v_regs += ELF_NVRREG;
err |= copy_vsx_to_user(v_regs, current);
/* set MSR_VSX in the MSR value in the frame to
@@ -270,7 +270,7 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
* VMX data.
*/
if (current->thread.used_vsr) {
- __giveup_vsx(current);
+ flush_vsx_to_thread(current);
v_regs += ELF_NVRREG;
tm_v_regs += ELF_NVRREG;
@@ -350,15 +350,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
err |= __get_user(set->sig[0], &sc->oldmask);
/*
- * Do this before updating the thread state in
- * current->thread.fpr/vr. That way, if we get preempted
- * and another task grabs the FPU/Altivec, it won't be
- * tempted to save the current CPU state into the thread_struct
- * and corrupt what we are writing there.
- */
- discard_lazy_cpu_state();
-
- /*
* Force reload of FP/VEC.
* This has to be done before copying stuff into current->thread.fpr/vr
* for the reasons explained in the previous comment.
@@ -438,6 +429,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
/* get MSR separately, transfer the LE bit if doing signal return */
err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
+ /* Don't allow reserved mode. */
+ if (MSR_TM_RESV(msr))
+ return -EINVAL;
+
/* pull in MSR TM from user context */
regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
@@ -465,15 +460,6 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
/*
- * Do this before updating the thread state in
- * current->thread.fpr/vr. That way, if we get preempted
- * and another task grabs the FPU/Altivec, it won't be
- * tempted to save the current CPU state into the thread_struct
- * and corrupt what we are writing there.
- */
- discard_lazy_cpu_state();
-
- /*
* Force reload of FP/VEC.
* This has to be done before copying stuff into current->thread.fpr/vr
* for the reasons explained in the previous comment.
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index ec9ec20..8cac1eb 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -206,7 +206,7 @@ int smp_request_message_ipi(int virq, int msg)
#ifdef CONFIG_PPC_SMP_MUXED_IPI
struct cpu_messages {
- int messages; /* current messages */
+ long messages; /* current messages */
unsigned long data; /* data for cause ipi */
};
static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_messages, ipi_message);
@@ -218,7 +218,7 @@ void smp_muxed_ipi_set_data(int cpu, unsigned long data)
info->data = data;
}
-void smp_muxed_ipi_message_pass(int cpu, int msg)
+void smp_muxed_ipi_set_message(int cpu, int msg)
{
struct cpu_messages *info = &per_cpu(ipi_message, cpu);
char *message = (char *)&info->messages;
@@ -228,6 +228,13 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)
*/
smp_mb();
message[msg] = 1;
+}
+
+void smp_muxed_ipi_message_pass(int cpu, int msg)
+{
+ struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+
+ smp_muxed_ipi_set_message(cpu, msg);
/*
* cause_ipi functions are required to include a full barrier
* before doing whatever causes the IPI.
@@ -236,20 +243,31 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)
}
#ifdef __BIG_ENDIAN__
-#define IPI_MESSAGE(A) (1 << (24 - 8 * (A)))
+#define IPI_MESSAGE(A) (1uL << ((BITS_PER_LONG - 8) - 8 * (A)))
#else
-#define IPI_MESSAGE(A) (1 << (8 * (A)))
+#define IPI_MESSAGE(A) (1uL << (8 * (A)))
#endif
irqreturn_t smp_ipi_demux(void)
{
struct cpu_messages *info = this_cpu_ptr(&ipi_message);
- unsigned int all;
+ unsigned long all;
mb(); /* order any irq clear */
do {
all = xchg(&info->messages, 0);
+#if defined(CONFIG_KVM_XICS) && defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE)
+ /*
+ * Must check for PPC_MSG_RM_HOST_ACTION messages
+ * before PPC_MSG_CALL_FUNCTION messages because when
+ * a VM is destroyed, we call kick_all_cpus_sync()
+ * to ensure that any pending PPC_MSG_RM_HOST_ACTION
+ * messages have completed before we free any VCPUs.
+ */
+ if (all & IPI_MESSAGE(PPC_MSG_RM_HOST_ACTION))
+ kvmppc_xics_ipi_action();
+#endif
if (all & IPI_MESSAGE(PPC_MSG_CALL_FUNCTION))
generic_smp_call_function_interrupt();
if (all & IPI_MESSAGE(PPC_MSG_RESCHEDULE))
@@ -427,7 +445,7 @@ void generic_cpu_die(unsigned int cpu)
for (i = 0; i < 100; i++) {
smp_rmb();
- if (per_cpu(cpu_state, cpu) == CPU_DEAD)
+ if (is_cpu_dead(cpu))
return;
msleep(100);
}
@@ -454,6 +472,11 @@ int generic_check_cpu_restart(unsigned int cpu)
return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
}
+int is_cpu_dead(unsigned int cpu)
+{
+ return per_cpu(cpu_state, cpu) == CPU_DEAD;
+}
+
static bool secondaries_inhibited(void)
{
return kvm_hv_mode_active();
@@ -727,7 +750,7 @@ void start_secondary(void *unused)
local_irq_enable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
BUG();
}
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index ea43a34..4f24606 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -61,3 +61,10 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
save_context_stack(trace, tsk->thread.ksp, tsk, 0);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
+
+void
+save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+{
+ save_context_stack(trace, regs->gpr[1], current, 0);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_regs);
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
index eae33e1..6669b17 100644
--- a/arch/powerpc/kernel/swsusp.c
+++ b/arch/powerpc/kernel/swsusp.c
@@ -20,9 +20,7 @@ void save_processor_state(void)
* flush out all the special registers so we don't need
* to save them in the snapshot
*/
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
- flush_spe_to_thread(current);
+ flush_all_to_thread(current);
#ifdef CONFIG_PPC64
hard_irq_disable();
diff --git a/arch/powerpc/kernel/systbl_chk.c b/arch/powerpc/kernel/systbl_chk.c
index 2384129..55323a6 100644
--- a/arch/powerpc/kernel/systbl_chk.c
+++ b/arch/powerpc/kernel/systbl_chk.c
@@ -57,4 +57,4 @@
START_TABLE
#include <asm/systbl.h>
-END_TABLE __NR_syscalls
+END_TABLE NR_syscalls
diff --git a/arch/powerpc/kernel/systbl_chk.sh b/arch/powerpc/kernel/systbl_chk.sh
index 19415e7..31b6e7c 100644
--- a/arch/powerpc/kernel/systbl_chk.sh
+++ b/arch/powerpc/kernel/systbl_chk.sh
@@ -16,7 +16,7 @@ awk 'BEGIN { num = -1; } # Ignore the beginning of the file
/^START_TABLE/ { num = 0; next; }
/^END_TABLE/ {
if (num != $2) {
- printf "__NR_syscalls (%s) is not one more than the last syscall (%s)\n",
+ printf "NR_syscalls (%s) is not one more than the last syscall (%s)\n",
$2, num - 1;
exit(1);
}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 1be1092..81b0900 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1002,38 +1002,6 @@ static int month_days[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
-/*
- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
- */
-void GregorianDay(struct rtc_time * tm)
-{
- int leapsToDate;
- int lastYear;
- int day;
- int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-
- lastYear = tm->tm_year - 1;
-
- /*
- * Number of leap corrections to apply up to end of last year
- */
- leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400;
-
- /*
- * This year is a leap year if it is divisible by 4 except when it is
- * divisible by 100 unless it is divisible by 400
- *
- * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was
- */
- day = tm->tm_mon > 2 && leapyear(tm->tm_year);
-
- day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
- tm->tm_mday;
-
- tm->tm_wday = day % 7;
-}
-EXPORT_SYMBOL_GPL(GregorianDay);
-
void to_tm(int tim, struct rtc_time * tm)
{
register int i;
@@ -1064,9 +1032,9 @@ void to_tm(int tim, struct rtc_time * tm)
tm->tm_mday = day + 1;
/*
- * Determine the day of week
+ * No-one uses the day of the week.
*/
- GregorianDay(tm);
+ tm->tm_wday = -1;
}
EXPORT_SYMBOL(to_tm);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 37de90f..9229ba6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -203,9 +203,8 @@ static int __kprobes __die(const char *str, struct pt_regs *regs, long err)
#ifdef CONFIG_SMP
printk("SMP NR_CPUS=%d ", NR_CPUS);
#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk("DEBUG_PAGEALLOC ");
-#endif
+ if (debug_pagealloc_enabled())
+ printk("DEBUG_PAGEALLOC ");
#ifdef CONFIG_NUMA
printk("NUMA ");
#endif
@@ -1148,6 +1147,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
goto bail;
}
if (reason & REASON_TRAP) {
+ unsigned long bugaddr;
/* Debugger is first in line to stop recursive faults in
* rcu_lock, notify_die, or atomic_notifier_call_chain */
if (debugger_bpt(regs))
@@ -1158,8 +1158,15 @@ void __kprobes program_check_exception(struct pt_regs *regs)
== NOTIFY_STOP)
goto bail;
+ bugaddr = regs->nip;
+ /*
+ * Fixup bugaddr for BUG_ON() in real mode
+ */
+ if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
+ bugaddr += PAGE_OFFSET;
+
if (!(regs->msr & MSR_PR) && /* not user-mode */
- report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
+ report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) {
regs->nip += 4;
goto bail;
}
@@ -1313,13 +1320,6 @@ void nonrecoverable_exception(struct pt_regs *regs)
die("nonrecoverable exception", regs, SIGKILL);
}
-void trace_syscall(struct pt_regs *regs)
-{
- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
- regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
-}
-
void kernel_fp_unavailable_exception(struct pt_regs *regs)
{
enum ctx_state prev_state = exception_enter();
@@ -1401,7 +1401,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
* is a read DSCR attempt through a mfspr instruction, we
* just emulate the instruction instead. This code path will
* always emulate all the mfspr instructions till the user
- * has attempted atleast one mtspr instruction. This way it
+ * has attempted at least one mtspr instruction. This way it
* preserves the same behaviour when the user is accessing
* the DSCR through privilege level only SPR number (0x11)
* which is emulated through illegal instruction exception.
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index b457bfa..def1b8b 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -671,7 +671,7 @@ static void __init vdso_setup_syscall_map(void)
extern unsigned long sys_ni_syscall;
- for (i = 0; i < __NR_syscalls; i++) {
+ for (i = 0; i < NR_syscalls; i++) {
#ifdef CONFIG_PPC64
if (sys_call_table[i*2] != sys_ni_syscall)
vdso_data->syscall_map_64[i >> 5] |=
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index 53e6c9b..cbabd14 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -15,10 +15,11 @@ targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
GCOV_PROFILE := n
+UBSAN_SANITIZE := n
ccflags-y := -shared -fno-common -fno-builtin
ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
- $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+ $(call cc-ldoption, -Wl$(comma)--hash-style=both)
asflags-y := -D__VDSO32__ -s
obj-y += vdso32_wrapper.o
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index dc21e89..3745113 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -16,6 +16,10 @@
#include <asm/vdso.h>
.text
+ .global __kernel_datapage_offset;
+__kernel_datapage_offset:
+ .long 0
+
V_FUNCTION_BEGIN(__get_datapage)
.cfi_startproc
/* We don't want that exposed or overridable as we want other objects
@@ -27,13 +31,11 @@ V_FUNCTION_BEGIN(__get_datapage)
mflr r0
.cfi_register lr,r0
- bcl 20,31,1f
- .global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
-1:
+ bcl 20,31,data_page_branch
+data_page_branch:
mflr r3
mtlr r0
+ addi r3, r3, __kernel_datapage_offset-data_page_branch
lwz r0,0(r3)
add r3,r0,r3
blr
@@ -59,7 +61,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
addi r3,r3,CFG_SYSCALL_MAP32
cmpli cr0,r4,0
beqlr
- li r0,__NR_syscalls
+ li r0,NR_syscalls
stw r0,0(r4)
crclr cr0*4+so
blr
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index effca94..c710802 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -8,10 +8,11 @@ targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
GCOV_PROFILE := n
+UBSAN_SANITIZE := n
ccflags-y := -shared -fno-common -fno-builtin
ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
- $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+ $(call cc-ldoption, -Wl$(comma)--hash-style=both)
asflags-y := -D__VDSO64__ -s
obj-y += vdso64_wrapper.o
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index 79796de..184a6ba 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -16,6 +16,10 @@
#include <asm/vdso.h>
.text
+.global __kernel_datapage_offset;
+__kernel_datapage_offset:
+ .long 0
+
V_FUNCTION_BEGIN(__get_datapage)
.cfi_startproc
/* We don't want that exposed or overridable as we want other objects
@@ -27,13 +31,11 @@ V_FUNCTION_BEGIN(__get_datapage)
mflr r0
.cfi_register lr,r0
- bcl 20,31,1f
- .global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
-1:
+ bcl 20,31,data_page_branch
+data_page_branch:
mflr r3
mtlr r0
+ addi r3, r3, __kernel_datapage_offset-data_page_branch
lwz r0,0(r3)
add r3,r0,r3
blr
@@ -60,7 +62,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
cmpli cr0,r4,0
crclr cr0*4+so
beqlr
- li r0,__NR_syscalls
+ li r0,NR_syscalls
stw r0,0(r4)
blr
.cfi_endproc
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index f5c80d5..1c2e7a3 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -29,24 +29,10 @@ _GLOBAL(do_load_up_transact_altivec)
addi r10,r3,THREAD_TRANSACT_VRSTATE
REST_32VRS(0,r4,r10)
- /* Disable VEC again. */
- MTMSRD(r6)
- isync
-
blr
#endif
/*
- * Enable use of VMX/Altivec for the caller.
- */
-_GLOBAL(vec_enable)
- mfmsr r3
- oris r3,r3,MSR_VEC@h
- MTMSRD(r3)
- isync
- blr
-
-/*
* Load state from memory into VMX registers including VSCR.
* Assumes the caller has enabled VMX in the MSR.
*/
@@ -84,39 +70,6 @@ _GLOBAL(load_up_altivec)
MTMSRD(r5) /* enable use of AltiVec now */
isync
-/*
- * For SMP, we don't do lazy VMX switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_altvec in switch_to.
- * VRSAVE isn't dealt with here, that is done in the normal context
- * switch code. Note that we could rely on vrsave value to eventually
- * avoid saving all of the VREGs here...
- */
-#ifndef CONFIG_SMP
- LOAD_REG_ADDRBASE(r3, last_task_used_altivec)
- toreal(r3)
- PPC_LL r4,ADDROFF(last_task_used_altivec)(r3)
- PPC_LCMPI 0,r4,0
- beq 1f
-
- /* Save VMX state to last_task_used_altivec's THREAD struct */
- toreal(r4)
- addi r4,r4,THREAD
- addi r6,r4,THREAD_VRSTATE
- SAVE_32VRS(0,r5,r6)
- mfvscr v0
- li r10,VRSTATE_VSCR
- stvx v0,r10,r6
- /* Disable VMX for last_task_used_altivec */
- PPC_LL r5,PT_REGS(r4)
- toreal(r5)
- PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r10,MSR_VEC@h
- andc r4,r4,r10
- PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-
/* Hack: if we get an altivec unavailable trap with VRSAVE
* set to all zeros, we assume this is a broken application
* that fails to set it properly, and thus we switch it to
@@ -138,6 +91,10 @@ _GLOBAL(load_up_altivec)
oris r12,r12,MSR_VEC@h
std r12,_MSR(r1)
#endif
+ /* Don't care if r4 overflows, this is desired behaviour */
+ lbz r4,THREAD_LOAD_VEC(r5)
+ addi r4,r4,1
+ stb r4,THREAD_LOAD_VEC(r5)
addi r6,r5,THREAD_VRSTATE
li r4,1
li r10,VRSTATE_VSCR
@@ -145,69 +102,24 @@ _GLOBAL(load_up_altivec)
lvx v0,r10,r6
mtvscr v0
REST_32VRS(0,r4,r6)
-#ifndef CONFIG_SMP
- /* Update last_task_used_altivec to 'current' */
- subi r4,r5,THREAD /* Back to 'current' */
- fromreal(r4)
- PPC_STL r4,ADDROFF(last_task_used_altivec)(r3)
-#endif /* CONFIG_SMP */
/* restore registers and return */
blr
-_GLOBAL(giveup_altivec_notask)
- mfmsr r3
- andis. r4,r3,MSR_VEC@h
- bnelr /* Already enabled? */
- oris r3,r3,MSR_VEC@h
- SYNC
- MTMSRD(r3) /* enable use of VMX now */
- isync
- blr
-
/*
- * giveup_altivec(tsk)
- * Disable VMX for the task given as the argument,
- * and save the vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
+ * save_altivec(tsk)
+ * Save the vector registers to its thread_struct
*/
-_GLOBAL(giveup_altivec)
- mfmsr r5
- oris r5,r5,MSR_VEC@h
- SYNC
- MTMSRD(r5) /* enable use of VMX now */
- isync
- PPC_LCMPI 0,r3,0
- beqlr /* if no previous owner, done */
+_GLOBAL(save_altivec)
addi r3,r3,THREAD /* want THREAD of task */
PPC_LL r7,THREAD_VRSAVEAREA(r3)
PPC_LL r5,PT_REGS(r3)
PPC_LCMPI 0,r7,0
bne 2f
addi r7,r3,THREAD_VRSTATE
-2: PPC_LCMPI 0,r5,0
- SAVE_32VRS(0,r4,r7)
+2: SAVE_32VRS(0,r4,r7)
mfvscr v0
li r4,VRSTATE_VSCR
stvx v0,r4,r7
- beq 1f
- PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
- lis r3,(MSR_VEC|MSR_VSX)@h
-FTR_SECTION_ELSE
- lis r3,MSR_VEC@h
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
-#else
- lis r3,MSR_VEC@h
-#endif
- andc r4,r4,r3 /* disable FP for previous task */
- PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- LOAD_REG_ADDRBASE(r4,last_task_used_altivec)
- PPC_STL r5,ADDROFF(last_task_used_altivec)(r4)
-#endif /* CONFIG_SMP */
blr
#ifdef CONFIG_VSX
@@ -230,20 +142,6 @@ _GLOBAL(load_up_vsx)
andis. r5,r12,MSR_VEC@h
beql+ load_up_altivec /* skip if already loaded */
-#ifndef CONFIG_SMP
- ld r3,last_task_used_vsx@got(r2)
- ld r4,0(r3)
- cmpdi 0,r4,0
- beq 1f
- /* Disable VSX for last_task_used_vsx */
- addi r4,r4,THREAD
- ld r5,PT_REGS(r4)
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r6,MSR_VSX@h
- andc r6,r4,r6
- std r6,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
ld r4,PACACURRENT(r13)
addi r4,r4,THREAD /* Get THREAD */
li r6,1
@@ -251,43 +149,8 @@ _GLOBAL(load_up_vsx)
/* enable use of VSX after return */
oris r12,r12,MSR_VSX@h
std r12,_MSR(r1)
-#ifndef CONFIG_SMP
- /* Update last_task_used_vsx to 'current' */
- ld r4,PACACURRENT(r13)
- std r4,0(r3)
-#endif /* CONFIG_SMP */
b fast_exception_return
-/*
- * __giveup_vsx(tsk)
- * Disable VSX for the task given as the argument.
- * Does NOT save vsx registers.
- * Enables the VSX for use in the kernel on return.
- */
-_GLOBAL(__giveup_vsx)
- mfmsr r5
- oris r5,r5,MSR_VSX@h
- mtmsrd r5 /* enable use of VSX now */
- isync
-
- cmpdi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- ld r5,PT_REGS(r3)
- cmpdi 0,r5,0
- beq 1f
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r3,MSR_VSX@h
- andc r4,r4,r3 /* disable VSX for previous task */
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- ld r4,last_task_used_vsx@got(r2)
- std r5,0(r4)
-#endif /* CONFIG_SMP */
- blr
-
#endif /* CONFIG_VSX */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 1db6851..d41fd0a 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -183,6 +183,12 @@ SECTIONS
*(.rela*)
}
#endif
+ /* .exit.data is discarded at runtime, not link time,
+ * to deal with references from .exit.text
+ */
+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
+ EXIT_DATA
+ }
/* freed after init ends here */
. = ALIGN(PAGE_SIZE);
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 0570eef..7f7b6d8 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -8,7 +8,7 @@ ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm
KVM := ../../../virt/kvm
common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
- $(KVM)/eventfd.o
+ $(KVM)/eventfd.o $(KVM)/vfio.o
CFLAGS_e500_mmu.o := -I.
CFLAGS_e500_mmu_host.o := -I.
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 099c79d..b34220d 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -366,7 +366,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter);
-pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
+kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
bool *writable)
{
ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM;
@@ -379,9 +379,9 @@ pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
gpa &= ~0xFFFULL;
if (unlikely(mp_pa) && unlikely((gpa & KVM_PAM) == mp_pa)) {
ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
- pfn_t pfn;
+ kvm_pfn_t pfn;
- pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
+ pfn = (kvm_pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
get_page(pfn_to_page(pfn));
if (writable)
*writable = true;
@@ -807,7 +807,7 @@ int kvmppc_core_init_vm(struct kvm *kvm)
{
#ifdef CONFIG_PPC64
- INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
+ INIT_LIST_HEAD_RCU(&kvm->arch.spapr_tce_tables);
INIT_LIST_HEAD(&kvm->arch.rtas_tokens);
#endif
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index d5c9bfe..9991069 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -22,7 +22,7 @@
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash32.h>
+#include <asm/book3s/32/mmu-hash.h>
#include <asm/machdep.h>
#include <asm/mmu_context.h>
#include <asm/hw_irq.h>
@@ -142,7 +142,7 @@ extern char etext[];
int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
bool iswrite)
{
- pfn_t hpaddr;
+ kvm_pfn_t hpaddr;
u64 vpn;
u64 vsid;
struct kvmppc_sid_map *map;
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index 774a253..b9131aa 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -26,7 +26,7 @@
#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
/* #define DEBUG_MMU */
@@ -377,15 +377,12 @@ no_seg_found:
static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb)
{
- struct kvmppc_vcpu_book3s *vcpu_book3s;
u64 esid, esid_1t;
int slb_nr;
struct kvmppc_slb *slbe;
dprintk("KVM MMU: slbmte(0x%llx, 0x%llx)\n", rs, rb);
- vcpu_book3s = to_book3s(vcpu);
-
esid = GET_ESID(rb);
esid_1t = GET_ESID_1T(rb);
slb_nr = rb & 0xfff;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 79ad35a..114edac 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -23,7 +23,7 @@
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#include <asm/machdep.h>
#include <asm/mmu_context.h>
#include <asm/hw_irq.h>
@@ -83,7 +83,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
bool iswrite)
{
unsigned long vpn;
- pfn_t hpaddr;
+ kvm_pfn_t hpaddr;
ulong hash, hpteg;
u64 vsid;
int ret;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 1f9c0a1..c7b78d8 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -32,7 +32,7 @@
#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#include <asm/hvcall.h>
#include <asm/synch.h>
#include <asm/ppc-opcode.h>
@@ -70,7 +70,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
}
/* Lastly try successively smaller sizes from the page allocator */
- while (!hpt && order > PPC_MIN_HPT_ORDER) {
+ /* Only do this if userspace didn't specify a size via ioctl */
+ while (!hpt && order > PPC_MIN_HPT_ORDER && !htab_orderp) {
hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|
__GFP_NOWARN, order - PAGE_SHIFT);
if (!hpt)
@@ -543,7 +544,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
*/
local_irq_save(flags);
ptep = find_linux_pte_or_hugepte(current->mm->pgd,
- hva, NULL);
+ hva, NULL, NULL);
if (ptep) {
pte = kvmppc_read_update_linux_pte(ptep, 1);
if (pte_write(pte))
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 54cf9bc..8297004 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -14,6 +14,7 @@
*
* Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
* Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com>
+ * Copyright 2016 Alexey Kardashevskiy, IBM Corporation <aik@au1.ibm.com>
*/
#include <linux/types.h>
@@ -30,34 +31,75 @@
#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#include <asm/hvcall.h>
#include <asm/synch.h>
#include <asm/ppc-opcode.h>
#include <asm/kvm_host.h>
#include <asm/udbg.h>
+#include <asm/iommu.h>
+#include <asm/tce.h>
-#define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64))
+static unsigned long kvmppc_tce_pages(unsigned long iommu_pages)
+{
+ return ALIGN(iommu_pages * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
+}
-static long kvmppc_stt_npages(unsigned long window_size)
+static unsigned long kvmppc_stt_pages(unsigned long tce_pages)
{
- return ALIGN((window_size >> SPAPR_TCE_SHIFT)
- * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
+ unsigned long stt_bytes = sizeof(struct kvmppc_spapr_tce_table) +
+ (tce_pages * sizeof(struct page *));
+
+ return tce_pages + ALIGN(stt_bytes, PAGE_SIZE) / PAGE_SIZE;
}
-static void release_spapr_tce_table(struct kvmppc_spapr_tce_table *stt)
+static long kvmppc_account_memlimit(unsigned long stt_pages, bool inc)
{
- struct kvm *kvm = stt->kvm;
- int i;
+ long ret = 0;
- mutex_lock(&kvm->lock);
- list_del(&stt->list);
- for (i = 0; i < kvmppc_stt_npages(stt->window_size); i++)
+ if (!current || !current->mm)
+ return ret; /* process exited */
+
+ down_write(&current->mm->mmap_sem);
+
+ if (inc) {
+ unsigned long locked, lock_limit;
+
+ locked = current->mm->locked_vm + stt_pages;
+ lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ ret = -ENOMEM;
+ else
+ current->mm->locked_vm += stt_pages;
+ } else {
+ if (WARN_ON_ONCE(stt_pages > current->mm->locked_vm))
+ stt_pages = current->mm->locked_vm;
+
+ current->mm->locked_vm -= stt_pages;
+ }
+
+ pr_debug("[%d] RLIMIT_MEMLOCK KVM %c%ld %ld/%ld%s\n", current->pid,
+ inc ? '+' : '-',
+ stt_pages << PAGE_SHIFT,
+ current->mm->locked_vm << PAGE_SHIFT,
+ rlimit(RLIMIT_MEMLOCK),
+ ret ? " - exceeded" : "");
+
+ up_write(&current->mm->mmap_sem);
+
+ return ret;
+}
+
+static void release_spapr_tce_table(struct rcu_head *head)
+{
+ struct kvmppc_spapr_tce_table *stt = container_of(head,
+ struct kvmppc_spapr_tce_table, rcu);
+ unsigned long i, npages = kvmppc_tce_pages(stt->size);
+
+ for (i = 0; i < npages; i++)
__free_page(stt->pages[i]);
- kfree(stt);
- mutex_unlock(&kvm->lock);
- kvm_put_kvm(kvm);
+ kfree(stt);
}
static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -65,7 +107,7 @@ static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data;
struct page *page;
- if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size))
+ if (vmf->pgoff >= kvmppc_tce_pages(stt->size))
return VM_FAULT_SIGBUS;
page = stt->pages[vmf->pgoff];
@@ -88,7 +130,14 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
{
struct kvmppc_spapr_tce_table *stt = filp->private_data;
- release_spapr_tce_table(stt);
+ list_del_rcu(&stt->list);
+
+ kvm_put_kvm(stt->kvm);
+
+ kvmppc_account_memlimit(
+ kvmppc_stt_pages(kvmppc_tce_pages(stt->size)), false);
+ call_rcu(&stt->rcu, release_spapr_tce_table);
+
return 0;
}
@@ -98,20 +147,29 @@ static const struct file_operations kvm_spapr_tce_fops = {
};
long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
- struct kvm_create_spapr_tce *args)
+ struct kvm_create_spapr_tce_64 *args)
{
struct kvmppc_spapr_tce_table *stt = NULL;
- long npages;
+ unsigned long npages, size;
int ret = -ENOMEM;
int i;
+ if (!args->size)
+ return -EINVAL;
+
/* Check this LIOBN hasn't been previously allocated */
list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
if (stt->liobn == args->liobn)
return -EBUSY;
}
- npages = kvmppc_stt_npages(args->window_size);
+ size = args->size;
+ npages = kvmppc_tce_pages(size);
+ ret = kvmppc_account_memlimit(kvmppc_stt_pages(npages), true);
+ if (ret) {
+ stt = NULL;
+ goto fail;
+ }
stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *),
GFP_KERNEL);
@@ -119,7 +177,9 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
goto fail;
stt->liobn = args->liobn;
- stt->window_size = args->window_size;
+ stt->page_shift = args->page_shift;
+ stt->offset = args->offset;
+ stt->size = size;
stt->kvm = kvm;
for (i = 0; i < npages; i++) {
@@ -131,7 +191,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
kvm_get_kvm(kvm);
mutex_lock(&kvm->lock);
- list_add(&stt->list, &kvm->arch.spapr_tce_tables);
+ list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables);
mutex_unlock(&kvm->lock);
@@ -148,3 +208,59 @@ fail:
}
return ret;
}
+
+long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
+ unsigned long liobn, unsigned long ioba,
+ unsigned long tce_list, unsigned long npages)
+{
+ struct kvmppc_spapr_tce_table *stt;
+ long i, ret = H_SUCCESS, idx;
+ unsigned long entry, ua = 0;
+ u64 __user *tces, tce;
+
+ stt = kvmppc_find_table(vcpu, liobn);
+ if (!stt)
+ return H_TOO_HARD;
+
+ entry = ioba >> stt->page_shift;
+ /*
+ * SPAPR spec says that the maximum size of the list is 512 TCEs
+ * so the whole table fits in 4K page
+ */
+ if (npages > 512)
+ return H_PARAMETER;
+
+ if (tce_list & (SZ_4K - 1))
+ return H_PARAMETER;
+
+ ret = kvmppc_ioba_validate(stt, ioba, npages);
+ if (ret != H_SUCCESS)
+ return ret;
+
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+ if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, NULL)) {
+ ret = H_TOO_HARD;
+ goto unlock_exit;
+ }
+ tces = (u64 __user *) ua;
+
+ for (i = 0; i < npages; ++i) {
+ if (get_user(tce, tces + i)) {
+ ret = H_TOO_HARD;
+ goto unlock_exit;
+ }
+ tce = be64_to_cpu(tce);
+
+ ret = kvmppc_tce_validate(stt, tce);
+ if (ret != H_SUCCESS)
+ goto unlock_exit;
+
+ kvmppc_tce_put(stt, entry + i, tce);
+ }
+
+unlock_exit:
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(kvmppc_h_put_tce_indirect);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 89e96b3..f88b859 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -14,6 +14,7 @@
*
* Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
* Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com>
+ * Copyright 2016 Alexey Kardashevskiy, IBM Corporation <aik@au1.ibm.com>
*/
#include <linux/types.h>
@@ -29,77 +30,322 @@
#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
+#include <asm/mmu_context.h>
#include <asm/hvcall.h>
#include <asm/synch.h>
#include <asm/ppc-opcode.h>
#include <asm/kvm_host.h>
#include <asm/udbg.h>
+#include <asm/iommu.h>
+#include <asm/tce.h>
+#include <asm/iommu.h>
#define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64))
-/* WARNING: This will be called in real-mode on HV KVM and virtual
+/*
+ * Finds a TCE table descriptor by LIOBN.
+ *
+ * WARNING: This will be called in real or virtual mode on HV KVM and virtual
* mode on PR KVM
*/
-long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
- unsigned long ioba, unsigned long tce)
+struct kvmppc_spapr_tce_table *kvmppc_find_table(struct kvm_vcpu *vcpu,
+ unsigned long liobn)
{
struct kvm *kvm = vcpu->kvm;
struct kvmppc_spapr_tce_table *stt;
+ list_for_each_entry_lockless(stt, &kvm->arch.spapr_tce_tables, list)
+ if (stt->liobn == liobn)
+ return stt;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(kvmppc_find_table);
+
+/*
+ * Validates IO address.
+ *
+ * WARNING: This will be called in real-mode on HV KVM and virtual
+ * mode on PR KVM
+ */
+long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
+ unsigned long ioba, unsigned long npages)
+{
+ unsigned long mask = (1ULL << stt->page_shift) - 1;
+ unsigned long idx = ioba >> stt->page_shift;
+
+ if ((ioba & mask) || (idx < stt->offset) ||
+ (idx - stt->offset + npages > stt->size) ||
+ (idx + npages < idx))
+ return H_PARAMETER;
+
+ return H_SUCCESS;
+}
+EXPORT_SYMBOL_GPL(kvmppc_ioba_validate);
+
+/*
+ * Validates TCE address.
+ * At the moment flags and page mask are validated.
+ * As the host kernel does not access those addresses (just puts them
+ * to the table and user space is supposed to process them), we can skip
+ * checking other things (such as TCE is a guest RAM address or the page
+ * was actually allocated).
+ *
+ * WARNING: This will be called in real-mode on HV KVM and virtual
+ * mode on PR KVM
+ */
+long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt, unsigned long tce)
+{
+ unsigned long page_mask = ~((1ULL << stt->page_shift) - 1);
+ unsigned long mask = ~(page_mask | TCE_PCI_WRITE | TCE_PCI_READ);
+
+ if (tce & mask)
+ return H_PARAMETER;
+
+ return H_SUCCESS;
+}
+EXPORT_SYMBOL_GPL(kvmppc_tce_validate);
+
+/* Note on the use of page_address() in real mode,
+ *
+ * It is safe to use page_address() in real mode on ppc64 because
+ * page_address() is always defined as lowmem_page_address()
+ * which returns __va(PFN_PHYS(page_to_pfn(page))) which is arithmetic
+ * operation and does not access page struct.
+ *
+ * Theoretically page_address() could be defined different
+ * but either WANT_PAGE_VIRTUAL or HASHED_PAGE_VIRTUAL
+ * would have to be enabled.
+ * WANT_PAGE_VIRTUAL is never enabled on ppc32/ppc64,
+ * HASHED_PAGE_VIRTUAL could be enabled for ppc32 only and only
+ * if CONFIG_HIGHMEM is defined. As CONFIG_SPARSEMEM_VMEMMAP
+ * is not expected to be enabled on ppc32, page_address()
+ * is safe for ppc32 as well.
+ *
+ * WARNING: This will be called in real-mode on HV KVM and virtual
+ * mode on PR KVM
+ */
+static u64 *kvmppc_page_address(struct page *page)
+{
+#if defined(HASHED_PAGE_VIRTUAL) || defined(WANT_PAGE_VIRTUAL)
+#error TODO: fix to avoid page_address() here
+#endif
+ return (u64 *) page_address(page);
+}
+
+/*
+ * Handles TCE requests for emulated devices.
+ * Puts guest TCE values to the table and expects user space to convert them.
+ * Called in both real and virtual modes.
+ * Cannot fail so kvmppc_tce_validate must be called before it.
+ *
+ * WARNING: This will be called in real-mode on HV KVM and virtual
+ * mode on PR KVM
+ */
+void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
+ unsigned long idx, unsigned long tce)
+{
+ struct page *page;
+ u64 *tbl;
+
+ idx -= stt->offset;
+ page = stt->pages[idx / TCES_PER_PAGE];
+ tbl = kvmppc_page_address(page);
+
+ tbl[idx % TCES_PER_PAGE] = tce;
+}
+EXPORT_SYMBOL_GPL(kvmppc_tce_put);
+
+long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
+ unsigned long *ua, unsigned long **prmap)
+{
+ unsigned long gfn = gpa >> PAGE_SHIFT;
+ struct kvm_memory_slot *memslot;
+
+ memslot = search_memslots(kvm_memslots(kvm), gfn);
+ if (!memslot)
+ return -EINVAL;
+
+ *ua = __gfn_to_hva_memslot(memslot, gfn) |
+ (gpa & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
+
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+ if (prmap)
+ *prmap = &memslot->arch.rmap[gfn - memslot->base_gfn];
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvmppc_gpa_to_ua);
+
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
+ unsigned long ioba, unsigned long tce)
+{
+ struct kvmppc_spapr_tce_table *stt = kvmppc_find_table(vcpu, liobn);
+ long ret;
+
/* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
/* liobn, ioba, tce); */
- list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
- if (stt->liobn == liobn) {
- unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
- struct page *page;
- u64 *tbl;
-
- /* udbg_printf("H_PUT_TCE: liobn 0x%lx => stt=%p window_size=0x%x\n", */
- /* liobn, stt, stt->window_size); */
- if (ioba >= stt->window_size)
- return H_PARAMETER;
-
- page = stt->pages[idx / TCES_PER_PAGE];
- tbl = (u64 *)page_address(page);
-
- /* FIXME: Need to validate the TCE itself */
- /* udbg_printf("tce @ %p\n", &tbl[idx % TCES_PER_PAGE]); */
- tbl[idx % TCES_PER_PAGE] = tce;
- return H_SUCCESS;
- }
- }
+ if (!stt)
+ return H_TOO_HARD;
+
+ ret = kvmppc_ioba_validate(stt, ioba, 1);
+ if (ret != H_SUCCESS)
+ return ret;
- /* Didn't find the liobn, punt it to userspace */
- return H_TOO_HARD;
+ ret = kvmppc_tce_validate(stt, tce);
+ if (ret != H_SUCCESS)
+ return ret;
+
+ kvmppc_tce_put(stt, ioba >> stt->page_shift, tce);
+
+ return H_SUCCESS;
}
EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
-long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
- unsigned long ioba)
+static long kvmppc_rm_ua_to_hpa(struct kvm_vcpu *vcpu,
+ unsigned long ua, unsigned long *phpa)
+{
+ pte_t *ptep, pte;
+ unsigned shift = 0;
+
+ ptep = __find_linux_pte_or_hugepte(vcpu->arch.pgdir, ua, NULL, &shift);
+ if (!ptep || !pte_present(*ptep))
+ return -ENXIO;
+ pte = *ptep;
+
+ if (!shift)
+ shift = PAGE_SHIFT;
+
+ /* Avoid handling anything potentially complicated in realmode */
+ if (shift > PAGE_SHIFT)
+ return -EAGAIN;
+
+ if (!pte_young(pte))
+ return -EAGAIN;
+
+ *phpa = (pte_pfn(pte) << PAGE_SHIFT) | (ua & ((1ULL << shift) - 1)) |
+ (ua & ~PAGE_MASK);
+
+ return 0;
+}
+
+long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
+ unsigned long liobn, unsigned long ioba,
+ unsigned long tce_list, unsigned long npages)
{
- struct kvm *kvm = vcpu->kvm;
struct kvmppc_spapr_tce_table *stt;
+ long i, ret = H_SUCCESS;
+ unsigned long tces, entry, ua = 0;
+ unsigned long *rmap = NULL;
+
+ stt = kvmppc_find_table(vcpu, liobn);
+ if (!stt)
+ return H_TOO_HARD;
+
+ entry = ioba >> stt->page_shift;
+ /*
+ * The spec says that the maximum size of the list is 512 TCEs
+ * so the whole table addressed resides in 4K page
+ */
+ if (npages > 512)
+ return H_PARAMETER;
+
+ if (tce_list & (SZ_4K - 1))
+ return H_PARAMETER;
+
+ ret = kvmppc_ioba_validate(stt, ioba, npages);
+ if (ret != H_SUCCESS)
+ return ret;
- list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
- if (stt->liobn == liobn) {
- unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
- struct page *page;
- u64 *tbl;
+ if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, &rmap))
+ return H_TOO_HARD;
- if (ioba >= stt->window_size)
- return H_PARAMETER;
+ rmap = (void *) vmalloc_to_phys(rmap);
- page = stt->pages[idx / TCES_PER_PAGE];
- tbl = (u64 *)page_address(page);
+ /*
+ * Synchronize with the MMU notifier callbacks in
+ * book3s_64_mmu_hv.c (kvm_unmap_hva_hv etc.).
+ * While we have the rmap lock, code running on other CPUs
+ * cannot finish unmapping the host real page that backs
+ * this guest real page, so we are OK to access the host
+ * real page.
+ */
+ lock_rmap(rmap);
+ if (kvmppc_rm_ua_to_hpa(vcpu, ua, &tces)) {
+ ret = H_TOO_HARD;
+ goto unlock_exit;
+ }
+
+ for (i = 0; i < npages; ++i) {
+ unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
+
+ ret = kvmppc_tce_validate(stt, tce);
+ if (ret != H_SUCCESS)
+ goto unlock_exit;
- vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE];
- return H_SUCCESS;
- }
+ kvmppc_tce_put(stt, entry + i, tce);
}
- /* Didn't find the liobn, punt it to userspace */
- return H_TOO_HARD;
+unlock_exit:
+ unlock_rmap(rmap);
+
+ return ret;
+}
+
+long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
+ unsigned long liobn, unsigned long ioba,
+ unsigned long tce_value, unsigned long npages)
+{
+ struct kvmppc_spapr_tce_table *stt;
+ long i, ret;
+
+ stt = kvmppc_find_table(vcpu, liobn);
+ if (!stt)
+ return H_TOO_HARD;
+
+ ret = kvmppc_ioba_validate(stt, ioba, npages);
+ if (ret != H_SUCCESS)
+ return ret;
+
+ /* Check permission bits only to allow userspace poison TCE for debug */
+ if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ))
+ return H_PARAMETER;
+
+ for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
+ kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
+
+ return H_SUCCESS;
+}
+EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce);
+
+long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
+ unsigned long ioba)
+{
+ struct kvmppc_spapr_tce_table *stt = kvmppc_find_table(vcpu, liobn);
+ long ret;
+ unsigned long idx;
+ struct page *page;
+ u64 *tbl;
+
+ if (!stt)
+ return H_TOO_HARD;
+
+ ret = kvmppc_ioba_validate(stt, ioba, 1);
+ if (ret != H_SUCCESS)
+ return ret;
+
+ idx = (ioba >> stt->page_shift) - stt->offset;
+ page = stt->pages[idx / TCES_PER_PAGE];
+ tbl = (u64 *)page_address(page);
+
+ vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE];
+
+ return H_SUCCESS;
}
EXPORT_SYMBOL_GPL(kvmppc_h_get_tce);
+
+#endif /* KVM_BOOK3S_HV_POSSIBLE */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 9c26c5a..84fb4fc 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -81,6 +81,17 @@ static int target_smt_mode;
module_param(target_smt_mode, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(target_smt_mode, "Target threads per core (0 = max)");
+#ifdef CONFIG_KVM_XICS
+static struct kernel_param_ops module_param_ops = {
+ .set = param_set_int,
+ .get = param_get_int,
+};
+
+module_param_cb(h_ipi_redirect, &module_param_ops, &h_ipi_redirect,
+ S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
+#endif
+
static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
@@ -114,11 +125,11 @@ static bool kvmppc_ipi_thread(int cpu)
static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
{
int cpu;
- wait_queue_head_t *wqp;
+ struct swait_queue_head *wqp;
wqp = kvm_arch_vcpu_wq(vcpu);
- if (waitqueue_active(wqp)) {
- wake_up_interruptible(wqp);
+ if (swait_active(wqp)) {
+ swake_up(wqp);
++vcpu->stat.halt_wakeup;
}
@@ -224,6 +235,12 @@ static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
{
+ /*
+ * Check for illegal transactional state bit combination
+ * and if we find it, force the TS field to a safe state.
+ */
+ if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
+ msr &= ~MSR_TS_MASK;
vcpu->arch.shregs.msr = msr;
kvmppc_end_cede(vcpu);
}
@@ -308,16 +325,10 @@ static void kvmppc_dump_regs(struct kvm_vcpu *vcpu)
static struct kvm_vcpu *kvmppc_find_vcpu(struct kvm *kvm, int id)
{
- int r;
- struct kvm_vcpu *v, *ret = NULL;
+ struct kvm_vcpu *ret;
mutex_lock(&kvm->lock);
- kvm_for_each_vcpu(r, v, kvm) {
- if (v->vcpu_id == id) {
- ret = v;
- break;
- }
- }
+ ret = kvm_get_vcpu_by_id(kvm, id);
mutex_unlock(&kvm->lock);
return ret;
}
@@ -701,8 +712,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
tvcpu->arch.prodded = 1;
smp_mb();
if (vcpu->arch.ceded) {
- if (waitqueue_active(&vcpu->wq)) {
- wake_up_interruptible(&vcpu->wq);
+ if (swait_active(&vcpu->wq)) {
+ swake_up(&vcpu->wq);
vcpu->stat.halt_wakeup++;
}
}
@@ -768,7 +779,31 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
if (kvmppc_xics_enabled(vcpu)) {
ret = kvmppc_xics_hcall(vcpu, req);
break;
- } /* fallthrough */
+ }
+ return RESUME_HOST;
+ case H_PUT_TCE:
+ ret = kvmppc_h_put_tce(vcpu, kvmppc_get_gpr(vcpu, 4),
+ kvmppc_get_gpr(vcpu, 5),
+ kvmppc_get_gpr(vcpu, 6));
+ if (ret == H_TOO_HARD)
+ return RESUME_HOST;
+ break;
+ case H_PUT_TCE_INDIRECT:
+ ret = kvmppc_h_put_tce_indirect(vcpu, kvmppc_get_gpr(vcpu, 4),
+ kvmppc_get_gpr(vcpu, 5),
+ kvmppc_get_gpr(vcpu, 6),
+ kvmppc_get_gpr(vcpu, 7));
+ if (ret == H_TOO_HARD)
+ return RESUME_HOST;
+ break;
+ case H_STUFF_TCE:
+ ret = kvmppc_h_stuff_tce(vcpu, kvmppc_get_gpr(vcpu, 4),
+ kvmppc_get_gpr(vcpu, 5),
+ kvmppc_get_gpr(vcpu, 6),
+ kvmppc_get_gpr(vcpu, 7));
+ if (ret == H_TOO_HARD)
+ return RESUME_HOST;
+ break;
default:
return RESUME_HOST;
}
@@ -833,6 +868,24 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
vcpu->stat.sum_exits++;
+ /*
+ * This can happen if an interrupt occurs in the last stages
+ * of guest entry or the first stages of guest exit (i.e. after
+ * setting paca->kvm_hstate.in_guest to KVM_GUEST_MODE_GUEST_HV
+ * and before setting it to KVM_GUEST_MODE_HOST_HV).
+ * That can happen due to a bug, or due to a machine check
+ * occurring at just the wrong time.
+ */
+ if (vcpu->arch.shregs.msr & MSR_HV) {
+ printk(KERN_EMERG "KVM trap in HV mode!\n");
+ printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
+ vcpu->arch.trap, kvmppc_get_pc(vcpu),
+ vcpu->arch.shregs.msr);
+ kvmppc_dump_regs(vcpu);
+ run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+ run->hw.hardware_exit_reason = vcpu->arch.trap;
+ return RESUME_HOST;
+ }
run->exit_reason = KVM_EXIT_UNKNOWN;
run->ready_for_interrupt_injection = 1;
switch (vcpu->arch.trap) {
@@ -1441,7 +1494,7 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core)
INIT_LIST_HEAD(&vcore->runnable_threads);
spin_lock_init(&vcore->lock);
spin_lock_init(&vcore->stoltb_lock);
- init_waitqueue_head(&vcore->wq);
+ init_swait_queue_head(&vcore->wq);
vcore->preempt_tb = TB_NIL;
vcore->lpcr = kvm->arch.lpcr;
vcore->first_vcpuid = core * threads_per_subcore;
@@ -2019,7 +2072,7 @@ static bool can_split_piggybacked_subcores(struct core_info *cip)
return false;
n_subcores += (cip->subcore_threads[sub] - 1) >> 1;
}
- if (n_subcores > 3 || large_sub < 0)
+ if (large_sub < 0 || !subcore_config_ok(n_subcores + 1, 2))
return false;
/*
@@ -2261,6 +2314,46 @@ static void post_guest_process(struct kvmppc_vcore *vc, bool is_master)
}
/*
+ * Clear core from the list of active host cores as we are about to
+ * enter the guest. Only do this if it is the primary thread of the
+ * core (not if a subcore) that is entering the guest.
+ */
+static inline void kvmppc_clear_host_core(int cpu)
+{
+ int core;
+
+ if (!kvmppc_host_rm_ops_hv || cpu_thread_in_core(cpu))
+ return;
+ /*
+ * Memory barrier can be omitted here as we will do a smp_wmb()
+ * later in kvmppc_start_thread and we need ensure that state is
+ * visible to other CPUs only after we enter guest.
+ */
+ core = cpu >> threads_shift;
+ kvmppc_host_rm_ops_hv->rm_core[core].rm_state.in_host = 0;
+}
+
+/*
+ * Advertise this core as an active host core since we exited the guest
+ * Only need to do this if it is the primary thread of the core that is
+ * exiting.
+ */
+static inline void kvmppc_set_host_core(int cpu)
+{
+ int core;
+
+ if (!kvmppc_host_rm_ops_hv || cpu_thread_in_core(cpu))
+ return;
+
+ /*
+ * Memory barrier can be omitted here because we do a spin_unlock
+ * immediately after this which provides the memory barrier.
+ */
+ core = cpu >> threads_shift;
+ kvmppc_host_rm_ops_hv->rm_core[core].rm_state.in_host = 1;
+}
+
+/*
* Run a set of guest threads on a physical core.
* Called with vc->lock held.
*/
@@ -2372,6 +2465,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
}
}
+ kvmppc_clear_host_core(pcpu);
+
/* Start all the threads */
active = 0;
for (sub = 0; sub < core_info.n_subcores; ++sub) {
@@ -2468,6 +2563,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
kvmppc_ipi_thread(pcpu + i);
}
+ kvmppc_set_host_core(pcpu);
+
spin_unlock(&vc->lock);
/* make sure updates to secondary vcpu structs are visible now */
@@ -2513,10 +2610,9 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
{
struct kvm_vcpu *vcpu;
int do_sleep = 1;
+ DECLARE_SWAITQUEUE(wait);
- DEFINE_WAIT(wait);
-
- prepare_to_wait(&vc->wq, &wait, TASK_INTERRUPTIBLE);
+ prepare_to_swait(&vc->wq, &wait, TASK_INTERRUPTIBLE);
/*
* Check one last time for pending exceptions and ceded state after
@@ -2530,7 +2626,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
}
if (!do_sleep) {
- finish_wait(&vc->wq, &wait);
+ finish_swait(&vc->wq, &wait);
return;
}
@@ -2538,7 +2634,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc)
trace_kvmppc_vcore_blocked(vc, 0);
spin_unlock(&vc->lock);
schedule();
- finish_wait(&vc->wq, &wait);
+ finish_swait(&vc->wq, &wait);
spin_lock(&vc->lock);
vc->vcore_state = VCORE_INACTIVE;
trace_kvmppc_vcore_blocked(vc, 1);
@@ -2594,7 +2690,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
kvmppc_start_thread(vcpu, vc);
trace_kvm_guest_enter(vcpu);
} else if (vc->vcore_state == VCORE_SLEEPING) {
- wake_up(&vc->wq);
+ swake_up(&vc->wq);
}
}
@@ -2700,9 +2796,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
goto out;
}
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
- flush_vsx_to_thread(current);
+ flush_all_to_thread(current);
+
vcpu->arch.wqp = &vcpu->arch.vcore->wq;
vcpu->arch.pgdir = current->mm->pgd;
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
@@ -2967,6 +3062,114 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
goto out_srcu;
}
+#ifdef CONFIG_KVM_XICS
+static int kvmppc_cpu_notify(struct notifier_block *self, unsigned long action,
+ void *hcpu)
+{
+ unsigned long cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ kvmppc_set_host_core(cpu);
+ break;
+
+#ifdef CONFIG_HOTPLUG_CPU
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
+ kvmppc_clear_host_core(cpu);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block kvmppc_cpu_notifier = {
+ .notifier_call = kvmppc_cpu_notify,
+};
+
+/*
+ * Allocate a per-core structure for managing state about which cores are
+ * running in the host versus the guest and for exchanging data between
+ * real mode KVM and CPU running in the host.
+ * This is only done for the first VM.
+ * The allocated structure stays even if all VMs have stopped.
+ * It is only freed when the kvm-hv module is unloaded.
+ * It's OK for this routine to fail, we just don't support host
+ * core operations like redirecting H_IPI wakeups.
+ */
+void kvmppc_alloc_host_rm_ops(void)
+{
+ struct kvmppc_host_rm_ops *ops;
+ unsigned long l_ops;
+ int cpu, core;
+ int size;
+
+ /* Not the first time here ? */
+ if (kvmppc_host_rm_ops_hv != NULL)
+ return;
+
+ ops = kzalloc(sizeof(struct kvmppc_host_rm_ops), GFP_KERNEL);
+ if (!ops)
+ return;
+
+ size = cpu_nr_cores() * sizeof(struct kvmppc_host_rm_core);
+ ops->rm_core = kzalloc(size, GFP_KERNEL);
+
+ if (!ops->rm_core) {
+ kfree(ops);
+ return;
+ }
+
+ get_online_cpus();
+
+ for (cpu = 0; cpu < nr_cpu_ids; cpu += threads_per_core) {
+ if (!cpu_online(cpu))
+ continue;
+
+ core = cpu >> threads_shift;
+ ops->rm_core[core].rm_state.in_host = 1;
+ }
+
+ ops->vcpu_kick = kvmppc_fast_vcpu_kick_hv;
+
+ /*
+ * Make the contents of the kvmppc_host_rm_ops structure visible
+ * to other CPUs before we assign it to the global variable.
+ * Do an atomic assignment (no locks used here), but if someone
+ * beats us to it, just free our copy and return.
+ */
+ smp_wmb();
+ l_ops = (unsigned long) ops;
+
+ if (cmpxchg64((unsigned long *)&kvmppc_host_rm_ops_hv, 0, l_ops)) {
+ put_online_cpus();
+ kfree(ops->rm_core);
+ kfree(ops);
+ return;
+ }
+
+ register_cpu_notifier(&kvmppc_cpu_notifier);
+
+ put_online_cpus();
+}
+
+void kvmppc_free_host_rm_ops(void)
+{
+ if (kvmppc_host_rm_ops_hv) {
+ unregister_cpu_notifier(&kvmppc_cpu_notifier);
+ kfree(kvmppc_host_rm_ops_hv->rm_core);
+ kfree(kvmppc_host_rm_ops_hv);
+ kvmppc_host_rm_ops_hv = NULL;
+ }
+}
+#endif
+
static int kvmppc_core_init_vm_hv(struct kvm *kvm)
{
unsigned long lpcr, lpid;
@@ -2979,6 +3182,8 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
return -ENOMEM;
kvm->arch.lpid = lpid;
+ kvmppc_alloc_host_rm_ops();
+
/*
* Since we don't flush the TLB when tearing down a VM,
* and this lpid might have previously been used,
@@ -3212,6 +3417,7 @@ static int kvmppc_book3s_init_hv(void)
static void kvmppc_book3s_exit_hv(void)
{
+ kvmppc_free_host_rm_ops();
kvmppc_hv_ops = NULL;
}
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index fd7006b..5f0380d 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -283,3 +283,6 @@ void kvmhv_commence_exit(int trap)
kvmhv_interrupt_vcore(vc, ee);
}
}
+
+struct kvmppc_host_rm_ops *kvmppc_host_rm_ops_hv;
+EXPORT_SYMBOL_GPL(kvmppc_host_rm_ops_hv);
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index c1df9bb..4cb8db0 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -17,7 +17,7 @@
#include <asm/tlbflush.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#include <asm/hvcall.h>
#include <asm/synch.h>
#include <asm/ppc-opcode.h>
@@ -32,7 +32,7 @@ static void *real_vmalloc_addr(void *x)
* So don't worry about THP collapse/split. Called
* Only in realmode, hence won't need irq_save/restore.
*/
- p = __find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL);
+ p = __find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL, NULL);
if (!p || !pte_present(*p))
return NULL;
addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK);
@@ -221,10 +221,12 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
* retry via mmu_notifier_retry.
*/
if (realmode)
- ptep = __find_linux_pte_or_hugepte(pgdir, hva, &hpage_shift);
+ ptep = __find_linux_pte_or_hugepte(pgdir, hva, NULL,
+ &hpage_shift);
else {
local_irq_save(irq_flags);
- ptep = find_linux_pte_or_hugepte(pgdir, hva, &hpage_shift);
+ ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL,
+ &hpage_shift);
}
if (ptep) {
pte_t pte;
@@ -470,6 +472,8 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,
note_hpte_modification(kvm, rev);
unlock_hpte(hpte, 0);
+ if (v & HPTE_V_ABSENT)
+ v = (v & ~HPTE_V_ABSENT) | HPTE_V_VALID;
hpret[0] = v;
hpret[1] = r;
return H_SUCCESS;
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index 24f5807..980d8a6 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -17,12 +17,16 @@
#include <asm/xics.h>
#include <asm/debug.h>
#include <asm/synch.h>
+#include <asm/cputhreads.h>
#include <asm/ppc-opcode.h>
#include "book3s_xics.h"
#define DEBUG_PASSUP
+int h_ipi_redirect = 1;
+EXPORT_SYMBOL(h_ipi_redirect);
+
static void icp_rm_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
u32 new_irq);
@@ -50,11 +54,84 @@ static void ics_rm_check_resend(struct kvmppc_xics *xics,
/* -- ICP routines -- */
+#ifdef CONFIG_SMP
+static inline void icp_send_hcore_msg(int hcore, struct kvm_vcpu *vcpu)
+{
+ int hcpu;
+
+ hcpu = hcore << threads_shift;
+ kvmppc_host_rm_ops_hv->rm_core[hcore].rm_data = vcpu;
+ smp_muxed_ipi_set_message(hcpu, PPC_MSG_RM_HOST_ACTION);
+ icp_native_cause_ipi_rm(hcpu);
+}
+#else
+static inline void icp_send_hcore_msg(int hcore, struct kvm_vcpu *vcpu) { }
+#endif
+
+/*
+ * We start the search from our current CPU Id in the core map
+ * and go in a circle until we get back to our ID looking for a
+ * core that is running in host context and that hasn't already
+ * been targeted for another rm_host_ops.
+ *
+ * In the future, could consider using a fairer algorithm (one
+ * that distributes the IPIs better)
+ *
+ * Returns -1, if no CPU could be found in the host
+ * Else, returns a CPU Id which has been reserved for use
+ */
+static inline int grab_next_hostcore(int start,
+ struct kvmppc_host_rm_core *rm_core, int max, int action)
+{
+ bool success;
+ int core;
+ union kvmppc_rm_state old, new;
+
+ for (core = start + 1; core < max; core++) {
+ old = new = READ_ONCE(rm_core[core].rm_state);
+
+ if (!old.in_host || old.rm_action)
+ continue;
+
+ /* Try to grab this host core if not taken already. */
+ new.rm_action = action;
+
+ success = cmpxchg64(&rm_core[core].rm_state.raw,
+ old.raw, new.raw) == old.raw;
+ if (success) {
+ /*
+ * Make sure that the store to the rm_action is made
+ * visible before we return to caller (and the
+ * subsequent store to rm_data) to synchronize with
+ * the IPI handler.
+ */
+ smp_wmb();
+ return core;
+ }
+ }
+
+ return -1;
+}
+
+static inline int find_available_hostcore(int action)
+{
+ int core;
+ int my_core = smp_processor_id() >> threads_shift;
+ struct kvmppc_host_rm_core *rm_core = kvmppc_host_rm_ops_hv->rm_core;
+
+ core = grab_next_hostcore(my_core, rm_core, cpu_nr_cores(), action);
+ if (core == -1)
+ core = grab_next_hostcore(core, rm_core, my_core, action);
+
+ return core;
+}
+
static void icp_rm_set_vcpu_irq(struct kvm_vcpu *vcpu,
struct kvm_vcpu *this_vcpu)
{
struct kvmppc_icp *this_icp = this_vcpu->arch.icp;
int cpu;
+ int hcore;
/* Mark the target VCPU as having an interrupt pending */
vcpu->stat.queue_intr++;
@@ -66,11 +143,22 @@ static void icp_rm_set_vcpu_irq(struct kvm_vcpu *vcpu,
return;
}
- /* Check if the core is loaded, if not, too hard */
+ /*
+ * Check if the core is loaded,
+ * if not, find an available host core to post to wake the VCPU,
+ * if we can't find one, set up state to eventually return too hard.
+ */
cpu = vcpu->arch.thread_cpu;
if (cpu < 0 || cpu >= nr_cpu_ids) {
- this_icp->rm_action |= XICS_RM_KICK_VCPU;
- this_icp->rm_kick_target = vcpu;
+ hcore = -1;
+ if (kvmppc_host_rm_ops_hv && h_ipi_redirect)
+ hcore = find_available_hostcore(XICS_RM_KICK_VCPU);
+ if (hcore != -1) {
+ icp_send_hcore_msg(hcore, vcpu);
+ } else {
+ this_icp->rm_action |= XICS_RM_KICK_VCPU;
+ this_icp->rm_kick_target = vcpu;
+ }
return;
}
@@ -623,3 +711,40 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
bail:
return check_too_hard(xics, icp);
}
+
+/* --- Non-real mode XICS-related built-in routines --- */
+
+/**
+ * Host Operations poked by RM KVM
+ */
+static void rm_host_ipi_action(int action, void *data)
+{
+ switch (action) {
+ case XICS_RM_KICK_VCPU:
+ kvmppc_host_rm_ops_hv->vcpu_kick(data);
+ break;
+ default:
+ WARN(1, "Unexpected rm_action=%d data=%p\n", action, data);
+ break;
+ }
+
+}
+
+void kvmppc_xics_ipi_action(void)
+{
+ int core;
+ unsigned int cpu = smp_processor_id();
+ struct kvmppc_host_rm_core *rm_corep;
+
+ core = cpu >> threads_shift;
+ rm_corep = &kvmppc_host_rm_ops_hv->rm_core[core];
+
+ if (rm_corep->rm_data) {
+ rm_host_ipi_action(rm_corep->rm_state.rm_action,
+ rm_corep->rm_data);
+ /* Order these stores against the real mode KVM */
+ rm_corep->rm_data = NULL;
+ smp_wmb();
+ rm_corep->rm_state.rm_action = 0;
+ }
+}
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b98889e..62ea3c6 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -27,7 +27,7 @@
#include <asm/asm-offsets.h>
#include <asm/exception-64s.h>
#include <asm/kvm_book3s_asm.h>
-#include <asm/mmu-hash64.h>
+#include <asm/book3s/64/mmu-hash.h>
#include <asm/tm.h>
#define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM)
@@ -150,6 +150,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
beq 11f
+ cmpwi r12, BOOK3S_INTERRUPT_H_DOORBELL
+ beq 15f /* Invoke the H_DOORBELL handler */
cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI
beq cr2, 14f /* HMI check */
@@ -174,6 +176,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtspr SPRN_HSRR1, r7
b hmi_exception_after_realmode
+15: mtspr SPRN_HSRR0, r8
+ mtspr SPRN_HSRR1, r7
+ ba 0xe80
+
kvmppc_primary_no_guest:
/* We handle this much like a ceded vcpu */
/* put the HDEC into the DEC, since HDEC interrupts don't wake us */
@@ -1364,6 +1370,20 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
std r6, VCPU_ACOP(r9)
stw r7, VCPU_GUEST_PID(r9)
std r8, VCPU_WORT(r9)
+ /*
+ * Restore various registers to 0, where non-zero values
+ * set by the guest could disrupt the host.
+ */
+ li r0, 0
+ mtspr SPRN_IAMR, r0
+ mtspr SPRN_CIABR, r0
+ mtspr SPRN_DAWRX, r0
+ mtspr SPRN_TCSCR, r0
+ mtspr SPRN_WORT, r0
+ /* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */
+ li r0, 1
+ sldi r0, r0, 31
+ mtspr SPRN_MMCRS, r0
8:
/* Save and reset AMR and UAMOR before turning on the MMU */
@@ -1743,7 +1763,8 @@ kvmppc_hdsi:
beq 3f
clrrdi r0, r4, 28
PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
- bne 1f /* if no SLB entry found */
+ li r0, BOOK3S_INTERRUPT_DATA_SEGMENT
+ bne 7f /* if no SLB entry found */
4: std r4, VCPU_FAULT_DAR(r9)
stw r6, VCPU_FAULT_DSISR(r9)
@@ -1762,14 +1783,15 @@ kvmppc_hdsi:
cmpdi r3, -2 /* MMIO emulation; need instr word */
beq 2f
- /* Synthesize a DSI for the guest */
+ /* Synthesize a DSI (or DSegI) for the guest */
ld r4, VCPU_FAULT_DAR(r9)
mr r6, r3
-1: mtspr SPRN_DAR, r4
+1: li r0, BOOK3S_INTERRUPT_DATA_STORAGE
mtspr SPRN_DSISR, r6
+7: mtspr SPRN_DAR, r4
mtspr SPRN_SRR0, r10
mtspr SPRN_SRR1, r11
- li r10, BOOK3S_INTERRUPT_DATA_STORAGE
+ mr r10, r0
bl kvmppc_msr_interrupt
fast_interrupt_c_return:
6: ld r7, VCPU_CTR(r9)
@@ -1817,7 +1839,8 @@ kvmppc_hisi:
beq 3f
clrrdi r0, r10, 28
PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
- bne 1f /* if no SLB entry found */
+ li r0, BOOK3S_INTERRUPT_INST_SEGMENT
+ bne 7f /* if no SLB entry found */
4:
/* Search the hash table. */
mr r3, r9 /* vcpu pointer */
@@ -1834,11 +1857,12 @@ kvmppc_hisi:
cmpdi r3, -1 /* handle in kernel mode */
beq guest_exit_cont
- /* Synthesize an ISI for the guest */
+ /* Synthesize an ISI (or ISegI) for the guest */
mr r11, r3
-1: mtspr SPRN_SRR0, r10
+1: li r0, BOOK3S_INTERRUPT_INST_STORAGE
+7: mtspr SPRN_SRR0, r10
mtspr SPRN_SRR1, r11
- li r10, BOOK3S_INTERRUPT_INST_STORAGE
+ mr r10, r0
bl kvmppc_msr_interrupt
b fast_interrupt_c_return
@@ -1996,8 +2020,8 @@ hcall_real_table:
.long 0 /* 0x12c */
.long 0 /* 0x130 */
.long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table
- .long 0 /* 0x138 */
- .long 0 /* 0x13c */
+ .long DOTSYM(kvmppc_h_stuff_tce) - hcall_real_table
+ .long DOTSYM(kvmppc_rm_h_put_tce_indirect) - hcall_real_table
.long 0 /* 0x140 */
.long 0 /* 0x144 */
.long 0 /* 0x148 */
@@ -2143,7 +2167,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
/* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */
2: rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW
- rlwimi r5, r4, 1, DAWRX_WT
+ rlwimi r5, r4, 2, DAWRX_WT
clrrdi r4, r4, 3
std r4, VCPU_DAWR(r3)
std r5, VCPU_DAWRX(r3)
@@ -2377,7 +2401,6 @@ machine_check_realmode:
mr r3, r9 /* get vcpu pointer */
bl kvmppc_realmode_machine_check
nop
- cmpdi r3, 0 /* Did we handle MCE ? */
ld r9, HSTATE_KVM_VCPU(r13)
li r12, BOOK3S_INTERRUPT_MACHINE_CHECK
/*
@@ -2390,13 +2413,20 @@ machine_check_realmode:
* The old code used to return to host for unhandled errors which
* was causing guest to hang with soft lockups inside guest and
* makes it difficult to recover guest instance.
+ *
+ * if we receive machine check with MSR(RI=0) then deliver it to
+ * guest as machine check causing guest to crash.
*/
- ld r10, VCPU_PC(r9)
ld r11, VCPU_MSR(r9)
+ rldicl. r0, r11, 64-MSR_HV_LG, 63 /* check if it happened in HV mode */
+ bne mc_cont /* if so, exit to host */
+ andi. r10, r11, MSR_RI /* check for unrecoverable exception */
+ beq 1f /* Deliver a machine check to guest */
+ ld r10, VCPU_PC(r9)
+ cmpdi r3, 0 /* Did we handle MCE ? */
bne 2f /* Continue guest execution. */
/* If not, deliver a machine check. SRR0/1 are already set */
- li r10, BOOK3S_INTERRUPT_MACHINE_CHECK
- ld r11, VCPU_MSR(r9)
+1: li r10, BOOK3S_INTERRUPT_MACHINE_CHECK
bl kvmppc_msr_interrupt
2: b fast_interrupt_c_return
@@ -2436,14 +2466,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
/* hypervisor doorbell */
3: li r12, BOOK3S_INTERRUPT_H_DOORBELL
+
+ /*
+ * Clear the doorbell as we will invoke the handler
+ * explicitly in the guest exit path.
+ */
+ lis r6, (PPC_DBELL_SERVER << (63-36))@h
+ PPC_MSGCLR(6)
/* see if it's a host IPI */
li r3, 1
lbz r0, HSTATE_HOST_IPI(r13)
cmpwi r0, 0
bnelr
- /* if not, clear it and return -1 */
- lis r6, (PPC_DBELL_SERVER << (63-36))@h
- PPC_MSGCLR(6)
+ /* if not, return -1 */
li r3, -1
blr
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c
index a759d9a..eab96cf 100644
--- a/arch/powerpc/kvm/book3s_paired_singles.c
+++ b/arch/powerpc/kvm/book3s_paired_singles.c
@@ -1265,6 +1265,7 @@ int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu)
if (rcomp)
kvmppc_set_cr(vcpu, cr);
+ disable_kernel_fp();
preempt_enable();
return emulated;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 64891b0..95bceca 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -512,7 +512,7 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
put_page(hpage);
}
-static int kvmppc_visible_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
+static bool kvmppc_visible_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
{
ulong mp_pa = vcpu->arch.magic_page_pa;
@@ -521,7 +521,7 @@ static int kvmppc_visible_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
gpa &= ~0xFFFULL;
if (unlikely(mp_pa) && unlikely((mp_pa & KVM_PAM) == (gpa & KVM_PAM))) {
- return 1;
+ return true;
}
return kvm_is_visible_gfn(vcpu->kvm, gpa >> PAGE_SHIFT);
@@ -751,6 +751,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
preempt_disable();
enable_kernel_fp();
load_fp_state(&vcpu->arch.fp);
+ disable_kernel_fp();
t->fp_save_area = &vcpu->arch.fp;
preempt_enable();
}
@@ -760,6 +761,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
preempt_disable();
enable_kernel_altivec();
load_vr_state(&vcpu->arch.vr);
+ disable_kernel_altivec();
t->vr_save_area = &vcpu->arch.vr;
preempt_enable();
#endif
@@ -788,6 +790,7 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu)
preempt_disable();
enable_kernel_fp();
load_fp_state(&vcpu->arch.fp);
+ disable_kernel_fp();
preempt_enable();
}
#ifdef CONFIG_ALTIVEC
@@ -795,6 +798,7 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu)
preempt_disable();
enable_kernel_altivec();
load_vr_state(&vcpu->arch.vr);
+ disable_kernel_altivec();
preempt_enable();
}
#endif
@@ -1486,21 +1490,8 @@ static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
goto out;
/* interrupts now hard-disabled */
- /* Save FPU state in thread_struct */
- if (current->thread.regs->msr & MSR_FP)
- giveup_fpu(current);
-
-#ifdef CONFIG_ALTIVEC
- /* Save Altivec state in thread_struct */
- if (current->thread.regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif
-
-#ifdef CONFIG_VSX
- /* Save VSX state in thread_struct */
- if (current->thread.regs->msr & MSR_VSX)
- __giveup_vsx(current);
-#endif
+ /* Save FPU, Altivec and VSX state */
+ giveup_all(current);
/* Preload FPU if it's enabled */
if (kvmppc_get_msr(vcpu) & MSR_FP)
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c
index f2c75a1..02176fd 100644
--- a/arch/powerpc/kvm/book3s_pr_papr.c
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
@@ -280,6 +280,37 @@ static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
return EMULATE_DONE;
}
+static int kvmppc_h_pr_put_tce_indirect(struct kvm_vcpu *vcpu)
+{
+ unsigned long liobn = kvmppc_get_gpr(vcpu, 4);
+ unsigned long ioba = kvmppc_get_gpr(vcpu, 5);
+ unsigned long tce = kvmppc_get_gpr(vcpu, 6);
+ unsigned long npages = kvmppc_get_gpr(vcpu, 7);
+ long rc;
+
+ rc = kvmppc_h_put_tce_indirect(vcpu, liobn, ioba,
+ tce, npages);
+ if (rc == H_TOO_HARD)
+ return EMULATE_FAIL;
+ kvmppc_set_gpr(vcpu, 3, rc);
+ return EMULATE_DONE;
+}
+
+static int kvmppc_h_pr_stuff_tce(struct kvm_vcpu *vcpu)
+{
+ unsigned long liobn = kvmppc_get_gpr(vcpu, 4);
+ unsigned long ioba = kvmppc_get_gpr(vcpu, 5);
+ unsigned long tce_value = kvmppc_get_gpr(vcpu, 6);
+ unsigned long npages = kvmppc_get_gpr(vcpu, 7);
+ long rc;
+
+ rc = kvmppc_h_stuff_tce(vcpu, liobn, ioba, tce_value, npages);
+ if (rc == H_TOO_HARD)
+ return EMULATE_FAIL;
+ kvmppc_set_gpr(vcpu, 3, rc);
+ return EMULATE_DONE;
+}
+
static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
{
long rc = kvmppc_xics_hcall(vcpu, cmd);
@@ -306,6 +337,10 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
return kvmppc_h_pr_bulk_remove(vcpu);
case H_PUT_TCE:
return kvmppc_h_pr_put_tce(vcpu);
+ case H_PUT_TCE_INDIRECT:
+ return kvmppc_h_pr_put_tce_indirect(vcpu);
+ case H_STUFF_TCE:
+ return kvmppc_h_pr_stuff_tce(vcpu);
case H_CEDE:
kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);
kvm_vcpu_block(vcpu);
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index 905e94a..46871d5 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -432,7 +432,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
* the whole masked_pending business which is about not
* losing interrupts that occur while masked.
*
- * I don't differenciate normal deliveries and resends, this
+ * I don't differentiate normal deliveries and resends, this
* implementation will differ from PAPR and not lose such
* interrupts.
*/
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index fd58751..4d66f44 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -98,6 +98,7 @@ void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu)
preempt_disable();
enable_kernel_spe();
kvmppc_save_guest_spe(vcpu);
+ disable_kernel_spe();
vcpu->arch.shadow_msr &= ~MSR_SPE;
preempt_enable();
}
@@ -107,6 +108,7 @@ static void kvmppc_vcpu_enable_spe(struct kvm_vcpu *vcpu)
preempt_disable();
enable_kernel_spe();
kvmppc_load_guest_spe(vcpu);
+ disable_kernel_spe();
vcpu->arch.shadow_msr |= MSR_SPE;
preempt_enable();
}
@@ -141,6 +143,7 @@ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
if (!(current->thread.regs->msr & MSR_FP)) {
enable_kernel_fp();
load_fp_state(&vcpu->arch.fp);
+ disable_kernel_fp();
current->thread.fp_save_area = &vcpu->arch.fp;
current->thread.regs->msr |= MSR_FP;
}
@@ -182,6 +185,7 @@ static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu)
if (!(current->thread.regs->msr & MSR_VEC)) {
enable_kernel_altivec();
load_vr_state(&vcpu->arch.vr);
+ disable_kernel_altivec();
current->thread.vr_save_area = &vcpu->arch.vr;
current->thread.regs->msr |= MSR_VEC;
}
@@ -988,7 +992,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
kvmppc_restart_interrupt(vcpu, exit_nr);
/*
- * get last instruction before beeing preempted
+ * get last instruction before being preempted
* TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA
*/
switch (exit_nr) {
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index b29ce75..32fdab5 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -237,7 +237,8 @@ void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
struct kvm_book3e_206_tlb_entry *gtlbe)
{
struct vcpu_id_table *idt = vcpu_e500->idt;
- unsigned int pr, tid, ts, pid;
+ unsigned int pr, tid, ts;
+ int pid;
u32 val, eaddr;
unsigned long flags;
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 72920be..94f04fc 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -41,7 +41,7 @@ enum vcpu_ftr {
#define E500_TLB_MAS2_ATTR (0x7f)
struct tlbe_ref {
- pfn_t pfn; /* valid only for TLB0, except briefly */
+ kvm_pfn_t pfn; /* valid only for TLB0, except briefly */
unsigned int flags; /* E500_TLB_* */
};
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index ce7291c..990db69 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -15,6 +15,7 @@
#include <asm/kvm_ppc.h>
#include <asm/disassemble.h>
#include <asm/dbell.h>
+#include <asm/reg_booke.h>
#include "booke.h"
#include "e500.h"
@@ -22,6 +23,7 @@
#define XOP_DCBTLS 166
#define XOP_MSGSND 206
#define XOP_MSGCLR 238
+#define XOP_MFTMR 366
#define XOP_TLBIVAX 786
#define XOP_TLBSX 914
#define XOP_TLBRE 946
@@ -113,6 +115,19 @@ static int kvmppc_e500_emul_dcbtls(struct kvm_vcpu *vcpu)
return EMULATE_DONE;
}
+static int kvmppc_e500_emul_mftmr(struct kvm_vcpu *vcpu, unsigned int inst,
+ int rt)
+{
+ /* Expose one thread per vcpu */
+ if (get_tmrn(inst) == TMRN_TMCFG0) {
+ kvmppc_set_gpr(vcpu, rt,
+ 1 | (1 << TMRN_TMCFG0_NATHRD_SHIFT));
+ return EMULATE_DONE;
+ }
+
+ return EMULATE_FAIL;
+}
+
int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int inst, int *advance)
{
@@ -165,6 +180,10 @@ int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
break;
+ case XOP_MFTMR:
+ emulated = kvmppc_e500_emul_mftmr(vcpu, inst, rt);
+ break;
+
case XOP_EHPRIV:
emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
advance);
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
index 4d33e19..b0333cc 100644
--- a/arch/powerpc/kvm/e500_mmu_host.c
+++ b/arch/powerpc/kvm/e500_mmu_host.c
@@ -163,9 +163,9 @@ void kvmppc_map_magic(struct kvm_vcpu *vcpu)
struct kvm_book3e_206_tlb_entry magic;
ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
unsigned int stid;
- pfn_t pfn;
+ kvm_pfn_t pfn;
- pfn = (pfn_t)virt_to_phys((void *)shared_page) >> PAGE_SHIFT;
+ pfn = (kvm_pfn_t)virt_to_phys((void *)shared_page) >> PAGE_SHIFT;
get_page(pfn_to_page(pfn));
preempt_disable();
@@ -246,7 +246,7 @@ static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe)
static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
struct kvm_book3e_206_tlb_entry *gtlbe,
- pfn_t pfn, unsigned int wimg)
+ kvm_pfn_t pfn, unsigned int wimg)
{
ref->pfn = pfn;
ref->flags = E500_TLB_VALID;
@@ -309,7 +309,7 @@ static void kvmppc_e500_setup_stlbe(
int tsize, struct tlbe_ref *ref, u64 gvaddr,
struct kvm_book3e_206_tlb_entry *stlbe)
{
- pfn_t pfn = ref->pfn;
+ kvm_pfn_t pfn = ref->pfn;
u32 pr = vcpu->arch.shared->msr & MSR_PR;
BUG_ON(!(ref->flags & E500_TLB_VALID));
@@ -406,7 +406,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
for (; tsize > BOOK3E_PAGESZ_4K; tsize -= 2) {
unsigned long gfn_start, gfn_end;
- tsize_pages = 1 << (tsize - 2);
+ tsize_pages = 1UL << (tsize - 2);
gfn_start = gfn & ~(tsize_pages - 1);
gfn_end = gfn_start + tsize_pages;
@@ -447,7 +447,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
}
if (likely(!pfnmap)) {
- tsize_pages = 1 << (tsize + 10 - PAGE_SHIFT);
+ tsize_pages = 1UL << (tsize + 10 - PAGE_SHIFT);
pfn = gfn_to_pfn_memslot(slot, gfn);
if (is_error_noslot_pfn(pfn)) {
if (printk_ratelimit())
@@ -476,7 +476,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
* can't run hence pfn won't change.
*/
local_irq_save(flags);
- ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL);
+ ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL, NULL);
if (ptep) {
pte_t pte = READ_ONCE(*ptep);
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index cda695d..f48a0c2 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -182,7 +182,7 @@ int kvmppc_core_check_processor_compat(void)
r = 0;
#ifdef CONFIG_ALTIVEC
/*
- * Since guests have the priviledge to enable AltiVec, we need AltiVec
+ * Since guests have the privilege to enable AltiVec, we need AltiVec
* support in the host to save/restore their context.
* Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit
* because it's cleared in the absence of CONFIG_ALTIVEC!
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2e51289..19aa59b 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -33,6 +33,7 @@
#include <asm/tlbflush.h>
#include <asm/cputhreads.h>
#include <asm/irqflags.h>
+#include <asm/iommu.h>
#include "timing.h"
#include "irq.h"
#include "../mm/mmu_decl.h"
@@ -437,6 +438,16 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
unsigned int i;
struct kvm_vcpu *vcpu;
+#ifdef CONFIG_KVM_XICS
+ /*
+ * We call kick_all_cpus_sync() to ensure that all
+ * CPUs have executed any pending IPIs before we
+ * continue and free VCPUs structures below.
+ */
+ if (is_kvmppc_hv_enabled(kvm))
+ kick_all_cpus_sync();
+#endif
+
kvm_for_each_vcpu(i, vcpu, kvm)
kvm_arch_vcpu_free(vcpu);
@@ -509,6 +520,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
#ifdef CONFIG_PPC_BOOK3S_64
case KVM_CAP_SPAPR_TCE:
+ case KVM_CAP_SPAPR_TCE_64:
case KVM_CAP_PPC_ALLOC_HTAB:
case KVM_CAP_PPC_RTAS:
case KVM_CAP_PPC_FIXUP_HCALL:
@@ -559,6 +571,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
else
r = num_online_cpus();
break;
+ case KVM_CAP_NR_MEMSLOTS:
+ r = KVM_USER_MEM_SLOTS;
+ break;
case KVM_CAP_MAX_VCPUS:
r = KVM_MAX_VCPUS;
break;
@@ -566,6 +581,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_PPC_GET_SMMU_INFO:
r = 1;
break;
+ case KVM_CAP_SPAPR_MULTITCE:
+ r = 1;
+ break;
#endif
default:
r = 0;
@@ -916,21 +934,17 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
r = -ENXIO;
break;
}
- vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
+ val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
break;
case KVM_REG_PPC_VSCR:
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
r = -ENXIO;
break;
}
- vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
+ val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
break;
case KVM_REG_PPC_VRSAVE:
- if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
- r = -ENXIO;
- break;
- }
- vcpu->arch.vrsave = set_reg_val(reg->id, val);
+ val = get_reg_val(reg->id, vcpu->arch.vrsave);
break;
#endif /* CONFIG_ALTIVEC */
default:
@@ -971,17 +985,21 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
r = -ENXIO;
break;
}
- val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
+ vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
break;
case KVM_REG_PPC_VSCR:
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
r = -ENXIO;
break;
}
- val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
+ vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
break;
case KVM_REG_PPC_VRSAVE:
- val = get_reg_val(reg->id, vcpu->arch.vrsave);
+ if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
+ r = -ENXIO;
+ break;
+ }
+ vcpu->arch.vrsave = set_reg_val(reg->id, val);
break;
#endif /* CONFIG_ALTIVEC */
default:
@@ -1328,13 +1346,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
break;
}
#ifdef CONFIG_PPC_BOOK3S_64
+ case KVM_CREATE_SPAPR_TCE_64: {
+ struct kvm_create_spapr_tce_64 create_tce_64;
+
+ r = -EFAULT;
+ if (copy_from_user(&create_tce_64, argp, sizeof(create_tce_64)))
+ goto out;
+ if (create_tce_64.flags) {
+ r = -EINVAL;
+ goto out;
+ }
+ r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
+ goto out;
+ }
case KVM_CREATE_SPAPR_TCE: {
struct kvm_create_spapr_tce create_tce;
+ struct kvm_create_spapr_tce_64 create_tce_64;
r = -EFAULT;
if (copy_from_user(&create_tce, argp, sizeof(create_tce)))
goto out;
- r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
+
+ create_tce_64.liobn = create_tce.liobn;
+ create_tce_64.page_shift = IOMMU_PAGE_SHIFT_4K;
+ create_tce_64.offset = 0;
+ create_tce_64.size = create_tce.window_size >>
+ IOMMU_PAGE_SHIFT_4K;
+ create_tce_64.flags = 0;
+ r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
goto out;
}
case KVM_PPC_GET_SMMU_INFO: {
diff --git a/arch/powerpc/kvm/trace_pr.h b/arch/powerpc/kvm/trace_pr.h
index 810507c..d44f324 100644
--- a/arch/powerpc/kvm/trace_pr.h
+++ b/arch/powerpc/kvm/trace_pr.h
@@ -30,7 +30,7 @@ TRACE_EVENT(kvm_book3s_reenter,
#ifdef CONFIG_PPC_BOOK3S_64
TRACE_EVENT(kvm_book3s_64_mmu_map,
- TP_PROTO(int rflags, ulong hpteg, ulong va, pfn_t hpaddr,
+ TP_PROTO(int rflags, ulong hpteg, ulong va, kvm_pfn_t hpaddr,
struct kvmppc_pte *orig_pte),
TP_ARGS(rflags, hpteg, va, hpaddr, orig_pte),
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index a47e142..ba21be1 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -6,8 +6,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
-CFLAGS_REMOVE_code-patching.o = -pg
-CFLAGS_REMOVE_feature-fixups.o = -pg
+CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \
feature-fixups.o
@@ -22,8 +22,7 @@ obj64-$(CONFIG_SMP) += locks.o
obj64-$(CONFIG_ALTIVEC) += vmx-helper.o
ifeq ($(CONFIG_GENERIC_CSUM),)
-obj-y += checksum_$(CONFIG_WORD_SIZE).o
-obj-$(CONFIG_PPC64) += checksum_wrappers_64.o
+obj-y += checksum_$(CONFIG_WORD_SIZE).o checksum_wrappers.o
endif
obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 6d67e05..d90870a 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -14,68 +14,59 @@
#include <linux/sys.h>
#include <asm/processor.h>
+#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/ppc_asm.h>
.text
/*
- * ip_fast_csum(buf, len) -- Optimized for IP header
- * len is in words and is always >= 5.
- */
-_GLOBAL(ip_fast_csum)
- lwz r0,0(r3)
- lwzu r5,4(r3)
- addic. r4,r4,-2
- addc r0,r0,r5
- mtctr r4
- blelr-
-1: lwzu r4,4(r3)
- adde r0,r0,r4
- bdnz 1b
- addze r0,r0 /* add in final carry */
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
- * csum_partial(buff, len, sum)
+ * __csum_partial(buff, len, sum)
*/
-_GLOBAL(csum_partial)
- addic r0,r5,0
+_GLOBAL(__csum_partial)
subi r3,r3,4
- srwi. r6,r4,2
+ srawi. r6,r4,2 /* Divide len by 4 and also clear carry */
beq 3f /* if we're doing < 4 bytes */
- andi. r5,r3,2 /* Align buffer to longword boundary */
+ andi. r0,r3,2 /* Align buffer to longword boundary */
beq+ 1f
- lhz r5,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
+ lhz r0,4(r3) /* do 2 bytes to get aligned */
subi r4,r4,2
- addc r0,r0,r5
+ addi r3,r3,2
srwi. r6,r4,2 /* # words to do */
+ adde r5,r5,r0
beq 3f
-1: mtctr r6
-2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */
- adde r0,r0,r5 /* be unnecessary to unroll this loop */
+1: andi. r6,r6,3 /* Prepare to handle words 4 by 4 */
+ beq 21f
+ mtctr r6
+2: lwzu r0,4(r3)
+ adde r5,r5,r0
bdnz 2b
- andi. r4,r4,3
-3: cmpwi 0,r4,2
- blt+ 4f
- lhz r5,4(r3)
+21: srwi. r6,r4,4 /* # blocks of 4 words to do */
+ beq 3f
+ mtctr r6
+22: lwz r0,4(r3)
+ lwz r6,8(r3)
+ lwz r7,12(r3)
+ lwzu r8,16(r3)
+ adde r5,r5,r0
+ adde r5,r5,r6
+ adde r5,r5,r7
+ adde r5,r5,r8
+ bdnz 22b
+3: andi. r0,r4,2
+ beq+ 4f
+ lhz r0,4(r3)
addi r3,r3,2
- subi r4,r4,2
- adde r0,r0,r5
-4: cmpwi 0,r4,1
- bne+ 5f
- lbz r5,4(r3)
- slwi r5,r5,8 /* Upper byte of word */
- adde r0,r0,r5
-5: addze r3,r0 /* add in final carry */
+ adde r5,r5,r0
+4: andi. r0,r4,1
+ beq+ 5f
+ lbz r0,4(r3)
+ slwi r0,r0,8 /* Upper byte of word */
+ adde r5,r5,r0
+5: addze r3,r5 /* add in final carry */
blr
/*
@@ -87,123 +78,220 @@ _GLOBAL(csum_partial)
*
* csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
*/
+#define CSUM_COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+ adde r12,r12,r7; \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+ adde r12,r12,r8; \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+ adde r12,r12,r9; \
+8 ## n ## 7: \
+ stwu r10,16(r6); \
+ adde r12,r12,r10
+
+#define CSUM_COPY_16_BYTES_EXCODE(n) \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,src_error; \
+ .long 8 ## n ## 1b,src_error; \
+ .long 8 ## n ## 2b,src_error; \
+ .long 8 ## n ## 3b,src_error; \
+ .long 8 ## n ## 4b,dst_error; \
+ .long 8 ## n ## 5b,dst_error; \
+ .long 8 ## n ## 6b,dst_error; \
+ .long 8 ## n ## 7b,dst_error; \
+ .text
+
+ .text
+ .stabs "arch/powerpc/lib/",N_SO,0,0,0f
+ .stabs "checksum_32.S",N_SO,0,0,0f
+0:
+
+CACHELINE_BYTES = L1_CACHE_BYTES
+LG_CACHELINE_BYTES = L1_CACHE_SHIFT
+CACHELINE_MASK = (L1_CACHE_BYTES-1)
+
_GLOBAL(csum_partial_copy_generic)
- addic r0,r6,0
- subi r3,r3,4
- subi r4,r4,4
- srwi. r6,r5,2
- beq 3f /* if we're doing < 4 bytes */
- andi. r9,r4,2 /* Align dst to longword boundary */
- beq+ 1f
-81: lhz r6,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r5,r5,2
-91: sth r6,4(r4)
- addi r4,r4,2
- addc r0,r0,r6
- srwi. r6,r5,2 /* # words to do */
- beq 3f
-1: srwi. r6,r5,4 /* # groups of 4 words to do */
- beq 10f
- mtctr r6
-71: lwz r6,4(r3)
-72: lwz r9,8(r3)
-73: lwz r10,12(r3)
-74: lwzu r11,16(r3)
- adde r0,r0,r6
-75: stw r6,4(r4)
- adde r0,r0,r9
-76: stw r9,8(r4)
- adde r0,r0,r10
-77: stw r10,12(r4)
- adde r0,r0,r11
-78: stwu r11,16(r4)
- bdnz 71b
-10: rlwinm. r6,r5,30,30,31 /* # words left to do */
- beq 13f
- mtctr r6
-82: lwzu r9,4(r3)
-92: stwu r9,4(r4)
- adde r0,r0,r9
- bdnz 82b
-13: andi. r5,r5,3
-3: cmpwi 0,r5,2
- blt+ 4f
-83: lhz r6,4(r3)
- addi r3,r3,2
- subi r5,r5,2
-93: sth r6,4(r4)
+ stwu r1,-16(r1)
+ stw r7,12(r1)
+ stw r8,8(r1)
+
+ andi. r0,r4,1 /* is destination address even ? */
+ cmplwi cr7,r0,0
+ addic r12,r6,0
+ addi r6,r4,-4
+ neg r0,r4
+ addi r4,r3,-4
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ mtctr r8
+ beq+ 61f
+ li r3,0
+70: lbz r9,4(r4) /* do some bytes */
+ addi r4,r4,1
+ slwi r3,r3,8
+ rlwimi r3,r9,0,24,31
+71: stb r9,4(r6)
+ addi r6,r6,1
+ bdnz 70b
+ adde r12,r12,r3
+61: subf r5,r0,r5
+ srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+ adde r12,r12,r9
+73: stwu r9,4(r6)
+ bdnz 72b
+
+58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+ clrlwi r5,r5,32-LG_CACHELINE_BYTES
+ li r11,4
+ beq 63f
+
+ /* Here we decide how far ahead to prefetch the source */
+ li r3,4
+ cmpwi r0,1
+ li r7,0
+ ble 114f
+ li r7,1
+#if MAX_COPY_PREFETCH > 1
+ /* Heuristically, for large transfers we prefetch
+ MAX_COPY_PREFETCH cachelines ahead. For small transfers
+ we prefetch 1 cacheline ahead. */
+ cmpwi r0,MAX_COPY_PREFETCH
+ ble 112f
+ li r7,MAX_COPY_PREFETCH
+112: mtctr r7
+111: dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+ bdnz 111b
+#else
+ dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+#endif /* MAX_COPY_PREFETCH > 1 */
+
+114: subf r8,r7,r0
+ mr r0,r7
+ mtctr r8
+
+53: dcbt r3,r4
+54: dcbz r11,r6
+/* the main body of the cacheline loop */
+ CSUM_COPY_16_BYTES_WITHEX(0)
+#if L1_CACHE_BYTES >= 32
+ CSUM_COPY_16_BYTES_WITHEX(1)
+#if L1_CACHE_BYTES >= 64
+ CSUM_COPY_16_BYTES_WITHEX(2)
+ CSUM_COPY_16_BYTES_WITHEX(3)
+#if L1_CACHE_BYTES >= 128
+ CSUM_COPY_16_BYTES_WITHEX(4)
+ CSUM_COPY_16_BYTES_WITHEX(5)
+ CSUM_COPY_16_BYTES_WITHEX(6)
+ CSUM_COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
+ bdnz 53b
+ cmpwi r0,0
+ li r3,4
+ li r7,0
+ bne 114b
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+ adde r12,r12,r0
+31: stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,2
+ beq+ 65f
+40: lhz r0,4(r4)
addi r4,r4,2
- adde r0,r0,r6
-4: cmpwi 0,r5,1
- bne+ 5f
-84: lbz r6,4(r3)
-94: stb r6,4(r4)
- slwi r6,r6,8 /* Upper byte of word */
- adde r0,r0,r6
-5: addze r3,r0 /* add in final carry */
+41: sth r0,4(r6)
+ adde r12,r12,r0
+ addi r6,r6,2
+65: andi. r0,r5,1
+ beq+ 66f
+50: lbz r0,4(r4)
+51: stb r0,4(r6)
+ slwi r0,r0,8
+ adde r12,r12,r0
+66: addze r3,r12
+ addi r1,r1,16
+ beqlr+ cr7
+ rlwinm r3,r3,8,0,31 /* swap bytes for odd destination */
blr
-/* These shouldn't go in the fixup section, since that would
- cause the ex_table addresses to get out of order. */
-
-src_error_4:
- mfctr r6 /* update # bytes remaining from ctr */
- rlwimi r5,r6,4,0,27
- b 79f
-src_error_1:
- li r6,0
- subi r5,r5,2
-95: sth r6,4(r4)
- addi r4,r4,2
-79: srwi. r6,r5,2
- beq 3f
- mtctr r6
-src_error_2:
- li r6,0
-96: stwu r6,4(r4)
- bdnz 96b
-3: andi. r5,r5,3
- beq src_error
-src_error_3:
- li r6,0
- mtctr r5
- addi r4,r4,3
-97: stbu r6,1(r4)
- bdnz 97b
+/* read fault */
src_error:
- cmpwi 0,r7,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r7)
-1: addze r3,r0
+ lwz r7,12(r1)
+ addi r1,r1,16
+ cmpwi cr0,r7,0
+ beqlr
+ li r0,-EFAULT
+ stw r0,0(r7)
blr
-
+/* write fault */
dst_error:
- cmpwi 0,r8,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r8)
-1: addze r3,r0
+ lwz r8,8(r1)
+ addi r1,r1,16
+ cmpwi cr0,r8,0
+ beqlr
+ li r0,-EFAULT
+ stw r0,0(r8)
blr
-.section __ex_table,"a"
- .long 81b,src_error_1
- .long 91b,dst_error
- .long 71b,src_error_4
- .long 72b,src_error_4
- .long 73b,src_error_4
- .long 74b,src_error_4
- .long 75b,dst_error
- .long 76b,dst_error
- .long 77b,dst_error
- .long 78b,dst_error
- .long 82b,src_error_2
- .long 92b,dst_error
- .long 83b,src_error_3
- .long 93b,dst_error
- .long 84b,src_error_3
- .long 94b,dst_error
- .long 95b,dst_error
- .long 96b,dst_error
- .long 97b,dst_error
+ .section __ex_table,"a"
+ .align 2
+ .long 70b,src_error
+ .long 71b,dst_error
+ .long 72b,src_error
+ .long 73b,dst_error
+ .long 54b,dst_error
+ .text
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * src_error (if in read part) or dst_error (if in write part)
+ */
+ CSUM_COPY_16_BYTES_EXCODE(0)
+#if L1_CACHE_BYTES >= 32
+ CSUM_COPY_16_BYTES_EXCODE(1)
+#if L1_CACHE_BYTES >= 64
+ CSUM_COPY_16_BYTES_EXCODE(2)
+ CSUM_COPY_16_BYTES_EXCODE(3)
+#if L1_CACHE_BYTES >= 128
+ CSUM_COPY_16_BYTES_EXCODE(4)
+ CSUM_COPY_16_BYTES_EXCODE(5)
+ CSUM_COPY_16_BYTES_EXCODE(6)
+ CSUM_COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+ .section __ex_table,"a"
+ .align 2
+ .long 30b,src_error
+ .long 31b,dst_error
+ .long 40b,src_error
+ .long 41b,dst_error
+ .long 50b,src_error
+ .long 51b,dst_error
diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
index f3ef354..8e6e510 100644
--- a/arch/powerpc/lib/checksum_64.S
+++ b/arch/powerpc/lib/checksum_64.S
@@ -18,39 +18,12 @@
#include <asm/ppc_asm.h>
/*
- * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
- * len is in words and is always >= 5.
- *
- * In practice len == 5, but this is not guaranteed. So this code does not
- * attempt to use doubleword instructions.
- */
-_GLOBAL(ip_fast_csum)
- lwz r0,0(r3)
- lwzu r5,4(r3)
- addic. r4,r4,-2
- addc r0,r0,r5
- mtctr r4
- blelr-
-1: lwzu r4,4(r3)
- adde r0,r0,r4
- bdnz 1b
- addze r0,r0 /* add in final carry */
- rldicl r4,r0,32,0 /* fold two 32-bit halves together */
- add r0,r0,r4
- srdi r0,r0,32
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
* Computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit).
*
- * csum_partial(r3=buff, r4=len, r5=sum)
+ * __csum_partial(r3=buff, r4=len, r5=sum)
*/
-_GLOBAL(csum_partial)
+_GLOBAL(__csum_partial)
addic r0,r5,0 /* clear carry */
srdi. r6,r4,3 /* less than 8 bytes? */
diff --git a/arch/powerpc/lib/checksum_wrappers_64.c b/arch/powerpc/lib/checksum_wrappers.c
index 08e3a33..08e3a33 100644
--- a/arch/powerpc/lib/checksum_wrappers_64.c
+++ b/arch/powerpc/lib/checksum_wrappers.c
diff --git a/arch/powerpc/lib/ppc_ksyms.c b/arch/powerpc/lib/ppc_ksyms.c
index c7f8e95..c422812 100644
--- a/arch/powerpc/lib/ppc_ksyms.c
+++ b/arch/powerpc/lib/ppc_ksyms.c
@@ -17,10 +17,8 @@ EXPORT_SYMBOL(strcmp);
EXPORT_SYMBOL(strncmp);
#ifndef CONFIG_GENERIC_CSUM
-EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(__csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
-EXPORT_SYMBOL(ip_fast_csum);
-EXPORT_SYMBOL(csum_tcpudp_magic);
#endif
EXPORT_SYMBOL(__copy_tofrom_user);
diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c
index ac93a3b..b27e030 100644
--- a/arch/powerpc/lib/vmx-helper.c
+++ b/arch/powerpc/lib/vmx-helper.c
@@ -46,6 +46,7 @@ int enter_vmx_usercopy(void)
*/
int exit_vmx_usercopy(void)
{
+ disable_kernel_altivec();
pagefault_enable();
preempt_enable();
return 0;
@@ -70,6 +71,7 @@ int enter_vmx_copy(void)
*/
void *exit_vmx_copy(void *dest)
{
+ disable_kernel_altivec();
preempt_enable();
return dest;
}
diff --git a/arch/powerpc/lib/xor_vmx.c b/arch/powerpc/lib/xor_vmx.c
index e905f7c..07f49f1 100644
--- a/arch/powerpc/lib/xor_vmx.c
+++ b/arch/powerpc/lib/xor_vmx.c
@@ -74,6 +74,7 @@ void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
v2 += 4;
} while (--lines > 0);
+ disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_2);
@@ -102,6 +103,7 @@ void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
v3 += 4;
} while (--lines > 0);
+ disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_3);
@@ -135,6 +137,7 @@ void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
v4 += 4;
} while (--lines > 0);
+ disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_4);
@@ -172,6 +175,7 @@ void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
v5 += 4;
} while (--lines > 0);
+ disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_5);
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 5810967..31a5d42 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -110,10 +110,10 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
- pmd_val(*pmdp++) = val;
- pmd_val(*pmdp++) = val;
- pmd_val(*pmdp++) = val;
- pmd_val(*pmdp++) = val;
+ *pmdp++ = __pmd(val);
+ *pmdp++ = __pmd(val);
+ *pmdp++ = __pmd(val);
+ *pmdp++ = __pmd(val);
v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M;
@@ -125,7 +125,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
- pmd_val(*pmdp) = val;
+ *pmdp = __pmd(val);
v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M;
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
new file mode 100644
index 0000000..9491005
--- /dev/null
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -0,0 +1,141 @@
+/*
+ * This file contains the routines for initializing the MMU
+ * on the 8xx series of chips.
+ * -- christophe
+ *
+ * Derived from arch/powerpc/mm/40x_mmu.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.
+ *
+ */
+
+#include <linux/memblock.h>
+
+#include "mmu_decl.h"
+
+extern int __map_without_ltlbs;
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ /* Nothing to do for the time being but keep it similar to other PPC */
+}
+
+#define LARGE_PAGE_SIZE_4M (1<<22)
+#define LARGE_PAGE_SIZE_8M (1<<23)
+#define LARGE_PAGE_SIZE_64M (1<<26)
+
+unsigned long __init mmu_mapin_ram(unsigned long top)
+{
+ unsigned long v, s, mapped;
+ phys_addr_t p;
+
+ v = KERNELBASE;
+ p = 0;
+ s = top;
+
+ if (__map_without_ltlbs)
+ return 0;
+
+#ifdef CONFIG_PPC_4K_PAGES
+ while (s >= LARGE_PAGE_SIZE_8M) {
+ pmd_t *pmdp;
+ unsigned long val = p | MD_PS8MEG;
+
+ pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
+ *pmdp++ = __pmd(val);
+ *pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M);
+
+ v += LARGE_PAGE_SIZE_8M;
+ p += LARGE_PAGE_SIZE_8M;
+ s -= LARGE_PAGE_SIZE_8M;
+ }
+#else /* CONFIG_PPC_16K_PAGES */
+ while (s >= LARGE_PAGE_SIZE_64M) {
+ pmd_t *pmdp;
+ unsigned long val = p | MD_PS8MEG;
+
+ pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
+ *pmdp++ = __pmd(val);
+
+ v += LARGE_PAGE_SIZE_64M;
+ p += LARGE_PAGE_SIZE_64M;
+ s -= LARGE_PAGE_SIZE_64M;
+ }
+#endif
+
+ mapped = top - s;
+
+ /* If the size of RAM is not an exact power of two, we may not
+ * have covered RAM in its entirety with 8 MiB
+ * pages. Consequently, restrict the top end of RAM currently
+ * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
+ * coverage with normal-sized pages (or other reasons) do not
+ * attempt to allocate outside the allowed range.
+ */
+ memblock_set_current_limit(mapped);
+
+ return mapped;
+}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+ phys_addr_t first_memblock_size)
+{
+ /* We don't currently support the first MEMBLOCK not mapping 0
+ * physical on those processors
+ */
+ BUG_ON(first_memblock_base != 0);
+
+#ifdef CONFIG_PIN_TLB
+ /* 8xx can only access 24MB at the moment */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
+#else
+ /* 8xx can only access 8MB at the moment */
+ memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
+#endif
+}
+
+/*
+ * Set up to use a given MMU context.
+ * id is context number, pgd is PGD pointer.
+ *
+ * We place the physical address of the new task page directory loaded
+ * into the MMU base register, and set the ASID compare register with
+ * the new "context."
+ */
+void set_context(unsigned long id, pgd_t *pgd)
+{
+ s16 offset = (s16)(__pa(swapper_pg_dir));
+
+#ifdef CONFIG_BDI_SWITCH
+ pgd_t **ptr = *(pgd_t ***)(KERNELBASE + 0xf0);
+
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ *(ptr + 1) = pgd;
+#endif
+
+ /* Register M_TW will contain base address of level 1 table minus the
+ * lower part of the kernel PGDIR base address, so that all accesses to
+ * level 1 table are done relative to lower part of kernel PGDIR base
+ * address.
+ */
+ mtspr(SPRN_M_TW, __pa(pgd) - offset);
+
+ /* Update context */
+ mtspr(SPRN_M_CASID, id);
+ /* sync */
+ mb();
+}
+
+void flush_instruction_cache(void)
+{
+ isync();
+ mtspr(SPRN_IC_CST, IDC_INVALL);
+ isync();
+}
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 3eb73a3..adfee3f 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -14,14 +14,18 @@ obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(CONFIG_WORD_SIZE)e.o
hash64-$(CONFIG_PPC_NATIVE) := hash_native_64.o
obj-$(CONFIG_PPC_STD_MMU_64) += hash_utils_64.o slb_low.o slb.o $(hash64-y)
-obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o
-obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
- tlb_hash$(CONFIG_WORD_SIZE).o \
+obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o
+obj-$(CONFIG_PPC_STD_MMU) += tlb_hash$(CONFIG_WORD_SIZE).o \
mmu_context_hash$(CONFIG_WORD_SIZE).o
+ifeq ($(CONFIG_PPC_STD_MMU_64),y)
+obj-$(CONFIG_PPC_4K_PAGES) += hash64_4k.o
+obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o
+endif
obj-$(CONFIG_PPC_ICSWX) += icswx.o
obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o
obj-$(CONFIG_40x) += 40x_mmu.o
obj-$(CONFIG_44x) += 44x_mmu.o
+obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o
obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o
obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
obj-$(CONFIG_PPC_SPLPAR) += vphn.o
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
index 169aba4..2dc74e5 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -327,7 +327,7 @@ void __dma_sync(void *vaddr, size_t size, int direction)
* invalidate only when cache-line aligned otherwise there is
* the potential for discarding uncommitted data from the cache
*/
- if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
+ if ((start | end) & (L1_CACHE_BYTES - 1))
flush_dcache_range(start, end);
else
invalidate_dcache_range(start, end);
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 354ba3c..a1b2713 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -72,10 +72,11 @@ unsigned long tlbcam_sz(int idx)
return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1;
}
+#ifdef CONFIG_FSL_BOOKE
/*
* Return PA for this VA if it is mapped by a CAM, or 0
*/
-phys_addr_t v_mapped_by_tlbcam(unsigned long va)
+phys_addr_t v_block_mapped(unsigned long va)
{
int b;
for (b = 0; b < tlbcam_index; ++b)
@@ -87,7 +88,7 @@ phys_addr_t v_mapped_by_tlbcam(unsigned long va)
/*
* Return VA for a given PA or 0 if not mapped
*/
-unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
+unsigned long p_block_mapped(phys_addr_t pa)
{
int b;
for (b = 0; b < tlbcam_index; ++b)
@@ -97,6 +98,7 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
return 0;
}
+#endif
/*
* Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
@@ -141,8 +143,6 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
tlbcam_addrs[index].start = virt;
tlbcam_addrs[index].limit = virt + size - 1;
tlbcam_addrs[index].phys = phys;
-
- loadcam_entry(index);
}
unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
@@ -171,7 +171,8 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
}
static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
- unsigned long ram, int max_cam_idx)
+ unsigned long ram, int max_cam_idx,
+ bool dryrun)
{
int i;
unsigned long amount_mapped = 0;
@@ -181,13 +182,20 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
unsigned long cam_sz;
cam_sz = calc_cam_sz(ram, virt, phys);
- settlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
+ if (!dryrun)
+ settlbcam(i, virt, phys, cam_sz,
+ pgprot_val(PAGE_KERNEL_X), 0);
ram -= cam_sz;
amount_mapped += cam_sz;
virt += cam_sz;
phys += cam_sz;
}
+
+ if (dryrun)
+ return amount_mapped;
+
+ loadcam_multi(0, i, max_cam_idx);
tlbcam_index = i;
#ifdef CONFIG_PPC64
@@ -199,12 +207,12 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
return amount_mapped;
}
-unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
+unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun)
{
unsigned long virt = PAGE_OFFSET;
phys_addr_t phys = memstart_addr;
- return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
+ return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun);
}
#ifdef CONFIG_PPC32
@@ -235,7 +243,7 @@ void __init adjust_total_lowmem(void)
ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
i = switch_to_as1();
- __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM);
+ __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false);
restore_to_as0(i, 0, 0, 1);
pr_info("Memory CAM mapping: ");
@@ -303,10 +311,12 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
n = switch_to_as1();
/* map a 64M area for the second relocation */
if (memstart_addr > start)
- map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM);
+ map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM,
+ false);
else
map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
- 0x4000000, CONFIG_LOWMEM_CAM_NUM);
+ 0x4000000, CONFIG_LOWMEM_CAM_NUM,
+ false);
restore_to_as0(n, offset, __va(dt_ptr), 1);
/* We should never reach here */
panic("Relocation error");
diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c
new file mode 100644
index 0000000..47d1b26
--- /dev/null
+++ b/arch/powerpc/mm/hash64_4k.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright IBM Corporation, 2015
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <linux/mm.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+
+int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ pte_t *ptep, unsigned long trap, unsigned long flags,
+ int ssize, int subpg_prot)
+{
+ unsigned long hpte_group;
+ unsigned long rflags, pa;
+ unsigned long old_pte, new_pte;
+ unsigned long vpn, hash, slot;
+ unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift;
+
+ /*
+ * atomically mark the linux large page PTE busy and dirty
+ */
+ do {
+ pte_t pte = READ_ONCE(*ptep);
+
+ old_pte = pte_val(pte);
+ /* If PTE busy, retry the access */
+ if (unlikely(old_pte & _PAGE_BUSY))
+ return 0;
+ /* If PTE permissions don't match, take page fault */
+ if (unlikely(access & ~old_pte))
+ return 1;
+ /*
+ * Try to lock the PTE, add ACCESSED and DIRTY if it was
+ * a write access. Since this is 4K insert of 64K page size
+ * also add _PAGE_COMBO
+ */
+ new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
+ if (access & _PAGE_RW)
+ new_pte |= _PAGE_DIRTY;
+ } while (old_pte != __cmpxchg_u64((unsigned long *)ptep,
+ old_pte, new_pte));
+ /*
+ * PP bits. _PAGE_USER is already PP bit 0x2, so we only
+ * need to add in 0x1 if it's a read-only user page
+ */
+ rflags = htab_convert_pte_flags(new_pte);
+
+ if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+
+ vpn = hpt_vpn(ea, vsid, ssize);
+ if (unlikely(old_pte & _PAGE_HASHPTE)) {
+ /*
+ * There MIGHT be an HPTE for this pte
+ */
+ hash = hpt_hash(vpn, shift, ssize);
+ if (old_pte & _PAGE_F_SECOND)
+ hash = ~hash;
+ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT;
+
+ if (ppc_md.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_4K,
+ MMU_PAGE_4K, ssize, flags) == -1)
+ old_pte &= ~_PAGE_HPTEFLAGS;
+ }
+
+ if (likely(!(old_pte & _PAGE_HASHPTE))) {
+
+ pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
+ hash = hpt_hash(vpn, shift, ssize);
+
+repeat:
+ hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+
+ /* Insert into the hash table, primary slot */
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
+ MMU_PAGE_4K, MMU_PAGE_4K, ssize);
+ /*
+ * Primary is full, try the secondary
+ */
+ if (unlikely(slot == -1)) {
+ hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa,
+ rflags, HPTE_V_SECONDARY,
+ MMU_PAGE_4K, MMU_PAGE_4K, ssize);
+ if (slot == -1) {
+ if (mftb() & 0x1)
+ hpte_group = ((hash & htab_hash_mask) *
+ HPTES_PER_GROUP) & ~0x7UL;
+ ppc_md.hpte_remove(hpte_group);
+ /*
+ * FIXME!! Should be try the group from which we removed ?
+ */
+ goto repeat;
+ }
+ }
+ /*
+ * Hypervisor failure. Restore old pte and return -1
+ * similar to __hash_page_*
+ */
+ if (unlikely(slot == -2)) {
+ *ptep = __pte(old_pte);
+ hash_failure_debug(ea, access, vsid, trap, ssize,
+ MMU_PAGE_4K, MMU_PAGE_4K, old_pte);
+ return -1;
+ }
+ new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
+ new_pte |= (slot << _PAGE_F_GIX_SHIFT) & (_PAGE_F_SECOND | _PAGE_F_GIX);
+ }
+ *ptep = __pte(new_pte & ~_PAGE_BUSY);
+ return 0;
+}
diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c
new file mode 100644
index 0000000..b2d659c
--- /dev/null
+++ b/arch/powerpc/mm/hash64_64k.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright IBM Corporation, 2015
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <linux/mm.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+/*
+ * index from 0 - 15
+ */
+bool __rpte_sub_valid(real_pte_t rpte, unsigned long index)
+{
+ unsigned long g_idx;
+ unsigned long ptev = pte_val(rpte.pte);
+
+ g_idx = (ptev & _PAGE_COMBO_VALID) >> _PAGE_F_GIX_SHIFT;
+ index = index >> 2;
+ if (g_idx & (0x1 << index))
+ return true;
+ else
+ return false;
+}
+/*
+ * index from 0 - 15
+ */
+static unsigned long mark_subptegroup_valid(unsigned long ptev, unsigned long index)
+{
+ unsigned long g_idx;
+
+ if (!(ptev & _PAGE_COMBO))
+ return ptev;
+ index = index >> 2;
+ g_idx = 0x1 << index;
+
+ return ptev | (g_idx << _PAGE_F_GIX_SHIFT);
+}
+
+int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ pte_t *ptep, unsigned long trap, unsigned long flags,
+ int ssize, int subpg_prot)
+{
+ real_pte_t rpte;
+ unsigned long *hidxp;
+ unsigned long hpte_group;
+ unsigned int subpg_index;
+ unsigned long rflags, pa, hidx;
+ unsigned long old_pte, new_pte, subpg_pte;
+ unsigned long vpn, hash, slot;
+ unsigned long shift = mmu_psize_defs[MMU_PAGE_4K].shift;
+
+ /*
+ * atomically mark the linux large page PTE busy and dirty
+ */
+ do {
+ pte_t pte = READ_ONCE(*ptep);
+
+ old_pte = pte_val(pte);
+ /* If PTE busy, retry the access */
+ if (unlikely(old_pte & _PAGE_BUSY))
+ return 0;
+ /* If PTE permissions don't match, take page fault */
+ if (unlikely(access & ~old_pte))
+ return 1;
+ /*
+ * Try to lock the PTE, add ACCESSED and DIRTY if it was
+ * a write access. Since this is 4K insert of 64K page size
+ * also add _PAGE_COMBO
+ */
+ new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_COMBO;
+ if (access & _PAGE_RW)
+ new_pte |= _PAGE_DIRTY;
+ } while (old_pte != __cmpxchg_u64((unsigned long *)ptep,
+ old_pte, new_pte));
+ /*
+ * Handle the subpage protection bits
+ */
+ subpg_pte = new_pte & ~subpg_prot;
+ rflags = htab_convert_pte_flags(subpg_pte);
+
+ if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
+
+ /*
+ * No CPU has hugepages but lacks no execute, so we
+ * don't need to worry about that case
+ */
+ rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+ }
+
+ subpg_index = (ea & (PAGE_SIZE - 1)) >> shift;
+ vpn = hpt_vpn(ea, vsid, ssize);
+ rpte = __real_pte(__pte(old_pte), ptep);
+ /*
+ *None of the sub 4k page is hashed
+ */
+ if (!(old_pte & _PAGE_HASHPTE))
+ goto htab_insert_hpte;
+ /*
+ * Check if the pte was already inserted into the hash table
+ * as a 64k HW page, and invalidate the 64k HPTE if so.
+ */
+ if (!(old_pte & _PAGE_COMBO)) {
+ flush_hash_page(vpn, rpte, MMU_PAGE_64K, ssize, flags);
+ /*
+ * clear the old slot details from the old and new pte.
+ * On hash insert failure we use old pte value and we don't
+ * want slot information there if we have a insert failure.
+ */
+ old_pte &= ~(_PAGE_HASHPTE | _PAGE_F_GIX | _PAGE_F_SECOND);
+ new_pte &= ~(_PAGE_HASHPTE | _PAGE_F_GIX | _PAGE_F_SECOND);
+ goto htab_insert_hpte;
+ }
+ /*
+ * Check for sub page valid and update
+ */
+ if (__rpte_sub_valid(rpte, subpg_index)) {
+ int ret;
+
+ hash = hpt_hash(vpn, shift, ssize);
+ hidx = __rpte_to_hidx(rpte, subpg_index);
+ if (hidx & _PTEIDX_SECONDARY)
+ hash = ~hash;
+ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot += hidx & _PTEIDX_GROUP_IX;
+
+ ret = ppc_md.hpte_updatepp(slot, rflags, vpn,
+ MMU_PAGE_4K, MMU_PAGE_4K,
+ ssize, flags);
+ /*
+ *if we failed because typically the HPTE wasn't really here
+ * we try an insertion.
+ */
+ if (ret == -1)
+ goto htab_insert_hpte;
+
+ *ptep = __pte(new_pte & ~_PAGE_BUSY);
+ return 0;
+ }
+
+htab_insert_hpte:
+ /*
+ * handle _PAGE_4K_PFN case
+ */
+ if (old_pte & _PAGE_4K_PFN) {
+ /*
+ * All the sub 4k page have the same
+ * physical address.
+ */
+ pa = pte_pfn(__pte(old_pte)) << HW_PAGE_SHIFT;
+ } else {
+ pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
+ pa += (subpg_index << shift);
+ }
+ hash = hpt_hash(vpn, shift, ssize);
+repeat:
+ hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+
+ /* Insert into the hash table, primary slot */
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
+ MMU_PAGE_4K, MMU_PAGE_4K, ssize);
+ /*
+ * Primary is full, try the secondary
+ */
+ if (unlikely(slot == -1)) {
+ hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa,
+ rflags, HPTE_V_SECONDARY,
+ MMU_PAGE_4K, MMU_PAGE_4K, ssize);
+ if (slot == -1) {
+ if (mftb() & 0x1)
+ hpte_group = ((hash & htab_hash_mask) *
+ HPTES_PER_GROUP) & ~0x7UL;
+ ppc_md.hpte_remove(hpte_group);
+ /*
+ * FIXME!! Should be try the group from which we removed ?
+ */
+ goto repeat;
+ }
+ }
+ /*
+ * Hypervisor failure. Restore old pte and return -1
+ * similar to __hash_page_*
+ */
+ if (unlikely(slot == -2)) {
+ *ptep = __pte(old_pte);
+ hash_failure_debug(ea, access, vsid, trap, ssize,
+ MMU_PAGE_4K, MMU_PAGE_4K, old_pte);
+ return -1;
+ }
+ /*
+ * Insert slot number & secondary bit in PTE second half,
+ * clear _PAGE_BUSY and set appropriate HPTE slot bit
+ * Since we have _PAGE_BUSY set on ptep, we can be sure
+ * nobody is undating hidx.
+ */
+ hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
+ rpte.hidx &= ~(0xfUL << (subpg_index << 2));
+ *hidxp = rpte.hidx | (slot << (subpg_index << 2));
+ new_pte = mark_subptegroup_valid(new_pte, subpg_index);
+ new_pte |= _PAGE_HASHPTE;
+ /*
+ * check __real_pte for details on matching smp_rmb()
+ */
+ smp_wmb();
+ *ptep = __pte(new_pte & ~_PAGE_BUSY);
+ return 0;
+}
+
+int __hash_page_64K(unsigned long ea, unsigned long access,
+ unsigned long vsid, pte_t *ptep, unsigned long trap,
+ unsigned long flags, int ssize)
+{
+
+ unsigned long hpte_group;
+ unsigned long rflags, pa;
+ unsigned long old_pte, new_pte;
+ unsigned long vpn, hash, slot;
+ unsigned long shift = mmu_psize_defs[MMU_PAGE_64K].shift;
+
+ /*
+ * atomically mark the linux large page PTE busy and dirty
+ */
+ do {
+ pte_t pte = READ_ONCE(*ptep);
+
+ old_pte = pte_val(pte);
+ /* If PTE busy, retry the access */
+ if (unlikely(old_pte & _PAGE_BUSY))
+ return 0;
+ /* If PTE permissions don't match, take page fault */
+ if (unlikely(access & ~old_pte))
+ return 1;
+ /*
+ * Check if PTE has the cache-inhibit bit set
+ * If so, bail out and refault as a 4k page
+ */
+ if (!mmu_has_feature(MMU_FTR_CI_LARGE_PAGE) &&
+ unlikely(old_pte & _PAGE_NO_CACHE))
+ return 0;
+ /*
+ * Try to lock the PTE, add ACCESSED and DIRTY if it was
+ * a write access.
+ */
+ new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
+ if (access & _PAGE_RW)
+ new_pte |= _PAGE_DIRTY;
+ } while (old_pte != __cmpxchg_u64((unsigned long *)ptep,
+ old_pte, new_pte));
+
+ rflags = htab_convert_pte_flags(new_pte);
+
+ if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+
+ vpn = hpt_vpn(ea, vsid, ssize);
+ if (unlikely(old_pte & _PAGE_HASHPTE)) {
+ /*
+ * There MIGHT be an HPTE for this pte
+ */
+ hash = hpt_hash(vpn, shift, ssize);
+ if (old_pte & _PAGE_F_SECOND)
+ hash = ~hash;
+ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT;
+
+ if (ppc_md.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_64K,
+ MMU_PAGE_64K, ssize, flags) == -1)
+ old_pte &= ~_PAGE_HPTEFLAGS;
+ }
+
+ if (likely(!(old_pte & _PAGE_HASHPTE))) {
+
+ pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
+ hash = hpt_hash(vpn, shift, ssize);
+
+repeat:
+ hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+
+ /* Insert into the hash table, primary slot */
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
+ MMU_PAGE_64K, MMU_PAGE_64K, ssize);
+ /*
+ * Primary is full, try the secondary
+ */
+ if (unlikely(slot == -1)) {
+ hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa,
+ rflags, HPTE_V_SECONDARY,
+ MMU_PAGE_64K, MMU_PAGE_64K, ssize);
+ if (slot == -1) {
+ if (mftb() & 0x1)
+ hpte_group = ((hash & htab_hash_mask) *
+ HPTES_PER_GROUP) & ~0x7UL;
+ ppc_md.hpte_remove(hpte_group);
+ /*
+ * FIXME!! Should be try the group from which we removed ?
+ */
+ goto repeat;
+ }
+ }
+ /*
+ * Hypervisor failure. Restore old pte and return -1
+ * similar to __hash_page_*
+ */
+ if (unlikely(slot == -2)) {
+ *ptep = __pte(old_pte);
+ hash_failure_debug(ea, access, vsid, trap, ssize,
+ MMU_PAGE_64K, MMU_PAGE_64K, old_pte);
+ return -1;
+ }
+ new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
+ new_pte |= (slot << _PAGE_F_GIX_SHIFT) & (_PAGE_F_SECOND | _PAGE_F_GIX);
+ }
+ *ptep = __pte(new_pte & ~_PAGE_BUSY);
+ return 0;
+}
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
deleted file mode 100644
index 3b49e32..0000000
--- a/arch/powerpc/mm/hash_low_64.S
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
- * ppc64 MMU hashtable management routines
- *
- * (c) Copyright IBM Corp. 2003, 2005
- *
- * Maintained by: Benjamin Herrenschmidt
- * <benh@kernel.crashing.org>
- *
- * This file is covered by the GNU Public Licence v2 as
- * described in the kernel's COPYING file.
- */
-
-#include <asm/reg.h>
-#include <asm/pgtable.h>
-#include <asm/mmu.h>
-#include <asm/page.h>
-#include <asm/types.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cputable.h>
-
- .text
-
-/*
- * Stackframe:
- *
- * +-> Back chain (SP + 256)
- * | General register save area (SP + 112)
- * | Parameter save area (SP + 48)
- * | TOC save area (SP + 40)
- * | link editor doubleword (SP + 32)
- * | compiler doubleword (SP + 24)
- * | LR save area (SP + 16)
- * | CR save area (SP + 8)
- * SP ---> +-- Back chain (SP + 0)
- */
-
-#ifndef CONFIG_PPC_64K_PAGES
-
-/*****************************************************************************
- * *
- * 4K SW & 4K HW pages implementation *
- * *
- *****************************************************************************/
-
-
-/*
- * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
- * pte_t *ptep, unsigned long trap, unsigned long flags,
- * int ssize)
- *
- * Adds a 4K page to the hash table in a segment of 4K pages only
- */
-
-_GLOBAL(__hash_page_4K)
- mflr r0
- std r0,16(r1)
- stdu r1,-STACKFRAMESIZE(r1)
- /* Save all params that we need after a function call */
- std r6,STK_PARAM(R6)(r1)
- std r8,STK_PARAM(R8)(r1)
- std r9,STK_PARAM(R9)(r1)
-
- /* Save non-volatile registers.
- * r31 will hold "old PTE"
- * r30 is "new PTE"
- * r29 is vpn
- * r28 is a hash value
- * r27 is hashtab mask (maybe dynamic patched instead ?)
- */
- std r27,STK_REG(R27)(r1)
- std r28,STK_REG(R28)(r1)
- std r29,STK_REG(R29)(r1)
- std r30,STK_REG(R30)(r1)
- std r31,STK_REG(R31)(r1)
-
- /* Step 1:
- *
- * Check permissions, atomically mark the linux PTE busy
- * and hashed.
- */
-1:
- ldarx r31,0,r6
- /* Check access rights (access & ~(pte_val(*ptep))) */
- andc. r0,r4,r31
- bne- htab_wrong_access
- /* Check if PTE is busy */
- andi. r0,r31,_PAGE_BUSY
- /* If so, just bail out and refault if needed. Someone else
- * is changing this PTE anyway and might hash it.
- */
- bne- htab_bail_ok
-
- /* Prepare new PTE value (turn access RW into DIRTY, then
- * add BUSY,HASHPTE and ACCESSED)
- */
- rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
- or r30,r30,r31
- ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
- /* Write the linux PTE atomically (setting busy) */
- stdcx. r30,0,r6
- bne- 1b
- isync
-
- /* Step 2:
- *
- * Insert/Update the HPTE in the hash table. At this point,
- * r4 (access) is re-useable, we use it for the new HPTE flags
- */
-
-BEGIN_FTR_SECTION
- cmpdi r9,0 /* check segment size */
- bne 3f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT - VPN_SHIFT
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
- or r29,r28,r29
- /*
- * Calculate hash value for primary slot and store it in r28
- * r3 = va, r5 = vsid
- * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
- */
- rldicl r0,r3,64-12,48
- xor r28,r5,r0 /* hash */
- b 4f
-
-3: /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
- or r29,r28,r29
-
- /*
- * calculate hash value for primary slot and
- * store it in r28 for 1T segment
- * r3 = va, r5 = vsid
- */
- sldi r28,r5,25 /* vsid << 25 */
- /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
- rldicl r0,r3,64-12,36
- xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
- xor r28,r28,r0 /* hash */
-
- /* Convert linux PTE bits into HW equivalents */
-4: andi. r3,r30,0x1fe /* Get basic set of flags */
- xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
- rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
- rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
- and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
- andc r0,r30,r0 /* r0 = pte & ~r0 */
- rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
- /*
- * Always add "C" bit for perf. Memory coherence is always enabled
- */
- ori r3,r3,HPTE_R_C | HPTE_R_M
-
- /* We eventually do the icache sync here (maybe inline that
- * code rather than call a C function...)
- */
-BEGIN_FTR_SECTION
- mr r4,r30
- mr r5,r7
- bl hash_page_do_lazy_icache
-END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
-
- /* At this point, r3 contains new PP bits, save them in
- * place of "access" in the param area (sic)
- */
- std r3,STK_PARAM(R4)(r1)
-
- /* Get htab_hash_mask */
- ld r4,htab_hash_mask@got(2)
- ld r27,0(r4) /* htab_hash_mask -> r27 */
-
- /* Check if we may already be in the hashtable, in this case, we
- * go to out-of-line code to try to modify the HPTE
- */
- andi. r0,r31,_PAGE_HASHPTE
- bne htab_modify_pte
-
-htab_insert_pte:
- /* Clear hpte bits in new pte (we also clear BUSY btw) and
- * add _PAGE_HASHPTE
- */
- lis r0,_PAGE_HPTEFLAGS@h
- ori r0,r0,_PAGE_HPTEFLAGS@l
- andc r30,r30,r0
- ori r30,r30,_PAGE_HASHPTE
-
- /* physical address r5 */
- rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
- sldi r5,r5,PAGE_SHIFT
-
- /* Calculate primary group hash */
- and r0,r28,r27
- rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,0 /* !bolted, !secondary */
- li r8,MMU_PAGE_4K /* page size */
- li r9,MMU_PAGE_4K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl htab_call_hpte_insert1
-htab_call_hpte_insert1:
- bl . /* Patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Now try secondary slot */
-
- /* physical address r5 */
- rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
- sldi r5,r5,PAGE_SHIFT
-
- /* Calculate secondary group hash */
- andc r0,r27,r28
- rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,HPTE_V_SECONDARY /* !bolted, secondary */
- li r8,MMU_PAGE_4K /* page size */
- li r9,MMU_PAGE_4K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl htab_call_hpte_insert2
-htab_call_hpte_insert2:
- bl . /* Patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge+ htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Both are full, we need to evict something */
- mftb r0
- /* Pick a random group based on TB */
- andi. r0,r0,1
- mr r5,r28
- bne 2f
- not r5,r5
-2: and r0,r5,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- /* Call ppc_md.hpte_remove */
-.globl htab_call_hpte_remove
-htab_call_hpte_remove:
- bl . /* Patched by htab_finish_init() */
-
- /* Try all again */
- b htab_insert_pte
-
-htab_bail_ok:
- li r3,0
- b htab_bail
-
-htab_pte_insert_ok:
- /* Insert slot number & secondary bit in PTE */
- rldimi r30,r3,12,63-15
-
- /* Write out the PTE with a normal write
- * (maybe add eieio may be good still ?)
- */
-htab_write_out_pte:
- ld r6,STK_PARAM(R6)(r1)
- std r30,0(r6)
- li r3, 0
-htab_bail:
- ld r27,STK_REG(R27)(r1)
- ld r28,STK_REG(R28)(r1)
- ld r29,STK_REG(R29)(r1)
- ld r30,STK_REG(R30)(r1)
- ld r31,STK_REG(R31)(r1)
- addi r1,r1,STACKFRAMESIZE
- ld r0,16(r1)
- mtlr r0
- blr
-
-htab_modify_pte:
- /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
- mr r4,r3
- rlwinm r3,r31,32-12,29,31
-
- /* Secondary group ? if yes, get a inverted hash value */
- mr r5,r28
- andi. r0,r31,_PAGE_SECONDARY
- beq 1f
- not r5,r5
-1:
- /* Calculate proper slot value for ppc_md.hpte_updatepp */
- and r0,r5,r27
- rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- add r3,r0,r3 /* add slot idx */
-
- /* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* vpn */
- li r6,MMU_PAGE_4K /* base page size */
- li r7,MMU_PAGE_4K /* actual page size */
- ld r8,STK_PARAM(R9)(r1) /* segment size */
- ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
-.globl htab_call_hpte_updatepp
-htab_call_hpte_updatepp:
- bl . /* Patched by htab_finish_init() */
-
- /* if we failed because typically the HPTE wasn't really here
- * we try an insertion.
- */
- cmpdi 0,r3,-1
- beq- htab_insert_pte
-
- /* Clear the BUSY bit and Write out the PTE */
- li r0,_PAGE_BUSY
- andc r30,r30,r0
- b htab_write_out_pte
-
-htab_wrong_access:
- /* Bail out clearing reservation */
- stdcx. r31,0,r6
- li r3,1
- b htab_bail
-
-htab_pte_insert_failure:
- /* Bail out restoring old PTE */
- ld r6,STK_PARAM(R6)(r1)
- std r31,0(r6)
- li r3,-1
- b htab_bail
-
-
-#else /* CONFIG_PPC_64K_PAGES */
-
-
-/*****************************************************************************
- * *
- * 64K SW & 4K or 64K HW in a 4K segment pages implementation *
- * *
- *****************************************************************************/
-
-/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
- * pte_t *ptep, unsigned long trap, unsigned local flags,
- * int ssize, int subpg_prot)
- */
-
-/*
- * For now, we do NOT implement Admixed pages
- */
-_GLOBAL(__hash_page_4K)
- mflr r0
- std r0,16(r1)
- stdu r1,-STACKFRAMESIZE(r1)
- /* Save all params that we need after a function call */
- std r6,STK_PARAM(R6)(r1)
- std r8,STK_PARAM(R8)(r1)
- std r9,STK_PARAM(R9)(r1)
-
- /* Save non-volatile registers.
- * r31 will hold "old PTE"
- * r30 is "new PTE"
- * r29 is vpn
- * r28 is a hash value
- * r27 is hashtab mask (maybe dynamic patched instead ?)
- * r26 is the hidx mask
- * r25 is the index in combo page
- */
- std r25,STK_REG(R25)(r1)
- std r26,STK_REG(R26)(r1)
- std r27,STK_REG(R27)(r1)
- std r28,STK_REG(R28)(r1)
- std r29,STK_REG(R29)(r1)
- std r30,STK_REG(R30)(r1)
- std r31,STK_REG(R31)(r1)
-
- /* Step 1:
- *
- * Check permissions, atomically mark the linux PTE busy
- * and hashed.
- */
-1:
- ldarx r31,0,r6
- /* Check access rights (access & ~(pte_val(*ptep))) */
- andc. r0,r4,r31
- bne- htab_wrong_access
- /* Check if PTE is busy */
- andi. r0,r31,_PAGE_BUSY
- /* If so, just bail out and refault if needed. Someone else
- * is changing this PTE anyway and might hash it.
- */
- bne- htab_bail_ok
- /* Prepare new PTE value (turn access RW into DIRTY, then
- * add BUSY and ACCESSED)
- */
- rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
- or r30,r30,r31
- ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
- oris r30,r30,_PAGE_COMBO@h
- /* Write the linux PTE atomically (setting busy) */
- stdcx. r30,0,r6
- bne- 1b
- isync
-
- /* Step 2:
- *
- * Insert/Update the HPTE in the hash table. At this point,
- * r4 (access) is re-useable, we use it for the new HPTE flags
- */
-
- /* Load the hidx index */
- rldicl r25,r3,64-12,60
-
-BEGIN_FTR_SECTION
- cmpdi r9,0 /* check segment size */
- bne 3f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT - VPN_SHIFT
- /*
- * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff
- * srdi r28,r3,VPN_SHIFT
- */
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
- or r29,r28,r29
- /*
- * Calculate hash value for primary slot and store it in r28
- * r3 = va, r5 = vsid
- * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
- */
- rldicl r0,r3,64-12,48
- xor r28,r5,r0 /* hash */
- b 4f
-
-3: /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
- /*
- * clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff
- * srdi r28,r3,VPN_SHIFT
- */
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
- or r29,r28,r29
-
- /*
- * Calculate hash value for primary slot and
- * store it in r28 for 1T segment
- * r3 = va, r5 = vsid
- */
- sldi r28,r5,25 /* vsid << 25 */
- /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
- rldicl r0,r3,64-12,36
- xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
- xor r28,r28,r0 /* hash */
-
- /* Convert linux PTE bits into HW equivalents */
-4:
-#ifdef CONFIG_PPC_SUBPAGE_PROT
- andc r10,r30,r10
- andi. r3,r10,0x1fe /* Get basic set of flags */
- rlwinm r0,r10,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
-#else
- andi. r3,r30,0x1fe /* Get basic set of flags */
- rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
-#endif
- xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
- rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
- and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
- andc r0,r3,r0 /* r0 = pte & ~r0 */
- rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
- /*
- * Always add "C" bit for perf. Memory coherence is always enabled
- */
- ori r3,r3,HPTE_R_C | HPTE_R_M
-
- /* We eventually do the icache sync here (maybe inline that
- * code rather than call a C function...)
- */
-BEGIN_FTR_SECTION
- mr r4,r30
- mr r5,r7
- bl hash_page_do_lazy_icache
-END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
-
- /* At this point, r3 contains new PP bits, save them in
- * place of "access" in the param area (sic)
- */
- std r3,STK_PARAM(R4)(r1)
-
- /* Get htab_hash_mask */
- ld r4,htab_hash_mask@got(2)
- ld r27,0(r4) /* htab_hash_mask -> r27 */
-
- /* Check if we may already be in the hashtable, in this case, we
- * go to out-of-line code to try to modify the HPTE. We look for
- * the bit at (1 >> (index + 32))
- */
- rldicl. r0,r31,64-12,48
- li r26,0 /* Default hidx */
- beq htab_insert_pte
-
- /*
- * Check if the pte was already inserted into the hash table
- * as a 64k HW page, and invalidate the 64k HPTE if so.
- */
- andis. r0,r31,_PAGE_COMBO@h
- beq htab_inval_old_hpte
-
- ld r6,STK_PARAM(R6)(r1)
- ori r26,r6,PTE_PAGE_HIDX_OFFSET /* Load the hidx mask. */
- ld r26,0(r26)
- addi r5,r25,36 /* Check actual HPTE_SUB bit, this */
- rldcr. r0,r31,r5,0 /* must match pgtable.h definition */
- bne htab_modify_pte
-
-htab_insert_pte:
- /* real page number in r5, PTE RPN value + index */
- andis. r0,r31,_PAGE_4K_PFN@h
- srdi r5,r31,PTE_RPN_SHIFT
- bne- htab_special_pfn
- sldi r5,r5,PAGE_FACTOR
- add r5,r5,r25
-htab_special_pfn:
- sldi r5,r5,HW_PAGE_SHIFT
-
- /* Calculate primary group hash */
- and r0,r28,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,0 /* !bolted, !secondary */
- li r8,MMU_PAGE_4K /* page size */
- li r9,MMU_PAGE_4K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl htab_call_hpte_insert1
-htab_call_hpte_insert1:
- bl . /* patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Now try secondary slot */
-
- /* real page number in r5, PTE RPN value + index */
- andis. r0,r31,_PAGE_4K_PFN@h
- srdi r5,r31,PTE_RPN_SHIFT
- bne- 3f
- sldi r5,r5,PAGE_FACTOR
- add r5,r5,r25
-3: sldi r5,r5,HW_PAGE_SHIFT
-
- /* Calculate secondary group hash */
- andc r0,r27,r28
- rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,HPTE_V_SECONDARY /* !bolted, secondary */
- li r8,MMU_PAGE_4K /* page size */
- li r9,MMU_PAGE_4K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl htab_call_hpte_insert2
-htab_call_hpte_insert2:
- bl . /* patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge+ htab_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- htab_pte_insert_failure
-
- /* Both are full, we need to evict something */
- mftb r0
- /* Pick a random group based on TB */
- andi. r0,r0,1
- mr r5,r28
- bne 2f
- not r5,r5
-2: and r0,r5,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- /* Call ppc_md.hpte_remove */
-.globl htab_call_hpte_remove
-htab_call_hpte_remove:
- bl . /* patched by htab_finish_init() */
-
- /* Try all again */
- b htab_insert_pte
-
- /*
- * Call out to C code to invalidate an 64k HW HPTE that is
- * useless now that the segment has been switched to 4k pages.
- */
-htab_inval_old_hpte:
- mr r3,r29 /* vpn */
- mr r4,r31 /* PTE.pte */
- li r5,0 /* PTE.hidx */
- li r6,MMU_PAGE_64K /* psize */
- ld r7,STK_PARAM(R9)(r1) /* ssize */
- ld r8,STK_PARAM(R8)(r1) /* flags */
- bl flush_hash_page
- /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */
- lis r0,_PAGE_HPTE_SUB@h
- ori r0,r0,_PAGE_HPTE_SUB@l
- andc r30,r30,r0
- b htab_insert_pte
-
-htab_bail_ok:
- li r3,0
- b htab_bail
-
-htab_pte_insert_ok:
- /* Insert slot number & secondary bit in PTE second half,
- * clear _PAGE_BUSY and set approriate HPTE slot bit
- */
- ld r6,STK_PARAM(R6)(r1)
- li r0,_PAGE_BUSY
- andc r30,r30,r0
- /* HPTE SUB bit */
- li r0,1
- subfic r5,r25,27 /* Must match bit position in */
- sld r0,r0,r5 /* pgtable.h */
- or r30,r30,r0
- /* hindx */
- sldi r5,r25,2
- sld r3,r3,r5
- li r4,0xf
- sld r4,r4,r5
- andc r26,r26,r4
- or r26,r26,r3
- ori r5,r6,PTE_PAGE_HIDX_OFFSET
- std r26,0(r5)
- lwsync
- std r30,0(r6)
- li r3, 0
-htab_bail:
- ld r25,STK_REG(R25)(r1)
- ld r26,STK_REG(R26)(r1)
- ld r27,STK_REG(R27)(r1)
- ld r28,STK_REG(R28)(r1)
- ld r29,STK_REG(R29)(r1)
- ld r30,STK_REG(R30)(r1)
- ld r31,STK_REG(R31)(r1)
- addi r1,r1,STACKFRAMESIZE
- ld r0,16(r1)
- mtlr r0
- blr
-
-htab_modify_pte:
- /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
- mr r4,r3
- sldi r5,r25,2
- srd r3,r26,r5
-
- /* Secondary group ? if yes, get a inverted hash value */
- mr r5,r28
- andi. r0,r3,0x8 /* page secondary ? */
- beq 1f
- not r5,r5
-1: andi. r3,r3,0x7 /* extract idx alone */
-
- /* Calculate proper slot value for ppc_md.hpte_updatepp */
- and r0,r5,r27
- rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- add r3,r0,r3 /* add slot idx */
-
- /* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* vpn */
- li r6,MMU_PAGE_4K /* base page size */
- li r7,MMU_PAGE_4K /* actual page size */
- ld r8,STK_PARAM(R9)(r1) /* segment size */
- ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
-.globl htab_call_hpte_updatepp
-htab_call_hpte_updatepp:
- bl . /* patched by htab_finish_init() */
-
- /* if we failed because typically the HPTE wasn't really here
- * we try an insertion.
- */
- cmpdi 0,r3,-1
- beq- htab_insert_pte
-
- /* Clear the BUSY bit and Write out the PTE */
- li r0,_PAGE_BUSY
- andc r30,r30,r0
- ld r6,STK_PARAM(R6)(r1)
- std r30,0(r6)
- li r3,0
- b htab_bail
-
-htab_wrong_access:
- /* Bail out clearing reservation */
- stdcx. r31,0,r6
- li r3,1
- b htab_bail
-
-htab_pte_insert_failure:
- /* Bail out restoring old PTE */
- ld r6,STK_PARAM(R6)(r1)
- std r31,0(r6)
- li r3,-1
- b htab_bail
-
-#endif /* CONFIG_PPC_64K_PAGES */
-
-#ifdef CONFIG_PPC_64K_PAGES
-
-/*****************************************************************************
- * *
- * 64K SW & 64K HW in a 64K segment pages implementation *
- * *
- *****************************************************************************/
-
-_GLOBAL(__hash_page_64K)
- mflr r0
- std r0,16(r1)
- stdu r1,-STACKFRAMESIZE(r1)
- /* Save all params that we need after a function call */
- std r6,STK_PARAM(R6)(r1)
- std r8,STK_PARAM(R8)(r1)
- std r9,STK_PARAM(R9)(r1)
-
- /* Save non-volatile registers.
- * r31 will hold "old PTE"
- * r30 is "new PTE"
- * r29 is vpn
- * r28 is a hash value
- * r27 is hashtab mask (maybe dynamic patched instead ?)
- */
- std r27,STK_REG(R27)(r1)
- std r28,STK_REG(R28)(r1)
- std r29,STK_REG(R29)(r1)
- std r30,STK_REG(R30)(r1)
- std r31,STK_REG(R31)(r1)
-
- /* Step 1:
- *
- * Check permissions, atomically mark the linux PTE busy
- * and hashed.
- */
-1:
- ldarx r31,0,r6
- /* Check access rights (access & ~(pte_val(*ptep))) */
- andc. r0,r4,r31
- bne- ht64_wrong_access
- /* Check if PTE is busy */
- andi. r0,r31,_PAGE_BUSY
- /* If so, just bail out and refault if needed. Someone else
- * is changing this PTE anyway and might hash it.
- */
- bne- ht64_bail_ok
-BEGIN_FTR_SECTION
- /* Check if PTE has the cache-inhibit bit set */
- andi. r0,r31,_PAGE_NO_CACHE
- /* If so, bail out and refault as a 4k page */
- bne- ht64_bail_ok
-END_MMU_FTR_SECTION_IFCLR(MMU_FTR_CI_LARGE_PAGE)
- /* Prepare new PTE value (turn access RW into DIRTY, then
- * add BUSY and ACCESSED)
- */
- rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
- or r30,r30,r31
- ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
- /* Write the linux PTE atomically (setting busy) */
- stdcx. r30,0,r6
- bne- 1b
- isync
-
- /* Step 2:
- *
- * Insert/Update the HPTE in the hash table. At this point,
- * r4 (access) is re-useable, we use it for the new HPTE flags
- */
-
-BEGIN_FTR_SECTION
- cmpdi r9,0 /* check segment size */
- bne 3f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT - VPN_SHIFT
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
- or r29,r28,r29
-
- /* Calculate hash value for primary slot and store it in r28
- * r3 = va, r5 = vsid
- * r0 = (va >> 16) & ((1ul << (28 - 16)) -1)
- */
- rldicl r0,r3,64-16,52
- xor r28,r5,r0 /* hash */
- b 4f
-
-3: /* Calc vpn and put it in r29 */
- sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
- rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
- or r29,r28,r29
- /*
- * calculate hash value for primary slot and
- * store it in r28 for 1T segment
- * r3 = va, r5 = vsid
- */
- sldi r28,r5,25 /* vsid << 25 */
- /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */
- rldicl r0,r3,64-16,40
- xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
- xor r28,r28,r0 /* hash */
-
- /* Convert linux PTE bits into HW equivalents */
-4: andi. r3,r30,0x1fe /* Get basic set of flags */
- xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
- rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
- rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
- and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
- andc r0,r30,r0 /* r0 = pte & ~r0 */
- rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
- /*
- * Always add "C" bit for perf. Memory coherence is always enabled
- */
- ori r3,r3,HPTE_R_C | HPTE_R_M
-
- /* We eventually do the icache sync here (maybe inline that
- * code rather than call a C function...)
- */
-BEGIN_FTR_SECTION
- mr r4,r30
- mr r5,r7
- bl hash_page_do_lazy_icache
-END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
-
- /* At this point, r3 contains new PP bits, save them in
- * place of "access" in the param area (sic)
- */
- std r3,STK_PARAM(R4)(r1)
-
- /* Get htab_hash_mask */
- ld r4,htab_hash_mask@got(2)
- ld r27,0(r4) /* htab_hash_mask -> r27 */
-
- /* Check if we may already be in the hashtable, in this case, we
- * go to out-of-line code to try to modify the HPTE
- */
- rldicl. r0,r31,64-12,48
- bne ht64_modify_pte
-
-ht64_insert_pte:
- /* Clear hpte bits in new pte (we also clear BUSY btw) and
- * add _PAGE_HPTE_SUB0
- */
- lis r0,_PAGE_HPTEFLAGS@h
- ori r0,r0,_PAGE_HPTEFLAGS@l
- andc r30,r30,r0
-#ifdef CONFIG_PPC_64K_PAGES
- oris r30,r30,_PAGE_HPTE_SUB0@h
-#else
- ori r30,r30,_PAGE_HASHPTE
-#endif
- /* Phyical address in r5 */
- rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
- sldi r5,r5,PAGE_SHIFT
-
- /* Calculate primary group hash */
- and r0,r28,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,0 /* !bolted, !secondary */
- li r8,MMU_PAGE_64K
- li r9,MMU_PAGE_64K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl ht64_call_hpte_insert1
-ht64_call_hpte_insert1:
- bl . /* patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge ht64_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- ht64_pte_insert_failure
-
- /* Now try secondary slot */
-
- /* Phyical address in r5 */
- rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
- sldi r5,r5,PAGE_SHIFT
-
- /* Calculate secondary group hash */
- andc r0,r27,r28
- rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
-
- /* Call ppc_md.hpte_insert */
- ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve vpn */
- li r7,HPTE_V_SECONDARY /* !bolted, secondary */
- li r8,MMU_PAGE_64K
- li r9,MMU_PAGE_64K /* actual page size */
- ld r10,STK_PARAM(R9)(r1) /* segment size */
-.globl ht64_call_hpte_insert2
-ht64_call_hpte_insert2:
- bl . /* patched by htab_finish_init() */
- cmpdi 0,r3,0
- bge+ ht64_pte_insert_ok /* Insertion successful */
- cmpdi 0,r3,-2 /* Critical failure */
- beq- ht64_pte_insert_failure
-
- /* Both are full, we need to evict something */
- mftb r0
- /* Pick a random group based on TB */
- andi. r0,r0,1
- mr r5,r28
- bne 2f
- not r5,r5
-2: and r0,r5,r27
- rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- /* Call ppc_md.hpte_remove */
-.globl ht64_call_hpte_remove
-ht64_call_hpte_remove:
- bl . /* patched by htab_finish_init() */
-
- /* Try all again */
- b ht64_insert_pte
-
-ht64_bail_ok:
- li r3,0
- b ht64_bail
-
-ht64_pte_insert_ok:
- /* Insert slot number & secondary bit in PTE */
- rldimi r30,r3,12,63-15
-
- /* Write out the PTE with a normal write
- * (maybe add eieio may be good still ?)
- */
-ht64_write_out_pte:
- ld r6,STK_PARAM(R6)(r1)
- std r30,0(r6)
- li r3, 0
-ht64_bail:
- ld r27,STK_REG(R27)(r1)
- ld r28,STK_REG(R28)(r1)
- ld r29,STK_REG(R29)(r1)
- ld r30,STK_REG(R30)(r1)
- ld r31,STK_REG(R31)(r1)
- addi r1,r1,STACKFRAMESIZE
- ld r0,16(r1)
- mtlr r0
- blr
-
-ht64_modify_pte:
- /* Keep PP bits in r4 and slot idx from the PTE around in r3 */
- mr r4,r3
- rlwinm r3,r31,32-12,29,31
-
- /* Secondary group ? if yes, get a inverted hash value */
- mr r5,r28
- andi. r0,r31,_PAGE_F_SECOND
- beq 1f
- not r5,r5
-1:
- /* Calculate proper slot value for ppc_md.hpte_updatepp */
- and r0,r5,r27
- rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
- add r3,r0,r3 /* add slot idx */
-
- /* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* vpn */
- li r6,MMU_PAGE_64K /* base page size */
- li r7,MMU_PAGE_64K /* actual page size */
- ld r8,STK_PARAM(R9)(r1) /* segment size */
- ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
-.globl ht64_call_hpte_updatepp
-ht64_call_hpte_updatepp:
- bl . /* patched by htab_finish_init() */
-
- /* if we failed because typically the HPTE wasn't really here
- * we try an insertion.
- */
- cmpdi 0,r3,-1
- beq- ht64_insert_pte
-
- /* Clear the BUSY bit and Write out the PTE */
- li r0,_PAGE_BUSY
- andc r30,r30,r0
- b ht64_write_out_pte
-
-ht64_wrong_access:
- /* Bail out clearing reservation */
- stdcx. r31,0,r6
- li r3,1
- b ht64_bail
-
-ht64_pte_insert_failure:
- /* Bail out restoring old PTE */
- ld r6,STK_PARAM(R6)(r1)
- std r31,0(r6)
- li r3,-1
- b ht64_bail
-
-
-#endif /* CONFIG_PPC_64K_PAGES */
-
-
-/*****************************************************************************
- * *
- * Huge pages implementation is in hugetlbpage.c *
- * *
- *****************************************************************************/
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index c8822af..8eaac81 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -429,6 +429,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
local_irq_restore(flags);
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
static void native_hugepage_invalidate(unsigned long vsid,
unsigned long addr,
unsigned char *hpte_slot_array,
@@ -482,6 +483,15 @@ static void native_hugepage_invalidate(unsigned long vsid,
}
local_irq_restore(flags);
}
+#else
+static void native_hugepage_invalidate(unsigned long vsid,
+ unsigned long addr,
+ unsigned char *hpte_slot_array,
+ int psize, int ssize, int local)
+{
+ WARN(1, "%s called without THP support\n", __func__);
+}
+#endif
static inline int __hpte_actual_psize(unsigned int lp, int psize)
{
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index aee7017..7635b1c 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -159,24 +159,41 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
},
};
-static unsigned long htab_convert_pte_flags(unsigned long pteflags)
+unsigned long htab_convert_pte_flags(unsigned long pteflags)
{
- unsigned long rflags = pteflags & 0x1fa;
+ unsigned long rflags = 0;
/* _PAGE_EXEC -> NOEXEC */
if ((pteflags & _PAGE_EXEC) == 0)
rflags |= HPTE_R_N;
-
- /* PP bits. PAGE_USER is already PP bit 0x2, so we only
- * need to add in 0x1 if it's a read-only user page
+ /*
+ * PP bits:
+ * Linux uses slb key 0 for kernel and 1 for user.
+ * kernel areas are mapped with PP=00
+ * and there is no kernel RO (_PAGE_KERNEL_RO).
+ * User area is mapped with PP=0x2 for read/write
+ * or PP=0x3 for read-only (including writeable but clean pages).
*/
- if ((pteflags & _PAGE_USER) && !((pteflags & _PAGE_RW) &&
- (pteflags & _PAGE_DIRTY)))
- rflags |= 1;
+ if (pteflags & _PAGE_USER) {
+ rflags |= 0x2;
+ if (!((pteflags & _PAGE_RW) && (pteflags & _PAGE_DIRTY)))
+ rflags |= 0x1;
+ }
/*
* Always add "C" bit for perf. Memory coherence is always enabled
*/
- return rflags | HPTE_R_C | HPTE_R_M;
+ rflags |= HPTE_R_C | HPTE_R_M;
+ /*
+ * Add in WIG bits
+ */
+ if (pteflags & _PAGE_WRITETHRU)
+ rflags |= HPTE_R_W;
+ if (pteflags & _PAGE_NO_CACHE)
+ rflags |= HPTE_R_I;
+ if (pteflags & _PAGE_GUARDED)
+ rflags |= HPTE_R_G;
+
+ return rflags;
}
int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
@@ -238,36 +255,42 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
if (ret < 0)
break;
+
#ifdef CONFIG_DEBUG_PAGEALLOC
- if ((paddr >> PAGE_SHIFT) < linear_map_hash_count)
+ if (debug_pagealloc_enabled() &&
+ (paddr >> PAGE_SHIFT) < linear_map_hash_count)
linear_map_hash_slots[paddr >> PAGE_SHIFT] = ret | 0x80;
#endif /* CONFIG_DEBUG_PAGEALLOC */
}
return ret < 0 ? ret : 0;
}
-#ifdef CONFIG_MEMORY_HOTPLUG
int htab_remove_mapping(unsigned long vstart, unsigned long vend,
int psize, int ssize)
{
unsigned long vaddr;
unsigned int step, shift;
+ int rc;
+ int ret = 0;
shift = mmu_psize_defs[psize].shift;
step = 1 << shift;
- if (!ppc_md.hpte_removebolted) {
- printk(KERN_WARNING "Platform doesn't implement "
- "hpte_removebolted\n");
- return -EINVAL;
- }
+ if (!ppc_md.hpte_removebolted)
+ return -ENODEV;
- for (vaddr = vstart; vaddr < vend; vaddr += step)
- ppc_md.hpte_removebolted(vaddr, psize, ssize);
+ for (vaddr = vstart; vaddr < vend; vaddr += step) {
+ rc = ppc_md.hpte_removebolted(vaddr, psize, ssize);
+ if (rc == -ENOENT) {
+ ret = -ENOENT;
+ continue;
+ }
+ if (rc < 0)
+ return rc;
+ }
- return 0;
+ return ret;
}
-#endif /* CONFIG_MEMORY_HOTPLUG */
static int __init htab_dt_scan_seg_sizes(unsigned long node,
const char *uname, int depth,
@@ -495,17 +518,17 @@ static void __init htab_init_page_sizes(void)
if (mmu_has_feature(MMU_FTR_16M_PAGE))
memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
sizeof(mmu_psize_defaults_gp));
- found:
-#ifndef CONFIG_DEBUG_PAGEALLOC
- /*
- * Pick a size for the linear mapping. Currently, we only support
- * 16M, 1M and 4K which is the default
- */
- if (mmu_psize_defs[MMU_PAGE_16M].shift)
- mmu_linear_psize = MMU_PAGE_16M;
- else if (mmu_psize_defs[MMU_PAGE_1M].shift)
- mmu_linear_psize = MMU_PAGE_1M;
-#endif /* CONFIG_DEBUG_PAGEALLOC */
+found:
+ if (!debug_pagealloc_enabled()) {
+ /*
+ * Pick a size for the linear mapping. Currently, we only
+ * support 16M, 1M and 4K which is the default
+ */
+ if (mmu_psize_defs[MMU_PAGE_16M].shift)
+ mmu_linear_psize = MMU_PAGE_16M;
+ else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+ mmu_linear_psize = MMU_PAGE_1M;
+ }
#ifdef CONFIG_PPC_64K_PAGES
/*
@@ -588,10 +611,28 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
return 0;
}
-static unsigned long __init htab_get_table_size(void)
+unsigned htab_shift_for_mem_size(unsigned long mem_size)
{
- unsigned long mem_size, rnd_mem_size, pteg_count, psize;
+ unsigned memshift = __ilog2(mem_size);
+ unsigned pshift = mmu_psize_defs[mmu_virtual_psize].shift;
+ unsigned pteg_shift;
+
+ /* round mem_size up to next power of 2 */
+ if ((1UL << memshift) < mem_size)
+ memshift += 1;
+
+ /* aim for 2 pages / pteg */
+ pteg_shift = memshift - (pshift + 1);
+ /*
+ * 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab
+ * size permitted by the architecture.
+ */
+ return max(pteg_shift + 7, 18U);
+}
+
+static unsigned long __init htab_get_table_size(void)
+{
/* If hash size isn't already provided by the platform, we try to
* retrieve it from the device-tree. If it's not there neither, we
* calculate it now based on the total RAM size
@@ -601,74 +642,33 @@ static unsigned long __init htab_get_table_size(void)
if (ppc64_pft_size)
return 1UL << ppc64_pft_size;
- /* round mem_size up to next power of 2 */
- mem_size = memblock_phys_mem_size();
- rnd_mem_size = 1UL << __ilog2(mem_size);
- if (rnd_mem_size < mem_size)
- rnd_mem_size <<= 1;
-
- /* # pages / 2 */
- psize = mmu_psize_defs[mmu_virtual_psize].shift;
- pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11);
-
- return pteg_count << 7;
+ return 1UL << htab_shift_for_mem_size(memblock_phys_mem_size());
}
#ifdef CONFIG_MEMORY_HOTPLUG
int create_section_mapping(unsigned long start, unsigned long end)
{
- return htab_bolt_mapping(start, end, __pa(start),
- pgprot_val(PAGE_KERNEL), mmu_linear_psize,
- mmu_kernel_ssize);
+ int rc = htab_bolt_mapping(start, end, __pa(start),
+ pgprot_val(PAGE_KERNEL), mmu_linear_psize,
+ mmu_kernel_ssize);
+
+ if (rc < 0) {
+ int rc2 = htab_remove_mapping(start, end, mmu_linear_psize,
+ mmu_kernel_ssize);
+ BUG_ON(rc2 && (rc2 != -ENOENT));
+ }
+ return rc;
}
int remove_section_mapping(unsigned long start, unsigned long end)
{
- return htab_remove_mapping(start, end, mmu_linear_psize,
- mmu_kernel_ssize);
+ int rc = htab_remove_mapping(start, end, mmu_linear_psize,
+ mmu_kernel_ssize);
+ WARN_ON(rc < 0);
+ return rc;
}
#endif /* CONFIG_MEMORY_HOTPLUG */
-extern u32 htab_call_hpte_insert1[];
-extern u32 htab_call_hpte_insert2[];
-extern u32 htab_call_hpte_remove[];
-extern u32 htab_call_hpte_updatepp[];
-extern u32 ht64_call_hpte_insert1[];
-extern u32 ht64_call_hpte_insert2[];
-extern u32 ht64_call_hpte_remove[];
-extern u32 ht64_call_hpte_updatepp[];
-
-static void __init htab_finish_init(void)
-{
-#ifdef CONFIG_PPC_64K_PAGES
- patch_branch(ht64_call_hpte_insert1,
- ppc_function_entry(ppc_md.hpte_insert),
- BRANCH_SET_LINK);
- patch_branch(ht64_call_hpte_insert2,
- ppc_function_entry(ppc_md.hpte_insert),
- BRANCH_SET_LINK);
- patch_branch(ht64_call_hpte_remove,
- ppc_function_entry(ppc_md.hpte_remove),
- BRANCH_SET_LINK);
- patch_branch(ht64_call_hpte_updatepp,
- ppc_function_entry(ppc_md.hpte_updatepp),
- BRANCH_SET_LINK);
-#endif /* CONFIG_PPC_64K_PAGES */
-
- patch_branch(htab_call_hpte_insert1,
- ppc_function_entry(ppc_md.hpte_insert),
- BRANCH_SET_LINK);
- patch_branch(htab_call_hpte_insert2,
- ppc_function_entry(ppc_md.hpte_insert),
- BRANCH_SET_LINK);
- patch_branch(htab_call_hpte_remove,
- ppc_function_entry(ppc_md.hpte_remove),
- BRANCH_SET_LINK);
- patch_branch(htab_call_hpte_updatepp,
- ppc_function_entry(ppc_md.hpte_updatepp),
- BRANCH_SET_LINK);
-}
-
static void __init htab_initialize(void)
{
unsigned long table;
@@ -744,10 +744,12 @@ static void __init htab_initialize(void)
prot = pgprot_val(PAGE_KERNEL);
#ifdef CONFIG_DEBUG_PAGEALLOC
- linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT;
- linear_map_hash_slots = __va(memblock_alloc_base(linear_map_hash_count,
- 1, ppc64_rma_size));
- memset(linear_map_hash_slots, 0, linear_map_hash_count);
+ if (debug_pagealloc_enabled()) {
+ linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT;
+ linear_map_hash_slots = __va(memblock_alloc_base(
+ linear_map_hash_count, 1, ppc64_rma_size));
+ memset(linear_map_hash_slots, 0, linear_map_hash_count);
+ }
#endif /* CONFIG_DEBUG_PAGEALLOC */
/* On U3 based machines, we need to reserve the DART area and
@@ -815,7 +817,6 @@ static void __init htab_initialize(void)
mmu_linear_psize, mmu_kernel_ssize));
}
- htab_finish_init();
DBG(" <- htab_initialize()\n");
}
@@ -877,11 +878,11 @@ static unsigned int get_paca_psize(unsigned long addr)
unsigned long index, mask_index;
if (addr < SLICE_LOW_TOP) {
- lpsizes = get_paca()->context.low_slices_psize;
+ lpsizes = get_paca()->mm_ctx_low_slices_psize;
index = GET_LOW_SLICE_INDEX(addr);
return (lpsizes >> (index * 4)) & 0xF;
}
- hpsizes = get_paca()->context.high_slices_psize;
+ hpsizes = get_paca()->mm_ctx_high_slices_psize;
index = GET_HIGH_SLICE_INDEX(addr);
mask_index = index & 0x1;
return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;
@@ -890,7 +891,7 @@ static unsigned int get_paca_psize(unsigned long addr)
#else
unsigned int get_paca_psize(unsigned long addr)
{
- return get_paca()->context.user_psize;
+ return get_paca()->mm_ctx_user_psize;
}
#endif
@@ -906,7 +907,8 @@ void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
slice_set_range_psize(mm, addr, 1, MMU_PAGE_4K);
copro_flush_all_slbs(mm);
if ((get_paca_psize(addr) != MMU_PAGE_4K) && (current->mm == mm)) {
- get_paca()->context = mm->context;
+
+ copy_mm_to_paca(&mm->context);
slb_flush_and_rebolt();
}
}
@@ -973,7 +975,7 @@ static void check_paca_psize(unsigned long ea, struct mm_struct *mm,
{
if (user_region) {
if (psize != get_paca_psize(ea)) {
- get_paca()->context = mm->context;
+ copy_mm_to_paca(&mm->context);
slb_flush_and_rebolt();
}
} else if (get_paca()->vmalloc_sllp !=
@@ -994,6 +996,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap,
unsigned long flags)
{
+ bool is_thp;
enum ctx_state prev_state = exception_enter();
pgd_t *pgdir;
unsigned long vsid;
@@ -1068,7 +1071,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
#endif /* CONFIG_PPC_64K_PAGES */
/* Get PTE and page size from page tables */
- ptep = __find_linux_pte_or_hugepte(pgdir, ea, &hugeshift);
+ ptep = __find_linux_pte_or_hugepte(pgdir, ea, &is_thp, &hugeshift);
if (ptep == NULL || !pte_present(*ptep)) {
DBG_LOW(" no PTE !\n");
rc = 1;
@@ -1088,7 +1091,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
}
if (hugeshift) {
- if (pmd_trans_huge(*(pmd_t *)ptep))
+ if (is_thp)
rc = __hash_page_thp(ea, access, vsid, (pmd_t *)ptep,
trap, flags, ssize, psize);
#ifdef CONFIG_HUGETLB_PAGE
@@ -1147,9 +1150,10 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
}
}
+#endif /* CONFIG_PPC_64K_PAGES */
+
if (current->mm == mm)
check_paca_psize(ea, mm, psize, user_region);
-#endif /* CONFIG_PPC_64K_PAGES */
#ifdef CONFIG_PPC_64K_PAGES
if (psize == MMU_PAGE_64K)
@@ -1202,6 +1206,35 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
}
EXPORT_SYMBOL_GPL(hash_page);
+int __hash_page(unsigned long ea, unsigned long msr, unsigned long trap,
+ unsigned long dsisr)
+{
+ unsigned long access = _PAGE_PRESENT;
+ unsigned long flags = 0;
+ struct mm_struct *mm = current->mm;
+
+ if (REGION_ID(ea) == VMALLOC_REGION_ID)
+ mm = &init_mm;
+
+ if (dsisr & DSISR_NOHPTE)
+ flags |= HPTE_NOHPTE_UPDATE;
+
+ if (dsisr & DSISR_ISSTORE)
+ access |= _PAGE_RW;
+ /*
+ * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+ * accessing a userspace segment (even from the kernel). We assume
+ * kernel addresses always have the high bit set.
+ */
+ if ((msr & MSR_PR) || (REGION_ID(ea) == USER_REGION_ID))
+ access |= _PAGE_USER;
+
+ if (trap == 0x400)
+ access |= _PAGE_EXEC;
+
+ return hash_page_mm(mm, ea, access, trap, flags);
+}
+
void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap)
{
@@ -1243,7 +1276,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
* THP pages use update_mmu_cache_pmd. We don't do
* hash preload there. Hence can ignore THP here
*/
- ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugepage_shift);
+ ptep = find_linux_pte_or_hugepte(pgdir, ea, NULL, &hugepage_shift);
if (!ptep)
goto out_exit;
diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c
index 4d87122..eb2accd 100644
--- a/arch/powerpc/mm/hugepage-hash64.c
+++ b/arch/powerpc/mm/hugepage-hash64.c
@@ -39,9 +39,6 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
/* If PMD busy, retry the access */
if (unlikely(old_pmd & _PAGE_BUSY))
return 0;
- /* If PMD is trans splitting retry the access */
- if (unlikely(old_pmd & _PAGE_SPLITTING))
- return 0;
/* If PMD permissions don't match, take page fault */
if (unlikely(access & ~old_pmd))
return 1;
@@ -54,18 +51,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
new_pmd |= _PAGE_DIRTY;
} while (old_pmd != __cmpxchg_u64((unsigned long *)pmdp,
old_pmd, new_pmd));
- /*
- * PP bits. _PAGE_USER is already PP bit 0x2, so we only
- * need to add in 0x1 if it's a read-only user page
- */
- rflags = new_pmd & _PAGE_USER;
- if ((new_pmd & _PAGE_USER) && !((new_pmd & _PAGE_RW) &&
- (new_pmd & _PAGE_DIRTY)))
- rflags |= 0x1;
- /*
- * _PAGE_EXEC -> HW_NO_EXEC since it's inverted
- */
- rflags |= ((new_pmd & _PAGE_EXEC) ? 0 : HPTE_R_N);
+ rflags = htab_convert_pte_flags(new_pmd);
#if 0
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
@@ -82,7 +68,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
*/
shift = mmu_psize_defs[psize].shift;
index = (ea & ~HPAGE_PMD_MASK) >> shift;
- BUG_ON(index >= 4096);
+ BUG_ON(index >= PTE_FRAG_SIZE);
vpn = hpt_vpn(ea, vsid, ssize);
hpte_slot_array = get_hpte_slot_array(pmdp);
@@ -92,9 +78,19 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
* base page size. This is because demote_segment won't flush
* hash page table entries.
*/
- if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO))
+ if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO)) {
flush_hash_hugepage(vsid, ea, pmdp, MMU_PAGE_64K,
ssize, flags);
+ /*
+ * With THP, we also clear the slot information with
+ * respect to all the 64K hash pte mapping the 16MB
+ * page. They are all invalid now. This make sure we
+ * don't find the slot valid when we fault with 4k
+ * base page size.
+ *
+ */
+ memset(hpte_slot_array, 0, PTE_FRAG_SIZE);
+ }
}
valid = hpte_valid(hpte_slot_array, index);
@@ -131,13 +127,6 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
pa = pmd_pfn(__pmd(old_pmd)) << PAGE_SHIFT;
new_pmd |= _PAGE_HASHPTE;
- /* Add in WIMG bits */
- rflags |= (new_pmd & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
- _PAGE_GUARDED));
- /*
- * enable the memory coherence always
- */
- rflags |= HPTE_R_M;
repeat:
hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index ba47aaf..83a8be7 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -8,6 +8,8 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
+#include <asm/mmu.h>
+
#ifdef CONFIG_PPC_FSL_BOOK3E
#ifdef CONFIG_PPC64
static inline int tlb1_next(void)
@@ -51,6 +53,59 @@ static inline int mmu_get_tsize(int psize)
return mmu_psize_defs[psize].enc;
}
+#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC64)
+#include <asm/paca.h>
+
+static inline void book3e_tlb_lock(void)
+{
+ struct paca_struct *paca = get_paca();
+ unsigned long tmp;
+ int token = smp_processor_id() + 1;
+
+ /*
+ * Besides being unnecessary in the absence of SMT, this
+ * check prevents trying to do lbarx/stbcx. on e5500 which
+ * doesn't implement either feature.
+ */
+ if (!cpu_has_feature(CPU_FTR_SMT))
+ return;
+
+ asm volatile("1: lbarx %0, 0, %1;"
+ "cmpwi %0, 0;"
+ "bne 2f;"
+ "stbcx. %2, 0, %1;"
+ "bne 1b;"
+ "b 3f;"
+ "2: lbzx %0, 0, %1;"
+ "cmpwi %0, 0;"
+ "bne 2b;"
+ "b 1b;"
+ "3:"
+ : "=&r" (tmp)
+ : "r" (&paca->tcd_ptr->lock), "r" (token)
+ : "memory");
+}
+
+static inline void book3e_tlb_unlock(void)
+{
+ struct paca_struct *paca = get_paca();
+
+ if (!cpu_has_feature(CPU_FTR_SMT))
+ return;
+
+ isync();
+ paca->tcd_ptr->lock = 0;
+}
+#else
+static inline void book3e_tlb_lock(void)
+{
+}
+
+static inline void book3e_tlb_unlock(void)
+{
+}
+#endif
+
static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid)
{
int found = 0;
@@ -109,7 +164,10 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
*/
local_irq_save(flags);
+ book3e_tlb_lock();
+
if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
+ book3e_tlb_unlock();
local_irq_restore(flags);
return;
}
@@ -141,6 +199,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
asm volatile ("tlbwe");
+ book3e_tlb_unlock();
local_irq_restore(flags);
}
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index d94b1af..8555fce 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -59,10 +59,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
new_pte |= _PAGE_DIRTY;
} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
old_pte, new_pte));
+ rflags = htab_convert_pte_flags(new_pte);
- rflags = 0x2 | (!(new_pte & _PAGE_RW));
- /* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
- rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
sz = ((1UL) << shift);
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
/* No CPU has hugepages but lacks no execute, so we
@@ -78,7 +76,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
if (old_pte & _PAGE_F_SECOND)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
- slot += (old_pte & _PAGE_F_GIX) >> 12;
+ slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT;
if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
mmu_psize, ssize, flags) == -1)
@@ -91,18 +89,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
/* clear HPTE slot informations in new PTE */
-#ifdef CONFIG_PPC_64K_PAGES
- new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0;
-#else
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
-#endif
- /* Add in WIMG bits */
- rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
- _PAGE_COHERENT | _PAGE_GUARDED));
- /*
- * enable the memory coherence always
- */
- rflags |= HPTE_R_M;
slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0,
mmu_psize, ssize);
@@ -118,7 +105,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
return -1;
}
- new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX);
+ new_pte |= (slot << _PAGE_F_GIX_SHIFT) &
+ (_PAGE_F_SECOND | _PAGE_F_GIX);
}
/*
@@ -127,3 +115,21 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
*ptep = __pte(new_pte & ~_PAGE_BUSY);
return 0;
}
+
+#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_DEBUG_VM)
+/*
+ * This enables us to catch the wrong page directory format
+ * Moved here so that we can use WARN() in the call.
+ */
+int hugepd_ok(hugepd_t hpd)
+{
+ bool is_hugepd;
+
+ /*
+ * We should not find this format in page directory, warn otherwise.
+ */
+ is_hugepd = (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0));
+ WARN(is_hugepd, "Found wrong page directory format\n");
+ return 0;
+}
+#endif
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 06c1452..6dd272b 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -53,63 +53,10 @@ static unsigned nr_gpages;
#define hugepd_none(hpd) ((hpd).pd == 0)
-#ifdef CONFIG_PPC_BOOK3S_64
-/*
- * At this point we do the placement change only for BOOK3S 64. This would
- * possibly work on other subarchs.
- */
-
-/*
- * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have
- * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD;
- *
- * Defined in such a way that we can optimize away code block at build time
- * if CONFIG_HUGETLB_PAGE=n.
- */
-int pmd_huge(pmd_t pmd)
-{
- /*
- * leaf pte for huge page, bottom two bits != 00
- */
- return ((pmd_val(pmd) & 0x3) != 0x0);
-}
-
-int pud_huge(pud_t pud)
-{
- /*
- * leaf pte for huge page, bottom two bits != 00
- */
- return ((pud_val(pud) & 0x3) != 0x0);
-}
-
-int pgd_huge(pgd_t pgd)
-{
- /*
- * leaf pte for huge page, bottom two bits != 00
- */
- return ((pgd_val(pgd) & 0x3) != 0x0);
-}
-#else
-int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
-
-int pud_huge(pud_t pud)
-{
- return 0;
-}
-
-int pgd_huge(pgd_t pgd)
-{
- return 0;
-}
-#endif
-
pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
{
/* Only called for hugetlbfs pages, hence can ignore THP */
- return __find_linux_pte_or_hugepte(mm->pgd, addr, NULL);
+ return __find_linux_pte_or_hugepte(mm->pgd, addr, NULL, NULL);
}
static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
@@ -160,8 +107,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
kmem_cache_free(cachep, new);
else {
#ifdef CONFIG_PPC_BOOK3S_64
- hpdp->pd = (unsigned long)new |
- (shift_to_mmu_psize(pshift) << 2);
+ hpdp->pd = __pa(new) | (shift_to_mmu_psize(pshift) << 2);
#else
hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
#endif
@@ -684,13 +630,14 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
struct page *
follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
{
+ bool is_thp;
pte_t *ptep, pte;
unsigned shift;
unsigned long mask, flags;
struct page *page = ERR_PTR(-EINVAL);
local_irq_save(flags);
- ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
+ ptep = find_linux_pte_or_hugepte(mm->pgd, address, &is_thp, &shift);
if (!ptep)
goto no_page;
pte = READ_ONCE(*ptep);
@@ -699,7 +646,7 @@ follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
* Transparent hugepages are handled by generic code. We can skip them
* here.
*/
- if (!shift || pmd_trans_huge(__pmd(pte_val(pte))))
+ if (!shift || is_thp)
goto no_page;
if (!pte_present(pte)) {
@@ -946,8 +893,8 @@ void flush_dcache_icache_hugepage(struct page *page)
* We have 4 cases for pgds and pmds:
* (1) invalid (all zeroes)
* (2) pointer to next table, as normal; bottom 6 bits == 0
- * (3) leaf pte for huge page, bottom two bits != 00
- * (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table
+ * (3) leaf pte for huge page _PAGE_PTE set
+ * (4) hugepd pointer, _PAGE_PTE = 0 and bits [2..6] indicate size of table
*
* So long as we atomically load page table pointers we are safe against teardown,
* we can follow the address down to the the page and take a ref on it.
@@ -956,7 +903,7 @@ void flush_dcache_icache_hugepage(struct page *page)
*/
pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
- unsigned *shift)
+ bool *is_thp, unsigned *shift)
{
pgd_t pgd, *pgdp;
pud_t pud, *pudp;
@@ -968,6 +915,9 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
if (shift)
*shift = 0;
+ if (is_thp)
+ *is_thp = false;
+
pgdp = pgdir + pgd_index(ea);
pgd = READ_ONCE(*pgdp);
/*
@@ -1007,15 +957,18 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
/*
* A hugepage collapse is captured by pmd_none, because
* it mark the pmd none and do a hpte invalidate.
- *
- * We don't worry about pmd_trans_splitting here, The
- * caller if it needs to handle the splitting case
- * should check for that.
*/
if (pmd_none(pmd))
return NULL;
- if (pmd_huge(pmd) || pmd_large(pmd)) {
+ if (pmd_trans_huge(pmd)) {
+ if (is_thp)
+ *is_thp = true;
+ ret_pte = (pte_t *) pmdp;
+ goto out;
+ }
+
+ if (pmd_huge(pmd)) {
ret_pte = (pte_t *) pmdp;
goto out;
} else if (is_hugepd(__hugepd(pmd_val(pmd))))
@@ -1041,7 +994,7 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
{
unsigned long mask;
unsigned long pte_end;
- struct page *head, *page, *tail;
+ struct page *head, *page;
pte_t pte;
int refs;
@@ -1064,7 +1017,6 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
head = pte_page(pte);
page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
- tail = page;
do {
VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page;
@@ -1086,15 +1038,5 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
return 0;
}
- /*
- * Any tail page need their mapcount reference taken before we
- * return.
- */
- while (refs--) {
- if (PageTail(tail))
- get_huge_page_tail(tail);
- tail++;
- }
-
return 1;
}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index a10be66..c899fe3 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -112,10 +112,10 @@ void __init MMU_setup(void)
if (strstr(boot_command_line, "noltlbs")) {
__map_without_ltlbs = 1;
}
-#ifdef CONFIG_DEBUG_PAGEALLOC
- __map_without_bats = 1;
- __map_without_ltlbs = 1;
-#endif
+ if (debug_pagealloc_enabled()) {
+ __map_without_bats = 1;
+ __map_without_ltlbs = 1;
+ }
}
/*
@@ -178,10 +178,6 @@ void __init MMU_init(void)
/* Initialize early top-down ioremap allocator */
ioremap_bot = IOREMAP_TOP;
- /* Map in I/O resources */
- if (ppc_md.progress)
- ppc_md.progress("MMU:setio", 0x302);
-
if (ppc_md.progress)
ppc_md.progress("MMU:exit", 0x211);
@@ -193,22 +189,3 @@ void __init MMU_init(void)
/* Shortly after that, the entire linear mapping will be available */
memblock_set_current_limit(lowmem_end_addr);
}
-
-#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
-void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
-{
- /* We don't currently support the first MEMBLOCK not mapping 0
- * physical on those processors
- */
- BUG_ON(first_memblock_base != 0);
-
-#ifdef CONFIG_PIN_TLB
- /* 8xx can only access 24MB at the moment */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
-#else
- /* 8xx can only access 8MB at the moment */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
-#endif
-}
-#endif /* CONFIG_8xx */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index d747dd7..ba65566 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -85,13 +85,14 @@ static void pgd_ctor(void *addr)
memset(addr, 0, PGD_TABLE_SIZE);
}
+static void pud_ctor(void *addr)
+{
+ memset(addr, 0, PUD_TABLE_SIZE);
+}
+
static void pmd_ctor(void *addr)
{
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- memset(addr, 0, PMD_TABLE_SIZE * 2);
-#else
memset(addr, 0, PMD_TABLE_SIZE);
-#endif
}
struct kmem_cache *pgtable_cache[MAX_PGTABLE_INDEX_SIZE];
@@ -142,14 +143,18 @@ void pgtable_cache_init(void)
{
pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor);
pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor);
+ /*
+ * In all current configs, when the PUD index exists it's the
+ * same size as either the pgd or pmd index except with THP enabled
+ * on book3s 64
+ */
+ if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
+ pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor);
+
if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX))
panic("Couldn't allocate pgtable caches");
- /* In all current configs, when the PUD index exists it's the
- * same size as either the pgd or pmd index. Verify that the
- * initialization above has also created a PUD cache. This
- * will need re-examiniation if we add new possibilities for
- * the pagetable layout. */
- BUG_ON(PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE));
+ if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
+ panic("Couldn't allocate pud pgtable caches");
}
#ifdef CONFIG_SPARSEMEM_VMEMMAP
@@ -192,9 +197,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)
*/
#ifdef CONFIG_PPC_BOOK3E
-static void __meminit vmemmap_create_mapping(unsigned long start,
- unsigned long page_size,
- unsigned long phys)
+static int __meminit vmemmap_create_mapping(unsigned long start,
+ unsigned long page_size,
+ unsigned long phys)
{
/* Create a PTE encoding without page size */
unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED |
@@ -212,6 +217,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
*/
for (i = 0; i < page_size; i += PAGE_SIZE)
BUG_ON(map_kernel_page(start + i, phys, flags));
+
+ return 0;
}
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -221,25 +228,31 @@ static void vmemmap_remove_mapping(unsigned long start,
}
#endif
#else /* CONFIG_PPC_BOOK3E */
-static void __meminit vmemmap_create_mapping(unsigned long start,
- unsigned long page_size,
- unsigned long phys)
+static int __meminit vmemmap_create_mapping(unsigned long start,
+ unsigned long page_size,
+ unsigned long phys)
{
- int mapped = htab_bolt_mapping(start, start + page_size, phys,
- pgprot_val(PAGE_KERNEL),
- mmu_vmemmap_psize,
- mmu_kernel_ssize);
- BUG_ON(mapped < 0);
+ int rc = htab_bolt_mapping(start, start + page_size, phys,
+ pgprot_val(PAGE_KERNEL),
+ mmu_vmemmap_psize, mmu_kernel_ssize);
+ if (rc < 0) {
+ int rc2 = htab_remove_mapping(start, start + page_size,
+ mmu_vmemmap_psize,
+ mmu_kernel_ssize);
+ BUG_ON(rc2 && (rc2 != -ENOENT));
+ }
+ return rc;
}
#ifdef CONFIG_MEMORY_HOTPLUG
static void vmemmap_remove_mapping(unsigned long start,
unsigned long page_size)
{
- int mapped = htab_remove_mapping(start, start + page_size,
- mmu_vmemmap_psize,
- mmu_kernel_ssize);
- BUG_ON(mapped < 0);
+ int rc = htab_remove_mapping(start, start + page_size,
+ mmu_vmemmap_psize,
+ mmu_kernel_ssize);
+ BUG_ON((rc < 0) && (rc != -ENOENT));
+ WARN_ON(rc == -ENOENT);
}
#endif
@@ -307,6 +320,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
for (; start < end; start += page_size) {
void *p;
+ int rc;
if (vmemmap_populated(start, page_size))
continue;
@@ -320,7 +334,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
pr_debug(" * %016lx..%016lx allocated at %p\n",
start, start + page_size, p);
- vmemmap_create_mapping(start, page_size, __pa(p));
+ rc = vmemmap_create_mapping(start, page_size, __pa(p));
+ if (rc < 0) {
+ pr_warning(
+ "vmemmap_populate: Unable to create vmemmap mapping: %d\n",
+ rc);
+ return -EFAULT;
+ }
}
return 0;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 22d94c3..ac79dbd 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
struct zone *zone;
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
+ int rc;
pgdata = NODE_DATA(nid);
start = (unsigned long)__va(start);
- if (create_section_mapping(start, start + size))
- return -EINVAL;
+ rc = create_section_mapping(start, start + size);
+ if (rc) {
+ pr_warning(
+ "Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n",
+ start, start + size, rc);
+ return -EFAULT;
+ }
/* this should work for most non-highmem platforms */
zone = pgdata->node_zones +
@@ -541,7 +547,7 @@ static int __init add_system_ram_resources(void)
res->name = "System RAM";
res->start = base;
res->end = base + size - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
WARN_ON(request_resource(&iomem_resource, res) < 0);
}
}
@@ -560,12 +566,12 @@ subsys_initcall(add_system_ram_resources);
*/
int devmem_is_allowed(unsigned long pfn)
{
+ if (page_is_rtas_user_buf(pfn))
+ return 1;
if (iomem_is_exclusive(PFN_PHYS(pfn)))
return 0;
if (!page_is_ram(pfn))
return 1;
- if (page_is_rtas_user_buf(pfn))
- return 1;
return 0;
}
#endif /* CONFIG_STRICT_DEVMEM */
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index 0f0502e..4087705 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -59,9 +59,9 @@ unsigned long arch_mmap_rnd(void)
/* 8MB for 32bit, 1GB for 64bit */
if (is_32bit_task())
- rnd = (unsigned long)get_random_int() % (1<<(23-PAGE_SHIFT));
+ rnd = get_random_long() % (1<<(23-PAGE_SHIFT));
else
- rnd = (unsigned long)get_random_int() % (1<<(30-PAGE_SHIFT));
+ rnd = get_random_long() % (1UL<<(30-PAGE_SHIFT));
return rnd << PAGE_SHIFT;
}
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 4e4efbc..9ca6fe1 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -118,8 +118,7 @@ static void destroy_pagetable_page(struct mm_struct *mm)
/* drop all the pending references */
count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT;
/* We allow PTE_FRAG_NR fragments from a PTE page */
- count = atomic_sub_return(PTE_FRAG_NR - count, &page->_count);
- if (!count) {
+ if (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) {
pgtable_page_dtor(page);
free_hot_cold_page(page, 0);
}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 085b66b..bfb7c0b 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -100,7 +100,6 @@ extern void setbat(int index, unsigned long virt, phys_addr_t phys,
extern int __map_without_bats;
extern int __allow_ioremap_reserved;
-extern unsigned long ioremap_base;
extern unsigned int rtas_data, rtas_size;
struct hash_pte;
@@ -110,7 +109,8 @@ extern unsigned long Hash_size, Hash_mask;
#endif /* CONFIG_PPC32 */
#ifdef CONFIG_PPC64
-extern int map_kernel_page(unsigned long ea, unsigned long pa, int flags);
+extern int map_kernel_page(unsigned long ea, unsigned long pa,
+ unsigned long flags);
#endif /* CONFIG_PPC64 */
extern unsigned long ioremap_bot;
@@ -132,26 +132,23 @@ extern void wii_memory_fixups(void);
/* ...and now those things that may be slightly different between processor
* architectures. -- Dan
*/
-#if defined(CONFIG_8xx)
-#define MMU_init_hw() do { } while(0)
-#define mmu_mapin_ram(top) (0UL)
-
-#elif defined(CONFIG_4xx)
+#ifdef CONFIG_PPC32
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(unsigned long top);
+#endif
-#elif defined(CONFIG_PPC_FSL_BOOK3E)
-extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
+#ifdef CONFIG_PPC_FSL_BOOK3E
+extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx,
+ bool dryrun);
extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
phys_addr_t phys);
#ifdef CONFIG_PPC32
-extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(unsigned long top);
extern void adjust_total_lowmem(void);
extern int switch_to_as1(void);
extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
#endif
extern void loadcam_entry(unsigned int index);
+extern void loadcam_multi(int first_idx, int num, int tmp_idx);
struct tlbcam {
u32 MAS0;
@@ -160,8 +157,14 @@ struct tlbcam {
u32 MAS3;
u32 MAS7;
};
-#elif defined(CONFIG_PPC32)
-/* anything 32-bit except 4xx or 8xx */
-extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(unsigned long top);
+#endif
+
+#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE)
+/* 6xx have BATS */
+/* FSL_BOOKE have TLBCAM */
+phys_addr_t v_block_mapped(unsigned long va);
+unsigned long p_block_mapped(phys_addr_t pa);
+#else
+static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; }
+static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; }
#endif
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 8b9502a..669a15e 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -80,7 +80,7 @@ static void __init setup_node_to_cpumask_map(void)
setup_nr_node_ids();
/* allocate the map */
- for (node = 0; node < nr_node_ids; node++)
+ for_each_node(node)
alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
/* cpumask_of_node() will now work */
@@ -276,7 +276,6 @@ static int of_node_to_nid_single(struct device_node *device)
/* Walk the device tree upwards, looking for an associativity id */
int of_node_to_nid(struct device_node *device)
{
- struct device_node *tmp;
int nid = -1;
of_node_get(device);
@@ -285,9 +284,7 @@ int of_node_to_nid(struct device_node *device)
if (nid != -1)
break;
- tmp = device;
- device = of_get_parent(tmp);
- of_node_put(tmp);
+ device = of_get_next_parent(device);
}
of_node_put(device);
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 83dfcb5..de37ff4 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -179,6 +179,10 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
*/
VM_WARN_ON((pte_val(*ptep) & (_PAGE_PRESENT | _PAGE_USER)) ==
(_PAGE_PRESENT | _PAGE_USER));
+ /*
+ * Add the pte bit when tryint set a pte
+ */
+ pte = __pte(pte_val(pte) | _PAGE_PTE);
/* Note: mm->context.id might not yet have been assigned as
* this context might not have been activated yet when this
@@ -239,3 +243,11 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
}
#endif /* CONFIG_DEBUG_VM */
+unsigned long vmalloc_to_phys(void *va)
+{
+ unsigned long pfn = vmalloc_to_pfn(va);
+
+ BUG_ON(!pfn);
+ return __pa(pfn_to_kaddr(pfn)) + offset_in_page(va);
+}
+EXPORT_SYMBOL_GPL(vmalloc_to_phys);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 7692d1b..bf7bf32 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -37,35 +37,10 @@
#include "mmu_decl.h"
-unsigned long ioremap_base;
unsigned long ioremap_bot;
EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
-#ifdef CONFIG_6xx
-#define HAVE_BATS 1
-#endif
-
-#if defined(CONFIG_FSL_BOOKE)
-#define HAVE_TLBCAM 1
-#endif
-
-extern char etext[], _stext[];
-
-#ifdef HAVE_BATS
-extern phys_addr_t v_mapped_by_bats(unsigned long va);
-extern unsigned long p_mapped_by_bats(phys_addr_t pa);
-#else /* !HAVE_BATS */
-#define v_mapped_by_bats(x) (0UL)
-#define p_mapped_by_bats(x) (0UL)
-#endif /* HAVE_BATS */
-
-#ifdef HAVE_TLBCAM
-extern phys_addr_t v_mapped_by_tlbcam(unsigned long va);
-extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
-#else /* !HAVE_TLBCAM */
-#define v_mapped_by_tlbcam(x) (0UL)
-#define p_mapped_by_tlbcam(x) (0UL)
-#endif /* HAVE_TLBCAM */
+extern char etext[], _stext[], _sinittext[], _einittext[];
#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)
@@ -197,7 +172,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
/*
* Choose an address to map it to.
* Once the vmalloc system is running, we use it.
- * Before then, we use space going down from ioremap_base
+ * Before then, we use space going down from IOREMAP_TOP
* (ioremap_bot records where we're up to).
*/
p = addr & PAGE_MASK;
@@ -228,19 +203,10 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
/*
* Is it already mapped? Perhaps overlapped by a previous
- * BAT mapping. If the whole area is mapped then we're done,
- * otherwise remap it since we want to keep the virt addrs for
- * each request contiguous.
- *
- * We make the assumption here that if the bottom and top
- * of the range we want are mapped then it's mapped to the
- * same virt address (and this is contiguous).
- * -- Cort
+ * mapping.
*/
- if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
- goto out;
-
- if ((v = p_mapped_by_tlbcam(p)))
+ v = p_block_mapped(p);
+ if (v)
goto out;
if (slab_is_available()) {
@@ -278,7 +244,8 @@ void iounmap(volatile void __iomem *addr)
* If mapped by BATs then there is nothing to do.
* Calling vfree() generates a benign warning.
*/
- if (v_mapped_by_bats((unsigned long)addr)) return;
+ if (v_block_mapped((unsigned long)addr))
+ return;
if (addr > high_memory && (unsigned long) addr < ioremap_bot)
vunmap((void *) (PAGE_MASK & (unsigned long)addr));
@@ -322,7 +289,8 @@ void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
v = PAGE_OFFSET + s;
p = memstart_addr + s;
for (; s < top; s += PAGE_SIZE) {
- ktext = ((char *) v >= _stext && (char *) v < etext);
+ ktext = ((char *)v >= _stext && (char *)v < etext) ||
+ ((char *)v >= _sinittext && (char *)v < _einittext);
f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL);
map_page(v, p, f);
#ifdef CONFIG_PPC_STD_MMU_32
@@ -403,7 +371,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
BUG_ON(PageHighMem(page));
address = (unsigned long)page_address(page);
- if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address))
+ if (v_block_mapped(address))
return 0;
if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
return -EINVAL;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index e92cb21..3471060 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -88,7 +88,7 @@ static __ref void *early_alloc_pgtable(unsigned long size)
* map_kernel_page adds an entry to the ioremap page table
* and adds an entry to the HPT, possibly bolting it
*/
-int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
+int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags)
{
pgd_t *pgdp;
pud_t *pudp;
@@ -359,7 +359,7 @@ struct page *pud_page(pud_t pud)
struct page *pmd_page(pmd_t pmd)
{
if (pmd_trans_huge(pmd) || pmd_huge(pmd))
- return pfn_to_page(pmd_pfn(pmd));
+ return pte_page(pmd_pte(pmd));
return virt_to_page(pmd_page_vaddr(pmd));
}
@@ -403,7 +403,7 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel)
* count.
*/
if (likely(!mm->context.pte_frag)) {
- atomic_set(&page->_count, PTE_FRAG_NR);
+ set_page_count(page, PTE_FRAG_NR);
mm->context.pte_frag = ret + PTE_FRAG_SIZE;
}
spin_unlock(&mm->page_table_lock);
@@ -604,55 +604,6 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma,
}
/*
- * We mark the pmd splitting and invalidate all the hpte
- * entries for this hugepage.
- */
-void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp)
-{
- unsigned long old, tmp;
-
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-
-#ifdef CONFIG_DEBUG_VM
- WARN_ON(!pmd_trans_huge(*pmdp));
- assert_spin_locked(&vma->vm_mm->page_table_lock);
-#endif
-
-#ifdef PTE_ATOMIC_UPDATES
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%3\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- ori %1,%0,%4 \n\
- stdcx. %1,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*pmdp)
- : "r" (pmdp), "i" (_PAGE_SPLITTING), "m" (*pmdp), "i" (_PAGE_BUSY)
- : "cc" );
-#else
- old = pmd_val(*pmdp);
- *pmdp = __pmd(old | _PAGE_SPLITTING);
-#endif
- /*
- * If we didn't had the splitting flag set, go and flush the
- * HPTE entries.
- */
- trace_hugepage_splitting(address, old);
- if (!(old & _PAGE_SPLITTING)) {
- /* We need to flush the hpte */
- if (old & _PAGE_HASHPTE)
- hpte_do_hugepage_flush(vma->vm_mm, address, pmdp, old);
- }
- /*
- * This ensures that generic code that rely on IRQ disabling
- * to prevent a parallel THP split work as expected.
- */
- kick_all_cpus_sync();
-}
-
-/*
* We want to put the pgtable in pmd and use pgtable for tracking
* the base page size hptes
*/
@@ -695,6 +646,28 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
return pgtable;
}
+void pmdp_huge_split_prepare(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp)
+{
+ VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+ VM_BUG_ON(REGION_ID(address) != USER_REGION_ID);
+
+ /*
+ * We can't mark the pmd none here, because that will cause a race
+ * against exit_mmap. We need to continue mark pmd TRANS HUGE, while
+ * we spilt, but at the same time we wan't rest of the ppc64 code
+ * not to insert hash pte on this, because we will be modifying
+ * the deposited pgtable in the caller of this function. Hence
+ * clear the _PAGE_USER so that we move the fault handling to
+ * higher level function and that will serialize against ptl.
+ * We need to flush existing hash pte entries here even though,
+ * the translation is still valid, because we will withdraw
+ * pgtable_t after this.
+ */
+ pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_USER, 0);
+}
+
+
/*
* set a new huge pmd. We should not be called for updating
* an existing pmd entry. That should go via pmd_hugepage_update.
@@ -712,10 +685,20 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));
}
+/*
+ * We use this to invalidate a pmdp entry before switching from a
+ * hugepte to regular pmd entry.
+ */
void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
pmd_t *pmdp)
{
pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0);
+
+ /*
+ * This ensures that generic code that rely on IRQ disabling
+ * to prevent a parallel THP split work as expected.
+ */
+ kick_all_cpus_sync();
}
/*
@@ -759,22 +742,15 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot)
{
- pmd_val(pmd) |= pgprot_val(pgprot);
- return pmd;
+ return __pmd(pmd_val(pmd) | pgprot_val(pgprot));
}
pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
{
- pmd_t pmd;
- /*
- * For a valid pte, we would have _PAGE_PRESENT always
- * set. We use this to check THP page at pmd level.
- * leaf pte for huge page, bottom two bits != 00
- */
- pmd_val(pmd) = pfn << PTE_RPN_SHIFT;
- pmd_val(pmd) |= _PAGE_THP_HUGE;
- pmd = pmd_set_protbits(pmd, pgprot);
- return pmd;
+ unsigned long pmdv;
+
+ pmdv = (pfn << PTE_RPN_SHIFT) & PTE_RPN_MASK;
+ return pmd_set_protbits(__pmd(pmdv), pgprot);
}
pmd_t mk_pmd(struct page *page, pgprot_t pgprot)
@@ -784,10 +760,11 @@ pmd_t mk_pmd(struct page *page, pgprot_t pgprot)
pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
{
+ unsigned long pmdv;
- pmd_val(pmd) &= _HPAGE_CHG_MASK;
- pmd = pmd_set_protbits(pmd, newprot);
- return pmd;
+ pmdv = pmd_val(pmd);
+ pmdv &= _HPAGE_CHG_MASK;
+ return pmd_set_protbits(__pmd(pmdv), newprot);
}
/*
@@ -840,6 +817,13 @@ pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
int has_transparent_hugepage(void)
{
+
+ BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) >= MAX_ORDER,
+ "hugepages can't be allocated by the buddy allocator");
+
+ BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) < 2,
+ "We need more than 2 pages to do deferred thp split");
+
if (!mmu_has_feature(MMU_FTR_16M_PAGE))
return 0;
/*
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 6b2f3e4..2a049fb 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -49,7 +49,7 @@ struct batrange { /* stores address ranges mapped by BATs */
/*
* Return PA for this VA if it is mapped by a BAT, or 0
*/
-phys_addr_t v_mapped_by_bats(unsigned long va)
+phys_addr_t v_block_mapped(unsigned long va)
{
int b;
for (b = 0; b < 4; ++b)
@@ -61,7 +61,7 @@ phys_addr_t v_mapped_by_bats(unsigned long va)
/*
* Return VA for a given PA or 0 if not mapped
*/
-unsigned long p_mapped_by_bats(phys_addr_t pa)
+unsigned long p_block_mapped(phys_addr_t pa)
{
int b;
for (b = 0; b < 4; ++b)
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 8a32a2b..825b687 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -25,6 +25,11 @@
#include <asm/udbg.h>
#include <asm/code-patching.h>
+enum slb_index {
+ LINEAR_INDEX = 0, /* Kernel linear map (0xc000000000000000) */
+ VMALLOC_INDEX = 1, /* Kernel virtual map (0xd000000000000000) */
+ KSTACK_INDEX = 2, /* Kernel stack map */
+};
extern void slb_allocate_realmode(unsigned long ea);
extern void slb_allocate_user(unsigned long ea);
@@ -41,9 +46,9 @@ static void slb_allocate(unsigned long ea)
(((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T)
static inline unsigned long mk_esid_data(unsigned long ea, int ssize,
- unsigned long entry)
+ enum slb_index index)
{
- return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | entry;
+ return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | index;
}
static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
@@ -55,39 +60,39 @@ static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
static inline void slb_shadow_update(unsigned long ea, int ssize,
unsigned long flags,
- unsigned long entry)
+ enum slb_index index)
{
+ struct slb_shadow *p = get_slb_shadow();
+
/*
* Clear the ESID first so the entry is not valid while we are
* updating it. No write barriers are needed here, provided
* we only update the current CPU's SLB shadow buffer.
*/
- get_slb_shadow()->save_area[entry].esid = 0;
- get_slb_shadow()->save_area[entry].vsid =
- cpu_to_be64(mk_vsid_data(ea, ssize, flags));
- get_slb_shadow()->save_area[entry].esid =
- cpu_to_be64(mk_esid_data(ea, ssize, entry));
+ p->save_area[index].esid = 0;
+ p->save_area[index].vsid = cpu_to_be64(mk_vsid_data(ea, ssize, flags));
+ p->save_area[index].esid = cpu_to_be64(mk_esid_data(ea, ssize, index));
}
-static inline void slb_shadow_clear(unsigned long entry)
+static inline void slb_shadow_clear(enum slb_index index)
{
- get_slb_shadow()->save_area[entry].esid = 0;
+ get_slb_shadow()->save_area[index].esid = 0;
}
static inline void create_shadowed_slbe(unsigned long ea, int ssize,
unsigned long flags,
- unsigned long entry)
+ enum slb_index index)
{
/*
* Updating the shadow buffer before writing the SLB ensures
* we don't get a stale entry here if we get preempted by PHYP
* between these two statements.
*/
- slb_shadow_update(ea, ssize, flags, entry);
+ slb_shadow_update(ea, ssize, flags, index);
asm volatile("slbmte %0,%1" :
: "r" (mk_vsid_data(ea, ssize, flags)),
- "r" (mk_esid_data(ea, ssize, entry))
+ "r" (mk_esid_data(ea, ssize, index))
: "memory" );
}
@@ -103,16 +108,16 @@ static void __slb_flush_and_rebolt(void)
lflags = SLB_VSID_KERNEL | linear_llp;
vflags = SLB_VSID_KERNEL | vmalloc_llp;
- ksp_esid_data = mk_esid_data(get_paca()->kstack, mmu_kernel_ssize, 2);
+ ksp_esid_data = mk_esid_data(get_paca()->kstack, mmu_kernel_ssize, KSTACK_INDEX);
if ((ksp_esid_data & ~0xfffffffUL) <= PAGE_OFFSET) {
ksp_esid_data &= ~SLB_ESID_V;
ksp_vsid_data = 0;
- slb_shadow_clear(2);
+ slb_shadow_clear(KSTACK_INDEX);
} else {
/* Update stack entry; others don't change */
- slb_shadow_update(get_paca()->kstack, mmu_kernel_ssize, lflags, 2);
+ slb_shadow_update(get_paca()->kstack, mmu_kernel_ssize, lflags, KSTACK_INDEX);
ksp_vsid_data =
- be64_to_cpu(get_slb_shadow()->save_area[2].vsid);
+ be64_to_cpu(get_slb_shadow()->save_area[KSTACK_INDEX].vsid);
}
/* We need to do this all in asm, so we're sure we don't touch
@@ -151,7 +156,7 @@ void slb_vmalloc_update(void)
unsigned long vflags;
vflags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_vmalloc_psize].sllp;
- slb_shadow_update(VMALLOC_START, mmu_kernel_ssize, vflags, 1);
+ slb_shadow_update(VMALLOC_START, mmu_kernel_ssize, vflags, VMALLOC_INDEX);
slb_flush_and_rebolt();
}
@@ -223,7 +228,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
asm volatile("slbie %0" : : "r" (slbie_data));
get_paca()->slb_cache_ptr = 0;
- get_paca()->context = mm->context;
+ copy_mm_to_paca(&mm->context);
/*
* preload some userspace segments into the SLB.
@@ -326,19 +331,19 @@ void slb_initialize(void)
asm volatile("isync":::"memory");
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
asm volatile("isync; slbia; isync":::"memory");
- create_shadowed_slbe(PAGE_OFFSET, mmu_kernel_ssize, lflags, 0);
- create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1);
+ create_shadowed_slbe(PAGE_OFFSET, mmu_kernel_ssize, lflags, LINEAR_INDEX);
+ create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, VMALLOC_INDEX);
/* For the boot cpu, we're running on the stack in init_thread_union,
* which is in the first segment of the linear mapping, and also
* get_paca()->kstack hasn't been initialized yet.
* For secondary cpus, we need to bolt the kernel stack entry now.
*/
- slb_shadow_clear(2);
+ slb_shadow_clear(KSTACK_INDEX);
if (raw_smp_processor_id() != boot_cpuid &&
(get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET)
create_shadowed_slbe(get_paca()->kstack,
- mmu_kernel_ssize, lflags, 2);
+ mmu_kernel_ssize, lflags, KSTACK_INDEX);
asm volatile("isync":::"memory");
}
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 0f432a7..42954f0 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -185,8 +185,7 @@ static void slice_flush_segments(void *parm)
if (mm != current->active_mm)
return;
- /* update the paca copy of the context struct */
- get_paca()->context = current->active_mm->context;
+ copy_mm_to_paca(&current->active_mm->context);
local_irq_save(flags);
slb_flush_and_rebolt();
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index fa9fb5b..d554351 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -135,7 +135,7 @@ static int subpage_walk_pmd_entry(pmd_t *pmd, unsigned long addr,
unsigned long end, struct mm_walk *walk)
{
struct vm_area_struct *vma = walk->vma;
- split_huge_page_pmd(vma, addr, pmd);
+ split_huge_pmd(vma, pmd, addr);
return 0;
}
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index c522969..f7b8039 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -190,6 +190,7 @@ void tlb_flush(struct mmu_gather *tlb)
void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
+ bool is_thp;
int hugepage_shift;
unsigned long flags;
@@ -208,21 +209,21 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
local_irq_save(flags);
arch_enter_lazy_mmu_mode();
for (; start < end; start += PAGE_SIZE) {
- pte_t *ptep = find_linux_pte_or_hugepte(mm->pgd, start,
+ pte_t *ptep = find_linux_pte_or_hugepte(mm->pgd, start, &is_thp,
&hugepage_shift);
unsigned long pte;
if (ptep == NULL)
continue;
pte = pte_val(*ptep);
- if (hugepage_shift)
+ if (is_thp)
trace_hugepage_invalidate(start, pte);
if (!(pte & _PAGE_HASHPTE))
continue;
- if (unlikely(hugepage_shift && pmd_trans_huge(*(pmd_t *)pte)))
+ if (unlikely(is_thp))
hpte_do_hugepage_flush(mm, start, (pmd_t *)ptep, pte);
else
- hpte_need_flush(mm, start, ptep, pte, 0);
+ hpte_need_flush(mm, start, ptep, pte, hugepage_shift);
}
arch_leave_lazy_mmu_mode();
local_irq_restore(flags);
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index e418558..eb82d78 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -68,11 +68,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
ld r14,PACAPGD(r13)
std r15,EX_TLB_R15(r12)
std r10,EX_TLB_CR(r12)
+#ifdef CONFIG_PPC_FSL_BOOK3E
+ std r7,EX_TLB_R7(r12)
+#endif
TLB_MISS_PROLOG_STATS
.endm
.macro tlb_epilog_bolted
ld r14,EX_TLB_CR(r12)
+#ifdef CONFIG_PPC_FSL_BOOK3E
+ ld r7,EX_TLB_R7(r12)
+#endif
ld r10,EX_TLB_R10(r12)
ld r11,EX_TLB_R11(r12)
ld r13,EX_TLB_R13(r12)
@@ -297,6 +303,7 @@ itlb_miss_fault_bolted:
* r13 = PACA
* r11 = tlb_per_core ptr
* r10 = crap (free to use)
+ * r7 = esel_next
*/
tlb_miss_common_e6500:
crmove cr2*4+2,cr0*4+2 /* cr2.eq != 0 if kernel address */
@@ -325,7 +332,11 @@ BEGIN_FTR_SECTION /* CPU_FTR_SMT */
bne 10b
b 1b
.previous
+END_FTR_SECTION_IFSET(CPU_FTR_SMT)
+
+ lbz r7,TCD_ESEL_NEXT(r11)
+BEGIN_FTR_SECTION /* CPU_FTR_SMT */
/*
* Erratum A-008139 says that we can't use tlbwe to change
* an indirect entry in any way (including replacing or
@@ -334,8 +345,7 @@ BEGIN_FTR_SECTION /* CPU_FTR_SMT */
* with tlbilx before overwriting.
*/
- lbz r15,TCD_ESEL_NEXT(r11)
- rlwinm r10,r15,16,0xff0000
+ rlwinm r10,r7,16,0xff0000
oris r10,r10,MAS0_TLBSEL(1)@h
mtspr SPRN_MAS0,r10
isync
@@ -429,15 +439,14 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_SMT)
mtspr SPRN_MAS2,r15
tlb_miss_huge_done_e6500:
- lbz r15,TCD_ESEL_NEXT(r11)
lbz r16,TCD_ESEL_MAX(r11)
lbz r14,TCD_ESEL_FIRST(r11)
- rlwimi r10,r15,16,0x00ff0000 /* insert esel_next into MAS0 */
- addi r15,r15,1 /* increment esel_next */
+ rlwimi r10,r7,16,0x00ff0000 /* insert esel_next into MAS0 */
+ addi r7,r7,1 /* increment esel_next */
mtspr SPRN_MAS0,r10
- cmpw r15,r16
- iseleq r15,r14,r15 /* if next == last use first */
- stb r15,TCD_ESEL_NEXT(r11)
+ cmpw r7,r16
+ iseleq r7,r14,r7 /* if next == last use first */
+ stb r7,TCD_ESEL_NEXT(r11)
tlbwe
@@ -886,7 +895,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
BEGIN_MMU_FTR_SECTION
virt_page_table_tlb_miss_done:
- /* We have overriden MAS2:EPN but currently our primary TLB miss
+ /* We have overridden MAS2:EPN but currently our primary TLB miss
* handler will always restore it so that should not be an issue,
* if we ever optimize the primary handler to not write MAS2 on
* some cases, we'll have to restore MAS2:EPN here based on the
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 723a099..f466848 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -42,6 +42,7 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/code-patching.h>
+#include <asm/cputhreads.h>
#include <asm/hugetlb.h>
#include <asm/paca.h>
@@ -628,10 +629,24 @@ static void early_init_this_mmu(void)
#ifdef CONFIG_PPC_FSL_BOOK3E
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
unsigned int num_cams;
+ int __maybe_unused cpu = smp_processor_id();
+ bool map = true;
/* use a quarter of the TLBCAM for bolted linear map */
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
- linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
+
+ /*
+ * Only do the mapping once per core, or else the
+ * transient mapping would cause problems.
+ */
+#ifdef CONFIG_SMP
+ if (hweight32(get_tensr()) > 1)
+ map = false;
+#endif
+
+ if (map)
+ linear_map_top = map_mem_in_cams(linear_map_top,
+ num_cams, false);
}
#endif
@@ -729,10 +744,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
* entries are supported though that may eventually
* change.
*
- * on FSL Embedded 64-bit, we adjust the RMA size to match the
- * first bolted TLB entry size. We still limit max to 1G even if
- * the TLB could cover more. This is due to what the early init
- * code is setup to do.
+ * on FSL Embedded 64-bit, usually all RAM is bolted, but with
+ * unusual memory sizes it's possible for some RAM to not be mapped
+ * (such RAM is not used at all by Linux, since we don't support
+ * highmem on 64-bit). We limit ppc64_rma_size to what would be
+ * mappable if this memblock is the only one. Additional memblocks
+ * can only increase, not decrease, the amount that ends up getting
+ * mapped. We still limit max to 1G even if we'll eventually map
+ * more. This is due to what the early init code is set up to do.
*
* We crop it to the size of the first MEMBLOCK to
* avoid going over total available memory just in case...
@@ -740,8 +759,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
#ifdef CONFIG_PPC_FSL_BOOK3E
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
unsigned long linear_sz;
- linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET,
- first_memblock_base);
+ unsigned int num_cams;
+
+ /* use a quarter of the TLBCAM for bolted linear map */
+ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+ linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
+ true);
+
ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
} else
#endif
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 43ff3c7..eabecfc 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -108,7 +108,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
blr
2:
#ifdef CONFIG_PPC_47x
- oris r7,r6,0x8000 /* specify way explicitely */
+ oris r7,r6,0x8000 /* specify way explicitly */
clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */
ori r4,r4,PPC47x_TLBE_SIZE
tlbwe r4,r7,0 /* write it */
@@ -149,7 +149,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
li r3,-1 /* Current set */
lis r10,tlb_47x_boltmap@h
ori r10,r10,tlb_47x_boltmap@l
- lis r7,0x8000 /* Specify way explicitely */
+ lis r7,0x8000 /* Specify way explicitly */
b 9f /* For each set */
@@ -400,6 +400,7 @@ _GLOBAL(set_context)
* extern void loadcam_entry(unsigned int index)
*
* Load TLBCAM[index] entry in to the L2 CAM MMU
+ * Must preserve r7, r8, r9, and r10
*/
_GLOBAL(loadcam_entry)
mflr r5
@@ -423,4 +424,66 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
tlbwe
isync
blr
+
+/*
+ * Load multiple TLB entries at once, using an alternate-space
+ * trampoline so that we don't have to care about whether the same
+ * TLB entry maps us before and after.
+ *
+ * r3 = first entry to write
+ * r4 = number of entries to write
+ * r5 = temporary tlb entry
+ */
+_GLOBAL(loadcam_multi)
+ mflr r8
+
+ /*
+ * Set up temporary TLB entry that is the same as what we're
+ * running from, but in AS=1.
+ */
+ bl 1f
+1: mflr r6
+ tlbsx 0,r8
+ mfspr r6,SPRN_MAS1
+ ori r6,r6,MAS1_TS
+ mtspr SPRN_MAS1,r6
+ mfspr r6,SPRN_MAS0
+ rlwimi r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+ mr r7,r5
+ mtspr SPRN_MAS0,r6
+ isync
+ tlbwe
+ isync
+
+ /* Switch to AS=1 */
+ mfmsr r6
+ ori r6,r6,MSR_IS|MSR_DS
+ mtmsr r6
+ isync
+
+ mr r9,r3
+ add r10,r3,r4
+2: bl loadcam_entry
+ addi r9,r9,1
+ cmpw r9,r10
+ mr r3,r9
+ blt 2b
+
+ /* Return to AS=0 and clear the temporary entry */
+ mfmsr r6
+ rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
+ mtmsr r6
+ isync
+
+ li r6,0
+ mtspr SPRN_MAS1,r6
+ rlwinm r6,r7,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+ oris r6,r6,MAS0_TLBSEL(1)@h
+ mtspr SPRN_MAS0,r6
+ isync
+ tlbwe
+ isync
+
+ mtlr r8
+ blr
#endif
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 17cea18..2d66a84 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
PPC_LI(r_X, 0);
}
- switch (filter[0].code) {
- case BPF_RET | BPF_K:
- 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:
- /* first instruction sets A register (or is RET 'constant') */
- break;
- default:
- /* make sure we dont leak kernel information to user */
+ /* make sure we dont leak kernel information to user */
+ if (bpf_needs_clear_a(&filter[0]))
PPC_LI(r_A, 0);
- }
}
static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
@@ -679,7 +670,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
((u64 *)image)[1] = local_paca->kernel_toc;
#endif
fp->bpf_func = (void *)image;
- fp->jited = true;
+ fp->jited = 1;
}
out:
kfree(addrs);
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index 863d893..c82497a 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -208,7 +208,7 @@ static void pm_rtas_reset_signals(u32 node)
/*
* The debug bus is being set to the passthru disable state.
- * However, the FW still expects atleast one legal signal routing
+ * However, the FW still expects at least one legal signal routing
* entry or it will return an error on the arguments. If we don't
* supply a valid entry, we must ignore all return values. Ignoring
* all return values means we might miss an error we should be
@@ -1008,7 +1008,7 @@ static int initial_lfsr[] = {
*
* To avoid the time to compute the LFSR, a lookup table is used. The 24 bit
* LFSR sequence is broken into four ranges. The spacing of the precomputed
- * values is adjusted in each range so the error between the user specifed
+ * values is adjusted in each range so the error between the user specified
* number (N) of events between samples and the actual number of events based
* on the precomputed value will be les then about 6.2%. Note, if the user
* specifies N < 2^16, the LFSR value that is 2^16 from the end will be used.
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index ff09cde..e04a675 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -127,7 +127,7 @@ static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
return -EFAULT;
local_irq_save(flags);
- ptep = find_linux_pte_or_hugepte(pgdir, addr, &shift);
+ ptep = find_linux_pte_or_hugepte(pgdir, addr, NULL, &shift);
if (!ptep)
goto err_out;
if (!shift)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index b0382f3..97a1d40 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -48,7 +48,7 @@ struct cpu_hw_events {
unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
- unsigned int group_flag;
+ unsigned int txn_flags;
int n_txn_start;
/* BHRB bits */
@@ -651,7 +651,7 @@ static void pmao_restore_workaround(bool ebb)
/*
* We are already soft-disabled in power_pmu_enable(). We need to hard
- * enable to actually prevent the PMU exception from firing.
+ * disable to actually prevent the PMU exception from firing.
*/
hard_irq_disable();
@@ -1441,7 +1441,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags)
* skip the schedulability test here, it will be performed
* at commit time(->commit_txn) as a whole
*/
- if (cpuhw->group_flag & PERF_EVENT_TXN)
+ if (cpuhw->txn_flags & PERF_PMU_TXN_ADD)
goto nocheck;
if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
@@ -1586,13 +1586,22 @@ static void power_pmu_stop(struct perf_event *event, int ef_flags)
* Start group events scheduling transaction
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
*/
-static void power_pmu_start_txn(struct pmu *pmu)
+static void power_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
{
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
+
+ cpuhw->txn_flags = txn_flags;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
perf_pmu_disable(pmu);
- cpuhw->group_flag |= PERF_EVENT_TXN;
cpuhw->n_txn_start = cpuhw->n_events;
}
@@ -1604,8 +1613,15 @@ static void power_pmu_start_txn(struct pmu *pmu)
static void power_pmu_cancel_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ unsigned int txn_flags;
+
+ WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
+
+ txn_flags = cpuhw->txn_flags;
+ cpuhw->txn_flags = 0;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
- cpuhw->group_flag &= ~PERF_EVENT_TXN;
perf_pmu_enable(pmu);
}
@@ -1621,7 +1637,15 @@ static int power_pmu_commit_txn(struct pmu *pmu)
if (!ppmu)
return -EAGAIN;
+
cpuhw = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
+
+ if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
+ cpuhw->txn_flags = 0;
+ return 0;
+ }
+
n = cpuhw->n_events;
if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
return -EAGAIN;
@@ -1632,7 +1656,7 @@ static int power_pmu_commit_txn(struct pmu *pmu)
for (i = cpuhw->n_txn_start; i < n; ++i)
cpuhw->event[i]->hw.config = cpuhw->events[i];
- cpuhw->group_flag &= ~PERF_EVENT_TXN;
+ cpuhw->txn_flags = 0;
perf_pmu_enable(pmu);
return 0;
}
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 527c8b9..2da41b7 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -27,20 +27,6 @@
#include "hv-24x7-catalog.h"
#include "hv-common.h"
-static const char *event_domain_suffix(unsigned domain)
-{
- switch (domain) {
-#define DOMAIN(n, v, x, c) \
- case HV_PERF_DOMAIN_##n: \
- return "__" #n;
-#include "hv-24x7-domains.h"
-#undef DOMAIN
- default:
- WARN(1, "unknown domain %d\n", domain);
- return "__UNKNOWN_DOMAIN_SUFFIX";
- }
-}
-
static bool domain_is_valid(unsigned domain)
{
switch (domain) {
@@ -68,6 +54,24 @@ static bool is_physical_domain(unsigned domain)
}
}
+static const char *domain_name(unsigned domain)
+{
+ if (!domain_is_valid(domain))
+ return NULL;
+
+ switch (domain) {
+ case HV_PERF_DOMAIN_PHYS_CHIP: return "Physical Chip";
+ case HV_PERF_DOMAIN_PHYS_CORE: return "Physical Core";
+ case HV_PERF_DOMAIN_VCPU_HOME_CORE: return "VCPU Home Core";
+ case HV_PERF_DOMAIN_VCPU_HOME_CHIP: return "VCPU Home Chip";
+ case HV_PERF_DOMAIN_VCPU_HOME_NODE: return "VCPU Home Node";
+ case HV_PERF_DOMAIN_VCPU_REMOTE_NODE: return "VCPU Remote Node";
+ }
+
+ WARN_ON_ONCE(domain);
+ return NULL;
+}
+
static bool catalog_entry_domain_is_valid(unsigned domain)
{
return is_physical_domain(domain);
@@ -101,6 +105,7 @@ static bool catalog_entry_domain_is_valid(unsigned domain)
EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
/* u16 */
EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31);
+EVENT_DEFINE_RANGE_FORMAT(chip, config, 16, 31);
EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31);
/* u32, see "data_offset" */
EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
@@ -115,6 +120,7 @@ static struct attribute *format_attrs[] = {
&format_attr_domain.attr,
&format_attr_offset.attr,
&format_attr_core.attr,
+ &format_attr_chip.attr,
&format_attr_vcpu.attr,
&format_attr_lpar.attr,
NULL,
@@ -142,6 +148,15 @@ static struct attribute_group event_long_desc_group = {
static struct kmem_cache *hv_page_cache;
+DEFINE_PER_CPU(int, hv_24x7_txn_flags);
+DEFINE_PER_CPU(int, hv_24x7_txn_err);
+
+struct hv_24x7_hw {
+ struct perf_event *events[255];
+};
+
+DEFINE_PER_CPU(struct hv_24x7_hw, hv_24x7_hw);
+
/*
* request_buffer and result_buffer are not required to be 4k aligned,
* but are not allowed to cross any 4k boundary. Aligning them to 4k is
@@ -265,32 +280,70 @@ static unsigned long h_get_24x7_catalog_page(char page[],
version, index);
}
-static unsigned core_domains[] = {
- HV_PERF_DOMAIN_PHYS_CORE,
- HV_PERF_DOMAIN_VCPU_HOME_CORE,
- HV_PERF_DOMAIN_VCPU_HOME_CHIP,
- HV_PERF_DOMAIN_VCPU_HOME_NODE,
- HV_PERF_DOMAIN_VCPU_REMOTE_NODE,
-};
-/* chip event data always yeilds a single event, core yeilds multiple */
-#define MAX_EVENTS_PER_EVENT_DATA ARRAY_SIZE(core_domains)
-
+/*
+ * Each event we find in the catalog, will have a sysfs entry. Format the
+ * data for this sysfs entry based on the event's domain.
+ *
+ * Events belonging to the Chip domain can only be monitored in that domain.
+ * i.e the domain for these events is a fixed/knwon value.
+ *
+ * Events belonging to the Core domain can be monitored either in the physical
+ * core or in one of the virtual CPU domains. So the domain value for these
+ * events must be specified by the user (i.e is a required parameter). Format
+ * the Core events with 'domain=?' so the perf-tool can error check required
+ * parameters.
+ *
+ * NOTE: For the Core domain events, rather than making domain a required
+ * parameter we could default it to PHYS_CORE and allowe users to
+ * override the domain to one of the VCPU domains.
+ *
+ * However, this can make the interface a little inconsistent.
+ *
+ * If we set domain=2 (PHYS_CHIP) and allow user to override this field
+ * the user may be tempted to also modify the "offset=x" field in which
+ * can lead to confusing usage. Consider the HPM_PCYC (offset=0x18) and
+ * HPM_INST (offset=0x20) events. With:
+ *
+ * perf stat -e hv_24x7/HPM_PCYC,offset=0x20/
+ *
+ * we end up monitoring HPM_INST, while the command line has HPM_PCYC.
+ *
+ * By not assigning a default value to the domain for the Core events,
+ * we can have simple guidelines:
+ *
+ * - Specifying values for parameters with "=?" is required.
+ *
+ * - Specifying (i.e overriding) values for other parameters
+ * is undefined.
+ */
static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain)
{
const char *sindex;
const char *lpar;
+ const char *domain_str;
+ char buf[8];
- if (is_physical_domain(domain)) {
+ switch (domain) {
+ case HV_PERF_DOMAIN_PHYS_CHIP:
+ snprintf(buf, sizeof(buf), "%d", domain);
+ domain_str = buf;
+ lpar = "0x0";
+ sindex = "chip";
+ break;
+ case HV_PERF_DOMAIN_PHYS_CORE:
+ domain_str = "?";
lpar = "0x0";
sindex = "core";
- } else {
+ break;
+ default:
+ domain_str = "?";
lpar = "?";
sindex = "vcpu";
}
return kasprintf(GFP_KERNEL,
- "domain=0x%x,offset=0x%x,%s=?,lpar=%s",
- domain,
+ "domain=%s,offset=0x%x,%s=?,lpar=%s",
+ domain_str,
be16_to_cpu(event->event_counter_offs) +
be16_to_cpu(event->event_group_record_offs),
sindex,
@@ -330,6 +383,15 @@ static struct attribute *device_str_attr_create_(char *name, char *str)
return &attr->attr.attr;
}
+/*
+ * Allocate and initialize strings representing event attributes.
+ *
+ * NOTE: The strings allocated here are never destroyed and continue to
+ * exist till shutdown. This is to allow us to create as many events
+ * from the catalog as possible, even if we encounter errors with some.
+ * In case of changes to error paths in future, these may need to be
+ * freed by the caller.
+ */
static struct attribute *device_str_attr_create(char *name, int name_max,
int name_nonce,
char *str, size_t str_max)
@@ -361,16 +423,6 @@ out_s:
return NULL;
}
-static void device_str_attr_destroy(struct attribute *attr)
-{
- struct dev_ext_attribute *d;
-
- d = container_of(attr, struct dev_ext_attribute, attr.attr);
- kfree(d->var);
- kfree(d->attr.attr.name);
- kfree(d);
-}
-
static struct attribute *event_to_attr(unsigned ix,
struct hv_24x7_event_data *event,
unsigned domain,
@@ -378,7 +430,6 @@ static struct attribute *event_to_attr(unsigned ix,
{
int event_name_len;
char *ev_name, *a_ev_name, *val;
- const char *ev_suffix;
struct attribute *attr;
if (!domain_is_valid(domain)) {
@@ -391,14 +442,13 @@ static struct attribute *event_to_attr(unsigned ix,
if (!val)
return NULL;
- ev_suffix = event_domain_suffix(domain);
ev_name = event_name(event, &event_name_len);
if (!nonce)
- a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s",
- (int)event_name_len, ev_name, ev_suffix);
+ a_ev_name = kasprintf(GFP_KERNEL, "%.*s",
+ (int)event_name_len, ev_name);
else
- a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s__%d",
- (int)event_name_len, ev_name, ev_suffix, nonce);
+ a_ev_name = kasprintf(GFP_KERNEL, "%.*s__%d",
+ (int)event_name_len, ev_name, nonce);
if (!a_ev_name)
goto out_val;
@@ -443,53 +493,14 @@ event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce)
return device_str_attr_create(name, nl, nonce, desc, dl);
}
-static ssize_t event_data_to_attrs(unsigned ix, struct attribute **attrs,
+static int event_data_to_attrs(unsigned ix, struct attribute **attrs,
struct hv_24x7_event_data *event, int nonce)
{
- unsigned i;
-
- switch (event->domain) {
- case HV_PERF_DOMAIN_PHYS_CHIP:
- *attrs = event_to_attr(ix, event, event->domain, nonce);
- return 1;
- case HV_PERF_DOMAIN_PHYS_CORE:
- for (i = 0; i < ARRAY_SIZE(core_domains); i++) {
- attrs[i] = event_to_attr(ix, event, core_domains[i],
- nonce);
- if (!attrs[i]) {
- pr_warn("catalog event %u: individual attr %u "
- "creation failure\n", ix, i);
- for (; i; i--)
- device_str_attr_destroy(attrs[i - 1]);
- return -1;
- }
- }
- return i;
- default:
- pr_warn("catalog event %u: domain %u is not allowed in the "
- "catalog\n", ix, event->domain);
+ *attrs = event_to_attr(ix, event, event->domain, nonce);
+ if (!*attrs)
return -1;
- }
-}
-static size_t event_to_attr_ct(struct hv_24x7_event_data *event)
-{
- switch (event->domain) {
- case HV_PERF_DOMAIN_PHYS_CHIP:
- return 1;
- case HV_PERF_DOMAIN_PHYS_CORE:
- return ARRAY_SIZE(core_domains);
- default:
- return 0;
- }
-}
-
-static unsigned long vmalloc_to_phys(void *v)
-{
- struct page *p = vmalloc_to_page(v);
-
- BUG_ON(!p);
- return page_to_phys(p) + offset_in_page(v);
+ return 0;
}
/* */
@@ -717,9 +728,8 @@ static int create_events_from_catalog(struct attribute ***events_,
goto e_free;
}
- if (SIZE_MAX / MAX_EVENTS_PER_EVENT_DATA - 1 < event_entry_count) {
- pr_err("event_entry_count %zu is invalid\n",
- event_entry_count);
+ if (SIZE_MAX - 1 < event_entry_count) {
+ pr_err("event_entry_count %zu is invalid\n", event_entry_count);
ret = -EIO;
goto e_free;
}
@@ -792,7 +802,7 @@ static int create_events_from_catalog(struct attribute ***events_,
continue;
}
- attr_max += event_to_attr_ct(event);
+ attr_max++;
}
event_idx_last = event_idx;
@@ -842,12 +852,12 @@ static int create_events_from_catalog(struct attribute ***events_,
nonce = event_uniq_add(&ev_uniq, name, nl, event->domain);
ct = event_data_to_attrs(event_idx, events + event_attr_ct,
event, nonce);
- if (ct <= 0) {
+ if (ct < 0) {
pr_warn("event %zu (%.*s) creation failure, skipping\n",
event_idx, nl, name);
junk_events++;
} else {
- event_attr_ct += ct;
+ event_attr_ct++;
event_descs[desc_ct] = event_to_desc_attr(event, nonce);
if (event_descs[desc_ct])
desc_ct++;
@@ -952,6 +962,27 @@ e_free:
return ret;
}
+static ssize_t domains_show(struct device *dev, struct device_attribute *attr,
+ char *page)
+{
+ int d, n, count = 0;
+ const char *str;
+
+ for (d = 0; d < HV_PERF_DOMAIN_MAX; d++) {
+ str = domain_name(d);
+ if (!str)
+ continue;
+
+ n = sprintf(page, "%d: %s\n", d, str);
+ if (n < 0)
+ break;
+
+ count += n;
+ page += n;
+ }
+ return count;
+}
+
#define PAGE_0_ATTR(_name, _fmt, _expr) \
static ssize_t _name##_show(struct device *dev, \
struct device_attribute *dev_attr, \
@@ -980,6 +1011,7 @@ PAGE_0_ATTR(catalog_version, "%lld\n",
PAGE_0_ATTR(catalog_len, "%lld\n",
(unsigned long long)be32_to_cpu(page_0->length) * 4096);
static BIN_ATTR_RO(catalog, 0/* real length varies */);
+static DEVICE_ATTR_RO(domains);
static struct bin_attribute *if_bin_attrs[] = {
&bin_attr_catalog,
@@ -989,6 +1021,7 @@ static struct bin_attribute *if_bin_attrs[] = {
static struct attribute *if_attrs[] = {
&dev_attr_catalog_len.attr,
&dev_attr_catalog_version.attr,
+ &dev_attr_domains.attr,
NULL,
};
@@ -1080,10 +1113,16 @@ static int add_event_to_24x7_request(struct perf_event *event,
return -EINVAL;
}
- if (is_physical_domain(event_get_domain(event)))
+ switch (event_get_domain(event)) {
+ case HV_PERF_DOMAIN_PHYS_CHIP:
+ idx = event_get_chip(event);
+ break;
+ case HV_PERF_DOMAIN_PHYS_CORE:
idx = event_get_core(event);
- else
+ break;
+ default:
idx = event_get_vcpu(event);
+ }
i = request_buffer->num_requests++;
req = &request_buffer->requests[i];
@@ -1199,11 +1238,12 @@ static int h_24x7_event_init(struct perf_event *event)
return -EACCES;
}
- /* see if the event complains */
+ /* Get the initial value of the counter for this event */
if (single_24x7_request(event, &ct)) {
pr_devel("test hcall failed\n");
return -EIO;
}
+ (void)local64_xchg(&event->hw.prev_count, ct);
return 0;
}
@@ -1231,9 +1271,58 @@ static void update_event_count(struct perf_event *event, u64 now)
static void h_24x7_event_read(struct perf_event *event)
{
u64 now;
+ struct hv_24x7_request_buffer *request_buffer;
+ struct hv_24x7_hw *h24x7hw;
+ int txn_flags;
+
+ txn_flags = __this_cpu_read(hv_24x7_txn_flags);
+
+ /*
+ * If in a READ transaction, add this counter to the list of
+ * counters to read during the next HCALL (i.e commit_txn()).
+ * If not in a READ transaction, go ahead and make the HCALL
+ * to read this counter by itself.
+ */
+
+ if (txn_flags & PERF_PMU_TXN_READ) {
+ int i;
+ int ret;
+
+ if (__this_cpu_read(hv_24x7_txn_err))
+ return;
+
+ request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+
+ ret = add_event_to_24x7_request(event, request_buffer);
+ if (ret) {
+ __this_cpu_write(hv_24x7_txn_err, ret);
+ } else {
+ /*
+ * Assoicate the event with the HCALL request index,
+ * so ->commit_txn() can quickly find/update count.
+ */
+ i = request_buffer->num_requests - 1;
+
+ h24x7hw = &get_cpu_var(hv_24x7_hw);
+ h24x7hw->events[i] = event;
+ put_cpu_var(h24x7hw);
+ /*
+ * Clear the event count so we can compute the _change_
+ * in the 24x7 raw counter value at the end of the txn.
+ *
+ * Note that we could alternatively read the 24x7 value
+ * now and save its value in event->hw.prev_count. But
+ * that would require issuing a hcall, which would then
+ * defeat the purpose of using the txn interface.
+ */
+ local64_set(&event->count, 0);
+ }
- now = h_24x7_get_value(event);
- update_event_count(event, now);
+ put_cpu_var(hv_24x7_reqb);
+ } else {
+ now = h_24x7_get_value(event);
+ update_event_count(event, now);
+ }
}
static void h_24x7_event_start(struct perf_event *event, int flags)
@@ -1255,6 +1344,117 @@ static int h_24x7_event_add(struct perf_event *event, int flags)
return 0;
}
+/*
+ * 24x7 counters only support READ transactions. They are
+ * always counting and dont need/support ADD transactions.
+ * Cache the flags, but otherwise ignore transactions that
+ * are not PERF_PMU_TXN_READ.
+ */
+static void h_24x7_event_start_txn(struct pmu *pmu, unsigned int flags)
+{
+ struct hv_24x7_request_buffer *request_buffer;
+ struct hv_24x7_data_result_buffer *result_buffer;
+
+ /* We should not be called if we are already in a txn */
+ WARN_ON_ONCE(__this_cpu_read(hv_24x7_txn_flags));
+
+ __this_cpu_write(hv_24x7_txn_flags, flags);
+ if (flags & ~PERF_PMU_TXN_READ)
+ return;
+
+ request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+ result_buffer = (void *)get_cpu_var(hv_24x7_resb);
+
+ init_24x7_request(request_buffer, result_buffer);
+
+ put_cpu_var(hv_24x7_resb);
+ put_cpu_var(hv_24x7_reqb);
+}
+
+/*
+ * Clean up transaction state.
+ *
+ * NOTE: Ignore state of request and result buffers for now.
+ * We will initialize them during the next read/txn.
+ */
+static void reset_txn(void)
+{
+ __this_cpu_write(hv_24x7_txn_flags, 0);
+ __this_cpu_write(hv_24x7_txn_err, 0);
+}
+
+/*
+ * 24x7 counters only support READ transactions. They are always counting
+ * and dont need/support ADD transactions. Clear ->txn_flags but otherwise
+ * ignore transactions that are not of type PERF_PMU_TXN_READ.
+ *
+ * For READ transactions, submit all pending 24x7 requests (i.e requests
+ * that were queued by h_24x7_event_read()), to the hypervisor and update
+ * the event counts.
+ */
+static int h_24x7_event_commit_txn(struct pmu *pmu)
+{
+ struct hv_24x7_request_buffer *request_buffer;
+ struct hv_24x7_data_result_buffer *result_buffer;
+ struct hv_24x7_result *resb;
+ struct perf_event *event;
+ u64 count;
+ int i, ret, txn_flags;
+ struct hv_24x7_hw *h24x7hw;
+
+ txn_flags = __this_cpu_read(hv_24x7_txn_flags);
+ WARN_ON_ONCE(!txn_flags);
+
+ ret = 0;
+ if (txn_flags & ~PERF_PMU_TXN_READ)
+ goto out;
+
+ ret = __this_cpu_read(hv_24x7_txn_err);
+ if (ret)
+ goto out;
+
+ request_buffer = (void *)get_cpu_var(hv_24x7_reqb);
+ result_buffer = (void *)get_cpu_var(hv_24x7_resb);
+
+ ret = make_24x7_request(request_buffer, result_buffer);
+ if (ret) {
+ log_24x7_hcall(request_buffer, result_buffer, ret);
+ goto put_reqb;
+ }
+
+ h24x7hw = &get_cpu_var(hv_24x7_hw);
+
+ /* Update event counts from hcall */
+ for (i = 0; i < request_buffer->num_requests; i++) {
+ resb = &result_buffer->results[i];
+ count = be64_to_cpu(resb->elements[0].element_data[0]);
+ event = h24x7hw->events[i];
+ h24x7hw->events[i] = NULL;
+ update_event_count(event, count);
+ }
+
+ put_cpu_var(hv_24x7_hw);
+
+put_reqb:
+ put_cpu_var(hv_24x7_resb);
+ put_cpu_var(hv_24x7_reqb);
+out:
+ reset_txn();
+ return ret;
+}
+
+/*
+ * 24x7 counters only support READ transactions. They are always counting
+ * and dont need/support ADD transactions. However, regardless of type
+ * of transaction, all we need to do is cleanup, so we don't have to check
+ * the type of transaction.
+ */
+static void h_24x7_event_cancel_txn(struct pmu *pmu)
+{
+ WARN_ON_ONCE(!__this_cpu_read(hv_24x7_txn_flags));
+ reset_txn();
+}
+
static struct pmu h_24x7_pmu = {
.task_ctx_nr = perf_invalid_context,
@@ -1266,6 +1466,9 @@ static struct pmu h_24x7_pmu = {
.start = h_24x7_event_start,
.stop = h_24x7_event_stop,
.read = h_24x7_event_read,
+ .start_txn = h_24x7_event_start_txn,
+ .commit_txn = h_24x7_event_commit_txn,
+ .cancel_txn = h_24x7_event_cancel_txn,
};
static int hv_24x7_init(void)
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h
index 0f9fa21..791455e 100644
--- a/arch/powerpc/perf/hv-24x7.h
+++ b/arch/powerpc/perf/hv-24x7.h
@@ -7,6 +7,7 @@ enum hv_perf_domains {
#define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v,
#include "hv-24x7-domains.h"
#undef DOMAIN
+ HV_PERF_DOMAIN_MAX,
};
struct hv_24x7_request {
@@ -80,7 +81,7 @@ struct hv_24x7_result {
__u8 results_complete;
__be16 num_elements_returned;
- /* This is a copy of @data_size from the coresponding hv_24x7_request */
+ /* This is a copy of @data_size from the corresponding hv_24x7_request */
__be16 result_element_data_size;
__u8 reserved[0x2];
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 856fe6e..7aa3723 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -127,8 +127,16 @@ static const struct attribute_group *attr_groups[] = {
NULL,
};
-#define GPCI_MAX_DATA_BYTES \
- (1024 - sizeof(struct hv_get_perf_counter_info_params))
+#define HGPCI_REQ_BUFFER_SIZE 4096
+#define HGPCI_MAX_DATA_BYTES \
+ (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params))
+
+DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t));
+
+struct hv_gpci_request_buffer {
+ struct hv_get_perf_counter_info_params params;
+ uint8_t bytes[HGPCI_MAX_DATA_BYTES];
+} __packed;
static unsigned long single_gpci_request(u32 req, u32 starting_index,
u16 secondary_index, u8 version_in, u32 offset, u8 length,
@@ -137,24 +145,21 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
unsigned long ret;
size_t i;
u64 count;
+ struct hv_gpci_request_buffer *arg;
+
+ arg = (void *)get_cpu_var(hv_gpci_reqb);
+ memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
- struct {
- struct hv_get_perf_counter_info_params params;
- uint8_t bytes[GPCI_MAX_DATA_BYTES];
- } __packed __aligned(sizeof(uint64_t)) arg = {
- .params = {
- .counter_request = cpu_to_be32(req),
- .starting_index = cpu_to_be32(starting_index),
- .secondary_index = cpu_to_be16(secondary_index),
- .counter_info_version_in = version_in,
- }
- };
+ arg->params.counter_request = cpu_to_be32(req);
+ arg->params.starting_index = cpu_to_be32(starting_index);
+ arg->params.secondary_index = cpu_to_be16(secondary_index);
+ arg->params.counter_info_version_in = version_in;
ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
- virt_to_phys(&arg), sizeof(arg));
+ virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
if (ret) {
pr_devel("hcall failed: 0x%lx\n", ret);
- return ret;
+ goto out;
}
/*
@@ -163,9 +168,11 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
*/
count = 0;
for (i = offset; i < offset + length; i++)
- count |= arg.bytes[i] << (i - offset);
+ count |= arg->bytes[i] << (i - offset);
*value = count;
+out:
+ put_cpu_var(hv_gpci_reqb);
return ret;
}
@@ -245,10 +252,10 @@ static int h_gpci_event_init(struct perf_event *event)
}
/* last byte within the buffer? */
- if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) {
+ if ((event_get_offset(event) + length) > HGPCI_MAX_DATA_BYTES) {
pr_devel("request outside of buffer: %zu > %zu\n",
(size_t)event_get_offset(event) + length,
- GPCI_MAX_DATA_BYTES);
+ HGPCI_MAX_DATA_BYTES);
return -EINVAL;
}
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 5b62f238..a383c23 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -54,7 +54,7 @@
* Power7 event codes.
*/
#define EVENT(_name, _code) \
- PME_##_name = _code,
+ _name = _code,
enum {
#include "power7-events-list.h"
@@ -318,14 +318,14 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[])
}
static int power7_generic_events[] = {
- [PERF_COUNT_HW_CPU_CYCLES] = PME_PM_CYC,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PME_PM_GCT_NOSLOT_CYC,
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PME_PM_CMPLU_STALL,
- [PERF_COUNT_HW_INSTRUCTIONS] = PME_PM_INST_CMPL,
- [PERF_COUNT_HW_CACHE_REFERENCES] = PME_PM_LD_REF_L1,
- [PERF_COUNT_HW_CACHE_MISSES] = PME_PM_LD_MISS_L1,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PME_PM_BRU_FIN,
- [PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BR_MPRED,
+ [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_GCT_NOSLOT_CYC,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL,
+ [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
+ [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_FIN,
+ [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED,
};
#define C(x) PERF_COUNT_HW_CACHE_##x
diff --git a/arch/powerpc/perf/power8-events-list.h b/arch/powerpc/perf/power8-events-list.h
new file mode 100644
index 0000000..741b77e
--- /dev/null
+++ b/arch/powerpc/perf/power8-events-list.h
@@ -0,0 +1,51 @@
+/*
+ * Performance counter support for POWER8 processors.
+ *
+ * Copyright 2014 Sukadev Bhattiprolu, IBM 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.
+ */
+
+/*
+ * Power8 event codes.
+ */
+EVENT(PM_CYC, 0x0001e)
+EVENT(PM_GCT_NOSLOT_CYC, 0x100f8)
+EVENT(PM_CMPLU_STALL, 0x4000a)
+EVENT(PM_INST_CMPL, 0x00002)
+EVENT(PM_BRU_FIN, 0x10068)
+EVENT(PM_BR_MPRED_CMPL, 0x400f6)
+
+/* All L1 D cache load references counted at finish, gated by reject */
+EVENT(PM_LD_REF_L1, 0x100ee)
+/* Load Missed L1 */
+EVENT(PM_LD_MISS_L1, 0x3e054)
+/* Store Missed L1 */
+EVENT(PM_ST_MISS_L1, 0x300f0)
+/* L1 cache data prefetches */
+EVENT(PM_L1_PREF, 0x0d8b8)
+/* Instruction fetches from L1 */
+EVENT(PM_INST_FROM_L1, 0x04080)
+/* Demand iCache Miss */
+EVENT(PM_L1_ICACHE_MISS, 0x200fd)
+/* Instruction Demand sectors wriittent into IL1 */
+EVENT(PM_L1_DEMAND_WRITE, 0x0408c)
+/* Instruction prefetch written into IL1 */
+EVENT(PM_IC_PREF_WRITE, 0x0408e)
+/* The data cache was reloaded from local core's L3 due to a demand load */
+EVENT(PM_DATA_FROM_L3, 0x4c042)
+/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
+EVENT(PM_DATA_FROM_L3MISS, 0x300fe)
+/* All successful D-side store dispatches for this thread */
+EVENT(PM_L2_ST, 0x17080)
+/* All successful D-side store dispatches for this thread that were L2 Miss */
+EVENT(PM_L2_ST_MISS, 0x17082)
+/* Total HW L3 prefetches(Load+store) */
+EVENT(PM_L3_PREF_ALL, 0x4e052)
+/* Data PTEG reload */
+EVENT(PM_DTLB_MISS, 0x300fc)
+/* ITLB Reloaded */
+EVENT(PM_ITLB_MISS, 0x400fc)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 396351d..690d918 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -17,48 +17,16 @@
#include <asm/firmware.h>
#include <asm/cputable.h>
-
/*
* Some power8 event codes.
*/
-#define PM_CYC 0x0001e
-#define PM_GCT_NOSLOT_CYC 0x100f8
-#define PM_CMPLU_STALL 0x4000a
-#define PM_INST_CMPL 0x00002
-#define PM_BRU_FIN 0x10068
-#define PM_BR_MPRED_CMPL 0x400f6
-
-/* All L1 D cache load references counted at finish, gated by reject */
-#define PM_LD_REF_L1 0x100ee
-/* Load Missed L1 */
-#define PM_LD_MISS_L1 0x3e054
-/* Store Missed L1 */
-#define PM_ST_MISS_L1 0x300f0
-/* L1 cache data prefetches */
-#define PM_L1_PREF 0x0d8b8
-/* Instruction fetches from L1 */
-#define PM_INST_FROM_L1 0x04080
-/* Demand iCache Miss */
-#define PM_L1_ICACHE_MISS 0x200fd
-/* Instruction Demand sectors wriittent into IL1 */
-#define PM_L1_DEMAND_WRITE 0x0408c
-/* Instruction prefetch written into IL1 */
-#define PM_IC_PREF_WRITE 0x0408e
-/* The data cache was reloaded from local core's L3 due to a demand load */
-#define PM_DATA_FROM_L3 0x4c042
-/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
-#define PM_DATA_FROM_L3MISS 0x300fe
-/* All successful D-side store dispatches for this thread */
-#define PM_L2_ST 0x17080
-/* All successful D-side store dispatches for this thread that were L2 Miss */
-#define PM_L2_ST_MISS 0x17082
-/* Total HW L3 prefetches(Load+store) */
-#define PM_L3_PREF_ALL 0x4e052
-/* Data PTEG reload */
-#define PM_DTLB_MISS 0x300fc
-/* ITLB Reloaded */
-#define PM_ITLB_MISS 0x400fc
+#define EVENT(_name, _code) _name = _code,
+
+enum {
+#include "power8-events-list.h"
+};
+#undef EVENT
/*
* Raw event encoding for POWER8:
@@ -415,7 +383,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
pmc_inuse |= 1 << pmc;
}
- /* In continous sampling mode, update SDAR on TLB miss */
+ /* In continuous sampling mode, update SDAR on TLB miss */
mmcra = MMCRA_SDAR_MODE_TLB;
mmcr1 = mmcr2 = 0;
@@ -604,6 +572,71 @@ static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[])
mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
}
+GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL);
+GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
+GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_FIN);
+GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
+GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1);
+GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1);
+
+CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1);
+CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1);
+
+CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF);
+CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);
+CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);
+CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1);
+CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE);
+
+CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);
+CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3);
+CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL);
+CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS);
+CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST);
+
+CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);
+CACHE_EVENT_ATTR(branch-loads, PM_BRU_FIN);
+CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
+CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
+
+static struct attribute *power8_events_attr[] = {
+ GENERIC_EVENT_PTR(PM_CYC),
+ GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC),
+ GENERIC_EVENT_PTR(PM_CMPLU_STALL),
+ GENERIC_EVENT_PTR(PM_INST_CMPL),
+ GENERIC_EVENT_PTR(PM_BRU_FIN),
+ GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
+ GENERIC_EVENT_PTR(PM_LD_REF_L1),
+ GENERIC_EVENT_PTR(PM_LD_MISS_L1),
+
+ CACHE_EVENT_PTR(PM_LD_MISS_L1),
+ CACHE_EVENT_PTR(PM_LD_REF_L1),
+ CACHE_EVENT_PTR(PM_L1_PREF),
+ CACHE_EVENT_PTR(PM_ST_MISS_L1),
+ CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
+ CACHE_EVENT_PTR(PM_INST_FROM_L1),
+ CACHE_EVENT_PTR(PM_IC_PREF_WRITE),
+ CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
+ CACHE_EVENT_PTR(PM_DATA_FROM_L3),
+ CACHE_EVENT_PTR(PM_L3_PREF_ALL),
+ CACHE_EVENT_PTR(PM_L2_ST_MISS),
+ CACHE_EVENT_PTR(PM_L2_ST),
+
+ CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
+ CACHE_EVENT_PTR(PM_BRU_FIN),
+
+ CACHE_EVENT_PTR(PM_DTLB_MISS),
+ CACHE_EVENT_PTR(PM_ITLB_MISS),
+ NULL
+};
+
+static struct attribute_group power8_pmu_events_group = {
+ .name = "events",
+ .attrs = power8_events_attr,
+};
+
PMU_FORMAT_ATTR(event, "config:0-49");
PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
PMU_FORMAT_ATTR(mark, "config:8");
@@ -640,6 +673,7 @@ struct attribute_group power8_pmu_format_group = {
static const struct attribute_group *power8_pmu_attr_groups[] = {
&power8_pmu_format_group,
+ &power8_pmu_events_group,
NULL,
};
@@ -676,6 +710,9 @@ static u64 power8_bhrb_filter_map(u64 branch_sample_type)
if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
return -1;
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_CALL)
+ return -1;
+
if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
return pmu_bhrb_filter;
@@ -813,7 +850,7 @@ static struct power_pmu power8_pmu = {
.get_constraint = power8_get_constraint,
.get_alternatives = power8_get_alternatives,
.disable_pmc = power8_disable_pmc,
- .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_ARCH_207S,
+ .flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
.n_generic = ARRAY_SIZE(power8_generic_events),
.generic_events = power8_generic_events,
.cache_events = &power8_cache_events,
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 48bf38d..f09016f 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -10,6 +10,12 @@ config PPC_MPC512x
select USB_EHCI_BIG_ENDIAN_MMIO if USB_EHCI_HCD
select USB_EHCI_BIG_ENDIAN_DESC if USB_EHCI_HCD
+config MPC512x_LPBFIFO
+ tristate "MPC512x LocalPlus Bus FIFO driver"
+ depends on PPC_MPC512x && MPC512X_DMA
+ help
+ Enable support for Freescale MPC512x LocalPlus Bus FIFO (SCLPC).
+
config MPC5121_ADS
bool "Freescale MPC5121E ADS"
depends on PPC_MPC512x
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 0169312..f47d422 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o
obj-y += mpc512x_shared.o
obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o
+obj-$(CONFIG_MPC512x_LPBFIFO) += mpc512x_lpbfifo.o
obj-$(CONFIG_PDM360NG) += pdm360ng.o
diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c
new file mode 100644
index 0000000..8eb82b0
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c
@@ -0,0 +1,540 @@
+/*
+ * The driver for Freescale MPC512x LocalPlus Bus FIFO
+ * (called SCLPC in the Reference Manual).
+ *
+ * Copyright (C) 2013-2015 Alexander Popov <alex.popov@linux.com>.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/mpc5121.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME "mpc512x_lpbfifo"
+
+struct cs_range {
+ u32 csnum;
+ u32 base; /* must be zero */
+ u32 addr;
+ u32 size;
+};
+
+static struct lpbfifo_data {
+ spinlock_t lock; /* for protecting lpbfifo_data */
+ phys_addr_t regs_phys;
+ resource_size_t regs_size;
+ struct mpc512x_lpbfifo __iomem *regs;
+ int irq;
+ struct cs_range *cs_ranges;
+ size_t cs_n;
+ struct dma_chan *chan;
+ struct mpc512x_lpbfifo_request *req;
+ dma_addr_t ram_bus_addr;
+ bool wait_lpbfifo_irq;
+ bool wait_lpbfifo_callback;
+} lpbfifo;
+
+/*
+ * A data transfer from RAM to some device on LPB is finished
+ * when both mpc512x_lpbfifo_irq() and mpc512x_lpbfifo_callback()
+ * have been called. We execute the callback registered in
+ * mpc512x_lpbfifo_request just after that.
+ * But for a data transfer from some device on LPB to RAM we don't enable
+ * LPBFIFO interrupt because clearing MPC512X_SCLPC_SUCCESS interrupt flag
+ * automatically disables LPBFIFO reading request to the DMA controller
+ * and the data transfer hangs. So the callback registered in
+ * mpc512x_lpbfifo_request is executed at the end of mpc512x_lpbfifo_callback().
+ */
+
+/*
+ * mpc512x_lpbfifo_irq - IRQ handler for LPB FIFO
+ */
+static irqreturn_t mpc512x_lpbfifo_irq(int irq, void *param)
+{
+ struct device *dev = (struct device *)param;
+ struct mpc512x_lpbfifo_request *req = NULL;
+ unsigned long flags;
+ u32 status;
+
+ spin_lock_irqsave(&lpbfifo.lock, flags);
+
+ if (!lpbfifo.regs)
+ goto end;
+
+ req = lpbfifo.req;
+ if (!req || req->dir == MPC512X_LPBFIFO_REQ_DIR_READ) {
+ dev_err(dev, "bogus LPBFIFO IRQ\n");
+ goto end;
+ }
+
+ status = in_be32(&lpbfifo.regs->status);
+ if (status != MPC512X_SCLPC_SUCCESS) {
+ dev_err(dev, "DMA transfer from RAM to peripheral failed\n");
+ out_be32(&lpbfifo.regs->enable,
+ MPC512X_SCLPC_RESET | MPC512X_SCLPC_FIFO_RESET);
+ goto end;
+ }
+ /* Clear the interrupt flag */
+ out_be32(&lpbfifo.regs->status, MPC512X_SCLPC_SUCCESS);
+
+ lpbfifo.wait_lpbfifo_irq = false;
+
+ if (lpbfifo.wait_lpbfifo_callback)
+ goto end;
+
+ /* Transfer is finished, set the FIFO as idle */
+ lpbfifo.req = NULL;
+
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+ if (req->callback)
+ req->callback(req);
+
+ return IRQ_HANDLED;
+
+ end:
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ return IRQ_HANDLED;
+}
+
+/*
+ * mpc512x_lpbfifo_callback is called by DMA driver when
+ * DMA transaction is finished.
+ */
+static void mpc512x_lpbfifo_callback(void *param)
+{
+ unsigned long flags;
+ struct mpc512x_lpbfifo_request *req = NULL;
+ enum dma_data_direction dir;
+
+ spin_lock_irqsave(&lpbfifo.lock, flags);
+
+ if (!lpbfifo.regs) {
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ return;
+ }
+
+ req = lpbfifo.req;
+ if (!req) {
+ pr_err("bogus LPBFIFO callback\n");
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ return;
+ }
+
+ /* Release the mapping */
+ if (req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE)
+ dir = DMA_TO_DEVICE;
+ else
+ dir = DMA_FROM_DEVICE;
+ dma_unmap_single(lpbfifo.chan->device->dev,
+ lpbfifo.ram_bus_addr, req->size, dir);
+
+ lpbfifo.wait_lpbfifo_callback = false;
+
+ if (!lpbfifo.wait_lpbfifo_irq) {
+ /* Transfer is finished, set the FIFO as idle */
+ lpbfifo.req = NULL;
+
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+ if (req->callback)
+ req->callback(req);
+ } else {
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ }
+}
+
+static int mpc512x_lpbfifo_kick(void)
+{
+ u32 bits;
+ bool no_incr = false;
+ u32 bpt = 32; /* max bytes per LPBFIFO transaction involving DMA */
+ u32 cs = 0;
+ size_t i;
+ struct dma_device *dma_dev = NULL;
+ struct scatterlist sg;
+ enum dma_data_direction dir;
+ struct dma_slave_config dma_conf = {};
+ struct dma_async_tx_descriptor *dma_tx = NULL;
+ dma_cookie_t cookie;
+ int ret;
+
+ /*
+ * 1. Fit the requirements:
+ * - the packet size must be a multiple of 4 since FIFO Data Word
+ * Register allows only full-word access according the Reference
+ * Manual;
+ * - the physical address of the device on LPB and the packet size
+ * must be aligned on BPT (bytes per transaction) or 8-bytes
+ * boundary according the Reference Manual;
+ * - but we choose DMA maxburst equal (or very close to) BPT to prevent
+ * DMA controller from overtaking FIFO and causing FIFO underflow
+ * error. So we force the packet size to be aligned on BPT boundary
+ * not to confuse DMA driver which requires the packet size to be
+ * aligned on maxburst boundary;
+ * - BPT should be set to the LPB device port size for operation with
+ * disabled auto-incrementing according Reference Manual.
+ */
+ if (lpbfifo.req->size == 0 || !IS_ALIGNED(lpbfifo.req->size, 4))
+ return -EINVAL;
+
+ if (lpbfifo.req->portsize != LPB_DEV_PORTSIZE_UNDEFINED) {
+ bpt = lpbfifo.req->portsize;
+ no_incr = true;
+ }
+
+ while (bpt > 1) {
+ if (IS_ALIGNED(lpbfifo.req->dev_phys_addr, min(bpt, 0x8u)) &&
+ IS_ALIGNED(lpbfifo.req->size, bpt)) {
+ break;
+ }
+
+ if (no_incr)
+ return -EINVAL;
+
+ bpt >>= 1;
+ }
+ dma_conf.dst_maxburst = max(bpt, 0x4u) / 4;
+ dma_conf.src_maxburst = max(bpt, 0x4u) / 4;
+
+ for (i = 0; i < lpbfifo.cs_n; i++) {
+ phys_addr_t cs_start = lpbfifo.cs_ranges[i].addr;
+ phys_addr_t cs_end = cs_start + lpbfifo.cs_ranges[i].size;
+ phys_addr_t access_start = lpbfifo.req->dev_phys_addr;
+ phys_addr_t access_end = access_start + lpbfifo.req->size;
+
+ if (access_start >= cs_start && access_end <= cs_end) {
+ cs = lpbfifo.cs_ranges[i].csnum;
+ break;
+ }
+ }
+ if (i == lpbfifo.cs_n)
+ return -EFAULT;
+
+ /* 2. Prepare DMA */
+ dma_dev = lpbfifo.chan->device;
+
+ if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE) {
+ dir = DMA_TO_DEVICE;
+ dma_conf.direction = DMA_MEM_TO_DEV;
+ dma_conf.dst_addr = lpbfifo.regs_phys +
+ offsetof(struct mpc512x_lpbfifo, data_word);
+ } else {
+ dir = DMA_FROM_DEVICE;
+ dma_conf.direction = DMA_DEV_TO_MEM;
+ dma_conf.src_addr = lpbfifo.regs_phys +
+ offsetof(struct mpc512x_lpbfifo, data_word);
+ }
+ dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+ /* Make DMA channel work with LPB FIFO data register */
+ if (dma_dev->device_config(lpbfifo.chan, &dma_conf)) {
+ ret = -EINVAL;
+ goto err_dma_prep;
+ }
+
+ sg_init_table(&sg, 1);
+
+ sg_dma_address(&sg) = dma_map_single(dma_dev->dev,
+ lpbfifo.req->ram_virt_addr, lpbfifo.req->size, dir);
+ if (dma_mapping_error(dma_dev->dev, sg_dma_address(&sg)))
+ return -EFAULT;
+
+ lpbfifo.ram_bus_addr = sg_dma_address(&sg); /* For freeing later */
+
+ sg_dma_len(&sg) = lpbfifo.req->size;
+
+ dma_tx = dmaengine_prep_slave_sg(lpbfifo.chan, &sg,
+ 1, dma_conf.direction, 0);
+ if (!dma_tx) {
+ ret = -ENOSPC;
+ goto err_dma_prep;
+ }
+ dma_tx->callback = mpc512x_lpbfifo_callback;
+ dma_tx->callback_param = NULL;
+
+ /* 3. Prepare FIFO */
+ out_be32(&lpbfifo.regs->enable,
+ MPC512X_SCLPC_RESET | MPC512X_SCLPC_FIFO_RESET);
+ out_be32(&lpbfifo.regs->enable, 0x0);
+
+ /*
+ * Configure the watermarks for write operation (RAM->DMA->FIFO->dev):
+ * - high watermark 7 words according the Reference Manual,
+ * - low watermark 512 bytes (half of the FIFO).
+ * These watermarks don't work for read operation since the
+ * MPC512X_SCLPC_FLUSH bit is set (according the Reference Manual).
+ */
+ out_be32(&lpbfifo.regs->fifo_ctrl, MPC512X_SCLPC_FIFO_CTRL(0x7));
+ out_be32(&lpbfifo.regs->fifo_alarm, MPC512X_SCLPC_FIFO_ALARM(0x200));
+
+ /*
+ * Start address is a physical address of the region which belongs
+ * to the device on the LocalPlus Bus
+ */
+ out_be32(&lpbfifo.regs->start_addr, lpbfifo.req->dev_phys_addr);
+
+ /*
+ * Configure chip select, transfer direction, address increment option
+ * and bytes per transaction option
+ */
+ bits = MPC512X_SCLPC_CS(cs);
+ if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_READ)
+ bits |= MPC512X_SCLPC_READ | MPC512X_SCLPC_FLUSH;
+ if (no_incr)
+ bits |= MPC512X_SCLPC_DAI;
+ bits |= MPC512X_SCLPC_BPT(bpt);
+ out_be32(&lpbfifo.regs->ctrl, bits);
+
+ /* Unmask irqs */
+ bits = MPC512X_SCLPC_ENABLE | MPC512X_SCLPC_ABORT_INT_ENABLE;
+ if (lpbfifo.req->dir == MPC512X_LPBFIFO_REQ_DIR_WRITE)
+ bits |= MPC512X_SCLPC_NORM_INT_ENABLE;
+ else
+ lpbfifo.wait_lpbfifo_irq = false;
+
+ out_be32(&lpbfifo.regs->enable, bits);
+
+ /* 4. Set packet size and kick FIFO off */
+ bits = lpbfifo.req->size | MPC512X_SCLPC_START;
+ out_be32(&lpbfifo.regs->pkt_size, bits);
+
+ /* 5. Finally kick DMA off */
+ cookie = dma_tx->tx_submit(dma_tx);
+ if (dma_submit_error(cookie)) {
+ ret = -ENOSPC;
+ goto err_dma_submit;
+ }
+
+ return 0;
+
+ err_dma_submit:
+ out_be32(&lpbfifo.regs->enable,
+ MPC512X_SCLPC_RESET | MPC512X_SCLPC_FIFO_RESET);
+ err_dma_prep:
+ dma_unmap_single(dma_dev->dev, sg_dma_address(&sg),
+ lpbfifo.req->size, dir);
+ return ret;
+}
+
+static int mpc512x_lpbfifo_submit_locked(struct mpc512x_lpbfifo_request *req)
+{
+ int ret = 0;
+
+ if (!lpbfifo.regs)
+ return -ENODEV;
+
+ /* Check whether a transfer is in progress */
+ if (lpbfifo.req)
+ return -EBUSY;
+
+ lpbfifo.wait_lpbfifo_irq = true;
+ lpbfifo.wait_lpbfifo_callback = true;
+ lpbfifo.req = req;
+
+ ret = mpc512x_lpbfifo_kick();
+ if (ret != 0)
+ lpbfifo.req = NULL; /* Set the FIFO as idle */
+
+ return ret;
+}
+
+int mpc512x_lpbfifo_submit(struct mpc512x_lpbfifo_request *req)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&lpbfifo.lock, flags);
+ ret = mpc512x_lpbfifo_submit_locked(req);
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(mpc512x_lpbfifo_submit);
+
+/*
+ * LPBFIFO driver uses "ranges" property of "localbus" device tree node
+ * for being able to determine the chip select number of a client device
+ * ordering a DMA transfer.
+ */
+static int get_cs_ranges(struct device *dev)
+{
+ int ret = -ENODEV;
+ struct device_node *lb_node;
+ const u32 *addr_cells_p;
+ const u32 *size_cells_p;
+ int proplen;
+ size_t i;
+
+ lb_node = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-localbus");
+ if (!lb_node)
+ return ret;
+
+ /*
+ * The node defined as compatible with 'fsl,mpc5121-localbus'
+ * should have two address cells and one size cell.
+ * Every item of its ranges property should consist of:
+ * - the first address cell which is the chipselect number;
+ * - the second address cell which is the offset in the chipselect,
+ * must be zero.
+ * - CPU address of the beginning of an access window;
+ * - the only size cell which is the size of an access window.
+ */
+ addr_cells_p = of_get_property(lb_node, "#address-cells", NULL);
+ size_cells_p = of_get_property(lb_node, "#size-cells", NULL);
+ if (addr_cells_p == NULL || *addr_cells_p != 2 ||
+ size_cells_p == NULL || *size_cells_p != 1) {
+ goto end;
+ }
+
+ proplen = of_property_count_u32_elems(lb_node, "ranges");
+ if (proplen <= 0 || proplen % 4 != 0)
+ goto end;
+
+ lpbfifo.cs_n = proplen / 4;
+ lpbfifo.cs_ranges = devm_kcalloc(dev, lpbfifo.cs_n,
+ sizeof(struct cs_range), GFP_KERNEL);
+ if (!lpbfifo.cs_ranges)
+ goto end;
+
+ if (of_property_read_u32_array(lb_node, "ranges",
+ (u32 *)lpbfifo.cs_ranges, proplen) != 0) {
+ goto end;
+ }
+
+ for (i = 0; i < lpbfifo.cs_n; i++) {
+ if (lpbfifo.cs_ranges[i].base != 0)
+ goto end;
+ }
+
+ ret = 0;
+
+ end:
+ of_node_put(lb_node);
+ return ret;
+}
+
+static int mpc512x_lpbfifo_probe(struct platform_device *pdev)
+{
+ struct resource r;
+ int ret = 0;
+
+ memset(&lpbfifo, 0, sizeof(struct lpbfifo_data));
+ spin_lock_init(&lpbfifo.lock);
+
+ lpbfifo.chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
+ if (lpbfifo.chan == NULL)
+ return -EPROBE_DEFER;
+
+ if (of_address_to_resource(pdev->dev.of_node, 0, &r) != 0) {
+ dev_err(&pdev->dev, "bad 'reg' in 'sclpc' device tree node\n");
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ lpbfifo.regs_phys = r.start;
+ lpbfifo.regs_size = resource_size(&r);
+
+ if (!devm_request_mem_region(&pdev->dev, lpbfifo.regs_phys,
+ lpbfifo.regs_size, DRV_NAME)) {
+ dev_err(&pdev->dev, "unable to request region\n");
+ ret = -EBUSY;
+ goto err0;
+ }
+
+ lpbfifo.regs = devm_ioremap(&pdev->dev,
+ lpbfifo.regs_phys, lpbfifo.regs_size);
+ if (!lpbfifo.regs) {
+ dev_err(&pdev->dev, "mapping registers failed\n");
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ out_be32(&lpbfifo.regs->enable,
+ MPC512X_SCLPC_RESET | MPC512X_SCLPC_FIFO_RESET);
+
+ if (get_cs_ranges(&pdev->dev) != 0) {
+ dev_err(&pdev->dev, "bad '/localbus' device tree node\n");
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ lpbfifo.irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (lpbfifo.irq == NO_IRQ) {
+ dev_err(&pdev->dev, "mapping irq failed\n");
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ if (request_irq(lpbfifo.irq, mpc512x_lpbfifo_irq, 0,
+ DRV_NAME, &pdev->dev) != 0) {
+ dev_err(&pdev->dev, "requesting irq failed\n");
+ ret = -ENODEV;
+ goto err1;
+ }
+
+ dev_info(&pdev->dev, "probe succeeded\n");
+ return 0;
+
+ err1:
+ irq_dispose_mapping(lpbfifo.irq);
+ err0:
+ dma_release_channel(lpbfifo.chan);
+ return ret;
+}
+
+static int mpc512x_lpbfifo_remove(struct platform_device *pdev)
+{
+ unsigned long flags;
+ struct dma_device *dma_dev = lpbfifo.chan->device;
+ struct mpc512x_lpbfifo __iomem *regs = NULL;
+
+ spin_lock_irqsave(&lpbfifo.lock, flags);
+ regs = lpbfifo.regs;
+ lpbfifo.regs = NULL;
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+ dma_dev->device_terminate_all(lpbfifo.chan);
+ out_be32(&regs->enable, MPC512X_SCLPC_RESET | MPC512X_SCLPC_FIFO_RESET);
+
+ free_irq(lpbfifo.irq, &pdev->dev);
+ irq_dispose_mapping(lpbfifo.irq);
+ dma_release_channel(lpbfifo.chan);
+
+ return 0;
+}
+
+static const struct of_device_id mpc512x_lpbfifo_match[] = {
+ { .compatible = "fsl,mpc512x-lpbfifo", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mpc512x_lpbfifo_match);
+
+static struct platform_driver mpc512x_lpbfifo_driver = {
+ .probe = mpc512x_lpbfifo_probe,
+ .remove = mpc512x_lpbfifo_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mpc512x_lpbfifo_match,
+ },
+};
+
+module_platform_driver(mpc512x_lpbfifo_driver);
+
+MODULE_AUTHOR("Alexander Popov <alex.popov@linux.com>");
+MODULE_DESCRIPTION("MPC512x LocalPlus Bus FIFO device driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 711f3d3..452da23 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -188,7 +188,7 @@ static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
static inline void mpc512x_free_bootmem(struct page *page)
{
BUG_ON(PageTail(page));
- BUG_ON(atomic_read(&page->_count) > 1);
+ BUG_ON(page_ref_count(page) > 1);
free_reserved_page(page);
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 78ac19a..3048e34 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -724,7 +724,7 @@ static int mpc52xx_gpt_probe(struct platform_device *ofdev)
{
struct mpc52xx_gpt_priv *gpt;
- gpt = kzalloc(sizeof *gpt, GFP_KERNEL);
+ gpt = devm_kzalloc(&ofdev->dev, sizeof *gpt, GFP_KERNEL);
if (!gpt)
return -ENOMEM;
@@ -732,10 +732,8 @@ static int mpc52xx_gpt_probe(struct platform_device *ofdev)
gpt->dev = &ofdev->dev;
gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
gpt->regs = of_iomap(ofdev->dev.of_node, 0);
- if (!gpt->regs) {
- kfree(gpt);
+ if (!gpt->regs)
return -ENOMEM;
- }
dev_set_drvdata(&ofdev->dev, gpt);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 251dcb9..7bb42a0 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -568,6 +568,7 @@ static const struct of_device_id mpc52xx_lpbfifo_match[] = {
{ .compatible = "fsl,mpc5200-lpbfifo", },
{},
};
+MODULE_DEVICE_TABLE(of, mpc52xx_lpbfifo_match);
static struct platform_driver mpc52xx_lpbfifo_driver = {
.driver = {
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 6eb3b2a..00282c2 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -319,7 +319,7 @@ mpc52xx_pci_setup(struct pci_controller *hose,
tmp = in_be32(&pci_regs->gscr);
#if 0
- /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
+ /* Reset the exteral bus ( internal PCI controller is NOT reset ) */
/* Not necessary and can be a bad thing if for example the bootloader
is displaying a splash screen or ... Just left here for
documentation purpose if anyone need it */
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index a0cb8bd..6781bda 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -131,23 +131,15 @@ static int ep8248e_mdio_probe(struct platform_device *ofdev)
if (!bus)
return -ENOMEM;
- bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- if (bus->irq == NULL) {
- ret = -ENOMEM;
- goto err_free_bus;
- }
-
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
ret = of_mdiobus_register(bus, ofdev->dev.of_node);
if (ret)
- goto err_free_irq;
+ goto err_free_bus;
return 0;
-err_free_irq:
- kfree(bus->irq);
err_free_bus:
free_mdio_bitbang(bus);
return ret;
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c
index bf4c447..4bc6bbb 100644
--- a/arch/powerpc/platforms/83xx/km83xx.c
+++ b/arch/powerpc/platforms/83xx/km83xx.c
@@ -37,8 +37,8 @@
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h"
@@ -136,8 +136,6 @@ static void __init mpc83xx_km_setup_arch(void)
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE
- qe_reset();
-
np = of_find_node_by_name(NULL, "par_io");
if (np != NULL) {
par_io_init(np);
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c
index ef9d01a..7e923ca 100644
--- a/arch/powerpc/platforms/83xx/misc.c
+++ b/arch/powerpc/platforms/83xx/misc.c
@@ -17,7 +17,7 @@
#include <asm/io.h>
#include <asm/hw_irq.h>
#include <asm/ipic.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 8d76220..a973b2a 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -36,8 +36,8 @@
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h"
@@ -74,8 +74,6 @@ static void __init mpc832x_sys_setup_arch(void)
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE
- qe_reset();
-
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
par_io_init(np);
of_node_put(np);
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index eff5baa..ea2b87d 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -25,8 +25,8 @@
#include <asm/time.h>
#include <asm/ipic.h>
#include <asm/udbg.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -203,8 +203,6 @@ static void __init mpc832x_rdb_setup_arch(void)
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE
- qe_reset();
-
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
par_io_init(np);
of_node_put(np);
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 1a26d2f..dd70b85 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -44,8 +44,8 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include <sysdev/simple_gpio.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include "mpc83xx.h"
@@ -82,8 +82,6 @@ static void __init mpc836x_mds_setup_arch(void)
mpc83xx_setup_pci();
#ifdef CONFIG_QUICC_ENGINE
- qe_reset();
-
if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) {
par_io_init(np);
of_node_put(np);
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
index b63b42d..4cd7153 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -20,8 +20,8 @@
#include <asm/time.h>
#include <asm/ipic.h>
#include <asm/udbg.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -35,9 +35,6 @@ static void __init mpc836x_rdk_setup_arch(void)
ppc_md.progress("mpc836x_rdk_setup_arch()", 0);
mpc83xx_setup_pci();
-#ifdef CONFIG_QUICC_ENGINE
- qe_reset();
-#endif
}
/*
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 97915fe..e626461 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE
select FSL_PCI if PCI
select SERIAL_8250_EXTENDED if SERIAL_8250
select SERIAL_8250_SHARE_IRQ if SERIAL_8250
+ select FSL_CORENET_RCPM if PPC_E500MC
default y
if FSL_SOC_BOOKE
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 1fe7fb9..7bc86da 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -2,6 +2,7 @@
# Makefile for the PowerPC 85xx linux kernel.
#
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o
obj-y += common.o
diff --git a/arch/powerpc/platforms/85xx/bsc913x_qds.c b/arch/powerpc/platforms/85xx/bsc913x_qds.c
index f0927e5..dcfafd6 100644
--- a/arch/powerpc/platforms/85xx/bsc913x_qds.c
+++ b/arch/powerpc/platforms/85xx/bsc913x_qds.c
@@ -17,6 +17,7 @@
#include <linux/pci.h>
#include <asm/mpic.h>
#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
#include <asm/udbg.h>
#include "mpc85xx.h"
@@ -46,10 +47,12 @@ static void __init bsc913x_qds_setup_arch(void)
mpc85xx_smp_init();
#endif
+ fsl_pci_assign_primary();
+
pr_info("bsc913x board from Freescale Semiconductor\n");
}
-machine_device_initcall(bsc9132_qds, mpc85xx_common_publish_devices);
+machine_arch_initcall(bsc9132_qds, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
@@ -67,6 +70,9 @@ define_machine(bsc9132_qds) {
.probe = bsc9132_qds_probe,
.setup_arch = bsc913x_qds_setup_arch,
.init_IRQ = bsc913x_qds_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
.get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
index 23791de..28720a4 100644
--- a/arch/powerpc/platforms/85xx/common.c
+++ b/arch/powerpc/platforms/85xx/common.c
@@ -9,11 +9,14 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-#include <asm/qe.h>
+#include <asm/fsl_pm.h>
+#include <soc/fsl/qe/qe.h>
#include <sysdev/cpm2_pic.h>
#include "mpc85xx.h"
+const struct fsl_pm_ops *qoriq_pm_ops;
+
static const struct of_device_id mpc85xx_common_ids[] __initconst = {
{ .type = "soc", },
{ .compatible = "soc", },
@@ -105,7 +108,6 @@ void __init mpc85xx_qe_init(void)
return;
}
- qe_reset();
of_node_put(np);
}
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index b395571..a2b0bc8 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -27,7 +27,7 @@
#include <asm/udbg.h>
#include <asm/mpic.h>
#include <asm/ehv_pic.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <linux/of_platform.h>
#include <sysdev/fsl_soc.h>
@@ -161,6 +161,7 @@ static const char * const boards[] __initconst = {
"fsl,T1042RDB",
"fsl,T1042RDB_PI",
"keymile,kmcoge4",
+ "varisys,CYRUS",
NULL
};
@@ -214,7 +215,17 @@ define_machine(corenet_generic) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
+/*
+ * Core reset may cause issues if using the proxy mode of MPIC.
+ * So, use the mixed mode of MPIC if enabling CPU hotplug.
+ *
+ * Likewise, problems have been seen with kexec when coreint is enabled.
+ */
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
+ .get_irq = mpic_get_irq,
+#else
.get_irq = mpic_get_coreint_irq,
+#endif
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 7d12a19..de72a5f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -36,17 +36,6 @@
#include "mpc85xx.h"
-#ifdef CONFIG_PCI
-static int mpc85xx_exclude_device(struct pci_controller *hose,
- u_char bus, u_char devfn)
-{
- if (bus == 0 && PCI_SLOT(devfn) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- else
- return PCIBIOS_SUCCESSFUL;
-}
-#endif /* CONFIG_PCI */
-
static void __init mpc85xx_ads_pic_init(void)
{
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
@@ -145,10 +134,6 @@ static void __init mpc85xx_ads_setup_arch(void)
init_ioports();
#endif
-#ifdef CONFIG_PCI
- ppc_md.pci_exclude_device = mpc85xx_exclude_device;
-#endif
-
fsl_pci_assign_primary();
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 5ac70de..d7e87ff 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -99,7 +99,7 @@ static void mpc85xx_cds_restart(char *cmd)
pci_read_config_byte(dev, 0x47, &tmp);
/*
- * At this point, the harware reset should have triggered.
+ * At this point, the hardware reset should have triggered.
* However, if it doesn't work for some mysterious reason,
* just fall through to the default reset below.
*/
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index a392e94..f61cbe2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -34,6 +34,7 @@
#include <linux/of_device.h>
#include <linux/phy.h>
#include <linux/memblock.h>
+#include <linux/fsl/guts.h>
#include <linux/atomic.h>
#include <asm/time.h>
@@ -47,11 +48,10 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include <sysdev/simple_gpio.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <asm/mpic.h>
#include <asm/swiotlb.h>
-#include <asm/fsl_guts.h>
#include "smp.h"
#include "mpc85xx.h"
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
new file mode 100644
index 0000000..f05325f
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
@@ -0,0 +1,106 @@
+/*
+ * MPC85xx PM operators
+ *
+ * Copyright 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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/fsl/guts.h>
+
+#include <asm/io.h>
+#include <asm/fsl_pm.h>
+
+static struct ccsr_guts __iomem *guts;
+
+static void mpc85xx_irq_mask(int cpu)
+{
+
+}
+
+static void mpc85xx_irq_unmask(int cpu)
+{
+
+}
+
+static void mpc85xx_cpu_die(int cpu)
+{
+ u32 tmp;
+
+ tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
+ mtspr(SPRN_HID0, tmp);
+
+ /* Enter NAP mode. */
+ tmp = mfmsr();
+ tmp |= MSR_WE;
+ asm volatile(
+ "msync\n"
+ "mtmsr %0\n"
+ "isync\n"
+ :
+ : "r" (tmp));
+}
+
+static void mpc85xx_cpu_up_prepare(int cpu)
+{
+
+}
+
+static void mpc85xx_freeze_time_base(bool freeze)
+{
+ uint32_t mask;
+
+ mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
+ if (freeze)
+ setbits32(&guts->devdisr, mask);
+ else
+ clrbits32(&guts->devdisr, mask);
+
+ in_be32(&guts->devdisr);
+}
+
+static const struct of_device_id mpc85xx_smp_guts_ids[] = {
+ { .compatible = "fsl,mpc8572-guts", },
+ { .compatible = "fsl,p1020-guts", },
+ { .compatible = "fsl,p1021-guts", },
+ { .compatible = "fsl,p1022-guts", },
+ { .compatible = "fsl,p1023-guts", },
+ { .compatible = "fsl,p2020-guts", },
+ { .compatible = "fsl,bsc9132-guts", },
+ {},
+};
+
+static const struct fsl_pm_ops mpc85xx_pm_ops = {
+ .freeze_time_base = mpc85xx_freeze_time_base,
+ .irq_mask = mpc85xx_irq_mask,
+ .irq_unmask = mpc85xx_irq_unmask,
+ .cpu_die = mpc85xx_cpu_die,
+ .cpu_up_prepare = mpc85xx_cpu_up_prepare,
+};
+
+int __init mpc85xx_setup_pmc(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
+ if (np) {
+ guts = of_iomap(np, 0);
+ of_node_put(np);
+ if (!guts) {
+ pr_err("Could not map guts node address\n");
+ return -ENOMEM;
+ }
+ }
+
+ qoriq_pm_ops = &mpc85xx_pm_ops;
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index e358bed..3f4dad1 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -17,6 +17,7 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
+#include <linux/fsl/guts.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -25,9 +26,8 @@
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 6ac986d3..371df82 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -16,6 +16,7 @@
* kind, whether express or implied.
*/
+#include <linux/fsl/guts.h>
#include <linux/pci.h>
#include <linux/of_platform.h>
#include <asm/div64.h>
@@ -25,7 +26,6 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include <asm/udbg.h>
-#include <asm/fsl_guts.h>
#include <asm/fsl_lbc.h>
#include "smp.h"
diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
index 680232d..5087bec 100644
--- a/arch/powerpc/platforms/85xx/p1022_rdk.c
+++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
@@ -12,6 +12,7 @@
* kind, whether express or implied.
*/
+#include <linux/fsl/guts.h>
#include <linux/pci.h>
#include <linux/of_platform.h>
#include <asm/div64.h>
@@ -21,7 +22,6 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include <asm/udbg.h>
-#include <asm/fsl_guts.h>
#include "smp.h"
#include "mpc85xx.h"
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index b8b8216..fe9f19e 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
* Author: Andy Fleming <afleming@freescale.com>
* Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
+ * Copyright 2006-2008, 2011-2012, 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 as published by the
@@ -15,10 +15,10 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/of.h>
-#include <linux/of_address.h>
#include <linux/kexec.h>
#include <linux/highmem.h>
#include <linux/cpu.h>
+#include <linux/fsl/guts.h>
#include <asm/machdep.h>
#include <asm/pgtable.h>
@@ -26,9 +26,9 @@
#include <asm/mpic.h>
#include <asm/cacheflush.h>
#include <asm/dbell.h>
-#include <asm/fsl_guts.h>
#include <asm/code-patching.h>
#include <asm/cputhreads.h>
+#include <asm/fsl_pm.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/mpic.h>
@@ -43,35 +43,23 @@ struct epapr_spin_table {
u32 pir;
};
-static struct ccsr_guts __iomem *guts;
+#ifdef CONFIG_HOTPLUG_CPU
static u64 timebase;
static int tb_req;
static int tb_valid;
-static void mpc85xx_timebase_freeze(int freeze)
-{
- uint32_t mask;
-
- mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
- if (freeze)
- setbits32(&guts->devdisr, mask);
- else
- clrbits32(&guts->devdisr, mask);
-
- in_be32(&guts->devdisr);
-}
-
static void mpc85xx_give_timebase(void)
{
unsigned long flags;
local_irq_save(flags);
+ hard_irq_disable();
while (!tb_req)
barrier();
tb_req = 0;
- mpc85xx_timebase_freeze(1);
+ qoriq_pm_ops->freeze_time_base(true);
#ifdef CONFIG_PPC64
/*
* e5500/e6500 have a workaround for erratum A-006958 in place
@@ -104,7 +92,7 @@ static void mpc85xx_give_timebase(void)
while (tb_valid)
barrier();
- mpc85xx_timebase_freeze(0);
+ qoriq_pm_ops->freeze_time_base(false);
local_irq_restore(flags);
}
@@ -114,6 +102,7 @@ static void mpc85xx_take_timebase(void)
unsigned long flags;
local_irq_save(flags);
+ hard_irq_disable();
tb_req = 1;
while (!tb_valid)
@@ -126,36 +115,54 @@ static void mpc85xx_take_timebase(void)
local_irq_restore(flags);
}
-#ifdef CONFIG_HOTPLUG_CPU
static void smp_85xx_mach_cpu_die(void)
{
unsigned int cpu = smp_processor_id();
- u32 tmp;
local_irq_disable();
+ hard_irq_disable();
+ /* mask all irqs to prevent cpu wakeup */
+ qoriq_pm_ops->irq_mask(cpu);
+
idle_task_exit();
- generic_set_cpu_dead(cpu);
- mb();
mtspr(SPRN_TCR, 0);
+ mtspr(SPRN_TSR, mfspr(SPRN_TSR));
- __flush_disable_L1();
- tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
- mtspr(SPRN_HID0, tmp);
- isync();
+ generic_set_cpu_dead(cpu);
- /* Enter NAP mode. */
- tmp = mfmsr();
- tmp |= MSR_WE;
- mb();
- mtmsr(tmp);
- isync();
+ cur_cpu_spec->cpu_down_flush();
+
+ qoriq_pm_ops->cpu_die(cpu);
while (1)
;
}
+
+static void qoriq_cpu_kill(unsigned int cpu)
+{
+ int i;
+
+ for (i = 0; i < 500; i++) {
+ if (is_cpu_dead(cpu)) {
+#ifdef CONFIG_PPC64
+ paca[cpu].cpu_start = 0;
+#endif
+ return;
+ }
+ msleep(20);
+ }
+ pr_err("CPU%d didn't die...\n", cpu);
+}
#endif
+/*
+ * To keep it compatible with old boot program which uses
+ * cache-inhibit spin table, we need to flush the cache
+ * before accessing spin table to invalidate any staled data.
+ * We also need to flush the cache after writing to spin
+ * table to push data out.
+ */
static inline void flush_spin_table(void *spin_table)
{
flush_dcache_range((ulong)spin_table,
@@ -173,65 +180,28 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
static void wake_hw_thread(void *info)
{
void fsl_secondary_thread_init(void);
- unsigned long imsr1, inia1;
- int nr = *(const int *)info;
-
- imsr1 = MSR_KERNEL;
- inia1 = *(unsigned long *)fsl_secondary_thread_init;
+ unsigned long inia;
+ int cpu = *(const int *)info;
- mttmr(TMRN_IMSR1, imsr1);
- mttmr(TMRN_INIA1, inia1);
- mtspr(SPRN_TENS, TEN_THREAD(1));
-
- smp_generic_kick_cpu(nr);
+ inia = *(unsigned long *)fsl_secondary_thread_init;
+ book3e_start_thread(cpu_thread_in_core(cpu), inia);
}
#endif
-static int smp_85xx_kick_cpu(int nr)
+static int smp_85xx_start_cpu(int cpu)
{
- unsigned long flags;
- const u64 *cpu_rel_addr;
- __iomem struct epapr_spin_table *spin_table;
+ int ret = 0;
struct device_node *np;
- int hw_cpu = get_hard_smp_processor_id(nr);
+ const u64 *cpu_rel_addr;
+ unsigned long flags;
int ioremappable;
- int ret = 0;
-
- WARN_ON(nr < 0 || nr >= NR_CPUS);
- WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ struct epapr_spin_table __iomem *spin_table;
- pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
-
-#ifdef CONFIG_PPC64
- /* Threads don't use the spin table */
- if (cpu_thread_in_core(nr) != 0) {
- int primary = cpu_first_thread_sibling(nr);
-
- if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
- return -ENOENT;
-
- if (cpu_thread_in_core(nr) != 1) {
- pr_err("%s: cpu %d: invalid hw thread %d\n",
- __func__, nr, cpu_thread_in_core(nr));
- return -ENOENT;
- }
-
- if (!cpu_online(primary)) {
- pr_err("%s: cpu %d: primary %d not online\n",
- __func__, nr, primary);
- return -ENOENT;
- }
-
- smp_call_function_single(primary, wake_hw_thread, &nr, 0);
- return 0;
- }
-#endif
-
- np = of_get_cpu_node(nr, NULL);
+ np = of_get_cpu_node(cpu, NULL);
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
-
- if (cpu_rel_addr == NULL) {
- printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
+ if (!cpu_rel_addr) {
+ pr_err("No cpu-release-addr for cpu %d\n", cpu);
return -ENOENT;
}
@@ -251,28 +221,18 @@ static int smp_85xx_kick_cpu(int nr)
spin_table = phys_to_virt(*cpu_rel_addr);
local_irq_save(flags);
-#ifdef CONFIG_PPC32
-#ifdef CONFIG_HOTPLUG_CPU
- /* Corresponding to generic_set_cpu_dead() */
- generic_set_cpu_up(nr);
+ hard_irq_disable();
- if (system_state == SYSTEM_RUNNING) {
- /*
- * To keep it compatible with old boot program which uses
- * cache-inhibit spin table, we need to flush the cache
- * before accessing spin table to invalidate any staled data.
- * We also need to flush the cache after writing to spin
- * table to push data out.
- */
- flush_spin_table(spin_table);
- out_be32(&spin_table->addr_l, 0);
- flush_spin_table(spin_table);
+ if (qoriq_pm_ops)
+ qoriq_pm_ops->cpu_up_prepare(cpu);
+ /* if cpu is not spinning, reset it */
+ if (read_spin_table_addr_l(spin_table) != 1) {
/*
* We don't set the BPTR register here since it already points
* to the boot page properly.
*/
- mpic_reset_core(nr);
+ mpic_reset_core(cpu);
/*
* wait until core is ready...
@@ -282,40 +242,23 @@ static int smp_85xx_kick_cpu(int nr)
if (!spin_event_timeout(
read_spin_table_addr_l(spin_table) == 1,
10000, 100)) {
- pr_err("%s: timeout waiting for core %d to reset\n",
- __func__, hw_cpu);
- ret = -ENOENT;
- goto out;
+ pr_err("timeout waiting for cpu %d to reset\n",
+ hw_cpu);
+ ret = -EAGAIN;
+ goto err;
}
-
- /* clear the acknowledge status */
- __secondary_hold_acknowledge = -1;
- }
-#endif
- flush_spin_table(spin_table);
- out_be32(&spin_table->pir, hw_cpu);
- out_be32(&spin_table->addr_l, __pa(__early_start));
- flush_spin_table(spin_table);
-
- /* Wait a bit for the CPU to ack. */
- if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
- 10000, 100)) {
- pr_err("%s: timeout waiting for core %d to ack\n",
- __func__, hw_cpu);
- ret = -ENOENT;
- goto out;
}
-out:
-#else
- smp_generic_kick_cpu(nr);
flush_spin_table(spin_table);
out_be32(&spin_table->pir, hw_cpu);
+#ifdef CONFIG_PPC64
out_be64((u64 *)(&spin_table->addr_h),
__pa(ppc_function_entry(generic_secondary_smp_init)));
- flush_spin_table(spin_table);
+#else
+ out_be32(&spin_table->addr_l, __pa(__early_start));
#endif
-
+ flush_spin_table(spin_table);
+err:
local_irq_restore(flags);
if (ioremappable)
@@ -324,6 +267,81 @@ out:
return ret;
}
+static int smp_85xx_kick_cpu(int nr)
+{
+ int ret = 0;
+#ifdef CONFIG_PPC64
+ int primary = nr;
+#endif
+
+ WARN_ON(nr < 0 || nr >= num_possible_cpus());
+
+ pr_debug("kick CPU #%d\n", nr);
+
+#ifdef CONFIG_PPC64
+ if (threads_per_core == 2) {
+ if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
+ return -ENOENT;
+
+ booting_thread_hwid = cpu_thread_in_core(nr);
+ primary = cpu_first_thread_sibling(nr);
+
+ if (qoriq_pm_ops)
+ qoriq_pm_ops->cpu_up_prepare(nr);
+
+ /*
+ * If either thread in the core is online, use it to start
+ * the other.
+ */
+ if (cpu_online(primary)) {
+ smp_call_function_single(primary,
+ wake_hw_thread, &nr, 1);
+ goto done;
+ } else if (cpu_online(primary + 1)) {
+ smp_call_function_single(primary + 1,
+ wake_hw_thread, &nr, 1);
+ goto done;
+ }
+
+ /*
+ * If getting here, it means both threads in the core are
+ * offline. So start the primary thread, then it will start
+ * the thread specified in booting_thread_hwid, the one
+ * corresponding to nr.
+ */
+
+ } else if (threads_per_core == 1) {
+ /*
+ * If one core has only one thread, set booting_thread_hwid to
+ * an invalid value.
+ */
+ booting_thread_hwid = INVALID_THREAD_HWID;
+
+ } else if (threads_per_core > 2) {
+ pr_err("Do not support more than 2 threads per CPU.");
+ return -EINVAL;
+ }
+
+ ret = smp_85xx_start_cpu(primary);
+ if (ret)
+ return ret;
+
+done:
+ paca[nr].cpu_start = 1;
+ generic_set_cpu_up(nr);
+
+ return ret;
+#else
+ ret = smp_85xx_start_cpu(nr);
+ if (ret)
+ return ret;
+
+ generic_set_cpu_up(nr);
+
+ return ret;
+#endif
+}
+
struct smp_ops_t smp_85xx_ops = {
.kick_cpu = smp_85xx_kick_cpu,
.cpu_bootable = smp_generic_cpu_bootable,
@@ -331,13 +349,14 @@ struct smp_ops_t smp_85xx_ops = {
.cpu_disable = generic_cpu_disable,
.cpu_die = generic_cpu_die,
#endif
-#ifdef CONFIG_KEXEC
+#if defined(CONFIG_KEXEC) && !defined(CONFIG_PPC64)
.give_timebase = smp_generic_give_timebase,
.take_timebase = smp_generic_take_timebase,
#endif
};
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_PPC32
atomic_t kexec_down_cpus = ATOMIC_INIT(0);
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
@@ -345,7 +364,7 @@ void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
local_irq_disable();
if (secondary) {
- __flush_disable_L1();
+ cur_cpu_spec->cpu_down_flush();
atomic_inc(&kexec_down_cpus);
/* loop forever */
while (1);
@@ -357,9 +376,64 @@ static void mpc85xx_smp_kexec_down(void *arg)
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(0,1);
}
+#else
+void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+ int cpu = smp_processor_id();
+ int sibling = cpu_last_thread_sibling(cpu);
+ bool notified = false;
+ int disable_cpu;
+ int disable_threadbit = 0;
+ long start = mftb();
+ long now;
+
+ local_irq_disable();
+ hard_irq_disable();
+ mpic_teardown_this_cpu(secondary);
+
+ if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
+ /*
+ * We enter the crash kernel on whatever cpu crashed,
+ * even if it's a secondary thread. If that's the case,
+ * disable the corresponding primary thread.
+ */
+ disable_threadbit = 1;
+ disable_cpu = cpu_first_thread_sibling(cpu);
+ } else if (sibling != crashing_cpu &&
+ cpu_thread_in_core(cpu) == 0 &&
+ cpu_thread_in_core(sibling) != 0) {
+ disable_threadbit = 2;
+ disable_cpu = sibling;
+ }
+
+ if (disable_threadbit) {
+ while (paca[disable_cpu].kexec_state < KEXEC_STATE_REAL_MODE) {
+ barrier();
+ now = mftb();
+ if (!notified && now - start > 1000000) {
+ pr_info("%s/%d: waiting for cpu %d to enter KEXEC_STATE_REAL_MODE (%d)\n",
+ __func__, smp_processor_id(),
+ disable_cpu,
+ paca[disable_cpu].kexec_state);
+ notified = true;
+ }
+ }
+
+ if (notified) {
+ pr_info("%s: cpu %d done waiting\n",
+ __func__, disable_cpu);
+ }
+
+ mtspr(SPRN_TENC, disable_threadbit);
+ while (mfspr(SPRN_TENSR) & disable_threadbit)
+ cpu_relax();
+ }
+}
+#endif
static void mpc85xx_smp_machine_kexec(struct kimage *image)
{
+#ifdef CONFIG_PPC32
int timeout = INT_MAX;
int i, num_cpus = num_present_cpus();
@@ -380,6 +454,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
if ( i == smp_processor_id() ) continue;
mpic_reset_core(i);
}
+#endif
default_machine_kexec(image);
}
@@ -397,16 +472,6 @@ static void smp_85xx_setup_cpu(int cpu_nr)
smp_85xx_basic_setup(cpu_nr);
}
-static const struct of_device_id mpc85xx_smp_guts_ids[] = {
- { .compatible = "fsl,mpc8572-guts", },
- { .compatible = "fsl,p1020-guts", },
- { .compatible = "fsl,p1021-guts", },
- { .compatible = "fsl,p1022-guts", },
- { .compatible = "fsl,p1023-guts", },
- { .compatible = "fsl,p2020-guts", },
- {},
-};
-
void __init mpc85xx_smp_init(void)
{
struct device_node *np;
@@ -430,22 +495,21 @@ void __init mpc85xx_smp_init(void)
smp_85xx_ops.probe = NULL;
}
- np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
- if (np) {
- guts = of_iomap(np, 0);
- of_node_put(np);
- if (!guts) {
- pr_err("%s: Could not map guts node address\n",
- __func__);
- return;
- }
+#ifdef CONFIG_HOTPLUG_CPU
+#ifdef CONFIG_FSL_CORENET_RCPM
+ fsl_rcpm_init();
+#endif
+
+#ifdef CONFIG_FSL_PMC
+ mpc85xx_setup_pmc();
+#endif
+ if (qoriq_pm_ops) {
smp_85xx_ops.give_timebase = mpc85xx_give_timebase;
smp_85xx_ops.take_timebase = mpc85xx_take_timebase;
-#ifdef CONFIG_HOTPLUG_CPU
ppc_md.cpu_die = smp_85xx_mach_cpu_die;
-#endif
+ smp_85xx_ops.cpu_die = qoriq_cpu_kill;
}
-
+#endif
smp_ops = &smp_85xx_ops;
#ifdef CONFIG_KEXEC
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h
index e2b4493..0b20ae3 100644
--- a/arch/powerpc/platforms/85xx/smp.h
+++ b/arch/powerpc/platforms/85xx/smp.h
@@ -5,6 +5,7 @@
#ifdef CONFIG_SMP
void __init mpc85xx_smp_init(void);
+int __init mpc85xx_setup_pmc(void);
#else
static inline void mpc85xx_smp_init(void)
{
diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c
index 30e002f..71bc255 100644
--- a/arch/powerpc/platforms/85xx/twr_p102x.c
+++ b/arch/powerpc/platforms/85xx/twr_p102x.c
@@ -15,15 +15,15 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/fsl/guts.h>
#include <linux/pci.h>
#include <linux/of_platform.h>
#include <asm/pci-bridge.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
-#include <asm/qe.h>
-#include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
+#include <soc/fsl/qe/qe.h>
+#include <soc/fsl/qe/qe_ic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index ede815d..2d889ad 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -2,7 +2,7 @@
# Makefile for the PowerPC 86xx linux kernel.
#
-obj-y := pic.o
+obj-y := pic.o common.o
obj-$(CONFIG_SMP) += mpc86xx_smp.o
obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
obj-$(CONFIG_SBC8641D) += sbc8641d.o
diff --git a/arch/powerpc/platforms/86xx/common.c b/arch/powerpc/platforms/86xx/common.c
new file mode 100644
index 0000000..0f7b7fc
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/common.c
@@ -0,0 +1,43 @@
+/*
+ * Routines common to most mpc86xx-based boards.
+ *
+ * This is free software; you can redistribute it 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/synch.h>
+
+#include "mpc86xx.h"
+
+static const struct of_device_id mpc86xx_common_ids[] __initconst = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .compatible = "simple-bus", },
+ { .name = "localbus", },
+ { .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
+ {},
+};
+
+int __init mpc86xx_common_publish_devices(void)
+{
+ return of_platform_bus_probe(NULL, mpc86xx_common_ids, NULL);
+}
+
+long __init mpc86xx_time_init(void)
+{
+ unsigned int temp;
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ temp = mfspr(SPRN_HID0);
+ temp |= HID0_TBEN;
+ mtspr(SPRN_HID0, temp);
+ isync();
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index bf17933..8e63b75 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -197,37 +197,7 @@ static int __init gef_ppc9a_probe(void)
return 0;
}
-static long __init mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
-static const struct of_device_id of_bus_ids[] __initconst = {
- { .compatible = "simple-bus", },
- { .compatible = "gianfar", },
- { .compatible = "fsl,mpc8641-pcie", },
- {},
-};
-
-static int __init declare_of_platform_devices(void)
-{
- printk(KERN_DEBUG "Probe platform devices\n");
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
-
- return 0;
-}
-machine_arch_initcall(gef_ppc9a, declare_of_platform_devices);
+machine_arch_initcall(gef_ppc9a, mpc86xx_common_publish_devices);
define_machine(gef_ppc9a) {
.name = "GE PPC9A",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index 8facf58..0e0be94 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -184,37 +184,7 @@ static int __init gef_sbc310_probe(void)
return 0;
}
-static long __init mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
-static const struct of_device_id of_bus_ids[] __initconst = {
- { .compatible = "simple-bus", },
- { .compatible = "gianfar", },
- { .compatible = "fsl,mpc8641-pcie", },
- {},
-};
-
-static int __init declare_of_platform_devices(void)
-{
- printk(KERN_DEBUG "Probe platform devices\n");
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
-
- return 0;
-}
-machine_arch_initcall(gef_sbc310, declare_of_platform_devices);
+machine_arch_initcall(gef_sbc310, mpc86xx_common_publish_devices);
define_machine(gef_sbc310) {
.name = "GE SBC310",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index 8c9058d..e8292b4 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -174,37 +174,7 @@ static int __init gef_sbc610_probe(void)
return 0;
}
-static long __init mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
-static const struct of_device_id of_bus_ids[] __initconst = {
- { .compatible = "simple-bus", },
- { .compatible = "gianfar", },
- { .compatible = "fsl,mpc8641-pcie", },
- {},
-};
-
-static int __init declare_of_platform_devices(void)
-{
- printk(KERN_DEBUG "Probe platform devices\n");
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
-
- return 0;
-}
-machine_arch_initcall(gef_sbc610, declare_of_platform_devices);
+machine_arch_initcall(gef_sbc610, mpc86xx_common_publish_devices);
define_machine(gef_sbc610) {
.name = "GE SBC610",
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 55413a5..957473e 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/of.h>
+#include <linux/fsl/guts.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -38,7 +39,6 @@
#include <sysdev/fsl_pci.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/simple_gpio.h>
-#include <asm/fsl_guts.h>
#include "mpc86xx.h"
@@ -88,12 +88,10 @@ static inline void mpc8610_suspend_init(void) { }
static const struct of_device_id mpc8610_ids[] __initconst = {
{ .compatible = "fsl,mpc8610-immr", },
{ .compatible = "fsl,mpc8610-guts", },
- { .compatible = "simple-bus", },
/* So that the DMA channel nodes can be probed individually: */
{ .compatible = "fsl,eloplus-dma", },
/* PCI controllers */
{ .compatible = "fsl,mpc8610-pci", },
- { .compatible = "fsl,mpc8641-pcie", },
{}
};
@@ -105,6 +103,8 @@ static int __init mpc8610_declare_of_platform_devices(void)
/* Enable wakeup on PIXIS' event IRQ. */
mpc8610_suspend_init();
+ mpc86xx_common_publish_devices();
+
/* Without this call, the SSI device driver won't get probed. */
of_platform_bus_probe(NULL, mpc8610_ids, NULL);
@@ -327,22 +327,6 @@ static int __init mpc86xx_hpcd_probe(void)
return 0;
}
-static long __init mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
define_machine(mpc86xx_hpcd) {
.name = "MPC86xx HPCD",
.probe = mpc86xx_hpcd_probe,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 08efb57..53500db 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -17,5 +17,7 @@
extern void mpc86xx_smp_init(void);
extern void mpc86xx_init_irq(void);
+extern long mpc86xx_time_init(void);
+extern int mpc86xx_common_publish_devices(void);
#endif /* __MPC86XX_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 07ccb1b..e508481 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -110,33 +110,14 @@ static int __init mpc86xx_hpcn_probe(void)
return 0;
}
-static long __init
-mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
static const struct of_device_id of_bus_ids[] __initconst = {
- { .compatible = "simple-bus", },
{ .compatible = "fsl,srio", },
- { .compatible = "gianfar", },
- { .compatible = "fsl,mpc8641-pcie", },
{},
};
static int __init declare_of_platform_devices(void)
{
+ mpc86xx_common_publish_devices();
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 6810b71..2a9cf27 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -75,37 +75,7 @@ static int __init sbc8641_probe(void)
return 0;
}
-static long __init
-mpc86xx_time_init(void)
-{
- unsigned int temp;
-
- /* Set the time base to zero */
- mtspr(SPRN_TBWL, 0);
- mtspr(SPRN_TBWU, 0);
-
- temp = mfspr(SPRN_HID0);
- temp |= HID0_TBEN;
- mtspr(SPRN_HID0, temp);
- asm volatile("isync");
-
- return 0;
-}
-
-static const struct of_device_id of_bus_ids[] __initconst = {
- { .compatible = "simple-bus", },
- { .compatible = "gianfar", },
- { .compatible = "fsl,mpc8641-pcie", },
- {},
-};
-
-static int __init declare_of_platform_devices(void)
-{
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
-
- return 0;
-}
-machine_arch_initcall(sbc8641, declare_of_platform_devices);
+machine_arch_initcall(sbc8641, mpc86xx_common_publish_devices);
define_machine(sbc8641) {
.name = "SBC8641D",
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index b7f9c40..46a3533 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -272,17 +272,6 @@ config TAU_AVERAGE
If in doubt, say N here.
-config QUICC_ENGINE
- bool "Freescale QUICC Engine (QE) Support"
- depends on FSL_SOC && PPC32
- select PPC_LIB_RHEAP
- select CRC32
- help
- The QUICC Engine (QE) is a new generation of communications
- coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
- Selecting this option means that you wish to build a kernel
- for a machine with a QE coprocessor.
-
config QE_GPIO
bool "QE GPIO support"
depends on QUICC_ENGINE
@@ -295,7 +284,6 @@ config CPM2
bool "Enable support for the CPM2 (Communications Processor Module)"
depends on (FSL_SOC_BOOKE && PPC32) || 8260
select CPM
- select PPC_LIB_RHEAP
select PPC_PCI_CHOICE
select ARCH_REQUIRE_GPIOLIB
help
@@ -325,6 +313,7 @@ config FSL_ULI1575
config CPM
bool
+ select GENERIC_ALLOCATOR
config OF_RTC
bool
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index c140e94..142dff5 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -147,17 +147,6 @@ config 6xx
depends on PPC32 && PPC_BOOK3S
select PPC_HAVE_PMU_SUPPORT
-config TUNE_CELL
- bool "Optimize for Cell Broadband Engine"
- depends on PPC64 && PPC_BOOK3S
- help
- Cause the compiler to optimize for the PPE of the Cell Broadband
- Engine. This will make the code run considerably faster on Cell
- but somewhat slower on other machines. This option only changes
- the scheduling of instructions, not the selection of instructions
- itself, so the resulting kernel will keep running on all other
- machines.
-
# this is temp to handle compat with arch=ppc
config 8xx
bool
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index b0ac177..d9088f0 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -25,7 +25,7 @@ config PPC_CELL_NATIVE
config PPC_IBM_CELL_BLADE
bool "IBM Cell Blade"
- depends on PPC64 && PPC_BOOK3S
+ depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN
select PPC_CELL_NATIVE
select PPC_OF_PLATFORM_PCI
select PCI
@@ -33,11 +33,6 @@ config PPC_IBM_CELL_BLADE
select PPC_UDBG_16550
select UDBG_RTAS_CONSOLE
-config PPC_CELL_QPACE
- bool "IBM Cell - QPACE"
- depends on PPC64 && PPC_BOOK3S
- select PPC_CELL_COMMON
-
config AXON_MSI
bool
depends on PPC_IBM_CELL_BLADE && PCI_MSI
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 34699bd..0046430 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o
-obj-$(CONFIG_PPC_CELL_QPACE) += smp.o
endif
# needed only when building loadable spufs.ko
@@ -26,6 +25,3 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
spufs/
obj-$(CONFIG_AXON_MSI) += axon_msi.o
-
-# qpace setup
-obj-$(CONFIG_PPC_CELL_QPACE) += qpace_setup.o
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index e0e68a1..aed7714 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -327,7 +327,7 @@ static void axon_msi_shutdown(struct platform_device *device)
u32 tmp;
pr_devel("axon_msi: disabling %s\n",
- msic->irq_domain->of_node->full_name);
+ irq_domain_get_of_node(msic->irq_domain)->full_name);
tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c
deleted file mode 100644
index d328140..0000000
--- a/arch/powerpc/platforms/cell/qpace_setup.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * linux/arch/powerpc/platforms/cell/qpace_setup.c
- *
- * Copyright (C) 1995 Linus Torvalds
- * Adapted from 'alpha' version by Gary Thomas
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * Modified by PPC64 Team, IBM Corp
- * Modified by Cell Team, IBM Deutschland Entwicklung GmbH
- * Modified by Benjamin Krill <ben@codiert.org>, IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/console.h>
-#include <linux/of_platform.h>
-
-#include <asm/mmu.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/kexec.h>
-#include <asm/pgtable.h>
-#include <asm/prom.h>
-#include <asm/rtas.h>
-#include <asm/dma.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/cputable.h>
-#include <asm/irq.h>
-#include <asm/spu.h>
-#include <asm/spu_priv1.h>
-#include <asm/udbg.h>
-#include <asm/cell-regs.h>
-
-#include "interrupt.h"
-#include "pervasive.h"
-#include "ras.h"
-
-static void qpace_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *root;
- const char *model = "";
-
- root = of_find_node_by_path("/");
- if (root)
- model = of_get_property(root, "model", NULL);
- seq_printf(m, "machine\t\t: CHRP %s\n", model);
- of_node_put(root);
-}
-
-static void qpace_progress(char *s, unsigned short hex)
-{
- printk("*** %04x : %s\n", hex, s ? s : "");
-}
-
-static const struct of_device_id qpace_bus_ids[] __initconst = {
- { .type = "soc", },
- { .compatible = "soc", },
- { .type = "spider", },
- { .type = "axon", },
- { .type = "plb5", },
- { .type = "plb4", },
- { .type = "opb", },
- { .type = "ebc", },
- {},
-};
-
-static int __init qpace_publish_devices(void)
-{
- int node;
-
- /* Publish OF platform devices for southbridge IOs */
- of_platform_bus_probe(NULL, qpace_bus_ids, NULL);
-
- /* There is no device for the MIC memory controller, thus we create
- * a platform device for it to attach the EDAC driver to.
- */
- for_each_online_node(node) {
- if (cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(node)) == NULL)
- continue;
- platform_device_register_simple("cbe-mic", node, NULL, 0);
- }
-
- return 0;
-}
-machine_subsys_initcall(qpace, qpace_publish_devices);
-
-static void __init qpace_setup_arch(void)
-{
-#ifdef CONFIG_SPU_BASE
- spu_priv1_ops = &spu_priv1_mmio_ops;
- spu_management_ops = &spu_management_of_ops;
-#endif
-
- cbe_regs_init();
-
-#ifdef CONFIG_CBE_RAS
- cbe_ras_init();
-#endif
-
-#ifdef CONFIG_SMP
- smp_init_cell();
-#endif
-
- /* init to some ~sane value until calibrate_delay() runs */
- loops_per_jiffy = 50000000;
-
- cbe_pervasive_init();
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-}
-
-static int __init qpace_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "IBM,QPACE"))
- return 0;
-
- hpte_init_native();
- pm_power_off = rtas_power_off;
-
- return 1;
-}
-
-define_machine(qpace) {
- .name = "QPACE",
- .probe = qpace_probe,
- .setup_arch = qpace_setup_arch,
- .show_cpuinfo = qpace_show_cpuinfo,
- .restart = rtas_restart,
- .halt = rtas_halt,
- .get_boot_time = rtas_get_boot_time,
- .get_rtc_time = rtas_get_rtc_time,
- .set_rtc_time = rtas_set_rtc_time,
- .calibrate_decr = generic_calibrate_decr,
- .progress = qpace_progress,
- .init_IRQ = iic_init_IRQ,
-};
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 9d27de6..54ee574 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -231,20 +231,23 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
const u32 *imap, *tmp;
int imaplen, intsize, unit;
struct device_node *iic;
+ struct device_node *of_node;
+
+ of_node = irq_domain_get_of_node(pic->host);
/* First, we check whether we have a real "interrupts" in the device
* tree in case the device-tree is ever fixed
*/
- virq = irq_of_parse_and_map(pic->host->of_node, 0);
+ virq = irq_of_parse_and_map(of_node, 0);
if (virq)
return virq;
/* Now do the horrible hacks */
- tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
+ tmp = of_get_property(of_node, "#interrupt-cells", NULL);
if (tmp == NULL)
return NO_IRQ;
intsize = *tmp;
- imap = of_get_property(pic->host->of_node, "interrupt-map", &imaplen);
+ imap = of_get_property(of_node, "interrupt-map", &imaplen);
if (imap == NULL || imaplen < (intsize + 1))
return NO_IRQ;
iic = of_find_node_by_phandle(imap[intsize]);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 5038fd5..2936a00 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1799,9 +1799,9 @@ static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int data
struct inode *inode = file_inode(file);
int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (!err) {
- mutex_lock(&inode->i_mutex);
+ inode_lock(inode);
err = spufs_mfc_flush(file, NULL);
- mutex_unlock(&inode->i_mutex);
+ inode_unlock(inode);
}
return err;
}
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 11634fa..dfa8638 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -163,7 +163,7 @@ static void spufs_prune_dir(struct dentry *dir)
{
struct dentry *dentry, *tmp;
- mutex_lock(&d_inode(dir)->i_mutex);
+ inode_lock(d_inode(dir));
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
spin_lock(&dentry->d_lock);
if (simple_positive(dentry)) {
@@ -180,7 +180,7 @@ static void spufs_prune_dir(struct dentry *dir)
}
}
shrink_dcache_parent(dir);
- mutex_unlock(&d_inode(dir)->i_mutex);
+ inode_unlock(d_inode(dir));
}
/* Caller must hold parent->i_mutex */
@@ -225,9 +225,9 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
parent = d_inode(dir->d_parent);
ctx = SPUFS_I(d_inode(dir))->i_ctx;
- mutex_lock_nested(&parent->i_mutex, I_MUTEX_PARENT);
+ inode_lock_nested(parent, I_MUTEX_PARENT);
ret = spufs_rmdir(parent, dir);
- mutex_unlock(&parent->i_mutex);
+ inode_unlock(parent);
WARN_ON(ret);
return dcache_dir_close(inode, file);
@@ -270,7 +270,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
- mutex_lock(&inode->i_mutex);
+ inode_lock(inode);
dget(dentry);
inc_nlink(dir);
@@ -291,7 +291,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
if (ret)
spufs_rmdir(dir, dentry);
- mutex_unlock(&inode->i_mutex);
+ inode_unlock(inode);
return ret;
}
@@ -767,7 +767,7 @@ static int __init spufs_init(void)
ret = -ENOMEM;
spufs_inode_cache = kmem_cache_create("spufs_inode_cache",
sizeof(struct spufs_inode_info), 0,
- SLAB_HWCACHE_ALIGN, spufs_init_once);
+ SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, spufs_init_once);
if (!spufs_inode_cache)
goto out;
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 4ddf769..9f79004 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -326,7 +326,7 @@ static int spu_process_callback(struct spu_context *ctx)
spu_ret = -ENOSYS;
npc += 4;
- if (s.nr_ret < __NR_syscalls) {
+ if (s.nr_ret < NR_syscalls) {
spu_release(ctx);
/* do actual system call from here */
spu_ret = spu_sys_callback(&s);
diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h
index b290b63..5ad1202 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc10x.h
+++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h
@@ -24,13 +24,11 @@
* Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff
* Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff
* PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000
- * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*
* MAP B (CHRP Map)
* Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
* Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
* PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
- * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*/
/*
@@ -138,14 +136,6 @@
#define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */
#define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */
-/*
- * Define some recommended places to put the EUMB regs.
- * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff.
- */
-extern unsigned long ioremap_base;
-#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE)
-#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE
-
enum ppc_sys_devices {
MPC10X_IIC1,
MPC10X_DMA0,
diff --git a/arch/powerpc/platforms/maple/Kconfig b/arch/powerpc/platforms/maple/Kconfig
index 1ea621a..e359d0d 100644
--- a/arch/powerpc/platforms/maple/Kconfig
+++ b/arch/powerpc/platforms/maple/Kconfig
@@ -1,5 +1,5 @@
config PPC_MAPLE
- depends on PPC64 && PPC_BOOK3S
+ depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN
bool "Maple 970FX Evaluation Board"
select PCI
select MPIC
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index b4a369d..81799d7 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -77,7 +77,7 @@ void maple_get_rtc_time(struct rtc_time *tm)
if ((tm->tm_year + 1900) < 1970)
tm->tm_year += 100;
- GregorianDay(tm);
+ tm->tm_wday = -1;
}
int maple_set_rtc_time(struct rtc_time *tm)
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index a2aeb32..00d4b28 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -1,5 +1,5 @@
config PPC_PASEMI
- depends on PPC64 && PPC_BOOK3S
+ depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN
bool "PA Semi SoC-based platforms"
default n
select MPIC
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index ae3f47b..ddf6350 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -41,7 +41,6 @@ static void __iomem *gpio_regs;
struct gpio_priv {
int mdc_pin;
int mdio_pin;
- int mdio_irqs[PHY_MAX_ADDR];
};
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
@@ -245,8 +244,6 @@ static int gpio_mdio_probe(struct platform_device *ofdev)
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
new_bus->priv = priv;
- new_bus->irq = priv->mdio_irqs;
-
prop = of_get_property(np, "mdc-pin", NULL);
priv->mdc_pin = *prop;
diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c
index b304a9f..d9af763 100644
--- a/arch/powerpc/platforms/pasemi/msi.c
+++ b/arch/powerpc/platforms/pasemi/msi.c
@@ -144,9 +144,11 @@ int mpic_pasemi_msi_init(struct mpic *mpic)
{
int rc;
struct pci_controller *phb;
+ struct device_node *of_node;
- if (!mpic->irqhost->of_node ||
- !of_device_is_compatible(mpic->irqhost->of_node,
+ of_node = irq_domain_get_of_node(mpic->irqhost);
+ if (!of_node ||
+ !of_device_is_compatible(of_node,
"pasemi,pwrficient-openpic"))
return -ENODEV;
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 607124b..43c6062 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -1,6 +1,6 @@
config PPC_PMAC
bool "Apple PowerMac based machines"
- depends on PPC_BOOK3S
+ depends on PPC_BOOK3S && CPU_BIG_ENDIAN
select MPIC
select PCI
select PPC_INDIRECT_PCI if PPC32
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 52c6ce1..1eb7b45 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPIC
ifdef CONFIG_FUNCTION_TRACER
# Do not trace early boot code
-CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog
+CFLAGS_REMOVE_bootx_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
endif
obj-y += pic.o setup.o time.o feature.o pci.o \
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index 76f5013..c3c9bbb 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -84,6 +84,7 @@ static void __init bootx_printf(const char *format, ...)
break;
}
}
+ va_end(args);
}
#else /* CONFIG_BOOTX_TEXT */
static void __init bootx_printf(const char *format, ...) {}
diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S
index 6be1a4a..cc5347e 100644
--- a/arch/powerpc/platforms/powermac/cache.S
+++ b/arch/powerpc/platforms/powermac/cache.S
@@ -23,7 +23,7 @@
* when going to sleep, when doing a PMU based cpufreq transition,
* or when "offlining" a CPU on SMP machines. This code is over
* paranoid, but I've had enough issues with various CPU revs and
- * bugs that I decided it was worth beeing over cautious
+ * bugs that I decided it was worth being over cautious
*/
_GLOBAL(flush_disable_caches)
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 4882bfd..1e02328 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -198,7 +198,7 @@ static long ohare_htw_scc_enable(struct device_node *node, long param,
if (htw) {
/* Side effect: this will also power up the
* modem, but it's too messy to figure out on which
- * ports this controls the tranceiver and on which
+ * ports this controls the transceiver and on which
* it controls the modem
*/
if (trans)
@@ -463,7 +463,7 @@ static long heathrow_sound_enable(struct device_node *node, long param,
unsigned long flags;
/* B&W G3 and Yikes don't support that properly (the
- * sound appear to never come back after beeing shut down).
+ * sound appear to never come back after being shut down).
*/
if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
pmac_mb.model_id == PMAC_TYPE_YIKES)
@@ -2770,7 +2770,7 @@ set_initial_features(void)
* but I'm not too sure it was audited for side-effects on other
* ohare based machines...
* Since I still have difficulties figuring the right way to
- * differenciate them all and since that hack was there for a long
+ * differentiate them all and since that hack was there for a long
* time, I'll keep it around
*/
if (macio_chips[0].type == macio_ohare) {
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 6f4f8b0..9815463 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -258,13 +258,14 @@ static unsigned int pmac_pic_get_irq(void)
#ifdef CONFIG_XMON
static struct irqaction xmon_action = {
.handler = xmon_irq,
- .flags = 0,
+ .flags = IRQF_NO_THREAD,
.name = "NMI - XMON"
};
#endif
static struct irqaction gatwick_cascade_action = {
.handler = gatwick_action,
+ .flags = IRQF_NO_THREAD,
.name = "cascade",
};
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 1c8cdb6..cd9711e 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -2,9 +2,10 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o
obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
+obj-y += opal-kmsg.o
obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
-obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
+obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o
obj-$(CONFIG_EEH) += eeh-powernv.o
obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 3bb6acb..950b3e5 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -43,19 +43,13 @@
static bool pnv_eeh_nb_init = false;
static int eeh_event_irq = -EINVAL;
-/**
- * pnv_eeh_init - EEH platform dependent initialization
- *
- * EEH platform dependent initialization on powernv
- */
static int pnv_eeh_init(void)
{
struct pci_controller *hose;
struct pnv_phb *phb;
- /* We require OPALv3 */
- if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
- pr_warn("%s: OPALv3 is required !\n",
+ if (!firmware_has_feature(FW_FEATURE_OPAL)) {
+ pr_warn("%s: OPAL is required !\n",
__func__);
return -EINVAL;
}
@@ -77,9 +71,9 @@ static int pnv_eeh_init(void)
/*
* PE#0 should be regarded as valid by EEH core
* if it's not the reserved one. Currently, we
- * have the reserved PE#0 and PE#127 for PHB3
+ * have the reserved PE#255 and PE#127 for PHB3
* and P7IOC separately. So we should regard
- * PE#0 as valid for P7IOC.
+ * PE#0 as valid for PHB3 and P7IOC.
*/
if (phb->ioda.reserved_pe != 0)
eeh_add_flag(EEH_VALID_PE_ZERO);
@@ -173,42 +167,26 @@ static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val)
return 0;
}
-static int pnv_eeh_outb_dbgfs_set(void *data, u64 val)
-{
- return pnv_eeh_dbgfs_set(data, 0xD10, val);
-}
-
-static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val)
-{
- return pnv_eeh_dbgfs_get(data, 0xD10, val);
-}
+#define PNV_EEH_DBGFS_ENTRY(name, reg) \
+static int pnv_eeh_dbgfs_set_##name(void *data, u64 val) \
+{ \
+ return pnv_eeh_dbgfs_set(data, reg, val); \
+} \
+ \
+static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val) \
+{ \
+ return pnv_eeh_dbgfs_get(data, reg, val); \
+} \
+ \
+DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name, \
+ pnv_eeh_dbgfs_get_##name, \
+ pnv_eeh_dbgfs_set_##name, \
+ "0x%llx\n")
+
+PNV_EEH_DBGFS_ENTRY(outb, 0xD10);
+PNV_EEH_DBGFS_ENTRY(inbA, 0xD90);
+PNV_EEH_DBGFS_ENTRY(inbB, 0xE10);
-static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val)
-{
- return pnv_eeh_dbgfs_set(data, 0xD90, val);
-}
-
-static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val)
-{
- return pnv_eeh_dbgfs_get(data, 0xD90, val);
-}
-
-static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val)
-{
- return pnv_eeh_dbgfs_set(data, 0xE10, val);
-}
-
-static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val)
-{
- return pnv_eeh_dbgfs_get(data, 0xE10, val);
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get,
- pnv_eeh_outb_dbgfs_set, "0x%llx\n");
-DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get,
- pnv_eeh_inbA_dbgfs_set, "0x%llx\n");
-DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get,
- pnv_eeh_inbB_dbgfs_set, "0x%llx\n");
#endif /* CONFIG_DEBUG_FS */
/**
@@ -274,43 +252,33 @@ static int pnv_eeh_post_init(void)
debugfs_create_file("err_injct_outbound", 0600,
phb->dbgfs, hose,
- &pnv_eeh_outb_dbgfs_ops);
+ &pnv_eeh_dbgfs_ops_outb);
debugfs_create_file("err_injct_inboundA", 0600,
phb->dbgfs, hose,
- &pnv_eeh_inbA_dbgfs_ops);
+ &pnv_eeh_dbgfs_ops_inbA);
debugfs_create_file("err_injct_inboundB", 0600,
phb->dbgfs, hose,
- &pnv_eeh_inbB_dbgfs_ops);
+ &pnv_eeh_dbgfs_ops_inbB);
#endif /* CONFIG_DEBUG_FS */
}
-
return ret;
}
-static int pnv_eeh_cap_start(struct pci_dn *pdn)
+static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
{
- u32 status;
+ int pos = PCI_CAPABILITY_LIST;
+ int cnt = 48; /* Maximal number of capabilities */
+ u32 status, id;
if (!pdn)
return 0;
+ /* Check if the device supports capabilities */
pnv_pci_cfg_read(pdn, PCI_STATUS, 2, &status);
if (!(status & PCI_STATUS_CAP_LIST))
return 0;
- return PCI_CAPABILITY_LIST;
-}
-
-static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
-{
- int pos = pnv_eeh_cap_start(pdn);
- int cnt = 48; /* Maximal number of capabilities */
- u32 id;
-
- if (!pos)
- return 0;
-
while (cnt--) {
pnv_pci_cfg_read(pdn, pos, 1, &pos);
if (pos < 0x40)
@@ -403,6 +371,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
edev->mode &= 0xFFFFFF00;
edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
+ edev->af_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF);
edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
edev->mode |= EEH_DEV_BRIDGE;
@@ -443,11 +412,14 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
* that PE to block its config space.
*
* Broadcom Austin 4-ports NICs (14e4:1657)
+ * Broadcom Shiner 4-ports 1G NICs (14e4:168a)
* Broadcom Shiner 2-ports 10G NICs (14e4:168e)
*/
if ((pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
pdn->device_id == 0x1657) ||
(pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
+ pdn->device_id == 0x168a) ||
+ (pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
pdn->device_id == 0x168e))
edev->pe->state |= EEH_PE_CFG_RESTRICTED;
@@ -457,9 +429,12 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
* PCI devices of the PE are expected to be removed prior
* to PE reset.
*/
- if (!edev->pe->bus)
+ if (!(edev->pe->state & EEH_PE_PRI_BUS)) {
edev->pe->bus = pci_find_bus(hose->global_number,
pdn->busno);
+ if (edev->pe->bus)
+ edev->pe->state |= EEH_PE_PRI_BUS;
+ }
/*
* Enable EEH explicitly so that we will do EEH check
@@ -487,10 +462,9 @@ static int pnv_eeh_set_option(struct eeh_pe *pe, int option)
struct pci_controller *hose = pe->phb;
struct pnv_phb *phb = hose->private_data;
bool freeze_pe = false;
- int opt, ret = 0;
+ int opt;
s64 rc;
- /* Sanity check on option */
switch (option) {
case EEH_OPT_DISABLE:
return -EPERM;
@@ -511,38 +485,37 @@ static int pnv_eeh_set_option(struct eeh_pe *pe, int option)
return -EINVAL;
}
- /* If PHB supports compound PE, to handle it */
+ /* Freeze master and slave PEs if PHB supports compound PEs */
if (freeze_pe) {
if (phb->freeze_pe) {
phb->freeze_pe(phb, pe->addr);
- } else {
- rc = opal_pci_eeh_freeze_set(phb->opal_id,
- pe->addr, opt);
- if (rc != OPAL_SUCCESS) {
- pr_warn("%s: Failure %lld freezing "
- "PHB#%x-PE#%x\n",
- __func__, rc,
- phb->hose->global_number, pe->addr);
- ret = -EIO;
- }
+ return 0;
}
- } else {
- if (phb->unfreeze_pe) {
- ret = phb->unfreeze_pe(phb, pe->addr, opt);
- } else {
- rc = opal_pci_eeh_freeze_clear(phb->opal_id,
- pe->addr, opt);
- if (rc != OPAL_SUCCESS) {
- pr_warn("%s: Failure %lld enable %d "
- "for PHB#%x-PE#%x\n",
- __func__, rc, option,
- phb->hose->global_number, pe->addr);
- ret = -EIO;
- }
+
+ rc = opal_pci_eeh_freeze_set(phb->opal_id, pe->addr, opt);
+ if (rc != OPAL_SUCCESS) {
+ pr_warn("%s: Failure %lld freezing PHB#%x-PE#%x\n",
+ __func__, rc, phb->hose->global_number,
+ pe->addr);
+ return -EIO;
}
+
+ return 0;
}
- return ret;
+ /* Unfreeze master and slave PEs if PHB supports */
+ if (phb->unfreeze_pe)
+ return phb->unfreeze_pe(phb, pe->addr, opt);
+
+ rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe->addr, opt);
+ if (rc != OPAL_SUCCESS) {
+ pr_warn("%s: Failure %lld enable %d for PHB#%x-PE#%x\n",
+ __func__, rc, option, phb->hose->global_number,
+ pe->addr);
+ return -EIO;
+ }
+
+ return 0;
}
/**
@@ -907,6 +880,120 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
}
}
+static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
+ int pos, u16 mask)
+{
+ struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+ int i, status = 0;
+
+ /* Wait for Transaction Pending bit to be cleared */
+ for (i = 0; i < 4; i++) {
+ eeh_ops->read_config(pdn, pos, 2, &status);
+ if (!(status & mask))
+ return;
+
+ msleep((1 << i) * 100);
+ }
+
+ pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n",
+ __func__, type,
+ edev->phb->global_number, pdn->busno,
+ PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
+}
+
+static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
+{
+ struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+ u32 reg = 0;
+
+ if (WARN_ON(!edev->pcie_cap))
+ return -ENOTTY;
+
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP, 4, &reg);
+ if (!(reg & PCI_EXP_DEVCAP_FLR))
+ return -ENOTTY;
+
+ switch (option) {
+ case EEH_RESET_HOT:
+ case EEH_RESET_FUNDAMENTAL:
+ pnv_eeh_wait_for_pending(pdn, "",
+ edev->pcie_cap + PCI_EXP_DEVSTA,
+ PCI_EXP_DEVSTA_TRPND);
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, &reg);
+ reg |= PCI_EXP_DEVCTL_BCR_FLR;
+ eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, reg);
+ msleep(EEH_PE_RST_HOLD_TIME);
+ break;
+ case EEH_RESET_DEACTIVATE:
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, &reg);
+ reg &= ~PCI_EXP_DEVCTL_BCR_FLR;
+ eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, reg);
+ msleep(EEH_PE_RST_SETTLE_TIME);
+ break;
+ }
+
+ return 0;
+}
+
+static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
+{
+ struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+ u32 cap = 0;
+
+ if (WARN_ON(!edev->af_cap))
+ return -ENOTTY;
+
+ eeh_ops->read_config(pdn, edev->af_cap + PCI_AF_CAP, 1, &cap);
+ if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
+ return -ENOTTY;
+
+ switch (option) {
+ case EEH_RESET_HOT:
+ case EEH_RESET_FUNDAMENTAL:
+ /*
+ * Wait for Transaction Pending bit to clear. A word-aligned
+ * test is used, so we use the conrol offset rather than status
+ * and shift the test bit to match.
+ */
+ pnv_eeh_wait_for_pending(pdn, "AF",
+ edev->af_cap + PCI_AF_CTRL,
+ PCI_AF_STATUS_TP << 8);
+ eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL,
+ 1, PCI_AF_CTRL_FLR);
+ msleep(EEH_PE_RST_HOLD_TIME);
+ break;
+ case EEH_RESET_DEACTIVATE:
+ eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, 1, 0);
+ msleep(EEH_PE_RST_SETTLE_TIME);
+ break;
+ }
+
+ return 0;
+}
+
+static int pnv_eeh_reset_vf_pe(struct eeh_pe *pe, int option)
+{
+ struct eeh_dev *edev;
+ struct pci_dn *pdn;
+ int ret;
+
+ /* The VF PE should have only one child device */
+ edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list);
+ pdn = eeh_dev_to_pdn(edev);
+ if (!pdn)
+ return -ENXIO;
+
+ ret = pnv_eeh_do_flr(pdn, option);
+ if (!ret)
+ return ret;
+
+ return pnv_eeh_do_af_flr(pdn, option);
+}
+
/**
* pnv_eeh_reset - Reset the specified PE
* @pe: EEH PE
@@ -968,7 +1055,9 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
}
bus = eeh_pe_bus_get(pe);
- if (pci_is_root_bus(bus) ||
+ if (pe->type & EEH_PE_VF)
+ ret = pnv_eeh_reset_vf_pe(pe, option);
+ else if (pci_is_root_bus(bus) ||
pci_is_root_bus(bus->parent))
ret = pnv_eeh_root_reset(hose, option);
else
@@ -1065,7 +1154,6 @@ static int pnv_eeh_err_inject(struct eeh_pe *pe, int type, int func,
struct pnv_phb *phb = hose->private_data;
s64 rc;
- /* Sanity check on error type */
if (type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR &&
type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64) {
pr_warn("%s: Invalid error type %d\n",
@@ -1108,6 +1196,14 @@ static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn)
if (!edev || !edev->pe)
return false;
+ /*
+ * We will issue FLR or AF FLR to all VFs, which are contained
+ * in VF PE. It relies on the EEH PCI config accessors. So we
+ * can't block them during the window.
+ */
+ if (edev->physfn && (edev->pe->state & EEH_PE_RESET))
+ return false;
+
if (edev->pe->state & EEH_PE_CFG_BLOCKED)
return true;
@@ -1492,6 +1588,65 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
return ret;
}
+static int pnv_eeh_restore_vf_config(struct pci_dn *pdn)
+{
+ struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+ u32 devctl, cmd, cap2, aer_capctl;
+ int old_mps;
+
+ if (edev->pcie_cap) {
+ /* Restore MPS */
+ old_mps = (ffs(pdn->mps) - 8) << 5;
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 2, &devctl);
+ devctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
+ devctl |= old_mps;
+ eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 2, devctl);
+
+ /* Disable Completion Timeout */
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
+ 4, &cap2);
+ if (cap2 & 0x10) {
+ eeh_ops->read_config(pdn,
+ edev->pcie_cap + PCI_EXP_DEVCTL2,
+ 4, &cap2);
+ cap2 |= 0x10;
+ eeh_ops->write_config(pdn,
+ edev->pcie_cap + PCI_EXP_DEVCTL2,
+ 4, cap2);
+ }
+ }
+
+ /* Enable SERR and parity checking */
+ eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd);
+ cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+ eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd);
+
+ /* Enable report various errors */
+ if (edev->pcie_cap) {
+ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 2, &devctl);
+ devctl &= ~PCI_EXP_DEVCTL_CERE;
+ devctl |= (PCI_EXP_DEVCTL_NFERE |
+ PCI_EXP_DEVCTL_FERE |
+ PCI_EXP_DEVCTL_URRE);
+ eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 2, devctl);
+ }
+
+ /* Enable ECRC generation and check */
+ if (edev->pcie_cap && edev->aer_cap) {
+ eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP,
+ 4, &aer_capctl);
+ aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
+ eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP,
+ 4, aer_capctl);
+ }
+
+ return 0;
+}
+
static int pnv_eeh_restore_config(struct pci_dn *pdn)
{
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
@@ -1501,9 +1656,21 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn)
if (!edev)
return -EEXIST;
- phb = edev->phb->private_data;
- ret = opal_pci_reinit(phb->opal_id,
- OPAL_REINIT_PCI_DEV, edev->config_addr);
+ /*
+ * We have to restore the PCI config space after reset since the
+ * firmware can't see SRIOV VFs.
+ *
+ * FIXME: The MPS, error routing rules, timeout setting are worthy
+ * to be exported by firmware in extendible way.
+ */
+ if (edev->physfn) {
+ ret = pnv_eeh_restore_vf_config(pdn);
+ } else {
+ phb = edev->phb->private_data;
+ ret = opal_pci_reinit(phb->opal_id,
+ OPAL_REINIT_PCI_DEV, edev->config_addr);
+ }
+
if (ret) {
pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
__func__, edev->config_addr, ret);
@@ -1532,6 +1699,40 @@ static struct eeh_ops pnv_eeh_ops = {
.restore_config = pnv_eeh_restore_config
};
+void pcibios_bus_add_device(struct pci_dev *pdev)
+{
+ struct pci_dn *pdn = pci_get_pdn(pdev);
+
+ if (!pdev->is_virtfn)
+ return;
+
+ /*
+ * The following operations will fail if VF's sysfs files
+ * aren't created or its resources aren't finalized.
+ */
+ eeh_add_device_early(pdn);
+ eeh_add_device_late(pdev);
+ eeh_sysfs_add_device(pdev);
+}
+
+#ifdef CONFIG_PCI_IOV
+static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev)
+{
+ struct pci_dn *pdn = pci_get_pdn(pdev);
+ int parent_mps;
+
+ if (!pdev->is_virtfn)
+ return;
+
+ /* Synchronize MPS for VF and PF */
+ parent_mps = pcie_get_mps(pdev->physfn);
+ if ((128 << pdev->pcie_mpss) >= parent_mps)
+ pcie_set_mps(pdev, parent_mps);
+ pdn->mps = pcie_get_mps(pdev);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_pci_fixup_vf_mps);
+#endif /* CONFIG_PCI_IOV */
+
/**
* eeh_powernv_init - Register platform dependent EEH operations
*
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 59d735d..fcc8b68 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -35,9 +35,9 @@ int pnv_save_sprs_for_winkle(void)
int rc;
/*
- * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric accross
+ * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across
* all cpus at boot. Get these reg values of current cpu and use the
- * same accross all cpus.
+ * same across all cpus.
*/
uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1;
uint64_t hid0_val = mfspr(SPRN_HID0);
@@ -185,7 +185,7 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev,
* fastsleep workaround needs to be left in 'applied' state on all
* the cores. Do this by-
* 1. Patching out the call to 'undo' workaround in fastsleep exit path
- * 2. Sending ipi to all the cores which have atleast one online thread
+ * 2. Sending ipi to all the cores which have at least one online thread
* 3. Patching out the call to 'apply' workaround in fastsleep entry
* path
* There is no need to send ipi to cores which have all threads
@@ -242,7 +242,7 @@ static int __init pnv_init_idle_states(void)
if (cpuidle_disable != IDLE_NO_OVERRIDE)
goto out;
- if (!firmware_has_feature(FW_FEATURE_OPALv3))
+ if (!firmware_has_feature(FW_FEATURE_OPAL))
goto out;
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
new file mode 100644
index 0000000..7229acd
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -0,0 +1,348 @@
+/*
+ * This file implements the DMA operations for NVLink devices. The NPU
+ * devices all point to the same iommu table as the parent PCI device.
+ *
+ * Copyright Alistair Popple, IBM Corporation 2015.
+ *
+ * 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/export.h>
+#include <linux/pci.h>
+#include <linux/memblock.h>
+
+#include <asm/iommu.h>
+#include <asm/pnv-pci.h>
+#include <asm/msi_bitmap.h>
+#include <asm/opal.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/*
+ * Other types of TCE cache invalidation are not functional in the
+ * hardware.
+ */
+#define TCE_KILL_INVAL_ALL PPC_BIT(0)
+
+static struct pci_dev *get_pci_dev(struct device_node *dn)
+{
+ return PCI_DN(dn)->pcidev;
+}
+
+/* Given a NPU device get the associated PCI device. */
+struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev)
+{
+ struct device_node *dn;
+ struct pci_dev *gpdev;
+
+ /* Get assoicated PCI device */
+ dn = of_parse_phandle(npdev->dev.of_node, "ibm,gpu", 0);
+ if (!dn)
+ return NULL;
+
+ gpdev = get_pci_dev(dn);
+ of_node_put(dn);
+
+ return gpdev;
+}
+EXPORT_SYMBOL(pnv_pci_get_gpu_dev);
+
+/* Given the real PCI device get a linked NPU device. */
+struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
+{
+ struct device_node *dn;
+ struct pci_dev *npdev;
+
+ /* Get assoicated PCI device */
+ dn = of_parse_phandle(gpdev->dev.of_node, "ibm,npu", index);
+ if (!dn)
+ return NULL;
+
+ npdev = get_pci_dev(dn);
+ of_node_put(dn);
+
+ return npdev;
+}
+EXPORT_SYMBOL(pnv_pci_get_npu_dev);
+
+#define NPU_DMA_OP_UNSUPPORTED() \
+ dev_err_once(dev, "%s operation unsupported for NVLink devices\n", \
+ __func__)
+
+static void *dma_npu_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag,
+ struct dma_attrs *attrs)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+ return NULL;
+}
+
+static void dma_npu_free(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle,
+ struct dma_attrs *attrs)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+}
+
+static dma_addr_t dma_npu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+ return 0;
+}
+
+static int dma_npu_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+ return 0;
+}
+
+static int dma_npu_dma_supported(struct device *dev, u64 mask)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+ return 0;
+}
+
+static u64 dma_npu_get_required_mask(struct device *dev)
+{
+ NPU_DMA_OP_UNSUPPORTED();
+ return 0;
+}
+
+struct dma_map_ops dma_npu_ops = {
+ .map_page = dma_npu_map_page,
+ .map_sg = dma_npu_map_sg,
+ .alloc = dma_npu_alloc,
+ .free = dma_npu_free,
+ .dma_supported = dma_npu_dma_supported,
+ .get_required_mask = dma_npu_get_required_mask,
+};
+
+/*
+ * Returns the PE assoicated with the PCI device of the given
+ * NPU. Returns the linked pci device if pci_dev != NULL.
+ */
+static struct pnv_ioda_pe *get_gpu_pci_dev_and_pe(struct pnv_ioda_pe *npe,
+ struct pci_dev **gpdev)
+{
+ struct pnv_phb *phb;
+ struct pci_controller *hose;
+ struct pci_dev *pdev;
+ struct pnv_ioda_pe *pe;
+ struct pci_dn *pdn;
+
+ if (npe->flags & PNV_IODA_PE_PEER) {
+ pe = npe->peers[0];
+ pdev = pe->pdev;
+ } else {
+ pdev = pnv_pci_get_gpu_dev(npe->pdev);
+ if (!pdev)
+ return NULL;
+
+ pdn = pci_get_pdn(pdev);
+ if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
+ return NULL;
+
+ hose = pci_bus_to_host(pdev->bus);
+ phb = hose->private_data;
+ pe = &phb->ioda.pe_array[pdn->pe_number];
+ }
+
+ if (gpdev)
+ *gpdev = pdev;
+
+ return pe;
+}
+
+void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe)
+{
+ struct pnv_phb *phb = npe->phb;
+
+ if (WARN_ON(phb->type != PNV_PHB_NPU ||
+ !phb->ioda.tce_inval_reg ||
+ !(npe->flags & PNV_IODA_PE_DEV)))
+ return;
+
+ mb(); /* Ensure previous TCE table stores are visible */
+ __raw_writeq(cpu_to_be64(TCE_KILL_INVAL_ALL),
+ phb->ioda.tce_inval_reg);
+}
+
+void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe,
+ struct iommu_table *tbl,
+ unsigned long index,
+ unsigned long npages,
+ bool rm)
+{
+ struct pnv_phb *phb = npe->phb;
+
+ /* We can only invalidate the whole cache on NPU */
+ unsigned long val = TCE_KILL_INVAL_ALL;
+
+ if (WARN_ON(phb->type != PNV_PHB_NPU ||
+ !phb->ioda.tce_inval_reg ||
+ !(npe->flags & PNV_IODA_PE_DEV)))
+ return;
+
+ mb(); /* Ensure previous TCE table stores are visible */
+ if (rm)
+ __raw_rm_writeq(cpu_to_be64(val),
+ (__be64 __iomem *) phb->ioda.tce_inval_reg_phys);
+ else
+ __raw_writeq(cpu_to_be64(val),
+ phb->ioda.tce_inval_reg);
+}
+
+void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe)
+{
+ struct pnv_ioda_pe *gpe;
+ struct pci_dev *gpdev;
+ int i, avail = -1;
+
+ if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV))
+ return;
+
+ gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+ if (!gpe)
+ return;
+
+ for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+ /* Nothing to do if the PE is already connected. */
+ if (gpe->peers[i] == npe)
+ return;
+
+ if (!gpe->peers[i])
+ avail = i;
+ }
+
+ if (WARN_ON(avail < 0))
+ return;
+
+ gpe->peers[avail] = npe;
+ gpe->flags |= PNV_IODA_PE_PEER;
+
+ /*
+ * We assume that the NPU devices only have a single peer PE
+ * (the GPU PCIe device PE).
+ */
+ npe->peers[0] = gpe;
+ npe->flags |= PNV_IODA_PE_PEER;
+}
+
+/*
+ * For the NPU we want to point the TCE table at the same table as the
+ * real PCI device.
+ */
+static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe)
+{
+ struct pnv_phb *phb = npe->phb;
+ struct pci_dev *gpdev;
+ struct pnv_ioda_pe *gpe;
+ void *addr;
+ unsigned int size;
+ int64_t rc;
+
+ /*
+ * Find the assoicated PCI devices and get the dma window
+ * information from there.
+ */
+ if (!npe->pdev || !(npe->flags & PNV_IODA_PE_DEV))
+ return;
+
+ gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+ if (!gpe)
+ return;
+
+ addr = (void *)gpe->table_group.tables[0]->it_base;
+ size = gpe->table_group.tables[0]->it_size << 3;
+ rc = opal_pci_map_pe_dma_window(phb->opal_id, npe->pe_number,
+ npe->pe_number, 1, __pa(addr),
+ size, 0x1000);
+ if (rc != OPAL_SUCCESS)
+ pr_warn("%s: Error %lld setting DMA window on PHB#%d-PE#%d\n",
+ __func__, rc, phb->hose->global_number, npe->pe_number);
+
+ /*
+ * We don't initialise npu_pe->tce32_table as we always use
+ * dma_npu_ops which are nops.
+ */
+ set_dma_ops(&npe->pdev->dev, &dma_npu_ops);
+}
+
+/*
+ * Enable/disable bypass mode on the NPU. The NPU only supports one
+ * window per link, so bypass needs to be explicitly enabled or
+ * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be
+ * active at the same time.
+ */
+int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enable)
+{
+ struct pnv_phb *phb = npe->phb;
+ int64_t rc = 0;
+
+ if (phb->type != PNV_PHB_NPU || !npe->pdev)
+ return -EINVAL;
+
+ if (enable) {
+ /* Enable the bypass window */
+ phys_addr_t top = memblock_end_of_DRAM();
+
+ npe->tce_bypass_base = 0;
+ top = roundup_pow_of_two(top);
+ dev_info(&npe->pdev->dev, "Enabling bypass for PE %d\n",
+ npe->pe_number);
+ rc = opal_pci_map_pe_dma_window_real(phb->opal_id,
+ npe->pe_number, npe->pe_number,
+ npe->tce_bypass_base, top);
+ } else {
+ /*
+ * Disable the bypass window by replacing it with the
+ * TCE32 window.
+ */
+ pnv_npu_disable_bypass(npe);
+ }
+
+ return rc;
+}
+
+int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask)
+{
+ struct pci_controller *hose = pci_bus_to_host(npdev->bus);
+ struct pnv_phb *phb = hose->private_data;
+ struct pci_dn *pdn = pci_get_pdn(npdev);
+ struct pnv_ioda_pe *npe, *gpe;
+ struct pci_dev *gpdev;
+ uint64_t top;
+ bool bypass = false;
+
+ if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
+ return -ENXIO;
+
+ /* We only do bypass if it's enabled on the linked device */
+ npe = &phb->ioda.pe_array[pdn->pe_number];
+ gpe = get_gpu_pci_dev_and_pe(npe, &gpdev);
+ if (!gpe)
+ return -ENODEV;
+
+ if (gpe->tce_bypass_enabled) {
+ top = gpe->tce_bypass_base + memblock_end_of_DRAM() - 1;
+ bypass = (dma_mask >= top);
+ }
+
+ if (bypass)
+ dev_info(&npdev->dev, "Using 64-bit DMA iommu bypass\n");
+ else
+ dev_info(&npdev->dev, "Using 32-bit DMA via iommu\n");
+
+ pnv_npu_dma_set_bypass(npe, bypass);
+ *npdev->dev.dma_mask = dma_mask;
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c
index 2c91ee7..e505223b 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -43,11 +43,34 @@ static unsigned int opal_irq_count;
static unsigned int *opal_irqs;
static void opal_handle_irq_work(struct irq_work *work);
-static __be64 last_outstanding_events;
+static u64 last_outstanding_events;
static struct irq_work opal_event_irq_work = {
.func = opal_handle_irq_work,
};
+void opal_handle_events(uint64_t events)
+{
+ int virq, hwirq = 0;
+ u64 mask = opal_event_irqchip.mask;
+
+ if (!in_irq() && (events & mask)) {
+ last_outstanding_events = events;
+ irq_work_queue(&opal_event_irq_work);
+ return;
+ }
+
+ while (events & mask) {
+ hwirq = fls64(events) - 1;
+ if (BIT_ULL(hwirq) & mask) {
+ virq = irq_find_mapping(opal_event_irqchip.domain,
+ hwirq);
+ if (virq)
+ generic_handle_irq(virq);
+ }
+ events &= ~BIT_ULL(hwirq);
+ }
+}
+
static void opal_event_mask(struct irq_data *d)
{
clear_bit(d->hwirq, &opal_event_irqchip.mask);
@@ -55,9 +78,21 @@ static void opal_event_mask(struct irq_data *d)
static void opal_event_unmask(struct irq_data *d)
{
+ __be64 events;
+
set_bit(d->hwirq, &opal_event_irqchip.mask);
- opal_poll_events(&last_outstanding_events);
+ opal_poll_events(&events);
+ last_outstanding_events = be64_to_cpu(events);
+
+ /*
+ * We can't just handle the events now with opal_handle_events().
+ * If we did we would deadlock when opal_event_unmask() is called from
+ * handle_level_irq() with the irq descriptor lock held, because
+ * calling opal_handle_events() would call generic_handle_irq() and
+ * then handle_level_irq() which would try to take the descriptor lock
+ * again. Instead queue the events for later.
+ */
if (last_outstanding_events & opal_event_irqchip.mask)
/* Need to retrigger the interrupt */
irq_work_queue(&opal_event_irq_work);
@@ -96,29 +131,6 @@ static int opal_event_map(struct irq_domain *d, unsigned int irq,
return 0;
}
-void opal_handle_events(uint64_t events)
-{
- int virq, hwirq = 0;
- u64 mask = opal_event_irqchip.mask;
-
- if (!in_irq() && (events & mask)) {
- last_outstanding_events = events;
- irq_work_queue(&opal_event_irq_work);
- return;
- }
-
- while (events & mask) {
- hwirq = fls64(events) - 1;
- if (BIT_ULL(hwirq) & mask) {
- virq = irq_find_mapping(opal_event_irqchip.domain,
- hwirq);
- if (virq)
- generic_handle_irq(virq);
- }
- events &= ~BIT_ULL(hwirq);
- }
-}
-
static irqreturn_t opal_interrupt(int irq, void *data)
{
__be64 events;
@@ -131,13 +143,13 @@ static irqreturn_t opal_interrupt(int irq, void *data)
static void opal_handle_irq_work(struct irq_work *work)
{
- opal_handle_events(be64_to_cpu(last_outstanding_events));
+ opal_handle_events(last_outstanding_events);
}
static int opal_event_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
- return h->of_node == node;
+ return irq_domain_get_of_node(h) == node;
}
static int opal_event_xlate(struct irq_domain *h, struct device_node *np,
diff --git a/arch/powerpc/platforms/powernv/opal-kmsg.c b/arch/powerpc/platforms/powernv/opal-kmsg.c
new file mode 100644
index 0000000..6f1214d
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-kmsg.c
@@ -0,0 +1,75 @@
+/*
+ * kmsg dumper that ensures the OPAL console fully flushes panic messages
+ *
+ * Author: Russell Currey <ruscur@russell.cc>
+ *
+ * Copyright 2015 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kmsg_dump.h>
+
+#include <asm/opal.h>
+#include <asm/opal-api.h>
+
+/*
+ * Console output is controlled by OPAL firmware. The kernel regularly calls
+ * OPAL_POLL_EVENTS, which flushes some console output. In a panic state,
+ * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message
+ * may not be completely printed. This function does not actually dump the
+ * message, it just ensures that OPAL completely flushes the console buffer.
+ */
+static void force_opal_console_flush(struct kmsg_dumper *dumper,
+ enum kmsg_dump_reason reason)
+{
+ int i;
+ int64_t ret;
+
+ /*
+ * Outside of a panic context the pollers will continue to run,
+ * so we don't need to do any special flushing.
+ */
+ if (reason != KMSG_DUMP_PANIC)
+ return;
+
+ if (opal_check_token(OPAL_CONSOLE_FLUSH)) {
+ ret = opal_console_flush(0);
+
+ if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER)
+ return;
+
+ /* Incrementally flush until there's nothing left */
+ while (opal_console_flush(0) != OPAL_SUCCESS);
+ } else {
+ /*
+ * If OPAL_CONSOLE_FLUSH is not implemented in the firmware,
+ * the console can still be flushed by calling the polling
+ * function enough times to flush the buffer. We don't know
+ * how much output still needs to be flushed, but we can be
+ * generous since the kernel is in panic and doesn't need
+ * to do much else.
+ */
+ printk(KERN_NOTICE "opal: OPAL_CONSOLE_FLUSH missing.\n");
+ for (i = 0; i < 1024; i++) {
+ opal_poll_events(NULL);
+ }
+ }
+}
+
+static struct kmsg_dumper opal_kmsg_dumper = {
+ .dump = force_opal_console_flush
+};
+
+void __init opal_kmsg_init(void)
+{
+ int rc;
+
+ /* Add our dumper to the list */
+ rc = kmsg_dump_register(&opal_kmsg_dumper);
+ if (rc != 0)
+ pr_err("opal: kmsg_dump_register failed; returned %d\n", rc);
+}
diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c
index 44ed78a..39d6ff9 100644
--- a/arch/powerpc/platforms/powernv/opal-msglog.c
+++ b/arch/powerpc/platforms/powernv/opal-msglog.c
@@ -31,26 +31,25 @@ struct memcons {
__be32 in_cons;
};
-static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *to,
- loff_t pos, size_t count)
+static struct memcons *opal_memcons = NULL;
+
+ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
{
- struct memcons *mc = bin_attr->private;
const char *conbuf;
ssize_t ret;
size_t first_read = 0;
uint32_t out_pos, avail;
- if (!mc)
+ if (!opal_memcons)
return -ENODEV;
- out_pos = be32_to_cpu(ACCESS_ONCE(mc->out_pos));
+ out_pos = be32_to_cpu(ACCESS_ONCE(opal_memcons->out_pos));
/* Now we've read out_pos, put a barrier in before reading the new
* data it points to in conbuf. */
smp_rmb();
- conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
+ conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys));
/* When the buffer has wrapped, read from the out_pos marker to the end
* of the buffer, and then read the remaining data as in the un-wrapped
@@ -58,7 +57,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
if (out_pos & MEMCONS_OUT_POS_WRAP) {
out_pos &= MEMCONS_OUT_POS_MASK;
- avail = be32_to_cpu(mc->obuf_size) - out_pos;
+ avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos;
ret = memory_read_from_buffer(to, count, &pos,
conbuf + out_pos, avail);
@@ -76,7 +75,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
}
/* Sanity check. The firmware should not do this to us. */
- if (out_pos > be32_to_cpu(mc->obuf_size)) {
+ if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) {
pr_err("OPAL: memory console corruption. Aborting read.\n");
return -EINVAL;
}
@@ -91,6 +90,13 @@ out:
return ret;
}
+static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *to,
+ loff_t pos, size_t count)
+{
+ return opal_msglog_copy(to, pos, count);
+}
+
static struct bin_attribute opal_msglog_attr = {
.attr = {.name = "msglog", .mode = 0444},
.read = opal_msglog_read
@@ -117,7 +123,15 @@ void __init opal_msglog_init(void)
return;
}
- opal_msglog_attr.private = mc;
+ opal_memcons = mc;
+}
+
+void __init opal_msglog_sysfs_init(void)
+{
+ if (!opal_memcons) {
+ pr_warn("OPAL: message log initialisation failed, not creating sysfs entry\n");
+ return;
+ }
if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0)
pr_warn("OPAL: sysfs file creation failed\n");
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c
index 4ece8e4..e315e70 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -434,7 +434,6 @@ static const struct of_device_id opal_prd_match[] = {
static struct platform_driver opal_prd_driver = {
.driver = {
.name = "opal-prd",
- .owner = THIS_MODULE,
.of_match_table = opal_prd_match,
},
.probe = opal_prd_probe,
diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c
index 37dbee1..f886886 100644
--- a/arch/powerpc/platforms/powernv/opal-rtc.c
+++ b/arch/powerpc/platforms/powernv/opal-rtc.c
@@ -31,8 +31,7 @@ static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm)
tm->tm_hour = bcd2bin((h_m_s_ms >> 56) & 0xff);
tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff);
tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff);
-
- GregorianDay(tm);
+ tm->tm_wday = -1;
}
unsigned long __init opal_get_boot_time(void)
@@ -51,7 +50,7 @@ unsigned long __init opal_get_boot_time(void)
rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
if (rc == OPAL_BUSY_EVENT)
opal_poll_events(NULL);
- else
+ else if (rc == OPAL_BUSY)
mdelay(10);
}
if (rc != OPAL_SUCCESS)
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index b7a464f..e45b88a 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -301,3 +301,4 @@ OPAL_CALL(opal_flash_erase, OPAL_FLASH_ERASE);
OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG);
OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR);
OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR);
+OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH);
diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c
index 7634d1c..d0ac535 100644
--- a/arch/powerpc/platforms/powernv/opal-xscom.c
+++ b/arch/powerpc/platforms/powernv/opal-xscom.c
@@ -126,7 +126,7 @@ static const struct scom_controller opal_scom_controller = {
static int opal_xscom_init(void)
{
- if (firmware_has_feature(FW_FEATURE_OPALv3))
+ if (firmware_has_feature(FW_FEATURE_OPAL))
scom_init(&opal_scom_controller);
return 0;
}
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 4296d55..0256d07 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -98,16 +98,11 @@ int __init early_init_dt_scan_opal(unsigned long node,
pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
opal.size, sizep, runtimesz);
- powerpc_firmware_features |= FW_FEATURE_OPAL;
if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
- powerpc_firmware_features |= FW_FEATURE_OPALv2;
- powerpc_firmware_features |= FW_FEATURE_OPALv3;
- pr_info("OPAL V3 detected !\n");
- } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
- powerpc_firmware_features |= FW_FEATURE_OPALv2;
- pr_info("OPAL V2 detected !\n");
+ powerpc_firmware_features |= FW_FEATURE_OPAL;
+ pr_info("OPAL detected !\n");
} else {
- pr_info("OPAL V1 detected !\n");
+ panic("OPAL != V3 detected, no longer supported.\n");
}
/* Reinit all cores with the right endian */
@@ -278,7 +273,7 @@ static void opal_handle_message(void)
/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
- pr_warning("%s: Unknown message type: %u\n", __func__, type);
+ pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
opal_message_do_notify(type, (void *)&msg);
@@ -352,17 +347,15 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
* enough room and be done with it
*/
spin_lock_irqsave(&opal_write_lock, flags);
- if (firmware_has_feature(FW_FEATURE_OPALv2)) {
- rc = opal_console_write_buffer_space(vtermno, &olen);
- len = be64_to_cpu(olen);
- if (rc || len < total_len) {
- spin_unlock_irqrestore(&opal_write_lock, flags);
- /* Closed -> drop characters */
- if (rc)
- return total_len;
- opal_poll_events(NULL);
- return -EAGAIN;
- }
+ rc = opal_console_write_buffer_space(vtermno, &olen);
+ len = be64_to_cpu(olen);
+ if (rc || len < total_len) {
+ spin_unlock_irqrestore(&opal_write_lock, flags);
+ /* Closed -> drop characters */
+ if (rc)
+ return total_len;
+ opal_poll_events(NULL);
+ return -EAGAIN;
}
/* We still try to handle partial completions, though they
@@ -555,7 +548,7 @@ bool opal_mce_check_early_recovery(struct pt_regs *regs)
goto out;
if ((regs->nip >= opal.base) &&
- (regs->nip <= (opal.base + opal.size)))
+ (regs->nip < (opal.base + opal.size)))
recover_addr = find_recovery_address(regs->nip);
/*
@@ -696,10 +689,7 @@ static int __init opal_init(void)
}
/* Register OPAL consoles if any ports */
- if (firmware_has_feature(FW_FEATURE_OPALv2))
- consoles = of_find_node_by_path("/ibm,opal/consoles");
- else
- consoles = of_node_get(opal_node);
+ consoles = of_find_node_by_path("/ibm,opal/consoles");
if (consoles) {
for_each_child_of_node(consoles, np) {
if (strcmp(np->name, "serial"))
@@ -734,6 +724,9 @@ static int __init opal_init(void)
of_node_put(leds);
}
+ /* Initialise OPAL message log interface */
+ opal_msglog_init();
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -749,8 +742,8 @@ static int __init opal_init(void)
opal_platform_dump_init();
/* Setup system parameters interface */
opal_sys_param_init();
- /* Setup message log interface. */
- opal_msglog_init();
+ /* Setup message log sysfs interface. */
+ opal_msglog_sysfs_init();
}
/* Initialize platform devices: IPMI backend, PRD & flash interface */
@@ -758,6 +751,9 @@ static int __init opal_init(void)
opal_pdev_init(opal_node, "ibm,opal-flash");
opal_pdev_init(opal_node, "ibm,opal-prd");
+ /* Initialise OPAL kmsg dumper for flushing console on panic */
+ opal_kmsg_init();
+
return 0;
}
machine_subsys_initcall(powernv, opal_init);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 414fd1a..c5baaf3 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -116,16 +116,6 @@ static int __init iommu_setup(char *str)
}
early_param("iommu", iommu_setup);
-/*
- * stdcix is only supposed to be used in hypervisor real mode as per
- * the architecture spec
- */
-static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
-{
- __asm__ __volatile__("stdcix %0,0,%1"
- : : "r" (val), "r" (paddr) : "memory");
-}
-
static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
{
return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) ==
@@ -344,7 +334,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
return;
}
- if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
+ if (!firmware_has_feature(FW_FEATURE_OPAL)) {
pr_info(" Firmware too old to support M64 window\n");
return;
}
@@ -357,6 +347,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
}
res = &hose->mem_resources[1];
+ res->name = dn->full_name;
res->start = of_translate_address(dn, r + 2);
res->end = res->start + of_read_number(r + 4, 2) - 1;
res->flags = (IORESOURCE_MEM | IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);
@@ -780,8 +771,12 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
return -ENXIO;
}
- /* Configure PELTV */
- pnv_ioda_set_peltv(phb, pe, true);
+ /*
+ * Configure PELTV. NPUs don't have a PELTV table so skip
+ * configuration on them.
+ */
+ if (phb->type != PNV_PHB_NPU)
+ pnv_ioda_set_peltv(phb, pe, true);
/* Setup reverse map */
for (rid = pe->rid; rid < rid_end; rid++)
@@ -877,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
/*
* The actual IOV BAR range is determined by the start address
* and the actual size for num_vfs VFs BAR. This check is to
@@ -908,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
res2 = *res;
res->start += size * offset;
@@ -924,7 +913,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)
}
#endif /* CONFIG_PCI_IOV */
-#if 0
static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
@@ -941,11 +929,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
if (pdn->pe_number != IODA_INVALID_PE)
return NULL;
- /* PE#0 has been pre-set */
- if (dev->bus->number == 0)
- pe_num = 0;
- else
- pe_num = pnv_ioda_alloc_pe(phb);
+ pe_num = pnv_ioda_alloc_pe(phb);
if (pe_num == IODA_INVALID_PE) {
pr_warning("%s: Not enough PE# available, disabling device\n",
pci_name(dev));
@@ -963,6 +947,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
pci_dev_get(dev);
pdn->pcidev = dev;
pdn->pe_number = pe_num;
+ pe->flags = PNV_IODA_PE_DEV;
pe->pdev = dev;
pe->pbus = NULL;
pe->tce32_seg = -1;
@@ -993,7 +978,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
return pe;
}
-#endif /* Useful for SRIOV case */
static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
{
@@ -1007,6 +991,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
pci_name(dev));
continue;
}
+ pdn->pcidev = dev;
pdn->pe_number = pe->pe_number;
pe->dma_weight += pnv_ioda_dma_weight(dev);
if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate)
@@ -1083,6 +1068,77 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)
pnv_ioda_link_pe_by_weight(phb, pe);
}
+static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev)
+{
+ int pe_num, found_pe = false, rc;
+ long rid;
+ struct pnv_ioda_pe *pe;
+ struct pci_dev *gpu_pdev;
+ struct pci_dn *npu_pdn;
+ struct pci_controller *hose = pci_bus_to_host(npu_pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
+
+ /*
+ * Due to a hardware errata PE#0 on the NPU is reserved for
+ * error handling. This means we only have three PEs remaining
+ * which need to be assigned to four links, implying some
+ * links must share PEs.
+ *
+ * To achieve this we assign PEs such that NPUs linking the
+ * same GPU get assigned the same PE.
+ */
+ gpu_pdev = pnv_pci_get_gpu_dev(npu_pdev);
+ for (pe_num = 0; pe_num < phb->ioda.total_pe; pe_num++) {
+ pe = &phb->ioda.pe_array[pe_num];
+ if (!pe->pdev)
+ continue;
+
+ if (pnv_pci_get_gpu_dev(pe->pdev) == gpu_pdev) {
+ /*
+ * This device has the same peer GPU so should
+ * be assigned the same PE as the existing
+ * peer NPU.
+ */
+ dev_info(&npu_pdev->dev,
+ "Associating to existing PE %d\n", pe_num);
+ pci_dev_get(npu_pdev);
+ npu_pdn = pci_get_pdn(npu_pdev);
+ rid = npu_pdev->bus->number << 8 | npu_pdn->devfn;
+ npu_pdn->pcidev = npu_pdev;
+ npu_pdn->pe_number = pe_num;
+ pe->dma_weight += pnv_ioda_dma_weight(npu_pdev);
+ phb->ioda.pe_rmap[rid] = pe->pe_number;
+
+ /* Map the PE to this link */
+ rc = opal_pci_set_pe(phb->opal_id, pe_num, rid,
+ OpalPciBusAll,
+ OPAL_COMPARE_RID_DEVICE_NUMBER,
+ OPAL_COMPARE_RID_FUNCTION_NUMBER,
+ OPAL_MAP_PE);
+ WARN_ON(rc != OPAL_SUCCESS);
+ found_pe = true;
+ break;
+ }
+ }
+
+ if (!found_pe)
+ /*
+ * Could not find an existing PE so allocate a new
+ * one.
+ */
+ return pnv_ioda_setup_dev_PE(npu_pdev);
+ else
+ return pe;
+}
+
+static void pnv_ioda_setup_npu_PEs(struct pci_bus *bus)
+{
+ struct pci_dev *pdev;
+
+ list_for_each_entry(pdev, &bus->devices, bus_list)
+ pnv_ioda_setup_npu_PE(pdev);
+}
+
static void pnv_ioda_setup_PEs(struct pci_bus *bus)
{
struct pci_dev *dev;
@@ -1119,34 +1175,51 @@ static void pnv_pci_ioda_setup_PEs(void)
if (phb->reserve_m64_pe)
phb->reserve_m64_pe(hose->bus, NULL, true);
- pnv_ioda_setup_PEs(hose->bus);
+ /*
+ * On NPU PHB, we expect separate PEs for individual PCI
+ * functions. PCI bus dependent PEs are required for the
+ * remaining types of PHBs.
+ */
+ if (phb->type == PNV_PHB_NPU) {
+ /* PE#0 is needed for error reporting */
+ pnv_ioda_reserve_pe(phb, 0);
+ pnv_ioda_setup_npu_PEs(hose->bus);
+ } else
+ pnv_ioda_setup_PEs(hose->bus);
}
}
#ifdef CONFIG_PCI_IOV
-static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
+static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs)
{
struct pci_bus *bus;
struct pci_controller *hose;
struct pnv_phb *phb;
struct pci_dn *pdn;
int i, j;
+ int m64_bars;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
phb = hose->private_data;
pdn = pci_get_pdn(pdev);
+ if (pdn->m64_single_mode)
+ m64_bars = num_vfs;
+ else
+ m64_bars = 1;
+
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
- for (j = 0; j < M64_PER_IOV; j++) {
- if (pdn->m64_wins[i][j] == IODA_INVALID_M64)
+ for (j = 0; j < m64_bars; j++) {
+ if (pdn->m64_map[j][i] == IODA_INVALID_M64)
continue;
opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0);
- clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc);
- pdn->m64_wins[i][j] = IODA_INVALID_M64;
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0);
+ clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc);
+ pdn->m64_map[j][i] = IODA_INVALID_M64;
}
+ kfree(pdn->m64_map);
return 0;
}
@@ -1163,8 +1236,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
int total_vfs;
resource_size_t size, start;
int pe_num;
- int vf_groups;
- int vf_per_group;
+ int m64_bars;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1172,29 +1244,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
pdn = pci_get_pdn(pdev);
total_vfs = pci_sriov_get_totalvfs(pdev);
- /* Initialize the m64_wins to IODA_INVALID_M64 */
- for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
- for (j = 0; j < M64_PER_IOV; j++)
- pdn->m64_wins[i][j] = IODA_INVALID_M64;
+ if (pdn->m64_single_mode)
+ m64_bars = num_vfs;
+ else
+ m64_bars = 1;
+
+ pdn->m64_map = kmalloc(sizeof(*pdn->m64_map) * m64_bars, GFP_KERNEL);
+ if (!pdn->m64_map)
+ return -ENOMEM;
+ /* Initialize the m64_map to IODA_INVALID_M64 */
+ for (i = 0; i < m64_bars ; i++)
+ for (j = 0; j < PCI_SRIOV_NUM_BARS; j++)
+ pdn->m64_map[i][j] = IODA_INVALID_M64;
- if (pdn->m64_per_iov == M64_PER_IOV) {
- vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV;
- vf_per_group = (num_vfs <= M64_PER_IOV)? 1:
- roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
- } else {
- vf_groups = 1;
- vf_per_group = 1;
- }
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
if (!res->flags || !res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags))
- continue;
-
- for (j = 0; j < vf_groups; j++) {
+ for (j = 0; j < m64_bars; j++) {
do {
win = find_next_zero_bit(&phb->ioda.m64_bar_alloc,
phb->ioda.m64_bar_idx + 1, 0);
@@ -1203,12 +1272,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
goto m64_failed;
} while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc));
- pdn->m64_wins[i][j] = win;
+ pdn->m64_map[j][i] = win;
- if (pdn->m64_per_iov == M64_PER_IOV) {
+ if (pdn->m64_single_mode) {
size = pci_iov_resource_size(pdev,
PCI_IOV_RESOURCES + i);
- size = size * vf_per_group;
start = res->start + size * j;
} else {
size = resource_size(res);
@@ -1216,16 +1284,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
}
/* Map the M64 here */
- if (pdn->m64_per_iov == M64_PER_IOV) {
- pe_num = pdn->offset + j;
+ if (pdn->m64_single_mode) {
+ pe_num = pdn->pe_num_map[j];
rc = opal_pci_map_pe_mmio_window(phb->opal_id,
pe_num, OPAL_M64_WINDOW_TYPE,
- pdn->m64_wins[i][j], 0);
+ pdn->m64_map[j][i], 0);
}
rc = opal_pci_set_phb_mem_window(phb->opal_id,
OPAL_M64_WINDOW_TYPE,
- pdn->m64_wins[i][j],
+ pdn->m64_map[j][i],
start,
0, /* unused */
size);
@@ -1237,12 +1305,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
goto m64_failed;
}
- if (pdn->m64_per_iov == M64_PER_IOV)
+ if (pdn->m64_single_mode)
rc = opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2);
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2);
else
rc = opal_pci_phb_mmio_enable(phb->opal_id,
- OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1);
+ OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1);
if (rc != OPAL_SUCCESS) {
dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n",
@@ -1254,7 +1322,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs)
return 0;
m64_failed:
- pnv_pci_vf_release_m64(pdev);
+ pnv_pci_vf_release_m64(pdev, num_vfs);
return -EBUSY;
}
@@ -1281,15 +1349,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe
iommu_free_table(tbl, of_node_full_name(dev->dev.of_node));
}
-static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
+static void pnv_ioda_release_vf_PE(struct pci_dev *pdev)
{
struct pci_bus *bus;
struct pci_controller *hose;
struct pnv_phb *phb;
struct pnv_ioda_pe *pe, *pe_n;
struct pci_dn *pdn;
- u16 vf_index;
- int64_t rc;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1299,35 +1365,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs)
if (!pdev->is_physfn)
return;
- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
- int vf_group;
- int vf_per_group;
- int vf_index1;
-
- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
-
- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++)
- for (vf_index = vf_group * vf_per_group;
- vf_index < (vf_group + 1) * vf_per_group &&
- vf_index < num_vfs;
- vf_index++)
- for (vf_index1 = vf_group * vf_per_group;
- vf_index1 < (vf_group + 1) * vf_per_group &&
- vf_index1 < num_vfs;
- vf_index1++){
-
- rc = opal_pci_set_peltv(phb->opal_id,
- pdn->offset + vf_index,
- pdn->offset + vf_index1,
- OPAL_REMOVE_PE_FROM_DOMAIN);
-
- if (rc)
- dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n",
- __func__,
- pdn->offset + vf_index1, rc);
- }
- }
-
list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) {
if (pe->parent_dev != pdev)
continue;
@@ -1352,7 +1389,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
struct pnv_phb *phb;
struct pci_dn *pdn;
struct pci_sriov *iov;
- u16 num_vfs;
+ u16 num_vfs, i;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1362,18 +1399,25 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
num_vfs = pdn->num_vfs;
/* Release VF PEs */
- pnv_ioda_release_vf_PE(pdev, num_vfs);
+ pnv_ioda_release_vf_PE(pdev);
if (phb->type == PNV_PHB_IODA2) {
- if (pdn->m64_per_iov == 1)
- pnv_pci_vf_resource_shift(pdev, -pdn->offset);
+ if (!pdn->m64_single_mode)
+ pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map);
/* Release M64 windows */
- pnv_pci_vf_release_m64(pdev);
+ pnv_pci_vf_release_m64(pdev, num_vfs);
/* Release PE numbers */
- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
- pdn->offset = 0;
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++) {
+ if (pdn->pe_num_map[i] != IODA_INVALID_PE)
+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
+ }
+ } else
+ bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
+ /* Releasing pe_num_map */
+ kfree(pdn->pe_num_map);
}
}
@@ -1388,7 +1432,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
int pe_num;
u16 vf_index;
struct pci_dn *pdn;
- int64_t rc;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1400,7 +1443,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
/* Reserve PE for each VF */
for (vf_index = 0; vf_index < num_vfs; vf_index++) {
- pe_num = pdn->offset + vf_index;
+ if (pdn->m64_single_mode)
+ pe_num = pdn->pe_num_map[vf_index];
+ else
+ pe_num = *pdn->pe_num_map + vf_index;
pe = &phb->ioda.pe_array[pe_num];
pe->pe_number = pe_num;
@@ -1433,37 +1479,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
pnv_pci_ioda2_setup_dma_pe(phb, pe);
}
-
- if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) {
- int vf_group;
- int vf_per_group;
- int vf_index1;
-
- vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
-
- for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) {
- for (vf_index = vf_group * vf_per_group;
- vf_index < (vf_group + 1) * vf_per_group &&
- vf_index < num_vfs;
- vf_index++) {
- for (vf_index1 = vf_group * vf_per_group;
- vf_index1 < (vf_group + 1) * vf_per_group &&
- vf_index1 < num_vfs;
- vf_index1++) {
-
- rc = opal_pci_set_peltv(phb->opal_id,
- pdn->offset + vf_index,
- pdn->offset + vf_index1,
- OPAL_ADD_PE_TO_DOMAIN);
-
- if (rc)
- dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n",
- __func__,
- pdn->offset + vf_index1, rc);
- }
- }
- }
- }
}
int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
@@ -1473,6 +1488,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
struct pnv_phb *phb;
struct pci_dn *pdn;
int ret;
+ u16 i;
bus = pdev->bus;
hose = pci_bus_to_host(bus);
@@ -1480,20 +1496,59 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
pdn = pci_get_pdn(pdev);
if (phb->type == PNV_PHB_IODA2) {
+ if (!pdn->vfs_expanded) {
+ dev_info(&pdev->dev, "don't support this SRIOV device"
+ " with non 64bit-prefetchable IOV BAR\n");
+ return -ENOSPC;
+ }
+
+ /*
+ * When M64 BARs functions in Single PE mode, the number of VFs
+ * could be enabled must be less than the number of M64 BARs.
+ */
+ if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) {
+ dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n");
+ return -EBUSY;
+ }
+
+ /* Allocating pe_num_map */
+ if (pdn->m64_single_mode)
+ pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map) * num_vfs,
+ GFP_KERNEL);
+ else
+ pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL);
+
+ if (!pdn->pe_num_map)
+ return -ENOMEM;
+
+ if (pdn->m64_single_mode)
+ for (i = 0; i < num_vfs; i++)
+ pdn->pe_num_map[i] = IODA_INVALID_PE;
+
/* Calculate available PE for required VFs */
- mutex_lock(&phb->ioda.pe_alloc_mutex);
- pdn->offset = bitmap_find_next_zero_area(
- phb->ioda.pe_alloc, phb->ioda.total_pe,
- 0, num_vfs, 0);
- if (pdn->offset >= phb->ioda.total_pe) {
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++) {
+ pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb);
+ if (pdn->pe_num_map[i] == IODA_INVALID_PE) {
+ ret = -EBUSY;
+ goto m64_failed;
+ }
+ }
+ } else {
+ mutex_lock(&phb->ioda.pe_alloc_mutex);
+ *pdn->pe_num_map = bitmap_find_next_zero_area(
+ phb->ioda.pe_alloc, phb->ioda.total_pe,
+ 0, num_vfs, 0);
+ if (*pdn->pe_num_map >= phb->ioda.total_pe) {
+ mutex_unlock(&phb->ioda.pe_alloc_mutex);
+ dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
+ kfree(pdn->pe_num_map);
+ return -EBUSY;
+ }
+ bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
mutex_unlock(&phb->ioda.pe_alloc_mutex);
- dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs);
- pdn->offset = 0;
- return -EBUSY;
}
- bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs);
pdn->num_vfs = num_vfs;
- mutex_unlock(&phb->ioda.pe_alloc_mutex);
/* Assign M64 window accordingly */
ret = pnv_pci_vf_assign_m64(pdev, num_vfs);
@@ -1507,8 +1562,8 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
* the IOV BAR according to the PE# allocated to the VFs.
* Otherwise, the PE# for the VF will conflict with others.
*/
- if (pdn->m64_per_iov == 1) {
- ret = pnv_pci_vf_resource_shift(pdev, pdn->offset);
+ if (!pdn->m64_single_mode) {
+ ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map);
if (ret)
goto m64_failed;
}
@@ -1520,8 +1575,16 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
return 0;
m64_failed:
- bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs);
- pdn->offset = 0;
+ if (pdn->m64_single_mode) {
+ for (i = 0; i < num_vfs; i++) {
+ if (pdn->pe_num_map[i] != IODA_INVALID_PE)
+ pnv_ioda_free_pe(phb, pdn->pe_num_map[i]);
+ }
+ } else
+ bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs);
+
+ /* Releasing pe_num_map */
+ kfree(pdn->pe_num_map);
return ret;
}
@@ -1540,8 +1603,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
/* Allocate PCI data */
add_dev_pci_data(pdev);
- pnv_pci_sriov_enable(pdev, num_vfs);
- return 0;
+ return pnv_pci_sriov_enable(pdev, num_vfs);
}
#endif /* CONFIG_PCI_IOV */
@@ -1578,6 +1640,8 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
struct pnv_ioda_pe *pe;
uint64_t top;
bool bypass = false;
+ struct pci_dev *linked_npu_dev;
+ int i;
if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
return -ENODEV;;
@@ -1596,6 +1660,18 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
set_dma_ops(&pdev->dev, &dma_iommu_ops);
}
*pdev->dev.dma_mask = dma_mask;
+
+ /* Update peer npu devices */
+ if (pe->flags & PNV_IODA_PE_PEER)
+ for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+ if (!pe->peers[i])
+ continue;
+
+ linked_npu_dev = pe->peers[i]->pdev;
+ if (dma_get_mask(&linked_npu_dev->dev) != dma_mask)
+ dma_set_mask(&linked_npu_dev->dev, dma_mask);
+ }
+
return 0;
}
@@ -1740,12 +1816,23 @@ static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe)
/* 01xb - invalidate TCEs that match the specified PE# */
unsigned long val = (0x4ull << 60) | (pe->pe_number & 0xFF);
struct pnv_phb *phb = pe->phb;
+ struct pnv_ioda_pe *npe;
+ int i;
if (!phb->ioda.tce_inval_reg)
return;
mb(); /* Ensure above stores are visible */
__raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg);
+
+ if (pe->flags & PNV_IODA_PE_PEER)
+ for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+ npe = pe->peers[i];
+ if (!npe || npe->phb->type != PNV_PHB_NPU)
+ continue;
+
+ pnv_npu_tce_invalidate_entire(npe);
+ }
}
static void pnv_pci_ioda2_do_tce_invalidate(unsigned pe_number, bool rm,
@@ -1780,15 +1867,28 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl,
struct iommu_table_group_link *tgl;
list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) {
+ struct pnv_ioda_pe *npe;
struct pnv_ioda_pe *pe = container_of(tgl->table_group,
struct pnv_ioda_pe, table_group);
__be64 __iomem *invalidate = rm ?
(__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys :
pe->phb->ioda.tce_inval_reg;
+ int i;
pnv_pci_ioda2_do_tce_invalidate(pe->pe_number, rm,
invalidate, tbl->it_page_shift,
index, npages);
+
+ if (pe->flags & PNV_IODA_PE_PEER)
+ /* Invalidate PEs using the same TCE table */
+ for (i = 0; i < PNV_IODA_MAX_PEER_PES; i++) {
+ npe = pe->peers[i];
+ if (!npe || npe->phb->type != PNV_PHB_NPU)
+ continue;
+
+ pnv_npu_tce_invalidate(npe, tbl, index,
+ npages, rm);
+ }
}
}
@@ -2436,10 +2536,17 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n",
pe->dma_weight, segs);
pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
- } else {
+ } else if (phb->type == PNV_PHB_IODA2) {
pe_info(pe, "Assign DMA32 space\n");
segs = 0;
pnv_pci_ioda2_setup_dma_pe(phb, pe);
+ } else if (phb->type == PNV_PHB_NPU) {
+ /*
+ * We initialise the DMA space for an NPU PHB
+ * after setup of the PHB is complete as we
+ * point the NPU TVT to the the same location
+ * as the PHB3 TVT.
+ */
}
remaining -= segs;
@@ -2734,45 +2841,58 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
#ifdef CONFIG_PCI_IOV
static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
{
- struct pci_controller *hose;
- struct pnv_phb *phb;
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
+ const resource_size_t gate = phb->ioda.m64_segsize >> 2;
struct resource *res;
int i;
- resource_size_t size;
+ resource_size_t size, total_vf_bar_sz;
struct pci_dn *pdn;
int mul, total_vfs;
if (!pdev->is_physfn || pdev->is_added)
return;
- hose = pci_bus_to_host(pdev->bus);
- phb = hose->private_data;
-
pdn = pci_get_pdn(pdev);
pdn->vfs_expanded = 0;
+ pdn->m64_single_mode = false;
total_vfs = pci_sriov_get_totalvfs(pdev);
- pdn->m64_per_iov = 1;
mul = phb->ioda.total_pe;
+ total_vf_bar_sz = 0;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
if (!res->flags || res->parent)
continue;
if (!pnv_pci_is_mem_pref_64(res->flags)) {
- dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n",
+ dev_warn(&pdev->dev, "Don't support SR-IOV with"
+ " non M64 VF BAR%d: %pR. \n",
i, res);
- continue;
+ goto truncate_iov;
}
- size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
+ total_vf_bar_sz += pci_iov_resource_size(pdev,
+ i + PCI_IOV_RESOURCES);
- /* bigger than 64M */
- if (size > (1 << 26)) {
- dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
- i, res);
- pdn->m64_per_iov = M64_PER_IOV;
+ /*
+ * If bigger than quarter of M64 segment size, just round up
+ * power of two.
+ *
+ * Generally, one M64 BAR maps one IOV BAR. To avoid conflict
+ * with other devices, IOV BAR size is expanded to be
+ * (total_pe * VF_BAR_size). When VF_BAR_size is half of M64
+ * segment size , the expanded size would equal to half of the
+ * whole M64 space size, which will exhaust the M64 Space and
+ * limit the system flexibility. This is a design decision to
+ * set the boundary to quarter of the M64 segment size.
+ */
+ if (total_vf_bar_sz > gate) {
mul = roundup_pow_of_two(total_vfs);
+ dev_info(&pdev->dev,
+ "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n",
+ total_vf_bar_sz, gate, mul);
+ pdn->m64_single_mode = true;
break;
}
}
@@ -2781,20 +2901,31 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
res = &pdev->resource[i + PCI_IOV_RESOURCES];
if (!res->flags || res->parent)
continue;
- if (!pnv_pci_is_mem_pref_64(res->flags)) {
- dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n",
- i, res);
- continue;
- }
- dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
+ /*
+ * On PHB3, the minimum size alignment of M64 BAR in single
+ * mode is 32MB.
+ */
+ if (pdn->m64_single_mode && (size < SZ_32M))
+ goto truncate_iov;
+ dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
res->end = res->start + size * mul - 1;
dev_dbg(&pdev->dev, " %pR\n", res);
dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
i, res, mul);
}
pdn->vfs_expanded = mul;
+
+ return;
+
+truncate_iov:
+ /* To save MMIO space, IOV BAR is truncated. */
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = &pdev->resource[i + PCI_IOV_RESOURCES];
+ res->flags = 0;
+ res->end = res->start - 1;
+ }
}
#endif /* CONFIG_PCI_IOV */
@@ -2881,6 +3012,11 @@ static void pnv_pci_ioda_setup_seg(void)
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
phb = hose->private_data;
+
+ /* NPU PHB does not support IO or MMIO segmentation */
+ if (phb->type == PNV_PHB_NPU)
+ continue;
+
list_for_each_entry(pe, &phb->ioda.pe_list, list) {
pnv_ioda_setup_pe_seg(hose, pe);
}
@@ -2920,6 +3056,27 @@ static void pnv_pci_ioda_create_dbgfs(void)
#endif /* CONFIG_DEBUG_FS */
}
+static void pnv_npu_ioda_fixup(void)
+{
+ bool enable_bypass;
+ struct pci_controller *hose, *tmp;
+ struct pnv_phb *phb;
+ struct pnv_ioda_pe *pe;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ phb = hose->private_data;
+ if (phb->type != PNV_PHB_NPU)
+ continue;
+
+ list_for_each_entry(pe, &phb->ioda.pe_dma_list, dma_link) {
+ enable_bypass = dma_get_mask(&pe->pdev->dev) ==
+ DMA_BIT_MASK(64);
+ pnv_npu_init_dma_pe(pe);
+ pnv_npu_dma_set_bypass(pe, enable_bypass);
+ }
+ }
+}
+
static void pnv_pci_ioda_fixup(void)
{
pnv_pci_ioda_setup_PEs();
@@ -2932,6 +3089,9 @@ static void pnv_pci_ioda_fixup(void)
eeh_init();
eeh_addr_cache_build();
#endif
+
+ /* Link NPU IODA tables to their PCI devices. */
+ pnv_npu_ioda_fixup();
}
/*
@@ -2979,18 +3139,35 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
int resno)
{
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
struct pci_dn *pdn = pci_get_pdn(pdev);
- resource_size_t align, iov_align;
-
- iov_align = resource_size(&pdev->resource[resno]);
- if (iov_align)
- return iov_align;
+ resource_size_t align;
+ /*
+ * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
+ * SR-IOV. While from hardware perspective, the range mapped by M64
+ * BAR should be size aligned.
+ *
+ * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra
+ * powernv-specific hardware restriction is gone. But if just use the
+ * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with
+ * in one segment of M64 #15, which introduces the PE conflict between
+ * PF and VF. Based on this, the minimum alignment of an IOV BAR is
+ * m64_segsize.
+ *
+ * This function returns the total IOV BAR size if M64 BAR is in
+ * Shared PE mode or just VF BAR size if not.
+ * If the M64 BAR is in Single PE mode, return the VF BAR size or
+ * M64 segment size if IOV BAR size is less.
+ */
align = pci_iov_resource_size(pdev, resno);
- if (pdn->vfs_expanded)
- return pdn->vfs_expanded * align;
+ if (!pdn->vfs_expanded)
+ return align;
+ if (pdn->m64_single_mode)
+ return max(align, (resource_size_t)phb->ioda.m64_segsize);
- return align;
+ return pdn->vfs_expanded * align;
}
#endif /* CONFIG_PCI_IOV */
@@ -3034,6 +3211,7 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
.dma_dev_setup = pnv_pci_dma_dev_setup,
+ .dma_bus_setup = pnv_pci_dma_bus_setup,
#ifdef CONFIG_PCI_MSI
.setup_msi_irqs = pnv_setup_msi_irqs,
.teardown_msi_irqs = pnv_teardown_msi_irqs,
@@ -3046,6 +3224,19 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
.shutdown = pnv_pci_ioda_shutdown,
};
+static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
+ .dma_dev_setup = pnv_pci_dma_dev_setup,
+#ifdef CONFIG_PCI_MSI
+ .setup_msi_irqs = pnv_setup_msi_irqs,
+ .teardown_msi_irqs = pnv_teardown_msi_irqs,
+#endif
+ .enable_device_hook = pnv_pci_enable_device_hook,
+ .window_alignment = pnv_pci_window_alignment,
+ .reset_secondary_bus = pnv_pci_reset_secondary_bus,
+ .dma_set_mask = pnv_npu_dma_set_mask,
+ .shutdown = pnv_pci_ioda_shutdown,
+};
+
static void __init pnv_pci_init_ioda_phb(struct device_node *np,
u64 hub_id, int ioda_type)
{
@@ -3101,6 +3292,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
phb->model = PNV_PHB_MODEL_P7IOC;
else if (of_device_is_compatible(np, "ibm,power8-pciex"))
phb->model = PNV_PHB_MODEL_PHB3;
+ else if (of_device_is_compatible(np, "ibm,power8-npu-pciex"))
+ phb->model = PNV_PHB_MODEL_NPU;
else
phb->model = PNV_PHB_MODEL_UNKNOWN;
@@ -3201,7 +3394,11 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
* the child P2P bridges) can form individual PE.
*/
ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
- hose->controller_ops = pnv_pci_ioda_controller_ops;
+
+ if (phb->type == PNV_PHB_NPU)
+ hose->controller_ops = pnv_npu_ioda_controller_ops;
+ else
+ hose->controller_ops = pnv_pci_ioda_controller_ops;
#ifdef CONFIG_PCI_IOV
ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
@@ -3236,6 +3433,11 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np)
pnv_pci_init_ioda_phb(np, 0, PNV_PHB_IODA2);
}
+void __init pnv_pci_init_npu_phb(struct device_node *np)
+{
+ pnv_pci_init_ioda_phb(np, 0, PNV_PHB_NPU);
+}
+
void __init pnv_pci_init_ioda_hub(struct device_node *np)
{
struct device_node *phbn;
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
deleted file mode 100644
index f2bdfea..0000000
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Support PCI/PCIe on PowerNV platforms
- *
- * Currently supports only P5IOC2
- *
- * Copyright 2011 Benjamin Herrenschmidt, IBM 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/msi.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/msi_bitmap.h>
-#include <asm/ppc-pci.h>
-#include <asm/opal.h>
-#include <asm/iommu.h>
-#include <asm/tce.h>
-
-#include "powernv.h"
-#include "pci.h"
-
-/* For now, use a fixed amount of TCE memory for each p5ioc2
- * hub, 16M will do
- */
-#define P5IOC2_TCE_MEMORY 0x01000000
-
-#ifdef CONFIG_PCI_MSI
-static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
- unsigned int hwirq, unsigned int virq,
- unsigned int is_64, struct msi_msg *msg)
-{
- if (WARN_ON(!is_64))
- return -ENXIO;
- msg->data = hwirq - phb->msi_base;
- msg->address_hi = 0x10000000;
- msg->address_lo = 0;
-
- return 0;
-}
-
-static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
-{
- unsigned int count;
- const __be32 *prop = of_get_property(phb->hose->dn,
- "ibm,opal-msi-ranges", NULL);
- if (!prop)
- return;
-
- /* Don't do MSI's on p5ioc2 PCI-X are they are not properly
- * verified in HW
- */
- if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix"))
- return;
- phb->msi_base = be32_to_cpup(prop);
- count = be32_to_cpup(prop + 1);
- if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) {
- pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
- phb->hose->global_number);
- return;
- }
- phb->msi_setup = pnv_pci_p5ioc2_msi_setup;
- phb->msi32_support = 0;
- pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
- count, phb->msi_base);
-}
-#else
-static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { }
-#endif /* CONFIG_PCI_MSI */
-
-static struct iommu_table_ops pnv_p5ioc2_iommu_ops = {
- .set = pnv_tce_build,
-#ifdef CONFIG_IOMMU_API
- .exchange = pnv_tce_xchg,
-#endif
- .clear = pnv_tce_free,
- .get = pnv_tce_get,
-};
-
-static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
- struct pci_dev *pdev)
-{
- struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0];
-
- if (!tbl->it_map) {
- tbl->it_ops = &pnv_p5ioc2_iommu_ops;
- iommu_init_table(tbl, phb->hose->node);
- iommu_register_group(&phb->p5ioc2.table_group,
- pci_domain_nr(phb->hose->bus), phb->opal_id);
- INIT_LIST_HEAD_RCU(&tbl->it_group_list);
- pnv_pci_link_table_and_group(phb->hose->node, 0,
- tbl, &phb->p5ioc2.table_group);
- }
-
- set_iommu_table_base(&pdev->dev, tbl);
- iommu_add_device(&pdev->dev);
-}
-
-static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = {
- .dma_dev_setup = pnv_pci_dma_dev_setup,
-#ifdef CONFIG_PCI_MSI
- .setup_msi_irqs = pnv_setup_msi_irqs,
- .teardown_msi_irqs = pnv_teardown_msi_irqs,
-#endif
-};
-
-static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
- void *tce_mem, u64 tce_size)
-{
- struct pnv_phb *phb;
- const __be64 *prop64;
- u64 phb_id;
- int64_t rc;
- static int primary = 1;
- struct iommu_table_group *table_group;
- struct iommu_table *tbl;
-
- pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name);
-
- prop64 = of_get_property(np, "ibm,opal-phbid", NULL);
- if (!prop64) {
- pr_err(" Missing \"ibm,opal-phbid\" property !\n");
- return;
- }
- phb_id = be64_to_cpup(prop64);
- pr_devel(" PHB-ID : 0x%016llx\n", phb_id);
- pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem));
- pr_devel(" TCE SZ : 0x%016llx\n", tce_size);
-
- rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size);
- if (rc != OPAL_SUCCESS) {
- pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc);
- return;
- }
-
- phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0);
- phb->hose = pcibios_alloc_controller(np);
- if (!phb->hose) {
- pr_err(" Failed to allocate PCI controller\n");
- return;
- }
-
- spin_lock_init(&phb->lock);
- phb->hose->first_busno = 0;
- phb->hose->last_busno = 0xff;
- phb->hose->private_data = phb;
- phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops;
- phb->hub_id = hub_id;
- phb->opal_id = phb_id;
- phb->type = PNV_PHB_P5IOC2;
- phb->model = PNV_PHB_MODEL_P5IOC2;
-
- phb->regs = of_iomap(np, 0);
-
- if (phb->regs == NULL)
- pr_err(" Failed to map registers !\n");
- else {
- pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100));
- pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0));
- pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0));
- pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0));
- pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190));
- pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0));
- pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0));
- pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0));
- pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0));
- pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0));
- pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0));
- }
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(phb->hose, np, primary);
- primary = 0;
-
- phb->hose->ops = &pnv_pci_ops;
-
- /* Setup MSI support */
- pnv_pci_init_p5ioc2_msis(phb);
-
- /* Setup TCEs */
- phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup;
- pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table,
- tce_mem, tce_size, 0,
- IOMMU_PAGE_SHIFT_4K);
- /*
- * We do not allocate iommu_table as we do not support
- * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table()
- * should not be called for phb->p5ioc2.table_group.tables[0] ever.
- */
- tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table;
- table_group = &phb->p5ioc2.table_group;
- table_group->tce32_start = tbl->it_offset << tbl->it_page_shift;
- table_group->tce32_size = tbl->it_size << tbl->it_page_shift;
-}
-
-void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
-{
- struct device_node *phbn;
- const __be64 *prop64;
- u64 hub_id;
- void *tce_mem;
- uint64_t tce_per_phb;
- int64_t rc;
- int phb_count = 0;
-
- pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name);
-
- prop64 = of_get_property(np, "ibm,opal-hubid", NULL);
- if (!prop64) {
- pr_err(" Missing \"ibm,opal-hubid\" property !\n");
- return;
- }
- hub_id = be64_to_cpup(prop64);
- pr_info(" HUB-ID : 0x%016llx\n", hub_id);
-
- /* Count child PHBs and calculate TCE space per PHB */
- for_each_child_of_node(np, phbn) {
- if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
- of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
- phb_count++;
- }
-
- if (phb_count <= 0) {
- pr_info(" No PHBs for Hub %s\n", np->full_name);
- return;
- }
-
- tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
- pr_info(" Allocating %lld MB of TCE memory per PHB\n",
- tce_per_phb >> 20);
-
- /* Currently allocate 16M of TCE memory for every Hub
- *
- * XXX TODO: Make it chip local if possible
- */
- tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY);
- pr_debug(" TCE : 0x%016lx..0x%016lx\n",
- __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1);
- rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem),
- P5IOC2_TCE_MEMORY);
- if (rc != OPAL_SUCCESS) {
- pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc);
- return;
- }
-
- /* Initialize PHBs */
- for_each_child_of_node(np, phbn) {
- if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
- of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) {
- pnv_pci_init_p5ioc2_phb(phbn, hub_id,
- tce_mem, tce_per_phb);
- tce_mem += tce_per_phb;
- }
- }
-}
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index f2dd772..73c8dc2 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -1,8 +1,6 @@
/*
* Support PCI/PCIe on PowerNV platforms
*
- * Currently supports only P5IOC2
- *
* Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
*
* This program is free software; you can redistribute it and/or
@@ -382,10 +380,7 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn)
*/
pe_no = pdn->pe_number;
if (pe_no == IODA_INVALID_PE) {
- if (phb->type == PNV_PHB_P5IOC2)
- pe_no = 0;
- else
- pe_no = phb->ioda.reserved_pe;
+ pe_no = phb->ioda.reserved_pe;
}
/*
@@ -601,6 +596,9 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
u64 rpn = __pa(uaddr) >> tbl->it_page_shift;
long i;
+ if (proto_tce & TCE_PCI_WRITE)
+ proto_tce |= TCE_PCI_READ;
+
for (i = 0; i < npages; i++) {
unsigned long newtce = proto_tce |
((rpn + i) << tbl->it_page_shift);
@@ -622,6 +620,9 @@ int pnv_tce_xchg(struct iommu_table *tbl, long index,
BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
+ if (newtce & TCE_PCI_WRITE)
+ newtce |= TCE_PCI_READ;
+
oldtce = xchg(pnv_tce(tbl, idx), cpu_to_be64(newtce));
*hpa = be64_to_cpu(oldtce) & ~(TCE_PCI_READ | TCE_PCI_WRITE);
*direction = iommu_tce_direction(oldtce);
@@ -762,6 +763,26 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
phb->dma_dev_setup(phb, pdev);
}
+void pnv_pci_dma_bus_setup(struct pci_bus *bus)
+{
+ struct pci_controller *hose = bus->sysdata;
+ struct pnv_phb *phb = hose->private_data;
+ struct pnv_ioda_pe *pe;
+
+ list_for_each_entry(pe, &phb->ioda.pe_list, list) {
+ if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
+ continue;
+
+ if (!pe->pbus)
+ continue;
+
+ if (bus->number == ((pe->rid >> 8) & 0xFF)) {
+ pe->pbus = bus;
+ break;
+ }
+ }
+}
+
void pnv_pci_shutdown(void)
{
struct pci_controller *hose;
@@ -781,7 +802,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk);
void __init pnv_pci_init(void)
{
struct device_node *np;
- bool found_ioda = false;
pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN);
@@ -789,24 +809,19 @@ void __init pnv_pci_init(void)
if (!firmware_has_feature(FW_FEATURE_OPAL))
return;
- /* Look for IODA IO-Hubs. We don't support mixing IODA
- * and p5ioc2 due to the need to change some global
- * probing flags
- */
+ /* Look for IODA IO-Hubs. */
for_each_compatible_node(np, NULL, "ibm,ioda-hub") {
pnv_pci_init_ioda_hub(np);
- found_ioda = true;
}
- /* Look for p5ioc2 IO-Hubs */
- if (!found_ioda)
- for_each_compatible_node(np, NULL, "ibm,p5ioc2")
- pnv_pci_init_p5ioc2_hub(np);
-
/* Look for ioda2 built-in PHB3's */
for_each_compatible_node(np, NULL, "ibm,ioda2-phb")
pnv_pci_init_ioda2_phb(np);
+ /* Look for NPU PHBs */
+ for_each_compatible_node(np, NULL, "ibm,ioda2-npu-phb")
+ pnv_pci_init_npu_phb(np);
+
/* Setup the linkage between OF nodes and PHBs */
pci_devs_phb_init();
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index c8ff50e..3f814f3 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -4,17 +4,17 @@
struct pci_dn;
enum pnv_phb_type {
- PNV_PHB_P5IOC2 = 0,
- PNV_PHB_IODA1 = 1,
- PNV_PHB_IODA2 = 2,
+ PNV_PHB_IODA1 = 0,
+ PNV_PHB_IODA2 = 1,
+ PNV_PHB_NPU = 2,
};
/* Precise PHB model for error management */
enum pnv_phb_model {
PNV_PHB_MODEL_UNKNOWN,
- PNV_PHB_MODEL_P5IOC2,
PNV_PHB_MODEL_P7IOC,
PNV_PHB_MODEL_PHB3,
+ PNV_PHB_MODEL_NPU,
};
#define PNV_PCI_DIAG_BUF_SIZE 8192
@@ -24,6 +24,7 @@ enum pnv_phb_model {
#define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */
#define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */
#define PNV_IODA_PE_VF (1 << 5) /* PE for one VF */
+#define PNV_IODA_PE_PEER (1 << 6) /* PE has peers */
/* Data associated with a PE, including IOMMU tracking etc.. */
struct pnv_phb;
@@ -31,6 +32,9 @@ struct pnv_ioda_pe {
unsigned long flags;
struct pnv_phb *phb;
+#define PNV_IODA_MAX_PEER_PES 8
+ struct pnv_ioda_pe *peers[PNV_IODA_MAX_PEER_PES];
+
/* A PE can be associated with a single device or an
* entire bus (& children). In the former case, pdev
* is populated, in the later case, pbus is.
@@ -115,81 +119,74 @@ struct pnv_phb {
void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt);
- union {
- struct {
- struct iommu_table iommu_table;
- struct iommu_table_group table_group;
- } p5ioc2;
-
- struct {
- /* Global bridge info */
- unsigned int total_pe;
- unsigned int reserved_pe;
-
- /* 32-bit MMIO window */
- unsigned int m32_size;
- unsigned int m32_segsize;
- unsigned int m32_pci_base;
-
- /* 64-bit MMIO window */
- unsigned int m64_bar_idx;
- unsigned long m64_size;
- unsigned long m64_segsize;
- unsigned long m64_base;
- unsigned long m64_bar_alloc;
-
- /* IO ports */
- unsigned int io_size;
- unsigned int io_segsize;
- unsigned int io_pci_base;
-
- /* PE allocation bitmap */
- unsigned long *pe_alloc;
- /* PE allocation mutex */
- struct mutex pe_alloc_mutex;
-
- /* M32 & IO segment maps */
- unsigned int *m32_segmap;
- unsigned int *io_segmap;
- struct pnv_ioda_pe *pe_array;
-
- /* IRQ chip */
- int irq_chip_init;
- struct irq_chip irq_chip;
-
- /* Sorted list of used PE's based
- * on the sequence of creation
- */
- struct list_head pe_list;
- struct mutex pe_list_mutex;
-
- /* Reverse map of PEs, will have to extend if
- * we are to support more than 256 PEs, indexed
- * bus { bus, devfn }
- */
- unsigned char pe_rmap[0x10000];
-
- /* 32-bit TCE tables allocation */
- unsigned long tce32_count;
-
- /* Total "weight" for the sake of DMA resources
- * allocation
- */
- unsigned int dma_weight;
- unsigned int dma_pe_count;
-
- /* Sorted list of used PE's, sorted at
- * boot for resource allocation purposes
- */
- struct list_head pe_dma_list;
-
- /* TCE cache invalidate registers (physical and
- * remapped)
- */
- phys_addr_t tce_inval_reg_phys;
- __be64 __iomem *tce_inval_reg;
- } ioda;
- };
+ struct {
+ /* Global bridge info */
+ unsigned int total_pe;
+ unsigned int reserved_pe;
+
+ /* 32-bit MMIO window */
+ unsigned int m32_size;
+ unsigned int m32_segsize;
+ unsigned int m32_pci_base;
+
+ /* 64-bit MMIO window */
+ unsigned int m64_bar_idx;
+ unsigned long m64_size;
+ unsigned long m64_segsize;
+ unsigned long m64_base;
+ unsigned long m64_bar_alloc;
+
+ /* IO ports */
+ unsigned int io_size;
+ unsigned int io_segsize;
+ unsigned int io_pci_base;
+
+ /* PE allocation bitmap */
+ unsigned long *pe_alloc;
+ /* PE allocation mutex */
+ struct mutex pe_alloc_mutex;
+
+ /* M32 & IO segment maps */
+ unsigned int *m32_segmap;
+ unsigned int *io_segmap;
+ struct pnv_ioda_pe *pe_array;
+
+ /* IRQ chip */
+ int irq_chip_init;
+ struct irq_chip irq_chip;
+
+ /* Sorted list of used PE's based
+ * on the sequence of creation
+ */
+ struct list_head pe_list;
+ struct mutex pe_list_mutex;
+
+ /* Reverse map of PEs, will have to extend if
+ * we are to support more than 256 PEs, indexed
+ * bus { bus, devfn }
+ */
+ unsigned char pe_rmap[0x10000];
+
+ /* 32-bit TCE tables allocation */
+ unsigned long tce32_count;
+
+ /* Total "weight" for the sake of DMA resources
+ * allocation
+ */
+ unsigned int dma_weight;
+ unsigned int dma_pe_count;
+
+ /* Sorted list of used PE's, sorted at
+ * boot for resource allocation purposes
+ */
+ struct list_head pe_dma_list;
+
+ /* TCE cache invalidate registers (physical and
+ * remapped)
+ */
+ phys_addr_t tce_inval_reg_phys;
+ __be64 __iomem *tce_inval_reg;
+ } ioda;
/* PHB and hub status structure */
union {
@@ -226,16 +223,29 @@ extern void pnv_pci_unlink_table_and_group(struct iommu_table *tbl,
extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
void *tce_mem, u64 tce_size,
u64 dma_offset, unsigned page_shift);
-extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
extern void pnv_pci_init_ioda_hub(struct device_node *np);
extern void pnv_pci_init_ioda2_phb(struct device_node *np);
+extern void pnv_pci_init_npu_phb(struct device_node *np);
extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
__be64 *startp, __be64 *endp, bool rm);
extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
+extern void pnv_pci_dma_bus_setup(struct pci_bus *bus);
extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
+/* Nvlink functions */
+extern void pnv_npu_tce_invalidate_entire(struct pnv_ioda_pe *npe);
+extern void pnv_npu_tce_invalidate(struct pnv_ioda_pe *npe,
+ struct iommu_table *tbl,
+ unsigned long index,
+ unsigned long npages,
+ bool rm);
+extern void pnv_npu_init_dma_pe(struct pnv_ioda_pe *npe);
+extern void pnv_npu_setup_dma_pe(struct pnv_ioda_pe *npe);
+extern int pnv_npu_dma_set_bypass(struct pnv_ioda_pe *npe, bool enabled);
+extern int pnv_npu_dma_set_mask(struct pci_dev *npdev, u64 dma_mask);
+
#endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 685b3cb..1acb0c7 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -90,12 +90,8 @@ static void pnv_show_cpuinfo(struct seq_file *m)
if (root)
model = of_get_property(root, "model", NULL);
seq_printf(m, "machine\t\t: PowerNV %s\n", model);
- if (firmware_has_feature(FW_FEATURE_OPALv3))
- seq_printf(m, "firmware\t: OPAL v3\n");
- else if (firmware_has_feature(FW_FEATURE_OPALv2))
- seq_printf(m, "firmware\t: OPAL v2\n");
- else if (firmware_has_feature(FW_FEATURE_OPAL))
- seq_printf(m, "firmware\t: OPAL v1\n");
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ seq_printf(m, "firmware\t: OPAL\n");
else
seq_printf(m, "firmware\t: BML\n");
of_node_put(root);
@@ -187,7 +183,7 @@ static void pnv_kexec_wait_secondaries_down(void)
for_each_online_cpu(i) {
uint8_t status;
- int64_t rc;
+ int64_t rc, timeout = 1000;
if (i == my_cpu)
continue;
@@ -204,6 +200,18 @@ static void pnv_kexec_wait_secondaries_down(void)
i, paca[i].hw_cpu_id);
notified = i;
}
+
+ /*
+ * On crash secondaries might be unreachable or hung,
+ * so timeout if we've waited too long
+ * */
+ mdelay(1);
+ if (timeout-- == 0) {
+ printk(KERN_ERR "kexec: timed out waiting for "
+ "cpu %d (physical %d) to enter OPAL\n",
+ i, paca[i].hw_cpu_id);
+ break;
+ }
}
}
}
@@ -212,9 +220,9 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
{
xics_kexec_teardown_cpu(secondary);
- /* On OPAL v3, we return all CPUs to firmware */
+ /* On OPAL, we return all CPUs to firmware */
- if (!firmware_has_feature(FW_FEATURE_OPALv3))
+ if (!firmware_has_feature(FW_FEATURE_OPAL))
return;
if (secondary) {
@@ -225,13 +233,6 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
/* Return the CPU to OPAL */
opal_return_cpu();
- } else if (crash_shutdown) {
- /*
- * On crash, we don't wait for secondaries to go
- * down as they might be unreachable or hung, so
- * instead we just wait a bit and move on.
- */
- mdelay(1);
} else {
/* Primary waits for the secondaries to have reached OPAL */
pnv_kexec_wait_secondaries_down();
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index ca26483..ad7b1a3 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -61,14 +61,15 @@ static int pnv_smp_kick_cpu(int nr)
unsigned long start_here =
__pa(ppc_function_entry(generic_secondary_smp_init));
long rc;
+ uint8_t status;
BUG_ON(nr < 0 || nr >= NR_CPUS);
/*
- * If we already started or OPALv2 is not supported, we just
+ * If we already started or OPAL is not supported, we just
* kick the CPU via the PACA
*/
- if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2))
+ if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPAL))
goto kick;
/*
@@ -77,55 +78,42 @@ static int pnv_smp_kick_cpu(int nr)
* first time. OPAL v3 allows us to query OPAL to know if it
* has the CPUs, so we do that
*/
- if (firmware_has_feature(FW_FEATURE_OPALv3)) {
- uint8_t status;
-
- rc = opal_query_cpu_status(pcpu, &status);
- if (rc != OPAL_SUCCESS) {
- pr_warn("OPAL Error %ld querying CPU %d state\n",
- rc, nr);
- return -ENODEV;
- }
+ rc = opal_query_cpu_status(pcpu, &status);
+ if (rc != OPAL_SUCCESS) {
+ pr_warn("OPAL Error %ld querying CPU %d state\n", rc, nr);
+ return -ENODEV;
+ }
- /*
- * Already started, just kick it, probably coming from
- * kexec and spinning
- */
- if (status == OPAL_THREAD_STARTED)
- goto kick;
+ /*
+ * Already started, just kick it, probably coming from
+ * kexec and spinning
+ */
+ if (status == OPAL_THREAD_STARTED)
+ goto kick;
- /*
- * Available/inactive, let's kick it
- */
- if (status == OPAL_THREAD_INACTIVE) {
- pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n",
- nr, pcpu);
- rc = opal_start_cpu(pcpu, start_here);
- if (rc != OPAL_SUCCESS) {
- pr_warn("OPAL Error %ld starting CPU %d\n",
- rc, nr);
- return -ENODEV;
- }
- } else {
- /*
- * An unavailable CPU (or any other unknown status)
- * shouldn't be started. It should also
- * not be in the possible map but currently it can
- * happen
- */
- pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
- " (status %d)...\n", nr, pcpu, status);
+ /*
+ * Available/inactive, let's kick it
+ */
+ if (status == OPAL_THREAD_INACTIVE) {
+ pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
+ rc = opal_start_cpu(pcpu, start_here);
+ if (rc != OPAL_SUCCESS) {
+ pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr);
return -ENODEV;
}
} else {
/*
- * On OPAL v2, we just kick it and hope for the best,
- * we must not test the error from opal_start_cpu() or
- * we would fail to get CPUs from kexec.
+ * An unavailable CPU (or any other unknown status)
+ * shouldn't be started. It should also
+ * not be in the possible map but currently it can
+ * happen
*/
- opal_start_cpu(pcpu, start_here);
+ pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
+ " (status %d)...\n", nr, pcpu, status);
+ return -ENODEV;
}
- kick:
+
+kick:
return smp_generic_kick_cpu(nr);
}
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c
index 503a73f..0babef1 100644
--- a/arch/powerpc/platforms/powernv/subcore.c
+++ b/arch/powerpc/platforms/powernv/subcore.c
@@ -407,7 +407,7 @@ static DEVICE_ATTR(subcores_per_core, 0644,
static int subcore_init(void)
{
- if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+ if (!cpu_has_feature(CPU_FTR_SUBCORE))
return 0;
/*
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 56f2740..b27f40f 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -1,6 +1,6 @@
config PPC_PS3
bool "Sony PS3"
- depends on PPC64 && PPC_BOOK3S
+ depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN
select PPC_CELL
select USB_OHCI_LITTLE_ENDIAN
select USB_OHCI_BIG_ENDIAN_MMIO
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
index 20b46a1..09bf24d 100644
--- a/arch/powerpc/platforms/ps3/gelic_udbg.c
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -13,6 +13,12 @@
*
*/
+#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+
#include <asm/io.h>
#include <asm/udbg.h>
#include <asm/lv1call.h>
@@ -56,39 +62,8 @@ struct debug_block {
u8 pkt[1520];
} __packed;
-struct ethhdr {
- u8 dest[6];
- u8 src[6];
- u16 type;
-} __packed;
-
-struct vlantag {
- u16 vlan;
- u16 subtype;
-} __packed;
-
-struct iphdr {
- u8 ver_len;
- u8 dscp_ecn;
- u16 total_length;
- u16 ident;
- u16 frag_off_flags;
- u8 ttl;
- u8 proto;
- u16 checksum;
- u32 src;
- u32 dest;
-} __packed;
-
-struct udphdr {
- u16 src;
- u16 dest;
- u16 len;
- u16 checksum;
-} __packed;
-
static __iomem struct ethhdr *h_eth;
-static __iomem struct vlantag *h_vlan;
+static __iomem struct vlan_hdr *h_vlan;
static __iomem struct iphdr *h_ip;
static __iomem struct udphdr *h_udp;
@@ -173,8 +148,8 @@ static void gelic_debug_init(void)
h_eth = (struct ethhdr *)dbg.pkt;
- memset(&h_eth->dest, 0xff, 6);
- memcpy(&h_eth->src, &mac, 6);
+ eth_broadcast_addr(h_eth->h_dest);
+ memcpy(&h_eth->h_source, &mac, ETH_ALEN);
header_size = sizeof(struct ethhdr);
@@ -183,28 +158,29 @@ static void gelic_debug_init(void)
GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
&vlan_id, &v2);
if (!result) {
- h_eth->type = 0x8100;
+ h_eth->h_proto= ETH_P_8021Q;
- header_size += sizeof(struct vlantag);
- h_vlan = (struct vlantag *)(h_eth + 1);
- h_vlan->vlan = vlan_id;
- h_vlan->subtype = 0x0800;
+ header_size += sizeof(struct vlan_hdr);
+ h_vlan = (struct vlan_hdr *)(h_eth + 1);
+ h_vlan->h_vlan_TCI = vlan_id;
+ h_vlan->h_vlan_encapsulated_proto = ETH_P_IP;
h_ip = (struct iphdr *)(h_vlan + 1);
} else {
- h_eth->type = 0x0800;
+ h_eth->h_proto= 0x0800;
h_ip = (struct iphdr *)(h_eth + 1);
}
header_size += sizeof(struct iphdr);
- h_ip->ver_len = 0x45;
+ h_ip->version = 4;
+ h_ip->ihl = 5;
h_ip->ttl = 10;
- h_ip->proto = 0x11;
- h_ip->src = 0x00000000;
- h_ip->dest = 0xffffffff;
+ h_ip->protocol = 0x11;
+ h_ip->saddr = 0x00000000;
+ h_ip->daddr = 0xffffffff;
header_size += sizeof(struct udphdr);
h_udp = (struct udphdr *)(h_ip + 1);
- h_udp->src = GELIC_DEBUG_PORT;
+ h_udp->source = GELIC_DEBUG_PORT;
h_udp->dest = GELIC_DEBUG_PORT;
pmsgc = pmsg = (char *)(h_udp + 1);
@@ -225,16 +201,16 @@ static void gelic_sendbuf(int msgsize)
int i;
dbg.descr.buf_size = header_size + msgsize;
- h_ip->total_length = msgsize + sizeof(struct udphdr) +
+ h_ip->tot_len = msgsize + sizeof(struct udphdr) +
sizeof(struct iphdr);
h_udp->len = msgsize + sizeof(struct udphdr);
- h_ip->checksum = 0;
+ h_ip->check = 0;
sum = 0;
p = (u16 *)h_ip;
for (i = 0; i < 5; i++)
sum += *p++;
- h_ip->checksum = ~(sum + (sum >> 16));
+ h_ip->check = ~(sum + (sum >> 16));
dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
GELIC_DESCR_TX_DMA_FRAME_TAIL;
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 638c406..b831638 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -78,7 +78,7 @@ struct ps3_bmp {
/**
* struct ps3_private - a per cpu data structure
* @bmp: ps3_bmp structure
- * @bmp_lock: Syncronize access to bmp.
+ * @bmp_lock: Synchronize access to bmp.
* @ipi_debug_brk_mask: Mask for debug break IPIs
* @ppe_id: HV logical_ppe_id
* @thread_id: HV thread_id
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 54c87d5..bec90fb 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -4,6 +4,7 @@ config PPC_PSERIES
select HAVE_PCSPKR_PLATFORM
select MPIC
select OF_DYNAMIC
+ select PCI
select PCI_MSI
select PPC_XICS
select PPC_ICP_NATIVE
@@ -15,7 +16,6 @@ config PPC_PSERIES
select RTAS_ERROR_LOGGING
select PPC_UDBG_16550
select PPC_NATIVE
- select PPC_PCI_CHOICE if EXPERT
select PPC_DOORBELL
select HAVE_CONTEXT_TRACKING
select HOTPLUG_CPU if SMP
@@ -43,11 +43,6 @@ config DTL
Say N if you are unsure.
-config PSERIES_MSI
- bool
- depends on PCI_MSI && PPC_PSERIES && EEH
- default y
-
config PSERIES_ENERGY
tristate "pSeries energy management capabilities driver"
depends on PPC_PSERIES
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 0348079..fedc2ccf0 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -2,14 +2,13 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG
obj-y := lpar.o hvCall.o nvram.o reconfig.o \
+ of_helpers.o \
setup.o iommu.o event_sources.o ras.o \
- firmware.o power.o dlpar.o mobility.o rng.o
+ firmware.o power.o dlpar.o mobility.o rng.o \
+ pci.o pci_dlpar.o eeh_pseries.o msi.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SCANLOG) += scanlog.o
-obj-$(CONFIG_EEH) += eeh_pseries.o
obj-$(CONFIG_KEXEC) += kexec.o
-obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
-obj-$(CONFIG_PSERIES_MSI) += msi.o
obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index db17827..2b93ae8 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -18,7 +18,8 @@
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/of.h>
-#include "offline_states.h"
+
+#include "of_helpers.h"
#include "pseries.h"
#include <asm/prom.h>
@@ -244,36 +245,13 @@ cc_error:
return first_dn;
}
-static struct device_node *derive_parent(const char *path)
-{
- struct device_node *parent;
- char *last_slash;
-
- last_slash = strrchr(path, '/');
- if (last_slash == path) {
- parent = of_find_node_by_path("/");
- } else {
- char *parent_path;
- int parent_path_len = last_slash - path + 1;
- parent_path = kmalloc(parent_path_len, GFP_KERNEL);
- if (!parent_path)
- return NULL;
-
- strlcpy(parent_path, path, parent_path_len);
- parent = of_find_node_by_path(parent_path);
- kfree(parent_path);
- }
-
- return parent;
-}
-
int dlpar_attach_node(struct device_node *dn)
{
int rc;
- dn->parent = derive_parent(dn->full_name);
- if (!dn->parent)
- return -ENOMEM;
+ dn->parent = pseries_of_derive_parent(dn->full_name);
+ if (IS_ERR(dn->parent))
+ return PTR_ERR(dn->parent);
rc = of_attach_node(dn);
if (rc) {
@@ -359,185 +337,6 @@ int dlpar_release_drc(u32 drc_index)
return 0;
}
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-
-static int dlpar_online_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const __be32 *intserv;
- u32 thread;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- thread = be32_to_cpu(intserv[i]);
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != thread)
- continue;
- BUG_ON(get_cpu_current_state(cpu)
- != CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = device_online(get_cpu_device(cpu));
- if (rc)
- goto out;
- cpu_maps_update_begin();
-
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to online "
- "with physical id 0x%x\n", thread);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
-{
- struct device_node *dn, *parent;
- u32 drc_index;
- int rc;
-
- rc = kstrtou32(buf, 0, &drc_index);
- if (rc)
- return -EINVAL;
-
- rc = dlpar_acquire_drc(drc_index);
- if (rc)
- return -EINVAL;
-
- parent = of_find_node_by_path("/cpus");
- if (!parent)
- return -ENODEV;
-
- dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
- of_node_put(parent);
- if (!dn) {
- dlpar_release_drc(drc_index);
- return -EINVAL;
- }
-
- rc = dlpar_attach_node(dn);
- if (rc) {
- dlpar_release_drc(drc_index);
- dlpar_free_cc_nodes(dn);
- return rc;
- }
-
- rc = dlpar_online_cpu(dn);
- if (rc)
- return rc;
-
- return count;
-}
-
-static int dlpar_offline_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const __be32 *intserv;
- u32 thread;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- thread = be32_to_cpu(intserv[i]);
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != thread)
- continue;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
- break;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = device_offline(get_cpu_device(cpu));
- if (rc)
- goto out;
- cpu_maps_update_begin();
- break;
-
- }
-
- /*
- * The cpu is in CPU_STATE_INACTIVE.
- * Upgrade it's state to CPU_STATE_OFFLINE.
- */
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- BUG_ON(plpar_hcall_norets(H_PROD, thread)
- != H_SUCCESS);
- __cpu_die(cpu);
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to offline "
- "with physical id 0x%x\n", thread);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_release(const char *buf, size_t count)
-{
- struct device_node *dn;
- u32 drc_index;
- int rc;
-
- dn = of_find_node_by_path(buf);
- if (!dn)
- return -EINVAL;
-
- rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
- if (rc) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_offline_cpu(dn);
- if (rc) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_release_drc(drc_index);
- if (rc) {
- of_node_put(dn);
- return rc;
- }
-
- rc = dlpar_detach_node(dn);
- if (rc) {
- dlpar_acquire_drc(drc_index);
- return rc;
- }
-
- of_node_put(dn);
-
- return count;
-}
-
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
{
int rc;
@@ -557,6 +356,9 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_RESOURCE_MEM:
rc = dlpar_memory(hp_elog);
break;
+ case PSERIES_HP_ELOG_RESOURCE_CPU:
+ rc = dlpar_cpu(hp_elog);
+ break;
default:
pr_warn_ratelimited("Invalid resource (%d) specified\n",
hp_elog->resource);
@@ -586,6 +388,9 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr,
if (!strncmp(arg, "memory", 6)) {
hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
arg += strlen("memory ");
+ } else if (!strncmp(arg, "cpu", 3)) {
+ hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_CPU;
+ arg += strlen("cpu ");
} else {
pr_err("Invalid resource specified: \"%s\"\n", buf);
rc = -EINVAL;
@@ -645,16 +450,7 @@ static CLASS_ATTR(dlpar, S_IWUSR, NULL, dlpar_store);
static int __init pseries_dlpar_init(void)
{
- int rc;
-
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
- ppc_md.cpu_probe = dlpar_cpu_probe;
- ppc_md.cpu_release = dlpar_cpu_release;
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
- rc = sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
-
- return rc;
+ return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
}
machine_device_initcall(pseries, pseries_dlpar_init);
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 1ba55d0..ac3ffd9 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -433,42 +433,34 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *state)
return ret;
/* Parse the result out */
- result = 0;
- if (rets[1]) {
- switch(rets[0]) {
- case 0:
- result &= ~EEH_STATE_RESET_ACTIVE;
- result |= EEH_STATE_MMIO_ACTIVE;
- result |= EEH_STATE_DMA_ACTIVE;
- break;
- case 1:
- result |= EEH_STATE_RESET_ACTIVE;
- result |= EEH_STATE_MMIO_ACTIVE;
- result |= EEH_STATE_DMA_ACTIVE;
- break;
- case 2:
- result &= ~EEH_STATE_RESET_ACTIVE;
- result &= ~EEH_STATE_MMIO_ACTIVE;
- result &= ~EEH_STATE_DMA_ACTIVE;
- break;
- case 4:
- result &= ~EEH_STATE_RESET_ACTIVE;
- result &= ~EEH_STATE_MMIO_ACTIVE;
- result &= ~EEH_STATE_DMA_ACTIVE;
- result |= EEH_STATE_MMIO_ENABLED;
- break;
- case 5:
- if (rets[2]) {
- if (state) *state = rets[2];
- result = EEH_STATE_UNAVAILABLE;
- } else {
- result = EEH_STATE_NOT_SUPPORT;
- }
- break;
- default:
+ if (!rets[1])
+ return EEH_STATE_NOT_SUPPORT;
+
+ switch(rets[0]) {
+ case 0:
+ result = EEH_STATE_MMIO_ACTIVE |
+ EEH_STATE_DMA_ACTIVE;
+ break;
+ case 1:
+ result = EEH_STATE_RESET_ACTIVE |
+ EEH_STATE_MMIO_ACTIVE |
+ EEH_STATE_DMA_ACTIVE;
+ break;
+ case 2:
+ result = 0;
+ break;
+ case 4:
+ result = EEH_STATE_MMIO_ENABLED;
+ break;
+ case 5:
+ if (rets[2]) {
+ if (state) *state = rets[2];
+ result = EEH_STATE_UNAVAILABLE;
+ } else {
result = EEH_STATE_NOT_SUPPORT;
}
- } else {
+ break;
+ default:
result = EEH_STATE_NOT_SUPPORT;
}
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 6247544..282837a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -18,12 +18,15 @@
* 2 of the License, or (at your option) any later version.
*/
+#define pr_fmt(fmt) "pseries-hotplug-cpu: " fmt
+
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sched.h> /* for idle_task_exit */
#include <linux/cpu.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/firmware.h>
@@ -32,6 +35,7 @@
#include <asm/xics.h>
#include <asm/plpar_wrappers.h>
+#include "pseries.h"
#include "offline_states.h"
/* This version can't take the spinlock, because it never returns */
@@ -43,20 +47,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE;
static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
-static int cede_offline_enabled __read_mostly = 1;
+static bool cede_offline_enabled __read_mostly = true;
/*
* Enable/disable cede_offline when available.
*/
static int __init setup_cede_offline(char *str)
{
- if (!strcmp(str, "off"))
- cede_offline_enabled = 0;
- else if (!strcmp(str, "on"))
- cede_offline_enabled = 1;
- else
- return 0;
- return 1;
+ return (kstrtobool(str, &cede_offline_enabled) == 0);
}
__setup("cede_offline=", setup_cede_offline);
@@ -88,13 +86,7 @@ void set_default_offline_state(int cpu)
static void rtas_stop_self(void)
{
- static struct rtas_args args = {
- .nargs = 0,
- .nret = cpu_to_be32(1),
- .rets = &args.args[0],
- };
-
- args.token = cpu_to_be32(rtas_stop_self_token);
+ static struct rtas_args args;
local_irq_disable();
@@ -102,7 +94,8 @@ static void rtas_stop_self(void)
printk("cpu %u (hwid %u) Ready to die...\n",
smp_processor_id(), hard_smp_processor_id());
- enter_rtas(__pa(&args));
+
+ rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
panic("Alas, I survived.\n");
}
@@ -339,6 +332,536 @@ static void pseries_remove_processor(struct device_node *np)
cpu_maps_update_done();
}
+static int dlpar_online_cpu(struct device_node *dn)
+{
+ int rc = 0;
+ unsigned int cpu;
+ int len, nthreads, i;
+ const __be32 *intserv;
+ u32 thread;
+
+ intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return -EINVAL;
+
+ nthreads = len / sizeof(u32);
+
+ cpu_maps_update_begin();
+ for (i = 0; i < nthreads; i++) {
+ thread = be32_to_cpu(intserv[i]);
+ for_each_present_cpu(cpu) {
+ if (get_hard_smp_processor_id(cpu) != thread)
+ continue;
+ BUG_ON(get_cpu_current_state(cpu)
+ != CPU_STATE_OFFLINE);
+ cpu_maps_update_done();
+ rc = device_online(get_cpu_device(cpu));
+ if (rc)
+ goto out;
+ cpu_maps_update_begin();
+
+ break;
+ }
+ if (cpu == num_possible_cpus())
+ printk(KERN_WARNING "Could not find cpu to online "
+ "with physical id 0x%x\n", thread);
+ }
+ cpu_maps_update_done();
+
+out:
+ return rc;
+
+}
+
+static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index)
+{
+ struct device_node *child = NULL;
+ u32 my_drc_index;
+ bool found;
+ int rc;
+
+ /* Assume cpu doesn't exist */
+ found = false;
+
+ for_each_child_of_node(parent, child) {
+ rc = of_property_read_u32(child, "ibm,my-drc-index",
+ &my_drc_index);
+ if (rc)
+ continue;
+
+ if (my_drc_index == drc_index) {
+ of_node_put(child);
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
+{
+ bool found = false;
+ int rc, index;
+
+ index = 0;
+ while (!found) {
+ u32 drc;
+
+ rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
+ index++, &drc);
+ if (rc)
+ break;
+
+ if (drc == drc_index)
+ found = true;
+ }
+
+ return found;
+}
+
+static ssize_t dlpar_cpu_add(u32 drc_index)
+{
+ struct device_node *dn, *parent;
+ int rc, saved_rc;
+
+ pr_debug("Attempting to add CPU, drc index: %x\n", drc_index);
+
+ parent = of_find_node_by_path("/cpus");
+ if (!parent) {
+ pr_warn("Failed to find CPU root node \"/cpus\"\n");
+ return -ENODEV;
+ }
+
+ if (dlpar_cpu_exists(parent, drc_index)) {
+ of_node_put(parent);
+ pr_warn("CPU with drc index %x already exists\n", drc_index);
+ return -EINVAL;
+ }
+
+ if (!valid_cpu_drc_index(parent, drc_index)) {
+ of_node_put(parent);
+ pr_warn("Cannot find CPU (drc index %x) to add.\n", drc_index);
+ return -EINVAL;
+ }
+
+ rc = dlpar_acquire_drc(drc_index);
+ if (rc) {
+ pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
+ rc, drc_index);
+ of_node_put(parent);
+ return -EINVAL;
+ }
+
+ dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
+ of_node_put(parent);
+ if (!dn) {
+ pr_warn("Failed call to configure-connector, drc index: %x\n",
+ drc_index);
+ dlpar_release_drc(drc_index);
+ return -EINVAL;
+ }
+
+ rc = dlpar_attach_node(dn);
+ if (rc) {
+ saved_rc = rc;
+ pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n",
+ dn->name, rc, drc_index);
+
+ rc = dlpar_release_drc(drc_index);
+ if (!rc)
+ dlpar_free_cc_nodes(dn);
+
+ return saved_rc;
+ }
+
+ rc = dlpar_online_cpu(dn);
+ if (rc) {
+ saved_rc = rc;
+ pr_warn("Failed to online cpu %s, rc: %d, drc index: %x\n",
+ dn->name, rc, drc_index);
+
+ rc = dlpar_detach_node(dn);
+ if (!rc)
+ dlpar_release_drc(drc_index);
+
+ return saved_rc;
+ }
+
+ pr_debug("Successfully added CPU %s, drc index: %x\n", dn->name,
+ drc_index);
+ return rc;
+}
+
+static int dlpar_offline_cpu(struct device_node *dn)
+{
+ int rc = 0;
+ unsigned int cpu;
+ int len, nthreads, i;
+ const __be32 *intserv;
+ u32 thread;
+
+ intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return -EINVAL;
+
+ nthreads = len / sizeof(u32);
+
+ cpu_maps_update_begin();
+ for (i = 0; i < nthreads; i++) {
+ thread = be32_to_cpu(intserv[i]);
+ for_each_present_cpu(cpu) {
+ if (get_hard_smp_processor_id(cpu) != thread)
+ continue;
+
+ if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
+ break;
+
+ if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
+ set_preferred_offline_state(cpu,
+ CPU_STATE_OFFLINE);
+ cpu_maps_update_done();
+ rc = device_offline(get_cpu_device(cpu));
+ if (rc)
+ goto out;
+ cpu_maps_update_begin();
+ break;
+
+ }
+
+ /*
+ * The cpu is in CPU_STATE_INACTIVE.
+ * Upgrade it's state to CPU_STATE_OFFLINE.
+ */
+ set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
+ BUG_ON(plpar_hcall_norets(H_PROD, thread)
+ != H_SUCCESS);
+ __cpu_die(cpu);
+ break;
+ }
+ if (cpu == num_possible_cpus())
+ printk(KERN_WARNING "Could not find cpu to offline with physical id 0x%x\n", thread);
+ }
+ cpu_maps_update_done();
+
+out:
+ return rc;
+
+}
+
+static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
+{
+ int rc;
+
+ pr_debug("Attemping to remove CPU %s, drc index: %x\n",
+ dn->name, drc_index);
+
+ rc = dlpar_offline_cpu(dn);
+ if (rc) {
+ pr_warn("Failed to offline CPU %s, rc: %d\n", dn->name, rc);
+ return -EINVAL;
+ }
+
+ rc = dlpar_release_drc(drc_index);
+ if (rc) {
+ pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
+ drc_index, dn->name, rc);
+ dlpar_online_cpu(dn);
+ return rc;
+ }
+
+ rc = dlpar_detach_node(dn);
+ if (rc) {
+ int saved_rc = rc;
+
+ pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc);
+
+ rc = dlpar_acquire_drc(drc_index);
+ if (!rc)
+ dlpar_online_cpu(dn);
+
+ return saved_rc;
+ }
+
+ pr_debug("Successfully removed CPU, drc index: %x\n", drc_index);
+ return 0;
+}
+
+static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
+{
+ struct device_node *dn;
+ u32 my_index;
+ int rc;
+
+ for_each_node_by_type(dn, "cpu") {
+ rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index);
+ if (rc)
+ continue;
+
+ if (my_index == drc_index)
+ break;
+ }
+
+ return dn;
+}
+
+static int dlpar_cpu_remove_by_index(u32 drc_index)
+{
+ struct device_node *dn;
+ int rc;
+
+ dn = cpu_drc_index_to_dn(drc_index);
+ if (!dn) {
+ pr_warn("Cannot find CPU (drc index %x) to remove\n",
+ drc_index);
+ return -ENODEV;
+ }
+
+ rc = dlpar_cpu_remove(dn, drc_index);
+ of_node_put(dn);
+ return rc;
+}
+
+static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
+{
+ struct device_node *dn;
+ int cpus_found = 0;
+ int rc;
+
+ /* We want to find cpus_to_remove + 1 CPUs to ensure we do not
+ * remove the last CPU.
+ */
+ for_each_node_by_type(dn, "cpu") {
+ cpus_found++;
+
+ if (cpus_found > cpus_to_remove) {
+ of_node_put(dn);
+ break;
+ }
+
+ /* Note that cpus_found is always 1 ahead of the index
+ * into the cpu_drcs array, so we use cpus_found - 1
+ */
+ rc = of_property_read_u32(dn, "ibm,my-drc-index",
+ &cpu_drcs[cpus_found - 1]);
+ if (rc) {
+ pr_warn("Error occurred getting drc-index for %s\n",
+ dn->name);
+ of_node_put(dn);
+ return -1;
+ }
+ }
+
+ if (cpus_found < cpus_to_remove) {
+ pr_warn("Failed to find enough CPUs (%d of %d) to remove\n",
+ cpus_found, cpus_to_remove);
+ } else if (cpus_found == cpus_to_remove) {
+ pr_warn("Cannot remove all CPUs\n");
+ }
+
+ return cpus_found;
+}
+
+static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
+{
+ u32 *cpu_drcs;
+ int cpus_found;
+ int cpus_removed = 0;
+ int i, rc;
+
+ pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove);
+
+ cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL);
+ if (!cpu_drcs)
+ return -EINVAL;
+
+ cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove);
+ if (cpus_found <= cpus_to_remove) {
+ kfree(cpu_drcs);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cpus_to_remove; i++) {
+ rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
+ if (rc)
+ break;
+
+ cpus_removed++;
+ }
+
+ if (cpus_removed != cpus_to_remove) {
+ pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
+
+ for (i = 0; i < cpus_removed; i++)
+ dlpar_cpu_add(cpu_drcs[i]);
+
+ rc = -EINVAL;
+ } else {
+ rc = 0;
+ }
+
+ kfree(cpu_drcs);
+ return rc;
+}
+
+static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add)
+{
+ struct device_node *parent;
+ int cpus_found = 0;
+ int index, rc;
+
+ parent = of_find_node_by_path("/cpus");
+ if (!parent) {
+ pr_warn("Could not find CPU root node in device tree\n");
+ kfree(cpu_drcs);
+ return -1;
+ }
+
+ /* Search the ibm,drc-indexes array for possible CPU drcs to
+ * add. Note that the format of the ibm,drc-indexes array is
+ * the number of entries in the array followed by the array
+ * of drc values so we start looking at index = 1.
+ */
+ index = 1;
+ while (cpus_found < cpus_to_add) {
+ u32 drc;
+
+ rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
+ index++, &drc);
+ if (rc)
+ break;
+
+ if (dlpar_cpu_exists(parent, drc))
+ continue;
+
+ cpu_drcs[cpus_found++] = drc;
+ }
+
+ of_node_put(parent);
+ return cpus_found;
+}
+
+static int dlpar_cpu_add_by_count(u32 cpus_to_add)
+{
+ u32 *cpu_drcs;
+ int cpus_added = 0;
+ int cpus_found;
+ int i, rc;
+
+ pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
+
+ cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
+ if (!cpu_drcs)
+ return -EINVAL;
+
+ cpus_found = find_dlpar_cpus_to_add(cpu_drcs, cpus_to_add);
+ if (cpus_found < cpus_to_add) {
+ pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
+ cpus_found, cpus_to_add);
+ kfree(cpu_drcs);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cpus_to_add; i++) {
+ rc = dlpar_cpu_add(cpu_drcs[i]);
+ if (rc)
+ break;
+
+ cpus_added++;
+ }
+
+ if (cpus_added < cpus_to_add) {
+ pr_warn("CPU hot-add failed, removing any added CPUs\n");
+
+ for (i = 0; i < cpus_added; i++)
+ dlpar_cpu_remove_by_index(cpu_drcs[i]);
+
+ rc = -EINVAL;
+ } else {
+ rc = 0;
+ }
+
+ kfree(cpu_drcs);
+ return rc;
+}
+
+int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
+{
+ u32 count, drc_index;
+ int rc;
+
+ count = hp_elog->_drc_u.drc_count;
+ drc_index = hp_elog->_drc_u.drc_index;
+
+ lock_device_hotplug();
+
+ switch (hp_elog->action) {
+ case PSERIES_HP_ELOG_ACTION_REMOVE:
+ if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
+ rc = dlpar_cpu_remove_by_count(count);
+ else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
+ rc = dlpar_cpu_remove_by_index(drc_index);
+ else
+ rc = -EINVAL;
+ break;
+ case PSERIES_HP_ELOG_ACTION_ADD:
+ if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
+ rc = dlpar_cpu_add_by_count(count);
+ else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
+ rc = dlpar_cpu_add(drc_index);
+ else
+ rc = -EINVAL;
+ break;
+ default:
+ pr_err("Invalid action (%d) specified\n", hp_elog->action);
+ rc = -EINVAL;
+ break;
+ }
+
+ unlock_device_hotplug();
+ return rc;
+}
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+
+static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
+{
+ u32 drc_index;
+ int rc;
+
+ rc = kstrtou32(buf, 0, &drc_index);
+ if (rc)
+ return -EINVAL;
+
+ rc = dlpar_cpu_add(drc_index);
+
+ return rc ? rc : count;
+}
+
+static ssize_t dlpar_cpu_release(const char *buf, size_t count)
+{
+ struct device_node *dn;
+ u32 drc_index;
+ int rc;
+
+ dn = of_find_node_by_path(buf);
+ if (!dn)
+ return -EINVAL;
+
+ rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
+ if (rc) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ rc = dlpar_cpu_remove(dn, drc_index);
+ of_node_put(dn);
+
+ return rc ? rc : count;
+}
+
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
static int pseries_smp_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -385,6 +908,11 @@ static int __init pseries_cpu_hotplug_init(void)
int cpu;
int qcss_tok;
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+ ppc_md.cpu_probe = dlpar_cpu_probe;
+ ppc_md.cpu_release = dlpar_cpu_release;
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
for_each_node_by_name(np, "interrupt-controller") {
typep = of_get_property(np, "compatible", NULL);
if (strstr(typep, "open-pic")) {
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 849b29b..74da18d 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -31,7 +31,7 @@
#include <asm/plpar_wrappers.h>
/**
- * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
+ * hvc_get_chars - retrieve characters from firmware for denoted vterm adapter
* @vtermno: The vtermno or unit_address of the adapter from which to fetch the
* data.
* @buf: The character buffer into which to put the character data fetched from
diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c
index eedb645..94a6e56 100644
--- a/arch/powerpc/platforms/pseries/hvcserver.c
+++ b/arch/powerpc/platforms/pseries/hvcserver.c
@@ -142,11 +142,11 @@ int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head,
int more = 1;
int retval;
- memset(pi_buff, 0x00, PAGE_SIZE);
/* invalid parameters */
if (!head || !pi_buff)
return -EINVAL;
+ memset(pi_buff, 0x00, PAGE_SIZE);
last_p_partition_ID = last_p_unit_address = ~0UL;
INIT_LIST_HEAD(head);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 0946b98..bd98ce2 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -532,7 +532,6 @@ static int tce_setrange_multi_pSeriesLP_walk(unsigned long start_pfn,
return tce_setrange_multi_pSeriesLP(start_pfn, num_pfn, arg);
}
-#ifdef CONFIG_PCI
static void iommu_table_setparms(struct pci_controller *phb,
struct device_node *dn,
struct iommu_table *tbl)
@@ -1292,15 +1291,6 @@ static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
return dma_iommu_ops.get_required_mask(dev);
}
-#else /* CONFIG_PCI */
-#define pci_dma_bus_setup_pSeries NULL
-#define pci_dma_dev_setup_pSeries NULL
-#define pci_dma_bus_setup_pSeriesLP NULL
-#define pci_dma_dev_setup_pSeriesLP NULL
-#define dma_set_mask_pSeriesLP NULL
-#define dma_get_required_mask_pSeriesLP NULL
-#endif /* !CONFIG_PCI */
-
static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index b7a67e3..2415a0d 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -315,48 +315,48 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
return 0;
}
-static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
+static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group)
{
- unsigned long dword0;
- unsigned long lpar_rc;
- unsigned long dummy_word1;
- unsigned long flags;
+ long lpar_rc;
+ unsigned long i, j;
+ struct {
+ unsigned long pteh;
+ unsigned long ptel;
+ } ptes[4];
- /* Read 1 pte at a time */
- /* Do not need RPN to logical page translation */
- /* No cross CEC PFT access */
- flags = 0;
+ for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) {
- lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
+ lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes);
+ if (lpar_rc != H_SUCCESS)
+ continue;
- BUG_ON(lpar_rc != H_SUCCESS);
+ for (j = 0; j < 4; j++) {
+ if (HPTE_V_COMPARE(ptes[j].pteh, want_v) &&
+ (ptes[j].pteh & HPTE_V_VALID))
+ return i + j;
+ }
+ }
- return dword0;
+ return -1;
}
static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
{
- unsigned long hash;
- unsigned long i;
long slot;
- unsigned long want_v, hpte_v;
+ unsigned long hash;
+ unsigned long want_v;
+ unsigned long hpte_group;
hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
want_v = hpte_encode_avpn(vpn, psize, ssize);
/* Bolted entries are always in the primary group */
- slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
- for (i = 0; i < HPTES_PER_GROUP; i++) {
- hpte_v = pSeries_lpar_hpte_getword0(slot);
-
- if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID))
- /* HPTE matches */
- return slot;
- ++slot;
- }
-
- return -1;
-}
+ hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+ slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
+ if (slot < 0)
+ return -1;
+ return hpte_group + slot;
+}
static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
unsigned long ea,
@@ -396,6 +396,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
BUG_ON(lpar_rc != H_SUCCESS);
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
/*
* Limit iterations holding pSeries_lpar_tlbie_lock to 3. We also need
* to make sure that we avoid bouncing the hypervisor tlbie lock.
@@ -494,9 +495,18 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
__pSeries_lpar_hugepage_invalidate(slot_array, vpn_array,
index, psize, ssize);
}
+#else
+static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
+ unsigned long addr,
+ unsigned char *hpte_slot_array,
+ int psize, int ssize, int local)
+{
+ WARN(1, "%s called without THP support\n", __func__);
+}
+#endif
-static void pSeries_lpar_hpte_removebolted(unsigned long ea,
- int psize, int ssize)
+static int pSeries_lpar_hpte_removebolted(unsigned long ea,
+ int psize, int ssize)
{
unsigned long vpn;
unsigned long slot, vsid;
@@ -505,11 +515,14 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
vpn = hpt_vpn(ea, vsid, ssize);
slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
- BUG_ON(slot == -1);
+ if (slot == -1)
+ return -ENOENT;
+
/*
* lpar doesn't use the passed actual page size
*/
pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0);
+ return 0;
}
/*
diff --git a/arch/powerpc/platforms/pseries/of_helpers.c b/arch/powerpc/platforms/pseries/of_helpers.c
new file mode 100644
index 0000000..2798933
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/of_helpers.c
@@ -0,0 +1,38 @@
+#include <linux/string.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "of_helpers.h"
+
+/**
+ * pseries_of_derive_parent - basically like dirname(1)
+ * @path: the full_name of a node to be added to the tree
+ *
+ * Returns the node which should be the parent of the node
+ * described by path. E.g., for path = "/foo/bar", returns
+ * the node with full_name = "/foo".
+ */
+struct device_node *pseries_of_derive_parent(const char *path)
+{
+ struct device_node *parent;
+ char *parent_path = "/";
+ const char *tail;
+
+ /* We do not want the trailing '/' character */
+ tail = kbasename(path) - 1;
+
+ /* reject if path is "/" */
+ if (!strcmp(path, "/"))
+ return ERR_PTR(-EINVAL);
+
+ if (tail > path) {
+ parent_path = kstrndup(path, tail - path, GFP_KERNEL);
+ if (!parent_path)
+ return ERR_PTR(-ENOMEM);
+ }
+ parent = of_find_node_by_path(parent_path);
+ if (strcmp(parent_path, "/"))
+ kfree(parent_path);
+ return parent ? parent : ERR_PTR(-EINVAL);
+}
diff --git a/arch/powerpc/platforms/pseries/of_helpers.h b/arch/powerpc/platforms/pseries/of_helpers.h
new file mode 100644
index 0000000..bb83d39
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/of_helpers.h
@@ -0,0 +1,8 @@
+#ifndef _PSERIES_OF_HELPERS_H
+#define _PSERIES_OF_HELPERS_H
+
+#include <linux/of.h>
+
+struct device_node *pseries_of_derive_parent(const char *path);
+
+#endif /* _PSERIES_OF_HELPERS_H */
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 8411c27..7aa83f0 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -73,6 +73,15 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
}
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
+#else
+static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
/* PCI root bridge prepare function override for pseries */
struct pci_host_bridge;
int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 3b6647e..9a3e27b 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -40,6 +40,9 @@ static int ras_check_exception_token;
#define EPOW_SENSOR_TOKEN 9
#define EPOW_SENSOR_INDEX 0
+/* EPOW events counter variable */
+static int num_epow_events;
+
static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
@@ -82,32 +85,30 @@ static void handle_system_shutdown(char event_modifier)
{
switch (event_modifier) {
case EPOW_SHUTDOWN_NORMAL:
- pr_emerg("Firmware initiated power off");
+ pr_emerg("Power off requested\n");
orderly_poweroff(true);
break;
case EPOW_SHUTDOWN_ON_UPS:
- pr_emerg("Loss of power reported by firmware, system is "
- "running on UPS/battery");
- pr_emerg("Check RTAS error log for details");
+ pr_emerg("Loss of system power detected. System is running on"
+ " UPS/battery. Check RTAS error log for details\n");
orderly_poweroff(true);
break;
case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:
- pr_emerg("Loss of system critical functions reported by "
- "firmware");
- pr_emerg("Check RTAS error log for details");
+ pr_emerg("Loss of system critical functions detected. Check"
+ " RTAS error log for details\n");
orderly_poweroff(true);
break;
case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH:
- pr_emerg("Ambient temperature too high reported by firmware");
- pr_emerg("Check RTAS error log for details");
+ pr_emerg("High ambient temperature detected. Check RTAS"
+ " error log for details\n");
orderly_poweroff(true);
break;
default:
- pr_err("Unknown power/cooling shutdown event (modifier %d)",
+ pr_err("Unknown power/cooling shutdown event (modifier = %d)\n",
event_modifier);
}
}
@@ -145,17 +146,20 @@ static void rtas_parse_epow_errlog(struct rtas_error_log *log)
switch (action_code) {
case EPOW_RESET:
- pr_err("Non critical power or cooling issue cleared");
+ if (num_epow_events) {
+ pr_info("Non critical power/cooling issue cleared\n");
+ num_epow_events--;
+ }
break;
case EPOW_WARN_COOLING:
- pr_err("Non critical cooling issue reported by firmware");
- pr_err("Check RTAS error log for details");
+ pr_info("Non-critical cooling issue detected. Check RTAS error"
+ " log for details\n");
break;
case EPOW_WARN_POWER:
- pr_err("Non critical power issue reported by firmware");
- pr_err("Check RTAS error log for details");
+ pr_info("Non-critical power issue detected. Check RTAS error"
+ " log for details\n");
break;
case EPOW_SYSTEM_SHUTDOWN:
@@ -163,23 +167,27 @@ static void rtas_parse_epow_errlog(struct rtas_error_log *log)
break;
case EPOW_SYSTEM_HALT:
- pr_emerg("Firmware initiated power off");
+ pr_emerg("Critical power/cooling issue detected. Check RTAS"
+ " error log for details. Powering off.\n");
orderly_poweroff(true);
break;
case EPOW_MAIN_ENCLOSURE:
case EPOW_POWER_OFF:
- pr_emerg("Critical power/cooling issue reported by firmware");
- pr_emerg("Check RTAS error log for details");
- pr_emerg("Immediate power off");
+ pr_emerg("System about to lose power. Check RTAS error log "
+ " for details. Powering off immediately.\n");
emergency_sync();
kernel_power_off();
break;
default:
- pr_err("Unknown power/cooling event (action code %d)",
+ pr_err("Unknown power/cooling event (action code = %d)\n",
action_code);
}
+
+ /* Increment epow events counter variable */
+ if (action_code != EPOW_RESET)
+ num_epow_events++;
}
/* Handle environmental and power warning (EPOW) interrupts. */
@@ -249,13 +257,12 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, fatal);
if (fatal) {
- pr_emerg("Fatal hardware error reported by firmware");
- pr_emerg("Check RTAS error log for details");
- pr_emerg("Immediate power off");
+ pr_emerg("Fatal hardware error detected. Check RTAS error"
+ " log for details. Powering off immediately\n");
emergency_sync();
kernel_power_off();
} else {
- pr_err("Recoverable hardware error reported by firmware");
+ pr_err("Recoverable hardware error detected\n");
}
spin_unlock(&ras_log_buf_lock);
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 0f31952..7c7fcc0 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -22,37 +22,7 @@
#include <asm/uaccess.h>
#include <asm/mmu.h>
-/**
- * derive_parent - basically like dirname(1)
- * @path: the full_name of a node to be added to the tree
- *
- * Returns the node which should be the parent of the node
- * described by path. E.g., for path = "/foo/bar", returns
- * the node with full_name = "/foo".
- */
-static struct device_node *derive_parent(const char *path)
-{
- struct device_node *parent = NULL;
- char *parent_path = "/";
- size_t parent_path_len = strrchr(path, '/') - path + 1;
-
- /* reject if path is "/" */
- if (!strcmp(path, "/"))
- return ERR_PTR(-EINVAL);
-
- if (strrchr(path, '/') != path) {
- parent_path = kmalloc(parent_path_len, GFP_KERNEL);
- if (!parent_path)
- return ERR_PTR(-ENOMEM);
- strlcpy(parent_path, path, parent_path_len);
- }
- parent = of_find_node_by_path(parent_path);
- if (!parent)
- return ERR_PTR(-EINVAL);
- if (strcmp(parent_path, "/"))
- kfree(parent_path);
- return parent;
-}
+#include "of_helpers.h"
static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
{
@@ -71,7 +41,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
of_node_set_flag(np, OF_DYNAMIC);
of_node_init(np);
- np->parent = derive_parent(path);
+ np->parent = pseries_of_derive_parent(path);
if (IS_ERR(np->parent)) {
err = PTR_ERR(np->parent);
goto out_err;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 9a83eb7..6e944fc 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -40,6 +40,7 @@
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/of.h>
+#include <linux/of_pci.h>
#include <linux/kexec.h>
#include <asm/mmu.h>
@@ -495,18 +496,7 @@ static void __init find_and_init_phbs(void)
* PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties
* in chosen.
*/
- if (of_chosen) {
- const int *prop;
-
- prop = of_get_property(of_chosen,
- "linux,pci-probe-only", NULL);
- if (prop) {
- if (*prop)
- pci_add_flags(PCI_PROBE_ONLY);
- else
- pci_clear_flags(PCI_PROBE_ONLY);
- }
- }
+ of_pci_check_probe_only();
}
static void __init pSeries_setup_arch(void)
@@ -525,7 +515,7 @@ static void __init pSeries_setup_arch(void)
fwnmi_init();
- /* By default, only probe PCI (can be overriden by rtas_pci) */
+ /* By default, only probe PCI (can be overridden by rtas_pci) */
pci_add_flags(PCI_PROBE_ONLY);
/* Find and initialize PCI host bridges */
@@ -837,10 +827,6 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
return PCI_PROBE_NORMAL;
}
-#ifndef CONFIG_PCI
-void pSeries_final_fixup(void) { }
-#endif
-
struct pci_controller_ops pseries_pci_controller_ops = {
.probe_mode = pSeries_pci_probe_mode,
};
diff --git a/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh
new file mode 100755
index 0000000..c658d8c
--- /dev/null
+++ b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+set -e
+set -o pipefail
+
+# To debug, uncomment the following line
+# set -x
+
+# Test whether the compile option -mprofile-kernel exists and generates
+# profiling code (ie. a call to _mcount()).
+echo "int func() { return 0; }" | \
+ $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
+ grep -q "_mcount"
+
+# Test whether the notrace attribute correctly suppresses calls to _mcount().
+
+echo -e "#include <linux/compiler.h>\nnotrace int func() { return 0; }" | \
+ $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
+ grep -q "_mcount" && \
+ exit 1
+
+echo "OK"
+exit 0
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index a19332a..52dc165 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -40,3 +40,8 @@ config SCOM_DEBUGFS
config GE_FPGA
bool
default n
+
+config FSL_CORENET_RCPM
+ bool
+ help
+ This option enables support for RCPM (Run Control/Power Management).
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 5b492a6..a254824 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -20,13 +20,13 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
+obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
-obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
mv64x60_udbg.o
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index d2b79bc..0d112b9 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -43,6 +43,7 @@
#include <linux/types.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
+#include <linux/pfn_t.h>
#include <asm/page.h>
#include <asm/prom.h>
@@ -103,7 +104,7 @@ axon_ram_irq_handler(int irq, void *dev)
* axon_ram_make_request - make_request() method for block device
* @queue, @bio: see blk_queue_make_request()
*/
-static void
+static blk_qc_t
axon_ram_make_request(struct request_queue *queue, struct bio *bio)
{
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
@@ -120,7 +121,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
bio_for_each_segment(vec, bio, iter) {
if (unlikely(phys_mem + vec.bv_len > phys_end)) {
bio_io_error(bio);
- return;
+ return BLK_QC_T_NONE;
}
user_mem = page_address(vec.bv_page) + vec.bv_offset;
@@ -133,6 +134,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
transfered += vec.bv_len;
}
bio_endio(bio);
+ return BLK_QC_T_NONE;
}
/**
@@ -141,15 +143,13 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
*/
static long
axon_ram_direct_access(struct block_device *device, sector_t sector,
- void __pmem **kaddr, unsigned long *pfn)
+ void __pmem **kaddr, pfn_t *pfn)
{
struct axon_ram_bank *bank = device->bd_disk->private_data;
loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
- void *addr = (void *)(bank->ph_addr + offset);
-
- *kaddr = (void __pmem *)addr;
- *pfn = virt_to_phys(addr) >> PAGE_SHIFT;
+ *kaddr = (void __pmem __force *) bank->io_addr + offset;
+ *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
return bank->size - offset;
}
@@ -312,6 +312,7 @@ static const struct of_device_id axon_ram_device_id[] = {
},
{}
};
+MODULE_DEVICE_TABLE(of, axon_ram_device_id);
static struct platform_driver axon_ram_driver = {
.probe = axon_ram_probe,
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5e6ff38..8ed6536 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -228,7 +228,10 @@ void __init cpm_reset(void)
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
siu_conf = immr_map(im_siu_conf);
- out_be32(&siu_conf->sc_sdcr, 1);
+ if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */
+ out_be32(&siu_conf->sc_sdcr, 0x40);
+ else
+ out_be32(&siu_conf->sc_sdcr, 1);
immr_unmap(siu_conf);
cpm_muram_init();
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index e2ea519..9d32465 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -27,8 +27,8 @@
#include <asm/udbg.h>
#include <asm/io.h>
-#include <asm/rheap.h>
#include <asm/cpm.h>
+#include <soc/fsl/qe/qe.h>
#include <mm/mmu_decl.h>
@@ -65,161 +65,6 @@ void __init udbg_init_cpm(void)
}
#endif
-static spinlock_t cpm_muram_lock;
-static rh_block_t cpm_boot_muram_rh_block[16];
-static rh_info_t cpm_muram_info;
-static u8 __iomem *muram_vbase;
-static phys_addr_t muram_pbase;
-
-/* Max address size we deal with */
-#define OF_MAX_ADDR_CELLS 4
-
-int cpm_muram_init(void)
-{
- struct device_node *np;
- struct resource r;
- u32 zero[OF_MAX_ADDR_CELLS] = {};
- resource_size_t max = 0;
- int i = 0;
- int ret = 0;
-
- if (muram_pbase)
- return 0;
-
- spin_lock_init(&cpm_muram_lock);
- /* initialize the info header */
- rh_init(&cpm_muram_info, 1,
- sizeof(cpm_boot_muram_rh_block) /
- sizeof(cpm_boot_muram_rh_block[0]),
- cpm_boot_muram_rh_block);
-
- np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data");
- if (!np) {
- /* try legacy bindings */
- np = of_find_node_by_name(NULL, "data-only");
- if (!np) {
- printk(KERN_ERR "Cannot find CPM muram data node");
- ret = -ENODEV;
- goto out;
- }
- }
-
- muram_pbase = of_translate_address(np, zero);
- if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
- printk(KERN_ERR "Cannot translate zero through CPM muram node");
- ret = -ENODEV;
- goto out;
- }
-
- while (of_address_to_resource(np, i++, &r) == 0) {
- if (r.end > max)
- max = r.end;
-
- rh_attach_region(&cpm_muram_info, r.start - muram_pbase,
- resource_size(&r));
- }
-
- muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1);
- if (!muram_vbase) {
- printk(KERN_ERR "Cannot map CPM muram");
- ret = -ENOMEM;
- }
-
-out:
- of_node_put(np);
- return ret;
-}
-
-/**
- * cpm_muram_alloc - allocate the requested size worth of multi-user ram
- * @size: number of bytes to allocate
- * @align: requested alignment, in bytes
- *
- * This function returns an offset into the muram area.
- * Use cpm_dpram_addr() to get the virtual address of the area.
- * Use cpm_muram_free() to free the allocation.
- */
-unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
-{
- unsigned long start;
- unsigned long flags;
-
- spin_lock_irqsave(&cpm_muram_lock, flags);
- cpm_muram_info.alignment = align;
- start = rh_alloc(&cpm_muram_info, size, "commproc");
- memset_io(cpm_muram_addr(start), 0, size);
- spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
- return start;
-}
-EXPORT_SYMBOL(cpm_muram_alloc);
-
-/**
- * cpm_muram_free - free a chunk of multi-user ram
- * @offset: The beginning of the chunk as returned by cpm_muram_alloc().
- */
-int cpm_muram_free(unsigned long offset)
-{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&cpm_muram_lock, flags);
- ret = rh_free(&cpm_muram_info, offset);
- spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(cpm_muram_free);
-
-/**
- * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram
- * @offset: the offset into the muram area to reserve
- * @size: the number of bytes to reserve
- *
- * This function returns "start" on success, -ENOMEM on failure.
- * Use cpm_dpram_addr() to get the virtual address of the area.
- * Use cpm_muram_free() to free the allocation.
- */
-unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
-{
- unsigned long start;
- unsigned long flags;
-
- spin_lock_irqsave(&cpm_muram_lock, flags);
- cpm_muram_info.alignment = 1;
- start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc");
- spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
- return start;
-}
-EXPORT_SYMBOL(cpm_muram_alloc_fixed);
-
-/**
- * cpm_muram_addr - turn a muram offset into a virtual address
- * @offset: muram offset to convert
- */
-void __iomem *cpm_muram_addr(unsigned long offset)
-{
- return muram_vbase + offset;
-}
-EXPORT_SYMBOL(cpm_muram_addr);
-
-unsigned long cpm_muram_offset(void __iomem *addr)
-{
- return addr - (void __iomem *)muram_vbase;
-}
-EXPORT_SYMBOL(cpm_muram_offset);
-
-/**
- * cpm_muram_dma - turn a muram virtual address into a DMA address
- * @offset: virtual address from cpm_muram_addr() to convert
- */
-dma_addr_t cpm_muram_dma(void __iomem *addr)
-{
- return muram_pbase + ((u8 __iomem *)addr - muram_vbase);
-}
-EXPORT_SYMBOL(cpm_muram_dma);
-
#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)
struct cpm2_ioports {
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index eca0b00..bffcc7a 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -181,7 +181,8 @@ static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
/* Exact match, unless ehv_pic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 38138cf..424b67f 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
+#include <linux/syscore_ops.h>
#include <asm/prom.h>
#include <asm/fsl_lbc.h>
@@ -243,8 +244,6 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
if (status & LTESR_CS)
dev_err(ctrl->dev, "Chip select error: "
"LTESR 0x%08X\n", status);
- if (status & LTESR_UPM)
- ;
if (status & LTESR_FCT) {
dev_err(ctrl->dev, "FCM command time-out: "
"LTESR 0x%08X\n", status);
@@ -354,24 +353,42 @@ err:
#ifdef CONFIG_SUSPEND
/* save lbc registers */
-static int fsl_lbc_suspend(struct platform_device *pdev, pm_message_t state)
+static int fsl_lbc_syscore_suspend(void)
{
- struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev);
- struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ struct fsl_lbc_ctrl *ctrl;
+ struct fsl_lbc_regs __iomem *lbc;
+
+ ctrl = fsl_lbc_ctrl_dev;
+ if (!ctrl)
+ goto out;
+
+ lbc = ctrl->regs;
+ if (!lbc)
+ goto out;
ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL);
if (!ctrl->saved_regs)
return -ENOMEM;
_memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs));
+
+out:
return 0;
}
/* restore lbc registers */
-static int fsl_lbc_resume(struct platform_device *pdev)
+static void fsl_lbc_syscore_resume(void)
{
- struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev);
- struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ struct fsl_lbc_ctrl *ctrl;
+ struct fsl_lbc_regs __iomem *lbc;
+
+ ctrl = fsl_lbc_ctrl_dev;
+ if (!ctrl)
+ goto out;
+
+ lbc = ctrl->regs;
+ if (!lbc)
+ goto out;
if (ctrl->saved_regs) {
_memcpy_toio(lbc, ctrl->saved_regs,
@@ -379,7 +396,9 @@ static int fsl_lbc_resume(struct platform_device *pdev)
kfree(ctrl->saved_regs);
ctrl->saved_regs = NULL;
}
- return 0;
+
+out:
+ return;
}
#endif /* CONFIG_SUSPEND */
@@ -391,20 +410,26 @@ static const struct of_device_id fsl_lbc_match[] = {
{},
};
+#ifdef CONFIG_SUSPEND
+static struct syscore_ops lbc_syscore_pm_ops = {
+ .suspend = fsl_lbc_syscore_suspend,
+ .resume = fsl_lbc_syscore_resume,
+};
+#endif
+
static struct platform_driver fsl_lbc_ctrl_driver = {
.driver = {
.name = "fsl-lbc",
.of_match_table = fsl_lbc_match,
},
.probe = fsl_lbc_ctrl_probe,
-#ifdef CONFIG_SUSPEND
- .suspend = fsl_lbc_suspend,
- .resume = fsl_lbc_resume,
-#endif
};
static int __init fsl_lbc_init(void)
{
+#ifdef CONFIG_SUSPEND
+ register_syscore_ops(&lbc_syscore_pm_ops);
+#endif
return platform_driver_register(&fsl_lbc_ctrl_driver);
}
subsys_initcall(fsl_lbc_init);
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 48a576a..3a2be36 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -110,7 +110,7 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
int rc, hwirq;
rc = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS_MAX,
- msi_data->irqhost->of_node);
+ irq_domain_get_of_node(msi_data->irqhost));
if (rc)
return rc;
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ebc1f412..85729f4 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -21,10 +21,12 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/string.h>
+#include <linux/fsl/edac.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
#include <linux/log2.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
@@ -179,6 +181,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
return i;
}
+static bool is_kdump(void)
+{
+ struct device_node *node;
+
+ node = of_find_node_by_type(NULL, "memory");
+ if (!node) {
+ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ return of_property_read_bool(node, "linux,usable-memory");
+}
+
/* atmu setup for fsl pci/pcie controller */
static void setup_pci_atmu(struct pci_controller *hose)
{
@@ -192,6 +207,29 @@ static void setup_pci_atmu(struct pci_controller *hose)
const char *name = hose->dn->full_name;
const u64 *reg;
int len;
+ bool setup_inbound;
+
+ /*
+ * If this is kdump, we don't want to trigger a bunch of PCI
+ * errors by closing the window on in-flight DMA.
+ *
+ * We still run most of the function's logic so that things like
+ * hose->dma_window_size still get set.
+ */
+ setup_inbound = !is_kdump();
+
+ if (of_device_is_compatible(hose->dn, "fsl,bsc9132-pcie")) {
+ /*
+ * BSC9132 Rev1.0 has an issue where all the PEX inbound
+ * windows have implemented the default target value as 0xf
+ * for CCSR space.In all Freescale legacy devices the target
+ * of 0xf is reserved for local memory space. 9132 Rev1.0
+ * now has local mempry space mapped to target 0x0 instead of
+ * 0xf. Hence adding a workaround to remove the target 0xf
+ * defined for memory space from Inbound window attributes.
+ */
+ piwar &= ~PIWAR_TGI_LOCAL;
+ }
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
@@ -204,8 +242,11 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0);
- for (i = start_idx; i < end_idx; i++)
- out_be32(&pci->piw[i].piwar, 0);
+
+ if (setup_inbound) {
+ for (i = start_idx; i < end_idx; i++)
+ out_be32(&pci->piw[i].piwar, 0);
+ }
/* Setup outbound MEM window */
for(i = 0, j = 1; i < 3; i++) {
@@ -278,6 +319,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Setup inbound mem window */
mem = memblock_end_of_DRAM();
+ pr_info("%s: end of DRAM %llx\n", __func__, mem);
/*
* The msi-address-64 property, if it exists, indicates the physical
@@ -320,12 +362,14 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
hose->dma_window_base_cur = 0x00000000;
hose->dma_window_size = (resource_size_t)sz;
@@ -343,13 +387,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbear,
- pci64_dma_offset >> 44);
- out_be32(&pci->piw[win_idx].piwbar,
- pci64_dma_offset >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbear,
+ pci64_dma_offset >> 44);
+ out_be32(&pci->piw[win_idx].piwbar,
+ pci64_dma_offset >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
/*
* install our own dma_set_mask handler to fixup dma_ops
@@ -362,12 +408,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
} else {
u64 paddr = 0;
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar,
+ (piwar | (mem_log - 1)));
+ }
+ win_idx--;
paddr += 1ull << mem_log;
sz -= 1ull << mem_log;
@@ -375,11 +424,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log = ilog2(sz);
piwar |= (mem_log - 1);
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ out_be32(&pci->piw[win_idx].pitar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
paddr += 1ull << mem_log;
}
@@ -522,7 +575,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
/* use fsl_indirect_read_config for PCIe */
hose->ops = &fsl_indirect_pcie_ops;
- /* For PCIE read HEADER_TYPE to identify controler mode */
+ /* For PCIE read HEADER_TYPE to identify controller mode */
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
goto no_bridge;
@@ -999,10 +1052,10 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
ret = get_user(regs->nip, &inst);
pagefault_enable();
} else {
- ret = probe_kernel_address(regs->nip, inst);
+ ret = probe_kernel_address((void *)regs->nip, inst);
}
- if (mcheck_handle_load(regs, inst)) {
+ if (!ret && mcheck_handle_load(regs, inst)) {
regs->nip += 4;
return 1;
}
@@ -1217,6 +1270,25 @@ void fsl_pcibios_fixup_phb(struct pci_controller *phb)
#endif
}
+static int add_err_dev(struct platform_device *pdev)
+{
+ struct platform_device *errdev;
+ struct mpc85xx_edac_pci_plat_data pd = {
+ .of_node = pdev->dev.of_node
+ };
+
+ errdev = platform_device_register_resndata(&pdev->dev,
+ "mpc85xx-pci-edac",
+ PLATFORM_DEVID_AUTO,
+ pdev->resource,
+ pdev->num_resources,
+ &pd, sizeof(pd));
+ if (IS_ERR(errdev))
+ return PTR_ERR(errdev);
+
+ return 0;
+}
+
static int fsl_pci_probe(struct platform_device *pdev)
{
struct device_node *node;
@@ -1224,8 +1296,13 @@ static int fsl_pci_probe(struct platform_device *pdev)
node = pdev->dev.of_node;
ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+ if (ret)
+ return ret;
- mpc85xx_pci_err_probe(pdev);
+ ret = add_err_dev(pdev);
+ if (ret)
+ dev_err(&pdev->dev, "couldn't register error device: %d\n",
+ ret);
return 0;
}
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index c1cec77..1515885 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -130,15 +130,6 @@ void fsl_pci_assign_primary(void);
static inline void fsl_pci_assign_primary(void) {}
#endif
-#ifdef CONFIG_EDAC_MPC85XX
-int mpc85xx_pci_err_probe(struct platform_device *op);
-#else
-static inline int mpc85xx_pci_err_probe(struct platform_device *op)
-{
- return -ENOTSUPP;
-}
-#endif
-
#ifdef CONFIG_FSL_PCI
extern int fsl_pci_mcheck_exception(struct pt_regs *);
#else
diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c
new file mode 100644
index 0000000..9259a94
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_rcpm.c
@@ -0,0 +1,386 @@
+/*
+ * RCPM(Run Control/Power Management) support
+ *
+ * Copyright 2012-2015 Freescale Semiconductor Inc.
+ *
+ * Author: Chenhui Zhao <chenhui.zhao@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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/of_address.h>
+#include <linux/export.h>
+
+#include <asm/io.h>
+#include <linux/fsl/guts.h>
+#include <asm/cputhreads.h>
+#include <asm/fsl_pm.h>
+#include <asm/smp.h>
+
+static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs;
+static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs;
+static unsigned int fsl_supported_pm_modes;
+
+static void rcpm_v1_irq_mask(int cpu)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ setbits32(&rcpm_v1_regs->cpmimr, mask);
+ setbits32(&rcpm_v1_regs->cpmcimr, mask);
+ setbits32(&rcpm_v1_regs->cpmmcmr, mask);
+ setbits32(&rcpm_v1_regs->cpmnmimr, mask);
+}
+
+static void rcpm_v2_irq_mask(int cpu)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ setbits32(&rcpm_v2_regs->tpmimr0, mask);
+ setbits32(&rcpm_v2_regs->tpmcimr0, mask);
+ setbits32(&rcpm_v2_regs->tpmmcmr0, mask);
+ setbits32(&rcpm_v2_regs->tpmnmimr0, mask);
+}
+
+static void rcpm_v1_irq_unmask(int cpu)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ clrbits32(&rcpm_v1_regs->cpmimr, mask);
+ clrbits32(&rcpm_v1_regs->cpmcimr, mask);
+ clrbits32(&rcpm_v1_regs->cpmmcmr, mask);
+ clrbits32(&rcpm_v1_regs->cpmnmimr, mask);
+}
+
+static void rcpm_v2_irq_unmask(int cpu)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ clrbits32(&rcpm_v2_regs->tpmimr0, mask);
+ clrbits32(&rcpm_v2_regs->tpmcimr0, mask);
+ clrbits32(&rcpm_v2_regs->tpmmcmr0, mask);
+ clrbits32(&rcpm_v2_regs->tpmnmimr0, mask);
+}
+
+static void rcpm_v1_set_ip_power(bool enable, u32 mask)
+{
+ if (enable)
+ setbits32(&rcpm_v1_regs->ippdexpcr, mask);
+ else
+ clrbits32(&rcpm_v1_regs->ippdexpcr, mask);
+}
+
+static void rcpm_v2_set_ip_power(bool enable, u32 mask)
+{
+ if (enable)
+ setbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
+ else
+ clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
+}
+
+static void rcpm_v1_cpu_enter_state(int cpu, int state)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ switch (state) {
+ case E500_PM_PH10:
+ setbits32(&rcpm_v1_regs->cdozcr, mask);
+ break;
+ case E500_PM_PH15:
+ setbits32(&rcpm_v1_regs->cnapcr, mask);
+ break;
+ default:
+ pr_warn("Unknown cpu PM state (%d)\n", state);
+ break;
+ }
+}
+
+static void rcpm_v2_cpu_enter_state(int cpu, int state)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ u32 mask = 1 << cpu_core_index_of_thread(cpu);
+
+ switch (state) {
+ case E500_PM_PH10:
+ /* one bit corresponds to one thread for PH10 of 6500 */
+ setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
+ break;
+ case E500_PM_PH15:
+ setbits32(&rcpm_v2_regs->pcph15setr, mask);
+ break;
+ case E500_PM_PH20:
+ setbits32(&rcpm_v2_regs->pcph20setr, mask);
+ break;
+ case E500_PM_PH30:
+ setbits32(&rcpm_v2_regs->pcph30setr, mask);
+ break;
+ default:
+ pr_warn("Unknown cpu PM state (%d)\n", state);
+ }
+}
+
+static void rcpm_v1_cpu_die(int cpu)
+{
+ rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15);
+}
+
+#ifdef CONFIG_PPC64
+static void qoriq_disable_thread(int cpu)
+{
+ int thread = cpu_thread_in_core(cpu);
+
+ book3e_stop_thread(thread);
+}
+#endif
+
+static void rcpm_v2_cpu_die(int cpu)
+{
+#ifdef CONFIG_PPC64
+ int primary;
+
+ if (threads_per_core == 2) {
+ primary = cpu_first_thread_sibling(cpu);
+ if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) {
+ /* if both threads are offline, put the cpu in PH20 */
+ rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
+ } else {
+ /* if only one thread is offline, disable the thread */
+ qoriq_disable_thread(cpu);
+ }
+ }
+#endif
+
+ if (threads_per_core == 1)
+ rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20);
+}
+
+static void rcpm_v1_cpu_exit_state(int cpu, int state)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ unsigned int mask = 1 << hw_cpu;
+
+ switch (state) {
+ case E500_PM_PH10:
+ clrbits32(&rcpm_v1_regs->cdozcr, mask);
+ break;
+ case E500_PM_PH15:
+ clrbits32(&rcpm_v1_regs->cnapcr, mask);
+ break;
+ default:
+ pr_warn("Unknown cpu PM state (%d)\n", state);
+ break;
+ }
+}
+
+static void rcpm_v1_cpu_up_prepare(int cpu)
+{
+ rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15);
+ rcpm_v1_irq_unmask(cpu);
+}
+
+static void rcpm_v2_cpu_exit_state(int cpu, int state)
+{
+ int hw_cpu = get_hard_smp_processor_id(cpu);
+ u32 mask = 1 << cpu_core_index_of_thread(cpu);
+
+ switch (state) {
+ case E500_PM_PH10:
+ setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
+ break;
+ case E500_PM_PH15:
+ setbits32(&rcpm_v2_regs->pcph15clrr, mask);
+ break;
+ case E500_PM_PH20:
+ setbits32(&rcpm_v2_regs->pcph20clrr, mask);
+ break;
+ case E500_PM_PH30:
+ setbits32(&rcpm_v2_regs->pcph30clrr, mask);
+ break;
+ default:
+ pr_warn("Unknown cpu PM state (%d)\n", state);
+ }
+}
+
+static void rcpm_v2_cpu_up_prepare(int cpu)
+{
+ rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20);
+ rcpm_v2_irq_unmask(cpu);
+}
+
+static int rcpm_v1_plat_enter_state(int state)
+{
+ u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr;
+ int ret = 0;
+ int result;
+
+ switch (state) {
+ case PLAT_PM_SLEEP:
+ setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
+
+ /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
+ result = spin_event_timeout(
+ !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10);
+ if (!result) {
+ pr_err("timeout waiting for SLP bit to be cleared\n");
+ ret = -ETIMEDOUT;
+ }
+ break;
+ default:
+ pr_warn("Unknown platform PM state (%d)", state);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int rcpm_v2_plat_enter_state(int state)
+{
+ u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr;
+ int ret = 0;
+ int result;
+
+ switch (state) {
+ case PLAT_PM_LPM20:
+ /* clear previous LPM20 status */
+ setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
+ /* enter LPM20 status */
+ setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
+
+ /* At this point, the device is in LPM20 status. */
+
+ /* resume ... */
+ result = spin_event_timeout(
+ !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10);
+ if (!result) {
+ pr_err("timeout waiting for LPM20 bit to be cleared\n");
+ ret = -ETIMEDOUT;
+ }
+ break;
+ default:
+ pr_warn("Unknown platform PM state (%d)\n", state);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int rcpm_v1_plat_enter_sleep(void)
+{
+ return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP);
+}
+
+static int rcpm_v2_plat_enter_sleep(void)
+{
+ return rcpm_v2_plat_enter_state(PLAT_PM_LPM20);
+}
+
+static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze)
+{
+ static u32 mask;
+
+ if (freeze) {
+ mask = in_be32(tben_reg);
+ clrbits32(tben_reg, mask);
+ } else {
+ setbits32(tben_reg, mask);
+ }
+
+ /* read back to push the previous write */
+ in_be32(tben_reg);
+}
+
+static void rcpm_v1_freeze_time_base(bool freeze)
+{
+ rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze);
+}
+
+static void rcpm_v2_freeze_time_base(bool freeze)
+{
+ rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze);
+}
+
+static unsigned int rcpm_get_pm_modes(void)
+{
+ return fsl_supported_pm_modes;
+}
+
+static const struct fsl_pm_ops qoriq_rcpm_v1_ops = {
+ .irq_mask = rcpm_v1_irq_mask,
+ .irq_unmask = rcpm_v1_irq_unmask,
+ .cpu_enter_state = rcpm_v1_cpu_enter_state,
+ .cpu_exit_state = rcpm_v1_cpu_exit_state,
+ .cpu_up_prepare = rcpm_v1_cpu_up_prepare,
+ .cpu_die = rcpm_v1_cpu_die,
+ .plat_enter_sleep = rcpm_v1_plat_enter_sleep,
+ .set_ip_power = rcpm_v1_set_ip_power,
+ .freeze_time_base = rcpm_v1_freeze_time_base,
+ .get_pm_modes = rcpm_get_pm_modes,
+};
+
+static const struct fsl_pm_ops qoriq_rcpm_v2_ops = {
+ .irq_mask = rcpm_v2_irq_mask,
+ .irq_unmask = rcpm_v2_irq_unmask,
+ .cpu_enter_state = rcpm_v2_cpu_enter_state,
+ .cpu_exit_state = rcpm_v2_cpu_exit_state,
+ .cpu_up_prepare = rcpm_v2_cpu_up_prepare,
+ .cpu_die = rcpm_v2_cpu_die,
+ .plat_enter_sleep = rcpm_v2_plat_enter_sleep,
+ .set_ip_power = rcpm_v2_set_ip_power,
+ .freeze_time_base = rcpm_v2_freeze_time_base,
+ .get_pm_modes = rcpm_get_pm_modes,
+};
+
+static const struct of_device_id rcpm_matches[] = {
+ {
+ .compatible = "fsl,qoriq-rcpm-1.0",
+ .data = &qoriq_rcpm_v1_ops,
+ },
+ {
+ .compatible = "fsl,qoriq-rcpm-2.0",
+ .data = &qoriq_rcpm_v2_ops,
+ },
+ {
+ .compatible = "fsl,qoriq-rcpm-2.1",
+ .data = &qoriq_rcpm_v2_ops,
+ },
+ {},
+};
+
+int __init fsl_rcpm_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ void __iomem *base;
+
+ np = of_find_matching_node_and_match(NULL, rcpm_matches, &match);
+ if (!np)
+ return 0;
+
+ base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!base) {
+ pr_err("of_iomap() error.\n");
+ return -ENOMEM;
+ }
+
+ rcpm_v1_regs = base;
+ rcpm_v2_regs = base;
+
+ /* support sleep by default */
+ fsl_supported_pm_modes = FSL_PM_SLEEP;
+
+ qoriq_pm_ops = match->data;
+
+ return 0;
+}
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c
index b48197a..ffe0ee8 100644
--- a/arch/powerpc/sysdev/fsl_rmu.c
+++ b/arch/powerpc/sysdev/fsl_rmu.c
@@ -570,7 +570,7 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw)
out_be32(&pw->pw_regs->pwsr,
(RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
- /* Configure port write contoller for snooping enable all reporting,
+ /* Configure port write controller for snooping enable all reporting,
clear queue full */
out_be32(&pw->pw_regs->pwmr,
RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ);
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index e1a9c2c..aa2c186 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -165,7 +165,8 @@ static struct resource pic_edgectrl_iores = {
static int i8259_host_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int i8259_host_map(struct irq_domain *h, unsigned int virq,
@@ -237,7 +238,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
/* init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
outb(0x00, 0x21); /* Vector base */
- outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+ outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */
outb(0x01, 0x21); /* Select 8086 mode */
/* init slave interrupt controller */
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index b1297ab..f76ee39 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -675,7 +675,8 @@ static int ipic_host_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
/* Exact match, unless ipic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int ipic_host_map(struct irq_domain *h, unsigned int virq,
diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c
index f4f0301..5732926 100644
--- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
+++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
@@ -13,7 +13,6 @@
unsigned long mpc5xxx_get_bus_frequency(struct device_node *node)
{
- struct device_node *np;
const unsigned int *p_bus_freq = NULL;
of_node_get(node);
@@ -22,9 +21,7 @@ unsigned long mpc5xxx_get_bus_frequency(struct device_node *node)
if (p_bus_freq)
break;
- np = of_get_parent(node);
- of_node_put(node);
- node = np;
+ node = of_get_next_parent(node);
}
of_node_put(node);
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 9a42397..b7cf7ab 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -61,7 +61,7 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
}
static struct irq_chip mpc8xx_pic = {
- .name = "MPC8XX SIU",
+ .name = "8XX SIU",
.irq_unmask = mpc8xx_unmask_irq,
.irq_mask = mpc8xx_mask_irq,
.irq_ack = mpc8xx_ack,
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 537e5db..afe3c7c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -2,7 +2,7 @@
* arch/powerpc/kernel/mpic.c
*
* Driver for interrupt controllers following the OpenPIC standard, the
- * common implementation beeing IBM's MPIC. This driver also can deal
+ * common implementation being IBM's MPIC. This driver also can deal
* with various broken implementations of this HW.
*
* Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
@@ -924,22 +924,6 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
return IRQ_SET_MASK_OK_NOCOPY;
}
-static int mpic_irq_set_wake(struct irq_data *d, unsigned int on)
-{
- struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
- struct mpic *mpic = mpic_from_irq_data(d);
-
- if (!(mpic->flags & MPIC_FSL))
- return -ENXIO;
-
- if (on)
- desc->action->flags |= IRQF_NO_SUSPEND;
- else
- desc->action->flags &= ~IRQF_NO_SUSPEND;
-
- return 0;
-}
-
void mpic_set_vector(unsigned int virq, unsigned int vector)
{
struct mpic *mpic = mpic_from_irq(virq);
@@ -977,7 +961,6 @@ static struct irq_chip mpic_irq_chip = {
.irq_unmask = mpic_unmask_irq,
.irq_eoi = mpic_end_irq,
.irq_set_type = mpic_set_irq_type,
- .irq_set_wake = mpic_irq_set_wake,
};
#ifdef CONFIG_SMP
@@ -992,7 +975,6 @@ static struct irq_chip mpic_tm_chip = {
.irq_mask = mpic_mask_tm,
.irq_unmask = mpic_unmask_tm,
.irq_eoi = mpic_end_irq,
- .irq_set_wake = mpic_irq_set_wake,
};
#ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -1011,7 +993,8 @@ static int mpic_host_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
/* Exact match, unless mpic node is NULL */
- return h->of_node == NULL || h->of_node == node;
+ struct device_node *of_node = irq_domain_get_of_node(h);
+ return of_node == NULL || of_node == node;
}
static int mpic_host_map(struct irq_domain *h, unsigned int virq,
@@ -1283,8 +1266,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
flags |= MPIC_NO_RESET;
if (of_get_property(node, "single-cpu-affinity", NULL))
flags |= MPIC_SINGLE_DEST_CPU;
- if (of_device_is_compatible(node, "fsl,mpic"))
+ if (of_device_is_compatible(node, "fsl,mpic")) {
flags |= MPIC_FSL | MPIC_LARGE_VECTORS;
+ mpic_irq_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
+ mpic_tm_chip.flags |= IRQCHIP_SKIP_SET_WAKE;
+ }
mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
if (mpic == NULL)
@@ -1671,7 +1657,7 @@ void __init mpic_init(struct mpic *mpic)
}
}
- /* FSL mpic error interrupt intialization */
+ /* FSL mpic error interrupt initialization */
if (mpic->flags & MPIC_FSL_HAS_EIMR)
mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);
}
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 7dc39f3..1d48a53 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -84,7 +84,7 @@ int mpic_msi_init_allocator(struct mpic *mpic)
int rc;
rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->num_sources,
- mpic->irqhost->of_node);
+ irq_domain_get_of_node(mpic->irqhost));
if (rc)
return rc;
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
index 73b64c7..ed5234e 100644
--- a/arch/powerpc/sysdev/msi_bitmap.c
+++ b/arch/powerpc/sysdev/msi_bitmap.c
@@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitmap.h>
+#include <linux/bootmem.h>
#include <asm/msi_bitmap.h>
#include <asm/setup.h>
@@ -111,7 +112,7 @@ int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp)
return 0;
}
-int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
+int __init_refok msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
struct device_node *of_node)
{
int size;
@@ -122,7 +123,15 @@ int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
size = BITS_TO_LONGS(irq_count) * sizeof(long);
pr_debug("msi_bitmap: allocator bitmap size is 0x%x bytes\n", size);
- bmp->bitmap = zalloc_maybe_bootmem(size, GFP_KERNEL);
+ bmp->bitmap_from_slab = slab_is_available();
+ if (bmp->bitmap_from_slab)
+ bmp->bitmap = kzalloc(size, GFP_KERNEL);
+ else {
+ bmp->bitmap = memblock_virt_alloc(size, 0);
+ /* the bitmap won't be freed from memblock allocator */
+ kmemleak_not_leak(bmp->bitmap);
+ }
+
if (!bmp->bitmap) {
pr_debug("msi_bitmap: ENOMEM allocating allocator bitmap!\n");
return -ENOMEM;
@@ -138,7 +147,8 @@ int msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
void msi_bitmap_free(struct msi_bitmap *bmp)
{
- /* we can't free the bitmap we don't know if it's bootmem etc. */
+ if (bmp->bitmap_from_slab)
+ kfree(bmp->bitmap);
of_node_put(bmp->of_node);
bmp->bitmap = NULL;
}
@@ -203,8 +213,6 @@ static void __init test_basics(void)
/* Clients may WARN_ON bitmap == NULL for "not-allocated" */
WARN_ON(bmp.bitmap != NULL);
-
- kfree(bmp.bitmap);
}
static void __init test_of_node(void)
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c
index fc65ad1..d7a7ef13 100644
--- a/arch/powerpc/sysdev/ppc4xx_gpio.c
+++ b/arch/powerpc/sysdev/ppc4xx_gpio.c
@@ -78,7 +78,7 @@ static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
- return in_be32(&regs->ir) & GPIO_MASK(gpio);
+ return !!(in_be32(&regs->ir) & GPIO_MASK(gpio));
}
static inline void
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
deleted file mode 100644
index 3c25199..0000000
--- a/arch/powerpc/sysdev/qe_lib/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# QE Communication options
-#
-
-config UCC_SLOW
- bool
- default y if SERIAL_QE
- help
- This option provides qe_lib support to UCC slow
- protocols: UART, BISYNC, QMC
-
-config UCC_FAST
- bool
- default y if UCC_GETH
- help
- This option provides qe_lib support to UCC fast
- protocols: HDLC, Ethernet, ATM, transparent
-
-config UCC
- bool
- default y if UCC_FAST || UCC_SLOW
-
-config QE_USB
- bool
- default y if USB_FSL_QE
- help
- QE USB Controller support
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile
deleted file mode 100644
index f1855c1..0000000
--- a/arch/powerpc/sysdev/qe_lib/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the linux ppc-specific parts of QE
-#
-obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
-
-obj-$(CONFIG_UCC) += ucc.o
-obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
-obj-$(CONFIG_UCC_FAST) += ucc_fast.o
-obj-$(CONFIG_QE_USB) += usb.o
-obj-$(CONFIG_QE_GPIO) += gpio.o
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
deleted file mode 100644
index 521e67a..0000000
--- a/arch/powerpc/sysdev/qe_lib/gpio.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * QUICC Engine GPIOs
- *
- * Copyright (c) MontaVista Software, Inc. 2008.
- *
- * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <asm/qe.h>
-
-struct qe_gpio_chip {
- struct of_mm_gpio_chip mm_gc;
- spinlock_t lock;
-
- unsigned long pin_flags[QE_PIO_PINS];
-#define QE_PIN_REQUESTED 0
-
- /* shadowed data register to clear/set bits safely */
- u32 cpdata;
-
- /* saved_regs used to restore dedicated functions */
- struct qe_pio_regs saved_regs;
-};
-
-static inline struct qe_gpio_chip *
-to_qe_gpio_chip(struct of_mm_gpio_chip *mm_gc)
-{
- return container_of(mm_gc, struct qe_gpio_chip, mm_gc);
-}
-
-static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
-{
- struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
- struct qe_pio_regs __iomem *regs = mm_gc->regs;
-
- qe_gc->cpdata = in_be32(&regs->cpdata);
- qe_gc->saved_regs.cpdata = qe_gc->cpdata;
- qe_gc->saved_regs.cpdir1 = in_be32(&regs->cpdir1);
- qe_gc->saved_regs.cpdir2 = in_be32(&regs->cpdir2);
- qe_gc->saved_regs.cppar1 = in_be32(&regs->cppar1);
- qe_gc->saved_regs.cppar2 = in_be32(&regs->cppar2);
- qe_gc->saved_regs.cpodr = in_be32(&regs->cpodr);
-}
-
-static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct qe_pio_regs __iomem *regs = mm_gc->regs;
- u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
-
- return in_be32(&regs->cpdata) & pin_mask;
-}
-
-static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
- struct qe_pio_regs __iomem *regs = mm_gc->regs;
- unsigned long flags;
- u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- if (val)
- qe_gc->cpdata |= pin_mask;
- else
- qe_gc->cpdata &= ~pin_mask;
-
- out_be32(&regs->cpdata, qe_gc->cpdata);
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-}
-
-static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
- unsigned long flags;
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0);
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-
- return 0;
-}
-
-static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
- unsigned long flags;
-
- qe_gpio_set(gc, gpio, val);
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-
- return 0;
-}
-
-struct qe_pin {
- /*
- * The qe_gpio_chip name is unfortunate, we should change that to
- * something like qe_pio_controller. Someday.
- */
- struct qe_gpio_chip *controller;
- int num;
-};
-
-/**
- * qe_pin_request - Request a QE pin
- * @np: device node to get a pin from
- * @index: index of a pin in the device tree
- * Context: non-atomic
- *
- * This function return qe_pin so that you could use it with the rest of
- * the QE Pin Multiplexing API.
- */
-struct qe_pin *qe_pin_request(struct device_node *np, int index)
-{
- struct qe_pin *qe_pin;
- struct gpio_chip *gc;
- struct of_mm_gpio_chip *mm_gc;
- struct qe_gpio_chip *qe_gc;
- int err;
- unsigned long flags;
-
- qe_pin = kzalloc(sizeof(*qe_pin), GFP_KERNEL);
- if (!qe_pin) {
- pr_debug("%s: can't allocate memory\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
-
- err = of_get_gpio(np, index);
- if (err < 0)
- goto err0;
- gc = gpio_to_chip(err);
- if (WARN_ON(!gc))
- goto err0;
-
- if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) {
- pr_debug("%s: tried to get a non-qe pin\n", __func__);
- err = -EINVAL;
- goto err0;
- }
-
- mm_gc = to_of_mm_gpio_chip(gc);
- qe_gc = to_qe_gpio_chip(mm_gc);
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- err -= gc->base;
- if (test_and_set_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[err]) == 0) {
- qe_pin->controller = qe_gc;
- qe_pin->num = err;
- err = 0;
- } else {
- err = -EBUSY;
- }
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-
- if (!err)
- return qe_pin;
-err0:
- kfree(qe_pin);
- pr_debug("%s failed with status %d\n", __func__, err);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(qe_pin_request);
-
-/**
- * qe_pin_free - Free a pin
- * @qe_pin: pointer to the qe_pin structure
- * Context: any
- *
- * This function frees the qe_pin structure and makes a pin available
- * for further qe_pin_request() calls.
- */
-void qe_pin_free(struct qe_pin *qe_pin)
-{
- struct qe_gpio_chip *qe_gc = qe_pin->controller;
- unsigned long flags;
- const int pin = qe_pin->num;
-
- spin_lock_irqsave(&qe_gc->lock, flags);
- test_and_clear_bit(QE_PIN_REQUESTED, &qe_gc->pin_flags[pin]);
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-
- kfree(qe_pin);
-}
-EXPORT_SYMBOL(qe_pin_free);
-
-/**
- * qe_pin_set_dedicated - Revert a pin to a dedicated peripheral function mode
- * @qe_pin: pointer to the qe_pin structure
- * Context: any
- *
- * This function resets a pin to a dedicated peripheral function that
- * has been set up by the firmware.
- */
-void qe_pin_set_dedicated(struct qe_pin *qe_pin)
-{
- struct qe_gpio_chip *qe_gc = qe_pin->controller;
- struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;
- struct qe_pio_regs *sregs = &qe_gc->saved_regs;
- int pin = qe_pin->num;
- u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1));
- u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2);
- bool second_reg = pin > (QE_PIO_PINS / 2) - 1;
- unsigned long flags;
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- if (second_reg) {
- clrsetbits_be32(&regs->cpdir2, mask2, sregs->cpdir2 & mask2);
- clrsetbits_be32(&regs->cppar2, mask2, sregs->cppar2 & mask2);
- } else {
- clrsetbits_be32(&regs->cpdir1, mask2, sregs->cpdir1 & mask2);
- clrsetbits_be32(&regs->cppar1, mask2, sregs->cppar1 & mask2);
- }
-
- if (sregs->cpdata & mask1)
- qe_gc->cpdata |= mask1;
- else
- qe_gc->cpdata &= ~mask1;
-
- out_be32(&regs->cpdata, qe_gc->cpdata);
- clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-}
-EXPORT_SYMBOL(qe_pin_set_dedicated);
-
-/**
- * qe_pin_set_gpio - Set a pin to the GPIO mode
- * @qe_pin: pointer to the qe_pin structure
- * Context: any
- *
- * This function sets a pin to the GPIO mode.
- */
-void qe_pin_set_gpio(struct qe_pin *qe_pin)
-{
- struct qe_gpio_chip *qe_gc = qe_pin->controller;
- struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;
- unsigned long flags;
-
- spin_lock_irqsave(&qe_gc->lock, flags);
-
- /* Let's make it input by default, GPIO API is able to change that. */
- __par_io_config_pin(regs, qe_pin->num, QE_PIO_DIR_IN, 0, 0, 0);
-
- spin_unlock_irqrestore(&qe_gc->lock, flags);
-}
-EXPORT_SYMBOL(qe_pin_set_gpio);
-
-static int __init qe_add_gpiochips(void)
-{
- struct device_node *np;
-
- for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") {
- int ret;
- struct qe_gpio_chip *qe_gc;
- struct of_mm_gpio_chip *mm_gc;
- struct gpio_chip *gc;
-
- qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
- if (!qe_gc) {
- ret = -ENOMEM;
- goto err;
- }
-
- spin_lock_init(&qe_gc->lock);
-
- mm_gc = &qe_gc->mm_gc;
- gc = &mm_gc->gc;
-
- mm_gc->save_regs = qe_gpio_save_regs;
- gc->ngpio = QE_PIO_PINS;
- gc->direction_input = qe_gpio_dir_in;
- gc->direction_output = qe_gpio_dir_out;
- gc->get = qe_gpio_get;
- gc->set = qe_gpio_set;
-
- ret = of_mm_gpiochip_add(np, mm_gc);
- if (ret)
- goto err;
- continue;
-err:
- pr_err("%s: registration failed with status %d\n",
- np->full_name, ret);
- kfree(qe_gc);
- /* try others anyway */
- }
- return 0;
-}
-arch_initcall(qe_add_gpiochips);
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
deleted file mode 100644
index c2518cd..0000000
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
- *
- * Description:
- * General Purpose functions for the global management of the
- * QUICC Engine (QE).
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/crc32.h>
-#include <linux/mod_devicetable.h>
-#include <linux/of_platform.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-#include <asm/prom.h>
-#include <asm/rheap.h>
-
-static void qe_snums_init(void);
-static int qe_sdma_init(void);
-
-static DEFINE_SPINLOCK(qe_lock);
-DEFINE_SPINLOCK(cmxgcr_lock);
-EXPORT_SYMBOL(cmxgcr_lock);
-
-/* QE snum state */
-enum qe_snum_state {
- QE_SNUM_STATE_USED,
- QE_SNUM_STATE_FREE
-};
-
-/* QE snum */
-struct qe_snum {
- u8 num;
- enum qe_snum_state state;
-};
-
-/* We allocate this here because it is used almost exclusively for
- * the communication processor devices.
- */
-struct qe_immap __iomem *qe_immr;
-EXPORT_SYMBOL(qe_immr);
-
-static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
-static unsigned int qe_num_of_snum;
-
-static phys_addr_t qebase = -1;
-
-phys_addr_t get_qe_base(void)
-{
- struct device_node *qe;
- int size;
- const u32 *prop;
-
- if (qebase != -1)
- return qebase;
-
- qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!qe) {
- qe = of_find_node_by_type(NULL, "qe");
- if (!qe)
- return qebase;
- }
-
- prop = of_get_property(qe, "reg", &size);
- if (prop && size >= sizeof(*prop))
- qebase = of_translate_address(qe, prop);
- of_node_put(qe);
-
- return qebase;
-}
-
-EXPORT_SYMBOL(get_qe_base);
-
-void qe_reset(void)
-{
- if (qe_immr == NULL)
- qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
-
- qe_snums_init();
-
- qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
- QE_CR_PROTOCOL_UNSPECIFIED, 0);
-
- /* Reclaim the MURAM memory for our use. */
- qe_muram_init();
-
- if (qe_sdma_init())
- panic("sdma init failed!");
-}
-
-int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
-{
- unsigned long flags;
- u8 mcn_shift = 0, dev_shift = 0;
- u32 ret;
-
- spin_lock_irqsave(&qe_lock, flags);
- if (cmd == QE_RESET) {
- out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
- } else {
- if (cmd == QE_ASSIGN_PAGE) {
- /* Here device is the SNUM, not sub-block */
- dev_shift = QE_CR_SNUM_SHIFT;
- } else if (cmd == QE_ASSIGN_RISC) {
- /* Here device is the SNUM, and mcnProtocol is
- * e_QeCmdRiscAssignment value */
- dev_shift = QE_CR_SNUM_SHIFT;
- mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
- } else {
- if (device == QE_CR_SUBBLOCK_USB)
- mcn_shift = QE_CR_MCN_USB_SHIFT;
- else
- mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
- }
-
- out_be32(&qe_immr->cp.cecdr, cmd_input);
- out_be32(&qe_immr->cp.cecr,
- (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
- mcn_protocol << mcn_shift));
- }
-
- /* wait for the QE_CR_FLG to clear */
- ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
- 100, 0);
- /* On timeout (e.g. failure), the expression will be false (ret == 0),
- otherwise it will be true (ret == 1). */
- spin_unlock_irqrestore(&qe_lock, flags);
-
- return ret == 1;
-}
-EXPORT_SYMBOL(qe_issue_cmd);
-
-/* Set a baud rate generator. This needs lots of work. There are
- * 16 BRGs, which can be connected to the QE channels or output
- * as clocks. The BRGs are in two different block of internal
- * memory mapped space.
- * The BRG clock is the QE clock divided by 2.
- * It was set up long ago during the initial boot phase and is
- * is given to us.
- * Baud rate clocks are zero-based in the driver code (as that maps
- * to port numbers). Documentation uses 1-based numbering.
- */
-static unsigned int brg_clk = 0;
-
-unsigned int qe_get_brg_clk(void)
-{
- struct device_node *qe;
- int size;
- const u32 *prop;
-
- if (brg_clk)
- return brg_clk;
-
- qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!qe) {
- qe = of_find_node_by_type(NULL, "qe");
- if (!qe)
- return brg_clk;
- }
-
- prop = of_get_property(qe, "brg-frequency", &size);
- if (prop && size == sizeof(*prop))
- brg_clk = *prop;
-
- of_node_put(qe);
-
- return brg_clk;
-}
-EXPORT_SYMBOL(qe_get_brg_clk);
-
-/* Program the BRG to the given sampling rate and multiplier
- *
- * @brg: the BRG, QE_BRG1 - QE_BRG16
- * @rate: the desired sampling rate
- * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
- * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
- * then 'multiplier' should be 8.
- */
-int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
-{
- u32 divisor, tempval;
- u32 div16 = 0;
-
- if ((brg < QE_BRG1) || (brg > QE_BRG16))
- return -EINVAL;
-
- divisor = qe_get_brg_clk() / (rate * multiplier);
-
- if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
- div16 = QE_BRGC_DIV16;
- divisor /= 16;
- }
-
- /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
- that the BRG divisor must be even if you're not using divide-by-16
- mode. */
- if (!div16 && (divisor & 1) && (divisor > 3))
- divisor++;
-
- tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
- QE_BRGC_ENABLE | div16;
-
- out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
-
- return 0;
-}
-EXPORT_SYMBOL(qe_setbrg);
-
-/* Convert a string to a QE clock source enum
- *
- * This function takes a string, typically from a property in the device
- * tree, and returns the corresponding "enum qe_clock" value.
-*/
-enum qe_clock qe_clock_source(const char *source)
-{
- unsigned int i;
-
- if (strcasecmp(source, "none") == 0)
- return QE_CLK_NONE;
-
- if (strncasecmp(source, "brg", 3) == 0) {
- i = simple_strtoul(source + 3, NULL, 10);
- if ((i >= 1) && (i <= 16))
- return (QE_BRG1 - 1) + i;
- else
- return QE_CLK_DUMMY;
- }
-
- if (strncasecmp(source, "clk", 3) == 0) {
- i = simple_strtoul(source + 3, NULL, 10);
- if ((i >= 1) && (i <= 24))
- return (QE_CLK1 - 1) + i;
- else
- return QE_CLK_DUMMY;
- }
-
- return QE_CLK_DUMMY;
-}
-EXPORT_SYMBOL(qe_clock_source);
-
-/* Initialize SNUMs (thread serial numbers) according to
- * QE Module Control chapter, SNUM table
- */
-static void qe_snums_init(void)
-{
- int i;
- static const u8 snum_init_76[] = {
- 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
- 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
- 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
- 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
- 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
- 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
- 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
- 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
- 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
- 0xF4, 0xF5, 0xFC, 0xFD,
- };
- static const u8 snum_init_46[] = {
- 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
- 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
- 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
- 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
- 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
- 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
- };
- static const u8 *snum_init;
-
- qe_num_of_snum = qe_get_num_of_snums();
-
- if (qe_num_of_snum == 76)
- snum_init = snum_init_76;
- else
- snum_init = snum_init_46;
-
- for (i = 0; i < qe_num_of_snum; i++) {
- snums[i].num = snum_init[i];
- snums[i].state = QE_SNUM_STATE_FREE;
- }
-}
-
-int qe_get_snum(void)
-{
- unsigned long flags;
- int snum = -EBUSY;
- int i;
-
- spin_lock_irqsave(&qe_lock, flags);
- for (i = 0; i < qe_num_of_snum; i++) {
- if (snums[i].state == QE_SNUM_STATE_FREE) {
- snums[i].state = QE_SNUM_STATE_USED;
- snum = snums[i].num;
- break;
- }
- }
- spin_unlock_irqrestore(&qe_lock, flags);
-
- return snum;
-}
-EXPORT_SYMBOL(qe_get_snum);
-
-void qe_put_snum(u8 snum)
-{
- int i;
-
- for (i = 0; i < qe_num_of_snum; i++) {
- if (snums[i].num == snum) {
- snums[i].state = QE_SNUM_STATE_FREE;
- break;
- }
- }
-}
-EXPORT_SYMBOL(qe_put_snum);
-
-static int qe_sdma_init(void)
-{
- struct sdma __iomem *sdma = &qe_immr->sdma;
- static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
-
- if (!sdma)
- return -ENODEV;
-
- /* allocate 2 internal temporary buffers (512 bytes size each) for
- * the SDMA */
- if (IS_ERR_VALUE(sdma_buf_offset)) {
- sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
- if (IS_ERR_VALUE(sdma_buf_offset))
- return -ENOMEM;
- }
-
- out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
- out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
- (0x1 << QE_SDMR_CEN_SHIFT)));
-
- return 0;
-}
-
-/* The maximum number of RISCs we support */
-#define MAX_QE_RISC 4
-
-/* Firmware information stored here for qe_get_firmware_info() */
-static struct qe_firmware_info qe_firmware_info;
-
-/*
- * Set to 1 if QE firmware has been uploaded, and therefore
- * qe_firmware_info contains valid data.
- */
-static int qe_firmware_uploaded;
-
-/*
- * Upload a QE microcode
- *
- * This function is a worker function for qe_upload_firmware(). It does
- * the actual uploading of the microcode.
- */
-static void qe_upload_microcode(const void *base,
- const struct qe_microcode *ucode)
-{
- const __be32 *code = base + be32_to_cpu(ucode->code_offset);
- unsigned int i;
-
- if (ucode->major || ucode->minor || ucode->revision)
- printk(KERN_INFO "qe-firmware: "
- "uploading microcode '%s' version %u.%u.%u\n",
- ucode->id, ucode->major, ucode->minor, ucode->revision);
- else
- printk(KERN_INFO "qe-firmware: "
- "uploading microcode '%s'\n", ucode->id);
-
- /* Use auto-increment */
- out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
- QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
-
- for (i = 0; i < be32_to_cpu(ucode->count); i++)
- out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
-
- /* Set I-RAM Ready Register */
- out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
-}
-
-/*
- * Upload a microcode to the I-RAM at a specific address.
- *
- * See Documentation/powerpc/qe_firmware.txt for information on QE microcode
- * uploading.
- *
- * Currently, only version 1 is supported, so the 'version' field must be
- * set to 1.
- *
- * The SOC model and revision are not validated, they are only displayed for
- * informational purposes.
- *
- * 'calc_size' is the calculated size, in bytes, of the firmware structure and
- * all of the microcode structures, minus the CRC.
- *
- * 'length' is the size that the structure says it is, including the CRC.
- */
-int qe_upload_firmware(const struct qe_firmware *firmware)
-{
- unsigned int i;
- unsigned int j;
- u32 crc;
- size_t calc_size = sizeof(struct qe_firmware);
- size_t length;
- const struct qe_header *hdr;
-
- if (!firmware) {
- printk(KERN_ERR "qe-firmware: invalid pointer\n");
- return -EINVAL;
- }
-
- hdr = &firmware->header;
- length = be32_to_cpu(hdr->length);
-
- /* Check the magic */
- if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
- (hdr->magic[2] != 'F')) {
- printk(KERN_ERR "qe-firmware: not a microcode\n");
- return -EPERM;
- }
-
- /* Check the version */
- if (hdr->version != 1) {
- printk(KERN_ERR "qe-firmware: unsupported version\n");
- return -EPERM;
- }
-
- /* Validate some of the fields */
- if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
- printk(KERN_ERR "qe-firmware: invalid data\n");
- return -EINVAL;
- }
-
- /* Validate the length and check if there's a CRC */
- calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
-
- for (i = 0; i < firmware->count; i++)
- /*
- * For situations where the second RISC uses the same microcode
- * as the first, the 'code_offset' and 'count' fields will be
- * zero, so it's okay to add those.
- */
- calc_size += sizeof(__be32) *
- be32_to_cpu(firmware->microcode[i].count);
-
- /* Validate the length */
- if (length != calc_size + sizeof(__be32)) {
- printk(KERN_ERR "qe-firmware: invalid length\n");
- return -EPERM;
- }
-
- /* Validate the CRC */
- crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
- if (crc != crc32(0, firmware, calc_size)) {
- printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
- return -EIO;
- }
-
- /*
- * If the microcode calls for it, split the I-RAM.
- */
- if (!firmware->split)
- setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
-
- if (firmware->soc.model)
- printk(KERN_INFO
- "qe-firmware: firmware '%s' for %u V%u.%u\n",
- firmware->id, be16_to_cpu(firmware->soc.model),
- firmware->soc.major, firmware->soc.minor);
- else
- printk(KERN_INFO "qe-firmware: firmware '%s'\n",
- firmware->id);
-
- /*
- * The QE only supports one microcode per RISC, so clear out all the
- * saved microcode information and put in the new.
- */
- memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
- strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
- qe_firmware_info.extended_modes = firmware->extended_modes;
- memcpy(qe_firmware_info.vtraps, firmware->vtraps,
- sizeof(firmware->vtraps));
-
- /* Loop through each microcode. */
- for (i = 0; i < firmware->count; i++) {
- const struct qe_microcode *ucode = &firmware->microcode[i];
-
- /* Upload a microcode if it's present */
- if (ucode->code_offset)
- qe_upload_microcode(firmware, ucode);
-
- /* Program the traps for this processor */
- for (j = 0; j < 16; j++) {
- u32 trap = be32_to_cpu(ucode->traps[j]);
-
- if (trap)
- out_be32(&qe_immr->rsp[i].tibcr[j], trap);
- }
-
- /* Enable traps */
- out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
- }
-
- qe_firmware_uploaded = 1;
-
- return 0;
-}
-EXPORT_SYMBOL(qe_upload_firmware);
-
-/*
- * Get info on the currently-loaded firmware
- *
- * This function also checks the device tree to see if the boot loader has
- * uploaded a firmware already.
- */
-struct qe_firmware_info *qe_get_firmware_info(void)
-{
- static int initialized;
- struct property *prop;
- struct device_node *qe;
- struct device_node *fw = NULL;
- const char *sprop;
- unsigned int i;
-
- /*
- * If we haven't checked yet, and a driver hasn't uploaded a firmware
- * yet, then check the device tree for information.
- */
- if (qe_firmware_uploaded)
- return &qe_firmware_info;
-
- if (initialized)
- return NULL;
-
- initialized = 1;
-
- /*
- * Newer device trees have an "fsl,qe" compatible property for the QE
- * node, but we still need to support older device trees.
- */
- qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!qe) {
- qe = of_find_node_by_type(NULL, "qe");
- if (!qe)
- return NULL;
- }
-
- /* Find the 'firmware' child node */
- for_each_child_of_node(qe, fw) {
- if (strcmp(fw->name, "firmware") == 0)
- break;
- }
-
- of_node_put(qe);
-
- /* Did we find the 'firmware' node? */
- if (!fw)
- return NULL;
-
- qe_firmware_uploaded = 1;
-
- /* Copy the data into qe_firmware_info*/
- sprop = of_get_property(fw, "id", NULL);
- if (sprop)
- strlcpy(qe_firmware_info.id, sprop,
- sizeof(qe_firmware_info.id));
-
- prop = of_find_property(fw, "extended-modes", NULL);
- if (prop && (prop->length == sizeof(u64))) {
- const u64 *iprop = prop->value;
-
- qe_firmware_info.extended_modes = *iprop;
- }
-
- prop = of_find_property(fw, "virtual-traps", NULL);
- if (prop && (prop->length == 32)) {
- const u32 *iprop = prop->value;
-
- for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
- qe_firmware_info.vtraps[i] = iprop[i];
- }
-
- of_node_put(fw);
-
- return &qe_firmware_info;
-}
-EXPORT_SYMBOL(qe_get_firmware_info);
-
-unsigned int qe_get_num_of_risc(void)
-{
- struct device_node *qe;
- int size;
- unsigned int num_of_risc = 0;
- const u32 *prop;
-
- qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!qe) {
- /* Older devices trees did not have an "fsl,qe"
- * compatible property, so we need to look for
- * the QE node by name.
- */
- qe = of_find_node_by_type(NULL, "qe");
- if (!qe)
- return num_of_risc;
- }
-
- prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
- if (prop && size == sizeof(*prop))
- num_of_risc = *prop;
-
- of_node_put(qe);
-
- return num_of_risc;
-}
-EXPORT_SYMBOL(qe_get_num_of_risc);
-
-unsigned int qe_get_num_of_snums(void)
-{
- struct device_node *qe;
- int size;
- unsigned int num_of_snums;
- const u32 *prop;
-
- num_of_snums = 28; /* The default number of snum for threads is 28 */
- qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!qe) {
- /* Older devices trees did not have an "fsl,qe"
- * compatible property, so we need to look for
- * the QE node by name.
- */
- qe = of_find_node_by_type(NULL, "qe");
- if (!qe)
- return num_of_snums;
- }
-
- prop = of_get_property(qe, "fsl,qe-num-snums", &size);
- if (prop && size == sizeof(*prop)) {
- num_of_snums = *prop;
- if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
- /* No QE ever has fewer than 28 SNUMs */
- pr_err("QE: number of snum is invalid\n");
- of_node_put(qe);
- return -EINVAL;
- }
- }
-
- of_node_put(qe);
-
- return num_of_snums;
-}
-EXPORT_SYMBOL(qe_get_num_of_snums);
-
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
-static int qe_resume(struct platform_device *ofdev)
-{
- if (!qe_alive_during_sleep())
- qe_reset();
- return 0;
-}
-
-static int qe_probe(struct platform_device *ofdev)
-{
- return 0;
-}
-
-static const struct of_device_id qe_ids[] = {
- { .compatible = "fsl,qe", },
- { },
-};
-
-static struct platform_driver qe_driver = {
- .driver = {
- .name = "fsl-qe",
- .of_match_table = qe_ids,
- },
- .probe = qe_probe,
- .resume = qe_resume,
-};
-
-static int __init qe_drv_init(void)
-{
- return platform_driver_register(&qe_driver);
-}
-device_initcall(qe_drv_init);
-#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
deleted file mode 100644
index fbcc1f8..0000000
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * arch/powerpc/sysdev/qe_lib/qe_ic.c
- *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Li Yang <leoli@freescale.com>
- * Based on code from Shlomi Gridish <gridish@freescale.com>
- *
- * QUICC ENGINE Interrupt Controller
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/errno.h>
-#include <linux/reboot.h>
-#include <linux/slab.h>
-#include <linux/stddef.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/qe_ic.h>
-
-#include "qe_ic.h"
-
-static DEFINE_RAW_SPINLOCK(qe_ic_lock);
-
-static struct qe_ic_info qe_ic_info[] = {
- [1] = {
- .mask = 0x00008000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 0,
- .pri_reg = QEIC_CIPWCC,
- },
- [2] = {
- .mask = 0x00004000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 1,
- .pri_reg = QEIC_CIPWCC,
- },
- [3] = {
- .mask = 0x00002000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 2,
- .pri_reg = QEIC_CIPWCC,
- },
- [10] = {
- .mask = 0x00000040,
- .mask_reg = QEIC_CIMR,
- .pri_code = 1,
- .pri_reg = QEIC_CIPZCC,
- },
- [11] = {
- .mask = 0x00000020,
- .mask_reg = QEIC_CIMR,
- .pri_code = 2,
- .pri_reg = QEIC_CIPZCC,
- },
- [12] = {
- .mask = 0x00000010,
- .mask_reg = QEIC_CIMR,
- .pri_code = 3,
- .pri_reg = QEIC_CIPZCC,
- },
- [13] = {
- .mask = 0x00000008,
- .mask_reg = QEIC_CIMR,
- .pri_code = 4,
- .pri_reg = QEIC_CIPZCC,
- },
- [14] = {
- .mask = 0x00000004,
- .mask_reg = QEIC_CIMR,
- .pri_code = 5,
- .pri_reg = QEIC_CIPZCC,
- },
- [15] = {
- .mask = 0x00000002,
- .mask_reg = QEIC_CIMR,
- .pri_code = 6,
- .pri_reg = QEIC_CIPZCC,
- },
- [20] = {
- .mask = 0x10000000,
- .mask_reg = QEIC_CRIMR,
- .pri_code = 3,
- .pri_reg = QEIC_CIPRTA,
- },
- [25] = {
- .mask = 0x00800000,
- .mask_reg = QEIC_CRIMR,
- .pri_code = 0,
- .pri_reg = QEIC_CIPRTB,
- },
- [26] = {
- .mask = 0x00400000,
- .mask_reg = QEIC_CRIMR,
- .pri_code = 1,
- .pri_reg = QEIC_CIPRTB,
- },
- [27] = {
- .mask = 0x00200000,
- .mask_reg = QEIC_CRIMR,
- .pri_code = 2,
- .pri_reg = QEIC_CIPRTB,
- },
- [28] = {
- .mask = 0x00100000,
- .mask_reg = QEIC_CRIMR,
- .pri_code = 3,
- .pri_reg = QEIC_CIPRTB,
- },
- [32] = {
- .mask = 0x80000000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 0,
- .pri_reg = QEIC_CIPXCC,
- },
- [33] = {
- .mask = 0x40000000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 1,
- .pri_reg = QEIC_CIPXCC,
- },
- [34] = {
- .mask = 0x20000000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 2,
- .pri_reg = QEIC_CIPXCC,
- },
- [35] = {
- .mask = 0x10000000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 3,
- .pri_reg = QEIC_CIPXCC,
- },
- [36] = {
- .mask = 0x08000000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 4,
- .pri_reg = QEIC_CIPXCC,
- },
- [40] = {
- .mask = 0x00800000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 0,
- .pri_reg = QEIC_CIPYCC,
- },
- [41] = {
- .mask = 0x00400000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 1,
- .pri_reg = QEIC_CIPYCC,
- },
- [42] = {
- .mask = 0x00200000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 2,
- .pri_reg = QEIC_CIPYCC,
- },
- [43] = {
- .mask = 0x00100000,
- .mask_reg = QEIC_CIMR,
- .pri_code = 3,
- .pri_reg = QEIC_CIPYCC,
- },
-};
-
-static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg)
-{
- return in_be32(base + (reg >> 2));
-}
-
-static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg,
- u32 value)
-{
- out_be32(base + (reg >> 2), value);
-}
-
-static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
-{
- return irq_get_chip_data(virq);
-}
-
-static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
-{
- return irq_data_get_irq_chip_data(d);
-}
-
-static void qe_ic_unmask_irq(struct irq_data *d)
-{
- struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
- unsigned int src = irqd_to_hwirq(d);
- unsigned long flags;
- u32 temp;
-
- raw_spin_lock_irqsave(&qe_ic_lock, flags);
-
- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
- qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
- temp | qe_ic_info[src].mask);
-
- raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
-}
-
-static void qe_ic_mask_irq(struct irq_data *d)
-{
- struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
- unsigned int src = irqd_to_hwirq(d);
- unsigned long flags;
- u32 temp;
-
- raw_spin_lock_irqsave(&qe_ic_lock, flags);
-
- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
- qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
- temp & ~qe_ic_info[src].mask);
-
- /* Flush the above write before enabling interrupts; otherwise,
- * spurious interrupts will sometimes happen. To be 100% sure
- * that the write has reached the device before interrupts are
- * enabled, the mask register would have to be read back; however,
- * this is not required for correctness, only to avoid wasting
- * time on a large number of spurious interrupts. In testing,
- * a sync reduced the observed spurious interrupts to zero.
- */
- mb();
-
- raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
-}
-
-static struct irq_chip qe_ic_irq_chip = {
- .name = "QEIC",
- .irq_unmask = qe_ic_unmask_irq,
- .irq_mask = qe_ic_mask_irq,
- .irq_mask_ack = qe_ic_mask_irq,
-};
-
-static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
- enum irq_domain_bus_token bus_token)
-{
- /* Exact match, unless qe_ic node is NULL */
- return h->of_node == NULL || h->of_node == node;
-}
-
-static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct qe_ic *qe_ic = h->host_data;
- struct irq_chip *chip;
-
- if (qe_ic_info[hw].mask == 0) {
- printk(KERN_ERR "Can't map reserved IRQ\n");
- return -EINVAL;
- }
- /* Default chip */
- chip = &qe_ic->hc_irq;
-
- irq_set_chip_data(virq, qe_ic);
- irq_set_status_flags(virq, IRQ_LEVEL);
-
- irq_set_chip_and_handler(virq, chip, handle_level_irq);
-
- return 0;
-}
-
-static const struct irq_domain_ops qe_ic_host_ops = {
- .match = qe_ic_host_match,
- .map = qe_ic_host_map,
- .xlate = irq_domain_xlate_onetwocell,
-};
-
-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
-{
- int irq;
-
- BUG_ON(qe_ic == NULL);
-
- /* get the interrupt source vector. */
- irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
-
- if (irq == 0)
- return NO_IRQ;
-
- return irq_linear_revmap(qe_ic->irqhost, irq);
-}
-
-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
-{
- int irq;
-
- BUG_ON(qe_ic == NULL);
-
- /* get the interrupt source vector. */
- irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
-
- if (irq == 0)
- return NO_IRQ;
-
- return irq_linear_revmap(qe_ic->irqhost, irq);
-}
-
-void __init qe_ic_init(struct device_node *node, unsigned int flags,
- void (*low_handler)(struct irq_desc *desc),
- void (*high_handler)(struct irq_desc *desc))
-{
- struct qe_ic *qe_ic;
- struct resource res;
- u32 temp = 0, ret, high_active = 0;
-
- ret = of_address_to_resource(node, 0, &res);
- if (ret)
- return;
-
- qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
- if (qe_ic == NULL)
- return;
-
- qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
- &qe_ic_host_ops, qe_ic);
- if (qe_ic->irqhost == NULL) {
- kfree(qe_ic);
- return;
- }
-
- qe_ic->regs = ioremap(res.start, resource_size(&res));
-
- qe_ic->hc_irq = qe_ic_irq_chip;
-
- qe_ic->virq_high = irq_of_parse_and_map(node, 0);
- qe_ic->virq_low = irq_of_parse_and_map(node, 1);
-
- if (qe_ic->virq_low == NO_IRQ) {
- printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
- kfree(qe_ic);
- return;
- }
-
- /* default priority scheme is grouped. If spread mode is */
- /* required, configure cicr accordingly. */
- if (flags & QE_IC_SPREADMODE_GRP_W)
- temp |= CICR_GWCC;
- if (flags & QE_IC_SPREADMODE_GRP_X)
- temp |= CICR_GXCC;
- if (flags & QE_IC_SPREADMODE_GRP_Y)
- temp |= CICR_GYCC;
- if (flags & QE_IC_SPREADMODE_GRP_Z)
- temp |= CICR_GZCC;
- if (flags & QE_IC_SPREADMODE_GRP_RISCA)
- temp |= CICR_GRTA;
- if (flags & QE_IC_SPREADMODE_GRP_RISCB)
- temp |= CICR_GRTB;
-
- /* choose destination signal for highest priority interrupt */
- if (flags & QE_IC_HIGH_SIGNAL) {
- temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
- high_active = 1;
- }
-
- qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
-
- irq_set_handler_data(qe_ic->virq_low, qe_ic);
- irq_set_chained_handler(qe_ic->virq_low, low_handler);
-
- if (qe_ic->virq_high != NO_IRQ &&
- qe_ic->virq_high != qe_ic->virq_low) {
- irq_set_handler_data(qe_ic->virq_high, qe_ic);
- irq_set_chained_handler(qe_ic->virq_high, high_handler);
- }
-}
-
-void qe_ic_set_highest_priority(unsigned int virq, int high)
-{
- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
- unsigned int src = virq_to_hw(virq);
- u32 temp = 0;
-
- temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
-
- temp &= ~CICR_HP_MASK;
- temp |= src << CICR_HP_SHIFT;
-
- temp &= ~CICR_HPIT_MASK;
- temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
-
- qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
-}
-
-/* Set Priority level within its group, from 1 to 8 */
-int qe_ic_set_priority(unsigned int virq, unsigned int priority)
-{
- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
- unsigned int src = virq_to_hw(virq);
- u32 temp;
-
- if (priority > 8 || priority == 0)
- return -EINVAL;
- if (src > 127)
- return -EINVAL;
- if (qe_ic_info[src].pri_reg == 0)
- return -EINVAL;
-
- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
-
- if (priority < 4) {
- temp &= ~(0x7 << (32 - priority * 3));
- temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
- } else {
- temp &= ~(0x7 << (24 - priority * 3));
- temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
- }
-
- qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
-
- return 0;
-}
-
-/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
-int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
-{
- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
- unsigned int src = virq_to_hw(virq);
- u32 temp, control_reg = QEIC_CICNR, shift = 0;
-
- if (priority > 2 || priority == 0)
- return -EINVAL;
-
- switch (qe_ic_info[src].pri_reg) {
- case QEIC_CIPZCC:
- shift = CICNR_ZCC1T_SHIFT;
- break;
- case QEIC_CIPWCC:
- shift = CICNR_WCC1T_SHIFT;
- break;
- case QEIC_CIPYCC:
- shift = CICNR_YCC1T_SHIFT;
- break;
- case QEIC_CIPXCC:
- shift = CICNR_XCC1T_SHIFT;
- break;
- case QEIC_CIPRTA:
- shift = CRICR_RTA1T_SHIFT;
- control_reg = QEIC_CRICR;
- break;
- case QEIC_CIPRTB:
- shift = CRICR_RTB1T_SHIFT;
- control_reg = QEIC_CRICR;
- break;
- default:
- return -EINVAL;
- }
-
- shift += (2 - priority) * 2;
- temp = qe_ic_read(qe_ic->regs, control_reg);
- temp &= ~(SIGNAL_MASK << shift);
- temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
- qe_ic_write(qe_ic->regs, control_reg, temp);
-
- return 0;
-}
-
-static struct bus_type qe_ic_subsys = {
- .name = "qe_ic",
- .dev_name = "qe_ic",
-};
-
-static struct device device_qe_ic = {
- .id = 0,
- .bus = &qe_ic_subsys,
-};
-
-static int __init init_qe_ic_sysfs(void)
-{
- int rc;
-
- printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
-
- rc = subsys_system_register(&qe_ic_subsys, NULL);
- if (rc) {
- printk(KERN_ERR "Failed registering qe_ic sys class\n");
- return -ENODEV;
- }
- rc = device_register(&device_qe_ic);
- if (rc) {
- printk(KERN_ERR "Failed registering qe_ic sys device\n");
- return -ENODEV;
- }
- return 0;
-}
-
-subsys_initcall(init_qe_ic_sysfs);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
deleted file mode 100644
index efef7ab..0000000
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * arch/powerpc/sysdev/qe_lib/qe_ic.h
- *
- * QUICC ENGINE Interrupt Controller Header
- *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Li Yang <leoli@freescale.com>
- * Based on code from Shlomi Gridish <gridish@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.
- */
-#ifndef _POWERPC_SYSDEV_QE_IC_H
-#define _POWERPC_SYSDEV_QE_IC_H
-
-#include <asm/qe_ic.h>
-
-#define NR_QE_IC_INTS 64
-
-/* QE IC registers offset */
-#define QEIC_CICR 0x00
-#define QEIC_CIVEC 0x04
-#define QEIC_CRIPNR 0x08
-#define QEIC_CIPNR 0x0c
-#define QEIC_CIPXCC 0x10
-#define QEIC_CIPYCC 0x14
-#define QEIC_CIPWCC 0x18
-#define QEIC_CIPZCC 0x1c
-#define QEIC_CIMR 0x20
-#define QEIC_CRIMR 0x24
-#define QEIC_CICNR 0x28
-#define QEIC_CIPRTA 0x30
-#define QEIC_CIPRTB 0x34
-#define QEIC_CRICR 0x3c
-#define QEIC_CHIVEC 0x60
-
-/* Interrupt priority registers */
-#define CIPCC_SHIFT_PRI0 29
-#define CIPCC_SHIFT_PRI1 26
-#define CIPCC_SHIFT_PRI2 23
-#define CIPCC_SHIFT_PRI3 20
-#define CIPCC_SHIFT_PRI4 13
-#define CIPCC_SHIFT_PRI5 10
-#define CIPCC_SHIFT_PRI6 7
-#define CIPCC_SHIFT_PRI7 4
-
-/* CICR priority modes */
-#define CICR_GWCC 0x00040000
-#define CICR_GXCC 0x00020000
-#define CICR_GYCC 0x00010000
-#define CICR_GZCC 0x00080000
-#define CICR_GRTA 0x00200000
-#define CICR_GRTB 0x00400000
-#define CICR_HPIT_SHIFT 8
-#define CICR_HPIT_MASK 0x00000300
-#define CICR_HP_SHIFT 24
-#define CICR_HP_MASK 0x3f000000
-
-/* CICNR */
-#define CICNR_WCC1T_SHIFT 20
-#define CICNR_ZCC1T_SHIFT 28
-#define CICNR_YCC1T_SHIFT 12
-#define CICNR_XCC1T_SHIFT 4
-
-/* CRICR */
-#define CRICR_RTA1T_SHIFT 20
-#define CRICR_RTB1T_SHIFT 28
-
-/* Signal indicator */
-#define SIGNAL_MASK 3
-#define SIGNAL_HIGH 2
-#define SIGNAL_LOW 0
-
-struct qe_ic {
- /* Control registers offset */
- volatile u32 __iomem *regs;
-
- /* The remapper for this QEIC */
- struct irq_domain *irqhost;
-
- /* The "linux" controller struct */
- struct irq_chip hc_irq;
-
- /* VIRQ numbers of QE high/low irqs */
- unsigned int virq_high;
- unsigned int virq_low;
-};
-
-/*
- * QE interrupt controller internal structure
- */
-struct qe_ic_info {
- u32 mask; /* location of this source at the QIMR register. */
- u32 mask_reg; /* Mask register offset */
- u8 pri_code; /* for grouped interrupts sources - the interrupt
- code as appears at the group priority register */
- u32 pri_reg; /* Group priority register offset */
-};
-
-#endif /* _POWERPC_SYSDEV_QE_IC_H */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
deleted file mode 100644
index 7ea0174..0000000
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * arch/powerpc/sysdev/qe_lib/qe_io.c
- *
- * QE Parallel I/O ports configuration routines
- *
- * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Li Yang <LeoLi@freescale.com>
- * Based on code from Shlomi Gridish <gridish@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.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/qe.h>
-#include <asm/prom.h>
-#include <sysdev/fsl_soc.h>
-
-#undef DEBUG
-
-static struct qe_pio_regs __iomem *par_io;
-static int num_par_io_ports = 0;
-
-int par_io_init(struct device_node *np)
-{
- struct resource res;
- int ret;
- const u32 *num_ports;
-
- /* Map Parallel I/O ports registers */
- ret = of_address_to_resource(np, 0, &res);
- if (ret)
- return ret;
- par_io = ioremap(res.start, resource_size(&res));
-
- num_ports = of_get_property(np, "num-ports", NULL);
- if (num_ports)
- num_par_io_ports = *num_ports;
-
- return 0;
-}
-
-void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
- int open_drain, int assignment, int has_irq)
-{
- u32 pin_mask1bit;
- u32 pin_mask2bits;
- u32 new_mask2bits;
- u32 tmp_val;
-
- /* calculate pin location for single and 2 bits information */
- pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1)));
-
- /* Set open drain, if required */
- tmp_val = in_be32(&par_io->cpodr);
- if (open_drain)
- out_be32(&par_io->cpodr, pin_mask1bit | tmp_val);
- else
- out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val);
-
- /* define direction */
- tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
- in_be32(&par_io->cpdir2) :
- in_be32(&par_io->cpdir1);
-
- /* get all bits mask for 2 bit per port */
- pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS -
- (pin % (QE_PIO_PINS / 2) + 1) * 2));
-
- /* Get the final mask we need for the right definition */
- new_mask2bits = (u32) (dir << (QE_PIO_PINS -
- (pin % (QE_PIO_PINS / 2) + 1) * 2));
-
- /* clear and set 2 bits mask */
- if (pin > (QE_PIO_PINS / 2) - 1) {
- out_be32(&par_io->cpdir2,
- ~pin_mask2bits & tmp_val);
- tmp_val &= ~pin_mask2bits;
- out_be32(&par_io->cpdir2, new_mask2bits | tmp_val);
- } else {
- out_be32(&par_io->cpdir1,
- ~pin_mask2bits & tmp_val);
- tmp_val &= ~pin_mask2bits;
- out_be32(&par_io->cpdir1, new_mask2bits | tmp_val);
- }
- /* define pin assignment */
- tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
- in_be32(&par_io->cppar2) :
- in_be32(&par_io->cppar1);
-
- new_mask2bits = (u32) (assignment << (QE_PIO_PINS -
- (pin % (QE_PIO_PINS / 2) + 1) * 2));
- /* clear and set 2 bits mask */
- if (pin > (QE_PIO_PINS / 2) - 1) {
- out_be32(&par_io->cppar2,
- ~pin_mask2bits & tmp_val);
- tmp_val &= ~pin_mask2bits;
- out_be32(&par_io->cppar2, new_mask2bits | tmp_val);
- } else {
- out_be32(&par_io->cppar1,
- ~pin_mask2bits & tmp_val);
- tmp_val &= ~pin_mask2bits;
- out_be32(&par_io->cppar1, new_mask2bits | tmp_val);
- }
-}
-EXPORT_SYMBOL(__par_io_config_pin);
-
-int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
- int assignment, int has_irq)
-{
- if (!par_io || port >= num_par_io_ports)
- return -EINVAL;
-
- __par_io_config_pin(&par_io[port], pin, dir, open_drain, assignment,
- has_irq);
- return 0;
-}
-EXPORT_SYMBOL(par_io_config_pin);
-
-int par_io_data_set(u8 port, u8 pin, u8 val)
-{
- u32 pin_mask, tmp_val;
-
- if (port >= num_par_io_ports)
- return -EINVAL;
- if (pin >= QE_PIO_PINS)
- return -EINVAL;
- /* calculate pin location */
- pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin));
-
- tmp_val = in_be32(&par_io[port].cpdata);
-
- if (val == 0) /* clear */
- out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val);
- else /* set */
- out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
-
- return 0;
-}
-EXPORT_SYMBOL(par_io_data_set);
-
-int par_io_of_config(struct device_node *np)
-{
- struct device_node *pio;
- const phandle *ph;
- int pio_map_len;
- const unsigned int *pio_map;
-
- if (par_io == NULL) {
- printk(KERN_ERR "par_io not initialized\n");
- return -1;
- }
-
- ph = of_get_property(np, "pio-handle", NULL);
- if (ph == NULL) {
- printk(KERN_ERR "pio-handle not available\n");
- return -1;
- }
-
- pio = of_find_node_by_phandle(*ph);
-
- pio_map = of_get_property(pio, "pio-map", &pio_map_len);
- if (pio_map == NULL) {
- printk(KERN_ERR "pio-map is not set!\n");
- return -1;
- }
- pio_map_len /= sizeof(unsigned int);
- if ((pio_map_len % 6) != 0) {
- printk(KERN_ERR "pio-map format wrong!\n");
- return -1;
- }
-
- while (pio_map_len > 0) {
- par_io_config_pin((u8) pio_map[0], (u8) pio_map[1],
- (int) pio_map[2], (int) pio_map[3],
- (int) pio_map[4], (int) pio_map[5]);
- pio_map += 6;
- pio_map_len -= 6;
- }
- of_node_put(pio);
- return 0;
-}
-EXPORT_SYMBOL(par_io_of_config);
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
deleted file mode 100644
index 621575b..0000000
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * arch/powerpc/sysdev/qe_lib/ucc.c
- *
- * QE UCC API Set - UCC specific routines implementations.
- *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@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.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/export.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-#include <asm/ucc.h>
-
-int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
-{
- unsigned long flags;
-
- if (ucc_num > UCC_MAX_NUM - 1)
- return -EINVAL;
-
- spin_lock_irqsave(&cmxgcr_lock, flags);
- clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
- ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
- spin_unlock_irqrestore(&cmxgcr_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
-
-/* Configure the UCC to either Slow or Fast.
- *
- * A given UCC can be figured to support either "slow" devices (e.g. UART)
- * or "fast" devices (e.g. Ethernet).
- *
- * 'ucc_num' is the UCC number, from 0 - 7.
- *
- * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
- * must always be set to 1.
- */
-int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
-{
- u8 __iomem *guemr;
-
- /* The GUEMR register is at the same location for both slow and fast
- devices, so we just use uccX.slow.guemr. */
- switch (ucc_num) {
- case 0: guemr = &qe_immr->ucc1.slow.guemr;
- break;
- case 1: guemr = &qe_immr->ucc2.slow.guemr;
- break;
- case 2: guemr = &qe_immr->ucc3.slow.guemr;
- break;
- case 3: guemr = &qe_immr->ucc4.slow.guemr;
- break;
- case 4: guemr = &qe_immr->ucc5.slow.guemr;
- break;
- case 5: guemr = &qe_immr->ucc6.slow.guemr;
- break;
- case 6: guemr = &qe_immr->ucc7.slow.guemr;
- break;
- case 7: guemr = &qe_immr->ucc8.slow.guemr;
- break;
- default:
- return -EINVAL;
- }
-
- clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
- UCC_GUEMR_SET_RESERVED3 | speed);
-
- return 0;
-}
-
-static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
- unsigned int *reg_num, unsigned int *shift)
-{
- unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
-
- *reg_num = cmx + 1;
- *cmxucr = &qe_immr->qmx.cmxucr[cmx];
- *shift = 16 - 8 * (ucc_num & 2);
-}
-
-int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
-{
- __be32 __iomem *cmxucr;
- unsigned int reg_num;
- unsigned int shift;
-
- /* check if the UCC number is in range. */
- if (ucc_num > UCC_MAX_NUM - 1)
- return -EINVAL;
-
- get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
-
- if (set)
- setbits32(cmxucr, mask << shift);
- else
- clrbits32(cmxucr, mask << shift);
-
- return 0;
-}
-
-int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
- enum comm_dir mode)
-{
- __be32 __iomem *cmxucr;
- unsigned int reg_num;
- unsigned int shift;
- u32 clock_bits = 0;
-
- /* check if the UCC number is in range. */
- if (ucc_num > UCC_MAX_NUM - 1)
- return -EINVAL;
-
- /* The communications direction must be RX or TX */
- if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX)))
- return -EINVAL;
-
- get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
-
- switch (reg_num) {
- case 1:
- switch (clock) {
- case QE_BRG1: clock_bits = 1; break;
- case QE_BRG2: clock_bits = 2; break;
- case QE_BRG7: clock_bits = 3; break;
- case QE_BRG8: clock_bits = 4; break;
- case QE_CLK9: clock_bits = 5; break;
- case QE_CLK10: clock_bits = 6; break;
- case QE_CLK11: clock_bits = 7; break;
- case QE_CLK12: clock_bits = 8; break;
- case QE_CLK15: clock_bits = 9; break;
- case QE_CLK16: clock_bits = 10; break;
- default: break;
- }
- break;
- case 2:
- switch (clock) {
- case QE_BRG5: clock_bits = 1; break;
- case QE_BRG6: clock_bits = 2; break;
- case QE_BRG7: clock_bits = 3; break;
- case QE_BRG8: clock_bits = 4; break;
- case QE_CLK13: clock_bits = 5; break;
- case QE_CLK14: clock_bits = 6; break;
- case QE_CLK19: clock_bits = 7; break;
- case QE_CLK20: clock_bits = 8; break;
- case QE_CLK15: clock_bits = 9; break;
- case QE_CLK16: clock_bits = 10; break;
- default: break;
- }
- break;
- case 3:
- switch (clock) {
- case QE_BRG9: clock_bits = 1; break;
- case QE_BRG10: clock_bits = 2; break;
- case QE_BRG15: clock_bits = 3; break;
- case QE_BRG16: clock_bits = 4; break;
- case QE_CLK3: clock_bits = 5; break;
- case QE_CLK4: clock_bits = 6; break;
- case QE_CLK17: clock_bits = 7; break;
- case QE_CLK18: clock_bits = 8; break;
- case QE_CLK7: clock_bits = 9; break;
- case QE_CLK8: clock_bits = 10; break;
- case QE_CLK16: clock_bits = 11; break;
- default: break;
- }
- break;
- case 4:
- switch (clock) {
- case QE_BRG13: clock_bits = 1; break;
- case QE_BRG14: clock_bits = 2; break;
- case QE_BRG15: clock_bits = 3; break;
- case QE_BRG16: clock_bits = 4; break;
- case QE_CLK5: clock_bits = 5; break;
- case QE_CLK6: clock_bits = 6; break;
- case QE_CLK21: clock_bits = 7; break;
- case QE_CLK22: clock_bits = 8; break;
- case QE_CLK7: clock_bits = 9; break;
- case QE_CLK8: clock_bits = 10; break;
- case QE_CLK16: clock_bits = 11; break;
- default: break;
- }
- break;
- default: break;
- }
-
- /* Check for invalid combination of clock and UCC number */
- if (!clock_bits)
- return -ENOENT;
-
- if (mode == COMM_DIR_RX)
- shift += 4;
-
- clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
- clock_bits << shift);
-
- return 0;
-}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
deleted file mode 100644
index 65aaf15..0000000
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * QE UCC Fast API Set - UCC Fast specific routines implementations.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/errno.h>
-#include <linux/slab.h>
-#include <linux/stddef.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/export.h>
-
-#include <asm/io.h>
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-#include <asm/ucc.h>
-#include <asm/ucc_fast.h>
-
-void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
-{
- printk(KERN_INFO "UCC%u Fast registers:\n", uccf->uf_info->ucc_num);
- printk(KERN_INFO "Base address: 0x%p\n", uccf->uf_regs);
-
- printk(KERN_INFO "gumr : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
- printk(KERN_INFO "upsmr : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
- printk(KERN_INFO "utodr : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
- printk(KERN_INFO "udsr : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
- printk(KERN_INFO "ucce : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
- printk(KERN_INFO "uccm : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
- printk(KERN_INFO "uccs : addr=0x%p, val=0x%02x\n",
- &uccf->uf_regs->uccs, in_8(&uccf->uf_regs->uccs));
- printk(KERN_INFO "urfb : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
- printk(KERN_INFO "urfs : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
- printk(KERN_INFO "urfet : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
- printk(KERN_INFO "urfset: addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->urfset, in_be16(&uccf->uf_regs->urfset));
- printk(KERN_INFO "utfb : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
- printk(KERN_INFO "utfs : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
- printk(KERN_INFO "utfet : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
- printk(KERN_INFO "utftt : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
- printk(KERN_INFO "utpt : addr=0x%p, val=0x%04x\n",
- &uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
- printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n",
- &uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
- printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n",
- &uccf->uf_regs->guemr, in_8(&uccf->uf_regs->guemr));
-}
-EXPORT_SYMBOL(ucc_fast_dump_regs);
-
-u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
-{
- switch (uccf_num) {
- case 0: return QE_CR_SUBBLOCK_UCCFAST1;
- case 1: return QE_CR_SUBBLOCK_UCCFAST2;
- case 2: return QE_CR_SUBBLOCK_UCCFAST3;
- case 3: return QE_CR_SUBBLOCK_UCCFAST4;
- case 4: return QE_CR_SUBBLOCK_UCCFAST5;
- case 5: return QE_CR_SUBBLOCK_UCCFAST6;
- case 6: return QE_CR_SUBBLOCK_UCCFAST7;
- case 7: return QE_CR_SUBBLOCK_UCCFAST8;
- default: return QE_CR_SUBBLOCK_INVALID;
- }
-}
-EXPORT_SYMBOL(ucc_fast_get_qe_cr_subblock);
-
-void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
-{
- out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
-}
-EXPORT_SYMBOL(ucc_fast_transmit_on_demand);
-
-void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
-{
- struct ucc_fast __iomem *uf_regs;
- u32 gumr;
-
- uf_regs = uccf->uf_regs;
-
- /* Enable reception and/or transmission on this UCC. */
- gumr = in_be32(&uf_regs->gumr);
- if (mode & COMM_DIR_TX) {
- gumr |= UCC_FAST_GUMR_ENT;
- uccf->enabled_tx = 1;
- }
- if (mode & COMM_DIR_RX) {
- gumr |= UCC_FAST_GUMR_ENR;
- uccf->enabled_rx = 1;
- }
- out_be32(&uf_regs->gumr, gumr);
-}
-EXPORT_SYMBOL(ucc_fast_enable);
-
-void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
-{
- struct ucc_fast __iomem *uf_regs;
- u32 gumr;
-
- uf_regs = uccf->uf_regs;
-
- /* Disable reception and/or transmission on this UCC. */
- gumr = in_be32(&uf_regs->gumr);
- if (mode & COMM_DIR_TX) {
- gumr &= ~UCC_FAST_GUMR_ENT;
- uccf->enabled_tx = 0;
- }
- if (mode & COMM_DIR_RX) {
- gumr &= ~UCC_FAST_GUMR_ENR;
- uccf->enabled_rx = 0;
- }
- out_be32(&uf_regs->gumr, gumr);
-}
-EXPORT_SYMBOL(ucc_fast_disable);
-
-int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
-{
- struct ucc_fast_private *uccf;
- struct ucc_fast __iomem *uf_regs;
- u32 gumr;
- int ret;
-
- if (!uf_info)
- return -EINVAL;
-
- /* check if the UCC port number is in range. */
- if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
- printk(KERN_ERR "%s: illegal UCC number\n", __func__);
- return -EINVAL;
- }
-
- /* Check that 'max_rx_buf_length' is properly aligned (4). */
- if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: max_rx_buf_length not aligned\n",
- __func__);
- return -EINVAL;
- }
-
- /* Validate Virtual Fifo register values */
- if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
- printk(KERN_ERR "%s: urfs is too small\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfs is not aligned\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfet is not aligned.\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfset is not aligned\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utfs is not aligned\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utfet is not aligned\n", __func__);
- return -EINVAL;
- }
-
- if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utftt is not aligned\n", __func__);
- return -EINVAL;
- }
-
- uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
- if (!uccf) {
- printk(KERN_ERR "%s: Cannot allocate private data\n",
- __func__);
- return -ENOMEM;
- }
-
- /* Fill fast UCC structure */
- uccf->uf_info = uf_info;
- /* Set the PHY base address */
- uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast));
- if (uccf->uf_regs == NULL) {
- printk(KERN_ERR "%s: Cannot map UCC registers\n", __func__);
- kfree(uccf);
- return -ENOMEM;
- }
-
- uccf->enabled_tx = 0;
- uccf->enabled_rx = 0;
- uccf->stopped_tx = 0;
- uccf->stopped_rx = 0;
- uf_regs = uccf->uf_regs;
- uccf->p_ucce = &uf_regs->ucce;
- uccf->p_uccm = &uf_regs->uccm;
-#ifdef CONFIG_UGETH_TX_ON_DEMAND
- uccf->p_utodr = &uf_regs->utodr;
-#endif
-#ifdef STATISTICS
- uccf->tx_frames = 0;
- uccf->rx_frames = 0;
- uccf->rx_discarded = 0;
-#endif /* STATISTICS */
-
- /* Set UCC to fast type */
- ret = ucc_set_type(uf_info->ucc_num, UCC_SPEED_TYPE_FAST);
- if (ret) {
- printk(KERN_ERR "%s: cannot set UCC type\n", __func__);
- ucc_fast_free(uccf);
- return ret;
- }
-
- uccf->mrblr = uf_info->max_rx_buf_length;
-
- /* Set GUMR */
- /* For more details see the hardware spec. */
- gumr = uf_info->ttx_trx;
- if (uf_info->tci)
- gumr |= UCC_FAST_GUMR_TCI;
- if (uf_info->cdp)
- gumr |= UCC_FAST_GUMR_CDP;
- if (uf_info->ctsp)
- gumr |= UCC_FAST_GUMR_CTSP;
- if (uf_info->cds)
- gumr |= UCC_FAST_GUMR_CDS;
- if (uf_info->ctss)
- gumr |= UCC_FAST_GUMR_CTSS;
- if (uf_info->txsy)
- gumr |= UCC_FAST_GUMR_TXSY;
- if (uf_info->rsyn)
- gumr |= UCC_FAST_GUMR_RSYN;
- gumr |= uf_info->synl;
- if (uf_info->rtsm)
- gumr |= UCC_FAST_GUMR_RTSM;
- gumr |= uf_info->renc;
- if (uf_info->revd)
- gumr |= UCC_FAST_GUMR_REVD;
- gumr |= uf_info->tenc;
- gumr |= uf_info->tcrc;
- gumr |= uf_info->mode;
- out_be32(&uf_regs->gumr, gumr);
-
- /* Allocate memory for Tx Virtual Fifo */
- uccf->ucc_fast_tx_virtual_fifo_base_offset =
- qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
- if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n",
- __func__);
- uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
- ucc_fast_free(uccf);
- return -ENOMEM;
- }
-
- /* Allocate memory for Rx Virtual Fifo */
- uccf->ucc_fast_rx_virtual_fifo_base_offset =
- qe_muram_alloc(uf_info->urfs +
- UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
- UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
- if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n",
- __func__);
- uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
- ucc_fast_free(uccf);
- return -ENOMEM;
- }
-
- /* Set Virtual Fifo registers */
- out_be16(&uf_regs->urfs, uf_info->urfs);
- out_be16(&uf_regs->urfet, uf_info->urfet);
- out_be16(&uf_regs->urfset, uf_info->urfset);
- out_be16(&uf_regs->utfs, uf_info->utfs);
- out_be16(&uf_regs->utfet, uf_info->utfet);
- out_be16(&uf_regs->utftt, uf_info->utftt);
- /* utfb, urfb are offsets from MURAM base */
- out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset);
- out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset);
-
- /* Mux clocking */
- /* Grant Support */
- ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support);
- /* Breakpoint Support */
- ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support);
- /* Set Tsa or NMSI mode. */
- ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa);
- /* If NMSI (not Tsa), set Tx and Rx clock. */
- if (!uf_info->tsa) {
- /* Rx clock routing */
- if ((uf_info->rx_clock != QE_CLK_NONE) &&
- ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock,
- COMM_DIR_RX)) {
- printk(KERN_ERR "%s: illegal value for RX clock\n",
- __func__);
- ucc_fast_free(uccf);
- return -EINVAL;
- }
- /* Tx clock routing */
- if ((uf_info->tx_clock != QE_CLK_NONE) &&
- ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock,
- COMM_DIR_TX)) {
- printk(KERN_ERR "%s: illegal value for TX clock\n",
- __func__);
- ucc_fast_free(uccf);
- return -EINVAL;
- }
- }
-
- /* Set interrupt mask register at UCC level. */
- out_be32(&uf_regs->uccm, uf_info->uccm_mask);
-
- /* First, clear anything pending at UCC level,
- * otherwise, old garbage may come through
- * as soon as the dam is opened. */
-
- /* Writing '1' clears */
- out_be32(&uf_regs->ucce, 0xffffffff);
-
- *uccf_ret = uccf;
- return 0;
-}
-EXPORT_SYMBOL(ucc_fast_init);
-
-void ucc_fast_free(struct ucc_fast_private * uccf)
-{
- if (!uccf)
- return;
-
- if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
- qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
-
- if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
- qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
-
- if (uccf->uf_regs)
- iounmap(uccf->uf_regs);
-
- kfree(uccf);
-}
-EXPORT_SYMBOL(ucc_fast_free);
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
deleted file mode 100644
index 5f91628..0000000
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors: Shlomi Gridish <gridish@freescale.com>
- * Li Yang <leoli@freescale.com>
- *
- * Description:
- * QE UCC Slow API Set - UCC Slow specific routines implementations.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/errno.h>
-#include <linux/slab.h>
-#include <linux/stddef.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/export.h>
-
-#include <asm/io.h>
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-#include <asm/ucc.h>
-#include <asm/ucc_slow.h>
-
-u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
-{
- switch (uccs_num) {
- case 0: return QE_CR_SUBBLOCK_UCCSLOW1;
- case 1: return QE_CR_SUBBLOCK_UCCSLOW2;
- case 2: return QE_CR_SUBBLOCK_UCCSLOW3;
- case 3: return QE_CR_SUBBLOCK_UCCSLOW4;
- case 4: return QE_CR_SUBBLOCK_UCCSLOW5;
- case 5: return QE_CR_SUBBLOCK_UCCSLOW6;
- case 6: return QE_CR_SUBBLOCK_UCCSLOW7;
- case 7: return QE_CR_SUBBLOCK_UCCSLOW8;
- default: return QE_CR_SUBBLOCK_INVALID;
- }
-}
-EXPORT_SYMBOL(ucc_slow_get_qe_cr_subblock);
-
-void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs)
-{
- struct ucc_slow_info *us_info = uccs->us_info;
- u32 id;
-
- id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
- QE_CR_PROTOCOL_UNSPECIFIED, 0);
-}
-EXPORT_SYMBOL(ucc_slow_graceful_stop_tx);
-
-void ucc_slow_stop_tx(struct ucc_slow_private * uccs)
-{
- struct ucc_slow_info *us_info = uccs->us_info;
- u32 id;
-
- id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
-}
-EXPORT_SYMBOL(ucc_slow_stop_tx);
-
-void ucc_slow_restart_tx(struct ucc_slow_private * uccs)
-{
- struct ucc_slow_info *us_info = uccs->us_info;
- u32 id;
-
- id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
-}
-EXPORT_SYMBOL(ucc_slow_restart_tx);
-
-void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
-{
- struct ucc_slow *us_regs;
- u32 gumr_l;
-
- us_regs = uccs->us_regs;
-
- /* Enable reception and/or transmission on this UCC. */
- gumr_l = in_be32(&us_regs->gumr_l);
- if (mode & COMM_DIR_TX) {
- gumr_l |= UCC_SLOW_GUMR_L_ENT;
- uccs->enabled_tx = 1;
- }
- if (mode & COMM_DIR_RX) {
- gumr_l |= UCC_SLOW_GUMR_L_ENR;
- uccs->enabled_rx = 1;
- }
- out_be32(&us_regs->gumr_l, gumr_l);
-}
-EXPORT_SYMBOL(ucc_slow_enable);
-
-void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
-{
- struct ucc_slow *us_regs;
- u32 gumr_l;
-
- us_regs = uccs->us_regs;
-
- /* Disable reception and/or transmission on this UCC. */
- gumr_l = in_be32(&us_regs->gumr_l);
- if (mode & COMM_DIR_TX) {
- gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
- uccs->enabled_tx = 0;
- }
- if (mode & COMM_DIR_RX) {
- gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
- uccs->enabled_rx = 0;
- }
- out_be32(&us_regs->gumr_l, gumr_l);
-}
-EXPORT_SYMBOL(ucc_slow_disable);
-
-/* Initialize the UCC for Slow operations
- *
- * The caller should initialize the following us_info
- */
-int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
-{
- struct ucc_slow_private *uccs;
- u32 i;
- struct ucc_slow __iomem *us_regs;
- u32 gumr;
- struct qe_bd *bd;
- u32 id;
- u32 command;
- int ret = 0;
-
- if (!us_info)
- return -EINVAL;
-
- /* check if the UCC port number is in range. */
- if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
- printk(KERN_ERR "%s: illegal UCC number\n", __func__);
- return -EINVAL;
- }
-
- /*
- * Set mrblr
- * Check that 'max_rx_buf_length' is properly aligned (4), unless
- * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
- * case when QE accepts 32 bits at a time.
- */
- if ((!us_info->rfw) &&
- (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
- printk(KERN_ERR "max_rx_buf_length not aligned.\n");
- return -EINVAL;
- }
-
- uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
- if (!uccs) {
- printk(KERN_ERR "%s: Cannot allocate private data\n",
- __func__);
- return -ENOMEM;
- }
-
- /* Fill slow UCC structure */
- uccs->us_info = us_info;
- /* Set the PHY base address */
- uccs->us_regs = ioremap(us_info->regs, sizeof(struct ucc_slow));
- if (uccs->us_regs == NULL) {
- printk(KERN_ERR "%s: Cannot map UCC registers\n", __func__);
- kfree(uccs);
- return -ENOMEM;
- }
-
- uccs->saved_uccm = 0;
- uccs->p_rx_frame = 0;
- us_regs = uccs->us_regs;
- uccs->p_ucce = (u16 *) & (us_regs->ucce);
- uccs->p_uccm = (u16 *) & (us_regs->uccm);
-#ifdef STATISTICS
- uccs->rx_frames = 0;
- uccs->tx_frames = 0;
- uccs->rx_discarded = 0;
-#endif /* STATISTICS */
-
- /* Get PRAM base */
- uccs->us_pram_offset =
- qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
- if (IS_ERR_VALUE(uccs->us_pram_offset)) {
- printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__);
- ucc_slow_free(uccs);
- return -ENOMEM;
- }
- id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, us_info->protocol,
- uccs->us_pram_offset);
-
- uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
-
- /* Set UCC to slow type */
- ret = ucc_set_type(us_info->ucc_num, UCC_SPEED_TYPE_SLOW);
- if (ret) {
- printk(KERN_ERR "%s: cannot set UCC type", __func__);
- ucc_slow_free(uccs);
- return ret;
- }
-
- out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
-
- INIT_LIST_HEAD(&uccs->confQ);
-
- /* Allocate BDs. */
- uccs->rx_base_offset =
- qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
- QE_ALIGNMENT_OF_BD);
- if (IS_ERR_VALUE(uccs->rx_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__,
- us_info->rx_bd_ring_len);
- uccs->rx_base_offset = 0;
- ucc_slow_free(uccs);
- return -ENOMEM;
- }
-
- uccs->tx_base_offset =
- qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
- QE_ALIGNMENT_OF_BD);
- if (IS_ERR_VALUE(uccs->tx_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate TX BDs", __func__);
- uccs->tx_base_offset = 0;
- ucc_slow_free(uccs);
- return -ENOMEM;
- }
-
- /* Init Tx bds */
- bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
- for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) {
- /* clear bd buffer */
- out_be32(&bd->buf, 0);
- /* set bd status and length */
- out_be32((u32 *) bd, 0);
- bd++;
- }
- /* for last BD set Wrap bit */
- out_be32(&bd->buf, 0);
- out_be32((u32 *) bd, cpu_to_be32(T_W));
-
- /* Init Rx bds */
- bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
- for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
- /* set bd status and length */
- out_be32((u32*)bd, 0);
- /* clear bd buffer */
- out_be32(&bd->buf, 0);
- bd++;
- }
- /* for last BD set Wrap bit */
- out_be32((u32*)bd, cpu_to_be32(R_W));
- out_be32(&bd->buf, 0);
-
- /* Set GUMR (For more details see the hardware spec.). */
- /* gumr_h */
- gumr = us_info->tcrc;
- if (us_info->cdp)
- gumr |= UCC_SLOW_GUMR_H_CDP;
- if (us_info->ctsp)
- gumr |= UCC_SLOW_GUMR_H_CTSP;
- if (us_info->cds)
- gumr |= UCC_SLOW_GUMR_H_CDS;
- if (us_info->ctss)
- gumr |= UCC_SLOW_GUMR_H_CTSS;
- if (us_info->tfl)
- gumr |= UCC_SLOW_GUMR_H_TFL;
- if (us_info->rfw)
- gumr |= UCC_SLOW_GUMR_H_RFW;
- if (us_info->txsy)
- gumr |= UCC_SLOW_GUMR_H_TXSY;
- if (us_info->rtsm)
- gumr |= UCC_SLOW_GUMR_H_RTSM;
- out_be32(&us_regs->gumr_h, gumr);
-
- /* gumr_l */
- gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
- us_info->diag | us_info->mode;
- if (us_info->tci)
- gumr |= UCC_SLOW_GUMR_L_TCI;
- if (us_info->rinv)
- gumr |= UCC_SLOW_GUMR_L_RINV;
- if (us_info->tinv)
- gumr |= UCC_SLOW_GUMR_L_TINV;
- if (us_info->tend)
- gumr |= UCC_SLOW_GUMR_L_TEND;
- out_be32(&us_regs->gumr_l, gumr);
-
- /* Function code registers */
-
- /* if the data is in cachable memory, the 'global' */
- /* in the function code should be set. */
- uccs->us_pram->tbmr = UCC_BMR_BO_BE;
- uccs->us_pram->rbmr = UCC_BMR_BO_BE;
-
- /* rbase, tbase are offsets from MURAM base */
- out_be16(&uccs->us_pram->rbase, uccs->rx_base_offset);
- out_be16(&uccs->us_pram->tbase, uccs->tx_base_offset);
-
- /* Mux clocking */
- /* Grant Support */
- ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support);
- /* Breakpoint Support */
- ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support);
- /* Set Tsa or NMSI mode. */
- ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa);
- /* If NMSI (not Tsa), set Tx and Rx clock. */
- if (!us_info->tsa) {
- /* Rx clock routing */
- if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->rx_clock,
- COMM_DIR_RX)) {
- printk(KERN_ERR "%s: illegal value for RX clock\n",
- __func__);
- ucc_slow_free(uccs);
- return -EINVAL;
- }
- /* Tx clock routing */
- if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->tx_clock,
- COMM_DIR_TX)) {
- printk(KERN_ERR "%s: illegal value for TX clock\n",
- __func__);
- ucc_slow_free(uccs);
- return -EINVAL;
- }
- }
-
- /* Set interrupt mask register at UCC level. */
- out_be16(&us_regs->uccm, us_info->uccm_mask);
-
- /* First, clear anything pending at UCC level,
- * otherwise, old garbage may come through
- * as soon as the dam is opened. */
-
- /* Writing '1' clears */
- out_be16(&us_regs->ucce, 0xffff);
-
- /* Issue QE Init command */
- if (us_info->init_tx && us_info->init_rx)
- command = QE_INIT_TX_RX;
- else if (us_info->init_tx)
- command = QE_INIT_TX;
- else
- command = QE_INIT_RX; /* We know at least one is TRUE */
-
- qe_issue_cmd(command, id, us_info->protocol, 0);
-
- *uccs_ret = uccs;
- return 0;
-}
-EXPORT_SYMBOL(ucc_slow_init);
-
-void ucc_slow_free(struct ucc_slow_private * uccs)
-{
- if (!uccs)
- return;
-
- if (uccs->rx_base_offset)
- qe_muram_free(uccs->rx_base_offset);
-
- if (uccs->tx_base_offset)
- qe_muram_free(uccs->tx_base_offset);
-
- if (uccs->us_pram)
- qe_muram_free(uccs->us_pram_offset);
-
- if (uccs->us_regs)
- iounmap(uccs->us_regs);
-
- kfree(uccs);
-}
-EXPORT_SYMBOL(ucc_slow_free);
-
diff --git a/arch/powerpc/sysdev/qe_lib/usb.c b/arch/powerpc/sysdev/qe_lib/usb.c
deleted file mode 100644
index 27f23bd..0000000
--- a/arch/powerpc/sysdev/qe_lib/usb.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * QE USB routines
- *
- * Copyright 2006 Freescale Semiconductor, Inc.
- * Shlomi Gridish <gridish@freescale.com>
- * Jerry Huang <Chang-Ming.Huang@freescale.com>
- * Copyright (c) MontaVista Software, Inc. 2008.
- * Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/export.h>
-#include <linux/io.h>
-#include <asm/immap_qe.h>
-#include <asm/qe.h>
-
-int qe_usb_clock_set(enum qe_clock clk, int rate)
-{
- struct qe_mux __iomem *mux = &qe_immr->qmx;
- unsigned long flags;
- u32 val;
-
- switch (clk) {
- case QE_CLK3: val = QE_CMXGCR_USBCS_CLK3; break;
- case QE_CLK5: val = QE_CMXGCR_USBCS_CLK5; break;
- case QE_CLK7: val = QE_CMXGCR_USBCS_CLK7; break;
- case QE_CLK9: val = QE_CMXGCR_USBCS_CLK9; break;
- case QE_CLK13: val = QE_CMXGCR_USBCS_CLK13; break;
- case QE_CLK17: val = QE_CMXGCR_USBCS_CLK17; break;
- case QE_CLK19: val = QE_CMXGCR_USBCS_CLK19; break;
- case QE_CLK21: val = QE_CMXGCR_USBCS_CLK21; break;
- case QE_BRG9: val = QE_CMXGCR_USBCS_BRG9; break;
- case QE_BRG10: val = QE_CMXGCR_USBCS_BRG10; break;
- default:
- pr_err("%s: requested unknown clock %d\n", __func__, clk);
- return -EINVAL;
- }
-
- if (qe_clock_is_brg(clk))
- qe_setbrg(clk, rate, 1);
-
- spin_lock_irqsave(&cmxgcr_lock, flags);
-
- clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val);
-
- spin_unlock_irqrestore(&cmxgcr_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(qe_usb_clock_set);
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c
index ff5e732..56ce8ca 100644
--- a/arch/powerpc/sysdev/simple_gpio.c
+++ b/arch/powerpc/sysdev/simple_gpio.c
@@ -46,7 +46,7 @@ static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- return in_8(mm_gc->regs) & u8_pin2mask(gpio);
+ return !!(in_8(mm_gc->regs) & u8_pin2mask(gpio));
}
static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index eae3265..afdf62f 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -159,6 +159,27 @@ static void icp_native_cause_ipi(int cpu, unsigned long data)
icp_native_set_qirr(cpu, IPI_PRIORITY);
}
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+void icp_native_cause_ipi_rm(int cpu)
+{
+ /*
+ * Currently not used to send IPIs to another CPU
+ * on the same core. Only caller is KVM real mode.
+ * Need the physical address of the XICS to be
+ * previously saved in kvm_hstate in the paca.
+ */
+ unsigned long xics_phys;
+
+ /*
+ * Just like the cause_ipi functions, it is required to
+ * include a full barrier (out8 includes a sync) before
+ * causing the IPI.
+ */
+ xics_phys = paca[cpu].kvm_hstate.xics_phys;
+ out_rm8((u8 *)(xics_phys + XICS_MFRR), IPI_PRIORITY);
+}
+#endif
+
/*
* Called when an interrupt is received on an off-line CPU to
* clear the interrupt, so that the CPU can go back to nap mode.
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 1278788..436062d 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -3,6 +3,7 @@
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
GCOV_PROFILE := n
+UBSAN_SANITIZE := n
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c
index c987486..d001234 100644
--- a/arch/powerpc/xmon/nonstdio.c
+++ b/arch/powerpc/xmon/nonstdio.c
@@ -11,10 +11,25 @@
#include <asm/time.h>
#include "nonstdio.h"
+static bool paginating, paginate_skipping;
+static unsigned long paginate_lpp; /* Lines Per Page */
+static unsigned long paginate_pos;
-static int xmon_write(const void *ptr, int nb)
+void xmon_start_pagination(void)
{
- return udbg_write(ptr, nb);
+ paginating = true;
+ paginate_skipping = false;
+ paginate_pos = 0;
+}
+
+void xmon_end_pagination(void)
+{
+ paginating = false;
+}
+
+void xmon_set_pagination_lpp(unsigned long lpp)
+{
+ paginate_lpp = lpp;
}
static int xmon_readchar(void)
@@ -24,6 +39,51 @@ static int xmon_readchar(void)
return -1;
}
+static int xmon_write(const char *ptr, int nb)
+{
+ int rv = 0;
+ const char *p = ptr, *q;
+ const char msg[] = "[Hit a key (a:all, q:truncate, any:next page)]";
+
+ if (nb <= 0)
+ return rv;
+
+ if (paginating && paginate_skipping)
+ return nb;
+
+ if (paginate_lpp) {
+ while (paginating && (q = strchr(p, '\n'))) {
+ rv += udbg_write(p, q - p + 1);
+ p = q + 1;
+ paginate_pos++;
+
+ if (paginate_pos >= paginate_lpp) {
+ udbg_write(msg, strlen(msg));
+
+ switch (xmon_readchar()) {
+ case 'a':
+ paginating = false;
+ break;
+ case 'q':
+ paginate_skipping = true;
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+
+ paginate_pos = 0;
+ udbg_write("\r\n", 2);
+
+ if (paginate_skipping)
+ return nb;
+ }
+ }
+ }
+
+ return rv + udbg_write(p, nb - (p - ptr));
+}
+
int xmon_putchar(int c)
{
char ch = c;
diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h
index 18a51de..f865336 100644
--- a/arch/powerpc/xmon/nonstdio.h
+++ b/arch/powerpc/xmon/nonstdio.h
@@ -3,6 +3,9 @@
#define printf xmon_printf
#define putchar xmon_putchar
+extern void xmon_set_pagination_lpp(unsigned long lpp);
+extern void xmon_start_pagination(void);
+extern void xmon_end_pagination(void);
extern int xmon_putchar(int c);
extern void xmon_puts(const char *);
extern char *xmon_gets(char *, int);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 6ef1231..942796f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -47,6 +47,9 @@
#include <asm/debug.h>
#include <asm/hw_breakpoint.h>
+#include <asm/opal.h>
+#include <asm/firmware.h>
+
#ifdef CONFIG_PPC64
#include <asm/hvcall.h>
#include <asm/paca.h>
@@ -119,6 +122,16 @@ static void dump(void);
static void prdump(unsigned long, long);
static int ppc_inst_dump(unsigned long, long, int);
static void dump_log_buf(void);
+
+#ifdef CONFIG_PPC_POWERNV
+static void dump_opal_msglog(void);
+#else
+static inline void dump_opal_msglog(void)
+{
+ printf("Machine is not running OPAL firmware.\n");
+}
+#endif
+
static void backtrace(struct pt_regs *);
static void excprint(struct pt_regs *);
static void prregs(struct pt_regs *);
@@ -150,6 +163,7 @@ static int cpu_cmd(void);
static void csum(void);
static void bootcmds(void);
static void proccall(void);
+static void show_tasks(void);
void dump_segments(void);
static void symbol_lookup(void);
static void xmon_show_stack(unsigned long sp, unsigned long lr,
@@ -202,6 +216,10 @@ Commands:\n\
df dump float values\n\
dd dump double values\n\
dl dump the kernel log buffer\n"
+#ifdef CONFIG_PPC_POWERNV
+ "\
+ do dump the OPAL message log\n"
+#endif
#ifdef CONFIG_PPC64
"\
dp[#] dump paca for current cpu, or cpu #\n\
@@ -221,6 +239,7 @@ Commands:\n\
mz zero a block of memory\n\
mi show information about memory allocation\n\
p call a procedure\n\
+ P list processes/tasks\n\
r print registers\n\
s single step\n"
#ifdef CONFIG_SPU_BASE
@@ -233,7 +252,7 @@ Commands:\n\
" S print special registers\n\
t print backtrace\n\
x exit monitor and recover\n\
- X exit monitor and dont recover\n"
+ X exit monitor and don't recover\n"
#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
" u dump segment table or SLB\n"
#elif defined(CONFIG_PPC_STD_MMU_32)
@@ -242,6 +261,7 @@ Commands:\n\
" u dump TLB\n"
#endif
" ? help\n"
+" # n limit output to n lines per page (for dp, dpa, dl)\n"
" zr reboot\n\
zh halt\n"
;
@@ -319,6 +339,7 @@ static inline void disable_surveillance(void)
#ifdef CONFIG_PPC_PSERIES
/* Since this can't be a module, args should end up below 4GB. */
static struct rtas_args args;
+ int token;
/*
* At this point we have got all the cpus we can into
@@ -327,17 +348,12 @@ static inline void disable_surveillance(void)
* If we did try to take rtas.lock there would be a
* real possibility of deadlock.
*/
- args.token = rtas_token("set-indicator");
- if (args.token == RTAS_UNKNOWN_SERVICE)
+ token = rtas_token("set-indicator");
+ if (token == RTAS_UNKNOWN_SERVICE)
return;
- args.token = cpu_to_be32(args.token);
- args.nargs = cpu_to_be32(3);
- args.nret = cpu_to_be32(1);
- args.rets = &args.args[3];
- args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
- args.args[1] = 0;
- args.args[2] = 0;
- enter_rtas(__pa(&args));
+
+ rtas_call_unlocked(&args, token, 3, 1, NULL, SURVEILLANCE_TOKEN, 0, 0);
+
#endif /* CONFIG_PPC_PSERIES */
}
@@ -833,6 +849,16 @@ static void remove_cpu_bpts(void)
write_ciabr(0);
}
+static void set_lpp_cmd(void)
+{
+ unsigned long lpp;
+
+ if (!scanhex(&lpp)) {
+ printf("Invalid number.\n");
+ lpp = 0;
+ }
+ xmon_set_pagination_lpp(lpp);
+}
/* Command interpreting routine */
static char *last_cmd;
@@ -924,6 +950,9 @@ cmds(struct pt_regs *excp)
case '?':
xmon_puts(help_string);
break;
+ case '#':
+ set_lpp_cmd();
+ break;
case 'b':
bpt_cmds();
break;
@@ -940,6 +969,9 @@ cmds(struct pt_regs *excp)
case 'p':
proccall();
break;
+ case 'P':
+ show_tasks();
+ break;
#ifdef CONFIG_PPC_STD_MMU
case 'u':
dump_segments();
@@ -1508,6 +1540,8 @@ static void excprint(struct pt_regs *fp)
if (trap == 0x700)
print_bug_trap(fp);
+
+ printf(linux_banner);
}
static void prregs(struct pt_regs *fp)
@@ -2072,6 +2106,9 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
static void dump_one_paca(int cpu)
{
struct paca_struct *p;
+#ifdef CONFIG_PPC_STD_MMU_64
+ int i = 0;
+#endif
if (setjmp(bus_error_jmp) != 0) {
printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
@@ -2085,12 +2122,12 @@ static void dump_one_paca(int cpu)
printf("paca for cpu 0x%x @ %p:\n", cpu, p);
- printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
- printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
- printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
+ printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu) ? "yes" : "no");
+ printf(" %-*s = %s\n", 20, "present", cpu_present(cpu) ? "yes" : "no");
+ printf(" %-*s = %s\n", 20, "online", cpu_online(cpu) ? "yes" : "no");
#define DUMP(paca, name, format) \
- printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
+ printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
offsetof(struct paca_struct, name));
DUMP(p, lock_token, "x");
@@ -2102,11 +2139,41 @@ static void dump_one_paca(int cpu)
#ifdef CONFIG_PPC_BOOK3S_64
DUMP(p, mc_emergency_sp, "p");
DUMP(p, in_mce, "x");
+ DUMP(p, hmi_event_available, "x");
#endif
DUMP(p, data_offset, "lx");
DUMP(p, hw_cpu_id, "x");
DUMP(p, cpu_start, "x");
DUMP(p, kexec_state, "x");
+#ifdef CONFIG_PPC_STD_MMU_64
+ for (i = 0; i < SLB_NUM_BOLTED; i++) {
+ u64 esid, vsid;
+
+ if (!p->slb_shadow_ptr)
+ continue;
+
+ esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
+ vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
+
+ if (esid || vsid) {
+ printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
+ i, esid, vsid);
+ }
+ }
+ DUMP(p, vmalloc_sllp, "x");
+ DUMP(p, slb_cache_ptr, "x");
+ for (i = 0; i < SLB_CACHE_ENTRIES; i++)
+ printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]);
+#endif
+ DUMP(p, dscr_default, "llx");
+#ifdef CONFIG_PPC_BOOK3E
+ DUMP(p, pgd, "p");
+ DUMP(p, kernel_pgd, "p");
+ DUMP(p, tcd_ptr, "p");
+ DUMP(p, mc_kstack, "p");
+ DUMP(p, crit_kstack, "p");
+ DUMP(p, dbg_kstack, "p");
+#endif
DUMP(p, __current, "p");
DUMP(p, kstack, "lx");
DUMP(p, stab_rr, "lx");
@@ -2117,7 +2184,27 @@ static void dump_one_paca(int cpu)
DUMP(p, io_sync, "x");
DUMP(p, irq_work_pending, "x");
DUMP(p, nap_state_lost, "x");
+ DUMP(p, sprg_vdso, "llx");
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ DUMP(p, tm_scratch, "llx");
+#endif
+
+#ifdef CONFIG_PPC_POWERNV
+ DUMP(p, core_idle_state_ptr, "p");
+ DUMP(p, thread_idle_state, "x");
+ DUMP(p, thread_mask, "x");
+ DUMP(p, subcore_sibling_mask, "x");
+#endif
+
+ DUMP(p, user_time, "llx");
+ DUMP(p, system_time, "llx");
+ DUMP(p, user_time_scaled, "llx");
+ DUMP(p, starttime, "llx");
+ DUMP(p, starttime_user, "llx");
+ DUMP(p, startspurr, "llx");
+ DUMP(p, utime_sspurr, "llx");
+ DUMP(p, stolen_time, "llx");
#undef DUMP
catch_memory_errors = 0;
@@ -2166,7 +2253,9 @@ dump(void)
#ifdef CONFIG_PPC64
if (c == 'p') {
+ xmon_start_pagination();
dump_pacas();
+ xmon_end_pagination();
return;
}
#endif
@@ -2186,6 +2275,8 @@ dump(void)
last_cmd = "di\n";
} else if (c == 'l') {
dump_log_buf();
+ } else if (c == 'o') {
+ dump_opal_msglog();
} else if (c == 'r') {
scanhex(&ndump);
if (ndump == 0)
@@ -2315,16 +2406,57 @@ dump_log_buf(void)
sync();
kmsg_dump_rewind_nolock(&dumper);
+ xmon_start_pagination();
while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
buf[len] = '\0';
printf("%s", buf);
}
+ xmon_end_pagination();
+
+ sync();
+ /* wait a little while to see if we get a machine check */
+ __delay(200);
+ catch_memory_errors = 0;
+}
+
+#ifdef CONFIG_PPC_POWERNV
+static void dump_opal_msglog(void)
+{
+ unsigned char buf[128];
+ ssize_t res;
+ loff_t pos = 0;
+
+ if (!firmware_has_feature(FW_FEATURE_OPAL)) {
+ printf("Machine is not running OPAL firmware.\n");
+ return;
+ }
+
+ if (setjmp(bus_error_jmp) != 0) {
+ printf("Error dumping OPAL msglog!\n");
+ return;
+ }
+
+ catch_memory_errors = 1;
+ sync();
+
+ xmon_start_pagination();
+ while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
+ if (res < 0) {
+ printf("Error dumping OPAL msglog! Error: %zd\n", res);
+ break;
+ }
+ buf[res] = '\0';
+ printf("%s", buf);
+ pos += res;
+ }
+ xmon_end_pagination();
sync();
/* wait a little while to see if we get a machine check */
__delay(200);
catch_memory_errors = 0;
}
+#endif
/*
* Memory operations - move, set, print differences
@@ -2439,6 +2571,61 @@ memzcan(void)
printf("%.8x\n", a - mskip);
}
+static void show_task(struct task_struct *tsk)
+{
+ char state;
+
+ /*
+ * Cloned from kdb_task_state_char(), which is not entirely
+ * appropriate for calling from xmon. This could be moved
+ * to a common, generic, routine used by both.
+ */
+ state = (tsk->state == 0) ? 'R' :
+ (tsk->state < 0) ? 'U' :
+ (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+ (tsk->state & TASK_STOPPED) ? 'T' :
+ (tsk->state & TASK_TRACED) ? 'C' :
+ (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
+ (tsk->exit_state & EXIT_DEAD) ? 'E' :
+ (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
+
+ printf("%p %016lx %6d %6d %c %2d %s\n", tsk,
+ tsk->thread.ksp,
+ tsk->pid, tsk->parent->pid,
+ state, task_thread_info(tsk)->cpu,
+ tsk->comm);
+}
+
+static void show_tasks(void)
+{
+ unsigned long tskv;
+ struct task_struct *tsk = NULL;
+
+ printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
+
+ if (scanhex(&tskv))
+ tsk = (struct task_struct *)tskv;
+
+ if (setjmp(bus_error_jmp) != 0) {
+ catch_memory_errors = 0;
+ printf("*** Error dumping task %p\n", tsk);
+ return;
+ }
+
+ catch_memory_errors = 1;
+ sync();
+
+ if (tsk)
+ show_task(tsk);
+ else
+ for_each_process(tsk)
+ show_task(tsk);
+
+ sync();
+ __delay(200);
+ catch_memory_errors = 0;
+}
+
static void proccall(void)
{
unsigned long args[8];
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 1d57000..7e3e8a8 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -10,9 +10,6 @@ config LOCKDEP_SUPPORT
config STACKTRACE_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config RWSEM_GENERIC_SPINLOCK
bool
@@ -66,6 +63,7 @@ config S390
def_bool y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_SG_CHAIN
@@ -101,6 +99,7 @@ config S390
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_NUMA_BALANCING
+ select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_WANTS_PROT_NUMA_PROT_NONE
select ARCH_WANT_IPC_PARSE_VERSION
@@ -118,6 +117,7 @@ config S390
select HAVE_ARCH_EARLY_PFN_TO_NID
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_SOFT_DIRTY
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
select HAVE_BPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES
@@ -164,8 +164,7 @@ config SCHED_OMIT_FRAME_POINTER
config PGTABLE_LEVELS
int
- default 4 if 64BIT
- default 2
+ default 4
source "init/Kconfig"
@@ -255,12 +254,12 @@ config MARCH_ZEC12
older machines.
config MARCH_Z13
- bool "IBM z13"
+ bool "IBM z13s and z13"
select HAVE_MARCH_Z13_FEATURES
help
- Select this to enable optimizations for IBM z13 (2964 series).
- The kernel will be slightly faster but will not work on older
- machines.
+ Select this to enable optimizations for IBM z13s and z13 (2965 and
+ 2964 series). The kernel will be slightly faster but will not work on
+ older machines.
endchoice
@@ -388,9 +387,6 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
-config SCHED_SMT
- def_bool n
-
# Some NUMA nodes have memory ranges that span
# other nodes. Even though a pfn is valid and
# between a node's start and end pfns, it may not
@@ -401,7 +397,7 @@ config NODES_SPAN_OTHER_NODES
config NUMA
bool "NUMA support"
- depends on SMP && 64BIT && SCHED_TOPOLOGY
+ depends on SMP && SCHED_TOPOLOGY
default n
help
Enable NUMA support
@@ -461,6 +457,9 @@ config EMU_SIZE
endmenu
+config SCHED_SMT
+ def_bool n
+
config SCHED_MC
def_bool n
@@ -580,8 +579,8 @@ config QDIO
menuconfig PCI
bool "PCI support"
- select HAVE_DMA_ATTRS
select PCI_MSI
+ select IOMMU_SUPPORT
help
Enable PCI support.
@@ -606,8 +605,6 @@ config PCI_NR_MSI
PCI devices.
source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
endif # PCI
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index c56878e..26c5d5be 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -5,18 +5,6 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug"
-config STRICT_DEVMEM
- def_bool y
- prompt "Filter access to /dev/mem"
- ---help---
- This option restricts access to /dev/mem. If this option is
- disabled, you allow userspace access to all memory, including
- kernel and userspace memory. Accidental memory access is likely
- to be disastrous.
- Memory access is required for experts who want to debug the kernel.
-
- If you are unsure, say Y.
-
config S390_PTDUMP
bool "Export kernel pagetable layout to userspace via debugfs"
depends on DEBUG_KERNEL
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index e8d4423..224b427 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -106,6 +106,7 @@ drivers-y += drivers/s390/
drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
boot := arch/s390/boot
+tools := arch/s390/tools
all: image bzImage
@@ -124,9 +125,17 @@ vdso_install:
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
+ $(Q)$(MAKE) $(clean)=$(tools)
+
+archprepare:
+ $(Q)$(MAKE) $(build)=$(tools) include/generated/facilities.h
# Don't use tabs in echo arguments
define archhelp
echo '* image - Kernel image for IPL ($(boot)/image)'
echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)'
+ echo ' install - Install kernel using'
+ echo ' (your) ~/bin/$(INSTALLKERNEL) or'
+ echo ' (distribution) /sbin/$(INSTALLKERNEL) or'
+ echo ' install to $$(INSTALL_PATH)'
endef
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
index ed7da28..0ac42cc 100644
--- a/arch/s390/configs/default_defconfig
+++ b/arch/s390/configs/default_defconfig
@@ -10,28 +10,35 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y
CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_PIDS=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_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
+CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
@@ -64,7 +71,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y
CONFIG_NET=y
@@ -106,7 +112,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
@@ -457,19 +462,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_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_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
@@ -490,7 +485,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
+CONFIG_FUSE_FS=y
CONFIG_CUSE=m
CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m
@@ -542,10 +537,11 @@ CONFIG_DLM=m
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO=y
-# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024
CONFIG_READABLE_ASM=y
CONFIG_UNUSED_SYMBOLS=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_OBJECTS=y
@@ -588,6 +584,7 @@ CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_LATENCYTOP=y
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
index 9858b14..a31dcd5 100644
--- a/arch/s390/configs/gcov_defconfig
+++ b/arch/s390/configs/gcov_defconfig
@@ -10,21 +10,27 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y
CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_PIDS=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_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y
CONFIG_NET=y
@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_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_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
+CONFIG_FUSE_FS=y
CONFIG_CUSE=m
CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m
@@ -550,6 +544,7 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
CONFIG_PM_NOTIFIER_ERROR_INJECT=m
CONFIG_LATENCYTOP=y
+CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_KPROBE_EVENT is not set
CONFIG_LKDTM=m
@@ -557,6 +552,7 @@ CONFIG_RBTREE_TEST=m
CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_TEST_BPF=m
# CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y
CONFIG_ENCRYPTED_KEYS=m
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index 7f14f80..7b73bf3 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -10,22 +10,28 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y
# CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set
CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_PIDS=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_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y
CONFIG_NET=y
@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_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_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
+CONFIG_FUSE_FS=y
CONFIG_CUSE=m
CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m
@@ -546,6 +540,7 @@ CONFIG_TIMER_STATS=y
CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_LATENCYTOP=y
+CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_STACK_TRACER=y
@@ -554,6 +549,7 @@ CONFIG_UPROBE_EVENT=y
CONFIG_LKDTM=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_TEST_BPF=m
# CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y
CONFIG_ENCRYPTED_KEYS=m
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig
index 92805d6..1719843 100644
--- a/arch/s390/configs/zfcpdump_defconfig
+++ b/arch/s390/configs/zfcpdump_defconfig
@@ -23,8 +23,6 @@ CONFIG_CRASH_DUMP=y
# CONFIG_SECCOMP is not set
CONFIG_NET=y
# CONFIG_IUCV is not set
-CONFIG_ATM=y
-CONFIG_ATM_LANE=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
@@ -54,14 +52,10 @@ CONFIG_RAW_DRIVER=y
# CONFIG_S390_VMUR is not set
# CONFIG_HID is not set
# 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_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 0b9b95f..48e1a2d 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -27,6 +27,7 @@
#include <linux/cpufeature.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <crypto/xts.h>
#include "crypt_s390.h"
#define AES_KEYLEN_128 1
@@ -587,6 +588,11 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
{
struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
u32 *flags = &tfm->crt_flags;
+ int err;
+
+ err = xts_check_key(tfm, in_key, key_len);
+ if (err)
+ return err;
switch (key_len) {
case 32:
diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h
index f4e9dc7..10f2007 100644
--- a/arch/s390/crypto/sha.h
+++ b/arch/s390/crypto/sha.h
@@ -19,7 +19,7 @@
#include <crypto/sha.h>
/* must be big enough for the largest SHA variant */
-#define SHA_MAX_STATE_SIZE 16
+#define SHA_MAX_STATE_SIZE (SHA512_DIGEST_SIZE / 4)
#define SHA_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
struct s390_sha_ctx {
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 9256b48..e24f2af 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -11,22 +11,31 @@ CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_PIDS=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_HUGETLB=y
+CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
+CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
@@ -37,6 +46,7 @@ CONFIG_DEFAULT_DEADLINE=y
CONFIG_LIVEPATCH=y
CONFIG_MARCH_Z196=y
CONFIG_NR_CPUS=256
+CONFIG_NUMA=y
CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
@@ -52,7 +62,6 @@ CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m
CONFIG_VLAN_8021Q=y
@@ -89,10 +98,26 @@ CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_ZFCP=y
CONFIG_SCSI_VIRTIO=y
+CONFIG_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
@@ -137,7 +162,6 @@ CONFIG_DEBUG_PI_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
-# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y
CONFIG_LATENCYTOP=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 5eeffee..0450357 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
+#include <asm/diag.h>
#include <asm/ebcdic.h>
#include "hypfs.h"
@@ -336,7 +337,7 @@ static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)
/* Diagnose 204 functions */
-static int diag204(unsigned long subcode, unsigned long size, void *addr)
+static inline int __diag204(unsigned long subcode, unsigned long size, void *addr)
{
register unsigned long _subcode asm("0") = subcode;
register unsigned long _size asm("1") = size;
@@ -351,6 +352,12 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr)
return _size;
}
+static int diag204(unsigned long subcode, unsigned long size, void *addr)
+{
+ diag_stat_inc(DIAG_STAT_X204);
+ return __diag204(subcode, size, addr);
+}
+
/*
* For the old diag subcode 4 with simple data format we have to use real
* memory. If we use subcode 6 or 7 with extended data format, we can (and
@@ -505,6 +512,7 @@ static int diag224(void *ptr)
{
int rc = -EOPNOTSUPP;
+ diag_stat_inc(DIAG_STAT_X224);
asm volatile(
" diag %1,%2,0x224\n"
"0: lhi %0,0x0\n"
diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c
index 24c747a..0f1927c 100644
--- a/arch/s390/hypfs/hypfs_diag0c.c
+++ b/arch/s390/hypfs/hypfs_diag0c.c
@@ -8,6 +8,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
+#include <asm/diag.h>
#include <asm/hypfs.h>
#include "hypfs.h"
@@ -18,6 +19,7 @@
*/
static void diag0c(struct hypfs_diag0c_entry *entry)
{
+ diag_stat_inc(DIAG_STAT_X00C);
asm volatile (
" sam31\n"
" diag %0,%0,0x0c\n"
diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c
index dd42a26..c9e5c72 100644
--- a/arch/s390/hypfs/hypfs_sprp.c
+++ b/arch/s390/hypfs/hypfs_sprp.c
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/uaccess.h>
#include <asm/compat.h>
+#include <asm/diag.h>
#include <asm/sclp.h>
#include "hypfs.h"
@@ -22,7 +23,7 @@
#define DIAG304_CMD_MAX 2
-static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
+static inline unsigned long __hypfs_sprp_diag304(void *data, unsigned long cmd)
{
register unsigned long _data asm("2") = (unsigned long) data;
register unsigned long _rc asm("3");
@@ -34,6 +35,12 @@ static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
return _rc;
}
+static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
+{
+ diag_stat_inc(DIAG_STAT_X304);
+ return __hypfs_sprp_diag304(data, cmd);
+}
+
static void hypfs_sprp_free(const void *data)
{
free_page((unsigned long) data);
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c
index afbe079..44feac3 100644
--- a/arch/s390/hypfs/hypfs_vm.c
+++ b/arch/s390/hypfs/hypfs_vm.c
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
+#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/timex.h>
#include "hypfs.h"
@@ -66,6 +67,7 @@ static int diag2fc(int size, char* query, void *addr)
memset(parm_list.aci_grp, 0x40, NAME_LEN);
rc = -1;
+ diag_stat_inc(DIAG_STAT_X2FC);
asm volatile(
" diag %0,%1,0x2fc\n"
"0:\n"
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index b2e5902..0f3da2c 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -67,7 +67,7 @@ static void hypfs_remove(struct dentry *dentry)
struct dentry *parent;
parent = dentry->d_parent;
- mutex_lock(&d_inode(parent)->i_mutex);
+ inode_lock(d_inode(parent));
if (simple_positive(dentry)) {
if (d_is_dir(dentry))
simple_rmdir(d_inode(parent), dentry);
@@ -76,7 +76,7 @@ static void hypfs_remove(struct dentry *dentry)
}
d_delete(dentry);
dput(dentry);
- mutex_unlock(&d_inode(parent)->i_mutex);
+ inode_unlock(d_inode(parent));
}
static void hypfs_delete_tree(struct dentry *root)
@@ -331,7 +331,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
struct dentry *dentry;
struct inode *inode;
- mutex_lock(&d_inode(parent)->i_mutex);
+ inode_lock(d_inode(parent));
dentry = lookup_one_len(name, parent, strlen(name));
if (IS_ERR(dentry)) {
dentry = ERR_PTR(-ENOMEM);
@@ -359,7 +359,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
d_instantiate(dentry, inode);
dget(dentry);
fail:
- mutex_unlock(&d_inode(parent)->i_mutex);
+ inode_unlock(d_inode(parent));
return dentry;
}
diff --git a/arch/s390/include/asm/appldata.h b/arch/s390/include/asm/appldata.h
index 16887c5..a6263d4 100644
--- a/arch/s390/include/asm/appldata.h
+++ b/arch/s390/include/asm/appldata.h
@@ -7,6 +7,7 @@
#ifndef _ASM_S390_APPLDATA_H
#define _ASM_S390_APPLDATA_H
+#include <asm/diag.h>
#include <asm/io.h>
#define APPLDATA_START_INTERVAL_REC 0x80
@@ -53,6 +54,7 @@ static inline int appldata_asm(struct appldata_product_id *id,
parm_list.buffer_length = length;
parm_list.product_id_addr = (unsigned long) id;
parm_list.buffer_addr = virt_to_phys(buffer);
+ diag_stat_inc(DIAG_STAT_X0DC);
asm volatile(
" diag %1,%0,0xdc"
: "=d" (ry)
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
index 117fa5c..911064a 100644
--- a/arch/s390/include/asm/atomic.h
+++ b/arch/s390/include/asm/atomic.h
@@ -36,7 +36,6 @@
\
typecheck(atomic_t *, ptr); \
asm volatile( \
- __barrier \
op_string " %0,%2,%1\n" \
__barrier \
: "=d" (old_val), "+Q" ((ptr)->counter) \
@@ -180,7 +179,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
\
typecheck(atomic64_t *, ptr); \
asm volatile( \
- __barrier \
op_string " %0,%2,%1\n" \
__barrier \
: "=d" (old_val), "+Q" ((ptr)->counter) \
diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
index d48fe01..5c8db3c 100644
--- a/arch/s390/include/asm/barrier.h
+++ b/arch/s390/include/asm/barrier.h
@@ -22,30 +22,22 @@
#define mb() do { asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
-#define rmb() mb()
-#define wmb() mb()
-#define dma_rmb() rmb()
-#define dma_wmb() wmb()
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
-
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() smp_mb()
-
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); mb(); } while (0)
-
-#define smp_store_release(p, v) \
+#define rmb() barrier()
+#define wmb() barrier()
+#define dma_rmb() mb()
+#define dma_wmb() mb()
+#define __smp_mb() mb()
+#define __smp_rmb() rmb()
+#define __smp_wmb() wmb()
+
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
barrier(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
@@ -53,4 +45,9 @@ do { \
___p1; \
})
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
+
+#include <asm-generic/barrier.h>
+
#endif /* __ASM_BARRIER_H */
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index 9b68e98..8043f10 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -11,30 +11,25 @@
* big-endian system because, unlike little endian, the number of each
* bit depends on the word size.
*
- * The bitop functions are defined to work on unsigned longs, so for an
- * s390x system the bits end up numbered:
+ * The bitop functions are defined to work on unsigned longs, so the bits
+ * end up numbered:
* |63..............0|127............64|191...........128|255...........192|
- * and on s390:
- * |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224|
*
* There are a few little-endian macros used mostly for filesystem
- * bitmaps, these work on similar bit arrays layouts, but
- * byte-oriented:
+ * bitmaps, these work on similar bit array layouts, but byte-oriented:
* |7...0|15...8|23...16|31...24|39...32|47...40|55...48|63...56|
*
- * The main difference is that bit 3-5 (64b) or 3-4 (32b) in the bit
- * number field needs to be reversed compared to the big-endian bit
- * fields. This can be achieved by XOR with 0x38 (64b) or 0x18 (32b).
+ * The main difference is that bit 3-5 in the bit number field needs to be
+ * reversed compared to the big-endian bit fields. This can be achieved by
+ * XOR with 0x38.
*
- * We also have special functions which work with an MSB0 encoding:
- * on an s390x system the bits are numbered:
+ * We also have special functions which work with an MSB0 encoding.
+ * The bits are numbered:
* |0..............63|64............127|128...........191|192...........255|
- * and on s390:
- * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
*
- * The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit
- * number field needs to be reversed compared to the LSB0 encoded bit
- * fields. This can be achieved by XOR with 0x3f (64b) or 0x1f (32b).
+ * The main difference is that bit 0-63 in the bit number field needs to be
+ * reversed compared to the LSB0 encoded bit fields. This can be achieved by
+ * XOR with 0x3f.
*
*/
@@ -64,7 +59,6 @@
\
typecheck(unsigned long *, (__addr)); \
asm volatile( \
- __barrier \
__op_string " %0,%2,%1\n" \
__barrier \
: "=d" (__old), "+Q" (*(__addr)) \
@@ -276,12 +270,32 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
return (*addr >> (nr & 7)) & 1;
}
+static inline int test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *ptr)
+{
+ if (test_bit(nr, ptr))
+ return 1;
+ return test_and_set_bit(nr, ptr);
+}
+
+static inline void clear_bit_unlock(unsigned long nr,
+ volatile unsigned long *ptr)
+{
+ smp_mb__before_atomic();
+ clear_bit(nr, ptr);
+}
+
+static inline void __clear_bit_unlock(unsigned long nr,
+ volatile unsigned long *ptr)
+{
+ smp_mb();
+ __clear_bit(nr, ptr);
+}
+
/*
* Functions which use MSB0 bit numbering.
- * On an s390x system the bits are numbered:
+ * The bits are numbered:
* |0..............63|64............127|128...........191|192...........255|
- * and on s390:
- * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
*/
unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size);
unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
@@ -446,7 +460,6 @@ static inline int fls(int word)
#include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
-#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h>
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index 7403648..d7f100c 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -91,8 +91,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
* returns a 32-bit checksum
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len, unsigned short proto,
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
__wsum sum)
{
__u32 csum = (__force __u32)sum;
@@ -118,8 +117,7 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
*/
static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len, unsigned short proto,
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 0963392..d1e7b0a 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -5,6 +5,7 @@
#define _ASM_S390_CIO_H_
#include <linux/spinlock.h>
+#include <linux/bitops.h>
#include <asm/types.h>
#define LPM_ANYPATH 0xff
@@ -296,12 +297,22 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
return 0;
}
+/**
+ * pathmask_to_pos() - find the position of the left-most bit in a pathmask
+ * @mask: pathmask with at least one bit set
+ */
+static inline u8 pathmask_to_pos(u8 mask)
+{
+ return 8 - ffs(mask);
+}
+
void channel_subsystem_reinit(void);
extern void css_schedule_reprobe(void);
extern void reipl_ccw_dev(struct ccw_dev_id *id);
struct cio_iplinfo {
+ u8 ssid;
u16 devno;
int is_qdio;
};
diff --git a/arch/s390/include/asm/clp.h b/arch/s390/include/asm/clp.h
index a0e71a5..5687d62 100644
--- a/arch/s390/include/asm/clp.h
+++ b/arch/s390/include/asm/clp.h
@@ -4,14 +4,23 @@
/* CLP common request & response block size */
#define CLP_BLK_SIZE PAGE_SIZE
+#define CLP_LPS_BASE 0
+#define CLP_LPS_PCI 2
+
struct clp_req_hdr {
u16 len;
u16 cmd;
+ u32 fmt : 4;
+ u32 reserved1 : 28;
+ u64 reserved2;
} __packed;
struct clp_rsp_hdr {
u16 len;
u16 rsp;
+ u32 fmt : 4;
+ u32 reserved1 : 28;
+ u64 reserved2;
} __packed;
/* CLP Response Codes */
@@ -25,4 +34,22 @@ struct clp_rsp_hdr {
#define CLP_RC_NODATA 0x0080 /* No data available */
#define CLP_RC_FC_UNKNOWN 0x0100 /* Function code not recognized */
+/* Store logical-processor characteristics request */
+struct clp_req_slpc {
+ struct clp_req_hdr hdr;
+} __packed;
+
+struct clp_rsp_slpc {
+ struct clp_rsp_hdr hdr;
+ u32 reserved2[4];
+ u32 lpif[8];
+ u32 reserved3[8];
+ u32 lpic[8];
+} __packed;
+
+struct clp_req_rsp_slpc {
+ struct clp_req_slpc request;
+ struct clp_rsp_slpc response;
+} __packed;
+
#endif
diff --git a/arch/s390/include/asm/cmb.h b/arch/s390/include/asm/cmb.h
index 806eac1..ed2630c 100644
--- a/arch/s390/include/asm/cmb.h
+++ b/arch/s390/include/asm/cmb.h
@@ -6,6 +6,7 @@
struct ccw_device;
extern int enable_cmf(struct ccw_device *cdev);
extern int disable_cmf(struct ccw_device *cdev);
+extern int __disable_cmf(struct ccw_device *cdev);
extern u64 cmf_read(struct ccw_device *cdev, int index);
extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data);
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h
index 411464f..24ea694 100644
--- a/arch/s390/include/asm/cmpxchg.h
+++ b/arch/s390/include/asm/cmpxchg.h
@@ -32,7 +32,7 @@
__old; \
})
-#define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \
+#define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
({ \
register __typeof__(*(p1)) __old1 asm("2") = (o1); \
register __typeof__(*(p2)) __old2 asm("3") = (o2); \
@@ -40,7 +40,7 @@
register __typeof__(*(p2)) __new2 asm("5") = (n2); \
int cc; \
asm volatile( \
- insn " %[old],%[new],%[ptr]\n" \
+ " cdsg %[old],%[new],%[ptr]\n" \
" ipm %[cc]\n" \
" srl %[cc],28" \
: [cc] "=d" (cc), [old] "+d" (__old1), "+d" (__old2) \
@@ -50,30 +50,6 @@
!cc; \
})
-#define __cmpxchg_double_4(p1, p2, o1, o2, n1, n2) \
- __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cds")
-
-#define __cmpxchg_double_8(p1, p2, o1, o2, n1, n2) \
- __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, "cdsg")
-
-extern void __cmpxchg_double_called_with_bad_pointer(void);
-
-#define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
-({ \
- int __ret; \
- switch (sizeof(*(p1))) { \
- case 4: \
- __ret = __cmpxchg_double_4(p1, p2, o1, o2, n1, n2); \
- break; \
- case 8: \
- __ret = __cmpxchg_double_8(p1, p2, o1, o2, n1, n2); \
- break; \
- default: \
- __cmpxchg_double_called_with_bad_pointer(); \
- } \
- __ret; \
-})
-
#define cmpxchg_double(p1, p2, o1, o2, n1, n2) \
({ \
__typeof__(p1) __p1 = (p1); \
@@ -81,7 +57,7 @@ extern void __cmpxchg_double_called_with_bad_pointer(void);
BUILD_BUG_ON(sizeof(*(p1)) != sizeof(long)); \
BUILD_BUG_ON(sizeof(*(p2)) != sizeof(long)); \
VM_BUG_ON((unsigned long)((__p1) + 1) != (unsigned long)(__p2));\
- __cmpxchg_double_8(__p1, __p2, o1, o2, n1, n2); \
+ __cmpxchg_double(__p1, __p2, o1, o2, n1, n2); \
})
#define system_has_cmpxchg_double() 1
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index d350ed9..352f7bd 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -284,7 +284,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
static inline int is_compat_task(void)
{
- return is_32bit_task();
+ return test_thread_flag(TIF_31BIT);
}
static inline void __user *arch_compat_alloc_user_space(long len)
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index 5243a86..9dd04b9 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -22,15 +22,10 @@
#define CPU_MF_INT_SF_LSDA (1 << 22) /* loss of sample data alert */
#define CPU_MF_INT_CF_CACA (1 << 7) /* counter auth. change alert */
#define CPU_MF_INT_CF_LCDA (1 << 6) /* loss of counter data alert */
-#define CPU_MF_INT_RI_HALTED (1 << 5) /* run-time instr. halted */
-#define CPU_MF_INT_RI_BUF_FULL (1 << 4) /* run-time instr. program
- buffer full */
-
#define CPU_MF_INT_CF_MASK (CPU_MF_INT_CF_CACA|CPU_MF_INT_CF_LCDA)
#define CPU_MF_INT_SF_MASK (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE| \
CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA| \
CPU_MF_INT_SF_LSDA)
-#define CPU_MF_INT_RI_MASK (CPU_MF_INT_RI_HALTED|CPU_MF_INT_RI_BUF_FULL)
/* CPU measurement facility support */
static inline int cpum_cf_avail(void)
diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h
index 7c31d3e..bcb9cd2 100644
--- a/arch/s390/include/asm/crw.h
+++ b/arch/s390/include/asm/crw.h
@@ -52,18 +52,4 @@ void crw_wait_for_channel_report(void);
#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
-static inline int stcrw(struct crw *pcrw)
-{
- int ccode;
-
- asm volatile(
- " stcrw 0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (ccode), "=m" (*pcrw)
- : "a" (pcrw)
- : "cc" );
- return ccode;
-}
-
#endif /* _ASM_S390_CRW_H */
diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h
index 17a3735..d7697ab 100644
--- a/arch/s390/include/asm/ctl_reg.h
+++ b/arch/s390/include/asm/ctl_reg.h
@@ -46,8 +46,6 @@ static inline void __ctl_clear_bit(unsigned int cr, unsigned int bit)
__ctl_load(reg, cr, cr);
}
-void __ctl_set_vx(void);
-
void smp_ctl_set_bit(int cr, int bit);
void smp_ctl_clear_bit(int cr, int bit);
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h
index 7e91c58..5fac921 100644
--- a/arch/s390/include/asm/diag.h
+++ b/arch/s390/include/asm/diag.h
@@ -8,6 +8,34 @@
#ifndef _ASM_S390_DIAG_H
#define _ASM_S390_DIAG_H
+#include <linux/percpu.h>
+
+enum diag_stat_enum {
+ DIAG_STAT_X008,
+ DIAG_STAT_X00C,
+ DIAG_STAT_X010,
+ DIAG_STAT_X014,
+ DIAG_STAT_X044,
+ DIAG_STAT_X064,
+ DIAG_STAT_X09C,
+ DIAG_STAT_X0DC,
+ DIAG_STAT_X204,
+ DIAG_STAT_X210,
+ DIAG_STAT_X224,
+ DIAG_STAT_X250,
+ DIAG_STAT_X258,
+ DIAG_STAT_X288,
+ DIAG_STAT_X2C4,
+ DIAG_STAT_X2FC,
+ DIAG_STAT_X304,
+ DIAG_STAT_X308,
+ DIAG_STAT_X500,
+ NR_DIAG_STAT
+};
+
+void diag_stat_inc(enum diag_stat_enum nr);
+void diag_stat_inc_norecursion(enum diag_stat_enum nr);
+
/*
* Diagnose 10: Release page range
*/
@@ -18,6 +46,7 @@ static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
start_addr = start_pfn << PAGE_SHIFT;
end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;
+ diag_stat_inc(DIAG_STAT_X010);
asm volatile(
"0: diag %0,%1,0x10\n"
"1:\n"
diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h
index b3fd54d..e64bfcb 100644
--- a/arch/s390/include/asm/dma-mapping.h
+++ b/arch/s390/include/asm/dma-mapping.h
@@ -23,8 +23,6 @@ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{
}
-#include <asm-generic/dma-mapping-common.h>
-
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 3ad48f2..563ab9f 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -104,6 +104,9 @@
#define HWCAP_S390_TE 1024
#define HWCAP_S390_VXRS 2048
+/* Internal bits, not exposed via elf */
+#define HWCAP_INT_SIE 1UL
+
/*
* These are used to set parameters in the core dumps.
*/
@@ -126,6 +129,7 @@ typedef s390_regs elf_gregset_t;
typedef s390_fp_regs compat_elf_fpregset_t;
typedef s390_compat_regs compat_elf_gregset_t;
+#include <linux/compat.h>
#include <linux/sched.h> /* for task_struct */
#include <asm/mmu_context.h>
@@ -159,7 +163,7 @@ extern unsigned int vdso_enabled;
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. 64-bit
tasks are aligned to 4GB. */
-#define ELF_ET_DYN_BASE (is_32bit_task() ? \
+#define ELF_ET_DYN_BASE (is_compat_task() ? \
(STACK_TOP / 3 * 2) : \
(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
@@ -169,6 +173,10 @@ extern unsigned int vdso_enabled;
extern unsigned long elf_hwcap;
#define ELF_HWCAP (elf_hwcap)
+/* Internal hardware capabilities, not exposed via elf */
+
+extern unsigned long int_hwcap;
+
/* 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.
@@ -206,9 +214,16 @@ do { \
} while (0)
#endif /* CONFIG_COMPAT */
-extern unsigned long mmap_rnd_mask;
-
-#define STACK_RND_MASK (test_thread_flag(TIF_31BIT) ? 0x7ff : mmap_rnd_mask)
+/*
+ * Cache aliasing on the latest machines calls for a mapping granularity
+ * of 512KB. For 64-bit processes use a 512KB alignment and a randomization
+ * of up to 1GB. For 31-bit processes the virtual address space is limited,
+ * use no alignment and limit the randomization to 8MB.
+ */
+#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ffffUL)
+#define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL)
+#define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL)
+#define STACK_RND_MASK MMAP_RND_MASK
#define ARCH_DLINFO \
do { \
@@ -222,6 +237,4 @@ struct linux_binprm;
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
int arch_setup_additional_pages(struct linux_binprm *, int);
-void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs);
-
#endif
diff --git a/arch/s390/include/asm/etr.h b/arch/s390/include/asm/etr.h
index f7e5c36..105f90e 100644
--- a/arch/s390/include/asm/etr.h
+++ b/arch/s390/include/asm/etr.h
@@ -211,8 +211,9 @@ static inline int etr_ptff(void *ptff_block, unsigned int func)
#define ETR_PTFF_SGS 0x43 /* set gross steering rate */
/* Functions needed by the machine check handler */
-void etr_switch_to_local(void);
-void etr_sync_check(void);
+int etr_switch_to_local(void);
+int etr_sync_check(void);
+void etr_queue_work(void);
/* notifier for syncs */
extern struct atomic_notifier_head s390_epoch_delta_notifier;
@@ -253,7 +254,8 @@ struct stp_sstpi {
} __attribute__ ((packed));
/* Functions needed by the machine check handler */
-void stp_sync_check(void);
-void stp_island_check(void);
+int stp_sync_check(void);
+int stp_island_check(void);
+void stp_queue_work(void);
#endif /* __S390_ETR_H */
diff --git a/arch/s390/include/asm/facilities_src.h b/arch/s390/include/asm/facilities_src.h
new file mode 100644
index 0000000..4917728
--- /dev/null
+++ b/arch/s390/include/asm/facilities_src.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright IBM Corp. 2015
+ */
+
+#ifndef S390_GEN_FACILITIES_C
+#error "This file can only be included by gen_facilities.c"
+#endif
+
+#include <linux/kconfig.h>
+
+struct facility_def {
+ char *name;
+ int *bits;
+};
+
+static struct facility_def facility_defs[] = {
+ {
+ /*
+ * FACILITIES_ALS contains the list of facilities that are
+ * required to run a kernel that is compiled e.g. with
+ * -march=<machine>.
+ */
+ .name = "FACILITIES_ALS",
+ .bits = (int[]){
+#ifdef CONFIG_HAVE_MARCH_Z900_FEATURES
+ 0, /* N3 instructions */
+ 1, /* z/Arch mode installed */
+#endif
+#ifdef CONFIG_HAVE_MARCH_Z990_FEATURES
+ 18, /* long displacement facility */
+#endif
+#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
+ 7, /* stfle */
+ 17, /* message security assist */
+ 21, /* extended-immediate facility */
+ 25, /* store clock fast */
+#endif
+#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+ 27, /* mvcos */
+ 32, /* compare and swap and store */
+ 33, /* compare and swap and store 2 */
+ 34, /* general extension facility */
+ 35, /* execute extensions */
+#endif
+#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
+ 45, /* fast-BCR, etc. */
+#endif
+#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
+ 49, /* misc-instruction-extensions */
+ 52, /* interlocked facility 2 */
+#endif
+#ifdef CONFIG_HAVE_MARCH_Z13_FEATURES
+ 53, /* load-and-zero-rightmost-byte, etc. */
+#endif
+ -1 /* END */
+ }
+ },
+};
diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h
index 0aa6a7e..09b406d 100644
--- a/arch/s390/include/asm/facility.h
+++ b/arch/s390/include/asm/facility.h
@@ -7,6 +7,10 @@
#ifndef __ASM_FACILITY_H
#define __ASM_FACILITY_H
+#include <generated/facilities.h>
+
+#ifndef __ASSEMBLY__
+
#include <linux/string.h>
#include <linux/preempt.h>
#include <asm/lowcore.h>
@@ -30,6 +34,12 @@ static inline int __test_facility(unsigned long nr, void *facilities)
*/
static inline int test_facility(unsigned long nr)
{
+ unsigned long facilities_als[] = { FACILITIES_ALS };
+
+ if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
+ if (__test_facility(nr, &facilities_als))
+ return 1;
+ }
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
}
@@ -44,10 +54,8 @@ static inline void stfle(u64 *stfle_fac_list, int size)
preempt_disable();
asm volatile(
- " .insn s,0xb2b10000,0(0)\n" /* stfl */
- "0:\n"
- EX_TABLE(0b, 0b)
- : "+m" (S390_lowcore.stfl_fac_list));
+ " stfl 0(0)\n"
+ : "=m" (S390_lowcore.stfl_fac_list));
nr = 4; /* bytes stored by stfl */
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
if (S390_lowcore.stfl_fac_list & 0x01000000) {
@@ -64,4 +72,5 @@ static inline void stfle(u64 *stfle_fac_list, int size)
preempt_enable();
}
+#endif /* __ASSEMBLY__ */
#endif /* __ASM_FACILITY_H */
diff --git a/arch/s390/include/asm/fpu-internal.h b/arch/s390/include/asm/fpu-internal.h
deleted file mode 100644
index 55dc2c0..0000000
--- a/arch/s390/include/asm/fpu-internal.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * General floating pointer and vector register helpers
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
- */
-
-#ifndef _ASM_S390_FPU_INTERNAL_H
-#define _ASM_S390_FPU_INTERNAL_H
-
-#define FPU_USE_VX 1 /* Vector extension is active */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <asm/linkage.h>
-#include <asm/ctl_reg.h>
-#include <asm/sigcontext.h>
-
-struct fpu {
- __u32 fpc; /* Floating-point control */
- __u32 flags;
- union {
- void *regs;
- freg_t *fprs; /* Floating-point register save area */
- __vector128 *vxrs; /* Vector register save area */
- };
-};
-
-void save_fpu_regs(void);
-
-#define is_vx_fpu(fpu) (!!((fpu)->flags & FPU_USE_VX))
-#define is_vx_task(tsk) (!!((tsk)->thread.fpu.flags & FPU_USE_VX))
-
-/* VX array structure for address operand constraints in inline assemblies */
-struct vx_array { __vector128 _[__NUM_VXRS]; };
-
-static inline int test_fp_ctl(u32 fpc)
-{
- u32 orig_fpc;
- int rc;
-
- asm volatile(
- " efpc %1\n"
- " sfpc %2\n"
- "0: sfpc %1\n"
- " la %0,0\n"
- "1:\n"
- EX_TABLE(0b,1b)
- : "=d" (rc), "=d" (orig_fpc)
- : "d" (fpc), "0" (-EINVAL));
- return rc;
-}
-
-static inline void save_vx_regs_safe(__vector128 *vxrs)
-{
- unsigned long cr0, flags;
-
- flags = arch_local_irq_save();
- __ctl_store(cr0, 0, 0);
- __ctl_set_bit(0, 17);
- __ctl_set_bit(0, 18);
- asm volatile(
- " la 1,%0\n"
- " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
- " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
- : "=Q" (*(struct vx_array *) vxrs) : : "1");
- __ctl_load(cr0, 0, 0);
- arch_local_irq_restore(flags);
-}
-
-static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
-{
- int i;
-
- for (i = 0; i < __NUM_FPRS; i++)
- fprs[i] = *(freg_t *)(vxrs + i);
-}
-
-static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
-{
- int i;
-
- for (i = 0; i < __NUM_FPRS; i++)
- *(freg_t *)(vxrs + i) = fprs[i];
-}
-
-static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
-{
- fpregs->pad = 0;
- if (is_vx_fpu(fpu))
- convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
- else
- memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
- sizeof(fpregs->fprs));
-}
-
-static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
-{
- if (is_vx_fpu(fpu))
- convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
- else
- memcpy(fpu->fprs, (freg_t *)&fpregs->fprs,
- sizeof(fpregs->fprs));
-}
-
-#endif
-
-#endif /* _ASM_S390_FPU_INTERNAL_H */
diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h
new file mode 100644
index 0000000..5e04f3c
--- /dev/null
+++ b/arch/s390/include/asm/fpu/api.h
@@ -0,0 +1,30 @@
+/*
+ * In-kernel FPU support functions
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_S390_FPU_API_H
+#define _ASM_S390_FPU_API_H
+
+void save_fpu_regs(void);
+
+static inline int test_fp_ctl(u32 fpc)
+{
+ u32 orig_fpc;
+ int rc;
+
+ asm volatile(
+ " efpc %1\n"
+ " sfpc %2\n"
+ "0: sfpc %1\n"
+ " la %0,0\n"
+ "1:\n"
+ EX_TABLE(0b,1b)
+ : "=d" (rc), "=d" (orig_fpc)
+ : "d" (fpc), "0" (-EINVAL));
+ return rc;
+}
+
+#endif /* _ASM_S390_FPU_API_H */
diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h
new file mode 100644
index 0000000..629c908
--- /dev/null
+++ b/arch/s390/include/asm/fpu/internal.h
@@ -0,0 +1,61 @@
+/*
+ * FPU state and register content conversion primitives
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_S390_FPU_INTERNAL_H
+#define _ASM_S390_FPU_INTERNAL_H
+
+#include <linux/string.h>
+#include <asm/ctl_reg.h>
+#include <asm/fpu/types.h>
+
+static inline void save_vx_regs(__vector128 *vxrs)
+{
+ asm volatile(
+ " la 1,%0\n"
+ " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
+ " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
+ : "=Q" (*(struct vx_array *) vxrs) : : "1");
+}
+
+static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
+{
+ int i;
+
+ for (i = 0; i < __NUM_FPRS; i++)
+ fprs[i] = *(freg_t *)(vxrs + i);
+}
+
+static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
+{
+ int i;
+
+ for (i = 0; i < __NUM_FPRS; i++)
+ *(freg_t *)(vxrs + i) = fprs[i];
+}
+
+static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
+{
+ fpregs->pad = 0;
+ fpregs->fpc = fpu->fpc;
+ if (MACHINE_HAS_VX)
+ convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
+ else
+ memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
+ sizeof(fpregs->fprs));
+}
+
+static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
+{
+ fpu->fpc = fpregs->fpc;
+ if (MACHINE_HAS_VX)
+ convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
+ else
+ memcpy(fpu->fprs, (freg_t *)&fpregs->fprs,
+ sizeof(fpregs->fprs));
+}
+
+#endif /* _ASM_S390_FPU_INTERNAL_H */
diff --git a/arch/s390/include/asm/fpu/types.h b/arch/s390/include/asm/fpu/types.h
new file mode 100644
index 0000000..14a8b0c
--- /dev/null
+++ b/arch/s390/include/asm/fpu/types.h
@@ -0,0 +1,25 @@
+/*
+ * FPU data structures
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_S390_FPU_TYPES_H
+#define _ASM_S390_FPU_TYPES_H
+
+#include <asm/sigcontext.h>
+
+struct fpu {
+ __u32 fpc; /* Floating-point control */
+ union {
+ void *regs;
+ freg_t *fprs; /* Floating-point register save area */
+ __vector128 *vxrs; /* Vector register save area */
+ };
+};
+
+/* VX array structure for address operand constraints in inline assemblies */
+struct vx_array { __vector128 _[__NUM_VXRS]; };
+
+#endif /* _ASM_S390_FPU_TYPES_H */
diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h
new file mode 100644
index 0000000..d054c1b
--- /dev/null
+++ b/arch/s390/include/asm/gmap.h
@@ -0,0 +1,64 @@
+/*
+ * KVM guest address space mapping code
+ *
+ * Copyright IBM Corp. 2007, 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_GMAP_H
+#define _ASM_S390_GMAP_H
+
+/**
+ * struct gmap_struct - guest address space
+ * @crst_list: list of all crst tables used in the guest address space
+ * @mm: pointer to the parent mm_struct
+ * @guest_to_host: radix tree with guest to host address translation
+ * @host_to_guest: radix tree with pointer to segment table entries
+ * @guest_table_lock: spinlock to protect all entries in the guest page table
+ * @table: pointer to the page directory
+ * @asce: address space control element for gmap page table
+ * @pfault_enabled: defines if pfaults are applicable for the guest
+ */
+struct gmap {
+ struct list_head list;
+ struct list_head crst_list;
+ struct mm_struct *mm;
+ struct radix_tree_root guest_to_host;
+ struct radix_tree_root host_to_guest;
+ spinlock_t guest_table_lock;
+ unsigned long *table;
+ unsigned long asce;
+ unsigned long asce_end;
+ void *private;
+ bool pfault_enabled;
+};
+
+/**
+ * struct gmap_notifier - notify function block for page invalidation
+ * @notifier_call: address of callback function
+ */
+struct gmap_notifier {
+ struct list_head list;
+ void (*notifier_call)(struct gmap *gmap, unsigned long gaddr);
+};
+
+struct gmap *gmap_alloc(struct mm_struct *mm, unsigned long limit);
+void gmap_free(struct gmap *gmap);
+void gmap_enable(struct gmap *gmap);
+void gmap_disable(struct gmap *gmap);
+int gmap_map_segment(struct gmap *gmap, unsigned long from,
+ unsigned long to, unsigned long len);
+int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
+unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
+unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
+int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
+int gmap_fault(struct gmap *, unsigned long gaddr, unsigned int fault_flags);
+void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
+void __gmap_zap(struct gmap *, unsigned long gaddr);
+void gmap_unlink(struct mm_struct *, unsigned long *table, unsigned long vmaddr);
+
+void gmap_register_ipte_notifier(struct gmap_notifier *);
+void gmap_unregister_ipte_notifier(struct gmap_notifier *);
+int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len);
+
+#endif /* _ASM_S390_GMAP_H */
diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h
index 113cd96..51ff96d 100644
--- a/arch/s390/include/asm/idle.h
+++ b/arch/s390/include/asm/idle.h
@@ -24,4 +24,6 @@ struct s390_idle_data {
extern struct device_attribute dev_attr_idle_count;
extern struct device_attribute dev_attr_idle_time_us;
+void psw_idle(struct s390_idle_data *, unsigned long);
+
#endif /* _S390_IDLE_H */
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index 39ae6a3..6fc44dc 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -64,7 +64,8 @@ struct ipl_block_fcp {
struct ipl_block_ccw {
u8 reserved1[84];
- u8 reserved2[2];
+ u16 reserved2 : 13;
+ u8 ssid : 3;
u16 devno;
u8 vm_flags;
u8 reserved3[3];
@@ -86,14 +87,12 @@ struct ipl_parameter_block {
* IPL validity flags
*/
extern u32 ipl_flags;
-extern u32 dump_prefix_page;
-struct dump_save_areas {
- struct save_area_ext **areas;
- int count;
-};
-
-extern struct dump_save_areas dump_save_areas;
+struct save_area;
+struct save_area * __init save_area_alloc(bool is_boot_cpu);
+struct save_area * __init save_area_boot_cpu(void);
+void __init save_area_add_regs(struct save_area *, void *regs);
+void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
extern void do_reipl(void);
extern void do_halt(void);
@@ -175,7 +174,7 @@ enum diag308_rc {
extern int diag308(unsigned long subcode, void *addr);
extern void diag308_reset(void);
-extern void store_status(void);
+extern void store_status(void (*fn)(void *), void *data);
extern void lgr_info_log(void);
#endif /* _ASM_S390_IPL_H */
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index ff95d15..f97b055 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -47,7 +47,6 @@ enum interruption_class {
IRQEXT_IUC,
IRQEXT_CMS,
IRQEXT_CMC,
- IRQEXT_CMR,
IRQEXT_FTP,
IRQIO_CIO,
IRQIO_QAI,
@@ -96,6 +95,19 @@ enum irq_subclass {
IRQ_SUBCLASS_SERVICE_SIGNAL = 9,
};
+#define CR0_IRQ_SUBCLASS_MASK \
+ ((1UL << (63 - 30)) /* Warning Track */ | \
+ (1UL << (63 - 48)) /* Malfunction Alert */ | \
+ (1UL << (63 - 49)) /* Emergency Signal */ | \
+ (1UL << (63 - 50)) /* External Call */ | \
+ (1UL << (63 - 52)) /* Clock Comparator */ | \
+ (1UL << (63 - 53)) /* CPU Timer */ | \
+ (1UL << (63 - 54)) /* Service Signal */ | \
+ (1UL << (63 - 57)) /* Interrupt Key */ | \
+ (1UL << (63 - 58)) /* Measurement Alert */ | \
+ (1UL << (63 - 59)) /* Timing Alert */ | \
+ (1UL << (63 - 62))) /* IUCV */
+
void irq_subclass_register(enum irq_subclass subclass);
void irq_subclass_unregister(enum irq_subclass subclass);
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h
index 16aa0c7..595a275 100644
--- a/arch/s390/include/asm/irqflags.h
+++ b/arch/s390/include/asm/irqflags.h
@@ -8,6 +8,8 @@
#include <linux/types.h>
+#define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8))
+
/* store then OR system mask. */
#define __arch_local_irq_stosm(__or) \
({ \
@@ -54,14 +56,17 @@ static inline notrace void arch_local_irq_enable(void)
__arch_local_irq_stosm(0x03);
}
+/* This only restores external and I/O interrupt state */
static inline notrace void arch_local_irq_restore(unsigned long flags)
{
- __arch_local_irq_ssm(flags);
+ /* only disabled->disabled and disabled->enabled is valid */
+ if (flags & ARCH_IRQ_ENABLED)
+ arch_local_irq_enable();
}
static inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
{
- return !(flags & (3UL << (BITS_PER_LONG - 8)));
+ return !(flags & ARCH_IRQ_ENABLED);
}
static inline notrace bool arch_irqs_disabled(void)
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 8ced426..6da41fa 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -20,12 +20,15 @@
#include <linux/kvm_types.h>
#include <linux/kvm_host.h>
#include <linux/kvm.h>
+#include <linux/seqlock.h>
#include <asm/debug.h>
#include <asm/cpu.h>
-#include <asm/fpu-internal.h>
+#include <asm/fpu/api.h>
#include <asm/isc.h>
-#define KVM_MAX_VCPUS 64
+#define KVM_S390_BSCA_CPU_SLOTS 64
+#define KVM_S390_ESCA_CPU_SLOTS 248
+#define KVM_MAX_VCPUS KVM_S390_ESCA_CPU_SLOTS
#define KVM_USER_MEM_SLOTS 32
/*
@@ -37,12 +40,41 @@
#define KVM_IRQCHIP_NUM_PINS 4096
#define KVM_HALT_POLL_NS_DEFAULT 0
+/* s390-specific vcpu->requests bit members */
+#define KVM_REQ_ENABLE_IBS 8
+#define KVM_REQ_DISABLE_IBS 9
+
#define SIGP_CTRL_C 0x80
#define SIGP_CTRL_SCN_MASK 0x3f
-struct sca_entry {
+union bsca_sigp_ctrl {
+ __u8 value;
+ struct {
+ __u8 c : 1;
+ __u8 r : 1;
+ __u8 scn : 6;
+ };
+} __packed;
+
+union esca_sigp_ctrl {
+ __u16 value;
+ struct {
+ __u8 c : 1;
+ __u8 reserved: 7;
+ __u8 scn;
+ };
+} __packed;
+
+struct esca_entry {
+ union esca_sigp_ctrl sigp_ctrl;
+ __u16 reserved1[3];
+ __u64 sda;
+ __u64 reserved2[6];
+} __packed;
+
+struct bsca_entry {
__u8 reserved0;
- __u8 sigp_ctrl;
+ union bsca_sigp_ctrl sigp_ctrl;
__u16 reserved[3];
__u64 sda;
__u64 reserved2[2];
@@ -57,14 +89,22 @@ union ipte_control {
};
};
-struct sca_block {
+struct bsca_block {
union ipte_control ipte_control;
__u64 reserved[5];
__u64 mcn;
__u64 reserved2;
- struct sca_entry cpu[64];
+ struct bsca_entry cpu[KVM_S390_BSCA_CPU_SLOTS];
} __attribute__((packed));
+struct esca_block {
+ union ipte_control ipte_control;
+ __u64 reserved1[7];
+ __u64 mcn[4];
+ __u64 reserved2[20];
+ struct esca_entry cpu[KVM_S390_ESCA_CPU_SLOTS];
+} __packed;
+
#define CPUSTAT_STOPPED 0x80000000
#define CPUSTAT_WAIT 0x10000000
#define CPUSTAT_ECALL_PEND 0x08000000
@@ -182,24 +222,19 @@ struct kvm_s390_sie_block {
__u64 pp; /* 0x01de */
__u8 reserved1e6[2]; /* 0x01e6 */
__u64 itdba; /* 0x01e8 */
- __u8 reserved1f0[16]; /* 0x01f0 */
+ __u64 riccbd; /* 0x01f0 */
+ __u8 reserved1f8[8]; /* 0x01f8 */
} __attribute__((packed));
struct kvm_s390_itdb {
__u8 data[256];
} __packed;
-struct kvm_s390_vregs {
- __vector128 vrs[32];
- __u8 reserved200[512]; /* for future vector expansion */
-} __packed;
-
struct sie_page {
struct kvm_s390_sie_block sie_block;
__u8 reserved200[1024]; /* 0x0200 */
struct kvm_s390_itdb itdb; /* 0x0600 */
- __u8 reserved700[1280]; /* 0x0700 */
- struct kvm_s390_vregs vregs; /* 0x0c00 */
+ __u8 reserved700[2304]; /* 0x0700 */
} __packed;
struct kvm_vcpu_stat {
@@ -427,7 +462,7 @@ struct kvm_s390_irq_payload {
struct kvm_s390_local_interrupt {
spinlock_t lock;
struct kvm_s390_float_interrupt *float_int;
- wait_queue_head_t *wq;
+ struct swait_queue_head *wq;
atomic_t *cpuflags;
DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS);
struct kvm_s390_irq_payload irq;
@@ -506,7 +541,6 @@ struct kvm_vcpu_arch {
struct kvm_s390_sie_block *sie_block;
unsigned int host_acrs[NUM_ACRS];
struct fpu host_fpregs;
- struct fpu guest_fpregs;
struct kvm_s390_local_interrupt local_int;
struct hrtimer ckc_timer;
struct kvm_s390_pgm_info pgm;
@@ -519,6 +553,15 @@ struct kvm_vcpu_arch {
unsigned long pfault_token;
unsigned long pfault_select;
unsigned long pfault_compare;
+ bool cputm_enabled;
+ /*
+ * The seqcount protects updates to cputm_start and sie_block.cputm,
+ * this way we can have non-blocking reads with consistent values.
+ * Only the owning VCPU thread (vcpu->cpu) is allowed to change these
+ * values and to start/stop/enable/disable cpu timer accounting.
+ */
+ seqcount_t cputm_seqcount;
+ __u64 cputm_start;
};
struct kvm_vm_stat {
@@ -557,15 +600,11 @@ struct s390_io_adapter {
#define S390_ARCH_FAC_MASK_SIZE_U64 \
(S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64))
-struct kvm_s390_fac {
- /* facility list requested by guest */
- __u64 list[S390_ARCH_FAC_LIST_SIZE_U64];
- /* facility mask supported by kvm & hosting machine */
- __u64 mask[S390_ARCH_FAC_LIST_SIZE_U64];
-};
-
struct kvm_s390_cpu_model {
- struct kvm_s390_fac *fac;
+ /* facility mask supported by kvm & hosting machine */
+ __u64 fac_mask[S390_ARCH_FAC_LIST_SIZE_U64];
+ /* facility list requested by guest (in dma page) */
+ __u64 *fac_list;
struct cpuid cpu_id;
unsigned short ibc;
};
@@ -584,12 +623,25 @@ struct kvm_s390_crypto_cb {
__u8 reserved80[128]; /* 0x0080 */
};
+/*
+ * sie_page2 has to be allocated as DMA because fac_list and crycb need
+ * 31bit addresses in the sie control block.
+ */
+struct sie_page2 {
+ __u64 fac_list[S390_ARCH_FAC_LIST_SIZE_U64]; /* 0x0000 */
+ struct kvm_s390_crypto_cb crycb; /* 0x0800 */
+ u8 reserved900[0x1000 - 0x900]; /* 0x0900 */
+} __packed;
+
struct kvm_arch{
- struct sca_block *sca;
+ void *sca;
+ int use_esca;
+ rwlock_t sca_lock;
debug_info_t *dbf;
struct kvm_s390_float_interrupt float_int;
struct kvm_device *flic;
struct gmap *gmap;
+ unsigned long mem_limit;
int css_support;
int use_irqchip;
int use_cmma;
@@ -601,6 +653,7 @@ struct kvm_arch{
int ipte_lock_count;
struct mutex ipte_mutex;
spinlock_t start_stop_lock;
+ struct sie_page2 *sie_page2;
struct kvm_s390_cpu_model model;
struct kvm_s390_crypto crypto;
u64 epoch;
@@ -644,5 +697,7 @@ static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslot
static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
#endif
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index e0f8423..4139305 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -27,10 +27,9 @@
#define __S390_KVM_PARA_H
#include <uapi/asm/kvm_para.h>
+#include <asm/diag.h>
-
-
-static inline long kvm_hypercall0(unsigned long nr)
+static inline long __kvm_hypercall0(unsigned long nr)
{
register unsigned long __nr asm("1") = nr;
register long __rc asm("2");
@@ -40,7 +39,13 @@ static inline long kvm_hypercall0(unsigned long nr)
return __rc;
}
-static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
+static inline long kvm_hypercall0(unsigned long nr)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall0(nr);
+}
+
+static inline long __kvm_hypercall1(unsigned long nr, unsigned long p1)
{
register unsigned long __nr asm("1") = nr;
register unsigned long __p1 asm("2") = p1;
@@ -51,7 +56,13 @@ static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
return __rc;
}
-static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall1(unsigned long nr, unsigned long p1)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall1(nr, p1);
+}
+
+static inline long __kvm_hypercall2(unsigned long nr, unsigned long p1,
unsigned long p2)
{
register unsigned long __nr asm("1") = nr;
@@ -65,7 +76,14 @@ static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
return __rc;
}
-static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall2(unsigned long nr, unsigned long p1,
+ unsigned long p2)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall2(nr, p1, p2);
+}
+
+static inline long __kvm_hypercall3(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3)
{
register unsigned long __nr asm("1") = nr;
@@ -80,8 +98,14 @@ static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
return __rc;
}
+static inline long kvm_hypercall3(unsigned long nr, unsigned long p1,
+ unsigned long p2, unsigned long p3)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall3(nr, p1, p2, p3);
+}
-static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
+static inline long __kvm_hypercall4(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
@@ -98,7 +122,15 @@ static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
return __rc;
}
-static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall4(unsigned long nr, unsigned long p1,
+ unsigned long p2, unsigned long p3,
+ unsigned long p4)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall4(nr, p1, p2, p3, p4);
+}
+
+static inline long __kvm_hypercall5(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5)
{
@@ -116,7 +148,15 @@ static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
return __rc;
}
-static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
+static inline long kvm_hypercall5(unsigned long nr, unsigned long p1,
+ unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall5(nr, p1, p2, p3, p4, p5);
+}
+
+static inline long __kvm_hypercall6(unsigned long nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5,
unsigned long p6)
@@ -137,6 +177,15 @@ static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
return __rc;
}
+static inline long kvm_hypercall6(unsigned long nr, unsigned long p1,
+ unsigned long p2, unsigned long p3,
+ unsigned long p4, unsigned long p5,
+ unsigned long p6)
+{
+ diag_stat_inc(DIAG_STAT_X500);
+ return __kvm_hypercall6(nr, p1, p2, p3, p4, p5, p6);
+}
+
/* kvm on s390 is always paravirtualization enabled */
static inline int kvm_para_available(void)
{
diff --git a/arch/s390/include/asm/livepatch.h b/arch/s390/include/asm/livepatch.h
index 7aa7991..d5427c7 100644
--- a/arch/s390/include/asm/livepatch.h
+++ b/arch/s390/include/asm/livepatch.h
@@ -19,7 +19,6 @@
#include <linux/module.h>
-#ifdef CONFIG_LIVEPATCH
static inline int klp_check_compiler_support(void)
{
return 0;
@@ -36,8 +35,5 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
{
regs->psw.addr = ip;
}
-#else
-#error Live patching support is disabled; check CONFIG_LIVEPATCH
-#endif
#endif
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 663f23e..d79ba7c 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -16,28 +16,7 @@
#define LC_ORDER 1
#define LC_PAGES 2
-struct save_area {
- u64 fp_regs[16];
- u64 gp_regs[16];
- u8 psw[16];
- u8 pad1[8];
- u32 pref_reg;
- u32 fp_ctrl_reg;
- u8 pad2[4];
- u32 tod_reg;
- u64 timer;
- u64 clk_cmp;
- u8 pad3[8];
- u32 acc_regs[16];
- u64 ctrl_regs[16];
-} __packed;
-
-struct save_area_ext {
- struct save_area sa;
- __vector128 vx_regs[32];
-};
-
-struct _lowcore {
+struct lowcore {
__u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */
__u32 ipl_parmblock_ptr; /* 0x0014 */
__u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */
@@ -67,7 +46,7 @@ struct _lowcore {
__u8 pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */
__u32 stfl_fac_list; /* 0x00c8 */
__u8 pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */
- __u32 mcck_interruption_code[2]; /* 0x00e8 */
+ __u64 mcck_interruption_code; /* 0x00e8 */
__u8 pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */
__u32 external_damage_code; /* 0x00f4 */
__u64 failing_storage_address; /* 0x00f8 */
@@ -132,7 +111,14 @@ struct _lowcore {
/* Address space pointer. */
__u64 kernel_asce; /* 0x0358 */
__u64 user_asce; /* 0x0360 */
- __u64 current_pid; /* 0x0368 */
+
+ /*
+ * The lpp and current_pid fields form a
+ * 64-bit value that is set as program
+ * parameter with the LPP instruction.
+ */
+ __u32 lpp; /* 0x0368 */
+ __u32 current_pid; /* 0x036c */
/* SMP info area */
__u32 cpu_nr; /* 0x0370 */
@@ -197,9 +183,9 @@ struct _lowcore {
__u8 vector_save_area[1024]; /* 0x1c00 */
} __packed;
-#define S390_lowcore (*((struct _lowcore *) 0))
+#define S390_lowcore (*((struct lowcore *) 0))
-extern struct _lowcore *lowcore_ptr[];
+extern struct lowcore *lowcore_ptr[];
static inline void set_prefix(__u32 address)
{
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index fb1b93e..e485817 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -15,17 +15,25 @@
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
{
+ spin_lock_init(&mm->context.list_lock);
+ INIT_LIST_HEAD(&mm->context.pgtable_list);
+ INIT_LIST_HEAD(&mm->context.gmap_list);
cpumask_clear(&mm->context.cpu_attach_mask);
atomic_set(&mm->context.attach_count, 0);
mm->context.flush_mm = 0;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
- mm->context.asce_bits |= _ASCE_TYPE_REGION3;
#ifdef CONFIG_PGSTE
mm->context.alloc_pgste = page_table_allocate_pgste;
mm->context.has_pgste = 0;
mm->context.use_skey = 0;
#endif
- mm->context.asce_limit = STACK_TOP_MAX;
+ if (mm->context.asce_limit == 0) {
+ /* context created by exec, set asce limit to 4TB */
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS | _ASCE_TYPE_REGION3;
+ mm->context.asce_limit = STACK_TOP_MAX;
+ } else if (mm->context.asce_limit == (1UL << 31)) {
+ mm_inc_nr_pmds(mm);
+ }
crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
return 0;
}
@@ -111,8 +119,6 @@ static inline void activate_mm(struct mm_struct *prev,
static inline void arch_dup_mmap(struct mm_struct *oldmm,
struct mm_struct *mm)
{
- if (oldmm->context.asce_limit < mm->context.asce_limit)
- crst_table_downgrade(mm, oldmm->context.asce_limit);
}
static inline void arch_exit_mmap(struct mm_struct *mm)
diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h
index 3027a5a..b75fd91 100644
--- a/arch/s390/include/asm/nmi.h
+++ b/arch/s390/include/asm/nmi.h
@@ -11,51 +11,62 @@
#ifndef _ASM_S390_NMI_H
#define _ASM_S390_NMI_H
+#include <linux/const.h>
#include <linux/types.h>
-struct mci {
- __u32 sd : 1; /* 00 system damage */
- __u32 pd : 1; /* 01 instruction-processing damage */
- __u32 sr : 1; /* 02 system recovery */
- __u32 : 1; /* 03 */
- __u32 cd : 1; /* 04 timing-facility damage */
- __u32 ed : 1; /* 05 external damage */
- __u32 : 1; /* 06 */
- __u32 dg : 1; /* 07 degradation */
- __u32 w : 1; /* 08 warning pending */
- __u32 cp : 1; /* 09 channel-report pending */
- __u32 sp : 1; /* 10 service-processor damage */
- __u32 ck : 1; /* 11 channel-subsystem damage */
- __u32 : 2; /* 12-13 */
- __u32 b : 1; /* 14 backed up */
- __u32 : 1; /* 15 */
- __u32 se : 1; /* 16 storage error uncorrected */
- __u32 sc : 1; /* 17 storage error corrected */
- __u32 ke : 1; /* 18 storage-key error uncorrected */
- __u32 ds : 1; /* 19 storage degradation */
- __u32 wp : 1; /* 20 psw mwp validity */
- __u32 ms : 1; /* 21 psw mask and key validity */
- __u32 pm : 1; /* 22 psw program mask and cc validity */
- __u32 ia : 1; /* 23 psw instruction address validity */
- __u32 fa : 1; /* 24 failing storage address validity */
- __u32 vr : 1; /* 25 vector register validity */
- __u32 ec : 1; /* 26 external damage code validity */
- __u32 fp : 1; /* 27 floating point register validity */
- __u32 gr : 1; /* 28 general register validity */
- __u32 cr : 1; /* 29 control register validity */
- __u32 : 1; /* 30 */
- __u32 st : 1; /* 31 storage logical validity */
- __u32 ie : 1; /* 32 indirect storage error */
- __u32 ar : 1; /* 33 access register validity */
- __u32 da : 1; /* 34 delayed access exception */
- __u32 : 7; /* 35-41 */
- __u32 pr : 1; /* 42 tod programmable register validity */
- __u32 fc : 1; /* 43 fp control register validity */
- __u32 ap : 1; /* 44 ancillary report */
- __u32 : 1; /* 45 */
- __u32 ct : 1; /* 46 cpu timer validity */
- __u32 cc : 1; /* 47 clock comparator validity */
- __u32 : 16; /* 47-63 */
+#define MCCK_CODE_SYSTEM_DAMAGE _BITUL(63)
+#define MCCK_CODE_CPU_TIMER_VALID _BITUL(63 - 46)
+#define MCCK_CODE_PSW_MWP_VALID _BITUL(63 - 20)
+#define MCCK_CODE_PSW_IA_VALID _BITUL(63 - 23)
+
+#ifndef __ASSEMBLY__
+
+union mci {
+ unsigned long val;
+ struct {
+ u64 sd : 1; /* 00 system damage */
+ u64 pd : 1; /* 01 instruction-processing damage */
+ u64 sr : 1; /* 02 system recovery */
+ u64 : 1; /* 03 */
+ u64 cd : 1; /* 04 timing-facility damage */
+ u64 ed : 1; /* 05 external damage */
+ u64 : 1; /* 06 */
+ u64 dg : 1; /* 07 degradation */
+ u64 w : 1; /* 08 warning pending */
+ u64 cp : 1; /* 09 channel-report pending */
+ u64 sp : 1; /* 10 service-processor damage */
+ u64 ck : 1; /* 11 channel-subsystem damage */
+ u64 : 2; /* 12-13 */
+ u64 b : 1; /* 14 backed up */
+ u64 : 1; /* 15 */
+ u64 se : 1; /* 16 storage error uncorrected */
+ u64 sc : 1; /* 17 storage error corrected */
+ u64 ke : 1; /* 18 storage-key error uncorrected */
+ u64 ds : 1; /* 19 storage degradation */
+ u64 wp : 1; /* 20 psw mwp validity */
+ u64 ms : 1; /* 21 psw mask and key validity */
+ u64 pm : 1; /* 22 psw program mask and cc validity */
+ u64 ia : 1; /* 23 psw instruction address validity */
+ u64 fa : 1; /* 24 failing storage address validity */
+ u64 vr : 1; /* 25 vector register validity */
+ u64 ec : 1; /* 26 external damage code validity */
+ u64 fp : 1; /* 27 floating point register validity */
+ u64 gr : 1; /* 28 general register validity */
+ u64 cr : 1; /* 29 control register validity */
+ u64 : 1; /* 30 */
+ u64 st : 1; /* 31 storage logical validity */
+ u64 ie : 1; /* 32 indirect storage error */
+ u64 ar : 1; /* 33 access register validity */
+ u64 da : 1; /* 34 delayed access exception */
+ u64 : 7; /* 35-41 */
+ u64 pr : 1; /* 42 tod programmable register validity */
+ u64 fc : 1; /* 43 fp control register validity */
+ u64 ap : 1; /* 44 ancillary report */
+ u64 : 1; /* 45 */
+ u64 ct : 1; /* 46 cpu timer validity */
+ u64 cc : 1; /* 47 clock comparator validity */
+ u64 : 16; /* 47-63 */
+ };
};
struct pt_regs;
@@ -63,4 +74,5 @@ struct pt_regs;
extern void s390_handle_mcck(void);
extern void s390_do_machine_check(struct pt_regs *regs);
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_NMI_H */
diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h
index 295f2c4..9434753 100644
--- a/arch/s390/include/asm/os_info.h
+++ b/arch/s390/include/asm/os_info.h
@@ -38,7 +38,7 @@ u32 os_info_csum(struct os_info *os_info);
#ifdef CONFIG_CRASH_DUMP
void *os_info_old_entry(int nr, unsigned long *size);
-int copy_from_oldmem(void *dest, void *src, size_t count);
+int copy_oldmem_kernel(void *dst, void *src, size_t count);
#else
static inline void *os_info_old_entry(int nr, unsigned long *size)
{
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 34d9603..b6bfa16 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -9,7 +9,6 @@
#include <linux/pci.h>
#include <linux/mutex.h>
#include <asm-generic/pci.h>
-#include <asm-generic/pci-dma-compat.h>
#include <asm/pci_clp.h>
#include <asm/pci_debug.h>
@@ -45,7 +44,7 @@ struct zpci_fmb {
u64 rpcit_ops;
u64 dma_rbytes;
u64 dma_wbytes;
-} __packed __aligned(16);
+} __packed __aligned(64);
enum zpci_state {
ZPCI_FN_STATE_RESERVED,
@@ -62,9 +61,10 @@ struct zpci_bar_struct {
u8 size; /* order 2 exponent */
};
+struct s390_domain;
+
/* Private data per function */
struct zpci_dev {
- struct pci_dev *pdev;
struct pci_bus *bus;
struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */
@@ -118,6 +118,8 @@ struct zpci_dev {
struct dentry *debugfs_dev;
struct dentry *debugfs_perf;
+
+ struct s390_domain *s390_domain; /* s390 IOMMU domain data */
};
static inline bool zdev_enabled(struct zpci_dev *zdev)
@@ -188,7 +190,7 @@ int zpci_fmb_disable_device(struct zpci_dev *);
/* Debug */
int zpci_debug_init(void);
void zpci_debug_exit(void);
-void zpci_debug_init_device(struct zpci_dev *);
+void zpci_debug_init_device(struct zpci_dev *, const char *);
void zpci_debug_exit_device(struct zpci_dev *);
void zpci_debug_info(struct zpci_dev *, struct seq_file *);
diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h
index dd78f92..e75c64cb 100644
--- a/arch/s390/include/asm/pci_clp.h
+++ b/arch/s390/include/asm/pci_clp.h
@@ -49,9 +49,6 @@ struct clp_fh_list_entry {
/* List PCI functions request */
struct clp_req_list_pci {
struct clp_req_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u64 resume_token;
u64 reserved2;
} __packed;
@@ -59,9 +56,6 @@ struct clp_req_list_pci {
/* List PCI functions response */
struct clp_rsp_list_pci {
struct clp_rsp_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u64 resume_token;
u32 reserved2;
u16 max_fn;
@@ -73,9 +67,6 @@ struct clp_rsp_list_pci {
/* Query PCI function request */
struct clp_req_query_pci {
struct clp_req_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u32 fh; /* function handle */
u32 reserved2;
u64 reserved3;
@@ -84,9 +75,6 @@ struct clp_req_query_pci {
/* Query PCI function response */
struct clp_rsp_query_pci {
struct clp_rsp_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 : 64;
u16 vfn; /* virtual fn number */
u16 : 7;
u16 util_str_avail : 1; /* utility string available? */
@@ -108,21 +96,15 @@ struct clp_rsp_query_pci {
/* Query PCI function group request */
struct clp_req_query_pci_grp {
struct clp_req_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
- u32 : 24;
+ u32 reserved2 : 24;
u32 pfgid : 8; /* function group id */
- u32 reserved2;
- u64 reserved3;
+ u32 reserved3;
+ u64 reserved4;
} __packed;
/* Query PCI function group response */
struct clp_rsp_query_pci_grp {
struct clp_rsp_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u16 : 4;
u16 noi : 12; /* number of interrupts */
u8 version;
@@ -141,9 +123,6 @@ struct clp_rsp_query_pci_grp {
/* Set PCI function request */
struct clp_req_set_pci {
struct clp_req_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u32 fh; /* function handle */
u16 reserved2;
u8 oc; /* operation controls */
@@ -154,9 +133,6 @@ struct clp_req_set_pci {
/* Set PCI function response */
struct clp_rsp_set_pci {
struct clp_rsp_hdr hdr;
- u32 fmt : 4; /* cmd request block format */
- u32 : 28;
- u64 reserved1;
u32 fh; /* function handle */
u32 reserved3;
u64 reserved4;
diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h
index 30b4c17..92df3eb 100644
--- a/arch/s390/include/asm/pci_dma.h
+++ b/arch/s390/include/asm/pci_dma.h
@@ -23,6 +23,8 @@ enum zpci_ioat_dtype {
#define ZPCI_IOTA_FS_2G 2
#define ZPCI_KEY (PAGE_DEFAULT_KEY << 5)
+#define ZPCI_TABLE_SIZE_RT (1UL << 42)
+
#define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST)
#define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT)
#define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS)
@@ -192,5 +194,10 @@ static inline unsigned long *get_st_pto(unsigned long entry)
/* Prototypes */
int zpci_dma_init_device(struct zpci_dev *);
void zpci_dma_exit_device(struct zpci_dev *);
+void dma_free_seg_table(unsigned long);
+unsigned long *dma_alloc_cpu_table(void);
+void dma_cleanup_tables(unsigned long *);
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr);
+void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags);
#endif
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
index 1a9a98d..69aa18b 100644
--- a/arch/s390/include/asm/pci_io.h
+++ b/arch/s390/include/asm/pci_io.h
@@ -8,10 +8,13 @@
#include <asm/pci_insn.h>
/* I/O Map */
-#define ZPCI_IOMAP_MAX_ENTRIES 0x7fff
-#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL
-#define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL
-#define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL
+#define ZPCI_IOMAP_SHIFT 48
+#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL
+#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
+#define ZPCI_IOMAP_MAX_ENTRIES \
+ ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT))
+#define ZPCI_IOMAP_ADDR_IDX_MASK \
+ (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE)
struct zpci_iomap_entry {
u32 fh;
@@ -21,8 +24,9 @@ struct zpci_iomap_entry {
extern struct zpci_iomap_entry *zpci_iomap_start;
+#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
#define ZPCI_IDX(addr) \
- (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48)
+ (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
#define ZPCI_OFFSET(addr) \
((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 6d6556c..90240df 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -178,7 +178,6 @@
ret__; \
})
-#define this_cpu_cmpxchg_double_4 arch_this_cpu_cmpxchg_double
#define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double
#include <asm-generic/percpu.h>
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
index f897ec7..1f7ff85 100644
--- a/arch/s390/include/asm/perf_event.h
+++ b/arch/s390/include/asm/perf_event.h
@@ -21,7 +21,7 @@
#define PMU_F_ERR_LSDA 0x0200
#define PMU_F_ERR_MASK (PMU_F_ERR_IBE|PMU_F_ERR_LSDA)
-/* Perf defintions for PMU event attributes in sysfs */
+/* Perf definitions for PMU event attributes in sysfs */
extern __init const struct attribute_group **cpumf_cf_event_group(void);
extern ssize_t cpumf_events_sysfs_show(struct device *dev,
struct device_attribute *attr,
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 7b7858f..9b3d9b6 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -23,10 +23,6 @@ void page_table_free(struct mm_struct *, unsigned long *);
void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long);
extern int page_table_allocate_pgste;
-int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
- unsigned long key, bool nq);
-unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr);
-
static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
{
typedef struct { char _[n]; } addrtype;
@@ -100,12 +96,26 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
- spin_lock_init(&mm->context.list_lock);
- INIT_LIST_HEAD(&mm->context.pgtable_list);
- INIT_LIST_HEAD(&mm->context.gmap_list);
- return (pgd_t *) crst_table_alloc(mm);
+ unsigned long *table = crst_table_alloc(mm);
+
+ if (!table)
+ return NULL;
+ if (mm->context.asce_limit == (1UL << 31)) {
+ /* Forking a compat process with 2 page table levels */
+ if (!pgtable_pmd_page_ctor(virt_to_page(table))) {
+ crst_table_free(mm, table);
+ return NULL;
+ }
+ }
+ return (pgd_t *) table;
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ if (mm->context.asce_limit == (1UL << 31))
+ pgtable_pmd_page_dtor(virt_to_page(pgd));
+ crst_table_free(mm, (unsigned long *) pgd);
}
-#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
static inline void pmd_populate(struct mm_struct *mm,
pmd_t *pmd, pgtable_t pte)
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index bdb2f51..2f66645 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -193,9 +193,15 @@ static inline int is_module_addr(void *addr)
#define _PAGE_UNUSED 0x080 /* SW bit for pgste usage state */
#define __HAVE_ARCH_PTE_SPECIAL
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SOFT_DIRTY 0x002 /* SW pte soft dirty bit */
+#else
+#define _PAGE_SOFT_DIRTY 0x000
+#endif
+
/* Set of bits not changed in pte_modify */
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL | _PAGE_DIRTY | \
- _PAGE_YOUNG)
+ _PAGE_YOUNG | _PAGE_SOFT_DIRTY)
/*
* handle_pte_fault uses pte_present and pte_none to find out the pte type
@@ -280,22 +286,27 @@ static inline int is_module_addr(void *addr)
#define _SEGMENT_ENTRY_DIRTY 0x2000 /* SW segment dirty bit */
#define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */
-#define _SEGMENT_ENTRY_SPLIT 0x0800 /* THP splitting bit */
#define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */
#define _SEGMENT_ENTRY_READ 0x0002 /* SW segment read bit */
#define _SEGMENT_ENTRY_WRITE 0x0001 /* SW segment write bit */
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _SEGMENT_ENTRY_SOFT_DIRTY 0x4000 /* SW segment soft dirty bit */
+#else
+#define _SEGMENT_ENTRY_SOFT_DIRTY 0x0000 /* SW segment soft dirty bit */
+#endif
+
/*
* Segment table entry encoding (R = read-only, I = invalid, y = young bit):
- * dy..R...I...wr
+ * dy..R...I...rw
* prot-none, clean, old 00..1...1...00
* prot-none, clean, young 01..1...1...00
* prot-none, dirty, old 10..1...1...00
* prot-none, dirty, young 11..1...1...00
- * read-only, clean, old 00..1...1...01
- * read-only, clean, young 01..1...0...01
- * read-only, dirty, old 10..1...1...01
- * read-only, dirty, young 11..1...0...01
+ * read-only, clean, old 00..1...1...10
+ * read-only, clean, young 01..1...0...10
+ * read-only, dirty, old 10..1...1...10
+ * read-only, dirty, young 11..1...0...10
* read-write, clean, old 00..1...1...11
* read-write, clean, young 01..1...0...11
* read-write, dirty, old 10..0...1...11
@@ -306,8 +317,6 @@ static inline int is_module_addr(void *addr)
* SW-bits: y young, d dirty, r read, w write
*/
-#define _SEGMENT_ENTRY_SPLIT_BIT 11 /* THP splitting bit number */
-
/* Page status table bits for virtualization */
#define PGSTE_ACC_BITS 0xf000000000000000UL
#define PGSTE_FP_BIT 0x0800000000000000UL
@@ -511,19 +520,6 @@ static inline int pmd_bad(pmd_t pmd)
return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0;
}
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-extern void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long addr, pmd_t *pmdp);
-
-#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
-extern int pmdp_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp,
- pmd_t entry, int dirty);
-
-#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
-extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp);
-
#define __HAVE_ARCH_PMD_WRITE
static inline int pmd_write(pmd_t pmd)
{
@@ -589,206 +585,41 @@ static inline int pmd_protnone(pmd_t pmd)
}
#endif
-static inline pgste_t pgste_get_lock(pte_t *ptep)
+static inline int pte_soft_dirty(pte_t pte)
{
- unsigned long new = 0;
-#ifdef CONFIG_PGSTE
- unsigned long old;
-
- preempt_disable();
- asm(
- " lg %0,%2\n"
- "0: lgr %1,%0\n"
- " nihh %0,0xff7f\n" /* clear PCL bit in old */
- " oihh %1,0x0080\n" /* set PCL bit in new */
- " csg %0,%1,%2\n"
- " jl 0b\n"
- : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
- : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory");
-#endif
- return __pgste(new);
+ return pte_val(pte) & _PAGE_SOFT_DIRTY;
}
+#define pte_swp_soft_dirty pte_soft_dirty
-static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
+static inline pte_t pte_mksoft_dirty(pte_t pte)
{
-#ifdef CONFIG_PGSTE
- asm(
- " nihh %1,0xff7f\n" /* clear PCL bit */
- " stg %1,%0\n"
- : "=Q" (ptep[PTRS_PER_PTE])
- : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
- : "cc", "memory");
- preempt_enable();
-#endif
-}
-
-static inline pgste_t pgste_get(pte_t *ptep)
-{
- unsigned long pgste = 0;
-#ifdef CONFIG_PGSTE
- pgste = *(unsigned long *)(ptep + PTRS_PER_PTE);
-#endif
- return __pgste(pgste);
-}
-
-static inline void pgste_set(pte_t *ptep, pgste_t pgste)
-{
-#ifdef CONFIG_PGSTE
- *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste;
-#endif
+ pte_val(pte) |= _PAGE_SOFT_DIRTY;
+ return pte;
}
+#define pte_swp_mksoft_dirty pte_mksoft_dirty
-static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste,
- struct mm_struct *mm)
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
{
-#ifdef CONFIG_PGSTE
- unsigned long address, bits, skey;
-
- if (!mm_use_skey(mm) || pte_val(*ptep) & _PAGE_INVALID)
- return pgste;
- address = pte_val(*ptep) & PAGE_MASK;
- skey = (unsigned long) page_get_storage_key(address);
- bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
- /* Transfer page changed & referenced bit to guest bits in pgste */
- pgste_val(pgste) |= bits << 48; /* GR bit & GC bit */
- /* Copy page access key and fetch protection bit to pgste */
- pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT);
- pgste_val(pgste) |= (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
-#endif
- return pgste;
-
+ pte_val(pte) &= ~_PAGE_SOFT_DIRTY;
+ return pte;
}
+#define pte_swp_clear_soft_dirty pte_clear_soft_dirty
-static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry,
- struct mm_struct *mm)
+static inline int pmd_soft_dirty(pmd_t pmd)
{
-#ifdef CONFIG_PGSTE
- unsigned long address;
- unsigned long nkey;
-
- if (!mm_use_skey(mm) || pte_val(entry) & _PAGE_INVALID)
- return;
- VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
- address = pte_val(entry) & PAGE_MASK;
- /*
- * Set page access key and fetch protection bit from pgste.
- * The guest C/R information is still in the PGSTE, set real
- * key C/R to 0.
- */
- nkey = (pgste_val(pgste) & (PGSTE_ACC_BITS | PGSTE_FP_BIT)) >> 56;
- nkey |= (pgste_val(pgste) & (PGSTE_GR_BIT | PGSTE_GC_BIT)) >> 48;
- page_set_storage_key(address, nkey, 0);
-#endif
+ return pmd_val(pmd) & _SEGMENT_ENTRY_SOFT_DIRTY;
}
-static inline pgste_t pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
-{
- if ((pte_val(entry) & _PAGE_PRESENT) &&
- (pte_val(entry) & _PAGE_WRITE) &&
- !(pte_val(entry) & _PAGE_INVALID)) {
- if (!MACHINE_HAS_ESOP) {
- /*
- * Without enhanced suppression-on-protection force
- * the dirty bit on for all writable ptes.
- */
- pte_val(entry) |= _PAGE_DIRTY;
- pte_val(entry) &= ~_PAGE_PROTECT;
- }
- if (!(pte_val(entry) & _PAGE_PROTECT))
- /* This pte allows write access, set user-dirty */
- pgste_val(pgste) |= PGSTE_UC_BIT;
- }
- *ptep = entry;
- return pgste;
-}
-
-/**
- * struct gmap_struct - guest address space
- * @crst_list: list of all crst tables used in the guest address space
- * @mm: pointer to the parent mm_struct
- * @guest_to_host: radix tree with guest to host address translation
- * @host_to_guest: radix tree with pointer to segment table entries
- * @guest_table_lock: spinlock to protect all entries in the guest page table
- * @table: pointer to the page directory
- * @asce: address space control element for gmap page table
- * @pfault_enabled: defines if pfaults are applicable for the guest
- */
-struct gmap {
- struct list_head list;
- struct list_head crst_list;
- struct mm_struct *mm;
- struct radix_tree_root guest_to_host;
- struct radix_tree_root host_to_guest;
- spinlock_t guest_table_lock;
- unsigned long *table;
- unsigned long asce;
- unsigned long asce_end;
- void *private;
- bool pfault_enabled;
-};
-
-/**
- * struct gmap_notifier - notify function block for page invalidation
- * @notifier_call: address of callback function
- */
-struct gmap_notifier {
- struct list_head list;
- void (*notifier_call)(struct gmap *gmap, unsigned long gaddr);
-};
-
-struct gmap *gmap_alloc(struct mm_struct *mm, unsigned long limit);
-void gmap_free(struct gmap *gmap);
-void gmap_enable(struct gmap *gmap);
-void gmap_disable(struct gmap *gmap);
-int gmap_map_segment(struct gmap *gmap, unsigned long from,
- unsigned long to, unsigned long len);
-int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
-unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
-unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
-int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
-int gmap_fault(struct gmap *, unsigned long gaddr, unsigned int fault_flags);
-void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
-void __gmap_zap(struct gmap *, unsigned long gaddr);
-bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *);
-
-
-void gmap_register_ipte_notifier(struct gmap_notifier *);
-void gmap_unregister_ipte_notifier(struct gmap_notifier *);
-int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len);
-void gmap_do_ipte_notify(struct mm_struct *, unsigned long addr, pte_t *);
-
-static inline pgste_t pgste_ipte_notify(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, pgste_t pgste)
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
{
-#ifdef CONFIG_PGSTE
- if (pgste_val(pgste) & PGSTE_IN_BIT) {
- pgste_val(pgste) &= ~PGSTE_IN_BIT;
- gmap_do_ipte_notify(mm, addr, ptep);
- }
-#endif
- return pgste;
+ pmd_val(pmd) |= _SEGMENT_ENTRY_SOFT_DIRTY;
+ return pmd;
}
-/*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified. Thus, the following
- * hook is made available.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t entry)
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
{
- pgste_t pgste;
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_get_lock(ptep);
- pgste_val(pgste) &= ~_PGSTE_GPS_ZERO;
- pgste_set_key(ptep, pgste, entry, mm);
- pgste = pgste_set_pte(ptep, pgste, entry);
- pgste_set_unlock(ptep, pgste);
- } else {
- *ptep = entry;
- }
+ pmd_val(pmd) &= ~_SEGMENT_ENTRY_SOFT_DIRTY;
+ return pmd;
}
/*
@@ -889,7 +720,7 @@ static inline pte_t pte_mkclean(pte_t pte)
static inline pte_t pte_mkdirty(pte_t pte)
{
- pte_val(pte) |= _PAGE_DIRTY;
+ pte_val(pte) |= _PAGE_DIRTY | _PAGE_SOFT_DIRTY;
if (pte_val(pte) & _PAGE_WRITE)
pte_val(pte) &= ~_PAGE_PROTECT;
return pte;
@@ -956,96 +787,30 @@ static inline void __ptep_ipte_range(unsigned long address, int nr, pte_t *ptep)
} while (nr != 255);
}
-static inline void ptep_flush_direct(struct mm_struct *mm,
- unsigned long address, pte_t *ptep)
-{
- int active, count;
-
- if (pte_val(*ptep) & _PAGE_INVALID)
- return;
- active = (mm == current->active_mm) ? 1 : 0;
- count = atomic_add_return(0x10000, &mm->context.attach_count);
- if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active &&
- cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
- __ptep_ipte_local(address, ptep);
- else
- __ptep_ipte(address, ptep);
- atomic_sub(0x10000, &mm->context.attach_count);
-}
-
-static inline void ptep_flush_lazy(struct mm_struct *mm,
- unsigned long address, pte_t *ptep)
-{
- int active, count;
-
- if (pte_val(*ptep) & _PAGE_INVALID)
- return;
- active = (mm == current->active_mm) ? 1 : 0;
- count = atomic_add_return(0x10000, &mm->context.attach_count);
- if ((count & 0xffff) <= active) {
- pte_val(*ptep) |= _PAGE_INVALID;
- mm->context.flush_mm = 1;
- } else
- __ptep_ipte(address, ptep);
- atomic_sub(0x10000, &mm->context.attach_count);
-}
-
/*
- * Get (and clear) the user dirty bit for a pte.
+ * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
+ * both clear the TLB for the unmapped pte. The reason is that
+ * ptep_get_and_clear is used in common code (e.g. change_pte_range)
+ * to modify an active pte. The sequence is
+ * 1) ptep_get_and_clear
+ * 2) set_pte_at
+ * 3) flush_tlb_range
+ * On s390 the tlb needs to get flushed with the modification of the pte
+ * if the pte is active. The only way how this can be implemented is to
+ * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
+ * is a nop.
*/
-static inline int ptep_test_and_clear_user_dirty(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep)
-{
- pgste_t pgste;
- pte_t pte;
- int dirty;
-
- if (!mm_has_pgste(mm))
- return 0;
- pgste = pgste_get_lock(ptep);
- dirty = !!(pgste_val(pgste) & PGSTE_UC_BIT);
- pgste_val(pgste) &= ~PGSTE_UC_BIT;
- pte = *ptep;
- if (dirty && (pte_val(pte) & _PAGE_PRESENT)) {
- pgste = pgste_ipte_notify(mm, addr, ptep, pgste);
- __ptep_ipte(addr, ptep);
- if (MACHINE_HAS_ESOP || !(pte_val(pte) & _PAGE_WRITE))
- pte_val(pte) |= _PAGE_PROTECT;
- else
- pte_val(pte) |= _PAGE_INVALID;
- *ptep = pte;
- }
- pgste_set_unlock(ptep, pgste);
- return dirty;
-}
+pte_t ptep_xchg_direct(struct mm_struct *, unsigned long, pte_t *, pte_t);
+pte_t ptep_xchg_lazy(struct mm_struct *, unsigned long, pte_t *, pte_t);
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
- pgste_t pgste;
- pte_t pte, oldpte;
- int young;
-
- if (mm_has_pgste(vma->vm_mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(vma->vm_mm, addr, ptep, pgste);
- }
-
- oldpte = pte = *ptep;
- ptep_flush_direct(vma->vm_mm, addr, ptep);
- young = pte_young(pte);
- pte = pte_mkold(pte);
-
- if (mm_has_pgste(vma->vm_mm)) {
- pgste = pgste_update_all(&oldpte, pgste, vma->vm_mm);
- pgste = pgste_set_pte(ptep, pgste, pte);
- pgste_set_unlock(ptep, pgste);
- } else
- *ptep = pte;
+ pte_t pte = *ptep;
- return young;
+ pte = ptep_xchg_direct(vma->vm_mm, addr, ptep, pte_mkold(pte));
+ return pte_young(pte);
}
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
@@ -1055,104 +820,22 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
return ptep_test_and_clear_young(vma, address, ptep);
}
-/*
- * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
- * both clear the TLB for the unmapped pte. The reason is that
- * ptep_get_and_clear is used in common code (e.g. change_pte_range)
- * to modify an active pte. The sequence is
- * 1) ptep_get_and_clear
- * 2) set_pte_at
- * 3) flush_tlb_range
- * On s390 the tlb needs to get flushed with the modification of the pte
- * if the pte is active. The only way how this can be implemented is to
- * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
- * is a nop.
- */
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
- unsigned long address, pte_t *ptep)
+ unsigned long addr, pte_t *ptep)
{
- pgste_t pgste;
- pte_t pte;
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(mm, address, ptep, pgste);
- }
-
- pte = *ptep;
- ptep_flush_lazy(mm, address, ptep);
- pte_val(*ptep) = _PAGE_INVALID;
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_update_all(&pte, pgste, mm);
- pgste_set_unlock(ptep, pgste);
- }
- return pte;
+ return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID));
}
#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
-static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
- unsigned long address,
- pte_t *ptep)
-{
- pgste_t pgste;
- pte_t pte;
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_get_lock(ptep);
- pgste_ipte_notify(mm, address, ptep, pgste);
- }
-
- pte = *ptep;
- ptep_flush_lazy(mm, address, ptep);
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_update_all(&pte, pgste, mm);
- pgste_set(ptep, pgste);
- }
- return pte;
-}
-
-static inline void ptep_modify_prot_commit(struct mm_struct *mm,
- unsigned long address,
- pte_t *ptep, pte_t pte)
-{
- pgste_t pgste;
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_get(ptep);
- pgste_set_key(ptep, pgste, pte, mm);
- pgste = pgste_set_pte(ptep, pgste, pte);
- pgste_set_unlock(ptep, pgste);
- } else
- *ptep = pte;
-}
+pte_t ptep_modify_prot_start(struct mm_struct *, unsigned long, pte_t *);
+void ptep_modify_prot_commit(struct mm_struct *, unsigned long, pte_t *, pte_t);
#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep)
+ unsigned long addr, pte_t *ptep)
{
- pgste_t pgste;
- pte_t pte;
-
- if (mm_has_pgste(vma->vm_mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste);
- }
-
- pte = *ptep;
- ptep_flush_direct(vma->vm_mm, address, ptep);
- pte_val(*ptep) = _PAGE_INVALID;
-
- if (mm_has_pgste(vma->vm_mm)) {
- if ((pgste_val(pgste) & _PGSTE_GPS_USAGE_MASK) ==
- _PGSTE_GPS_USAGE_UNUSED)
- pte_val(pte) |= _PAGE_UNUSED;
- pgste = pgste_update_all(&pte, pgste, vma->vm_mm);
- pgste_set_unlock(ptep, pgste);
- }
- return pte;
+ return ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID));
}
/*
@@ -1164,77 +847,66 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
*/
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
- unsigned long address,
+ unsigned long addr,
pte_t *ptep, int full)
{
- pgste_t pgste;
- pte_t pte;
-
- if (!full && mm_has_pgste(mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(mm, address, ptep, pgste);
+ if (full) {
+ pte_t pte = *ptep;
+ *ptep = __pte(_PAGE_INVALID);
+ return pte;
}
-
- pte = *ptep;
- if (!full)
- ptep_flush_lazy(mm, address, ptep);
- pte_val(*ptep) = _PAGE_INVALID;
-
- if (!full && mm_has_pgste(mm)) {
- pgste = pgste_update_all(&pte, pgste, mm);
- pgste_set_unlock(ptep, pgste);
- }
- return pte;
+ return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID));
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline pte_t ptep_set_wrprotect(struct mm_struct *mm,
- unsigned long address, pte_t *ptep)
+static inline void ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
- pgste_t pgste;
pte_t pte = *ptep;
- if (pte_write(pte)) {
- if (mm_has_pgste(mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(mm, address, ptep, pgste);
- }
-
- ptep_flush_lazy(mm, address, ptep);
- pte = pte_wrprotect(pte);
-
- if (mm_has_pgste(mm)) {
- pgste = pgste_set_pte(ptep, pgste, pte);
- pgste_set_unlock(ptep, pgste);
- } else
- *ptep = pte;
- }
- return pte;
+ if (pte_write(pte))
+ ptep_xchg_lazy(mm, addr, ptep, pte_wrprotect(pte));
}
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
static inline int ptep_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep,
+ unsigned long addr, pte_t *ptep,
pte_t entry, int dirty)
{
- pgste_t pgste;
-
if (pte_same(*ptep, entry))
return 0;
- if (mm_has_pgste(vma->vm_mm)) {
- pgste = pgste_get_lock(ptep);
- pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste);
- }
+ ptep_xchg_direct(vma->vm_mm, addr, ptep, entry);
+ return 1;
+}
- ptep_flush_direct(vma->vm_mm, address, ptep);
+/*
+ * Additional functions to handle KVM guest page tables
+ */
+void ptep_set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry);
+void ptep_set_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+void ptep_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+void ptep_zap_unused(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep , int reset);
+void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+
+bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long address);
+int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
+ unsigned char key, bool nq);
+unsigned char get_guest_storage_key(struct mm_struct *mm, unsigned long addr);
- if (mm_has_pgste(vma->vm_mm)) {
- pgste_set_key(ptep, pgste, entry, vma->vm_mm);
- pgste = pgste_set_pte(ptep, pgste, entry);
- pgste_set_unlock(ptep, pgste);
- } else
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
+{
+ if (mm_has_pgste(mm))
+ ptep_set_pte_at(mm, addr, ptep, entry);
+ else
*ptep = entry;
- return 1;
}
/*
@@ -1340,7 +1012,8 @@ static inline pmd_t pmd_mkclean(pmd_t pmd)
static inline pmd_t pmd_mkdirty(pmd_t pmd)
{
if (pmd_large(pmd)) {
- pmd_val(pmd) |= _SEGMENT_ENTRY_DIRTY;
+ pmd_val(pmd) |= _SEGMENT_ENTRY_DIRTY |
+ _SEGMENT_ENTRY_SOFT_DIRTY;
if (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE)
pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT;
}
@@ -1371,7 +1044,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
if (pmd_large(pmd)) {
pmd_val(pmd) &= _SEGMENT_ENTRY_ORIGIN_LARGE |
_SEGMENT_ENTRY_DIRTY | _SEGMENT_ENTRY_YOUNG |
- _SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_SPLIT;
+ _SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_SOFT_DIRTY;
pmd_val(pmd) |= massage_pgprot_pmd(newprot);
if (!(pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY))
pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT;
@@ -1430,59 +1103,50 @@ static inline void __pmdp_idte_local(unsigned long address, pmd_t *pmdp)
: "cc" );
}
-static inline void pmdp_flush_direct(struct mm_struct *mm,
- unsigned long address, pmd_t *pmdp)
-{
- int active, count;
+pmd_t pmdp_xchg_direct(struct mm_struct *, unsigned long, pmd_t *, pmd_t);
+pmd_t pmdp_xchg_lazy(struct mm_struct *, unsigned long, pmd_t *, pmd_t);
- if (pmd_val(*pmdp) & _SEGMENT_ENTRY_INVALID)
- return;
- if (!MACHINE_HAS_IDTE) {
- __pmdp_csp(pmdp);
- return;
- }
- active = (mm == current->active_mm) ? 1 : 0;
- count = atomic_add_return(0x10000, &mm->context.attach_count);
- if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active &&
- cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
- __pmdp_idte_local(address, pmdp);
- else
- __pmdp_idte(address, pmdp);
- atomic_sub(0x10000, &mm->context.attach_count);
-}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static inline void pmdp_flush_lazy(struct mm_struct *mm,
- unsigned long address, pmd_t *pmdp)
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pmd_t *pmdp,
+ pmd_t entry, int dirty)
{
- int active, count;
+ VM_BUG_ON(addr & ~HPAGE_MASK);
- if (pmd_val(*pmdp) & _SEGMENT_ENTRY_INVALID)
- return;
- active = (mm == current->active_mm) ? 1 : 0;
- count = atomic_add_return(0x10000, &mm->context.attach_count);
- if ((count & 0xffff) <= active) {
- pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID;
- mm->context.flush_mm = 1;
- } else if (MACHINE_HAS_IDTE)
- __pmdp_idte(address, pmdp);
- else
- __pmdp_csp(pmdp);
- atomic_sub(0x10000, &mm->context.attach_count);
+ entry = pmd_mkyoung(entry);
+ if (dirty)
+ entry = pmd_mkdirty(entry);
+ if (pmd_val(*pmdp) == pmd_val(entry))
+ return 0;
+ pmdp_xchg_direct(vma->vm_mm, addr, pmdp, entry);
+ return 1;
}
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-
-#define __HAVE_ARCH_PGTABLE_DEPOSIT
-extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
- pgtable_t pgtable);
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pmd_t *pmdp)
+{
+ pmd_t pmd = *pmdp;
-#define __HAVE_ARCH_PGTABLE_WITHDRAW
-extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+ pmd = pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd_mkold(pmd));
+ return pmd_young(pmd);
+}
-static inline int pmd_trans_splitting(pmd_t pmd)
+#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
+static inline int pmdp_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long addr, pmd_t *pmdp)
{
- return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) &&
- (pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT);
+ VM_BUG_ON(addr & ~HPAGE_MASK);
+ return pmdp_test_and_clear_young(vma, addr, pmdp);
}
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
@@ -1499,66 +1163,48 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
return pmd;
}
-#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
-static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp)
-{
- pmd_t pmd;
-
- pmd = *pmdp;
- pmdp_flush_direct(vma->vm_mm, address, pmdp);
- *pmdp = pmd_mkold(pmd);
- return pmd_young(pmd);
-}
-
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
- unsigned long address, pmd_t *pmdp)
+ unsigned long addr, pmd_t *pmdp)
{
- pmd_t pmd = *pmdp;
-
- pmdp_flush_direct(mm, address, pmdp);
- pmd_clear(pmdp);
- return pmd;
+ return pmdp_xchg_direct(mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_INVALID));
}
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR_FULL
static inline pmd_t pmdp_huge_get_and_clear_full(struct mm_struct *mm,
- unsigned long address,
+ unsigned long addr,
pmd_t *pmdp, int full)
{
- pmd_t pmd = *pmdp;
-
- if (!full)
- pmdp_flush_lazy(mm, address, pmdp);
- pmd_clear(pmdp);
- return pmd;
+ if (full) {
+ pmd_t pmd = *pmdp;
+ *pmdp = __pmd(_SEGMENT_ENTRY_INVALID);
+ return pmd;
+ }
+ return pmdp_xchg_lazy(mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_INVALID));
}
#define __HAVE_ARCH_PMDP_HUGE_CLEAR_FLUSH
static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp)
+ unsigned long addr, pmd_t *pmdp)
{
- return pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
+ return pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp);
}
#define __HAVE_ARCH_PMDP_INVALIDATE
static inline void pmdp_invalidate(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp)
+ unsigned long addr, pmd_t *pmdp)
{
- pmdp_flush_direct(vma->vm_mm, address, pmdp);
+ pmdp_xchg_direct(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_INVALID));
}
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
static inline void pmdp_set_wrprotect(struct mm_struct *mm,
- unsigned long address, pmd_t *pmdp)
+ unsigned long addr, pmd_t *pmdp)
{
pmd_t pmd = *pmdp;
- if (pmd_write(pmd)) {
- pmdp_flush_direct(mm, address, pmdp);
- set_pmd_at(mm, address, pmdp, pmd_wrprotect(pmd));
- }
+ if (pmd_write(pmd))
+ pmd = pmdp_xchg_lazy(mm, addr, pmdp, pmd_wrprotect(pmd));
}
static inline pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 085fb0d..d6fd22e 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -11,15 +11,21 @@
#ifndef __ASM_S390_PROCESSOR_H
#define __ASM_S390_PROCESSOR_H
+#include <linux/const.h>
+
#define CIF_MCCK_PENDING 0 /* machine check handling is pending */
#define CIF_ASCE 1 /* user asce needs fixup / uaccess */
#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
-#define CIF_FPU 3 /* restore vector registers */
+#define CIF_FPU 3 /* restore FPU registers */
+#define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */
+#define CIF_ENABLED_WAIT 5 /* in enabled wait state */
-#define _CIF_MCCK_PENDING (1<<CIF_MCCK_PENDING)
-#define _CIF_ASCE (1<<CIF_ASCE)
-#define _CIF_NOHZ_DELAY (1<<CIF_NOHZ_DELAY)
-#define _CIF_FPU (1<<CIF_FPU)
+#define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING)
+#define _CIF_ASCE _BITUL(CIF_ASCE)
+#define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY)
+#define _CIF_FPU _BITUL(CIF_FPU)
+#define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ)
+#define _CIF_ENABLED_WAIT _BITUL(CIF_ENABLED_WAIT)
#ifndef __ASSEMBLY__
@@ -30,21 +36,32 @@
#include <asm/ptrace.h>
#include <asm/setup.h>
#include <asm/runtime_instr.h>
-#include <asm/fpu-internal.h>
+#include <asm/fpu/types.h>
+#include <asm/fpu/internal.h>
static inline void set_cpu_flag(int flag)
{
- S390_lowcore.cpu_flags |= (1U << flag);
+ S390_lowcore.cpu_flags |= (1UL << flag);
}
static inline void clear_cpu_flag(int flag)
{
- S390_lowcore.cpu_flags &= ~(1U << flag);
+ S390_lowcore.cpu_flags &= ~(1UL << flag);
}
static inline int test_cpu_flag(int flag)
{
- return !!(S390_lowcore.cpu_flags & (1U << flag));
+ return !!(S390_lowcore.cpu_flags & (1UL << flag));
+}
+
+/*
+ * Test CIF flag of another CPU. The caller needs to ensure that
+ * CPU hotplug can not happen, e.g. by disabling preemption.
+ */
+static inline int test_cpu_flag_of(int flag, int cpu)
+{
+ struct lowcore *lc = lowcore_ptr[cpu];
+ return !!(lc->cpu_flags & (1UL << flag));
}
#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
@@ -102,7 +119,6 @@ struct thread_struct {
struct list_head list;
/* cpu runtime instrumentation */
struct runtime_instr_cb *ri_cb;
- int ri_signum;
unsigned char trap_tdb[256]; /* Transaction abort diagnose block */
};
@@ -139,8 +155,10 @@ struct stack_frame {
#define ARCH_MIN_TASKALIGN 8
+extern __vector128 init_task_fpu_regs[__NUM_VXRS];
#define INIT_THREAD { \
.ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
+ .fpu.regs = (void *)&init_task_fpu_regs, \
}
/*
@@ -148,14 +166,14 @@ struct stack_frame {
*/
#define start_thread(regs, new_psw, new_stackp) do { \
regs->psw.mask = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA; \
- regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
+ regs->psw.addr = new_psw; \
regs->gprs[15] = new_stackp; \
execve_tail(); \
} while (0)
#define start_thread31(regs, new_psw, new_stackp) do { \
regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \
- regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
+ regs->psw.addr = new_psw; \
regs->gprs[15] = new_stackp; \
crst_table_downgrade(current->mm, 1UL << 31); \
execve_tail(); \
@@ -166,6 +184,10 @@ struct task_struct;
struct mm_struct;
struct seq_file;
+typedef int (*dump_trace_func_t)(void *data, unsigned long address);
+void dump_trace(dump_trace_func_t func, void *data,
+ struct task_struct *task, unsigned long sp);
+
void show_cacheinfo(struct seq_file *m);
/* Free all resources held by a thread. */
@@ -185,6 +207,14 @@ unsigned long get_wchan(struct task_struct *p);
/* Has task runtime instrumentation enabled ? */
#define is_ri_task(tsk) (!!(tsk)->thread.ri_cb)
+static inline unsigned long current_stack_pointer(void)
+{
+ unsigned long sp;
+
+ asm volatile("la %0,0(15)" : "=a" (sp));
+ return sp;
+}
+
static inline unsigned short stap(void)
{
unsigned short cpu_address;
@@ -217,7 +247,7 @@ static inline void __load_psw(psw_t psw)
* Set PSW mask to specified value, while leaving the
* PSW addr pointing to the next instruction.
*/
-static inline void __load_psw_mask (unsigned long mask)
+static inline void __load_psw_mask(unsigned long mask)
{
unsigned long addr;
psw_t psw;
@@ -243,6 +273,16 @@ static inline unsigned long __extract_psw(void)
return (((unsigned long) reg1) << 32) | ((unsigned long) reg2);
}
+static inline void local_mcck_enable(void)
+{
+ __load_psw_mask(__extract_psw() | PSW_MASK_MCHECK);
+}
+
+static inline void local_mcck_disable(void)
+{
+ __load_psw_mask(__extract_psw() & ~PSW_MASK_MCHECK);
+}
+
/*
* Rewind PSW instruction address by specified number of bytes.
*/
@@ -266,65 +306,14 @@ void enabled_wait(void);
*/
static inline void __noreturn disabled_wait(unsigned long code)
{
- unsigned long ctl_buf;
- psw_t dw_psw;
-
- dw_psw.mask = PSW_MASK_BASE | PSW_MASK_WAIT | PSW_MASK_BA | PSW_MASK_EA;
- dw_psw.addr = code;
- /*
- * Store status and then load disabled wait psw,
- * the processor is dead afterwards
- */
- asm volatile(
- " stctg 0,0,0(%2)\n"
- " ni 4(%2),0xef\n" /* switch off protection */
- " lctlg 0,0,0(%2)\n"
- " lghi 1,0x1000\n"
- " stpt 0x328(1)\n" /* store timer */
- " stckc 0x330(1)\n" /* store clock comparator */
- " stpx 0x318(1)\n" /* store prefix register */
- " stam 0,15,0x340(1)\n"/* store access registers */
- " stfpc 0x31c(1)\n" /* store fpu control */
- " std 0,0x200(1)\n" /* store f0 */
- " std 1,0x208(1)\n" /* store f1 */
- " std 2,0x210(1)\n" /* store f2 */
- " std 3,0x218(1)\n" /* store f3 */
- " std 4,0x220(1)\n" /* store f4 */
- " std 5,0x228(1)\n" /* store f5 */
- " std 6,0x230(1)\n" /* store f6 */
- " std 7,0x238(1)\n" /* store f7 */
- " std 8,0x240(1)\n" /* store f8 */
- " std 9,0x248(1)\n" /* store f9 */
- " std 10,0x250(1)\n" /* store f10 */
- " std 11,0x258(1)\n" /* store f11 */
- " std 12,0x260(1)\n" /* store f12 */
- " std 13,0x268(1)\n" /* store f13 */
- " std 14,0x270(1)\n" /* store f14 */
- " std 15,0x278(1)\n" /* store f15 */
- " stmg 0,15,0x280(1)\n"/* store general registers */
- " stctg 0,15,0x380(1)\n"/* store control registers */
- " oi 0x384(1),0x10\n"/* fake protection bit */
- " lpswe 0(%1)"
- : "=m" (ctl_buf)
- : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0", "1");
- while (1);
-}
+ psw_t psw;
-/*
- * Use to set psw mask except for the first byte which
- * won't be changed by this function.
- */
-static inline void
-__set_psw_mask(unsigned long mask)
-{
- __load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
+ psw.mask = PSW_MASK_BASE | PSW_MASK_WAIT | PSW_MASK_BA | PSW_MASK_EA;
+ psw.addr = code;
+ __load_psw(psw);
+ while (1);
}
-#define local_mcck_enable() \
- __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK)
-#define local_mcck_disable() \
- __set_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT)
-
/*
* Basic Machine Check/Program Check Handler.
*/
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 6feda25..99bc456 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -6,13 +6,14 @@
#ifndef _S390_PTRACE_H
#define _S390_PTRACE_H
+#include <linux/const.h>
#include <uapi/asm/ptrace.h>
#define PIF_SYSCALL 0 /* inside a system call */
#define PIF_PER_TRAP 1 /* deliver sigtrap on return to user */
-#define _PIF_SYSCALL (1<<PIF_SYSCALL)
-#define _PIF_PER_TRAP (1<<PIF_PER_TRAP)
+#define _PIF_SYSCALL _BITUL(PIF_SYSCALL)
+#define _PIF_PER_TRAP _BITUL(PIF_PER_TRAP)
#ifndef __ASSEMBLY__
@@ -23,25 +24,25 @@
PSW_MASK_PSTATE | PSW_ASC_PRIMARY)
struct psw_bits {
- unsigned long long : 1;
- unsigned long long r : 1; /* PER-Mask */
- unsigned long long : 3;
- unsigned long long t : 1; /* DAT Mode */
- unsigned long long i : 1; /* Input/Output Mask */
- unsigned long long e : 1; /* External Mask */
- unsigned long long key : 4; /* PSW Key */
- unsigned long long : 1;
- unsigned long long m : 1; /* Machine-Check Mask */
- unsigned long long w : 1; /* Wait State */
- unsigned long long p : 1; /* Problem State */
- unsigned long long as : 2; /* Address Space Control */
- unsigned long long cc : 2; /* Condition Code */
- unsigned long long pm : 4; /* Program Mask */
- unsigned long long ri : 1; /* Runtime Instrumentation */
- unsigned long long : 6;
- unsigned long long eaba : 2; /* Addressing Mode */
- unsigned long long : 31;
- unsigned long long ia : 64;/* Instruction Address */
+ unsigned long : 1;
+ unsigned long r : 1; /* PER-Mask */
+ unsigned long : 3;
+ unsigned long t : 1; /* DAT Mode */
+ unsigned long i : 1; /* Input/Output Mask */
+ unsigned long e : 1; /* External Mask */
+ unsigned long key : 4; /* PSW Key */
+ unsigned long : 1;
+ unsigned long m : 1; /* Machine-Check Mask */
+ unsigned long w : 1; /* Wait State */
+ unsigned long p : 1; /* Problem State */
+ unsigned long as : 2; /* Address Space Control */
+ unsigned long cc : 2; /* Condition Code */
+ unsigned long pm : 4; /* Program Mask */
+ unsigned long ri : 1; /* Runtime Instrumentation */
+ unsigned long : 6;
+ unsigned long eaba : 2; /* Addressing Mode */
+ unsigned long : 31;
+ unsigned long ia : 64; /* Instruction Address */
};
enum {
@@ -128,17 +129,17 @@ struct per_struct_kernel {
static inline void set_pt_regs_flag(struct pt_regs *regs, int flag)
{
- regs->flags |= (1U << flag);
+ regs->flags |= (1UL << flag);
}
static inline void clear_pt_regs_flag(struct pt_regs *regs, int flag)
{
- regs->flags &= ~(1U << flag);
+ regs->flags &= ~(1UL << flag);
}
static inline int test_pt_regs_flag(struct pt_regs *regs, int flag)
{
- return !!(regs->flags & (1U << flag));
+ return !!(regs->flags & (1UL << flag));
}
/*
@@ -148,7 +149,7 @@ static inline int test_pt_regs_flag(struct pt_regs *regs, int flag)
#define arch_has_block_step() (1)
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
-#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
+#define instruction_pointer(regs) ((regs)->psw.addr)
#define user_stack_pointer(regs)((regs)->gprs[15])
#define profile_pc(regs) instruction_pointer(regs)
@@ -160,7 +161,7 @@ static inline long regs_return_value(struct pt_regs *regs)
static inline void instruction_pointer_set(struct pt_regs *regs,
unsigned long val)
{
- regs->psw.addr = val | PSW_ADDR_AMODE;
+ regs->psw.addr = val;
}
int regs_query_register_offset(const char *name);
@@ -170,7 +171,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
- return regs->gprs[15] & PSW_ADDR_INSN;
+ return regs->gprs[15];
}
#endif /* __ASSEMBLY__ */
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h
index 7278606..fe11fa8 100644
--- a/arch/s390/include/asm/reset.h
+++ b/arch/s390/include/asm/reset.h
@@ -15,6 +15,5 @@ struct reset_call {
extern void register_reset_call(struct reset_call *reset);
extern void unregister_reset_call(struct reset_call *reset);
-extern void s390_reset_system(void (*fn_pre)(void),
- void (*fn_post)(void *), void *data);
+extern void s390_reset_system(void);
#endif /* _ASM_S390_RESET_H */
diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h
index 4b43ee7..fead491 100644
--- a/arch/s390/include/asm/rwsem.h
+++ b/arch/s390/include/asm/rwsem.h
@@ -31,7 +31,7 @@
* This should be totally fair - if anything is waiting, a process that wants a
* lock will go to the back of the queue. When the currently active lock is
* released, if there's a writer at the front of the queue, then that and only
- * that will be woken up; if there's a bunch of consequtive readers at the
+ * that will be woken up; if there's a bunch of consecutive readers at the
* front, then they'll all be woken up, but no other readers will be.
*/
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index 821dde5..bab456b 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -29,7 +29,10 @@ struct sclp_ipl_info {
struct sclp_core_entry {
u8 core_id;
- u8 reserved0[2];
+ u8 reserved0;
+ u8 : 4;
+ u8 sief2 : 1;
+ u8 : 3;
u8 : 3;
u8 siif : 1;
u8 sigpif : 1;
@@ -53,16 +56,19 @@ struct sclp_info {
unsigned char has_sigpif : 1;
unsigned char has_core_type : 1;
unsigned char has_sprp : 1;
+ unsigned char has_hvs : 1;
+ unsigned char has_esca : 1;
+ unsigned char has_sief2 : 1;
unsigned int ibc;
unsigned int mtid;
unsigned int mtid_cp;
unsigned int mtid_prev;
- unsigned long long rzm;
- unsigned long long rnmax;
- unsigned long long hamax;
+ unsigned long rzm;
+ unsigned long rnmax;
+ unsigned long hamax;
unsigned int max_cores;
unsigned long hsa_size;
- unsigned long long facilities;
+ unsigned long facilities;
};
extern struct sclp_info sclp;
@@ -77,8 +83,9 @@ int sclp_chp_read_info(struct sclp_chp_info *info);
void sclp_get_ipl_info(struct sclp_ipl_info *info);
int sclp_pci_configure(u32 fid);
int sclp_pci_deconfigure(u32 fid);
-int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
+int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count);
+int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count);
void sclp_early_detect(void);
-int _sclp_print_early(const char *);
+void _sclp_print_early(const char *);
#endif /* _ASM_S390_SCLP_H */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index b8ffc1b..c0f0efb 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -5,11 +5,35 @@
#ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H
+#include <linux/const.h>
#include <uapi/asm/setup.h>
#define PARMAREA 0x10400
+/*
+ * Machine features detected in early.c
+ */
+
+#define MACHINE_FLAG_VM _BITUL(0)
+#define MACHINE_FLAG_KVM _BITUL(1)
+#define MACHINE_FLAG_LPAR _BITUL(2)
+#define MACHINE_FLAG_DIAG9C _BITUL(3)
+#define MACHINE_FLAG_ESOP _BITUL(4)
+#define MACHINE_FLAG_IDTE _BITUL(5)
+#define MACHINE_FLAG_DIAG44 _BITUL(6)
+#define MACHINE_FLAG_EDAT1 _BITUL(7)
+#define MACHINE_FLAG_EDAT2 _BITUL(8)
+#define MACHINE_FLAG_LPP _BITUL(9)
+#define MACHINE_FLAG_TOPOLOGY _BITUL(10)
+#define MACHINE_FLAG_TE _BITUL(11)
+#define MACHINE_FLAG_TLB_LC _BITUL(12)
+#define MACHINE_FLAG_VX _BITUL(13)
+#define MACHINE_FLAG_CAD _BITUL(14)
+
+#define LPP_MAGIC _BITUL(31)
+#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
+
#ifndef __ASSEMBLY__
#include <asm/lowcore.h>
@@ -28,29 +52,6 @@ extern unsigned long max_physmem_end;
extern void detect_memory_memblock(void);
-/*
- * Machine features detected in head.S
- */
-
-#define MACHINE_FLAG_VM (1UL << 0)
-#define MACHINE_FLAG_IEEE (1UL << 1)
-#define MACHINE_FLAG_CSP (1UL << 2)
-#define MACHINE_FLAG_MVPG (1UL << 3)
-#define MACHINE_FLAG_DIAG44 (1UL << 4)
-#define MACHINE_FLAG_IDTE (1UL << 5)
-#define MACHINE_FLAG_DIAG9C (1UL << 6)
-#define MACHINE_FLAG_KVM (1UL << 8)
-#define MACHINE_FLAG_ESOP (1UL << 9)
-#define MACHINE_FLAG_EDAT1 (1UL << 10)
-#define MACHINE_FLAG_EDAT2 (1UL << 11)
-#define MACHINE_FLAG_LPAR (1UL << 12)
-#define MACHINE_FLAG_LPP (1UL << 13)
-#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
-#define MACHINE_FLAG_TE (1UL << 15)
-#define MACHINE_FLAG_TLB_LC (1UL << 17)
-#define MACHINE_FLAG_VX (1UL << 18)
-#define MACHINE_FLAG_CAD (1UL << 19)
-
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
@@ -100,6 +101,8 @@ extern void pfault_fini(void);
#define pfault_fini() do { } while (0)
#endif /* CONFIG_PFAULT */
+void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault);
+
extern void cmma_init(void);
extern void (*_machine_restart)(char *command);
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 5df26b1..0cc383b 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -18,6 +18,7 @@
extern struct mutex smp_cpu_state_mutex;
extern unsigned int smp_cpu_mt_shift;
extern unsigned int smp_cpu_mtid;
+extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS];
extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
@@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_fill_possible_mask(void) { }
-static inline void smp_save_dump_cpus(void) { }
#endif /* CONFIG_SMP */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index 0e37cd0..63ebf37 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -87,7 +87,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp)
{
typecheck(unsigned int, lp->lock);
asm volatile(
- __ASM_BARRIER
"st %1,%0\n"
: "+Q" (lp->lock)
: "d" (0)
@@ -169,7 +168,6 @@ static inline int arch_write_trylock_once(arch_rwlock_t *rw)
\
typecheck(unsigned int *, ptr); \
asm volatile( \
- "bcr 14,0\n" \
op_string " %0,%2,%1\n" \
: "=d" (old_val), "+Q" (*ptr) \
: "d" (op_val) \
@@ -243,7 +241,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
rw->owner = 0;
asm volatile(
- __ASM_BARRIER
"st %1,%0\n"
: "+Q" (rw->lock)
: "d" (0)
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h
index dcadfde..12d45f0 100644
--- a/arch/s390/include/asm/switch_to.h
+++ b/arch/s390/include/asm/switch_to.h
@@ -8,7 +8,7 @@
#define __ASM_SWITCH_TO_H
#include <linux/thread_info.h>
-#include <asm/fpu-internal.h>
+#include <asm/fpu/api.h>
#include <asm/ptrace.h>
extern struct task_struct *__switch_to(void *, void *);
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index f7054a8..2728114 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -56,7 +56,12 @@ struct sysinfo_1_2_2 {
char format;
char reserved_0[1];
unsigned short acc_offset;
- char reserved_1[20];
+ unsigned char mt_installed :1;
+ unsigned char :2;
+ unsigned char mt_stid :5;
+ unsigned char :3;
+ unsigned char mt_gtid :5;
+ char reserved_1[18];
unsigned int nominal_cap;
unsigned int secondary_cap;
unsigned int capability;
@@ -92,9 +97,13 @@ struct sysinfo_2_2_2 {
char name[8];
unsigned int caf;
char reserved_2[8];
- unsigned char mt_installed;
- unsigned char mt_general;
- unsigned char mt_psmtid;
+ unsigned char mt_installed :1;
+ unsigned char :2;
+ unsigned char mt_stid :5;
+ unsigned char :3;
+ unsigned char mt_gtid :5;
+ unsigned char :3;
+ unsigned char mt_psmtid :5;
char reserved_3[5];
unsigned short cpus_dedicated;
unsigned short cpus_shared;
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 4c27ec7..2fffc2c 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -7,6 +7,8 @@
#ifndef _ASM_THREAD_INFO_H
#define _ASM_THREAD_INFO_H
+#include <linux/const.h>
+
/*
* Size of kernel stack for each process
*/
@@ -83,17 +85,15 @@ void arch_release_task_struct(struct task_struct *tsk);
#define TIF_BLOCK_STEP 20 /* This task is block stepped */
#define TIF_UPROBE_SINGLESTEP 21 /* This task is uprobe single stepped */
-#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
-#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
-#define _TIF_SECCOMP (1<<TIF_SECCOMP)
-#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_UPROBE (1<<TIF_UPROBE)
-#define _TIF_31BIT (1<<TIF_31BIT)
-#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
-
-#define is_32bit_task() (test_thread_flag(TIF_31BIT))
+#define _TIF_NOTIFY_RESUME _BITUL(TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING _BITUL(TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED _BITUL(TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_TRACE _BITUL(TIF_SYSCALL_TRACE)
+#define _TIF_SYSCALL_AUDIT _BITUL(TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP _BITUL(TIF_SECCOMP)
+#define _TIF_SYSCALL_TRACEPOINT _BITUL(TIF_SYSCALL_TRACEPOINT)
+#define _TIF_UPROBE _BITUL(TIF_UPROBE)
+#define _TIF_31BIT _BITUL(TIF_31BIT)
+#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP)
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 94fc55f..6b53962 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -7,7 +7,7 @@
struct sysinfo_15_1_x;
struct cpu;
-#ifdef CONFIG_SCHED_BOOK
+#ifdef CONFIG_SCHED_TOPOLOGY
struct cpu_topology_s390 {
unsigned short thread_id;
@@ -40,13 +40,13 @@ void store_topology(struct sysinfo_15_1_x *info);
void topology_expect_change(void);
const struct cpumask *cpu_coregroup_mask(int cpu);
-#else /* CONFIG_SCHED_BOOK */
+#else /* CONFIG_SCHED_TOPOLOGY */
static inline void topology_schedule_update(void) { }
static inline int topology_cpu_init(struct cpu *cpu) { return 0; }
static inline void topology_expect_change(void) { }
-#endif /* CONFIG_SCHED_BOOK */
+#endif /* CONFIG_SCHED_TOPOLOGY */
#define POLARIZATION_UNKNOWN (-1)
#define POLARIZATION_HRZ (0)
diff --git a/arch/s390/include/asm/trace/diag.h b/arch/s390/include/asm/trace/diag.h
new file mode 100644
index 0000000..cc6cfe7
--- /dev/null
+++ b/arch/s390/include/asm/trace/diag.h
@@ -0,0 +1,43 @@
+/*
+ * Tracepoint header for s390 diagnose calls
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM s390
+
+#if !defined(_TRACE_S390_DIAG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_S390_DIAG_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm/trace
+#define TRACE_INCLUDE_FILE diag
+
+TRACE_EVENT(s390_diagnose,
+ TP_PROTO(unsigned short nr),
+ TP_ARGS(nr),
+ TP_STRUCT__entry(
+ __field(unsigned short, nr)
+ ),
+ TP_fast_assign(
+ __entry->nr = nr;
+ ),
+ TP_printk("nr=0x%x", __entry->nr)
+);
+
+#ifdef CONFIG_TRACEPOINTS
+void trace_s390_diagnose_norecursion(int diag_nr);
+#else
+static inline void trace_s390_diagnose_norecursion(int diag_nr) { }
+#endif
+
+#endif /* _TRACE_S390_DIAG_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index 787acd4..d0a2dbf 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -38,12 +38,14 @@ struct vdso_data {
struct vdso_per_cpu_data {
__u64 ectg_timer_base;
__u64 ectg_user_time;
+ __u32 cpu_nr;
+ __u32 node_id;
};
extern struct vdso_data *vdso_data;
-int vdso_alloc_per_cpu(struct _lowcore *lowcore);
-void vdso_free_per_cpu(struct _lowcore *lowcore);
+int vdso_alloc_per_cpu(struct lowcore *lowcore);
+void vdso_free_per_cpu(struct lowcore *lowcore);
#endif /* __ASSEMBLY__ */
#endif /* __S390_VDSO_H__ */
diff --git a/arch/s390/include/asm/xor.h b/arch/s390/include/asm/xor.h
index c82eb12..c988df7 100644
--- a/arch/s390/include/asm/xor.h
+++ b/arch/s390/include/asm/xor.h
@@ -1 +1,20 @@
-#include <asm-generic/xor.h>
+/*
+ * Optimited xor routines
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+#ifndef _ASM_S390_XOR_H
+#define _ASM_S390_XOR_H
+
+extern struct xor_block_template xor_block_xc;
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES \
+do { \
+ xor_speed(&xor_block_xc); \
+} while (0)
+
+#define XOR_SELECT_TEMPLATE(FASTEST) (&xor_block_xc)
+
+#endif /* _ASM_S390_XOR_H */
diff --git a/arch/s390/include/uapi/asm/clp.h b/arch/s390/include/uapi/asm/clp.h
new file mode 100644
index 0000000..ab72d9d
--- /dev/null
+++ b/arch/s390/include/uapi/asm/clp.h
@@ -0,0 +1,28 @@
+/*
+ * ioctl interface for /dev/clp
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#ifndef _ASM_CLP_H
+#define _ASM_CLP_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+struct clp_req {
+ unsigned int c : 1;
+ unsigned int r : 1;
+ unsigned int lps : 6;
+ unsigned int cmd : 8;
+ unsigned int : 16;
+ unsigned int reserved;
+ __u64 data_p;
+};
+
+#define CLP_IOCTL_MAGIC 'c'
+
+#define CLP_SYNC _IOWR(CLP_IOCTL_MAGIC, 0xC1, struct clp_req)
+
+#endif
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index ef1a5fc..347fe5a 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -66,6 +66,8 @@ struct kvm_s390_io_adapter_req {
#define KVM_S390_VM_MEM_CLR_CMMA 1
#define KVM_S390_VM_MEM_LIMIT_SIZE 2
+#define KVM_S390_NO_MEM_LIMIT U64_MAX
+
/* kvm attributes for KVM_S390_VM_TOD */
#define KVM_S390_VM_TOD_LOW 0
#define KVM_S390_VM_TOD_HIGH 1
@@ -151,6 +153,8 @@ struct kvm_guest_debug_arch {
#define KVM_SYNC_ARCH0 (1UL << 4)
#define KVM_SYNC_PFAULT (1UL << 5)
#define KVM_SYNC_VRS (1UL << 6)
+#define KVM_SYNC_RICCB (1UL << 7)
+#define KVM_SYNC_FPRS (1UL << 8)
/* definition of registers in kvm_run */
struct kvm_sync_regs {
__u64 prefix; /* prefix register */
@@ -165,9 +169,14 @@ struct kvm_sync_regs {
__u64 pft; /* pfault token [PFAULT] */
__u64 pfs; /* pfault select [PFAULT] */
__u64 pfc; /* pfault compare [PFAULT] */
- __u64 vrs[32][2]; /* vector registers */
+ union {
+ __u64 vrs[32][2]; /* vector registers (KVM_SYNC_VRS) */
+ __u64 fprs[16]; /* fp registers (KVM_SYNC_FPRS) */
+ };
__u8 reserved[512]; /* for future vector expansion */
- __u32 fpc; /* only valid with vector registers */
+ __u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
+ __u8 padding[52]; /* riccb needs to be 64byte aligned */
+ __u8 riccb[64]; /* runtime instrumentation controls block */
};
#define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1)
diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h
index ee69c08..5dbaa72 100644
--- a/arch/s390/include/uapi/asm/sie.h
+++ b/arch/s390/include/uapi/asm/sie.h
@@ -7,6 +7,7 @@
{ 0x9c, "DIAG (0x9c) time slice end directed" }, \
{ 0x204, "DIAG (0x204) logical-cpu utilization" }, \
{ 0x258, "DIAG (0x258) page-reference services" }, \
+ { 0x288, "DIAG (0x288) watchdog functions" }, \
{ 0x308, "DIAG (0x308) ipl functions" }, \
{ 0x500, "DIAG (0x500) KVM virtio functions" }, \
{ 0x501, "DIAG (0x501) KVM breakpoint" }
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
index 296942d..41b51c2 100644
--- a/arch/s390/include/uapi/asm/socket.h
+++ b/arch/s390/include/uapi/asm/socket.h
@@ -91,4 +91,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
index a848adb..ab3aa68 100644
--- a/arch/s390/include/uapi/asm/unistd.h
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -192,14 +192,14 @@
#define __NR_set_tid_address 252
#define __NR_fadvise64 253
#define __NR_timer_create 254
-#define __NR_timer_settime (__NR_timer_create+1)
-#define __NR_timer_gettime (__NR_timer_create+2)
-#define __NR_timer_getoverrun (__NR_timer_create+3)
-#define __NR_timer_delete (__NR_timer_create+4)
-#define __NR_clock_settime (__NR_timer_create+5)
-#define __NR_clock_gettime (__NR_timer_create+6)
-#define __NR_clock_getres (__NR_timer_create+7)
-#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_timer_settime 255
+#define __NR_timer_gettime 256
+#define __NR_timer_getoverrun 257
+#define __NR_timer_delete 258
+#define __NR_clock_settime 259
+#define __NR_clock_gettime 260
+#define __NR_clock_getres 261
+#define __NR_clock_nanosleep 262
/* Number 263 is reserved for vserver */
#define __NR_statfs64 265
#define __NR_fstatfs64 266
@@ -309,7 +309,9 @@
#define __NR_recvfrom 371
#define __NR_recvmsg 372
#define __NR_shutdown 373
-#define NR_syscalls 374
+#define __NR_mlock2 374
+#define __NR_copy_file_range 375
+#define NR_syscalls 376
/*
* There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index b756c63..2f5586a 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -34,8 +34,10 @@ CFLAGS_sysinfo.o += -w
#
CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE)
ifneq ($(CC_FLAGS_MARCH),-march=z900)
-CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH)
-CFLAGS_sclp.o += -march=z900
+CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH)
+CFLAGS_sclp.o += -march=z900
+AFLAGS_REMOVE_head.o += $(CC_FLAGS_MARCH)
+AFLAGS_head.o += -march=z900
endif
GCOV_PROFILE_sclp.o := n
@@ -50,7 +52,7 @@ extra-y += head.o head64.o vmlinux.lds
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SCHED_BOOK) += topology.o
+obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o
obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o
obj-$(CONFIG_AUDIT) += audit.o
compat-obj-$(CONFIG_AUDIT) += compat_audit.o
@@ -66,6 +68,8 @@ obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o
+obj-$(CONFIG_TRACEPOINTS) += trace.o
+
# vdso
obj-y += vdso64/
obj-$(CONFIG_COMPAT) += vdso32/
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 3aeeb1b..1f95cc1 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -12,6 +12,7 @@
#include <asm/idle.h>
#include <asm/vdso.h>
#include <asm/pgtable.h>
+#include <asm/gmap.h>
/*
* Make sure that the compiler is new enough. We want a compiler that
@@ -23,59 +24,66 @@
int main(void)
{
- DEFINE(__TASK_thread_info, offsetof(struct task_struct, stack));
- DEFINE(__TASK_thread, offsetof(struct task_struct, thread));
- DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
+ /* task struct offsets */
+ OFFSET(__TASK_thread_info, task_struct, stack);
+ OFFSET(__TASK_thread, task_struct, thread);
+ OFFSET(__TASK_pid, task_struct, pid);
BLANK();
- DEFINE(__THREAD_ksp, offsetof(struct thread_struct, ksp));
- DEFINE(__THREAD_FPU_fpc, offsetof(struct thread_struct, fpu.fpc));
- DEFINE(__THREAD_FPU_flags, offsetof(struct thread_struct, fpu.flags));
- DEFINE(__THREAD_FPU_regs, offsetof(struct thread_struct, fpu.regs));
- DEFINE(__THREAD_per_cause, offsetof(struct thread_struct, per_event.cause));
- DEFINE(__THREAD_per_address, offsetof(struct thread_struct, per_event.address));
- DEFINE(__THREAD_per_paid, offsetof(struct thread_struct, per_event.paid));
- DEFINE(__THREAD_trap_tdb, offsetof(struct thread_struct, trap_tdb));
+ /* thread struct offsets */
+ OFFSET(__THREAD_ksp, thread_struct, ksp);
+ OFFSET(__THREAD_FPU_fpc, thread_struct, fpu.fpc);
+ OFFSET(__THREAD_FPU_regs, thread_struct, fpu.regs);
+ OFFSET(__THREAD_per_cause, thread_struct, per_event.cause);
+ OFFSET(__THREAD_per_address, thread_struct, per_event.address);
+ OFFSET(__THREAD_per_paid, thread_struct, per_event.paid);
+ OFFSET(__THREAD_trap_tdb, thread_struct, trap_tdb);
BLANK();
- DEFINE(__TI_task, offsetof(struct thread_info, task));
- DEFINE(__TI_flags, offsetof(struct thread_info, flags));
- DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table));
- DEFINE(__TI_cpu, offsetof(struct thread_info, cpu));
- DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
- DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));
- DEFINE(__TI_system_timer, offsetof(struct thread_info, system_timer));
- DEFINE(__TI_last_break, offsetof(struct thread_info, last_break));
+ /* thread info offsets */
+ OFFSET(__TI_task, thread_info, task);
+ OFFSET(__TI_flags, thread_info, flags);
+ OFFSET(__TI_sysc_table, thread_info, sys_call_table);
+ OFFSET(__TI_cpu, thread_info, cpu);
+ OFFSET(__TI_precount, thread_info, preempt_count);
+ OFFSET(__TI_user_timer, thread_info, user_timer);
+ OFFSET(__TI_system_timer, thread_info, system_timer);
+ OFFSET(__TI_last_break, thread_info, last_break);
BLANK();
- DEFINE(__PT_ARGS, offsetof(struct pt_regs, args));
- DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
- DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
- DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
- DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
- DEFINE(__PT_INT_PARM, offsetof(struct pt_regs, int_parm));
- DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
- DEFINE(__PT_FLAGS, offsetof(struct pt_regs, flags));
+ /* pt_regs offsets */
+ OFFSET(__PT_ARGS, pt_regs, args);
+ OFFSET(__PT_PSW, pt_regs, psw);
+ OFFSET(__PT_GPRS, pt_regs, gprs);
+ OFFSET(__PT_ORIG_GPR2, pt_regs, orig_gpr2);
+ OFFSET(__PT_INT_CODE, pt_regs, int_code);
+ OFFSET(__PT_INT_PARM, pt_regs, int_parm);
+ OFFSET(__PT_INT_PARM_LONG, pt_regs, int_parm_long);
+ OFFSET(__PT_FLAGS, pt_regs, flags);
DEFINE(__PT_SIZE, sizeof(struct pt_regs));
BLANK();
- DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
- DEFINE(__SF_GPRS, offsetof(struct stack_frame, gprs));
- DEFINE(__SF_EMPTY, offsetof(struct stack_frame, empty1));
+ /* stack_frame offsets */
+ OFFSET(__SF_BACKCHAIN, stack_frame, back_chain);
+ OFFSET(__SF_GPRS, stack_frame, gprs);
+ OFFSET(__SF_EMPTY, stack_frame, empty1);
BLANK();
/* timeval/timezone offsets for use by vdso */
- DEFINE(__VDSO_UPD_COUNT, offsetof(struct vdso_data, tb_update_count));
- DEFINE(__VDSO_XTIME_STAMP, offsetof(struct vdso_data, xtime_tod_stamp));
- DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec));
- DEFINE(__VDSO_XTIME_NSEC, offsetof(struct vdso_data, xtime_clock_nsec));
- DEFINE(__VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
- DEFINE(__VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
- DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec));
- DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
- DEFINE(__VDSO_WTOM_CRS_SEC, offsetof(struct vdso_data, wtom_coarse_sec));
- DEFINE(__VDSO_WTOM_CRS_NSEC, offsetof(struct vdso_data, wtom_coarse_nsec));
- DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
- DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
- DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
- DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
- DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
- DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
+ OFFSET(__VDSO_UPD_COUNT, vdso_data, tb_update_count);
+ OFFSET(__VDSO_XTIME_STAMP, vdso_data, xtime_tod_stamp);
+ OFFSET(__VDSO_XTIME_SEC, vdso_data, xtime_clock_sec);
+ OFFSET(__VDSO_XTIME_NSEC, vdso_data, xtime_clock_nsec);
+ OFFSET(__VDSO_XTIME_CRS_SEC, vdso_data, xtime_coarse_sec);
+ OFFSET(__VDSO_XTIME_CRS_NSEC, vdso_data, xtime_coarse_nsec);
+ OFFSET(__VDSO_WTOM_SEC, vdso_data, wtom_clock_sec);
+ OFFSET(__VDSO_WTOM_NSEC, vdso_data, wtom_clock_nsec);
+ OFFSET(__VDSO_WTOM_CRS_SEC, vdso_data, wtom_coarse_sec);
+ OFFSET(__VDSO_WTOM_CRS_NSEC, vdso_data, wtom_coarse_nsec);
+ OFFSET(__VDSO_TIMEZONE, vdso_data, tz_minuteswest);
+ OFFSET(__VDSO_ECTG_OK, vdso_data, ectg_available);
+ OFFSET(__VDSO_TK_MULT, vdso_data, tk_mult);
+ OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
+ OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
+ OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
+ OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
+ OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id);
+ BLANK();
/* constants used by the vdso */
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
@@ -86,102 +94,106 @@ int main(void)
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
BLANK();
/* idle data offsets */
- DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter));
- DEFINE(__CLOCK_IDLE_EXIT, offsetof(struct s390_idle_data, clock_idle_exit));
- DEFINE(__TIMER_IDLE_ENTER, offsetof(struct s390_idle_data, timer_idle_enter));
- DEFINE(__TIMER_IDLE_EXIT, offsetof(struct s390_idle_data, timer_idle_exit));
- /* lowcore offsets */
- DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
- DEFINE(__LC_EXT_CPU_ADDR, offsetof(struct _lowcore, ext_cpu_addr));
- DEFINE(__LC_EXT_INT_CODE, offsetof(struct _lowcore, ext_int_code));
- DEFINE(__LC_SVC_ILC, offsetof(struct _lowcore, svc_ilc));
- DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
- DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
- DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
- DEFINE(__LC_TRANS_EXC_CODE, offsetof(struct _lowcore, trans_exc_code));
- DEFINE(__LC_MON_CLASS_NR, offsetof(struct _lowcore, mon_class_num));
- DEFINE(__LC_PER_CODE, offsetof(struct _lowcore, per_code));
- DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_atmid));
- DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
- DEFINE(__LC_EXC_ACCESS_ID, offsetof(struct _lowcore, exc_access_id));
- DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
- DEFINE(__LC_OP_ACCESS_ID, offsetof(struct _lowcore, op_access_id));
- DEFINE(__LC_AR_MODE_ID, offsetof(struct _lowcore, ar_mode_id));
- DEFINE(__LC_MON_CODE, offsetof(struct _lowcore, monitor_code));
- DEFINE(__LC_SUBCHANNEL_ID, offsetof(struct _lowcore, subchannel_id));
- DEFINE(__LC_SUBCHANNEL_NR, offsetof(struct _lowcore, subchannel_nr));
- DEFINE(__LC_IO_INT_PARM, offsetof(struct _lowcore, io_int_parm));
- DEFINE(__LC_IO_INT_WORD, offsetof(struct _lowcore, io_int_word));
- DEFINE(__LC_STFL_FAC_LIST, offsetof(struct _lowcore, stfl_fac_list));
- DEFINE(__LC_MCCK_CODE, offsetof(struct _lowcore, mcck_interruption_code));
- DEFINE(__LC_MCCK_EXT_DAM_CODE, offsetof(struct _lowcore, external_damage_code));
- DEFINE(__LC_RST_OLD_PSW, offsetof(struct _lowcore, restart_old_psw));
- DEFINE(__LC_EXT_OLD_PSW, offsetof(struct _lowcore, external_old_psw));
- DEFINE(__LC_SVC_OLD_PSW, offsetof(struct _lowcore, svc_old_psw));
- DEFINE(__LC_PGM_OLD_PSW, offsetof(struct _lowcore, program_old_psw));
- DEFINE(__LC_MCK_OLD_PSW, offsetof(struct _lowcore, mcck_old_psw));
- DEFINE(__LC_IO_OLD_PSW, offsetof(struct _lowcore, io_old_psw));
- DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
- DEFINE(__LC_EXT_NEW_PSW, offsetof(struct _lowcore, external_new_psw));
- DEFINE(__LC_SVC_NEW_PSW, offsetof(struct _lowcore, svc_new_psw));
- DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
- DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
- DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
+ OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter);
+ OFFSET(__CLOCK_IDLE_EXIT, s390_idle_data, clock_idle_exit);
+ OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter);
+ OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit);
BLANK();
- DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
- DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
- DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
- DEFINE(__LC_CPU_FLAGS, offsetof(struct _lowcore, cpu_flags));
- DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
- DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
- DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
- DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer));
- DEFINE(__LC_MCCK_ENTER_TIMER, offsetof(struct _lowcore, mcck_enter_timer));
- DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer));
- DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer));
- DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer));
- DEFINE(__LC_STEAL_TIMER, offsetof(struct _lowcore, steal_timer));
- DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
- DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
- DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
- DEFINE(__LC_CURRENT_PID, offsetof(struct _lowcore, current_pid));
- DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
- DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
- DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
- DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
- DEFINE(__LC_RESTART_STACK, offsetof(struct _lowcore, restart_stack));
- DEFINE(__LC_RESTART_FN, offsetof(struct _lowcore, restart_fn));
- DEFINE(__LC_RESTART_DATA, offsetof(struct _lowcore, restart_data));
- DEFINE(__LC_RESTART_SOURCE, offsetof(struct _lowcore, restart_source));
- DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
- DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
- DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
- DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
- DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
- DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
+ /* hardware defined lowcore locations 0x000 - 0x1ff */
+ OFFSET(__LC_EXT_PARAMS, lowcore, ext_params);
+ OFFSET(__LC_EXT_CPU_ADDR, lowcore, ext_cpu_addr);
+ OFFSET(__LC_EXT_INT_CODE, lowcore, ext_int_code);
+ OFFSET(__LC_SVC_ILC, lowcore, svc_ilc);
+ OFFSET(__LC_SVC_INT_CODE, lowcore, svc_code);
+ OFFSET(__LC_PGM_ILC, lowcore, pgm_ilc);
+ OFFSET(__LC_PGM_INT_CODE, lowcore, pgm_code);
+ OFFSET(__LC_DATA_EXC_CODE, lowcore, data_exc_code);
+ OFFSET(__LC_MON_CLASS_NR, lowcore, mon_class_num);
+ OFFSET(__LC_PER_CODE, lowcore, per_code);
+ OFFSET(__LC_PER_ATMID, lowcore, per_atmid);
+ OFFSET(__LC_PER_ADDRESS, lowcore, per_address);
+ OFFSET(__LC_EXC_ACCESS_ID, lowcore, exc_access_id);
+ OFFSET(__LC_PER_ACCESS_ID, lowcore, per_access_id);
+ OFFSET(__LC_OP_ACCESS_ID, lowcore, op_access_id);
+ OFFSET(__LC_AR_MODE_ID, lowcore, ar_mode_id);
+ OFFSET(__LC_TRANS_EXC_CODE, lowcore, trans_exc_code);
+ OFFSET(__LC_MON_CODE, lowcore, monitor_code);
+ OFFSET(__LC_SUBCHANNEL_ID, lowcore, subchannel_id);
+ OFFSET(__LC_SUBCHANNEL_NR, lowcore, subchannel_nr);
+ OFFSET(__LC_IO_INT_PARM, lowcore, io_int_parm);
+ OFFSET(__LC_IO_INT_WORD, lowcore, io_int_word);
+ OFFSET(__LC_STFL_FAC_LIST, lowcore, stfl_fac_list);
+ OFFSET(__LC_STFLE_FAC_LIST, lowcore, stfle_fac_list);
+ OFFSET(__LC_MCCK_CODE, lowcore, mcck_interruption_code);
+ OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address);
+ OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr);
+ OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw);
+ OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw);
+ OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw);
+ OFFSET(__LC_PGM_OLD_PSW, lowcore, program_old_psw);
+ OFFSET(__LC_MCK_OLD_PSW, lowcore, mcck_old_psw);
+ OFFSET(__LC_IO_OLD_PSW, lowcore, io_old_psw);
+ OFFSET(__LC_RST_NEW_PSW, lowcore, restart_psw);
+ OFFSET(__LC_EXT_NEW_PSW, lowcore, external_new_psw);
+ OFFSET(__LC_SVC_NEW_PSW, lowcore, svc_new_psw);
+ OFFSET(__LC_PGM_NEW_PSW, lowcore, program_new_psw);
+ OFFSET(__LC_MCK_NEW_PSW, lowcore, mcck_new_psw);
+ OFFSET(__LC_IO_NEW_PSW, lowcore, io_new_psw);
+ /* software defined lowcore locations 0x200 - 0xdff*/
+ OFFSET(__LC_SAVE_AREA_SYNC, lowcore, save_area_sync);
+ OFFSET(__LC_SAVE_AREA_ASYNC, lowcore, save_area_async);
+ OFFSET(__LC_SAVE_AREA_RESTART, lowcore, save_area_restart);
+ OFFSET(__LC_CPU_FLAGS, lowcore, cpu_flags);
+ OFFSET(__LC_RETURN_PSW, lowcore, return_psw);
+ OFFSET(__LC_RETURN_MCCK_PSW, lowcore, return_mcck_psw);
+ OFFSET(__LC_SYNC_ENTER_TIMER, lowcore, sync_enter_timer);
+ OFFSET(__LC_ASYNC_ENTER_TIMER, lowcore, async_enter_timer);
+ OFFSET(__LC_MCCK_ENTER_TIMER, lowcore, mcck_enter_timer);
+ OFFSET(__LC_EXIT_TIMER, lowcore, exit_timer);
+ OFFSET(__LC_USER_TIMER, lowcore, user_timer);
+ OFFSET(__LC_SYSTEM_TIMER, lowcore, system_timer);
+ OFFSET(__LC_STEAL_TIMER, lowcore, steal_timer);
+ OFFSET(__LC_LAST_UPDATE_TIMER, lowcore, last_update_timer);
+ OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock);
+ OFFSET(__LC_INT_CLOCK, lowcore, int_clock);
+ OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock);
+ OFFSET(__LC_CURRENT, lowcore, current_task);
+ OFFSET(__LC_THREAD_INFO, lowcore, thread_info);
+ OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack);
+ OFFSET(__LC_ASYNC_STACK, lowcore, async_stack);
+ OFFSET(__LC_PANIC_STACK, lowcore, panic_stack);
+ OFFSET(__LC_RESTART_STACK, lowcore, restart_stack);
+ OFFSET(__LC_RESTART_FN, lowcore, restart_fn);
+ OFFSET(__LC_RESTART_DATA, lowcore, restart_data);
+ OFFSET(__LC_RESTART_SOURCE, lowcore, restart_source);
+ OFFSET(__LC_USER_ASCE, lowcore, user_asce);
+ OFFSET(__LC_LPP, lowcore, lpp);
+ OFFSET(__LC_CURRENT_PID, lowcore, current_pid);
+ OFFSET(__LC_PERCPU_OFFSET, lowcore, percpu_offset);
+ OFFSET(__LC_VDSO_PER_CPU, lowcore, vdso_per_cpu_data);
+ OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags);
+ OFFSET(__LC_GMAP, lowcore, gmap);
+ OFFSET(__LC_PASTE, lowcore, paste);
+ /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
+ OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
+ /* hardware defined lowcore locations 0x1000 - 0x18ff */
+ OFFSET(__LC_VX_SAVE_AREA_ADDR, lowcore, vector_save_area_addr);
+ OFFSET(__LC_EXT_PARAMS2, lowcore, ext_params2);
+ OFFSET(__LC_FPREGS_SAVE_AREA, lowcore, floating_pt_save_area);
+ OFFSET(__LC_GPREGS_SAVE_AREA, lowcore, gpregs_save_area);
+ OFFSET(__LC_PSW_SAVE_AREA, lowcore, psw_save_area);
+ OFFSET(__LC_PREFIX_SAVE_AREA, lowcore, prefixreg_save_area);
+ OFFSET(__LC_FP_CREG_SAVE_AREA, lowcore, fpt_creg_save_area);
+ OFFSET(__LC_TOD_PROGREG_SAVE_AREA, lowcore, tod_progreg_save_area);
+ OFFSET(__LC_CPU_TIMER_SAVE_AREA, lowcore, cpu_timer_save_area);
+ OFFSET(__LC_CLOCK_COMP_SAVE_AREA, lowcore, clock_comp_save_area);
+ OFFSET(__LC_AREGS_SAVE_AREA, lowcore, access_regs_save_area);
+ OFFSET(__LC_CREGS_SAVE_AREA, lowcore, cregs_save_area);
+ OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb);
BLANK();
- DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
- DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
- DEFINE(__LC_PSW_SAVE_AREA, offsetof(struct _lowcore, psw_save_area));
- DEFINE(__LC_PREFIX_SAVE_AREA, offsetof(struct _lowcore, prefixreg_save_area));
- DEFINE(__LC_AREGS_SAVE_AREA, offsetof(struct _lowcore, access_regs_save_area));
- DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
- DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
- DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
- DEFINE(__LC_DATA_EXC_CODE, offsetof(struct _lowcore, data_exc_code));
- DEFINE(__LC_MCCK_FAIL_STOR_ADDR, offsetof(struct _lowcore, failing_storage_address));
- DEFINE(__LC_VX_SAVE_AREA_ADDR, offsetof(struct _lowcore, vector_save_area_addr));
- DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
- DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
- DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
- DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area));
- DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
- DEFINE(__LC_PERCPU_OFFSET, offsetof(struct _lowcore, percpu_offset));
- DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
- DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
- DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
- DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
- DEFINE(__SIE_PROG0C, offsetof(struct kvm_s390_sie_block, prog0c));
- DEFINE(__SIE_PROG20, offsetof(struct kvm_s390_sie_block, prog20));
+ /* gmap/sie offsets */
+ OFFSET(__GMAP_ASCE, gmap, asce);
+ OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c);
+ OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20);
return 0;
}
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index e0f9d27..4af6037 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -249,7 +249,7 @@ static int save_sigregs_ext32(struct pt_regs *regs,
return -EFAULT;
/* Save vector registers to signal stack */
- if (is_vx_task(current)) {
+ if (MACHINE_HAS_VX) {
for (i = 0; i < __NUM_VXRS_LOW; i++)
vxrs[i] = *((__u64 *)(current->thread.fpu.vxrs + i) + 1);
if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
@@ -271,13 +271,13 @@ static int restore_sigregs_ext32(struct pt_regs *regs,
/* Restore high gprs from signal stack */
if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
- sizeof(&sregs_ext->gprs_high)))
+ sizeof(sregs_ext->gprs_high)))
return -EFAULT;
for (i = 0; i < NUM_GPRS; i++)
*(__u32 *)&regs->gprs[i] = gprs_high[i];
/* Restore vector registers from signal stack */
- if (is_vx_task(current)) {
+ if (MACHINE_HAS_VX) {
if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
sizeof(sregs_ext->vxrs_low)) ||
__copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
@@ -470,8 +470,7 @@ static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
*/
uc_flags = UC_GPRS_HIGH;
if (MACHINE_HAS_VX) {
- if (is_vx_task(current))
- uc_flags |= UC_VXRS;
+ uc_flags |= UC_VXRS;
} else
frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) +
sizeof(frame->uc.uc_mcontext_ext.vxrs_high);
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
index 09f1940..ae2cda5 100644
--- a/arch/s390/kernel/compat_wrapper.c
+++ b/arch/s390/kernel/compat_wrapper.c
@@ -176,3 +176,5 @@ COMPAT_SYSCALL_WRAP4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len);
+COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags);
+COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 199ec92..7f48e56 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/cpcmd.h>
#include <asm/io.h>
@@ -70,6 +71,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
memcpy(cpcmd_buf, cmd, cmdlen);
ASCEBC(cpcmd_buf, cmdlen);
+ diag_stat_inc(DIAG_STAT_X008);
if (response) {
memset(response, 0, rlen);
response_len = rlen;
@@ -94,8 +96,7 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
(((unsigned long)response + rlen) >> 31)) {
lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
if (!lowbuf) {
- pr_warning("The cpcmd kernel function failed to "
- "allocate a response buffer\n");
+ pr_warn("The cpcmd kernel function failed to allocate a response buffer\n");
return -ENOMEM;
}
spin_lock_irqsave(&cpcmd_lock, flags);
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index 0c6c01e..3986c9f 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/elf.h>
+#include <asm/asm-offsets.h>
#include <linux/memblock.h>
#include <asm/os_info.h>
#include <asm/elf.h>
@@ -32,17 +33,82 @@ static struct memblock_type oldmem_type = {
.regions = &oldmem_region,
};
-#define for_each_dump_mem_range(i, nid, p_start, p_end, p_nid) \
- for (i = 0, __next_mem_range(&i, nid, MEMBLOCK_NONE, \
- &memblock.physmem, \
- &oldmem_type, p_start, \
- p_end, p_nid); \
- i != (u64)ULLONG_MAX; \
- __next_mem_range(&i, nid, MEMBLOCK_NONE, &memblock.physmem,\
- &oldmem_type, \
- p_start, p_end, p_nid))
+struct save_area {
+ struct list_head list;
+ u64 psw[2];
+ u64 ctrs[16];
+ u64 gprs[16];
+ u32 acrs[16];
+ u64 fprs[16];
+ u32 fpc;
+ u32 prefix;
+ u64 todpreg;
+ u64 timer;
+ u64 todcmp;
+ u64 vxrs_low[16];
+ __vector128 vxrs_high[16];
+};
+
+static LIST_HEAD(dump_save_areas);
+
+/*
+ * Allocate a save area
+ */
+struct save_area * __init save_area_alloc(bool is_boot_cpu)
+{
+ struct save_area *sa;
-struct dump_save_areas dump_save_areas;
+ sa = (void *) memblock_alloc(sizeof(*sa), 8);
+ if (is_boot_cpu)
+ list_add(&sa->list, &dump_save_areas);
+ else
+ list_add_tail(&sa->list, &dump_save_areas);
+ return sa;
+}
+
+/*
+ * Return the address of the save area for the boot CPU
+ */
+struct save_area * __init save_area_boot_cpu(void)
+{
+ if (list_empty(&dump_save_areas))
+ return NULL;
+ return list_first_entry(&dump_save_areas, struct save_area, list);
+}
+
+/*
+ * Copy CPU registers into the save area
+ */
+void __init save_area_add_regs(struct save_area *sa, void *regs)
+{
+ struct lowcore *lc;
+
+ lc = (struct lowcore *)(regs - __LC_FPREGS_SAVE_AREA);
+ memcpy(&sa->psw, &lc->psw_save_area, sizeof(sa->psw));
+ memcpy(&sa->ctrs, &lc->cregs_save_area, sizeof(sa->ctrs));
+ memcpy(&sa->gprs, &lc->gpregs_save_area, sizeof(sa->gprs));
+ memcpy(&sa->acrs, &lc->access_regs_save_area, sizeof(sa->acrs));
+ memcpy(&sa->fprs, &lc->floating_pt_save_area, sizeof(sa->fprs));
+ memcpy(&sa->fpc, &lc->fpt_creg_save_area, sizeof(sa->fpc));
+ memcpy(&sa->prefix, &lc->prefixreg_save_area, sizeof(sa->prefix));
+ memcpy(&sa->todpreg, &lc->tod_progreg_save_area, sizeof(sa->todpreg));
+ memcpy(&sa->timer, &lc->cpu_timer_save_area, sizeof(sa->timer));
+ memcpy(&sa->todcmp, &lc->clock_comp_save_area, sizeof(sa->todcmp));
+}
+
+/*
+ * Copy vector registers into the save area
+ */
+void __init save_area_add_vxrs(struct save_area *sa, __vector128 *vxrs)
+{
+ int i;
+
+ /* Copy lower halves of vector registers 0-15 */
+ for (i = 0; i < 16; i++)
+ memcpy(&sa->vxrs_low[i], &vxrs[i].u[2], 8);
+ /* Copy vector registers 16-31 */
+ memcpy(sa->vxrs_high, vxrs + 16, 16 * sizeof(__vector128));
+}
/*
* Return physical address for virtual address
@@ -61,79 +127,85 @@ static inline void *load_real_addr(void *addr)
}
/*
- * Copy real to virtual or real memory
+ * Copy memory of the old, dumped system to a kernel space virtual address
*/
-static int copy_from_realmem(void *dest, void *src, size_t count)
-{
- unsigned long size;
-
- if (!count)
- return 0;
- if (!is_vmalloc_or_module_addr(dest))
- return memcpy_real(dest, src, count);
- do {
- size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK));
- if (memcpy_real(load_real_addr(dest), src, size))
- return -EFAULT;
- count -= size;
- dest += size;
- src += size;
- } while (count);
- return 0;
-}
-
-/*
- * Pointer to ELF header in new kernel
- */
-static void *elfcorehdr_newmem;
-
-/*
- * Copy one page from zfcpdump "oldmem"
- *
- * For pages below HSA size memory from the HSA is copied. Otherwise
- * real memory copy is used.
- */
-static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize,
- unsigned long src, int userbuf)
+int copy_oldmem_kernel(void *dst, void *src, size_t count)
{
+ unsigned long from, len;
+ void *ra;
int rc;
- if (src < sclp.hsa_size) {
- rc = memcpy_hsa(buf, src, csize, userbuf);
- } else {
- if (userbuf)
- rc = copy_to_user_real((void __force __user *) buf,
- (void *) src, csize);
- else
- rc = memcpy_real(buf, (void *) src, csize);
+ while (count) {
+ from = __pa(src);
+ if (!OLDMEM_BASE && from < sclp.hsa_size) {
+ /* Copy from zfcpdump HSA area */
+ len = min(count, sclp.hsa_size - from);
+ rc = memcpy_hsa_kernel(dst, from, len);
+ if (rc)
+ return rc;
+ } else {
+ /* Check for swapped kdump oldmem areas */
+ if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) {
+ from -= OLDMEM_BASE;
+ len = min(count, OLDMEM_SIZE - from);
+ } else if (OLDMEM_BASE && from < OLDMEM_SIZE) {
+ len = min(count, OLDMEM_SIZE - from);
+ from += OLDMEM_BASE;
+ } else {
+ len = count;
+ }
+ if (is_vmalloc_or_module_addr(dst)) {
+ ra = load_real_addr(dst);
+ len = min(PAGE_SIZE - offset_in_page(ra), len);
+ } else {
+ ra = dst;
+ }
+ if (memcpy_real(ra, (void *) from, len))
+ return -EFAULT;
+ }
+ dst += len;
+ src += len;
+ count -= len;
}
- return rc ? rc : csize;
+ return 0;
}
/*
- * Copy one page from kdump "oldmem"
- *
- * For the kdump reserved memory this functions performs a swap operation:
- * - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE].
- * - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
+ * Copy memory of the old, dumped system to a user space virtual address
*/
-static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize,
- unsigned long src, int userbuf)
-
+int copy_oldmem_user(void __user *dst, void *src, size_t count)
{
+ unsigned long from, len;
int rc;
- if (src < OLDMEM_SIZE)
- src += OLDMEM_BASE;
- else if (src > OLDMEM_BASE &&
- src < OLDMEM_BASE + OLDMEM_SIZE)
- src -= OLDMEM_BASE;
- if (userbuf)
- rc = copy_to_user_real((void __force __user *) buf,
- (void *) src, csize);
- else
- rc = copy_from_realmem(buf, (void *) src, csize);
- return (rc == 0) ? rc : csize;
+ while (count) {
+ from = __pa(src);
+ if (!OLDMEM_BASE && from < sclp.hsa_size) {
+ /* Copy from zfcpdump HSA area */
+ len = min(count, sclp.hsa_size - from);
+ rc = memcpy_hsa_user(dst, from, len);
+ if (rc)
+ return rc;
+ } else {
+ /* Check for swapped kdump oldmem areas */
+ if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) {
+ from -= OLDMEM_BASE;
+ len = min(count, OLDMEM_SIZE - from);
+ } else if (OLDMEM_BASE && from < OLDMEM_SIZE) {
+ len = min(count, OLDMEM_SIZE - from);
+ from += OLDMEM_BASE;
+ } else {
+ len = count;
+ }
+ rc = copy_to_user_real(dst, (void *) from, count);
+ if (rc)
+ return rc;
+ }
+ dst += len;
+ src += len;
+ count -= len;
+ }
+ return 0;
}
/*
@@ -142,15 +214,17 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize,
ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
unsigned long offset, int userbuf)
{
- unsigned long src;
+ void *src;
+ int rc;
if (!csize)
return 0;
- src = (pfn << PAGE_SHIFT) + offset;
- if (OLDMEM_BASE)
- return copy_oldmem_page_kdump(buf, csize, src, userbuf);
+ src = (void *) (pfn << PAGE_SHIFT) + offset;
+ if (userbuf)
+ rc = copy_oldmem_user((void __force __user *) buf, src, csize);
else
- return copy_oldmem_page_zfcpdump(buf, csize, src, userbuf);
+ rc = copy_oldmem_kernel((void *) buf, src, csize);
+ return rc;
}
/*
@@ -219,33 +293,6 @@ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from,
}
/*
- * Copy memory from old kernel
- */
-int copy_from_oldmem(void *dest, void *src, size_t count)
-{
- unsigned long copied = 0;
- int rc;
-
- if (OLDMEM_BASE) {
- if ((unsigned long) src < OLDMEM_SIZE) {
- copied = min(count, OLDMEM_SIZE - (unsigned long) src);
- rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied);
- if (rc)
- return rc;
- }
- } else {
- unsigned long hsa_end = sclp.hsa_size;
- if ((unsigned long) src < hsa_end) {
- copied = min(count, hsa_end - (unsigned long) src);
- rc = memcpy_hsa(dest, (unsigned long) src, copied, 0);
- if (rc)
- return rc;
- }
- }
- return copy_from_realmem(dest + copied, src + copied, count - copied);
-}
-
-/*
* Alloc memory and panic in case of ENOMEM
*/
static void *kzalloc_panic(int len)
@@ -261,8 +308,8 @@ static void *kzalloc_panic(int len)
/*
* Initialize ELF note
*/
-static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len,
- const char *name)
+static void *nt_init_name(void *buf, Elf64_Word type, void *desc, int d_len,
+ const char *name)
{
Elf64_Nhdr *note;
u64 len;
@@ -282,136 +329,42 @@ static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len,
return PTR_ADD(buf, len);
}
-/*
- * Initialize prstatus note
- */
-static void *nt_prstatus(void *ptr, struct save_area *sa)
+static inline void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len)
{
- struct elf_prstatus nt_prstatus;
- static int cpu_nr = 1;
-
- memset(&nt_prstatus, 0, sizeof(nt_prstatus));
- memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs));
- memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
- memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs));
- nt_prstatus.pr_pid = cpu_nr;
- cpu_nr++;
-
- return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus),
- "CORE");
+ return nt_init_name(buf, type, desc, d_len, KEXEC_CORE_NOTE_NAME);
}
/*
- * Initialize fpregset (floating point) note
+ * Fill ELF notes for one CPU with save area registers
*/
-static void *nt_fpregset(void *ptr, struct save_area *sa)
+static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa)
{
+ struct elf_prstatus nt_prstatus;
elf_fpregset_t nt_fpregset;
+ /* Prepare prstatus note */
+ memset(&nt_prstatus, 0, sizeof(nt_prstatus));
+ memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs));
+ memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
+ memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs));
+ nt_prstatus.pr_pid = cpu;
+ /* Prepare fpregset (floating point) note */
memset(&nt_fpregset, 0, sizeof(nt_fpregset));
- memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg));
- memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs));
-
- return nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset),
- "CORE");
-}
-
-/*
- * Initialize timer note
- */
-static void *nt_s390_timer(void *ptr, struct save_area *sa)
-{
- return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer),
- KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize TOD clock comparator note
- */
-static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa)
-{
- return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp,
- sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize TOD programmable register note
- */
-static void *nt_s390_tod_preg(void *ptr, struct save_area *sa)
-{
- return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg,
- sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize control register note
- */
-static void *nt_s390_ctrs(void *ptr, struct save_area *sa)
-{
- return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs,
- sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize prefix register note
- */
-static void *nt_s390_prefix(void *ptr, struct save_area *sa)
-{
- return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg,
- sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize vxrs high note (full 128 bit VX registers 16-31)
- */
-static void *nt_s390_vx_high(void *ptr, __vector128 *vx_regs)
-{
- return nt_init(ptr, NT_S390_VXRS_HIGH, &vx_regs[16],
- 16 * sizeof(__vector128), KEXEC_CORE_NOTE_NAME);
-}
-
-/*
- * Initialize vxrs low note (lower halves of VX registers 0-15)
- */
-static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs)
-{
- Elf64_Nhdr *note;
- u64 len;
- int i;
-
- note = (Elf64_Nhdr *)ptr;
- note->n_namesz = strlen(KEXEC_CORE_NOTE_NAME) + 1;
- note->n_descsz = 16 * 8;
- note->n_type = NT_S390_VXRS_LOW;
- len = sizeof(Elf64_Nhdr);
-
- memcpy(ptr + len, KEXEC_CORE_NOTE_NAME, note->n_namesz);
- len = roundup(len + note->n_namesz, 4);
-
- ptr += len;
- /* Copy lower halves of SIMD registers 0-15 */
- for (i = 0; i < 16; i++) {
- memcpy(ptr, &vx_regs[i].u[2], 8);
- ptr += 8;
- }
- return ptr;
-}
-
-/*
- * Fill ELF notes for one CPU with save area registers
- */
-void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vx_regs)
-{
- ptr = nt_prstatus(ptr, sa);
- ptr = nt_fpregset(ptr, sa);
- ptr = nt_s390_timer(ptr, sa);
- ptr = nt_s390_tod_cmp(ptr, sa);
- ptr = nt_s390_tod_preg(ptr, sa);
- ptr = nt_s390_ctrs(ptr, sa);
- ptr = nt_s390_prefix(ptr, sa);
- if (MACHINE_HAS_VX && vx_regs) {
- ptr = nt_s390_vx_low(ptr, vx_regs);
- ptr = nt_s390_vx_high(ptr, vx_regs);
+ memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc));
+ memcpy(&nt_fpregset.fprs, &sa->fprs, sizeof(sa->fprs));
+ /* Create ELF notes for the CPU */
+ ptr = nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus));
+ ptr = nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset));
+ ptr = nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer));
+ ptr = nt_init(ptr, NT_S390_TODCMP, &sa->todcmp, sizeof(sa->todcmp));
+ ptr = nt_init(ptr, NT_S390_TODPREG, &sa->todpreg, sizeof(sa->todpreg));
+ ptr = nt_init(ptr, NT_S390_CTRS, &sa->ctrs, sizeof(sa->ctrs));
+ ptr = nt_init(ptr, NT_S390_PREFIX, &sa->prefix, sizeof(sa->prefix));
+ if (MACHINE_HAS_VX) {
+ ptr = nt_init(ptr, NT_S390_VXRS_HIGH,
+ &sa->vxrs_high, sizeof(sa->vxrs_high));
+ ptr = nt_init(ptr, NT_S390_VXRS_LOW,
+ &sa->vxrs_low, sizeof(sa->vxrs_low));
}
return ptr;
}
@@ -426,8 +379,7 @@ static void *nt_prpsinfo(void *ptr)
memset(&prpsinfo, 0, sizeof(prpsinfo));
prpsinfo.pr_sname = 'R';
strcpy(prpsinfo.pr_fname, "vmlinux");
- return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo),
- KEXEC_CORE_NOTE_NAME);
+ return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
}
/*
@@ -439,17 +391,18 @@ static void *get_vmcoreinfo_old(unsigned long *size)
Elf64_Nhdr note;
void *addr;
- if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr)))
+ if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr)))
return NULL;
memset(nt_name, 0, sizeof(nt_name));
- if (copy_from_oldmem(&note, addr, sizeof(note)))
+ if (copy_oldmem_kernel(&note, addr, sizeof(note)))
return NULL;
- if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1))
+ if (copy_oldmem_kernel(nt_name, addr + sizeof(note),
+ sizeof(nt_name) - 1))
return NULL;
if (strcmp(nt_name, "VMCOREINFO") != 0)
return NULL;
vmcoreinfo = kzalloc_panic(note.n_descsz);
- if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz))
+ if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz))
return NULL;
*size = note.n_descsz;
return vmcoreinfo;
@@ -468,7 +421,7 @@ static void *nt_vmcoreinfo(void *ptr)
vmcoreinfo = get_vmcoreinfo_old(&size);
if (!vmcoreinfo)
return ptr;
- return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
+ return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
}
/*
@@ -497,13 +450,12 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
*/
static int get_cpu_cnt(void)
{
- int i, cpus = 0;
+ struct save_area *sa;
+ int cpus = 0;
- for (i = 0; i < dump_save_areas.count; i++) {
- if (dump_save_areas.areas[i]->sa.pref_reg == 0)
- continue;
- cpus++;
- }
+ list_for_each_entry(sa, &dump_save_areas, list)
+ if (sa->prefix != 0)
+ cpus++;
return cpus;
}
@@ -515,7 +467,8 @@ static int get_mem_chunk_cnt(void)
int cnt = 0;
u64 idx;
- for_each_dump_mem_range(idx, NUMA_NO_NODE, NULL, NULL, NULL)
+ for_each_mem_range(idx, &memblock.physmem, &oldmem_type, NUMA_NO_NODE,
+ MEMBLOCK_NONE, NULL, NULL, NULL)
cnt++;
return cnt;
}
@@ -528,7 +481,8 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset)
phys_addr_t start, end;
u64 idx;
- for_each_dump_mem_range(idx, NUMA_NO_NODE, &start, &end, NULL) {
+ for_each_mem_range(idx, &memblock.physmem, &oldmem_type, NUMA_NO_NODE,
+ MEMBLOCK_NONE, &start, &end, NULL) {
phdr->p_filesz = end - start;
phdr->p_type = PT_LOAD;
phdr->p_offset = start;
@@ -546,18 +500,16 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset)
*/
static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
{
- struct save_area_ext *sa_ext;
+ struct save_area *sa;
void *ptr_start = ptr;
- int i;
+ int cpu;
ptr = nt_prpsinfo(ptr);
- for (i = 0; i < dump_save_areas.count; i++) {
- sa_ext = dump_save_areas.areas[i];
- if (sa_ext->sa.pref_reg == 0)
- continue;
- ptr = fill_cpu_elf_notes(ptr, &sa_ext->sa, sa_ext->vx_regs);
- }
+ cpu = 1;
+ list_for_each_entry(sa, &dump_save_areas, list)
+ if (sa->prefix != 0)
+ ptr = fill_cpu_elf_notes(ptr, cpu++, sa);
ptr = nt_vmcoreinfo(ptr);
memset(phdr, 0, sizeof(*phdr));
phdr->p_type = PT_NOTE;
@@ -581,9 +533,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
/* If we are not in kdump or zfcpdump mode return */
if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP)
return 0;
- /* If elfcorehdr= has been passed via cmdline, we use that one */
- if (elfcorehdr_addr != ELFCORE_ADDR_MAX)
- return 0;
/* If we cannot get HSA size for zfcpdump return error */
if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size)
return -ENODEV;
@@ -614,7 +563,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
hdr_off = PTR_DIFF(ptr, hdr);
loads_init(phdr_loads, hdr_off);
*addr = (unsigned long long) hdr;
- elfcorehdr_newmem = hdr;
*size = (unsigned long long) hdr_off;
BUG_ON(elfcorehdr_size > alloc_size);
return 0;
@@ -625,8 +573,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
*/
void elfcorehdr_free(unsigned long long addr)
{
- if (!elfcorehdr_newmem)
- return;
kfree((void *)(unsigned long)addr);
}
@@ -637,7 +583,6 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
{
void *src = (void *)(unsigned long)*ppos;
- src = elfcorehdr_newmem ? src : src - OLDMEM_BASE;
memcpy(buf, src, count);
*ppos += count;
return count;
@@ -649,15 +594,8 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
{
void *src = (void *)(unsigned long)*ppos;
- int rc;
- if (elfcorehdr_newmem) {
- memcpy(buf, src, count);
- } else {
- rc = copy_from_oldmem(buf, src, count);
- if (rc)
- return rc;
- }
+ memcpy(buf, src, count);
*ppos += count;
return count;
}
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 6fca0e4..aa12de7 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -699,8 +699,7 @@ debug_info_t *debug_register_mode(const char *name, int pages_per_area,
/* Since debugfs currently does not support uid/gid other than root, */
/* we do not allow gid/uid != 0 until we get support for that. */
if ((uid != 0) || (gid != 0))
- pr_warning("Root becomes the owner of all s390dbf files "
- "in sysfs\n");
+ pr_warn("Root becomes the owner of all s390dbf files in sysfs\n");
BUG_ON(!initialized);
mutex_lock(&debug_mutex);
@@ -1307,8 +1306,7 @@ debug_input_level_fn(debug_info_t * id, struct debug_view *view,
new_level = debug_get_uint(str);
}
if(new_level < 0) {
- pr_warning("%s is not a valid level for a debug "
- "feature\n", str);
+ pr_warn("%s is not a valid level for a debug feature\n", str);
rc = -EINVAL;
} else {
debug_set_level(id, new_level);
@@ -1470,7 +1468,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
except_str = "*";
else
except_str = "-";
- caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN;
+ caller = (unsigned long) entry->caller;
rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ",
area, (long long)time_spec.tv_sec,
time_spec.tv_nsec / 1000, level, except_str,
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index 2f69243..48b37b8 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -6,12 +6,137 @@
*/
#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
#include <asm/diag.h>
+#include <asm/trace/diag.h>
+
+struct diag_stat {
+ unsigned int counter[NR_DIAG_STAT];
+};
+
+static DEFINE_PER_CPU(struct diag_stat, diag_stat);
+
+struct diag_desc {
+ int code;
+ char *name;
+};
+
+static const struct diag_desc diag_map[NR_DIAG_STAT] = {
+ [DIAG_STAT_X008] = { .code = 0x008, .name = "Console Function" },
+ [DIAG_STAT_X00C] = { .code = 0x00c, .name = "Pseudo Timer" },
+ [DIAG_STAT_X010] = { .code = 0x010, .name = "Release Pages" },
+ [DIAG_STAT_X014] = { .code = 0x014, .name = "Spool File Services" },
+ [DIAG_STAT_X044] = { .code = 0x044, .name = "Voluntary Timeslice End" },
+ [DIAG_STAT_X064] = { .code = 0x064, .name = "NSS Manipulation" },
+ [DIAG_STAT_X09C] = { .code = 0x09c, .name = "Relinquish Timeslice" },
+ [DIAG_STAT_X0DC] = { .code = 0x0dc, .name = "Appldata Control" },
+ [DIAG_STAT_X204] = { .code = 0x204, .name = "Logical-CPU Utilization" },
+ [DIAG_STAT_X210] = { .code = 0x210, .name = "Device Information" },
+ [DIAG_STAT_X224] = { .code = 0x224, .name = "EBCDIC-Name Table" },
+ [DIAG_STAT_X250] = { .code = 0x250, .name = "Block I/O" },
+ [DIAG_STAT_X258] = { .code = 0x258, .name = "Page-Reference Services" },
+ [DIAG_STAT_X288] = { .code = 0x288, .name = "Time Bomb" },
+ [DIAG_STAT_X2C4] = { .code = 0x2c4, .name = "FTP Services" },
+ [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" },
+ [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" },
+ [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" },
+ [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" },
+};
+
+static int show_diag_stat(struct seq_file *m, void *v)
+{
+ struct diag_stat *stat;
+ unsigned long n = (unsigned long) v - 1;
+ int cpu, prec, tmp;
+
+ get_online_cpus();
+ if (n == 0) {
+ seq_puts(m, " ");
+
+ for_each_online_cpu(cpu) {
+ prec = 10;
+ for (tmp = 10; cpu >= tmp; tmp *= 10)
+ prec--;
+ seq_printf(m, "%*s%d", prec, "CPU", cpu);
+ }
+ seq_putc(m, '\n');
+ } else if (n <= NR_DIAG_STAT) {
+ seq_printf(m, "diag %03x:", diag_map[n-1].code);
+ for_each_online_cpu(cpu) {
+ stat = &per_cpu(diag_stat, cpu);
+ seq_printf(m, " %10u", stat->counter[n-1]);
+ }
+ seq_printf(m, " %s\n", diag_map[n-1].name);
+ }
+ put_online_cpus();
+ return 0;
+}
+
+static void *show_diag_stat_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos <= nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL;
+}
+
+static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return show_diag_stat_start(m, pos);
+}
+
+static void show_diag_stat_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations show_diag_stat_sops = {
+ .start = show_diag_stat_start,
+ .next = show_diag_stat_next,
+ .stop = show_diag_stat_stop,
+ .show = show_diag_stat,
+};
+
+static int show_diag_stat_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &show_diag_stat_sops);
+}
+
+static const struct file_operations show_diag_stat_fops = {
+ .open = show_diag_stat_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+
+static int __init show_diag_stat_init(void)
+{
+ debugfs_create_file("diag_stat", 0400, NULL, NULL,
+ &show_diag_stat_fops);
+ return 0;
+}
+
+device_initcall(show_diag_stat_init);
+
+void diag_stat_inc(enum diag_stat_enum nr)
+{
+ this_cpu_inc(diag_stat.counter[nr]);
+ trace_s390_diagnose(diag_map[nr].code);
+}
+EXPORT_SYMBOL(diag_stat_inc);
+
+void diag_stat_inc_norecursion(enum diag_stat_enum nr)
+{
+ this_cpu_inc(diag_stat.counter[nr]);
+ trace_s390_diagnose_norecursion(diag_map[nr].code);
+}
+EXPORT_SYMBOL(diag_stat_inc_norecursion);
/*
* Diagnose 14: Input spool file manipulation
*/
-int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
+static inline int __diag14(unsigned long rx, unsigned long ry1,
+ unsigned long subcode)
{
register unsigned long _ry1 asm("2") = ry1;
register unsigned long _ry2 asm("3") = subcode;
@@ -29,6 +154,12 @@ int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
return rc;
}
+
+int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
+{
+ diag_stat_inc(DIAG_STAT_X014);
+ return __diag14(rx, ry1, subcode);
+}
EXPORT_SYMBOL(diag14);
/*
@@ -48,6 +179,7 @@ int diag210(struct diag210 *addr)
spin_lock_irqsave(&diag210_lock, flags);
diag210_tmp = *addr;
+ diag_stat_inc(DIAG_STAT_X210);
asm volatile(
" lhi %0,-1\n"
" sam31\n"
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 8140d10..8cb9bfd 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -2015,7 +2015,7 @@ void show_code(struct pt_regs *regs)
*ptr++ = '\t';
ptr += print_insn(ptr, code + start, addr);
start += opsize;
- printk(buffer);
+ printk("%s", buffer);
ptr = buffer;
ptr += sprintf(ptr, "\n ");
hops++;
@@ -2042,7 +2042,7 @@ void print_fn_code(unsigned char *code, unsigned long len)
ptr += print_insn(ptr, code, (unsigned long) code);
*ptr++ = '\n';
*ptr++ = 0;
- printk(buffer);
+ printk("%s", buffer);
code += opsize;
len -= opsize;
}
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index dc8e204..1b6081c 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/kdebug.h>
#include <linux/ptrace.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/processor.h>
@@ -19,76 +20,87 @@
#include <asm/ipl.h>
/*
- * For show_trace we have tree different stack to consider:
+ * For dump_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
* - the asynchronous interrupt stack (cpu related)
* - the synchronous kernel stack (process related)
- * The stack trace can start at any of the three stack and can potentially
+ * The stack trace can start at any of the three stacks and can potentially
* touch all of them. The order is: panic stack, async stack, sync stack.
*/
static unsigned long
-__show_trace(unsigned long sp, unsigned long low, unsigned long high)
+__dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
+ unsigned long low, unsigned long high)
{
struct stack_frame *sf;
struct pt_regs *regs;
- unsigned long addr;
while (1) {
- sp = sp & PSW_ADDR_INSN;
if (sp < low || sp > high - sizeof(*sf))
return sp;
sf = (struct stack_frame *) sp;
- addr = sf->gprs[8] & PSW_ADDR_INSN;
- printk("([<%016lx>] %pSR)\n", addr, (void *)addr);
/* Follow the backchain. */
while (1) {
+ if (func(data, sf->gprs[8]))
+ return sp;
low = sp;
- sp = sf->back_chain & PSW_ADDR_INSN;
+ sp = sf->back_chain;
if (!sp)
break;
if (sp <= low || sp > high - sizeof(*sf))
return sp;
sf = (struct stack_frame *) sp;
- addr = sf->gprs[8] & PSW_ADDR_INSN;
- printk(" [<%016lx>] %pSR\n", addr, (void *)addr);
}
/* Zero backchain detected, check for interrupt frame. */
sp = (unsigned long) (sf + 1);
if (sp <= low || sp > high - sizeof(*regs))
return sp;
regs = (struct pt_regs *) sp;
- addr = regs->psw.addr & PSW_ADDR_INSN;
- printk(" [<%016lx>] %pSR\n", addr, (void *)addr);
+ if (!user_mode(regs)) {
+ if (func(data, regs->psw.addr))
+ return sp;
+ }
low = sp;
sp = regs->gprs[15];
}
}
-static void show_trace(struct task_struct *task, unsigned long *stack)
+void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task,
+ unsigned long sp)
{
- const unsigned long frame_size =
- STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
- register unsigned long __r15 asm ("15");
- unsigned long sp;
+ unsigned long frame_size;
- sp = (unsigned long) stack;
- if (!sp)
- sp = task ? task->thread.ksp : __r15;
- printk("Call Trace:\n");
+ frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
#ifdef CONFIG_CHECK_STACK
- sp = __show_trace(sp,
+ sp = __dump_trace(func, data, sp,
S390_lowcore.panic_stack + frame_size - 4096,
S390_lowcore.panic_stack + frame_size);
#endif
- sp = __show_trace(sp,
+ sp = __dump_trace(func, data, sp,
S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
S390_lowcore.async_stack + frame_size);
if (task)
- __show_trace(sp, (unsigned long) task_stack_page(task),
- (unsigned long) task_stack_page(task) + THREAD_SIZE);
+ __dump_trace(func, data, sp,
+ (unsigned long)task_stack_page(task),
+ (unsigned long)task_stack_page(task) + THREAD_SIZE);
else
- __show_trace(sp, S390_lowcore.thread_info,
+ __dump_trace(func, data, sp,
+ S390_lowcore.thread_info,
S390_lowcore.thread_info + THREAD_SIZE);
+}
+EXPORT_SYMBOL_GPL(dump_trace);
+
+static int show_address(void *data, unsigned long address)
+{
+ printk("([<%016lx>] %pSR)\n", address, (void *)address);
+ return 0;
+}
+
+static void show_trace(struct task_struct *task, unsigned long sp)
+{
+ if (!sp)
+ sp = task ? task->thread.ksp : current_stack_pointer();
+ printk("Call Trace:\n");
+ dump_trace(show_address, NULL, task, sp);
if (!task)
task = current;
debug_show_held_locks(task);
@@ -96,15 +108,16 @@ static void show_trace(struct task_struct *task, unsigned long *stack)
void show_stack(struct task_struct *task, unsigned long *sp)
{
- register unsigned long *__r15 asm ("15");
unsigned long *stack;
int i;
- if (!sp)
- stack = task ? (unsigned long *) task->thread.ksp : __r15;
- else
- stack = sp;
-
+ stack = sp;
+ if (!stack) {
+ if (!task)
+ stack = (unsigned long *)current_stack_pointer();
+ else
+ stack = (unsigned long *)task->thread.ksp;
+ }
for (i = 0; i < 20; i++) {
if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
break;
@@ -113,7 +126,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
printk("%016lx ", *stack++);
}
printk("\n");
- show_trace(task, sp);
+ show_trace(task, (unsigned long)sp);
}
static void show_last_breaking_event(struct pt_regs *regs)
@@ -122,13 +135,9 @@ static void show_last_breaking_event(struct pt_regs *regs)
printk(" [<%016lx>] %pSR\n", regs->args[0], (void *)regs->args[0]);
}
-static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
-{
- return (regs->psw.mask & bits) / ((~bits + 1) & bits);
-}
-
void show_registers(struct pt_regs *regs)
{
+ struct psw_bits *psw = &psw_bits(regs->psw);
char *mode;
mode = user_mode(regs) ? "User" : "Krnl";
@@ -137,13 +146,9 @@ void show_registers(struct pt_regs *regs)
printk(" (%pSR)", (void *)regs->psw.addr);
printk("\n");
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
- "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER),
- mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO),
- mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY),
- mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT),
- mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC),
- mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM));
- printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA));
+ "P:%x AS:%x CC:%x PM:%x", psw->r, psw->t, psw->i, psw->e,
+ psw->key, psw->m, psw->w, psw->p, psw->as, psw->cc, psw->pm);
+ printk(" RI:%x EA:%x", psw->ri, psw->eaba);
printk("\n%s GPRS: %016lx %016lx %016lx %016lx\n", mode,
regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
printk(" %016lx %016lx %016lx %016lx\n",
@@ -161,7 +166,7 @@ void show_regs(struct pt_regs *regs)
show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */
if (!user_mode(regs))
- show_trace(NULL, (unsigned long *) regs->gprs[15]);
+ show_trace(NULL, regs->gprs[15]);
show_last_breaking_event(regs);
}
@@ -185,9 +190,8 @@ void die(struct pt_regs *regs, const char *str)
#ifdef CONFIG_SMP
printk("SMP ");
#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk("DEBUG_PAGEALLOC");
-#endif
+ if (debug_pagealloc_enabled())
+ printk("DEBUG_PAGEALLOC");
printk("\n");
notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
print_modules();
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 549a73a..a0684de 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -17,6 +17,7 @@
#include <linux/pfn.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
+#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/ipl.h>
#include <asm/lowcore.h>
@@ -251,14 +252,14 @@ static void early_pgm_check_handler(void)
unsigned long addr;
addr = S390_lowcore.program_old_psw.addr;
- fixup = search_exception_tables(addr & PSW_ADDR_INSN);
+ fixup = search_exception_tables(addr);
if (!fixup)
disabled_wait(0);
/* Disable low address protection before storing into lowcore. */
__ctl_store(cr0, 0, 0);
cr0_new = cr0 & ~(1UL << 28);
__ctl_load(cr0_new, 0, 0);
- S390_lowcore.program_old_psw.addr = extable_fixup(fixup)|PSW_ADDR_AMODE;
+ S390_lowcore.program_old_psw.addr = extable_fixup(fixup);
__ctl_load(cr0, 0, 0);
}
@@ -267,9 +268,9 @@ static noinline __init void setup_lowcore_early(void)
psw_t psw;
psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA;
- psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler;
+ psw.addr = (unsigned long) s390_base_ext_handler;
S390_lowcore.external_new_psw = psw;
- psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
+ psw.addr = (unsigned long) s390_base_pgm_handler;
S390_lowcore.program_new_psw = psw;
s390_base_pgm_handler_fn = early_pgm_check_handler;
}
@@ -286,6 +287,7 @@ static __init void detect_diag9c(void)
int rc;
cpu_address = stap();
+ diag_stat_inc(DIAG_STAT_X09C);
asm volatile(
" diag %2,0,0x9c\n"
"0: la %0,0\n"
@@ -300,6 +302,7 @@ static __init void detect_diag44(void)
{
int rc;
+ diag_stat_inc(DIAG_STAT_X044);
asm volatile(
" diag 0,0,0x44\n"
"0: la %0,0\n"
@@ -326,9 +329,27 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
if (test_facility(51))
S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC;
- if (test_facility(129))
+ if (test_facility(129)) {
S390_lowcore.machine_flags |= MACHINE_FLAG_VX;
+ __ctl_set_bit(0, 17);
+ }
+}
+
+static inline void save_vector_registers(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+ if (test_facility(129))
+ save_vx_regs(boot_cpu_vector_save_area);
+#endif
+}
+
+static int __init disable_vector_extension(char *str)
+{
+ S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX;
+ __ctl_clear_bit(0, 17);
+ return 1;
}
+early_param("novx", disable_vector_extension);
static int __init cad_setup(char *str)
{
@@ -427,7 +448,6 @@ void __init startup_init(void)
rescue_initrd();
clear_bss_section();
init_kernel_storage_key();
- lockdep_init();
lockdep_off();
setup_lowcore_early();
setup_facility_list();
@@ -438,6 +458,7 @@ void __init startup_init(void)
detect_diag9c();
detect_diag44();
detect_machine_facilities();
+ save_vector_registers();
setup_topology();
sclp_early_detect();
lockdep_on();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 582fe44..2d47f9c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -20,8 +20,9 @@
#include <asm/page.h>
#include <asm/sigp.h>
#include <asm/irq.h>
-#include <asm/fpu-internal.h>
#include <asm/vx-insn.h>
+#include <asm/setup.h>
+#include <asm/nmi.h>
__PT_R0 = __PT_GPRS
__PT_R1 = __PT_GPRS + 8
@@ -139,6 +140,28 @@ _PIF_WORK = (_PIF_PER_TRAP)
#endif
.endm
+ /*
+ * The TSTMSK macro generates a test-under-mask instruction by
+ * calculating the memory offset for the specified mask value.
+ * Mask value can be any constant. The macro shifts the mask
+ * value to calculate the memory offset for the test-under-mask
+ * instruction.
+ */
+ .macro TSTMSK addr, mask, size=8, bytepos=0
+ .if (\bytepos < \size) && (\mask >> 8)
+ .if (\mask & 0xff)
+ .error "Mask exceeds byte boundary"
+ .endif
+ TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
+ .exitm
+ .endif
+ .ifeq \mask
+ .error "Mask must not be zero"
+ .endif
+ off = \size - \bytepos - 1
+ tm off+\addr, \mask
+ .endm
+
.section .kprobes.text, "ax"
/*
@@ -163,9 +186,13 @@ ENTRY(__switch_to)
stg %r5,__LC_THREAD_INFO # store thread info of next
stg %r15,__LC_KERNEL_STACK # store end of kernel stack
lg %r15,__THREAD_ksp(%r1) # load kernel stack of next
+ /* c4 is used in guest detection: arch/s390/kernel/perf_cpum_sf.c */
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
- mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
+ mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
+ TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
+ bzr %r14
+ .insn s,0xb2800000,__LC_LPP # set program parameter
br %r14
.L__critical_start:
@@ -180,8 +207,8 @@ ENTRY(sie64a)
stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
stg %r2,__SF_EMPTY(%r15) # save control block pointer
stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
- xc __SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason
- tm __LC_CPU_FLAGS+7,_CIF_FPU # load guest fp/vx registers ?
+ xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
jno .Lsie_load_guest_gprs
brasl %r14,load_fpu_regs # load guest fp/vx regs
.Lsie_load_guest_gprs:
@@ -195,16 +222,9 @@ ENTRY(sie64a)
oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now
tm __SIE_PROG20+3(%r14),3 # last exit...
jnz .Lsie_skip
- tm __LC_CPU_FLAGS+7,_CIF_FPU
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsie_skip # exit if fp/vx regs changed
- tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP
- jz .Lsie_enter
- .insn s,0xb2800000,__LC_CURRENT_PID # set guest id to pid
-.Lsie_enter:
sie 0(%r14)
- tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP
- jz .Lsie_skip
- .insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
.Lsie_skip:
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -221,11 +241,11 @@ sie_exit:
lg %r14,__SF_EMPTY+8(%r15) # load guest register save area
stmg %r0,%r13,0(%r14) # save guest gprs 0-13
lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
- lg %r2,__SF_EMPTY+24(%r15) # return exit reason code
+ lg %r2,__SF_EMPTY+16(%r15) # return exit reason code
br %r14
.Lsie_fault:
lghi %r14,-EFAULT
- stg %r14,__SF_EMPTY+24(%r15) # set exit reason code
+ stg %r14,__SF_EMPTY+16(%r15) # set exit reason code
j sie_exit
EX_TABLE(.Lrewind_pad,.Lsie_fault)
@@ -271,7 +291,7 @@ ENTRY(system_call)
stg %r2,__PT_ORIG_GPR2(%r11)
stg %r7,STACK_FRAME_OVERHEAD(%r15)
lgf %r9,0(%r8,%r10) # get system call add.
- tm __TI_flags+7(%r12),_TIF_TRACE
+ TSTMSK __TI_flags(%r12),_TIF_TRACE
jnz .Lsysc_tracesys
basr %r14,%r9 # call sys_xxxx
stg %r2,__PT_R2(%r11) # store return value
@@ -279,11 +299,11 @@ ENTRY(system_call)
.Lsysc_return:
LOCKDEP_SYS_EXIT
.Lsysc_tif:
- tm __PT_FLAGS+7(%r11),_PIF_WORK
+ TSTMSK __PT_FLAGS(%r11),_PIF_WORK
jnz .Lsysc_work
- tm __TI_flags+7(%r12),_TIF_WORK
+ TSTMSK __TI_flags(%r12),_TIF_WORK
jnz .Lsysc_work # check for work
- tm __LC_CPU_FLAGS+7,_CIF_WORK
+ TSTMSK __LC_CPU_FLAGS,_CIF_WORK
jnz .Lsysc_work
.Lsysc_restore:
lg %r14,__LC_VDSO_PER_CPU
@@ -299,23 +319,23 @@ ENTRY(system_call)
# One of the work bits is on. Find out which one.
#
.Lsysc_work:
- tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
+ TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jo .Lsysc_mcck_pending
- tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
+ TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jo .Lsysc_reschedule
#ifdef CONFIG_UPROBES
- tm __TI_flags+7(%r12),_TIF_UPROBE
+ TSTMSK __TI_flags(%r12),_TIF_UPROBE
jo .Lsysc_uprobe_notify
#endif
- tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP
+ TSTMSK __PT_FLAGS(%r11),_PIF_PER_TRAP
jo .Lsysc_singlestep
- tm __TI_flags+7(%r12),_TIF_SIGPENDING
+ TSTMSK __TI_flags(%r12),_TIF_SIGPENDING
jo .Lsysc_sigpending
- tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
+ TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lsysc_notify_resume
- tm __LC_CPU_FLAGS+7,_CIF_FPU
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsysc_vxrs
- tm __LC_CPU_FLAGS+7,_CIF_ASCE
+ TSTMSK __LC_CPU_FLAGS,_CIF_ASCE
jo .Lsysc_uaccess
j .Lsysc_return # beware of critical section cleanup
@@ -354,7 +374,7 @@ ENTRY(system_call)
.Lsysc_sigpending:
lgr %r2,%r11 # pass pointer to pt_regs
brasl %r14,do_signal
- tm __PT_FLAGS+7(%r11),_PIF_SYSCALL
+ TSTMSK __PT_FLAGS(%r11),_PIF_SYSCALL
jno .Lsysc_return
lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
lg %r10,__TI_sysc_table(%r12) # address of system call table
@@ -414,7 +434,7 @@ ENTRY(system_call)
basr %r14,%r9 # call sys_xxx
stg %r2,__PT_R2(%r11) # store return value
.Lsysc_tracenogo:
- tm __TI_flags+7(%r12),_TIF_TRACE
+ TSTMSK __TI_flags(%r12),_TIF_TRACE
jz .Lsysc_return
lgr %r2,%r11 # pass pointer to pt_regs
larl %r14,.Lsysc_return
@@ -544,6 +564,8 @@ ENTRY(io_int_handler)
stmg %r8,%r9,__PT_PSW(%r11)
mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
+ TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ
+ jo .Lio_restore
TRACE_IRQS_OFF
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
.Lio_loop:
@@ -554,7 +576,7 @@ ENTRY(io_int_handler)
lghi %r3,THIN_INTERRUPT
.Lio_call:
brasl %r14,do_IRQ
- tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR
+ TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
jz .Lio_return
tpi 0
jz .Lio_return
@@ -564,9 +586,9 @@ ENTRY(io_int_handler)
LOCKDEP_SYS_EXIT
TRACE_IRQS_ON
.Lio_tif:
- tm __TI_flags+7(%r12),_TIF_WORK
+ TSTMSK __TI_flags(%r12),_TIF_WORK
jnz .Lio_work # there is work to do (signals etc.)
- tm __LC_CPU_FLAGS+7,_CIF_WORK
+ TSTMSK __LC_CPU_FLAGS,_CIF_WORK
jnz .Lio_work
.Lio_restore:
lg %r14,__LC_VDSO_PER_CPU
@@ -594,7 +616,7 @@ ENTRY(io_int_handler)
# check for preemptive scheduling
icm %r0,15,__TI_precount(%r12)
jnz .Lio_restore # preemption is disabled
- tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
+ TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jno .Lio_restore
# switch to kernel stack
lg %r1,__PT_R15(%r11)
@@ -626,17 +648,17 @@ ENTRY(io_int_handler)
# One of the work bits is on. Find out which one.
#
.Lio_work_tif:
- tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
+ TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jo .Lio_mcck_pending
- tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
+ TSTMSK __TI_flags(%r12),_TIF_NEED_RESCHED
jo .Lio_reschedule
- tm __TI_flags+7(%r12),_TIF_SIGPENDING
+ TSTMSK __TI_flags(%r12),_TIF_SIGPENDING
jo .Lio_sigpending
- tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
+ TSTMSK __TI_flags(%r12),_TIF_NOTIFY_RESUME
jo .Lio_notify_resume
- tm __LC_CPU_FLAGS+7,_CIF_FPU
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lio_vxrs
- tm __LC_CPU_FLAGS+7,_CIF_ASCE
+ TSTMSK __LC_CPU_FLAGS,_CIF_ASCE
jo .Lio_uaccess
j .Lio_return # beware of critical section cleanup
@@ -719,6 +741,8 @@ ENTRY(ext_int_handler)
mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
mvc __PT_INT_PARM_LONG(8,%r11),0(%r1)
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
+ TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ
+ jo .Lio_restore
TRACE_IRQS_OFF
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
lgr %r2,%r11 # pass pointer to pt_regs
@@ -741,6 +765,7 @@ ENTRY(psw_idle)
.insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
.Lpsw_idle_stcctm:
#endif
+ oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
STCK __CLOCK_IDLE_ENTER(%r2)
stpt __TIMER_IDLE_ENTER(%r2)
.Lpsw_idle_lpsw:
@@ -748,27 +773,22 @@ ENTRY(psw_idle)
br %r14
.Lpsw_idle_end:
-/* Store floating-point controls and floating-point or vector extension
- * registers instead. A critical section cleanup assures that the registers
- * are stored even if interrupted for some other work. The register %r2
- * designates a struct fpu to store register contents. If the specified
- * structure does not contain a register save area, the register store is
- * omitted (see also comments in arch_dup_task_struct()).
- *
- * The CIF_FPU flag is set in any case. The CIF_FPU triggers a lazy restore
- * of the register contents at system call or io return.
+/*
+ * Store floating-point controls and floating-point or vector register
+ * depending whether the vector facility is available. A critical section
+ * cleanup assures that the registers are stored even if interrupted for
+ * some other work. The CIF_FPU flag is set to trigger a lazy restore
+ * of the register contents at return from io or a system call.
*/
ENTRY(save_fpu_regs)
lg %r2,__LC_CURRENT
aghi %r2,__TASK_thread
- tm __LC_CPU_FLAGS+7,_CIF_FPU
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bor %r14
stfpc __THREAD_FPU_fpc(%r2)
.Lsave_fpu_regs_fpc_end:
lg %r3,__THREAD_FPU_regs(%r2)
- ltgr %r3,%r3
- jz .Lsave_fpu_regs_done # no save area -> set CIF_FPU
- tm __THREAD_FPU_flags+3(%r2),FPU_USE_VX
+ TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
jz .Lsave_fpu_regs_fp # no -> store FP regs
.Lsave_fpu_regs_vx_low:
VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3)
@@ -797,41 +817,30 @@ ENTRY(save_fpu_regs)
br %r14
.Lsave_fpu_regs_end:
-/* Load floating-point controls and floating-point or vector extension
- * registers. A critical section cleanup assures that the register contents
- * are loaded even if interrupted for some other work. Depending on the saved
- * FP/VX state, the vector-enablement control, CR0.46, is either set or cleared.
+/*
+ * Load floating-point controls and floating-point or vector registers.
+ * A critical section cleanup assures that the register contents are
+ * loaded even if interrupted for some other work.
*
* There are special calling conventions to fit into sysc and io return work:
* %r15: <kernel stack>
* The function requires:
- * %r4 and __SF_EMPTY+32(%r15)
+ * %r4
*/
load_fpu_regs:
lg %r4,__LC_CURRENT
aghi %r4,__TASK_thread
- tm __LC_CPU_FLAGS+7,_CIF_FPU
+ TSTMSK __LC_CPU_FLAGS,_CIF_FPU
bnor %r14
lfpc __THREAD_FPU_fpc(%r4)
- stctg %c0,%c0,__SF_EMPTY+32(%r15) # store CR0
- tm __THREAD_FPU_flags+3(%r4),FPU_USE_VX # VX-enabled task ?
+ TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area
- jz .Lload_fpu_regs_fp_ctl # -> no VX, load FP regs
-.Lload_fpu_regs_vx_ctl:
- tm __SF_EMPTY+32+5(%r15),2 # test VX control
- jo .Lload_fpu_regs_vx
- oi __SF_EMPTY+32+5(%r15),2 # set VX control
- lctlg %c0,%c0,__SF_EMPTY+32(%r15)
+ jz .Lload_fpu_regs_fp # -> no VX, load FP regs
.Lload_fpu_regs_vx:
VLM %v0,%v15,0,%r4
.Lload_fpu_regs_vx_high:
VLM %v16,%v31,256,%r4
j .Lload_fpu_regs_done
-.Lload_fpu_regs_fp_ctl:
- tm __SF_EMPTY+32+5(%r15),2 # test VX control
- jz .Lload_fpu_regs_fp
- ni __SF_EMPTY+32+5(%r15),253 # clear VX control
- lctlg %c0,%c0,__SF_EMPTY+32(%r15)
.Lload_fpu_regs_fp:
ld 0,0(%r4)
ld 1,8(%r4)
@@ -854,16 +863,6 @@ load_fpu_regs:
br %r14
.Lload_fpu_regs_end:
-/* Test and set the vector enablement control in CR0.46 */
-ENTRY(__ctl_set_vx)
- stctg %c0,%c0,__SF_EMPTY(%r15)
- tm __SF_EMPTY+5(%r15),2
- bor %r14
- oi __SF_EMPTY+5(%r15),2
- lctlg %c0,%c0,__SF_EMPTY(%r15)
- br %r14
-.L__ctl_set_vx_end:
-
.L__critical_end:
/*
@@ -878,11 +877,11 @@ ENTRY(mcck_int_handler)
lg %r12,__LC_THREAD_INFO
larl %r13,cleanup_critical
lmg %r8,%r9,__LC_MCK_OLD_PSW
- tm __LC_MCCK_CODE,0x80 # system damage?
+ TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
jo .Lmcck_panic # yes -> rest of mcck code invalid
lghi %r14,__LC_CPU_TIMER_SAVE_AREA
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
- tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
+ TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
jo 3f
la %r14,__LC_SYNC_ENTER_TIMER
clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
@@ -896,7 +895,7 @@ ENTRY(mcck_int_handler)
la %r14,__LC_LAST_UPDATE_TIMER
2: spt 0(%r14)
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
-3: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
+3: TSTMSK __LC_MCCK_CODE,(MCCK_CODE_PSW_MWP_VALID|MCCK_CODE_PSW_IA_VALID)
jno .Lmcck_panic # no -> skip cleanup critical
SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
.Lmcck_skip:
@@ -916,7 +915,7 @@ ENTRY(mcck_int_handler)
la %r11,STACK_FRAME_OVERHEAD(%r1)
lgr %r15,%r1
ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
- tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
+ TSTMSK __LC_CPU_FLAGS,_CIF_MCCK_PENDING
jno .Lmcck_return
TRACE_IRQS_OFF
brasl %r14,s390_handle_mcck
@@ -941,7 +940,10 @@ ENTRY(mcck_int_handler)
# PSW restart interrupt handler
#
ENTRY(restart_int_handler)
- stg %r15,__LC_SAVE_AREA_RESTART
+ TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
+ jz 0f
+ .insn s,0xb2800000,__LC_LPP
+0: stg %r15,__LC_SAVE_AREA_RESTART
lg %r15,__LC_RESTART_STACK
aghi %r15,-__PT_SIZE # create pt_regs on stack
xc 0(__PT_SIZE,%r15),0(%r15)
@@ -1019,10 +1021,6 @@ cleanup_critical:
jl 0f
clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end
jl .Lcleanup_load_fpu_regs
- clg %r9,BASED(.Lcleanup_table+112) # __ctl_set_vx
- jl 0f
- clg %r9,BASED(.Lcleanup_table+120) # .L__ctl_set_vx_end
- jl .Lcleanup___ctl_set_vx
0: br %r14
.align 8
@@ -1041,8 +1039,6 @@ cleanup_critical:
.quad .Lsave_fpu_regs_end
.quad load_fpu_regs
.quad .Lload_fpu_regs_end
- .quad __ctl_set_vx
- .quad .L__ctl_set_vx_end
#if IS_ENABLED(CONFIG_KVM)
.Lcleanup_table_sie:
@@ -1051,10 +1047,7 @@ cleanup_critical:
.Lcleanup_sie:
lg %r9,__SF_EMPTY(%r15) # get control block pointer
- tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP
- jz 0f
- .insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
-0: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
+ ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
larl %r9,sie_exit # skip forward to sie_exit
br %r14
@@ -1155,6 +1148,7 @@ cleanup_critical:
.quad .Lio_done - 4
.Lcleanup_idle:
+ ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
# copy interrupt clock & cpu timer
mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
@@ -1206,144 +1200,11 @@ cleanup_critical:
.quad .Lpsw_idle_lpsw
.Lcleanup_save_fpu_regs:
- tm __LC_CPU_FLAGS+7,_CIF_FPU
- bor %r14
- clg %r9,BASED(.Lcleanup_save_fpu_regs_done)
- jhe 5f
- clg %r9,BASED(.Lcleanup_save_fpu_regs_fp)
- jhe 4f
- clg %r9,BASED(.Lcleanup_save_fpu_regs_vx_high)
- jhe 3f
- clg %r9,BASED(.Lcleanup_save_fpu_regs_vx_low)
- jhe 2f
- clg %r9,BASED(.Lcleanup_save_fpu_fpc_end)
- jhe 1f
- lg %r2,__LC_CURRENT
- aghi %r2,__TASK_thread
-0: # Store floating-point controls
- stfpc __THREAD_FPU_fpc(%r2)
-1: # Load register save area and check if VX is active
- lg %r3,__THREAD_FPU_regs(%r2)
- ltgr %r3,%r3
- jz 5f # no save area -> set CIF_FPU
- tm __THREAD_FPU_flags+3(%r2),FPU_USE_VX
- jz 4f # no VX -> store FP regs
-2: # Store vector registers (V0-V15)
- VSTM %v0,%v15,0,%r3 # vstm 0,15,0(3)
-3: # Store vector registers (V16-V31)
- VSTM %v16,%v31,256,%r3 # vstm 16,31,256(3)
- j 5f # -> done, set CIF_FPU flag
-4: # Store floating-point registers
- std 0,0(%r3)
- std 1,8(%r3)
- std 2,16(%r3)
- std 3,24(%r3)
- std 4,32(%r3)
- std 5,40(%r3)
- std 6,48(%r3)
- std 7,56(%r3)
- std 8,64(%r3)
- std 9,72(%r3)
- std 10,80(%r3)
- std 11,88(%r3)
- std 12,96(%r3)
- std 13,104(%r3)
- std 14,112(%r3)
- std 15,120(%r3)
-5: # Set CIF_FPU flag
- oi __LC_CPU_FLAGS+7,_CIF_FPU
- lg %r9,48(%r11) # return from save_fpu_regs
+ larl %r9,save_fpu_regs
br %r14
-.Lcleanup_save_fpu_fpc_end:
- .quad .Lsave_fpu_regs_fpc_end
-.Lcleanup_save_fpu_regs_vx_low:
- .quad .Lsave_fpu_regs_vx_low
-.Lcleanup_save_fpu_regs_vx_high:
- .quad .Lsave_fpu_regs_vx_high
-.Lcleanup_save_fpu_regs_fp:
- .quad .Lsave_fpu_regs_fp
-.Lcleanup_save_fpu_regs_done:
- .quad .Lsave_fpu_regs_done
.Lcleanup_load_fpu_regs:
- tm __LC_CPU_FLAGS+7,_CIF_FPU
- bnor %r14
- clg %r9,BASED(.Lcleanup_load_fpu_regs_done)
- jhe 1f
- clg %r9,BASED(.Lcleanup_load_fpu_regs_fp)
- jhe 2f
- clg %r9,BASED(.Lcleanup_load_fpu_regs_fp_ctl)
- jhe 3f
- clg %r9,BASED(.Lcleanup_load_fpu_regs_vx_high)
- jhe 4f
- clg %r9,BASED(.Lcleanup_load_fpu_regs_vx)
- jhe 5f
- clg %r9,BASED(.Lcleanup_load_fpu_regs_vx_ctl)
- jhe 6f
- lg %r4,__LC_CURRENT
- aghi %r4,__TASK_thread
- lfpc __THREAD_FPU_fpc(%r4)
- tm __THREAD_FPU_flags+3(%r4),FPU_USE_VX # VX-enabled task ?
- lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area
- jz 3f # -> no VX, load FP regs
-6: # Set VX-enablement control
- stctg %c0,%c0,__SF_EMPTY+32(%r15) # store CR0
- tm __SF_EMPTY+32+5(%r15),2 # test VX control
- jo 5f
- oi __SF_EMPTY+32+5(%r15),2 # set VX control
- lctlg %c0,%c0,__SF_EMPTY+32(%r15)
-5: # Load V0 ..V15 registers
- VLM %v0,%v15,0,%r4
-4: # Load V16..V31 registers
- VLM %v16,%v31,256,%r4
- j 1f
-3: # Clear VX-enablement control for FP
- stctg %c0,%c0,__SF_EMPTY+32(%r15) # store CR0
- tm __SF_EMPTY+32+5(%r15),2 # test VX control
- jz 2f
- ni __SF_EMPTY+32+5(%r15),253 # clear VX control
- lctlg %c0,%c0,__SF_EMPTY+32(%r15)
-2: # Load floating-point registers
- ld 0,0(%r4)
- ld 1,8(%r4)
- ld 2,16(%r4)
- ld 3,24(%r4)
- ld 4,32(%r4)
- ld 5,40(%r4)
- ld 6,48(%r4)
- ld 7,56(%r4)
- ld 8,64(%r4)
- ld 9,72(%r4)
- ld 10,80(%r4)
- ld 11,88(%r4)
- ld 12,96(%r4)
- ld 13,104(%r4)
- ld 14,112(%r4)
- ld 15,120(%r4)
-1: # Clear CIF_FPU bit
- ni __LC_CPU_FLAGS+7,255-_CIF_FPU
- lg %r9,48(%r11) # return from load_fpu_regs
- br %r14
-.Lcleanup_load_fpu_regs_vx_ctl:
- .quad .Lload_fpu_regs_vx_ctl
-.Lcleanup_load_fpu_regs_vx:
- .quad .Lload_fpu_regs_vx
-.Lcleanup_load_fpu_regs_vx_high:
- .quad .Lload_fpu_regs_vx_high
-.Lcleanup_load_fpu_regs_fp_ctl:
- .quad .Lload_fpu_regs_fp_ctl
-.Lcleanup_load_fpu_regs_fp:
- .quad .Lload_fpu_regs_fp
-.Lcleanup_load_fpu_regs_done:
- .quad .Lload_fpu_regs_done
-
-.Lcleanup___ctl_set_vx:
- stctg %c0,%c0,__SF_EMPTY(%r15)
- tm __SF_EMPTY+5(%r15),2
- bor %r14
- oi __SF_EMPTY+5(%r15),2
- lctlg %c0,%c0,__SF_EMPTY(%r15)
- lg %r9,48(%r11) # return from __ctl_set_vx
+ larl %r9,load_fpu_regs
br %r14
/*
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 834df04..b7019ab 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -16,13 +16,10 @@ void io_int_handler(void);
void mcck_int_handler(void);
void restart_int_handler(void);
void restart_call_handler(void);
-void psw_idle(struct s390_idle_data *, unsigned long);
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
-int alloc_vector_registers(struct task_struct *tsk);
-
void do_protection_exception(struct pt_regs *regs);
void do_dat_exception(struct pt_regs *regs);
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index e0eaf11..0f7bfeb 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -203,7 +203,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
goto out;
if (unlikely(atomic_read(&current->tracing_graph_pause)))
goto out;
- ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE;
+ ip -= MCOUNT_INSN_SIZE;
trace.func = ip;
trace.depth = current->curr_ret_stack + 1;
/* Only trace if the calling function expects to. */
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 1255c6c..fcaefb0 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -25,7 +25,9 @@
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
+#include <asm/facility.h>
#include <asm/page.h>
+#include <asm/ptrace.h>
#define ARCH_OFFSET 4
@@ -59,19 +61,6 @@ __HEAD
.long 0x020006e0,0x20000050
.org 0x200
-#
-# subroutine to set architecture mode
-#
-.Lsetmode:
- mvi __LC_AR_MODE_ID,1 # set esame flag
- slr %r0,%r0 # set cpuid to zero
- lhi %r1,2 # mode 2 = esame (dump)
- sigp %r1,%r0,0x12 # switch to esame mode
- bras %r13,0f
- .fill 16,4,0x0
-0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
- sam31 # switch to 31 bit addressing mode
- br %r14
#
# subroutine to wait for end I/O
@@ -159,7 +148,14 @@ __HEAD
.long 0x02200050,0x00000000
iplstart:
- bas %r14,.Lsetmode # Immediately switch to 64 bit mode
+ mvi __LC_AR_MODE_ID,1 # set esame flag
+ slr %r0,%r0 # set cpuid to zero
+ lhi %r1,2 # mode 2 = esame (dump)
+ sigp %r1,%r0,0x12 # switch to esame mode
+ bras %r13,0f
+ .fill 16,4,0x0
+0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
+ sam31 # switch to 31 bit addressing mode
lh %r1,0xb8 # test if subchannel number
bct %r1,.Lnoload # is valid
l %r1,0xb8 # load ipl subchannel number
@@ -269,71 +265,6 @@ iplstart:
.Lcpuid:.fill 8,1,0
#
-# SALIPL loader support. Based on a patch by Rob van der Heij.
-# This entry point is called directly from the SALIPL loader and
-# doesn't need a builtin ipl record.
-#
- .org 0x800
-ENTRY(start)
- stm %r0,%r15,0x07b0 # store registers
- bas %r14,.Lsetmode # Immediately switch to 64 bit mode
- basr %r12,%r0
-.base:
- l %r11,.parm
- l %r8,.cmd # pointer to command buffer
-
- ltr %r9,%r9 # do we have SALIPL parameters?
- bp .sk8x8
-
- mvc 0(64,%r8),0x00b0 # copy saved registers
- xc 64(240-64,%r8),0(%r8) # remainder of buffer
- tr 0(64,%r8),.lowcase
- b .gotr
-.sk8x8:
- mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
-.gotr:
- slr %r0,%r0
- st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
- st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
- j startup # continue with startup
-.cmd: .long COMMAND_LINE # address of command line buffer
-.parm: .long PARMAREA
-.lowcase:
- .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
- .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17
- .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
- .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
- .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
- .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37
- .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
- .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47
- .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
- .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57
- .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
- .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67
- .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
- .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77
- .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
-
- .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87
- .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
- .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97
- .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
- .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7
- .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
- .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7
- .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
- .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg
- .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi
- .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop
- .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr
- .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx
- .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz
- .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
- .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-
-#
# startup-code at 0x10000, running in absolute addressing mode
# this is called either by the ipl loader or directly by PSW restart
# or linload or SALIPL
@@ -364,38 +295,38 @@ ENTRY(startup_kdump)
bras %r13,0f
.fill 16,4,0x0
0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
- sam31 # switch to 31 bit addressing mode
+ sam64 # switch to 64 bit addressing mode
basr %r13,0 # get base
.LPG0:
xc 0x200(256),0x200 # partially clear lowcore
xc 0x300(256),0x300
xc 0xe00(256),0xe00
+ xc 0xf00(256),0xf00
lctlg %c0,%c15,0x200(%r0) # initialize control registers
stck __LC_LAST_UPDATE_CLOCK
spt 6f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
- xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
- # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
- .insn s,0xb2b10000,0 # store facilities @ __LC_STFL_FAC_LIST
- tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
+ stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST
+ mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
+ tm __LC_STFLE_FAC_LIST,0x01 # stfle available ?
jz 0f
- la %r0,1
- .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended
+ lghi %r0,FACILITIES_ALS_DWORDS-1
+ .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
# verify if all required facilities are supported by the machine
-0: la %r1,__LC_STFL_FAC_LIST
+0: la %r1,__LC_STFLE_FAC_LIST
la %r2,3f+8-.LPG0(%r13)
- l %r3,0(%r2)
-1: l %r0,0(%r1)
- n %r0,4(%r2)
- cl %r0,4(%r2)
+ lhi %r3,FACILITIES_ALS_DWORDS
+1: lg %r0,0(%r1)
+ ng %r0,0(%r2)
+ clg %r0,0(%r2)
jne 2f
- la %r1,4(%r1)
- la %r2,4(%r2)
+ la %r1,8(%r1)
+ la %r2,8(%r2)
ahi %r3,-1
jnz 1b
j 4f
2: l %r15,.Lstack-.LPG0(%r13)
- ahi %r15,-96
+ ahi %r15,-STACK_FRAME_OVERHEAD
la %r2,.Lals_string-.LPG0(%r13)
l %r3,.Lsclp_print-.LPG0(%r13)
basr %r14,%r3
@@ -410,27 +341,12 @@ ENTRY(startup_kdump)
3: .long 0x000a0000,0x8badcccc
# List of facilities that are required. If not all facilities are present
-# the kernel will crash. Format is number of facility words with bits set,
-# followed by the facility words.
+# the kernel will crash.
+
+ .quad FACILITIES_ALS
-#if defined(CONFIG_MARCH_Z13)
- .long 2, 0xc100eff2, 0xf46cc800
-#elif defined(CONFIG_MARCH_ZEC12)
- .long 2, 0xc100eff2, 0xf46cc800
-#elif defined(CONFIG_MARCH_Z196)
- .long 2, 0xc100eff2, 0xf46c0000
-#elif defined(CONFIG_MARCH_Z10)
- .long 2, 0xc100eff2, 0xf0680000
-#elif defined(CONFIG_MARCH_Z9_109)
- .long 1, 0xc100efc2
-#elif defined(CONFIG_MARCH_Z990)
- .long 1, 0xc0002000
-#elif defined(CONFIG_MARCH_Z900)
- .long 1, 0xc0000000
-#endif
4:
- /* Continue with 64bit startup code in head64.S */
- sam64 # switch to 64 bit mode
+ /* Continue with startup code in head64.S */
jg startup_continue
.align 8
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index d7c0050..03c2b46 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -16,7 +16,12 @@
__HEAD
ENTRY(startup_continue)
- larl %r1,sched_clock_base_cc
+ tm __LC_STFLE_FAC_LIST+5,0x80 # LPP available ?
+ jz 0f
+ xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid
+ mvi __LC_LPP,0x80 # and set LPP_MAGIC
+ .insn s,0xb2800000,__LC_LPP # load program parameter
+0: larl %r1,sched_clock_base_cc
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
larl %r13,.LPG1 # get base
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 52fbef9..f20abdb 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -17,6 +17,7 @@
#include <linux/gfp.h>
#include <linux/crash_dump.h>
#include <linux/debug_locks.h>
+#include <asm/diag.h>
#include <asm/ipl.h>
#include <asm/smp.h>
#include <asm/setup.h>
@@ -120,6 +121,7 @@ static char *dump_type_str(enum dump_type type)
* Must be in data section since the bss section
* is not cleared when these are accessed.
*/
+static u8 ipl_ssid __attribute__((__section__(".data"))) = 0;
static u16 ipl_devno __attribute__((__section__(".data"))) = 0;
u32 ipl_flags __attribute__((__section__(".data"))) = 0;
@@ -165,7 +167,7 @@ static struct ipl_parameter_block *dump_block_ccw;
static struct sclp_ipl_info sclp_ipl_info;
-int diag308(unsigned long subcode, void *addr)
+static inline int __diag308(unsigned long subcode, void *addr)
{
register unsigned long _addr asm("0") = (unsigned long) addr;
register unsigned long _rc asm("1") = 0;
@@ -178,6 +180,12 @@ int diag308(unsigned long subcode, void *addr)
: "d" (subcode) : "cc", "memory");
return _rc;
}
+
+int diag308(unsigned long subcode, void *addr)
+{
+ diag_stat_inc(DIAG_STAT_X308);
+ return __diag308(subcode, addr);
+}
EXPORT_SYMBOL_GPL(diag308);
/* SYSFS */
@@ -190,6 +198,33 @@ static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
return snprintf(page, PAGE_SIZE, _format, ##args); \
}
+#define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk) \
+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ const char *buf, size_t len) \
+{ \
+ unsigned long long ssid, devno; \
+ \
+ if (sscanf(buf, "0.%llx.%llx\n", &ssid, &devno) != 2) \
+ return -EINVAL; \
+ \
+ if (ssid > __MAX_SSID || devno > __MAX_SUBCHANNEL) \
+ return -EINVAL; \
+ \
+ _ipl_blk.ssid = ssid; \
+ _ipl_blk.devno = devno; \
+ return len; \
+}
+
+#define DEFINE_IPL_CCW_ATTR_RW(_prefix, _name, _ipl_blk) \
+IPL_ATTR_SHOW_FN(_prefix, _name, "0.%x.%04x\n", \
+ _ipl_blk.ssid, _ipl_blk.devno); \
+IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk); \
+static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
+ __ATTR(_name, (S_IRUGO | S_IWUSR), \
+ sys_##_prefix##_##_name##_show, \
+ sys_##_prefix##_##_name##_store) \
+
#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value) \
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
@@ -388,7 +423,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
switch (ipl_info.type) {
case IPL_TYPE_CCW:
- return sprintf(page, "0.0.%04x\n", ipl_devno);
+ return sprintf(page, "0.%x.%04x\n", ipl_ssid, ipl_devno);
case IPL_TYPE_FCP:
case IPL_TYPE_FCP_DUMP:
return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
@@ -680,21 +715,14 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
+ size_t scpdata_len = count;
size_t padding;
- size_t scpdata_len;
-
- if (off < 0)
- return -EINVAL;
- if (off >= DIAG308_SCPDATA_SIZE)
- return -ENOSPC;
- if (count > DIAG308_SCPDATA_SIZE - off)
- count = DIAG308_SCPDATA_SIZE - off;
-
- memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count);
- scpdata_len = off + count;
+ if (off)
+ return -EINVAL;
+ memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf, count);
if (scpdata_len % 8) {
padding = 8 - (scpdata_len % 8);
memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
@@ -710,7 +738,7 @@ static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
}
static struct bin_attribute sys_reipl_fcp_scp_data_attr =
__BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read,
- reipl_fcp_scpdata_write, PAGE_SIZE);
+ reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);
static struct bin_attribute *reipl_fcp_bin_attrs[] = {
&sys_reipl_fcp_scp_data_attr,
@@ -807,9 +835,7 @@ static struct attribute_group reipl_fcp_attr_group = {
};
/* CCW reipl device attributes */
-
-DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
- reipl_block_ccw->ipl_info.ccw.devno);
+DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ipl_info.ccw);
/* NSS wrapper */
static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
@@ -1049,8 +1075,8 @@ static void __reipl_run(void *unused)
switch (reipl_method) {
case REIPL_METHOD_CCW_CIO:
+ devid.ssid = reipl_block_ccw->ipl_info.ccw.ssid;
devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
- devid.ssid = 0;
reipl_ccw_dev(&devid);
break;
case REIPL_METHOD_CCW_VM:
@@ -1185,6 +1211,7 @@ static int __init reipl_ccw_init(void)
reipl_block_ccw_init(reipl_block_ccw);
if (ipl_info.type == IPL_TYPE_CCW) {
+ reipl_block_ccw->ipl_info.ccw.ssid = ipl_ssid;
reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
reipl_block_ccw_fill_parms(reipl_block_ccw);
}
@@ -1329,9 +1356,7 @@ static struct attribute_group dump_fcp_attr_group = {
};
/* CCW dump device attributes */
-
-DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
- dump_block_ccw->ipl_info.ccw.devno);
+DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ipl_info.ccw);
static struct attribute *dump_ccw_attrs[] = {
&sys_dump_ccw_device_attr.attr,
@@ -1411,8 +1436,8 @@ static void __dump_run(void *unused)
switch (dump_method) {
case DUMP_METHOD_CCW_CIO:
+ devid.ssid = dump_block_ccw->ipl_info.ccw.ssid;
devid.devno = dump_block_ccw->ipl_info.ccw.devno;
- devid.ssid = 0;
reipl_ccw_dev(&devid);
break;
case DUMP_METHOD_CCW_VM:
@@ -1932,14 +1957,14 @@ void __init setup_ipl(void)
ipl_info.type = get_ipl_type();
switch (ipl_info.type) {
case IPL_TYPE_CCW:
+ ipl_info.data.ccw.dev_id.ssid = ipl_ssid;
ipl_info.data.ccw.dev_id.devno = ipl_devno;
- ipl_info.data.ccw.dev_id.ssid = 0;
break;
case IPL_TYPE_FCP:
case IPL_TYPE_FCP_DUMP:
+ ipl_info.data.fcp.dev_id.ssid = 0;
ipl_info.data.fcp.dev_id.devno =
IPL_PARMBLOCK_START->ipl_info.fcp.devno;
- ipl_info.data.fcp.dev_id.ssid = 0;
ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
break;
@@ -1971,6 +1996,7 @@ void __init ipl_save_parameters(void)
if (cio_get_iplinfo(&iplinfo))
return;
+ ipl_ssid = iplinfo.ssid;
ipl_devno = iplinfo.devno;
ipl_flags |= IPL_DEVNO_VALID;
if (!iplinfo.is_qdio)
@@ -2013,21 +2039,15 @@ static void do_reset_calls(void)
reset->fn();
}
-u32 dump_prefix_page;
-
-void s390_reset_system(void (*fn_pre)(void),
- void (*fn_post)(void *), void *data)
+void s390_reset_system(void)
{
- struct _lowcore *lc;
+ struct lowcore *lc;
- lc = (struct _lowcore *)(unsigned long) store_prefix();
+ lc = (struct lowcore *)(unsigned long) store_prefix();
/* Stack for interrupt/machine check handler */
lc->panic_stack = S390_lowcore.panic_stack;
- /* Save prefix page address for dump case */
- dump_prefix_page = (u32)(unsigned long) lc;
-
/* Disable prefixing */
set_prefix(0);
@@ -2037,12 +2057,12 @@ void s390_reset_system(void (*fn_pre)(void),
/* Set new machine check handler */
S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
S390_lowcore.mcck_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
+ (unsigned long) s390_base_mcck_handler;
/* Set new program check handler */
S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
S390_lowcore.program_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
+ (unsigned long) s390_base_pgm_handler;
/*
* Clear subchannel ID and number to signal new kernel that no CCW or
@@ -2051,14 +2071,5 @@ void s390_reset_system(void (*fn_pre)(void),
S390_lowcore.subchannel_id = 0;
S390_lowcore.subchannel_nr = 0;
- /* Store status at absolute zero */
- store_status();
-
- /* Call function before reset */
- if (fn_pre)
- fn_pre();
do_reset_calls();
- /* Call function after reset */
- if (fn_post)
- fn_post(data);
}
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index e9d9add..c373a1d 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -69,7 +69,6 @@ static const struct irq_class irqclass_sub_desc[] = {
{.irq = IRQEXT_IUC, .name = "IUC", .desc = "[EXT] IUCV"},
{.irq = IRQEXT_CMS, .name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"},
{.irq = IRQEXT_CMC, .name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"},
- {.irq = IRQEXT_CMR, .name = "CMR", .desc = "[EXT] CPU-Measurement: RI"},
{.irq = IRQEXT_FTP, .name = "FTP", .desc = "[EXT] HMC FTP Service"},
{.irq = IRQIO_CIO, .name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"},
{.irq = IRQIO_QAI, .name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt"},
@@ -165,8 +164,7 @@ void do_softirq_own_stack(void)
{
unsigned long old, new;
- /* Get current stack pointer. */
- asm volatile("la %0,0(15)" : "=a" (old));
+ old = current_stack_pointer();
/* Check against async. stack address range. */
new = S390_lowcore.async_stack;
if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) {
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 389db56..250f597 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -226,7 +226,7 @@ static void enable_singlestep(struct kprobe_ctlblk *kcb,
__ctl_load(per_kprobe, 9, 11);
regs->psw.mask |= PSW_MASK_PER;
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
- regs->psw.addr = ip | PSW_ADDR_AMODE;
+ regs->psw.addr = ip;
}
NOKPROBE_SYMBOL(enable_singlestep);
@@ -238,7 +238,7 @@ static void disable_singlestep(struct kprobe_ctlblk *kcb,
__ctl_load(kcb->kprobe_saved_ctl, 9, 11);
regs->psw.mask &= ~PSW_MASK_PER;
regs->psw.mask |= kcb->kprobe_saved_imask;
- regs->psw.addr = ip | PSW_ADDR_AMODE;
+ regs->psw.addr = ip;
}
NOKPROBE_SYMBOL(disable_singlestep);
@@ -310,7 +310,7 @@ static int kprobe_handler(struct pt_regs *regs)
*/
preempt_disable();
kcb = get_kprobe_ctlblk();
- p = get_kprobe((void *)((regs->psw.addr & PSW_ADDR_INSN) - 2));
+ p = get_kprobe((void *)(regs->psw.addr - 2));
if (p) {
if (kprobe_running()) {
@@ -460,7 +460,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}
- regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
+ regs->psw.addr = orig_ret_address;
pop_kprobe(get_kprobe_ctlblk());
kretprobe_hash_unlock(current, &flags);
@@ -490,7 +490,7 @@ NOKPROBE_SYMBOL(trampoline_probe_handler);
static void resume_execution(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- unsigned long ip = regs->psw.addr & PSW_ADDR_INSN;
+ unsigned long ip = regs->psw.addr;
int fixup = probe_get_fixup_type(p->ainsn.insn);
/* Check if the kprobes location is an enabled ftrace caller */
@@ -605,9 +605,9 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
* In case the user-specified fault handler returned
* zero, try to fix up.
*/
- entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
+ entry = search_exception_tables(regs->psw.addr);
if (entry) {
- regs->psw.addr = extable_fixup(entry) | PSW_ADDR_AMODE;
+ regs->psw.addr = extable_fixup(entry);
return 1;
}
@@ -683,7 +683,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
/* setup return addr to the jprobe handler routine */
- regs->psw.addr = (unsigned long) jp->entry | PSW_ADDR_AMODE;
+ regs->psw.addr = (unsigned long) jp->entry;
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
/* r15 is the stack pointer */
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index fb0901e..2f1b721 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -35,46 +35,6 @@ extern const unsigned long long relocate_kernel_len;
#ifdef CONFIG_CRASH_DUMP
/*
- * Create ELF notes for one CPU
- */
-static void add_elf_notes(int cpu)
-{
- struct save_area *sa = (void *) 4608 + store_prefix();
- void *ptr;
-
- memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa));
- ptr = (u64 *) per_cpu_ptr(crash_notes, cpu);
- ptr = fill_cpu_elf_notes(ptr, sa, NULL);
- memset(ptr, 0, sizeof(struct elf_note));
-}
-
-/*
- * Initialize CPU ELF notes
- */
-static void setup_regs(void)
-{
- unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE;
- struct _lowcore *lc;
- int cpu, this_cpu;
-
- /* Get lowcore pointer from store status of this CPU (absolute zero) */
- lc = (struct _lowcore *)(unsigned long)S390_lowcore.prefixreg_save_area;
- this_cpu = smp_find_processor_id(stap());
- add_elf_notes(this_cpu);
- for_each_online_cpu(cpu) {
- if (cpu == this_cpu)
- continue;
- if (smp_store_status(cpu))
- continue;
- add_elf_notes(cpu);
- }
- if (MACHINE_HAS_VX)
- save_vx_regs_safe((void *) lc->vector_save_area_addr);
- /* Copy dump CPU store status info to absolute zero */
- memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area));
-}
-
-/*
* PM notifier callback for kdump
*/
static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action,
@@ -105,14 +65,66 @@ static int __init machine_kdump_pm_init(void)
arch_initcall(machine_kdump_pm_init);
/*
- * Start kdump: We expect here that a store status has been done on our CPU
+ * Reset the system, copy boot CPU registers to absolute zero,
+ * and jump to the kdump image
*/
static void __do_machine_kdump(void *image)
{
- int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
+ int (*start_kdump)(int);
+ unsigned long prefix;
+
+ /* store_status() saved the prefix register to lowcore */
+ prefix = (unsigned long) S390_lowcore.prefixreg_save_area;
+
+ /* Now do the reset */
+ s390_reset_system();
+
+ /*
+ * Copy dump CPU store status info to absolute zero.
+ * This need to be done *after* s390_reset_system set the
+ * prefix register of this CPU to zero
+ */
+ memcpy((void *) __LC_FPREGS_SAVE_AREA,
+ (void *)(prefix + __LC_FPREGS_SAVE_AREA), 512);
__load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
+ start_kdump = (void *)((struct kimage *) image)->start;
start_kdump(1);
+
+ /* Die if start_kdump returns */
+ disabled_wait((unsigned long) __builtin_return_address(0));
+}
+
+/*
+ * Start kdump: create a LGR log entry, store status of all CPUs and
+ * branch to __do_machine_kdump.
+ */
+static noinline void __machine_kdump(void *image)
+{
+ int this_cpu, cpu;
+
+ lgr_info_log();
+ /* Get status of the other CPUs */
+ this_cpu = smp_find_processor_id(stap());
+ for_each_online_cpu(cpu) {
+ if (cpu == this_cpu)
+ continue;
+ if (smp_store_status(cpu))
+ continue;
+ }
+ /* Store status of the boot CPU */
+ if (MACHINE_HAS_VX)
+ save_vx_regs((void *) &S390_lowcore.vector_save_area);
+ /*
+ * To create a good backchain for this CPU in the dump store_status
+ * is passed the address of a function. The address is saved into
+ * the PSW save area of the boot CPU and the function is invoked as
+ * a tail call of store_status. The backchain in the dump will look
+ * like this:
+ * restart_int_handler -> __machine_kexec -> __do_machine_kdump
+ * The call to store_status() will not return.
+ */
+ store_status(__do_machine_kdump, image);
}
#endif
@@ -235,10 +247,14 @@ static void __do_machine_kexec(void *data)
relocate_kernel_t data_mover;
struct kimage *image = data;
+ s390_reset_system();
data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page);
/* Call the moving routine */
(*data_mover)(&image->head, image->start);
+
+ /* Die if kexec returns */
+ disabled_wait((unsigned long) __builtin_return_address(0));
}
/*
@@ -251,14 +267,10 @@ static void __machine_kexec(void *data)
tracing_off();
debug_locks_off();
#ifdef CONFIG_CRASH_DUMP
- if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) {
-
- lgr_info_log();
- s390_reset_system(setup_regs, __do_machine_kdump, data);
- } else
+ if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH)
+ __machine_kdump(data);
#endif
- s390_reset_system(NULL, __do_machine_kexec, data);
- disabled_wait((unsigned long) __builtin_return_address(0));
+ __do_machine_kexec(data);
}
/*
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 0c1a679..7873e17 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -159,11 +159,11 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
/* Increase core size by size of got & plt and set start
offsets for got and plt. */
- me->core_size = ALIGN(me->core_size, 4);
- me->arch.got_offset = me->core_size;
- me->core_size += me->arch.got_size;
- me->arch.plt_offset = me->core_size;
- me->core_size += me->arch.plt_size;
+ me->core_layout.size = ALIGN(me->core_layout.size, 4);
+ me->arch.got_offset = me->core_layout.size;
+ me->core_layout.size += me->arch.got_size;
+ me->arch.plt_offset = me->core_layout.size;
+ me->core_layout.size += me->arch.plt_size;
return 0;
}
@@ -279,7 +279,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
if (info->got_initialized == 0) {
Elf_Addr *gotent;
- gotent = me->module_core + me->arch.got_offset +
+ gotent = me->core_layout.base + me->arch.got_offset +
info->got_offset;
*gotent = val;
info->got_initialized = 1;
@@ -302,7 +302,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
rc = apply_rela_bits(loc, val, 0, 64, 0);
else if (r_type == R_390_GOTENT ||
r_type == R_390_GOTPLTENT) {
- val += (Elf_Addr) me->module_core - loc;
+ val += (Elf_Addr) me->core_layout.base - loc;
rc = apply_rela_bits(loc, val, 1, 32, 1);
}
break;
@@ -315,7 +315,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
if (info->plt_initialized == 0) {
unsigned int *ip;
- ip = me->module_core + me->arch.plt_offset +
+ ip = me->core_layout.base + me->arch.plt_offset +
info->plt_offset;
ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
ip[1] = 0x100a0004;
@@ -334,7 +334,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
val - loc + 0xffffUL < 0x1ffffeUL) ||
(r_type == R_390_PLT32DBL &&
val - loc + 0xffffffffULL < 0x1fffffffeULL)))
- val = (Elf_Addr) me->module_core +
+ val = (Elf_Addr) me->core_layout.base +
me->arch.plt_offset +
info->plt_offset;
val += rela->r_addend - loc;
@@ -356,7 +356,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
case R_390_GOTOFF32: /* 32 bit offset to GOT. */
case R_390_GOTOFF64: /* 64 bit offset to GOT. */
val = val + rela->r_addend -
- ((Elf_Addr) me->module_core + me->arch.got_offset);
+ ((Elf_Addr) me->core_layout.base + me->arch.got_offset);
if (r_type == R_390_GOTOFF16)
rc = apply_rela_bits(loc, val, 0, 16, 0);
else if (r_type == R_390_GOTOFF32)
@@ -366,7 +366,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
break;
case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
- val = (Elf_Addr) me->module_core + me->arch.got_offset +
+ val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
rela->r_addend - loc;
if (r_type == R_390_GOTPC)
rc = apply_rela_bits(loc, val, 1, 32, 0);
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 0ae6f8e..07302ce 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -21,19 +21,20 @@
#include <asm/nmi.h>
#include <asm/crw.h>
#include <asm/switch_to.h>
-#include <asm/fpu-internal.h>
#include <asm/ctl_reg.h>
struct mcck_struct {
- int kill_task;
- int channel_report;
- int warning;
- unsigned long long mcck_code;
+ unsigned int kill_task : 1;
+ unsigned int channel_report : 1;
+ unsigned int warning : 1;
+ unsigned int etr_queue : 1;
+ unsigned int stp_queue : 1;
+ unsigned long mcck_code;
};
static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
-static void s390_handle_damage(char *msg)
+static void s390_handle_damage(void)
{
smp_send_stop();
disabled_wait((unsigned long) __builtin_return_address(0));
@@ -81,10 +82,14 @@ void s390_handle_mcck(void)
if (xchg(&mchchk_wng_posted, 1) == 0)
kill_cad_pid(SIGPWR, 1);
}
+ if (mcck.etr_queue)
+ etr_queue_work();
+ if (mcck.stp_queue)
+ stp_queue_work();
if (mcck.kill_task) {
local_irq_enable();
printk(KERN_EMERG "mcck: Terminating task because of machine "
- "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+ "malfunction (code 0x%016lx).\n", mcck.mcck_code);
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
current->comm, current->pid);
do_exit(SIGSEGV);
@@ -96,7 +101,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
* returns 0 if all registers could be validated
* returns 1 otherwise
*/
-static int notrace s390_revalidate_registers(struct mci *mci)
+static int notrace s390_validate_registers(union mci mci)
{
int kill_task;
u64 zero;
@@ -105,14 +110,14 @@ static int notrace s390_revalidate_registers(struct mci *mci)
kill_task = 0;
zero = 0;
- if (!mci->gr) {
+ if (!mci.gr) {
/*
* General purpose registers couldn't be restored and have
* unknown contents. Process needs to be terminated.
*/
kill_task = 1;
}
- if (!mci->fp) {
+ if (!mci.fp) {
/*
* Floating point registers can't be restored and
* therefore the process needs to be terminated.
@@ -121,7 +126,7 @@ static int notrace s390_revalidate_registers(struct mci *mci)
}
fpt_save_area = &S390_lowcore.floating_pt_save_area;
fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
- if (!mci->fc) {
+ if (!mci.fc) {
/*
* Floating point control register can't be restored.
* Task will be terminated.
@@ -132,7 +137,7 @@ static int notrace s390_revalidate_registers(struct mci *mci)
asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
if (!MACHINE_HAS_VX) {
- /* Revalidate floating point registers */
+ /* Validate floating point registers */
asm volatile(
" ld 0,0(%0)\n"
" ld 1,8(%0)\n"
@@ -152,10 +157,10 @@ static int notrace s390_revalidate_registers(struct mci *mci)
" ld 15,120(%0)\n"
: : "a" (fpt_save_area));
} else {
- /* Revalidate vector registers */
+ /* Validate vector registers */
union ctlreg0 cr0;
- if (!mci->vr) {
+ if (!mci.vr) {
/*
* Vector registers can't be restored and therefore
* the process needs to be terminated.
@@ -173,38 +178,38 @@ static int notrace s390_revalidate_registers(struct mci *mci)
&S390_lowcore.vector_save_area) : "1");
__ctl_load(S390_lowcore.cregs_save_area[0], 0, 0);
}
- /* Revalidate access registers */
+ /* Validate access registers */
asm volatile(
" lam 0,15,0(%0)"
: : "a" (&S390_lowcore.access_regs_save_area));
- if (!mci->ar) {
+ if (!mci.ar) {
/*
* Access registers have unknown contents.
* Terminating task.
*/
kill_task = 1;
}
- /* Revalidate control registers */
- if (!mci->cr) {
+ /* Validate control registers */
+ if (!mci.cr) {
/*
* Control registers have unknown contents.
* Can't recover and therefore stopping machine.
*/
- s390_handle_damage("invalid control registers.");
+ s390_handle_damage();
} else {
asm volatile(
" lctlg 0,15,0(%0)"
: : "a" (&S390_lowcore.cregs_save_area));
}
/*
- * We don't even try to revalidate the TOD register, since we simply
+ * We don't even try to validate the TOD register, since we simply
* can't write something sensible into that register.
*/
/*
- * See if we can revalidate the TOD programmable register with its
+ * See if we can validate the TOD programmable register with its
* old contents (should be zero) otherwise set it to zero.
*/
- if (!mci->pr)
+ if (!mci.pr)
asm volatile(
" sr 0,0\n"
" sckpf"
@@ -215,17 +220,17 @@ static int notrace s390_revalidate_registers(struct mci *mci)
" sckpf"
: : "a" (&S390_lowcore.tod_progreg_save_area)
: "0", "cc");
- /* Revalidate clock comparator register */
+ /* Validate clock comparator register */
set_clock_comparator(S390_lowcore.clock_comparator);
/* Check if old PSW is valid */
- if (!mci->wp)
+ if (!mci.wp)
/*
* Can't tell if we come from user or kernel mode
* -> stopping machine.
*/
- s390_handle_damage("old psw invalid.");
+ s390_handle_damage();
- if (!mci->ms || !mci->pm || !mci->ia)
+ if (!mci.ms || !mci.pm || !mci.ia)
kill_task = 1;
return kill_task;
@@ -249,21 +254,21 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
static unsigned long long last_ipd;
struct mcck_struct *mcck;
unsigned long long tmp;
- struct mci *mci;
+ union mci mci;
int umode;
nmi_enter();
inc_irq_stat(NMI_NMI);
- mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+ mci.val = S390_lowcore.mcck_interruption_code;
mcck = this_cpu_ptr(&cpu_mcck);
umode = user_mode(regs);
- if (mci->sd) {
+ if (mci.sd) {
/* System damage -> stopping machine */
- s390_handle_damage("received system damage machine check.");
+ s390_handle_damage();
}
- if (mci->pd) {
- if (mci->b) {
+ if (mci.pd) {
+ if (mci.b) {
/* Processing backup -> verify if we can survive this */
u64 z_mcic, o_mcic, t_mcic;
z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
@@ -271,12 +276,11 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
1ULL<<16);
- t_mcic = *(u64 *)mci;
+ t_mcic = mci.val;
if (((t_mcic & z_mcic) != 0) ||
((t_mcic & o_mcic) != o_mcic)) {
- s390_handle_damage("processing backup machine "
- "check with damage.");
+ s390_handle_damage();
}
/*
@@ -291,64 +295,62 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
ipd_count = 1;
last_ipd = tmp;
if (ipd_count == MAX_IPD_COUNT)
- s390_handle_damage("too many ipd retries.");
+ s390_handle_damage();
spin_unlock(&ipd_lock);
} else {
/* Processing damage -> stopping machine */
- s390_handle_damage("received instruction processing "
- "damage machine check.");
+ s390_handle_damage();
}
}
- if (s390_revalidate_registers(mci)) {
+ if (s390_validate_registers(mci)) {
if (umode) {
/*
* Couldn't restore all register contents while in
* user mode -> mark task for termination.
*/
mcck->kill_task = 1;
- mcck->mcck_code = *(unsigned long long *) mci;
+ mcck->mcck_code = mci.val;
set_cpu_flag(CIF_MCCK_PENDING);
} else {
/*
* Couldn't restore all register contents while in
* kernel mode -> stopping machine.
*/
- s390_handle_damage("unable to revalidate registers.");
+ s390_handle_damage();
}
}
- if (mci->cd) {
+ if (mci.cd) {
/* Timing facility damage */
- s390_handle_damage("TOD clock damaged");
+ s390_handle_damage();
}
- if (mci->ed && mci->ec) {
+ if (mci.ed && mci.ec) {
/* External damage */
if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
- etr_sync_check();
+ mcck->etr_queue |= etr_sync_check();
if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
- etr_switch_to_local();
+ mcck->etr_queue |= etr_switch_to_local();
if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
- stp_sync_check();
+ mcck->stp_queue |= stp_sync_check();
if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
- stp_island_check();
+ mcck->stp_queue |= stp_island_check();
+ if (mcck->etr_queue || mcck->stp_queue)
+ set_cpu_flag(CIF_MCCK_PENDING);
}
- if (mci->se)
+ if (mci.se)
/* Storage error uncorrected */
- s390_handle_damage("received storage error uncorrected "
- "machine check.");
- if (mci->ke)
+ s390_handle_damage();
+ if (mci.ke)
/* Storage key-error uncorrected */
- s390_handle_damage("received storage key-error uncorrected "
- "machine check.");
- if (mci->ds && mci->fa)
+ s390_handle_damage();
+ if (mci.ds && mci.fa)
/* Storage degradation */
- s390_handle_damage("received storage degradation machine "
- "check.");
- if (mci->cp) {
+ s390_handle_damage();
+ if (mci.cp) {
/* Channel report word pending */
mcck->channel_report = 1;
set_cpu_flag(CIF_MCCK_PENDING);
}
- if (mci->w) {
+ if (mci.w) {
/* Warning pending */
mcck->warning = 1;
set_cpu_flag(CIF_MCCK_PENDING);
diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
index d112fc6..87f05e4 100644
--- a/arch/s390/kernel/os_info.c
+++ b/arch/s390/kernel/os_info.c
@@ -89,7 +89,7 @@ static void os_info_old_alloc(int nr, int align)
goto fail;
}
buf_align = PTR_ALIGN(buf, align);
- if (copy_from_oldmem(buf_align, (void *) addr, size)) {
+ if (copy_oldmem_kernel(buf_align, (void *) addr, size)) {
msg = "copy failed";
goto fail_free;
}
@@ -122,14 +122,15 @@ static void os_info_old_init(void)
return;
if (!OLDMEM_BASE)
goto fail;
- if (copy_from_oldmem(&addr, &S390_lowcore.os_info, sizeof(addr)))
+ if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr)))
goto fail;
if (addr == 0 || addr % PAGE_SIZE)
goto fail;
os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL);
if (!os_info_old)
goto fail;
- if (copy_from_oldmem(os_info_old, (void *) addr, sizeof(*os_info_old)))
+ if (copy_oldmem_kernel(os_info_old, (void *) addr,
+ sizeof(*os_info_old)))
goto fail_free;
if (os_info_old->magic != OS_INFO_MAGIC)
goto fail_free;
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index a956340..58bf457 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -72,6 +72,7 @@ struct cpu_hw_events {
atomic_t ctr_set[CPUMF_CTR_SET_MAX];
u64 state, tx_state;
unsigned int flags;
+ unsigned int txn_flags;
};
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
.ctr_set = {
@@ -82,6 +83,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
},
.state = 0,
.flags = 0,
+ .txn_flags = 0,
};
static int get_counter_set(u64 event)
@@ -381,7 +383,7 @@ static int __hw_perf_event_init(struct perf_event *event)
/* Validate the counter that is assigned to this event.
* Because the counter facility can use numerous counters at the
- * same time without constraints, it is not necessary to explicity
+ * same time without constraints, it is not necessary to explicitly
* validate event groups (event->group_leader != event).
*/
err = validate_event(hwc);
@@ -538,7 +540,7 @@ static int cpumf_pmu_add(struct perf_event *event, int flags)
* For group events transaction, the authorization check is
* done in cpumf_pmu_commit_txn().
*/
- if (!(cpuhw->flags & PERF_EVENT_TXN))
+ if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD))
if (validate_ctr_auth(&event->hw))
return -ENOENT;
@@ -576,13 +578,22 @@ static void cpumf_pmu_del(struct perf_event *event, int flags)
/*
* Start group events scheduling transaction.
* Set flags to perform a single test at commit time.
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
*/
-static void cpumf_pmu_start_txn(struct pmu *pmu)
+static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
{
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
+
+ cpuhw->txn_flags = txn_flags;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
perf_pmu_disable(pmu);
- cpuhw->flags |= PERF_EVENT_TXN;
cpuhw->tx_state = cpuhw->state;
}
@@ -593,11 +604,18 @@ static void cpumf_pmu_start_txn(struct pmu *pmu)
*/
static void cpumf_pmu_cancel_txn(struct pmu *pmu)
{
+ unsigned int txn_flags;
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
+
+ txn_flags = cpuhw->txn_flags;
+ cpuhw->txn_flags = 0;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
WARN_ON(cpuhw->tx_state != cpuhw->state);
- cpuhw->flags &= ~PERF_EVENT_TXN;
perf_pmu_enable(pmu);
}
@@ -611,13 +629,20 @@ static int cpumf_pmu_commit_txn(struct pmu *pmu)
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
u64 state;
+ WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
+
+ if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
+ cpuhw->txn_flags = 0;
+ return 0;
+ }
+
/* check if the updated state can be scheduled */
state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
state >>= CPUMF_LCCTL_ENABLE_SHIFT;
if ((state & cpuhw->info.auth_ctl) != state)
return -ENOENT;
- cpuhw->flags &= ~PERF_EVENT_TXN;
+ cpuhw->txn_flags = 0;
perf_pmu_enable(pmu);
return 0;
}
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index b973972..1a43474 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -1019,11 +1019,16 @@ static int perf_push_sample(struct perf_event *event, struct sf_raw_sample *sfr)
break;
}
- /* The host-program-parameter (hpp) contains the pid of
- * the CPU thread as set by sie64a() in entry.S.
- * If non-zero assume a guest sample.
+ /*
+ * A non-zero guest program parameter indicates a guest
+ * sample.
+ * Note that some early samples or samples from guests without
+ * lpp usage would be misaccounted to the host. We use the asn
+ * value as a heuristic to detect most of these guest samples.
+ * If the value differs from the host hpp value, we assume
+ * it to be a KVM guest.
*/
- if (sfr->basic.hpp)
+ if (sfr->basic.gpp || sfr->basic.prim_asn != (u16) sfr->basic.hpp)
sde_regs->in_guest = 1;
overflow = 0;
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
index 61595c1..c3e4099 100644
--- a/arch/s390/kernel/perf_event.c
+++ b/arch/s390/kernel/perf_event.c
@@ -74,7 +74,7 @@ static unsigned long guest_is_user_mode(struct pt_regs *regs)
static unsigned long instruction_pointer_guest(struct pt_regs *regs)
{
- return sie_block(regs)->gpsw.addr & PSW_ADDR_INSN;
+ return sie_block(regs)->gpsw.addr;
}
unsigned long perf_instruction_pointer(struct pt_regs *regs)
@@ -222,67 +222,23 @@ static int __init service_level_perf_register(void)
}
arch_initcall(service_level_perf_register);
-/* See also arch/s390/kernel/traps.c */
-static unsigned long __store_trace(struct perf_callchain_entry *entry,
- unsigned long sp,
- unsigned long low, unsigned long high)
+static int __perf_callchain_kernel(void *data, unsigned long address)
{
- struct stack_frame *sf;
- struct pt_regs *regs;
-
- while (1) {
- sp = sp & PSW_ADDR_INSN;
- if (sp < low || sp > high - sizeof(*sf))
- return sp;
- sf = (struct stack_frame *) sp;
- perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN);
- /* Follow the backchain. */
- while (1) {
- low = sp;
- sp = sf->back_chain & PSW_ADDR_INSN;
- if (!sp)
- break;
- if (sp <= low || sp > high - sizeof(*sf))
- return sp;
- sf = (struct stack_frame *) sp;
- perf_callchain_store(entry,
- sf->gprs[8] & PSW_ADDR_INSN);
- }
- /* Zero backchain detected, check for interrupt frame. */
- sp = (unsigned long) (sf + 1);
- if (sp <= low || sp > high - sizeof(*regs))
- return sp;
- regs = (struct pt_regs *) sp;
- perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN);
- low = sp;
- sp = regs->gprs[15];
- }
+ struct perf_callchain_entry *entry = data;
+
+ perf_callchain_store(entry, address);
+ return 0;
}
void perf_callchain_kernel(struct perf_callchain_entry *entry,
struct pt_regs *regs)
{
- unsigned long head;
- struct stack_frame *head_sf;
-
if (user_mode(regs))
return;
-
- head = regs->gprs[15];
- head_sf = (struct stack_frame *) head;
-
- if (!head_sf || !head_sf->back_chain)
- return;
-
- head = head_sf->back_chain;
- head = __store_trace(entry, head, S390_lowcore.async_stack - ASYNC_SIZE,
- S390_lowcore.async_stack);
-
- __store_trace(entry, head, S390_lowcore.thread_info,
- S390_lowcore.thread_info + THREAD_SIZE);
+ dump_trace(__perf_callchain_kernel, entry, NULL, regs->gprs[15]);
}
-/* Perf defintions for PMU event attributes in sysfs */
+/* Perf definitions for PMU event attributes in sysfs */
ssize_t cpumf_events_sysfs_show(struct device *dev,
struct device_attribute *attr, char *page)
{
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index f2dac9f..2bba7df 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -23,6 +23,7 @@
#include <linux/kprobes.h>
#include <linux/random.h>
#include <linux/module.h>
+#include <linux/init_task.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/vtimer.h>
@@ -36,6 +37,9 @@
asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
+/* FPU save area for the init task */
+__vector128 init_task_fpu_regs[__NUM_VXRS] __init_task_data;
+
/*
* Return saved PC of a blocked thread. used in kernel/sched.
* resume in entry.S does not create a new stack frame, it
@@ -52,10 +56,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
return 0;
low = task_stack_page(tsk);
high = (struct stack_frame *) task_pt_regs(tsk);
- sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN);
+ sf = (struct stack_frame *) tsk->thread.ksp;
if (sf <= low || sf > high)
return 0;
- sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
+ sf = (struct stack_frame *) sf->back_chain;
if (sf <= low || sf > high)
return 0;
return sf->gprs[8];
@@ -87,31 +91,29 @@ void arch_release_task_struct(struct task_struct *tsk)
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
+ size_t fpu_regs_size;
+
*dst = *src;
- /* Set up a new floating-point register save area */
- dst->thread.fpu.fpc = 0;
- dst->thread.fpu.flags = 0; /* Always start with VX disabled */
- dst->thread.fpu.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS,
- GFP_KERNEL|__GFP_REPEAT);
- if (!dst->thread.fpu.fprs)
+ /*
+ * If the vector extension is available, it is enabled for all tasks,
+ * and, thus, the FPU register save area must be allocated accordingly.
+ */
+ fpu_regs_size = MACHINE_HAS_VX ? sizeof(__vector128) * __NUM_VXRS
+ : sizeof(freg_t) * __NUM_FPRS;
+ dst->thread.fpu.regs = kzalloc(fpu_regs_size, GFP_KERNEL|__GFP_REPEAT);
+ if (!dst->thread.fpu.regs)
return -ENOMEM;
/*
* Save the floating-point or vector register state of the current
- * task. The state is not saved for early kernel threads, for example,
- * the init_task, which do not have an allocated save area.
- * The CIF_FPU flag is set in any case to lazy clear or restore a saved
- * state when switching to a different task or returning to user space.
+ * task and set the CIF_FPU flag to lazy restore the FPU register
+ * state when returning to user space.
*/
save_fpu_regs();
dst->thread.fpu.fpc = current->thread.fpu.fpc;
- if (is_vx_task(current))
- convert_vx_to_fp(dst->thread.fpu.fprs,
- current->thread.fpu.vxrs);
- else
- memcpy(dst->thread.fpu.fprs, current->thread.fpu.fprs,
- sizeof(freg_t) * __NUM_FPRS);
+ memcpy(dst->thread.fpu.regs, current->thread.fpu.regs, fpu_regs_size);
+
return 0;
}
@@ -152,7 +154,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
memset(&frame->childregs, 0, sizeof(struct pt_regs));
frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
- frame->childregs.psw.addr = PSW_ADDR_AMODE |
+ frame->childregs.psw.addr =
(unsigned long) kernel_thread_starter;
frame->childregs.gprs[9] = new_stackp; /* function */
frame->childregs.gprs[10] = arg;
@@ -169,7 +171,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
/* Don't copy runtime instrumentation info */
p->thread.ri_cb = NULL;
- p->thread.ri_signum = 0;
frame->childregs.psw.mask &= ~PSW_MASK_RI;
/* Set a new TLS ? */
@@ -199,7 +200,7 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
save_fpu_regs();
fpregs->fpc = current->thread.fpu.fpc;
fpregs->pad = 0;
- if (is_vx_task(current))
+ if (MACHINE_HAS_VX)
convert_vx_to_fp((freg_t *)&fpregs->fprs,
current->thread.fpu.vxrs);
else
@@ -219,14 +220,14 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
low = task_stack_page(p);
high = (struct stack_frame *) task_pt_regs(p);
- sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN);
+ sf = (struct stack_frame *) p->thread.ksp;
if (sf <= low || sf > high)
return 0;
for (count = 0; count < 16; count++) {
- sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
+ sf = (struct stack_frame *) sf->back_chain;
if (sf <= low || sf > high)
return 0;
- return_address = sf->gprs[8] & PSW_ADDR_INSN;
+ return_address = sf->gprs[8];
if (!in_sched_functions(return_address))
return return_address;
}
@@ -242,11 +243,7 @@ unsigned long arch_align_stack(unsigned long sp)
static inline unsigned long brk_rnd(void)
{
- /* 8MB for 32bit, 1GB for 64bit */
- if (is_32bit_task())
- return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
- else
- return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
+ return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
}
unsigned long arch_randomize_brk(struct mm_struct *mm)
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index e6e077a..647128d 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -11,6 +11,7 @@
#include <linux/seq_file.h>
#include <linux/delay.h>
#include <linux/cpu.h>
+#include <asm/diag.h>
#include <asm/elf.h>
#include <asm/lowcore.h>
#include <asm/param.h>
@@ -20,8 +21,10 @@ static DEFINE_PER_CPU(struct cpuid, cpu_id);
void notrace cpu_relax(void)
{
- if (!smp_cpu_mtid && MACHINE_HAS_DIAG44)
+ if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) {
+ diag_stat_inc(DIAG_STAT_X044);
asm volatile("diag 0,0,0x44");
+ }
barrier();
}
EXPORT_SYMBOL(cpu_relax);
@@ -58,6 +61,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
"edat", "etf3eh", "highgprs", "te", "vx"
};
+ static const char * const int_hwcap_str[] = {
+ "sie"
+ };
unsigned long n = (unsigned long) v - 1;
int i;
@@ -72,6 +78,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
for (i = 0; i < ARRAY_SIZE(hwcap_str); i++)
if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
seq_printf(m, "%s ", hwcap_str[i]);
+ for (i = 0; i < ARRAY_SIZE(int_hwcap_str); i++)
+ if (int_hwcap_str[i] && (int_hwcap & (1UL << i)))
+ seq_printf(m, "%s ", int_hwcap_str[i]);
seq_puts(m, "\n");
show_cacheinfo(m);
}
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 8b1c8e3..49b1c13 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -84,7 +84,7 @@ void update_cr_regs(struct task_struct *task)
if (test_tsk_thread_flag(task, TIF_UPROBE_SINGLESTEP))
new.control |= PER_EVENT_IFETCH;
new.start = 0;
- new.end = PSW_ADDR_INSN;
+ new.end = -1UL;
}
/* Take care of the PER enablement bit in the PSW. */
@@ -148,7 +148,7 @@ static inline unsigned long __peek_user_per(struct task_struct *child,
else if (addr == (addr_t) &dummy->cr11)
/* End address of the active per set. */
return test_thread_flag(TIF_SINGLE_STEP) ?
- PSW_ADDR_INSN : child->thread.per_user.end;
+ -1UL : child->thread.per_user.end;
else if (addr == (addr_t) &dummy->bits)
/* Single-step bit. */
return test_thread_flag(TIF_SINGLE_STEP) ?
@@ -239,12 +239,12 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
* or the child->thread.fpu.vxrs array
*/
offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
- if (is_vx_task(child))
+ if (MACHINE_HAS_VX)
tmp = *(addr_t *)
((addr_t) child->thread.fpu.vxrs + 2*offset);
else
tmp = *(addr_t *)
- ((addr_t) &child->thread.fpu.fprs + offset);
+ ((addr_t) child->thread.fpu.fprs + offset);
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
/*
@@ -383,12 +383,12 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
* or the child->thread.fpu.vxrs array
*/
offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
- if (is_vx_task(child))
+ if (MACHINE_HAS_VX)
*(addr_t *)((addr_t)
child->thread.fpu.vxrs + 2*offset) = data;
else
*(addr_t *)((addr_t)
- &child->thread.fpu.fprs + offset) = data;
+ child->thread.fpu.fprs + offset) = data;
} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
/*
@@ -495,8 +495,6 @@ long arch_ptrace(struct task_struct *child, long request,
}
return 0;
default:
- /* Removing high order bit from addr (only for 31 bit). */
- addr &= PSW_ADDR_INSN;
return ptrace_request(child, request, addr, data);
}
}
@@ -617,12 +615,12 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
* or the child->thread.fpu.vxrs array
*/
offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
- if (is_vx_task(child))
+ if (MACHINE_HAS_VX)
tmp = *(__u32 *)
((addr_t) child->thread.fpu.vxrs + 2*offset);
else
tmp = *(__u32 *)
- ((addr_t) &child->thread.fpu.fprs + offset);
+ ((addr_t) child->thread.fpu.fprs + offset);
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
/*
@@ -742,12 +740,12 @@ static int __poke_user_compat(struct task_struct *child,
* or the child->thread.fpu.vxrs array
*/
offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
- if (is_vx_task(child))
+ if (MACHINE_HAS_VX)
*(__u32 *)((addr_t)
child->thread.fpu.vxrs + 2*offset) = tmp;
else
*(__u32 *)((addr_t)
- &child->thread.fpu.fprs + offset) = tmp;
+ child->thread.fpu.fprs + offset) = tmp;
} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
/*
@@ -981,7 +979,7 @@ static int s390_fpregs_set(struct task_struct *target,
if (rc)
return rc;
- if (is_vx_task(target))
+ if (MACHINE_HAS_VX)
convert_fp_to_vx(target->thread.fpu.vxrs, fprs);
else
memcpy(target->thread.fpu.fprs, &fprs, sizeof(fprs));
@@ -1047,13 +1045,10 @@ static int s390_vxrs_low_get(struct task_struct *target,
if (!MACHINE_HAS_VX)
return -ENODEV;
- if (is_vx_task(target)) {
- if (target == current)
- save_fpu_regs();
- for (i = 0; i < __NUM_VXRS_LOW; i++)
- vxrs[i] = *((__u64 *)(target->thread.fpu.vxrs + i) + 1);
- } else
- memset(vxrs, 0, sizeof(vxrs));
+ if (target == current)
+ save_fpu_regs();
+ for (i = 0; i < __NUM_VXRS_LOW; i++)
+ vxrs[i] = *((__u64 *)(target->thread.fpu.vxrs + i) + 1);
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
}
@@ -1067,11 +1062,7 @@ static int s390_vxrs_low_set(struct task_struct *target,
if (!MACHINE_HAS_VX)
return -ENODEV;
- if (!is_vx_task(target)) {
- rc = alloc_vector_registers(target);
- if (rc)
- return rc;
- } else if (target == current)
+ if (target == current)
save_fpu_regs();
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
@@ -1091,13 +1082,10 @@ static int s390_vxrs_high_get(struct task_struct *target,
if (!MACHINE_HAS_VX)
return -ENODEV;
- if (is_vx_task(target)) {
- if (target == current)
- save_fpu_regs();
- memcpy(vxrs, target->thread.fpu.vxrs + __NUM_VXRS_LOW,
- sizeof(vxrs));
- } else
- memset(vxrs, 0, sizeof(vxrs));
+ if (target == current)
+ save_fpu_regs();
+ memcpy(vxrs, target->thread.fpu.vxrs + __NUM_VXRS_LOW, sizeof(vxrs));
+
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
}
@@ -1110,11 +1098,7 @@ static int s390_vxrs_high_set(struct task_struct *target,
if (!MACHINE_HAS_VX)
return -ENODEV;
- if (!is_vx_task(target)) {
- rc = alloc_vector_registers(target);
- if (rc)
- return rc;
- } else if (target == current)
+ if (target == current)
save_fpu_regs();
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 52aab0b..89ea8c2 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -9,60 +9,66 @@
#include <asm/sigp.h>
#
-# store_status
+# Issue "store status" for the current CPU to its prefix page
+# and call passed function afterwards
#
-# Prerequisites to run this function:
-# - Prefix register is set to zero
-# - Original prefix register is stored in "dump_prefix_page"
-# - Lowcore protection is off
+# r2 = Function to be called after store status
+# r3 = Parameter for function
#
ENTRY(store_status)
/* Save register one and load save area base */
stg %r1,__LC_SAVE_AREA_RESTART
- lghi %r1,SAVE_AREA_BASE
/* General purpose registers */
- stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- lg %r2,__LC_SAVE_AREA_RESTART
- stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
+ lghi %r1,__LC_GPREGS_SAVE_AREA
+ stmg %r0,%r15,0(%r1)
+ mvc 8(8,%r1),__LC_SAVE_AREA_RESTART
/* Control registers */
- stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+ lghi %r1,__LC_CREGS_SAVE_AREA
+ stctg %c0,%c15,0(%r1)
/* Access registers */
- stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+ lghi %r1,__LC_AREGS_SAVE_AREA
+ stam %a0,%a15,0(%r1)
/* Floating point registers */
- std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
- std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+ lghi %r1,__LC_FPREGS_SAVE_AREA
+ std %f0, 0x00(%r1)
+ std %f1, 0x08(%r1)
+ std %f2, 0x10(%r1)
+ std %f3, 0x18(%r1)
+ std %f4, 0x20(%r1)
+ std %f5, 0x28(%r1)
+ std %f6, 0x30(%r1)
+ std %f7, 0x38(%r1)
+ std %f8, 0x40(%r1)
+ std %f9, 0x48(%r1)
+ std %f10,0x50(%r1)
+ std %f11,0x58(%r1)
+ std %f12,0x60(%r1)
+ std %f13,0x68(%r1)
+ std %f14,0x70(%r1)
+ std %f15,0x78(%r1)
/* Floating point control register */
- stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1)
+ lghi %r1,__LC_FP_CREG_SAVE_AREA
+ stfpc 0(%r1)
/* CPU timer */
- stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1)
- /* Saved prefix register */
- larl %r2,dump_prefix_page
- mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2)
+ lghi %r1,__LC_CPU_TIMER_SAVE_AREA
+ stpt 0(%r1)
+ /* Store prefix register */
+ lghi %r1,__LC_PREFIX_SAVE_AREA
+ stpx 0(%r1)
/* Clock comparator - seven bytes */
- larl %r2,.Lclkcmp
- stckc 0(%r2)
- mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2)
+ lghi %r1,__LC_CLOCK_COMP_SAVE_AREA
+ larl %r4,.Lclkcmp
+ stckc 0(%r4)
+ mvc 1(7,%r1),1(%r4)
/* Program status word */
- epsw %r2,%r3
- st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1)
- st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1)
- larl %r2,store_status
- stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1)
- br %r14
+ lghi %r1,__LC_PSW_SAVE_AREA
+ epsw %r4,%r5
+ st %r4,0(%r1)
+ st %r5,4(%r1)
+ stg %r2,8(%r1)
+ lgr %r1,%r2
+ lgr %r2,%r3
+ br %r1
.section .bss
.align 8
@@ -77,9 +83,11 @@ ENTRY(store_status)
ENTRY(do_reipl_asm)
basr %r13,0
.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
-.Lpg1: brasl %r14,store_status
+.Lpg1: lgr %r3,%r2
+ larl %r2,.Lstatus
+ brasl %r14,store_status
- lctlg %c6,%c6,.Lall-.Lpg0(%r13)
+.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
lgr %r1,%r2
mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
stsch .Lschib-.Lpg0(%r13)
diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c
index 26b4ae9..fffa0e5 100644
--- a/arch/s390/kernel/runtime_instr.c
+++ b/arch/s390/kernel/runtime_instr.c
@@ -18,11 +18,6 @@
/* empty control block to disable RI by loading it */
struct runtime_instr_cb runtime_instr_empty_cb;
-static int runtime_instr_avail(void)
-{
- return test_facility(64);
-}
-
static void disable_runtime_instr(void)
{
struct pt_regs *regs = task_pt_regs(current);
@@ -40,7 +35,6 @@ static void disable_runtime_instr(void)
static void init_runtime_instr_cb(struct runtime_instr_cb *cb)
{
cb->buf_limit = 0xfff;
- cb->int_requested = 1;
cb->pstate = 1;
cb->pstate_set_buf = 1;
cb->pstate_sample = 1;
@@ -57,46 +51,14 @@ void exit_thread_runtime_instr(void)
return;
disable_runtime_instr();
kfree(task->thread.ri_cb);
- task->thread.ri_signum = 0;
task->thread.ri_cb = NULL;
}
-static void runtime_instr_int_handler(struct ext_code ext_code,
- unsigned int param32, unsigned long param64)
-{
- struct siginfo info;
-
- if (!(param32 & CPU_MF_INT_RI_MASK))
- return;
-
- inc_irq_stat(IRQEXT_CMR);
-
- if (!current->thread.ri_cb)
- return;
- if (current->thread.ri_signum < SIGRTMIN ||
- current->thread.ri_signum > SIGRTMAX) {
- WARN_ON_ONCE(1);
- return;
- }
-
- memset(&info, 0, sizeof(info));
- info.si_signo = current->thread.ri_signum;
- info.si_code = SI_QUEUE;
- if (param32 & CPU_MF_INT_RI_BUF_FULL)
- info.si_int = ENOBUFS;
- else if (param32 & CPU_MF_INT_RI_HALTED)
- info.si_int = ECANCELED;
- else
- return; /* unknown reason */
-
- send_sig_info(current->thread.ri_signum, &info, current);
-}
-
-SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
+SYSCALL_DEFINE1(s390_runtime_instr, int, command)
{
struct runtime_instr_cb *cb;
- if (!runtime_instr_avail())
+ if (!test_facility(64))
return -EOPNOTSUPP;
if (command == S390_RUNTIME_INSTR_STOP) {
@@ -106,8 +68,7 @@ SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
return 0;
}
- if (command != S390_RUNTIME_INSTR_START ||
- (signum < SIGRTMIN || signum > SIGRTMAX))
+ if (command != S390_RUNTIME_INSTR_START)
return -EINVAL;
if (!current->thread.ri_cb) {
@@ -120,7 +81,6 @@ SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
}
init_runtime_instr_cb(cb);
- current->thread.ri_signum = signum;
/* now load the control block to make it available */
preempt_disable();
@@ -129,21 +89,3 @@ SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
preempt_enable();
return 0;
}
-
-static int __init runtime_instr_init(void)
-{
- int rc;
-
- if (!runtime_instr_avail())
- return 0;
-
- irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
- rc = register_external_irq(EXT_IRQ_MEASURE_ALERT,
- runtime_instr_int_handler);
- if (rc)
- irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
- else
- pr_info("Runtime instrumentation facility initialized\n");
- return rc;
-}
-device_initcall(runtime_instr_init);
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 5090d3d..e67453b 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -1,6 +1,6 @@
#include <linux/module.h>
#include <linux/kvm_host.h>
-#include <asm/fpu-internal.h>
+#include <asm/fpu/api.h>
#include <asm/ftrace.h>
#ifdef CONFIG_FUNCTION_TRACER
@@ -10,7 +10,6 @@ EXPORT_SYMBOL(_mcount);
EXPORT_SYMBOL(sie64a);
EXPORT_SYMBOL(sie_exit);
EXPORT_SYMBOL(save_fpu_regs);
-EXPORT_SYMBOL(__ctl_set_vx);
#endif
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
diff --git a/arch/s390/kernel/sclp.c b/arch/s390/kernel/sclp.c
index fa0bdff..d88db40 100644
--- a/arch/s390/kernel/sclp.c
+++ b/arch/s390/kernel/sclp.c
@@ -9,7 +9,11 @@
#include <asm/processor.h>
#include <asm/sclp.h>
+#define EVTYP_VT220MSG_MASK 0x00000040
+#define EVTYP_MSG_MASK 0x40000000
+
static char _sclp_work_area[4096] __aligned(PAGE_SIZE);
+static bool have_vt220, have_linemode;
static void _sclp_wait_int(void)
{
@@ -21,7 +25,7 @@ static void _sclp_wait_int(void)
__ctl_load(cr0_new, 0, 0);
psw_ext_save = S390_lowcore.external_new_psw;
- psw_mask = __extract_psw() & (PSW_MASK_EA | PSW_MASK_BA);
+ psw_mask = __extract_psw();
S390_lowcore.external_new_psw.mask = psw_mask;
psw_wait.mask = psw_mask | PSW_MASK_EXT | PSW_MASK_WAIT;
S390_lowcore.ext_int_code = 0;
@@ -68,7 +72,7 @@ static int _sclp_setup(int disable)
0x00, 0x1c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04,
- 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int *masks;
@@ -82,13 +86,13 @@ static int _sclp_setup(int disable)
rc = _sclp_servc(0x00780005, _sclp_work_area);
if (rc)
return rc;
- if ((masks[0] & masks[3]) != masks[0] ||
- (masks[1] & masks[2]) != masks[1])
- return -EIO;
+ have_vt220 = masks[2] & EVTYP_VT220MSG_MASK;
+ have_linemode = masks[2] & EVTYP_MSG_MASK;
return 0;
}
-static int _sclp_print(const char *str)
+/* Output multi-line text using SCLP Message interface. */
+static void _sclp_print_lm(const char *str)
{
static unsigned char write_head[] = {
/* sccb header */
@@ -143,18 +147,49 @@ static int _sclp_print(const char *str)
} while (ch != 0);
/* SCLP write data */
- return _sclp_servc(0x00760005, _sclp_work_area);
+ _sclp_servc(0x00760005, _sclp_work_area);
}
-int _sclp_print_early(const char *str)
+/* Output multi-line text (plus a newline) using SCLP VT220
+ * interface.
+ */
+static void _sclp_print_vt220(const char *str)
{
- int rc;
+ static unsigned char const write_head[] = {
+ /* sccb header */
+ 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* evbuf header */
+ 0x00, 0x06,
+ 0x1a, 0x00, 0x00, 0x00,
+ };
+ size_t len = strlen(str);
- rc = _sclp_setup(0);
- if (rc)
- return rc;
- rc = _sclp_print(str);
- if (rc)
- return rc;
- return _sclp_setup(1);
+ if (sizeof(write_head) + len >= sizeof(_sclp_work_area))
+ len = sizeof(_sclp_work_area) - sizeof(write_head) - 1;
+
+ memcpy(_sclp_work_area, write_head, sizeof(write_head));
+ memcpy(_sclp_work_area + sizeof(write_head), str, len);
+ _sclp_work_area[sizeof(write_head) + len] = '\n';
+
+ /* Update length fields in evbuf and sccb headers */
+ *(unsigned short *)(_sclp_work_area + 8) += len + 1;
+ *(unsigned short *)(_sclp_work_area + 0) += len + 1;
+
+ /* SCLP write data */
+ (void)_sclp_servc(0x00760005, _sclp_work_area);
+}
+
+/* Output one or more lines of text on the SCLP console (VT220 and /
+ * or line-mode). All lines get terminated; no need for a trailing LF.
+ */
+void _sclp_print_early(const char *str)
+{
+ if (_sclp_setup(0) != 0)
+ return;
+ if (have_linemode)
+ _sclp_print_lm(str);
+ if (have_vt220)
+ _sclp_print_vt220(str);
+ _sclp_setup(1);
}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index ce0cbd6..d3f9688 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -80,6 +80,8 @@ EXPORT_SYMBOL(console_irq);
unsigned long elf_hwcap __read_mostly = 0;
char elf_platform[ELF_PLATFORM_SIZE];
+unsigned long int_hwcap = 0;
+
int __initdata memory_end_set;
unsigned long __initdata memory_end;
unsigned long __initdata max_physmem_end;
@@ -97,7 +99,7 @@ unsigned long MODULES_VADDR;
unsigned long MODULES_END;
/* An array with a pointer to the lowcore of every CPU. */
-struct _lowcore *lowcore_ptr[NR_CPUS];
+struct lowcore *lowcore_ptr[NR_CPUS];
EXPORT_SYMBOL(lowcore_ptr);
/*
@@ -291,33 +293,29 @@ void *restart_stack __attribute__((__section__(".data")));
static void __init setup_lowcore(void)
{
- struct _lowcore *lc;
+ struct lowcore *lc;
/*
* Setup lowcore for boot cpu
*/
- BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
+ BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096);
lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
lc->restart_psw.mask = PSW_KERNEL_BITS;
- lc->restart_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
+ lc->restart_psw.addr = (unsigned long) restart_int_handler;
lc->external_new_psw.mask = PSW_KERNEL_BITS |
PSW_MASK_DAT | PSW_MASK_MCHECK;
- lc->external_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
+ lc->external_new_psw.addr = (unsigned long) ext_int_handler;
lc->svc_new_psw.mask = PSW_KERNEL_BITS |
PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
- lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
+ lc->svc_new_psw.addr = (unsigned long) system_call;
lc->program_new_psw.mask = PSW_KERNEL_BITS |
PSW_MASK_DAT | PSW_MASK_MCHECK;
- lc->program_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) pgm_check_handler;
+ lc->program_new_psw.addr = (unsigned long) pgm_check_handler;
lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
- lc->mcck_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
+ lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler;
lc->io_new_psw.mask = PSW_KERNEL_BITS |
PSW_MASK_DAT | PSW_MASK_MCHECK;
- lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
+ lc->io_new_psw.addr = (unsigned long) io_int_handler;
lc->clock_comparator = -1ULL;
lc->kernel_stack = ((unsigned long) &init_thread_union)
+ THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
@@ -329,6 +327,7 @@ static void __init setup_lowcore(void)
+ PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
lc->current_task = (unsigned long) init_thread_union.thread_info.task;
lc->thread_info = (unsigned long) &init_thread_union;
+ lc->lpp = LPP_MAGIC;
lc->machine_flags = S390_lowcore.machine_flags;
lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
@@ -376,17 +375,17 @@ static void __init setup_lowcore(void)
static struct resource code_resource = {
.name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource data_resource = {
.name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource bss_resource = {
.name = "Kernel bss",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource __initdata *standard_resources[] = {
@@ -410,7 +409,7 @@ static void __init setup_resources(void)
for_each_memblock(memory, reg) {
res = alloc_bootmem_low(sizeof(*res));
- res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM;
res->name = "System RAM";
res->start = reg->base;
@@ -661,15 +660,6 @@ static void __init reserve_kernel(void)
#endif
}
-static void __init reserve_elfcorehdr(void)
-{
-#ifdef CONFIG_CRASH_DUMP
- if (is_kdump_kernel())
- memblock_reserve(elfcorehdr_addr - OLDMEM_BASE,
- PAGE_ALIGN(elfcorehdr_size));
-#endif
-}
-
static void __init setup_memory(void)
{
struct memblock_region *reg;
@@ -764,9 +754,6 @@ static int __init setup_hwcaps(void)
get_cpu_id(&cpu_id);
add_device_randomness(&cpu_id, sizeof(cpu_id));
switch (cpu_id.machine) {
- case 0x9672:
- strcpy(elf_platform, "g5");
- break;
case 0x2064:
case 0x2066:
default: /* Use "z900" as default for 64 bit kernels. */
@@ -793,9 +780,17 @@ static int __init setup_hwcaps(void)
strcpy(elf_platform, "zEC12");
break;
case 0x2964:
+ case 0x2965:
strcpy(elf_platform, "z13");
break;
}
+
+ /*
+ * Virtualization support HWCAP_INT_SIE is bit 0.
+ */
+ if (sclp.has_sief2)
+ int_hwcap |= HWCAP_INT_SIE;
+
return 0;
}
arch_initcall(setup_hwcaps);
@@ -844,6 +839,11 @@ void __init setup_arch(char **cmdline_p)
init_mm.brk = (unsigned long) &_end;
parse_early_param();
+#ifdef CONFIG_CRASH_DUMP
+ /* Deactivate elfcorehdr= kernel parameter */
+ elfcorehdr_addr = ELFCORE_ADDR_MAX;
+#endif
+
os_info_init();
setup_ipl();
@@ -852,7 +852,6 @@ void __init setup_arch(char **cmdline_p)
reserve_oldmem();
reserve_kernel();
reserve_initrd();
- reserve_elfcorehdr();
memblock_allow_resize();
/* Get information about *all* installed memory */
@@ -873,11 +872,13 @@ void __init setup_arch(char **cmdline_p)
check_initrd();
reserve_crashkernel();
+#ifdef CONFIG_CRASH_DUMP
/*
* Be aware that smp_save_dump_cpus() triggers a system reset.
* Therefore CPU and device initialization should be done afterwards.
*/
smp_save_dump_cpus();
+#endif
setup_resources();
setup_vmcoreinfo();
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 9549af1..d82562c 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -179,7 +179,7 @@ static int save_sigregs_ext(struct pt_regs *regs,
int i;
/* Save vector registers to signal stack */
- if (is_vx_task(current)) {
+ if (MACHINE_HAS_VX) {
for (i = 0; i < __NUM_VXRS_LOW; i++)
vxrs[i] = *((__u64 *)(current->thread.fpu.vxrs + i) + 1);
if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
@@ -199,7 +199,7 @@ static int restore_sigregs_ext(struct pt_regs *regs,
int i;
/* Restore vector registers from signal stack */
- if (is_vx_task(current)) {
+ if (MACHINE_HAS_VX) {
if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
sizeof(sregs_ext->vxrs_low)) ||
__copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
@@ -331,13 +331,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) {
- restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE;
+ restorer = (unsigned long) ka->sa.sa_restorer;
} else {
/* Signal frame without vector registers are short ! */
__u16 __user *svc = (void __user *) frame + frame_size - 2;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
return -EFAULT;
- restorer = (unsigned long) svc | PSW_ADDR_AMODE;
+ restorer = (unsigned long) svc;
}
/* Set up registers for signal handler */
@@ -347,7 +347,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
- regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
+ regs->psw.addr = (unsigned long) ka->sa.sa_handler;
regs->gprs[2] = sig;
regs->gprs[3] = (unsigned long) &frame->sc;
@@ -381,8 +381,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
uc_flags = 0;
if (MACHINE_HAS_VX) {
frame_size += sizeof(_sigregs_ext);
- if (is_vx_task(current))
- uc_flags |= UC_VXRS;
+ uc_flags |= UC_VXRS;
}
frame = get_sigframe(&ksig->ka, regs, frame_size);
if (frame == (void __user *) -1UL)
@@ -395,13 +394,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
- restorer = (unsigned long)
- ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE;
+ restorer = (unsigned long) ksig->ka.sa.sa_restorer;
} else {
__u16 __user *svc = &frame->svc_insn;
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
return -EFAULT;
- restorer = (unsigned long) svc | PSW_ADDR_AMODE;
+ restorer = (unsigned long) svc;
}
/* Create siginfo on the signal stack */
@@ -427,7 +425,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
- regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE;
+ regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler;
regs->gprs[2] = ksig->sig;
regs->gprs[3] = (unsigned long) &frame->info;
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index c6355e6..40a6b4f 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -33,6 +33,7 @@
#include <linux/crash_dump.h>
#include <linux/memblock.h>
#include <asm/asm-offsets.h>
+#include <asm/diag.h>
#include <asm/switch_to.h>
#include <asm/facility.h>
#include <asm/ipl.h>
@@ -63,8 +64,9 @@ enum {
static DEFINE_PER_CPU(struct cpu *, cpu_device);
struct pcpu {
- struct _lowcore *lowcore; /* lowcore page(s) for the cpu */
+ struct lowcore *lowcore; /* lowcore page(s) for the cpu */
unsigned long ec_mask; /* bit mask for ec_xxx functions */
+ unsigned long ec_clk; /* sigp timestamp for ec_xxx */
signed char state; /* physical cpu state */
signed char polarization; /* physical polarization */
u16 address; /* physical cpu address */
@@ -79,6 +81,10 @@ EXPORT_SYMBOL(smp_cpu_mt_shift);
unsigned int smp_cpu_mtid;
EXPORT_SYMBOL(smp_cpu_mtid);
+#ifdef CONFIG_CRASH_DUMP
+__vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS];
+#endif
+
static unsigned int smp_max_threads __initdata = -1U;
static int __init early_nosmt(char *s)
@@ -104,8 +110,7 @@ DEFINE_MUTEX(smp_cpu_state_mutex);
/*
* Signal processor helper functions.
*/
-static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm,
- u32 *status)
+static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm)
{
int cc;
@@ -170,6 +175,7 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
if (test_and_set_bit(ec_bit, &pcpu->ec_mask))
return;
order = pcpu_running(pcpu) ? SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL;
+ pcpu->ec_clk = get_tod_clock_fast();
pcpu_sigp_retry(pcpu, order, 0);
}
@@ -179,10 +185,10 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
{
unsigned long async_stack, panic_stack;
- struct _lowcore *lc;
+ struct lowcore *lc;
if (pcpu != &pcpu_devices[0]) {
- pcpu->lowcore = (struct _lowcore *)
+ pcpu->lowcore = (struct lowcore *)
__get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
panic_stack = __get_free_page(GFP_KERNEL);
@@ -234,7 +240,7 @@ static void pcpu_free_lowcore(struct pcpu *pcpu)
static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
{
- struct _lowcore *lc = pcpu->lowcore;
+ struct lowcore *lc = pcpu->lowcore;
if (MACHINE_HAS_TLB_LC)
cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask);
@@ -254,13 +260,15 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
{
- struct _lowcore *lc = pcpu->lowcore;
+ struct lowcore *lc = pcpu->lowcore;
struct thread_info *ti = task_thread_info(tsk);
lc->kernel_stack = (unsigned long) task_stack_page(tsk)
+ THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
lc->thread_info = (unsigned long) task_thread_info(tsk);
lc->current_task = (unsigned long) tsk;
+ lc->lpp = LPP_MAGIC;
+ lc->current_pid = tsk->pid;
lc->user_timer = ti->user_timer;
lc->system_timer = ti->system_timer;
lc->steal_timer = 0;
@@ -268,7 +276,7 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
{
- struct _lowcore *lc = pcpu->lowcore;
+ struct lowcore *lc = pcpu->lowcore;
lc->restart_stack = lc->kernel_stack;
lc->restart_fn = (unsigned long) func;
@@ -283,7 +291,7 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
void *data, unsigned long stack)
{
- struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
+ struct lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
unsigned long source_cpu = stap();
__load_psw_mask(PSW_KERNEL_BITS);
@@ -375,11 +383,14 @@ int smp_vcpu_scheduled(int cpu)
void smp_yield_cpu(int cpu)
{
- if (MACHINE_HAS_DIAG9C)
+ if (MACHINE_HAS_DIAG9C) {
+ diag_stat_inc_norecursion(DIAG_STAT_X09C);
asm volatile("diag %0,0,0x9c"
: : "d" (pcpu_devices[cpu].address));
- else if (MACHINE_HAS_DIAG44)
+ } else if (MACHINE_HAS_DIAG44) {
+ diag_stat_inc_norecursion(DIAG_STAT_X044);
asm volatile("diag 0,0,0x44");
+ }
}
/*
@@ -532,53 +543,24 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
#ifdef CONFIG_CRASH_DUMP
-static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext,
- u16 address, int is_boot_cpu)
-{
- void *lc = (void *)(unsigned long) store_prefix();
- unsigned long vx_sa;
-
- if (is_boot_cpu) {
- /* Copy the registers of the boot CPU. */
- copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa),
- SAVE_AREA_BASE - PAGE_SIZE, 0);
- if (MACHINE_HAS_VX)
- save_vx_regs_safe(sa_ext->vx_regs);
- return;
- }
- /* Get the registers of a non-boot cpu. */
- __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL);
- memcpy_real(&sa_ext->sa, lc + SAVE_AREA_BASE, sizeof(sa_ext->sa));
- if (!MACHINE_HAS_VX)
- return;
- /* Get the VX registers */
- vx_sa = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
- if (!vx_sa)
- panic("could not allocate memory for VX save area\n");
- __pcpu_sigp_relax(address, SIGP_STORE_ADDITIONAL_STATUS, vx_sa, NULL);
- memcpy(sa_ext->vx_regs, (void *) vx_sa, sizeof(sa_ext->vx_regs));
- memblock_free(vx_sa, PAGE_SIZE);
-}
-
int smp_store_status(int cpu)
{
- unsigned long vx_sa;
- struct pcpu *pcpu;
+ struct pcpu *pcpu = pcpu_devices + cpu;
+ unsigned long pa;
- pcpu = pcpu_devices + cpu;
- if (__pcpu_sigp_relax(pcpu->address, SIGP_STOP_AND_STORE_STATUS,
- 0, NULL) != SIGP_CC_ORDER_CODE_ACCEPTED)
+ pa = __pa(&pcpu->lowcore->floating_pt_save_area);
+ if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_STATUS_AT_ADDRESS,
+ pa) != SIGP_CC_ORDER_CODE_ACCEPTED)
return -EIO;
if (!MACHINE_HAS_VX)
return 0;
- vx_sa = __pa(pcpu->lowcore->vector_save_area_addr);
- __pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS,
- vx_sa, NULL);
+ pa = __pa(pcpu->lowcore->vector_save_area_addr);
+ if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS,
+ pa) != SIGP_CC_ORDER_CODE_ACCEPTED)
+ return -EIO;
return 0;
}
-#endif /* CONFIG_CRASH_DUMP */
-
/*
* Collect CPU state of the previous, crashed system.
* There are four cases:
@@ -587,7 +569,7 @@ int smp_store_status(int cpu)
* The state for all CPUs except the boot CPU needs to be collected
* with sigp stop-and-store-status. The boot CPU state is located in
* the absolute lowcore of the memory stored in the HSA. The zcore code
- * will allocate the save area and copy the boot CPU state from the HSA.
+ * will copy the boot CPU state from the HSA.
* 2) stand-alone kdump for SCSI (zfcp dump with swapped memory)
* condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP
* The state for all CPUs except the boot CPU needs to be collected
@@ -602,55 +584,76 @@ int smp_store_status(int cpu)
* stored the registers of the boot CPU in the memory of the old system.
* 4) kdump and the old kernel stored the CPU state
* condition: OLDMEM_BASE != NULL && is_kdump_kernel()
- * The state of all CPUs is stored in ELF sections in the memory of the
- * old system. The ELF sections are picked up by the crash_dump code
- * via elfcorehdr_addr.
+ * This case does not exist for s390 anymore, setup_arch explicitly
+ * deactivates the elfcorehdr= kernel parameter
*/
+static __init void smp_save_cpu_vxrs(struct save_area *sa, u16 addr,
+ bool is_boot_cpu, unsigned long page)
+{
+ __vector128 *vxrs = (__vector128 *) page;
+
+ if (is_boot_cpu)
+ vxrs = boot_cpu_vector_save_area;
+ else
+ __pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, page);
+ save_area_add_vxrs(sa, vxrs);
+}
+
+static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr,
+ bool is_boot_cpu, unsigned long page)
+{
+ void *regs = (void *) page;
+
+ if (is_boot_cpu)
+ copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512);
+ else
+ __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page);
+ save_area_add_regs(sa, regs);
+}
+
void __init smp_save_dump_cpus(void)
{
-#ifdef CONFIG_CRASH_DUMP
- int addr, cpu, boot_cpu_addr, max_cpu_addr;
- struct save_area_ext *sa_ext;
+ int addr, boot_cpu_addr, max_cpu_addr;
+ struct save_area *sa;
+ unsigned long page;
bool is_boot_cpu;
- if (is_kdump_kernel())
- /* Previous system stored the CPU states. Nothing to do. */
- return;
if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP))
/* No previous system present, normal boot. */
return;
+ /* Allocate a page as dumping area for the store status sigps */
+ page = memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, 1UL << 31);
/* Set multi-threading state to the previous system. */
pcpu_set_smt(sclp.mtid_prev);
- max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev;
- for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) {
- if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) ==
- SIGP_CC_NOT_OPERATIONAL)
- continue;
- cpu += 1;
- }
- dump_save_areas.areas = (void *)memblock_alloc(sizeof(void *) * cpu, 8);
- dump_save_areas.count = cpu;
boot_cpu_addr = stap();
- for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) {
- if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) ==
+ max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev;
+ for (addr = 0; addr <= max_cpu_addr; addr++) {
+ if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) ==
SIGP_CC_NOT_OPERATIONAL)
continue;
- sa_ext = (void *) memblock_alloc(sizeof(*sa_ext), 8);
- dump_save_areas.areas[cpu] = sa_ext;
- if (!sa_ext)
- panic("could not allocate memory for save area\n");
is_boot_cpu = (addr == boot_cpu_addr);
- cpu += 1;
- if (is_boot_cpu && !OLDMEM_BASE)
- /* Skip boot CPU for standard zfcp dump. */
- continue;
- /* Get state for this CPU. */
- __smp_store_cpu_state(sa_ext, addr, is_boot_cpu);
+ /* Allocate save area */
+ sa = save_area_alloc(is_boot_cpu);
+ if (!sa)
+ panic("could not allocate memory for save area\n");
+ if (MACHINE_HAS_VX)
+ /* Get the vector registers */
+ smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page);
+ /*
+ * For a zfcp dump OLDMEM_BASE == NULL and the registers
+ * of the boot CPU are stored in the HSA. To retrieve
+ * these registers an SCLP request is required which is
+ * done by drivers/s390/char/zcore.c:init_cpu_info()
+ */
+ if (!is_boot_cpu || OLDMEM_BASE)
+ /* Get the CPU registers */
+ smp_save_cpu_regs(sa, addr, is_boot_cpu, page);
}
+ memblock_free(page, PAGE_SIZE);
diag308_reset();
pcpu_set_smt(0);
-#endif /* CONFIG_CRASH_DUMP */
}
+#endif /* CONFIG_CRASH_DUMP */
void smp_cpu_set_polarization(int cpu, int val)
{
@@ -674,7 +677,7 @@ static struct sclp_core_info *smp_get_core_info(void)
for (address = 0;
address < (SCLP_MAX_CORES << smp_cpu_mt_shift);
address += (1U << smp_cpu_mt_shift)) {
- if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) ==
+ if (__pcpu_sigp_relax(address, SIGP_SENSE, 0) ==
SIGP_CC_NOT_OPERATIONAL)
continue;
info->core[info->configured].core_id =
@@ -795,7 +798,7 @@ static void smp_start_secondary(void *cpuvoid)
set_cpu_online(smp_processor_id(), true);
inc_irq_stat(CPU_RST);
local_irq_enable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
/* Upping and downing of CPUs */
@@ -918,7 +921,7 @@ void __init smp_prepare_boot_cpu(void)
pcpu->state = CPU_STATE_CONFIGURED;
pcpu->address = stap();
- pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();
+ pcpu->lowcore = (struct lowcore *)(unsigned long) store_prefix();
S390_lowcore.percpu_offset = __per_cpu_offset[0];
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
set_cpu_present(0, true);
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 1785cd8..44f84b2 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -10,87 +10,64 @@
#include <linux/kallsyms.h>
#include <linux/module.h>
-static unsigned long save_context_stack(struct stack_trace *trace,
- unsigned long sp,
- unsigned long low,
- unsigned long high,
- int savesched)
+static int __save_address(void *data, unsigned long address, int nosched)
{
- struct stack_frame *sf;
- struct pt_regs *regs;
- unsigned long addr;
+ struct stack_trace *trace = data;
- while(1) {
- sp &= PSW_ADDR_INSN;
- if (sp < low || sp > high)
- return sp;
- sf = (struct stack_frame *)sp;
- while(1) {
- addr = sf->gprs[8] & PSW_ADDR_INSN;
- if (!trace->skip)
- trace->entries[trace->nr_entries++] = addr;
- else
- trace->skip--;
- if (trace->nr_entries >= trace->max_entries)
- return sp;
- low = sp;
- sp = sf->back_chain & PSW_ADDR_INSN;
- if (!sp)
- break;
- if (sp <= low || sp > high - sizeof(*sf))
- return sp;
- sf = (struct stack_frame *)sp;
- }
- /* Zero backchain detected, check for interrupt frame. */
- sp = (unsigned long)(sf + 1);
- if (sp <= low || sp > high - sizeof(*regs))
- return sp;
- regs = (struct pt_regs *)sp;
- addr = regs->psw.addr & PSW_ADDR_INSN;
- if (savesched || !in_sched_functions(addr)) {
- if (!trace->skip)
- trace->entries[trace->nr_entries++] = addr;
- else
- trace->skip--;
- }
- if (trace->nr_entries >= trace->max_entries)
- return sp;
- low = sp;
- sp = regs->gprs[15];
+ if (nosched && in_sched_functions(address))
+ return 0;
+ if (trace->skip > 0) {
+ trace->skip--;
+ return 0;
}
+ if (trace->nr_entries < trace->max_entries) {
+ trace->entries[trace->nr_entries++] = address;
+ return 0;
+ }
+ return 1;
+}
+
+static int save_address(void *data, unsigned long address)
+{
+ return __save_address(data, address, 0);
+}
+
+static int save_address_nosched(void *data, unsigned long address)
+{
+ return __save_address(data, address, 1);
}
void save_stack_trace(struct stack_trace *trace)
{
- register unsigned long sp asm ("15");
- unsigned long orig_sp, new_sp;
+ unsigned long sp;
- orig_sp = sp & PSW_ADDR_INSN;
- new_sp = save_context_stack(trace, orig_sp,
- S390_lowcore.panic_stack - PAGE_SIZE,
- S390_lowcore.panic_stack, 1);
- if (new_sp != orig_sp)
- return;
- new_sp = save_context_stack(trace, new_sp,
- S390_lowcore.async_stack - ASYNC_SIZE,
- S390_lowcore.async_stack, 1);
- if (new_sp != orig_sp)
- return;
- save_context_stack(trace, new_sp,
- S390_lowcore.thread_info,
- S390_lowcore.thread_info + THREAD_SIZE, 1);
+ sp = current_stack_pointer();
+ dump_trace(save_address, trace, NULL, sp);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL_GPL(save_stack_trace);
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
- unsigned long sp, low, high;
+ unsigned long sp;
- sp = tsk->thread.ksp & PSW_ADDR_INSN;
- low = (unsigned long) task_stack_page(tsk);
- high = (unsigned long) task_pt_regs(tsk);
- save_context_stack(trace, sp, low, high, 0);
+ sp = tsk->thread.ksp;
+ if (tsk == current)
+ sp = current_stack_pointer();
+ dump_trace(save_address_nosched, trace, tsk, sp);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
+
+void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+{
+ unsigned long sp;
+
+ sp = kernel_stack_pointer(regs);
+ dump_trace(save_address, trace, NULL, sp);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_regs);
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 8c56929..293d8b9 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -382,3 +382,5 @@ SYSCALL(sys_sendmsg,compat_sys_sendmsg) /* 370 */
SYSCALL(sys_recvfrom,compat_sys_recvfrom)
SYSCALL(sys_recvmsg,compat_sys_recvmsg)
SYSCALL(sys_shutdown,sys_shutdown)
+SYSCALL(sys_mlock2,compat_sys_mlock2)
+SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index 99babea..f7dba388 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -111,8 +111,7 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
{
- static int max_mnest;
- int i, rc;
+ int i;
seq_putc(m, '\n');
if (!MACHINE_HAS_TOPOLOGY)
@@ -123,7 +122,7 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
seq_printf(m, " %d", info->mag[i]);
seq_putc(m, '\n');
-#ifdef CONFIG_SCHED_MC
+#ifdef CONFIG_SCHED_TOPOLOGY
store_topology(info);
seq_printf(m, "CPU Topology SW: ");
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
@@ -145,6 +144,10 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info)
seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured);
seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby);
seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved);
+ if (info->mt_installed) {
+ seq_printf(m, "CPUs G-MTID: %d\n", info->mt_gtid);
+ seq_printf(m, "CPUs S-MTID: %d\n", info->mt_stid);
+ }
/*
* Sigh 2. According to the specification the alternate
* capability field is a 32 bit floating point number
@@ -194,13 +197,10 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved);
seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated);
seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared);
- if (info->mt_installed & 0x80) {
- seq_printf(m, "LPAR CPUs G-MTID: %d\n",
- info->mt_general & 0x1f);
- seq_printf(m, "LPAR CPUs S-MTID: %d\n",
- info->mt_installed & 0x1f);
- seq_printf(m, "LPAR CPUs PS-MTID: %d\n",
- info->mt_psmtid & 0x1f);
+ if (info->mt_installed) {
+ seq_printf(m, "LPAR CPUs G-MTID: %d\n", info->mt_gtid);
+ seq_printf(m, "LPAR CPUs S-MTID: %d\n", info->mt_stid);
+ seq_printf(m, "LPAR CPUs PS-MTID: %d\n", info->mt_psmtid);
}
}
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 017c3a9..9409d32 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -499,8 +499,7 @@ static void etr_reset(void)
if (etr_port0_online && etr_port1_online)
set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
} else if (etr_port0_online || etr_port1_online) {
- pr_warning("The real or virtual hardware system does "
- "not provide an ETR interface\n");
+ pr_warn("The real or virtual hardware system does not provide an ETR interface\n");
etr_port0_online = etr_port1_online = 0;
}
}
@@ -542,16 +541,17 @@ arch_initcall(etr_init);
* Switch to local machine check. This is called when the last usable
* ETR port goes inactive. After switch to local the clock is not in sync.
*/
-void etr_switch_to_local(void)
+int etr_switch_to_local(void)
{
if (!etr_eacr.sl)
- return;
+ return 0;
disable_sync_clock(NULL);
if (!test_and_set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events)) {
etr_eacr.es = etr_eacr.sl = 0;
etr_setr(&etr_eacr);
- queue_work(time_sync_wq, &etr_work);
+ return 1;
}
+ return 0;
}
/*
@@ -560,16 +560,22 @@ void etr_switch_to_local(void)
* After a ETR sync check the clock is not in sync. The machine check
* is broadcasted to all cpus at the same time.
*/
-void etr_sync_check(void)
+int etr_sync_check(void)
{
if (!etr_eacr.es)
- return;
+ return 0;
disable_sync_clock(NULL);
if (!test_and_set_bit(ETR_EVENT_SYNC_CHECK, &etr_events)) {
etr_eacr.es = 0;
etr_setr(&etr_eacr);
- queue_work(time_sync_wq, &etr_work);
+ return 1;
}
+ return 0;
+}
+
+void etr_queue_work(void)
+{
+ queue_work(time_sync_wq, &etr_work);
}
/*
@@ -1426,7 +1432,7 @@ device_initcall(etr_init_sysfs);
/*
* Server Time Protocol (STP) code.
*/
-static int stp_online;
+static bool stp_online;
static struct stp_sstpi stp_info;
static void *stp_page;
@@ -1437,11 +1443,7 @@ static struct timer_list stp_timer;
static int __init early_parse_stp(char *p)
{
- if (strncmp(p, "off", 3) == 0)
- stp_online = 0;
- else if (strncmp(p, "on", 2) == 0)
- stp_online = 1;
- return 0;
+ return kstrtobool(p, &stp_online);
}
early_param("stp", early_parse_stp);
@@ -1457,8 +1459,7 @@ static void __init stp_reset(void)
if (rc == 0)
set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags);
else if (stp_online) {
- pr_warning("The real or virtual hardware system does "
- "not provide an STP interface\n");
+ pr_warn("The real or virtual hardware system does not provide an STP interface\n");
free_page((unsigned long) stp_page);
stp_page = NULL;
stp_online = 0;
@@ -1504,10 +1505,10 @@ static void stp_timing_alert(struct stp_irq_parm *intparm)
* After a STP sync check the clock is not in sync. The machine check
* is broadcasted to all cpus at the same time.
*/
-void stp_sync_check(void)
+int stp_sync_check(void)
{
disable_sync_clock(NULL);
- queue_work(time_sync_wq, &stp_work);
+ return 1;
}
/*
@@ -1516,12 +1517,16 @@ void stp_sync_check(void)
* have matching CTN ids and have a valid stratum-1 configuration
* but the configurations do not match.
*/
-void stp_island_check(void)
+int stp_island_check(void)
{
disable_sync_clock(NULL);
- queue_work(time_sync_wq, &stp_work);
+ return 1;
}
+void stp_queue_work(void)
+{
+ queue_work(time_sync_wq, &stp_work);
+}
static int stp_sync_clock(void *data)
{
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index bf05e7f..64298a8 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -37,7 +37,7 @@ static void set_topology_timer(void);
static void topology_work_fn(struct work_struct *work);
static struct sysinfo_15_1_x *tl_info;
-static int topology_enabled = 1;
+static bool topology_enabled = true;
static DECLARE_WORK(topology_work, topology_work_fn);
/*
@@ -84,6 +84,7 @@ static struct mask_info *add_cpus_to_mask(struct topology_core *tl_core,
struct mask_info *socket,
int one_socket_per_cpu)
{
+ struct cpu_topology_s390 *topo;
unsigned int core;
for_each_set_bit(core, &tl_core->mask[0], TOPOLOGY_CORE_BITS) {
@@ -95,15 +96,16 @@ static struct mask_info *add_cpus_to_mask(struct topology_core *tl_core,
if (lcpu < 0)
continue;
for (i = 0; i <= smp_cpu_mtid; i++) {
- per_cpu(cpu_topology, lcpu + i).book_id = book->id;
- per_cpu(cpu_topology, lcpu + i).core_id = rcore;
- per_cpu(cpu_topology, lcpu + i).thread_id = lcpu + i;
+ topo = &per_cpu(cpu_topology, lcpu + i);
+ topo->book_id = book->id;
+ topo->core_id = rcore;
+ topo->thread_id = lcpu + i;
cpumask_set_cpu(lcpu + i, &book->mask);
cpumask_set_cpu(lcpu + i, &socket->mask);
if (one_socket_per_cpu)
- per_cpu(cpu_topology, lcpu + i).socket_id = rcore;
+ topo->socket_id = rcore;
else
- per_cpu(cpu_topology, lcpu + i).socket_id = socket->id;
+ topo->socket_id = socket->id;
smp_cpu_set_polarization(lcpu + i, tl_core->pp);
}
if (one_socket_per_cpu)
@@ -247,17 +249,19 @@ int topology_set_cpu_management(int fc)
static void update_cpu_masks(void)
{
+ struct cpu_topology_s390 *topo;
int cpu;
for_each_possible_cpu(cpu) {
- per_cpu(cpu_topology, cpu).thread_mask = cpu_thread_map(cpu);
- per_cpu(cpu_topology, cpu).core_mask = cpu_group_map(&socket_info, cpu);
- per_cpu(cpu_topology, cpu).book_mask = cpu_group_map(&book_info, cpu);
+ topo = &per_cpu(cpu_topology, cpu);
+ topo->thread_mask = cpu_thread_map(cpu);
+ topo->core_mask = cpu_group_map(&socket_info, cpu);
+ topo->book_mask = cpu_group_map(&book_info, cpu);
if (!MACHINE_HAS_TOPOLOGY) {
- per_cpu(cpu_topology, cpu).thread_id = cpu;
- per_cpu(cpu_topology, cpu).core_id = cpu;
- per_cpu(cpu_topology, cpu).socket_id = cpu;
- per_cpu(cpu_topology, cpu).book_id = cpu;
+ topo->thread_id = cpu;
+ topo->core_id = cpu;
+ topo->socket_id = cpu;
+ topo->book_id = cpu;
}
}
numa_update_cpu_topology();
@@ -440,10 +444,7 @@ static const struct cpumask *cpu_book_mask(int cpu)
static int __init early_parse_topology(char *p)
{
- if (strncmp(p, "off", 3))
- return 0;
- topology_enabled = 0;
- return 0;
+ return kstrtobool(p, &topology_enabled);
}
early_param("topology", early_parse_topology);
diff --git a/arch/s390/kernel/trace.c b/arch/s390/kernel/trace.c
new file mode 100644
index 0000000..dde7654
--- /dev/null
+++ b/arch/s390/kernel/trace.c
@@ -0,0 +1,32 @@
+/*
+ * Tracepoint definitions for s390
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/percpu.h>
+#define CREATE_TRACE_POINTS
+#include <asm/trace/diag.h>
+
+EXPORT_TRACEPOINT_SYMBOL(s390_diagnose);
+
+static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
+
+void trace_s390_diagnose_norecursion(int diag_nr)
+{
+ unsigned long flags;
+ unsigned int *depth;
+
+ /* Avoid lockdep recursion. */
+ if (IS_ENABLED(CONFIG_LOCKDEP))
+ return;
+ local_irq_save(flags);
+ depth = this_cpu_ptr(&diagnose_trace_depth);
+ if (*depth == 0) {
+ (*depth)++;
+ trace_s390_diagnose(diag_nr);
+ (*depth)--;
+ }
+ local_irq_restore(flags);
+}
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 9861613..dd97a3e 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -19,11 +19,9 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/fpu-internal.h>
+#include <asm/fpu/api.h>
#include "entry.h"
-int show_unhandled_signals = 1;
-
static inline void __user *get_trap_ip(struct pt_regs *regs)
{
unsigned long address;
@@ -32,23 +30,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs)
address = *(unsigned long *)(current->thread.trap_tdb + 24);
else
address = regs->psw.addr;
- return (void __user *)
- ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN);
-}
-
-static inline void report_user_fault(struct pt_regs *regs, int signr)
-{
- if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
- return;
- if (!unhandled_signal(current, signr))
- return;
- if (!printk_ratelimit())
- return;
- printk("User process fault: interruption code %04x ilc:%d ",
- regs->int_code & 0xffff, regs->int_code >> 17);
- print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
- printk("\n");
- show_regs(regs);
+ return (void __user *) (address - (regs->int_code >> 16));
}
int is_valid_bugaddr(unsigned long addr)
@@ -66,16 +48,16 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
info.si_code = si_code;
info.si_addr = get_trap_ip(regs);
force_sig_info(si_signo, &info, current);
- report_user_fault(regs, si_signo);
+ report_user_fault(regs, si_signo, 0);
} else {
const struct exception_table_entry *fixup;
- fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
+ fixup = search_exception_tables(regs->psw.addr);
if (fixup)
- regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE;
+ regs->psw.addr = extable_fixup(fixup);
else {
enum bug_trap_type btt;
- btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
+ btt = report_bug(regs->psw.addr, regs);
if (btt == BUG_TRAP_TYPE_WARN)
return;
die(regs, str);
@@ -112,7 +94,7 @@ NOKPROBE_SYMBOL(do_per_trap);
void default_trap_handler(struct pt_regs *regs)
{
if (user_mode(regs)) {
- report_user_fault(regs, SIGSEGV);
+ report_user_fault(regs, SIGSEGV, 0);
do_exit(SIGSEGV);
} else
die(regs, "Unknown program exception");
@@ -224,29 +206,6 @@ NOKPROBE_SYMBOL(illegal_op);
DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
"specification exception");
-int alloc_vector_registers(struct task_struct *tsk)
-{
- __vector128 *vxrs;
- freg_t *fprs;
-
- /* Allocate vector register save area. */
- vxrs = kzalloc(sizeof(__vector128) * __NUM_VXRS,
- GFP_KERNEL|__GFP_REPEAT);
- if (!vxrs)
- return -ENOMEM;
- preempt_disable();
- if (tsk == current)
- save_fpu_regs();
- /* Copy the 16 floating point registers */
- convert_fp_to_vx(vxrs, tsk->thread.fpu.fprs);
- fprs = tsk->thread.fpu.fprs;
- tsk->thread.fpu.vxrs = vxrs;
- tsk->thread.fpu.flags |= FPU_USE_VX;
- kfree(fprs);
- preempt_enable();
- return 0;
-}
-
void vector_exception(struct pt_regs *regs)
{
int si_code, vic;
@@ -281,30 +240,11 @@ void vector_exception(struct pt_regs *regs)
do_trap(regs, SIGFPE, si_code, "vector exception");
}
-static int __init disable_vector_extension(char *str)
-{
- S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX;
- return 1;
-}
-__setup("novx", disable_vector_extension);
-
void data_exception(struct pt_regs *regs)
{
- __u16 __user *location;
int signal = 0;
- location = get_trap_ip(regs);
-
save_fpu_regs();
- /* Check for vector register enablement */
- if (MACHINE_HAS_VX && !is_vx_task(current) &&
- (current->thread.fpu.fpc & FPC_DXC_MASK) == 0xfe00) {
- alloc_vector_registers(current);
- /* Vector data exception is suppressing, rewind psw. */
- regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16);
- clear_pt_regs_flag(regs, PIF_PER_TRAP);
- return;
- }
if (current->thread.fpu.fpc & FPC_DXC_MASK)
signal = SIGFPE;
else
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 0d58269..94495ca 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
/*
* Setup vdso data page.
*/
-static void vdso_init_data(struct vdso_data *vd)
+static void __init vdso_init_data(struct vdso_data *vd)
{
vd->ectg_available = test_facility(31);
}
@@ -90,9 +90,10 @@ static void vdso_init_data(struct vdso_data *vd)
*/
#define SEGMENT_ORDER 2
-int vdso_alloc_per_cpu(struct _lowcore *lowcore)
+int vdso_alloc_per_cpu(struct lowcore *lowcore)
{
unsigned long segment_table, page_table, page_frame;
+ struct vdso_per_cpu_data *vd;
u32 *psal, *aste;
int i;
@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
if (!segment_table || !page_table || !page_frame)
goto out;
+ /* Initialize per-cpu vdso data page */
+ vd = (struct vdso_per_cpu_data *) page_frame;
+ vd->cpu_nr = lowcore->cpu_nr;
+ vd->node_id = cpu_to_node(vd->cpu_nr);
+
+ /* Set up access register mode page table */
clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY,
PAGE_SIZE << SEGMENT_ORDER);
clear_table((unsigned long *) page_table, _PAGE_INVALID,
@@ -138,7 +145,7 @@ out:
return -ENOMEM;
}
-void vdso_free_per_cpu(struct _lowcore *lowcore)
+void vdso_free_per_cpu(struct lowcore *lowcore)
{
unsigned long segment_table, page_table, page_frame;
u32 *psal, *aste;
@@ -163,7 +170,7 @@ static void vdso_init_cr5(void)
if (!vdso_enabled)
return;
- cr5 = offsetof(struct _lowcore, paste);
+ cr5 = offsetof(struct lowcore, paste);
__ctl_load(cr5, 5, 5);
}
@@ -299,8 +306,6 @@ static int __init vdso_init(void)
get_page(virt_to_page(vdso_data));
- smp_wmb();
-
return 0;
}
early_initcall(vdso_init);
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index ee8a18e..f9c4595 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -1,6 +1,6 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o
+obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules
diff --git a/arch/s390/kernel/vdso32/getcpu.S b/arch/s390/kernel/vdso32/getcpu.S
new file mode 100644
index 0000000..c1ed0b7
--- /dev/null
+++ b/arch/s390/kernel/vdso32/getcpu.S
@@ -0,0 +1,43 @@
+/*
+ * Userland implementation of getcpu() for 32 bits processes in a
+ * s390 kernel for use in the vDSO
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+#include <asm/vdso.h>
+#include <asm/asm-offsets.h>
+
+ .text
+ .align 4
+ .globl __kernel_getcpu
+ .type __kernel_getcpu,@function
+__kernel_getcpu:
+ .cfi_startproc
+ ear %r1,%a4
+ lhi %r4,1
+ sll %r4,24
+ sar %a4,%r4
+ la %r4,0
+ epsw %r0,0
+ sacf 512
+ l %r5,__VDSO_CPU_NR(%r4)
+ l %r4,__VDSO_NODE_ID(%r4)
+ tml %r0,0x4000
+ jo 1f
+ tml %r0,0x8000
+ jno 0f
+ sacf 256
+ j 1f
+0: sacf 0
+1: sar %a4,%r1
+ ltr %r2,%r2
+ jz 2f
+ st %r5,0(%r2)
+2: ltr %r3,%r3
+ jz 3f
+ st %r4,0(%r3)
+3: lhi %r2,0
+ br %r14
+ .cfi_endproc
+ .size __kernel_getcpu,.-__kernel_getcpu
diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S
index a8c379f..8f048c2 100644
--- a/arch/s390/kernel/vdso32/vdso32.lds.S
+++ b/arch/s390/kernel/vdso32/vdso32.lds.S
@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday;
__kernel_clock_gettime;
__kernel_clock_getres;
+ __kernel_getcpu;
local: *;
};
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index c4b03f9..058659c 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -1,6 +1,6 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o
+obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules
diff --git a/arch/s390/kernel/vdso64/getcpu.S b/arch/s390/kernel/vdso64/getcpu.S
new file mode 100644
index 0000000..4cbe982
--- /dev/null
+++ b/arch/s390/kernel/vdso64/getcpu.S
@@ -0,0 +1,42 @@
+/*
+ * Userland implementation of getcpu() for 64 bits processes in a
+ * s390 kernel for use in the vDSO
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+#include <asm/vdso.h>
+#include <asm/asm-offsets.h>
+
+ .text
+ .align 4
+ .globl __kernel_getcpu
+ .type __kernel_getcpu,@function
+__kernel_getcpu:
+ .cfi_startproc
+ ear %r1,%a4
+ llilh %r4,0x0100
+ sar %a4,%r4
+ la %r4,0
+ epsw %r0,0
+ sacf 512
+ l %r5,__VDSO_CPU_NR(%r4)
+ l %r4,__VDSO_NODE_ID(%r4)
+ tml %r0,0x4000
+ jo 1f
+ tml %r0,0x8000
+ jno 0f
+ sacf 256
+ j 1f
+0: sacf 0
+1: sar %a4,%r1
+ ltgr %r2,%r2
+ jz 2f
+ st %r5,0(%r2)
+2: ltgr %r3,%r3
+ jz 3f
+ st %r4,0(%r3)
+3: lghi %r2,0
+ br %r14
+ .cfi_endproc
+ .size __kernel_getcpu,.-__kernel_getcpu
diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S
index 9f5979d..f35455d 100644
--- a/arch/s390/kernel/vdso64/vdso64.lds.S
+++ b/arch/s390/kernel/vdso64/vdso64.lds.S
@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday;
__kernel_clock_gettime;
__kernel_clock_getres;
+ __kernel_getcpu;
local: *;
};
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 5fce52c..5ea5af3 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -29,6 +29,7 @@ config KVM
select HAVE_KVM_IRQFD
select HAVE_KVM_IRQ_ROUTING
select SRCU
+ select KVM_VFIO
---help---
Support hosting paravirtualized guest machines using the SIE
virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
index b3b5534..d42fa38 100644
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -7,7 +7,7 @@
# as published by the Free Software Foundation.
KVM := ../../../virt/kvm
-common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o
+common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o $(KVM)/vfio.o
ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 5fbfb88..1ea4095 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -14,6 +14,7 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <asm/pgalloc.h>
+#include <asm/gmap.h>
#include <asm/virtio-ccw.h>
#include "kvm-s390.h"
#include "trace.h"
@@ -155,10 +156,8 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu)
static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu)
{
- struct kvm *kvm = vcpu->kvm;
struct kvm_vcpu *tcpu;
int tid;
- int i;
tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
vcpu->stat.diagnose_9c++;
@@ -167,12 +166,9 @@ static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu)
if (tid == vcpu->vcpu_id)
return 0;
- kvm_for_each_vcpu(i, tcpu, kvm)
- if (tcpu->vcpu_id == tid) {
- kvm_vcpu_yield_to(tcpu);
- break;
- }
-
+ tcpu = kvm_get_vcpu_by_id(vcpu->kvm, tid);
+ if (tcpu)
+ kvm_vcpu_yield_to(tcpu);
return 0;
}
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index a7559f7..66938d2 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -259,10 +259,14 @@ struct aste {
int ipte_lock_held(struct kvm_vcpu *vcpu)
{
- union ipte_control *ic = &vcpu->kvm->arch.sca->ipte_control;
+ if (vcpu->arch.sie_block->eca & 1) {
+ int rc;
- if (vcpu->arch.sie_block->eca & 1)
- return ic->kh != 0;
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ rc = kvm_s390_get_ipte_control(vcpu->kvm)->kh != 0;
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+ return rc;
+ }
return vcpu->kvm->arch.ipte_lock_count != 0;
}
@@ -274,16 +278,20 @@ static void ipte_lock_simple(struct kvm_vcpu *vcpu)
vcpu->kvm->arch.ipte_lock_count++;
if (vcpu->kvm->arch.ipte_lock_count > 1)
goto out;
- ic = &vcpu->kvm->arch.sca->ipte_control;
+retry:
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ ic = kvm_s390_get_ipte_control(vcpu->kvm);
do {
old = READ_ONCE(*ic);
- while (old.k) {
+ if (old.k) {
+ read_unlock(&vcpu->kvm->arch.sca_lock);
cond_resched();
- old = READ_ONCE(*ic);
+ goto retry;
}
new = old;
new.k = 1;
} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
+ read_unlock(&vcpu->kvm->arch.sca_lock);
out:
mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
}
@@ -296,12 +304,14 @@ static void ipte_unlock_simple(struct kvm_vcpu *vcpu)
vcpu->kvm->arch.ipte_lock_count--;
if (vcpu->kvm->arch.ipte_lock_count)
goto out;
- ic = &vcpu->kvm->arch.sca->ipte_control;
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ ic = kvm_s390_get_ipte_control(vcpu->kvm);
do {
old = READ_ONCE(*ic);
new = old;
new.k = 0;
} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
+ read_unlock(&vcpu->kvm->arch.sca_lock);
wake_up(&vcpu->kvm->arch.ipte_wq);
out:
mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
@@ -311,24 +321,29 @@ static void ipte_lock_siif(struct kvm_vcpu *vcpu)
{
union ipte_control old, new, *ic;
- ic = &vcpu->kvm->arch.sca->ipte_control;
+retry:
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ ic = kvm_s390_get_ipte_control(vcpu->kvm);
do {
old = READ_ONCE(*ic);
- while (old.kg) {
+ if (old.kg) {
+ read_unlock(&vcpu->kvm->arch.sca_lock);
cond_resched();
- old = READ_ONCE(*ic);
+ goto retry;
}
new = old;
new.k = 1;
new.kh++;
} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
+ read_unlock(&vcpu->kvm->arch.sca_lock);
}
static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
{
union ipte_control old, new, *ic;
- ic = &vcpu->kvm->arch.sca->ipte_control;
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ ic = kvm_s390_get_ipte_control(vcpu->kvm);
do {
old = READ_ONCE(*ic);
new = old;
@@ -336,6 +351,7 @@ static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
if (!new.kh)
new.k = 0;
} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
+ read_unlock(&vcpu->kvm->arch.sca_lock);
if (!new.kh)
wake_up(&vcpu->kvm->arch.ipte_wq);
}
@@ -357,7 +373,7 @@ void ipte_unlock(struct kvm_vcpu *vcpu)
}
static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar,
- int write)
+ enum gacc_mode mode)
{
union alet alet;
struct ale ale;
@@ -438,7 +454,7 @@ static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar,
}
}
- if (ale.fo == 1 && write)
+ if (ale.fo == 1 && mode == GACC_STORE)
return PGM_PROTECTION;
asce->val = aste.asce;
@@ -461,25 +477,28 @@ enum {
};
static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
- ar_t ar, int write)
+ ar_t ar, enum gacc_mode mode)
{
int rc;
- psw_t *psw = &vcpu->arch.sie_block->gpsw;
+ struct psw_bits psw = psw_bits(vcpu->arch.sie_block->gpsw);
struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
struct trans_exc_code_bits *tec_bits;
memset(pgm, 0, sizeof(*pgm));
tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
- tec_bits->fsi = write ? FSI_STORE : FSI_FETCH;
- tec_bits->as = psw_bits(*psw).as;
+ tec_bits->fsi = mode == GACC_STORE ? FSI_STORE : FSI_FETCH;
+ tec_bits->as = psw.as;
- if (!psw_bits(*psw).t) {
+ if (!psw.t) {
asce->val = 0;
asce->r = 1;
return 0;
}
- switch (psw_bits(vcpu->arch.sie_block->gpsw).as) {
+ if (mode == GACC_IFETCH)
+ psw.as = psw.as == PSW_AS_HOME ? PSW_AS_HOME : PSW_AS_PRIMARY;
+
+ switch (psw.as) {
case PSW_AS_PRIMARY:
asce->val = vcpu->arch.sie_block->gcr[1];
return 0;
@@ -490,7 +509,7 @@ static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
asce->val = vcpu->arch.sie_block->gcr[13];
return 0;
case PSW_AS_ACCREG:
- rc = ar_translation(vcpu, asce, ar, write);
+ rc = ar_translation(vcpu, asce, ar, mode);
switch (rc) {
case PGM_ALEN_TRANSLATION:
case PGM_ALE_SEQUENCE:
@@ -522,7 +541,7 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val)
* @gva: guest virtual address
* @gpa: points to where guest physical (absolute) address should be stored
* @asce: effective asce
- * @write: indicates if access is a write access
+ * @mode: indicates the access mode to be used
*
* Translate a guest virtual address into a guest absolute address by means
* of dynamic address translation as specified by the architecture.
@@ -538,7 +557,7 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val)
*/
static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
unsigned long *gpa, const union asce asce,
- int write)
+ enum gacc_mode mode)
{
union vaddress vaddr = {.addr = gva};
union raddress raddr = {.addr = gva};
@@ -683,7 +702,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
real_address:
raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr);
absolute_address:
- if (write && dat_protection)
+ if (mode == GACC_STORE && dat_protection)
return PGM_PROTECTION;
if (kvm_is_error_gpa(vcpu->kvm, raddr.addr))
return PGM_ADDRESSING;
@@ -712,7 +731,7 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga,
unsigned long *pages, unsigned long nr_pages,
- const union asce asce, int write)
+ const union asce asce, enum gacc_mode mode)
{
struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
psw_t *psw = &vcpu->arch.sie_block->gpsw;
@@ -724,13 +743,13 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga,
while (nr_pages) {
ga = kvm_s390_logical_to_effective(vcpu, ga);
tec_bits->addr = ga >> PAGE_SHIFT;
- if (write && lap_enabled && is_low_address(ga)) {
+ if (mode == GACC_STORE && lap_enabled && is_low_address(ga)) {
pgm->code = PGM_PROTECTION;
return pgm->code;
}
ga &= PAGE_MASK;
if (psw_bits(*psw).t) {
- rc = guest_translate(vcpu, ga, pages, asce, write);
+ rc = guest_translate(vcpu, ga, pages, asce, mode);
if (rc < 0)
return rc;
if (rc == PGM_PROTECTION)
@@ -752,7 +771,7 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga,
}
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
- unsigned long len, int write)
+ unsigned long len, enum gacc_mode mode)
{
psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned long _len, nr_pages, gpa, idx;
@@ -764,7 +783,7 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
if (!len)
return 0;
- rc = get_vcpu_asce(vcpu, &asce, ar, write);
+ rc = get_vcpu_asce(vcpu, &asce, ar, mode);
if (rc)
return rc;
nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
@@ -776,11 +795,11 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
need_ipte_lock = psw_bits(*psw).t && !asce.r;
if (need_ipte_lock)
ipte_lock(vcpu);
- rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, write);
+ rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, mode);
for (idx = 0; idx < nr_pages && !rc; idx++) {
gpa = *(pages + idx) + (ga & ~PAGE_MASK);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
- if (write)
+ if (mode == GACC_STORE)
rc = kvm_write_guest(vcpu->kvm, gpa, data, _len);
else
rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
@@ -796,7 +815,7 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
}
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
- void *data, unsigned long len, int write)
+ void *data, unsigned long len, enum gacc_mode mode)
{
unsigned long _len, gpa;
int rc = 0;
@@ -804,7 +823,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
while (len && !rc) {
gpa = kvm_s390_real_to_abs(vcpu, gra);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
- if (write)
+ if (mode)
rc = write_guest_abs(vcpu, gpa, data, _len);
else
rc = read_guest_abs(vcpu, gpa, data, _len);
@@ -825,7 +844,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
* has to take care of this.
*/
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
- unsigned long *gpa, int write)
+ unsigned long *gpa, enum gacc_mode mode)
{
struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
psw_t *psw = &vcpu->arch.sie_block->gpsw;
@@ -835,19 +854,19 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
gva = kvm_s390_logical_to_effective(vcpu, gva);
tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
- rc = get_vcpu_asce(vcpu, &asce, ar, write);
+ rc = get_vcpu_asce(vcpu, &asce, ar, mode);
tec->addr = gva >> PAGE_SHIFT;
if (rc)
return rc;
if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) {
- if (write) {
+ if (mode == GACC_STORE) {
rc = pgm->code = PGM_PROTECTION;
return rc;
}
}
if (psw_bits(*psw).t && !asce.r) { /* Use DAT? */
- rc = guest_translate(vcpu, gva, gpa, asce, write);
+ rc = guest_translate(vcpu, gva, gpa, asce, mode);
if (rc > 0) {
if (rc == PGM_PROTECTION)
tec->b61 = 1;
@@ -867,7 +886,7 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
* check_gva_range - test a range of guest virtual addresses for accessibility
*/
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
- unsigned long length, int is_write)
+ unsigned long length, enum gacc_mode mode)
{
unsigned long gpa;
unsigned long currlen;
@@ -876,7 +895,7 @@ int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
ipte_lock(vcpu);
while (length > 0 && !rc) {
currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
- rc = guest_translate_address(vcpu, gva, ar, &gpa, is_write);
+ rc = guest_translate_address(vcpu, gva, ar, &gpa, mode);
gva += currlen;
length -= currlen;
}
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index ef03726..df0a79d 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -155,16 +155,22 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
return kvm_read_guest(vcpu->kvm, gpa, data, len);
}
+enum gacc_mode {
+ GACC_FETCH,
+ GACC_STORE,
+ GACC_IFETCH,
+};
+
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
- ar_t ar, unsigned long *gpa, int write);
+ ar_t ar, unsigned long *gpa, enum gacc_mode mode);
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
- unsigned long length, int is_write);
+ unsigned long length, enum gacc_mode mode);
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
- unsigned long len, int write);
+ unsigned long len, enum gacc_mode mode);
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
- void *data, unsigned long len, int write);
+ void *data, unsigned long len, enum gacc_mode mode);
/**
* write_guest - copy data from kernel space to guest space
@@ -215,7 +221,7 @@ static inline __must_check
int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
unsigned long len)
{
- return access_guest(vcpu, ga, ar, data, len, 1);
+ return access_guest(vcpu, ga, ar, data, len, GACC_STORE);
}
/**
@@ -235,7 +241,27 @@ static inline __must_check
int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
unsigned long len)
{
- return access_guest(vcpu, ga, ar, data, len, 0);
+ return access_guest(vcpu, ga, ar, data, len, GACC_FETCH);
+}
+
+/**
+ * read_guest_instr - copy instruction data from guest space to kernel space
+ * @vcpu: virtual cpu
+ * @data: destination address in kernel space
+ * @len: number of bytes to copy
+ *
+ * Copy @len bytes from the current psw address (guest space) to @data (kernel
+ * space).
+ *
+ * The behaviour of read_guest_instr is identical to read_guest, except that
+ * instruction data will be read from primary space when in home-space or
+ * address-space mode.
+ */
+static inline __must_check
+int read_guest_instr(struct kvm_vcpu *vcpu, void *data, unsigned long len)
+{
+ return access_guest(vcpu, vcpu->arch.sie_block->gpsw.addr, 0, data, len,
+ GACC_IFETCH);
}
/**
diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c
index 47518a3..e8c6843 100644
--- a/arch/s390/kvm/guestdbg.c
+++ b/arch/s390/kvm/guestdbg.c
@@ -17,7 +17,7 @@
/*
* Extends the address range given by *start and *stop to include the address
* range starting with estart and the length len. Takes care of overflowing
- * intervals and tries to minimize the overall intervall size.
+ * intervals and tries to minimize the overall interval size.
*/
static void extend_address_range(u64 *start, u64 *stop, u64 estart, int len)
{
@@ -72,7 +72,7 @@ static void enable_all_hw_bp(struct kvm_vcpu *vcpu)
return;
/*
- * If the guest is not interrested in branching events, we can savely
+ * If the guest is not interested in branching events, we can safely
* limit them to the PER address range.
*/
if (!(*cr9 & PER_EVENT_BRANCH))
@@ -116,7 +116,7 @@ static void enable_all_hw_wp(struct kvm_vcpu *vcpu)
if (*cr9 & PER_EVENT_STORE && *cr9 & PER_CONTROL_ALTERATION) {
*cr9 &= ~PER_CONTROL_ALTERATION;
*cr10 = 0;
- *cr11 = PSW_ADDR_INSN;
+ *cr11 = -1UL;
} else {
*cr9 &= ~PER_CONTROL_ALTERATION;
*cr9 |= PER_EVENT_STORE;
@@ -159,7 +159,7 @@ void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->gcr[0] &= ~0x800ul;
vcpu->arch.sie_block->gcr[9] |= PER_EVENT_IFETCH;
vcpu->arch.sie_block->gcr[10] = 0;
- vcpu->arch.sie_block->gcr[11] = PSW_ADDR_INSN;
+ vcpu->arch.sie_block->gcr[11] = -1UL;
}
if (guestdbg_hw_bp_enabled(vcpu)) {
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 7365e8a..2e6b54e 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -38,25 +38,37 @@ static const intercept_handler_t instruction_handlers[256] = {
[0xeb] = kvm_s390_handle_eb,
};
-void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc)
+u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
{
struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
+ u8 ilen = 0;
- /* Use the length of the EXECUTE instruction if necessary */
- if (sie_block->icptstatus & 1) {
- ilc = (sie_block->icptstatus >> 4) & 0x6;
- if (!ilc)
- ilc = 4;
+ switch (vcpu->arch.sie_block->icptcode) {
+ case ICPT_INST:
+ case ICPT_INSTPROGI:
+ case ICPT_OPEREXC:
+ case ICPT_PARTEXEC:
+ case ICPT_IOINST:
+ /* instruction only stored for these icptcodes */
+ ilen = insn_length(vcpu->arch.sie_block->ipa >> 8);
+ /* Use the length of the EXECUTE instruction if necessary */
+ if (sie_block->icptstatus & 1) {
+ ilen = (sie_block->icptstatus >> 4) & 0x6;
+ if (!ilen)
+ ilen = 4;
+ }
+ break;
+ case ICPT_PROGI:
+ /* bit 1+2 of pgmilc are the ilc, so we directly get ilen */
+ ilen = vcpu->arch.sie_block->pgmilc & 0x6;
+ break;
}
- sie_block->gpsw.addr = __rewind_psw(sie_block->gpsw, ilc);
+ return ilen;
}
static int handle_noop(struct kvm_vcpu *vcpu)
{
switch (vcpu->arch.sie_block->icptcode) {
- case 0x0:
- vcpu->stat.exit_null++;
- break;
case 0x10:
vcpu->stat.exit_external_request++;
break;
@@ -124,11 +136,13 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
return -EOPNOTSUPP;
}
-static void __extract_prog_irq(struct kvm_vcpu *vcpu,
- struct kvm_s390_pgm_info *pgm_info)
+static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu)
{
- memset(pgm_info, 0, sizeof(struct kvm_s390_pgm_info));
- pgm_info->code = vcpu->arch.sie_block->iprcc;
+ struct kvm_s390_pgm_info pgm_info = {
+ .code = vcpu->arch.sie_block->iprcc,
+ /* the PSW has already been rewound */
+ .flags = KVM_S390_PGM_FLAGS_NO_REWIND,
+ };
switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) {
case PGM_AFX_TRANSLATION:
@@ -141,7 +155,7 @@ static void __extract_prog_irq(struct kvm_vcpu *vcpu,
case PGM_PRIMARY_AUTHORITY:
case PGM_SECONDARY_AUTHORITY:
case PGM_SPACE_SWITCH:
- pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
+ pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc;
break;
case PGM_ALEN_TRANSLATION:
case PGM_ALE_SEQUENCE:
@@ -149,7 +163,7 @@ static void __extract_prog_irq(struct kvm_vcpu *vcpu,
case PGM_ASTE_SEQUENCE:
case PGM_ASTE_VALIDITY:
case PGM_EXTENDED_AUTHORITY:
- pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
+ pgm_info.exc_access_id = vcpu->arch.sie_block->eai;
break;
case PGM_ASCE_TYPE:
case PGM_PAGE_TRANSLATION:
@@ -157,32 +171,33 @@ static void __extract_prog_irq(struct kvm_vcpu *vcpu,
case PGM_REGION_SECOND_TRANS:
case PGM_REGION_THIRD_TRANS:
case PGM_SEGMENT_TRANSLATION:
- pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
- pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
- pgm_info->op_access_id = vcpu->arch.sie_block->oai;
+ pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc;
+ pgm_info.exc_access_id = vcpu->arch.sie_block->eai;
+ pgm_info.op_access_id = vcpu->arch.sie_block->oai;
break;
case PGM_MONITOR:
- pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn;
- pgm_info->mon_code = vcpu->arch.sie_block->tecmc;
+ pgm_info.mon_class_nr = vcpu->arch.sie_block->mcn;
+ pgm_info.mon_code = vcpu->arch.sie_block->tecmc;
break;
case PGM_VECTOR_PROCESSING:
case PGM_DATA:
- pgm_info->data_exc_code = vcpu->arch.sie_block->dxc;
+ pgm_info.data_exc_code = vcpu->arch.sie_block->dxc;
break;
case PGM_PROTECTION:
- pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc;
- pgm_info->exc_access_id = vcpu->arch.sie_block->eai;
+ pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc;
+ pgm_info.exc_access_id = vcpu->arch.sie_block->eai;
break;
default:
break;
}
if (vcpu->arch.sie_block->iprcc & PGM_PER) {
- pgm_info->per_code = vcpu->arch.sie_block->perc;
- pgm_info->per_atmid = vcpu->arch.sie_block->peratmid;
- pgm_info->per_address = vcpu->arch.sie_block->peraddr;
- pgm_info->per_access_id = vcpu->arch.sie_block->peraid;
+ pgm_info.per_code = vcpu->arch.sie_block->perc;
+ pgm_info.per_atmid = vcpu->arch.sie_block->peratmid;
+ pgm_info.per_address = vcpu->arch.sie_block->peraddr;
+ pgm_info.per_access_id = vcpu->arch.sie_block->peraid;
}
+ return kvm_s390_inject_prog_irq(vcpu, &pgm_info);
}
/*
@@ -211,7 +226,6 @@ static int handle_itdb(struct kvm_vcpu *vcpu)
static int handle_prog(struct kvm_vcpu *vcpu)
{
- struct kvm_s390_pgm_info pgm_info;
psw_t psw;
int rc;
@@ -237,8 +251,7 @@ static int handle_prog(struct kvm_vcpu *vcpu)
if (rc)
return rc;
- __extract_prog_irq(vcpu, &pgm_info);
- return kvm_s390_inject_prog_irq(vcpu, &pgm_info);
+ return inject_prog_on_prog_intercept(vcpu);
}
/**
@@ -305,7 +318,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
/* Make sure that the source is paged-in */
rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2],
- reg2, &srcaddr, 0);
+ reg2, &srcaddr, GACC_FETCH);
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0);
@@ -314,14 +327,14 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
/* Make sure that the destination is paged-in */
rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1],
- reg1, &dstaddr, 1);
+ reg1, &dstaddr, GACC_STORE);
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1);
if (rc != 0)
return rc;
- kvm_s390_rewind_psw(vcpu, 4);
+ kvm_s390_retry_instr(vcpu);
return 0;
}
@@ -336,28 +349,30 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
return -EOPNOTSUPP;
}
-static const intercept_handler_t intercept_funcs[] = {
- [0x00 >> 2] = handle_noop,
- [0x04 >> 2] = handle_instruction,
- [0x08 >> 2] = handle_prog,
- [0x10 >> 2] = handle_noop,
- [0x14 >> 2] = handle_external_interrupt,
- [0x18 >> 2] = handle_noop,
- [0x1C >> 2] = kvm_s390_handle_wait,
- [0x20 >> 2] = handle_validity,
- [0x28 >> 2] = handle_stop,
- [0x38 >> 2] = handle_partial_execution,
-};
-
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
{
- intercept_handler_t func;
- u8 code = vcpu->arch.sie_block->icptcode;
+ if (kvm_is_ucontrol(vcpu->kvm))
+ return -EOPNOTSUPP;
- if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
+ switch (vcpu->arch.sie_block->icptcode) {
+ case 0x10:
+ case 0x18:
+ return handle_noop(vcpu);
+ case 0x04:
+ return handle_instruction(vcpu);
+ case 0x08:
+ return handle_prog(vcpu);
+ case 0x14:
+ return handle_external_interrupt(vcpu);
+ case 0x1c:
+ return kvm_s390_handle_wait(vcpu);
+ case 0x20:
+ return handle_validity(vcpu);
+ case 0x28:
+ return handle_stop(vcpu);
+ case 0x38:
+ return handle_partial_execution(vcpu);
+ default:
return -EOPNOTSUPP;
- func = intercept_funcs[code >> 2];
- if (func)
- return func(vcpu);
- return -EOPNOTSUPP;
+ }
}
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 5c2c169..84efc2b 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -23,6 +23,7 @@
#include <asm/uaccess.h>
#include <asm/sclp.h>
#include <asm/isc.h>
+#include <asm/gmap.h>
#include "kvm-s390.h"
#include "gaccess.h"
#include "trace-s390.h"
@@ -34,6 +35,106 @@
#define PFAULT_DONE 0x0680
#define VIRTIO_PARAM 0x0d00
+/* handle external calls via sigp interpretation facility */
+static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
+{
+ int c, scn;
+
+ if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_ECALL_PEND))
+ return 0;
+
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ if (vcpu->kvm->arch.use_esca) {
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+ union esca_sigp_ctrl sigp_ctrl =
+ sca->cpu[vcpu->vcpu_id].sigp_ctrl;
+
+ c = sigp_ctrl.c;
+ scn = sigp_ctrl.scn;
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl sigp_ctrl =
+ sca->cpu[vcpu->vcpu_id].sigp_ctrl;
+
+ c = sigp_ctrl.c;
+ scn = sigp_ctrl.scn;
+ }
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+
+ if (src_id)
+ *src_id = scn;
+
+ return c;
+}
+
+static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
+{
+ int expect, rc;
+
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ if (vcpu->kvm->arch.use_esca) {
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+ union esca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union esca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
+
+ new_val.scn = src_id;
+ new_val.c = 1;
+ old_val.c = 0;
+
+ expect = old_val.value;
+ rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value);
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
+
+ new_val.scn = src_id;
+ new_val.c = 1;
+ old_val.c = 0;
+
+ expect = old_val.value;
+ rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value);
+ }
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+
+ if (rc != expect) {
+ /* another external call is pending */
+ return -EBUSY;
+ }
+ atomic_or(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags);
+ return 0;
+}
+
+static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
+{
+ struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
+ int rc, expect;
+
+ atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags);
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ if (vcpu->kvm->arch.use_esca) {
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+ union esca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union esca_sigp_ctrl old = *sigp_ctrl;
+
+ expect = old.value;
+ rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl *sigp_ctrl =
+ &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union bsca_sigp_ctrl old = *sigp_ctrl;
+
+ expect = old.value;
+ rc = cmpxchg(&sigp_ctrl->value, old.value, 0);
+ }
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+ WARN_ON(rc != expect); /* cannot clear? */
+}
+
int psw_extint_disabled(struct kvm_vcpu *vcpu)
{
return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT);
@@ -51,11 +152,9 @@ static int psw_mchk_disabled(struct kvm_vcpu *vcpu)
static int psw_interrupts_disabled(struct kvm_vcpu *vcpu)
{
- if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) ||
- (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO) ||
- (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT))
- return 0;
- return 1;
+ return psw_extint_disabled(vcpu) &&
+ psw_ioint_disabled(vcpu) &&
+ psw_mchk_disabled(vcpu);
}
static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
@@ -71,13 +170,8 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
static int ckc_irq_pending(struct kvm_vcpu *vcpu)
{
- preempt_disable();
- if (!(vcpu->arch.sie_block->ckc <
- get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) {
- preempt_enable();
+ if (vcpu->arch.sie_block->ckc >= kvm_s390_get_tod_clock_fast(vcpu->kvm))
return 0;
- }
- preempt_enable();
return ckc_interrupts_enabled(vcpu);
}
@@ -89,8 +183,9 @@ static int cpu_timer_interrupts_enabled(struct kvm_vcpu *vcpu)
static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
{
- return (vcpu->arch.sie_block->cputm >> 63) &&
- cpu_timer_interrupts_enabled(vcpu);
+ if (!cpu_timer_interrupts_enabled(vcpu))
+ return 0;
+ return kvm_s390_get_cpu_timer(vcpu) >> 63;
}
static inline int is_ioirq(unsigned long irq_type)
@@ -109,14 +204,10 @@ static inline u8 int_word_to_isc(u32 int_word)
return (int_word & 0x38000000) >> 27;
}
-static inline unsigned long pending_floating_irqs(struct kvm_vcpu *vcpu)
-{
- return vcpu->kvm->arch.float_int.pending_irqs;
-}
-
-static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu)
+static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.local_int.pending_irqs;
+ return vcpu->kvm->arch.float_int.pending_irqs |
+ vcpu->arch.local_int.pending_irqs;
}
static unsigned long disable_iscs(struct kvm_vcpu *vcpu,
@@ -135,8 +226,7 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu)
{
unsigned long active_mask;
- active_mask = pending_local_irqs(vcpu);
- active_mask |= pending_floating_irqs(vcpu);
+ active_mask = pending_irqs(vcpu);
if (!active_mask)
return 0;
@@ -204,7 +294,7 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag)
static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
{
- if (!(pending_floating_irqs(vcpu) & IRQ_PEND_IO_MASK))
+ if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK))
return;
else if (psw_ioint_disabled(vcpu))
__set_cpuflag(vcpu, CPUSTAT_IO_INT);
@@ -214,7 +304,7 @@ static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu)
{
- if (!(pending_local_irqs(vcpu) & IRQ_PEND_EXT_MASK))
+ if (!(pending_irqs(vcpu) & IRQ_PEND_EXT_MASK))
return;
if (psw_extint_disabled(vcpu))
__set_cpuflag(vcpu, CPUSTAT_EXT_INT);
@@ -224,7 +314,7 @@ static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu)
static void set_intercept_indicators_mchk(struct kvm_vcpu *vcpu)
{
- if (!(pending_local_irqs(vcpu) & IRQ_PEND_MCHK_MASK))
+ if (!(pending_irqs(vcpu) & IRQ_PEND_MCHK_MASK))
return;
if (psw_mchk_disabled(vcpu))
vcpu->arch.sie_block->ictl |= ICTL_LPSW;
@@ -247,23 +337,6 @@ static void set_intercept_indicators(struct kvm_vcpu *vcpu)
set_intercept_indicators_stop(vcpu);
}
-static u16 get_ilc(struct kvm_vcpu *vcpu)
-{
- switch (vcpu->arch.sie_block->icptcode) {
- case ICPT_INST:
- case ICPT_INSTPROGI:
- case ICPT_OPEREXC:
- case ICPT_PARTEXEC:
- case ICPT_IOINST:
- /* last instruction only stored for these icptcodes */
- return insn_length(vcpu->arch.sie_block->ipa >> 8);
- case ICPT_PROGI:
- return vcpu->arch.sie_block->pgmilc;
- default:
- return 0;
- }
-}
-
static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
@@ -411,9 +484,9 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu)
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0);
rc = write_guest_lc(vcpu,
- offsetof(struct _lowcore, restart_old_psw),
+ offsetof(struct lowcore, restart_old_psw),
&vcpu->arch.sie_block->gpsw, sizeof(psw_t));
- rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw),
+ rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw),
&vcpu->arch.sie_block->gpsw, sizeof(psw_t));
clear_bit(IRQ_PEND_RESTART, &li->pending_irqs);
return rc ? -EFAULT : 0;
@@ -500,7 +573,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_pgm_info pgm_info;
int rc = 0, nullifying = false;
- u16 ilc = get_ilc(vcpu);
+ u16 ilen;
spin_lock(&li->lock);
pgm_info = li->irq.pgm;
@@ -508,8 +581,9 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
memset(&li->irq.pgm, 0, sizeof(pgm_info));
spin_unlock(&li->lock);
- VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilc:%d",
- pgm_info.code, ilc);
+ ilen = pgm_info.flags & KVM_S390_PGM_FLAGS_ILC_MASK;
+ VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilen:%d",
+ pgm_info.code, ilen);
vcpu->stat.deliver_program_int++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
pgm_info.code, 0);
@@ -593,10 +667,11 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
(u8 *) __LC_PER_ACCESS_ID);
}
- if (nullifying && vcpu->arch.sie_block->icptcode == ICPT_INST)
- kvm_s390_rewind_psw(vcpu, ilc);
+ if (nullifying && !(pgm_info.flags & KVM_S390_PGM_FLAGS_NO_REWIND))
+ kvm_s390_rewind_psw(vcpu, ilen);
- rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC);
+ /* bit 1+2 of the target are the ilc, so we can directly use ilen */
+ rc |= put_guest_lc(vcpu, ilen, (u16 *) __LC_PGM_ILC);
rc |= put_guest_lc(vcpu, vcpu->arch.sie_block->gbea,
(u64 *) __LC_LAST_BREAK);
rc |= put_guest_lc(vcpu, pgm_info.code,
@@ -804,34 +879,30 @@ static const deliver_irq_t deliver_irq_funcs[] = {
int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
- uint8_t sigp_ctrl = vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl;
if (!sclp.has_sigpif)
return test_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs);
- return (sigp_ctrl & SIGP_CTRL_C) &&
- (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_ECALL_PEND);
+ return sca_ext_call_pending(vcpu, NULL);
}
int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop)
{
- int rc;
+ if (deliverable_irqs(vcpu))
+ return 1;
- rc = !!deliverable_irqs(vcpu);
-
- if (!rc && kvm_cpu_has_pending_timer(vcpu))
- rc = 1;
+ if (kvm_cpu_has_pending_timer(vcpu))
+ return 1;
/* external call pending and deliverable */
- if (!rc && kvm_s390_ext_call_pending(vcpu) &&
+ if (kvm_s390_ext_call_pending(vcpu) &&
!psw_extint_disabled(vcpu) &&
(vcpu->arch.sie_block->gcr[0] & 0x2000ul))
- rc = 1;
-
- if (!rc && !exclude_stop && kvm_s390_is_stop_irq_pending(vcpu))
- rc = 1;
+ return 1;
- return rc;
+ if (!exclude_stop && kvm_s390_is_stop_irq_pending(vcpu))
+ return 1;
+ return 0;
}
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -839,14 +910,40 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
return ckc_irq_pending(vcpu) || cpu_timer_irq_pending(vcpu);
}
+static u64 __calculate_sltime(struct kvm_vcpu *vcpu)
+{
+ u64 now, cputm, sltime = 0;
+
+ if (ckc_interrupts_enabled(vcpu)) {
+ now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
+ sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
+ /* already expired or overflow? */
+ if (!sltime || vcpu->arch.sie_block->ckc <= now)
+ return 0;
+ if (cpu_timer_interrupts_enabled(vcpu)) {
+ cputm = kvm_s390_get_cpu_timer(vcpu);
+ /* already expired? */
+ if (cputm >> 63)
+ return 0;
+ return min(sltime, tod_to_ns(cputm));
+ }
+ } else if (cpu_timer_interrupts_enabled(vcpu)) {
+ sltime = kvm_s390_get_cpu_timer(vcpu);
+ /* already expired? */
+ if (sltime >> 63)
+ return 0;
+ }
+ return sltime;
+}
+
int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
{
- u64 now, sltime;
+ u64 sltime;
vcpu->stat.exit_wait_state++;
/* fast path */
- if (kvm_cpu_has_pending_timer(vcpu) || kvm_arch_vcpu_runnable(vcpu))
+ if (kvm_arch_vcpu_runnable(vcpu))
return 0;
if (psw_interrupts_disabled(vcpu)) {
@@ -854,24 +951,20 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
return -EOPNOTSUPP; /* disabled wait */
}
- if (!ckc_interrupts_enabled(vcpu)) {
+ if (!ckc_interrupts_enabled(vcpu) &&
+ !cpu_timer_interrupts_enabled(vcpu)) {
VCPU_EVENT(vcpu, 3, "%s", "enabled wait w/o timer");
__set_cpu_idle(vcpu);
goto no_timer;
}
- preempt_disable();
- now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
- preempt_enable();
- sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
-
- /* underflow */
- if (vcpu->arch.sie_block->ckc < now)
+ sltime = __calculate_sltime(vcpu);
+ if (!sltime)
return 0;
__set_cpu_idle(vcpu);
hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL);
- VCPU_EVENT(vcpu, 4, "enabled wait via clock comparator: %llu ns", sltime);
+ VCPU_EVENT(vcpu, 4, "enabled wait: %llu ns", sltime);
no_timer:
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
kvm_vcpu_block(vcpu);
@@ -884,13 +977,13 @@ no_timer:
void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu)
{
- if (waitqueue_active(&vcpu->wq)) {
+ if (swait_active(&vcpu->wq)) {
/*
* The vcpu gave up the cpu voluntarily, mark it as a good
* yield-candidate.
*/
vcpu->preempted = true;
- wake_up_interruptible(&vcpu->wq);
+ swake_up(&vcpu->wq);
vcpu->stat.halt_wakeup++;
}
}
@@ -898,20 +991,16 @@ void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu)
enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer)
{
struct kvm_vcpu *vcpu;
- u64 now, sltime;
+ u64 sltime;
vcpu = container_of(timer, struct kvm_vcpu, arch.ckc_timer);
- preempt_disable();
- now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
- preempt_enable();
- sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
+ sltime = __calculate_sltime(vcpu);
/*
* If the monotonic clock runs faster than the tod clock we might be
* woken up too early and have to go back to sleep to avoid deadlocks.
*/
- if (vcpu->arch.sie_block->ckc > now &&
- hrtimer_forward_now(timer, ns_to_ktime(sltime)))
+ if (sltime && hrtimer_forward_now(timer, ns_to_ktime(sltime)))
return HRTIMER_RESTART;
kvm_s390_vcpu_wakeup(vcpu);
return HRTIMER_NORESTART;
@@ -927,9 +1016,7 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
memset(&li->irq, 0, sizeof(li->irq));
spin_unlock(&li->lock);
- /* clear pending external calls set by sigp interpretation facility */
- atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags);
- vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl = 0;
+ sca_clear_ext_call(vcpu);
}
int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
@@ -981,39 +1068,39 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
irq->u.pgm.code, 0);
- li->irq.pgm = irq->u.pgm;
- set_bit(IRQ_PEND_PROG, &li->pending_irqs);
- return 0;
-}
-
-int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
-{
- struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
- struct kvm_s390_irq irq;
+ if (!(irq->u.pgm.flags & KVM_S390_PGM_FLAGS_ILC_VALID)) {
+ /* auto detection if no valid ILC was given */
+ irq->u.pgm.flags &= ~KVM_S390_PGM_FLAGS_ILC_MASK;
+ irq->u.pgm.flags |= kvm_s390_get_ilen(vcpu);
+ irq->u.pgm.flags |= KVM_S390_PGM_FLAGS_ILC_VALID;
+ }
- spin_lock(&li->lock);
- irq.u.pgm.code = code;
- __inject_prog(vcpu, &irq);
- BUG_ON(waitqueue_active(li->wq));
- spin_unlock(&li->lock);
+ if (irq->u.pgm.code == PGM_PER) {
+ li->irq.pgm.code |= PGM_PER;
+ li->irq.pgm.flags = irq->u.pgm.flags;
+ /* only modify PER related information */
+ li->irq.pgm.per_address = irq->u.pgm.per_address;
+ li->irq.pgm.per_code = irq->u.pgm.per_code;
+ li->irq.pgm.per_atmid = irq->u.pgm.per_atmid;
+ li->irq.pgm.per_access_id = irq->u.pgm.per_access_id;
+ } else if (!(irq->u.pgm.code & PGM_PER)) {
+ li->irq.pgm.code = (li->irq.pgm.code & PGM_PER) |
+ irq->u.pgm.code;
+ li->irq.pgm.flags = irq->u.pgm.flags;
+ /* only modify non-PER information */
+ li->irq.pgm.trans_exc_code = irq->u.pgm.trans_exc_code;
+ li->irq.pgm.mon_code = irq->u.pgm.mon_code;
+ li->irq.pgm.data_exc_code = irq->u.pgm.data_exc_code;
+ li->irq.pgm.mon_class_nr = irq->u.pgm.mon_class_nr;
+ li->irq.pgm.exc_access_id = irq->u.pgm.exc_access_id;
+ li->irq.pgm.op_access_id = irq->u.pgm.op_access_id;
+ } else {
+ li->irq.pgm = irq->u.pgm;
+ }
+ set_bit(IRQ_PEND_PROG, &li->pending_irqs);
return 0;
}
-int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
- struct kvm_s390_pgm_info *pgm_info)
-{
- struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
- struct kvm_s390_irq irq;
- int rc;
-
- spin_lock(&li->lock);
- irq.u.pgm = *pgm_info;
- rc = __inject_prog(vcpu, &irq);
- BUG_ON(waitqueue_active(li->wq));
- spin_unlock(&li->lock);
- return rc;
-}
-
static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
@@ -1030,21 +1117,6 @@ static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
return 0;
}
-static int __inject_extcall_sigpif(struct kvm_vcpu *vcpu, uint16_t src_id)
-{
- unsigned char new_val, old_val;
- uint8_t *sigp_ctrl = &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl;
-
- new_val = SIGP_CTRL_C | (src_id & SIGP_CTRL_SCN_MASK);
- old_val = *sigp_ctrl & ~SIGP_CTRL_C;
- if (cmpxchg(sigp_ctrl, old_val, new_val) != old_val) {
- /* another external call is pending */
- return -EBUSY;
- }
- atomic_or(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags);
- return 0;
-}
-
static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
@@ -1057,12 +1129,11 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
src_id, 0);
/* sending vcpu invalid */
- if (src_id >= KVM_MAX_VCPUS ||
- kvm_get_vcpu(vcpu->kvm, src_id) == NULL)
+ if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL)
return -EINVAL;
if (sclp.has_sigpif)
- return __inject_extcall_sigpif(vcpu, src_id);
+ return sca_inject_ext_call(vcpu, src_id);
if (test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs))
return -EBUSY;
@@ -1137,6 +1208,10 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
irq->u.emerg.code, 0);
+ /* sending vcpu invalid */
+ if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL)
+ return -EINVAL;
+
set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
@@ -1390,12 +1465,9 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
{
- struct kvm_s390_float_interrupt *fi;
u64 type = READ_ONCE(inti->type);
int rc;
- fi = &kvm->arch.float_int;
-
switch (type) {
case KVM_S390_MCHK:
rc = __inject_float_mchk(kvm, inti);
@@ -2230,7 +2302,7 @@ static void store_local_irq(struct kvm_s390_local_interrupt *li,
int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len)
{
- uint8_t sigp_ctrl = vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl;
+ int scn;
unsigned long sigp_emerg_pending[BITS_TO_LONGS(KVM_MAX_VCPUS)];
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
unsigned long pending_irqs;
@@ -2270,14 +2342,12 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len)
}
}
- if ((sigp_ctrl & SIGP_CTRL_C) &&
- (atomic_read(&vcpu->arch.sie_block->cpuflags) &
- CPUSTAT_ECALL_PEND)) {
+ if (sca_ext_call_pending(vcpu, &scn)) {
if (n + sizeof(irq) > len)
return -ENOBUFS;
memset(&irq, 0, sizeof(irq));
irq.type = KVM_S390_INT_EXTERNAL_CALL;
- irq.u.extcall.code = sigp_ctrl & SIGP_CTRL_SCN_MASK;
+ irq.u.extcall.code = scn;
if (copy_to_user(&buf[n], &irq, sizeof(irq)))
return -EFAULT;
n += sizeof(irq);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 0a67c40..668c087 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -30,6 +30,7 @@
#include <asm/lowcore.h>
#include <asm/etr.h>
#include <asm/pgtable.h>
+#include <asm/gmap.h>
#include <asm/nmi.h>
#include <asm/switch_to.h>
#include <asm/isc.h>
@@ -158,6 +159,8 @@ static int kvm_clock_sync(struct notifier_block *notifier, unsigned long val,
kvm->arch.epoch -= *delta;
kvm_for_each_vcpu(i, vcpu, kvm) {
vcpu->arch.sie_block->epoch -= *delta;
+ if (vcpu->arch.cputm_enabled)
+ vcpu->arch.cputm_start += *delta;
}
}
return NOTIFY_OK;
@@ -246,7 +249,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
break;
case KVM_CAP_NR_VCPUS:
case KVM_CAP_MAX_VCPUS:
- r = KVM_MAX_VCPUS;
+ r = sclp.has_esca ? KVM_S390_ESCA_CPU_SLOTS
+ : KVM_S390_BSCA_CPU_SLOTS;
break;
case KVM_CAP_NR_MEMSLOTS:
r = KVM_USER_MEM_SLOTS;
@@ -257,6 +261,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_S390_VECTOR_REGISTERS:
r = MACHINE_HAS_VX;
break;
+ case KVM_CAP_S390_RI:
+ r = test_facility(64);
+ break;
default:
r = 0;
}
@@ -270,19 +277,22 @@ static void kvm_s390_sync_dirty_log(struct kvm *kvm,
unsigned long address;
struct gmap *gmap = kvm->arch.gmap;
- down_read(&gmap->mm->mmap_sem);
/* Loop over all guest pages */
last_gfn = memslot->base_gfn + memslot->npages;
for (cur_gfn = memslot->base_gfn; cur_gfn <= last_gfn; cur_gfn++) {
address = gfn_to_hva_memslot(memslot, cur_gfn);
- if (gmap_test_and_clear_dirty(address, gmap))
+ if (test_and_clear_guest_dirty(gmap->mm, address))
mark_page_dirty(kvm, cur_gfn);
+ if (fatal_signal_pending(current))
+ return;
+ cond_resched();
}
- up_read(&gmap->mm->mmap_sem);
}
/* Section: vm related */
+static void sca_del_vcpu(struct kvm_vcpu *vcpu);
+
/*
* Get (and clear) the dirty memory log for a memory slot.
*/
@@ -342,15 +352,33 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
r = 0;
break;
case KVM_CAP_S390_VECTOR_REGISTERS:
- if (MACHINE_HAS_VX) {
- set_kvm_facility(kvm->arch.model.fac->mask, 129);
- set_kvm_facility(kvm->arch.model.fac->list, 129);
+ mutex_lock(&kvm->lock);
+ if (atomic_read(&kvm->online_vcpus)) {
+ r = -EBUSY;
+ } else if (MACHINE_HAS_VX) {
+ set_kvm_facility(kvm->arch.model.fac_mask, 129);
+ set_kvm_facility(kvm->arch.model.fac_list, 129);
r = 0;
} else
r = -EINVAL;
+ mutex_unlock(&kvm->lock);
VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s",
r ? "(not available)" : "(success)");
break;
+ case KVM_CAP_S390_RI:
+ r = -EINVAL;
+ mutex_lock(&kvm->lock);
+ if (atomic_read(&kvm->online_vcpus)) {
+ r = -EBUSY;
+ } else if (test_facility(64)) {
+ set_kvm_facility(kvm->arch.model.fac_mask, 64);
+ set_kvm_facility(kvm->arch.model.fac_list, 64);
+ r = 0;
+ }
+ mutex_unlock(&kvm->lock);
+ VM_EVENT(kvm, 3, "ENABLE: CAP_S390_RI %s",
+ r ? "(not available)" : "(success)");
+ break;
case KVM_CAP_S390_USER_STSI:
VM_EVENT(kvm, 3, "%s", "ENABLE: CAP_S390_USER_STSI");
kvm->arch.user_stsi = 1;
@@ -371,8 +399,8 @@ static int kvm_s390_get_mem_control(struct kvm *kvm, struct kvm_device_attr *att
case KVM_S390_VM_MEM_LIMIT_SIZE:
ret = 0;
VM_EVENT(kvm, 3, "QUERY: max guest memory: %lu bytes",
- kvm->arch.gmap->asce_end);
- if (put_user(kvm->arch.gmap->asce_end, (u64 __user *)attr->addr))
+ kvm->arch.mem_limit);
+ if (put_user(kvm->arch.mem_limit, (u64 __user *)attr->addr))
ret = -EFAULT;
break;
default:
@@ -424,9 +452,17 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
if (get_user(new_limit, (u64 __user *)attr->addr))
return -EFAULT;
- if (new_limit > kvm->arch.gmap->asce_end)
+ if (kvm->arch.mem_limit != KVM_S390_NO_MEM_LIMIT &&
+ new_limit > kvm->arch.mem_limit)
return -E2BIG;
+ if (!new_limit)
+ return -EINVAL;
+
+ /* gmap_alloc takes last usable address */
+ if (new_limit != KVM_S390_NO_MEM_LIMIT)
+ new_limit -= 1;
+
ret = -EBUSY;
mutex_lock(&kvm->lock);
if (atomic_read(&kvm->online_vcpus) == 0) {
@@ -443,7 +479,9 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
}
}
mutex_unlock(&kvm->lock);
- VM_EVENT(kvm, 3, "SET: max guest memory: %lu bytes", new_limit);
+ VM_EVENT(kvm, 3, "SET: max guest address: %lu", new_limit);
+ VM_EVENT(kvm, 3, "New guest asce: 0x%pK",
+ (void *) kvm->arch.gmap->asce);
break;
}
default:
@@ -514,35 +552,20 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
if (gtod_high != 0)
return -EINVAL;
- VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x\n", gtod_high);
+ VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x", gtod_high);
return 0;
}
static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
{
- struct kvm_vcpu *cur_vcpu;
- unsigned int vcpu_idx;
- u64 host_tod, gtod;
- int r;
+ u64 gtod;
if (copy_from_user(&gtod, (void __user *)attr->addr, sizeof(gtod)))
return -EFAULT;
- r = store_tod_clock(&host_tod);
- if (r)
- return r;
-
- mutex_lock(&kvm->lock);
- preempt_disable();
- kvm->arch.epoch = gtod - host_tod;
- kvm_s390_vcpu_block_all(kvm);
- kvm_for_each_vcpu(vcpu_idx, cur_vcpu, kvm)
- cur_vcpu->arch.sie_block->epoch = kvm->arch.epoch;
- kvm_s390_vcpu_unblock_all(kvm);
- preempt_enable();
- mutex_unlock(&kvm->lock);
- VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx\n", gtod);
+ kvm_s390_set_tod_clock(kvm, gtod);
+ VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod);
return 0;
}
@@ -574,26 +597,19 @@ static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
if (copy_to_user((void __user *)attr->addr, &gtod_high,
sizeof(gtod_high)))
return -EFAULT;
- VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x\n", gtod_high);
+ VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x", gtod_high);
return 0;
}
static int kvm_s390_get_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
{
- u64 host_tod, gtod;
- int r;
+ u64 gtod;
- r = store_tod_clock(&host_tod);
- if (r)
- return r;
-
- preempt_disable();
- gtod = host_tod + kvm->arch.epoch;
- preempt_enable();
+ gtod = kvm_s390_get_tod_clock_fast(kvm);
if (copy_to_user((void __user *)attr->addr, &gtod, sizeof(gtod)))
return -EFAULT;
- VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx\n", gtod);
+ VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx", gtod);
return 0;
}
@@ -639,7 +655,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr)
memcpy(&kvm->arch.model.cpu_id, &proc->cpuid,
sizeof(struct cpuid));
kvm->arch.model.ibc = proc->ibc;
- memcpy(kvm->arch.model.fac->list, proc->fac_list,
+ memcpy(kvm->arch.model.fac_list, proc->fac_list,
S390_ARCH_FAC_LIST_SIZE_BYTE);
} else
ret = -EFAULT;
@@ -673,7 +689,8 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr)
}
memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid));
proc->ibc = kvm->arch.model.ibc;
- memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE);
+ memcpy(&proc->fac_list, kvm->arch.model.fac_list,
+ S390_ARCH_FAC_LIST_SIZE_BYTE);
if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc)))
ret = -EFAULT;
kfree(proc);
@@ -693,7 +710,7 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr)
}
get_cpu_id((struct cpuid *) &mach->cpuid);
mach->ibc = sclp.ibc;
- memcpy(&mach->fac_mask, kvm->arch.model.fac->mask,
+ memcpy(&mach->fac_mask, kvm->arch.model.fac_mask,
S390_ARCH_FAC_LIST_SIZE_BYTE);
memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list,
S390_ARCH_FAC_LIST_SIZE_BYTE);
@@ -1042,7 +1059,7 @@ static int kvm_s390_apxa_installed(void)
u8 config[128];
int cc;
- if (test_facility(2) && test_facility(12)) {
+ if (test_facility(12)) {
cc = kvm_s390_query_ap_config(config);
if (cc)
@@ -1070,16 +1087,12 @@ static void kvm_s390_get_cpu_id(struct cpuid *cpu_id)
cpu_id->version = 0xff;
}
-static int kvm_s390_crypto_init(struct kvm *kvm)
+static void kvm_s390_crypto_init(struct kvm *kvm)
{
if (!test_kvm_facility(kvm, 76))
- return 0;
-
- kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb),
- GFP_KERNEL | GFP_DMA);
- if (!kvm->arch.crypto.crycb)
- return -ENOMEM;
+ return;
+ kvm->arch.crypto.crycb = &kvm->arch.sie_page2->crycb;
kvm_s390_set_crycb_format(kvm);
/* Enable AES/DEA protected key functions by default */
@@ -1089,8 +1102,15 @@ static int kvm_s390_crypto_init(struct kvm *kvm)
sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
get_random_bytes(kvm->arch.crypto.crycb->dea_wrapping_key_mask,
sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
+}
- return 0;
+static void sca_dispose(struct kvm *kvm)
+{
+ if (kvm->arch.use_esca)
+ free_pages_exact(kvm->arch.sca, sizeof(struct esca_block));
+ else
+ free_page((unsigned long)(kvm->arch.sca));
+ kvm->arch.sca = NULL;
}
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
@@ -1116,12 +1136,17 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
rc = -ENOMEM;
- kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
+ kvm->arch.use_esca = 0; /* start with basic SCA */
+ rwlock_init(&kvm->arch.sca_lock);
+ kvm->arch.sca = (struct bsca_block *) get_zeroed_page(GFP_KERNEL);
if (!kvm->arch.sca)
goto out_err;
spin_lock(&kvm_lock);
- sca_offset = (sca_offset + 16) & 0x7f0;
- kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset);
+ sca_offset += 16;
+ if (sca_offset + sizeof(struct bsca_block) > PAGE_SIZE)
+ sca_offset = 0;
+ kvm->arch.sca = (struct bsca_block *)
+ ((char *) kvm->arch.sca + sca_offset);
spin_unlock(&kvm_lock);
sprintf(debug_name, "kvm-%u", current->pid);
@@ -1130,37 +1155,30 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (!kvm->arch.dbf)
goto out_err;
- /*
- * The architectural maximum amount of facilities is 16 kbit. To store
- * this amount, 2 kbyte of memory is required. Thus we need a full
- * page to hold the guest facility list (arch.model.fac->list) and the
- * facility mask (arch.model.fac->mask). Its address size has to be
- * 31 bits and word aligned.
- */
- kvm->arch.model.fac =
- (struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
- if (!kvm->arch.model.fac)
+ kvm->arch.sie_page2 =
+ (struct sie_page2 *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
+ if (!kvm->arch.sie_page2)
goto out_err;
/* Populate the facility mask initially. */
- memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list,
+ memcpy(kvm->arch.model.fac_mask, S390_lowcore.stfle_fac_list,
S390_ARCH_FAC_LIST_SIZE_BYTE);
for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) {
if (i < kvm_s390_fac_list_mask_size())
- kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i];
+ kvm->arch.model.fac_mask[i] &= kvm_s390_fac_list_mask[i];
else
- kvm->arch.model.fac->mask[i] = 0UL;
+ kvm->arch.model.fac_mask[i] = 0UL;
}
/* Populate the facility list initially. */
- memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask,
+ kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list;
+ memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask,
S390_ARCH_FAC_LIST_SIZE_BYTE);
kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id);
kvm->arch.model.ibc = sclp.ibc & 0x0fff;
- if (kvm_s390_crypto_init(kvm) < 0)
- goto out_err;
+ kvm_s390_crypto_init(kvm);
spin_lock_init(&kvm->arch.float_int.lock);
for (i = 0; i < FIRQ_LIST_COUNT; i++)
@@ -1173,8 +1191,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (type & KVM_VM_S390_UCONTROL) {
kvm->arch.gmap = NULL;
+ kvm->arch.mem_limit = KVM_S390_NO_MEM_LIMIT;
} else {
- kvm->arch.gmap = gmap_alloc(current->mm, (1UL << 44) - 1);
+ if (sclp.hamax == U64_MAX)
+ kvm->arch.mem_limit = TASK_MAX_SIZE;
+ else
+ kvm->arch.mem_limit = min_t(unsigned long, TASK_MAX_SIZE,
+ sclp.hamax + 1);
+ kvm->arch.gmap = gmap_alloc(current->mm, kvm->arch.mem_limit - 1);
if (!kvm->arch.gmap)
goto out_err;
kvm->arch.gmap->private = kvm;
@@ -1186,14 +1210,13 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.epoch = 0;
spin_lock_init(&kvm->arch.start_stop_lock);
- KVM_EVENT(3, "vm 0x%p created by pid %u", kvm, current->pid);
+ KVM_EVENT(3, "vm 0x%pK created by pid %u", kvm, current->pid);
return 0;
out_err:
- kfree(kvm->arch.crypto.crycb);
- free_page((unsigned long)kvm->arch.model.fac);
+ free_page((unsigned long)kvm->arch.sie_page2);
debug_unregister(kvm->arch.dbf);
- free_page((unsigned long)(kvm->arch.sca));
+ sca_dispose(kvm);
KVM_EVENT(3, "creation of vm failed: %d", rc);
return rc;
}
@@ -1204,14 +1227,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id);
kvm_s390_clear_local_irqs(vcpu);
kvm_clear_async_pf_completion_queue(vcpu);
- if (!kvm_is_ucontrol(vcpu->kvm)) {
- clear_bit(63 - vcpu->vcpu_id,
- (unsigned long *) &vcpu->kvm->arch.sca->mcn);
- if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
- (__u64) vcpu->arch.sie_block)
- vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
- }
- smp_mb();
+ if (!kvm_is_ucontrol(vcpu->kvm))
+ sca_del_vcpu(vcpu);
if (kvm_is_ucontrol(vcpu->kvm))
gmap_free(vcpu->arch.gmap);
@@ -1243,15 +1260,14 @@ static void kvm_free_vcpus(struct kvm *kvm)
void kvm_arch_destroy_vm(struct kvm *kvm)
{
kvm_free_vcpus(kvm);
- free_page((unsigned long)kvm->arch.model.fac);
- free_page((unsigned long)(kvm->arch.sca));
+ sca_dispose(kvm);
debug_unregister(kvm->arch.dbf);
- kfree(kvm->arch.crypto.crycb);
+ free_page((unsigned long)kvm->arch.sie_page2);
if (!kvm_is_ucontrol(kvm))
gmap_free(kvm->arch.gmap);
kvm_s390_destroy_adapters(kvm);
kvm_s390_clear_float_irqs(kvm);
- KVM_EVENT(3, "vm 0x%p destroyed", kvm);
+ KVM_EVENT(3, "vm 0x%pK destroyed", kvm);
}
/* Section: vcpu related */
@@ -1265,6 +1281,117 @@ static int __kvm_ucontrol_vcpu_init(struct kvm_vcpu *vcpu)
return 0;
}
+static void sca_del_vcpu(struct kvm_vcpu *vcpu)
+{
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ if (vcpu->kvm->arch.use_esca) {
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+
+ clear_bit_inv(vcpu->vcpu_id, (unsigned long *) sca->mcn);
+ sca->cpu[vcpu->vcpu_id].sda = 0;
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+
+ clear_bit_inv(vcpu->vcpu_id, (unsigned long *) &sca->mcn);
+ sca->cpu[vcpu->vcpu_id].sda = 0;
+ }
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+}
+
+static void sca_add_vcpu(struct kvm_vcpu *vcpu)
+{
+ read_lock(&vcpu->kvm->arch.sca_lock);
+ if (vcpu->kvm->arch.use_esca) {
+ struct esca_block *sca = vcpu->kvm->arch.sca;
+
+ sca->cpu[vcpu->vcpu_id].sda = (__u64) vcpu->arch.sie_block;
+ vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32);
+ vcpu->arch.sie_block->scaol = (__u32)(__u64)sca & ~0x3fU;
+ vcpu->arch.sie_block->ecb2 |= 0x04U;
+ set_bit_inv(vcpu->vcpu_id, (unsigned long *) sca->mcn);
+ } else {
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+
+ sca->cpu[vcpu->vcpu_id].sda = (__u64) vcpu->arch.sie_block;
+ vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32);
+ vcpu->arch.sie_block->scaol = (__u32)(__u64)sca;
+ set_bit_inv(vcpu->vcpu_id, (unsigned long *) &sca->mcn);
+ }
+ read_unlock(&vcpu->kvm->arch.sca_lock);
+}
+
+/* Basic SCA to Extended SCA data copy routines */
+static inline void sca_copy_entry(struct esca_entry *d, struct bsca_entry *s)
+{
+ d->sda = s->sda;
+ d->sigp_ctrl.c = s->sigp_ctrl.c;
+ d->sigp_ctrl.scn = s->sigp_ctrl.scn;
+}
+
+static void sca_copy_b_to_e(struct esca_block *d, struct bsca_block *s)
+{
+ int i;
+
+ d->ipte_control = s->ipte_control;
+ d->mcn[0] = s->mcn;
+ for (i = 0; i < KVM_S390_BSCA_CPU_SLOTS; i++)
+ sca_copy_entry(&d->cpu[i], &s->cpu[i]);
+}
+
+static int sca_switch_to_extended(struct kvm *kvm)
+{
+ struct bsca_block *old_sca = kvm->arch.sca;
+ struct esca_block *new_sca;
+ struct kvm_vcpu *vcpu;
+ unsigned int vcpu_idx;
+ u32 scaol, scaoh;
+
+ new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL|__GFP_ZERO);
+ if (!new_sca)
+ return -ENOMEM;
+
+ scaoh = (u32)((u64)(new_sca) >> 32);
+ scaol = (u32)(u64)(new_sca) & ~0x3fU;
+
+ kvm_s390_vcpu_block_all(kvm);
+ write_lock(&kvm->arch.sca_lock);
+
+ sca_copy_b_to_e(new_sca, old_sca);
+
+ kvm_for_each_vcpu(vcpu_idx, vcpu, kvm) {
+ vcpu->arch.sie_block->scaoh = scaoh;
+ vcpu->arch.sie_block->scaol = scaol;
+ vcpu->arch.sie_block->ecb2 |= 0x04U;
+ }
+ kvm->arch.sca = new_sca;
+ kvm->arch.use_esca = 1;
+
+ write_unlock(&kvm->arch.sca_lock);
+ kvm_s390_vcpu_unblock_all(kvm);
+
+ free_page((unsigned long)old_sca);
+
+ VM_EVENT(kvm, 2, "Switched to ESCA (0x%pK -> 0x%pK)",
+ old_sca, kvm->arch.sca);
+ return 0;
+}
+
+static int sca_can_add_vcpu(struct kvm *kvm, unsigned int id)
+{
+ int rc;
+
+ if (id < KVM_S390_BSCA_CPU_SLOTS)
+ return true;
+ if (!sclp.has_esca)
+ return false;
+
+ mutex_lock(&kvm->lock);
+ rc = kvm->arch.use_esca ? 0 : sca_switch_to_extended(kvm);
+ mutex_unlock(&kvm->lock);
+
+ return rc == 0 && id < KVM_S390_ESCA_CPU_SLOTS;
+}
+
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
@@ -1275,8 +1402,15 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
KVM_SYNC_CRS |
KVM_SYNC_ARCH0 |
KVM_SYNC_PFAULT;
- if (test_kvm_facility(vcpu->kvm, 129))
+ if (test_kvm_facility(vcpu->kvm, 64))
+ vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
+ /* fprs can be synchronized via vrs, even if the guest has no vx. With
+ * MACHINE_HAS_VX, (load|store)_fpu_regs() will work with vrs format.
+ */
+ if (MACHINE_HAS_VX)
vcpu->run->kvm_valid_regs |= KVM_SYNC_VRS;
+ else
+ vcpu->run->kvm_valid_regs |= KVM_SYNC_FPRS;
if (kvm_is_ucontrol(vcpu->kvm))
return __kvm_ucontrol_vcpu_init(vcpu);
@@ -1284,49 +1418,105 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
return 0;
}
-/*
- * Backs up the current FP/VX register save area on a particular
- * destination. Used to switch between different register save
- * areas.
- */
-static inline void save_fpu_to(struct fpu *dst)
+/* needs disabled preemption to protect from TOD sync and vcpu_load/put */
+static void __start_cpu_timer_accounting(struct kvm_vcpu *vcpu)
{
- dst->fpc = current->thread.fpu.fpc;
- dst->flags = current->thread.fpu.flags;
- dst->regs = current->thread.fpu.regs;
+ WARN_ON_ONCE(vcpu->arch.cputm_start != 0);
+ raw_write_seqcount_begin(&vcpu->arch.cputm_seqcount);
+ vcpu->arch.cputm_start = get_tod_clock_fast();
+ raw_write_seqcount_end(&vcpu->arch.cputm_seqcount);
}
-/*
- * Switches the FP/VX register save area from which to lazy
- * restore register contents.
- */
-static inline void load_fpu_from(struct fpu *from)
+/* needs disabled preemption to protect from TOD sync and vcpu_load/put */
+static void __stop_cpu_timer_accounting(struct kvm_vcpu *vcpu)
{
- current->thread.fpu.fpc = from->fpc;
- current->thread.fpu.flags = from->flags;
- current->thread.fpu.regs = from->regs;
+ WARN_ON_ONCE(vcpu->arch.cputm_start == 0);
+ raw_write_seqcount_begin(&vcpu->arch.cputm_seqcount);
+ vcpu->arch.sie_block->cputm -= get_tod_clock_fast() - vcpu->arch.cputm_start;
+ vcpu->arch.cputm_start = 0;
+ raw_write_seqcount_end(&vcpu->arch.cputm_seqcount);
}
-void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+/* needs disabled preemption to protect from TOD sync and vcpu_load/put */
+static void __enable_cpu_timer_accounting(struct kvm_vcpu *vcpu)
{
- /* Save host register state */
- save_fpu_regs();
- save_fpu_to(&vcpu->arch.host_fpregs);
+ WARN_ON_ONCE(vcpu->arch.cputm_enabled);
+ vcpu->arch.cputm_enabled = true;
+ __start_cpu_timer_accounting(vcpu);
+}
- if (test_kvm_facility(vcpu->kvm, 129)) {
- current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
- current->thread.fpu.flags = FPU_USE_VX;
+/* needs disabled preemption to protect from TOD sync and vcpu_load/put */
+static void __disable_cpu_timer_accounting(struct kvm_vcpu *vcpu)
+{
+ WARN_ON_ONCE(!vcpu->arch.cputm_enabled);
+ __stop_cpu_timer_accounting(vcpu);
+ vcpu->arch.cputm_enabled = false;
+}
+
+static void enable_cpu_timer_accounting(struct kvm_vcpu *vcpu)
+{
+ preempt_disable(); /* protect from TOD sync and vcpu_load/put */
+ __enable_cpu_timer_accounting(vcpu);
+ preempt_enable();
+}
+
+static void disable_cpu_timer_accounting(struct kvm_vcpu *vcpu)
+{
+ preempt_disable(); /* protect from TOD sync and vcpu_load/put */
+ __disable_cpu_timer_accounting(vcpu);
+ preempt_enable();
+}
+
+/* set the cpu timer - may only be called from the VCPU thread itself */
+void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm)
+{
+ preempt_disable(); /* protect from TOD sync and vcpu_load/put */
+ raw_write_seqcount_begin(&vcpu->arch.cputm_seqcount);
+ if (vcpu->arch.cputm_enabled)
+ vcpu->arch.cputm_start = get_tod_clock_fast();
+ vcpu->arch.sie_block->cputm = cputm;
+ raw_write_seqcount_end(&vcpu->arch.cputm_seqcount);
+ preempt_enable();
+}
+
+/* update and get the cpu timer - can also be called from other VCPU threads */
+__u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu)
+{
+ unsigned int seq;
+ __u64 value;
+
+ if (unlikely(!vcpu->arch.cputm_enabled))
+ return vcpu->arch.sie_block->cputm;
+
+ preempt_disable(); /* protect from TOD sync and vcpu_load/put */
+ do {
+ seq = raw_read_seqcount(&vcpu->arch.cputm_seqcount);
/*
- * Use the register save area in the SIE-control block
- * for register restore and save in kvm_arch_vcpu_put()
+ * If the writer would ever execute a read in the critical
+ * section, e.g. in irq context, we have a deadlock.
*/
- current->thread.fpu.vxrs =
- (__vector128 *)&vcpu->run->s.regs.vrs;
- /* Always enable the vector extension for KVM */
- __ctl_set_vx();
- } else
- load_fpu_from(&vcpu->arch.guest_fpregs);
+ WARN_ON_ONCE((seq & 1) && smp_processor_id() == vcpu->cpu);
+ value = vcpu->arch.sie_block->cputm;
+ /* if cputm_start is 0, accounting is being started/stopped */
+ if (likely(vcpu->arch.cputm_start))
+ value -= get_tod_clock_fast() - vcpu->arch.cputm_start;
+ } while (read_seqcount_retry(&vcpu->arch.cputm_seqcount, seq & ~1));
+ preempt_enable();
+ return value;
+}
+void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+ /* Save host register state */
+ save_fpu_regs();
+ vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
+ vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
+
+ if (MACHINE_HAS_VX)
+ current->thread.fpu.regs = vcpu->run->s.regs.vrs;
+ else
+ current->thread.fpu.regs = vcpu->run->s.regs.fprs;
+ current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
if (test_fp_ctl(current->thread.fpu.fpc))
/* User space provided an invalid FPC, let's clear it */
current->thread.fpu.fpc = 0;
@@ -1335,26 +1525,26 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
restore_access_regs(vcpu->run->s.regs.acrs);
gmap_enable(vcpu->arch.gmap);
atomic_or(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+ if (vcpu->arch.cputm_enabled && !is_vcpu_idle(vcpu))
+ __start_cpu_timer_accounting(vcpu);
+ vcpu->cpu = cpu;
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
+ vcpu->cpu = -1;
+ if (vcpu->arch.cputm_enabled && !is_vcpu_idle(vcpu))
+ __stop_cpu_timer_accounting(vcpu);
atomic_andnot(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
gmap_disable(vcpu->arch.gmap);
+ /* Save guest register state */
save_fpu_regs();
+ vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
- if (test_kvm_facility(vcpu->kvm, 129))
- /*
- * kvm_arch_vcpu_load() set up the register save area to
- * the &vcpu->run->s.regs.vrs and, thus, the vector registers
- * are already saved. Only the floating-point control must be
- * copied.
- */
- vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
- else
- save_fpu_to(&vcpu->arch.guest_fpregs);
- load_fpu_from(&vcpu->arch.host_fpregs);
+ /* Restore host register state */
+ current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
+ current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
save_access_regs(vcpu->run->s.regs.acrs);
restore_access_regs(vcpu->arch.host_acrs);
@@ -1366,14 +1556,15 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->gpsw.mask = 0UL;
vcpu->arch.sie_block->gpsw.addr = 0UL;
kvm_s390_set_prefix(vcpu, 0);
- vcpu->arch.sie_block->cputm = 0UL;
+ kvm_s390_set_cpu_timer(vcpu, 0);
vcpu->arch.sie_block->ckc = 0UL;
vcpu->arch.sie_block->todpr = 0;
memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
vcpu->arch.sie_block->gcr[0] = 0xE0UL;
vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
- vcpu->arch.guest_fpregs.fpc = 0;
- asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
+ /* make sure the new fpc will be lazily loaded */
+ save_fpu_regs();
+ current->thread.fpu.fpc = 0;
vcpu->arch.sie_block->gbea = 1;
vcpu->arch.sie_block->pp = 0;
vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
@@ -1390,8 +1581,11 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->epoch = vcpu->kvm->arch.epoch;
preempt_enable();
mutex_unlock(&vcpu->kvm->lock);
- if (!kvm_is_ucontrol(vcpu->kvm))
+ if (!kvm_is_ucontrol(vcpu->kvm)) {
vcpu->arch.gmap = vcpu->kvm->arch.gmap;
+ sca_add_vcpu(vcpu);
+ }
+
}
static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
@@ -1432,7 +1626,8 @@ static void kvm_s390_vcpu_setup_model(struct kvm_vcpu *vcpu)
vcpu->arch.cpu_id = model->cpu_id;
vcpu->arch.sie_block->ibc = model->ibc;
- vcpu->arch.sie_block->fac = (int) (long) model->fac->list;
+ if (test_kvm_facility(vcpu->kvm, 7))
+ vcpu->arch.sie_block->fac = (u32)(u64) model->fac_list;
}
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
@@ -1460,10 +1655,13 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->eca |= 1;
if (sclp.has_sigpif)
vcpu->arch.sie_block->eca |= 0x10000000U;
+ if (test_kvm_facility(vcpu->kvm, 64))
+ vcpu->arch.sie_block->ecb3 |= 0x01;
if (test_kvm_facility(vcpu->kvm, 129)) {
vcpu->arch.sie_block->eca |= 0x00020000;
vcpu->arch.sie_block->ecd |= 0x20000000;
}
+ vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb;
vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE;
if (vcpu->kvm->arch.use_cmma) {
@@ -1486,7 +1684,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
struct sie_page *sie_page;
int rc = -EINVAL;
- if (id >= KVM_MAX_VCPUS)
+ if (!kvm_is_ucontrol(kvm) && !sca_can_add_vcpu(kvm, id))
goto out;
rc = -ENOMEM;
@@ -1503,42 +1701,16 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb;
vcpu->arch.sie_block->icpua = id;
- if (!kvm_is_ucontrol(kvm)) {
- if (!kvm->arch.sca) {
- WARN_ON_ONCE(1);
- goto out_free_cpu;
- }
- if (!kvm->arch.sca->cpu[id].sda)
- kvm->arch.sca->cpu[id].sda =
- (__u64) vcpu->arch.sie_block;
- vcpu->arch.sie_block->scaoh =
- (__u32)(((__u64)kvm->arch.sca) >> 32);
- vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
- set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
- }
-
spin_lock_init(&vcpu->arch.local_int.lock);
vcpu->arch.local_int.float_int = &kvm->arch.float_int;
vcpu->arch.local_int.wq = &vcpu->wq;
vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
-
- /*
- * Allocate a save area for floating-point registers. If the vector
- * extension is available, register contents are saved in the SIE
- * control block. The allocated save area is still required in
- * particular places, for example, in kvm_s390_vcpu_store_status().
- */
- vcpu->arch.guest_fpregs.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS,
- GFP_KERNEL);
- if (!vcpu->arch.guest_fpregs.fprs) {
- rc = -ENOMEM;
- goto out_free_sie_block;
- }
+ seqcount_init(&vcpu->arch.cputm_seqcount);
rc = kvm_vcpu_init(vcpu, kvm, id);
if (rc)
goto out_free_sie_block;
- VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
+ VM_EVENT(kvm, 3, "create cpu %d at 0x%pK, sie block at 0x%pK", id, vcpu,
vcpu->arch.sie_block);
trace_kvm_s390_create_vcpu(id, vcpu, vcpu->arch.sie_block);
@@ -1633,7 +1805,7 @@ static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
(u64 __user *)reg->addr);
break;
case KVM_REG_S390_CPU_TIMER:
- r = put_user(vcpu->arch.sie_block->cputm,
+ r = put_user(kvm_s390_get_cpu_timer(vcpu),
(u64 __user *)reg->addr);
break;
case KVM_REG_S390_CLOCK_COMP:
@@ -1671,6 +1843,7 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
struct kvm_one_reg *reg)
{
int r = -EINVAL;
+ __u64 val;
switch (reg->id) {
case KVM_REG_S390_TODPR:
@@ -1682,8 +1855,9 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
(u64 __user *)reg->addr);
break;
case KVM_REG_S390_CPU_TIMER:
- r = get_user(vcpu->arch.sie_block->cputm,
- (u64 __user *)reg->addr);
+ r = get_user(val, (u64 __user *)reg->addr);
+ if (!r)
+ kvm_s390_set_cpu_timer(vcpu, val);
break;
case KVM_REG_S390_CLOCK_COMP:
r = get_user(vcpu->arch.sie_block->ckc,
@@ -1755,19 +1929,27 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
+ /* make sure the new values will be lazily loaded */
+ save_fpu_regs();
if (test_fp_ctl(fpu->fpc))
return -EINVAL;
- memcpy(vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
- vcpu->arch.guest_fpregs.fpc = fpu->fpc;
- save_fpu_regs();
- load_fpu_from(&vcpu->arch.guest_fpregs);
+ current->thread.fpu.fpc = fpu->fpc;
+ if (MACHINE_HAS_VX)
+ convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs);
+ else
+ memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs));
return 0;
}
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- memcpy(&fpu->fprs, vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
- fpu->fpc = vcpu->arch.guest_fpregs.fpc;
+ /* make sure we have the latest values */
+ save_fpu_regs();
+ if (MACHINE_HAS_VX)
+ convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs);
+ else
+ memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs));
+ fpu->fpc = current->thread.fpu.fpc;
return 0;
}
@@ -1916,6 +2098,22 @@ retry:
return 0;
}
+void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod)
+{
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ mutex_lock(&kvm->lock);
+ preempt_disable();
+ kvm->arch.epoch = tod - get_tod_clock();
+ kvm_s390_vcpu_block_all(kvm);
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ vcpu->arch.sie_block->epoch = kvm->arch.epoch;
+ kvm_s390_vcpu_unblock_all(kvm);
+ preempt_enable();
+ mutex_unlock(&kvm->lock);
+}
+
/**
* kvm_arch_fault_in_page - fault-in guest page if necessary
* @vcpu: The corresponding virtual cpu
@@ -2018,7 +2216,8 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu)
*/
kvm_check_async_pf_completion(vcpu);
- memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
+ vcpu->arch.sie_block->gg14 = vcpu->run->s.regs.gprs[14];
+ vcpu->arch.sie_block->gg15 = vcpu->run->s.regs.gprs[15];
if (need_resched())
schedule();
@@ -2051,8 +2250,10 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu)
static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu)
{
- psw_t *psw = &vcpu->arch.sie_block->gpsw;
- u8 opcode;
+ struct kvm_s390_pgm_info pgm_info = {
+ .code = PGM_ADDRESSING,
+ };
+ u8 opcode, ilen;
int rc;
VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
@@ -2066,18 +2267,25 @@ static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu)
* to look up the current opcode to get the length of the instruction
* to be able to forward the PSW.
*/
- rc = read_guest(vcpu, psw->addr, 0, &opcode, 1);
- if (rc)
- return kvm_s390_inject_prog_cond(vcpu, rc);
- psw->addr = __rewind_psw(*psw, -insn_length(opcode));
-
- return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+ rc = read_guest_instr(vcpu, &opcode, 1);
+ ilen = insn_length(opcode);
+ if (rc < 0) {
+ return rc;
+ } else if (rc) {
+ /* Instruction-Fetching Exceptions - we can't detect the ilen.
+ * Forward by arbitrary ilc, injection will take care of
+ * nullification if necessary.
+ */
+ pgm_info = vcpu->arch.pgm;
+ ilen = 4;
+ }
+ pgm_info.flags = ilen | KVM_S390_PGM_FLAGS_ILC_VALID;
+ kvm_s390_forward_psw(vcpu, ilen);
+ return kvm_s390_inject_prog_irq(vcpu, &pgm_info);
}
static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
{
- int rc = -1;
-
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
vcpu->arch.sie_block->icptcode);
trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
@@ -2085,40 +2293,36 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
if (guestdbg_enabled(vcpu))
kvm_s390_restore_guest_per_regs(vcpu);
- if (exit_reason >= 0) {
- rc = 0;
+ vcpu->run->s.regs.gprs[14] = vcpu->arch.sie_block->gg14;
+ vcpu->run->s.regs.gprs[15] = vcpu->arch.sie_block->gg15;
+
+ if (vcpu->arch.sie_block->icptcode > 0) {
+ int rc = kvm_handle_sie_intercept(vcpu);
+
+ if (rc != -EOPNOTSUPP)
+ return rc;
+ vcpu->run->exit_reason = KVM_EXIT_S390_SIEIC;
+ vcpu->run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
+ vcpu->run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
+ vcpu->run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
+ return -EREMOTE;
+ } else if (exit_reason != -EFAULT) {
+ vcpu->stat.exit_null++;
+ return 0;
} else if (kvm_is_ucontrol(vcpu->kvm)) {
vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL;
vcpu->run->s390_ucontrol.trans_exc_code =
current->thread.gmap_addr;
vcpu->run->s390_ucontrol.pgm_code = 0x10;
- rc = -EREMOTE;
-
+ return -EREMOTE;
} else if (current->thread.gmap_pfault) {
trace_kvm_s390_major_guest_pfault(vcpu);
current->thread.gmap_pfault = 0;
- if (kvm_arch_setup_async_pf(vcpu)) {
- rc = 0;
- } else {
- gpa_t gpa = current->thread.gmap_addr;
- rc = kvm_arch_fault_in_page(vcpu, gpa, 1);
- }
- }
-
- if (rc == -1)
- rc = vcpu_post_run_fault_in_sie(vcpu);
-
- memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
-
- if (rc == 0) {
- if (kvm_is_ucontrol(vcpu->kvm))
- /* Don't exit for host interrupts. */
- rc = vcpu->arch.sie_block->icptcode ? -EOPNOTSUPP : 0;
- else
- rc = kvm_handle_sie_intercept(vcpu);
+ if (kvm_arch_setup_async_pf(vcpu))
+ return 0;
+ return kvm_arch_fault_in_page(vcpu, current->thread.gmap_addr, 1);
}
-
- return rc;
+ return vcpu_post_run_fault_in_sie(vcpu);
}
static int __vcpu_run(struct kvm_vcpu *vcpu)
@@ -2143,10 +2347,12 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
*/
local_irq_disable();
__kvm_guest_enter();
+ __disable_cpu_timer_accounting(vcpu);
local_irq_enable();
exit_reason = sie64a(vcpu->arch.sie_block,
vcpu->run->s.regs.gprs);
local_irq_disable();
+ __enable_cpu_timer_accounting(vcpu);
__kvm_guest_exit();
local_irq_enable();
vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
@@ -2170,7 +2376,7 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
}
if (kvm_run->kvm_dirty_regs & KVM_SYNC_ARCH0) {
- vcpu->arch.sie_block->cputm = kvm_run->s.regs.cputm;
+ kvm_s390_set_cpu_timer(vcpu, kvm_run->s.regs.cputm);
vcpu->arch.sie_block->ckc = kvm_run->s.regs.ckc;
vcpu->arch.sie_block->todpr = kvm_run->s.regs.todpr;
vcpu->arch.sie_block->pp = kvm_run->s.regs.pp;
@@ -2192,7 +2398,7 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
kvm_run->s.regs.prefix = kvm_s390_get_prefix(vcpu);
memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
- kvm_run->s.regs.cputm = vcpu->arch.sie_block->cputm;
+ kvm_run->s.regs.cputm = kvm_s390_get_cpu_timer(vcpu);
kvm_run->s.regs.ckc = vcpu->arch.sie_block->ckc;
kvm_run->s.regs.todpr = vcpu->arch.sie_block->todpr;
kvm_run->s.regs.pp = vcpu->arch.sie_block->pp;
@@ -2224,6 +2430,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
sync_regs(vcpu, kvm_run);
+ enable_cpu_timer_accounting(vcpu);
might_fault();
rc = __vcpu_run(vcpu);
@@ -2238,21 +2445,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
rc = 0;
}
- if (rc == -EOPNOTSUPP) {
- /* intercept cannot be handled in-kernel, prepare kvm-run */
- kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
- kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
- kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
- kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
- rc = 0;
- }
-
if (rc == -EREMOTE) {
- /* intercept was handled, but userspace support is needed
- * kvm_run has been prepared by the handler */
+ /* userspace support is needed, kvm_run has been prepared */
rc = 0;
}
+ disable_cpu_timer_accounting(vcpu);
store_regs(vcpu, kvm_run);
if (vcpu->sigset_active)
@@ -2271,41 +2469,51 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
{
unsigned char archmode = 1;
+ freg_t fprs[NUM_FPRS];
unsigned int px;
- u64 clkcomp;
+ u64 clkcomp, cputm;
int rc;
+ px = kvm_s390_get_prefix(vcpu);
if (gpa == KVM_S390_STORE_STATUS_NOADDR) {
if (write_guest_abs(vcpu, 163, &archmode, 1))
return -EFAULT;
- gpa = SAVE_AREA_BASE;
+ gpa = 0;
} else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) {
if (write_guest_real(vcpu, 163, &archmode, 1))
return -EFAULT;
- gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE);
+ gpa = px;
+ } else
+ gpa -= __LC_FPREGS_SAVE_AREA;
+
+ /* manually convert vector registers if necessary */
+ if (MACHINE_HAS_VX) {
+ convert_vx_to_fp(fprs, (__vector128 *) vcpu->run->s.regs.vrs);
+ rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
+ fprs, 128);
+ } else {
+ rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
+ vcpu->run->s.regs.fprs, 128);
}
- rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs),
- vcpu->arch.guest_fpregs.fprs, 128);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs),
+ rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA,
vcpu->run->s.regs.gprs, 128);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw),
+ rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA,
&vcpu->arch.sie_block->gpsw, 16);
- px = kvm_s390_get_prefix(vcpu);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg),
+ rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA,
&px, 4);
- rc |= write_guest_abs(vcpu,
- gpa + offsetof(struct save_area, fp_ctrl_reg),
- &vcpu->arch.guest_fpregs.fpc, 4);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg),
+ rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA,
+ &vcpu->run->s.regs.fpc, 4);
+ rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA,
&vcpu->arch.sie_block->todpr, 4);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer),
- &vcpu->arch.sie_block->cputm, 8);
+ cputm = kvm_s390_get_cpu_timer(vcpu);
+ rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA,
+ &cputm, 8);
clkcomp = vcpu->arch.sie_block->ckc >> 8;
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp),
+ rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA,
&clkcomp, 8);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs),
+ rc |= write_guest_abs(vcpu, gpa + __LC_AREGS_SAVE_AREA,
&vcpu->run->s.regs.acrs, 64);
- rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs),
+ rc |= write_guest_abs(vcpu, gpa + __LC_CREGS_SAVE_AREA,
&vcpu->arch.sie_block->gcr, 128);
return rc ? -EFAULT : 0;
}
@@ -2318,20 +2526,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
* it into the save area
*/
save_fpu_regs();
- if (test_kvm_facility(vcpu->kvm, 129)) {
- /*
- * If the vector extension is available, the vector registers
- * which overlaps with floating-point registers are saved in
- * the SIE-control block. Hence, extract the floating-point
- * registers and the FPC value and store them in the
- * guest_fpregs structure.
- */
- WARN_ON(!is_vx_task(current)); /* XXX remove later */
- vcpu->arch.guest_fpregs.fpc = current->thread.fpu.fpc;
- convert_vx_to_fp(vcpu->arch.guest_fpregs.fprs,
- current->thread.fpu.vxrs);
- } else
- save_fpu_to(&vcpu->arch.guest_fpregs);
+ vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
save_access_regs(vcpu->run->s.regs.acrs);
return kvm_s390_store_status_unloaded(vcpu, addr);
@@ -2518,7 +2713,8 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
switch (mop->op) {
case KVM_S390_MEMOP_LOGICAL_READ:
if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
- r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, false);
+ r = check_gva_range(vcpu, mop->gaddr, mop->ar,
+ mop->size, GACC_FETCH);
break;
}
r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size);
@@ -2529,7 +2725,8 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
break;
case KVM_S390_MEMOP_LOGICAL_WRITE:
if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
- r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, true);
+ r = check_gva_range(vcpu, mop->gaddr, mop->ar,
+ mop->size, GACC_STORE);
break;
}
if (copy_from_user(tmpbuf, uaddr, mop->size)) {
@@ -2742,6 +2939,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
if (mem->memory_size & 0xffffful)
return -EINVAL;
+ if (mem->guest_phys_addr + mem->memory_size > kvm->arch.mem_limit)
+ return -EINVAL;
+
return 0;
}
@@ -2773,6 +2973,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
static int __init kvm_s390_init(void)
{
+ if (!sclp.has_sief2) {
+ pr_info("SIE not available\n");
+ return -ENODEV;
+ }
+
return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
}
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index c446aab..8621ab0 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -19,6 +19,7 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <asm/facility.h>
+#include <asm/processor.h>
typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
@@ -53,6 +54,11 @@ static inline int is_vcpu_stopped(struct kvm_vcpu *vcpu)
return atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED;
}
+static inline int is_vcpu_idle(struct kvm_vcpu *vcpu)
+{
+ return atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_WAIT;
+}
+
static inline int kvm_is_ucontrol(struct kvm *kvm)
{
#ifdef CONFIG_KVM_S390_UCONTROL
@@ -154,8 +160,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc)
/* test availability of facility in a kvm instance */
static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr)
{
- return __test_facility(nr, kvm->arch.model.fac->mask) &&
- __test_facility(nr, kvm->arch.model.fac->list);
+ return __test_facility(nr, kvm->arch.model.fac_mask) &&
+ __test_facility(nr, kvm->arch.model.fac_list);
}
static inline int set_kvm_facility(u64 *fac_list, unsigned long nr)
@@ -175,6 +181,7 @@ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm)
return kvm->arch.user_cpu_state_ctrl != 0;
}
+/* implemented in interrupt.c */
int kvm_s390_handle_wait(struct kvm_vcpu *vcpu);
void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu);
enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer);
@@ -185,7 +192,25 @@ int __must_check kvm_s390_inject_vm(struct kvm *kvm,
struct kvm_s390_interrupt *s390int);
int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
struct kvm_s390_irq *irq);
-int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
+static inline int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
+ struct kvm_s390_pgm_info *pgm_info)
+{
+ struct kvm_s390_irq irq = {
+ .type = KVM_S390_PROGRAM_INT,
+ .u.pgm = *pgm_info,
+ };
+
+ return kvm_s390_inject_vcpu(vcpu, &irq);
+}
+static inline int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
+{
+ struct kvm_s390_irq irq = {
+ .type = KVM_S390_PROGRAM_INT,
+ .u.pgm.code = code,
+ };
+
+ return kvm_s390_inject_vcpu(vcpu, &irq);
+}
struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
u64 isc_mask, u32 schid);
int kvm_s390_reinject_io_int(struct kvm *kvm,
@@ -193,8 +218,22 @@ int kvm_s390_reinject_io_int(struct kvm *kvm,
int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked);
/* implemented in intercept.c */
-void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc);
+u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu);
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
+static inline void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilen)
+{
+ struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
+
+ sie_block->gpsw.addr = __rewind_psw(sie_block->gpsw, ilen);
+}
+static inline void kvm_s390_forward_psw(struct kvm_vcpu *vcpu, int ilen)
+{
+ kvm_s390_rewind_psw(vcpu, -ilen);
+}
+static inline void kvm_s390_retry_instr(struct kvm_vcpu *vcpu)
+{
+ kvm_s390_rewind_psw(vcpu, kvm_s390_get_ilen(vcpu));
+}
/* implemented in priv.c */
int is_valid_psw(psw_t *psw);
@@ -212,6 +251,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
/* implemented in kvm-s390.c */
+void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod);
long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu,
@@ -228,12 +268,11 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu);
void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu);
unsigned long kvm_s390_fac_list_mask_size(void);
extern unsigned long kvm_s390_fac_list_mask[];
+void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm);
+__u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu);
/* implemented in diag.c */
int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
-/* implemented in interrupt.c */
-int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu,
- struct kvm_s390_pgm_info *pgm_info);
static inline void kvm_s390_vcpu_block_all(struct kvm *kvm)
{
@@ -254,6 +293,16 @@ static inline void kvm_s390_vcpu_unblock_all(struct kvm *kvm)
kvm_s390_vcpu_unblock(vcpu);
}
+static inline u64 kvm_s390_get_tod_clock_fast(struct kvm *kvm)
+{
+ u64 rc;
+
+ preempt_disable();
+ rc = get_tod_clock_fast() + kvm->arch.epoch;
+ preempt_enable();
+ return rc;
+}
+
/**
* kvm_s390_inject_prog_cond - conditionally inject a program check
* @vcpu: virtual cpu
@@ -313,4 +362,11 @@ void kvm_s390_clear_bp_data(struct kvm_vcpu *vcpu);
void kvm_s390_prepare_debug_exit(struct kvm_vcpu *vcpu);
void kvm_s390_handle_per_event(struct kvm_vcpu *vcpu);
+/* support for Basic/Extended SCA handling */
+static inline union ipte_control *kvm_s390_get_ipte_control(struct kvm *kvm)
+{
+ struct bsca_block *sca = kvm->arch.sca; /* SCA version doesn't matter */
+
+ return &sca->ipte_control;
+}
#endif
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 4d21dc4..0a1591d 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -23,6 +23,7 @@
#include <asm/sysinfo.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
+#include <asm/gmap.h>
#include <asm/io.h>
#include <asm/ptrace.h>
#include <asm/compat.h>
@@ -33,11 +34,9 @@
/* Handle SCK (SET CLOCK) interception */
static int handle_set_clock(struct kvm_vcpu *vcpu)
{
- struct kvm_vcpu *cpup;
- s64 hostclk, val;
- int i, rc;
+ int rc;
ar_t ar;
- u64 op2;
+ u64 op2, val;
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
@@ -49,19 +48,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
- if (store_tod_clock(&hostclk)) {
- kvm_s390_set_psw_cc(vcpu, 3);
- return 0;
- }
VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", val);
- val = (val - hostclk) & ~0x3fUL;
-
- mutex_lock(&vcpu->kvm->lock);
- preempt_disable();
- kvm_for_each_vcpu(i, cpup, vcpu->kvm)
- cpup->arch.sie_block->epoch = val;
- preempt_enable();
- mutex_unlock(&vcpu->kvm->lock);
+ kvm_s390_set_tod_clock(vcpu->kvm, val);
kvm_s390_set_psw_cc(vcpu, 0);
return 0;
@@ -186,7 +174,7 @@ static int handle_skey(struct kvm_vcpu *vcpu)
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
- kvm_s390_rewind_psw(vcpu, 4);
+ kvm_s390_retry_instr(vcpu);
VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation");
return 0;
}
@@ -197,7 +185,7 @@ static int handle_ipte_interlock(struct kvm_vcpu *vcpu)
if (psw_bits(vcpu->arch.sie_block->gpsw).p)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
wait_event(vcpu->kvm->arch.ipte_wq, !ipte_lock_held(vcpu));
- kvm_s390_rewind_psw(vcpu, 4);
+ kvm_s390_retry_instr(vcpu);
VCPU_EVENT(vcpu, 4, "%s", "retrying ipte interlock operation");
return 0;
}
@@ -367,8 +355,8 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
* We need to shift the lower 32 facility bits (bit 0-31) from a u64
* into a u32 memory representation. They will remain bits 0-31.
*/
- fac = *vcpu->kvm->arch.model.fac->list >> 32;
- rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list),
+ fac = *vcpu->kvm->arch.model.fac_list >> 32;
+ rc = write_guest_lc(vcpu, offsetof(struct lowcore, stfl_fac_list),
&fac, sizeof(fac));
if (rc)
return rc;
@@ -673,7 +661,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
- if (!MACHINE_HAS_PFMF)
+ if (!test_kvm_facility(vcpu->kvm, 8))
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
@@ -772,8 +760,8 @@ static int handle_essa(struct kvm_vcpu *vcpu)
if (((vcpu->arch.sie_block->ipb & 0xf0000000) >> 28) > 6)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
- /* Rewind PSW to repeat the ESSA instruction */
- kvm_s390_rewind_psw(vcpu, 4);
+ /* Retry the ESSA instruction */
+ kvm_s390_retry_instr(vcpu);
vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */
cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo);
down_read(&gmap->mm->mmap_sem);
@@ -994,11 +982,12 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
return -EOPNOTSUPP;
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT)
ipte_lock(vcpu);
- ret = guest_translate_address(vcpu, address1, ar, &gpa, 1);
+ ret = guest_translate_address(vcpu, address1, ar, &gpa, GACC_STORE);
if (ret == PGM_PROTECTION) {
/* Write protected? Try again with read-only... */
cc = 1;
- ret = guest_translate_address(vcpu, address1, ar, &gpa, 0);
+ ret = guest_translate_address(vcpu, address1, ar, &gpa,
+ GACC_FETCH);
}
if (ret) {
if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) {
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index da690b6..77c22d6 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
u16 cpu_addr, u32 parameter, u64 *status_reg)
{
int rc;
- struct kvm_vcpu *dst_vcpu;
+ struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
- if (cpu_addr >= KVM_MAX_VCPUS)
- return SIGP_CC_NOT_OPERATIONAL;
-
- dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
if (!dst_vcpu)
return SIGP_CC_NOT_OPERATIONAL;
@@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu)
trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
if (order_code == SIGP_EXTERNAL_CALL) {
- dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
+ dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
BUG_ON(dest_vcpu == NULL);
kvm_s390_vcpu_wakeup(dest_vcpu);
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h
index cc1d6c6..396485b 100644
--- a/arch/s390/kvm/trace-s390.h
+++ b/arch/s390/kvm/trace-s390.h
@@ -55,8 +55,8 @@ TRACE_EVENT(kvm_s390_create_vcpu,
__entry->sie_block = sie_block;
),
- TP_printk("create cpu %d at %p, sie block at %p", __entry->id,
- __entry->vcpu, __entry->sie_block)
+ TP_printk("create cpu %d at 0x%pK, sie block at 0x%pK",
+ __entry->id, __entry->vcpu, __entry->sie_block)
);
TRACE_EVENT(kvm_s390_destroy_vcpu,
@@ -254,7 +254,7 @@ TRACE_EVENT(kvm_s390_enable_css,
__entry->kvm = kvm;
),
- TP_printk("enabling channel I/O support (kvm @ %p)\n",
+ TP_printk("enabling channel I/O support (kvm @ %pK)\n",
__entry->kvm)
);
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 0e8fefe..1d1af31 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -3,7 +3,7 @@
#
lib-y += delay.o string.o uaccess.o find.o
-obj-y += mem.o
+obj-y += mem.o xor.o
lib-$(CONFIG_SMP) += spinlock.o
lib-$(CONFIG_KPROBES) += probes.o
lib-$(CONFIG_UPROBES) += probes.o
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 246a7eb..501dcd4 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -12,8 +12,10 @@
#include <linux/module.h>
#include <linux/irqflags.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <asm/vtimer.h>
#include <asm/div64.h>
+#include <asm/idle.h>
void __delay(unsigned long loops)
{
@@ -30,26 +32,22 @@ EXPORT_SYMBOL(__delay);
static void __udelay_disabled(unsigned long long usecs)
{
- unsigned long cr0, cr6, new;
- u64 clock_saved, end;
+ unsigned long cr0, cr0_new, psw_mask;
+ struct s390_idle_data idle;
+ u64 end;
end = get_tod_clock() + (usecs << 12);
- clock_saved = local_tick_disable();
__ctl_store(cr0, 0, 0);
- __ctl_store(cr6, 6, 6);
- new = (cr0 & 0xffff00e0) | 0x00000800;
- __ctl_load(new , 0, 0);
- new = 0;
- __ctl_load(new, 6, 6);
- lockdep_off();
- do {
- set_clock_comparator(end);
- enabled_wait();
- } while (get_tod_clock_fast() < end);
- lockdep_on();
+ cr0_new = cr0 & ~CR0_IRQ_SUBCLASS_MASK;
+ cr0_new |= (1UL << (63 - 52)); /* enable clock comparator irq */
+ __ctl_load(cr0_new, 0, 0);
+ psw_mask = __extract_psw() | PSW_MASK_EXT | PSW_MASK_WAIT;
+ set_clock_comparator(end);
+ set_cpu_flag(CIF_IGNORE_IRQ);
+ psw_idle(&idle, psw_mask);
+ clear_cpu_flag(CIF_IGNORE_IRQ);
+ set_clock_comparator(S390_lowcore.clock_comparator);
__ctl_load(cr0, 0, 0);
- __ctl_load(cr6, 6, 6);
- local_tick_enable(clock_saved);
}
static void __udelay_enabled(unsigned long long usecs)
diff --git a/arch/s390/lib/find.c b/arch/s390/lib/find.c
index 922003c..d90b924 100644
--- a/arch/s390/lib/find.c
+++ b/arch/s390/lib/find.c
@@ -1,10 +1,8 @@
/*
* MSB0 numbered special bitops handling.
*
- * On s390x the bits are numbered:
+ * The bits are numbered:
* |0..............63|64............127|128...........191|192...........255|
- * and on s390:
- * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
*
* The reason for this bit numbering is the fact that the hardware sets bits
* in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index d6c9991..d4549c9 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -37,12 +37,22 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old)
asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock));
}
+static inline int cpu_is_preempted(int cpu)
+{
+ if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
+ return 0;
+ if (smp_vcpu_scheduled(cpu))
+ return 0;
+ return 1;
+}
+
void arch_spin_lock_wait(arch_spinlock_t *lp)
{
unsigned int cpu = SPINLOCK_LOCKVAL;
unsigned int owner;
- int count;
+ int count, first_diag;
+ first_diag = 1;
while (1) {
owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */
@@ -51,9 +61,10 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
return;
continue;
}
- /* Check if the lock owner is running. */
- if (!smp_vcpu_scheduled(~owner)) {
+ /* First iteration: check if the lock owner is running. */
+ if (first_diag && cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner);
+ first_diag = 0;
continue;
}
/* Loop for a while on the lock value. */
@@ -67,10 +78,13 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
continue;
/*
* For multiple layers of hypervisors, e.g. z/VM + LPAR
- * yield the CPU if the lock is still unavailable.
+ * yield the CPU unconditionally. For LPAR rely on the
+ * sense running status.
*/
- if (!MACHINE_IS_LPAR)
+ if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner);
+ first_diag = 0;
+ }
}
}
EXPORT_SYMBOL(arch_spin_lock_wait);
@@ -79,9 +93,10 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
{
unsigned int cpu = SPINLOCK_LOCKVAL;
unsigned int owner;
- int count;
+ int count, first_diag;
local_irq_restore(flags);
+ first_diag = 1;
while (1) {
owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */
@@ -92,8 +107,9 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
local_irq_restore(flags);
}
/* Check if the lock owner is running. */
- if (!smp_vcpu_scheduled(~owner)) {
+ if (first_diag && cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner);
+ first_diag = 0;
continue;
}
/* Loop for a while on the lock value. */
@@ -107,10 +123,13 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
continue;
/*
* For multiple layers of hypervisors, e.g. z/VM + LPAR
- * yield the CPU if the lock is still unavailable.
+ * yield the CPU unconditionally. For LPAR rely on the
+ * sense running status.
*/
- if (!MACHINE_IS_LPAR)
+ if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner);
+ first_diag = 0;
+ }
}
}
EXPORT_SYMBOL(arch_spin_lock_wait_flags);
@@ -145,7 +164,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw)
owner = 0;
while (1) {
if (count-- <= 0) {
- if (owner && !smp_vcpu_scheduled(~owner))
+ if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner);
count = spin_retry;
}
@@ -191,13 +210,13 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev)
owner = 0;
while (1) {
if (count-- <= 0) {
- if (owner && !smp_vcpu_scheduled(~owner))
+ if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner);
count = spin_retry;
}
old = ACCESS_ONCE(rw->lock);
owner = ACCESS_ONCE(rw->owner);
- smp_rmb();
+ smp_mb();
if ((int) old >= 0) {
prev = __RAW_LOCK(&rw->lock, 0x80000000, __RAW_OP_OR);
old = prev;
@@ -221,7 +240,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
owner = 0;
while (1) {
if (count-- <= 0) {
- if (owner && !smp_vcpu_scheduled(~owner))
+ if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner);
count = spin_retry;
}
@@ -231,7 +250,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
_raw_compare_and_swap(&rw->lock, old, old | 0x80000000))
prev = old;
else
- smp_rmb();
+ smp_mb();
if ((old & 0x7fffffff) == 0 && (int) prev >= 0)
break;
if (MACHINE_HAS_CAD)
@@ -265,7 +284,7 @@ void arch_lock_relax(unsigned int cpu)
{
if (!cpu)
return;
- if (MACHINE_IS_LPAR && smp_vcpu_scheduled(~cpu))
+ if (MACHINE_IS_LPAR && !cpu_is_preempted(~cpu))
return;
smp_yield_cpu(~cpu);
}
diff --git a/arch/s390/lib/xor.c b/arch/s390/lib/xor.c
new file mode 100644
index 0000000..7d94e3e
--- /dev/null
+++ b/arch/s390/lib/xor.c
@@ -0,0 +1,134 @@
+/*
+ * Optimized xor_block operation for RAID4/5
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/raid/xor.h>
+
+static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+{
+ asm volatile(
+ " larl 1,2f\n"
+ " aghi %0,-1\n"
+ " jm 3f\n"
+ " srlg 0,%0,8\n"
+ " ltgr 0,0\n"
+ " jz 1f\n"
+ "0: xc 0(256,%1),0(%2)\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ " brctg 0,0b\n"
+ "1: ex %0,0(1)\n"
+ " j 3f\n"
+ "2: xc 0(1,%1),0(%2)\n"
+ "3:\n"
+ : : "d" (bytes), "a" (p1), "a" (p2)
+ : "0", "1", "cc", "memory");
+}
+
+static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3)
+{
+ asm volatile(
+ " larl 1,2f\n"
+ " aghi %0,-1\n"
+ " jm 3f\n"
+ " srlg 0,%0,8\n"
+ " ltgr 0,0\n"
+ " jz 1f\n"
+ "0: xc 0(256,%1),0(%2)\n"
+ " xc 0(256,%1),0(%3)\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ " la %3,256(%3)\n"
+ " brctg 0,0b\n"
+ "1: ex %0,0(1)\n"
+ " ex %0,6(1)\n"
+ " j 3f\n"
+ "2: xc 0(1,%1),0(%2)\n"
+ " xc 0(1,%1),0(%3)\n"
+ "3:\n"
+ : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
+ : : "0", "1", "cc", "memory");
+}
+
+static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4)
+{
+ asm volatile(
+ " larl 1,2f\n"
+ " aghi %0,-1\n"
+ " jm 3f\n"
+ " srlg 0,%0,8\n"
+ " ltgr 0,0\n"
+ " jz 1f\n"
+ "0: xc 0(256,%1),0(%2)\n"
+ " xc 0(256,%1),0(%3)\n"
+ " xc 0(256,%1),0(%4)\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ " la %3,256(%3)\n"
+ " la %4,256(%4)\n"
+ " brctg 0,0b\n"
+ "1: ex %0,0(1)\n"
+ " ex %0,6(1)\n"
+ " ex %0,12(1)\n"
+ " j 3f\n"
+ "2: xc 0(1,%1),0(%2)\n"
+ " xc 0(1,%1),0(%3)\n"
+ " xc 0(1,%1),0(%4)\n"
+ "3:\n"
+ : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
+ : : "0", "1", "cc", "memory");
+}
+
+static void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+ /* Get around a gcc oddity */
+ register unsigned long *reg7 asm ("7") = p5;
+
+ asm volatile(
+ " larl 1,2f\n"
+ " aghi %0,-1\n"
+ " jm 3f\n"
+ " srlg 0,%0,8\n"
+ " ltgr 0,0\n"
+ " jz 1f\n"
+ "0: xc 0(256,%1),0(%2)\n"
+ " xc 0(256,%1),0(%3)\n"
+ " xc 0(256,%1),0(%4)\n"
+ " xc 0(256,%1),0(%5)\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ " la %3,256(%3)\n"
+ " la %4,256(%4)\n"
+ " la %5,256(%5)\n"
+ " brctg 0,0b\n"
+ "1: ex %0,0(1)\n"
+ " ex %0,6(1)\n"
+ " ex %0,12(1)\n"
+ " ex %0,18(1)\n"
+ " j 3f\n"
+ "2: xc 0(1,%1),0(%2)\n"
+ " xc 0(1,%1),0(%3)\n"
+ " xc 0(1,%1),0(%4)\n"
+ " xc 0(1,%1),0(%5)\n"
+ "3:\n"
+ : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
+ "+a" (reg7)
+ : : "0", "1", "cc", "memory");
+}
+
+struct xor_block_template xor_block_xc = {
+ .name = "xc",
+ .do_2 = xor_xc_2,
+ .do_3 = xor_xc_3,
+ .do_4 = xor_xc_4,
+ .do_5 = xor_xc_5,
+};
+EXPORT_SYMBOL(xor_block_xc);
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 839592c..2ae54ca 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -2,9 +2,11 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
-obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o
+obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o
obj-y += page-states.o gup.o extable.o pageattr.o mem_detect.o
+obj-y += pgtable.o pgalloc.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o
+obj-$(CONFIG_PGSTE) += gmap.o
diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c
index 4d1ee88..18c8b81 100644
--- a/arch/s390/mm/extable.c
+++ b/arch/s390/mm/extable.c
@@ -52,12 +52,16 @@ void sort_extable(struct exception_table_entry *start,
int i;
/* Normalize entries to being relative to the start of the section */
- for (p = start, i = 0; p < finish; p++, i += 8)
+ for (p = start, i = 0; p < finish; p++, i += 8) {
p->insn += i;
+ p->fixup += i + 4;
+ }
sort(start, finish - start, sizeof(*start), cmp_ex, NULL);
/* Denormalize all entries */
- for (p = start, i = 0; p < finish; p++, i += 8)
+ for (p = start, i = 0; p < finish; p++, i += 8) {
p->insn -= i;
+ p->fixup -= i + 4;
+ }
}
#ifdef CONFIG_MODULES
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 23c4969..02042b6 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -18,6 +18,7 @@
#include <linux/bootmem.h>
#include <linux/ctype.h>
#include <linux/ioport.h>
+#include <asm/diag.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/ebcdic.h>
@@ -93,7 +94,7 @@ static DEFINE_MUTEX(dcss_lock);
static LIST_HEAD(dcss_list);
static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
"EW/EN-MIXED" };
-static int loadshr_scode, loadnsr_scode, findseg_scode;
+static int loadshr_scode, loadnsr_scode;
static int segext_scode, purgeseg_scode;
static int scode_set;
@@ -112,6 +113,7 @@ dcss_set_subcodes(void)
ry = DCSS_FINDSEGX;
strcpy(name, "dummy");
+ diag_stat_inc(DIAG_STAT_X064);
asm volatile(
" diag %0,%1,0x64\n"
"0: ipm %2\n"
@@ -128,7 +130,6 @@ dcss_set_subcodes(void)
loadshr_scode = DCSS_LOADSHRX;
loadnsr_scode = DCSS_LOADNSRX;
purgeseg_scode = DCSS_PURGESEG;
- findseg_scode = DCSS_FINDSEGX;
segext_scode = DCSS_SEGEXTX;
return 0;
}
@@ -136,7 +137,6 @@ dcss_set_subcodes(void)
loadshr_scode = DCSS_LOADNOLY;
loadnsr_scode = DCSS_LOADNSR;
purgeseg_scode = DCSS_PURGESEG;
- findseg_scode = DCSS_FINDSEG;
segext_scode = DCSS_SEGEXT;
return 0;
}
@@ -205,6 +205,7 @@ dcss_diag(int *func, void *parameter,
ry = (unsigned long) *func;
/* 64-bit Diag x'64' new subcode, keep in 64-bit addressing mode */
+ diag_stat_inc(DIAG_STAT_X064);
if (*func > DCSS_SEGEXT)
asm volatile(
" diag %0,%1,0x64\n"
@@ -264,7 +265,7 @@ query_segment_type (struct dcss_segment *seg)
goto out_free;
}
if (diag_cc > 1) {
- pr_warning("Querying a DCSS type failed with rc=%ld\n", vmrc);
+ pr_warn("Querying a DCSS type failed with rc=%ld\n", vmrc);
rc = dcss_diag_translate_rc (vmrc);
goto out_free;
}
@@ -456,8 +457,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
goto out_resource;
}
if (diag_cc > 1) {
- pr_warning("Loading DCSS %s failed with rc=%ld\n", name,
- end_addr);
+ pr_warn("Loading DCSS %s failed with rc=%ld\n", name, end_addr);
rc = dcss_diag_translate_rc(end_addr);
dcss_diag(&purgeseg_scode, seg->dcss_name,
&dummy, &dummy);
@@ -573,8 +573,7 @@ segment_modify_shared (char *name, int do_nonshared)
goto out_unlock;
}
if (atomic_read (&seg->ref_count) != 1) {
- pr_warning("DCSS %s is in use and cannot be reloaded\n",
- name);
+ pr_warn("DCSS %s is in use and cannot be reloaded\n", name);
rc = -EAGAIN;
goto out_unlock;
}
@@ -587,8 +586,8 @@ segment_modify_shared (char *name, int do_nonshared)
seg->res->flags |= IORESOURCE_READONLY;
if (request_resource(&iomem_resource, seg->res)) {
- pr_warning("DCSS %s overlaps with used memory resources "
- "and cannot be reloaded\n", name);
+ pr_warn("DCSS %s overlaps with used memory resources and cannot be reloaded\n",
+ name);
rc = -EBUSY;
kfree(seg->res);
goto out_del_mem;
@@ -606,8 +605,8 @@ segment_modify_shared (char *name, int do_nonshared)
goto out_del_res;
}
if (diag_cc > 1) {
- pr_warning("Reloading DCSS %s failed with rc=%ld\n", name,
- end_addr);
+ pr_warn("Reloading DCSS %s failed with rc=%ld\n",
+ name, end_addr);
rc = dcss_diag_translate_rc(end_addr);
goto out_del_res;
}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index f985856..cce577f 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -30,7 +30,9 @@
#include <linux/uaccess.h>
#include <linux/hugetlb.h>
#include <asm/asm-offsets.h>
+#include <asm/diag.h>
#include <asm/pgtable.h>
+#include <asm/gmap.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/facility.h>
@@ -182,6 +184,8 @@ static void dump_fault_info(struct pt_regs *regs)
{
unsigned long asce;
+ pr_alert("Failing address: %016lx TEID: %016lx\n",
+ regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
pr_alert("Fault in ");
switch (regs->int_parm_long & 3) {
case 3:
@@ -217,7 +221,9 @@ static void dump_fault_info(struct pt_regs *regs)
dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK);
}
-static inline void report_user_fault(struct pt_regs *regs, long signr)
+int show_unhandled_signals = 1;
+
+void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault)
{
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
return;
@@ -227,11 +233,10 @@ static inline void report_user_fault(struct pt_regs *regs, long signr)
return;
printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ",
regs->int_code & 0xffff, regs->int_code >> 17);
- print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
+ print_vma_addr(KERN_CONT "in ", regs->psw.addr);
printk(KERN_CONT "\n");
- printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
- regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
- dump_fault_info(regs);
+ if (is_mm_fault)
+ dump_fault_info(regs);
show_regs(regs);
}
@@ -243,7 +248,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
{
struct siginfo si;
- report_user_fault(regs, SIGSEGV);
+ report_user_fault(regs, SIGSEGV, 1);
si.si_signo = SIGSEGV;
si.si_code = si_code;
si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
@@ -253,12 +258,11 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
static noinline void do_no_context(struct pt_regs *regs)
{
const struct exception_table_entry *fixup;
- unsigned long address;
/* Are we prepared to handle this kernel fault? */
- fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
+ fixup = search_exception_tables(regs->psw.addr);
if (fixup) {
- regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE;
+ regs->psw.addr = extable_fixup(fixup);
return;
}
@@ -266,15 +270,12 @@ static noinline void do_no_context(struct pt_regs *regs)
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
*/
- address = regs->int_parm_long & __FAIL_ADDR_MASK;
if (!user_space_fault(regs))
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
" in virtual kernel address space\n");
else
printk(KERN_ALERT "Unable to handle kernel paging request"
" in virtual user address space\n");
- printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
- regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
dump_fault_info(regs);
die(regs, "Oops");
do_exit(SIGKILL);
@@ -589,7 +590,7 @@ int pfault_init(void)
.reffcode = 0,
.refdwlen = 5,
.refversn = 2,
- .refgaddr = __LC_CURRENT_PID,
+ .refgaddr = __LC_LPP,
.refselmk = 1ULL << 48,
.refcmpmk = 1ULL << 48,
.reserved = __PF_RES_FIELD };
@@ -597,6 +598,7 @@ int pfault_init(void)
if (pfault_disable)
return -1;
+ diag_stat_inc(DIAG_STAT_X258);
asm volatile(
" diag %1,%0,0x258\n"
"0: j 2f\n"
@@ -618,6 +620,7 @@ void pfault_fini(void)
if (pfault_disable)
return;
+ diag_stat_inc(DIAG_STAT_X258);
asm volatile(
" diag %0,0,0x258\n"
"0:\n"
@@ -646,7 +649,7 @@ static void pfault_interrupt(struct ext_code ext_code,
return;
inc_irq_stat(IRQEXT_PFL);
/* Get the token (= pid of the affected task). */
- pid = param64;
+ pid = param64 & LPP_PFAULT_PID_MASK;
rcu_read_lock();
tsk = find_task_by_pid_ns(pid, &init_pid_ns);
if (tsk)
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
new file mode 100644
index 0000000..69247b4
--- /dev/null
+++ b/arch/s390/mm/gmap.c
@@ -0,0 +1,774 @@
+/*
+ * KVM guest address space mapping code
+ *
+ * Copyright IBM Corp. 2007, 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/swapops.h>
+#include <linux/ksm.h>
+#include <linux/mman.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/gmap.h>
+#include <asm/tlb.h>
+
+/**
+ * gmap_alloc - allocate a guest address space
+ * @mm: pointer to the parent mm_struct
+ * @limit: maximum size of the gmap address space
+ *
+ * Returns a guest address space structure.
+ */
+struct gmap *gmap_alloc(struct mm_struct *mm, unsigned long limit)
+{
+ struct gmap *gmap;
+ struct page *page;
+ unsigned long *table;
+ unsigned long etype, atype;
+
+ if (limit < (1UL << 31)) {
+ limit = (1UL << 31) - 1;
+ atype = _ASCE_TYPE_SEGMENT;
+ etype = _SEGMENT_ENTRY_EMPTY;
+ } else if (limit < (1UL << 42)) {
+ limit = (1UL << 42) - 1;
+ atype = _ASCE_TYPE_REGION3;
+ etype = _REGION3_ENTRY_EMPTY;
+ } else if (limit < (1UL << 53)) {
+ limit = (1UL << 53) - 1;
+ atype = _ASCE_TYPE_REGION2;
+ etype = _REGION2_ENTRY_EMPTY;
+ } else {
+ limit = -1UL;
+ atype = _ASCE_TYPE_REGION1;
+ etype = _REGION1_ENTRY_EMPTY;
+ }
+ gmap = kzalloc(sizeof(struct gmap), GFP_KERNEL);
+ if (!gmap)
+ goto out;
+ INIT_LIST_HEAD(&gmap->crst_list);
+ INIT_RADIX_TREE(&gmap->guest_to_host, GFP_KERNEL);
+ INIT_RADIX_TREE(&gmap->host_to_guest, GFP_ATOMIC);
+ spin_lock_init(&gmap->guest_table_lock);
+ gmap->mm = mm;
+ page = alloc_pages(GFP_KERNEL, 2);
+ if (!page)
+ goto out_free;
+ page->index = 0;
+ list_add(&page->lru, &gmap->crst_list);
+ table = (unsigned long *) page_to_phys(page);
+ crst_table_init(table, etype);
+ gmap->table = table;
+ gmap->asce = atype | _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS | __pa(table);
+ gmap->asce_end = limit;
+ down_write(&mm->mmap_sem);
+ list_add(&gmap->list, &mm->context.gmap_list);
+ up_write(&mm->mmap_sem);
+ return gmap;
+
+out_free:
+ kfree(gmap);
+out:
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gmap_alloc);
+
+static void gmap_flush_tlb(struct gmap *gmap)
+{
+ if (MACHINE_HAS_IDTE)
+ __tlb_flush_asce(gmap->mm, gmap->asce);
+ else
+ __tlb_flush_global();
+}
+
+static void gmap_radix_tree_free(struct radix_tree_root *root)
+{
+ struct radix_tree_iter iter;
+ unsigned long indices[16];
+ unsigned long index;
+ void **slot;
+ int i, nr;
+
+ /* A radix tree is freed by deleting all of its entries */
+ index = 0;
+ do {
+ nr = 0;
+ radix_tree_for_each_slot(slot, root, &iter, index) {
+ indices[nr] = iter.index;
+ if (++nr == 16)
+ break;
+ }
+ for (i = 0; i < nr; i++) {
+ index = indices[i];
+ radix_tree_delete(root, index);
+ }
+ } while (nr > 0);
+}
+
+/**
+ * gmap_free - free a guest address space
+ * @gmap: pointer to the guest address space structure
+ */
+void gmap_free(struct gmap *gmap)
+{
+ struct page *page, *next;
+
+ /* Flush tlb. */
+ if (MACHINE_HAS_IDTE)
+ __tlb_flush_asce(gmap->mm, gmap->asce);
+ else
+ __tlb_flush_global();
+
+ /* Free all segment & region tables. */
+ list_for_each_entry_safe(page, next, &gmap->crst_list, lru)
+ __free_pages(page, 2);
+ gmap_radix_tree_free(&gmap->guest_to_host);
+ gmap_radix_tree_free(&gmap->host_to_guest);
+ down_write(&gmap->mm->mmap_sem);
+ list_del(&gmap->list);
+ up_write(&gmap->mm->mmap_sem);
+ kfree(gmap);
+}
+EXPORT_SYMBOL_GPL(gmap_free);
+
+/**
+ * gmap_enable - switch primary space to the guest address space
+ * @gmap: pointer to the guest address space structure
+ */
+void gmap_enable(struct gmap *gmap)
+{
+ S390_lowcore.gmap = (unsigned long) gmap;
+}
+EXPORT_SYMBOL_GPL(gmap_enable);
+
+/**
+ * gmap_disable - switch back to the standard primary address space
+ * @gmap: pointer to the guest address space structure
+ */
+void gmap_disable(struct gmap *gmap)
+{
+ S390_lowcore.gmap = 0UL;
+}
+EXPORT_SYMBOL_GPL(gmap_disable);
+
+/*
+ * gmap_alloc_table is assumed to be called with mmap_sem held
+ */
+static int gmap_alloc_table(struct gmap *gmap, unsigned long *table,
+ unsigned long init, unsigned long gaddr)
+{
+ struct page *page;
+ unsigned long *new;
+
+ /* since we dont free the gmap table until gmap_free we can unlock */
+ page = alloc_pages(GFP_KERNEL, 2);
+ if (!page)
+ return -ENOMEM;
+ new = (unsigned long *) page_to_phys(page);
+ crst_table_init(new, init);
+ spin_lock(&gmap->mm->page_table_lock);
+ if (*table & _REGION_ENTRY_INVALID) {
+ list_add(&page->lru, &gmap->crst_list);
+ *table = (unsigned long) new | _REGION_ENTRY_LENGTH |
+ (*table & _REGION_ENTRY_TYPE_MASK);
+ page->index = gaddr;
+ page = NULL;
+ }
+ spin_unlock(&gmap->mm->page_table_lock);
+ if (page)
+ __free_pages(page, 2);
+ return 0;
+}
+
+/**
+ * __gmap_segment_gaddr - find virtual address from segment pointer
+ * @entry: pointer to a segment table entry in the guest address space
+ *
+ * Returns the virtual address in the guest address space for the segment
+ */
+static unsigned long __gmap_segment_gaddr(unsigned long *entry)
+{
+ struct page *page;
+ unsigned long offset, mask;
+
+ offset = (unsigned long) entry / sizeof(unsigned long);
+ offset = (offset & (PTRS_PER_PMD - 1)) * PMD_SIZE;
+ mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
+ page = virt_to_page((void *)((unsigned long) entry & mask));
+ return page->index + offset;
+}
+
+/**
+ * __gmap_unlink_by_vmaddr - unlink a single segment via a host address
+ * @gmap: pointer to the guest address space structure
+ * @vmaddr: address in the host process address space
+ *
+ * Returns 1 if a TLB flush is required
+ */
+static int __gmap_unlink_by_vmaddr(struct gmap *gmap, unsigned long vmaddr)
+{
+ unsigned long *entry;
+ int flush = 0;
+
+ spin_lock(&gmap->guest_table_lock);
+ entry = radix_tree_delete(&gmap->host_to_guest, vmaddr >> PMD_SHIFT);
+ if (entry) {
+ flush = (*entry != _SEGMENT_ENTRY_INVALID);
+ *entry = _SEGMENT_ENTRY_INVALID;
+ }
+ spin_unlock(&gmap->guest_table_lock);
+ return flush;
+}
+
+/**
+ * __gmap_unmap_by_gaddr - unmap a single segment via a guest address
+ * @gmap: pointer to the guest address space structure
+ * @gaddr: address in the guest address space
+ *
+ * Returns 1 if a TLB flush is required
+ */
+static int __gmap_unmap_by_gaddr(struct gmap *gmap, unsigned long gaddr)
+{
+ unsigned long vmaddr;
+
+ vmaddr = (unsigned long) radix_tree_delete(&gmap->guest_to_host,
+ gaddr >> PMD_SHIFT);
+ return vmaddr ? __gmap_unlink_by_vmaddr(gmap, vmaddr) : 0;
+}
+
+/**
+ * gmap_unmap_segment - unmap segment from the guest address space
+ * @gmap: pointer to the guest address space structure
+ * @to: address in the guest address space
+ * @len: length of the memory area to unmap
+ *
+ * Returns 0 if the unmap succeeded, -EINVAL if not.
+ */
+int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len)
+{
+ unsigned long off;
+ int flush;
+
+ if ((to | len) & (PMD_SIZE - 1))
+ return -EINVAL;
+ if (len == 0 || to + len < to)
+ return -EINVAL;
+
+ flush = 0;
+ down_write(&gmap->mm->mmap_sem);
+ for (off = 0; off < len; off += PMD_SIZE)
+ flush |= __gmap_unmap_by_gaddr(gmap, to + off);
+ up_write(&gmap->mm->mmap_sem);
+ if (flush)
+ gmap_flush_tlb(gmap);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gmap_unmap_segment);
+
+/**
+ * gmap_map_segment - map a segment to the guest address space
+ * @gmap: pointer to the guest address space structure
+ * @from: source address in the parent address space
+ * @to: target address in the guest address space
+ * @len: length of the memory area to map
+ *
+ * Returns 0 if the mmap succeeded, -EINVAL or -ENOMEM if not.
+ */
+int gmap_map_segment(struct gmap *gmap, unsigned long from,
+ unsigned long to, unsigned long len)
+{
+ unsigned long off;
+ int flush;
+
+ if ((from | to | len) & (PMD_SIZE - 1))
+ return -EINVAL;
+ if (len == 0 || from + len < from || to + len < to ||
+ from + len > TASK_MAX_SIZE || to + len > gmap->asce_end)
+ return -EINVAL;
+
+ flush = 0;
+ down_write(&gmap->mm->mmap_sem);
+ for (off = 0; off < len; off += PMD_SIZE) {
+ /* Remove old translation */
+ flush |= __gmap_unmap_by_gaddr(gmap, to + off);
+ /* Store new translation */
+ if (radix_tree_insert(&gmap->guest_to_host,
+ (to + off) >> PMD_SHIFT,
+ (void *) from + off))
+ break;
+ }
+ up_write(&gmap->mm->mmap_sem);
+ if (flush)
+ gmap_flush_tlb(gmap);
+ if (off >= len)
+ return 0;
+ gmap_unmap_segment(gmap, to, len);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(gmap_map_segment);
+
+/**
+ * __gmap_translate - translate a guest address to a user space address
+ * @gmap: pointer to guest mapping meta data structure
+ * @gaddr: guest address
+ *
+ * Returns user space address which corresponds to the guest address or
+ * -EFAULT if no such mapping exists.
+ * This function does not establish potentially missing page table entries.
+ * The mmap_sem of the mm that belongs to the address space must be held
+ * when this function gets called.
+ */
+unsigned long __gmap_translate(struct gmap *gmap, unsigned long gaddr)
+{
+ unsigned long vmaddr;
+
+ vmaddr = (unsigned long)
+ radix_tree_lookup(&gmap->guest_to_host, gaddr >> PMD_SHIFT);
+ return vmaddr ? (vmaddr | (gaddr & ~PMD_MASK)) : -EFAULT;
+}
+EXPORT_SYMBOL_GPL(__gmap_translate);
+
+/**
+ * gmap_translate - translate a guest address to a user space address
+ * @gmap: pointer to guest mapping meta data structure
+ * @gaddr: guest address
+ *
+ * Returns user space address which corresponds to the guest address or
+ * -EFAULT if no such mapping exists.
+ * This function does not establish potentially missing page table entries.
+ */
+unsigned long gmap_translate(struct gmap *gmap, unsigned long gaddr)
+{
+ unsigned long rc;
+
+ down_read(&gmap->mm->mmap_sem);
+ rc = __gmap_translate(gmap, gaddr);
+ up_read(&gmap->mm->mmap_sem);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(gmap_translate);
+
+/**
+ * gmap_unlink - disconnect a page table from the gmap shadow tables
+ * @gmap: pointer to guest mapping meta data structure
+ * @table: pointer to the host page table
+ * @vmaddr: vm address associated with the host page table
+ */
+void gmap_unlink(struct mm_struct *mm, unsigned long *table,
+ unsigned long vmaddr)
+{
+ struct gmap *gmap;
+ int flush;
+
+ list_for_each_entry(gmap, &mm->context.gmap_list, list) {
+ flush = __gmap_unlink_by_vmaddr(gmap, vmaddr);
+ if (flush)
+ gmap_flush_tlb(gmap);
+ }
+}
+
+/**
+ * gmap_link - set up shadow page tables to connect a host to a guest address
+ * @gmap: pointer to guest mapping meta data structure
+ * @gaddr: guest address
+ * @vmaddr: vm address
+ *
+ * Returns 0 on success, -ENOMEM for out of memory conditions, and -EFAULT
+ * if the vm address is already mapped to a different guest segment.
+ * The mmap_sem of the mm that belongs to the address space must be held
+ * when this function gets called.
+ */
+int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
+{
+ struct mm_struct *mm;
+ unsigned long *table;
+ spinlock_t *ptl;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ int rc;
+
+ /* Create higher level tables in the gmap page table */
+ table = gmap->table;
+ if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION1) {
+ table += (gaddr >> 53) & 0x7ff;
+ if ((*table & _REGION_ENTRY_INVALID) &&
+ gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY,
+ gaddr & 0xffe0000000000000UL))
+ return -ENOMEM;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ }
+ if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION2) {
+ table += (gaddr >> 42) & 0x7ff;
+ if ((*table & _REGION_ENTRY_INVALID) &&
+ gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY,
+ gaddr & 0xfffffc0000000000UL))
+ return -ENOMEM;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ }
+ if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION3) {
+ table += (gaddr >> 31) & 0x7ff;
+ if ((*table & _REGION_ENTRY_INVALID) &&
+ gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY,
+ gaddr & 0xffffffff80000000UL))
+ return -ENOMEM;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ }
+ table += (gaddr >> 20) & 0x7ff;
+ /* Walk the parent mm page table */
+ mm = gmap->mm;
+ pgd = pgd_offset(mm, vmaddr);
+ VM_BUG_ON(pgd_none(*pgd));
+ pud = pud_offset(pgd, vmaddr);
+ VM_BUG_ON(pud_none(*pud));
+ pmd = pmd_offset(pud, vmaddr);
+ VM_BUG_ON(pmd_none(*pmd));
+ /* large pmds cannot yet be handled */
+ if (pmd_large(*pmd))
+ return -EFAULT;
+ /* Link gmap segment table entry location to page table. */
+ rc = radix_tree_preload(GFP_KERNEL);
+ if (rc)
+ return rc;
+ ptl = pmd_lock(mm, pmd);
+ spin_lock(&gmap->guest_table_lock);
+ if (*table == _SEGMENT_ENTRY_INVALID) {
+ rc = radix_tree_insert(&gmap->host_to_guest,
+ vmaddr >> PMD_SHIFT, table);
+ if (!rc)
+ *table = pmd_val(*pmd);
+ } else
+ rc = 0;
+ spin_unlock(&gmap->guest_table_lock);
+ spin_unlock(ptl);
+ radix_tree_preload_end();
+ return rc;
+}
+
+/**
+ * gmap_fault - resolve a fault on a guest address
+ * @gmap: pointer to guest mapping meta data structure
+ * @gaddr: guest address
+ * @fault_flags: flags to pass down to handle_mm_fault()
+ *
+ * Returns 0 on success, -ENOMEM for out of memory conditions, and -EFAULT
+ * if the vm address is already mapped to a different guest segment.
+ */
+int gmap_fault(struct gmap *gmap, unsigned long gaddr,
+ unsigned int fault_flags)
+{
+ unsigned long vmaddr;
+ int rc;
+ bool unlocked;
+
+ down_read(&gmap->mm->mmap_sem);
+
+retry:
+ unlocked = false;
+ vmaddr = __gmap_translate(gmap, gaddr);
+ if (IS_ERR_VALUE(vmaddr)) {
+ rc = vmaddr;
+ goto out_up;
+ }
+ if (fixup_user_fault(current, gmap->mm, vmaddr, fault_flags,
+ &unlocked)) {
+ rc = -EFAULT;
+ goto out_up;
+ }
+ /*
+ * In the case that fixup_user_fault unlocked the mmap_sem during
+ * faultin redo __gmap_translate to not race with a map/unmap_segment.
+ */
+ if (unlocked)
+ goto retry;
+
+ rc = __gmap_link(gmap, gaddr, vmaddr);
+out_up:
+ up_read(&gmap->mm->mmap_sem);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(gmap_fault);
+
+/*
+ * this function is assumed to be called with mmap_sem held
+ */
+void __gmap_zap(struct gmap *gmap, unsigned long gaddr)
+{
+ unsigned long vmaddr;
+ spinlock_t *ptl;
+ pte_t *ptep;
+
+ /* Find the vm address for the guest address */
+ vmaddr = (unsigned long) radix_tree_lookup(&gmap->guest_to_host,
+ gaddr >> PMD_SHIFT);
+ if (vmaddr) {
+ vmaddr |= gaddr & ~PMD_MASK;
+ /* Get pointer to the page table entry */
+ ptep = get_locked_pte(gmap->mm, vmaddr, &ptl);
+ if (likely(ptep))
+ ptep_zap_unused(gmap->mm, vmaddr, ptep, 0);
+ pte_unmap_unlock(ptep, ptl);
+ }
+}
+EXPORT_SYMBOL_GPL(__gmap_zap);
+
+void gmap_discard(struct gmap *gmap, unsigned long from, unsigned long to)
+{
+ unsigned long gaddr, vmaddr, size;
+ struct vm_area_struct *vma;
+
+ down_read(&gmap->mm->mmap_sem);
+ for (gaddr = from; gaddr < to;
+ gaddr = (gaddr + PMD_SIZE) & PMD_MASK) {
+ /* Find the vm address for the guest address */
+ vmaddr = (unsigned long)
+ radix_tree_lookup(&gmap->guest_to_host,
+ gaddr >> PMD_SHIFT);
+ if (!vmaddr)
+ continue;
+ vmaddr |= gaddr & ~PMD_MASK;
+ /* Find vma in the parent mm */
+ vma = find_vma(gmap->mm, vmaddr);
+ size = min(to - gaddr, PMD_SIZE - (gaddr & ~PMD_MASK));
+ zap_page_range(vma, vmaddr, size, NULL);
+ }
+ up_read(&gmap->mm->mmap_sem);
+}
+EXPORT_SYMBOL_GPL(gmap_discard);
+
+static LIST_HEAD(gmap_notifier_list);
+static DEFINE_SPINLOCK(gmap_notifier_lock);
+
+/**
+ * gmap_register_ipte_notifier - register a pte invalidation callback
+ * @nb: pointer to the gmap notifier block
+ */
+void gmap_register_ipte_notifier(struct gmap_notifier *nb)
+{
+ spin_lock(&gmap_notifier_lock);
+ list_add(&nb->list, &gmap_notifier_list);
+ spin_unlock(&gmap_notifier_lock);
+}
+EXPORT_SYMBOL_GPL(gmap_register_ipte_notifier);
+
+/**
+ * gmap_unregister_ipte_notifier - remove a pte invalidation callback
+ * @nb: pointer to the gmap notifier block
+ */
+void gmap_unregister_ipte_notifier(struct gmap_notifier *nb)
+{
+ spin_lock(&gmap_notifier_lock);
+ list_del_init(&nb->list);
+ spin_unlock(&gmap_notifier_lock);
+}
+EXPORT_SYMBOL_GPL(gmap_unregister_ipte_notifier);
+
+/**
+ * gmap_ipte_notify - mark a range of ptes for invalidation notification
+ * @gmap: pointer to guest mapping meta data structure
+ * @gaddr: virtual address in the guest address space
+ * @len: size of area
+ *
+ * Returns 0 if for each page in the given range a gmap mapping exists and
+ * the invalidation notification could be set. If the gmap mapping is missing
+ * for one or more pages -EFAULT is returned. If no memory could be allocated
+ * -ENOMEM is returned. This function establishes missing page table entries.
+ */
+int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len)
+{
+ unsigned long addr;
+ spinlock_t *ptl;
+ pte_t *ptep;
+ bool unlocked;
+ int rc = 0;
+
+ if ((gaddr & ~PAGE_MASK) || (len & ~PAGE_MASK))
+ return -EINVAL;
+ down_read(&gmap->mm->mmap_sem);
+ while (len) {
+ unlocked = false;
+ /* Convert gmap address and connect the page tables */
+ addr = __gmap_translate(gmap, gaddr);
+ if (IS_ERR_VALUE(addr)) {
+ rc = addr;
+ break;
+ }
+ /* Get the page mapped */
+ if (fixup_user_fault(current, gmap->mm, addr, FAULT_FLAG_WRITE,
+ &unlocked)) {
+ rc = -EFAULT;
+ break;
+ }
+ /* While trying to map mmap_sem got unlocked. Let us retry */
+ if (unlocked)
+ continue;
+ rc = __gmap_link(gmap, gaddr, addr);
+ if (rc)
+ break;
+ /* Walk the process page table, lock and get pte pointer */
+ ptep = get_locked_pte(gmap->mm, addr, &ptl);
+ VM_BUG_ON(!ptep);
+ /* Set notification bit in the pgste of the pte */
+ if ((pte_val(*ptep) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) {
+ ptep_set_notify(gmap->mm, addr, ptep);
+ gaddr += PAGE_SIZE;
+ len -= PAGE_SIZE;
+ }
+ pte_unmap_unlock(ptep, ptl);
+ }
+ up_read(&gmap->mm->mmap_sem);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(gmap_ipte_notify);
+
+/**
+ * ptep_notify - call all invalidation callbacks for a specific pte.
+ * @mm: pointer to the process mm_struct
+ * @addr: virtual address in the process address space
+ * @pte: pointer to the page table entry
+ *
+ * This function is assumed to be called with the page table lock held
+ * for the pte to notify.
+ */
+void ptep_notify(struct mm_struct *mm, unsigned long vmaddr, pte_t *pte)
+{
+ unsigned long offset, gaddr;
+ unsigned long *table;
+ struct gmap_notifier *nb;
+ struct gmap *gmap;
+
+ offset = ((unsigned long) pte) & (255 * sizeof(pte_t));
+ offset = offset * (4096 / sizeof(pte_t));
+ spin_lock(&gmap_notifier_lock);
+ list_for_each_entry(gmap, &mm->context.gmap_list, list) {
+ table = radix_tree_lookup(&gmap->host_to_guest,
+ vmaddr >> PMD_SHIFT);
+ if (!table)
+ continue;
+ gaddr = __gmap_segment_gaddr(table) + offset;
+ list_for_each_entry(nb, &gmap_notifier_list, list)
+ nb->notifier_call(gmap, gaddr);
+ }
+ spin_unlock(&gmap_notifier_lock);
+}
+EXPORT_SYMBOL_GPL(ptep_notify);
+
+static inline void thp_split_mm(struct mm_struct *mm)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct vm_area_struct *vma;
+ unsigned long addr;
+
+ for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
+ for (addr = vma->vm_start;
+ addr < vma->vm_end;
+ addr += PAGE_SIZE)
+ follow_page(vma, addr, FOLL_SPLIT);
+ vma->vm_flags &= ~VM_HUGEPAGE;
+ vma->vm_flags |= VM_NOHUGEPAGE;
+ }
+ mm->def_flags |= VM_NOHUGEPAGE;
+#endif
+}
+
+/*
+ * switch on pgstes for its userspace process (for kvm)
+ */
+int s390_enable_sie(void)
+{
+ struct mm_struct *mm = current->mm;
+
+ /* Do we have pgstes? if yes, we are done */
+ if (mm_has_pgste(mm))
+ return 0;
+ /* Fail if the page tables are 2K */
+ if (!mm_alloc_pgste(mm))
+ return -EINVAL;
+ down_write(&mm->mmap_sem);
+ mm->context.has_pgste = 1;
+ /* split thp mappings and disable thp for future mappings */
+ thp_split_mm(mm);
+ up_write(&mm->mmap_sem);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s390_enable_sie);
+
+/*
+ * Enable storage key handling from now on and initialize the storage
+ * keys with the default key.
+ */
+static int __s390_enable_skey(pte_t *pte, unsigned long addr,
+ unsigned long next, struct mm_walk *walk)
+{
+ /*
+ * Remove all zero page mappings,
+ * after establishing a policy to forbid zero page mappings
+ * following faults for that page will get fresh anonymous pages
+ */
+ if (is_zero_pfn(pte_pfn(*pte)))
+ ptep_xchg_direct(walk->mm, addr, pte, __pte(_PAGE_INVALID));
+ /* Clear storage key */
+ ptep_zap_key(walk->mm, addr, pte);
+ return 0;
+}
+
+int s390_enable_skey(void)
+{
+ struct mm_walk walk = { .pte_entry = __s390_enable_skey };
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ int rc = 0;
+
+ down_write(&mm->mmap_sem);
+ if (mm_use_skey(mm))
+ goto out_up;
+
+ mm->context.use_skey = 1;
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
+ MADV_UNMERGEABLE, &vma->vm_flags)) {
+ mm->context.use_skey = 0;
+ rc = -ENOMEM;
+ goto out_up;
+ }
+ }
+ mm->def_flags &= ~VM_MERGEABLE;
+
+ walk.mm = mm;
+ walk_page_range(0, TASK_SIZE, &walk);
+
+out_up:
+ up_write(&mm->mmap_sem);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(s390_enable_skey);
+
+/*
+ * Reset CMMA state, make all pages stable again.
+ */
+static int __s390_reset_cmma(pte_t *pte, unsigned long addr,
+ unsigned long next, struct mm_walk *walk)
+{
+ ptep_zap_unused(walk->mm, addr, pte, 1);
+ return 0;
+}
+
+void s390_reset_cmma(struct mm_struct *mm)
+{
+ struct mm_walk walk = { .pte_entry = __s390_reset_cmma };
+
+ down_write(&mm->mmap_sem);
+ walk.mm = mm;
+ walk_page_range(0, TASK_SIZE, &walk);
+ up_write(&mm->mmap_sem);
+}
+EXPORT_SYMBOL_GPL(s390_reset_cmma);
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index 12bbf0e..13dab0c 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -55,7 +55,7 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
unsigned long mask, result;
- struct page *head, *page, *tail;
+ struct page *head, *page;
int refs;
result = write ? 0 : _SEGMENT_ENTRY_PROTECT;
@@ -67,7 +67,6 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
refs = 0;
head = pmd_page(pmd);
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
- tail = page;
do {
VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page;
@@ -88,16 +87,6 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
return 0;
}
- /*
- * Any tail page need their mapcount reference taken before we
- * return.
- */
- while (refs--) {
- if (PageTail(tail))
- get_huge_page_tail(tail);
- tail++;
- }
-
return 1;
}
@@ -116,16 +105,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
pmd = *pmdp;
barrier();
next = pmd_addr_end(addr, end);
- /*
- * The pmd_trans_splitting() check below explains why
- * pmdp_splitting_flush() has to serialize with
- * smp_call_function() against our disabled IRQs, to stop
- * this gup-fast code from running while we set the
- * splitting bit in the pmd. Returning zero will take
- * the slow path that will call wait_split_huge_page()
- * if the pmd is still in splitting state.
- */
- if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+ if (pmd_none(pmd))
return 0;
if (unlikely(pmd_large(pmd))) {
/*
@@ -233,6 +213,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct mm_struct *mm = current->mm;
int nr, ret;
+ might_sleep();
start &= PAGE_MASK;
nr = __get_user_pages_fast(start, nr_pages, write, pages);
if (nr == nr_pages)
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index fb4bf2c..1b5e898 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -40,6 +40,7 @@ static inline pmd_t __pte_to_pmd(pte_t pte)
pmd_val(pmd) |= (pte_val(pte) & _PAGE_PROTECT);
pmd_val(pmd) |= (pte_val(pte) & _PAGE_DIRTY) << 10;
pmd_val(pmd) |= (pte_val(pte) & _PAGE_YOUNG) << 10;
+ pmd_val(pmd) |= (pte_val(pte) & _PAGE_SOFT_DIRTY) << 13;
} else
pmd_val(pmd) = _SEGMENT_ENTRY_INVALID;
return pmd;
@@ -78,6 +79,7 @@ static inline pte_t __pmd_to_pte(pmd_t pmd)
pte_val(pte) |= (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT);
pte_val(pte) |= (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) >> 10;
pte_val(pte) |= (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) >> 10;
+ pte_val(pte) |= (pmd_val(pmd) & _SEGMENT_ENTRY_SOFT_DIRTY) >> 13;
} else
pte_val(pte) = _PAGE_INVALID;
return pte;
@@ -103,11 +105,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
pmd_t *pmdp = (pmd_t *) ptep;
- pte_t pte = huge_ptep_get(ptep);
+ pmd_t old;
- pmdp_flush_direct(mm, addr, pmdp);
- pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
- return pte;
+ old = pmdp_xchg_direct(mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+ return __pmd_to_pte(old);
}
pte_t *huge_pte_alloc(struct mm_struct *mm,
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index c3c07d3..73e2903 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -48,37 +48,13 @@ EXPORT_SYMBOL(zero_page_mask);
static void __init setup_zero_pages(void)
{
- struct cpuid cpu_id;
unsigned int order;
struct page *page;
int i;
- get_cpu_id(&cpu_id);
- switch (cpu_id.machine) {
- case 0x9672: /* g5 */
- case 0x2064: /* z900 */
- case 0x2066: /* z900 */
- case 0x2084: /* z990 */
- case 0x2086: /* z990 */
- case 0x2094: /* z9-109 */
- case 0x2096: /* z9-109 */
- order = 0;
- break;
- case 0x2097: /* z10 */
- case 0x2098: /* z10 */
- case 0x2817: /* z196 */
- case 0x2818: /* z196 */
- order = 2;
- break;
- case 0x2827: /* zEC12 */
- case 0x2828: /* zEC12 */
- order = 5;
- break;
- case 0x2964: /* z13 */
- default:
- order = 7;
- break;
- }
+ /* Latest machines require a mapping granularity of 512KB */
+ order = 7;
+
/* Limit number of empty zero pages for small memory sizes */
while (order > 2 && (totalram_pages >> 10) < (1UL << order))
order--;
@@ -122,7 +98,7 @@ void __init paging_init(void)
__ctl_load(S390_lowcore.kernel_asce, 1, 1);
__ctl_load(S390_lowcore.kernel_asce, 7, 7);
__ctl_load(S390_lowcore.kernel_asce, 13, 13);
- arch_local_irq_restore(4UL << (BITS_PER_LONG - 8));
+ __arch_local_irq_stosm(0x04);
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 8a993a5..792f9c6 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -93,15 +93,19 @@ static int __memcpy_real(void *dest, void *src, size_t count)
*/
int memcpy_real(void *dest, void *src, size_t count)
{
+ int irqs_disabled, rc;
unsigned long flags;
- int rc;
if (!count)
return 0;
- local_irq_save(flags);
- __arch_local_irq_stnsm(0xfbUL);
+ flags = __arch_local_irq_stnsm(0xf8UL);
+ irqs_disabled = arch_irqs_disabled_flags(flags);
+ if (!irqs_disabled)
+ trace_hardirqs_off();
rc = __memcpy_real(dest, src, count);
- local_irq_restore(flags);
+ if (!irqs_disabled)
+ trace_hardirqs_on();
+ __arch_local_irq_ssm(flags);
return rc;
}
@@ -163,11 +167,11 @@ static int is_swapped(unsigned long addr)
unsigned long lc;
int cpu;
- if (addr < sizeof(struct _lowcore))
+ if (addr < sizeof(struct lowcore))
return 1;
for_each_online_cpu(cpu) {
lc = (unsigned long) lowcore_ptr[cpu];
- if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc)
+ if (addr > lc + sizeof(struct lowcore) - 1 || addr < lc)
continue;
return 1;
}
diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c
index e00f0d5..d612cc3 100644
--- a/arch/s390/mm/mem_detect.c
+++ b/arch/s390/mm/mem_detect.c
@@ -14,8 +14,6 @@
#include <asm/sclp.h>
#include <asm/setup.h>
-#define ADDR2G (1ULL << 31)
-
#define CHUNK_READ_WRITE 0
#define CHUNK_READ_ONLY 1
@@ -27,15 +25,14 @@ static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size)
void __init detect_memory_memblock(void)
{
- unsigned long long memsize, rnmax, rzm;
- unsigned long addr, size;
+ unsigned long memsize, rnmax, rzm, addr, size;
int type;
rzm = sclp.rzm;
rnmax = sclp.rnmax;
memsize = rzm * rnmax;
if (!rzm)
- rzm = 1ULL << 17;
+ rzm = 1UL << 17;
max_physmem_end = memsize;
addr = 0;
/* keep memblock lists close to the kernel */
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 6e552af..45c4daa 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -31,9 +31,6 @@
#include <linux/security.h>
#include <asm/pgalloc.h>
-unsigned long mmap_rnd_mask;
-static unsigned long mmap_align_mask;
-
static unsigned long stack_maxrandom_size(void)
{
if (!(current->flags & PF_RANDOMIZE))
@@ -62,10 +59,7 @@ static inline int mmap_is_legacy(void)
unsigned long arch_mmap_rnd(void)
{
- if (is_32bit_task())
- return (get_random_int() & 0x7ff) << PAGE_SHIFT;
- else
- return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT;
+ return (get_random_int() & MMAP_RND_MASK) << PAGE_SHIFT;
}
static unsigned long mmap_base_legacy(unsigned long rnd)
@@ -92,7 +86,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
struct vm_unmapped_area_info info;
- int do_color_align;
if (len > TASK_SIZE - mmap_min_addr)
return -ENOMEM;
@@ -108,15 +101,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr;
}
- do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
- do_color_align = !is_32bit_task();
-
info.flags = 0;
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
- info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0;
+ if (filp || (flags & MAP_SHARED))
+ info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
+ else
+ info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
}
@@ -130,7 +122,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
struct vm_unmapped_area_info info;
- int do_color_align;
/* requested length too big for entire address space */
if (len > TASK_SIZE - mmap_min_addr)
@@ -148,15 +139,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
- do_color_align = !is_32bit_task();
-
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
info.length = len;
info.low_limit = max(PAGE_SIZE, mmap_min_addr);
info.high_limit = mm->mmap_base;
- info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0;
+ if (filp || (flags & MAP_SHARED))
+ info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
+ else
+ info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
@@ -179,12 +169,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
{
- if (is_compat_task() || (TASK_SIZE >= (1UL << 53)))
+ if (is_compat_task() || TASK_SIZE >= TASK_MAX_SIZE)
return 0;
if (!(flags & MAP_FIXED))
addr = 0;
if ((addr + len) >= TASK_SIZE)
- return crst_table_upgrade(current->mm, 1UL << 53);
+ return crst_table_upgrade(current->mm, TASK_MAX_SIZE);
return 0;
}
@@ -199,9 +189,9 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
if (!(area & ~PAGE_MASK))
return area;
- if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
+ if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) {
/* Upgrade the page table to 4 levels and retry. */
- rc = crst_table_upgrade(mm, 1UL << 53);
+ rc = crst_table_upgrade(mm, TASK_MAX_SIZE);
if (rc)
return (unsigned long) rc;
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
@@ -221,9 +211,9 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
if (!(area & ~PAGE_MASK))
return area;
- if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
+ if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) {
/* Upgrade the page table to 4 levels and retry. */
- rc = crst_table_upgrade(mm, 1UL << 53);
+ rc = crst_table_upgrade(mm, TASK_MAX_SIZE);
if (rc)
return (unsigned long) rc;
area = arch_get_unmapped_area_topdown(filp, addr, len,
@@ -254,35 +244,3 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
mm->get_unmapped_area = s390_get_unmapped_area_topdown;
}
}
-
-static int __init setup_mmap_rnd(void)
-{
- struct cpuid cpu_id;
-
- get_cpu_id(&cpu_id);
- switch (cpu_id.machine) {
- case 0x9672:
- case 0x2064:
- case 0x2066:
- case 0x2084:
- case 0x2086:
- case 0x2094:
- case 0x2096:
- case 0x2097:
- case 0x2098:
- case 0x2817:
- case 0x2818:
- case 0x2827:
- case 0x2828:
- mmap_rnd_mask = 0x7ffUL;
- mmap_align_mask = 0UL;
- break;
- case 0x2964: /* z13 */
- default:
- mmap_rnd_mask = 0x3ff80UL;
- mmap_align_mask = 0x7fUL;
- break;
- }
- return 0;
-}
-early_initcall(setup_mmap_rnd);
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 749c984..f2a5c29 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -65,19 +65,17 @@ static pte_t *walk_page_table(unsigned long addr)
static void change_page_attr(unsigned long addr, int numpages,
pte_t (*set) (pte_t))
{
- pte_t *ptep, pte;
+ pte_t *ptep;
int i;
for (i = 0; i < numpages; i++) {
ptep = walk_page_table(addr);
if (WARN_ON_ONCE(!ptep))
break;
- pte = *ptep;
- pte = set(pte);
- __ptep_ipte(addr, ptep);
- *ptep = pte;
+ *ptep = set(*ptep);
addr += PAGE_SIZE;
}
+ __tlb_flush_kernel();
}
int set_memory_ro(unsigned long addr, int numpages)
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
new file mode 100644
index 0000000..f6c3de2
--- /dev/null
+++ b/arch/s390/mm/pgalloc.c
@@ -0,0 +1,360 @@
+/*
+ * Page table allocation functions
+ *
+ * Copyright IBM Corp. 2016
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/sysctl.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/gmap.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_PGSTE
+
+static int page_table_allocate_pgste_min = 0;
+static int page_table_allocate_pgste_max = 1;
+int page_table_allocate_pgste = 0;
+EXPORT_SYMBOL(page_table_allocate_pgste);
+
+static struct ctl_table page_table_sysctl[] = {
+ {
+ .procname = "allocate_pgste",
+ .data = &page_table_allocate_pgste,
+ .maxlen = sizeof(int),
+ .mode = S_IRUGO | S_IWUSR,
+ .proc_handler = proc_dointvec,
+ .extra1 = &page_table_allocate_pgste_min,
+ .extra2 = &page_table_allocate_pgste_max,
+ },
+ { }
+};
+
+static struct ctl_table page_table_sysctl_dir[] = {
+ {
+ .procname = "vm",
+ .maxlen = 0,
+ .mode = 0555,
+ .child = page_table_sysctl,
+ },
+ { }
+};
+
+static int __init page_table_register_sysctl(void)
+{
+ return register_sysctl_table(page_table_sysctl_dir) ? 0 : -ENOMEM;
+}
+__initcall(page_table_register_sysctl);
+
+#endif /* CONFIG_PGSTE */
+
+unsigned long *crst_table_alloc(struct mm_struct *mm)
+{
+ struct page *page = alloc_pages(GFP_KERNEL, 2);
+
+ if (!page)
+ return NULL;
+ return (unsigned long *) page_to_phys(page);
+}
+
+void crst_table_free(struct mm_struct *mm, unsigned long *table)
+{
+ free_pages((unsigned long) table, 2);
+}
+
+static void __crst_table_upgrade(void *arg)
+{
+ struct mm_struct *mm = arg;
+
+ if (current->active_mm == mm) {
+ clear_user_asce();
+ set_user_asce(mm);
+ }
+ __tlb_flush_local();
+}
+
+int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
+{
+ unsigned long *table, *pgd;
+ unsigned long entry;
+ int flush;
+
+ BUG_ON(limit > TASK_MAX_SIZE);
+ flush = 0;
+repeat:
+ table = crst_table_alloc(mm);
+ if (!table)
+ return -ENOMEM;
+ spin_lock_bh(&mm->page_table_lock);
+ if (mm->context.asce_limit < limit) {
+ pgd = (unsigned long *) mm->pgd;
+ if (mm->context.asce_limit <= (1UL << 31)) {
+ entry = _REGION3_ENTRY_EMPTY;
+ mm->context.asce_limit = 1UL << 42;
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS |
+ _ASCE_TYPE_REGION3;
+ } else {
+ entry = _REGION2_ENTRY_EMPTY;
+ mm->context.asce_limit = 1UL << 53;
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS |
+ _ASCE_TYPE_REGION2;
+ }
+ crst_table_init(table, entry);
+ pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
+ mm->pgd = (pgd_t *) table;
+ mm->task_size = mm->context.asce_limit;
+ table = NULL;
+ flush = 1;
+ }
+ spin_unlock_bh(&mm->page_table_lock);
+ if (table)
+ crst_table_free(mm, table);
+ if (mm->context.asce_limit < limit)
+ goto repeat;
+ if (flush)
+ on_each_cpu(__crst_table_upgrade, mm, 0);
+ return 0;
+}
+
+void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
+{
+ pgd_t *pgd;
+
+ if (current->active_mm == mm) {
+ clear_user_asce();
+ __tlb_flush_mm(mm);
+ }
+ while (mm->context.asce_limit > limit) {
+ pgd = mm->pgd;
+ switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
+ case _REGION_ENTRY_TYPE_R2:
+ mm->context.asce_limit = 1UL << 42;
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS |
+ _ASCE_TYPE_REGION3;
+ break;
+ case _REGION_ENTRY_TYPE_R3:
+ mm->context.asce_limit = 1UL << 31;
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH |
+ _ASCE_USER_BITS |
+ _ASCE_TYPE_SEGMENT;
+ break;
+ default:
+ BUG();
+ }
+ mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
+ mm->task_size = mm->context.asce_limit;
+ crst_table_free(mm, (unsigned long *) pgd);
+ }
+ if (current->active_mm == mm)
+ set_user_asce(mm);
+}
+
+static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits)
+{
+ unsigned int old, new;
+
+ do {
+ old = atomic_read(v);
+ new = old ^ bits;
+ } while (atomic_cmpxchg(v, old, new) != old);
+ return new;
+}
+
+/*
+ * page table entry allocation/free routines.
+ */
+unsigned long *page_table_alloc(struct mm_struct *mm)
+{
+ unsigned long *table;
+ struct page *page;
+ unsigned int mask, bit;
+
+ /* Try to get a fragment of a 4K page as a 2K page table */
+ if (!mm_alloc_pgste(mm)) {
+ table = NULL;
+ spin_lock_bh(&mm->context.list_lock);
+ if (!list_empty(&mm->context.pgtable_list)) {
+ page = list_first_entry(&mm->context.pgtable_list,
+ struct page, lru);
+ mask = atomic_read(&page->_mapcount);
+ mask = (mask | (mask >> 4)) & 3;
+ if (mask != 3) {
+ table = (unsigned long *) page_to_phys(page);
+ bit = mask & 1; /* =1 -> second 2K */
+ if (bit)
+ table += PTRS_PER_PTE;
+ atomic_xor_bits(&page->_mapcount, 1U << bit);
+ list_del(&page->lru);
+ }
+ }
+ spin_unlock_bh(&mm->context.list_lock);
+ if (table)
+ return table;
+ }
+ /* Allocate a fresh page */
+ page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
+ if (!page)
+ return NULL;
+ if (!pgtable_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
+ /* Initialize page table */
+ table = (unsigned long *) page_to_phys(page);
+ if (mm_alloc_pgste(mm)) {
+ /* Return 4K page table with PGSTEs */
+ atomic_set(&page->_mapcount, 3);
+ clear_table(table, _PAGE_INVALID, PAGE_SIZE/2);
+ clear_table(table + PTRS_PER_PTE, 0, PAGE_SIZE/2);
+ } else {
+ /* Return the first 2K fragment of the page */
+ atomic_set(&page->_mapcount, 1);
+ clear_table(table, _PAGE_INVALID, PAGE_SIZE);
+ spin_lock_bh(&mm->context.list_lock);
+ list_add(&page->lru, &mm->context.pgtable_list);
+ spin_unlock_bh(&mm->context.list_lock);
+ }
+ return table;
+}
+
+void page_table_free(struct mm_struct *mm, unsigned long *table)
+{
+ struct page *page;
+ unsigned int bit, mask;
+
+ page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+ if (!mm_alloc_pgste(mm)) {
+ /* Free 2K page table fragment of a 4K page */
+ bit = (__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t));
+ spin_lock_bh(&mm->context.list_lock);
+ mask = atomic_xor_bits(&page->_mapcount, 1U << bit);
+ if (mask & 3)
+ list_add(&page->lru, &mm->context.pgtable_list);
+ else
+ list_del(&page->lru);
+ spin_unlock_bh(&mm->context.list_lock);
+ if (mask != 0)
+ return;
+ }
+
+ pgtable_page_dtor(page);
+ atomic_set(&page->_mapcount, -1);
+ __free_page(page);
+}
+
+void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table,
+ unsigned long vmaddr)
+{
+ struct mm_struct *mm;
+ struct page *page;
+ unsigned int bit, mask;
+
+ mm = tlb->mm;
+ page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+ if (mm_alloc_pgste(mm)) {
+ gmap_unlink(mm, table, vmaddr);
+ table = (unsigned long *) (__pa(table) | 3);
+ tlb_remove_table(tlb, table);
+ return;
+ }
+ bit = (__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t));
+ spin_lock_bh(&mm->context.list_lock);
+ mask = atomic_xor_bits(&page->_mapcount, 0x11U << bit);
+ if (mask & 3)
+ list_add_tail(&page->lru, &mm->context.pgtable_list);
+ else
+ list_del(&page->lru);
+ spin_unlock_bh(&mm->context.list_lock);
+ table = (unsigned long *) (__pa(table) | (1U << bit));
+ tlb_remove_table(tlb, table);
+}
+
+static void __tlb_remove_table(void *_table)
+{
+ unsigned int mask = (unsigned long) _table & 3;
+ void *table = (void *)((unsigned long) _table ^ mask);
+ struct page *page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+
+ switch (mask) {
+ case 0: /* pmd or pud */
+ free_pages((unsigned long) table, 2);
+ break;
+ case 1: /* lower 2K of a 4K page table */
+ case 2: /* higher 2K of a 4K page table */
+ if (atomic_xor_bits(&page->_mapcount, mask << 4) != 0)
+ break;
+ /* fallthrough */
+ case 3: /* 4K page table with pgstes */
+ pgtable_page_dtor(page);
+ atomic_set(&page->_mapcount, -1);
+ __free_page(page);
+ break;
+ }
+}
+
+static void tlb_remove_table_smp_sync(void *arg)
+{
+ /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
+{
+ /*
+ * This isn't an RCU grace period and hence the page-tables cannot be
+ * assumed to be actually RCU-freed.
+ *
+ * It is however sufficient for software page-table walkers that rely
+ * on IRQ disabling. See the comment near struct mmu_table_batch.
+ */
+ smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+ __tlb_remove_table(table);
+}
+
+static void tlb_remove_table_rcu(struct rcu_head *head)
+{
+ struct mmu_table_batch *batch;
+ int i;
+
+ batch = container_of(head, struct mmu_table_batch, rcu);
+
+ for (i = 0; i < batch->nr; i++)
+ __tlb_remove_table(batch->tables[i]);
+
+ free_page((unsigned long)batch);
+}
+
+void tlb_table_flush(struct mmu_gather *tlb)
+{
+ struct mmu_table_batch **batch = &tlb->batch;
+
+ if (*batch) {
+ call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
+ *batch = NULL;
+ }
+}
+
+void tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+ struct mmu_table_batch **batch = &tlb->batch;
+
+ tlb->mm->context.flush_mm = 1;
+ if (*batch == NULL) {
+ *batch = (struct mmu_table_batch *)
+ __get_free_page(GFP_NOWAIT | __GFP_NOWARN);
+ if (*batch == NULL) {
+ __tlb_flush_mm_lazy(tlb->mm);
+ tlb_remove_table_one(table);
+ return;
+ }
+ (*batch)->nr = 0;
+ }
+ (*batch)->tables[(*batch)->nr++] = table;
+ if ((*batch)->nr == MAX_TABLE_BATCH)
+ tlb_flush_mmu(tlb);
+}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 54ef3bc..4324b87 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -24,799 +24,501 @@
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
-unsigned long *crst_table_alloc(struct mm_struct *mm)
-{
- struct page *page = alloc_pages(GFP_KERNEL, 2);
-
- if (!page)
- return NULL;
- return (unsigned long *) page_to_phys(page);
+static inline pte_t ptep_flush_direct(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ int active, count;
+ pte_t old;
+
+ old = *ptep;
+ if (unlikely(pte_val(old) & _PAGE_INVALID))
+ return old;
+ active = (mm == current->active_mm) ? 1 : 0;
+ count = atomic_add_return(0x10000, &mm->context.attach_count);
+ if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active &&
+ cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
+ __ptep_ipte_local(addr, ptep);
+ else
+ __ptep_ipte(addr, ptep);
+ atomic_sub(0x10000, &mm->context.attach_count);
+ return old;
}
-void crst_table_free(struct mm_struct *mm, unsigned long *table)
+static inline pte_t ptep_flush_lazy(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
- free_pages((unsigned long) table, 2);
+ int active, count;
+ pte_t old;
+
+ old = *ptep;
+ if (unlikely(pte_val(old) & _PAGE_INVALID))
+ return old;
+ active = (mm == current->active_mm) ? 1 : 0;
+ count = atomic_add_return(0x10000, &mm->context.attach_count);
+ if ((count & 0xffff) <= active) {
+ pte_val(*ptep) |= _PAGE_INVALID;
+ mm->context.flush_mm = 1;
+ } else
+ __ptep_ipte(addr, ptep);
+ atomic_sub(0x10000, &mm->context.attach_count);
+ return old;
}
-static void __crst_table_upgrade(void *arg)
+static inline pgste_t pgste_get_lock(pte_t *ptep)
{
- struct mm_struct *mm = arg;
+ unsigned long new = 0;
+#ifdef CONFIG_PGSTE
+ unsigned long old;
- if (current->active_mm == mm) {
- clear_user_asce();
- set_user_asce(mm);
- }
- __tlb_flush_local();
+ preempt_disable();
+ asm(
+ " lg %0,%2\n"
+ "0: lgr %1,%0\n"
+ " nihh %0,0xff7f\n" /* clear PCL bit in old */
+ " oihh %1,0x0080\n" /* set PCL bit in new */
+ " csg %0,%1,%2\n"
+ " jl 0b\n"
+ : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
+ : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory");
+#endif
+ return __pgste(new);
}
-int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
+static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
{
- unsigned long *table, *pgd;
- unsigned long entry;
- int flush;
-
- BUG_ON(limit > (1UL << 53));
- flush = 0;
-repeat:
- table = crst_table_alloc(mm);
- if (!table)
- return -ENOMEM;
- spin_lock_bh(&mm->page_table_lock);
- if (mm->context.asce_limit < limit) {
- pgd = (unsigned long *) mm->pgd;
- if (mm->context.asce_limit <= (1UL << 31)) {
- entry = _REGION3_ENTRY_EMPTY;
- mm->context.asce_limit = 1UL << 42;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH |
- _ASCE_USER_BITS |
- _ASCE_TYPE_REGION3;
- } else {
- entry = _REGION2_ENTRY_EMPTY;
- mm->context.asce_limit = 1UL << 53;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH |
- _ASCE_USER_BITS |
- _ASCE_TYPE_REGION2;
- }
- crst_table_init(table, entry);
- pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
- mm->pgd = (pgd_t *) table;
- mm->task_size = mm->context.asce_limit;
- table = NULL;
- flush = 1;
- }
- spin_unlock_bh(&mm->page_table_lock);
- if (table)
- crst_table_free(mm, table);
- if (mm->context.asce_limit < limit)
- goto repeat;
- if (flush)
- on_each_cpu(__crst_table_upgrade, mm, 0);
- return 0;
+#ifdef CONFIG_PGSTE
+ asm(
+ " nihh %1,0xff7f\n" /* clear PCL bit */
+ " stg %1,%0\n"
+ : "=Q" (ptep[PTRS_PER_PTE])
+ : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
+ : "cc", "memory");
+ preempt_enable();
+#endif
}
-void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
+static inline pgste_t pgste_get(pte_t *ptep)
{
- pgd_t *pgd;
-
- if (current->active_mm == mm) {
- clear_user_asce();
- __tlb_flush_mm(mm);
- }
- while (mm->context.asce_limit > limit) {
- pgd = mm->pgd;
- switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
- case _REGION_ENTRY_TYPE_R2:
- mm->context.asce_limit = 1UL << 42;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH |
- _ASCE_USER_BITS |
- _ASCE_TYPE_REGION3;
- break;
- case _REGION_ENTRY_TYPE_R3:
- mm->context.asce_limit = 1UL << 31;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH |
- _ASCE_USER_BITS |
- _ASCE_TYPE_SEGMENT;
- break;
- default:
- BUG();
- }
- mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
- mm->task_size = mm->context.asce_limit;
- crst_table_free(mm, (unsigned long *) pgd);
- }
- if (current->active_mm == mm)
- set_user_asce(mm);
+ unsigned long pgste = 0;
+#ifdef CONFIG_PGSTE
+ pgste = *(unsigned long *)(ptep + PTRS_PER_PTE);
+#endif
+ return __pgste(pgste);
}
+static inline void pgste_set(pte_t *ptep, pgste_t pgste)
+{
#ifdef CONFIG_PGSTE
+ *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste;
+#endif
+}
-/**
- * gmap_alloc - allocate a guest address space
- * @mm: pointer to the parent mm_struct
- * @limit: maximum size of the gmap address space
- *
- * Returns a guest address space structure.
- */
-struct gmap *gmap_alloc(struct mm_struct *mm, unsigned long limit)
+static inline pgste_t pgste_update_all(pte_t pte, pgste_t pgste,
+ struct mm_struct *mm)
{
- struct gmap *gmap;
- struct page *page;
- unsigned long *table;
- unsigned long etype, atype;
-
- if (limit < (1UL << 31)) {
- limit = (1UL << 31) - 1;
- atype = _ASCE_TYPE_SEGMENT;
- etype = _SEGMENT_ENTRY_EMPTY;
- } else if (limit < (1UL << 42)) {
- limit = (1UL << 42) - 1;
- atype = _ASCE_TYPE_REGION3;
- etype = _REGION3_ENTRY_EMPTY;
- } else if (limit < (1UL << 53)) {
- limit = (1UL << 53) - 1;
- atype = _ASCE_TYPE_REGION2;
- etype = _REGION2_ENTRY_EMPTY;
- } else {
- limit = -1UL;
- atype = _ASCE_TYPE_REGION1;
- etype = _REGION1_ENTRY_EMPTY;
- }
- gmap = kzalloc(sizeof(struct gmap), GFP_KERNEL);
- if (!gmap)
- goto out;
- INIT_LIST_HEAD(&gmap->crst_list);
- INIT_RADIX_TREE(&gmap->guest_to_host, GFP_KERNEL);
- INIT_RADIX_TREE(&gmap->host_to_guest, GFP_ATOMIC);
- spin_lock_init(&gmap->guest_table_lock);
- gmap->mm = mm;
- page = alloc_pages(GFP_KERNEL, 2);
- if (!page)
- goto out_free;
- page->index = 0;
- list_add(&page->lru, &gmap->crst_list);
- table = (unsigned long *) page_to_phys(page);
- crst_table_init(table, etype);
- gmap->table = table;
- gmap->asce = atype | _ASCE_TABLE_LENGTH |
- _ASCE_USER_BITS | __pa(table);
- gmap->asce_end = limit;
- down_write(&mm->mmap_sem);
- list_add(&gmap->list, &mm->context.gmap_list);
- up_write(&mm->mmap_sem);
- return gmap;
-
-out_free:
- kfree(gmap);
-out:
- return NULL;
+#ifdef CONFIG_PGSTE
+ unsigned long address, bits, skey;
+
+ if (!mm_use_skey(mm) || pte_val(pte) & _PAGE_INVALID)
+ return pgste;
+ address = pte_val(pte) & PAGE_MASK;
+ skey = (unsigned long) page_get_storage_key(address);
+ bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
+ /* Transfer page changed & referenced bit to guest bits in pgste */
+ pgste_val(pgste) |= bits << 48; /* GR bit & GC bit */
+ /* Copy page access key and fetch protection bit to pgste */
+ pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT);
+ pgste_val(pgste) |= (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
+#endif
+ return pgste;
+
}
-EXPORT_SYMBOL_GPL(gmap_alloc);
-static void gmap_flush_tlb(struct gmap *gmap)
+static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry,
+ struct mm_struct *mm)
{
- if (MACHINE_HAS_IDTE)
- __tlb_flush_asce(gmap->mm, gmap->asce);
- else
- __tlb_flush_global();
+#ifdef CONFIG_PGSTE
+ unsigned long address;
+ unsigned long nkey;
+
+ if (!mm_use_skey(mm) || pte_val(entry) & _PAGE_INVALID)
+ return;
+ VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
+ address = pte_val(entry) & PAGE_MASK;
+ /*
+ * Set page access key and fetch protection bit from pgste.
+ * The guest C/R information is still in the PGSTE, set real
+ * key C/R to 0.
+ */
+ nkey = (pgste_val(pgste) & (PGSTE_ACC_BITS | PGSTE_FP_BIT)) >> 56;
+ nkey |= (pgste_val(pgste) & (PGSTE_GR_BIT | PGSTE_GC_BIT)) >> 48;
+ page_set_storage_key(address, nkey, 0);
+#endif
}
-static void gmap_radix_tree_free(struct radix_tree_root *root)
+static inline pgste_t pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
{
- struct radix_tree_iter iter;
- unsigned long indices[16];
- unsigned long index;
- void **slot;
- int i, nr;
-
- /* A radix tree is freed by deleting all of its entries */
- index = 0;
- do {
- nr = 0;
- radix_tree_for_each_slot(slot, root, &iter, index) {
- indices[nr] = iter.index;
- if (++nr == 16)
- break;
- }
- for (i = 0; i < nr; i++) {
- index = indices[i];
- radix_tree_delete(root, index);
+#ifdef CONFIG_PGSTE
+ if ((pte_val(entry) & _PAGE_PRESENT) &&
+ (pte_val(entry) & _PAGE_WRITE) &&
+ !(pte_val(entry) & _PAGE_INVALID)) {
+ if (!MACHINE_HAS_ESOP) {
+ /*
+ * Without enhanced suppression-on-protection force
+ * the dirty bit on for all writable ptes.
+ */
+ pte_val(entry) |= _PAGE_DIRTY;
+ pte_val(entry) &= ~_PAGE_PROTECT;
}
- } while (nr > 0);
+ if (!(pte_val(entry) & _PAGE_PROTECT))
+ /* This pte allows write access, set user-dirty */
+ pgste_val(pgste) |= PGSTE_UC_BIT;
+ }
+#endif
+ *ptep = entry;
+ return pgste;
}
-/**
- * gmap_free - free a guest address space
- * @gmap: pointer to the guest address space structure
- */
-void gmap_free(struct gmap *gmap)
+static inline pgste_t pgste_ipte_notify(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, pgste_t pgste)
{
- struct page *page, *next;
-
- /* Flush tlb. */
- if (MACHINE_HAS_IDTE)
- __tlb_flush_asce(gmap->mm, gmap->asce);
- else
- __tlb_flush_global();
-
- /* Free all segment & region tables. */
- list_for_each_entry_safe(page, next, &gmap->crst_list, lru)
- __free_pages(page, 2);
- gmap_radix_tree_free(&gmap->guest_to_host);
- gmap_radix_tree_free(&gmap->host_to_guest);
- down_write(&gmap->mm->mmap_sem);
- list_del(&gmap->list);
- up_write(&gmap->mm->mmap_sem);
- kfree(gmap);
+#ifdef CONFIG_PGSTE
+ if (pgste_val(pgste) & PGSTE_IN_BIT) {
+ pgste_val(pgste) &= ~PGSTE_IN_BIT;
+ ptep_notify(mm, addr, ptep);
+ }
+#endif
+ return pgste;
}
-EXPORT_SYMBOL_GPL(gmap_free);
-/**
- * gmap_enable - switch primary space to the guest address space
- * @gmap: pointer to the guest address space structure
- */
-void gmap_enable(struct gmap *gmap)
+static inline pgste_t ptep_xchg_start(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
{
- S390_lowcore.gmap = (unsigned long) gmap;
+ pgste_t pgste = __pgste(0);
+
+ if (mm_has_pgste(mm)) {
+ pgste = pgste_get_lock(ptep);
+ pgste = pgste_ipte_notify(mm, addr, ptep, pgste);
+ }
+ return pgste;
}
-EXPORT_SYMBOL_GPL(gmap_enable);
-/**
- * gmap_disable - switch back to the standard primary address space
- * @gmap: pointer to the guest address space structure
- */
-void gmap_disable(struct gmap *gmap)
+static inline void ptep_xchg_commit(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep,
+ pgste_t pgste, pte_t old, pte_t new)
{
- S390_lowcore.gmap = 0UL;
+ if (mm_has_pgste(mm)) {
+ if (pte_val(old) & _PAGE_INVALID)
+ pgste_set_key(ptep, pgste, new, mm);
+ if (pte_val(new) & _PAGE_INVALID) {
+ pgste = pgste_update_all(old, pgste, mm);
+ if ((pgste_val(pgste) & _PGSTE_GPS_USAGE_MASK) ==
+ _PGSTE_GPS_USAGE_UNUSED)
+ pte_val(old) |= _PAGE_UNUSED;
+ }
+ pgste = pgste_set_pte(ptep, pgste, new);
+ pgste_set_unlock(ptep, pgste);
+ } else {
+ *ptep = new;
+ }
}
-EXPORT_SYMBOL_GPL(gmap_disable);
-/*
- * gmap_alloc_table is assumed to be called with mmap_sem held
- */
-static int gmap_alloc_table(struct gmap *gmap, unsigned long *table,
- unsigned long init, unsigned long gaddr)
+pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t new)
{
- struct page *page;
- unsigned long *new;
-
- /* since we dont free the gmap table until gmap_free we can unlock */
- page = alloc_pages(GFP_KERNEL, 2);
- if (!page)
- return -ENOMEM;
- new = (unsigned long *) page_to_phys(page);
- crst_table_init(new, init);
- spin_lock(&gmap->mm->page_table_lock);
- if (*table & _REGION_ENTRY_INVALID) {
- list_add(&page->lru, &gmap->crst_list);
- *table = (unsigned long) new | _REGION_ENTRY_LENGTH |
- (*table & _REGION_ENTRY_TYPE_MASK);
- page->index = gaddr;
- page = NULL;
- }
- spin_unlock(&gmap->mm->page_table_lock);
- if (page)
- __free_pages(page, 2);
- return 0;
+ pgste_t pgste;
+ pte_t old;
+
+ pgste = ptep_xchg_start(mm, addr, ptep);
+ old = ptep_flush_direct(mm, addr, ptep);
+ ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
+ return old;
}
+EXPORT_SYMBOL(ptep_xchg_direct);
-/**
- * __gmap_segment_gaddr - find virtual address from segment pointer
- * @entry: pointer to a segment table entry in the guest address space
- *
- * Returns the virtual address in the guest address space for the segment
- */
-static unsigned long __gmap_segment_gaddr(unsigned long *entry)
+pte_t ptep_xchg_lazy(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t new)
{
- struct page *page;
- unsigned long offset, mask;
-
- offset = (unsigned long) entry / sizeof(unsigned long);
- offset = (offset & (PTRS_PER_PMD - 1)) * PMD_SIZE;
- mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
- page = virt_to_page((void *)((unsigned long) entry & mask));
- return page->index + offset;
+ pgste_t pgste;
+ pte_t old;
+
+ pgste = ptep_xchg_start(mm, addr, ptep);
+ old = ptep_flush_lazy(mm, addr, ptep);
+ ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
+ return old;
}
+EXPORT_SYMBOL(ptep_xchg_lazy);
-/**
- * __gmap_unlink_by_vmaddr - unlink a single segment via a host address
- * @gmap: pointer to the guest address space structure
- * @vmaddr: address in the host process address space
- *
- * Returns 1 if a TLB flush is required
- */
-static int __gmap_unlink_by_vmaddr(struct gmap *gmap, unsigned long vmaddr)
+pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
{
- unsigned long *entry;
- int flush = 0;
-
- spin_lock(&gmap->guest_table_lock);
- entry = radix_tree_delete(&gmap->host_to_guest, vmaddr >> PMD_SHIFT);
- if (entry) {
- flush = (*entry != _SEGMENT_ENTRY_INVALID);
- *entry = _SEGMENT_ENTRY_INVALID;
+ pgste_t pgste;
+ pte_t old;
+
+ pgste = ptep_xchg_start(mm, addr, ptep);
+ old = ptep_flush_lazy(mm, addr, ptep);
+ if (mm_has_pgste(mm)) {
+ pgste = pgste_update_all(old, pgste, mm);
+ pgste_set(ptep, pgste);
}
- spin_unlock(&gmap->guest_table_lock);
- return flush;
+ return old;
}
+EXPORT_SYMBOL(ptep_modify_prot_start);
-/**
- * __gmap_unmap_by_gaddr - unmap a single segment via a guest address
- * @gmap: pointer to the guest address space structure
- * @gaddr: address in the guest address space
- *
- * Returns 1 if a TLB flush is required
- */
-static int __gmap_unmap_by_gaddr(struct gmap *gmap, unsigned long gaddr)
+void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
{
- unsigned long vmaddr;
+ pgste_t pgste;
- vmaddr = (unsigned long) radix_tree_delete(&gmap->guest_to_host,
- gaddr >> PMD_SHIFT);
- return vmaddr ? __gmap_unlink_by_vmaddr(gmap, vmaddr) : 0;
+ if (mm_has_pgste(mm)) {
+ pgste = pgste_get(ptep);
+ pgste_set_key(ptep, pgste, pte, mm);
+ pgste = pgste_set_pte(ptep, pgste, pte);
+ pgste_set_unlock(ptep, pgste);
+ } else {
+ *ptep = pte;
+ }
}
+EXPORT_SYMBOL(ptep_modify_prot_commit);
-/**
- * gmap_unmap_segment - unmap segment from the guest address space
- * @gmap: pointer to the guest address space structure
- * @to: address in the guest address space
- * @len: length of the memory area to unmap
- *
- * Returns 0 if the unmap succeeded, -EINVAL if not.
- */
-int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len)
+static inline pmd_t pmdp_flush_direct(struct mm_struct *mm,
+ unsigned long addr, pmd_t *pmdp)
{
- unsigned long off;
- int flush;
-
- if ((to | len) & (PMD_SIZE - 1))
- return -EINVAL;
- if (len == 0 || to + len < to)
- return -EINVAL;
-
- flush = 0;
- down_write(&gmap->mm->mmap_sem);
- for (off = 0; off < len; off += PMD_SIZE)
- flush |= __gmap_unmap_by_gaddr(gmap, to + off);
- up_write(&gmap->mm->mmap_sem);
- if (flush)
- gmap_flush_tlb(gmap);
- return 0;
+ int active, count;
+ pmd_t old;
+
+ old = *pmdp;
+ if (pmd_val(old) & _SEGMENT_ENTRY_INVALID)
+ return old;
+ if (!MACHINE_HAS_IDTE) {
+ __pmdp_csp(pmdp);
+ return old;
+ }
+ active = (mm == current->active_mm) ? 1 : 0;
+ count = atomic_add_return(0x10000, &mm->context.attach_count);
+ if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active &&
+ cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
+ __pmdp_idte_local(addr, pmdp);
+ else
+ __pmdp_idte(addr, pmdp);
+ atomic_sub(0x10000, &mm->context.attach_count);
+ return old;
+}
+
+static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm,
+ unsigned long addr, pmd_t *pmdp)
+{
+ int active, count;
+ pmd_t old;
+
+ old = *pmdp;
+ if (pmd_val(old) & _SEGMENT_ENTRY_INVALID)
+ return old;
+ active = (mm == current->active_mm) ? 1 : 0;
+ count = atomic_add_return(0x10000, &mm->context.attach_count);
+ if ((count & 0xffff) <= active) {
+ pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID;
+ mm->context.flush_mm = 1;
+ } else if (MACHINE_HAS_IDTE)
+ __pmdp_idte(addr, pmdp);
+ else
+ __pmdp_csp(pmdp);
+ atomic_sub(0x10000, &mm->context.attach_count);
+ return old;
}
-EXPORT_SYMBOL_GPL(gmap_unmap_segment);
-
-/**
- * gmap_mmap_segment - map a segment to the guest address space
- * @gmap: pointer to the guest address space structure
- * @from: source address in the parent address space
- * @to: target address in the guest address space
- * @len: length of the memory area to map
- *
- * Returns 0 if the mmap succeeded, -EINVAL or -ENOMEM if not.
- */
-int gmap_map_segment(struct gmap *gmap, unsigned long from,
- unsigned long to, unsigned long len)
+
+pmd_t pmdp_xchg_direct(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t new)
{
- unsigned long off;
- int flush;
-
- if ((from | to | len) & (PMD_SIZE - 1))
- return -EINVAL;
- if (len == 0 || from + len < from || to + len < to ||
- from + len > TASK_MAX_SIZE || to + len > gmap->asce_end)
- return -EINVAL;
-
- flush = 0;
- down_write(&gmap->mm->mmap_sem);
- for (off = 0; off < len; off += PMD_SIZE) {
- /* Remove old translation */
- flush |= __gmap_unmap_by_gaddr(gmap, to + off);
- /* Store new translation */
- if (radix_tree_insert(&gmap->guest_to_host,
- (to + off) >> PMD_SHIFT,
- (void *) from + off))
- break;
- }
- up_write(&gmap->mm->mmap_sem);
- if (flush)
- gmap_flush_tlb(gmap);
- if (off >= len)
- return 0;
- gmap_unmap_segment(gmap, to, len);
- return -ENOMEM;
+ pmd_t old;
+
+ old = pmdp_flush_direct(mm, addr, pmdp);
+ *pmdp = new;
+ return old;
}
-EXPORT_SYMBOL_GPL(gmap_map_segment);
-
-/**
- * __gmap_translate - translate a guest address to a user space address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- *
- * Returns user space address which corresponds to the guest address or
- * -EFAULT if no such mapping exists.
- * This function does not establish potentially missing page table entries.
- * The mmap_sem of the mm that belongs to the address space must be held
- * when this function gets called.
- */
-unsigned long __gmap_translate(struct gmap *gmap, unsigned long gaddr)
+EXPORT_SYMBOL(pmdp_xchg_direct);
+
+pmd_t pmdp_xchg_lazy(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t new)
{
- unsigned long vmaddr;
+ pmd_t old;
- vmaddr = (unsigned long)
- radix_tree_lookup(&gmap->guest_to_host, gaddr >> PMD_SHIFT);
- return vmaddr ? (vmaddr | (gaddr & ~PMD_MASK)) : -EFAULT;
+ old = pmdp_flush_lazy(mm, addr, pmdp);
+ *pmdp = new;
+ return old;
}
-EXPORT_SYMBOL_GPL(__gmap_translate);
-
-/**
- * gmap_translate - translate a guest address to a user space address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- *
- * Returns user space address which corresponds to the guest address or
- * -EFAULT if no such mapping exists.
- * This function does not establish potentially missing page table entries.
- */
-unsigned long gmap_translate(struct gmap *gmap, unsigned long gaddr)
+EXPORT_SYMBOL(pmdp_xchg_lazy);
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable)
{
- unsigned long rc;
+ struct list_head *lh = (struct list_head *) pgtable;
+
+ assert_spin_locked(pmd_lockptr(mm, pmdp));
- down_read(&gmap->mm->mmap_sem);
- rc = __gmap_translate(gmap, gaddr);
- up_read(&gmap->mm->mmap_sem);
- return rc;
+ /* FIFO */
+ if (!pmd_huge_pte(mm, pmdp))
+ INIT_LIST_HEAD(lh);
+ else
+ list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp));
+ pmd_huge_pte(mm, pmdp) = pgtable;
}
-EXPORT_SYMBOL_GPL(gmap_translate);
-/**
- * gmap_unlink - disconnect a page table from the gmap shadow tables
- * @gmap: pointer to guest mapping meta data structure
- * @table: pointer to the host page table
- * @vmaddr: vm address associated with the host page table
- */
-static void gmap_unlink(struct mm_struct *mm, unsigned long *table,
- unsigned long vmaddr)
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
{
- struct gmap *gmap;
- int flush;
+ struct list_head *lh;
+ pgtable_t pgtable;
+ pte_t *ptep;
+
+ assert_spin_locked(pmd_lockptr(mm, pmdp));
- list_for_each_entry(gmap, &mm->context.gmap_list, list) {
- flush = __gmap_unlink_by_vmaddr(gmap, vmaddr);
- if (flush)
- gmap_flush_tlb(gmap);
+ /* FIFO */
+ pgtable = pmd_huge_pte(mm, pmdp);
+ lh = (struct list_head *) pgtable;
+ if (list_empty(lh))
+ pmd_huge_pte(mm, pmdp) = NULL;
+ else {
+ pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next;
+ list_del(lh);
}
+ ptep = (pte_t *) pgtable;
+ pte_val(*ptep) = _PAGE_INVALID;
+ ptep++;
+ pte_val(*ptep) = _PAGE_INVALID;
+ return pgtable;
}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-/**
- * gmap_link - set up shadow page tables to connect a host to a guest address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- * @vmaddr: vm address
- *
- * Returns 0 on success, -ENOMEM for out of memory conditions, and -EFAULT
- * if the vm address is already mapped to a different guest segment.
- * The mmap_sem of the mm that belongs to the address space must be held
- * when this function gets called.
- */
-int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
+#ifdef CONFIG_PGSTE
+void ptep_set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t entry)
{
- struct mm_struct *mm;
- unsigned long *table;
- spinlock_t *ptl;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- int rc;
-
- /* Create higher level tables in the gmap page table */
- table = gmap->table;
- if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION1) {
- table += (gaddr >> 53) & 0x7ff;
- if ((*table & _REGION_ENTRY_INVALID) &&
- gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY,
- gaddr & 0xffe0000000000000UL))
- return -ENOMEM;
- table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
- }
- if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION2) {
- table += (gaddr >> 42) & 0x7ff;
- if ((*table & _REGION_ENTRY_INVALID) &&
- gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY,
- gaddr & 0xfffffc0000000000UL))
- return -ENOMEM;
- table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
- }
- if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION3) {
- table += (gaddr >> 31) & 0x7ff;
- if ((*table & _REGION_ENTRY_INVALID) &&
- gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY,
- gaddr & 0xffffffff80000000UL))
- return -ENOMEM;
- table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
- }
- table += (gaddr >> 20) & 0x7ff;
- /* Walk the parent mm page table */
- mm = gmap->mm;
- pgd = pgd_offset(mm, vmaddr);
- VM_BUG_ON(pgd_none(*pgd));
- pud = pud_offset(pgd, vmaddr);
- VM_BUG_ON(pud_none(*pud));
- pmd = pmd_offset(pud, vmaddr);
- VM_BUG_ON(pmd_none(*pmd));
- /* large pmds cannot yet be handled */
- if (pmd_large(*pmd))
- return -EFAULT;
- /* Link gmap segment table entry location to page table. */
- rc = radix_tree_preload(GFP_KERNEL);
- if (rc)
- return rc;
- ptl = pmd_lock(mm, pmd);
- spin_lock(&gmap->guest_table_lock);
- if (*table == _SEGMENT_ENTRY_INVALID) {
- rc = radix_tree_insert(&gmap->host_to_guest,
- vmaddr >> PMD_SHIFT, table);
- if (!rc)
- *table = pmd_val(*pmd);
- } else
- rc = 0;
- spin_unlock(&gmap->guest_table_lock);
- spin_unlock(ptl);
- radix_tree_preload_end();
- return rc;
+ pgste_t pgste;
+
+ /* the mm_has_pgste() check is done in set_pte_at() */
+ pgste = pgste_get_lock(ptep);
+ pgste_val(pgste) &= ~_PGSTE_GPS_ZERO;
+ pgste_set_key(ptep, pgste, entry, mm);
+ pgste = pgste_set_pte(ptep, pgste, entry);
+ pgste_set_unlock(ptep, pgste);
}
-/**
- * gmap_fault - resolve a fault on a guest address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- * @fault_flags: flags to pass down to handle_mm_fault()
- *
- * Returns 0 on success, -ENOMEM for out of memory conditions, and -EFAULT
- * if the vm address is already mapped to a different guest segment.
- */
-int gmap_fault(struct gmap *gmap, unsigned long gaddr,
- unsigned int fault_flags)
+void ptep_set_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
- unsigned long vmaddr;
- int rc;
-
- down_read(&gmap->mm->mmap_sem);
- vmaddr = __gmap_translate(gmap, gaddr);
- if (IS_ERR_VALUE(vmaddr)) {
- rc = vmaddr;
- goto out_up;
- }
- if (fixup_user_fault(current, gmap->mm, vmaddr, fault_flags)) {
- rc = -EFAULT;
- goto out_up;
- }
- rc = __gmap_link(gmap, gaddr, vmaddr);
-out_up:
- up_read(&gmap->mm->mmap_sem);
- return rc;
+ pgste_t pgste;
+
+ pgste = pgste_get_lock(ptep);
+ pgste_val(pgste) |= PGSTE_IN_BIT;
+ pgste_set_unlock(ptep, pgste);
}
-EXPORT_SYMBOL_GPL(gmap_fault);
-static void gmap_zap_swap_entry(swp_entry_t entry, struct mm_struct *mm)
+static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry)
{
if (!non_swap_entry(entry))
dec_mm_counter(mm, MM_SWAPENTS);
else if (is_migration_entry(entry)) {
struct page *page = migration_entry_to_page(entry);
- if (PageAnon(page))
- dec_mm_counter(mm, MM_ANONPAGES);
- else
- dec_mm_counter(mm, MM_FILEPAGES);
+ dec_mm_counter(mm, mm_counter(page));
}
free_swap_and_cache(entry);
}
-/*
- * this function is assumed to be called with mmap_sem held
- */
-void __gmap_zap(struct gmap *gmap, unsigned long gaddr)
+void ptep_zap_unused(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, int reset)
{
- unsigned long vmaddr, ptev, pgstev;
- pte_t *ptep, pte;
- spinlock_t *ptl;
+ unsigned long pgstev;
pgste_t pgste;
+ pte_t pte;
- /* Find the vm address for the guest address */
- vmaddr = (unsigned long) radix_tree_lookup(&gmap->guest_to_host,
- gaddr >> PMD_SHIFT);
- if (!vmaddr)
- return;
- vmaddr |= gaddr & ~PMD_MASK;
- /* Get pointer to the page table entry */
- ptep = get_locked_pte(gmap->mm, vmaddr, &ptl);
- if (unlikely(!ptep))
- return;
- pte = *ptep;
- if (!pte_swap(pte))
- goto out_pte;
/* Zap unused and logically-zero pages */
pgste = pgste_get_lock(ptep);
pgstev = pgste_val(pgste);
- ptev = pte_val(pte);
- if (((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED) ||
- ((pgstev & _PGSTE_GPS_ZERO) && (ptev & _PAGE_INVALID))) {
- gmap_zap_swap_entry(pte_to_swp_entry(pte), gmap->mm);
- pte_clear(gmap->mm, vmaddr, ptep);
- }
+ pte = *ptep;
+ if (pte_swap(pte) &&
+ ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED ||
+ (pgstev & _PGSTE_GPS_ZERO))) {
+ ptep_zap_swap_entry(mm, pte_to_swp_entry(pte));
+ pte_clear(mm, addr, ptep);
+ }
+ if (reset)
+ pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK;
pgste_set_unlock(ptep, pgste);
-out_pte:
- pte_unmap_unlock(ptep, ptl);
}
-EXPORT_SYMBOL_GPL(__gmap_zap);
-void gmap_discard(struct gmap *gmap, unsigned long from, unsigned long to)
+void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
- unsigned long gaddr, vmaddr, size;
- struct vm_area_struct *vma;
-
- down_read(&gmap->mm->mmap_sem);
- for (gaddr = from; gaddr < to;
- gaddr = (gaddr + PMD_SIZE) & PMD_MASK) {
- /* Find the vm address for the guest address */
- vmaddr = (unsigned long)
- radix_tree_lookup(&gmap->guest_to_host,
- gaddr >> PMD_SHIFT);
- if (!vmaddr)
- continue;
- vmaddr |= gaddr & ~PMD_MASK;
- /* Find vma in the parent mm */
- vma = find_vma(gmap->mm, vmaddr);
- size = min(to - gaddr, PMD_SIZE - (gaddr & ~PMD_MASK));
- zap_page_range(vma, vmaddr, size, NULL);
- }
- up_read(&gmap->mm->mmap_sem);
-}
-EXPORT_SYMBOL_GPL(gmap_discard);
-
-static LIST_HEAD(gmap_notifier_list);
-static DEFINE_SPINLOCK(gmap_notifier_lock);
+ unsigned long ptev;
+ pgste_t pgste;
-/**
- * gmap_register_ipte_notifier - register a pte invalidation callback
- * @nb: pointer to the gmap notifier block
- */
-void gmap_register_ipte_notifier(struct gmap_notifier *nb)
-{
- spin_lock(&gmap_notifier_lock);
- list_add(&nb->list, &gmap_notifier_list);
- spin_unlock(&gmap_notifier_lock);
+ /* Clear storage key */
+ pgste = pgste_get_lock(ptep);
+ pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT |
+ PGSTE_GR_BIT | PGSTE_GC_BIT);
+ ptev = pte_val(*ptep);
+ if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE))
+ page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1);
+ pgste_set_unlock(ptep, pgste);
}
-EXPORT_SYMBOL_GPL(gmap_register_ipte_notifier);
-/**
- * gmap_unregister_ipte_notifier - remove a pte invalidation callback
- * @nb: pointer to the gmap notifier block
- */
-void gmap_unregister_ipte_notifier(struct gmap_notifier *nb)
-{
- spin_lock(&gmap_notifier_lock);
- list_del_init(&nb->list);
- spin_unlock(&gmap_notifier_lock);
-}
-EXPORT_SYMBOL_GPL(gmap_unregister_ipte_notifier);
-
-/**
- * gmap_ipte_notify - mark a range of ptes for invalidation notification
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: virtual address in the guest address space
- * @len: size of area
- *
- * Returns 0 if for each page in the given range a gmap mapping exists and
- * the invalidation notification could be set. If the gmap mapping is missing
- * for one or more pages -EFAULT is returned. If no memory could be allocated
- * -ENOMEM is returned. This function establishes missing page table entries.
+/*
+ * Test and reset if a guest page is dirty
*/
-int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len)
+bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr)
{
- unsigned long addr;
spinlock_t *ptl;
- pte_t *ptep, entry;
pgste_t pgste;
- int rc = 0;
-
- if ((gaddr & ~PAGE_MASK) || (len & ~PAGE_MASK))
- return -EINVAL;
- down_read(&gmap->mm->mmap_sem);
- while (len) {
- /* Convert gmap address and connect the page tables */
- addr = __gmap_translate(gmap, gaddr);
- if (IS_ERR_VALUE(addr)) {
- rc = addr;
- break;
- }
- /* Get the page mapped */
- if (fixup_user_fault(current, gmap->mm, addr, FAULT_FLAG_WRITE)) {
- rc = -EFAULT;
- break;
- }
- rc = __gmap_link(gmap, gaddr, addr);
- if (rc)
- break;
- /* Walk the process page table, lock and get pte pointer */
- ptep = get_locked_pte(gmap->mm, addr, &ptl);
- VM_BUG_ON(!ptep);
- /* Set notification bit in the pgste of the pte */
- entry = *ptep;
- if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) {
- pgste = pgste_get_lock(ptep);
- pgste_val(pgste) |= PGSTE_IN_BIT;
- pgste_set_unlock(ptep, pgste);
- gaddr += PAGE_SIZE;
- len -= PAGE_SIZE;
- }
- pte_unmap_unlock(ptep, ptl);
- }
- up_read(&gmap->mm->mmap_sem);
- return rc;
-}
-EXPORT_SYMBOL_GPL(gmap_ipte_notify);
-
-/**
- * gmap_do_ipte_notify - call all invalidation callbacks for a specific pte.
- * @mm: pointer to the process mm_struct
- * @addr: virtual address in the process address space
- * @pte: pointer to the page table entry
- *
- * This function is assumed to be called with the page table lock held
- * for the pte to notify.
- */
-void gmap_do_ipte_notify(struct mm_struct *mm, unsigned long vmaddr, pte_t *pte)
-{
- unsigned long offset, gaddr;
- unsigned long *table;
- struct gmap_notifier *nb;
- struct gmap *gmap;
-
- offset = ((unsigned long) pte) & (255 * sizeof(pte_t));
- offset = offset * (4096 / sizeof(pte_t));
- spin_lock(&gmap_notifier_lock);
- list_for_each_entry(gmap, &mm->context.gmap_list, list) {
- table = radix_tree_lookup(&gmap->host_to_guest,
- vmaddr >> PMD_SHIFT);
- if (!table)
- continue;
- gaddr = __gmap_segment_gaddr(table) + offset;
- list_for_each_entry(nb, &gmap_notifier_list, list)
- nb->notifier_call(gmap, gaddr);
+ pte_t *ptep;
+ pte_t pte;
+ bool dirty;
+
+ ptep = get_locked_pte(mm, addr, &ptl);
+ if (unlikely(!ptep))
+ return false;
+
+ pgste = pgste_get_lock(ptep);
+ dirty = !!(pgste_val(pgste) & PGSTE_UC_BIT);
+ pgste_val(pgste) &= ~PGSTE_UC_BIT;
+ pte = *ptep;
+ if (dirty && (pte_val(pte) & _PAGE_PRESENT)) {
+ pgste = pgste_ipte_notify(mm, addr, ptep, pgste);
+ __ptep_ipte(addr, ptep);
+ if (MACHINE_HAS_ESOP || !(pte_val(pte) & _PAGE_WRITE))
+ pte_val(pte) |= _PAGE_PROTECT;
+ else
+ pte_val(pte) |= _PAGE_INVALID;
+ *ptep = pte;
}
- spin_unlock(&gmap_notifier_lock);
+ pgste_set_unlock(ptep, pgste);
+
+ spin_unlock(ptl);
+ return dirty;
}
-EXPORT_SYMBOL_GPL(gmap_do_ipte_notify);
+EXPORT_SYMBOL_GPL(test_and_clear_guest_dirty);
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
- unsigned long key, bool nq)
+ unsigned char key, bool nq)
{
+ unsigned long keyul;
spinlock_t *ptl;
pgste_t old, new;
pte_t *ptep;
down_read(&mm->mmap_sem);
-retry:
ptep = get_locked_pte(mm, addr, &ptl);
if (unlikely(!ptep)) {
up_read(&mm->mmap_sem);
return -EFAULT;
}
- if (!(pte_val(*ptep) & _PAGE_INVALID) &&
- (pte_val(*ptep) & _PAGE_PROTECT)) {
- pte_unmap_unlock(ptep, ptl);
- if (fixup_user_fault(current, mm, addr, FAULT_FLAG_WRITE)) {
- up_read(&mm->mmap_sem);
- return -EFAULT;
- }
- goto retry;
- }
new = old = pgste_get_lock(ptep);
pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |
PGSTE_ACC_BITS | PGSTE_FP_BIT);
- pgste_val(new) |= (key & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48;
- pgste_val(new) |= (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
+ keyul = (unsigned long) key;
+ pgste_val(new) |= (keyul & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48;
+ pgste_val(new) |= (keyul & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
if (!(pte_val(*ptep) & _PAGE_INVALID)) {
unsigned long address, bits, skey;
@@ -841,13 +543,12 @@ retry:
}
EXPORT_SYMBOL(set_guest_storage_key);
-unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr)
+unsigned char get_guest_storage_key(struct mm_struct *mm, unsigned long addr)
{
+ unsigned char key;
spinlock_t *ptl;
pgste_t pgste;
pte_t *ptep;
- uint64_t physaddr;
- unsigned long key = 0;
down_read(&mm->mmap_sem);
ptep = get_locked_pte(mm, addr, &ptl);
@@ -858,13 +559,12 @@ unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr)
pgste = pgste_get_lock(ptep);
if (pte_val(*ptep) & _PAGE_INVALID) {
- key |= (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56;
+ key = (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56;
key |= (pgste_val(pgste) & PGSTE_FP_BIT) >> 56;
key |= (pgste_val(pgste) & PGSTE_GR_BIT) >> 48;
key |= (pgste_val(pgste) & PGSTE_GC_BIT) >> 48;
} else {
- physaddr = pte_val(*ptep) & PAGE_MASK;
- key = page_get_storage_key(physaddr);
+ key = page_get_storage_key(pte_val(*ptep) & PAGE_MASK);
/* Reflect guest's logical view, not physical */
if (pgste_val(pgste) & PGSTE_GR_BIT)
@@ -879,487 +579,4 @@ unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr)
return key;
}
EXPORT_SYMBOL(get_guest_storage_key);
-
-static int page_table_allocate_pgste_min = 0;
-static int page_table_allocate_pgste_max = 1;
-int page_table_allocate_pgste = 0;
-EXPORT_SYMBOL(page_table_allocate_pgste);
-
-static struct ctl_table page_table_sysctl[] = {
- {
- .procname = "allocate_pgste",
- .data = &page_table_allocate_pgste,
- .maxlen = sizeof(int),
- .mode = S_IRUGO | S_IWUSR,
- .proc_handler = proc_dointvec,
- .extra1 = &page_table_allocate_pgste_min,
- .extra2 = &page_table_allocate_pgste_max,
- },
- { }
-};
-
-static struct ctl_table page_table_sysctl_dir[] = {
- {
- .procname = "vm",
- .maxlen = 0,
- .mode = 0555,
- .child = page_table_sysctl,
- },
- { }
-};
-
-static int __init page_table_register_sysctl(void)
-{
- return register_sysctl_table(page_table_sysctl_dir) ? 0 : -ENOMEM;
-}
-__initcall(page_table_register_sysctl);
-
-#else /* CONFIG_PGSTE */
-
-static inline void gmap_unlink(struct mm_struct *mm, unsigned long *table,
- unsigned long vmaddr)
-{
-}
-
-#endif /* CONFIG_PGSTE */
-
-static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits)
-{
- unsigned int old, new;
-
- do {
- old = atomic_read(v);
- new = old ^ bits;
- } while (atomic_cmpxchg(v, old, new) != old);
- return new;
-}
-
-/*
- * page table entry allocation/free routines.
- */
-unsigned long *page_table_alloc(struct mm_struct *mm)
-{
- unsigned long *table;
- struct page *page;
- unsigned int mask, bit;
-
- /* Try to get a fragment of a 4K page as a 2K page table */
- if (!mm_alloc_pgste(mm)) {
- table = NULL;
- spin_lock_bh(&mm->context.list_lock);
- if (!list_empty(&mm->context.pgtable_list)) {
- page = list_first_entry(&mm->context.pgtable_list,
- struct page, lru);
- mask = atomic_read(&page->_mapcount);
- mask = (mask | (mask >> 4)) & 3;
- if (mask != 3) {
- table = (unsigned long *) page_to_phys(page);
- bit = mask & 1; /* =1 -> second 2K */
- if (bit)
- table += PTRS_PER_PTE;
- atomic_xor_bits(&page->_mapcount, 1U << bit);
- list_del(&page->lru);
- }
- }
- spin_unlock_bh(&mm->context.list_lock);
- if (table)
- return table;
- }
- /* Allocate a fresh page */
- page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
- if (!page)
- return NULL;
- if (!pgtable_page_ctor(page)) {
- __free_page(page);
- return NULL;
- }
- /* Initialize page table */
- table = (unsigned long *) page_to_phys(page);
- if (mm_alloc_pgste(mm)) {
- /* Return 4K page table with PGSTEs */
- atomic_set(&page->_mapcount, 3);
- clear_table(table, _PAGE_INVALID, PAGE_SIZE/2);
- clear_table(table + PTRS_PER_PTE, 0, PAGE_SIZE/2);
- } else {
- /* Return the first 2K fragment of the page */
- atomic_set(&page->_mapcount, 1);
- clear_table(table, _PAGE_INVALID, PAGE_SIZE);
- spin_lock_bh(&mm->context.list_lock);
- list_add(&page->lru, &mm->context.pgtable_list);
- spin_unlock_bh(&mm->context.list_lock);
- }
- return table;
-}
-
-void page_table_free(struct mm_struct *mm, unsigned long *table)
-{
- struct page *page;
- unsigned int bit, mask;
-
- page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
- if (!mm_alloc_pgste(mm)) {
- /* Free 2K page table fragment of a 4K page */
- bit = (__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t));
- spin_lock_bh(&mm->context.list_lock);
- mask = atomic_xor_bits(&page->_mapcount, 1U << bit);
- if (mask & 3)
- list_add(&page->lru, &mm->context.pgtable_list);
- else
- list_del(&page->lru);
- spin_unlock_bh(&mm->context.list_lock);
- if (mask != 0)
- return;
- }
-
- pgtable_page_dtor(page);
- atomic_set(&page->_mapcount, -1);
- __free_page(page);
-}
-
-void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table,
- unsigned long vmaddr)
-{
- struct mm_struct *mm;
- struct page *page;
- unsigned int bit, mask;
-
- mm = tlb->mm;
- page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
- if (mm_alloc_pgste(mm)) {
- gmap_unlink(mm, table, vmaddr);
- table = (unsigned long *) (__pa(table) | 3);
- tlb_remove_table(tlb, table);
- return;
- }
- bit = (__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t));
- spin_lock_bh(&mm->context.list_lock);
- mask = atomic_xor_bits(&page->_mapcount, 0x11U << bit);
- if (mask & 3)
- list_add_tail(&page->lru, &mm->context.pgtable_list);
- else
- list_del(&page->lru);
- spin_unlock_bh(&mm->context.list_lock);
- table = (unsigned long *) (__pa(table) | (1U << bit));
- tlb_remove_table(tlb, table);
-}
-
-static void __tlb_remove_table(void *_table)
-{
- unsigned int mask = (unsigned long) _table & 3;
- void *table = (void *)((unsigned long) _table ^ mask);
- struct page *page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
-
- switch (mask) {
- case 0: /* pmd or pud */
- free_pages((unsigned long) table, 2);
- break;
- case 1: /* lower 2K of a 4K page table */
- case 2: /* higher 2K of a 4K page table */
- if (atomic_xor_bits(&page->_mapcount, mask << 4) != 0)
- break;
- /* fallthrough */
- case 3: /* 4K page table with pgstes */
- pgtable_page_dtor(page);
- atomic_set(&page->_mapcount, -1);
- __free_page(page);
- break;
- }
-}
-
-static void tlb_remove_table_smp_sync(void *arg)
-{
- /* Simply deliver the interrupt */
-}
-
-static void tlb_remove_table_one(void *table)
-{
- /*
- * This isn't an RCU grace period and hence the page-tables cannot be
- * assumed to be actually RCU-freed.
- *
- * It is however sufficient for software page-table walkers that rely
- * on IRQ disabling. See the comment near struct mmu_table_batch.
- */
- smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
- __tlb_remove_table(table);
-}
-
-static void tlb_remove_table_rcu(struct rcu_head *head)
-{
- struct mmu_table_batch *batch;
- int i;
-
- batch = container_of(head, struct mmu_table_batch, rcu);
-
- for (i = 0; i < batch->nr; i++)
- __tlb_remove_table(batch->tables[i]);
-
- free_page((unsigned long)batch);
-}
-
-void tlb_table_flush(struct mmu_gather *tlb)
-{
- struct mmu_table_batch **batch = &tlb->batch;
-
- if (*batch) {
- call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
- *batch = NULL;
- }
-}
-
-void tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- struct mmu_table_batch **batch = &tlb->batch;
-
- tlb->mm->context.flush_mm = 1;
- if (*batch == NULL) {
- *batch = (struct mmu_table_batch *)
- __get_free_page(GFP_NOWAIT | __GFP_NOWARN);
- if (*batch == NULL) {
- __tlb_flush_mm_lazy(tlb->mm);
- tlb_remove_table_one(table);
- return;
- }
- (*batch)->nr = 0;
- }
- (*batch)->tables[(*batch)->nr++] = table;
- if ((*batch)->nr == MAX_TABLE_BATCH)
- tlb_flush_mmu(tlb);
-}
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static inline void thp_split_vma(struct vm_area_struct *vma)
-{
- unsigned long addr;
-
- for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE)
- follow_page(vma, addr, FOLL_SPLIT);
-}
-
-static inline void thp_split_mm(struct mm_struct *mm)
-{
- struct vm_area_struct *vma;
-
- for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
- thp_split_vma(vma);
- vma->vm_flags &= ~VM_HUGEPAGE;
- vma->vm_flags |= VM_NOHUGEPAGE;
- }
- mm->def_flags |= VM_NOHUGEPAGE;
-}
-#else
-static inline void thp_split_mm(struct mm_struct *mm)
-{
-}
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-
-/*
- * switch on pgstes for its userspace process (for kvm)
- */
-int s390_enable_sie(void)
-{
- struct mm_struct *mm = current->mm;
-
- /* Do we have pgstes? if yes, we are done */
- if (mm_has_pgste(mm))
- return 0;
- /* Fail if the page tables are 2K */
- if (!mm_alloc_pgste(mm))
- return -EINVAL;
- down_write(&mm->mmap_sem);
- mm->context.has_pgste = 1;
- /* split thp mappings and disable thp for future mappings */
- thp_split_mm(mm);
- up_write(&mm->mmap_sem);
- return 0;
-}
-EXPORT_SYMBOL_GPL(s390_enable_sie);
-
-/*
- * Enable storage key handling from now on and initialize the storage
- * keys with the default key.
- */
-static int __s390_enable_skey(pte_t *pte, unsigned long addr,
- unsigned long next, struct mm_walk *walk)
-{
- unsigned long ptev;
- pgste_t pgste;
-
- pgste = pgste_get_lock(pte);
- /*
- * Remove all zero page mappings,
- * after establishing a policy to forbid zero page mappings
- * following faults for that page will get fresh anonymous pages
- */
- if (is_zero_pfn(pte_pfn(*pte))) {
- ptep_flush_direct(walk->mm, addr, pte);
- pte_val(*pte) = _PAGE_INVALID;
- }
- /* Clear storage key */
- pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT |
- PGSTE_GR_BIT | PGSTE_GC_BIT);
- ptev = pte_val(*pte);
- if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE))
- page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1);
- pgste_set_unlock(pte, pgste);
- return 0;
-}
-
-int s390_enable_skey(void)
-{
- struct mm_walk walk = { .pte_entry = __s390_enable_skey };
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- int rc = 0;
-
- down_write(&mm->mmap_sem);
- if (mm_use_skey(mm))
- goto out_up;
-
- mm->context.use_skey = 1;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
- MADV_UNMERGEABLE, &vma->vm_flags)) {
- mm->context.use_skey = 0;
- rc = -ENOMEM;
- goto out_up;
- }
- }
- mm->def_flags &= ~VM_MERGEABLE;
-
- walk.mm = mm;
- walk_page_range(0, TASK_SIZE, &walk);
-
-out_up:
- up_write(&mm->mmap_sem);
- return rc;
-}
-EXPORT_SYMBOL_GPL(s390_enable_skey);
-
-/*
- * Reset CMMA state, make all pages stable again.
- */
-static int __s390_reset_cmma(pte_t *pte, unsigned long addr,
- unsigned long next, struct mm_walk *walk)
-{
- pgste_t pgste;
-
- pgste = pgste_get_lock(pte);
- pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK;
- pgste_set_unlock(pte, pgste);
- return 0;
-}
-
-void s390_reset_cmma(struct mm_struct *mm)
-{
- struct mm_walk walk = { .pte_entry = __s390_reset_cmma };
-
- down_write(&mm->mmap_sem);
- walk.mm = mm;
- walk_page_range(0, TASK_SIZE, &walk);
- up_write(&mm->mmap_sem);
-}
-EXPORT_SYMBOL_GPL(s390_reset_cmma);
-
-/*
- * Test and reset if a guest page is dirty
- */
-bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *gmap)
-{
- pte_t *pte;
- spinlock_t *ptl;
- bool dirty = false;
-
- pte = get_locked_pte(gmap->mm, address, &ptl);
- if (unlikely(!pte))
- return false;
-
- if (ptep_test_and_clear_user_dirty(gmap->mm, address, pte))
- dirty = true;
-
- spin_unlock(ptl);
- return dirty;
-}
-EXPORT_SYMBOL_GPL(gmap_test_and_clear_dirty);
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp)
-{
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- /* No need to flush TLB
- * On s390 reference bits are in storage key and never in TLB */
- return pmdp_test_and_clear_young(vma, address, pmdp);
-}
-
-int pmdp_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp,
- pmd_t entry, int dirty)
-{
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-
- entry = pmd_mkyoung(entry);
- if (dirty)
- entry = pmd_mkdirty(entry);
- if (pmd_same(*pmdp, entry))
- return 0;
- pmdp_invalidate(vma, address, pmdp);
- set_pmd_at(vma->vm_mm, address, pmdp, entry);
- return 1;
-}
-
-static void pmdp_splitting_flush_sync(void *arg)
-{
- /* Simply deliver the interrupt */
-}
-
-void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp)
-{
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- if (!test_and_set_bit(_SEGMENT_ENTRY_SPLIT_BIT,
- (unsigned long *) pmdp)) {
- /* need to serialize against gup-fast (IRQ disabled) */
- smp_call_function(pmdp_splitting_flush_sync, NULL, 1);
- }
-}
-
-void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
- pgtable_t pgtable)
-{
- struct list_head *lh = (struct list_head *) pgtable;
-
- assert_spin_locked(pmd_lockptr(mm, pmdp));
-
- /* FIFO */
- if (!pmd_huge_pte(mm, pmdp))
- INIT_LIST_HEAD(lh);
- else
- list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp));
- pmd_huge_pte(mm, pmdp) = pgtable;
-}
-
-pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
-{
- struct list_head *lh;
- pgtable_t pgtable;
- pte_t *ptep;
-
- assert_spin_locked(pmd_lockptr(mm, pmdp));
-
- /* FIFO */
- pgtable = pmd_huge_pte(mm, pmdp);
- lh = (struct list_head *) pgtable;
- if (list_empty(lh))
- pmd_huge_pte(mm, pmdp) = NULL;
- else {
- pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next;
- list_del(lh);
- }
- ptep = (pte_t *) pgtable;
- pte_val(*ptep) = _PAGE_INVALID;
- ptep++;
- pte_val(*ptep) = _PAGE_INVALID;
- return pgtable;
-}
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index ef7d6c8..d27fccba 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -94,16 +94,15 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
pgd_populate(&init_mm, pg_dir, pu_dir);
}
pu_dir = pud_offset(pg_dir, address);
-#ifndef CONFIG_DEBUG_PAGEALLOC
if (MACHINE_HAS_EDAT2 && pud_none(*pu_dir) && address &&
- !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) {
+ !(address & ~PUD_MASK) && (address + PUD_SIZE <= end) &&
+ !debug_pagealloc_enabled()) {
pud_val(*pu_dir) = __pa(address) |
_REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE |
(ro ? _REGION_ENTRY_PROTECT : 0);
address += PUD_SIZE;
continue;
}
-#endif
if (pud_none(*pu_dir)) {
pm_dir = vmem_pmd_alloc();
if (!pm_dir)
@@ -111,9 +110,9 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
pud_populate(&init_mm, pu_dir, pm_dir);
}
pm_dir = pmd_offset(pu_dir, address);
-#ifndef CONFIG_DEBUG_PAGEALLOC
if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address &&
- !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) {
+ !(address & ~PMD_MASK) && (address + PMD_SIZE <= end) &&
+ !debug_pagealloc_enabled()) {
pmd_val(*pm_dir) = __pa(address) |
_SEGMENT_ENTRY | _SEGMENT_ENTRY_LARGE |
_SEGMENT_ENTRY_YOUNG |
@@ -121,7 +120,6 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
address += PMD_SIZE;
continue;
}
-#endif
if (pmd_none(*pm_dir)) {
pt_dir = vmem_pte_alloc(address);
if (!pt_dir)
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index eeda051..3c0bfc1 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -408,7 +408,7 @@ static void emit_load_skb_data_hlen(struct bpf_jit *jit)
* Save registers and create stack frame if necessary.
* See stack frame layout desription in "bpf_jit.h"!
*/
-static void bpf_jit_prologue(struct bpf_jit *jit, bool is_classic)
+static void bpf_jit_prologue(struct bpf_jit *jit)
{
if (jit->seen & SEEN_TAIL_CALL) {
/* xc STK_OFF_TCCNT(4,%r15),STK_OFF_TCCNT(%r15) */
@@ -448,15 +448,6 @@ static void bpf_jit_prologue(struct bpf_jit *jit, bool is_classic)
/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, REG_15,
STK_OFF_SKBP);
- /* Clear A (%b0) and X (%b7) registers for converted BPF programs */
- if (is_classic) {
- if (REG_SEEN(BPF_REG_A))
- /* lghi %ba,0 */
- EMIT4_IMM(0xa7090000, BPF_REG_A, 0);
- if (REG_SEEN(BPF_REG_X))
- /* lghi %bx,0 */
- EMIT4_IMM(0xa7090000, BPF_REG_X, 0);
- }
}
/*
@@ -1245,7 +1236,7 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp)
jit->lit = jit->lit_start;
jit->prg = 0;
- bpf_jit_prologue(jit, bpf_prog_was_classic(fp));
+ bpf_jit_prologue(jit);
for (i = 0; i < fp->len; i += insn_count) {
insn_count = bpf_jit_insn(jit, fp, i);
if (insn_count < 0)
@@ -1310,7 +1301,7 @@ void bpf_int_jit_compile(struct bpf_prog *fp)
if (jit.prg_buf) {
set_memory_ro((unsigned long)header, header->pages);
fp->bpf_func = (void *) jit.prg_buf;
- fp->jited = true;
+ fp->jited = 1;
}
free_addrs:
kfree(jit.addrs);
diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c
index 30b2698a..828d069 100644
--- a/arch/s390/numa/mode_emu.c
+++ b/arch/s390/numa/mode_emu.c
@@ -436,9 +436,15 @@ static void emu_update_cpu_topology(void)
*/
static unsigned long emu_setup_size_adjust(unsigned long size)
{
+ unsigned long size_new;
+
size = size ? : CONFIG_EMU_SIZE;
- size = roundup(size, memory_block_size_bytes());
- return size;
+ size_new = roundup(size, memory_block_size_bytes());
+ if (size_new == size)
+ return size;
+ pr_warn("Increasing memory stripe size from %ld MB to %ld MB\n",
+ size >> 20, size_new >> 20);
+ return size_new;
}
/*
diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c
index 43f32ce..2794845 100644
--- a/arch/s390/numa/numa.c
+++ b/arch/s390/numa/numa.c
@@ -57,9 +57,7 @@ static __init pg_data_t *alloc_node_data(void)
{
pg_data_t *res;
- res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 1);
- if (!res)
- panic("Could not allocate memory for node data!\n");
+ res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8);
memset(res, 0, sizeof(pg_data_t));
return res;
}
@@ -162,7 +160,7 @@ static int __init numa_init_late(void)
register_one_node(nid);
return 0;
}
-device_initcall(numa_init_late);
+arch_initcall(numa_init_late);
static int __init parse_debug(char *parm)
{
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile
index 1bd2301..496e4a7 100644
--- a/arch/s390/oprofile/Makefile
+++ b/arch/s390/oprofile/Makefile
@@ -6,5 +6,5 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
-oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
+oprofile-y := $(DRIVER_OBJS) init.o
oprofile-y += hwsampler.o
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c
deleted file mode 100644
index 8a6811b..0000000
--- a/arch/s390/oprofile/backtrace.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * S390 Version
- * Copyright IBM Corp. 2005
- * Author(s): Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
- */
-
-#include <linux/oprofile.h>
-
-#include <asm/processor.h> /* for struct stack_frame */
-
-static unsigned long
-__show_trace(unsigned int *depth, unsigned long sp,
- unsigned long low, unsigned long high)
-{
- struct stack_frame *sf;
- struct pt_regs *regs;
-
- while (*depth) {
- sp = sp & PSW_ADDR_INSN;
- if (sp < low || sp > high - sizeof(*sf))
- return sp;
- sf = (struct stack_frame *) sp;
- (*depth)--;
- oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
-
- /* Follow the backchain. */
- while (*depth) {
- low = sp;
- sp = sf->back_chain & PSW_ADDR_INSN;
- if (!sp)
- break;
- if (sp <= low || sp > high - sizeof(*sf))
- return sp;
- sf = (struct stack_frame *) sp;
- (*depth)--;
- oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
-
- }
-
- if (*depth == 0)
- break;
-
- /* Zero backchain detected, check for interrupt frame. */
- sp = (unsigned long) (sf + 1);
- if (sp <= low || sp > high - sizeof(*regs))
- return sp;
- regs = (struct pt_regs *) sp;
- (*depth)--;
- oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
- low = sp;
- sp = regs->gprs[15];
- }
- return sp;
-}
-
-void s390_backtrace(struct pt_regs * const regs, unsigned int depth)
-{
- unsigned long head;
- struct stack_frame* head_sf;
-
- if (user_mode(regs))
- return;
-
- head = regs->gprs[15];
- head_sf = (struct stack_frame*)head;
-
- if (!head_sf->back_chain)
- return;
-
- head = head_sf->back_chain;
-
- head = __show_trace(&depth, head, S390_lowcore.async_stack - ASYNC_SIZE,
- S390_lowcore.async_stack);
-
- __show_trace(&depth, head, S390_lowcore.thread_info,
- S390_lowcore.thread_info + THREAD_SIZE);
-}
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
index 9cfa2ff..791935a 100644
--- a/arch/s390/oprofile/init.c
+++ b/arch/s390/oprofile/init.c
@@ -20,8 +20,6 @@
#include "../../../drivers/oprofile/oprof.h"
-extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth);
-
#include "hwsampler.h"
#include "op_counter.h"
@@ -456,6 +454,7 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops)
case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break;
case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break;
case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break;
+ case 0x2964: case 0x2965: ops->cpu_type = "s390/z13"; break;
default: return -ENODEV;
}
}
@@ -494,6 +493,24 @@ static void oprofile_hwsampler_exit(void)
hwsampler_shutdown();
}
+static int __s390_backtrace(void *data, unsigned long address)
+{
+ unsigned int *depth = data;
+
+ if (*depth == 0)
+ return 1;
+ (*depth)--;
+ oprofile_add_trace(address);
+ return 0;
+}
+
+static void s390_backtrace(struct pt_regs *regs, unsigned int depth)
+{
+ if (user_mode(regs))
+ return;
+ dump_trace(__s390_backtrace, &depth, NULL, regs->gprs[15]);
+}
+
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
ops->backtrace = s390_backtrace;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 7ef12a3..9fd59a7 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = {
.isc = PCI_ISC,
};
-/* I/O Map */
+#define ZPCI_IOMAP_ENTRIES \
+ min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT), \
+ ZPCI_IOMAP_MAX_ENTRIES)
+
static DEFINE_SPINLOCK(zpci_iomap_lock);
-static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
+static unsigned long *zpci_iomap_bitmap;
struct zpci_iomap_entry *zpci_iomap_start;
EXPORT_SYMBOL_GPL(zpci_iomap_start);
@@ -265,27 +268,20 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev,
unsigned long max)
{
struct zpci_dev *zdev = to_zpci(pdev);
- u64 addr;
int idx;
- if ((bar & 7) != bar)
+ if (!pci_resource_len(pdev, bar))
return NULL;
idx = zdev->bars[bar].map_idx;
spin_lock(&zpci_iomap_lock);
- if (zpci_iomap_start[idx].count++) {
- BUG_ON(zpci_iomap_start[idx].fh != zdev->fh ||
- zpci_iomap_start[idx].bar != bar);
- } else {
- zpci_iomap_start[idx].fh = zdev->fh;
- zpci_iomap_start[idx].bar = bar;
- }
/* Detect overrun */
- BUG_ON(!zpci_iomap_start[idx].count);
+ WARN_ON(!++zpci_iomap_start[idx].count);
+ zpci_iomap_start[idx].fh = zdev->fh;
+ zpci_iomap_start[idx].bar = bar;
spin_unlock(&zpci_iomap_lock);
- addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
- return (void __iomem *) addr + offset;
+ return (void __iomem *) ZPCI_ADDR(idx) + offset;
}
EXPORT_SYMBOL(pci_iomap_range);
@@ -297,12 +293,11 @@ EXPORT_SYMBOL(pci_iomap);
void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
{
- unsigned int idx;
+ unsigned int idx = ZPCI_IDX(addr);
- idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
spin_lock(&zpci_iomap_lock);
/* Detect underrun */
- BUG_ON(!zpci_iomap_start[idx].count);
+ WARN_ON(!zpci_iomap_start[idx].count);
if (!--zpci_iomap_start[idx].count) {
zpci_iomap_start[idx].fh = 0;
zpci_iomap_start[idx].bar = 0;
@@ -544,15 +539,15 @@ static void zpci_irq_exit(void)
static int zpci_alloc_iomap(struct zpci_dev *zdev)
{
- int entry;
+ unsigned long entry;
spin_lock(&zpci_iomap_lock);
- entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
- if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
+ entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES);
+ if (entry == ZPCI_IOMAP_ENTRIES) {
spin_unlock(&zpci_iomap_lock);
return -ENOSPC;
}
- set_bit(entry, zpci_iomap);
+ set_bit(entry, zpci_iomap_bitmap);
spin_unlock(&zpci_iomap_lock);
return entry;
}
@@ -561,7 +556,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
{
spin_lock(&zpci_iomap_lock);
memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
- clear_bit(entry, zpci_iomap);
+ clear_bit(entry, zpci_iomap_bitmap);
spin_unlock(&zpci_iomap_lock);
}
@@ -611,8 +606,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev,
if (zdev->bars[i].val & 4)
flags |= IORESOURCE_MEM_64;
- addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
-
+ addr = ZPCI_ADDR(entry);
size = 1UL << zdev->bars[i].size;
res = __alloc_res(zdev, addr, size, flags);
@@ -643,11 +637,9 @@ static void zpci_cleanup_bus_resources(struct zpci_dev *zdev)
int pcibios_add_device(struct pci_dev *pdev)
{
- struct zpci_dev *zdev = to_zpci(pdev);
struct resource *res;
int i;
- zdev->pdev = pdev;
pdev->dev.groups = zpci_attr_groups;
zpci_map_resources(pdev);
@@ -670,8 +662,7 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask)
{
struct zpci_dev *zdev = to_zpci(pdev);
- zdev->pdev = pdev;
- zpci_debug_init_device(zdev);
+ zpci_debug_init_device(zdev, dev_name(&pdev->dev));
zpci_fmb_enable_device(zdev);
return pci_enable_resources(pdev, mask);
@@ -683,7 +674,6 @@ void pcibios_disable_device(struct pci_dev *pdev)
zpci_fmb_disable_device(zdev);
zpci_debug_exit_device(zdev);
- zdev->pdev = NULL;
}
#ifdef CONFIG_HIBERNATE_CALLBACKS
@@ -701,8 +691,7 @@ static int zpci_restore(struct device *dev)
goto out;
zpci_map_resources(pdev);
- zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
- zdev->start_dma + zdev->iommu_size - 1,
+ zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
(u64) zdev->dma_table);
out:
@@ -871,26 +860,36 @@ static inline int barsize(u8 size)
static int zpci_mem_init(void)
{
+ BUILD_BUG_ON(!is_power_of_2(__alignof__(struct zpci_fmb)) ||
+ __alignof__(struct zpci_fmb) < sizeof(struct zpci_fmb));
+
zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
- 16, 0, NULL);
+ __alignof__(struct zpci_fmb), 0, NULL);
if (!zdev_fmb_cache)
- goto error_zdev;
+ goto error_fmb;
- /* TODO: use realloc */
- zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
- GFP_KERNEL);
+ zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES,
+ sizeof(*zpci_iomap_start), GFP_KERNEL);
if (!zpci_iomap_start)
goto error_iomap;
- return 0;
+ zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES),
+ sizeof(*zpci_iomap_bitmap), GFP_KERNEL);
+ if (!zpci_iomap_bitmap)
+ goto error_iomap_bitmap;
+
+ return 0;
+error_iomap_bitmap:
+ kfree(zpci_iomap_start);
error_iomap:
kmem_cache_destroy(zdev_fmb_cache);
-error_zdev:
+error_fmb:
return -ENOMEM;
}
static void zpci_mem_exit(void)
{
+ kfree(zpci_iomap_bitmap);
kfree(zpci_iomap_start);
kmem_cache_destroy(zdev_fmb_cache);
}
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index d6e411e..21591dd 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -8,13 +8,19 @@
#define KMSG_COMPONENT "zpci"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/compat.h>
#include <linux/kernel.h>
+#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/uaccess.h>
#include <asm/pci_debug.h>
#include <asm/pci_clp.h>
+#include <asm/compat.h>
+#include <asm/clp.h>
+#include <uapi/asm/clp.h>
static inline void zpci_err_clp(unsigned int rsp, int rc)
{
@@ -27,21 +33,43 @@ static inline void zpci_err_clp(unsigned int rsp, int rc)
}
/*
- * Call Logical Processor
- * Retry logic is handled by the caller.
+ * Call Logical Processor with c=1, lps=0 and command 1
+ * to get the bit mask of installed logical processors
*/
-static inline u8 clp_instr(void *data)
+static inline int clp_get_ilp(unsigned long *ilp)
+{
+ unsigned long mask;
+ int cc = 3;
+
+ asm volatile (
+ " .insn rrf,0xb9a00000,%[mask],%[cmd],8,0\n"
+ "0: ipm %[cc]\n"
+ " srl %[cc],28\n"
+ "1:\n"
+ EX_TABLE(0b, 1b)
+ : [cc] "+d" (cc), [mask] "=d" (mask) : [cmd] "a" (1)
+ : "cc");
+ *ilp = mask;
+ return cc;
+}
+
+/*
+ * Call Logical Processor with c=0, the give constant lps and an lpcb request.
+ */
+static inline int clp_req(void *data, unsigned int lps)
{
struct { u8 _[CLP_BLK_SIZE]; } *req = data;
u64 ignored;
- u8 cc;
+ int cc = 3;
asm volatile (
- " .insn rrf,0xb9a00000,%[ign],%[req],0x0,0x2\n"
- " ipm %[cc]\n"
+ " .insn rrf,0xb9a00000,%[ign],%[req],0,%[lps]\n"
+ "0: ipm %[cc]\n"
" srl %[cc],28\n"
- : [cc] "=d" (cc), [ign] "=d" (ignored), "+m" (*req)
- : [req] "a" (req)
+ "1:\n"
+ EX_TABLE(0b, 1b)
+ : [cc] "+d" (cc), [ign] "=d" (ignored), "+m" (*req)
+ : [req] "a" (req), [lps] "i" (lps)
: "cc");
return cc;
}
@@ -90,7 +118,7 @@ static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
rrb->response.hdr.len = sizeof(rrb->response);
rrb->request.pfgid = pfgid;
- rc = clp_instr(rrb);
+ rc = clp_req(rrb, CLP_LPS_PCI);
if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
clp_store_query_pci_fngrp(zdev, &rrb->response);
else {
@@ -143,7 +171,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
rrb->response.hdr.len = sizeof(rrb->response);
rrb->request.fh = fh;
- rc = clp_instr(rrb);
+ rc = clp_req(rrb, CLP_LPS_PCI);
if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
rc = clp_store_query_pci_fn(zdev, &rrb->response);
if (rc)
@@ -214,7 +242,7 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
rrb->request.oc = command;
rrb->request.ndas = nr_dma_as;
- rc = clp_instr(rrb);
+ rc = clp_req(rrb, CLP_LPS_PCI);
if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) {
retries--;
if (retries < 0)
@@ -280,7 +308,7 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,
rrb->request.resume_token = resume_token;
/* Get PCI function handle list */
- rc = clp_instr(rrb);
+ rc = clp_req(rrb, CLP_LPS_PCI);
if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
zpci_err("List PCI FN:\n");
zpci_err_clp(rrb->response.hdr.rsp, rc);
@@ -391,3 +419,198 @@ int clp_rescan_pci_devices_simple(void)
clp_free_block(rrb);
return rc;
}
+
+static int clp_base_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
+{
+ unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+ if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+ lpcb->response.hdr.len > limit)
+ return -EINVAL;
+ return clp_req(lpcb, CLP_LPS_BASE) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_base_command(struct clp_req *req, struct clp_req_hdr *lpcb)
+{
+ switch (lpcb->cmd) {
+ case 0x0001: /* store logical-processor characteristics */
+ return clp_base_slpc(req, (void *) lpcb);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
+{
+ unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+ if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+ lpcb->response.hdr.len > limit)
+ return -EINVAL;
+ return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_list(struct clp_req *req, struct clp_req_rsp_list_pci *lpcb)
+{
+ unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+ if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+ lpcb->response.hdr.len > limit)
+ return -EINVAL;
+ if (lpcb->request.reserved2 != 0)
+ return -EINVAL;
+ return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_query(struct clp_req *req,
+ struct clp_req_rsp_query_pci *lpcb)
+{
+ unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+ if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+ lpcb->response.hdr.len > limit)
+ return -EINVAL;
+ if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0)
+ return -EINVAL;
+ return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_query_grp(struct clp_req *req,
+ struct clp_req_rsp_query_pci_grp *lpcb)
+{
+ unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
+
+ if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
+ lpcb->response.hdr.len > limit)
+ return -EINVAL;
+ if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0 ||
+ lpcb->request.reserved4 != 0)
+ return -EINVAL;
+ return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
+}
+
+static int clp_pci_command(struct clp_req *req, struct clp_req_hdr *lpcb)
+{
+ switch (lpcb->cmd) {
+ case 0x0001: /* store logical-processor characteristics */
+ return clp_pci_slpc(req, (void *) lpcb);
+ case 0x0002: /* list PCI functions */
+ return clp_pci_list(req, (void *) lpcb);
+ case 0x0003: /* query PCI function */
+ return clp_pci_query(req, (void *) lpcb);
+ case 0x0004: /* query PCI function group */
+ return clp_pci_query_grp(req, (void *) lpcb);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int clp_normal_command(struct clp_req *req)
+{
+ struct clp_req_hdr *lpcb;
+ void __user *uptr;
+ int rc;
+
+ rc = -EINVAL;
+ if (req->lps != 0 && req->lps != 2)
+ goto out;
+
+ rc = -ENOMEM;
+ lpcb = clp_alloc_block(GFP_KERNEL);
+ if (!lpcb)
+ goto out;
+
+ rc = -EFAULT;
+ uptr = (void __force __user *)(unsigned long) req->data_p;
+ if (copy_from_user(lpcb, uptr, PAGE_SIZE) != 0)
+ goto out_free;
+
+ rc = -EINVAL;
+ if (lpcb->fmt != 0 || lpcb->reserved1 != 0 || lpcb->reserved2 != 0)
+ goto out_free;
+
+ switch (req->lps) {
+ case 0:
+ rc = clp_base_command(req, lpcb);
+ break;
+ case 2:
+ rc = clp_pci_command(req, lpcb);
+ break;
+ }
+ if (rc)
+ goto out_free;
+
+ rc = -EFAULT;
+ if (copy_to_user(uptr, lpcb, PAGE_SIZE) != 0)
+ goto out_free;
+
+ rc = 0;
+
+out_free:
+ clp_free_block(lpcb);
+out:
+ return rc;
+}
+
+static int clp_immediate_command(struct clp_req *req)
+{
+ void __user *uptr;
+ unsigned long ilp;
+ int exists;
+
+ if (req->cmd > 1 || clp_get_ilp(&ilp) != 0)
+ return -EINVAL;
+
+ uptr = (void __force __user *)(unsigned long) req->data_p;
+ if (req->cmd == 0) {
+ /* Command code 0: test for a specific processor */
+ exists = test_bit_inv(req->lps, &ilp);
+ return put_user(exists, (int __user *) uptr);
+ }
+ /* Command code 1: return bit mask of installed processors */
+ return put_user(ilp, (unsigned long __user *) uptr);
+}
+
+static long clp_misc_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct clp_req req;
+ void __user *argp;
+
+ if (cmd != CLP_SYNC)
+ return -EINVAL;
+
+ argp = is_compat_task() ? compat_ptr(arg) : (void __user *) arg;
+ if (copy_from_user(&req, argp, sizeof(req)))
+ return -EFAULT;
+ if (req.r != 0)
+ return -EINVAL;
+ return req.c ? clp_immediate_command(&req) : clp_normal_command(&req);
+}
+
+static int clp_misc_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static const struct file_operations clp_misc_fops = {
+ .owner = THIS_MODULE,
+ .open = nonseekable_open,
+ .release = clp_misc_release,
+ .unlocked_ioctl = clp_misc_ioctl,
+ .compat_ioctl = clp_misc_ioctl,
+ .llseek = no_llseek,
+};
+
+static struct miscdevice clp_misc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "clp",
+ .fops = &clp_misc_fops,
+};
+
+static int __init clp_misc_init(void)
+{
+ return misc_register(&clp_misc_device);
+}
+
+device_initcall(clp_misc_init);
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
index 4129b0a..c555de3 100644
--- a/arch/s390/pci/pci_debug.c
+++ b/arch/s390/pci/pci_debug.c
@@ -128,10 +128,9 @@ static const struct file_operations debugfs_pci_perf_fops = {
.release = single_release,
};
-void zpci_debug_init_device(struct zpci_dev *zdev)
+void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
{
- zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
- debugfs_root);
+ zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
if (IS_ERR(zdev->debugfs_dev))
zdev->debugfs_dev = NULL;
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 37505b8..a06ce80 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -24,7 +24,7 @@ static int zpci_refresh_global(struct zpci_dev *zdev)
zdev->iommu_pages * PAGE_SIZE);
}
-static unsigned long *dma_alloc_cpu_table(void)
+unsigned long *dma_alloc_cpu_table(void)
{
unsigned long *table, *entry;
@@ -33,7 +33,7 @@ static unsigned long *dma_alloc_cpu_table(void)
return NULL;
for (entry = table; entry < table + ZPCI_TABLE_ENTRIES; entry++)
- *entry = ZPCI_TABLE_INVALID | ZPCI_TABLE_PROTECTED;
+ *entry = ZPCI_TABLE_INVALID;
return table;
}
@@ -51,7 +51,7 @@ static unsigned long *dma_alloc_page_table(void)
return NULL;
for (entry = table; entry < table + ZPCI_PT_ENTRIES; entry++)
- *entry = ZPCI_PTE_INVALID | ZPCI_TABLE_PROTECTED;
+ *entry = ZPCI_PTE_INVALID;
return table;
}
@@ -95,7 +95,7 @@ static unsigned long *dma_get_page_table_origin(unsigned long *entry)
return pto;
}
-static unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr)
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr)
{
unsigned long *sto, *pto;
unsigned int rtx, sx, px;
@@ -114,20 +114,10 @@ static unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr
return &pto[px];
}
-static void dma_update_cpu_trans(struct zpci_dev *zdev, void *page_addr,
- dma_addr_t dma_addr, int flags)
+void dma_update_cpu_trans(unsigned long *entry, void *page_addr, int flags)
{
- unsigned long *entry;
-
- entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
- if (!entry) {
- WARN_ON_ONCE(1);
- return;
- }
-
if (flags & ZPCI_PTE_INVALID) {
invalidate_pt_entry(entry);
- return;
} else {
set_pt_pfaa(entry, page_addr);
validate_pt_entry(entry);
@@ -146,17 +136,25 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
u8 *page_addr = (u8 *) (pa & PAGE_MASK);
dma_addr_t start_dma_addr = dma_addr;
unsigned long irq_flags;
+ unsigned long *entry;
int i, rc = 0;
if (!nr_pages)
return -EINVAL;
spin_lock_irqsave(&zdev->dma_table_lock, irq_flags);
- if (!zdev->dma_table)
+ if (!zdev->dma_table) {
+ rc = -EINVAL;
goto no_refresh;
+ }
for (i = 0; i < nr_pages; i++) {
- dma_update_cpu_trans(zdev, page_addr, dma_addr, flags);
+ entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+ if (!entry) {
+ rc = -ENOMEM;
+ goto undo_cpu_trans;
+ }
+ dma_update_cpu_trans(entry, page_addr, flags);
page_addr += PAGE_SIZE;
dma_addr += PAGE_SIZE;
}
@@ -175,13 +173,25 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa,
rc = zpci_refresh_trans((u64) zdev->fh << 32, start_dma_addr,
nr_pages * PAGE_SIZE);
+undo_cpu_trans:
+ if (rc && ((flags & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID)) {
+ flags = ZPCI_PTE_INVALID;
+ while (i-- > 0) {
+ page_addr -= PAGE_SIZE;
+ dma_addr -= PAGE_SIZE;
+ entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+ if (!entry)
+ break;
+ dma_update_cpu_trans(entry, page_addr, flags);
+ }
+ }
no_refresh:
spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags);
return rc;
}
-static void dma_free_seg_table(unsigned long entry)
+void dma_free_seg_table(unsigned long entry)
{
unsigned long *sto = get_rt_sto(entry);
int sx;
@@ -193,44 +203,43 @@ static void dma_free_seg_table(unsigned long entry)
dma_free_cpu_table(sto);
}
-static void dma_cleanup_tables(struct zpci_dev *zdev)
+void dma_cleanup_tables(unsigned long *table)
{
- unsigned long *table;
int rtx;
- if (!zdev || !zdev->dma_table)
+ if (!table)
return;
- table = zdev->dma_table;
for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)
if (reg_entry_isvalid(table[rtx]))
dma_free_seg_table(table[rtx]);
dma_free_cpu_table(table);
- zdev->dma_table = NULL;
}
-static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev,
+static unsigned long __dma_alloc_iommu(struct device *dev,
unsigned long start, int size)
{
+ struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
unsigned long boundary_size;
- boundary_size = ALIGN(dma_get_seg_boundary(&zdev->pdev->dev) + 1,
+ boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
PAGE_SIZE) >> PAGE_SHIFT;
return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages,
start, size, 0, boundary_size, 0);
}
-static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size)
+static unsigned long dma_alloc_iommu(struct device *dev, int size)
{
+ struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
unsigned long offset, flags;
int wrap = 0;
spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
- offset = __dma_alloc_iommu(zdev, zdev->next_bit, size);
+ offset = __dma_alloc_iommu(dev, zdev->next_bit, size);
if (offset == -1) {
/* wrap-around */
- offset = __dma_alloc_iommu(zdev, 0, size);
+ offset = __dma_alloc_iommu(dev, 0, size);
wrap = 1;
}
@@ -244,8 +253,9 @@ static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size)
return offset;
}
-static void dma_free_iommu(struct zpci_dev *zdev, unsigned long offset, int size)
+static void dma_free_iommu(struct device *dev, unsigned long offset, int size)
{
+ struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
unsigned long flags;
spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
@@ -262,6 +272,16 @@ out:
spin_unlock_irqrestore(&zdev->iommu_bitmap_lock, flags);
}
+static inline void zpci_err_dma(unsigned long rc, unsigned long addr)
+{
+ struct {
+ unsigned long rc;
+ unsigned long addr;
+ } __packed data = {rc, addr};
+
+ zpci_err_hex(&data, sizeof(data));
+}
+
static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction direction,
@@ -272,33 +292,40 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
unsigned long pa = page_to_phys(page) + offset;
int flags = ZPCI_PTE_VALID;
dma_addr_t dma_addr;
+ int ret;
/* This rounds up number of pages based on size and offset */
nr_pages = iommu_num_pages(pa, size, PAGE_SIZE);
- iommu_page_index = dma_alloc_iommu(zdev, nr_pages);
- if (iommu_page_index == -1)
+ iommu_page_index = dma_alloc_iommu(dev, nr_pages);
+ if (iommu_page_index == -1) {
+ ret = -ENOSPC;
goto out_err;
+ }
/* Use rounded up size */
size = nr_pages * PAGE_SIZE;
dma_addr = zdev->start_dma + iommu_page_index * PAGE_SIZE;
- if (dma_addr + size > zdev->end_dma)
+ if (dma_addr + size > zdev->end_dma) {
+ ret = -ERANGE;
goto out_free;
+ }
if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
flags |= ZPCI_TABLE_PROTECTED;
- if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
- atomic64_add(nr_pages, &zdev->mapped_pages);
- return dma_addr + (offset & ~PAGE_MASK);
- }
+ ret = dma_update_trans(zdev, pa, dma_addr, size, flags);
+ if (ret)
+ goto out_free;
+
+ atomic64_add(nr_pages, &zdev->mapped_pages);
+ return dma_addr + (offset & ~PAGE_MASK);
out_free:
- dma_free_iommu(zdev, iommu_page_index, nr_pages);
+ dma_free_iommu(dev, iommu_page_index, nr_pages);
out_err:
zpci_err("map error:\n");
- zpci_err_hex(&pa, sizeof(pa));
+ zpci_err_dma(ret, pa);
return DMA_ERROR_CODE;
}
@@ -308,19 +335,21 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
{
struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
unsigned long iommu_page_index;
- int npages;
+ int npages, ret;
npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
dma_addr = dma_addr & PAGE_MASK;
- if (dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE,
- ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) {
+ ret = dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE,
+ ZPCI_PTE_INVALID);
+ if (ret) {
zpci_err("unmap error:\n");
- zpci_err_hex(&dma_addr, sizeof(dma_addr));
+ zpci_err_dma(ret, dma_addr);
+ return;
}
atomic64_add(npages, &zdev->unmapped_pages);
iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
- dma_free_iommu(zdev, iommu_page_index, npages);
+ dma_free_iommu(dev, iommu_page_index, npages);
}
static void *s390_dma_alloc(struct device *dev, size_t size,
@@ -340,8 +369,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
pa = page_to_phys(page);
memset((void *) pa, 0, size);
- map = s390_dma_map_pages(dev, page, pa % PAGE_SIZE,
- size, DMA_BIDIRECTIONAL, NULL);
+ map = s390_dma_map_pages(dev, page, 0, size, DMA_BIDIRECTIONAL, NULL);
if (dma_mapping_error(dev, map)) {
free_pages(pa, get_order(size));
return NULL;
@@ -416,6 +444,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
{
int rc;
+ /*
+ * At this point, if the device is part of an IOMMU domain, this would
+ * be a strong hint towards a bug in the IOMMU API (common) code and/or
+ * simultaneous access via IOMMU and DMA API. So let's issue a warning.
+ */
+ WARN_ON(zdev->s390_domain);
+
spin_lock_init(&zdev->iommu_bitmap_lock);
spin_lock_init(&zdev->dma_table_lock);
@@ -425,7 +460,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
goto out_clean;
}
- zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
+ /*
+ * Restrict the iommu bitmap size to the minimum of the following:
+ * - main memory size
+ * - 3-level pagetable address limit minus start_dma offset
+ * - DMA address range allowed by the hardware (clp query pci fn)
+ *
+ * Also set zdev->end_dma to the actual end address of the usable
+ * range, instead of the theoretical maximum as reported by hardware.
+ */
+ zdev->iommu_size = min3((u64) high_memory,
+ ZPCI_TABLE_SIZE_RT - zdev->start_dma,
+ zdev->end_dma - zdev->start_dma + 1);
+ zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
if (!zdev->iommu_bitmap) {
@@ -433,10 +480,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
goto out_reg;
}
- rc = zpci_register_ioat(zdev,
- 0,
- zdev->start_dma + PAGE_OFFSET,
- zdev->start_dma + zdev->iommu_size - 1,
+ rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
(u64) zdev->dma_table);
if (rc)
goto out_reg;
@@ -450,8 +494,16 @@ out_clean:
void zpci_dma_exit_device(struct zpci_dev *zdev)
{
+ /*
+ * At this point, if the device is part of an IOMMU domain, this would
+ * be a strong hint towards a bug in the IOMMU API (common) code and/or
+ * simultaneous access via IOMMU and DMA API. So let's issue a warning.
+ */
+ WARN_ON(zdev->s390_domain);
+
zpci_unregister_ioat(zdev, 0);
- dma_cleanup_tables(zdev);
+ dma_cleanup_tables(zdev->dma_table);
+ zdev->dma_table = NULL;
vfree(zdev->iommu_bitmap);
zdev->iommu_bitmap = NULL;
zdev->next_bit = 0;
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index 369a3e0..fb2a9a5 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -46,13 +46,22 @@ struct zpci_ccdf_avail {
static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
{
struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
- struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
+ struct pci_dev *pdev = NULL;
zpci_err("error CCDF:\n");
zpci_err_hex(ccdf, sizeof(*ccdf));
+ if (zdev)
+ pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
+
pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
+
+ if (!pdev)
+ return;
+
+ pdev->error_state = pci_channel_io_perm_failure;
+ pci_dev_put(pdev);
}
void zpci_event_error(void *data)
@@ -64,9 +73,12 @@ void zpci_event_error(void *data)
static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
{
struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
- struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
+ struct pci_dev *pdev = NULL;
int ret;
+ if (zdev)
+ pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
+
pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
zpci_err("avail CCDF:\n");
@@ -133,6 +145,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
default:
break;
}
+ if (pdev)
+ pci_dev_put(pdev);
}
void zpci_event_availability(void *data)
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c
index dcc2634..10ca15d 100644
--- a/arch/s390/pci/pci_insn.c
+++ b/arch/s390/pci/pci_insn.c
@@ -16,11 +16,11 @@
static inline void zpci_err_insn(u8 cc, u8 status, u64 req, u64 offset)
{
struct {
- u8 cc;
- u8 status;
u64 req;
u64 offset;
- } data = {cc, status, req, offset};
+ u8 cc;
+ u8 status;
+ } __packed data = {req, offset, cc, status};
zpci_err_hex(&data, sizeof(data));
}
diff --git a/arch/s390/tools/.gitignore b/arch/s390/tools/.gitignore
new file mode 100644
index 0000000..72a4b2c
--- /dev/null
+++ b/arch/s390/tools/.gitignore
@@ -0,0 +1 @@
+gen_facilities
diff --git a/arch/s390/tools/Makefile b/arch/s390/tools/Makefile
new file mode 100644
index 0000000..6d9814c
--- /dev/null
+++ b/arch/s390/tools/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for s390 specific build tools
+#
+
+hostprogs-y += gen_facilities
+HOSTCFLAGS_gen_facilities.o += -Wall $(LINUXINCLUDE)
+
+define filechk_facilities.h
+ $(obj)/gen_facilities
+endef
+
+$(obj)/gen_facilities.o: $(srctree)/arch/s390/tools/gen_facilities.c
+
+include/generated/facilities.h: $(obj)/gen_facilities FORCE
+ $(call filechk,facilities.h)
diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c
new file mode 100644
index 0000000..e2660d2
--- /dev/null
+++ b/arch/s390/tools/gen_facilities.c
@@ -0,0 +1,67 @@
+/*
+ * Simple program to generate defines out of facility lists that use the bit
+ * numbering scheme from the Princples of Operations: most significant bit
+ * has bit number 0.
+ *
+ * Copyright IBM Corp. 2015
+ *
+ */
+
+#define S390_GEN_FACILITIES_C
+
+#include <strings.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <asm/facilities_src.h>
+
+static void print_facility_list(struct facility_def *def)
+{
+ unsigned int high, bit, dword, i;
+ unsigned long long *array;
+
+ array = calloc(1, 8);
+ if (!array)
+ exit(EXIT_FAILURE);
+ high = 0;
+ for (i = 0; def->bits[i] != -1; i++) {
+ bit = 63 - (def->bits[i] & 63);
+ dword = def->bits[i] / 64;
+ if (dword > high) {
+ array = realloc(array, (dword + 1) * 8);
+ if (!array)
+ exit(EXIT_FAILURE);
+ memset(array + high + 1, 0, (dword - high) * 8);
+ high = dword;
+ }
+ array[dword] |= 1ULL << bit;
+ }
+ printf("#define %s ", def->name);
+ for (i = 0; i <= high; i++)
+ printf("_AC(0x%016llx,UL)%c", array[i], i < high ? ',' : '\n');
+ printf("#define %s_DWORDS %d\n", def->name, high + 1);
+ free(array);
+}
+
+static void print_facility_lists(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(facility_defs) / sizeof(facility_defs[0]); i++)
+ print_facility_list(&facility_defs[i]);
+}
+
+int main(int argc, char **argv)
+{
+ printf("#ifndef __ASM_S390_FACILITIES__\n");
+ printf("#define __ASM_S390_FACILITIES__\n");
+ printf("/*\n");
+ printf(" * DO NOT MODIFY.\n");
+ printf(" *\n");
+ printf(" * This file was generated by %s\n", __FILE__);
+ printf(" */\n\n");
+ printf("#include <linux/const.h>\n\n");
+ print_facility_lists();
+ printf("\n#endif\n");
+ return 0;
+}
diff --git a/arch/score/configs/spct6600_defconfig b/arch/score/configs/spct6600_defconfig
index df1edbf..b2d8802 100644
--- a/arch/score/configs/spct6600_defconfig
+++ b/arch/score/configs/spct6600_defconfig
@@ -70,7 +70,6 @@ CONFIG_NFSD=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_CRYPTO_NULL=y
diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h
index 961bd64..539d9fd 100644
--- a/arch/score/include/asm/checksum.h
+++ b/arch/score/include/asm/checksum.h
@@ -127,10 +127,10 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
- unsigned long tmp = (ntohs(len) << 16) + proto * 256;
+ unsigned long tmp = (len + proto) << 8;
__asm__ __volatile__(
".set volatile\n\t"
"add\t%0, %0, %2\n\t"
@@ -161,8 +161,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* 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)
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
@@ -179,9 +179,8 @@ static inline unsigned short ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
+ const struct in6_addr *daddr,
+ __u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__(
".set\tvolatile\t\t\t# csum_ipv6_magic\n\t"
diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c
index b48459a..f3a0649 100644
--- a/arch/score/kernel/setup.c
+++ b/arch/score/kernel/setup.c
@@ -101,7 +101,7 @@ static void __init resource_init(void)
res->name = "System RAM";
res->start = MEMORY_START;
res->end = MEMORY_START + MEMORY_SIZE - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
request_resource(res, &code_resource);
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index d514df7e..7ed20fc 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,5 +1,6 @@
config SUPERH
def_bool y
+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_MIGHT_HAVE_PC_PARPORT
select HAVE_PATA_PLATFORM
select CLKDEV_LOOKUP
@@ -11,7 +12,6 @@ config SUPERH
select HAVE_GENERIC_DMA_COHERENT
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
- select HAVE_DMA_ATTRS
select HAVE_PERF_EVENTS
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_CUSTOM_GPIO_H
@@ -130,9 +130,6 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config ARCH_HAS_ILOG2_U32
def_bool n
@@ -851,14 +848,10 @@ config PCI
config PCI_DOMAINS
bool
-source "drivers/pci/pcie/Kconfig"
-
source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
endmenu
menu "Executable file formats"
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 89963d13..5e52d53 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -6,6 +6,21 @@ config SOLUTION_ENGINE
config SH_ALPHA_BOARD
bool
+config SH_DEVICE_TREE
+ bool "Board Described by Device Tree"
+ select OF
+ select OF_EARLY_FLATTREE
+ select CLKSRC_OF
+ select GENERIC_CALIBRATE_DELAY
+ help
+ Select Board Described by Device Tree to build a kernel that
+ does not hard-code any board-specific knowledge but instead uses
+ a device tree blob provided by the boot-loader. You must enable
+ drivers for any hardware you want to use separately. At this
+ time, only boards based on the open-hardware J-Core processors
+ have sufficient driver coverage to use this option; do not
+ select it if you are using original SuperH hardware.
+
config SH_SOLUTION_ENGINE
bool "SolutionEngine"
select SOLUTION_ENGINE
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 975a0f6..cea3003 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -15,3 +15,5 @@ obj-$(CONFIG_SH_TITAN) += board-titan.o
obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o
obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o
+
+obj-$(CONFIG_SH_DEVICE_TREE) += of-generic.o
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index cbd2a9f..62c3b81 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -27,10 +27,10 @@
#include <linux/gpio.h>
#include <linux/videodev2.h>
#include <linux/sh_intc.h>
-#include <media/ov772x.h>
+#include <media/i2c/ov772x.h>
#include <media/soc_camera.h>
-#include <media/soc_camera_platform.h>
-#include <media/sh_mobile_ceu.h>
+#include <linux/platform_data/media/soc_camera_platform.h>
+#include <media/drv-intf/sh_mobile_ceu.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/io.h>
#include <asm/clock.h>
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index d531791..a9c0c07 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -38,10 +38,10 @@
#include <video/sh_mobile_lcdc.h>
#include <sound/sh_fsi.h>
#include <sound/simple_card.h>
-#include <media/sh_mobile_ceu.h>
+#include <media/drv-intf/sh_mobile_ceu.h>
#include <media/soc_camera.h>
-#include <media/tw9910.h>
-#include <media/mt9t112.h>
+#include <media/i2c/tw9910.h>
+#include <media/i2c/mt9t112.h>
#include <asm/heartbeat.h>
#include <asm/clock.h>
#include <asm/suspend.h>
@@ -900,8 +900,8 @@ static struct platform_device irda_device = {
.resource = irda_resources,
};
-#include <media/ak881x.h>
-#include <media/sh_vou.h>
+#include <media/i2c/ak881x.h>
+#include <media/drv-intf/sh_vou.h>
static struct ak881x_pdata ak881x_pdata = {
.flags = AK881X_IF_MODE_SLAVE,
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 7d997ce..6bd9230 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -27,9 +27,9 @@
#include <linux/usb/r8a66597.h>
#include <linux/videodev2.h>
#include <linux/sh_intc.h>
-#include <media/rj54n1cb0c.h>
+#include <media/i2c/rj54n1cb0c.h>
#include <media/soc_camera.h>
-#include <media/sh_mobile_ceu.h>
+#include <media/drv-intf/sh_mobile_ceu.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/suspend.h>
#include <asm/clock.h>
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 29b7c0d..7a04da3 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -27,10 +27,10 @@
#include <linux/videodev2.h>
#include <linux/sh_intc.h>
#include <video/sh_mobile_lcdc.h>
-#include <media/sh_mobile_ceu.h>
-#include <media/ov772x.h>
+#include <media/drv-intf/sh_mobile_ceu.h>
+#include <media/i2c/ov772x.h>
#include <media/soc_camera.h>
-#include <media/tw9910.h>
+#include <media/i2c/tw9910.h>
#include <asm/clock.h>
#include <asm/machvec.h>
#include <asm/io.h>
@@ -167,7 +167,7 @@ static struct mtd_partition migor_nand_flash_partitions[] = {
static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
index 2685ea0..6bc134b 100644
--- a/arch/sh/boards/mach-rsk/setup.c
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -27,8 +27,6 @@ static struct regulator_consumer_supply dummy_supplies[] = {
REGULATOR_SUPPLY("vdd33a", "smsc911x"),
};
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
static struct mtd_partition rsk_partitions[] = {
{
.name = "Bootloader",
@@ -50,7 +48,6 @@ static struct physmap_flash_data flash_data = {
.parts = rsk_partitions,
.nr_parts = ARRAY_SIZE(rsk_partitions),
.width = 2,
- .part_probe_types = part_probes,
};
static struct resource flash_resource = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 4f6635a..e0e1df1 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -30,7 +30,7 @@
#include <linux/sh_intc.h>
#include <linux/videodev2.h>
#include <video/sh_mobile_lcdc.h>
-#include <media/sh_mobile_ceu.h>
+#include <media/drv-intf/sh_mobile_ceu.h>
#include <sound/sh_fsi.h>
#include <sound/simple_card.h>
#include <asm/io.h>
@@ -534,8 +534,8 @@ static struct platform_device irda_device = {
.resource = irda_resources,
};
-#include <media/ak881x.h>
-#include <media/sh_vou.h>
+#include <media/i2c/ak881x.h>
+#include <media/drv-intf/sh_vou.h>
static struct ak881x_pdata ak881x_pdata = {
.flags = AK881X_IF_MODE_SLAVE,
diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
new file mode 100644
index 0000000..bf3a166
--- /dev/null
+++ b/arch/sh/boards/of-generic.c
@@ -0,0 +1,196 @@
+/*
+ * SH generic board support, using device tree
+ *
+ * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
+ *
+ * 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/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/of_iommu.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/clk-provider.h>
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+
+#ifdef CONFIG_SMP
+
+static void dummy_smp_setup(void)
+{
+}
+
+static void dummy_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point)
+{
+}
+
+static unsigned int dummy_smp_processor_id(void)
+{
+ return 0;
+}
+
+static void dummy_send_ipi(unsigned int cpu, unsigned int message)
+{
+}
+
+static struct plat_smp_ops dummy_smp_ops = {
+ .smp_setup = dummy_smp_setup,
+ .prepare_cpus = dummy_prepare_cpus,
+ .start_cpu = dummy_start_cpu,
+ .smp_processor_id = dummy_smp_processor_id,
+ .send_ipi = dummy_send_ipi,
+ .cpu_die = native_cpu_die,
+ .cpu_disable = native_cpu_disable,
+ .play_dead = native_play_dead,
+};
+
+extern const struct of_cpu_method __cpu_method_of_table[];
+const struct of_cpu_method __cpu_method_of_table_sentinel
+ __section(__cpu_method_of_table_end);
+
+static void sh_of_smp_probe(void)
+{
+ struct device_node *np = 0;
+ const char *method = 0;
+ const struct of_cpu_method *m = __cpu_method_of_table;
+
+ pr_info("SH generic board support: scanning for cpus\n");
+
+ init_cpu_possible(cpumask_of(0));
+
+ while ((np = of_find_node_by_type(np, "cpu"))) {
+ const __be32 *cell = of_get_property(np, "reg", NULL);
+ u64 id = -1;
+ if (cell) id = of_read_number(cell, of_n_addr_cells(np));
+ if (id < NR_CPUS) {
+ if (!method)
+ of_property_read_string(np, "enable-method", &method);
+ set_cpu_possible(id, true);
+ set_cpu_present(id, true);
+ __cpu_number_map[id] = id;
+ __cpu_logical_map[id] = id;
+ }
+ }
+ if (!method) {
+ np = of_find_node_by_name(NULL, "cpus");
+ of_property_read_string(np, "enable-method", &method);
+ }
+
+ pr_info("CPU enable method: %s\n", method);
+ if (method)
+ for (; m->method; m++)
+ if (!strcmp(m->method, method)) {
+ register_smp_ops(m->ops);
+ return;
+ }
+
+ register_smp_ops(&dummy_smp_ops);
+}
+
+#else
+
+static void sh_of_smp_probe(void)
+{
+}
+
+#endif
+
+static void noop(void)
+{
+}
+
+static int noopi(void)
+{
+ return 0;
+}
+
+static void __init sh_of_mem_reserve(void)
+{
+ early_init_fdt_reserve_self();
+ early_init_fdt_scan_reserved_mem();
+}
+
+static void __init sh_of_time_init(void)
+{
+ pr_info("SH generic board support: scanning for clocksource devices\n");
+ clocksource_probe();
+}
+
+static void __init sh_of_setup(char **cmdline_p)
+{
+ unflatten_device_tree();
+
+ board_time_init = sh_of_time_init;
+
+ sh_mv.mv_name = of_flat_dt_get_machine_name();
+ if (!sh_mv.mv_name)
+ sh_mv.mv_name = "Unknown SH model";
+
+ sh_of_smp_probe();
+}
+
+static int sh_of_irq_demux(int irq)
+{
+ /* FIXME: eventually this should not be used at all;
+ * the interrupt controller should set_handle_irq(). */
+ return irq;
+}
+
+static void __init sh_of_init_irq(void)
+{
+ pr_info("SH generic board support: scanning for interrupt controllers\n");
+ irqchip_init();
+}
+
+static int __init sh_of_clk_init(void)
+{
+#ifdef CONFIG_COMMON_CLK
+ /* Disabled pending move to COMMON_CLK framework. */
+ pr_info("SH generic board support: scanning for clk providers\n");
+ of_clk_init(NULL);
+#endif
+ return 0;
+}
+
+static struct sh_machine_vector __initmv sh_of_generic_mv = {
+ .mv_setup = sh_of_setup,
+ .mv_name = "devicetree", /* replaced by DT root's model */
+ .mv_irq_demux = sh_of_irq_demux,
+ .mv_init_irq = sh_of_init_irq,
+ .mv_clk_init = sh_of_clk_init,
+ .mv_mode_pins = noopi,
+ .mv_mem_init = noop,
+ .mv_mem_reserve = sh_of_mem_reserve,
+};
+
+struct sh_clk_ops;
+
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
+{
+}
+
+void __init plat_irq_setup(void)
+{
+}
+
+static int __init sh_of_device_init(void)
+{
+ pr_info("SH generic board support: populating platform devices\n");
+ if (of_have_populated_dt()) {
+ of_iommu_init();
+ of_platform_populate(NULL, of_default_bus_match_table,
+ NULL, NULL);
+ } else {
+ pr_crit("Device tree not populated\n");
+ }
+ return 0;
+}
+arch_initcall_sync(sh_of_device_init);
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 23bc849..6df826e 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -48,7 +48,7 @@ ifeq ($(BITS),64)
lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir))
endif
-KBUILD_CFLAGS += -I$(lib1funcs-dir)
+KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING
$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE
$(call cmd,shipped)
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index aac452b..a319745 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,5 +1,6 @@
generic-y += bitsperlong.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += current.h
generic-y += delay.h
diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h
index 05b9f74..c399e1c 100644
--- a/arch/sh/include/asm/atomic.h
+++ b/arch/sh/include/asm/atomic.h
@@ -14,8 +14,8 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic_set(v,i) ((v)->counter = (i))
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
#if defined(CONFIG_GUSA_RB)
#include <asm/atomic-grb.h>
diff --git a/arch/sh/include/asm/barrier.h b/arch/sh/include/asm/barrier.h
index bf91037..8a84e05 100644
--- a/arch/sh/include/asm/barrier.h
+++ b/arch/sh/include/asm/barrier.h
@@ -32,7 +32,7 @@
#define ctrl_barrier() __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop")
#endif
-#define smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
+#define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
#include <asm-generic/barrier.h>
diff --git a/arch/sh/include/asm/checksum_32.h b/arch/sh/include/asm/checksum_32.h
index 14b7ac2..9c84386 100644
--- a/arch/sh/include/asm/checksum_32.h
+++ b/arch/sh/include/asm/checksum_32.h
@@ -115,8 +115,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
#ifdef __LITTLE_ENDIAN__
@@ -142,8 +141,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
@@ -161,8 +159,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
unsigned int __dummy;
__asm__("clrt\n\t"
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
deleted file mode 100644
index c419014..0000000
--- a/arch/sh/include/asm/clkdev.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.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.
- *
- * Helper for the clk API to assist looking up a struct clk.
- */
-
-#ifndef __CLKDEV__H_
-#define __CLKDEV__H_
-
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-#include <asm/clock.h>
-
-static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
-{
- if (!slab_is_available())
- return alloc_bootmem_low_pages(size);
- else
- return kzalloc(size, GFP_KERNEL);
-}
-
-#ifndef CONFIG_COMMON_CLK
-#define __clk_put(clk)
-#define __clk_get(clk) ({ 1; })
-#endif
-
-#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h
index f848dec..2ed557b 100644
--- a/arch/sh/include/asm/cmpxchg-grb.h
+++ b/arch/sh/include/asm/cmpxchg-grb.h
@@ -23,6 +23,28 @@ static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
return retval;
}
+static inline unsigned long xchg_u16(volatile u16 *m, unsigned long val)
+{
+ unsigned long retval;
+
+ __asm__ __volatile__ (
+ " .align 2 \n\t"
+ " mova 1f, r0 \n\t" /* r0 = end point */
+ " mov r15, r1 \n\t" /* r1 = saved sp */
+ " mov #-6, r15 \n\t" /* LOGIN */
+ " mov.w @%1, %0 \n\t" /* load old value */
+ " extu.w %0, %0 \n\t" /* extend as unsigned */
+ " mov.w %2, @%1 \n\t" /* store new value */
+ "1: mov r1, r15 \n\t" /* LOGOUT */
+ : "=&r" (retval),
+ "+r" (m),
+ "+r" (val) /* inhibit r15 overloading */
+ :
+ : "memory" , "r0", "r1");
+
+ return retval;
+}
+
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
{
unsigned long retval;
diff --git a/arch/sh/include/asm/cmpxchg-irq.h b/arch/sh/include/asm/cmpxchg-irq.h
index bd11f63..f888772 100644
--- a/arch/sh/include/asm/cmpxchg-irq.h
+++ b/arch/sh/include/asm/cmpxchg-irq.h
@@ -14,6 +14,17 @@ static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
return retval;
}
+static inline unsigned long xchg_u16(volatile u16 *m, unsigned long val)
+{
+ unsigned long flags, retval;
+
+ local_irq_save(flags);
+ retval = *m;
+ *m = val;
+ local_irq_restore(flags);
+ return retval;
+}
+
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
{
unsigned long flags, retval;
diff --git a/arch/sh/include/asm/cmpxchg-llsc.h b/arch/sh/include/asm/cmpxchg-llsc.h
index 4713666..fcfd322 100644
--- a/arch/sh/include/asm/cmpxchg-llsc.h
+++ b/arch/sh/include/asm/cmpxchg-llsc.h
@@ -22,29 +22,8 @@ static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
return retval;
}
-static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
-{
- unsigned long retval;
- unsigned long tmp;
-
- __asm__ __volatile__ (
- "1: \n\t"
- "movli.l @%2, %0 ! xchg_u8 \n\t"
- "mov %0, %1 \n\t"
- "mov %3, %0 \n\t"
- "movco.l %0, @%2 \n\t"
- "bf 1b \n\t"
- "synco \n\t"
- : "=&z"(tmp), "=&r" (retval)
- : "r" (m), "r" (val & 0xff)
- : "t", "memory"
- );
-
- return retval;
-}
-
static inline unsigned long
-__cmpxchg_u32(volatile int *m, unsigned long old, unsigned long new)
+__cmpxchg_u32(volatile u32 *m, unsigned long old, unsigned long new)
{
unsigned long retval;
unsigned long tmp;
@@ -68,4 +47,6 @@ __cmpxchg_u32(volatile int *m, unsigned long old, unsigned long new)
return retval;
}
+#include <asm/cmpxchg-xchg.h>
+
#endif /* __ASM_SH_CMPXCHG_LLSC_H */
diff --git a/arch/sh/include/asm/cmpxchg-xchg.h b/arch/sh/include/asm/cmpxchg-xchg.h
new file mode 100644
index 0000000..7219719
--- /dev/null
+++ b/arch/sh/include/asm/cmpxchg-xchg.h
@@ -0,0 +1,51 @@
+#ifndef __ASM_SH_CMPXCHG_XCHG_H
+#define __ASM_SH_CMPXCHG_XCHG_H
+
+/*
+ * Copyright (C) 2016 Red Hat, Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See the
+ * file "COPYING" in the main directory of this archive for more details.
+ */
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+
+/*
+ * Portable implementations of 1 and 2 byte xchg using a 4 byte cmpxchg.
+ * Note: this header isn't self-contained: before including it, __cmpxchg_u32
+ * must be defined first.
+ */
+static inline u32 __xchg_cmpxchg(volatile void *ptr, u32 x, int size)
+{
+ int off = (unsigned long)ptr % sizeof(u32);
+ volatile u32 *p = ptr - off;
+#ifdef __BIG_ENDIAN
+ int bitoff = (sizeof(u32) - 1 - off) * BITS_PER_BYTE;
+#else
+ int bitoff = off * BITS_PER_BYTE;
+#endif
+ u32 bitmask = ((0x1 << size * BITS_PER_BYTE) - 1) << bitoff;
+ u32 oldv, newv;
+ u32 ret;
+
+ do {
+ oldv = READ_ONCE(*p);
+ ret = (oldv & bitmask) >> bitoff;
+ newv = (oldv & ~bitmask) | (x << bitoff);
+ } while (__cmpxchg_u32(p, oldv, newv) != oldv);
+
+ return ret;
+}
+
+static inline unsigned long xchg_u16(volatile u16 *m, unsigned long val)
+{
+ return __xchg_cmpxchg(m, val, sizeof *m);
+}
+
+static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
+{
+ return __xchg_cmpxchg(m, val, sizeof *m);
+}
+
+#endif /* __ASM_SH_CMPXCHG_XCHG_H */
diff --git a/arch/sh/include/asm/cmpxchg.h b/arch/sh/include/asm/cmpxchg.h
index 85c97b18..5225916 100644
--- a/arch/sh/include/asm/cmpxchg.h
+++ b/arch/sh/include/asm/cmpxchg.h
@@ -27,6 +27,9 @@ extern void __xchg_called_with_bad_pointer(void);
case 4: \
__xchg__res = xchg_u32(__xchg_ptr, x); \
break; \
+ case 2: \
+ __xchg__res = xchg_u16(__xchg_ptr, x); \
+ break; \
case 1: \
__xchg__res = xchg_u8(__xchg_ptr, x); \
break; \
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index a3745a3..e11cf0c 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -11,8 +11,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
#define DMA_ERROR_CODE 0
-#include <asm-generic/dma-mapping-common.h>
-
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir);
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index e343dbd0..644314f 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -105,9 +105,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
return channel ? 15 : 14;
}
-/* generic DMA-mapping stuff */
-#include <asm-generic/pci-dma-compat.h>
-
#endif /* __KERNEL__ */
#endif /* __ASM_SH_PCI_H */
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h
index 78b0d0f4..1baf0ba 100644
--- a/arch/sh/include/asm/smp.h
+++ b/arch/sh/include/asm/smp.h
@@ -69,6 +69,16 @@ static inline int hard_smp_processor_id(void)
return mp_ops->smp_processor_id();
}
+struct of_cpu_method {
+ const char *method;
+ struct plat_smp_ops *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 }
+
#else
#define hard_smp_processor_id() (0)
diff --git a/arch/sh/include/mach-common/mach/magicpanelr2.h b/arch/sh/include/mach-common/mach/magicpanelr2.h
index 183a2f7..eb0cf20 100644
--- a/arch/sh/include/mach-common/mach/magicpanelr2.h
+++ b/arch/sh/include/mach-common/mach/magicpanelr2.h
@@ -13,7 +13,7 @@
#ifndef __ASM_SH_MAGICPANELR2_H
#define __ASM_SH_MAGICPANELR2_H
-#include <asm/gpio.h>
+#include <linux/gpio.h>
#define __IO_PREFIX mpr2
#include <asm/io_generic.h>
diff --git a/arch/sh/include/uapi/asm/unistd_64.h b/arch/sh/include/uapi/asm/unistd_64.h
index e6820c8..47ebd5b 100644
--- a/arch/sh/include/uapi/asm/unistd_64.h
+++ b/arch/sh/include/uapi/asm/unistd_64.h
@@ -278,7 +278,7 @@
#define __NR_fsetxattr 256
#define __NR_getxattr 257
#define __NR_lgetxattr 258
-#define __NR_fgetxattr 269
+#define __NR_fgetxattr 259
#define __NR_listxattr 260
#define __NR_llistxattr 261
#define __NR_flistxattr 262
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 2ccf36c..09040fd 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -46,6 +46,5 @@ obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
ccflags-y := -Werror
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index 8525a67..786c076 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -63,7 +63,6 @@ int __init __deprecated cpg_clk_init(void)
clk_add_alias("fck", "sh-mtu2", "peripheral_clk", NULL);
clk_add_alias("fck", "sh-cmt-16.0", "peripheral_clk", NULL);
clk_add_alias("fck", "sh-cmt-32.0", "peripheral_clk", NULL);
- clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
return ret;
}
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index c8a4331..a150595 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -144,9 +144,9 @@ ENTRY(exception_handler)
mov #64,r8
cmp/hs r8,r9
bt interrupt_entry ! vec >= 64 is interrupt
- mov #32,r8
+ mov #31,r8
cmp/hs r8,r9
- bt trap_entry ! 64 > vec >= 32 is trap
+ bt trap_entry ! 64 > vec >= 31 is trap
mov.l 4f,r8
mov r9,r4
@@ -178,9 +178,9 @@ interrupt_entry:
trap_entry:
mov #0x30,r8
- cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
+ cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
bt 1f
- add #-0x10,r9 ! convert SH2 to SH3/4 ABI
+ mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
1:
shll2 r9 ! TRA
bra system_call ! jump common systemcall entry
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
index 8638fba..7e06e39 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7264.c
@@ -115,7 +115,14 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
/* MSTP clocks */
- CLKDEV_CON_ID("sci_ick", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP77]),
+ CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP77]),
CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]),
CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]),
CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
index f8a5c2a..663a97b 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7269.c
@@ -150,14 +150,14 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
/* MSTP clocks */
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP47]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP46]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP45]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP44]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP43]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP42]),
+ CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP41]),
+ CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP40]),
CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]),
CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP35]),
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index 222742d..da77a8e 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -109,9 +109,9 @@ ENTRY(exception_handler)
mov #64,r8
cmp/hs r8,r9
bt interrupt_entry ! vec >= 64 is interrupt
- mov #32,r8
+ mov #31,r8
cmp/hs r8,r9
- bt trap_entry ! 64 > vec >= 32 is trap
+ bt trap_entry ! 64 > vec >= 31 is trap
mov.l 4f,r8
mov r9,r4
@@ -143,9 +143,9 @@ interrupt_entry:
trap_entry:
mov #0x30,r8
- cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
+ cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall
bt 1f
- add #-0x10,r9 ! convert SH2 to SH3/4 ABI
+ mov #0x1f,r9 ! convert to unified SH2/3/4 trap number
1:
shll2 r9 ! TRA
bra system_call ! jump common systemcall entry
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 9edc06c..a907ee2 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -232,10 +232,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP004]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP004]),
CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]),
CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 955b9ad..ac98541 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -230,9 +230,9 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]),
CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index ccbcab5..fe84422 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -267,12 +267,12 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[HWBLK_TMU0]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[HWBLK_TMU1]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c
index 7f54bf2..354dcac 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7734.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7734.c
@@ -194,12 +194,12 @@ static struct clk_lookup lookups[] = {
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh7734.0", &mstp_clks[MSTP030]),
CLKDEV_DEV_ID("i2c-sh7734.1", &mstp_clks[MSTP029]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP026]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP024]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP023]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP022]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP021]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP026]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP024]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP023]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP022]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("hscif", &mstp_clks[MSTP019]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index e40ec2c..b10af2a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -125,9 +125,9 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP113]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP114]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP112]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP112]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP111]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP110]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]),
CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index 8eb6e62..1aafd54 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -132,12 +132,12 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP029]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP028]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index 5e50e7e..ac3dcfe 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -139,12 +139,12 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
- CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
+ CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP029]),
+ CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP028]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]),
CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]),
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 605221d..b1bdbc3 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -114,10 +114,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
- CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
- CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
+ CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP027]),
+ CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP026]),
+ CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP025]),
+ CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]),
CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]),
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
index f617bcb..69b8a50 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c
@@ -28,7 +28,7 @@ static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif0_resources[] = {
@@ -50,7 +50,7 @@ static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif1_resources[] = {
@@ -72,7 +72,7 @@ static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif2_resources[] = {
@@ -94,7 +94,7 @@ static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif3_resources[] = {
@@ -116,7 +116,7 @@ static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif4_resources[] = {
@@ -138,7 +138,7 @@ static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
- .regtype = SCIx_SH4_SCIF_REGTYPE,
+ .regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
static struct resource scif5_resources[] = {
diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c
index 10aed41..3a4fed4 100644
--- a/arch/sh/kernel/cpu/sh5/unwind.c
+++ b/arch/sh/kernel/cpu/sh5/unwind.c
@@ -159,7 +159,7 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
/* Sign extend */
regcache[dest] =
- ((((s64)(u64)op >> 10) & 0xffff) << 54) >> 54;
+ sign_extend64((((u64)op >> 10) & 0xffff), 9);
break;
case (0xd0 >> 2): /* addi */
case (0xd4 >> 2): /* addi.l */
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 13047a4..c001f78 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -268,20 +268,29 @@ debug_trap:
* Syscall #: R3
* Arguments #0 to #3: R4--R7
* Arguments #4 to #6: R0, R1, R2
- * TRA: (number of arguments + ABI revision) x 4
+ * TRA: See following table.
*
- * This code also handles delegating other traps to the BIOS/gdb stub
- * according to:
- *
- * Trap number
* (TRA>>2) Purpose
* -------- -------
* 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
* 0x10-0x1f general SH-3/4 syscall ABI.
- * 0x20-0x2f syscall ABI for SH-2 parts.
+ * 0x1f unified SH-2/3/4 syscall ABI (preferred).
+ * 0x20-0x2f original SH-2 syscall ABI.
* 0x30-0x3f debug traps used by the kernel.
* 0x40-0xff Not supported by all parts, so left unhandled.
*
+ * For making system calls, any trap number in the range for the
+ * given cpu model may be used, but the unified trap number 0x1f is
+ * preferred for compatibility with all models.
+ *
+ * The low bits of the trap number were once documented as matching
+ * the number of arguments, but they were never actually used as such
+ * by the kernel. SH-2 originally used its own separate trap range
+ * because several hardware exceptions fell in the range used for the
+ * SH-3/4 syscall ABI.
+ *
+ * This code also handles delegating other traps to the BIOS/gdb stub.
+ *
* Note: When we're first called, the TRA value must be shifted
* right 2 bits in order to get the value that was used as the "trapa"
* argument.
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 079d70e..38993e0 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -212,13 +212,11 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
unsigned char replaced[MCOUNT_INSN_SIZE];
/*
- * Note: Due to modules and __init, code can
- * disappear and change, we need to protect against faulting
- * as well as code changing. We do this by using the
- * probe_kernel_* functions.
- *
- * No real locking needed, this code is run through
- * kstop_machine, or before SMP starts.
+ * Note:
+ * We are paranoid about modifying text, as if a bug was to happen, it
+ * could cause us to read or write to someplace that could cause harm.
+ * Carefully read and modify the code with probe_kernel_*(), and make
+ * sure what we read is what we expected it to be before modifying it.
*/
/* read the text we want to modify */
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 7db2489..974bc15 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -66,6 +66,10 @@ ENTRY(_stext)
mov #0, r0
ldc r0, r6_bank
#endif
+
+#ifdef CONFIG_OF
+ mov r4, r12 ! Store device tree blob pointer in r12
+#endif
/*
* Prefetch if possible to reduce cache miss penalty.
@@ -314,6 +318,12 @@ ENTRY(_stext)
10:
#endif
+#ifdef CONFIG_OF
+ mov.l 8f, r0 ! Make flat device tree available early.
+ jsr @r0
+ mov r12, r4
+#endif
+
! Additional CPU initialization
mov.l 6f, r0
jsr @r0
@@ -339,6 +349,9 @@ ENTRY(stack_start)
5: .long start_kernel
6: .long cpu_init
7: .long init_thread_union
+#if defined(CONFIG_OF)
+8: .long sh_fdt_init
+#endif
#ifdef CONFIG_PMB
.LPMB_ADDR: .long PMB_ADDR
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
deleted file mode 100644
index cbb7d46..0000000
--- a/arch/sh/kernel/localtimer.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Dummy local timer
- *
- * Copyright (C) 2008 Paul Mundt
- *
- * cloned from:
- *
- * linux/arch/arm/mach-realview/localtimer.c
- *
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/smp.h>
-#include <linux/jiffies.h>
-#include <linux/percpu.h>
-#include <linux/clockchips.h>
-#include <linux/hardirq.h>
-#include <linux/irq.h>
-
-static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
-
-/*
- * Used on SMP for either the local timer or SMP_MSG_TIMER
- */
-void local_timer_interrupt(void)
-{
- struct clock_event_device *clk = this_cpu_ptr(&local_clockevent);
-
- irq_enter();
- clk->event_handler(clk);
- irq_exit();
-}
-
-void local_timer_setup(unsigned int cpu)
-{
- struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
-
- clk->name = "dummy_timer";
- clk->features = CLOCK_EVT_FEAT_ONESHOT |
- CLOCK_EVT_FEAT_PERIODIC |
- CLOCK_EVT_FEAT_DUMMY;
- clk->rating = 400;
- clk->mult = 1;
- clk->broadcast = smp_timer_broadcast;
- clk->cpumask = cpumask_of(cpu);
-
- clockevents_register_device(clk);
-}
-
-void local_timer_stop(unsigned int cpu)
-{
-}
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
index 7cfd7f1..4dca183 100644
--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -10,7 +10,7 @@
* Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
* Copyright (C) 2009 Jaswinder Singh Rajput
* Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
* Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
*
* ppc:
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index de19cfa..5d34605 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -29,6 +29,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -78,17 +80,17 @@ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, };
static struct resource code_resource = {
.name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource data_resource = {
.name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
static struct resource bss_resource = {
.name = "Kernel bss",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
};
unsigned long memory_start;
@@ -172,6 +174,7 @@ disable:
#endif
}
+#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
void calibrate_delay(void)
{
struct clk *clk = clk_get(NULL, "cpu_clk");
@@ -187,6 +190,7 @@ void calibrate_delay(void)
(loops_per_jiffy/(5000/HZ)) % 100,
loops_per_jiffy);
}
+#endif
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn)
@@ -202,7 +206,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
res->name = "System RAM";
res->start = start;
res->end = end - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
if (request_resource(&iomem_resource, res)) {
pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
@@ -238,6 +242,29 @@ void __init __weak plat_early_device_setup(void)
{
}
+#ifdef CONFIG_OF
+void __ref sh_fdt_init(phys_addr_t dt_phys)
+{
+ static int done = 0;
+ void *dt_virt;
+
+ /* Avoid calling an __init function on secondary cpus. */
+ if (done) return;
+
+ dt_virt = phys_to_virt(dt_phys);
+
+ if (!dt_virt || !early_init_dt_scan(dt_virt)) {
+ pr_crit("Error: invalid device tree blob"
+ " at physical address %p\n", (void *)dt_phys);
+
+ while (true)
+ cpu_relax();
+ }
+
+ done = 1;
+}
+#endif
+
void __init setup_arch(char **cmdline_p)
{
enable_mmu();
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index d77f2f6..0b30b9d 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3);
DECLARE_EXPORT(__lshrsi3);
DECLARE_EXPORT(__ashrsi3);
DECLARE_EXPORT(__ashlsi3);
+DECLARE_EXPORT(__lshrsi3_r0);
+DECLARE_EXPORT(__ashrsi3_r0);
+DECLARE_EXPORT(__ashlsi3_r0);
DECLARE_EXPORT(__ashiftrt_r4_6);
DECLARE_EXPORT(__ashiftrt_r4_7);
DECLARE_EXPORT(__ashiftrt_r4_8);
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index de6be00..38e7860 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/atomic.h>
+#include <linux/clockchips.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
#include <asm/smp.h>
@@ -141,16 +142,13 @@ int __cpu_disable(void)
migrate_irqs();
/*
- * Stop the local timer for this CPU.
- */
- local_timer_stop(cpu);
-
- /*
* Flush user cache and TLB mappings, and then remove this CPU
* from the vm mask set of all processes.
*/
flush_cache_all();
+#ifdef CONFIG_MMU
local_flush_tlb_all();
+#endif
clear_tasks_mm_cpumask(cpu);
@@ -183,8 +181,10 @@ asmlinkage void start_secondary(void)
atomic_inc(&mm->mm_count);
atomic_inc(&mm->mm_users);
current->active_mm = mm;
+#ifdef CONFIG_MMU
enter_lazy_tlb(mm, current);
local_flush_tlb_all();
+#endif
per_cpu_trap_init();
@@ -194,8 +194,6 @@ asmlinkage void start_secondary(void)
local_irq_enable();
- /* Enable local timers */
- local_timer_setup(cpu);
calibrate_delay();
smp_store_cpu_info(cpu);
@@ -203,7 +201,7 @@ asmlinkage void start_secondary(void)
set_cpu_online(cpu, true);
per_cpu(cpu_state, cpu) = CPU_ONLINE;
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
extern struct {
@@ -285,7 +283,8 @@ void arch_send_call_function_single_ipi(int cpu)
mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
}
-void smp_timer_broadcast(const struct cpumask *mask)
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+void tick_broadcast(const struct cpumask *mask)
{
int cpu;
@@ -296,9 +295,10 @@ void smp_timer_broadcast(const struct cpumask *mask)
static void ipi_timer(void)
{
irq_enter();
- local_timer_interrupt();
+ tick_receive_broadcast();
irq_exit();
}
+#endif
void smp_message_recv(unsigned int msg)
{
@@ -312,9 +312,11 @@ void smp_message_recv(unsigned int msg)
case SMP_MSG_FUNCTION_SINGLE:
generic_smp_call_function_single_interrupt();
break;
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
case SMP_MSG_TIMER:
ipi_timer();
break;
+#endif
default:
printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n",
smp_processor_id(), __func__, msg);
@@ -328,6 +330,8 @@ int setup_profiling_timer(unsigned int multiplier)
return 0;
}
+#ifdef CONFIG_MMU
+
static void flush_tlb_all_ipi(void *info)
{
local_flush_tlb_all();
@@ -467,3 +471,5 @@ void flush_tlb_one(unsigned long asid, unsigned long vaddr)
smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1);
local_flush_tlb_one(asid, vaddr);
}
+
+#endif
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index 112ea11..d208c27 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -101,7 +101,7 @@ static int generate_and_check_address(struct pt_regs *regs,
if (displacement_not_indexed) {
__s64 displacement;
displacement = (opcode >> 10) & 0x3ff;
- displacement = ((displacement << 54) >> 54); /* sign extend */
+ displacement = sign_extend64(displacement, 9);
addr = (__u64)((__s64)base_address + (displacement << width_shift));
} else {
__u64 offset;
diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S
index bd47e9b..70a6434 100644
--- a/arch/sh/lib/ashlsi3.S
+++ b/arch/sh/lib/ashlsi3.S
@@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */
!
! (none)
!
+! __ashlsi3_r0
+!
+! Entry:
+!
+! r4: Value to shift
+! r0: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
+
+
.global __ashlsi3
+ .global __ashlsi3_r0
.align 2
__ashlsi3:
- mov #31,r0
- and r0,r5
+ mov r5,r0
+ .align 2
+__ashlsi3_r0:
+ and #31,r0
+ mov.l r4,@-r15
+ mov r0,r4
mova ashlsi3_table,r0
- mov.b @(r0,r5),r5
-#ifdef __sh1__
- add r5,r0
+ mov.b @(r0,r4),r4
+ add r4,r0
jmp @r0
-#else
- braf r5
-#endif
- mov r4,r0
+ mov.l @r15+,r0
.align 2
ashlsi3_table:
diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S
index 6f3cf46..602599d 100644
--- a/arch/sh/lib/ashrsi3.S
+++ b/arch/sh/lib/ashrsi3.S
@@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */
!
! (none)
!
+! __ashrsi3_r0
+!
+! Entry:
+!
+! r4: Value to shift
+! r0: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
.global __ashrsi3
+ .global __ashrsi3_r0
.align 2
__ashrsi3:
- mov #31,r0
- and r0,r5
+ mov r5,r0
+ .align 2
+__ashrsi3_r0:
+ and #31,r0
+ mov.l r4,@-r15
+ mov r0,r4
mova ashrsi3_table,r0
- mov.b @(r0,r5),r5
-#ifdef __sh1__
- add r5,r0
+ mov.b @(r0,r4),r4
+ add r4,r0
jmp @r0
-#else
- braf r5
-#endif
- mov r4,r0
+ mov.l @r15+,r0
.align 2
ashrsi3_table:
diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S
index 1e7aaa5..f2a6959 100644
--- a/arch/sh/lib/lshrsi3.S
+++ b/arch/sh/lib/lshrsi3.S
@@ -54,21 +54,37 @@ Boston, MA 02110-1301, USA. */
!
! (none)
!
+! __lshrsi3_r0
+!
+! Entry:
+!
+! r0: Value to shift
+! r5: Shifts
+!
+! Exit:
+!
+! r0: Result
+!
+! Destroys:
+!
+! (none)
+!
.global __lshrsi3
+ .global __lshrsi3_r0
.align 2
__lshrsi3:
- mov #31,r0
- and r0,r5
+ mov r5,r0
+ .align 2
+__lshrsi3_r0:
+ and #31,r0
+ mov.l r4,@-r15
+ mov r0,r4
mova lshrsi3_table,r0
- mov.b @(r0,r5),r5
-#ifdef __sh1__
- add r5,r0
+ mov.b @(r0,r4),r4
+ add r4,r0
jmp @r0
-#else
- braf r5
-#endif
- mov r4,r0
+ mov.l @r15+,r0
.align 2
lshrsi3_table:
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 51d8f7f..58aaa4f 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -241,7 +241,7 @@ static void sh4_flush_cache_page(void *args)
*/
map_coherent = (current_cpu_data.dcache.n_aliases &&
test_bit(PG_dcache_clean, &page->flags) &&
- page_mapped(page));
+ page_mapcount(page));
if (map_coherent)
vaddr = kmap_coherent(page, address);
else
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index f770e39..e58cfbf 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -59,7 +59,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+ if (boot_cpu_data.dcache.n_aliases && page_mapcount(page) &&
test_bit(PG_dcache_clean, &page->flags)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
@@ -78,7 +78,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+ if (boot_cpu_data.dcache.n_aliases && page_mapcount(page) &&
test_bit(PG_dcache_clean, &page->flags)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
@@ -97,7 +97,7 @@ void copy_user_highpage(struct page *to, struct page *from,
vto = kmap_atomic(to);
- if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
+ if (boot_cpu_data.dcache.n_aliases && page_mapcount(from) &&
test_bit(PG_dcache_clean, &from->flags)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
@@ -153,7 +153,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
unsigned long addr = (unsigned long) page_address(page);
if (pages_do_alias(addr, vmaddr)) {
- if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+ if (boot_cpu_data.dcache.n_aliases && page_mapcount(page) &&
test_bit(PG_dcache_clean, &page->flags)) {
void *kaddr;
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 6385f60..cc948db 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -35,7 +35,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
if (pud) {
pmd = pmd_alloc(mm, pud, addr);
if (pmd)
- pte = pte_alloc_map(mm, NULL, pmd, addr);
+ pte = pte_alloc_map(mm, pmd, addr);
}
}
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
index ec29e14..bf25d7c 100644
--- a/arch/sh/mm/kmap.c
+++ b/arch/sh/mm/kmap.c
@@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
+ preempt_disable();
pagefault_disable();
idx = FIX_CMAP_END -
@@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr)
}
pagefault_enable();
+ preempt_enable();
}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 56442d2..57ffaf2 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -26,7 +26,6 @@ config SPARC
select RTC_CLASS
select RTC_DRV_M48T59
select RTC_SYSTOHC
- select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_ARCH_JUMP_LABEL if SPARC64
select GENERIC_IRQ_SHOW
@@ -101,10 +100,6 @@ config LOCKDEP_SUPPORT
bool
default y if SPARC64
-config HAVE_LATENCYTOP_SUPPORT
- bool
- default y if SPARC64
-
config ARCH_HIBERNATION_POSSIBLE
def_bool y if SPARC64
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index eaee146..8496a07 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -24,7 +24,13 @@ LDFLAGS := -m elf32_sparc
export BITS := 32
UTS_MACHINE := sparc
+# We are adding -Wa,-Av8 to KBUILD_CFLAGS to deal with a specs bug in some
+# versions of gcc. Some gcc versions won't pass -Av8 to binutils when you
+# give -mcpu=v8. This silently worked with older bintutils versions but
+# does not any more.
KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+KBUILD_CFLAGS += -Wa,-Av8
+
KBUILD_AFLAGS += -m32 -Wa,-Av8
else
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index 6b68f12..04920ab 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -102,6 +102,7 @@ CONFIG_SUNLANCE=m
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=m
CONFIG_SUNVNET=m
+CONFIG_LDMVSW=m
CONFIG_NET_PCI=y
CONFIG_E1000=m
CONFIG_E1000E=m
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index 917084a..f2fbf9e 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -14,11 +14,11 @@
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
-#define atomic64_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
+#define atomic64_read(v) READ_ONCE((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = i)
-#define atomic64_set(v, i) (((v)->counter) = i)
+#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
+#define atomic64_set(v, i) WRITE_ONCE(((v)->counter), (i))
#define ATOMIC_OP(op) \
void atomic_##op(int, atomic_t *); \
diff --git a/arch/sparc/include/asm/barrier_32.h b/arch/sparc/include/asm/barrier_32.h
index ae69eda..8059130 100644
--- a/arch/sparc/include/asm/barrier_32.h
+++ b/arch/sparc/include/asm/barrier_32.h
@@ -1,7 +1,6 @@
#ifndef __SPARC_BARRIER_H
#define __SPARC_BARRIER_H
-#include <asm/processor.h> /* for nop() */
#include <asm-generic/barrier.h>
#endif /* !(__SPARC_BARRIER_H) */
diff --git a/arch/sparc/include/asm/barrier_64.h b/arch/sparc/include/asm/barrier_64.h
index 14a9286..c9f6ee6 100644
--- a/arch/sparc/include/asm/barrier_64.h
+++ b/arch/sparc/include/asm/barrier_64.h
@@ -37,33 +37,14 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
#define rmb() __asm__ __volatile__("":::"memory")
#define wmb() __asm__ __volatile__("":::"memory")
-#define dma_rmb() rmb()
-#define dma_wmb() wmb()
-
-#define smp_store_mb(__var, __value) \
- do { WRITE_ONCE(__var, __value); membar_safe("#StoreLoad"); } while(0)
-
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#else
-#define smp_mb() __asm__ __volatile__("":::"memory")
-#define smp_rmb() __asm__ __volatile__("":::"memory")
-#define smp_wmb() __asm__ __volatile__("":::"memory")
-#endif
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
-
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
barrier(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
@@ -71,7 +52,9 @@ do { \
___p1; \
})
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
+
+#include <asm-generic/barrier.h>
#endif /* !(__SPARC64_BARRIER_H) */
diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h
index 426b238..eff748c 100644
--- a/arch/sparc/include/asm/checksum_32.h
+++ b/arch/sparc/include/asm/checksum_32.h
@@ -170,9 +170,8 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
"addxcc\t%2, %0, %0\n\t"
@@ -190,9 +189,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
@@ -201,8 +199,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__ (
"addcc %3, %4, %%g4\n\t"
diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h
index b8779a6..0395d75 100644
--- a/arch/sparc/include/asm/checksum_64.h
+++ b/arch/sparc/include/asm/checksum_64.h
@@ -96,8 +96,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned int len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__(
@@ -116,8 +115,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
@@ -127,8 +125,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__ (
" addcc %3, %4, %%g7\n"
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index a21da59..1180ae2 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -37,21 +37,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return dma_ops;
}
-#define HAVE_ARCH_DMA_SET_MASK 1
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type) {
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EINVAL;
- *dev->dma_mask = mask;
- return 0;
- }
-#endif
- return -EINVAL;
-}
-
-#include <asm-generic/dma-mapping-common.h>
-
#endif
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index 370ca1e..9331083 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -95,6 +95,7 @@
* really available. So we simply advertise only "crypto" support.
*/
#define HWCAP_SPARC_CRYPTO 0x04000000 /* CRYPTO insns available */
+#define HWCAP_SPARC_ADI 0x08000000 /* ADI available */
#define CORE_DUMP_USE_REGSET
diff --git a/arch/sparc/include/asm/gpio.h b/arch/sparc/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/sparc/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/sparc/include/asm/pci.h b/arch/sparc/include/asm/pci.h
index d9c031f..6e14fd1 100644
--- a/arch/sparc/include/asm/pci.h
+++ b/arch/sparc/include/asm/pci.h
@@ -5,7 +5,4 @@
#else
#include <asm/pci_32.h>
#endif
-
-#include <asm-generic/pci-dma-compat.h>
-
#endif
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 131d36f..7a38d6a 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -681,13 +681,6 @@ static inline unsigned long pmd_trans_huge(pmd_t pmd)
return pte_val(pte) & _PAGE_PMD_HUGE;
}
-static inline unsigned long pmd_trans_splitting(pmd_t pmd)
-{
- pte_t pte = __pte(pmd_val(pmd));
-
- return pmd_trans_huge(pmd) && pte_special(pte);
-}
-
#define has_transparent_hugepage() 1
static inline pmd_t pmd_mkold(pmd_t pmd)
@@ -717,29 +710,29 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
return __pmd(pte_val(pte));
}
-static inline pmd_t pmd_mkyoung(pmd_t pmd)
+static inline pmd_t pmd_mkclean(pmd_t pmd)
{
pte_t pte = __pte(pmd_val(pmd));
- pte = pte_mkyoung(pte);
+ pte = pte_mkclean(pte);
return __pmd(pte_val(pte));
}
-static inline pmd_t pmd_mkwrite(pmd_t pmd)
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
{
pte_t pte = __pte(pmd_val(pmd));
- pte = pte_mkwrite(pte);
+ pte = pte_mkyoung(pte);
return __pmd(pte_val(pte));
}
-static inline pmd_t pmd_mksplitting(pmd_t pmd)
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
{
pte_t pte = __pte(pmd_val(pmd));
- pte = pte_mkspecial(pte);
+ pte = pte_mkwrite(pte);
return __pmd(pte_val(pte));
}
diff --git a/arch/sparc/include/asm/processor.h b/arch/sparc/include/asm/processor.h
index 2fe99e6..9da9646 100644
--- a/arch/sparc/include/asm/processor.h
+++ b/arch/sparc/include/asm/processor.h
@@ -5,7 +5,4 @@
#else
#include <asm/processor_32.h>
#endif
-
-#define nop() __asm__ __volatile__ ("nop")
-
#endif
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index 01d1704..bec481a 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -31,6 +31,9 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
+int __node_distance(int, int);
+#define node_distance(a, b) __node_distance(a, b)
+
#else /* CONFIG_NUMA */
#include <asm-generic/topology.h>
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 64ee103..57aca27 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -205,31 +205,6 @@ int __put_user_bad(void);
__gu_ret; \
})
-#define __get_user_check_ret(x, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- if (__access_ok(addr, size)) { \
- switch (size) { \
- case 1: \
- __get_user_asm_ret(__gu_val, ub, addr, retval); \
- break; \
- case 2: \
- __get_user_asm_ret(__gu_val, uh, addr, retval); \
- break; \
- case 4: \
- __get_user_asm_ret(__gu_val, , addr, retval); \
- break; \
- case 8: \
- __get_user_asm_ret(__gu_val, d, addr, retval); \
- break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- x = (__force type) __gu_val; \
- } else \
- return retval; \
-})
-
#define __get_user_nocheck(x, addr, size, type) ({ \
register int __gu_ret; \
register unsigned long __gu_val; \
@@ -247,20 +222,6 @@ int __put_user_bad(void);
__gu_ret; \
})
-#define __get_user_nocheck_ret(x, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- switch (size) { \
- case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
- case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
- case 4: __get_user_asm_ret(__gu_val, , addr, retval); break; \
- case 8: __get_user_asm_ret(__gu_val, d, addr, retval); break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- x = (__force type) __gu_val; \
-})
-
#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
"/* Get user asm, inline. */\n" \
@@ -281,32 +242,6 @@ __asm__ __volatile__( \
: "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \
"i" (-EFAULT))
-#define __get_user_asm_ret(x, size, addr, retval) \
-if (__builtin_constant_p(retval) && retval == -EFAULT) \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr))); \
-else \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
- "3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
-
int __get_user_bad(void);
unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index ea6e9a2..e9a51d6 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -179,20 +179,6 @@ int __put_user_bad(void);
__gu_ret; \
})
-#define __get_user_nocheck_ret(data, addr, size, type, retval) ({ \
- register unsigned long __gu_val __asm__ ("l1"); \
- switch (size) { \
- case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
- case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
- case 4: __get_user_asm_ret(__gu_val, uw, addr, retval); break; \
- case 8: __get_user_asm_ret(__gu_val, x, addr, retval); break; \
- default: \
- if (__get_user_bad()) \
- return retval; \
- } \
- data = (__force type) __gu_val; \
-})
-
#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
"/* Get user asm, inline. */\n" \
@@ -214,32 +200,6 @@ __asm__ __volatile__( \
: "=r" (ret), "=r" (x) : "r" (__m(addr)), \
"i" (-EFAULT))
-#define __get_user_asm_ret(x, size, addr, retval) \
-if (__builtin_constant_p(retval) && retval == -EFAULT) \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr))); \
-else \
- __asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
- "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
- "3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr)), "i" (retval))
-
int __get_user_bad(void);
unsigned long __must_check ___copy_from_user(void *to,
diff --git a/arch/sparc/include/uapi/asm/asi.h b/arch/sparc/include/uapi/asm/asi.h
index aace6f3..7ad7203d 100644
--- a/arch/sparc/include/uapi/asm/asi.h
+++ b/arch/sparc/include/uapi/asm/asi.h
@@ -279,7 +279,7 @@
* Most-Recently-Used, primary,
* implicit
*/
-#define ASI_ST_BLKINIT_MRU_S 0xf2 /* (NG4) init-store, twin load,
+#define ASI_ST_BLKINIT_MRU_S 0xf3 /* (NG4) init-store, twin load,
* Most-Recently-Used, secondary,
* implicit
*/
diff --git a/arch/sparc/include/uapi/asm/mman.h b/arch/sparc/include/uapi/asm/mman.h
index 0b14df3..9765896 100644
--- a/arch/sparc/include/uapi/asm/mman.h
+++ b/arch/sparc/include/uapi/asm/mman.h
@@ -17,6 +17,7 @@
#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
#define MCL_FUTURE 0x4000 /* lock all additions to address space */
+#define MCL_ONFAULT 0x8000 /* lock all pages that are faulted in */
#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x10000 /* do not block on IO */
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index e6a16c4..31aede3 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -81,6 +81,11 @@
#define SO_ATTACH_BPF 0x0034
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 0x0035
+#define SO_ATTACH_REUSEPORT_EBPF 0x0036
+
+#define SO_CNX_ADVICE 0x0037
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
index 6f35f4d..b6de8b1 100644
--- a/arch/sparc/include/uapi/asm/unistd.h
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -416,8 +416,15 @@
#define __NR_memfd_create 348
#define __NR_bpf 349
#define __NR_execveat 350
+#define __NR_membarrier 351
+#define __NR_userfaultfd 352
+#define __NR_bind 353
+#define __NR_listen 354
+#define __NR_setsockopt 355
+#define __NR_mlock2 356
+#define __NR_copy_file_range 357
-#define NR_syscalls 351
+#define NR_syscalls 358
/* Bitmask values returned from kern_features system call. */
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 33c02b1..a83707c 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -948,7 +948,24 @@ linux_syscall_trace:
cmp %o0, 0
bne 3f
mov -ENOSYS, %o0
+
+ /* Syscall tracing can modify the registers. */
+ ld [%sp + STACKFRAME_SZ + PT_G1], %g1
+ sethi %hi(sys_call_table), %l7
+ ld [%sp + STACKFRAME_SZ + PT_I0], %i0
+ or %l7, %lo(sys_call_table), %l7
+ ld [%sp + STACKFRAME_SZ + PT_I1], %i1
+ ld [%sp + STACKFRAME_SZ + PT_I2], %i2
+ ld [%sp + STACKFRAME_SZ + PT_I3], %i3
+ ld [%sp + STACKFRAME_SZ + PT_I4], %i4
+ ld [%sp + STACKFRAME_SZ + PT_I5], %i5
+ cmp %g1, NR_syscalls
+ bgeu 3f
+ mov -ENOSYS, %o0
+
+ sll %g1, 2, %l4
mov %i0, %o0
+ ld [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 3d61fca..cd1f592 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -696,14 +696,6 @@ tlb_fixup_done:
call __bzero
sub %o1, %o0, %o1
-#ifdef CONFIG_LOCKDEP
- /* We have this call this super early, as even prom_init can grab
- * spinlocks and thus call into the lockdep code.
- */
- call lockdep_init
- nop
-#endif
-
call prom_init
mov %l7, %o0 ! OpenPROM cif handler
@@ -946,6 +938,12 @@ ENTRY(__retl_one)
mov 1, %o0
ENDPROC(__retl_one)
+ENTRY(__retl_one_fp)
+ VISExitHalf
+ retl
+ mov 1, %o0
+ENDPROC(__retl_one_fp)
+
ENTRY(__ret_one_asi)
wr %g0, ASI_AIUS, %asi
ret
@@ -958,6 +956,13 @@ ENTRY(__retl_one_asi)
mov 1, %o0
ENDPROC(__retl_one_asi)
+ENTRY(__retl_one_asi_fp)
+ wr %g0, ASI_AIUS, %asi
+ VISExitHalf
+ retl
+ mov 1, %o0
+ENDPROC(__retl_one_asi_fp)
+
ENTRY(__retl_o1)
retl
mov %o1, %o0
diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S
index afbaba5..d127130 100644
--- a/arch/sparc/kernel/hvcalls.S
+++ b/arch/sparc/kernel/hvcalls.S
@@ -338,8 +338,9 @@ ENTRY(sun4v_mach_set_watchdog)
mov %o1, %o4
mov HV_FAST_MACH_SET_WATCHDOG, %o5
ta HV_FAST_TRAP
+ brnz,a,pn %o4, 0f
stx %o1, [%o4]
- retl
+0: retl
nop
ENDPROC(sun4v_mach_set_watchdog)
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index 6bd7501..f95dd11 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/export.h>
+#include <linux/etherdevice.h>
#include <asm/oplib.h>
#include <asm/idprom.h>
@@ -60,6 +61,12 @@ static void __init display_system_type(unsigned char machtype)
{
}
#endif
+
+unsigned char *arch_get_platform_mac_address(void)
+{
+ return idprom->id_ethaddr;
+}
+
/* Calculate the IDPROM checksum (xor of the data bytes). */
static unsigned char __init calc_idprom_cksum(struct idprom *idprom)
{
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5320689..3768682 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -161,7 +161,7 @@ static inline iopte_t *alloc_npages(struct device *dev,
entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, NULL,
(unsigned long)(-1), 0);
- if (unlikely(entry == DMA_ERROR_CODE))
+ if (unlikely(entry == IOMMU_ERROR_CODE))
return NULL;
return iommu->page_table + entry;
@@ -253,7 +253,7 @@ static void dma_4u_free_coherent(struct device *dev, size_t size,
npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
iommu = dev->archdata.iommu;
- iommu_tbl_range_free(&iommu->tbl, dvma, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, dvma, npages, IOMMU_ERROR_CODE);
order = get_order(size);
if (order < 10)
@@ -426,7 +426,7 @@ static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr,
iommu_free_ctx(iommu, ctx);
spin_unlock_irqrestore(&iommu->lock, flags);
- iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE);
}
static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
@@ -492,7 +492,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
&handle, (unsigned long)(-1), 0);
/* Handle failure */
- if (unlikely(entry == DMA_ERROR_CODE)) {
+ if (unlikely(entry == IOMMU_ERROR_CODE)) {
if (printk_ratelimit())
printk(KERN_INFO "iommu_alloc failed, iommu %p paddr %lx"
" npages %lx\n", iommu, paddr, npages);
@@ -571,7 +571,7 @@ iommu_map_failed:
iopte_make_dummy(iommu, base + j);
iommu_tbl_range_free(&iommu->tbl, vaddr, npages,
- DMA_ERROR_CODE);
+ IOMMU_ERROR_CODE);
s->dma_address = DMA_ERROR_CODE;
s->dma_length = 0;
@@ -648,7 +648,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
iopte_make_dummy(iommu, base + i);
iommu_tbl_range_free(&iommu->tbl, dma_handle, npages,
- DMA_ERROR_CODE);
+ IOMMU_ERROR_CODE);
sg = sg_next(sg);
}
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index 1ae5eb1..59d5038 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1953,7 +1953,7 @@ static struct ldc_mtable_entry *alloc_npages(struct ldc_iommu *iommu,
entry = iommu_tbl_range_alloc(NULL, &iommu->iommu_map_table,
npages, NULL, (unsigned long)-1, 0);
- if (unlikely(entry < 0))
+ if (unlikely(entry == IOMMU_ERROR_CODE))
return NULL;
return iommu->page_table + entry;
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 6f80936..1122886 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -1033,25 +1033,9 @@ static ssize_t mdesc_read(struct file *file, char __user *buf,
static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
{
- struct mdesc_handle *hp;
-
- switch (whence) {
- case SEEK_CUR:
- offset += file->f_pos;
- break;
- case SEEK_SET:
- break;
- default:
- return -EINVAL;
- }
-
- hp = file->private_data;
- if (offset > hp->handle_size)
- return -EINVAL;
- else
- file->f_pos = offset;
+ struct mdesc_handle *hp = file->private_data;
- return offset;
+ return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
}
/* mdesc_close() - /dev/mdesc is being closed, release the reference to
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b91d7f1..badf095 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -185,8 +185,10 @@ static unsigned long pci_parse_of_flags(u32 addr0)
if (addr0 & 0x02000000) {
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
- flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+ if (addr0 & 0x01000000)
+ flags |= IORESOURCE_MEM_64
+ | PCI_BASE_ADDRESS_MEM_TYPE_64;
if (addr0 & 0x40000000)
flags |= IORESOURCE_PREFETCH
| PCI_BASE_ADDRESS_MEM_PREFETCH;
@@ -655,6 +657,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
pbm->io_space.start);
pci_add_resource_offset(&resources, &pbm->mem_space,
pbm->mem_space.start);
+ if (pbm->mem64_space.flags)
+ pci_add_resource_offset(&resources, &pbm->mem64_space,
+ pbm->mem_space.start);
pbm->busn.start = pbm->pci_first_busno;
pbm->busn.end = pbm->pci_last_busno;
pbm->busn.flags = IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 944a065..33524c1 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -406,6 +406,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
}
num_pbm_ranges = i / sizeof(*pbm_ranges);
+ memset(&pbm->mem64_space, 0, sizeof(struct resource));
for (i = 0; i < num_pbm_ranges; i++) {
const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
@@ -451,7 +452,12 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
break;
case 3:
- /* XXX 64-bit MEM handling XXX */
+ /* 64-bit MEM handling */
+ pbm->mem64_space.start = a;
+ pbm->mem64_space.end = a + size - 1UL;
+ pbm->mem64_space.flags = IORESOURCE_MEM;
+ saw_mem = 1;
+ break;
default:
break;
@@ -465,15 +471,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
prom_halt();
}
- printk("%s: PCI IO[%llx] MEM[%llx]\n",
+ printk("%s: PCI IO[%llx] MEM[%llx]",
pbm->name,
pbm->io_space.start,
pbm->mem_space.start);
+ if (pbm->mem64_space.flags)
+ printk(" MEM64[%llx]",
+ pbm->mem64_space.start);
+ printk("\n");
pbm->io_space.name = pbm->mem_space.name = pbm->name;
+ pbm->mem64_space.name = pbm->name;
request_resource(&ioport_resource, &pbm->io_space);
request_resource(&iomem_resource, &pbm->mem_space);
+ if (pbm->mem64_space.flags)
+ request_resource(&iomem_resource, &pbm->mem64_space);
pci_register_legacy_regions(&pbm->io_space,
&pbm->mem_space);
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 75803c7..37222ca 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -97,6 +97,7 @@ struct pci_pbm_info {
/* PBM I/O and Memory space resources. */
struct resource io_space;
struct resource mem_space;
+ struct resource mem64_space;
struct resource busn;
/* Base of PCI Config space, can be per-PBM or shared. */
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index d2fe57d..836e8ce 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -159,7 +159,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, NULL,
(unsigned long)(-1), 0);
- if (unlikely(entry == DMA_ERROR_CODE))
+ if (unlikely(entry == IOMMU_ERROR_CODE))
goto range_alloc_fail;
*dma_addrp = (iommu->tbl.table_map_base + (entry << IO_PAGE_SHIFT));
@@ -187,7 +187,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
return ret;
iommu_map_fail:
- iommu_tbl_range_free(&iommu->tbl, *dma_addrp, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, *dma_addrp, npages, IOMMU_ERROR_CODE);
range_alloc_fail:
free_pages(first_page, order);
@@ -226,7 +226,7 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
devhandle = pbm->devhandle;
entry = ((dvma - iommu->tbl.table_map_base) >> IO_PAGE_SHIFT);
dma_4v_iommu_demap(&devhandle, entry, npages);
- iommu_tbl_range_free(&iommu->tbl, dvma, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, dvma, npages, IOMMU_ERROR_CODE);
order = get_order(size);
if (order < 10)
free_pages((unsigned long)cpu, order);
@@ -256,7 +256,7 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page,
entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, NULL,
(unsigned long)(-1), 0);
- if (unlikely(entry == DMA_ERROR_CODE))
+ if (unlikely(entry == IOMMU_ERROR_CODE))
goto bad;
bus_addr = (iommu->tbl.table_map_base + (entry << IO_PAGE_SHIFT));
@@ -288,7 +288,7 @@ bad:
return DMA_ERROR_CODE;
iommu_map_fail:
- iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE);
return DMA_ERROR_CODE;
}
@@ -317,7 +317,7 @@ static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr,
bus_addr &= IO_PAGE_MASK;
entry = (bus_addr - iommu->tbl.table_map_base) >> IO_PAGE_SHIFT;
dma_4v_iommu_demap(&devhandle, entry, npages);
- iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE);
}
static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
@@ -376,7 +376,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
&handle, (unsigned long)(-1), 0);
/* Handle failure */
- if (unlikely(entry == DMA_ERROR_CODE)) {
+ if (unlikely(entry == IOMMU_ERROR_CODE)) {
if (printk_ratelimit())
printk(KERN_INFO "iommu_alloc failed, iommu %p paddr %lx"
" npages %lx\n", iommu, paddr, npages);
@@ -451,7 +451,7 @@ iommu_map_failed:
npages = iommu_num_pages(s->dma_address, s->dma_length,
IO_PAGE_SIZE);
iommu_tbl_range_free(&iommu->tbl, vaddr, npages,
- DMA_ERROR_CODE);
+ IOMMU_ERROR_CODE);
/* XXX demap? XXX */
s->dma_address = DMA_ERROR_CODE;
s->dma_length = 0;
@@ -496,7 +496,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
entry = ((dma_handle - tbl->table_map_base) >> shift);
dma_4v_iommu_demap(&devhandle, entry, npages);
iommu_tbl_range_free(&iommu->tbl, dma_handle, npages,
- DMA_ERROR_CODE);
+ IOMMU_ERROR_CODE);
sg = sg_next(sg);
}
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 689db65..6596f66 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -9,7 +9,7 @@
* Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
* Copyright (C) 2009 Jaswinder Singh Rajput
* Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
*/
#include <linux/perf_event.h>
@@ -108,7 +108,7 @@ struct cpu_hw_events {
/* Enabled/disable state. */
int enabled;
- unsigned int group_flag;
+ unsigned int txn_flags;
};
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
@@ -1379,7 +1379,7 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags)
* skip the schedulability test here, it will be performed
* at commit time(->commit_txn) as a whole
*/
- if (cpuc->group_flag & PERF_EVENT_TXN)
+ if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
goto nocheck;
if (check_excludes(cpuc->event, n0, 1))
@@ -1494,12 +1494,17 @@ static int sparc_pmu_event_init(struct perf_event *event)
* Set the flag to make pmu::enable() not perform the
* schedulability test, it will be performed at commit time
*/
-static void sparc_pmu_start_txn(struct pmu *pmu)
+static void sparc_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
{
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
+
+ cpuhw->txn_flags = txn_flags;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
perf_pmu_disable(pmu);
- cpuhw->group_flag |= PERF_EVENT_TXN;
}
/*
@@ -1510,8 +1515,15 @@ static void sparc_pmu_start_txn(struct pmu *pmu)
static void sparc_pmu_cancel_txn(struct pmu *pmu)
{
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
+ unsigned int txn_flags;
+
+ WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
+
+ txn_flags = cpuhw->txn_flags;
+ cpuhw->txn_flags = 0;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
- cpuhw->group_flag &= ~PERF_EVENT_TXN;
perf_pmu_enable(pmu);
}
@@ -1528,14 +1540,20 @@ static int sparc_pmu_commit_txn(struct pmu *pmu)
if (!sparc_pmu)
return -EINVAL;
- cpuc = this_cpu_ptr(&cpu_hw_events);
+ WARN_ON_ONCE(!cpuc->txn_flags); /* no txn in flight */
+
+ if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
+ cpuc->txn_flags = 0;
+ return 0;
+ }
+
n = cpuc->n_events;
if (check_excludes(cpuc->event, 0, n))
return -EINVAL;
if (sparc_check_constraints(cpuc->event, cpuc->events, n))
return -EAGAIN;
- cpuc->group_flag &= ~PERF_EVENT_TXN;
+ cpuc->txn_flags = 0;
perf_pmu_enable(pmu);
return 0;
}
@@ -1810,11 +1828,18 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
void
perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
+ u64 saved_fault_address = current_thread_info()->fault_address;
+ u8 saved_fault_code = get_thread_fault_code();
+ mm_segment_t old_fs;
+
perf_callchain_store(entry, regs->tpc);
if (!current->mm)
return;
+ old_fs = get_fs();
+ set_fs(USER_DS);
+
flushw_user();
pagefault_disable();
@@ -1825,4 +1850,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
perf_callchain_user_64(entry, regs);
pagefault_enable();
+
+ set_fs(old_fs);
+ set_thread_fault_code(saved_fault_code);
+ current_thread_info()->fault_address = saved_fault_address;
}
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 39f0c66..d08bdaf 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -73,7 +73,13 @@ rtrap_nmi: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
andn %l1, %l4, %l1
srl %l4, 20, %l4
ba,pt %xcc, rtrap_no_irq_enable
- wrpr %l4, %pil
+ nop
+ /* Do not actually set the %pil here. We will do that
+ * below after we clear PSTATE_IE in the %pstate register.
+ * If we re-enable interrupts here, we can recurse down
+ * the hardirq stack potentially endlessly, causing a
+ * stack overflow.
+ */
.align 64
.globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index f7b2617..f3185e2 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -380,7 +380,8 @@ static const char *hwcaps[] = {
*/
"mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
"ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau",
- "ima", "cspare", "pause", "cbcond",
+ "ima", "cspare", "pause", "cbcond", NULL /*reserved for crypto */,
+ "adp",
};
static const char *crypto_hwcaps[] = {
@@ -396,7 +397,7 @@ void cpucap_info(struct seq_file *m)
seq_puts(m, "cpucaps\t\t: ");
for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
unsigned long bit = 1UL << i;
- if (caps & bit) {
+ if (hwcaps[i] && (caps & bit)) {
seq_printf(m, "%s%s",
printed ? "," : "", hwcaps[i]);
printed++;
@@ -450,7 +451,7 @@ static void __init report_hwcaps(unsigned long caps)
for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
unsigned long bit = 1UL << i;
- if (caps & bit)
+ if (hwcaps[i] && (caps & bit))
report_one_hwcap(&printed, hwcaps[i]);
}
if (caps & HWCAP_SPARC_CRYPTO)
@@ -485,7 +486,7 @@ static unsigned long __init mdesc_cpu_hwcap_list(void)
for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
unsigned long bit = 1UL << i;
- if (!strcmp(prop, hwcaps[i])) {
+ if (hwcaps[i] && !strcmp(prop, hwcaps[i])) {
caps |= bit;
break;
}
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index d88beff4..39aaec1 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
unsigned char fenab;
int err;
- flush_user_windows();
+ synchronize_user_stack();
if (get_thread_wsaved() ||
(((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
(!__access_ok(ucp, sizeof(*ucp))))
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index b3a5d81..fb30e7c 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -364,7 +364,7 @@ static void sparc_start_secondary(void *arg)
local_irq_enable();
wmb();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
/* We should never reach here! */
BUG();
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 19cd08d..8a6151a 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -134,7 +134,7 @@ void smp_callin(void)
local_irq_enable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
void cpu_panic(void)
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c
index a92d5d2..9e034f2 100644
--- a/arch/sparc/kernel/sparc_ksyms_64.c
+++ b/arch/sparc/kernel/sparc_ksyms_64.c
@@ -37,6 +37,7 @@ EXPORT_SYMBOL(sun4v_niagara_getperf);
EXPORT_SYMBOL(sun4v_niagara_setperf);
EXPORT_SYMBOL(sun4v_niagara2_getperf);
EXPORT_SYMBOL(sun4v_niagara2_setperf);
+EXPORT_SYMBOL(sun4v_mach_set_watchdog);
/* from hweight.S */
EXPORT_SYMBOL(__arch_hweight8);
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 30e7ddb..b489e97 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -264,7 +264,7 @@ static unsigned long mmap_rnd(void)
unsigned long rnd = 0UL;
if (current->flags & PF_RANDOMIZE) {
- unsigned long val = get_random_int();
+ unsigned long val = get_random_long();
if (test_thread_flag(TIF_32BIT))
rnd = (val % (1UL << (23UL-PAGE_SHIFT)));
else
@@ -413,7 +413,7 @@ out:
SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
{
- int ret;
+ long ret;
if (personality(current->personality) == PER_LINUX32 &&
personality(personality) == PER_LINUX)
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index bb00089..c4a1b5c 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -158,7 +158,25 @@ linux_syscall_trace32:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
+
+ /* Syscall tracing can modify the registers. */
+ ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
+ sethi %hi(sys_call_table32), %l7
+ ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
+ or %l7, %lo(sys_call_table32), %l7
+ ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
+ ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
+ ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
+ ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
+ ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+ cmp %g1, NR_syscalls
+ bgeu,pn %xcc, 3f
+ mov -ENOSYS, %o0
+
+ sll %g1, 2, %l4
srl %i0, 0, %o0
+ lduw [%l7 + %l4], %l7
srl %i4, 0, %o4
srl %i1, 0, %o1
srl %i2, 0, %o2
@@ -170,7 +188,25 @@ linux_syscall_trace:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
+
+ /* Syscall tracing can modify the registers. */
+ ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
+ sethi %hi(sys_call_table64), %l7
+ ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
+ or %l7, %lo(sys_call_table64), %l7
+ ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
+ ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
+ ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
+ ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
+ ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
+
+ cmp %g1, NR_syscalls
+ bgeu,pn %xcc, 3f
+ mov -ENOSYS, %o0
+
+ sll %g1, 2, %l4
mov %i0, %o0
+ lduw [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index e31a905..6c3dd6c 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -35,18 +35,18 @@ sys_call_table:
/*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64
/*85*/ .long sys_swapon, sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
/*90*/ .long sys_dup2, sys_setfsuid, sys_fcntl, sys_select, sys_setfsgid
-/*95*/ .long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+/*95*/ .long sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
/*100*/ .long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
/*105*/ .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/ .long sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
-/*115*/ .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/ .long sys_setresgid, sys_getresgid, sys_setregid, sys_recvmsg, sys_sendmsg
+/*115*/ .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_getsockopt, sys_getcwd
/*120*/ .long sys_readv, sys_writev, sys_settimeofday, sys_fchown16, sys_fchmod
-/*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
-/*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
-/*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
-/*140*/ .long sys_sendfile64, sys_nis_syscall, sys_futex, sys_gettid, sys_getrlimit
+/*125*/ .long sys_recvfrom, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
+/*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_sendto, sys_shutdown
+/*135*/ .long sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
+/*140*/ .long sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit
/*145*/ .long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/ .long sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+/*150*/ .long sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
/*155*/ .long sys_fcntl64, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
/*160*/ .long sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
/*165*/ .long sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
@@ -87,4 +87,5 @@ sys_call_table:
/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/ .long sys_execveat
+/*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index d72f76a..12b524c 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -37,15 +37,15 @@ sys_call_table32:
/*80*/ .word sys_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64
.word sys_swapon, compat_sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
- .word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ .word sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
/*100*/ .word sys_getpriority, sys32_rt_sigreturn, compat_sys_rt_sigaction, compat_sys_rt_sigprocmask, compat_sys_rt_sigpending
.word compat_sys_rt_sigtimedwait, compat_sys_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
- .word sys_getgroups, compat_sys_gettimeofday, compat_sys_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, compat_sys_recvmsg, compat_sys_sendmsg
+ .word sys_getgroups, compat_sys_gettimeofday, compat_sys_getrusage, compat_sys_getsockopt, sys_getcwd
/*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
- .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate
-/*130*/ .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
- .word sys_nis_syscall, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
+ .word sys_recvfrom, sys_setreuid16, sys_setregid16, sys_rename, compat_sys_truncate
+/*130*/ .word compat_sys_ftruncate, sys_flock, compat_sys_lstat64, sys_sendto, sys_shutdown
+ .word sys_socketpair, sys_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
/*140*/ .word sys_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
.word compat_sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
/*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
@@ -88,7 +88,8 @@ sys_call_table32:
.word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/ .word sys32_execveat
+/*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+ .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range
#endif /* CONFIG_COMPAT */
@@ -168,4 +169,5 @@ sys_call_table:
.word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
-/*350*/ .word sys64_execveat
+/*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
+ .word sys_setsockopt, sys_mlock2, sys_copy_file_range
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index 62098a8..d89e97b 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -436,24 +436,26 @@ extern void sun4v_data_access_exception(struct pt_regs *regs,
int handle_ldf_stq(u32 insn, struct pt_regs *regs)
{
unsigned long addr = compute_effective_address(regs, insn, 0);
- int freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20);
+ int freg;
struct fpustate *f = FPUSTATE;
int asi = decode_asi(insn, regs);
- int flag = (freg < 32) ? FPRS_DL : FPRS_DU;
+ int flag;
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
save_and_clear_fpu();
current_thread_info()->xfsr[0] &= ~0x1c000;
- if (freg & 3) {
- current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
- do_fpother(regs);
- return 0;
- }
if (insn & 0x200000) {
/* STQ */
u64 first = 0, second = 0;
+ freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20);
+ flag = (freg < 32) ? FPRS_DL : FPRS_DU;
+ if (freg & 3) {
+ current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
+ do_fpother(regs);
+ return 0;
+ }
if (current_thread_info()->fpsaved[0] & flag) {
first = *(u64 *)&f->regs[freg];
second = *(u64 *)&f->regs[freg+2];
@@ -513,6 +515,12 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs)
case 0x100000: size = 4; break;
default: size = 2; break;
}
+ if (size == 1)
+ freg = (insn >> 25) & 0x1f;
+ else
+ freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20);
+ flag = (freg < 32) ? FPRS_DL : FPRS_DU;
+
for (i = 0; i < size; i++)
data[i] = 0;
diff --git a/arch/sparc/lib/NG2copy_from_user.S b/arch/sparc/lib/NG2copy_from_user.S
index 119ccb9..d5242b8 100644
--- a/arch/sparc/lib/NG2copy_from_user.S
+++ b/arch/sparc/lib/NG2copy_from_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_LD_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_asi_fp;\
+ .text; \
+ .align 4;
+
#ifndef ASI_AIUS
#define ASI_AIUS 0x11
#endif
diff --git a/arch/sparc/lib/NG2copy_to_user.S b/arch/sparc/lib/NG2copy_to_user.S
index 7fe1cce..4e962d9 100644
--- a/arch/sparc/lib/NG2copy_to_user.S
+++ b/arch/sparc/lib/NG2copy_to_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_ST_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_asi_fp;\
+ .text; \
+ .align 4;
+
#ifndef ASI_AIUS
#define ASI_AIUS 0x11
#endif
diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S
index 30eee6e..d5f585d 100644
--- a/arch/sparc/lib/NG2memcpy.S
+++ b/arch/sparc/lib/NG2memcpy.S
@@ -34,10 +34,16 @@
#ifndef EX_LD
#define EX_LD(x) x
#endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x) x
+#endif
#ifndef EX_ST
#define EX_ST(x) x
#endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x) x
+#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
@@ -134,40 +140,40 @@
fsrc2 %x6, %f12; \
fsrc2 %x7, %f14;
#define FREG_LOAD_1(base, x0) \
- EX_LD(LOAD(ldd, base + 0x00, %x0))
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0))
#define FREG_LOAD_2(base, x0, x1) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1));
#define FREG_LOAD_3(base, x0, x1, x2) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1)); \
- EX_LD(LOAD(ldd, base + 0x10, %x2));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD_FP(LOAD(ldd, base + 0x10, %x2));
#define FREG_LOAD_4(base, x0, x1, x2, x3) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1)); \
- EX_LD(LOAD(ldd, base + 0x10, %x2)); \
- EX_LD(LOAD(ldd, base + 0x18, %x3));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD_FP(LOAD(ldd, base + 0x18, %x3));
#define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1)); \
- EX_LD(LOAD(ldd, base + 0x10, %x2)); \
- EX_LD(LOAD(ldd, base + 0x18, %x3)); \
- EX_LD(LOAD(ldd, base + 0x20, %x4));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD_FP(LOAD(ldd, base + 0x20, %x4));
#define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1)); \
- EX_LD(LOAD(ldd, base + 0x10, %x2)); \
- EX_LD(LOAD(ldd, base + 0x18, %x3)); \
- EX_LD(LOAD(ldd, base + 0x20, %x4)); \
- EX_LD(LOAD(ldd, base + 0x28, %x5));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+ EX_LD_FP(LOAD(ldd, base + 0x28, %x5));
#define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
- EX_LD(LOAD(ldd, base + 0x00, %x0)); \
- EX_LD(LOAD(ldd, base + 0x08, %x1)); \
- EX_LD(LOAD(ldd, base + 0x10, %x2)); \
- EX_LD(LOAD(ldd, base + 0x18, %x3)); \
- EX_LD(LOAD(ldd, base + 0x20, %x4)); \
- EX_LD(LOAD(ldd, base + 0x28, %x5)); \
- EX_LD(LOAD(ldd, base + 0x30, %x6));
+ EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+ EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); \
+ EX_LD_FP(LOAD(ldd, base + 0x30, %x6));
.register %g2,#scratch
.register %g3,#scratch
@@ -275,11 +281,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop
/* fall through for 0 < low bits < 8 */
110: sub %o4, 64, %g2
- EX_LD(LOAD_BLK(%g2, %f0))
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+ EX_LD_FP(LOAD_BLK(%g2, %f0))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -290,10 +296,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
120: sub %o4, 56, %g2
FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -304,10 +310,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
130: sub %o4, 48, %g2
FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -318,10 +324,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
140: sub %o4, 40, %g2
FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_5(f22, f24, f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -332,10 +338,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
150: sub %o4, 32, %g2
FREG_LOAD_4(%g2, f0, f2, f4, f6)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_4(f24, f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -346,10 +352,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
160: sub %o4, 24, %g2
FREG_LOAD_3(%g2, f0, f2, f4)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_3(f26, f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -360,10 +366,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
170: sub %o4, 16, %g2
FREG_LOAD_2(%g2, f0, f2)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_2(f28, f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -374,10 +380,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
180: sub %o4, 8, %g2
FREG_LOAD_1(%g2, f0)
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
- EX_LD(LOAD_BLK(%o4, %f16))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f16))
FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
FREG_MOVE_1(f30)
subcc %g1, 64, %g1
add %o4, 64, %o4
@@ -387,10 +393,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop
190:
-1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
subcc %g1, 64, %g1
- EX_LD(LOAD_BLK(%o4, %f0))
- EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ EX_LD_FP(LOAD_BLK(%o4, %f0))
+ EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
add %o4, 64, %o4
bne,pt %xcc, 1b
LOAD(prefetch, %o4 + 64, #one_read)
diff --git a/arch/sparc/lib/NG4copy_from_user.S b/arch/sparc/lib/NG4copy_from_user.S
index fd9f903..2e8ee7a 100644
--- a/arch/sparc/lib/NG4copy_from_user.S
+++ b/arch/sparc/lib/NG4copy_from_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_LD_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_asi_fp;\
+ .text; \
+ .align 4;
+
#ifndef ASI_AIUS
#define ASI_AIUS 0x11
#endif
diff --git a/arch/sparc/lib/NG4copy_to_user.S b/arch/sparc/lib/NG4copy_to_user.S
index 9744c454..be0bf45 100644
--- a/arch/sparc/lib/NG4copy_to_user.S
+++ b/arch/sparc/lib/NG4copy_to_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_ST_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_asi_fp;\
+ .text; \
+ .align 4;
+
#ifndef ASI_AIUS
#define ASI_AIUS 0x11
#endif
diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S
index 83aeeb1..8e13ee1 100644
--- a/arch/sparc/lib/NG4memcpy.S
+++ b/arch/sparc/lib/NG4memcpy.S
@@ -48,10 +48,16 @@
#ifndef EX_LD
#define EX_LD(x) x
#endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x) x
+#endif
#ifndef EX_ST
#define EX_ST(x) x
#endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x) x
+#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
@@ -210,17 +216,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %o2, %o4, %o2
alignaddr %o1, %g0, %g1
add %o1, %o4, %o1
- EX_LD(LOAD(ldd, %g1 + 0x00, %f0))
-1: EX_LD(LOAD(ldd, %g1 + 0x08, %f2))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0))
+1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2))
subcc %o4, 0x40, %o4
- EX_LD(LOAD(ldd, %g1 + 0x10, %f4))
- EX_LD(LOAD(ldd, %g1 + 0x18, %f6))
- EX_LD(LOAD(ldd, %g1 + 0x20, %f8))
- EX_LD(LOAD(ldd, %g1 + 0x28, %f10))
- EX_LD(LOAD(ldd, %g1 + 0x30, %f12))
- EX_LD(LOAD(ldd, %g1 + 0x38, %f14))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14))
faligndata %f0, %f2, %f16
- EX_LD(LOAD(ldd, %g1 + 0x40, %f0))
+ EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0))
faligndata %f2, %f4, %f18
add %g1, 0x40, %g1
faligndata %f4, %f6, %f20
@@ -229,14 +235,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
faligndata %f10, %f12, %f26
faligndata %f12, %f14, %f28
faligndata %f14, %f0, %f30
- EX_ST(STORE(std, %f16, %o0 + 0x00))
- EX_ST(STORE(std, %f18, %o0 + 0x08))
- EX_ST(STORE(std, %f20, %o0 + 0x10))
- EX_ST(STORE(std, %f22, %o0 + 0x18))
- EX_ST(STORE(std, %f24, %o0 + 0x20))
- EX_ST(STORE(std, %f26, %o0 + 0x28))
- EX_ST(STORE(std, %f28, %o0 + 0x30))
- EX_ST(STORE(std, %f30, %o0 + 0x38))
+ EX_ST_FP(STORE(std, %f16, %o0 + 0x00))
+ EX_ST_FP(STORE(std, %f18, %o0 + 0x08))
+ EX_ST_FP(STORE(std, %f20, %o0 + 0x10))
+ EX_ST_FP(STORE(std, %f22, %o0 + 0x18))
+ EX_ST_FP(STORE(std, %f24, %o0 + 0x20))
+ EX_ST_FP(STORE(std, %f26, %o0 + 0x28))
+ EX_ST_FP(STORE(std, %f28, %o0 + 0x30))
+ EX_ST_FP(STORE(std, %f30, %o0 + 0x38))
add %o0, 0x40, %o0
bne,pt %icc, 1b
LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
diff --git a/arch/sparc/lib/U1copy_from_user.S b/arch/sparc/lib/U1copy_from_user.S
index a6ae2ea..ecc5692 100644
--- a/arch/sparc/lib/U1copy_from_user.S
+++ b/arch/sparc/lib/U1copy_from_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_LD_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_fp;\
+ .text; \
+ .align 4;
+
#define FUNC_NAME ___copy_from_user
#define LOAD(type,addr,dest) type##a [addr] %asi, dest
#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_AIUS, dest
diff --git a/arch/sparc/lib/U1copy_to_user.S b/arch/sparc/lib/U1copy_to_user.S
index f4b970e..9eea392 100644
--- a/arch/sparc/lib/U1copy_to_user.S
+++ b/arch/sparc/lib/U1copy_to_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_ST_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_fp;\
+ .text; \
+ .align 4;
+
#define FUNC_NAME ___copy_to_user
#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS
#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS
diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S
index b67142b..3e6209e 100644
--- a/arch/sparc/lib/U1memcpy.S
+++ b/arch/sparc/lib/U1memcpy.S
@@ -25,10 +25,16 @@
#ifndef EX_LD
#define EX_LD(x) x
#endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x) x
+#endif
#ifndef EX_ST
#define EX_ST(x) x
#endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x) x
+#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
@@ -73,8 +79,8 @@
faligndata %f8, %f9, %f62;
#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \
- EX_LD(LOAD_BLK(%src, %fdest)); \
- EX_ST(STORE_BLK(%fsrc, %dest)); \
+ EX_LD_FP(LOAD_BLK(%src, %fdest)); \
+ EX_ST_FP(STORE_BLK(%fsrc, %dest)); \
add %src, 0x40, %src; \
subcc %len, 0x40, %len; \
be,pn %xcc, jmptgt; \
@@ -89,12 +95,12 @@
#define DO_SYNC membar #Sync;
#define STORE_SYNC(dest, fsrc) \
- EX_ST(STORE_BLK(%fsrc, %dest)); \
+ EX_ST_FP(STORE_BLK(%fsrc, %dest)); \
add %dest, 0x40, %dest; \
DO_SYNC
#define STORE_JUMP(dest, fsrc, target) \
- EX_ST(STORE_BLK(%fsrc, %dest)); \
+ EX_ST_FP(STORE_BLK(%fsrc, %dest)); \
add %dest, 0x40, %dest; \
ba,pt %xcc, target; \
nop;
@@ -103,7 +109,7 @@
subcc %left, 8, %left;\
bl,pn %xcc, 95f; \
faligndata %f0, %f1, %f48; \
- EX_ST(STORE(std, %f48, %dest)); \
+ EX_ST_FP(STORE(std, %f48, %dest)); \
add %dest, 8, %dest;
#define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \
@@ -160,8 +166,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
and %g2, 0x38, %g2
1: subcc %g1, 0x1, %g1
- EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
- EX_ST(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
+ EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+ EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
bgu,pt %XCC, 1b
add %o1, 0x1, %o1
@@ -172,20 +178,20 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
be,pt %icc, 3f
alignaddr %o1, %g0, %o1
- EX_LD(LOAD(ldd, %o1, %f4))
-1: EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+ EX_LD_FP(LOAD(ldd, %o1, %f4))
+1: EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f4, %f6, %f0
- EX_ST(STORE(std, %f0, %o0))
+ EX_ST_FP(STORE(std, %f0, %o0))
be,pn %icc, 3f
add %o0, 0x8, %o0
- EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f6, %f4, %f0
- EX_ST(STORE(std, %f0, %o0))
+ EX_ST_FP(STORE(std, %f0, %o0))
bne,pt %icc, 1b
add %o0, 0x8, %o0
@@ -208,13 +214,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
add %g1, %GLOBAL_SPARE, %g1
subcc %o2, %g3, %o2
- EX_LD(LOAD_BLK(%o1, %f0))
+ EX_LD_FP(LOAD_BLK(%o1, %f0))
add %o1, 0x40, %o1
add %g1, %g3, %g1
- EX_LD(LOAD_BLK(%o1, %f16))
+ EX_LD_FP(LOAD_BLK(%o1, %f16))
add %o1, 0x40, %o1
sub %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
- EX_LD(LOAD_BLK(%o1, %f32))
+ EX_LD_FP(LOAD_BLK(%o1, %f32))
add %o1, 0x40, %o1
/* There are 8 instances of the unrolled loop,
@@ -426,28 +432,28 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
62: FINISH_VISCHUNK(o0, f44, f46, g3)
63: UNEVEN_VISCHUNK_LAST(o0, f46, f0, g3)
-93: EX_LD(LOAD(ldd, %o1, %f2))
+93: EX_LD_FP(LOAD(ldd, %o1, %f2))
add %o1, 8, %o1
subcc %g3, 8, %g3
faligndata %f0, %f2, %f8
- EX_ST(STORE(std, %f8, %o0))
+ EX_ST_FP(STORE(std, %f8, %o0))
bl,pn %xcc, 95f
add %o0, 8, %o0
- EX_LD(LOAD(ldd, %o1, %f0))
+ EX_LD_FP(LOAD(ldd, %o1, %f0))
add %o1, 8, %o1
subcc %g3, 8, %g3
faligndata %f2, %f0, %f8
- EX_ST(STORE(std, %f8, %o0))
+ EX_ST_FP(STORE(std, %f8, %o0))
bge,pt %xcc, 93b
add %o0, 8, %o0
95: brz,pt %o2, 2f
mov %g1, %o1
-1: EX_LD(LOAD(ldub, %o1, %o3))
+1: EX_LD_FP(LOAD(ldub, %o1, %o3))
add %o1, 1, %o1
subcc %o2, 1, %o2
- EX_ST(STORE(stb, %o3, %o0))
+ EX_ST_FP(STORE(stb, %o3, %o0))
bne,pt %xcc, 1b
add %o0, 1, %o0
diff --git a/arch/sparc/lib/U3copy_from_user.S b/arch/sparc/lib/U3copy_from_user.S
index b1acd13..88ad73d 100644
--- a/arch/sparc/lib/U3copy_from_user.S
+++ b/arch/sparc/lib/U3copy_from_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_LD_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_fp;\
+ .text; \
+ .align 4;
+
#define FUNC_NAME U3copy_from_user
#define LOAD(type,addr,dest) type##a [addr] %asi, dest
#define EX_RETVAL(x) 0
diff --git a/arch/sparc/lib/U3copy_to_user.S b/arch/sparc/lib/U3copy_to_user.S
index ef1e493..845139d 100644
--- a/arch/sparc/lib/U3copy_to_user.S
+++ b/arch/sparc/lib/U3copy_to_user.S
@@ -11,6 +11,14 @@
.text; \
.align 4;
+#define EX_ST_FP(x) \
+98: x; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, __retl_one_fp;\
+ .text; \
+ .align 4;
+
#define FUNC_NAME U3copy_to_user
#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS
#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS
diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S
index 7cae9cc..491ee69 100644
--- a/arch/sparc/lib/U3memcpy.S
+++ b/arch/sparc/lib/U3memcpy.S
@@ -24,10 +24,16 @@
#ifndef EX_LD
#define EX_LD(x) x
#endif
+#ifndef EX_LD_FP
+#define EX_LD_FP(x) x
+#endif
#ifndef EX_ST
#define EX_ST(x) x
#endif
+#ifndef EX_ST_FP
+#define EX_ST_FP(x) x
+#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
@@ -120,8 +126,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
and %g2, 0x38, %g2
1: subcc %g1, 0x1, %g1
- EX_LD(LOAD(ldub, %o1 + 0x00, %o3))
- EX_ST(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
+ EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+ EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
bgu,pt %XCC, 1b
add %o1, 0x1, %o1
@@ -132,20 +138,20 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
be,pt %icc, 3f
alignaddr %o1, %g0, %o1
- EX_LD(LOAD(ldd, %o1, %f4))
-1: EX_LD(LOAD(ldd, %o1 + 0x8, %f6))
+ EX_LD_FP(LOAD(ldd, %o1, %f4))
+1: EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f4, %f6, %f0
- EX_ST(STORE(std, %f0, %o0))
+ EX_ST_FP(STORE(std, %f0, %o0))
be,pn %icc, 3f
add %o0, 0x8, %o0
- EX_LD(LOAD(ldd, %o1 + 0x8, %f4))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f6, %f4, %f2
- EX_ST(STORE(std, %f2, %o0))
+ EX_ST_FP(STORE(std, %f2, %o0))
bne,pt %icc, 1b
add %o0, 0x8, %o0
@@ -155,25 +161,25 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
LOAD(prefetch, %o1 + 0x080, #one_read)
LOAD(prefetch, %o1 + 0x0c0, #one_read)
LOAD(prefetch, %o1 + 0x100, #one_read)
- EX_LD(LOAD(ldd, %o1 + 0x000, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0))
LOAD(prefetch, %o1 + 0x140, #one_read)
- EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
LOAD(prefetch, %o1 + 0x180, #one_read)
- EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
LOAD(prefetch, %o1 + 0x1c0, #one_read)
faligndata %f0, %f2, %f16
- EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
faligndata %f2, %f4, %f18
- EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
faligndata %f4, %f6, %f20
- EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
faligndata %f6, %f8, %f22
- EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
faligndata %f8, %f10, %f24
- EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
faligndata %f10, %f12, %f26
- EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
subcc GLOBAL_SPARE, 0x80, GLOBAL_SPARE
add %o1, 0x40, %o1
@@ -184,26 +190,26 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
.align 64
1:
- EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
faligndata %f12, %f14, %f28
- EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
faligndata %f14, %f0, %f30
- EX_ST(STORE_BLK(%f16, %o0))
- EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+ EX_ST_FP(STORE_BLK(%f16, %o0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
faligndata %f0, %f2, %f16
add %o0, 0x40, %o0
- EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
faligndata %f2, %f4, %f18
- EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
faligndata %f4, %f6, %f20
- EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
subcc %o3, 0x01, %o3
faligndata %f6, %f8, %f22
- EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
faligndata %f8, %f10, %f24
- EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
LOAD(prefetch, %o1 + 0x1c0, #one_read)
faligndata %f10, %f12, %f26
bg,pt %XCC, 1b
@@ -211,29 +217,29 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
/* Finally we copy the last full 64-byte block. */
2:
- EX_LD(LOAD(ldd, %o1 + 0x008, %f2))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
faligndata %f12, %f14, %f28
- EX_LD(LOAD(ldd, %o1 + 0x010, %f4))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
faligndata %f14, %f0, %f30
- EX_ST(STORE_BLK(%f16, %o0))
- EX_LD(LOAD(ldd, %o1 + 0x018, %f6))
+ EX_ST_FP(STORE_BLK(%f16, %o0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
faligndata %f0, %f2, %f16
- EX_LD(LOAD(ldd, %o1 + 0x020, %f8))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
faligndata %f2, %f4, %f18
- EX_LD(LOAD(ldd, %o1 + 0x028, %f10))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
faligndata %f4, %f6, %f20
- EX_LD(LOAD(ldd, %o1 + 0x030, %f12))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
faligndata %f6, %f8, %f22
- EX_LD(LOAD(ldd, %o1 + 0x038, %f14))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
faligndata %f8, %f10, %f24
cmp %g1, 0
be,pt %XCC, 1f
add %o0, 0x40, %o0
- EX_LD(LOAD(ldd, %o1 + 0x040, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
1: faligndata %f10, %f12, %f26
faligndata %f12, %f14, %f28
faligndata %f14, %f0, %f30
- EX_ST(STORE_BLK(%f16, %o0))
+ EX_ST_FP(STORE_BLK(%f16, %o0))
add %o0, 0x40, %o0
add %o1, 0x40, %o1
membar #Sync
@@ -253,20 +259,20 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %o2, %g2, %o2
be,a,pt %XCC, 1f
- EX_LD(LOAD(ldd, %o1 + 0x00, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0))
-1: EX_LD(LOAD(ldd, %o1 + 0x08, %f2))
+1: EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f0, %f2, %f8
- EX_ST(STORE(std, %f8, %o0))
+ EX_ST_FP(STORE(std, %f8, %o0))
be,pn %XCC, 2f
add %o0, 0x8, %o0
- EX_LD(LOAD(ldd, %o1 + 0x08, %f0))
+ EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0))
add %o1, 0x8, %o1
subcc %g2, 0x8, %g2
faligndata %f2, %f0, %f8
- EX_ST(STORE(std, %f8, %o0))
+ EX_ST_FP(STORE(std, %f8, %o0))
bne,pn %XCC, 1b
add %o0, 0x8, %o0
diff --git a/arch/sparc/lib/VISsave.S b/arch/sparc/lib/VISsave.S
index a063d84..62c2647b 100644
--- a/arch/sparc/lib/VISsave.S
+++ b/arch/sparc/lib/VISsave.S
@@ -6,24 +6,23 @@
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
*/
+#include <linux/linkage.h>
+
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/visasm.h>
#include <asm/thread_info.h>
- .text
- .globl VISenter, VISenterhalf
-
/* On entry: %o5=current FPRS value, %g7 is callers address */
/* May clobber %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
/* Nothing special need be done here to handle pre-emption, this
* FPU save/restore mechanism is already preemption safe.
*/
-
+ .text
.align 32
-VISenter:
+ENTRY(VISenter)
ldub [%g6 + TI_FPDEPTH], %g1
brnz,a,pn %g1, 1f
cmp %g1, 1
@@ -79,3 +78,4 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3
.align 32
80: jmpl %g7 + %g0, %g0
nop
+ENDPROC(VISenter)
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index dbabe57..cb841a3 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -113,9 +113,6 @@ static unsigned int get_user_insn(unsigned long tpc)
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
if (pmd_trans_huge(*pmdp)) {
- if (pmd_trans_splitting(*pmdp))
- goto out_irq_enable;
-
pa = pmd_pfn(*pmdp) << PAGE_SHIFT;
pa += tpc & ~HPAGE_MASK;
diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c
index 2e5c4fc..eb3d8e8 100644
--- a/arch/sparc/mm/gup.c
+++ b/arch/sparc/mm/gup.c
@@ -56,8 +56,6 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
put_page(head);
return 0;
}
- if (head != page)
- get_huge_page_tail(page);
pages[*nr] = page;
(*nr)++;
@@ -70,7 +68,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages,
int *nr)
{
- struct page *head, *page, *tail;
+ struct page *head, *page;
int refs;
if (!(pmd_val(pmd) & _PAGE_VALID))
@@ -82,7 +80,6 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
refs = 0;
head = pmd_page(pmd);
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
- tail = page;
do {
VM_BUG_ON(compound_head(page) != head);
pages[*nr] = page;
@@ -103,15 +100,6 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
return 0;
}
- /* Any tail page need their mapcount reference taken before we
- * return.
- */
- while (refs--) {
- if (PageTail(tail))
- get_huge_page_tail(tail);
- tail++;
- }
-
return 1;
}
@@ -126,7 +114,7 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
pmd_t pmd = *pmdp;
next = pmd_addr_end(addr, end);
- if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+ if (pmd_none(pmd))
return 0;
if (unlikely(pmd_large(pmd))) {
if (!gup_huge_pmd(pmdp, pmd, addr, next,
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 131eaf4..4977800 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -146,7 +146,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
if (pud) {
pmd = pmd_alloc(mm, pud, addr);
if (pmd)
- pte = pte_alloc_map(mm, NULL, pmd, addr);
+ pte = pte_alloc_map(mm, pmd, addr);
}
return pte;
}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 4ac88b7..1cfe6aa 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -93,6 +93,8 @@ static unsigned long cpu_pgsz_mask;
static struct linux_prom64_registers pavail[MAX_BANKS];
static int pavail_ents;
+u64 numa_latency[MAX_NUMNODES][MAX_NUMNODES];
+
static int cmp_p64(const void *a, const void *b)
{
const struct linux_prom64_registers *x = a, *y = b;
@@ -1157,6 +1159,48 @@ static struct mdesc_mlgroup * __init find_mlgroup(u64 node)
return NULL;
}
+int __node_distance(int from, int to)
+{
+ if ((from >= MAX_NUMNODES) || (to >= MAX_NUMNODES)) {
+ pr_warn("Returning default NUMA distance value for %d->%d\n",
+ from, to);
+ return (from == to) ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+ }
+ return numa_latency[from][to];
+}
+
+static int find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUMNODES; i++) {
+ struct node_mem_mask *n = &node_masks[i];
+
+ if ((grp->mask == n->mask) && (grp->match == n->val))
+ break;
+ }
+ return i;
+}
+
+static void find_numa_latencies_for_group(struct mdesc_handle *md, u64 grp,
+ int index)
+{
+ u64 arc;
+
+ mdesc_for_each_arc(arc, md, grp, MDESC_ARC_TYPE_FWD) {
+ int tnode;
+ u64 target = mdesc_arc_target(md, arc);
+ struct mdesc_mlgroup *m = find_mlgroup(target);
+
+ if (!m)
+ continue;
+ tnode = find_best_numa_node_for_mlgroup(m);
+ if (tnode == MAX_NUMNODES)
+ continue;
+ numa_latency[index][tnode] = m->latency;
+ }
+}
+
static int __init numa_attach_mlgroup(struct mdesc_handle *md, u64 grp,
int index)
{
@@ -1220,7 +1264,7 @@ static int __init numa_parse_mdesc_group(struct mdesc_handle *md, u64 grp,
static int __init numa_parse_mdesc(void)
{
struct mdesc_handle *md = mdesc_grab();
- int i, err, count;
+ int i, j, err, count;
u64 node;
node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
@@ -1245,6 +1289,23 @@ static int __init numa_parse_mdesc(void)
count++;
}
+ count = 0;
+ mdesc_for_each_node_by_name(md, node, "group") {
+ find_numa_latencies_for_group(md, node, count);
+ count++;
+ }
+
+ /* Normalize numa latency matrix according to ACPI SLIT spec. */
+ for (i = 0; i < MAX_NUMNODES; i++) {
+ u64 self_latency = numa_latency[i][i];
+
+ for (j = 0; j < MAX_NUMNODES; j++) {
+ numa_latency[i][j] =
+ (numa_latency[i][j] * LOCAL_DISTANCE) /
+ self_latency;
+ }
+ }
+
add_node_ranges();
for (i = 0; i < num_node_masks; i++) {
@@ -1301,10 +1362,18 @@ static int __init numa_parse_sun4u(void)
static int __init bootmem_init_numa(void)
{
+ int i, j;
int err = -1;
numadbg("bootmem_init_numa()\n");
+ /* Some sane defaults for numa latency values */
+ for (i = 0; i < MAX_NUMNODES; i++) {
+ for (j = 0; j < MAX_NUMNODES; j++)
+ numa_latency[i][j] = (i == j) ?
+ LOCAL_DISTANCE : REMOTE_DISTANCE;
+ }
+
if (numa_enabled) {
if (tlb_type == hypervisor)
err = numa_parse_mdesc();
@@ -2794,17 +2863,17 @@ void hugetlb_setup(struct pt_regs *regs)
static struct resource code_resource = {
.name = "Kernel code",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource data_resource = {
.name = "Kernel data",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource bss_resource = {
.name = "Kernel bss",
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static inline resource_size_t compute_kern_paddr(void *addr)
@@ -2840,7 +2909,7 @@ static int __init report_memory(void)
res->name = "System RAM";
res->start = pavail[i].phys_addr;
res->end = pavail[i].phys_addr + pavail[i].reg_size - 1;
- res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM;
if (insert_resource(&iomem_resource, res) < 0) {
pr_warn("Resource insertion failed.\n");
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
index f8b9f71..3e6e05a 100644
--- a/arch/sparc/net/bpf_jit_comp.c
+++ b/arch/sparc/net/bpf_jit_comp.c
@@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp)
}
emit_reg_move(O7, r_saved_O7);
- switch (filter[0].code) {
- case BPF_RET | BPF_K:
- 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:
- /* The first instruction sets the A register (or is
- * a "RET 'constant'")
- */
- break;
- default:
- /* Make sure we dont leak kernel information to the
- * user.
- */
+ /* Make sure we dont leak kernel information to the user. */
+ if (bpf_needs_clear_a(&filter[0]))
emit_clear(r_A); /* A = 0 */
- }
for (i = 0; i < flen; i++) {
unsigned int K = filter[i].k;
@@ -812,7 +799,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
if (image) {
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
- fp->jited = true;
+ fp->jited = 1;
}
out:
kfree(addrs);
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 106c21b..8171930 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -5,7 +5,6 @@ config TILE
def_bool y
select HAVE_PERF_EVENTS
select USE_PMC if PERF_EVENTS
- select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT
@@ -19,6 +18,7 @@ config TILE
select VIRT_TO_BUS
select SYS_HYPERVISOR
select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
@@ -116,9 +116,6 @@ config ARCH_DISCONTIGMEM_DEFAULT
config TRACE_IRQFLAGS_SUPPORT
def_bool y
-config STRICT_DEVMEM
- def_bool y
-
# SMP is required for Tilera Linux.
config SMP
def_bool y
@@ -143,6 +140,7 @@ config TILEGX
select HAVE_KRETPROBES
select HAVE_ARCH_KGDB
select ARCH_SUPPORTS_ATOMIC_RMW
+ select HAVE_ARCH_JUMP_LABEL
config TILEPRO
def_bool !TILEGX
@@ -176,8 +174,6 @@ config NR_CPUS
smaller kernel memory footprint results from using a smaller
value on chips with fewer tiles.
-if TILEGX
-
choice
prompt "Kernel page size"
default PAGE_SIZE_64KB
@@ -188,8 +184,11 @@ choice
connections, etc., it may be better to select 16KB, which uses
memory more efficiently at some cost in TLB performance.
- Note that this option is TILE-Gx specific; currently
- TILEPro page size is set by rebuilding the hypervisor.
+ Note that for TILEPro, you must also rebuild the hypervisor
+ with a matching page size.
+
+config PAGE_SIZE_4KB
+ bool "4KB" if TILEPRO
config PAGE_SIZE_16KB
bool "16KB"
@@ -199,8 +198,6 @@ config PAGE_SIZE_64KB
endchoice
-endif
-
source "kernel/Kconfig.hz"
config KEXEC
@@ -458,8 +455,6 @@ config TILE_PCI_IO
source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
-
config TILE_USB
tristate "Tilera USB host adapter support"
default y
@@ -470,8 +465,6 @@ config TILE_USB
Provides USB host adapter support for the built-in EHCI and OHCI
interfaces on TILE-Gx chips.
-source "drivers/pci/hotplug/Kconfig"
-
endmenu
menu "Executable file formats"
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index 37dc936..3f3dfb8 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -222,7 +222,7 @@ CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_NET_DSA_MV88E6060=y
CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6123=y
CONFIG_SKY2=y
CONFIG_PTP_1588_CLOCK_TILEGX=y
# CONFIG_WLAN is not set
@@ -374,7 +374,6 @@ CONFIG_DEBUG_CREDENTIALS=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_ASYNC_RAID6_TEST=m
CONFIG_KGDB=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig
index 76a2781..ef9e27e 100644
--- a/arch/tile/configs/tilepro_defconfig
+++ b/arch/tile/configs/tilepro_defconfig
@@ -341,7 +341,7 @@ CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_NET_DSA_MV88E6060=y
CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_DSA_MV88E6123=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_E1000E=y
# CONFIG_WLAN is not set
@@ -486,7 +486,6 @@ CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_ASYNC_RAID6_TEST=m
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h
index 7097984..9fc0107 100644
--- a/arch/tile/include/asm/atomic.h
+++ b/arch/tile/include/asm/atomic.h
@@ -34,7 +34,7 @@
*/
static inline int atomic_read(const atomic_t *v)
{
- return ACCESS_ONCE(v->counter);
+ return READ_ONCE(v->counter);
}
/**
diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
index 096a56d..51cabc2 100644
--- a/arch/tile/include/asm/atomic_64.h
+++ b/arch/tile/include/asm/atomic_64.h
@@ -24,7 +24,7 @@
/* First, the 32-bit atomic ops that are "real" on our 64-bit platform. */
-#define atomic_set(v, i) ((v)->counter = (i))
+#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
/*
* The smp_mb() operations throughout are to support the fact that
@@ -82,8 +82,8 @@ static inline void atomic_xor(int i, atomic_t *v)
#define ATOMIC64_INIT(i) { (i) }
-#define atomic64_read(v) ((v)->counter)
-#define atomic64_set(v, i) ((v)->counter = (i))
+#define atomic64_read(v) READ_ONCE((v)->counter)
+#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i))
static inline void atomic64_add(long i, atomic64_t *v)
{
diff --git a/arch/tile/include/asm/barrier.h b/arch/tile/include/asm/barrier.h
index 96a42ae..d552228 100644
--- a/arch/tile/include/asm/barrier.h
+++ b/arch/tile/include/asm/barrier.h
@@ -79,11 +79,12 @@ mb_incoherent(void)
* But after the word is updated, the routine issues an "mf" before returning,
* and since it's a function call, we don't even need a compiler barrier.
*/
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() do { } while (0)
+#define __smp_mb__before_atomic() __smp_mb()
+#define __smp_mb__after_atomic() do { } while (0)
+#define smp_mb__after_atomic() __smp_mb__after_atomic()
#else /* 64 bit */
-#define smp_mb__before_atomic() smp_mb()
-#define smp_mb__after_atomic() smp_mb()
+#define __smp_mb__before_atomic() __smp_mb()
+#define __smp_mb__after_atomic() __smp_mb()
#endif
#include <asm-generic/barrier.h>
diff --git a/arch/tile/include/asm/cmpxchg.h b/arch/tile/include/asm/cmpxchg.h
index 0ccda3c..25d5899 100644
--- a/arch/tile/include/asm/cmpxchg.h
+++ b/arch/tile/include/asm/cmpxchg.h
@@ -127,8 +127,6 @@ long long _atomic64_cmpxchg(long long *v, long long o, long long n);
#endif
-#define tas(ptr) xchg((ptr), 1)
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_TILE_CMPXCHG_H */
diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h
index 96ac6cc..01ceb4a 100644
--- a/arch/tile/include/asm/dma-mapping.h
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -73,37 +73,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
}
#define HAVE_ARCH_DMA_SET_MASK 1
-
-#include <asm-generic/dma-mapping-common.h>
-
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
- struct dma_map_ops *dma_ops = get_dma_ops(dev);
-
- /*
- * For PCI devices with 64-bit DMA addressing capability, promote
- * the dma_ops to hybrid, with the consistent memory DMA space limited
- * to 32-bit. For 32-bit capable devices, limit the streaming DMA
- * address range to max_direct_dma_addr.
- */
- if (dma_ops == gx_pci_dma_map_ops ||
- dma_ops == gx_hybrid_pci_dma_map_ops ||
- dma_ops == gx_legacy_pci_dma_map_ops) {
- if (mask == DMA_BIT_MASK(64) &&
- dma_ops == gx_legacy_pci_dma_map_ops)
- set_dma_ops(dev, gx_hybrid_pci_dma_map_ops);
- else if (mask > dev->archdata.max_direct_dma_addr)
- mask = dev->archdata.max_direct_dma_addr;
- }
-
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
-}
+int dma_set_mask(struct device *dev, u64 mask);
/*
* dma_alloc_noncoherent() is #defined to return coherent memory,
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h
index fc8429a..979579b 100644
--- a/arch/tile/include/asm/highmem.h
+++ b/arch/tile/include/asm/highmem.h
@@ -63,7 +63,6 @@ void *kmap_atomic(struct page *page);
void __kunmap_atomic(void *kvaddr);
void *kmap_atomic_pfn(unsigned long pfn);
void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
-struct page *kmap_atomic_to_page(void *ptr);
void *kmap_atomic_prot(struct page *page, pgprot_t prot);
void kmap_atomic_fix_kpte(struct page *page, int finished);
diff --git a/arch/tile/include/asm/insn.h b/arch/tile/include/asm/insn.h
new file mode 100644
index 0000000..f78ba5c
--- /dev/null
+++ b/arch/tile/include/asm/insn.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+#ifndef __ASM_TILE_INSN_H
+#define __ASM_TILE_INSN_H
+
+#include <arch/opcode.h>
+
+static inline tilegx_bundle_bits NOP(void)
+{
+ return create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) |
+ create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) |
+ create_Opcode_X0(RRR_0_OPCODE_X0) |
+ create_UnaryOpcodeExtension_X1(NOP_UNARY_OPCODE_X1) |
+ create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) |
+ create_Opcode_X1(RRR_0_OPCODE_X1);
+}
+
+static inline tilegx_bundle_bits tilegx_gen_branch(unsigned long pc,
+ unsigned long addr,
+ bool link)
+{
+ tilegx_bundle_bits opcode_x0, opcode_x1;
+ long pcrel_by_instr = (addr - pc) >> TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES;
+
+ if (link) {
+ /* opcode: jal addr */
+ opcode_x1 =
+ create_Opcode_X1(JUMP_OPCODE_X1) |
+ create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) |
+ create_JumpOff_X1(pcrel_by_instr);
+ } else {
+ /* opcode: j addr */
+ opcode_x1 =
+ create_Opcode_X1(JUMP_OPCODE_X1) |
+ create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) |
+ create_JumpOff_X1(pcrel_by_instr);
+ }
+
+ /* opcode: fnop */
+ opcode_x0 =
+ create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) |
+ create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) |
+ create_Opcode_X0(RRR_0_OPCODE_X0);
+
+ return opcode_x1 | opcode_x0;
+}
+
+#endif /* __ASM_TILE_INSN_H */
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index 322b5fe..30f4a21 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -161,14 +161,14 @@ extern void _tile_writew(u16 val, unsigned long addr);
extern void _tile_writel(u32 val, unsigned long addr);
extern void _tile_writeq(u64 val, unsigned long addr);
-#define __raw_readb(addr) _tile_readb((unsigned long)addr)
-#define __raw_readw(addr) _tile_readw((unsigned long)addr)
-#define __raw_readl(addr) _tile_readl((unsigned long)addr)
-#define __raw_readq(addr) _tile_readq((unsigned long)addr)
-#define __raw_writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
-#define __raw_writew(val, addr) _tile_writew(val, (unsigned long)addr)
-#define __raw_writel(val, addr) _tile_writel(val, (unsigned long)addr)
-#define __raw_writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
+#define __raw_readb(addr) _tile_readb((unsigned long)(addr))
+#define __raw_readw(addr) _tile_readw((unsigned long)(addr))
+#define __raw_readl(addr) _tile_readl((unsigned long)(addr))
+#define __raw_readq(addr) _tile_readq((unsigned long)(addr))
+#define __raw_writeb(val, addr) _tile_writeb(val, (unsigned long)(addr))
+#define __raw_writew(val, addr) _tile_writew(val, (unsigned long)(addr))
+#define __raw_writel(val, addr) _tile_writel(val, (unsigned long)(addr))
+#define __raw_writeq(val, addr) _tile_writeq(val, (unsigned long)(addr))
#else /* CONFIG_PCI */
diff --git a/arch/tile/include/asm/jump_label.h b/arch/tile/include/asm/jump_label.h
new file mode 100644
index 0000000..cde7573
--- /dev/null
+++ b/arch/tile/include/asm/jump_label.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_JUMP_LABEL_H
+#define _ASM_TILE_JUMP_LABEL_H
+
+#include <arch/opcode.h>
+
+#define JUMP_LABEL_NOP_SIZE TILE_BUNDLE_SIZE_IN_BYTES
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+ bool branch)
+{
+ asm_volatile_goto("1:\n\t"
+ "nop" "\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".quad 1b, %l[l_yes], %0 + %1 \n\t"
+ ".popsection\n\t"
+ : : "i" (key), "i" (branch) : : l_yes);
+ return false;
+l_yes:
+ return true;
+}
+
+static __always_inline bool arch_static_branch_jump(struct static_key *key,
+ bool branch)
+{
+ asm_volatile_goto("1:\n\t"
+ "j %l[l_yes]" "\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".quad 1b, %l[l_yes], %0 + %1 \n\t"
+ ".popsection\n\t"
+ : : "i" (key), "i" (branch) : : l_yes);
+ return false;
+l_yes:
+ return true;
+}
+
+typedef u64 jump_label_t;
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* _ASM_TILE_JUMP_LABEL_H */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index a213a8d..498a5f7 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -20,15 +20,17 @@
#include <arch/chip.h>
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
-#if defined(CONFIG_PAGE_SIZE_16KB)
+#if defined(CONFIG_PAGE_SIZE_4KB) /* tilepro only */
+#define PAGE_SHIFT 12
+#define CTX_PAGE_FLAG HV_CTX_PG_SM_4K
+#elif defined(CONFIG_PAGE_SIZE_16KB)
#define PAGE_SHIFT 14
#define CTX_PAGE_FLAG HV_CTX_PG_SM_16K
#elif defined(CONFIG_PAGE_SIZE_64KB)
#define PAGE_SHIFT 16
#define CTX_PAGE_FLAG HV_CTX_PG_SM_64K
#else
-#define PAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_SMALL
-#define CTX_PAGE_FLAG 0
+#error Page size not specified in Kconfig
#endif
#define HPAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_LARGE
@@ -319,6 +321,16 @@ static inline int pfn_valid(unsigned long pfn)
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
+/*
+ * The kernel text is mapped at MEM_SV_START as read-only. To allow
+ * modifying kernel text, it is also mapped at PAGE_OFFSET as read-write.
+ * This macro converts a kernel address to its writable kernel text mapping,
+ * which is used to modify the text code on a running kernel by kgdb,
+ * ftrace, kprobe, jump label, etc.
+ */
+#define ktext_writable_addr(kaddr) \
+ ((unsigned long)(kaddr) - MEM_SV_START + PAGE_OFFSET)
+
struct mm_struct;
extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
extern pte_t *virt_to_kpte(unsigned long kaddr);
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index dfedd7a..fe3de50 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -226,7 +226,4 @@ static inline int pcibios_assign_all_busses(void)
/* Use any cpu for PCI. */
#define cpumask_of_pcibus(bus) cpu_online_mask
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
#endif /* _ASM_TILE_PCI_H */
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
index 2b05ccb..96cecf5 100644
--- a/arch/tile/include/asm/pgtable.h
+++ b/arch/tile/include/asm/pgtable.h
@@ -489,16 +489,6 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define has_transparent_hugepage() 1
#define pmd_trans_huge pmd_huge_page
-
-static inline pmd_t pmd_mksplitting(pmd_t pmd)
-{
- return pte_pmd(hv_pte_set_client2(pmd_pte(pmd)));
-}
-
-static inline int pmd_trans_splitting(pmd_t pmd)
-{
- return hv_pte_get_client2(pmd_pte(pmd));
-}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
/*
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index 139dfde..0684e88 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -212,7 +212,7 @@ static inline void release_thread(struct task_struct *dead_task)
/* Nothing for now */
}
-extern int do_work_pending(struct pt_regs *regs, u32 flags);
+extern void prepare_exit_to_usermode(struct pt_regs *regs, u32 flags);
/*
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
index dc1fb28..4b7cef9 100644
--- a/arch/tile/include/asm/thread_info.h
+++ b/arch/tile/include/asm/thread_info.h
@@ -140,10 +140,14 @@ extern void _cpu_idle(void);
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_NOHZ (1<<TIF_NOHZ)
+/* Work to do as we loop to exit to user space. */
+#define _TIF_WORK_MASK \
+ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+ _TIF_ASYNC_TLB | _TIF_NOTIFY_RESUME)
+
/* Work to do on any return to user space. */
#define _TIF_ALLWORK_MASK \
- (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_SINGLESTEP | \
- _TIF_ASYNC_TLB | _TIF_NOTIFY_RESUME | _TIF_NOHZ)
+ (_TIF_WORK_MASK | _TIF_SINGLESTEP | _TIF_NOHZ)
/* Work to do at syscall entry. */
#define _TIF_SYSCALL_ENTRY_WORK \
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h
index 76b0d0e..b11d5fc 100644
--- a/arch/tile/include/asm/topology.h
+++ b/arch/tile/include/asm/topology.h
@@ -44,9 +44,6 @@ static inline const struct cpumask *cpumask_of_node(int node)
/* For now, use numa node -1 for global allocation. */
#define pcibus_to_node(bus) ((void)(bus), -1)
-/* By definition, we create nodes based on online memory. */
-#define node_has_online_mem(nid) 1
-
#endif /* CONFIG_NUMA */
#include <asm-generic/topology.h>
diff --git a/arch/tile/include/uapi/asm/mman.h b/arch/tile/include/uapi/asm/mman.h
index 81b8fc3..63ee13f 100644
--- a/arch/tile/include/uapi/asm/mman.h
+++ b/arch/tile/include/uapi/asm/mman.h
@@ -36,6 +36,7 @@
*/
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
+#define MCL_ONFAULT 4 /* lock all pages that are faulted in */
#endif /* _ASM_TILE_MMAN_H */
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
index 21f77bf..09936d0 100644
--- a/arch/tile/kernel/Makefile
+++ b/arch/tile/kernel/Makefile
@@ -32,5 +32,6 @@ obj-$(CONFIG_TILE_HVGLUE_TRACE) += hvglue_trace.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount_64.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KGDB) += kgdb.o
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-y += vdso/
diff --git a/arch/tile/kernel/ftrace.c b/arch/tile/kernel/ftrace.c
index 0c09961..4a57208 100644
--- a/arch/tile/kernel/ftrace.c
+++ b/arch/tile/kernel/ftrace.c
@@ -20,21 +20,12 @@
#include <asm/cacheflush.h>
#include <asm/ftrace.h>
#include <asm/sections.h>
+#include <asm/insn.h>
#include <arch/opcode.h>
#ifdef CONFIG_DYNAMIC_FTRACE
-static inline tilegx_bundle_bits NOP(void)
-{
- return create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) |
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) |
- create_Opcode_X0(RRR_0_OPCODE_X0) |
- create_UnaryOpcodeExtension_X1(NOP_UNARY_OPCODE_X1) |
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) |
- create_Opcode_X1(RRR_0_OPCODE_X1);
-}
-
static int machine_stopped __read_mostly;
int ftrace_arch_code_modify_prepare(void)
@@ -117,7 +108,7 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
return -EINVAL;
/* Operate on writable kernel text mapping. */
- pc_wr = pc - MEM_SV_START + PAGE_OFFSET;
+ pc_wr = ktext_writable_addr(pc);
if (probe_kernel_write((void *)pc_wr, &new, MCOUNT_INSN_SIZE))
return -EPERM;
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index fbbe2ea..9ff75e3 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -572,7 +572,7 @@ intvec_\vecname:
}
wh64 r52
-#ifdef CONFIG_TRACE_IRQFLAGS
+#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
.ifnc \function,handle_nmi
/*
* We finally have enough state set up to notify the irq
@@ -588,6 +588,9 @@ intvec_\vecname:
{ move r32, r2; move r33, r3 }
.endif
TRACE_IRQS_OFF
+#ifdef CONFIG_CONTEXT_TRACKING
+ jal context_tracking_user_exit
+#endif
.ifnc \function,handle_syscall
{ move r0, r30; move r1, r31 }
{ move r2, r32; move r3, r33 }
@@ -846,18 +849,6 @@ STD_ENTRY(interrupt_return)
FEEDBACK_REENTER(interrupt_return)
/*
- * Use r33 to hold whether we have already loaded the callee-saves
- * into ptregs. We don't want to do it twice in this loop, since
- * then we'd clobber whatever changes are made by ptrace, etc.
- * Get base of stack in r32.
- */
- {
- GET_THREAD_INFO(r32)
- movei r33, 0
- }
-
-.Lretry_work_pending:
- /*
* Disable interrupts so as to make sure we don't
* miss an interrupt that sets any of the thread flags (like
* need_resched or sigpending) between sampling and the iret.
@@ -867,33 +858,27 @@ STD_ENTRY(interrupt_return)
IRQ_DISABLE(r20, r21)
TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
-
- /* Check to see if there is any work to do before returning to user. */
+ /*
+ * See if there are any work items (including single-shot items)
+ * to do. If so, save the callee-save registers to pt_regs
+ * and then dispatch to C code.
+ */
+ GET_THREAD_INFO(r21)
{
- addi r29, r32, THREAD_INFO_FLAGS_OFFSET
- moveli r1, lo16(_TIF_ALLWORK_MASK)
+ addi r22, r21, THREAD_INFO_FLAGS_OFFSET
+ moveli r20, lo16(_TIF_ALLWORK_MASK)
}
{
- lw r29, r29
- auli r1, r1, ha16(_TIF_ALLWORK_MASK)
+ lw r22, r22
+ auli r20, r20, ha16(_TIF_ALLWORK_MASK)
}
- and r1, r29, r1
- bzt r1, .Lrestore_all
-
- /*
- * Make sure we have all the registers saved for signal
- * handling, notify-resume, or single-step. Call out to C
- * code to figure out exactly what we need to do for each flag bit,
- * then if necessary, reload the flags and recheck.
- */
+ and r1, r22, r20
{
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
- bnz r33, 1f
+ bzt r1, .Lrestore_all
}
push_extra_callee_saves r0
- movei r33, 1
-1: jal do_work_pending
- bnz r0, .Lretry_work_pending
+ jal prepare_exit_to_usermode
/*
* In the NMI case we
@@ -1327,7 +1312,7 @@ STD_ENTRY(ret_from_kernel_thread)
FEEDBACK_REENTER(ret_from_kernel_thread)
{
movei r30, 0 /* not an NMI */
- j .Lresume_userspace /* jump into middle of interrupt_return */
+ j interrupt_return
}
STD_ENDPROC(ret_from_kernel_thread)
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 58964d2..3b51bdf 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -658,7 +658,7 @@ intvec_\vecname:
*/
mfspr r32, SPR_EX_CONTEXT_K_1
{
- IS_KERNEL_EX1(r22, r22)
+ IS_KERNEL_EX1(r32, r32)
PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
}
beqzt r32, 1f /* zero if from user space */
@@ -753,7 +753,7 @@ intvec_\vecname:
}
wh64 r52
-#ifdef CONFIG_TRACE_IRQFLAGS
+#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
.ifnc \function,handle_nmi
/*
* We finally have enough state set up to notify the irq
@@ -769,6 +769,9 @@ intvec_\vecname:
{ move r32, r2; move r33, r3 }
.endif
TRACE_IRQS_OFF
+#ifdef CONFIG_CONTEXT_TRACKING
+ jal context_tracking_user_exit
+#endif
.ifnc \function,handle_syscall
{ move r0, r30; move r1, r31 }
{ move r2, r32; move r3, r33 }
@@ -879,20 +882,6 @@ STD_ENTRY(interrupt_return)
FEEDBACK_REENTER(interrupt_return)
/*
- * Use r33 to hold whether we have already loaded the callee-saves
- * into ptregs. We don't want to do it twice in this loop, since
- * then we'd clobber whatever changes are made by ptrace, etc.
- */
- {
- movei r33, 0
- move r32, sp
- }
-
- /* Get base of stack in r32. */
- EXTRACT_THREAD_INFO(r32)
-
-.Lretry_work_pending:
- /*
* Disable interrupts so as to make sure we don't
* miss an interrupt that sets any of the thread flags (like
* need_resched or sigpending) between sampling and the iret.
@@ -902,33 +891,28 @@ STD_ENTRY(interrupt_return)
IRQ_DISABLE(r20, r21)
TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
-
- /* Check to see if there is any work to do before returning to user. */
+ /*
+ * See if there are any work items (including single-shot items)
+ * to do. If so, save the callee-save registers to pt_regs
+ * and then dispatch to C code.
+ */
+ move r21, sp
+ EXTRACT_THREAD_INFO(r21)
{
- addi r29, r32, THREAD_INFO_FLAGS_OFFSET
- moveli r1, hw1_last(_TIF_ALLWORK_MASK)
+ addi r22, r21, THREAD_INFO_FLAGS_OFFSET
+ moveli r20, hw1_last(_TIF_ALLWORK_MASK)
}
{
- ld r29, r29
- shl16insli r1, r1, hw0(_TIF_ALLWORK_MASK)
+ ld r22, r22
+ shl16insli r20, r20, hw0(_TIF_ALLWORK_MASK)
}
- and r1, r29, r1
- beqzt r1, .Lrestore_all
-
- /*
- * Make sure we have all the registers saved for signal
- * handling or notify-resume. Call out to C code to figure out
- * exactly what we need to do for each flag bit, then if
- * necessary, reload the flags and recheck.
- */
+ and r1, r22, r20
{
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
- bnez r33, 1f
+ beqzt r1, .Lrestore_all
}
push_extra_callee_saves r0
- movei r33, 1
-1: jal do_work_pending
- bnez r0, .Lretry_work_pending
+ jal prepare_exit_to_usermode
/*
* In the NMI case we
@@ -1411,7 +1395,7 @@ STD_ENTRY(ret_from_kernel_thread)
FEEDBACK_REENTER(ret_from_kernel_thread)
{
movei r30, 0 /* not an NMI */
- j .Lresume_userspace /* jump into middle of interrupt_return */
+ j interrupt_return
}
STD_ENDPROC(ret_from_kernel_thread)
diff --git a/arch/tile/kernel/jump_label.c b/arch/tile/kernel/jump_label.c
new file mode 100644
index 0000000..07802d5
--- /dev/null
+++ b/arch/tile/kernel/jump_label.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * jump label TILE-Gx support
+ */
+
+#include <linux/jump_label.h>
+#include <linux/memory.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/insn.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+static void __jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ tilegx_bundle_bits opcode;
+ /* Operate on writable kernel text mapping. */
+ unsigned long pc_wr = ktext_writable_addr(e->code);
+
+ if (type == JUMP_LABEL_JMP)
+ opcode = tilegx_gen_branch(e->code, e->target, false);
+ else
+ opcode = NOP();
+
+ *(tilegx_bundle_bits *)pc_wr = opcode;
+ /* Make sure that above mem writes were issued towards the memory. */
+ smp_wmb();
+}
+
+void arch_jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+
+ __jump_label_transform(e, type);
+ flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits));
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+__init_or_module void arch_jump_label_transform_static(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ __jump_label_transform(e, type);
+}
+
+#endif /* HAVE_JUMP_LABEL */
diff --git a/arch/tile/kernel/kgdb.c b/arch/tile/kernel/kgdb.c
index ff5335a..a506c2c 100644
--- a/arch/tile/kernel/kgdb.c
+++ b/arch/tile/kernel/kgdb.c
@@ -164,7 +164,7 @@ static unsigned long writable_address(unsigned long addr)
unsigned long ret = 0;
if (core_kernel_text(addr))
- ret = addr - MEM_SV_START + PAGE_OFFSET;
+ ret = ktext_writable_addr(addr);
else if (is_module_text_address(addr))
ret = addr;
else
diff --git a/arch/tile/kernel/kprobes.c b/arch/tile/kernel/kprobes.c
index f8a45c5..c68694b 100644
--- a/arch/tile/kernel/kprobes.c
+++ b/arch/tile/kernel/kprobes.c
@@ -116,7 +116,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
unsigned long addr_wr;
/* Operate on writable kernel text mapping. */
- addr_wr = (unsigned long)p->addr - MEM_SV_START + PAGE_OFFSET;
+ addr_wr = ktext_writable_addr(p->addr);
if (probe_kernel_write((void *)addr_wr, &breakpoint_insn,
sizeof(breakpoint_insn)))
@@ -131,7 +131,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *kp)
unsigned long addr_wr;
/* Operate on writable kernel text mapping. */
- addr_wr = (unsigned long)kp->addr - MEM_SV_START + PAGE_OFFSET;
+ addr_wr = ktext_writable_addr(kp->addr);
if (probe_kernel_write((void *)addr_wr, &kp->opcode,
sizeof(kp->opcode)))
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index 09b5870..b6bc054 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -583,6 +583,35 @@ struct dma_map_ops *gx_hybrid_pci_dma_map_ops;
EXPORT_SYMBOL(gx_legacy_pci_dma_map_ops);
EXPORT_SYMBOL(gx_hybrid_pci_dma_map_ops);
+int dma_set_mask(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+ /*
+ * For PCI devices with 64-bit DMA addressing capability, promote
+ * the dma_ops to hybrid, with the consistent memory DMA space limited
+ * to 32-bit. For 32-bit capable devices, limit the streaming DMA
+ * address range to max_direct_dma_addr.
+ */
+ if (dma_ops == gx_pci_dma_map_ops ||
+ dma_ops == gx_hybrid_pci_dma_map_ops ||
+ dma_ops == gx_legacy_pci_dma_map_ops) {
+ if (mask == DMA_BIT_MASK(64) &&
+ dma_ops == gx_legacy_pci_dma_map_ops)
+ set_dma_ops(dev, gx_hybrid_pci_dma_map_ops);
+ else if (mask > dev->archdata.max_direct_dma_addr)
+ mask = dev->archdata.max_direct_dma_addr;
+ }
+
+ if (!dev->dma_mask || !dma_supported(dev, mask))
+ return -EIO;
+
+ *dev->dma_mask = mask;
+
+ return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
#ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
int dma_set_coherent_mask(struct device *dev, u64 mask)
{
diff --git a/arch/tile/kernel/perf_event.c b/arch/tile/kernel/perf_event.c
index bb509ce..8767060 100644
--- a/arch/tile/kernel/perf_event.c
+++ b/arch/tile/kernel/perf_event.c
@@ -21,7 +21,7 @@
* Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
* Copyright (C) 2009 Jaswinder Singh Rajput
* Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
* Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
* Copyright (C) 2009 Google, Inc., Stephane Eranian
*/
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 7d57693..b5f30d3 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -462,54 +462,57 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
/*
* This routine is called on return from interrupt if any of the
- * TIF_WORK_MASK flags are set in thread_info->flags. It is
- * entered with interrupts disabled so we don't miss an event
- * that modified the thread_info flags. If any flag is set, we
- * handle it and return, and the calling assembly code will
- * re-disable interrupts, reload the thread flags, and call back
- * if more flags need to be handled.
- *
- * We return whether we need to check the thread_info flags again
- * or not. Note that we don't clear TIF_SINGLESTEP here, so it's
- * important that it be tested last, and then claim that we don't
- * need to recheck the flags.
+ * TIF_ALLWORK_MASK flags are set in thread_info->flags. It is
+ * entered with interrupts disabled so we don't miss an event that
+ * modified the thread_info flags. We loop until all the tested flags
+ * are clear. Note that the function is called on certain conditions
+ * that are not listed in the loop condition here (e.g. SINGLESTEP)
+ * which guarantees we will do those things once, and redo them if any
+ * of the other work items is re-done, but won't continue looping if
+ * all the other work is done.
*/
-int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
+void prepare_exit_to_usermode(struct pt_regs *regs, u32 thread_info_flags)
{
- /* If we enter in kernel mode, do nothing and exit the caller loop. */
- if (!user_mode(regs))
- return 0;
+ if (WARN_ON(!user_mode(regs)))
+ return;
- user_exit();
+ do {
+ local_irq_enable();
- /* Enable interrupts; they are disabled again on return to caller. */
- local_irq_enable();
+ if (thread_info_flags & _TIF_NEED_RESCHED)
+ schedule();
- if (thread_info_flags & _TIF_NEED_RESCHED) {
- schedule();
- return 1;
- }
#if CHIP_HAS_TILE_DMA()
- if (thread_info_flags & _TIF_ASYNC_TLB) {
- do_async_page_fault(regs);
- return 1;
- }
+ if (thread_info_flags & _TIF_ASYNC_TLB)
+ do_async_page_fault(regs);
#endif
- if (thread_info_flags & _TIF_SIGPENDING) {
- do_signal(regs);
- return 1;
- }
- if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
- return 1;
- }
- if (thread_info_flags & _TIF_SINGLESTEP)
+
+ if (thread_info_flags & _TIF_SIGPENDING)
+ do_signal(regs);
+
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+
+ local_irq_disable();
+ thread_info_flags = READ_ONCE(current_thread_info()->flags);
+
+ } while (thread_info_flags & _TIF_WORK_MASK);
+
+ if (thread_info_flags & _TIF_SINGLESTEP) {
single_step_once(regs);
+#ifndef __tilegx__
+ /*
+ * FIXME: on tilepro, since we enable interrupts in
+ * this routine, it's possible that we miss a signal
+ * or other asynchronous event.
+ */
+ local_irq_disable();
+#endif
+ }
user_enter();
-
- return 0;
}
unsigned long get_wchan(struct task_struct *p)
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index bdc126f..54e7b72 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -255,13 +255,6 @@ int do_syscall_trace_enter(struct pt_regs *regs)
{
u32 work = ACCESS_ONCE(current_thread_info()->flags);
- /*
- * If TIF_NOHZ is set, we are required to call user_exit() before
- * doing anything that could touch RCU.
- */
- if (work & _TIF_NOHZ)
- user_exit();
-
if (secure_computing() == -1)
return -1;
@@ -281,12 +274,6 @@ void do_syscall_trace_exit(struct pt_regs *regs)
long errno;
/*
- * We may come here right after calling schedule_user()
- * in which case we can be in RCU user mode.
- */
- user_exit();
-
- /*
* The standard tile calling convention returns the value (or negative
* errno) in r0, and zero (or positive errno) in r1.
* It saves a couple of cycles on the hot path to do this work in
@@ -322,7 +309,5 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs)
/* Handle synthetic interrupt delivered only by the simulator. */
void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
{
- enum ctx_state prev_state = exception_enter();
send_sigtrap(current, regs);
- exception_exit(prev_state);
}
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index 6b755d1..a992238 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -882,7 +882,7 @@ static int __init node_neighbors(int node, int cpu,
static void __init setup_numa_mapping(void)
{
- int distance[MAX_NUMNODES][NR_CPUS];
+ u8 distance[MAX_NUMNODES][NR_CPUS];
HV_Coord coord;
int cpu, node, cpus, i, x, y;
int num_nodes = num_online_nodes();
@@ -1632,14 +1632,14 @@ static struct resource data_resource = {
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource code_resource = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
/*
@@ -1673,10 +1673,15 @@ insert_ram_resource(u64 start_pfn, u64 end_pfn, bool reserved)
kzalloc(sizeof(struct resource), GFP_ATOMIC);
if (!res)
return NULL;
- res->name = reserved ? "Reserved" : "System RAM";
res->start = start_pfn << PAGE_SHIFT;
res->end = (end_pfn << PAGE_SHIFT) - 1;
res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ if (reserved) {
+ res->name = "Reserved";
+ } else {
+ res->name = "System RAM";
+ res->flags |= IORESOURCE_SYSRAM;
+ }
if (insert_resource(&iomem_resource, res)) {
kfree(res);
return NULL;
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 53f7b9d..8629730 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -23,7 +23,6 @@
#include <linux/types.h>
#include <linux/err.h>
#include <linux/prctl.h>
-#include <linux/context_tracking.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
@@ -739,7 +738,6 @@ static DEFINE_PER_CPU(unsigned long, ss_saved_pc);
void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
{
- enum ctx_state prev_state = exception_enter();
unsigned long *ss_pc = this_cpu_ptr(&ss_saved_pc);
struct thread_info *info = (void *)current_thread_info();
int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
@@ -756,7 +754,6 @@ void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
__insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
send_sigtrap(current, regs);
}
- exception_exit(prev_state);
}
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c
index 20d52a9..6c0abaa 100644
--- a/arch/tile/kernel/smpboot.c
+++ b/arch/tile/kernel/smpboot.c
@@ -208,7 +208,7 @@ void online_secondary(void)
/* Set up tile-timer clock-event device on this cpu */
setup_tile_timer();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
index 402b9c8..22bbbd3 100644
--- a/arch/tile/kernel/stack.c
+++ b/arch/tile/kernel/stack.c
@@ -78,8 +78,7 @@ static bool read_memory_func(void *result, unsigned long address,
/* Return a pt_regs pointer for a valid fault handler frame */
static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
{
- const char *fault = NULL; /* happy compiler */
- char fault_buf[64];
+ char fault[64];
unsigned long sp = kbt->it.sp;
struct pt_regs *p;
@@ -90,14 +89,14 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
return NULL;
p = (struct pt_regs *)(sp + C_ABI_SAVE_AREA_SIZE);
- if (p->faultnum == INT_SWINT_1 || p->faultnum == INT_SWINT_1_SIGRETURN)
- fault = "syscall";
- else {
- if (kbt->verbose) { /* else we aren't going to use it */
- snprintf(fault_buf, sizeof(fault_buf),
+ if (kbt->verbose) { /* else we aren't going to use it */
+ if (p->faultnum == INT_SWINT_1 ||
+ p->faultnum == INT_SWINT_1_SIGRETURN)
+ snprintf(fault, sizeof(fault),
+ "syscall %ld", p->regs[TREG_SYSCALL_NR]);
+ else
+ snprintf(fault, sizeof(fault),
"interrupt %ld", p->faultnum);
- fault = fault_buf;
- }
}
if (EX1_PL(p->ex1) == KERNEL_PL &&
__kernel_text_address(p->pc) &&
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 0011a9f..4d9651c 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -20,7 +20,6 @@
#include <linux/reboot.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
-#include <linux/context_tracking.h>
#include <asm/stack.h>
#include <asm/traps.h>
#include <asm/setup.h>
@@ -254,7 +253,6 @@ static int do_bpt(struct pt_regs *regs)
void __kprobes do_trap(struct pt_regs *regs, int fault_num,
unsigned long reason)
{
- enum ctx_state prev_state = exception_enter();
siginfo_t info = { 0 };
int signo, code;
unsigned long address = 0;
@@ -263,7 +261,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
/* Handle breakpoints, etc. */
if (is_kernel && fault_num == INT_ILL && do_bpt(regs))
- goto done;
+ return;
/* Re-enable interrupts, if they were previously enabled. */
if (!(regs->flags & PT_FLAGS_DISABLE_IRQ))
@@ -277,7 +275,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
const char *name;
char buf[100];
if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */
- goto done;
+ return;
if (fault_num >= 0 &&
fault_num < ARRAY_SIZE(int_name) &&
int_name[fault_num] != NULL)
@@ -319,7 +317,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
case INT_GPV:
#if CHIP_HAS_TILE_DMA()
if (retry_gpv(reason))
- goto done;
+ return;
#endif
/*FALLTHROUGH*/
case INT_UDN_ACCESS:
@@ -346,7 +344,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
if (!state ||
(void __user *)(regs->pc) != state->buffer) {
single_step_once(regs);
- goto done;
+ return;
}
}
#endif
@@ -390,9 +388,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
if (signo != SIGTRAP)
trace_unhandled_signal("trap", regs, address, signo);
force_sig_info(signo, &info, current);
-
-done:
- exception_exit(prev_state);
}
void do_nmi(struct pt_regs *regs, int fault_num, unsigned long reason)
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c
index d075f92..0db5f7c 100644
--- a/arch/tile/kernel/unaligned.c
+++ b/arch/tile/kernel/unaligned.c
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <linux/compat.h>
#include <linux/prctl.h>
-#include <linux/context_tracking.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
@@ -1449,7 +1448,6 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle,
void do_unaligned(struct pt_regs *regs, int vecnum)
{
- enum ctx_state prev_state = exception_enter();
tilegx_bundle_bits __user *pc;
tilegx_bundle_bits bundle;
struct thread_info *info = current_thread_info();
@@ -1503,7 +1501,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
*((tilegx_bundle_bits *)(regs->pc)));
jit_bundle_gen(regs, bundle, align_ctl);
}
- goto done;
+ return;
}
/*
@@ -1527,7 +1525,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS);
force_sig_info(info.si_signo, &info, current);
- goto done;
+ return;
}
@@ -1544,7 +1542,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
trace_unhandled_signal("segfault in unalign fixup", regs,
(unsigned long)info.si_addr, SIGSEGV);
force_sig_info(info.si_signo, &info, current);
- goto done;
+ return;
}
if (!info->unalign_jit_base) {
@@ -1579,7 +1577,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
if (IS_ERR((void __force *)user_page)) {
pr_err("Out of kernel pages trying do_mmap\n");
- goto done;
+ return;
}
/* Save the address in the thread_info struct */
@@ -1592,9 +1590,6 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
/* Generate unalign JIT */
jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl);
-
-done:
- exception_exit(prev_state);
}
#endif /* __tilegx__ */
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 13eac59..2673421 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -35,7 +35,6 @@
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
-#include <linux/context_tracking.h>
#include <asm/pgalloc.h>
#include <asm/sections.h>
@@ -845,9 +844,7 @@ static inline void __do_page_fault(struct pt_regs *regs, int fault_num,
void do_page_fault(struct pt_regs *regs, int fault_num,
unsigned long address, unsigned long write)
{
- enum ctx_state prev_state = exception_enter();
__do_page_fault(regs, fault_num, address, write);
- exception_exit(prev_state);
}
#if CHIP_HAS_TILE_DMA()
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
index fcd5450..eca2855 100644
--- a/arch/tile/mm/highmem.c
+++ b/arch/tile/mm/highmem.c
@@ -275,15 +275,3 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
{
return kmap_atomic_prot(pfn_to_page(pfn), prot);
}
-
-struct page *kmap_atomic_to_page(void *ptr)
-{
- pte_t *pte;
- unsigned long vaddr = (unsigned long)ptr;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- pte = kmap_get_pte(vaddr);
- return pte_page(*pte);
-}
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index c034dc3..e212c64 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -77,7 +77,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
else {
if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE])
panic("Unexpected page size %#lx\n", sz);
- return pte_alloc_map(mm, NULL, pmd, addr);
+ return pte_alloc_map(mm, pmd, addr);
}
}
#else
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index d4e1fc4..a0582b7 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -896,17 +896,15 @@ void __init pgtable_cache_init(void)
panic("pgtable_cache_init(): Cannot create pgd cache");
}
-#ifdef CONFIG_DEBUG_PAGEALLOC
-static long __write_once initfree;
-#else
static long __write_once initfree = 1;
-#endif
+static bool __write_once set_initfree_done;
/* Select whether to free (1) or mark unusable (0) the __init pages. */
static int __init set_initfree(char *str)
{
long val;
if (kstrtol(str, 0, &val) == 0) {
+ set_initfree_done = true;
initfree = val;
pr_info("initfree: %s free init pages\n",
initfree ? "will" : "won't");
@@ -919,6 +917,11 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end)
{
unsigned long addr = (unsigned long) begin;
+ /* Prefer user request first */
+ if (!set_initfree_done) {
+ if (debug_pagealloc_enabled())
+ initfree = 0;
+ }
if (kdata_huge && !initfree) {
pr_warn("Warning: ignoring initfree=0: incompatible with kdata=huge\n");
initfree = 1;
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index d195a87..cc00134 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -2,6 +2,7 @@ config UML
bool
default y
select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_UID16
select HAVE_FUTEX_CMPXCHG if FUTEX
select GENERIC_IRQ_SHOW
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 28a9885..4b2ed58 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -104,3 +104,19 @@ config PGTABLE_LEVELS
int
default 3 if 3_LEVEL_PGTABLES
default 2
+
+config SECCOMP
+ def_bool y
+ 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.
+
+ If unsure, say Y.
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index f6b911c..3a4b587 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -105,13 +105,9 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count);
#endif
- kbuf = kmalloc(count, GFP_KERNEL);
- if (kbuf == NULL)
- return -ENOMEM;
-
- err = -EFAULT;
- if (copy_from_user(kbuf, buffer, count))
- goto out;
+ kbuf = memdup_user(buffer, count);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
err = os_write_file(state->fd, kbuf, count);
if (err < 0)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 29880c9..b821b13 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -748,19 +748,11 @@ static ssize_t mconsole_proc_write(struct file *file,
{
char *buf;
- buf = kmalloc(count + 1, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- if (copy_from_user(buf, buffer, count)) {
- count = -EFAULT;
- goto out;
- }
-
- buf[count] = '\0';
+ buf = memdup_user_nul(buffer, count);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
- out:
kfree(buf);
return count;
}
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index f70dd54..9ef669d 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -388,7 +388,7 @@ static const struct net_device_ops uml_netdev_ops = {
static int driver_registered;
static void eth_configure(int n, void *init, char *mac,
- struct transport *transport)
+ struct transport *transport, gfp_t gfp_mask)
{
struct uml_net *device;
struct net_device *dev;
@@ -397,7 +397,7 @@ static void eth_configure(int n, void *init, char *mac,
size = transport->private_size + sizeof(struct uml_net_private);
- device = kzalloc(sizeof(*device), GFP_KERNEL);
+ device = kzalloc(sizeof(*device), gfp_mask);
if (device == NULL) {
printk(KERN_ERR "eth_configure failed to allocate struct "
"uml_net\n");
@@ -568,7 +568,7 @@ static LIST_HEAD(transports);
static LIST_HEAD(eth_cmd_line);
static int check_transport(struct transport *transport, char *eth, int n,
- void **init_out, char **mac_out)
+ void **init_out, char **mac_out, gfp_t gfp_mask)
{
int len;
@@ -582,7 +582,7 @@ static int check_transport(struct transport *transport, char *eth, int n,
else if (*eth != '\0')
return 0;
- *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
+ *init_out = kmalloc(transport->setup_size, gfp_mask);
if (*init_out == NULL)
return 1;
@@ -609,11 +609,11 @@ void register_transport(struct transport *new)
list_for_each_safe(ele, next, &eth_cmd_line) {
eth = list_entry(ele, struct eth_init, list);
match = check_transport(new, eth->init, eth->index, &init,
- &mac);
+ &mac, GFP_KERNEL);
if (!match)
continue;
else if (init != NULL) {
- eth_configure(eth->index, init, mac, new);
+ eth_configure(eth->index, init, mac, new, GFP_KERNEL);
kfree(init);
}
list_del(&eth->list);
@@ -631,10 +631,11 @@ static int eth_setup_common(char *str, int index)
spin_lock(&transports_lock);
list_for_each(ele, &transports) {
transport = list_entry(ele, struct transport, list);
- if (!check_transport(transport, str, index, &init, &mac))
+ if (!check_transport(transport, str, index, &init,
+ &mac, GFP_ATOMIC))
continue;
if (init != NULL) {
- eth_configure(index, init, mac, transport);
+ eth_configure(index, init, mac, transport, GFP_ATOMIC);
kfree(init);
}
found = 1;
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index e697a41..e9f8445 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -249,21 +249,23 @@ void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
char *split_if_spec(char *str, ...)
{
- char **arg, *end;
+ char **arg, *end, *ret = NULL;
va_list ap;
va_start(ap, str);
while ((arg = va_arg(ap, char **)) != NULL) {
if (*str == '\0')
- return NULL;
+ goto out;
end = strchr(str, ',');
if (end != str)
*arg = str;
if (end == NULL)
- return NULL;
+ goto out;
*end++ = '\0';
str = end;
}
+ ret = str;
+out:
va_end(ap);
- return str;
+ return ret;
}
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index e8ab93c..39ba207 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -535,11 +535,7 @@ static int read_cow_bitmap(int fd, void *buf, int offset, int len)
{
int err;
- err = os_seek_file(fd, offset);
- if (err < 0)
- return err;
-
- err = os_read_file(fd, buf, len);
+ err = os_pread_file(fd, buf, len, offset);
if (err < 0)
return err;
@@ -1377,14 +1373,8 @@ static int update_bitmap(struct io_thread_req *req)
if(req->cow_offset == -1)
return 0;
- n = os_seek_file(req->fds[1], req->cow_offset);
- if(n < 0){
- printk("do_io - bitmap lseek failed : err = %d\n", -n);
- return 1;
- }
-
- n = os_write_file(req->fds[1], &req->bitmap_words,
- sizeof(req->bitmap_words));
+ n = os_pwrite_file(req->fds[1], &req->bitmap_words,
+ sizeof(req->bitmap_words), req->cow_offset);
if(n != sizeof(req->bitmap_words)){
printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
req->fds[1]);
@@ -1399,7 +1389,6 @@ static void do_io(struct io_thread_req *req)
char *buf;
unsigned long len;
int n, nsectors, start, end, bit;
- int err;
__u64 off;
if (req->op == UBD_FLUSH) {
@@ -1428,18 +1417,12 @@ static void do_io(struct io_thread_req *req)
len = (end - start) * req->sectorsize;
buf = &req->buffer[start * req->sectorsize];
- err = os_seek_file(req->fds[bit], off);
- if(err < 0){
- printk("do_io - lseek failed : err = %d\n", -err);
- req->error = 1;
- return;
- }
if(req->op == UBD_READ){
n = 0;
do {
buf = &buf[n];
len -= n;
- n = os_read_file(req->fds[bit], buf, len);
+ n = os_pread_file(req->fds[bit], buf, len, off);
if (n < 0) {
printk("do_io - read failed, err = %d "
"fd = %d\n", -n, req->fds[bit]);
@@ -1449,7 +1432,7 @@ static void do_io(struct io_thread_req *req)
} while((n < len) && (n != 0));
if (n < len) memset(&buf[n], 0, len - n);
} else {
- n = os_write_file(req->fds[bit], buf, len);
+ n = os_pwrite_file(req->fds[bit], buf, len, off);
if(n != len){
printk("do_io - write failed err = %d "
"fd = %d\n", -n, req->fds[bit]);
diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h
new file mode 100644
index 0000000..756f0778
--- /dev/null
+++ b/arch/um/include/asm/hardirq.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_UM_HARDIRQ_H
+#define __ASM_UM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+#include <linux/irq.h>
+
+#ifndef ack_bad_irq
+static inline void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+}
+#endif
+
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
+
+#endif /* __ASM_UM_HARDIRQ_H */
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
index 71c5d13..f878bec 100644
--- a/arch/um/include/asm/page.h
+++ b/arch/um/include/asm/page.h
@@ -18,6 +18,7 @@
struct page;
+#include <linux/pfn.h>
#include <linux/types.h>
#include <asm/vm-flags.h>
@@ -33,26 +34,22 @@ struct page;
#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT)
-typedef struct { unsigned long pte_low, pte_high; } pte_t;
+typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
-#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32))
-
-#define pte_get_bits(pte, bits) ((pte).pte_low & (bits))
-#define pte_set_bits(pte, bits) ((pte).pte_low |= (bits))
-#define pte_clear_bits(pte, bits) ((pte).pte_low &= ~(bits))
-#define pte_copy(to, from) ({ (to).pte_high = (from).pte_high; \
- smp_wmb(); \
- (to).pte_low = (from).pte_low; })
-#define pte_is_zero(pte) (!((pte).pte_low & ~_PAGE_NEWPAGE) && !(pte).pte_high)
-#define pte_set_val(pte, phys, prot) \
- ({ (pte).pte_high = (phys) >> 32; \
- (pte).pte_low = (phys) | pgprot_val(prot); })
+#define pte_val(p) ((p).pte)
+
+#define pte_get_bits(p, bits) ((p).pte & (bits))
+#define pte_set_bits(p, bits) ((p).pte |= (bits))
+#define pte_clear_bits(p, bits) ((p).pte &= ~(bits))
+#define pte_copy(to, from) ({ (to).pte = (from).pte; })
+#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE))
+#define pte_set_val(p, phys, prot) \
+ ({ (p).pte = (phys) | pgprot_val(prot); })
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) } )
-typedef unsigned long long pfn_t;
typedef unsigned long long phys_t;
#else
@@ -76,7 +73,6 @@ typedef struct { unsigned long pmd; } pmd_t;
#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE))
#define pte_set_val(p, phys, prot) (p).pte = (phys | pgprot_val(prot))
-typedef unsigned long pfn_t;
typedef unsigned long phys_t;
#endif
@@ -109,8 +105,8 @@ extern unsigned long uml_physmem;
#define __pa(virt) to_phys((void *) (unsigned long) (virt))
#define __va(phys) to_virt((unsigned long) (phys))
-#define phys_to_pfn(p) ((pfn_t) ((p) >> PAGE_SHIFT))
-#define pfn_to_phys(pfn) ((phys_t) ((pfn) << PAGE_SHIFT))
+#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
+#define pfn_to_phys(pfn) PFN_PHYS(pfn)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
index 2b4274e..bae8523 100644
--- a/arch/um/include/asm/pgtable-3level.h
+++ b/arch/um/include/asm/pgtable-3level.h
@@ -98,7 +98,7 @@ static inline unsigned long pte_pfn(pte_t pte)
return phys_to_pfn(pte_val(pte));
}
-static inline pte_t pfn_pte(pfn_t page_nr, pgprot_t pgprot)
+static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
{
pte_t pte;
phys_t phys = pfn_to_phys(page_nr);
@@ -107,7 +107,7 @@ static inline pte_t pfn_pte(pfn_t page_nr, pgprot_t pgprot)
return pte;
}
-static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot)
+static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
{
return __pmd((page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
}
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 18eb992..7485398 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -271,7 +271,7 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b)
#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
#define __virt_to_page(virt) phys_to_page(__pa(virt))
-#define page_to_phys(page) pfn_to_phys((pfn_t) page_to_pfn(page))
+#define page_to_phys(page) pfn_to_phys(page_to_pfn(page))
#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
#define mk_pte(page, pgprot) \
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 2966adb..5ab2062 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -27,6 +27,8 @@ struct pt_regs {
#define instruction_pointer(regs) PT_REGS_IP(regs)
+#define PTRACE_OLDSETOPTIONS 21
+
struct task_struct;
extern long subarch_ptrace(struct task_struct *child, long request,
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
new file mode 100644
index 0000000..9fb9cf8
--- /dev/null
+++ b/arch/um/include/asm/syscall-generic.h
@@ -0,0 +1,138 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2015 Mickaël Salaün <mic@digikod.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 __UM_SYSCALL_GENERIC_H
+#define __UM_SYSCALL_GENERIC_H
+
+#include <asm/ptrace.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <sysdep/ptrace.h>
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+
+ return PT_REGS_SYSCALL_NR(regs);
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* do nothing */
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ const long error = regs_return_value(regs);
+
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs_return_value(regs);
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ PT_REGS_SET_SYSCALL_RETURN(regs, (long) error ?: val);
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ const struct uml_pt_regs *r = &regs->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG1(r);
+ case 1:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG2(r);
+ case 2:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG3(r);
+ case 3:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG4(r);
+ case 4:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG5(r);
+ case 5:
+ if (!n--)
+ break;
+ *args++ = UPT_SYSCALL_ARG6(r);
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ struct uml_pt_regs *r = &regs->regs;
+
+ switch (i) {
+ case 0:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG1(r) = *args++;
+ case 1:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG2(r) = *args++;
+ case 2:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG3(r) = *args++;
+ case 3:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG4(r) = *args++;
+ case 4:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG5(r) = *args++;
+ case 5:
+ if (!n--)
+ break;
+ UPT_SYSCALL_ARG6(r) = *args++;
+ case 6:
+ if (!n--)
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
+
+#endif /* __UM_SYSCALL_GENERIC_H */
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 53968aa..053baff 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -62,11 +62,13 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
+#define TIF_SECCOMP 9 /* secure computing */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#endif
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index ad3fa3a..de5d572 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -144,6 +146,8 @@ extern int os_read_file(int fd, void *buf, int len);
extern int os_write_file(int fd, const void *buf, int count);
extern int os_sync_file(int fd);
extern int os_file_size(const char *file, unsigned long long *size_out);
+extern int os_pread_file(int fd, void *buf, int len, unsigned long long offset);
+extern int os_pwrite_file(int fd, const void *buf, int count, unsigned long long offset);
extern int os_file_modtime(const char *file, unsigned long *modtime);
extern int os_pipe(int *fd, int stream, int close_on_exec);
extern int os_set_fd_async(int fd);
@@ -183,6 +187,7 @@ extern int create_mem_file(unsigned long long len);
/* process.c */
extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
+extern void os_alarm_process(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
@@ -217,7 +222,7 @@ extern int set_umid(char *name);
extern char *get_umid(void);
/* signal.c */
-extern void timer_init(void);
+extern void timer_set_signal_handler(void);
extern void set_sigstack(void *sig_stack, int size);
extern void remove_sigstack(void);
extern void set_handler(int sig);
@@ -227,6 +232,7 @@ extern void unblock_signals(void);
extern int get_signals(void);
extern int set_signals(int enable);
extern int os_is_signal_stack(void);
+extern void deliver_alarm(void);
/* util.c */
extern void stack_protections(unsigned long address);
@@ -238,12 +244,16 @@ extern void um_early_printk(const char *s, unsigned int n);
extern void os_fix_helper_signals(void);
/* time.c */
-extern void idle_sleep(unsigned long long nsecs);
-extern int set_interval(void);
-extern int timer_one_shot(int ticks);
-extern long long disable_timer(void);
+extern void os_idle_sleep(unsigned long long nsecs);
+extern int os_timer_create(void* timer);
+extern int os_timer_set_interval(void* timer, void* its);
+extern int os_timer_one_shot(int ticks);
+extern long long os_timer_disable(void);
+extern long os_timer_remain(void* timer);
extern void uml_idle_timer(void);
+extern long long os_persistent_clock_emulation(void);
extern long long os_nsecs(void);
+extern long long os_vnsecs(void);
/* skas/mem.c */
extern long run_syscall_stub(struct mm_id * mm_idp,
diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h
index f6ed92c..a9deece 100644
--- a/arch/um/include/shared/skas/stub-data.h
+++ b/arch/um/include/shared/skas/stub-data.h
@@ -1,4 +1,6 @@
/*
+
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -6,12 +8,11 @@
#ifndef __STUB_DATA_H
#define __STUB_DATA_H
-#include <sys/time.h>
+#include <time.h>
struct stub_data {
- long offset;
+ unsigned long offset;
int fd;
- struct itimerval timer;
long err;
};
diff --git a/arch/um/include/shared/timer-internal.h b/arch/um/include/shared/timer-internal.h
new file mode 100644
index 0000000..03e6f21
--- /dev/null
+++ b/arch/um/include/shared/timer-internal.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 - 2014 Cisco Systems
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TIMER_INTERNAL_H__
+#define __TIMER_INTERNAL_H__
+
+#define TIMER_MULTIPLIER 256
+#define TIMER_MIN_DELTA 500
+
+#endif
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index a6d9226..48af59a 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright 2003 PathScale, Inc.
* Licensed under the GPL
@@ -27,6 +29,7 @@
#include <kern_util.h>
#include <os.h>
#include <skas.h>
+#include <timer-internal.h>
/*
* This is a per-cpu array. A processor only modifies its entry and it only
@@ -203,11 +206,8 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
void arch_cpu_idle(void)
{
- unsigned long long nsecs;
-
cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
- nsecs = disable_timer();
- idle_sleep(nsecs);
+ os_idle_sleep(UM_NSEC_PER_SEC);
local_irq_enable();
}
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 9bdf67a..b60a9f8 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -12,6 +12,7 @@
#include <skas.h>
void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
static void kill_off_processes(void)
{
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index 289771d..0f25d41 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -35,11 +36,6 @@ stub_clone_handler(void)
if (err)
goto out;
- err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
- (long) &data->timer, 0);
- if (err)
- goto out;
-
remap_stack(data->fd, data->offset);
goto done;
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index fda1deb..3943e9d 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -30,7 +31,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
if (!pmd)
goto out_pmd;
- pte = pte_alloc_map(mm, NULL, pmd, proc);
+ pte = pte_alloc_map(mm, pmd, proc);
if (!pte)
goto out_pte;
@@ -61,10 +62,12 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
if (current->mm != NULL && current->mm != &init_mm)
from_mm = &current->mm->context;
+ block_signals();
if (from_mm)
to_mm->id.u.pid = copy_context_skas0(stack,
from_mm->id.u.pid);
else to_mm->id.u.pid = start_userspace(stack);
+ unblock_signals();
if (to_mm->id.u.pid < 0) {
ret = to_mm->id.u.pid;
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index d9ec006..48b0dcb 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -5,40 +5,38 @@
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <linux/seccomp.h>
#include <kern_util.h>
#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
#include <sysdep/syscalls.h>
-extern int syscall_table_size;
-#define NR_SYSCALLS (syscall_table_size / sizeof(void *))
-
void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
- long result;
int syscall;
- if (syscall_trace_enter(regs)) {
- result = -ENOSYS;
+ /* Initialize the syscall number and default return value. */
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
+ PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
+
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing() == -1)
+ return;
+
+ if (syscall_trace_enter(regs))
goto out;
- }
-
- /*
- * This should go in the declaration of syscall, but when I do that,
- * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing
- * children at all, sometimes hanging when bash doesn't see the first
- * ls exit.
- * The assembly looks functionally the same to me. This is
- * gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)
- * in case it's a compiler bug.
+
+ /* Update the syscall number after orig_ax has potentially been updated
+ * with ptrace.
*/
+ UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
syscall = UPT_SYSCALL_NR(r);
- if ((syscall >= NR_SYSCALLS) || (syscall < 0))
- result = -ENOSYS;
- else result = EXECUTE_SYSCALL(syscall, regs);
-out:
- PT_REGS_SET_SYSCALL_RETURN(regs, result);
+ if (syscall >= 0 && syscall <= __NR_syscall_max)
+ PT_REGS_SET_SYSCALL_RETURN(regs,
+ EXECUTE_SYSCALL(syscall, regs));
+out:
syscall_trace_leave(regs);
}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 5af441e..25c2366 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
+ * Copyright (C) 2012-2014 Cisco Systems
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -7,11 +10,15 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
#include <linux/threads.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <kern_util.h>
#include <os.h>
+#include <timer-internal.h>
void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
@@ -24,81 +31,97 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
static int itimer_shutdown(struct clock_event_device *evt)
{
- disable_timer();
+ os_timer_disable();
return 0;
}
static int itimer_set_periodic(struct clock_event_device *evt)
{
- set_interval();
+ os_timer_set_interval(NULL, NULL);
return 0;
}
static int itimer_next_event(unsigned long delta,
struct clock_event_device *evt)
{
- return timer_one_shot(delta + 1);
+ return os_timer_one_shot(delta);
}
-static struct clock_event_device itimer_clockevent = {
- .name = "itimer",
+static int itimer_one_shot(struct clock_event_device *evt)
+{
+ os_timer_one_shot(1);
+ return 0;
+}
+
+static struct clock_event_device timer_clockevent = {
+ .name = "posix-timer",
.rating = 250,
.cpumask = cpu_all_mask,
.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT,
.set_state_shutdown = itimer_shutdown,
.set_state_periodic = itimer_set_periodic,
- .set_state_oneshot = itimer_shutdown,
+ .set_state_oneshot = itimer_one_shot,
.set_next_event = itimer_next_event,
- .shift = 32,
+ .shift = 0,
+ .max_delta_ns = 0xffffffff,
+ .min_delta_ns = TIMER_MIN_DELTA, //microsecond resolution should be enough for anyone, same as 640K RAM
.irq = 0,
+ .mult = 1,
};
static irqreturn_t um_timer(int irq, void *dev)
{
- (*itimer_clockevent.event_handler)(&itimer_clockevent);
+ if (get_current()->mm != NULL)
+ {
+ /* userspace - relay signal, results in correct userspace timers */
+ os_alarm_process(get_current()->mm->context.id.u.pid);
+ }
+
+ (*timer_clockevent.event_handler)(&timer_clockevent);
return IRQ_HANDLED;
}
-static cycle_t itimer_read(struct clocksource *cs)
+static cycle_t timer_read(struct clocksource *cs)
{
- return os_nsecs() / 1000;
+ return os_nsecs() / TIMER_MULTIPLIER;
}
-static struct clocksource itimer_clocksource = {
- .name = "itimer",
+static struct clocksource timer_clocksource = {
+ .name = "timer",
.rating = 300,
- .read = itimer_read,
+ .read = timer_read,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init setup_itimer(void)
+static void __init timer_setup(void)
{
int err;
- err = request_irq(TIMER_IRQ, um_timer, 0, "timer", NULL);
+ err = request_irq(TIMER_IRQ, um_timer, IRQF_TIMER, "hr timer", NULL);
if (err != 0)
printk(KERN_ERR "register_timer : request_irq failed - "
"errno = %d\n", -err);
- itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
- itimer_clockevent.max_delta_ns =
- clockevent_delta2ns(60 * HZ, &itimer_clockevent);
- itimer_clockevent.min_delta_ns =
- clockevent_delta2ns(1, &itimer_clockevent);
- err = clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
+ err = os_timer_create(NULL);
+ if (err != 0) {
+ printk(KERN_ERR "creation of timer failed - errno = %d\n", -err);
+ return;
+ }
+
+ err = clocksource_register_hz(&timer_clocksource, NSEC_PER_SEC/TIMER_MULTIPLIER);
if (err) {
printk(KERN_ERR "clocksource_register_hz returned %d\n", err);
return;
}
- clockevents_register_device(&itimer_clockevent);
+ clockevents_register_device(&timer_clockevent);
}
void read_persistent_clock(struct timespec *ts)
{
- long long nsecs = os_nsecs();
+ long long nsecs = os_persistent_clock_emulation();
set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
nsecs % NSEC_PER_SEC);
@@ -106,6 +129,6 @@ void read_persistent_clock(struct timespec *ts)
void __init time_init(void)
{
- timer_init();
- late_time_init = setup_itimer;
+ timer_set_signal_handler();
+ late_time_init = timer_setup;
}
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 2077248..3777b82 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -50,6 +50,13 @@ struct host_vm_change {
.index = 0, \
.force = force })
+static void report_enomem(void)
+{
+ printk(KERN_ERR "UML ran out of memory on the host side! "
+ "This can happen due to a memory limitation or "
+ "vm.max_map_count has been reached.\n");
+}
+
static int do_ops(struct host_vm_change *hvc, int end,
int finished)
{
@@ -81,6 +88,9 @@ static int do_ops(struct host_vm_change *hvc, int end,
}
}
+ if (ret == -ENOMEM)
+ report_enomem();
+
return ret;
}
@@ -433,8 +443,12 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
else if (pte_newprot(*pte))
err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
- if (err)
+ if (err) {
+ if (err == -ENOMEM)
+ report_enomem();
+
goto kill;
+ }
*pte = pte_mkuptodate(*pte);
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 26e0164..2db18cb 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -264,6 +264,15 @@ int os_read_file(int fd, void *buf, int len)
return n;
}
+int os_pread_file(int fd, void *buf, int len, unsigned long long offset)
+{
+ int n = pread(fd, buf, len, offset);
+
+ if (n < 0)
+ return -errno;
+ return n;
+}
+
int os_write_file(int fd, const void *buf, int len)
{
int n = write(fd, (void *) buf, len);
@@ -282,6 +291,16 @@ int os_sync_file(int fd)
return n;
}
+int os_pwrite_file(int fd, const void *buf, int len, unsigned long long offset)
+{
+ int n = pwrite(fd, (void *) buf, len, offset);
+
+ if (n < 0)
+ return -errno;
+ return n;
+}
+
+
int os_file_size(const char *file, unsigned long long *size_out)
{
struct uml_stat buf;
diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h
deleted file mode 100644
index 0dc2c9f..0000000
--- a/arch/um/os-Linux/internal.h
+++ /dev/null
@@ -1 +0,0 @@
-void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc);
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index df9191a..9d499de 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -163,13 +164,13 @@ int __init main(int argc, char **argv, char **envp)
/*
* This signal stuff used to be in the reboot case. However,
- * sometimes a SIGVTALRM can come in when we're halting (reproducably
+ * sometimes a timer signal can come in when we're halting (reproducably
* when writing out gcov information, presumably because that takes
* some time) and cause a segfault.
*/
- /* stop timers and set SIGVTALRM to be ignored */
- disable_timer();
+ /* stop timers and set timer signal to be ignored */
+ os_timer_disable();
/* disable SIGIO for the fds and set SIGIO to be ignored */
err = deactivate_all_fds();
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 897e9ad..8b17676 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -106,6 +106,17 @@ static int __init make_tempfile(const char *template)
}
}
+#ifdef O_TMPFILE
+ fd = open(tempdir, O_CLOEXEC | O_RDWR | O_EXCL | O_TMPFILE, 0700);
+ /*
+ * If the running system does not support O_TMPFILE flag then retry
+ * without it.
+ */
+ if (fd != -1 || (errno != EINVAL && errno != EISDIR &&
+ errno != EOPNOTSUPP))
+ return fd;
+#endif
+
tempname = malloc(strlen(tempdir) + strlen(template) + 1);
if (tempname == NULL)
return -1;
@@ -142,12 +153,6 @@ static int __init create_tmp_file(unsigned long long len)
if (fd < 0)
exit(1);
- err = fchmod(fd, 0777);
- if (err < 0) {
- perror("fchmod");
- exit(1);
- }
-
/*
* Seek to len - 1 because writing a character there will
* increase the file size by one byte, to the desired length.
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 8408aba..b3e0d40 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -89,6 +90,11 @@ int os_process_parent(int pid)
return parent;
}
+void os_alarm_process(int pid)
+{
+ kill(pid, SIGALRM);
+}
+
void os_stop_process(int pid)
{
kill(pid, SIGSTOP);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 036d0db..7801666 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2004 PathScale, Inc
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
@@ -13,7 +15,6 @@
#include <kern_util.h>
#include <os.h>
#include <sysdep/mcontext.h>
-#include "internal.h"
void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
[SIGTRAP] = relay_signal,
@@ -23,7 +24,8 @@ void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
[SIGBUS] = bus_handler,
[SIGSEGV] = segv_handler,
[SIGIO] = sigio_handler,
- [SIGVTALRM] = timer_handler };
+ [SIGALRM] = timer_handler
+};
static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
{
@@ -38,7 +40,7 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
}
/* enable signals if sig isn't IRQ signal */
- if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
+ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGALRM))
unblock_signals();
(*sig_info[sig])(sig, si, &r);
@@ -55,11 +57,12 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
#define SIGIO_BIT 0
#define SIGIO_MASK (1 << SIGIO_BIT)
-#define SIGVTALRM_BIT 1
-#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
+#define SIGALRM_BIT 1
+#define SIGALRM_MASK (1 << SIGALRM_BIT)
static int signals_enabled;
static unsigned int signals_pending;
+static unsigned int signals_active = 0;
void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
{
@@ -78,36 +81,43 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
set_signals(enabled);
}
-static void real_alarm_handler(mcontext_t *mc)
+static void timer_real_alarm_handler(mcontext_t *mc)
{
struct uml_pt_regs regs;
if (mc != NULL)
get_regs_from_mc(&regs, mc);
- regs.is_user = 0;
- unblock_signals();
- timer_handler(SIGVTALRM, NULL, &regs);
+ timer_handler(SIGALRM, NULL, &regs);
}
-void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
+void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
{
int enabled;
enabled = signals_enabled;
if (!signals_enabled) {
- signals_pending |= SIGVTALRM_MASK;
+ signals_pending |= SIGALRM_MASK;
return;
}
block_signals();
- real_alarm_handler(mc);
+ signals_active |= SIGALRM_MASK;
+
+ timer_real_alarm_handler(mc);
+
+ signals_active &= ~SIGALRM_MASK;
+
set_signals(enabled);
}
-void timer_init(void)
+void deliver_alarm(void) {
+ timer_alarm_handler(SIGALRM, NULL, NULL);
+}
+
+void timer_set_signal_handler(void)
{
- set_handler(SIGVTALRM);
+ set_handler(SIGALRM);
}
void set_sigstack(void *sig_stack, int size)
@@ -131,10 +141,9 @@ static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
[SIGIO] = sig_handler,
[SIGWINCH] = sig_handler,
- [SIGVTALRM] = alarm_handler
+ [SIGALRM] = timer_alarm_handler
};
-
static void hard_handler(int sig, siginfo_t *si, void *p)
{
struct ucontext *uc = p;
@@ -188,9 +197,9 @@ void set_handler(int sig)
/* block irq ones */
sigemptyset(&action.sa_mask);
- sigaddset(&action.sa_mask, SIGVTALRM);
sigaddset(&action.sa_mask, SIGIO);
sigaddset(&action.sa_mask, SIGWINCH);
+ sigaddset(&action.sa_mask, SIGALRM);
if (sig == SIGSEGV)
flags |= SA_NODEFER;
@@ -283,8 +292,16 @@ void unblock_signals(void)
if (save_pending & SIGIO_MASK)
sig_handler_common(SIGIO, NULL, NULL);
- if (save_pending & SIGVTALRM_MASK)
- real_alarm_handler(NULL);
+ /* Do not reenter the handler */
+
+ if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK)))
+ timer_real_alarm_handler(NULL);
+
+ /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */
+
+ if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
+ return;
+
}
}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 3dddedb..23025d6 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -45,7 +46,7 @@ static int ptrace_dump_regs(int pid)
* Signals that are OK to receive in the stub - we'll just continue it.
* SIGWINCH will happen when UML is inside a detached screen.
*/
-#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
+#define STUB_SIG_MASK ((1 << SIGALRM) | (1 << SIGWINCH))
/* Signals that the stub will finish with - anything else is an error */
#define STUB_DONE_MASK (1 << SIGTRAP)
@@ -137,9 +138,6 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
fatal_sigsegv();
- /* Mark this as a syscall */
- UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
-
if (!local_using_sysemu)
{
err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
@@ -179,19 +177,13 @@ extern char __syscall_stub_start[];
static int userspace_tramp(void *stack)
{
void *addr;
- int err, fd;
+ int fd;
unsigned long long offset;
ptrace(PTRACE_TRACEME, 0, 0, 0);
signal(SIGTERM, SIG_DFL);
signal(SIGWINCH, SIG_IGN);
- err = set_interval();
- if (err) {
- printk(UM_KERN_ERR "userspace_tramp - setting timer failed, "
- "errno = %d\n", err);
- exit(1);
- }
/*
* This has a pte, but it can't be mapped in with the usual
@@ -282,7 +274,7 @@ int start_userspace(unsigned long stub_stack)
"errno = %d\n", errno);
goto out_kill;
}
- } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
+ } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGALRM));
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
err = -EINVAL;
@@ -315,8 +307,6 @@ int start_userspace(unsigned long stub_stack)
void userspace(struct uml_pt_regs *regs)
{
- struct itimerval timer;
- unsigned long long nsecs, now;
int err, status, op, pid = userspace_pid[0];
/* To prevent races if using_sysemu changes under us.*/
int local_using_sysemu;
@@ -325,13 +315,8 @@ void userspace(struct uml_pt_regs *regs)
/* Handle any immediate reschedules or signals */
interrupt_end();
- if (getitimer(ITIMER_VIRTUAL, &timer))
- printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno);
- nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
- timer.it_value.tv_usec * UM_NSEC_PER_USEC;
- nsecs += os_nsecs();
-
while (1) {
+
/*
* This can legitimately fail if the process loads a
* bogus value into a segment register. It will
@@ -401,18 +386,7 @@ void userspace(struct uml_pt_regs *regs)
case SIGTRAP:
relay_signal(SIGTRAP, (struct siginfo *)&si, regs);
break;
- case SIGVTALRM:
- now = os_nsecs();
- if (now < nsecs)
- break;
- block_signals();
- (*sig_info[sig])(sig, (struct siginfo *)&si, regs);
- unblock_signals();
- nsecs = timer.it_value.tv_sec *
- UM_NSEC_PER_SEC +
- timer.it_value.tv_usec *
- UM_NSEC_PER_USEC;
- nsecs += os_nsecs();
+ case SIGALRM:
break;
case SIGIO:
case SIGILL:
@@ -460,7 +434,6 @@ __initcall(init_thread_regs);
int copy_context_skas0(unsigned long new_stack, int pid)
{
- struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };
int err;
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
@@ -472,11 +445,10 @@ int copy_context_skas0(unsigned long new_stack, int pid)
* prepare offset and fd of child's stack as argument for parent's
* and child's mmap2 calls
*/
- *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
- .fd = new_fd,
- .timer = ((struct itimerval)
- { .it_value = tv,
- .it_interval = tv }) });
+ *data = ((struct stub_data) {
+ .offset = MMAP_OFFSET(new_offset),
+ .fd = new_fd
+ });
err = ptrace_setregs(pid, thread_regs);
if (err < 0) {
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 47f1ff0..22a358e 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -94,6 +94,8 @@ static int start_ptraced_child(void)
{
int pid, n, status;
+ fflush(stdout);
+
pid = fork();
if (pid == 0)
ptrace_child();
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index e9824d5..0e39b99 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
+ * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
+ * Copyright (C) 2012-2014 Cisco Systems
* Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -10,177 +13,177 @@
#include <sys/time.h>
#include <kern_util.h>
#include <os.h>
-#include "internal.h"
+#include <string.h>
+#include <timer-internal.h>
-int set_interval(void)
-{
- int usec = UM_USEC_PER_SEC / UM_HZ;
- struct itimerval interval = ((struct itimerval) { { 0, usec },
- { 0, usec } });
-
- if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
- return -errno;
+static timer_t event_high_res_timer = 0;
- return 0;
+static inline long long timeval_to_ns(const struct timeval *tv)
+{
+ return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
+ tv->tv_usec * UM_NSEC_PER_USEC;
}
-int timer_one_shot(int ticks)
+static inline long long timespec_to_ns(const struct timespec *ts)
{
- unsigned long usec = ticks * UM_USEC_PER_SEC / UM_HZ;
- unsigned long sec = usec / UM_USEC_PER_SEC;
- struct itimerval interval;
-
- usec %= UM_USEC_PER_SEC;
- interval = ((struct itimerval) { { 0, 0 }, { sec, usec } });
+ return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) +
+ ts->tv_nsec;
+}
- if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
- return -errno;
+long long os_persistent_clock_emulation (void) {
+ struct timespec realtime_tp;
- return 0;
+ clock_gettime(CLOCK_REALTIME, &realtime_tp);
+ return timespec_to_ns(&realtime_tp);
}
/**
- * timeval_to_ns - Convert timeval to nanoseconds
- * @ts: pointer to the timeval variable to be converted
- *
- * Returns the scalar nanosecond representation of the timeval
- * parameter.
- *
- * Ripped from linux/time.h because it's a kernel header, and thus
- * unusable from here.
+ * os_timer_create() - create an new posix (interval) timer
*/
-static inline long long timeval_to_ns(const struct timeval *tv)
-{
- return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
- tv->tv_usec * UM_NSEC_PER_USEC;
+int os_timer_create(void* timer) {
+
+ timer_t* t = timer;
+
+ if(t == NULL) {
+ t = &event_high_res_timer;
+ }
+
+ if (timer_create(
+ CLOCK_MONOTONIC,
+ NULL,
+ t) == -1) {
+ return -1;
+ }
+ return 0;
}
-long long disable_timer(void)
+int os_timer_set_interval(void* timer, void* i)
{
- struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
- long long remain, max = UM_NSEC_PER_SEC / UM_HZ;
+ struct itimerspec its;
+ unsigned long long nsec;
+ timer_t* t = timer;
+ struct itimerspec* its_in = i;
- if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
- printk(UM_KERN_ERR "disable_timer - setitimer failed, "
- "errno = %d\n", errno);
+ if(t == NULL) {
+ t = &event_high_res_timer;
+ }
- remain = timeval_to_ns(&time.it_value);
- if (remain > max)
- remain = max;
+ nsec = UM_NSEC_PER_SEC / UM_HZ;
- return remain;
-}
+ if(its_in != NULL) {
+ its.it_value.tv_sec = its_in->it_value.tv_sec;
+ its.it_value.tv_nsec = its_in->it_value.tv_nsec;
+ } else {
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = nsec;
+ }
-long long os_nsecs(void)
-{
- struct timeval tv;
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = nsec;
- gettimeofday(&tv, NULL);
- return timeval_to_ns(&tv);
-}
+ if(timer_settime(*t, 0, &its, NULL) == -1) {
+ return -errno;
+ }
-#ifdef UML_CONFIG_NO_HZ_COMMON
-static int after_sleep_interval(struct timespec *ts)
-{
return 0;
}
-static void deliver_alarm(void)
+/**
+ * os_timer_remain() - returns the remaining nano seconds of the given interval
+ * timer
+ * Because this is the remaining time of an interval timer, which correspondends
+ * to HZ, this value can never be bigger than one second. Just
+ * the nanosecond part of the timer is returned.
+ * The returned time is relative to the start time of the interval timer.
+ * Return an negative value in an error case.
+ */
+long os_timer_remain(void* timer)
{
- alarm_handler(SIGVTALRM, NULL, NULL);
-}
+ struct itimerspec its;
+ timer_t* t = timer;
-static unsigned long long sleep_time(unsigned long long nsecs)
-{
- return nsecs;
-}
+ if(t == NULL) {
+ t = &event_high_res_timer;
+ }
-#else
-unsigned long long last_tick;
-unsigned long long skew;
+ if(timer_gettime(t, &its) == -1) {
+ return -errno;
+ }
-static void deliver_alarm(void)
-{
- unsigned long long this_tick = os_nsecs();
- int one_tick = UM_NSEC_PER_SEC / UM_HZ;
+ return its.it_value.tv_nsec;
+}
- /* Protection against the host's time going backwards */
- if ((last_tick != 0) && (this_tick < last_tick))
- this_tick = last_tick;
+int os_timer_one_shot(int ticks)
+{
+ struct itimerspec its;
+ unsigned long long nsec;
+ unsigned long sec;
- if (last_tick == 0)
- last_tick = this_tick - one_tick;
+ nsec = (ticks + 1);
+ sec = nsec / UM_NSEC_PER_SEC;
+ nsec = nsec % UM_NSEC_PER_SEC;
- skew += this_tick - last_tick;
+ its.it_value.tv_sec = nsec / UM_NSEC_PER_SEC;
+ its.it_value.tv_nsec = nsec;
- while (skew >= one_tick) {
- alarm_handler(SIGVTALRM, NULL, NULL);
- skew -= one_tick;
- }
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0; // we cheat here
- last_tick = this_tick;
+ timer_settime(event_high_res_timer, 0, &its, NULL);
+ return 0;
}
-static unsigned long long sleep_time(unsigned long long nsecs)
+/**
+ * os_timer_disable() - disable the posix (interval) timer
+ * Returns the remaining interval timer time in nanoseconds
+ */
+long long os_timer_disable(void)
{
- return nsecs > skew ? nsecs - skew : 0;
-}
+ struct itimerspec its;
-static inline long long timespec_to_us(const struct timespec *ts)
-{
- return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
- ts->tv_nsec / UM_NSEC_PER_USEC;
+ memset(&its, 0, sizeof(struct itimerspec));
+ timer_settime(event_high_res_timer, 0, &its, &its);
+
+ return its.it_value.tv_sec * UM_NSEC_PER_SEC + its.it_value.tv_nsec;
}
-static int after_sleep_interval(struct timespec *ts)
+long long os_vnsecs(void)
{
- int usec = UM_USEC_PER_SEC / UM_HZ;
- long long start_usecs = timespec_to_us(ts);
- struct timeval tv;
- struct itimerval interval;
-
- /*
- * It seems that rounding can increase the value returned from
- * setitimer to larger than the one passed in. Over time,
- * this will cause the remaining time to be greater than the
- * tick interval. If this happens, then just reduce the first
- * tick to the interval value.
- */
- if (start_usecs > usec)
- start_usecs = usec;
-
- start_usecs -= skew / UM_NSEC_PER_USEC;
- if (start_usecs < 0)
- start_usecs = 0;
+ struct timespec ts;
- tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC,
- .tv_usec = start_usecs % UM_USEC_PER_SEC });
- interval = ((struct itimerval) { { 0, usec }, tv });
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&ts);
+ return timespec_to_ns(&ts);
+}
- if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
- return -errno;
+long long os_nsecs(void)
+{
+ struct timespec ts;
- return 0;
+ clock_gettime(CLOCK_MONOTONIC,&ts);
+ return timespec_to_ns(&ts);
}
-#endif
-void idle_sleep(unsigned long long nsecs)
+/**
+ * os_idle_sleep() - sleep for a given time of nsecs
+ * @nsecs: nanoseconds to sleep
+ */
+void os_idle_sleep(unsigned long long nsecs)
{
struct timespec ts;
- /*
- * nsecs can come in as zero, in which case, this starts a
- * busy loop. To prevent this, reset nsecs to the tick
- * interval if it is zero.
- */
- if (nsecs == 0)
- nsecs = UM_NSEC_PER_SEC / UM_HZ;
+ if (nsecs <= 0) {
+ return;
+ }
- nsecs = sleep_time(nsecs);
- ts = ((struct timespec) { .tv_sec = nsecs / UM_NSEC_PER_SEC,
- .tv_nsec = nsecs % UM_NSEC_PER_SEC });
+ ts = ((struct timespec) {
+ .tv_sec = nsecs / UM_NSEC_PER_SEC,
+ .tv_nsec = nsecs % UM_NSEC_PER_SEC
+ });
- if (nanosleep(&ts, &ts) == 0)
+ /*
+ * Relay the signal if clock_nanosleep is interrupted.
+ */
+ if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) {
deliver_alarm();
- after_sleep_interval(&ts);
+ }
}
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 928237a..e5602ee 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -1,10 +1,10 @@
config UNICORE32
def_bool y
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select HAVE_MEMBLOCK
select HAVE_GENERIC_DMA_COHERENT
- select HAVE_DMA_ATTRS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select GENERIC_ATOMIC64
@@ -33,9 +33,6 @@ config NO_IOPORT_MAP
config STACKTRACE_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config LOCKDEP_SUPPORT
def_bool y
@@ -222,7 +219,7 @@ config I2C_BATTERY_BQ27200
tristate "I2C Battery BQ27200 Support"
select I2C_PUV3
select POWER_SUPPLY
- select BATTERY_BQ27x00
+ select BATTERY_BQ27XXX
config I2C_EEPROM_AT24
tristate "I2C EEPROMs AT24 support"
diff --git a/arch/unicore32/Kconfig.debug b/arch/unicore32/Kconfig.debug
index 1a36262..f075bbe 100644
--- a/arch/unicore32/Kconfig.debug
+++ b/arch/unicore32/Kconfig.debug
@@ -2,20 +2,6 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-config STRICT_DEVMEM
- bool "Filter access to /dev/mem"
- depends on MMU
- ---help---
- If this option is disabled, you allow userspace (root) access to all
- of memory, including kernel and userspace memory. Accidental
- access to this is obviously disastrous, but specific access can
- be used by people debugging the kernel.
-
- If this option is switched on, the /dev/mem file only allows
- userspace access to memory mapped peripherals.
-
- If in doubt, say Y.
-
config EARLY_PRINTK
def_bool DEBUG_OCD
help
diff --git a/arch/unicore32/include/asm/checksum.h b/arch/unicore32/include/asm/checksum.h
index f55c3f9..23ceb9e 100644
--- a/arch/unicore32/include/asm/checksum.h
+++ b/arch/unicore32/include/asm/checksum.h
@@ -20,8 +20,8 @@
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
__asm__(
"add.a %0, %1, %2\n"
diff --git a/arch/unicore32/include/asm/dma-mapping.h b/arch/unicore32/include/asm/dma-mapping.h
index 8140e05..4749854 100644
--- a/arch/unicore32/include/asm/dma-mapping.h
+++ b/arch/unicore32/include/asm/dma-mapping.h
@@ -28,8 +28,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &swiotlb_dma_map_ops;
}
-#include <asm-generic/dma-mapping-common.h>
-
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (dev && dev->dma_mask)
diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h
index 38b3f37..37e55d0 100644
--- a/arch/unicore32/include/asm/pci.h
+++ b/arch/unicore32/include/asm/pci.h
@@ -13,8 +13,6 @@
#define __UNICORE_PCI_H__
#ifdef __KERNEL__
-#include <asm-generic/pci-dma-compat.h>
-#include <asm-generic/pci-bridge.h>
#include <asm-generic/pci.h>
#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
@@ -23,5 +21,4 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
#endif /* __KERNEL__ */
-
#endif
diff --git a/arch/unicore32/include/mach/hardware.h b/arch/unicore32/include/mach/hardware.h
index 9e20b5d..2514623 100644
--- a/arch/unicore32/include/mach/hardware.h
+++ b/arch/unicore32/include/mach/hardware.h
@@ -28,11 +28,6 @@
#define PCIBIOS_MIN_IO 0x4000 /* should lower than 64KB */
#define PCIBIOS_MIN_MEM io_v2p(PKUNITY_PCIMEM_BASE)
-/*
- * We override the standard dma-mask routines for bouncing.
- */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
#define pcibios_assign_all_busses() 1
#endif /* __MACH_PUV3_HARDWARE_H__ */
diff --git a/arch/unicore32/kernel/gpio.c b/arch/unicore32/kernel/gpio.c
index cb12ec3..5ab2379 100644
--- a/arch/unicore32/kernel/gpio.c
+++ b/arch/unicore32/kernel/gpio.c
@@ -52,7 +52,7 @@ device_initcall(puv3_gpio_leds_init);
static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- return readl(GPIO_GPLR) & GPIO_GPIO(offset);
+ return !!(readl(GPIO_GPLR) & GPIO_GPIO(offset));
}
static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c
index 46ebfdc..aab5f34 100644
--- a/arch/unicore32/kernel/puv3-nb0916.c
+++ b/arch/unicore32/kernel/puv3-nb0916.c
@@ -19,6 +19,7 @@
#include <linux/reboot.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
@@ -49,11 +50,14 @@ static struct resource puv3_i2c_resources[] = {
}
};
+static struct pwm_lookup nb0916_pwm_lookup[] = {
+ PWM_LOOKUP("PKUnity-v3-PWM", 0, "pwm-backlight", NULL, 70 * 1024,
+ PWM_POLARITY_NORMAL),
+};
+
static struct platform_pwm_backlight_data nb0916_backlight_data = {
- .pwm_id = 0,
.max_brightness = 100,
.dft_brightness = 100,
- .pwm_period_ns = 70 * 1024,
.enable_gpio = -1,
};
@@ -112,6 +116,8 @@ int __init mach_nb0916_init(void)
platform_device_register_simple("PKUnity-v3-I2C", -1,
puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
+ pwm_add_table(nb0916_pwm_lookup, ARRAY_SIZE(nb0916_pwm_lookup));
+
platform_device_register_data(NULL, "pwm-backlight", -1,
&nb0916_backlight_data, sizeof(nb0916_backlight_data));
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c
index 3fa317f..c2bffa5 100644
--- a/arch/unicore32/kernel/setup.c
+++ b/arch/unicore32/kernel/setup.c
@@ -72,13 +72,13 @@ static struct resource mem_res[] = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
},
{
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_MEM
+ .flags = IORESOURCE_SYSTEM_RAM
}
};
@@ -211,7 +211,7 @@ request_standard_resources(struct meminfo *mi)
res->name = "System RAM";
res->start = mi->bank[i].start;
res->end = mi->bank[i].start + mi->bank[i].size - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index afccef552..2ec3d3a 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -276,7 +276,7 @@ retry:
up_read(&mm->mmap_sem);
/*
- * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
+ * Handle the "normal" case first - VM_FAULT_MAJOR
*/
if (likely(!(fault &
(VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
diff --git a/arch/unicore32/mm/pgd.c b/arch/unicore32/mm/pgd.c
index 2ade20d..c572a28 100644
--- a/arch/unicore32/mm/pgd.c
+++ b/arch/unicore32/mm/pgd.c
@@ -54,7 +54,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if (!new_pmd)
goto no_pmd;
- new_pte = pte_alloc_map(mm, NULL, new_pmd, 0);
+ new_pte = pte_alloc_map(mm, new_pmd, 0);
if (!new_pte)
goto no_pte;
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index 1538562..eb3abf8 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,6 +1,7 @@
-
obj-y += entry/
+obj-$(CONFIG_PERF_EVENTS) += events/
+
obj-$(CONFIG_KVM) += kvm/
# Xen paravirtualization support
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 96d058a..3c74b54 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -24,12 +24,14 @@ config X86
select ARCH_DISCARD_MEMBLOCK
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
+ select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_PMEM_API if X86_64
select ARCH_HAS_MMIO_FLUSH
select ARCH_HAS_SG_CHAIN
+ select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
select ARCH_MIGHT_HAVE_PC_PARPORT
@@ -82,6 +84,8 @@ config X86
select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP
select HAVE_ARCH_KGDB
select HAVE_ARCH_KMEMCHECK
+ select HAVE_ARCH_MMAP_RND_BITS if MMU
+ select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_SOFT_DIRTY if X86_64
select HAVE_ARCH_TRACEHOOK
@@ -96,7 +100,6 @@ config X86
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DMA_API_DEBUG
- select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_REGS
@@ -177,12 +180,23 @@ config LOCKDEP_SUPPORT
config STACKTRACE_SUPPORT
def_bool y
-config HAVE_LATENCYTOP_SUPPORT
- def_bool y
-
config MMU
def_bool y
+config ARCH_MMAP_RND_BITS_MIN
+ default 28 if 64BIT
+ default 8
+
+config ARCH_MMAP_RND_BITS_MAX
+ default 32 if 64BIT
+ default 16
+
+config ARCH_MMAP_RND_COMPAT_BITS_MIN
+ default 8
+
+config ARCH_MMAP_RND_COMPAT_BITS_MAX
+ default 16
+
config SBUS
bool
@@ -289,6 +303,9 @@ config ARCH_SUPPORTS_UPROBES
config FIX_EARLYCON_MEM
def_bool y
+config DEBUG_RODATA
+ def_bool y
+
config PGTABLE_LEVELS
int
default 4 if X86_64
@@ -349,6 +366,17 @@ config X86_FEATURE_NAMES
If in doubt, say Y.
+config X86_FAST_FEATURE_TESTS
+ bool "Fast CPU feature tests" if EMBEDDED
+ default y
+ ---help---
+ Some fast-paths in the kernel depend on the capabilities of the CPU.
+ Say Y here for the kernel to patch in the appropriate code at runtime
+ based on the capabilities of the CPU. The infrastructure for patching
+ code at runtime takes up some additional space; space-constrained
+ embedded systems may wish to say N here to produce smaller, slightly
+ slower code.
+
config X86_X2APIC
bool "Support x2apic"
depends on X86_LOCAL_APIC && X86_64 && (IRQ_REMAP || HYPERVISOR_GUEST)
@@ -450,6 +478,7 @@ config X86_UV
depends on X86_64
depends on X86_EXTENDED_PLATFORM
depends on NUMA
+ depends on EFI
depends on X86_X2APIC
depends on PCI
---help---
@@ -484,11 +513,10 @@ config X86_INTEL_CE
config X86_INTEL_MID
bool "Intel MID platform support"
- depends on X86_32
depends on X86_EXTENDED_PLATFORM
depends on X86_PLATFORM_DEVICES
depends on PCI
- depends on PCI_GOANY
+ depends on X86_64 || (PCI_GOANY && X86_32)
depends on X86_IO_APIC
select SFI
select I2C
@@ -523,9 +551,10 @@ config X86_INTEL_QUARK
config X86_INTEL_LPSS
bool "Intel Low Power Subsystem Support"
- depends on ACPI
+ depends on X86 && ACPI
select COMMON_CLK
select PINCTRL
+ select IOSF_MBI
---help---
Select to build support for Intel Low Power Subsystem such as
found on Intel Lynxpoint PCH. Selecting this option enables
@@ -687,6 +716,14 @@ config PARAVIRT_SPINLOCKS
If you are unsure how to answer this question, answer Y.
+config QUEUED_LOCK_STAT
+ bool "Paravirt queued spinlock statistics"
+ depends on PARAVIRT_SPINLOCKS && DEBUG_FS && QUEUED_SPINLOCKS
+ ---help---
+ Enable the collection of statistical data on the slowpath
+ behavior of paravirtualized queued spinlocks and report
+ them on debugfs.
+
source "arch/x86/xen/Kconfig"
config KVM_GUEST
@@ -744,8 +781,8 @@ config HPET_TIMER
HPET is the next generation timer replacing legacy 8254s.
The HPET provides a stable time base on SMP
systems, unlike the TSC, but it is more expensive to access,
- as it is off-chip. You can find the HPET spec at
- <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
+ as it is off-chip. The interface used is documented
+ in the HPET spec, revision 1.
You can safely choose Y here. However, HPET will only be
activated if the platform and the BIOS support this feature.
@@ -1123,23 +1160,26 @@ config X86_REBOOTFIXUPS
Say N otherwise.
config MICROCODE
- tristate "CPU microcode loading support"
+ bool "CPU microcode loading support"
+ default y
depends on CPU_SUP_AMD || CPU_SUP_INTEL
select FW_LOADER
---help---
-
If you say Y here, you will be able to update the microcode on
- certain Intel and AMD processors. The Intel support is for the
- IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
- Xeon etc. The AMD support is for families 0x10 and later. You will
- obviously need the actual microcode binary data itself which is not
- shipped with the Linux kernel.
+ Intel and AMD processors. The Intel support is for the IA32 family,
+ e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4, Xeon etc. The
+ AMD support is for families 0x10 and later. You will obviously need
+ the actual microcode binary data itself which is not shipped with
+ the Linux kernel.
- This option selects the general module only, you need to select
- at least one vendor specific module as well.
+ The preferred method to load microcode from a detached initrd is described
+ in Documentation/x86/early-microcode.txt. For that you need to enable
+ CONFIG_BLK_DEV_INITRD in order for the loader to be able to scan the
+ initrd for microcode blobs.
- To compile this driver as a module, choose M here: the module
- will be called microcode.
+ In addition, you can build-in the microcode into the kernel. For that you
+ need to enable FIRMWARE_IN_KERNEL and add the vendor-supplied microcode
+ to the CONFIG_EXTRA_FIRMWARE config option.
config MICROCODE_INTEL
bool "Intel microcode loading support"
@@ -1166,24 +1206,6 @@ config MICROCODE_OLD_INTERFACE
def_bool y
depends on MICROCODE
-config MICROCODE_INTEL_EARLY
- bool
-
-config MICROCODE_AMD_EARLY
- bool
-
-config MICROCODE_EARLY
- bool "Early load microcode"
- depends on MICROCODE=y && BLK_DEV_INITRD
- select MICROCODE_INTEL_EARLY if MICROCODE_INTEL
- select MICROCODE_AMD_EARLY if MICROCODE_AMD
- default y
- help
- This option provides functionality to read additional microcode data
- at the beginning of initrd image. The data tells kernel to load
- microcode to CPU's as early as possible. No functional change if no
- microcode data is glued to the initrd, therefore it's safe to say Y.
-
config X86_MSR
tristate "/dev/cpu/*/msr - Model-specific register support"
---help---
@@ -2043,6 +2065,55 @@ config COMPAT_VDSO
If unsure, say N: if you are compiling your own kernel, you
are unlikely to be using a buggy version of glibc.
+choice
+ prompt "vsyscall table for legacy applications"
+ depends on X86_64
+ default LEGACY_VSYSCALL_EMULATE
+ help
+ Legacy user code that does not know how to find the vDSO expects
+ to be able to issue three syscalls by calling fixed addresses in
+ kernel space. Since this location is not randomized with ASLR,
+ it can be used to assist security vulnerability exploitation.
+
+ This setting can be changed at boot time via the kernel command
+ line parameter vsyscall=[native|emulate|none].
+
+ On a system with recent enough glibc (2.14 or newer) and no
+ static binaries, you can say None without a performance penalty
+ to improve security.
+
+ If unsure, select "Emulate".
+
+ config LEGACY_VSYSCALL_NATIVE
+ bool "Native"
+ help
+ Actual executable code is located in the fixed vsyscall
+ address mapping, implementing time() efficiently. Since
+ this makes the mapping executable, it can be used during
+ security vulnerability exploitation (traditionally as
+ ROP gadgets). This configuration is not recommended.
+
+ config LEGACY_VSYSCALL_EMULATE
+ bool "Emulate"
+ help
+ The kernel traps and emulates calls into the fixed
+ vsyscall address mapping. This makes the mapping
+ non-executable, but it still contains known contents,
+ which could be used in certain rare security vulnerability
+ exploits. This configuration is recommended when userspace
+ still uses the vsyscall area.
+
+ config LEGACY_VSYSCALL_NONE
+ bool "None"
+ help
+ There will be no vsyscall mapping at all. This will
+ eliminate any risk of ASLR bypass due to the vsyscall
+ fixed address mapping. Attempts to use the vsyscalls
+ will be reported to dmesg, so that either old or
+ malicious userspace programs can be identified.
+
+endchoice
+
config CMDLINE_BOOL
bool "Built-in kernel command line"
---help---
@@ -2364,8 +2435,6 @@ config PCI_CNB20LE_QUIRK
You should say N unless you know you need this.
-source "drivers/pci/pcie/Kconfig"
-
source "drivers/pci/Kconfig"
# x86_64 have no ISA slots, but can have ISA-style DMA.
@@ -2521,8 +2590,6 @@ config AMD_NB
source "drivers/pcmcia/Kconfig"
-source "drivers/pci/hotplug/Kconfig"
-
config RAPIDIO
tristate "RapidIO support"
depends on PCI
@@ -2632,6 +2699,19 @@ config PMC_ATOM
def_bool y
depends on PCI
+config VMD
+ depends on PCI_MSI
+ tristate "Volume Management Device Driver"
+ default N
+ ---help---
+ Adds support for the Intel Volume Management Device (VMD). VMD is a
+ secondary PCI host bridge that allows PCI Express root ports,
+ and devices attached to them, to be removed from the default
+ PCI domain and placed within the VMD domain. This provides
+ more bus resources than are otherwise possible with a
+ single domain. If you know your system provides one of these and
+ has devices attached to it, say Y; if you are not sure, say N.
+
source "net/Kconfig"
source "drivers/Kconfig"
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 6983314..3ba5ff2 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -3,10 +3,6 @@ choice
prompt "Processor family"
default M686 if X86_32
default GENERIC_CPU if X86_64
-
-config M486
- bool "486"
- depends on X86_32
---help---
This is the processor type of your CPU. This information is
used for optimizing purposes. In order to compile a kernel
@@ -23,9 +19,9 @@ config M486
Here are the settings recommended for greatest speed:
- "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
- SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+ SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
- "586" for generic Pentium CPUs lacking the TSC
- (time stamp counter) register.
+ (time stamp counter) register.
- "Pentium-Classic" for the Intel Pentium.
- "Pentium-MMX" for the Intel Pentium MMX.
- "Pentium-Pro" for the Intel Pentium Pro.
@@ -34,17 +30,31 @@ config M486
- "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
- "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
- "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+ - "Opteron/Athlon64/Hammer/K8" for all K8 and newer AMD CPUs.
- "Crusoe" for the Transmeta Crusoe series.
- "Efficeon" for the Transmeta Efficeon series.
- "Winchip-C6" for original IDT Winchip.
- "Winchip-2" for IDT Winchips with 3dNow! capabilities.
+ - "AMD Elan" for the 32-bit AMD Elan embedded CPU.
- "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
- "Geode GX/LX" For AMD Geode GX and LX processors.
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
- "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above).
- "VIA C7" for VIA C7.
+ - "Intel P4" for the Pentium 4/Netburst microarchitecture.
+ - "Core 2/newer Xeon" for all core2 and newer Intel CPUs.
+ - "Intel Atom" for the Atom-microarchitecture CPUs.
+ - "Generic-x86-64" for a kernel which runs on any x86-64 CPU.
+
+ See each option's help text for additional details. If you don't know
+ what to do, choose "486".
- If you don't know what to do, choose "486".
+config M486
+ bool "486"
+ depends on X86_32
+ ---help---
+ Select this for an 486-class CPU such as AMD/Cyrix/IBM/Intel
+ 486DX/DX2/DX4 or SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
config M586
bool "586/K5/5x86/6x86/6x86MX"
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index d8c0d32..67eec55 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -5,23 +5,6 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug"
-config STRICT_DEVMEM
- bool "Filter access to /dev/mem"
- ---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. Note that with PAT support
- enabled, even in this case there are restrictions on /dev/mem
- use due to the cache aliasing requirements.
-
- If this option is switched on, the /dev/mem file only allows
- userspace access to PCI space and the BIOS code and data regions.
- This is sufficient for dosemu and X and all common users of
- /dev/mem.
-
- If in doubt, say Y.
-
config X86_VERBOSE_BOOTUP
bool "Enable verbose x86 bootup info messages"
default y
@@ -65,10 +48,14 @@ config EARLY_PRINTK_EFI
This is useful for kernel debugging when your machine crashes very
early before the console code is initialized.
+config X86_PTDUMP_CORE
+ def_bool n
+
config X86_PTDUMP
- bool "Export kernel pagetable layout to userspace via debugfs"
+ tristate "Export kernel pagetable layout to userspace via debugfs"
depends on DEBUG_KERNEL
select DEBUG_FS
+ select X86_PTDUMP_CORE
---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
@@ -79,32 +66,49 @@ config X86_PTDUMP
config EFI_PGT_DUMP
bool "Dump the EFI pagetable"
- depends on EFI && X86_PTDUMP
+ depends on EFI
+ select X86_PTDUMP_CORE
---help---
Enable this if you want to dump the EFI page table before
enabling virtual mode. This can be used to debug miscellaneous
issues with the mapping of the EFI runtime regions into that
table.
-config DEBUG_RODATA
- bool "Write protect kernel read-only data structures"
- default y
- depends on DEBUG_KERNEL
- ---help---
- Mark the kernel read-only data as write-protected in the pagetables,
- in order to catch accidental (and incorrect) writes to such const
- data. This is recommended so that we can catch kernel bugs sooner.
- If in doubt, say "Y".
-
config DEBUG_RODATA_TEST
- bool "Testcase for the DEBUG_RODATA feature"
- depends on DEBUG_RODATA
+ bool "Testcase for the marking rodata read-only"
default y
---help---
- This option enables a testcase for the DEBUG_RODATA
- feature as well as for the change_page_attr() infrastructure.
+ This option enables a testcase for the setting rodata read-only
+ as well as for the change_page_attr() infrastructure.
If in doubt, say "N"
+config DEBUG_WX
+ bool "Warn on W+X mappings at boot"
+ select X86_PTDUMP_CORE
+ ---help---
+ Generate a warning if any W+X mappings are found at boot.
+
+ This is useful for discovering cases where the kernel is leaving
+ W+X mappings after applying NX, as such mappings are a security risk.
+
+ Look for a message in dmesg output like this:
+
+ x86/mm: Checked W+X mappings: passed, no W+X pages found.
+
+ or like this, if the check failed:
+
+ x86/mm: Checked W+X mappings: FAILED, <N> W+X pages found.
+
+ Note that even if the check fails, your kernel is possibly
+ still fine, as W+X mappings are not a security hole in
+ themselves, what they do is that they make the exploitation
+ of other unfixed kernel bugs easier.
+
+ There is no runtime or memory usage effect of this option
+ once the kernel has booted up - it's a one time check.
+
+ If in doubt, say "Y".
+
config DEBUG_SET_MODULE_RONX
bool "Set loadable kernel module data as NX and text as RO"
depends on MODULES
@@ -334,16 +338,6 @@ config DEBUG_IMR_SELFTEST
If unsure say N here.
-config X86_DEBUG_STATIC_CPU_HAS
- bool "Debug alternatives"
- depends on DEBUG_KERNEL
- ---help---
- This option causes additional code to be generated which
- fails if static_cpu_has() is used before alternatives have
- run.
-
- If unsure, say N.
-
config X86_DEBUG_FPU
bool "Debug the x86 FPU code"
depends on DEBUG_KERNEL
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 747860c..4086abc 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -159,15 +159,23 @@ endif
sp-$(CONFIG_X86_32) := esp
sp-$(CONFIG_X86_64) := rsp
+# do binutils support CFI?
+cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
+# is .cfi_signal_frame supported too?
+cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
+cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)
+
# does binutils support specific instructions?
asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1)
asinstr += $(call as-instr,pshufb %xmm0$(comma)%xmm0,-DCONFIG_AS_SSSE3=1)
asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1)
avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1)
avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1)
+sha1_ni_instr :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA1_NI=1)
+sha256_ni_instr :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA256_NI=1)
-KBUILD_AFLAGS += $(asinstr) $(avx_instr) $(avx2_instr)
-KBUILD_CFLAGS += $(asinstr) $(avx_instr) $(avx2_instr)
+KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(sha1_ni_instr) $(sha256_ni_instr)
+KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(sha1_ni_instr) $(sha256_ni_instr)
LDFLAGS := -m elf_$(UTS_MACHINE)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 0d553e5..bbe1a62 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -9,13 +9,13 @@
# Changed by many, many contributors over the years.
#
+KASAN_SANITIZE := n
+
# If you want to preset the SVGA mode, uncomment the next line and
# set SVGA_MODE to whatever number you want.
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
# The number is the same as you would ordinarily press at bootup.
-KASAN_SANITIZE := n
-
SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
targets := vmlinux.bin setup.bin setup.elf bzImage
@@ -60,6 +60,7 @@ clean-files += cpustr.h
KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
+UBSAN_SANITIZE := n
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index 0033e96..9011a88 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -23,7 +23,6 @@
#include <stdarg.h>
#include <linux/types.h>
#include <linux/edd.h>
-#include <asm/boot.h>
#include <asm/setup.h>
#include "bitops.h"
#include "ctype.h"
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 0a291cd..f9ce75d 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -33,6 +33,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
+UBSAN_SANITIZE :=n
LDFLAGS := -m elf_$(UTS_MACHINE)
LDFLAGS_vmlinux := -T
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index db51c1f..583d539 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -624,7 +624,7 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
static efi_status_t
__gop_query32(struct efi_graphics_output_protocol_32 *gop32,
struct efi_graphics_output_mode_info **info,
- unsigned long *size, u32 *fb_base)
+ unsigned long *size, u64 *fb_base)
{
struct efi_graphics_output_protocol_mode_32 *mode;
efi_status_t status;
@@ -650,7 +650,8 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
unsigned long nr_gops;
u16 width, height;
u32 pixels_per_scan_line;
- u32 fb_base;
+ u32 ext_lfb_base;
+ u64 fb_base;
struct efi_pixel_bitmask pixel_info;
int pixel_format;
efi_status_t status;
@@ -667,7 +668,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
bool conout_found = false;
void *dummy = NULL;
u32 h = handles[i];
- u32 current_fb_base;
+ u64 current_fb_base;
status = efi_call_early(handle_protocol, h,
proto, (void **)&gop32);
@@ -715,6 +716,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
si->lfb_width = width;
si->lfb_height = height;
si->lfb_base = fb_base;
+
+ ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+ if (ext_lfb_base) {
+ si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+ si->ext_lfb_base = ext_lfb_base;
+ }
+
si->pages = 1;
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
@@ -729,7 +737,7 @@ out:
static efi_status_t
__gop_query64(struct efi_graphics_output_protocol_64 *gop64,
struct efi_graphics_output_mode_info **info,
- unsigned long *size, u32 *fb_base)
+ unsigned long *size, u64 *fb_base)
{
struct efi_graphics_output_protocol_mode_64 *mode;
efi_status_t status;
@@ -755,7 +763,8 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
unsigned long nr_gops;
u16 width, height;
u32 pixels_per_scan_line;
- u32 fb_base;
+ u32 ext_lfb_base;
+ u64 fb_base;
struct efi_pixel_bitmask pixel_info;
int pixel_format;
efi_status_t status;
@@ -772,7 +781,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
bool conout_found = false;
void *dummy = NULL;
u64 h = handles[i];
- u32 current_fb_base;
+ u64 current_fb_base;
status = efi_call_early(handle_protocol, h,
proto, (void **)&gop64);
@@ -820,6 +829,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
si->lfb_width = width;
si->lfb_height = height;
si->lfb_base = fb_base;
+
+ ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+ if (ext_lfb_base) {
+ si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+ si->ext_lfb_base = ext_lfb_base;
+ }
+
si->pages = 1;
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h
index ea97697..4cb404f 100644
--- a/arch/x86/boot/cpuflags.h
+++ b/arch/x86/boot/cpuflags.h
@@ -1,7 +1,7 @@
#ifndef BOOT_CPUFLAGS_H
#define BOOT_CPUFLAGS_H
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/processor-flags.h>
struct cpu_features {
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 2d6b309..6236b9e 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -154,7 +154,7 @@ extra_header_fields:
#else
.quad 0 # ImageBase
#endif
- .long CONFIG_PHYSICAL_ALIGN # SectionAlignment
+ .long 0x20 # SectionAlignment
.long 0x20 # FileAlignment
.word 0 # MajorOperatingSystemVersion
.word 0 # MinorOperatingSystemVersion
diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c
index 637097e..f72498d 100644
--- a/arch/x86/boot/mkcpustr.c
+++ b/arch/x86/boot/mkcpustr.c
@@ -17,7 +17,7 @@
#include "../include/asm/required-features.h"
#include "../include/asm/disabled-features.h"
-#include "../include/asm/cpufeature.h"
+#include "../include/asm/cpufeatures.h"
#include "../kernel/cpu/capflags.c"
int main(void)
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index a7661c4..0702d25 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -49,7 +49,6 @@ typedef unsigned int u32;
/* This must be large enough to hold the entire setup */
u8 buf[SETUP_SECT_MAX*512];
-int is_big_kernel;
#define PECOFF_RELOC_RESERVE 0x20
diff --git a/arch/x86/boot/video-mode.c b/arch/x86/boot/video-mode.c
index aa8a96b..95c7a81 100644
--- a/arch/x86/boot/video-mode.c
+++ b/arch/x86/boot/video-mode.c
@@ -19,6 +19,8 @@
#include "video.h"
#include "vesa.h"
+#include <uapi/asm/boot.h>
+
/*
* Common variables
*/
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index 05111bb..77780e3 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -13,6 +13,8 @@
* Select video mode
*/
+#include <uapi/asm/boot.h>
+
#include "boot.h"
#include "video.h"
#include "vesa.h"
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 028be48..265901a 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -288,7 +288,7 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
-CONFIG_FRAME_WARN=2048
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
@@ -303,7 +303,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_RODATA_TEST is not set
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_OPTIMIZE_INLINING=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SELINUX=y
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index cb5b3ab..4f404a6 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -300,7 +300,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_RODATA_TEST is not set
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_OPTIMIZE_INLINING=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SELINUX=y
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9a2838c..b9b912a 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -5,6 +5,8 @@
avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
$(comma)4)$(comma)%ymm2,yes,no)
+sha1_ni_supported :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,yes,no)
+sha256_ni_supported :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,yes,no)
obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
@@ -91,9 +93,15 @@ ifeq ($(avx2_supported),yes)
sha1-ssse3-y += sha1_avx2_x86_64_asm.o
poly1305-x86_64-y += poly1305-avx2-x86_64.o
endif
+ifeq ($(sha1_ni_supported),yes)
+sha1-ssse3-y += sha1_ni_asm.o
+endif
crc32c-intel-y := crc32c-intel_glue.o
crc32c-intel-$(CONFIG_64BIT) += crc32c-pcl-intel-asm_64.o
crc32-pclmul-y := crc32-pclmul_asm.o crc32-pclmul_glue.o
sha256-ssse3-y := sha256-ssse3-asm.o sha256-avx-asm.o sha256-avx2-asm.o sha256_ssse3_glue.o
+ifeq ($(sha256_ni_supported),yes)
+sha256-ssse3-y += sha256_ni_asm.o
+endif
sha512-ssse3-y := sha512-ssse3-asm.o sha512-avx-asm.o sha512-avx2-asm.o sha512_ssse3_glue.o
crct10dif-pclmul-y := crct10dif-pcl-asm_64.o crct10dif-pclmul_glue.o
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 3633ad6..064c7e2 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -639,16 +639,11 @@ static int xts_aesni_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen / 2);
diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c
index 4c65c70..d844569 100644
--- a/arch/x86/crypto/camellia_aesni_avx2_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c
@@ -567,7 +567,8 @@ static int __init camellia_aesni_init(void)
return -ENODEV;
}
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c
index bacaa13..93d8f29 100644
--- a/arch/x86/crypto/camellia_aesni_avx_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c
@@ -559,7 +559,8 @@ static int __init camellia_aesni_init(void)
return -ENODEV;
}
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c
index 5c8b626..aa76cad 100644
--- a/arch/x86/crypto/camellia_glue.c
+++ b/arch/x86/crypto/camellia_glue.c
@@ -1503,13 +1503,9 @@ int xts_camellia_setkey(struct crypto_tfm *tfm, const u8 *key,
u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = __camellia_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c
index be00aa4..8648158 100644
--- a/arch/x86/crypto/cast5_avx_glue.c
+++ b/arch/x86/crypto/cast5_avx_glue.c
@@ -469,7 +469,8 @@ static int __init cast5_init(void)
{
const char *feature_name;
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c
index 5dbba72..50e6847 100644
--- a/arch/x86/crypto/cast6_avx_glue.c
+++ b/arch/x86/crypto/cast6_avx_glue.c
@@ -329,13 +329,9 @@ static int xts_cast6_setkey(struct crypto_tfm *tfm, const u8 *key,
u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
@@ -591,7 +587,8 @@ static int __init cast6_init(void)
{
const char *feature_name;
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/chacha20-ssse3-x86_64.S b/arch/x86/crypto/chacha20-ssse3-x86_64.S
index 712b130..3a33124 100644
--- a/arch/x86/crypto/chacha20-ssse3-x86_64.S
+++ b/arch/x86/crypto/chacha20-ssse3-x86_64.S
@@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3)
# done with the slightly better performing SSSE3 byte shuffling,
# 7/12-bit word rotation uses traditional shift+OR.
- sub $0x40,%rsp
+ mov %rsp,%r11
+ sub $0x80,%rsp
+ and $~63,%rsp
# x0..15[0-3] = s0..3[0..3]
movq 0x00(%rdi),%xmm1
@@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3)
pxor %xmm1,%xmm15
movdqu %xmm15,0xf0(%rsi)
- add $0x40,%rsp
+ mov %r11,%rsp
ret
ENDPROC(chacha20_4block_xor_ssse3)
diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c
index effe216..8baaff5 100644
--- a/arch/x86/crypto/chacha20_glue.c
+++ b/arch/x86/crypto/chacha20_glue.c
@@ -125,12 +125,12 @@ static struct crypto_alg alg = {
static int __init chacha20_simd_mod_init(void)
{
- if (!cpu_has_ssse3)
+ if (!boot_cpu_has(X86_FEATURE_SSSE3))
return -ENODEV;
#ifdef CONFIG_AS_AVX2
chacha20_use_avx2 = cpu_has_avx && cpu_has_avx2 &&
- cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL);
+ cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL);
#endif
return crypto_register_alg(&alg);
}
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
index 07d2c6c..27226df 100644
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ b/arch/x86/crypto/crc32-pclmul_glue.c
@@ -33,7 +33,7 @@
#include <linux/crc32.h>
#include <crypto/internal/hash.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/cpu_device_id.h>
#include <asm/fpu/api.h>
diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
index 81a595d..0857b1a 100644
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ b/arch/x86/crypto/crc32c-intel_glue.c
@@ -30,7 +30,7 @@
#include <linux/kernel.h>
#include <crypto/internal/hash.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/cpu_device_id.h>
#include <asm/fpu/internal.h>
@@ -257,7 +257,7 @@ static int __init crc32c_intel_mod_init(void)
if (!x86_match_cpu(crc32c_cpu_id))
return -ENODEV;
#ifdef CONFIG_X86_64
- if (cpu_has_pclmulqdq) {
+ if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) {
alg.update = crc32c_pcl_intel_update;
alg.finup = crc32c_pcl_intel_finup;
alg.digest = crc32c_pcl_intel_digest;
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
index 225be06..4fe27e0 100644
--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
@@ -330,7 +330,7 @@ ENDPROC(crc_pcl)
## PCLMULQDQ tables
## Table is 128 entries x 2 words (8 bytes) each
################################################################
-.section .rotata, "a", %progbits
+.section .rodata, "a", %progbits
.align 8
K_table:
.long 0x493c7d27, 0x00000001
diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c
index a3fcfc9..cd4df93 100644
--- a/arch/x86/crypto/crct10dif-pclmul_glue.c
+++ b/arch/x86/crypto/crct10dif-pclmul_glue.c
@@ -30,7 +30,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/fpu/api.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/cpu_device_id.h>
asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf,
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
index 440df0c..a69321a 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -219,6 +219,29 @@ static int ghash_async_final(struct ahash_request *req)
}
}
+static int ghash_async_import(struct ahash_request *req, const void *in)
+{
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ ghash_async_init(req);
+ memcpy(dctx, in, sizeof(*dctx));
+ return 0;
+
+}
+
+static int ghash_async_export(struct ahash_request *req, void *out)
+{
+ struct ahash_request *cryptd_req = ahash_request_ctx(req);
+ struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+ struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ memcpy(out, dctx, sizeof(*dctx));
+ return 0;
+
+}
+
static int ghash_async_digest(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -288,8 +311,11 @@ static struct ahash_alg ghash_async_alg = {
.final = ghash_async_final,
.setkey = ghash_async_setkey,
.digest = ghash_async_digest,
+ .export = ghash_async_export,
+ .import = ghash_async_import,
.halg = {
.digestsize = GHASH_DIGEST_SIZE,
+ .statesize = sizeof(struct ghash_desc_ctx),
.base = {
.cra_name = "ghash",
.cra_driver_name = "ghash-clmulni",
diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c
index f7170d7..4264a3d 100644
--- a/arch/x86/crypto/poly1305_glue.c
+++ b/arch/x86/crypto/poly1305_glue.c
@@ -184,7 +184,7 @@ static int __init poly1305_simd_mod_init(void)
#ifdef CONFIG_AS_AVX2
poly1305_use_avx2 = cpu_has_avx && cpu_has_avx2 &&
- cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL);
+ cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL);
alg.descsize = sizeof(struct poly1305_simd_desc_ctx);
if (poly1305_use_avx2)
alg.descsize += 10 * sizeof(u32);
diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c
index 7d838dc..6d19834 100644
--- a/arch/x86/crypto/serpent_avx2_glue.c
+++ b/arch/x86/crypto/serpent_avx2_glue.c
@@ -542,7 +542,8 @@ static int __init init(void)
pr_info("AVX2 instructions are not detected.\n");
return -ENODEV;
}
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
index da7dafc..6f778d3 100644
--- a/arch/x86/crypto/serpent_avx_glue.c
+++ b/arch/x86/crypto/serpent_avx_glue.c
@@ -332,16 +332,11 @@ int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
@@ -597,7 +592,8 @@ static int __init serpent_init(void)
{
const char *feature_name;
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c
index 3643dd5..8943407 100644
--- a/arch/x86/crypto/serpent_sse2_glue.c
+++ b/arch/x86/crypto/serpent_sse2_glue.c
@@ -309,16 +309,11 @@ static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
- u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c
index a841e97..a8a0224 100644
--- a/arch/x86/crypto/sha-mb/sha1_mb.c
+++ b/arch/x86/crypto/sha-mb/sha1_mb.c
@@ -762,6 +762,38 @@ static int sha1_mb_async_digest(struct ahash_request *req)
return crypto_ahash_digest(mcryptd_req);
}
+static int sha1_mb_async_export(struct ahash_request *req, void *out)
+{
+ struct ahash_request *mcryptd_req = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
+
+ memcpy(mcryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
+ return crypto_ahash_export(mcryptd_req, out);
+}
+
+static int sha1_mb_async_import(struct ahash_request *req, const void *in)
+{
+ struct ahash_request *mcryptd_req = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct sha1_mb_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct mcryptd_ahash *mcryptd_tfm = ctx->mcryptd_tfm;
+ struct crypto_shash *child = mcryptd_ahash_child(mcryptd_tfm);
+ struct mcryptd_hash_request_ctx *rctx;
+ struct shash_desc *desc;
+
+ memcpy(mcryptd_req, req, sizeof(*req));
+ ahash_request_set_tfm(mcryptd_req, &mcryptd_tfm->base);
+ rctx = ahash_request_ctx(mcryptd_req);
+ desc = &rctx->desc;
+ desc->tfm = child;
+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ return crypto_ahash_import(mcryptd_req, in);
+}
+
static int sha1_mb_async_init_tfm(struct crypto_tfm *tfm)
{
struct mcryptd_ahash *mcryptd_tfm;
@@ -796,8 +828,11 @@ static struct ahash_alg sha1_mb_async_alg = {
.final = sha1_mb_async_final,
.finup = sha1_mb_async_finup,
.digest = sha1_mb_async_digest,
+ .export = sha1_mb_async_export,
+ .import = sha1_mb_async_import,
.halg = {
.digestsize = SHA1_DIGEST_SIZE,
+ .statesize = sizeof(struct sha1_hash_ctx),
.base = {
.cra_name = "sha1",
.cra_driver_name = "sha1_mb",
diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
index 2ab9560..c420d89 100644
--- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
+++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
@@ -197,7 +197,7 @@ len_is_0:
vpinsrd $1, _args_digest+1*32(state , idx, 4), %xmm0, %xmm0
vpinsrd $2, _args_digest+2*32(state , idx, 4), %xmm0, %xmm0
vpinsrd $3, _args_digest+3*32(state , idx, 4), %xmm0, %xmm0
- movl 4*32(state, idx, 4), DWORD_tmp
+ movl _args_digest+4*32(state, idx, 4), DWORD_tmp
vmovdqu %xmm0, _result_digest(job_rax)
movl DWORD_tmp, _result_digest+1*16(job_rax)
diff --git a/arch/x86/crypto/sha1_ni_asm.S b/arch/x86/crypto/sha1_ni_asm.S
new file mode 100644
index 0000000..874a651
--- /dev/null
+++ b/arch/x86/crypto/sha1_ni_asm.S
@@ -0,0 +1,302 @@
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-1 update function
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ * Sean Gulley <sean.m.gulley@intel.com>
+ * Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * 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 Intel 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 <linux/linkage.h>
+
+#define DIGEST_PTR %rdi /* 1st arg */
+#define DATA_PTR %rsi /* 2nd arg */
+#define NUM_BLKS %rdx /* 3rd arg */
+
+#define RSPSAVE %rax
+
+/* gcc conversion */
+#define FRAME_SIZE 32 /* space for 2x16 bytes */
+
+#define ABCD %xmm0
+#define E0 %xmm1 /* Need two E's b/c they ping pong */
+#define E1 %xmm2
+#define MSG0 %xmm3
+#define MSG1 %xmm4
+#define MSG2 %xmm5
+#define MSG3 %xmm6
+#define SHUF_MASK %xmm7
+
+
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-1 update function
+ *
+ * The function takes a pointer to the current hash values, a pointer to the
+ * input data, and a number of 64 byte blocks to process. Once all blocks have
+ * been processed, the digest pointer is updated with the resulting hash value.
+ * The function only processes complete blocks, there is no functionality to
+ * store partial blocks. All message padding and hash value initialization must
+ * be done outside the update function.
+ *
+ * The indented lines in the loop are instructions related to rounds processing.
+ * The non-indented lines are instructions related to the message schedule.
+ *
+ * void sha1_ni_transform(uint32_t *digest, const void *data,
+ uint32_t numBlocks)
+ * digest : pointer to digest
+ * data: pointer to input data
+ * numBlocks: Number of blocks to process
+ */
+.text
+.align 32
+ENTRY(sha1_ni_transform)
+ mov %rsp, RSPSAVE
+ sub $FRAME_SIZE, %rsp
+ and $~0xF, %rsp
+
+ shl $6, NUM_BLKS /* convert to bytes */
+ jz .Ldone_hash
+ add DATA_PTR, NUM_BLKS /* pointer to end of data */
+
+ /* load initial hash values */
+ pinsrd $3, 1*16(DIGEST_PTR), E0
+ movdqu 0*16(DIGEST_PTR), ABCD
+ pand UPPER_WORD_MASK(%rip), E0
+ pshufd $0x1B, ABCD, ABCD
+
+ movdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), SHUF_MASK
+
+.Lloop0:
+ /* Save hash values for addition after rounds */
+ movdqa E0, (0*16)(%rsp)
+ movdqa ABCD, (1*16)(%rsp)
+
+ /* Rounds 0-3 */
+ movdqu 0*16(DATA_PTR), MSG0
+ pshufb SHUF_MASK, MSG0
+ paddd MSG0, E0
+ movdqa ABCD, E1
+ sha1rnds4 $0, E0, ABCD
+
+ /* Rounds 4-7 */
+ movdqu 1*16(DATA_PTR), MSG1
+ pshufb SHUF_MASK, MSG1
+ sha1nexte MSG1, E1
+ movdqa ABCD, E0
+ sha1rnds4 $0, E1, ABCD
+ sha1msg1 MSG1, MSG0
+
+ /* Rounds 8-11 */
+ movdqu 2*16(DATA_PTR), MSG2
+ pshufb SHUF_MASK, MSG2
+ sha1nexte MSG2, E0
+ movdqa ABCD, E1
+ sha1rnds4 $0, E0, ABCD
+ sha1msg1 MSG2, MSG1
+ pxor MSG2, MSG0
+
+ /* Rounds 12-15 */
+ movdqu 3*16(DATA_PTR), MSG3
+ pshufb SHUF_MASK, MSG3
+ sha1nexte MSG3, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG3, MSG0
+ sha1rnds4 $0, E1, ABCD
+ sha1msg1 MSG3, MSG2
+ pxor MSG3, MSG1
+
+ /* Rounds 16-19 */
+ sha1nexte MSG0, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG0, MSG1
+ sha1rnds4 $0, E0, ABCD
+ sha1msg1 MSG0, MSG3
+ pxor MSG0, MSG2
+
+ /* Rounds 20-23 */
+ sha1nexte MSG1, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG1, MSG2
+ sha1rnds4 $1, E1, ABCD
+ sha1msg1 MSG1, MSG0
+ pxor MSG1, MSG3
+
+ /* Rounds 24-27 */
+ sha1nexte MSG2, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG2, MSG3
+ sha1rnds4 $1, E0, ABCD
+ sha1msg1 MSG2, MSG1
+ pxor MSG2, MSG0
+
+ /* Rounds 28-31 */
+ sha1nexte MSG3, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG3, MSG0
+ sha1rnds4 $1, E1, ABCD
+ sha1msg1 MSG3, MSG2
+ pxor MSG3, MSG1
+
+ /* Rounds 32-35 */
+ sha1nexte MSG0, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG0, MSG1
+ sha1rnds4 $1, E0, ABCD
+ sha1msg1 MSG0, MSG3
+ pxor MSG0, MSG2
+
+ /* Rounds 36-39 */
+ sha1nexte MSG1, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG1, MSG2
+ sha1rnds4 $1, E1, ABCD
+ sha1msg1 MSG1, MSG0
+ pxor MSG1, MSG3
+
+ /* Rounds 40-43 */
+ sha1nexte MSG2, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG2, MSG3
+ sha1rnds4 $2, E0, ABCD
+ sha1msg1 MSG2, MSG1
+ pxor MSG2, MSG0
+
+ /* Rounds 44-47 */
+ sha1nexte MSG3, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG3, MSG0
+ sha1rnds4 $2, E1, ABCD
+ sha1msg1 MSG3, MSG2
+ pxor MSG3, MSG1
+
+ /* Rounds 48-51 */
+ sha1nexte MSG0, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG0, MSG1
+ sha1rnds4 $2, E0, ABCD
+ sha1msg1 MSG0, MSG3
+ pxor MSG0, MSG2
+
+ /* Rounds 52-55 */
+ sha1nexte MSG1, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG1, MSG2
+ sha1rnds4 $2, E1, ABCD
+ sha1msg1 MSG1, MSG0
+ pxor MSG1, MSG3
+
+ /* Rounds 56-59 */
+ sha1nexte MSG2, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG2, MSG3
+ sha1rnds4 $2, E0, ABCD
+ sha1msg1 MSG2, MSG1
+ pxor MSG2, MSG0
+
+ /* Rounds 60-63 */
+ sha1nexte MSG3, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG3, MSG0
+ sha1rnds4 $3, E1, ABCD
+ sha1msg1 MSG3, MSG2
+ pxor MSG3, MSG1
+
+ /* Rounds 64-67 */
+ sha1nexte MSG0, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG0, MSG1
+ sha1rnds4 $3, E0, ABCD
+ sha1msg1 MSG0, MSG3
+ pxor MSG0, MSG2
+
+ /* Rounds 68-71 */
+ sha1nexte MSG1, E1
+ movdqa ABCD, E0
+ sha1msg2 MSG1, MSG2
+ sha1rnds4 $3, E1, ABCD
+ pxor MSG1, MSG3
+
+ /* Rounds 72-75 */
+ sha1nexte MSG2, E0
+ movdqa ABCD, E1
+ sha1msg2 MSG2, MSG3
+ sha1rnds4 $3, E0, ABCD
+
+ /* Rounds 76-79 */
+ sha1nexte MSG3, E1
+ movdqa ABCD, E0
+ sha1rnds4 $3, E1, ABCD
+
+ /* Add current hash values with previously saved */
+ sha1nexte (0*16)(%rsp), E0
+ paddd (1*16)(%rsp), ABCD
+
+ /* Increment data pointer and loop if more to process */
+ add $64, DATA_PTR
+ cmp NUM_BLKS, DATA_PTR
+ jne .Lloop0
+
+ /* Write hash values back in the correct order */
+ pshufd $0x1B, ABCD, ABCD
+ movdqu ABCD, 0*16(DIGEST_PTR)
+ pextrd $3, E0, 1*16(DIGEST_PTR)
+
+.Ldone_hash:
+ mov RSPSAVE, %rsp
+
+ ret
+ENDPROC(sha1_ni_transform)
+
+.data
+
+.align 64
+PSHUFFLE_BYTE_FLIP_MASK:
+ .octa 0x000102030405060708090a0b0c0d0e0f
+UPPER_WORD_MASK:
+ .octa 0xFFFFFFFF000000000000000000000000
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
index 7c48e8b..dd14616 100644
--- a/arch/x86/crypto/sha1_ssse3_glue.c
+++ b/arch/x86/crypto/sha1_ssse3_glue.c
@@ -31,24 +31,11 @@
#include <crypto/sha1_base.h>
#include <asm/fpu/api.h>
+typedef void (sha1_transform_fn)(u32 *digest, const char *data,
+ unsigned int rounds);
-asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
- unsigned int rounds);
-#ifdef CONFIG_AS_AVX
-asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
- unsigned int rounds);
-#endif
-#ifdef CONFIG_AS_AVX2
-#define SHA1_AVX2_BLOCK_OPTSIZE 4 /* optimal 4*64 bytes of SHA1 blocks */
-
-asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
- unsigned int rounds);
-#endif
-
-static void (*sha1_transform_asm)(u32 *, const char *, unsigned int);
-
-static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
+static int sha1_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha1_transform_fn *sha1_xform)
{
struct sha1_state *sctx = shash_desc_ctx(desc);
@@ -61,14 +48,14 @@ static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
sha1_base_do_update(desc, data, len,
- (sha1_block_fn *)sha1_transform_asm);
+ (sha1_block_fn *)sha1_xform);
kernel_fpu_end();
return 0;
}
-static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
+static int sha1_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out, sha1_transform_fn *sha1_xform)
{
if (!irq_fpu_usable())
return crypto_sha1_finup(desc, data, len, out);
@@ -76,32 +63,37 @@ static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
if (len)
sha1_base_do_update(desc, data, len,
- (sha1_block_fn *)sha1_transform_asm);
- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_transform_asm);
+ (sha1_block_fn *)sha1_xform);
+ sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_xform);
kernel_fpu_end();
return sha1_base_finish(desc, out);
}
-/* Add padding and return the message digest. */
-static int sha1_ssse3_final(struct shash_desc *desc, u8 *out)
+asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
+ unsigned int rounds);
+
+static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
{
- return sha1_ssse3_finup(desc, NULL, 0, out);
+ return sha1_update(desc, data, len,
+ (sha1_transform_fn *) sha1_transform_ssse3);
}
-#ifdef CONFIG_AS_AVX2
-static void sha1_apply_transform_avx2(u32 *digest, const char *data,
- unsigned int rounds)
+static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
{
- /* Select the optimal transform based on data block size */
- if (rounds >= SHA1_AVX2_BLOCK_OPTSIZE)
- sha1_transform_avx2(digest, data, rounds);
- else
- sha1_transform_avx(digest, data, rounds);
+ return sha1_finup(desc, data, len, out,
+ (sha1_transform_fn *) sha1_transform_ssse3);
+}
+
+/* Add padding and return the message digest. */
+static int sha1_ssse3_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_ssse3_finup(desc, NULL, 0, out);
}
-#endif
-static struct shash_alg alg = {
+static struct shash_alg sha1_ssse3_alg = {
.digestsize = SHA1_DIGEST_SIZE,
.init = sha1_base_init,
.update = sha1_ssse3_update,
@@ -110,7 +102,7 @@ static struct shash_alg alg = {
.descsize = sizeof(struct sha1_state),
.base = {
.cra_name = "sha1",
- .cra_driver_name= "sha1-ssse3",
+ .cra_driver_name = "sha1-ssse3",
.cra_priority = 150,
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
.cra_blocksize = SHA1_BLOCK_SIZE,
@@ -118,10 +110,62 @@ static struct shash_alg alg = {
}
};
+static int register_sha1_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ return crypto_register_shash(&sha1_ssse3_alg);
+ return 0;
+}
+
+static void unregister_sha1_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ crypto_unregister_shash(&sha1_ssse3_alg);
+}
+
#ifdef CONFIG_AS_AVX
-static bool __init avx_usable(void)
+asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
+ unsigned int rounds);
+
+static int sha1_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
{
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+ return sha1_update(desc, data, len,
+ (sha1_transform_fn *) sha1_transform_avx);
+}
+
+static int sha1_avx_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha1_finup(desc, data, len, out,
+ (sha1_transform_fn *) sha1_transform_avx);
+}
+
+static int sha1_avx_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_avx_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha1_avx_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_base_init,
+ .update = sha1_avx_update,
+ .final = sha1_avx_final,
+ .finup = sha1_avx_finup,
+ .descsize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-avx",
+ .cra_priority = 160,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static bool avx_usable(void)
+{
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
if (cpu_has_avx)
pr_info("AVX detected but unusable.\n");
return false;
@@ -130,55 +174,197 @@ static bool __init avx_usable(void)
return true;
}
-#ifdef CONFIG_AS_AVX2
-static bool __init avx2_usable(void)
+static int register_sha1_avx(void)
+{
+ if (avx_usable())
+ return crypto_register_shash(&sha1_avx_alg);
+ return 0;
+}
+
+static void unregister_sha1_avx(void)
{
- if (avx_usable() && cpu_has_avx2 && boot_cpu_has(X86_FEATURE_BMI1) &&
- boot_cpu_has(X86_FEATURE_BMI2))
+ if (avx_usable())
+ crypto_unregister_shash(&sha1_avx_alg);
+}
+
+#else /* CONFIG_AS_AVX */
+static inline int register_sha1_avx(void) { return 0; }
+static inline void unregister_sha1_avx(void) { }
+#endif /* CONFIG_AS_AVX */
+
+
+#if defined(CONFIG_AS_AVX2) && (CONFIG_AS_AVX)
+#define SHA1_AVX2_BLOCK_OPTSIZE 4 /* optimal 4*64 bytes of SHA1 blocks */
+
+asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
+ unsigned int rounds);
+
+static bool avx2_usable(void)
+{
+ if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
+ && boot_cpu_has(X86_FEATURE_BMI1)
+ && boot_cpu_has(X86_FEATURE_BMI2))
return true;
return false;
}
+
+static void sha1_apply_transform_avx2(u32 *digest, const char *data,
+ unsigned int rounds)
+{
+ /* Select the optimal transform based on data block size */
+ if (rounds >= SHA1_AVX2_BLOCK_OPTSIZE)
+ sha1_transform_avx2(digest, data, rounds);
+ else
+ sha1_transform_avx(digest, data, rounds);
+}
+
+static int sha1_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha1_update(desc, data, len,
+ (sha1_transform_fn *) sha1_apply_transform_avx2);
+}
+
+static int sha1_avx2_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha1_finup(desc, data, len, out,
+ (sha1_transform_fn *) sha1_apply_transform_avx2);
+}
+
+static int sha1_avx2_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_avx2_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha1_avx2_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_base_init,
+ .update = sha1_avx2_update,
+ .final = sha1_avx2_final,
+ .finup = sha1_avx2_finup,
+ .descsize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-avx2",
+ .cra_priority = 170,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int register_sha1_avx2(void)
+{
+ if (avx2_usable())
+ return crypto_register_shash(&sha1_avx2_alg);
+ return 0;
+}
+
+static void unregister_sha1_avx2(void)
+{
+ if (avx2_usable())
+ crypto_unregister_shash(&sha1_avx2_alg);
+}
+
+#else
+static inline int register_sha1_avx2(void) { return 0; }
+static inline void unregister_sha1_avx2(void) { }
#endif
+
+#ifdef CONFIG_AS_SHA1_NI
+asmlinkage void sha1_ni_transform(u32 *digest, const char *data,
+ unsigned int rounds);
+
+static int sha1_ni_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha1_update(desc, data, len,
+ (sha1_transform_fn *) sha1_ni_transform);
+}
+
+static int sha1_ni_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha1_finup(desc, data, len, out,
+ (sha1_transform_fn *) sha1_ni_transform);
+}
+
+static int sha1_ni_final(struct shash_desc *desc, u8 *out)
+{
+ return sha1_ni_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha1_ni_alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_base_init,
+ .update = sha1_ni_update,
+ .final = sha1_ni_final,
+ .finup = sha1_ni_finup,
+ .descsize = sizeof(struct sha1_state),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-ni",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int register_sha1_ni(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SHA_NI))
+ return crypto_register_shash(&sha1_ni_alg);
+ return 0;
+}
+
+static void unregister_sha1_ni(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SHA_NI))
+ crypto_unregister_shash(&sha1_ni_alg);
+}
+
+#else
+static inline int register_sha1_ni(void) { return 0; }
+static inline void unregister_sha1_ni(void) { }
#endif
static int __init sha1_ssse3_mod_init(void)
{
- char *algo_name;
+ if (register_sha1_ssse3())
+ goto fail;
- /* test for SSSE3 first */
- if (cpu_has_ssse3) {
- sha1_transform_asm = sha1_transform_ssse3;
- algo_name = "SSSE3";
+ if (register_sha1_avx()) {
+ unregister_sha1_ssse3();
+ goto fail;
}
-#ifdef CONFIG_AS_AVX
- /* allow AVX to override SSSE3, it's a little faster */
- if (avx_usable()) {
- sha1_transform_asm = sha1_transform_avx;
- algo_name = "AVX";
-#ifdef CONFIG_AS_AVX2
- /* allow AVX2 to override AVX, it's a little faster */
- if (avx2_usable()) {
- sha1_transform_asm = sha1_apply_transform_avx2;
- algo_name = "AVX2";
- }
-#endif
+ if (register_sha1_avx2()) {
+ unregister_sha1_avx();
+ unregister_sha1_ssse3();
+ goto fail;
}
-#endif
- if (sha1_transform_asm) {
- pr_info("Using %s optimized SHA-1 implementation\n", algo_name);
- return crypto_register_shash(&alg);
+ if (register_sha1_ni()) {
+ unregister_sha1_avx2();
+ unregister_sha1_avx();
+ unregister_sha1_ssse3();
+ goto fail;
}
- pr_info("Neither AVX nor AVX2 nor SSSE3 is available/usable.\n");
+ return 0;
+fail:
return -ENODEV;
}
static void __exit sha1_ssse3_mod_fini(void)
{
- crypto_unregister_shash(&alg);
+ unregister_sha1_ni();
+ unregister_sha1_avx2();
+ unregister_sha1_avx();
+ unregister_sha1_ssse3();
}
module_init(sha1_ssse3_mod_init);
diff --git a/arch/x86/crypto/sha256_ni_asm.S b/arch/x86/crypto/sha256_ni_asm.S
new file mode 100644
index 0000000..748cdf2
--- /dev/null
+++ b/arch/x86/crypto/sha256_ni_asm.S
@@ -0,0 +1,353 @@
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-256 update function
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ * Sean Gulley <sean.m.gulley@intel.com>
+ * Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * 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 Intel 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 <linux/linkage.h>
+
+#define DIGEST_PTR %rdi /* 1st arg */
+#define DATA_PTR %rsi /* 2nd arg */
+#define NUM_BLKS %rdx /* 3rd arg */
+
+#define SHA256CONSTANTS %rax
+
+#define MSG %xmm0
+#define STATE0 %xmm1
+#define STATE1 %xmm2
+#define MSGTMP0 %xmm3
+#define MSGTMP1 %xmm4
+#define MSGTMP2 %xmm5
+#define MSGTMP3 %xmm6
+#define MSGTMP4 %xmm7
+
+#define SHUF_MASK %xmm8
+
+#define ABEF_SAVE %xmm9
+#define CDGH_SAVE %xmm10
+
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-256 update function
+ *
+ * The function takes a pointer to the current hash values, a pointer to the
+ * input data, and a number of 64 byte blocks to process. Once all blocks have
+ * been processed, the digest pointer is updated with the resulting hash value.
+ * The function only processes complete blocks, there is no functionality to
+ * store partial blocks. All message padding and hash value initialization must
+ * be done outside the update function.
+ *
+ * The indented lines in the loop are instructions related to rounds processing.
+ * The non-indented lines are instructions related to the message schedule.
+ *
+ * void sha256_ni_transform(uint32_t *digest, const void *data,
+ uint32_t numBlocks);
+ * digest : pointer to digest
+ * data: pointer to input data
+ * numBlocks: Number of blocks to process
+ */
+
+.text
+.align 32
+ENTRY(sha256_ni_transform)
+
+ shl $6, NUM_BLKS /* convert to bytes */
+ jz .Ldone_hash
+ add DATA_PTR, NUM_BLKS /* pointer to end of data */
+
+ /*
+ * load initial hash values
+ * Need to reorder these appropriately
+ * DCBA, HGFE -> ABEF, CDGH
+ */
+ movdqu 0*16(DIGEST_PTR), STATE0
+ movdqu 1*16(DIGEST_PTR), STATE1
+
+ pshufd $0xB1, STATE0, STATE0 /* CDAB */
+ pshufd $0x1B, STATE1, STATE1 /* EFGH */
+ movdqa STATE0, MSGTMP4
+ palignr $8, STATE1, STATE0 /* ABEF */
+ pblendw $0xF0, MSGTMP4, STATE1 /* CDGH */
+
+ movdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), SHUF_MASK
+ lea K256(%rip), SHA256CONSTANTS
+
+.Lloop0:
+ /* Save hash values for addition after rounds */
+ movdqa STATE0, ABEF_SAVE
+ movdqa STATE1, CDGH_SAVE
+
+ /* Rounds 0-3 */
+ movdqu 0*16(DATA_PTR), MSG
+ pshufb SHUF_MASK, MSG
+ movdqa MSG, MSGTMP0
+ paddd 0*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+
+ /* Rounds 4-7 */
+ movdqu 1*16(DATA_PTR), MSG
+ pshufb SHUF_MASK, MSG
+ movdqa MSG, MSGTMP1
+ paddd 1*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP1, MSGTMP0
+
+ /* Rounds 8-11 */
+ movdqu 2*16(DATA_PTR), MSG
+ pshufb SHUF_MASK, MSG
+ movdqa MSG, MSGTMP2
+ paddd 2*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP2, MSGTMP1
+
+ /* Rounds 12-15 */
+ movdqu 3*16(DATA_PTR), MSG
+ pshufb SHUF_MASK, MSG
+ movdqa MSG, MSGTMP3
+ paddd 3*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP3, MSGTMP4
+ palignr $4, MSGTMP2, MSGTMP4
+ paddd MSGTMP4, MSGTMP0
+ sha256msg2 MSGTMP3, MSGTMP0
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP3, MSGTMP2
+
+ /* Rounds 16-19 */
+ movdqa MSGTMP0, MSG
+ paddd 4*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP0, MSGTMP4
+ palignr $4, MSGTMP3, MSGTMP4
+ paddd MSGTMP4, MSGTMP1
+ sha256msg2 MSGTMP0, MSGTMP1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP0, MSGTMP3
+
+ /* Rounds 20-23 */
+ movdqa MSGTMP1, MSG
+ paddd 5*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP1, MSGTMP4
+ palignr $4, MSGTMP0, MSGTMP4
+ paddd MSGTMP4, MSGTMP2
+ sha256msg2 MSGTMP1, MSGTMP2
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP1, MSGTMP0
+
+ /* Rounds 24-27 */
+ movdqa MSGTMP2, MSG
+ paddd 6*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP2, MSGTMP4
+ palignr $4, MSGTMP1, MSGTMP4
+ paddd MSGTMP4, MSGTMP3
+ sha256msg2 MSGTMP2, MSGTMP3
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP2, MSGTMP1
+
+ /* Rounds 28-31 */
+ movdqa MSGTMP3, MSG
+ paddd 7*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP3, MSGTMP4
+ palignr $4, MSGTMP2, MSGTMP4
+ paddd MSGTMP4, MSGTMP0
+ sha256msg2 MSGTMP3, MSGTMP0
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP3, MSGTMP2
+
+ /* Rounds 32-35 */
+ movdqa MSGTMP0, MSG
+ paddd 8*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP0, MSGTMP4
+ palignr $4, MSGTMP3, MSGTMP4
+ paddd MSGTMP4, MSGTMP1
+ sha256msg2 MSGTMP0, MSGTMP1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP0, MSGTMP3
+
+ /* Rounds 36-39 */
+ movdqa MSGTMP1, MSG
+ paddd 9*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP1, MSGTMP4
+ palignr $4, MSGTMP0, MSGTMP4
+ paddd MSGTMP4, MSGTMP2
+ sha256msg2 MSGTMP1, MSGTMP2
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP1, MSGTMP0
+
+ /* Rounds 40-43 */
+ movdqa MSGTMP2, MSG
+ paddd 10*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP2, MSGTMP4
+ palignr $4, MSGTMP1, MSGTMP4
+ paddd MSGTMP4, MSGTMP3
+ sha256msg2 MSGTMP2, MSGTMP3
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP2, MSGTMP1
+
+ /* Rounds 44-47 */
+ movdqa MSGTMP3, MSG
+ paddd 11*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP3, MSGTMP4
+ palignr $4, MSGTMP2, MSGTMP4
+ paddd MSGTMP4, MSGTMP0
+ sha256msg2 MSGTMP3, MSGTMP0
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP3, MSGTMP2
+
+ /* Rounds 48-51 */
+ movdqa MSGTMP0, MSG
+ paddd 12*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP0, MSGTMP4
+ palignr $4, MSGTMP3, MSGTMP4
+ paddd MSGTMP4, MSGTMP1
+ sha256msg2 MSGTMP0, MSGTMP1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+ sha256msg1 MSGTMP0, MSGTMP3
+
+ /* Rounds 52-55 */
+ movdqa MSGTMP1, MSG
+ paddd 13*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP1, MSGTMP4
+ palignr $4, MSGTMP0, MSGTMP4
+ paddd MSGTMP4, MSGTMP2
+ sha256msg2 MSGTMP1, MSGTMP2
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+
+ /* Rounds 56-59 */
+ movdqa MSGTMP2, MSG
+ paddd 14*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ movdqa MSGTMP2, MSGTMP4
+ palignr $4, MSGTMP1, MSGTMP4
+ paddd MSGTMP4, MSGTMP3
+ sha256msg2 MSGTMP2, MSGTMP3
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+
+ /* Rounds 60-63 */
+ movdqa MSGTMP3, MSG
+ paddd 15*16(SHA256CONSTANTS), MSG
+ sha256rnds2 STATE0, STATE1
+ pshufd $0x0E, MSG, MSG
+ sha256rnds2 STATE1, STATE0
+
+ /* Add current hash values with previously saved */
+ paddd ABEF_SAVE, STATE0
+ paddd CDGH_SAVE, STATE1
+
+ /* Increment data pointer and loop if more to process */
+ add $64, DATA_PTR
+ cmp NUM_BLKS, DATA_PTR
+ jne .Lloop0
+
+ /* Write hash values back in the correct order */
+ pshufd $0x1B, STATE0, STATE0 /* FEBA */
+ pshufd $0xB1, STATE1, STATE1 /* DCHG */
+ movdqa STATE0, MSGTMP4
+ pblendw $0xF0, STATE1, STATE0 /* DCBA */
+ palignr $8, MSGTMP4, STATE1 /* HGFE */
+
+ movdqu STATE0, 0*16(DIGEST_PTR)
+ movdqu STATE1, 1*16(DIGEST_PTR)
+
+.Ldone_hash:
+
+ ret
+ENDPROC(sha256_ni_transform)
+
+.data
+.align 64
+K256:
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+PSHUFFLE_BYTE_FLIP_MASK:
+ .octa 0x0c0d0e0f08090a0b0405060700010203
diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c
index f8097fc..5f4d608 100644
--- a/arch/x86/crypto/sha256_ssse3_glue.c
+++ b/arch/x86/crypto/sha256_ssse3_glue.c
@@ -42,19 +42,10 @@
asmlinkage void sha256_transform_ssse3(u32 *digest, const char *data,
u64 rounds);
-#ifdef CONFIG_AS_AVX
-asmlinkage void sha256_transform_avx(u32 *digest, const char *data,
- u64 rounds);
-#endif
-#ifdef CONFIG_AS_AVX2
-asmlinkage void sha256_transform_rorx(u32 *digest, const char *data,
- u64 rounds);
-#endif
-
-static void (*sha256_transform_asm)(u32 *, const char *, u64);
+typedef void (sha256_transform_fn)(u32 *digest, const char *data, u64 rounds);
-static int sha256_ssse3_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
+static int sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha256_transform_fn *sha256_xform)
{
struct sha256_state *sctx = shash_desc_ctx(desc);
@@ -67,14 +58,14 @@ static int sha256_ssse3_update(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
sha256_base_do_update(desc, data, len,
- (sha256_block_fn *)sha256_transform_asm);
+ (sha256_block_fn *)sha256_xform);
kernel_fpu_end();
return 0;
}
-static int sha256_ssse3_finup(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
+static int sha256_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out, sha256_transform_fn *sha256_xform)
{
if (!irq_fpu_usable())
return crypto_sha256_finup(desc, data, len, out);
@@ -82,20 +73,32 @@ static int sha256_ssse3_finup(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
if (len)
sha256_base_do_update(desc, data, len,
- (sha256_block_fn *)sha256_transform_asm);
- sha256_base_do_finalize(desc, (sha256_block_fn *)sha256_transform_asm);
+ (sha256_block_fn *)sha256_xform);
+ sha256_base_do_finalize(desc, (sha256_block_fn *)sha256_xform);
kernel_fpu_end();
return sha256_base_finish(desc, out);
}
+static int sha256_ssse3_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha256_update(desc, data, len, sha256_transform_ssse3);
+}
+
+static int sha256_ssse3_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha256_finup(desc, data, len, out, sha256_transform_ssse3);
+}
+
/* Add padding and return the message digest. */
static int sha256_ssse3_final(struct shash_desc *desc, u8 *out)
{
return sha256_ssse3_finup(desc, NULL, 0, out);
}
-static struct shash_alg algs[] = { {
+static struct shash_alg sha256_ssse3_algs[] = { {
.digestsize = SHA256_DIGEST_SIZE,
.init = sha256_base_init,
.update = sha256_ssse3_update,
@@ -127,10 +130,77 @@ static struct shash_alg algs[] = { {
}
} };
+static int register_sha256_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ return crypto_register_shashes(sha256_ssse3_algs,
+ ARRAY_SIZE(sha256_ssse3_algs));
+ return 0;
+}
+
+static void unregister_sha256_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ crypto_unregister_shashes(sha256_ssse3_algs,
+ ARRAY_SIZE(sha256_ssse3_algs));
+}
+
#ifdef CONFIG_AS_AVX
-static bool __init avx_usable(void)
+asmlinkage void sha256_transform_avx(u32 *digest, const char *data,
+ u64 rounds);
+
+static int sha256_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha256_update(desc, data, len, sha256_transform_avx);
+}
+
+static int sha256_avx_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha256_finup(desc, data, len, out, sha256_transform_avx);
+}
+
+static int sha256_avx_final(struct shash_desc *desc, u8 *out)
+{
+ return sha256_avx_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha256_avx_algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = sha256_avx_update,
+ .final = sha256_avx_final,
+ .finup = sha256_avx_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-avx",
+ .cra_priority = 160,
+ .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_avx_update,
+ .final = sha256_avx_final,
+ .finup = sha256_avx_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-avx",
+ .cra_priority = 160,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static bool avx_usable(void)
{
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
if (cpu_has_avx)
pr_info("AVX detected but unusable.\n");
return false;
@@ -138,47 +208,216 @@ static bool __init avx_usable(void)
return true;
}
-#endif
-static int __init sha256_ssse3_mod_init(void)
+static int register_sha256_avx(void)
{
- /* test for SSSE3 first */
- if (cpu_has_ssse3)
- sha256_transform_asm = sha256_transform_ssse3;
+ if (avx_usable())
+ return crypto_register_shashes(sha256_avx_algs,
+ ARRAY_SIZE(sha256_avx_algs));
+ return 0;
+}
-#ifdef CONFIG_AS_AVX
- /* allow AVX to override SSSE3, it's a little faster */
- if (avx_usable()) {
-#ifdef CONFIG_AS_AVX2
- if (boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_BMI2))
- sha256_transform_asm = sha256_transform_rorx;
- else
+static void unregister_sha256_avx(void)
+{
+ if (avx_usable())
+ crypto_unregister_shashes(sha256_avx_algs,
+ ARRAY_SIZE(sha256_avx_algs));
+}
+
+#else
+static inline int register_sha256_avx(void) { return 0; }
+static inline void unregister_sha256_avx(void) { }
#endif
- sha256_transform_asm = sha256_transform_avx;
+
+#if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX)
+asmlinkage void sha256_transform_rorx(u32 *digest, const char *data,
+ u64 rounds);
+
+static int sha256_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha256_update(desc, data, len, sha256_transform_rorx);
+}
+
+static int sha256_avx2_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha256_finup(desc, data, len, out, sha256_transform_rorx);
+}
+
+static int sha256_avx2_final(struct shash_desc *desc, u8 *out)
+{
+ return sha256_avx2_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha256_avx2_algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = sha256_avx2_update,
+ .final = sha256_avx2_final,
+ .finup = sha256_avx2_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-avx2",
+ .cra_priority = 170,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
}
-#endif
+}, {
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_base_init,
+ .update = sha256_avx2_update,
+ .final = sha256_avx2_final,
+ .finup = sha256_avx2_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-avx2",
+ .cra_priority = 170,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
- if (sha256_transform_asm) {
-#ifdef CONFIG_AS_AVX
- if (sha256_transform_asm == sha256_transform_avx)
- pr_info("Using AVX optimized SHA-256 implementation\n");
-#ifdef CONFIG_AS_AVX2
- else if (sha256_transform_asm == sha256_transform_rorx)
- pr_info("Using AVX2 optimized SHA-256 implementation\n");
+static bool avx2_usable(void)
+{
+ if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) &&
+ boot_cpu_has(X86_FEATURE_BMI2))
+ return true;
+
+ return false;
+}
+
+static int register_sha256_avx2(void)
+{
+ if (avx2_usable())
+ return crypto_register_shashes(sha256_avx2_algs,
+ ARRAY_SIZE(sha256_avx2_algs));
+ return 0;
+}
+
+static void unregister_sha256_avx2(void)
+{
+ if (avx2_usable())
+ crypto_unregister_shashes(sha256_avx2_algs,
+ ARRAY_SIZE(sha256_avx2_algs));
+}
+
+#else
+static inline int register_sha256_avx2(void) { return 0; }
+static inline void unregister_sha256_avx2(void) { }
#endif
- else
+
+#ifdef CONFIG_AS_SHA256_NI
+asmlinkage void sha256_ni_transform(u32 *digest, const char *data,
+ u64 rounds); /*unsigned int rounds);*/
+
+static int sha256_ni_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha256_update(desc, data, len, sha256_ni_transform);
+}
+
+static int sha256_ni_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha256_finup(desc, data, len, out, sha256_ni_transform);
+}
+
+static int sha256_ni_final(struct shash_desc *desc, u8 *out)
+{
+ return sha256_ni_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha256_ni_algs[] = { {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_base_init,
+ .update = sha256_ni_update,
+ .final = sha256_ni_final,
+ .finup = sha256_ni_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-ni",
+ .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_ni_update,
+ .final = sha256_ni_final,
+ .finup = sha256_ni_finup,
+ .descsize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-ni",
+ .cra_priority = 250,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static int register_sha256_ni(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SHA_NI))
+ return crypto_register_shashes(sha256_ni_algs,
+ ARRAY_SIZE(sha256_ni_algs));
+ return 0;
+}
+
+static void unregister_sha256_ni(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SHA_NI))
+ crypto_unregister_shashes(sha256_ni_algs,
+ ARRAY_SIZE(sha256_ni_algs));
+}
+
+#else
+static inline int register_sha256_ni(void) { return 0; }
+static inline void unregister_sha256_ni(void) { }
#endif
- pr_info("Using SSSE3 optimized SHA-256 implementation\n");
- return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+
+static int __init sha256_ssse3_mod_init(void)
+{
+ if (register_sha256_ssse3())
+ goto fail;
+
+ if (register_sha256_avx()) {
+ unregister_sha256_ssse3();
+ goto fail;
}
- pr_info("Neither AVX nor SSSE3 is available/usable.\n");
+ if (register_sha256_avx2()) {
+ unregister_sha256_avx();
+ unregister_sha256_ssse3();
+ goto fail;
+ }
+
+ if (register_sha256_ni()) {
+ unregister_sha256_avx2();
+ unregister_sha256_avx();
+ unregister_sha256_ssse3();
+ goto fail;
+ }
+
+ return 0;
+fail:
return -ENODEV;
}
static void __exit sha256_ssse3_mod_fini(void)
{
- crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+ unregister_sha256_ni();
+ unregister_sha256_avx2();
+ unregister_sha256_avx();
+ unregister_sha256_ssse3();
}
module_init(sha256_ssse3_mod_init);
diff --git a/arch/x86/crypto/sha512_ssse3_glue.c b/arch/x86/crypto/sha512_ssse3_glue.c
index 2edad7b..34e5083 100644
--- a/arch/x86/crypto/sha512_ssse3_glue.c
+++ b/arch/x86/crypto/sha512_ssse3_glue.c
@@ -41,19 +41,11 @@
asmlinkage void sha512_transform_ssse3(u64 *digest, const char *data,
u64 rounds);
-#ifdef CONFIG_AS_AVX
-asmlinkage void sha512_transform_avx(u64 *digest, const char *data,
- u64 rounds);
-#endif
-#ifdef CONFIG_AS_AVX2
-asmlinkage void sha512_transform_rorx(u64 *digest, const char *data,
- u64 rounds);
-#endif
-static void (*sha512_transform_asm)(u64 *, const char *, u64);
+typedef void (sha512_transform_fn)(u64 *digest, const char *data, u64 rounds);
-static int sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
+static int sha512_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha512_transform_fn *sha512_xform)
{
struct sha512_state *sctx = shash_desc_ctx(desc);
@@ -66,14 +58,14 @@ static int sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
sha512_base_do_update(desc, data, len,
- (sha512_block_fn *)sha512_transform_asm);
+ (sha512_block_fn *)sha512_xform);
kernel_fpu_end();
return 0;
}
-static int sha512_ssse3_finup(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
+static int sha512_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out, sha512_transform_fn *sha512_xform)
{
if (!irq_fpu_usable())
return crypto_sha512_finup(desc, data, len, out);
@@ -81,20 +73,32 @@ static int sha512_ssse3_finup(struct shash_desc *desc, const u8 *data,
kernel_fpu_begin();
if (len)
sha512_base_do_update(desc, data, len,
- (sha512_block_fn *)sha512_transform_asm);
- sha512_base_do_finalize(desc, (sha512_block_fn *)sha512_transform_asm);
+ (sha512_block_fn *)sha512_xform);
+ sha512_base_do_finalize(desc, (sha512_block_fn *)sha512_xform);
kernel_fpu_end();
return sha512_base_finish(desc, out);
}
+static int sha512_ssse3_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha512_update(desc, data, len, sha512_transform_ssse3);
+}
+
+static int sha512_ssse3_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha512_finup(desc, data, len, out, sha512_transform_ssse3);
+}
+
/* Add padding and return the message digest. */
static int sha512_ssse3_final(struct shash_desc *desc, u8 *out)
{
return sha512_ssse3_finup(desc, NULL, 0, out);
}
-static struct shash_alg algs[] = { {
+static struct shash_alg sha512_ssse3_algs[] = { {
.digestsize = SHA512_DIGEST_SIZE,
.init = sha512_base_init,
.update = sha512_ssse3_update,
@@ -126,10 +130,27 @@ static struct shash_alg algs[] = { {
}
} };
+static int register_sha512_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ return crypto_register_shashes(sha512_ssse3_algs,
+ ARRAY_SIZE(sha512_ssse3_algs));
+ return 0;
+}
+
+static void unregister_sha512_ssse3(void)
+{
+ if (boot_cpu_has(X86_FEATURE_SSSE3))
+ crypto_unregister_shashes(sha512_ssse3_algs,
+ ARRAY_SIZE(sha512_ssse3_algs));
+}
+
#ifdef CONFIG_AS_AVX
-static bool __init avx_usable(void)
+asmlinkage void sha512_transform_avx(u64 *digest, const char *data,
+ u64 rounds);
+static bool avx_usable(void)
{
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, NULL)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
if (cpu_has_avx)
pr_info("AVX detected but unusable.\n");
return false;
@@ -137,47 +158,185 @@ static bool __init avx_usable(void)
return true;
}
-#endif
-static int __init sha512_ssse3_mod_init(void)
+static int sha512_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
{
- /* test for SSSE3 first */
- if (cpu_has_ssse3)
- sha512_transform_asm = sha512_transform_ssse3;
+ return sha512_update(desc, data, len, sha512_transform_avx);
+}
-#ifdef CONFIG_AS_AVX
- /* allow AVX to override SSSE3, it's a little faster */
- if (avx_usable()) {
-#ifdef CONFIG_AS_AVX2
- if (boot_cpu_has(X86_FEATURE_AVX2))
- sha512_transform_asm = sha512_transform_rorx;
- else
-#endif
- sha512_transform_asm = sha512_transform_avx;
+static int sha512_avx_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha512_finup(desc, data, len, out, sha512_transform_avx);
+}
+
+/* Add padding and return the message digest. */
+static int sha512_avx_final(struct shash_desc *desc, u8 *out)
+{
+ return sha512_avx_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha512_avx_algs[] = { {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .init = sha512_base_init,
+ .update = sha512_avx_update,
+ .final = sha512_avx_final,
+ .finup = sha512_avx_finup,
+ .descsize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha512",
+ .cra_driver_name = "sha512-avx",
+ .cra_priority = 160,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
}
-#endif
+}, {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .init = sha384_base_init,
+ .update = sha512_avx_update,
+ .final = sha512_avx_final,
+ .finup = sha512_avx_finup,
+ .descsize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha384",
+ .cra_driver_name = "sha384-avx",
+ .cra_priority = 160,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
- if (sha512_transform_asm) {
-#ifdef CONFIG_AS_AVX
- if (sha512_transform_asm == sha512_transform_avx)
- pr_info("Using AVX optimized SHA-512 implementation\n");
-#ifdef CONFIG_AS_AVX2
- else if (sha512_transform_asm == sha512_transform_rorx)
- pr_info("Using AVX2 optimized SHA-512 implementation\n");
+static int register_sha512_avx(void)
+{
+ if (avx_usable())
+ return crypto_register_shashes(sha512_avx_algs,
+ ARRAY_SIZE(sha512_avx_algs));
+ return 0;
+}
+
+static void unregister_sha512_avx(void)
+{
+ if (avx_usable())
+ crypto_unregister_shashes(sha512_avx_algs,
+ ARRAY_SIZE(sha512_avx_algs));
+}
+#else
+static inline int register_sha512_avx(void) { return 0; }
+static inline void unregister_sha512_avx(void) { }
#endif
- else
+
+#if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX)
+asmlinkage void sha512_transform_rorx(u64 *digest, const char *data,
+ u64 rounds);
+
+static int sha512_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ return sha512_update(desc, data, len, sha512_transform_rorx);
+}
+
+static int sha512_avx2_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha512_finup(desc, data, len, out, sha512_transform_rorx);
+}
+
+/* Add padding and return the message digest. */
+static int sha512_avx2_final(struct shash_desc *desc, u8 *out)
+{
+ return sha512_avx2_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg sha512_avx2_algs[] = { {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .init = sha512_base_init,
+ .update = sha512_avx2_update,
+ .final = sha512_avx2_final,
+ .finup = sha512_avx2_finup,
+ .descsize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha512",
+ .cra_driver_name = "sha512-avx2",
+ .cra_priority = 170,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+}, {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .init = sha384_base_init,
+ .update = sha512_avx2_update,
+ .final = sha512_avx2_final,
+ .finup = sha512_avx2_finup,
+ .descsize = sizeof(struct sha512_state),
+ .base = {
+ .cra_name = "sha384",
+ .cra_driver_name = "sha384-avx2",
+ .cra_priority = 170,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+} };
+
+static bool avx2_usable(void)
+{
+ if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) &&
+ boot_cpu_has(X86_FEATURE_BMI2))
+ return true;
+
+ return false;
+}
+
+static int register_sha512_avx2(void)
+{
+ if (avx2_usable())
+ return crypto_register_shashes(sha512_avx2_algs,
+ ARRAY_SIZE(sha512_avx2_algs));
+ return 0;
+}
+
+static void unregister_sha512_avx2(void)
+{
+ if (avx2_usable())
+ crypto_unregister_shashes(sha512_avx2_algs,
+ ARRAY_SIZE(sha512_avx2_algs));
+}
+#else
+static inline int register_sha512_avx2(void) { return 0; }
+static inline void unregister_sha512_avx2(void) { }
#endif
- pr_info("Using SSSE3 optimized SHA-512 implementation\n");
- return crypto_register_shashes(algs, ARRAY_SIZE(algs));
+
+static int __init sha512_ssse3_mod_init(void)
+{
+
+ if (register_sha512_ssse3())
+ goto fail;
+
+ if (register_sha512_avx()) {
+ unregister_sha512_ssse3();
+ goto fail;
}
- pr_info("Neither AVX nor SSSE3 is available/usable.\n");
+ if (register_sha512_avx2()) {
+ unregister_sha512_avx();
+ unregister_sha512_ssse3();
+ goto fail;
+ }
+
+ return 0;
+fail:
return -ENODEV;
}
static void __exit sha512_ssse3_mod_fini(void)
{
- crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
+ unregister_sha512_avx2();
+ unregister_sha512_avx();
+ unregister_sha512_ssse3();
}
module_init(sha512_ssse3_mod_init);
diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index c2bd0ce..b7a3904 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -558,7 +558,7 @@ static int __init twofish_init(void)
{
const char *feature_name;
- if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
pr_info("CPU feature '%s' is not supported.\n", feature_name);
return -ENODEV;
}
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 56d8a08..2ebb5e9 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -277,13 +277,9 @@ int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
u32 *flags = &tfm->crt_flags;
int err;
- /* key consists of keys of equal size concatenated, therefore
- * the length must be even
- */
- if (keylen % 2) {
- *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
- return -EINVAL;
- }
+ err = xts_check_key(tfm, key, keylen);
+ if (err)
+ return err;
/* first half of xts-key is for crypt */
err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 3c71dd9..9a9e588 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -1,3 +1,5 @@
+#include <linux/jump_label.h>
+
/*
x86 function call convention, 64-bit:
@@ -199,36 +201,18 @@ For 32-bit we have the following conventions - kernel is built with
.byte 0xf1
.endm
-#else /* CONFIG_X86_64 */
+#endif /* CONFIG_X86_64 */
/*
- * For 32bit only simplified versions of SAVE_ALL/RESTORE_ALL. These
- * are different from the entry_32.S versions in not changing the segment
- * registers. So only suitable for in kernel use, not when transitioning
- * from or to user space. The resulting stack frame is not a standard
- * pt_regs frame. The main use case is calling C code from assembler
- * when all the registers need to be preserved.
+ * This does 'call enter_from_user_mode' unless we can avoid it based on
+ * kernel config or using the static jump infrastructure.
*/
-
- .macro SAVE_ALL
- pushl %eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx
- pushl %ebx
- .endm
-
- .macro RESTORE_ALL
- popl %ebx
- popl %ecx
- popl %edx
- popl %esi
- popl %edi
- popl %ebp
- popl %eax
- .endm
-
-#endif /* CONFIG_X86_64 */
-
+.macro CALL_enter_from_user_mode
+#ifdef CONFIG_CONTEXT_TRACKING
+#ifdef HAVE_JUMP_LABEL
+ STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0
+#endif
+ call enter_from_user_mode
+.Lafter_call_\@:
+#endif
+.endm
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 80dcc92..e79d93d 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -24,10 +24,20 @@
#include <asm/desc.h>
#include <asm/traps.h>
+#include <asm/vdso.h>
+#include <asm/uaccess.h>
+#include <asm/cpufeature.h>
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
+static struct thread_info *pt_regs_to_thread_info(struct pt_regs *regs)
+{
+ unsigned long top_of_stack =
+ (unsigned long)(regs + 1) + TOP_OF_KERNEL_STACK_PADDING;
+ return (struct thread_info *)(top_of_stack - THREAD_SIZE);
+}
+
#ifdef CONFIG_CONTEXT_TRACKING
/* Called on entry from user mode with IRQs off. */
__visible void enter_from_user_mode(void)
@@ -35,6 +45,8 @@ __visible void enter_from_user_mode(void)
CT_WARN_ON(ct_state() != CONTEXT_USER);
user_exit();
}
+#else
+static inline void enter_from_user_mode(void) {}
#endif
static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
@@ -66,24 +78,14 @@ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
*/
unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
{
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
unsigned long ret = 0;
u32 work;
- BUG_ON(regs != task_pt_regs(current));
+ if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
+ BUG_ON(regs != task_pt_regs(current));
- work = ACCESS_ONCE(current_thread_info()->flags) &
- _TIF_WORK_SYSCALL_ENTRY;
-
-#ifdef CONFIG_CONTEXT_TRACKING
- /*
- * If TIF_NOHZ is set, we are required to call user_exit() before
- * doing anything that could touch RCU.
- */
- if (work & _TIF_NOHZ) {
- enter_from_user_mode();
- work &= ~_TIF_NOHZ;
- }
-#endif
+ work = ACCESS_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY;
#ifdef CONFIG_SECCOMP
/*
@@ -154,21 +156,12 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
unsigned long phase1_result)
{
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
long ret = 0;
- u32 work = ACCESS_ONCE(current_thread_info()->flags) &
- _TIF_WORK_SYSCALL_ENTRY;
+ u32 work = ACCESS_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY;
- BUG_ON(regs != task_pt_regs(current));
-
- /*
- * If we stepped into a sysenter/syscall insn, it trapped in
- * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
- * If user-mode had set TF itself, then it's still clear from
- * do_debug() and we need to set it again to restore the user
- * state. If we entered on the slow path, TF was already set.
- */
- if (work & _TIF_SINGLESTEP)
- regs->flags |= X86_EFLAGS_TF;
+ if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
+ BUG_ON(regs != task_pt_regs(current));
#ifdef CONFIG_SECCOMP
/*
@@ -207,19 +200,12 @@ long syscall_trace_enter(struct pt_regs *regs)
return syscall_trace_enter_phase2(regs, arch, phase1_result);
}
-static struct thread_info *pt_regs_to_thread_info(struct pt_regs *regs)
-{
- unsigned long top_of_stack =
- (unsigned long)(regs + 1) + TOP_OF_KERNEL_STACK_PADDING;
- return (struct thread_info *)(top_of_stack - THREAD_SIZE);
-}
+#define EXIT_TO_USERMODE_LOOP_FLAGS \
+ (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
+ _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY)
-/* Called with IRQs disabled. */
-__visible void prepare_exit_to_usermode(struct pt_regs *regs)
+static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags)
{
- if (WARN_ON(!irqs_disabled()))
- local_irq_disable();
-
/*
* In order to return to user mode, we need to have IRQs off with
* none of _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_USER_RETURN_NOTIFY,
@@ -229,14 +215,6 @@ __visible void prepare_exit_to_usermode(struct pt_regs *regs)
* work to clear some of the flags can sleep.
*/
while (true) {
- u32 cached_flags =
- READ_ONCE(pt_regs_to_thread_info(regs)->flags);
-
- if (!(cached_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME |
- _TIF_UPROBE | _TIF_NEED_RESCHED |
- _TIF_USER_RETURN_NOTIFY)))
- break;
-
/* We have work to do. */
local_irq_enable();
@@ -260,59 +238,249 @@ __visible void prepare_exit_to_usermode(struct pt_regs *regs)
/* Disable IRQs and retry */
local_irq_disable();
+
+ cached_flags = READ_ONCE(pt_regs_to_thread_info(regs)->flags);
+
+ if (!(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
+ break;
+
}
+}
+
+/* Called with IRQs disabled. */
+__visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
+{
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
+ u32 cached_flags;
+
+ if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
+ local_irq_disable();
+
+ lockdep_sys_exit();
+
+ cached_flags = READ_ONCE(ti->flags);
+
+ if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
+ exit_to_usermode_loop(regs, cached_flags);
+
+#ifdef CONFIG_COMPAT
+ /*
+ * Compat syscalls set TS_COMPAT. Make sure we clear it before
+ * returning to user mode. We need to clear it *after* signal
+ * handling, because syscall restart has a fixup for compat
+ * syscalls. The fixup is exercised by the ptrace_syscall_32
+ * selftest.
+ */
+ ti->status &= ~TS_COMPAT;
+#endif
user_enter();
}
+#define SYSCALL_EXIT_WORK_FLAGS \
+ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+ _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)
+
+static void syscall_slow_exit_work(struct pt_regs *regs, u32 cached_flags)
+{
+ bool step;
+
+ audit_syscall_exit(regs);
+
+ if (cached_flags & _TIF_SYSCALL_TRACEPOINT)
+ trace_sys_exit(regs, regs->ax);
+
+ /*
+ * If TIF_SYSCALL_EMU is set, we only get here because of
+ * TIF_SINGLESTEP (i.e. this is PTRACE_SYSEMU_SINGLESTEP).
+ * We already reported this syscall instruction in
+ * syscall_trace_enter().
+ */
+ step = unlikely(
+ (cached_flags & (_TIF_SINGLESTEP | _TIF_SYSCALL_EMU))
+ == _TIF_SINGLESTEP);
+ if (step || cached_flags & _TIF_SYSCALL_TRACE)
+ tracehook_report_syscall_exit(regs, step);
+}
+
/*
* Called with IRQs on and fully valid regs. Returns with IRQs off in a
* state such that we can immediately switch to user mode.
*/
-__visible void syscall_return_slowpath(struct pt_regs *regs)
+__visible inline void syscall_return_slowpath(struct pt_regs *regs)
{
struct thread_info *ti = pt_regs_to_thread_info(regs);
u32 cached_flags = READ_ONCE(ti->flags);
- bool step;
CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
- if (WARN(irqs_disabled(), "syscall %ld left IRQs disabled",
- regs->orig_ax))
+ if (IS_ENABLED(CONFIG_PROVE_LOCKING) &&
+ WARN(irqs_disabled(), "syscall %ld left IRQs disabled", regs->orig_ax))
local_irq_enable();
/*
* First do one-time work. If these work items are enabled, we
* want to run them exactly once per syscall exit with IRQs on.
*/
- if (cached_flags & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT |
- _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)) {
- audit_syscall_exit(regs);
+ if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
+ syscall_slow_exit_work(regs, cached_flags);
+
+ local_irq_disable();
+ prepare_exit_to_usermode(regs);
+}
+
+#ifdef CONFIG_X86_64
+__visible void do_syscall_64(struct pt_regs *regs)
+{
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
+ unsigned long nr = regs->orig_ax;
+
+ enter_from_user_mode();
+ local_irq_enable();
+
+ if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY)
+ nr = syscall_trace_enter(regs);
+
+ /*
+ * NB: Native and x32 syscalls are dispatched from the same
+ * table. The only functional difference is the x32 bit in
+ * regs->orig_ax, which changes the behavior of some syscalls.
+ */
+ if (likely((nr & __SYSCALL_MASK) < NR_syscalls)) {
+ regs->ax = sys_call_table[nr & __SYSCALL_MASK](
+ regs->di, regs->si, regs->dx,
+ regs->r10, regs->r8, regs->r9);
+ }
- if (cached_flags & _TIF_SYSCALL_TRACEPOINT)
- trace_sys_exit(regs, regs->ax);
+ syscall_return_slowpath(regs);
+}
+#endif
+
+#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
+/*
+ * Does a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL. Does
+ * all entry and exit work and returns with IRQs off. This function is
+ * extremely hot in workloads that use it, and it's usually called from
+ * do_fast_syscall_32, so forcibly inline it to improve performance.
+ */
+static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
+{
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
+ unsigned int nr = (unsigned int)regs->orig_ax;
+#ifdef CONFIG_IA32_EMULATION
+ ti->status |= TS_COMPAT;
+#endif
+
+ if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY) {
/*
- * If TIF_SYSCALL_EMU is set, we only get here because of
- * TIF_SINGLESTEP (i.e. this is PTRACE_SYSEMU_SINGLESTEP).
- * We already reported this syscall instruction in
- * syscall_trace_enter().
+ * Subtlety here: if ptrace pokes something larger than
+ * 2^32-1 into orig_ax, this truncates it. This may or
+ * may not be necessary, but it matches the old asm
+ * behavior.
*/
- step = unlikely(
- (cached_flags & (_TIF_SINGLESTEP | _TIF_SYSCALL_EMU))
- == _TIF_SINGLESTEP);
- if (step || cached_flags & _TIF_SYSCALL_TRACE)
- tracehook_report_syscall_exit(regs, step);
+ nr = syscall_trace_enter(regs);
}
-#ifdef CONFIG_COMPAT
+ if (likely(nr < IA32_NR_syscalls)) {
+ /*
+ * It's possible that a 32-bit syscall implementation
+ * takes a 64-bit parameter but nonetheless assumes that
+ * the high bits are zero. Make sure we zero-extend all
+ * of the args.
+ */
+ regs->ax = ia32_sys_call_table[nr](
+ (unsigned int)regs->bx, (unsigned int)regs->cx,
+ (unsigned int)regs->dx, (unsigned int)regs->si,
+ (unsigned int)regs->di, (unsigned int)regs->bp);
+ }
+
+ syscall_return_slowpath(regs);
+}
+
+/* Handles int $0x80 */
+__visible void do_int80_syscall_32(struct pt_regs *regs)
+{
+ enter_from_user_mode();
+ local_irq_enable();
+ do_syscall_32_irqs_on(regs);
+}
+
+/* Returns 0 to return using IRET or 1 to return using SYSEXIT/SYSRETL. */
+__visible long do_fast_syscall_32(struct pt_regs *regs)
+{
/*
- * Compat syscalls set TS_COMPAT. Make sure we clear it before
- * returning to user mode.
+ * Called using the internal vDSO SYSENTER/SYSCALL32 calling
+ * convention. Adjust regs so it looks like we entered using int80.
*/
- ti->status &= ~TS_COMPAT;
+
+ unsigned long landing_pad = (unsigned long)current->mm->context.vdso +
+ vdso_image_32.sym_int80_landing_pad;
+
+ /*
+ * SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward
+ * so that 'regs->ip -= 2' lands back on an int $0x80 instruction.
+ * Fix it up.
+ */
+ regs->ip = landing_pad;
+
+ enter_from_user_mode();
+
+ local_irq_enable();
+
+ /* Fetch EBP from where the vDSO stashed it. */
+ if (
+#ifdef CONFIG_X86_64
+ /*
+ * Micro-optimization: the pointer we're following is explicitly
+ * 32 bits, so it can't be out of range.
+ */
+ __get_user(*(u32 *)&regs->bp,
+ (u32 __user __force *)(unsigned long)(u32)regs->sp)
+#else
+ get_user(*(u32 *)&regs->bp,
+ (u32 __user __force *)(unsigned long)(u32)regs->sp)
#endif
+ ) {
- local_irq_disable();
- prepare_exit_to_usermode(regs);
+ /* User code screwed up. */
+ local_irq_disable();
+ regs->ax = -EFAULT;
+ prepare_exit_to_usermode(regs);
+ return 0; /* Keep it simple: use IRET. */
+ }
+
+ /* Now this is just like a normal syscall. */
+ do_syscall_32_irqs_on(regs);
+
+#ifdef CONFIG_X86_64
+ /*
+ * Opportunistic SYSRETL: if possible, try to return using SYSRETL.
+ * SYSRETL is available on all 64-bit CPUs, so we don't need to
+ * bother with SYSEXIT.
+ *
+ * Unlike 64-bit opportunistic SYSRET, we can't check that CX == IP,
+ * because the ECX fixup above will ensure that this is essentially
+ * never the case.
+ */
+ return regs->cs == __USER32_CS && regs->ss == __USER_DS &&
+ regs->ip == landing_pad &&
+ (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF)) == 0;
+#else
+ /*
+ * Opportunistic SYSEXIT: if possible, try to return using SYSEXIT.
+ *
+ * Unlike 64-bit opportunistic SYSRET, we can't check that CX == IP,
+ * because the ECX fixup above will ensure that this is essentially
+ * never the case.
+ *
+ * We don't allow syscalls at all from VM86 mode, but we still
+ * need to check VM, because we might be returning from sys_vm86.
+ */
+ return static_cpu_has(X86_FEATURE_SEP) &&
+ regs->cs == __USER_CS && regs->ss == __USER_DS &&
+ regs->ip == landing_pad &&
+ (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)) == 0;
+#endif
}
+#endif
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index b2909bf..10868aa 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -3,7 +3,7 @@
*
* entry_32.S contains the system-call and low-level fault and trap handling routines.
*
- * Stack layout in 'syscall_exit':
+ * Stack layout while running C code:
* ptrace needs to have all registers on the stack.
* If the order here is changed, it needs to be
* updated in fork.c:copy_process(), signal.c:do_signal(),
@@ -40,7 +40,7 @@
#include <asm/processor-flags.h>
#include <asm/ftrace.h>
#include <asm/irq_vectors.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
#include <asm/asm.h>
#include <asm/smap.h>
@@ -153,13 +153,13 @@
#endif /* CONFIG_X86_32_LAZY_GS */
-.macro SAVE_ALL
+.macro SAVE_ALL pt_regs_ax=%eax
cld
PUSH_GS
pushl %fs
pushl %es
pushl %ds
- pushl %eax
+ pushl \pt_regs_ax
pushl %ebp
pushl %edi
pushl %esi
@@ -211,7 +211,11 @@ ENTRY(ret_from_fork)
popl %eax
pushl $0x0202 # Reset kernel eflags
popfl
- jmp syscall_exit
+
+ /* When we fork, we trace the syscall return in the child, too. */
+ movl %esp, %eax
+ call syscall_return_slowpath
+ jmp restore_all
END(ret_from_fork)
ENTRY(ret_from_kernel_thread)
@@ -224,7 +228,15 @@ ENTRY(ret_from_kernel_thread)
movl PT_EBP(%esp), %eax
call *PT_EBX(%esp)
movl $0, PT_EAX(%esp)
- jmp syscall_exit
+
+ /*
+ * Kernel threads return to userspace as if returning from a syscall.
+ * We should check whether anything actually uses this path and, if so,
+ * consider switching it over to ret_from_fork.
+ */
+ movl %esp, %eax
+ call syscall_return_slowpath
+ jmp restore_all
ENDPROC(ret_from_kernel_thread)
/*
@@ -255,7 +267,6 @@ ret_from_intr:
jb resume_kernel # not returning to v8086 or userspace
ENTRY(resume_userspace)
- LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
movl %esp, %eax
@@ -276,77 +287,133 @@ need_resched:
END(resume_kernel)
#endif
+GLOBAL(__begin_SYSENTER_singlestep_region)
+/*
+ * All code from here through __end_SYSENTER_singlestep_region is subject
+ * to being single-stepped if a user program sets TF and executes SYSENTER.
+ * There is absolutely nothing that we can do to prevent this from happening
+ * (thanks Intel!). To keep our handling of this situation as simple as
+ * possible, we handle TF just like AC and NT, except that our #DB handler
+ * will ignore all of the single-step traps generated in this range.
+ */
+
+#ifdef CONFIG_XEN
/*
- * SYSENTER_RETURN points to after the SYSENTER instruction
- * in the vsyscall page. See vsyscall-sysentry.S, which defines
- * the symbol.
+ * Xen doesn't set %esp to be precisely what the normal SYSENTER
+ * entry point expects, so fix it up before using the normal path.
*/
+ENTRY(xen_sysenter_target)
+ addl $5*4, %esp /* remove xen-provided frame */
+ jmp sysenter_past_esp
+#endif
- # SYSENTER call handler stub
+/*
+ * 32-bit SYSENTER entry.
+ *
+ * 32-bit system calls through the vDSO's __kernel_vsyscall enter here
+ * if X86_FEATURE_SEP is available. This is the preferred system call
+ * entry on 32-bit systems.
+ *
+ * The SYSENTER instruction, in principle, should *only* occur in the
+ * vDSO. In practice, a small number of Android devices were shipped
+ * with a copy of Bionic that inlined a SYSENTER instruction. This
+ * never happened in any of Google's Bionic versions -- it only happened
+ * in a narrow range of Intel-provided versions.
+ *
+ * SYSENTER loads SS, ESP, CS, and EIP from previously programmed MSRs.
+ * IF and VM in RFLAGS are cleared (IOW: interrupts are off).
+ * SYSENTER does not save anything on the stack,
+ * and does not save old EIP (!!!), ESP, or EFLAGS.
+ *
+ * To avoid losing track of EFLAGS.VM (and thus potentially corrupting
+ * user and/or vm86 state), we explicitly disable the SYSENTER
+ * instruction in vm86 mode by reprogramming the MSRs.
+ *
+ * Arguments:
+ * eax system call number
+ * ebx arg1
+ * ecx arg2
+ * edx arg3
+ * esi arg4
+ * edi arg5
+ * ebp user stack
+ * 0(%ebp) arg6
+ */
ENTRY(entry_SYSENTER_32)
movl TSS_sysenter_sp0(%esp), %esp
sysenter_past_esp:
+ pushl $__USER_DS /* pt_regs->ss */
+ pushl %ebp /* pt_regs->sp (stashed in bp) */
+ pushfl /* pt_regs->flags (except IF = 0) */
+ orl $X86_EFLAGS_IF, (%esp) /* Fix IF */
+ pushl $__USER_CS /* pt_regs->cs */
+ pushl $0 /* pt_regs->ip = 0 (placeholder) */
+ pushl %eax /* pt_regs->orig_ax */
+ SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
+
/*
- * Interrupts are disabled here, but we can't trace it until
- * enough kernel state to call TRACE_IRQS_OFF can be called - but
- * we immediately enable interrupts at that point anyway.
+ * SYSENTER doesn't filter flags, so we need to clear NT, AC
+ * and TF ourselves. To save a few cycles, we can check whether
+ * either was set instead of doing an unconditional popfq.
+ * This needs to happen before enabling interrupts so that
+ * we don't get preempted with NT set.
+ *
+ * If TF is set, we will single-step all the way to here -- do_debug
+ * will ignore all the traps. (Yes, this is slow, but so is
+ * single-stepping in general. This allows us to avoid having
+ * a more complicated code to handle the case where a user program
+ * forces us to single-step through the SYSENTER entry code.)
+ *
+ * NB.: .Lsysenter_fix_flags is a label with the code under it moved
+ * out-of-line as an optimization: NT is unlikely to be set in the
+ * majority of the cases and instead of polluting the I$ unnecessarily,
+ * we're keeping that code behind a branch which will predict as
+ * not-taken and therefore its instructions won't be fetched.
*/
- pushl $__USER_DS
- pushl %ebp
- pushfl
- orl $X86_EFLAGS_IF, (%esp)
- pushl $__USER_CS
+ testl $X86_EFLAGS_NT|X86_EFLAGS_AC|X86_EFLAGS_TF, PT_EFLAGS(%esp)
+ jnz .Lsysenter_fix_flags
+.Lsysenter_flags_fixed:
+
/*
- * Push current_thread_info()->sysenter_return to the stack.
- * A tiny bit of offset fixup is necessary: TI_sysenter_return
- * is relative to thread_info, which is at the bottom of the
- * kernel stack page. 4*4 means the 4 words pushed above;
- * TOP_OF_KERNEL_STACK_PADDING takes us to the top of the stack;
- * and THREAD_SIZE takes us to the bottom.
+ * User mode is traced as though IRQs are on, and SYSENTER
+ * turned them off.
*/
- pushl ((TI_sysenter_return) - THREAD_SIZE + TOP_OF_KERNEL_STACK_PADDING + 4*4)(%esp)
-
- pushl %eax
- SAVE_ALL
- ENABLE_INTERRUPTS(CLBR_NONE)
-
-/*
- * Load the potential sixth argument from user stack.
- * Careful about security.
- */
- cmpl $__PAGE_OFFSET-3, %ebp
- jae syscall_fault
- ASM_STAC
-1: movl (%ebp), %ebp
- ASM_CLAC
- movl %ebp, PT_EBP(%esp)
- _ASM_EXTABLE(1b, syscall_fault)
-
- GET_THREAD_INFO(%ebp)
-
- testl $_TIF_WORK_SYSCALL_ENTRY, TI_flags(%ebp)
- jnz syscall_trace_entry
-sysenter_do_call:
- cmpl $(NR_syscalls), %eax
- jae sysenter_badsys
- call *sys_call_table(, %eax, 4)
-sysenter_after_call:
- movl %eax, PT_EAX(%esp)
- LOCKDEP_SYS_EXIT
- DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
- movl TI_flags(%ebp), %ecx
- testl $_TIF_ALLWORK_MASK, %ecx
- jnz syscall_exit_work_irqs_off
-sysenter_exit:
-/* if something modifies registers it must also disable sysexit */
- movl PT_EIP(%esp), %edx
- movl PT_OLDESP(%esp), %ecx
- xorl %ebp, %ebp
- TRACE_IRQS_ON
+
+ movl %esp, %eax
+ call do_fast_syscall_32
+ /* XEN PV guests always use IRET path */
+ ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
+ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
+
+/* Opportunistic SYSEXIT */
+ TRACE_IRQS_ON /* User mode traces as IRQs on. */
+ movl PT_EIP(%esp), %edx /* pt_regs->ip */
+ movl PT_OLDESP(%esp), %ecx /* pt_regs->sp */
1: mov PT_FS(%esp), %fs
PTGS_TO_GS
- ENABLE_INTERRUPTS_SYSEXIT
+ popl %ebx /* pt_regs->bx */
+ addl $2*4, %esp /* skip pt_regs->cx and pt_regs->dx */
+ popl %esi /* pt_regs->si */
+ popl %edi /* pt_regs->di */
+ popl %ebp /* pt_regs->bp */
+ popl %eax /* pt_regs->ax */
+
+ /*
+ * Restore all flags except IF. (We restore IF separately because
+ * STI gives a one-instruction window in which we won't be interrupted,
+ * whereas POPF does not.)
+ */
+ addl $PT_EFLAGS-PT_DS, %esp /* point esp at pt_regs->flags */
+ btr $X86_EFLAGS_IF_BIT, (%esp)
+ popfl
+
+ /*
+ * Return back to the vDSO, which will pop ecx and edx.
+ * Don't bother with DS and ES (they already contain __USER_DS).
+ */
+ sti
+ sysexit
.pushsection .fixup, "ax"
2: movl $0, PT_FS(%esp)
@@ -354,31 +421,63 @@ sysenter_exit:
.popsection
_ASM_EXTABLE(1b, 2b)
PTGS_TO_GS_EX
+
+.Lsysenter_fix_flags:
+ pushl $X86_EFLAGS_FIXED
+ popfl
+ jmp .Lsysenter_flags_fixed
+GLOBAL(__end_SYSENTER_singlestep_region)
ENDPROC(entry_SYSENTER_32)
- # system call handler stub
+/*
+ * 32-bit legacy system call entry.
+ *
+ * 32-bit x86 Linux system calls traditionally used the INT $0x80
+ * instruction. INT $0x80 lands here.
+ *
+ * This entry point can be used by any 32-bit perform system calls.
+ * Instances of INT $0x80 can be found inline in various programs and
+ * libraries. It is also used by the vDSO's __kernel_vsyscall
+ * fallback for hardware that doesn't support a faster entry method.
+ * Restarted 32-bit system calls also fall back to INT $0x80
+ * regardless of what instruction was originally used to do the system
+ * call. (64-bit programs can use INT $0x80 as well, but they can
+ * only run on 64-bit kernels and therefore land in
+ * entry_INT80_compat.)
+ *
+ * This is considered a slow path. It is not used by most libc
+ * implementations on modern hardware except during process startup.
+ *
+ * Arguments:
+ * eax system call number
+ * ebx arg1
+ * ecx arg2
+ * edx arg3
+ * esi arg4
+ * edi arg5
+ * ebp arg6
+ */
ENTRY(entry_INT80_32)
ASM_CLAC
- pushl %eax # save orig_eax
- SAVE_ALL
- GET_THREAD_INFO(%ebp)
- # system call tracing in operation / emulation
- testl $_TIF_WORK_SYSCALL_ENTRY, TI_flags(%ebp)
- jnz syscall_trace_entry
- cmpl $(NR_syscalls), %eax
- jae syscall_badsys
-syscall_call:
- call *sys_call_table(, %eax, 4)
-syscall_after_call:
- movl %eax, PT_EAX(%esp) # store the return value
-syscall_exit:
- LOCKDEP_SYS_EXIT
- jmp syscall_exit_work
+ pushl %eax /* pt_regs->orig_ax */
+ SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
+
+ /*
+ * User mode is traced as though IRQs are on, and the interrupt gate
+ * turned them off.
+ */
+ TRACE_IRQS_OFF
+
+ movl %esp, %eax
+ call do_int80_syscall_32
+.Lsyscall_32_done:
restore_all:
TRACE_IRQS_IRET
restore_all_notrace:
#ifdef CONFIG_X86_ESPFIX32
+ ALTERNATIVE "jmp restore_nocheck", "", X86_BUG_ESPFIX
+
movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
/*
* Warning: PT_OLDSS(%esp) contains the wrong/random values if we
@@ -405,19 +504,6 @@ ENTRY(iret_exc )
#ifdef CONFIG_X86_ESPFIX32
ldt_ss:
-#ifdef CONFIG_PARAVIRT
- /*
- * The kernel can't run on a non-flat stack if paravirt mode
- * is active. Rather than try to fixup the high bits of
- * ESP, bypass this code entirely. This may break DOSemu
- * and/or Wine support in a paravirt VM, although the option
- * is still available to implement the setting of the high
- * 16-bits in the INTERRUPT_RETURN paravirt-op.
- */
- cmpl $0, pv_info+PARAVIRT_enabled
- jne restore_nocheck
-#endif
-
/*
* Setup and switch to ESPFIX stack
*
@@ -450,47 +536,6 @@ ldt_ss:
#endif
ENDPROC(entry_INT80_32)
- # perform syscall exit tracing
- ALIGN
-syscall_trace_entry:
- movl $-ENOSYS, PT_EAX(%esp)
- movl %esp, %eax
- call syscall_trace_enter
- /* What it returned is what we'll actually use. */
- cmpl $(NR_syscalls), %eax
- jnae syscall_call
- jmp syscall_exit
-END(syscall_trace_entry)
-
- # perform syscall exit tracing
- ALIGN
-syscall_exit_work_irqs_off:
- TRACE_IRQS_ON
- ENABLE_INTERRUPTS(CLBR_ANY)
-
-syscall_exit_work:
- movl %esp, %eax
- call syscall_return_slowpath
- jmp restore_all
-END(syscall_exit_work)
-
-syscall_fault:
- ASM_CLAC
- GET_THREAD_INFO(%ebp)
- movl $-EFAULT, PT_EAX(%esp)
- jmp resume_userspace
-END(syscall_fault)
-
-syscall_badsys:
- movl $-ENOSYS, %eax
- jmp syscall_after_call
-END(syscall_badsys)
-
-sysenter_badsys:
- movl $-ENOSYS, %eax
- jmp sysenter_after_call
-END(sysenter_badsys)
-
.macro FIXUP_ESPFIX_STACK
/*
* Switch back for ESPFIX stack to the normal zerobased stack
@@ -613,11 +658,6 @@ ENTRY(native_iret)
iret
_ASM_EXTABLE(native_iret, iret_exc)
END(native_iret)
-
-ENTRY(native_irq_enable_sysexit)
- sti
- sysexit
-END(native_irq_enable_sysexit)
#endif
ENTRY(overflow)
@@ -696,14 +736,6 @@ ENTRY(spurious_interrupt_bug)
END(spurious_interrupt_bug)
#ifdef CONFIG_XEN
-/*
- * Xen doesn't set %esp to be precisely what the normal SYSENTER
- * entry point expects, so fix it up before using the normal path.
- */
-ENTRY(xen_sysenter_target)
- addl $5*4, %esp /* remove xen-provided frame */
- jmp sysenter_past_esp
-
ENTRY(xen_hypervisor_callback)
pushl $-1 /* orig_ax = -1 => not a system call */
SAVE_ALL
@@ -1003,51 +1035,48 @@ error_code:
jmp ret_from_exception
END(page_fault)
-/*
- * Debug traps and NMI can happen at the one SYSENTER instruction
- * that sets up the real kernel stack. Check here, since we can't
- * allow the wrong stack to be used.
- *
- * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have
- * already pushed 3 words if it hits on the sysenter instruction:
- * eflags, cs and eip.
- *
- * We just load the right stack, and push the three (known) values
- * by hand onto the new stack - while updating the return eip past
- * the instruction that would have done it for sysenter.
- */
-.macro FIX_STACK offset ok label
- cmpw $__KERNEL_CS, 4(%esp)
- jne \ok
-\label:
- movl TSS_sysenter_sp0 + \offset(%esp), %esp
- pushfl
- pushl $__KERNEL_CS
- pushl $sysenter_past_esp
-.endm
-
ENTRY(debug)
+ /*
+ * #DB can happen at the first instruction of
+ * entry_SYSENTER_32 or in Xen's SYSENTER prologue. If this
+ * happens, then we will be running on a very small stack. We
+ * need to detect this condition and switch to the thread
+ * stack before calling any C code at all.
+ *
+ * If you edit this code, keep in mind that NMIs can happen in here.
+ */
ASM_CLAC
- cmpl $entry_SYSENTER_32, (%esp)
- jne debug_stack_correct
- FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
-debug_stack_correct:
pushl $-1 # mark this as an int
SAVE_ALL
- TRACE_IRQS_OFF
xorl %edx, %edx # error code 0
movl %esp, %eax # pt_regs pointer
+
+ /* Are we currently on the SYSENTER stack? */
+ PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx)
+ subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */
+ cmpl $SIZEOF_SYSENTER_stack, %ecx
+ jb .Ldebug_from_sysenter_stack
+
+ TRACE_IRQS_OFF
+ call do_debug
+ jmp ret_from_exception
+
+.Ldebug_from_sysenter_stack:
+ /* We're on the SYSENTER stack. Switch off. */
+ movl %esp, %ebp
+ movl PER_CPU_VAR(cpu_current_top_of_stack), %esp
+ TRACE_IRQS_OFF
call do_debug
+ movl %ebp, %esp
jmp ret_from_exception
END(debug)
/*
- * NMI is doubly nasty. It can happen _while_ we're handling
- * a debug fault, and the debug fault hasn't yet been able to
- * clear up the stack. So we first check whether we got an
- * NMI on the sysenter entry path, but after that we need to
- * check whether we got an NMI on the debug path where the debug
- * fault happened on the sysenter path.
+ * NMI is doubly nasty. It can happen on the first instruction of
+ * entry_SYSENTER_32 (just like #DB), but it can also interrupt the beginning
+ * of the #DB handler even if that #DB in turn hit before entry_SYSENTER_32
+ * switched stacks. We handle both conditions by simply checking whether we
+ * interrupted kernel code running on the SYSENTER stack.
*/
ENTRY(nmi)
ASM_CLAC
@@ -1058,41 +1087,32 @@ ENTRY(nmi)
popl %eax
je nmi_espfix_stack
#endif
- cmpl $entry_SYSENTER_32, (%esp)
- je nmi_stack_fixup
- pushl %eax
- movl %esp, %eax
- /*
- * Do not access memory above the end of our stack page,
- * it might not exist.
- */
- andl $(THREAD_SIZE-1), %eax
- cmpl $(THREAD_SIZE-20), %eax
- popl %eax
- jae nmi_stack_correct
- cmpl $entry_SYSENTER_32, 12(%esp)
- je nmi_debug_stack_check
-nmi_stack_correct:
- pushl %eax
+
+ pushl %eax # pt_regs->orig_ax
SAVE_ALL
xorl %edx, %edx # zero error code
movl %esp, %eax # pt_regs pointer
+
+ /* Are we currently on the SYSENTER stack? */
+ PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx)
+ subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */
+ cmpl $SIZEOF_SYSENTER_stack, %ecx
+ jb .Lnmi_from_sysenter_stack
+
+ /* Not on SYSENTER stack. */
call do_nmi
jmp restore_all_notrace
-nmi_stack_fixup:
- FIX_STACK 12, nmi_stack_correct, 1
- jmp nmi_stack_correct
-
-nmi_debug_stack_check:
- cmpw $__KERNEL_CS, 16(%esp)
- jne nmi_stack_correct
- cmpl $debug, (%esp)
- jb nmi_stack_correct
- cmpl $debug_esp_fix_insn, (%esp)
- ja nmi_stack_correct
- FIX_STACK 24, nmi_stack_correct, 1
- jmp nmi_stack_correct
+.Lnmi_from_sysenter_stack:
+ /*
+ * We're on the SYSENTER stack. Switch off. No one (not even debug)
+ * is using the thread stack right now, so it's safe for us to use it.
+ */
+ movl %esp, %ebp
+ movl PER_CPU_VAR(cpu_current_top_of_stack), %esp
+ call do_nmi
+ movl %ebp, %esp
+ jmp restore_all_notrace
#ifdef CONFIG_X86_ESPFIX32
nmi_espfix_stack:
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 055a01d..858b555 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -103,6 +103,16 @@ ENDPROC(native_usergs_sysret64)
/*
* 64-bit SYSCALL instruction entry. Up to 6 arguments in registers.
*
+ * This is the only entry point used for 64-bit system calls. The
+ * hardware interface is reasonably well designed and the register to
+ * argument mapping Linux uses fits well with the registers that are
+ * available when SYSCALL is used.
+ *
+ * SYSCALL instructions can be found inlined in libc implementations as
+ * well as some other programs and libraries. There are also a handful
+ * of SYSCALL instructions in the vDSO used, for example, as a
+ * clock_gettimeofday fallback.
+ *
* 64-bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,
* then loads new ss, cs, and rip from previously programmed MSRs.
* rflags gets masked by a value from another MSR (so CLD and CLAC
@@ -145,17 +155,11 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
movq %rsp, PER_CPU_VAR(rsp_scratch)
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+ TRACE_IRQS_OFF
+
/* Construct struct pt_regs on stack */
pushq $__USER_DS /* pt_regs->ss */
pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */
- /*
- * Re-enable interrupts.
- * We use 'rsp_scratch' as a scratch space, hence irq-off block above
- * must execute atomically in the face of possible interrupt-driven
- * task preemption. We must enable interrupts only after we're done
- * with using rsp_scratch:
- */
- ENABLE_INTERRUPTS(CLBR_NONE)
pushq %r11 /* pt_regs->flags */
pushq $__USER_CS /* pt_regs->cs */
pushq %rcx /* pt_regs->ip */
@@ -171,9 +175,21 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
pushq %r11 /* pt_regs->r11 */
sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz tracesys
+ /*
+ * If we need to do entry work or if we guess we'll need to do
+ * exit work, go straight to the slow path.
+ */
+ testl $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
+ jnz entry_SYSCALL64_slow_path
+
entry_SYSCALL_64_fastpath:
+ /*
+ * Easy case: enable interrupts and issue the syscall. If the syscall
+ * needs pt_regs, we'll call a stub that disables interrupts again
+ * and jumps to the slow path.
+ */
+ TRACE_IRQS_ON
+ ENABLE_INTERRUPTS(CLBR_NONE)
#if __SYSCALL_MASK == ~0
cmpq $__NR_syscall_max, %rax
#else
@@ -182,103 +198,56 @@ entry_SYSCALL_64_fastpath:
#endif
ja 1f /* return -ENOSYS (already in pt_regs->ax) */
movq %r10, %rcx
+
+ /*
+ * This call instruction is handled specially in stub_ptregs_64.
+ * It might end up jumping to the slow path. If it jumps, RAX
+ * and all argument registers are clobbered.
+ */
call *sys_call_table(, %rax, 8)
+.Lentry_SYSCALL_64_after_fastpath_call:
+
movq %rax, RAX(%rsp)
1:
-/*
- * Syscall return path ending with SYSRET (fast path).
- * Has incompletely filled pt_regs.
- */
- LOCKDEP_SYS_EXIT
- /*
- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
- * it is too small to ever cause noticeable irq latency.
- */
- DISABLE_INTERRUPTS(CLBR_NONE)
/*
- * We must check ti flags with interrupts (or at least preemption)
- * off because we must *never* return to userspace without
- * processing exit work that is enqueued if we're preempted here.
- * In particular, returning to userspace with any of the one-shot
- * flags (TIF_NOTIFY_RESUME, TIF_USER_RETURN_NOTIFY, etc) set is
- * very bad.
+ * If we get here, then we know that pt_regs is clean for SYSRET64.
+ * If we see that no exit work is required (which we are required
+ * to check with IRQs off), then we can go straight to SYSRET64.
*/
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF
testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz int_ret_from_sys_call_irqs_off /* Go to the slow path */
+ jnz 1f
- RESTORE_C_REGS_EXCEPT_RCX_R11
+ LOCKDEP_SYS_EXIT
+ TRACE_IRQS_ON /* user mode is traced as IRQs on */
movq RIP(%rsp), %rcx
movq EFLAGS(%rsp), %r11
+ RESTORE_C_REGS_EXCEPT_RCX_R11
movq RSP(%rsp), %rsp
- /*
- * 64-bit SYSRET restores rip from rcx,
- * rflags from r11 (but RF and VM bits are forced to 0),
- * cs and ss are loaded from MSRs.
- * Restoration of rflags re-enables interrupts.
- *
- * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss
- * descriptor is not reinitialized. This means that we should
- * avoid SYSRET with SS == NULL, which could happen if we schedule,
- * exit the kernel, and re-enter using an interrupt vector. (All
- * interrupt entries on x86_64 set SS to NULL.) We prevent that
- * from happening by reloading SS in __switch_to. (Actually
- * detecting the failure in 64-bit userspace is tricky but can be
- * done.)
- */
USERGS_SYSRET64
-GLOBAL(int_ret_from_sys_call_irqs_off)
+1:
+ /*
+ * The fast path looked good when we started, but something changed
+ * along the way and we need to switch to the slow path. Calling
+ * raise(3) will trigger this, for example. IRQs are off.
+ */
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
- jmp int_ret_from_sys_call
-
- /* Do syscall entry tracing */
-tracesys:
- movq %rsp, %rdi
- movl $AUDIT_ARCH_X86_64, %esi
- call syscall_trace_enter_phase1
- test %rax, %rax
- jnz tracesys_phase2 /* if needed, run the slow path */
- RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */
- movq ORIG_RAX(%rsp), %rax
- jmp entry_SYSCALL_64_fastpath /* and return to the fast path */
-
-tracesys_phase2:
SAVE_EXTRA_REGS
movq %rsp, %rdi
- movl $AUDIT_ARCH_X86_64, %esi
- movq %rax, %rdx
- call syscall_trace_enter_phase2
-
- /*
- * Reload registers from stack in case ptrace changed them.
- * We don't reload %rax because syscall_trace_entry_phase2() returned
- * the value it wants us to use in the table lookup.
- */
- RESTORE_C_REGS_EXCEPT_RAX
- RESTORE_EXTRA_REGS
-#if __SYSCALL_MASK == ~0
- cmpq $__NR_syscall_max, %rax
-#else
- andl $__SYSCALL_MASK, %eax
- cmpl $__NR_syscall_max, %eax
-#endif
- ja 1f /* return -ENOSYS (already in pt_regs->ax) */
- movq %r10, %rcx /* fixup for C */
- call *sys_call_table(, %rax, 8)
- movq %rax, RAX(%rsp)
-1:
- /* Use IRET because user could have changed pt_regs->foo */
+ call syscall_return_slowpath /* returns with IRQs disabled */
+ jmp return_from_SYSCALL_64
-/*
- * Syscall return path ending with IRET.
- * Has correct iret frame.
- */
-GLOBAL(int_ret_from_sys_call)
+entry_SYSCALL64_slow_path:
+ /* IRQs are off. */
SAVE_EXTRA_REGS
movq %rsp, %rdi
- call syscall_return_slowpath /* returns with IRQs disabled */
+ call do_syscall_64 /* returns with IRQs disabled */
+
+return_from_SYSCALL_64:
RESTORE_EXTRA_REGS
TRACE_IRQS_IRETQ /* we're about to change IF */
@@ -355,87 +324,45 @@ opportunistic_sysret_failed:
jmp restore_c_regs_and_iret
END(entry_SYSCALL_64)
+ENTRY(stub_ptregs_64)
+ /*
+ * Syscalls marked as needing ptregs land here.
+ * If we are on the fast path, we need to save the extra regs,
+ * which we achieve by trying again on the slow path. If we are on
+ * the slow path, the extra regs are already saved.
+ *
+ * RAX stores a pointer to the C function implementing the syscall.
+ * IRQs are on.
+ */
+ cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp)
+ jne 1f
- .macro FORK_LIKE func
-ENTRY(stub_\func)
- SAVE_EXTRA_REGS 8
- jmp sys_\func
-END(stub_\func)
- .endm
-
- FORK_LIKE clone
- FORK_LIKE fork
- FORK_LIKE vfork
-
-ENTRY(stub_execve)
- call sys_execve
-return_from_execve:
- testl %eax, %eax
- jz 1f
- /* exec failed, can use fast SYSRET code path in this case */
- ret
-1:
- /* must use IRET code path (pt_regs->cs may have changed) */
- addq $8, %rsp
- ZERO_EXTRA_REGS
- movq %rax, RAX(%rsp)
- jmp int_ret_from_sys_call
-END(stub_execve)
-/*
- * Remaining execve stubs are only 7 bytes long.
- * ENTRY() often aligns to 16 bytes, which in this case has no benefits.
- */
- .align 8
-GLOBAL(stub_execveat)
- call sys_execveat
- jmp return_from_execve
-END(stub_execveat)
-
-#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)
- .align 8
-GLOBAL(stub_x32_execve)
-GLOBAL(stub32_execve)
- call compat_sys_execve
- jmp return_from_execve
-END(stub32_execve)
-END(stub_x32_execve)
- .align 8
-GLOBAL(stub_x32_execveat)
-GLOBAL(stub32_execveat)
- call compat_sys_execveat
- jmp return_from_execve
-END(stub32_execveat)
-END(stub_x32_execveat)
-#endif
-
-/*
- * sigreturn is special because it needs to restore all registers on return.
- * This cannot be done with SYSRET, so use the IRET return path instead.
- */
-ENTRY(stub_rt_sigreturn)
/*
- * SAVE_EXTRA_REGS result is not normally needed:
- * sigreturn overwrites all pt_regs->GPREGS.
- * But sigreturn can fail (!), and there is no easy way to detect that.
- * To make sure RESTORE_EXTRA_REGS doesn't restore garbage on error,
- * we SAVE_EXTRA_REGS here.
+ * Called from fast path -- disable IRQs again, pop return address
+ * and jump to slow path
*/
- SAVE_EXTRA_REGS 8
- call sys_rt_sigreturn
-return_from_stub:
- addq $8, %rsp
- RESTORE_EXTRA_REGS
- movq %rax, RAX(%rsp)
- jmp int_ret_from_sys_call
-END(stub_rt_sigreturn)
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF
+ popq %rax
+ jmp entry_SYSCALL64_slow_path
-#ifdef CONFIG_X86_X32_ABI
-ENTRY(stub_x32_rt_sigreturn)
- SAVE_EXTRA_REGS 8
- call sys32_x32_rt_sigreturn
- jmp return_from_stub
-END(stub_x32_rt_sigreturn)
-#endif
+1:
+ /* Called from C */
+ jmp *%rax /* called from C */
+END(stub_ptregs_64)
+
+.macro ptregs_stub func
+ENTRY(ptregs_\func)
+ leaq \func(%rip), %rax
+ jmp stub_ptregs_64
+END(ptregs_\func)
+.endm
+
+/* Instantiate ptregs_stub for each ptregs-using syscall */
+#define __SYSCALL_64_QUAL_(sym)
+#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_stub sym
+#define __SYSCALL_64(nr, sym, qual) __SYSCALL_64_QUAL_##qual(sym)
+#include <asm/syscalls_64.h>
/*
* A newly forked process directly context switches into this address.
@@ -443,7 +370,6 @@ END(stub_x32_rt_sigreturn)
* rdi: prev task we switched from
*/
ENTRY(ret_from_fork)
-
LOCK ; btr $TIF_FORK, TI_flags(%r8)
pushq $0x0002
@@ -451,28 +377,32 @@ ENTRY(ret_from_fork)
call schedule_tail /* rdi: 'prev' task parameter */
- RESTORE_EXTRA_REGS
-
testb $3, CS(%rsp) /* from kernel_thread? */
+ jnz 1f
/*
- * By the time we get here, we have no idea whether our pt_regs,
- * ti flags, and ti status came from the 64-bit SYSCALL fast path,
- * the slow path, or one of the 32-bit compat paths.
- * Use IRET code path to return, since it can safely handle
- * all of the above.
+ * We came from kernel_thread. This code path is quite twisted, and
+ * someone should clean it up.
+ *
+ * copy_thread_tls stashes the function pointer in RBX and the
+ * parameter to be passed in RBP. The called function is permitted
+ * to call do_execve and thereby jump to user mode.
*/
- jnz int_ret_from_sys_call
+ movq RBP(%rsp), %rdi
+ call *RBX(%rsp)
+ movl $0, RAX(%rsp)
/*
- * We came from kernel_thread
- * nb: we depend on RESTORE_EXTRA_REGS above
+ * Fall through as though we're exiting a syscall. This makes a
+ * twisted sort of sense if we just called do_execve.
*/
- movq %rbp, %rdi
- call *%rbx
- movl $0, RAX(%rsp)
- RESTORE_EXTRA_REGS
- jmp int_ret_from_sys_call
+
+1:
+ movq %rsp, %rdi
+ call syscall_return_slowpath /* returns with IRQs disabled */
+ TRACE_IRQS_ON /* user mode is traced as IRQS on */
+ SWAPGS
+ jmp restore_regs_and_iret
END(ret_from_fork)
/*
@@ -513,9 +443,18 @@ END(irq_entries_start)
* tracking that we're in kernel mode.
*/
SWAPGS
-#ifdef CONFIG_CONTEXT_TRACKING
- call enter_from_user_mode
-#endif
+
+ /*
+ * We need to tell lockdep that IRQs are off. We can't do this until
+ * we fix gsbase, and we should do it before enter_from_user_mode
+ * (which can take locks). Since TRACE_IRQS_OFF idempotent,
+ * the simplest way to handle it is to just call it twice if
+ * we enter from user mode. There's no reason to optimize this since
+ * TRACE_IRQS_OFF is a no-op if lockdep is off.
+ */
+ TRACE_IRQS_OFF
+
+ CALL_enter_from_user_mode
1:
/*
@@ -557,7 +496,6 @@ ret_from_intr:
jz retint_kernel
/* Interrupt came from user space */
- LOCKDEP_SYS_EXIT_IRQ
GLOBAL(retint_user)
mov %rsp,%rdi
call prepare_exit_to_usermode
@@ -587,7 +525,7 @@ retint_kernel:
* At this label, code paths which return to kernel and to user,
* which come from interrupts/exception and from syscalls, merge.
*/
-restore_regs_and_iret:
+GLOBAL(restore_regs_and_iret)
RESTORE_EXTRA_REGS
restore_c_regs_and_iret:
RESTORE_C_REGS
@@ -1054,12 +992,16 @@ ENTRY(error_entry)
SWAPGS
.Lerror_entry_from_usermode_after_swapgs:
-#ifdef CONFIG_CONTEXT_TRACKING
- call enter_from_user_mode
-#endif
+ /*
+ * We need to tell lockdep that IRQs are off. We can't do this until
+ * we fix gsbase, and we should do it before enter_from_user_mode
+ * (which can take locks).
+ */
+ TRACE_IRQS_OFF
+ CALL_enter_from_user_mode
+ ret
.Lerror_entry_done:
-
TRACE_IRQS_OFF
ret
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index a9360d4..847f2f0 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -16,32 +16,24 @@
#include <linux/linkage.h>
#include <linux/err.h>
-/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
-#include <linux/elf-em.h>
-#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
-#define __AUDIT_ARCH_LE 0x40000000
-
-#ifndef CONFIG_AUDITSYSCALL
-# define sysexit_audit ia32_ret_from_sys_call_irqs_off
-# define sysretl_audit ia32_ret_from_sys_call_irqs_off
-#endif
-
.section .entry.text, "ax"
-#ifdef CONFIG_PARAVIRT
-ENTRY(native_usergs_sysret32)
- swapgs
- sysretl
-ENDPROC(native_usergs_sysret32)
-#endif
-
/*
- * 32-bit SYSENTER instruction entry.
+ * 32-bit SYSENTER entry.
+ *
+ * 32-bit system calls through the vDSO's __kernel_vsyscall enter here
+ * on 64-bit kernels running on Intel CPUs.
+ *
+ * The SYSENTER instruction, in principle, should *only* occur in the
+ * vDSO. In practice, a small number of Android devices were shipped
+ * with a copy of Bionic that inlined a SYSENTER instruction. This
+ * never happened in any of Google's Bionic versions -- it only happened
+ * in a narrow range of Intel-provided versions.
*
- * SYSENTER loads ss, rsp, cs, and rip from previously programmed MSRs.
- * IF and VM in rflags are cleared (IOW: interrupts are off).
+ * SYSENTER loads SS, RSP, CS, and RIP from previously programmed MSRs.
+ * IF and VM in RFLAGS are cleared (IOW: interrupts are off).
* SYSENTER does not save anything on the stack,
- * and does not save old rip (!!!) and rflags.
+ * and does not save old RIP (!!!), RSP, or RFLAGS.
*
* Arguments:
* eax system call number
@@ -52,239 +44,130 @@ ENDPROC(native_usergs_sysret32)
* edi arg5
* ebp user stack
* 0(%ebp) arg6
- *
- * This is purely a fast path. For anything complicated we use the int 0x80
- * path below. We set up a complete hardware stack frame to share code
- * with the int 0x80 path.
*/
ENTRY(entry_SYSENTER_compat)
- /*
- * Interrupts are off on entry.
- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
- * it is too small to ever cause noticeable irq latency.
- */
+ /* Interrupts are off on entry. */
SWAPGS_UNSAFE_STACK
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- ENABLE_INTERRUPTS(CLBR_NONE)
- /* Zero-extending 32-bit regs, do not remove */
- movl %ebp, %ebp
+ /*
+ * User tracing code (ptrace or signal handlers) might assume that
+ * the saved RAX contains a 32-bit number when we're invoking a 32-bit
+ * syscall. Just in case the high bits are nonzero, zero-extend
+ * the syscall number. (This could almost certainly be deleted
+ * with no ill effects.)
+ */
movl %eax, %eax
- movl ASM_THREAD_INFO(TI_sysenter_return, %rsp, 0), %r10d
-
/* Construct struct pt_regs on stack */
pushq $__USER32_DS /* pt_regs->ss */
- pushq %rbp /* pt_regs->sp */
- pushfq /* pt_regs->flags */
+ pushq %rbp /* pt_regs->sp (stashed in bp) */
+
+ /*
+ * Push flags. This is nasty. First, interrupts are currently
+ * off, but we need pt_regs->flags to have IF set. Second, even
+ * if TF was set when SYSENTER started, it's clear by now. We fix
+ * that later using TIF_SINGLESTEP.
+ */
+ pushfq /* pt_regs->flags (except IF = 0) */
+ orl $X86_EFLAGS_IF, (%rsp) /* Fix saved flags */
pushq $__USER32_CS /* pt_regs->cs */
- pushq %r10 /* pt_regs->ip = thread_info->sysenter_return */
+ xorq %r8,%r8
+ pushq %r8 /* pt_regs->ip = 0 (placeholder) */
pushq %rax /* pt_regs->orig_ax */
pushq %rdi /* pt_regs->di */
pushq %rsi /* pt_regs->si */
pushq %rdx /* pt_regs->dx */
pushq %rcx /* pt_regs->cx */
pushq $-ENOSYS /* pt_regs->ax */
+ pushq %r8 /* pt_regs->r8 = 0 */
+ pushq %r8 /* pt_regs->r9 = 0 */
+ pushq %r8 /* pt_regs->r10 = 0 */
+ pushq %r8 /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp (will be overwritten) */
+ pushq %r8 /* pt_regs->r12 = 0 */
+ pushq %r8 /* pt_regs->r13 = 0 */
+ pushq %r8 /* pt_regs->r14 = 0 */
+ pushq %r8 /* pt_regs->r15 = 0 */
cld
- sub $(10*8), %rsp /* pt_regs->r8-11, bp, bx, r12-15 not saved */
-
- /*
- * no need to do an access_ok check here because rbp has been
- * 32-bit zero extended
- */
- ASM_STAC
-1: movl (%rbp), %ebp
- _ASM_EXTABLE(1b, ia32_badarg)
- ASM_CLAC
/*
- * Sysenter doesn't filter flags, so we need to clear NT
+ * SYSENTER doesn't filter flags, so we need to clear NT and AC
* ourselves. To save a few cycles, we can check whether
- * NT was set instead of doing an unconditional popfq.
- */
- testl $X86_EFLAGS_NT, EFLAGS(%rsp)
- jnz sysenter_fix_flags
-sysenter_flags_fixed:
-
- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz sysenter_tracesys
-
-sysenter_do_call:
- /* 32-bit syscall -> 64-bit C ABI argument conversion */
- movl %edi, %r8d /* arg5 */
- movl %ebp, %r9d /* arg6 */
- xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */
- movl %ebx, %edi /* arg1 */
- movl %edx, %edx /* arg3 (zero extension) */
-sysenter_dispatch:
- cmpq $(IA32_NR_syscalls-1), %rax
- ja 1f
- call *ia32_sys_call_table(, %rax, 8)
- movq %rax, RAX(%rsp)
-1:
- DISABLE_INTERRUPTS(CLBR_NONE)
- TRACE_IRQS_OFF
- testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz sysexit_audit
-sysexit_from_sys_call:
- /*
- * NB: SYSEXIT is not obviously safe for 64-bit kernels -- an
- * NMI between STI and SYSEXIT has poorly specified behavior,
- * and and NMI followed by an IRQ with usergs is fatal. So
- * we just pretend we're using SYSEXIT but we really use
- * SYSRETL instead.
+ * either was set instead of doing an unconditional popfq.
+ * This needs to happen before enabling interrupts so that
+ * we don't get preempted with NT set.
*
- * This code path is still called 'sysexit' because it pairs
- * with 'sysenter' and it uses the SYSENTER calling convention.
- */
- andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
- movl RIP(%rsp), %ecx /* User %eip */
- movq RAX(%rsp), %rax
- movl RSI(%rsp), %esi
- movl RDI(%rsp), %edi
- xorl %edx, %edx /* Do not leak kernel information */
- xorq %r8, %r8
- xorq %r9, %r9
- xorq %r10, %r10
- movl EFLAGS(%rsp), %r11d /* User eflags */
- TRACE_IRQS_ON
-
- /*
- * SYSRETL works even on Intel CPUs. Use it in preference to SYSEXIT,
- * since it avoids a dicey window with interrupts enabled.
- */
- movl RSP(%rsp), %esp
-
- /*
- * USERGS_SYSRET32 does:
- * gsbase = user's gs base
- * eip = ecx
- * rflags = r11
- * cs = __USER32_CS
- * ss = __USER_DS
- *
- * The prologue set RIP(%rsp) to VDSO32_SYSENTER_RETURN, which does:
- *
- * pop %ebp
- * pop %edx
- * pop %ecx
- *
- * Therefore, we invoke SYSRETL with EDX and R8-R10 zeroed to
- * avoid info leaks. R11 ends up with VDSO32_SYSENTER_RETURN's
- * address (already known to user code), and R12-R15 are
- * callee-saved and therefore don't contain any interesting
- * kernel data.
- */
- USERGS_SYSRET32
-
-#ifdef CONFIG_AUDITSYSCALL
- .macro auditsys_entry_common
- /*
- * At this point, registers hold syscall args in the 32-bit syscall ABI:
- * EAX is syscall number, the 6 args are in EBX,ECX,EDX,ESI,EDI,EBP.
+ * If TF is set, we will single-step all the way to here -- do_debug
+ * will ignore all the traps. (Yes, this is slow, but so is
+ * single-stepping in general. This allows us to avoid having
+ * a more complicated code to handle the case where a user program
+ * forces us to single-step through the SYSENTER entry code.)
*
- * We want to pass them to __audit_syscall_entry(), which is a 64-bit
- * C function with 5 parameters, so shuffle them to match what
- * the function expects: RDI,RSI,RDX,RCX,R8.
+ * NB.: .Lsysenter_fix_flags is a label with the code under it moved
+ * out-of-line as an optimization: NT is unlikely to be set in the
+ * majority of the cases and instead of polluting the I$ unnecessarily,
+ * we're keeping that code behind a branch which will predict as
+ * not-taken and therefore its instructions won't be fetched.
*/
- movl %esi, %r8d /* arg5 (R8 ) <= 4th syscall arg (ESI) */
- xchg %ecx, %edx /* arg4 (RCX) <= 3rd syscall arg (EDX) */
- /* arg3 (RDX) <= 2nd syscall arg (ECX) */
- movl %ebx, %esi /* arg2 (RSI) <= 1st syscall arg (EBX) */
- movl %eax, %edi /* arg1 (RDI) <= syscall number (EAX) */
- call __audit_syscall_entry
+ testl $X86_EFLAGS_NT|X86_EFLAGS_AC|X86_EFLAGS_TF, EFLAGS(%rsp)
+ jnz .Lsysenter_fix_flags
+.Lsysenter_flags_fixed:
/*
- * We are going to jump back to the syscall dispatch code.
- * Prepare syscall args as required by the 64-bit C ABI.
- * Registers clobbered by __audit_syscall_entry() are
- * loaded from pt_regs on stack:
+ * User mode is traced as though IRQs are on, and SYSENTER
+ * turned them off.
*/
- movl ORIG_RAX(%rsp), %eax /* syscall number */
- movl %ebx, %edi /* arg1 */
- movl RCX(%rsp), %esi /* arg2 */
- movl RDX(%rsp), %edx /* arg3 */
- movl RSI(%rsp), %ecx /* arg4 */
- movl RDI(%rsp), %r8d /* arg5 */
- .endm
-
- .macro auditsys_exit exit
- TRACE_IRQS_ON
- ENABLE_INTERRUPTS(CLBR_NONE)
- testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz ia32_ret_from_sys_call
- movl %eax, %esi /* second arg, syscall return value */
- cmpl $-MAX_ERRNO, %eax /* is it an error ? */
- jbe 1f
- movslq %eax, %rsi /* if error sign extend to 64 bits */
-1: setbe %al /* 1 if error, 0 if not */
- movzbl %al, %edi /* zero-extend that into %edi */
- call __audit_syscall_exit
- movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %edi
- DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
- testl %edi, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jz \exit
- xorl %eax, %eax /* Do not leak kernel information */
- movq %rax, R11(%rsp)
- movq %rax, R10(%rsp)
- movq %rax, R9(%rsp)
- movq %rax, R8(%rsp)
- jmp int_ret_from_sys_call_irqs_off
- .endm
-sysenter_auditsys:
- auditsys_entry_common
- movl %ebp, %r9d /* reload 6th syscall arg */
- jmp sysenter_dispatch
+ movq %rsp, %rdi
+ call do_fast_syscall_32
+ /* XEN PV guests always use IRET path */
+ ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
+ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
+ jmp sysret32_from_system_call
-sysexit_audit:
- auditsys_exit sysexit_from_sys_call
-#endif
-
-sysenter_fix_flags:
- pushq $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)
+.Lsysenter_fix_flags:
+ pushq $X86_EFLAGS_FIXED
popfq
- jmp sysenter_flags_fixed
-
-sysenter_tracesys:
-#ifdef CONFIG_AUDITSYSCALL
- testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jz sysenter_auditsys
-#endif
- SAVE_EXTRA_REGS
- xorl %eax, %eax /* Do not leak kernel information */
- movq %rax, R11(%rsp)
- movq %rax, R10(%rsp)
- movq %rax, R9(%rsp)
- movq %rax, R8(%rsp)
- movq %rsp, %rdi /* &pt_regs -> arg1 */
- call syscall_trace_enter
-
- /* Reload arg registers from stack. (see sysenter_tracesys) */
- movl RCX(%rsp), %ecx
- movl RDX(%rsp), %edx
- movl RSI(%rsp), %esi
- movl RDI(%rsp), %edi
- movl %eax, %eax /* zero extension */
-
- RESTORE_EXTRA_REGS
- jmp sysenter_do_call
+ jmp .Lsysenter_flags_fixed
+GLOBAL(__end_entry_SYSENTER_compat)
ENDPROC(entry_SYSENTER_compat)
/*
- * 32-bit SYSCALL instruction entry.
+ * 32-bit SYSCALL entry.
+ *
+ * 32-bit system calls through the vDSO's __kernel_vsyscall enter here
+ * on 64-bit kernels running on AMD CPUs.
*
- * 32-bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,
- * then loads new ss, cs, and rip from previously programmed MSRs.
- * rflags gets masked by a value from another MSR (so CLD and CLAC
- * are not needed). SYSCALL does not save anything on the stack
- * and does not change rsp.
+ * The SYSCALL instruction, in principle, should *only* occur in the
+ * vDSO. In practice, it appears that this really is the case.
+ * As evidence:
*
- * Note: rflags saving+masking-with-MSR happens only in Long mode
+ * - The calling convention for SYSCALL has changed several times without
+ * anyone noticing.
+ *
+ * - Prior to the in-kernel X86_BUG_SYSRET_SS_ATTRS fixup, anything
+ * user task that did SYSCALL without immediately reloading SS
+ * would randomly crash.
+ *
+ * - Most programmers do not directly target AMD CPUs, and the 32-bit
+ * SYSCALL instruction does not exist on Intel CPUs. Even on AMD
+ * CPUs, Linux disables the SYSCALL instruction on 32-bit kernels
+ * because the SYSCALL instruction in legacy/native 32-bit mode (as
+ * opposed to compat mode) is sufficiently poorly designed as to be
+ * essentially unusable.
+ *
+ * 32-bit SYSCALL saves RIP to RCX, clears RFLAGS.RF, then saves
+ * RFLAGS to R11, then loads new SS, CS, and RIP from previously
+ * programmed MSRs. RFLAGS gets masked by a value from another MSR
+ * (so CLD and CLAC are not needed). SYSCALL does not save anything on
+ * the stack and does not change RSP.
+ *
+ * Note: RFLAGS saving+masking-with-MSR happens only in Long mode
* (in legacy 32-bit mode, IF, RF and VM bits are cleared and that's it).
- * Don't get confused: rflags saving+masking depends on Long Mode Active bit
+ * Don't get confused: RFLAGS saving+masking depends on Long Mode Active bit
* (EFER.LMA=1), NOT on bitness of userspace where SYSCALL executes
* or target CS descriptor's L bit (SYSCALL does not read segment descriptors).
*
@@ -298,21 +181,14 @@ ENDPROC(entry_SYSENTER_compat)
* edi arg5
* esp user stack
* 0(%esp) arg6
- *
- * This is purely a fast path. For anything complicated we use the int 0x80
- * path below. We set up a complete hardware stack frame to share code
- * with the int 0x80 path.
*/
ENTRY(entry_SYSCALL_compat)
- /*
- * Interrupts are off on entry.
- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
- * it is too small to ever cause noticeable irq latency.
- */
+ /* Interrupts are off on entry. */
SWAPGS_UNSAFE_STACK
+
+ /* Stash user ESP and switch to the kernel stack. */
movl %esp, %r8d
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- ENABLE_INTERRUPTS(CLBR_NONE)
/* Zero-extending 32-bit regs, do not remove */
movl %eax, %eax
@@ -327,164 +203,85 @@ ENTRY(entry_SYSCALL_compat)
pushq %rdi /* pt_regs->di */
pushq %rsi /* pt_regs->si */
pushq %rdx /* pt_regs->dx */
- pushq %rbp /* pt_regs->cx */
- movl %ebp, %ecx
+ pushq %rbp /* pt_regs->cx (stashed in bp) */
pushq $-ENOSYS /* pt_regs->ax */
- sub $(10*8), %rsp /* pt_regs->r8-11, bp, bx, r12-15 not saved */
+ xorq %r8,%r8
+ pushq %r8 /* pt_regs->r8 = 0 */
+ pushq %r8 /* pt_regs->r9 = 0 */
+ pushq %r8 /* pt_regs->r10 = 0 */
+ pushq %r8 /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp (will be overwritten) */
+ pushq %r8 /* pt_regs->r12 = 0 */
+ pushq %r8 /* pt_regs->r13 = 0 */
+ pushq %r8 /* pt_regs->r14 = 0 */
+ pushq %r8 /* pt_regs->r15 = 0 */
/*
- * No need to do an access_ok check here because r8 has been
- * 32-bit zero extended:
+ * User mode is traced as though IRQs are on, and SYSENTER
+ * turned them off.
*/
- ASM_STAC
-1: movl (%r8), %r9d
- _ASM_EXTABLE(1b, ia32_badarg)
- ASM_CLAC
- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz cstar_tracesys
-
-cstar_do_call:
- /* 32-bit syscall -> 64-bit C ABI argument conversion */
- movl %edi, %r8d /* arg5 */
- /* r9 already loaded */ /* arg6 */
- xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */
- movl %ebx, %edi /* arg1 */
- movl %edx, %edx /* arg3 (zero extension) */
-
-cstar_dispatch:
- cmpq $(IA32_NR_syscalls-1), %rax
- ja 1f
-
- call *ia32_sys_call_table(, %rax, 8)
- movq %rax, RAX(%rsp)
-1:
- DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
- testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz sysretl_audit
-sysretl_from_sys_call:
- andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
- movl RDX(%rsp), %edx
- movl RSI(%rsp), %esi
- movl RDI(%rsp), %edi
- movl RIP(%rsp), %ecx
- movl EFLAGS(%rsp), %r11d
- movq RAX(%rsp), %rax
- xorq %r10, %r10
- xorq %r9, %r9
- xorq %r8, %r8
- TRACE_IRQS_ON
- movl RSP(%rsp), %esp
- /*
- * 64-bit->32-bit SYSRET restores eip from ecx,
- * eflags from r11 (but RF and VM bits are forced to 0),
- * cs and ss are loaded from MSRs.
- * (Note: 32-bit->32-bit SYSRET is different: since r11
- * does not exist, it merely sets eflags.IF=1).
+ movq %rsp, %rdi
+ call do_fast_syscall_32
+ /* XEN PV guests always use IRET path */
+ ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
+ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
+
+ /* Opportunistic SYSRET */
+sysret32_from_system_call:
+ TRACE_IRQS_ON /* User mode traces as IRQs on. */
+ movq RBX(%rsp), %rbx /* pt_regs->rbx */
+ movq RBP(%rsp), %rbp /* pt_regs->rbp */
+ movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */
+ movq RIP(%rsp), %rcx /* pt_regs->ip (in rcx) */
+ addq $RAX, %rsp /* Skip r8-r15 */
+ popq %rax /* pt_regs->rax */
+ popq %rdx /* Skip pt_regs->cx */
+ popq %rdx /* pt_regs->dx */
+ popq %rsi /* pt_regs->si */
+ popq %rdi /* pt_regs->di */
+
+ /*
+ * USERGS_SYSRET32 does:
+ * GSBASE = user's GS base
+ * EIP = ECX
+ * RFLAGS = R11
+ * CS = __USER32_CS
+ * SS = __USER_DS
+ *
+ * ECX will not match pt_regs->cx, but we're returning to a vDSO
+ * trampoline that will fix up RCX, so this is okay.
*
- * NB: On AMD CPUs with the X86_BUG_SYSRET_SS_ATTRS bug, the ss
- * descriptor is not reinitialized. This means that we must
- * avoid SYSRET with SS == NULL, which could happen if we schedule,
- * exit the kernel, and re-enter using an interrupt vector. (All
- * interrupt entries on x86_64 set SS to NULL.) We prevent that
- * from happening by reloading SS in __switch_to.
- */
- USERGS_SYSRET32
-
-#ifdef CONFIG_AUDITSYSCALL
-cstar_auditsys:
- movl %r9d, R9(%rsp) /* register to be clobbered by call */
- auditsys_entry_common
- movl R9(%rsp), %r9d /* reload 6th syscall arg */
- jmp cstar_dispatch
-
-sysretl_audit:
- auditsys_exit sysretl_from_sys_call
-#endif
-
-cstar_tracesys:
-#ifdef CONFIG_AUDITSYSCALL
- testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jz cstar_auditsys
-#endif
- xchgl %r9d, %ebp
- SAVE_EXTRA_REGS
- xorl %eax, %eax /* Do not leak kernel information */
- movq %rax, R11(%rsp)
- movq %rax, R10(%rsp)
- movq %r9, R9(%rsp)
- movq %rax, R8(%rsp)
- movq %rsp, %rdi /* &pt_regs -> arg1 */
- call syscall_trace_enter
- movl R9(%rsp), %r9d
-
- /* Reload arg registers from stack. (see sysenter_tracesys) */
- movl RCX(%rsp), %ecx
- movl RDX(%rsp), %edx
- movl RSI(%rsp), %esi
- movl RDI(%rsp), %edi
- movl %eax, %eax /* zero extension */
-
- RESTORE_EXTRA_REGS
- xchgl %ebp, %r9d
- jmp cstar_do_call
+ * R12-R15 are callee-saved, so they contain whatever was in them
+ * when the system call started, which is already known to user
+ * code. We zero R8-R10 to avoid info leaks.
+ */
+ xorq %r8, %r8
+ xorq %r9, %r9
+ xorq %r10, %r10
+ movq RSP-ORIG_RAX(%rsp), %rsp
+ swapgs
+ sysretl
END(entry_SYSCALL_compat)
-ia32_badarg:
- /*
- * So far, we've entered kernel mode, set AC, turned on IRQs, and
- * saved C regs except r8-r11. We haven't done any of the other
- * standard entry work, though. We want to bail, but we shouldn't
- * treat this as a syscall entry since we don't even know what the
- * args are. Instead, treat this as a non-syscall entry, finish
- * the entry work, and immediately exit after setting AX = -EFAULT.
- *
- * We're really just being polite here. Killing the task outright
- * would be a reasonable action, too. Given that the only valid
- * way to have gotten here is through the vDSO, and we already know
- * that the stack pointer is bad, the task isn't going to survive
- * for long no matter what we do.
- */
-
- ASM_CLAC /* undo STAC */
- movq $-EFAULT, RAX(%rsp) /* return -EFAULT if possible */
-
- /* Fill in the rest of pt_regs */
- xorl %eax, %eax
- movq %rax, R11(%rsp)
- movq %rax, R10(%rsp)
- movq %rax, R9(%rsp)
- movq %rax, R8(%rsp)
- SAVE_EXTRA_REGS
-
- /* Turn IRQs back off. */
- DISABLE_INTERRUPTS(CLBR_NONE)
- TRACE_IRQS_OFF
-
- /* Now finish entering normal kernel mode. */
-#ifdef CONFIG_CONTEXT_TRACKING
- call enter_from_user_mode
-#endif
-
- /* And exit again. */
- jmp retint_user
-
-ia32_ret_from_sys_call_irqs_off:
- TRACE_IRQS_ON
- ENABLE_INTERRUPTS(CLBR_NONE)
-
-ia32_ret_from_sys_call:
- xorl %eax, %eax /* Do not leak kernel information */
- movq %rax, R11(%rsp)
- movq %rax, R10(%rsp)
- movq %rax, R9(%rsp)
- movq %rax, R8(%rsp)
- jmp int_ret_from_sys_call
-
/*
- * Emulated IA32 system calls via int 0x80.
+ * 32-bit legacy system call entry.
+ *
+ * 32-bit x86 Linux system calls traditionally used the INT $0x80
+ * instruction. INT $0x80 lands here.
+ *
+ * This entry point can be used by 32-bit and 64-bit programs to perform
+ * 32-bit system calls. Instances of INT $0x80 can be found inline in
+ * various programs and libraries. It is also used by the vDSO's
+ * __kernel_vsyscall fallback for hardware that doesn't support a faster
+ * entry method. Restarted 32-bit system calls also fall back to INT
+ * $0x80 regardless of what instruction was originally used to do the
+ * system call.
+ *
+ * This is considered a slow path. It is not used by most libc
+ * implementations on modern hardware except during process startup.
*
* Arguments:
* eax system call number
@@ -493,28 +290,23 @@ ia32_ret_from_sys_call:
* edx arg3
* esi arg4
* edi arg5
- * ebp arg6 (note: not saved in the stack frame, should not be touched)
- *
- * Notes:
- * Uses the same stack frame as the x86-64 version.
- * All registers except eax must be saved (but ptrace may violate that).
- * Arguments are zero extended. For system calls that want sign extension and
- * take long arguments a wrapper is needed. Most calls can just be called
- * directly.
- * Assumes it is only called from user space and entered with interrupts off.
+ * ebp arg6
*/
-
ENTRY(entry_INT80_compat)
/*
* Interrupts are off on entry.
- * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
- * it is too small to ever cause noticeable irq latency.
*/
PARAVIRT_ADJUST_EXCEPTION_FRAME
+ ASM_CLAC /* Do this early to minimize exposure */
SWAPGS
- ENABLE_INTERRUPTS(CLBR_NONE)
- /* Zero-extending 32-bit regs, do not remove */
+ /*
+ * User tracing code (ptrace or signal handlers) might assume that
+ * the saved RAX contains a 32-bit number when we're invoking a 32-bit
+ * syscall. Just in case the high bits are nonzero, zero-extend
+ * the syscall number. (This could almost certainly be deleted
+ * with no ill effects.)
+ */
movl %eax, %eax
/* Construct struct pt_regs on stack (iret frame is already on stack) */
@@ -524,67 +316,37 @@ ENTRY(entry_INT80_compat)
pushq %rdx /* pt_regs->dx */
pushq %rcx /* pt_regs->cx */
pushq $-ENOSYS /* pt_regs->ax */
- pushq $0 /* pt_regs->r8 */
- pushq $0 /* pt_regs->r9 */
- pushq $0 /* pt_regs->r10 */
- pushq $0 /* pt_regs->r11 */
+ xorq %r8,%r8
+ pushq %r8 /* pt_regs->r8 = 0 */
+ pushq %r8 /* pt_regs->r9 = 0 */
+ pushq %r8 /* pt_regs->r10 = 0 */
+ pushq %r8 /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp */
+ pushq %r12 /* pt_regs->r12 */
+ pushq %r13 /* pt_regs->r13 */
+ pushq %r14 /* pt_regs->r14 */
+ pushq %r15 /* pt_regs->r15 */
cld
- sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
-
- orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
- testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
- jnz ia32_tracesys
-
-ia32_do_call:
- /* 32-bit syscall -> 64-bit C ABI argument conversion */
- movl %edi, %r8d /* arg5 */
- movl %ebp, %r9d /* arg6 */
- xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */
- movl %ebx, %edi /* arg1 */
- movl %edx, %edx /* arg3 (zero extension) */
- cmpq $(IA32_NR_syscalls-1), %rax
- ja 1f
- call *ia32_sys_call_table(, %rax, 8)
- movq %rax, RAX(%rsp)
-1:
- jmp int_ret_from_sys_call
-
-ia32_tracesys:
- SAVE_EXTRA_REGS
- movq %rsp, %rdi /* &pt_regs -> arg1 */
- call syscall_trace_enter
/*
- * Reload arg registers from stack in case ptrace changed them.
- * Don't reload %eax because syscall_trace_enter() returned
- * the %rax value we should see. But do truncate it to 32 bits.
- * If it's -1 to make us punt the syscall, then (u32)-1 is still
- * an appropriately invalid value.
+ * User mode is traced as though IRQs are on, and the interrupt
+ * gate turned them off.
*/
- movl RCX(%rsp), %ecx
- movl RDX(%rsp), %edx
- movl RSI(%rsp), %esi
- movl RDI(%rsp), %edi
- movl %eax, %eax /* zero extension */
- RESTORE_EXTRA_REGS
- jmp ia32_do_call
-END(entry_INT80_compat)
+ TRACE_IRQS_OFF
- .macro PTREGSCALL label, func
- ALIGN
-GLOBAL(\label)
- leaq \func(%rip), %rax
- jmp ia32_ptregs_common
- .endm
+ movq %rsp, %rdi
+ call do_int80_syscall_32
+.Lsyscall_32_done:
- PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
- PTREGSCALL stub32_sigreturn, sys32_sigreturn
- PTREGSCALL stub32_fork, sys_fork
- PTREGSCALL stub32_vfork, sys_vfork
+ /* Go back to user mode. */
+ TRACE_IRQS_ON
+ SWAPGS
+ jmp restore_regs_and_iret
+END(entry_INT80_compat)
ALIGN
GLOBAL(stub32_clone)
- leaq sys_clone(%rip), %rax
/*
* The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
* The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).
@@ -593,12 +355,4 @@ GLOBAL(stub32_clone)
* so we need to swap arguments here before calling it:
*/
xchg %r8, %rcx
- jmp ia32_ptregs_common
-
- ALIGN
-ia32_ptregs_common:
- SAVE_EXTRA_REGS 8
- call *%rax
- RESTORE_EXTRA_REGS 8
- ret
-END(ia32_ptregs_common)
+ jmp sys_clone
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
index 8ea34f9..8f895ee 100644
--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -4,24 +4,15 @@
#include <linux/sys.h>
#include <linux/cache.h>
#include <asm/asm-offsets.h>
+#include <asm/syscall.h>
-#ifdef CONFIG_IA32_EMULATION
-#define SYM(sym, compat) compat
-#else
-#define SYM(sym, compat) sym
-#define ia32_sys_call_table sys_call_table
-#define __NR_syscall_compat_max __NR_syscall_max
-#endif
-
-#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void SYM(sym, compat)(void) ;
+#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_32.h>
#undef __SYSCALL_I386
-#define __SYSCALL_I386(nr, sym, compat) [nr] = SYM(sym, compat),
-
-typedef asmlinkage void (*sys_call_ptr_t)(void);
+#define __SYSCALL_I386(nr, sym, qual) [nr] = sym,
-extern asmlinkage void sys_ni_syscall(void);
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
__visible const sys_call_ptr_t ia32_sys_call_table[__NR_syscall_compat_max+1] = {
/*
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c
index 4ac730b..9dbc5ab 100644
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -6,21 +6,16 @@
#include <asm/asm-offsets.h>
#include <asm/syscall.h>
-#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
+#define __SYSCALL_64_QUAL_(sym) sym
+#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_##sym
-#ifdef CONFIG_X86_X32_ABI
-# define __SYSCALL_X32(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
-#else
-# define __SYSCALL_X32(nr, sym, compat) /* nothing */
-#endif
-
-#define __SYSCALL_64(nr, sym, compat) extern asmlinkage void sym(void) ;
+#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long __SYSCALL_64_QUAL_##qual(sym)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_64.h>
#undef __SYSCALL_64
-#define __SYSCALL_64(nr, sym, compat) [nr] = sym,
+#define __SYSCALL_64(nr, sym, qual) [nr] = __SYSCALL_64_QUAL_##qual(sym),
-extern void sys_ni_syscall(void);
+extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
/*
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 7663c45..b30dd81 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -8,7 +8,7 @@
#
0 i386 restart_syscall sys_restart_syscall
1 i386 exit sys_exit
-2 i386 fork sys_fork stub32_fork
+2 i386 fork sys_fork sys_fork
3 i386 read sys_read
4 i386 write sys_write
5 i386 open sys_open compat_sys_open
@@ -17,7 +17,7 @@
8 i386 creat sys_creat
9 i386 link sys_link
10 i386 unlink sys_unlink
-11 i386 execve sys_execve stub32_execve
+11 i386 execve sys_execve compat_sys_execve
12 i386 chdir sys_chdir
13 i386 time sys_time compat_sys_time
14 i386 mknod sys_mknod
@@ -125,7 +125,7 @@
116 i386 sysinfo sys_sysinfo compat_sys_sysinfo
117 i386 ipc sys_ipc compat_sys_ipc
118 i386 fsync sys_fsync
-119 i386 sigreturn sys_sigreturn stub32_sigreturn
+119 i386 sigreturn sys_sigreturn sys32_sigreturn
120 i386 clone sys_clone stub32_clone
121 i386 setdomainname sys_setdomainname
122 i386 uname sys_newuname
@@ -179,7 +179,7 @@
170 i386 setresgid sys_setresgid16
171 i386 getresgid sys_getresgid16
172 i386 prctl sys_prctl
-173 i386 rt_sigreturn sys_rt_sigreturn stub32_rt_sigreturn
+173 i386 rt_sigreturn sys_rt_sigreturn sys32_rt_sigreturn
174 i386 rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
175 i386 rt_sigprocmask sys_rt_sigprocmask
176 i386 rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
@@ -196,7 +196,7 @@
187 i386 sendfile sys_sendfile compat_sys_sendfile
188 i386 getpmsg
189 i386 putpmsg
-190 i386 vfork sys_vfork stub32_vfork
+190 i386 vfork sys_vfork sys_vfork
191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit
192 i386 mmap2 sys_mmap_pgoff
193 i386 truncate64 sys_truncate64 sys32_truncate64
@@ -364,7 +364,7 @@
355 i386 getrandom sys_getrandom
356 i386 memfd_create sys_memfd_create
357 i386 bpf sys_bpf
-358 i386 execveat sys_execveat stub32_execveat
+358 i386 execveat sys_execveat compat_sys_execveat
359 i386 socket sys_socket
360 i386 socketpair sys_socketpair
361 i386 bind sys_bind
@@ -382,3 +382,7 @@
373 i386 shutdown sys_shutdown
374 i386 userfaultfd sys_userfaultfd
375 i386 membarrier sys_membarrier
+376 i386 mlock2 sys_mlock2
+377 i386 copy_file_range sys_copy_file_range
+378 i386 preadv2 sys_preadv2
+379 i386 pwritev2 sys_pwritev2
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 278842f..cac6d17 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -21,7 +21,7 @@
12 common brk sys_brk
13 64 rt_sigaction sys_rt_sigaction
14 common rt_sigprocmask sys_rt_sigprocmask
-15 64 rt_sigreturn stub_rt_sigreturn
+15 64 rt_sigreturn sys_rt_sigreturn/ptregs
16 64 ioctl sys_ioctl
17 common pread64 sys_pread64
18 common pwrite64 sys_pwrite64
@@ -62,10 +62,10 @@
53 common socketpair sys_socketpair
54 64 setsockopt sys_setsockopt
55 64 getsockopt sys_getsockopt
-56 common clone stub_clone
-57 common fork stub_fork
-58 common vfork stub_vfork
-59 64 execve stub_execve
+56 common clone sys_clone/ptregs
+57 common fork sys_fork/ptregs
+58 common vfork sys_vfork/ptregs
+59 64 execve sys_execve/ptregs
60 common exit sys_exit
61 common wait4 sys_wait4
62 common kill sys_kill
@@ -178,7 +178,7 @@
169 common reboot sys_reboot
170 common sethostname sys_sethostname
171 common setdomainname sys_setdomainname
-172 common iopl sys_iopl
+172 common iopl sys_iopl/ptregs
173 common ioperm sys_ioperm
174 64 create_module
175 common init_module sys_init_module
@@ -328,23 +328,27 @@
319 common memfd_create sys_memfd_create
320 common kexec_file_load sys_kexec_file_load
321 common bpf sys_bpf
-322 64 execveat stub_execveat
+322 64 execveat sys_execveat/ptregs
323 common userfaultfd sys_userfaultfd
324 common membarrier sys_membarrier
+325 common mlock2 sys_mlock2
+326 common copy_file_range sys_copy_file_range
+327 64 preadv2 sys_preadv2
+328 64 pwritev2 sys_pwritev2
#
# x32-specific system call numbers start at 512 to avoid cache impact
# for native 64-bit operation.
#
512 x32 rt_sigaction compat_sys_rt_sigaction
-513 x32 rt_sigreturn stub_x32_rt_sigreturn
+513 x32 rt_sigreturn sys32_x32_rt_sigreturn
514 x32 ioctl compat_sys_ioctl
515 x32 readv compat_sys_readv
516 x32 writev compat_sys_writev
517 x32 recvfrom compat_sys_recvfrom
518 x32 sendmsg compat_sys_sendmsg
519 x32 recvmsg compat_sys_recvmsg
-520 x32 execve stub_x32_execve
+520 x32 execve compat_sys_execve/ptregs
521 x32 ptrace compat_sys_ptrace
522 x32 rt_sigpending compat_sys_rt_sigpending
523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
@@ -369,4 +373,4 @@
542 x32 getsockopt compat_sys_getsockopt
543 x32 io_setup compat_sys_io_setup
544 x32 io_submit compat_sys_io_submit
-545 x32 execveat stub_x32_execveat
+545 x32 execveat compat_sys_execveat/ptregs
diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh
index 0e7f8ec..cd3d301 100644
--- a/arch/x86/entry/syscalls/syscalltbl.sh
+++ b/arch/x86/entry/syscalls/syscalltbl.sh
@@ -3,13 +3,63 @@
in="$1"
out="$2"
+syscall_macro() {
+ abi="$1"
+ nr="$2"
+ entry="$3"
+
+ # Entry can be either just a function name or "function/qualifier"
+ real_entry="${entry%%/*}"
+ qualifier="${entry:${#real_entry}}" # Strip the function name
+ qualifier="${qualifier:1}" # Strip the slash, if any
+
+ echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)"
+}
+
+emit() {
+ abi="$1"
+ nr="$2"
+ entry="$3"
+ compat="$4"
+
+ if [ "$abi" == "64" -a -n "$compat" ]; then
+ echo "a compat entry for a 64-bit syscall makes no sense" >&2
+ exit 1
+ fi
+
+ if [ -z "$compat" ]; then
+ if [ -n "$entry" ]; then
+ syscall_macro "$abi" "$nr" "$entry"
+ fi
+ else
+ echo "#ifdef CONFIG_X86_32"
+ if [ -n "$entry" ]; then
+ syscall_macro "$abi" "$nr" "$entry"
+ fi
+ echo "#else"
+ syscall_macro "$abi" "$nr" "$compat"
+ echo "#endif"
+ fi
+}
+
grep '^[0-9]' "$in" | sort -n | (
while read nr abi name entry compat; do
abi=`echo "$abi" | tr '[a-z]' '[A-Z]'`
- if [ -n "$compat" ]; then
- echo "__SYSCALL_${abi}($nr, $entry, $compat)"
- elif [ -n "$entry" ]; then
- echo "__SYSCALL_${abi}($nr, $entry, $entry)"
+ if [ "$abi" == "COMMON" -o "$abi" == "64" ]; then
+ # COMMON is the same as 64, except that we don't expect X32
+ # programs to use it. Our expectation has nothing to do with
+ # any generated code, so treat them the same.
+ emit 64 "$nr" "$entry" "$compat"
+ elif [ "$abi" == "X32" ]; then
+ # X32 is equivalent to 64 on an X32-compatible kernel.
+ echo "#ifdef CONFIG_X86_X32_ABI"
+ emit 64 "$nr" "$entry" "$compat"
+ echo "#endif"
+ elif [ "$abi" == "I386" ]; then
+ emit "$abi" "$nr" "$entry" "$compat"
+ else
+ echo "Unknown abi $abi" >&2
+ exit 1
fi
done
) > "$out"
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index a3d0767..c854541 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -4,6 +4,7 @@
KBUILD_CFLAGS += $(DISABLE_LTO)
KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
VDSO64-$(CONFIG_X86_64) := y
VDSOX32-$(CONFIG_X86_X32_ABI) := y
@@ -19,9 +20,7 @@ obj-y += vma.o
# vDSO images to build
vdso_img-$(VDSO64-y) += 64
vdso_img-$(VDSOX32-y) += x32
-vdso_img-$(VDSO32-y) += 32-int80
-vdso_img-$(CONFIG_IA32_EMULATION) += 32-syscall
-vdso_img-$(VDSO32-y) += 32-sysenter
+vdso_img-$(VDSO32-y) += 32
obj-$(VDSO32-y) += vdso32-setup.o
@@ -69,7 +68,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
$(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
-fno-omit-frame-pointer -foptimize-sibling-calls \
- -DDISABLE_BRANCH_PROFILING
+ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
$(vobjs): KBUILD_CFLAGS += $(CFL)
@@ -122,15 +121,6 @@ $(obj)/%.so: $(obj)/%.so.dbg
$(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
$(call if_changed,vdso)
-#
-# Build multiple 32-bit vDSO images to choose from at boot time.
-#
-vdso32.so-$(VDSO32-y) += int80
-vdso32.so-$(CONFIG_IA32_EMULATION) += syscall
-vdso32.so-$(VDSO32-y) += sysenter
-
-vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
-
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
@@ -139,14 +129,12 @@ VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
targets += vdso32/vdso32.lds
-targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o)
+targets += vdso32/note.o vdso32/vclock_gettime.o vdso32/system_call.o
targets += vdso32/vclock_gettime.o
-$(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%)
-
-KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
-$(vdso32-images:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
-$(vdso32-images:%=$(obj)/%.dbg): asflags-$(CONFIG_X86_64) += -m32
+KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) -DBUILD_VDSO
+$(obj)/vdso32.so.dbg: KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
+$(obj)/vdso32.so.dbg: asflags-$(CONFIG_X86_64) += -m32
KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
@@ -157,13 +145,13 @@ KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
-$(vdso32-images:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
+$(obj)/vdso32.so.dbg: KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
-$(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
- $(obj)/vdso32/vdso32.lds \
- $(obj)/vdso32/vclock_gettime.o \
- $(obj)/vdso32/note.o \
- $(obj)/vdso32/%.o
+$(obj)/vdso32.so.dbg: FORCE \
+ $(obj)/vdso32/vdso32.lds \
+ $(obj)/vdso32/vclock_gettime.o \
+ $(obj)/vdso32/note.o \
+ $(obj)/vdso32/system_call.o
$(call if_changed,vdso)
#
@@ -206,4 +194,4 @@ $(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso FORCE
PHONY += vdso_install $(vdso_img_insttargets)
vdso_install: $(vdso_img_insttargets) FORCE
-clean-files := vdso32-syscall* vdso32-sysenter* vdso32-int80* vdso64* vdso-image-*.c vdsox32.so*
+clean-files := vdso32.so vdso32.so.dbg vdso64* vdso-image-*.c vdsox32.so*
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index ca94fa6..1a50e09 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -17,8 +17,10 @@
#include <asm/vvar.h>
#include <asm/unistd.h>
#include <asm/msr.h>
+#include <asm/pvclock.h>
#include <linux/math64.h>
#include <linux/time.h>
+#include <linux/kernel.h>
#define gtod (&VVAR(vsyscall_gtod_data))
@@ -36,12 +38,12 @@ static notrace cycle_t vread_hpet(void)
}
#endif
-#ifndef BUILD_VDSO32
+#ifdef CONFIG_PARAVIRT_CLOCK
+extern u8 pvclock_page
+ __attribute__((visibility("hidden")));
+#endif
-#include <linux/kernel.h>
-#include <asm/vsyscall.h>
-#include <asm/fixmap.h>
-#include <asm/pvclock.h>
+#ifndef BUILD_VDSO32
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{
@@ -60,75 +62,6 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
return ret;
}
-#ifdef CONFIG_PARAVIRT_CLOCK
-
-static notrace const struct pvclock_vsyscall_time_info *get_pvti(int cpu)
-{
- const struct pvclock_vsyscall_time_info *pvti_base;
- int idx = cpu / (PAGE_SIZE/PVTI_SIZE);
- int offset = cpu % (PAGE_SIZE/PVTI_SIZE);
-
- BUG_ON(PVCLOCK_FIXMAP_BEGIN + idx > PVCLOCK_FIXMAP_END);
-
- pvti_base = (struct pvclock_vsyscall_time_info *)
- __fix_to_virt(PVCLOCK_FIXMAP_BEGIN+idx);
-
- return &pvti_base[offset];
-}
-
-static notrace cycle_t vread_pvclock(int *mode)
-{
- const struct pvclock_vsyscall_time_info *pvti;
- cycle_t ret;
- u64 last;
- u32 version;
- u8 flags;
- unsigned cpu, cpu1;
-
-
- /*
- * Note: hypervisor must guarantee that:
- * 1. cpu ID number maps 1:1 to per-CPU pvclock time info.
- * 2. that per-CPU pvclock time info is updated if the
- * underlying CPU changes.
- * 3. that version is increased whenever underlying CPU
- * changes.
- *
- */
- do {
- cpu = __getcpu() & VGETCPU_CPU_MASK;
- /* TODO: We can put vcpu id into higher bits of pvti.version.
- * This will save a couple of cycles by getting rid of
- * __getcpu() calls (Gleb).
- */
-
- pvti = get_pvti(cpu);
-
- version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags);
-
- /*
- * Test we're still on the cpu as well as the version.
- * We could have been migrated just after the first
- * vgetcpu but before fetching the version, so we
- * wouldn't notice a version change.
- */
- cpu1 = __getcpu() & VGETCPU_CPU_MASK;
- } while (unlikely(cpu != cpu1 ||
- (pvti->pvti.version & 1) ||
- pvti->pvti.version != version));
-
- if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT)))
- *mode = VCLOCK_NONE;
-
- /* refer to tsc.c read_tsc() comment for rationale */
- last = gtod->cycle_last;
-
- if (likely(ret >= last))
- return ret;
-
- return last;
-}
-#endif
#else
@@ -162,15 +95,77 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
return ret;
}
+#endif
+
#ifdef CONFIG_PARAVIRT_CLOCK
+static notrace const struct pvclock_vsyscall_time_info *get_pvti0(void)
+{
+ return (const struct pvclock_vsyscall_time_info *)&pvclock_page;
+}
static notrace cycle_t vread_pvclock(int *mode)
{
- *mode = VCLOCK_NONE;
- return 0;
-}
-#endif
+ const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti;
+ cycle_t ret;
+ u64 tsc, pvti_tsc;
+ u64 last, delta, pvti_system_time;
+ u32 version, pvti_tsc_to_system_mul, pvti_tsc_shift;
+ /*
+ * Note: The kernel and hypervisor must guarantee that cpu ID
+ * number maps 1:1 to per-CPU pvclock time info.
+ *
+ * Because the hypervisor is entirely unaware of guest userspace
+ * preemption, it cannot guarantee that per-CPU pvclock time
+ * info is updated if the underlying CPU changes or that that
+ * version is increased whenever underlying CPU changes.
+ *
+ * On KVM, we are guaranteed that pvti updates for any vCPU are
+ * atomic as seen by *all* vCPUs. This is an even stronger
+ * guarantee than we get with a normal seqlock.
+ *
+ * On Xen, we don't appear to have that guarantee, but Xen still
+ * supplies a valid seqlock using the version field.
+ *
+ * We only do pvclock vdso timing at all if
+ * PVCLOCK_TSC_STABLE_BIT is set, and we interpret that bit to
+ * mean that all vCPUs have matching pvti and that the TSC is
+ * synced, so we can just look at vCPU 0's pvti.
+ */
+
+ do {
+ version = pvti->version;
+
+ smp_rmb();
+
+ if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) {
+ *mode = VCLOCK_NONE;
+ return 0;
+ }
+
+ tsc = rdtsc_ordered();
+ pvti_tsc_to_system_mul = pvti->tsc_to_system_mul;
+ pvti_tsc_shift = pvti->tsc_shift;
+ pvti_system_time = pvti->system_time;
+ pvti_tsc = pvti->tsc_timestamp;
+
+ /* Make sure that the version double-check is last. */
+ smp_rmb();
+ } while (unlikely((version & 1) || version != pvti->version));
+
+ delta = tsc - pvti_tsc;
+ ret = pvti_system_time +
+ pvclock_scale_delta(delta, pvti_tsc_to_system_mul,
+ pvti_tsc_shift);
+
+ /* refer to vread_tsc() comment for rationale */
+ last = gtod->cycle_last;
+
+ if (likely(ret >= last))
+ return ret;
+
+ return last;
+}
#endif
notrace static cycle_t vread_tsc(void)
diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S
index de2c921..4158acc 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -25,7 +25,7 @@ SECTIONS
* segment.
*/
- vvar_start = . - 2 * PAGE_SIZE;
+ vvar_start = . - 3 * PAGE_SIZE;
vvar_page = vvar_start;
/* Place all vvars at the offsets in asm/vvar.h. */
@@ -36,6 +36,7 @@ SECTIONS
#undef EMIT_VVAR
hpet_page = vvar_start + PAGE_SIZE;
+ pvclock_page = vvar_start + 2 * PAGE_SIZE;
. = SIZEOF_HEADERS;
diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c
index 8627db2..491020b 100644
--- a/arch/x86/entry/vdso/vdso2c.c
+++ b/arch/x86/entry/vdso/vdso2c.c
@@ -73,6 +73,7 @@ enum {
sym_vvar_start,
sym_vvar_page,
sym_hpet_page,
+ sym_pvclock_page,
sym_VDSO_FAKE_SECTION_TABLE_START,
sym_VDSO_FAKE_SECTION_TABLE_END,
};
@@ -80,6 +81,7 @@ enum {
const int special_pages[] = {
sym_vvar_page,
sym_hpet_page,
+ sym_pvclock_page,
};
struct vdso_sym {
@@ -91,6 +93,7 @@ struct vdso_sym required_syms[] = {
[sym_vvar_start] = {"vvar_start", true},
[sym_vvar_page] = {"vvar_page", true},
[sym_hpet_page] = {"hpet_page", true},
+ [sym_pvclock_page] = {"pvclock_page", true},
[sym_VDSO_FAKE_SECTION_TABLE_START] = {
"VDSO_FAKE_SECTION_TABLE_START", false
},
@@ -98,10 +101,10 @@ struct vdso_sym required_syms[] = {
"VDSO_FAKE_SECTION_TABLE_END", false
},
{"VDSO32_NOTE_MASK", true},
- {"VDSO32_SYSENTER_RETURN", true},
{"__kernel_vsyscall", true},
{"__kernel_sigreturn", true},
{"__kernel_rt_sigreturn", true},
+ {"int80_landing_pad", true},
};
__attribute__((format(printf, 1, 2))) __attribute__((noreturn))
diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h
index 0224987..63a03bb 100644
--- a/arch/x86/entry/vdso/vdso2c.h
+++ b/arch/x86/entry/vdso/vdso2c.h
@@ -140,7 +140,7 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
fprintf(outfile, "#include <asm/vdso.h>\n");
fprintf(outfile, "\n");
fprintf(outfile,
- "static unsigned char raw_data[%lu] __page_aligned_data = {",
+ "static unsigned char raw_data[%lu] __ro_after_init __aligned(PAGE_SIZE) = {",
mapping_size);
for (j = 0; j < stripped_len; j++) {
if (j % 10 == 0)
@@ -150,16 +150,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
}
fprintf(outfile, "\n};\n\n");
- fprintf(outfile, "static struct page *pages[%lu];\n\n",
- mapping_size / 4096);
-
fprintf(outfile, "const struct vdso_image %s = {\n", name);
fprintf(outfile, "\t.data = raw_data,\n");
fprintf(outfile, "\t.size = %lu,\n", mapping_size);
- fprintf(outfile, "\t.text_mapping = {\n");
- fprintf(outfile, "\t\t.name = \"[vdso]\",\n");
- fprintf(outfile, "\t\t.pages = pages,\n");
- fprintf(outfile, "\t},\n");
if (alt_sec) {
fprintf(outfile, "\t.alt = %lu,\n",
(unsigned long)GET_LE(&alt_sec->sh_offset));
diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c
index e904c27..7853b53 100644
--- a/arch/x86/entry/vdso/vdso32-setup.c
+++ b/arch/x86/entry/vdso/vdso32-setup.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/mm_types.h>
-#include <asm/cpufeature.h>
#include <asm/processor.h>
#include <asm/vdso.h>
@@ -48,35 +47,9 @@ __setup("vdso32=", vdso32_setup);
__setup_param("vdso=", vdso_setup, vdso32_setup, 0);
#endif
-#ifdef CONFIG_X86_64
-
-#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32))
-#define vdso32_syscall() (boot_cpu_has(X86_FEATURE_SYSCALL32))
-
-#else /* CONFIG_X86_32 */
-
-#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SEP))
-#define vdso32_syscall() (0)
-
-#endif /* CONFIG_X86_64 */
-
-#if defined(CONFIG_X86_32) || defined(CONFIG_COMPAT)
-const struct vdso_image *selected_vdso32;
-#endif
-
int __init sysenter_setup(void)
{
-#ifdef CONFIG_COMPAT
- if (vdso32_syscall())
- selected_vdso32 = &vdso_image_32_syscall;
- else
-#endif
- if (vdso32_sysenter())
- selected_vdso32 = &vdso_image_32_sysenter;
- else
- selected_vdso32 = &vdso_image_32_int80;
-
- init_vdso_image(selected_vdso32);
+ init_vdso_image(&vdso_image_32);
return 0;
}
diff --git a/arch/x86/entry/vdso/vdso32/int80.S b/arch/x86/entry/vdso/vdso32/int80.S
deleted file mode 100644
index b15b7c0..0000000
--- a/arch/x86/entry/vdso/vdso32/int80.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Code for the vDSO. This version uses the old int $0x80 method.
- *
- * First get the common code for the sigreturn entry points.
- * This must come first.
- */
-#include "sigreturn.S"
-
- .text
- .globl __kernel_vsyscall
- .type __kernel_vsyscall,@function
- ALIGN
-__kernel_vsyscall:
-.LSTART_vsyscall:
- int $0x80
- ret
-.LEND_vsyscall:
- .size __kernel_vsyscall,.-.LSTART_vsyscall
- .previous
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMEDLSI:
- .long .LENDCIEDLSI-.LSTARTCIEDLSI
-.LSTARTCIEDLSI:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIEDLSI:
- .long .LENDFDEDLSI-.LSTARTFDEDLSI /* Length FDE */
-.LSTARTFDEDLSI:
- .long .LSTARTFDEDLSI-.LSTARTFRAMEDLSI /* CIE pointer */
- .long .LSTART_vsyscall-. /* PC-relative start address */
- .long .LEND_vsyscall-.LSTART_vsyscall
- .uleb128 0
- .align 4
-.LENDFDEDLSI:
- .previous
-
- /*
- * Pad out the segment to match the size of the sysenter.S version.
- */
-VDSO32_vsyscall_eh_frame_size = 0x40
- .section .data,"aw",@progbits
- .space VDSO32_vsyscall_eh_frame_size-(.LENDFDEDLSI-.LSTARTFRAMEDLSI), 0
- .previous
diff --git a/arch/x86/entry/vdso/vdso32/syscall.S b/arch/x86/entry/vdso/vdso32/syscall.S
deleted file mode 100644
index 6b286bb..0000000
--- a/arch/x86/entry/vdso/vdso32/syscall.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Code for the vDSO. This version uses the syscall instruction.
- *
- * First get the common code for the sigreturn entry points.
- * This must come first.
- */
-#define SYSCALL_ENTER_KERNEL syscall
-#include "sigreturn.S"
-
-#include <asm/segment.h>
-
- .text
- .globl __kernel_vsyscall
- .type __kernel_vsyscall,@function
- ALIGN
-__kernel_vsyscall:
-.LSTART_vsyscall:
- push %ebp
-.Lpush_ebp:
- movl %ecx, %ebp
- syscall
- movl %ebp, %ecx
- popl %ebp
-.Lpop_ebp:
- ret
-.LEND_vsyscall:
- .size __kernel_vsyscall,.-.LSTART_vsyscall
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAME:
- .long .LENDCIE-.LSTARTCIE
-.LSTARTCIE:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIE:
-
- .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */
-.LSTARTFDE1:
- .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */
- .long .LSTART_vsyscall-. /* PC-relative start address */
- .long .LEND_vsyscall-.LSTART_vsyscall
- .uleb128 0 /* Augmentation length */
- /* What follows are the instructions for the table generation.
- We have to record all changes of the stack pointer. */
- .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .uleb128 8
- .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */
- .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */
- .byte 0xc5 /* DW_CFA_restore %ebp */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .uleb128 4
- .align 4
-.LENDFDE1:
- .previous
-
- /*
- * Pad out the segment to match the size of the sysenter.S version.
- */
-VDSO32_vsyscall_eh_frame_size = 0x40
- .section .data,"aw",@progbits
- .space VDSO32_vsyscall_eh_frame_size-(.LENDFDE1-.LSTARTFRAME), 0
- .previous
diff --git a/arch/x86/entry/vdso/vdso32/sysenter.S b/arch/x86/entry/vdso/vdso32/sysenter.S
deleted file mode 100644
index e354bce..0000000
--- a/arch/x86/entry/vdso/vdso32/sysenter.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Code for the vDSO. This version uses the sysenter instruction.
- *
- * First get the common code for the sigreturn entry points.
- * This must come first.
- */
-#include "sigreturn.S"
-
-/*
- * The caller puts arg2 in %ecx, which gets pushed. The kernel will use
- * %ecx itself for arg2. The pushing is because the sysexit instruction
- * (found in entry.S) requires that we clobber %ecx with the desired %esp.
- * User code might expect that %ecx is unclobbered though, as it would be
- * for returning via the iret instruction, so we must push and pop.
- *
- * The caller puts arg3 in %edx, which the sysexit instruction requires
- * for %eip. Thus, exactly as for arg2, we must push and pop.
- *
- * Arg6 is different. The caller puts arg6 in %ebp. Since the sysenter
- * instruction clobbers %esp, the user's %esp won't even survive entry
- * into the kernel. We store %esp in %ebp. Code in entry.S must fetch
- * arg6 from the stack.
- *
- * You can not use this vsyscall for the clone() syscall because the
- * three words on the parent stack do not get copied to the child.
- */
- .text
- .globl __kernel_vsyscall
- .type __kernel_vsyscall,@function
- ALIGN
-__kernel_vsyscall:
-.LSTART_vsyscall:
- push %ecx
-.Lpush_ecx:
- push %edx
-.Lpush_edx:
- push %ebp
-.Lenter_kernel:
- movl %esp,%ebp
- sysenter
-
- /* 7: align return point with nop's to make disassembly easier */
- .space 7,0x90
-
- /* 14: System call restart point is here! (SYSENTER_RETURN-2) */
- int $0x80
- /* 16: System call normal return point is here! */
-VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */
- pop %ebp
-.Lpop_ebp:
- pop %edx
-.Lpop_edx:
- pop %ecx
-.Lpop_ecx:
- ret
-.LEND_vsyscall:
- .size __kernel_vsyscall,.-.LSTART_vsyscall
- .previous
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMEDLSI:
- .long .LENDCIEDLSI-.LSTARTCIEDLSI
-.LSTARTCIEDLSI:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NUL-terminated augmentation string */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIEDLSI:
- .long .LENDFDEDLSI-.LSTARTFDEDLSI /* Length FDE */
-.LSTARTFDEDLSI:
- .long .LSTARTFDEDLSI-.LSTARTFRAMEDLSI /* CIE pointer */
- .long .LSTART_vsyscall-. /* PC-relative start address */
- .long .LEND_vsyscall-.LSTART_vsyscall
- .uleb128 0
- /* What follows are the instructions for the table generation.
- We have to record all changes of the stack pointer. */
- .byte 0x40 + (.Lpush_ecx-.LSTART_vsyscall) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x08 /* RA at offset 8 now */
- .byte 0x40 + (.Lpush_edx-.Lpush_ecx) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x0c /* RA at offset 12 now */
- .byte 0x40 + (.Lenter_kernel-.Lpush_edx) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x10 /* RA at offset 16 now */
- .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */
- /* Finally the epilogue. */
- .byte 0x40 + (.Lpop_ebp-.Lenter_kernel) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x0c /* RA at offset 12 now */
- .byte 0xc5 /* DW_CFA_restore %ebp */
- .byte 0x40 + (.Lpop_edx-.Lpop_ebp) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x08 /* RA at offset 8 now */
- .byte 0x40 + (.Lpop_ecx-.Lpop_edx) /* DW_CFA_advance_loc */
- .byte 0x0e /* DW_CFA_def_cfa_offset */
- .byte 0x04 /* RA at offset 4 now */
- .align 4
-.LENDFDEDLSI:
- .previous
-
- /*
- * Emit a symbol with the size of this .eh_frame data,
- * to verify it matches the other versions.
- */
-VDSO32_vsyscall_eh_frame_size = (.LENDFDEDLSI-.LSTARTFRAMEDLSI)
diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S
new file mode 100644
index 0000000..0109ac6
--- /dev/null
+++ b/arch/x86/entry/vdso/vdso32/system_call.S
@@ -0,0 +1,89 @@
+/*
+ * AT_SYSINFO entry point
+*/
+
+#include <asm/dwarf2.h>
+#include <asm/cpufeatures.h>
+#include <asm/alternative-asm.h>
+
+/*
+ * First get the common code for the sigreturn entry points.
+ * This must come first.
+ */
+#include "sigreturn.S"
+
+ .text
+ .globl __kernel_vsyscall
+ .type __kernel_vsyscall,@function
+ ALIGN
+__kernel_vsyscall:
+ CFI_STARTPROC
+ /*
+ * Reshuffle regs so that all of any of the entry instructions
+ * will preserve enough state.
+ *
+ * A really nice entry sequence would be:
+ * pushl %edx
+ * pushl %ecx
+ * movl %esp, %ecx
+ *
+ * Unfortunately, naughty Android versions between July and December
+ * 2015 actually hardcode the traditional Linux SYSENTER entry
+ * sequence. That is severely broken for a number of reasons (ask
+ * anyone with an AMD CPU, for example). Nonetheless, we try to keep
+ * it working approximately as well as it ever worked.
+ *
+ * This link may eludicate some of the history:
+ * https://android-review.googlesource.com/#/q/Iac3295376d61ef83e713ac9b528f3b50aa780cd7
+ * personally, I find it hard to understand what's going on there.
+ *
+ * Note to future user developers: DO NOT USE SYSENTER IN YOUR CODE.
+ * Execute an indirect call to the address in the AT_SYSINFO auxv
+ * entry. That is the ONLY correct way to make a fast 32-bit system
+ * call on Linux. (Open-coding int $0x80 is also fine, but it's
+ * slow.)
+ */
+ pushl %ecx
+ CFI_ADJUST_CFA_OFFSET 4
+ CFI_REL_OFFSET ecx, 0
+ pushl %edx
+ CFI_ADJUST_CFA_OFFSET 4
+ CFI_REL_OFFSET edx, 0
+ pushl %ebp
+ CFI_ADJUST_CFA_OFFSET 4
+ CFI_REL_OFFSET ebp, 0
+
+ #define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter"
+ #define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall"
+
+#ifdef CONFIG_X86_64
+ /* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */
+ ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \
+ SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32
+#else
+ ALTERNATIVE "", SYSENTER_SEQUENCE, X86_FEATURE_SEP
+#endif
+
+ /* Enter using int $0x80 */
+ int $0x80
+GLOBAL(int80_landing_pad)
+
+ /*
+ * Restore EDX and ECX in case they were clobbered. EBP is not
+ * clobbered (the kernel restores it), but it's cleaner and
+ * probably faster to pop it than to adjust ESP using addl.
+ */
+ popl %ebp
+ CFI_RESTORE ebp
+ CFI_ADJUST_CFA_OFFSET -4
+ popl %edx
+ CFI_RESTORE edx
+ CFI_ADJUST_CFA_OFFSET -4
+ popl %ecx
+ CFI_RESTORE ecx
+ CFI_ADJUST_CFA_OFFSET -4
+ ret
+ CFI_ENDPROC
+
+ .size __kernel_vsyscall,.-__kernel_vsyscall
+ .previous
diff --git a/arch/x86/entry/vdso/vdso32/vclock_gettime.c b/arch/x86/entry/vdso/vdso32/vclock_gettime.c
index 175cc72..87a86e0 100644
--- a/arch/x86/entry/vdso/vdso32/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vdso32/vclock_gettime.c
@@ -14,11 +14,13 @@
*/
#undef CONFIG_64BIT
#undef CONFIG_X86_64
+#undef CONFIG_PGTABLE_LEVELS
#undef CONFIG_ILLEGAL_POINTER_VALUE
#undef CONFIG_SPARSEMEM_VMEMMAP
#undef CONFIG_NR_CPUS
#define CONFIG_X86_32 1
+#define CONFIG_PGTABLE_LEVELS 2
#define CONFIG_PAGE_OFFSET 0
#define CONFIG_ILLEGAL_POINTER_VALUE 0
#define CONFIG_NR_CPUS 1
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 4345431..10f7045 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -12,6 +12,7 @@
#include <linux/random.h>
#include <linux/elf.h>
#include <linux/cpu.h>
+#include <asm/pvclock.h>
#include <asm/vgtod.h>
#include <asm/proto.h>
#include <asm/vdso.h>
@@ -19,6 +20,7 @@
#include <asm/page.h>
#include <asm/hpet.h>
#include <asm/desc.h>
+#include <asm/cpufeature.h>
#if defined(CONFIG_X86_64)
unsigned int __read_mostly vdso64_enabled = 1;
@@ -26,13 +28,7 @@ unsigned int __read_mostly vdso64_enabled = 1;
void __init init_vdso_image(const struct vdso_image *image)
{
- int i;
- int npages = (image->size) / PAGE_SIZE;
-
BUG_ON(image->size % PAGE_SIZE != 0);
- for (i = 0; i < npages; i++)
- image->text_mapping.pages[i] =
- virt_to_page(image->data + i*PAGE_SIZE);
apply_alternatives((struct alt_instr *)(image->data + image->alt),
(struct alt_instr *)(image->data + image->alt +
@@ -89,16 +85,86 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
#endif
}
+static int vdso_fault(const struct vm_special_mapping *sm,
+ struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ const struct vdso_image *image = vma->vm_mm->context.vdso_image;
+
+ if (!image || (vmf->pgoff << PAGE_SHIFT) >= image->size)
+ return VM_FAULT_SIGBUS;
+
+ vmf->page = virt_to_page(image->data + (vmf->pgoff << PAGE_SHIFT));
+ get_page(vmf->page);
+ return 0;
+}
+
+static const struct vm_special_mapping text_mapping = {
+ .name = "[vdso]",
+ .fault = vdso_fault,
+};
+
+static int vvar_fault(const struct vm_special_mapping *sm,
+ struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ const struct vdso_image *image = vma->vm_mm->context.vdso_image;
+ long sym_offset;
+ int ret = -EFAULT;
+
+ if (!image)
+ return VM_FAULT_SIGBUS;
+
+ sym_offset = (long)(vmf->pgoff << PAGE_SHIFT) +
+ image->sym_vvar_start;
+
+ /*
+ * Sanity check: a symbol offset of zero means that the page
+ * does not exist for this vdso image, not that the page is at
+ * offset zero relative to the text mapping. This should be
+ * impossible here, because sym_offset should only be zero for
+ * the page past the end of the vvar mapping.
+ */
+ if (sym_offset == 0)
+ return VM_FAULT_SIGBUS;
+
+ if (sym_offset == image->sym_vvar_page) {
+ ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
+ __pa_symbol(&__vvar_page) >> PAGE_SHIFT);
+ } else if (sym_offset == image->sym_hpet_page) {
+#ifdef CONFIG_HPET_TIMER
+ if (hpet_address && vclock_was_used(VCLOCK_HPET)) {
+ ret = vm_insert_pfn_prot(
+ vma,
+ (unsigned long)vmf->virtual_address,
+ hpet_address >> PAGE_SHIFT,
+ pgprot_noncached(PAGE_READONLY));
+ }
+#endif
+ } else if (sym_offset == image->sym_pvclock_page) {
+ struct pvclock_vsyscall_time_info *pvti =
+ pvclock_pvti_cpu0_va();
+ if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) {
+ ret = vm_insert_pfn(
+ vma,
+ (unsigned long)vmf->virtual_address,
+ __pa(pvti) >> PAGE_SHIFT);
+ }
+ }
+
+ if (ret == 0 || ret == -EBUSY)
+ return VM_FAULT_NOPAGE;
+
+ return VM_FAULT_SIGBUS;
+}
+
static int map_vdso(const struct vdso_image *image, bool calculate_addr)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long addr, text_start;
int ret = 0;
- static struct page *no_pages[] = {NULL};
- static struct vm_special_mapping vvar_mapping = {
+ static const struct vm_special_mapping vvar_mapping = {
.name = "[vvar]",
- .pages = no_pages,
+ .fault = vvar_fault,
};
if (calculate_addr) {
@@ -119,6 +185,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
text_start = addr - image->sym_vvar_start;
current->mm->context.vdso = (void __user *)text_start;
+ current->mm->context.vdso_image = image;
/*
* MAYWRITE to allow gdb to COW and set breakpoints
@@ -128,7 +195,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
image->size,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- &image->text_mapping);
+ &text_mapping);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
@@ -138,7 +205,8 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
vma = _install_special_mapping(mm,
addr,
-image->sym_vvar_start,
- VM_READ|VM_MAYREAD,
+ VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
+ VM_PFNMAP,
&vvar_mapping);
if (IS_ERR(vma)) {
@@ -146,29 +214,6 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
goto up_fail;
}
- if (image->sym_vvar_page)
- ret = remap_pfn_range(vma,
- text_start + image->sym_vvar_page,
- __pa_symbol(&__vvar_page) >> PAGE_SHIFT,
- PAGE_SIZE,
- PAGE_READONLY);
-
- if (ret)
- goto up_fail;
-
-#ifdef CONFIG_HPET_TIMER
- if (hpet_address && image->sym_hpet_page) {
- ret = io_remap_pfn_range(vma,
- text_start + image->sym_hpet_page,
- hpet_address >> PAGE_SHIFT,
- PAGE_SIZE,
- pgprot_noncached(PAGE_READONLY));
-
- if (ret)
- goto up_fail;
- }
-#endif
-
up_fail:
if (ret)
current->mm->context.vdso = NULL;
@@ -180,21 +225,10 @@ up_fail:
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
static int load_vdso32(void)
{
- int ret;
-
if (vdso32_enabled != 1) /* Other values all mean "disabled" */
return 0;
- ret = map_vdso(selected_vdso32, false);
- if (ret)
- return ret;
-
- if (selected_vdso32->sym_VDSO32_SYSENTER_RETURN)
- current_thread_info()->sysenter_return =
- current->mm->context.vdso +
- selected_vdso32->sym_VDSO32_SYSENTER_RETURN;
-
- return 0;
+ return map_vdso(&vdso_image_32, false);
}
#endif
@@ -251,7 +285,7 @@ static void vgetcpu_cpu_init(void *arg)
#ifdef CONFIG_NUMA
node = cpu_to_node(cpu);
#endif
- if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
+ if (static_cpu_has(X86_FEATURE_RDTSCP))
write_rdtscp_aux((node << 12) | cpu);
/*
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index b160c0c..174c254 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -38,7 +38,14 @@
#define CREATE_TRACE_POINTS
#include "vsyscall_trace.h"
-static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
+static enum { EMULATE, NATIVE, NONE } vsyscall_mode =
+#if defined(CONFIG_LEGACY_VSYSCALL_NATIVE)
+ NATIVE;
+#elif defined(CONFIG_LEGACY_VSYSCALL_NONE)
+ NONE;
+#else
+ EMULATE;
+#endif
static int __init vsyscall_setup(char *str)
{
diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c
index 51e3304..0fb3a10 100644
--- a/arch/x86/entry/vsyscall/vsyscall_gtod.c
+++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c
@@ -16,6 +16,8 @@
#include <asm/vgtod.h>
#include <asm/vvar.h>
+int vclocks_used __read_mostly;
+
DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data);
void update_vsyscall_tz(void)
@@ -26,12 +28,17 @@ void update_vsyscall_tz(void)
void update_vsyscall(struct timekeeper *tk)
{
+ int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
+ /* Mark the new vclock used. */
+ BUILD_BUG_ON(VCLOCK_MAX >= 32);
+ WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode));
+
gtod_write_begin(vdata);
/* copy vsyscall data */
- vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
+ vdata->vclock_mode = vclock_mode;
vdata->cycle_last = tk->tkr_mono.cycle_last;
vdata->mask = tk->tkr_mono.mask;
vdata->mult = tk->tkr_mono.mult;
diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile
new file mode 100644
index 0000000..fdfea15
--- /dev/null
+++ b/arch/x86/events/Makefile
@@ -0,0 +1,13 @@
+obj-y += core.o
+
+obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o
+obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o
+ifdef CONFIG_AMD_IOMMU
+obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
+endif
+obj-$(CONFIG_CPU_SUP_INTEL) += intel/core.o intel/bts.o intel/cqm.o
+obj-$(CONFIG_CPU_SUP_INTEL) += intel/cstate.o intel/ds.o intel/knc.o
+obj-$(CONFIG_CPU_SUP_INTEL) += intel/lbr.o intel/p4.o intel/p6.o intel/pt.o
+obj-$(CONFIG_CPU_SUP_INTEL) += intel/rapl.o msr.o
+obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore.o intel/uncore_nhmex.o
+obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore_snb.o intel/uncore_snbep.o
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
new file mode 100644
index 0000000..049ada8d
--- /dev/null
+++ b/arch/x86/events/amd/core.c
@@ -0,0 +1,731 @@
+#include <linux/perf_event.h>
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/apicdef.h>
+
+#include "../perf_event.h"
+
+static __initconst const u64 amd_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
+ [ C(RESULT_MISS) ] = 0x0141, /* Data Cache Misses */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts */
+ [ C(RESULT_MISS) ] = 0x0167, /* Data Prefetcher :cancelled */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches */
+ [ C(RESULT_MISS) ] = 0x0081, /* Instruction cache misses */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
+ [ C(RESULT_MISS) ] = 0x037E, /* L2 Cache Misses : IC+DC */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
+ [ C(RESULT_MISS) ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes */
+ [ C(RESULT_MISS) ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr. */
+ [ C(RESULT_MISS) ] = 0x00c3, /* Retired Mispredicted BI */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0xb8e9, /* CPU Request to Memory, l+r */
+ [ C(RESULT_MISS) ] = 0x98e9, /* CPU Request to Memory, r */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+/*
+ * AMD Performance Monitor K7 and later.
+ */
+static const u64 amd_perfmon_event_map[] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x00d1, /* "Dispatch stalls" event */
+};
+
+static u64 amd_pmu_event_map(int hw_event)
+{
+ return amd_perfmon_event_map[hw_event];
+}
+
+/*
+ * Previously calculated offsets
+ */
+static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
+static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;
+
+/*
+ * Legacy CPUs:
+ * 4 counters starting at 0xc0010000 each offset by 1
+ *
+ * CPUs with core performance counter extensions:
+ * 6 counters starting at 0xc0010200 each offset by 2
+ */
+static inline int amd_pmu_addr_offset(int index, bool eventsel)
+{
+ int offset;
+
+ if (!index)
+ return index;
+
+ if (eventsel)
+ offset = event_offsets[index];
+ else
+ offset = count_offsets[index];
+
+ if (offset)
+ return offset;
+
+ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
+ offset = index;
+ else
+ offset = index << 1;
+
+ if (eventsel)
+ event_offsets[index] = offset;
+ else
+ count_offsets[index] = offset;
+
+ return offset;
+}
+
+static int amd_core_hw_config(struct perf_event *event)
+{
+ if (event->attr.exclude_host && event->attr.exclude_guest)
+ /*
+ * When HO == GO == 1 the hardware treats that as GO == HO == 0
+ * and will count in both modes. We don't want to count in that
+ * case so we emulate no-counting by setting US = OS = 0.
+ */
+ event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR |
+ ARCH_PERFMON_EVENTSEL_OS);
+ else if (event->attr.exclude_host)
+ event->hw.config |= AMD64_EVENTSEL_GUESTONLY;
+ else if (event->attr.exclude_guest)
+ event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
+
+ return 0;
+}
+
+/*
+ * AMD64 events are detected based on their event codes.
+ */
+static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
+{
+ return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
+}
+
+static inline int amd_is_nb_event(struct hw_perf_event *hwc)
+{
+ return (hwc->config & 0xe0) == 0xe0;
+}
+
+static inline int amd_has_nb(struct cpu_hw_events *cpuc)
+{
+ struct amd_nb *nb = cpuc->amd_nb;
+
+ return nb && nb->nb_id != -1;
+}
+
+static int amd_pmu_hw_config(struct perf_event *event)
+{
+ int ret;
+
+ /* pass precise event sampling to ibs: */
+ if (event->attr.precise_ip && get_ibs_caps())
+ return -ENOENT;
+
+ if (has_branch_stack(event))
+ return -EOPNOTSUPP;
+
+ ret = x86_pmu_hw_config(event);
+ if (ret)
+ return ret;
+
+ if (event->attr.type == PERF_TYPE_RAW)
+ event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
+
+ return amd_core_hw_config(event);
+}
+
+static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct amd_nb *nb = cpuc->amd_nb;
+ int i;
+
+ /*
+ * need to scan whole list because event may not have
+ * been assigned during scheduling
+ *
+ * no race condition possible because event can only
+ * be removed on one CPU at a time AND PMU is disabled
+ * when we come here
+ */
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ if (cmpxchg(nb->owners + i, event, NULL) == event)
+ break;
+ }
+}
+
+ /*
+ * AMD64 NorthBridge events need special treatment because
+ * counter access needs to be synchronized across all cores
+ * of a package. Refer to BKDG section 3.12
+ *
+ * NB events are events measuring L3 cache, Hypertransport
+ * traffic. They are identified by an event code >= 0xe00.
+ * They measure events on the NorthBride which is shared
+ * by all cores on a package. NB events are counted on a
+ * shared set of counters. When a NB event is programmed
+ * in a counter, the data actually comes from a shared
+ * counter. Thus, access to those counters needs to be
+ * synchronized.
+ *
+ * We implement the synchronization such that no two cores
+ * can be measuring NB events using the same counters. Thus,
+ * we maintain a per-NB allocation table. The available slot
+ * is propagated using the event_constraint structure.
+ *
+ * We provide only one choice for each NB event based on
+ * the fact that only NB events have restrictions. Consequently,
+ * if a counter is available, there is a guarantee the NB event
+ * will be assigned to it. If no slot is available, an empty
+ * constraint is returned and scheduling will eventually fail
+ * for this event.
+ *
+ * Note that all cores attached the same NB compete for the same
+ * counters to host NB events, this is why we use atomic ops. Some
+ * multi-chip CPUs may have more than one NB.
+ *
+ * Given that resources are allocated (cmpxchg), they must be
+ * eventually freed for others to use. This is accomplished by
+ * calling __amd_put_nb_event_constraints()
+ *
+ * Non NB events are not impacted by this restriction.
+ */
+static struct event_constraint *
+__amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
+ struct event_constraint *c)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct amd_nb *nb = cpuc->amd_nb;
+ struct perf_event *old;
+ int idx, new = -1;
+
+ if (!c)
+ c = &unconstrained;
+
+ if (cpuc->is_fake)
+ return c;
+
+ /*
+ * detect if already present, if so reuse
+ *
+ * cannot merge with actual allocation
+ * because of possible holes
+ *
+ * event can already be present yet not assigned (in hwc->idx)
+ * because of successive calls to x86_schedule_events() from
+ * hw_perf_group_sched_in() without hw_perf_enable()
+ */
+ for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
+ if (new == -1 || hwc->idx == idx)
+ /* assign free slot, prefer hwc->idx */
+ old = cmpxchg(nb->owners + idx, NULL, event);
+ else if (nb->owners[idx] == event)
+ /* event already present */
+ old = event;
+ else
+ continue;
+
+ if (old && old != event)
+ continue;
+
+ /* reassign to this slot */
+ if (new != -1)
+ cmpxchg(nb->owners + new, event, NULL);
+ new = idx;
+
+ /* already present, reuse */
+ if (old == event)
+ break;
+ }
+
+ if (new == -1)
+ return &emptyconstraint;
+
+ return &nb->event_constraints[new];
+}
+
+static struct amd_nb *amd_alloc_nb(int cpu)
+{
+ struct amd_nb *nb;
+ int i;
+
+ nb = kzalloc_node(sizeof(struct amd_nb), GFP_KERNEL, cpu_to_node(cpu));
+ if (!nb)
+ return NULL;
+
+ nb->nb_id = -1;
+
+ /*
+ * initialize all possible NB constraints
+ */
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ __set_bit(i, nb->event_constraints[i].idxmsk);
+ nb->event_constraints[i].weight = 1;
+ }
+ return nb;
+}
+
+static int amd_pmu_cpu_prepare(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+ WARN_ON_ONCE(cpuc->amd_nb);
+
+ if (boot_cpu_data.x86_max_cores < 2)
+ return NOTIFY_OK;
+
+ cpuc->amd_nb = amd_alloc_nb(cpu);
+ if (!cpuc->amd_nb)
+ return NOTIFY_BAD;
+
+ return NOTIFY_OK;
+}
+
+static void amd_pmu_cpu_starting(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
+ struct amd_nb *nb;
+ int i, nb_id;
+
+ cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
+
+ if (boot_cpu_data.x86_max_cores < 2)
+ return;
+
+ nb_id = amd_get_nb_id(cpu);
+ WARN_ON_ONCE(nb_id == BAD_APICID);
+
+ for_each_online_cpu(i) {
+ nb = per_cpu(cpu_hw_events, i).amd_nb;
+ if (WARN_ON_ONCE(!nb))
+ continue;
+
+ if (nb->nb_id == nb_id) {
+ *onln = cpuc->amd_nb;
+ cpuc->amd_nb = nb;
+ break;
+ }
+ }
+
+ cpuc->amd_nb->nb_id = nb_id;
+ cpuc->amd_nb->refcnt++;
+}
+
+static void amd_pmu_cpu_dead(int cpu)
+{
+ struct cpu_hw_events *cpuhw;
+
+ if (boot_cpu_data.x86_max_cores < 2)
+ return;
+
+ cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+ if (cpuhw->amd_nb) {
+ struct amd_nb *nb = cpuhw->amd_nb;
+
+ if (nb->nb_id == -1 || --nb->refcnt == 0)
+ kfree(nb);
+
+ cpuhw->amd_nb = NULL;
+ }
+}
+
+static struct event_constraint *
+amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ /*
+ * if not NB event or no NB, then no constraints
+ */
+ if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw)))
+ return &unconstrained;
+
+ return __amd_get_nb_event_constraints(cpuc, event, NULL);
+}
+
+static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ if (amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))
+ __amd_put_nb_event_constraints(cpuc, event);
+}
+
+PMU_FORMAT_ATTR(event, "config:0-7,32-35");
+PMU_FORMAT_ATTR(umask, "config:8-15" );
+PMU_FORMAT_ATTR(edge, "config:18" );
+PMU_FORMAT_ATTR(inv, "config:23" );
+PMU_FORMAT_ATTR(cmask, "config:24-31" );
+
+static struct attribute *amd_format_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ NULL,
+};
+
+/* AMD Family 15h */
+
+#define AMD_EVENT_TYPE_MASK 0x000000F0ULL
+
+#define AMD_EVENT_FP 0x00000000ULL ... 0x00000010ULL
+#define AMD_EVENT_LS 0x00000020ULL ... 0x00000030ULL
+#define AMD_EVENT_DC 0x00000040ULL ... 0x00000050ULL
+#define AMD_EVENT_CU 0x00000060ULL ... 0x00000070ULL
+#define AMD_EVENT_IC_DE 0x00000080ULL ... 0x00000090ULL
+#define AMD_EVENT_EX_LS 0x000000C0ULL
+#define AMD_EVENT_DE 0x000000D0ULL
+#define AMD_EVENT_NB 0x000000E0ULL ... 0x000000F0ULL
+
+/*
+ * AMD family 15h event code/PMC mappings:
+ *
+ * type = event_code & 0x0F0:
+ *
+ * 0x000 FP PERF_CTL[5:3]
+ * 0x010 FP PERF_CTL[5:3]
+ * 0x020 LS PERF_CTL[5:0]
+ * 0x030 LS PERF_CTL[5:0]
+ * 0x040 DC PERF_CTL[5:0]
+ * 0x050 DC PERF_CTL[5:0]
+ * 0x060 CU PERF_CTL[2:0]
+ * 0x070 CU PERF_CTL[2:0]
+ * 0x080 IC/DE PERF_CTL[2:0]
+ * 0x090 IC/DE PERF_CTL[2:0]
+ * 0x0A0 ---
+ * 0x0B0 ---
+ * 0x0C0 EX/LS PERF_CTL[5:0]
+ * 0x0D0 DE PERF_CTL[2:0]
+ * 0x0E0 NB NB_PERF_CTL[3:0]
+ * 0x0F0 NB NB_PERF_CTL[3:0]
+ *
+ * Exceptions:
+ *
+ * 0x000 FP PERF_CTL[3], PERF_CTL[5:3] (*)
+ * 0x003 FP PERF_CTL[3]
+ * 0x004 FP PERF_CTL[3], PERF_CTL[5:3] (*)
+ * 0x00B FP PERF_CTL[3]
+ * 0x00D FP PERF_CTL[3]
+ * 0x023 DE PERF_CTL[2:0]
+ * 0x02D LS PERF_CTL[3]
+ * 0x02E LS PERF_CTL[3,0]
+ * 0x031 LS PERF_CTL[2:0] (**)
+ * 0x043 CU PERF_CTL[2:0]
+ * 0x045 CU PERF_CTL[2:0]
+ * 0x046 CU PERF_CTL[2:0]
+ * 0x054 CU PERF_CTL[2:0]
+ * 0x055 CU PERF_CTL[2:0]
+ * 0x08F IC PERF_CTL[0]
+ * 0x187 DE PERF_CTL[0]
+ * 0x188 DE PERF_CTL[0]
+ * 0x0DB EX PERF_CTL[5:0]
+ * 0x0DC LS PERF_CTL[5:0]
+ * 0x0DD LS PERF_CTL[5:0]
+ * 0x0DE LS PERF_CTL[5:0]
+ * 0x0DF LS PERF_CTL[5:0]
+ * 0x1C0 EX PERF_CTL[5:3]
+ * 0x1D6 EX PERF_CTL[5:0]
+ * 0x1D8 EX PERF_CTL[5:0]
+ *
+ * (*) depending on the umask all FPU counters may be used
+ * (**) only one unitmask enabled at a time
+ */
+
+static struct event_constraint amd_f15_PMC0 = EVENT_CONSTRAINT(0, 0x01, 0);
+static struct event_constraint amd_f15_PMC20 = EVENT_CONSTRAINT(0, 0x07, 0);
+static struct event_constraint amd_f15_PMC3 = EVENT_CONSTRAINT(0, 0x08, 0);
+static struct event_constraint amd_f15_PMC30 = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
+static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0);
+static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0);
+
+static struct event_constraint *
+amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int event_code = amd_get_event_code(hwc);
+
+ switch (event_code & AMD_EVENT_TYPE_MASK) {
+ case AMD_EVENT_FP:
+ switch (event_code) {
+ case 0x000:
+ if (!(hwc->config & 0x0000F000ULL))
+ break;
+ if (!(hwc->config & 0x00000F00ULL))
+ break;
+ return &amd_f15_PMC3;
+ case 0x004:
+ if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
+ break;
+ return &amd_f15_PMC3;
+ case 0x003:
+ case 0x00B:
+ case 0x00D:
+ return &amd_f15_PMC3;
+ }
+ return &amd_f15_PMC53;
+ case AMD_EVENT_LS:
+ case AMD_EVENT_DC:
+ case AMD_EVENT_EX_LS:
+ switch (event_code) {
+ case 0x023:
+ case 0x043:
+ case 0x045:
+ case 0x046:
+ case 0x054:
+ case 0x055:
+ return &amd_f15_PMC20;
+ case 0x02D:
+ return &amd_f15_PMC3;
+ case 0x02E:
+ return &amd_f15_PMC30;
+ case 0x031:
+ if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
+ return &amd_f15_PMC20;
+ return &emptyconstraint;
+ case 0x1C0:
+ return &amd_f15_PMC53;
+ default:
+ return &amd_f15_PMC50;
+ }
+ case AMD_EVENT_CU:
+ case AMD_EVENT_IC_DE:
+ case AMD_EVENT_DE:
+ switch (event_code) {
+ case 0x08F:
+ case 0x187:
+ case 0x188:
+ return &amd_f15_PMC0;
+ case 0x0DB ... 0x0DF:
+ case 0x1D6:
+ case 0x1D8:
+ return &amd_f15_PMC50;
+ default:
+ return &amd_f15_PMC20;
+ }
+ case AMD_EVENT_NB:
+ /* moved to perf_event_amd_uncore.c */
+ return &emptyconstraint;
+ default:
+ return &emptyconstraint;
+ }
+}
+
+static ssize_t amd_event_sysfs_show(char *page, u64 config)
+{
+ u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
+ (config & AMD64_EVENTSEL_EVENT) >> 24;
+
+ return x86_event_sysfs_show(page, config, event);
+}
+
+static __initconst const struct x86_pmu amd_pmu = {
+ .name = "AMD",
+ .handle_irq = x86_pmu_handle_irq,
+ .disable_all = x86_pmu_disable_all,
+ .enable_all = x86_pmu_enable_all,
+ .enable = x86_pmu_enable_event,
+ .disable = x86_pmu_disable_event,
+ .hw_config = amd_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_K7_EVNTSEL0,
+ .perfctr = MSR_K7_PERFCTR0,
+ .addr_offset = amd_pmu_addr_offset,
+ .event_map = amd_pmu_event_map,
+ .max_events = ARRAY_SIZE(amd_perfmon_event_map),
+ .num_counters = AMD64_NUM_COUNTERS,
+ .cntval_bits = 48,
+ .cntval_mask = (1ULL << 48) - 1,
+ .apic = 1,
+ /* use highest bit to detect overflow */
+ .max_period = (1ULL << 47) - 1,
+ .get_event_constraints = amd_get_event_constraints,
+ .put_event_constraints = amd_put_event_constraints,
+
+ .format_attrs = amd_format_attr,
+ .events_sysfs_show = amd_event_sysfs_show,
+
+ .cpu_prepare = amd_pmu_cpu_prepare,
+ .cpu_starting = amd_pmu_cpu_starting,
+ .cpu_dead = amd_pmu_cpu_dead,
+};
+
+static int __init amd_core_pmu_init(void)
+{
+ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
+ return 0;
+
+ switch (boot_cpu_data.x86) {
+ case 0x15:
+ pr_cont("Fam15h ");
+ x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
+ break;
+
+ default:
+ pr_err("core perfctr but no constraints; unknown hardware!\n");
+ return -ENODEV;
+ }
+
+ /*
+ * If core performance counter extensions exists, we must use
+ * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
+ * amd_pmu_addr_offset().
+ */
+ x86_pmu.eventsel = MSR_F15H_PERF_CTL;
+ x86_pmu.perfctr = MSR_F15H_PERF_CTR;
+ x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
+
+ pr_cont("core perfctr, ");
+ return 0;
+}
+
+__init int amd_pmu_init(void)
+{
+ int ret;
+
+ /* Performance-monitoring supported from K7 and later: */
+ if (boot_cpu_data.x86 < 6)
+ return -ENODEV;
+
+ x86_pmu = amd_pmu;
+
+ ret = amd_core_pmu_init();
+ if (ret)
+ return ret;
+
+ /* Events are common for all AMDs */
+ memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ return 0;
+}
+
+void amd_pmu_enable_virt(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ cpuc->perf_ctr_virt_mask = 0;
+
+ /* Reload all events */
+ x86_pmu_disable_all();
+ x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
+
+void amd_pmu_disable_virt(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ /*
+ * We only mask out the Host-only bit so that host-only counting works
+ * when SVM is disabled. If someone sets up a guest-only counter when
+ * SVM is disabled the Guest-only bits still gets set and the counter
+ * will not count anything.
+ */
+ cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
+
+ /* Reload all events */
+ x86_pmu_disable_all();
+ x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
new file mode 100644
index 0000000..51087c2
--- /dev/null
+++ b/arch/x86/events/amd/ibs.c
@@ -0,0 +1,959 @@
+/*
+ * Performance events - AMD IBS
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+static u32 ibs_caps;
+
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
+
+#include <linux/kprobes.h>
+#include <linux/hardirq.h>
+
+#include <asm/nmi.h>
+
+#define IBS_FETCH_CONFIG_MASK (IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
+#define IBS_OP_CONFIG_MASK IBS_OP_MAX_CNT
+
+enum ibs_states {
+ IBS_ENABLED = 0,
+ IBS_STARTED = 1,
+ IBS_STOPPING = 2,
+
+ IBS_MAX_STATES,
+};
+
+struct cpu_perf_ibs {
+ struct perf_event *event;
+ unsigned long state[BITS_TO_LONGS(IBS_MAX_STATES)];
+};
+
+struct perf_ibs {
+ struct pmu pmu;
+ unsigned int msr;
+ u64 config_mask;
+ u64 cnt_mask;
+ u64 enable_mask;
+ u64 valid_mask;
+ u64 max_period;
+ unsigned long offset_mask[1];
+ int offset_max;
+ struct cpu_perf_ibs __percpu *pcpu;
+
+ struct attribute **format_attrs;
+ struct attribute_group format_group;
+ const struct attribute_group *attr_groups[2];
+
+ u64 (*get_count)(u64 config);
+};
+
+struct perf_ibs_data {
+ u32 size;
+ union {
+ u32 data[0]; /* data buffer starts here */
+ u32 caps;
+ };
+ u64 regs[MSR_AMD64_IBS_REG_COUNT_MAX];
+};
+
+static int
+perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
+{
+ s64 left = local64_read(&hwc->period_left);
+ s64 period = hwc->sample_period;
+ int overflow = 0;
+
+ /*
+ * If we are way outside a reasonable range then just skip forward:
+ */
+ if (unlikely(left <= -period)) {
+ left = period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ overflow = 1;
+ }
+
+ if (unlikely(left < (s64)min)) {
+ left += period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ overflow = 1;
+ }
+
+ /*
+ * If the hw period that triggers the sw overflow is too short
+ * we might hit the irq handler. This biases the results.
+ * Thus we shorten the next-to-last period and set the last
+ * period to the max period.
+ */
+ if (left > max) {
+ left -= max;
+ if (left > max)
+ left = max;
+ else if (left < min)
+ left = min;
+ }
+
+ *hw_period = (u64)left;
+
+ return overflow;
+}
+
+static int
+perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int shift = 64 - width;
+ u64 prev_raw_count;
+ u64 delta;
+
+ /*
+ * Careful: an NMI might modify the previous event value.
+ *
+ * Our tactic to handle this is to first atomically read and
+ * exchange a new raw count - then add that new-prev delta
+ * count to the generic event atomically:
+ */
+ prev_raw_count = local64_read(&hwc->prev_count);
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ return 0;
+
+ /*
+ * Now we have the new raw value and have updated the prev
+ * timestamp already. We can now calculate the elapsed delta
+ * (event-)time and add that to the generic event.
+ *
+ * Careful, not all hw sign-extends above the physical width
+ * of the count.
+ */
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return 1;
+}
+
+static struct perf_ibs perf_ibs_fetch;
+static struct perf_ibs perf_ibs_op;
+
+static struct perf_ibs *get_ibs_pmu(int type)
+{
+ if (perf_ibs_fetch.pmu.type == type)
+ return &perf_ibs_fetch;
+ if (perf_ibs_op.pmu.type == type)
+ return &perf_ibs_op;
+ return NULL;
+}
+
+/*
+ * Use IBS for precise event sampling:
+ *
+ * perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count
+ * perf record -a -e r076:p ... # same as -e cpu-cycles:p
+ * perf record -a -e r0C1:p ... # use ibs op counting micro-ops
+ *
+ * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
+ * MSRC001_1033) is used to select either cycle or micro-ops counting
+ * mode.
+ *
+ * The rip of IBS samples has skid 0. Thus, IBS supports precise
+ * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
+ * rip is invalid when IBS was not able to record the rip correctly.
+ * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
+ *
+ */
+static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
+{
+ switch (event->attr.precise_ip) {
+ case 0:
+ return -ENOENT;
+ case 1:
+ case 2:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ switch (event->attr.type) {
+ case PERF_TYPE_HARDWARE:
+ switch (event->attr.config) {
+ case PERF_COUNT_HW_CPU_CYCLES:
+ *config = 0;
+ return 0;
+ }
+ break;
+ case PERF_TYPE_RAW:
+ switch (event->attr.config) {
+ case 0x0076:
+ *config = 0;
+ return 0;
+ case 0x00C1:
+ *config = IBS_OP_CNT_CTL;
+ return 0;
+ }
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static const struct perf_event_attr ibs_notsupp = {
+ .exclude_user = 1,
+ .exclude_kernel = 1,
+ .exclude_hv = 1,
+ .exclude_idle = 1,
+ .exclude_host = 1,
+ .exclude_guest = 1,
+};
+
+static int perf_ibs_init(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_ibs *perf_ibs;
+ u64 max_cnt, config;
+ int ret;
+
+ perf_ibs = get_ibs_pmu(event->attr.type);
+ if (perf_ibs) {
+ config = event->attr.config;
+ } else {
+ perf_ibs = &perf_ibs_op;
+ ret = perf_ibs_precise_event(event, &config);
+ if (ret)
+ return ret;
+ }
+
+ if (event->pmu != &perf_ibs->pmu)
+ return -ENOENT;
+
+ if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+ return -EINVAL;
+
+ if (config & ~perf_ibs->config_mask)
+ return -EINVAL;
+
+ if (hwc->sample_period) {
+ if (config & perf_ibs->cnt_mask)
+ /* raw max_cnt may not be set */
+ return -EINVAL;
+ if (!event->attr.sample_freq && hwc->sample_period & 0x0f)
+ /*
+ * lower 4 bits can not be set in ibs max cnt,
+ * but allowing it in case we adjust the
+ * sample period to set a frequency.
+ */
+ return -EINVAL;
+ hwc->sample_period &= ~0x0FULL;
+ if (!hwc->sample_period)
+ hwc->sample_period = 0x10;
+ } else {
+ max_cnt = config & perf_ibs->cnt_mask;
+ config &= ~perf_ibs->cnt_mask;
+ event->attr.sample_period = max_cnt << 4;
+ hwc->sample_period = event->attr.sample_period;
+ }
+
+ if (!hwc->sample_period)
+ return -EINVAL;
+
+ /*
+ * If we modify hwc->sample_period, we also need to update
+ * hwc->last_period and hwc->period_left.
+ */
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+
+ hwc->config_base = perf_ibs->msr;
+ hwc->config = config;
+
+ return 0;
+}
+
+static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
+ struct hw_perf_event *hwc, u64 *period)
+{
+ int overflow;
+
+ /* ignore lower 4 bits in min count: */
+ overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
+ local64_set(&hwc->prev_count, 0);
+
+ return overflow;
+}
+
+static u64 get_ibs_fetch_count(u64 config)
+{
+ return (config & IBS_FETCH_CNT) >> 12;
+}
+
+static u64 get_ibs_op_count(u64 config)
+{
+ u64 count = 0;
+
+ if (config & IBS_OP_VAL)
+ count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */
+
+ if (ibs_caps & IBS_CAPS_RDWROPCNT)
+ count += (config & IBS_OP_CUR_CNT) >> 32;
+
+ return count;
+}
+
+static void
+perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
+ u64 *config)
+{
+ u64 count = perf_ibs->get_count(*config);
+
+ /*
+ * Set width to 64 since we do not overflow on max width but
+ * instead on max count. In perf_ibs_set_period() we clear
+ * prev count manually on overflow.
+ */
+ while (!perf_event_try_update(event, count, 64)) {
+ rdmsrl(event->hw.config_base, *config);
+ count = perf_ibs->get_count(*config);
+ }
+}
+
+static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
+ struct hw_perf_event *hwc, u64 config)
+{
+ wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
+}
+
+/*
+ * Erratum #420 Instruction-Based Sampling Engine May Generate
+ * Interrupt that Cannot Be Cleared:
+ *
+ * Must clear counter mask first, then clear the enable bit. See
+ * Revision Guide for AMD Family 10h Processors, Publication #41322.
+ */
+static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
+ struct hw_perf_event *hwc, u64 config)
+{
+ config &= ~perf_ibs->cnt_mask;
+ wrmsrl(hwc->config_base, config);
+ config &= ~perf_ibs->enable_mask;
+ wrmsrl(hwc->config_base, config);
+}
+
+/*
+ * We cannot restore the ibs pmu state, so we always needs to update
+ * the event while stopping it and then reset the state when starting
+ * again. Thus, ignoring PERF_EF_RELOAD and PERF_EF_UPDATE flags in
+ * perf_ibs_start()/perf_ibs_stop() and instead always do it.
+ */
+static void perf_ibs_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+ struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+ u64 period;
+
+ if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+ return;
+
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+ hwc->state = 0;
+
+ perf_ibs_set_period(perf_ibs, hwc, &period);
+ set_bit(IBS_STARTED, pcpu->state);
+ perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+
+ perf_event_update_userpage(event);
+}
+
+static void perf_ibs_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+ struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+ u64 config;
+ int stopping;
+
+ stopping = test_and_clear_bit(IBS_STARTED, pcpu->state);
+
+ if (!stopping && (hwc->state & PERF_HES_UPTODATE))
+ return;
+
+ rdmsrl(hwc->config_base, config);
+
+ if (stopping) {
+ set_bit(IBS_STOPPING, pcpu->state);
+ perf_ibs_disable_event(perf_ibs, hwc, config);
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+ }
+
+ if (hwc->state & PERF_HES_UPTODATE)
+ return;
+
+ /*
+ * Clear valid bit to not count rollovers on update, rollovers
+ * are only updated in the irq handler.
+ */
+ config &= ~perf_ibs->valid_mask;
+
+ perf_ibs_event_update(perf_ibs, event, &config);
+ hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int perf_ibs_add(struct perf_event *event, int flags)
+{
+ struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+ struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+ if (test_and_set_bit(IBS_ENABLED, pcpu->state))
+ return -ENOSPC;
+
+ event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+ pcpu->event = event;
+
+ if (flags & PERF_EF_START)
+ perf_ibs_start(event, PERF_EF_RELOAD);
+
+ return 0;
+}
+
+static void perf_ibs_del(struct perf_event *event, int flags)
+{
+ struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+ struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+ if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
+ return;
+
+ perf_ibs_stop(event, PERF_EF_UPDATE);
+
+ pcpu->event = NULL;
+
+ perf_event_update_userpage(event);
+}
+
+static void perf_ibs_read(struct perf_event *event) { }
+
+PMU_FORMAT_ATTR(rand_en, "config:57");
+PMU_FORMAT_ATTR(cnt_ctl, "config:19");
+
+static struct attribute *ibs_fetch_format_attrs[] = {
+ &format_attr_rand_en.attr,
+ NULL,
+};
+
+static struct attribute *ibs_op_format_attrs[] = {
+ NULL, /* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
+ NULL,
+};
+
+static struct perf_ibs perf_ibs_fetch = {
+ .pmu = {
+ .task_ctx_nr = perf_invalid_context,
+
+ .event_init = perf_ibs_init,
+ .add = perf_ibs_add,
+ .del = perf_ibs_del,
+ .start = perf_ibs_start,
+ .stop = perf_ibs_stop,
+ .read = perf_ibs_read,
+ },
+ .msr = MSR_AMD64_IBSFETCHCTL,
+ .config_mask = IBS_FETCH_CONFIG_MASK,
+ .cnt_mask = IBS_FETCH_MAX_CNT,
+ .enable_mask = IBS_FETCH_ENABLE,
+ .valid_mask = IBS_FETCH_VAL,
+ .max_period = IBS_FETCH_MAX_CNT << 4,
+ .offset_mask = { MSR_AMD64_IBSFETCH_REG_MASK },
+ .offset_max = MSR_AMD64_IBSFETCH_REG_COUNT,
+ .format_attrs = ibs_fetch_format_attrs,
+
+ .get_count = get_ibs_fetch_count,
+};
+
+static struct perf_ibs perf_ibs_op = {
+ .pmu = {
+ .task_ctx_nr = perf_invalid_context,
+
+ .event_init = perf_ibs_init,
+ .add = perf_ibs_add,
+ .del = perf_ibs_del,
+ .start = perf_ibs_start,
+ .stop = perf_ibs_stop,
+ .read = perf_ibs_read,
+ },
+ .msr = MSR_AMD64_IBSOPCTL,
+ .config_mask = IBS_OP_CONFIG_MASK,
+ .cnt_mask = IBS_OP_MAX_CNT,
+ .enable_mask = IBS_OP_ENABLE,
+ .valid_mask = IBS_OP_VAL,
+ .max_period = IBS_OP_MAX_CNT << 4,
+ .offset_mask = { MSR_AMD64_IBSOP_REG_MASK },
+ .offset_max = MSR_AMD64_IBSOP_REG_COUNT,
+ .format_attrs = ibs_op_format_attrs,
+
+ .get_count = get_ibs_op_count,
+};
+
+static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
+{
+ struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+ struct perf_event *event = pcpu->event;
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_sample_data data;
+ struct perf_raw_record raw;
+ struct pt_regs regs;
+ struct perf_ibs_data ibs_data;
+ int offset, size, check_rip, offset_max, throttle = 0;
+ unsigned int msr;
+ u64 *buf, *config, period;
+
+ if (!test_bit(IBS_STARTED, pcpu->state)) {
+ /*
+ * Catch spurious interrupts after stopping IBS: After
+ * disabling IBS there could be still incoming NMIs
+ * with samples that even have the valid bit cleared.
+ * Mark all this NMIs as handled.
+ */
+ return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0;
+ }
+
+ msr = hwc->config_base;
+ buf = ibs_data.regs;
+ rdmsrl(msr, *buf);
+ if (!(*buf++ & perf_ibs->valid_mask))
+ return 0;
+
+ config = &ibs_data.regs[0];
+ perf_ibs_event_update(perf_ibs, event, config);
+ perf_sample_data_init(&data, 0, hwc->last_period);
+ if (!perf_ibs_set_period(perf_ibs, hwc, &period))
+ goto out; /* no sw counter overflow */
+
+ ibs_data.caps = ibs_caps;
+ size = 1;
+ offset = 1;
+ check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
+ if (event->attr.sample_type & PERF_SAMPLE_RAW)
+ offset_max = perf_ibs->offset_max;
+ else if (check_rip)
+ offset_max = 2;
+ else
+ offset_max = 1;
+ do {
+ rdmsrl(msr + offset, *buf++);
+ size++;
+ offset = find_next_bit(perf_ibs->offset_mask,
+ perf_ibs->offset_max,
+ offset + 1);
+ } while (offset < offset_max);
+ if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+ /*
+ * Read IbsBrTarget and IbsOpData4 separately
+ * depending on their availability.
+ * Can't add to offset_max as they are staggered
+ */
+ if (ibs_caps & IBS_CAPS_BRNTRGT) {
+ rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
+ size++;
+ }
+ if (ibs_caps & IBS_CAPS_OPDATA4) {
+ rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
+ size++;
+ }
+ }
+ ibs_data.size = sizeof(u64) * size;
+
+ regs = *iregs;
+ if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
+ regs.flags &= ~PERF_EFLAGS_EXACT;
+ } else {
+ set_linear_ip(&regs, ibs_data.regs[1]);
+ regs.flags |= PERF_EFLAGS_EXACT;
+ }
+
+ if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+ raw.size = sizeof(u32) + ibs_data.size;
+ raw.data = ibs_data.data;
+ data.raw = &raw;
+ }
+
+ throttle = perf_event_overflow(event, &data, &regs);
+out:
+ if (throttle)
+ perf_ibs_disable_event(perf_ibs, hwc, *config);
+ else
+ perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+
+ perf_event_update_userpage(event);
+
+ return 1;
+}
+
+static int
+perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
+{
+ int handled = 0;
+
+ handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
+ handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
+
+ if (handled)
+ inc_irq_stat(apic_perf_irqs);
+
+ return handled;
+}
+NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
+
+static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
+{
+ struct cpu_perf_ibs __percpu *pcpu;
+ int ret;
+
+ pcpu = alloc_percpu(struct cpu_perf_ibs);
+ if (!pcpu)
+ return -ENOMEM;
+
+ perf_ibs->pcpu = pcpu;
+
+ /* register attributes */
+ if (perf_ibs->format_attrs[0]) {
+ memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
+ perf_ibs->format_group.name = "format";
+ perf_ibs->format_group.attrs = perf_ibs->format_attrs;
+
+ memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
+ perf_ibs->attr_groups[0] = &perf_ibs->format_group;
+ perf_ibs->pmu.attr_groups = perf_ibs->attr_groups;
+ }
+
+ ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
+ if (ret) {
+ perf_ibs->pcpu = NULL;
+ free_percpu(pcpu);
+ }
+
+ return ret;
+}
+
+static __init int perf_event_ibs_init(void)
+{
+ struct attribute **attr = ibs_op_format_attrs;
+
+ if (!ibs_caps)
+ return -ENODEV; /* ibs not supported by the cpu */
+
+ perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
+
+ if (ibs_caps & IBS_CAPS_OPCNT) {
+ perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
+ *attr++ = &format_attr_cnt_ctl.attr;
+ }
+ perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
+
+ register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
+ pr_info("perf: AMD IBS detected (0x%08x)\n", ibs_caps);
+
+ return 0;
+}
+
+#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
+
+static __init int perf_event_ibs_init(void) { return 0; }
+
+#endif
+
+/* IBS - apic initialization, for perf and oprofile */
+
+static __init u32 __get_ibs_caps(void)
+{
+ u32 caps;
+ unsigned int max_level;
+
+ if (!boot_cpu_has(X86_FEATURE_IBS))
+ return 0;
+
+ /* check IBS cpuid feature flags */
+ max_level = cpuid_eax(0x80000000);
+ if (max_level < IBS_CPUID_FEATURES)
+ return IBS_CAPS_DEFAULT;
+
+ caps = cpuid_eax(IBS_CPUID_FEATURES);
+ if (!(caps & IBS_CAPS_AVAIL))
+ /* cpuid flags not valid */
+ return IBS_CAPS_DEFAULT;
+
+ return caps;
+}
+
+u32 get_ibs_caps(void)
+{
+ return ibs_caps;
+}
+
+EXPORT_SYMBOL(get_ibs_caps);
+
+static inline int get_eilvt(int offset)
+{
+ return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
+}
+
+static inline int put_eilvt(int offset)
+{
+ return !setup_APIC_eilvt(offset, 0, 0, 1);
+}
+
+/*
+ * Check and reserve APIC extended interrupt LVT offset for IBS if available.
+ */
+static inline int ibs_eilvt_valid(void)
+{
+ int offset;
+ u64 val;
+ int valid = 0;
+
+ preempt_disable();
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ offset = val & IBSCTL_LVT_OFFSET_MASK;
+
+ if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
+ pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ goto out;
+ }
+
+ if (!get_eilvt(offset)) {
+ pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ goto out;
+ }
+
+ valid = 1;
+out:
+ preempt_enable();
+
+ return valid;
+}
+
+static int setup_ibs_ctl(int ibs_eilvt_off)
+{
+ struct pci_dev *cpu_cfg;
+ int nodes;
+ u32 value = 0;
+
+ nodes = 0;
+ cpu_cfg = NULL;
+ do {
+ cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_10H_NB_MISC,
+ cpu_cfg);
+ if (!cpu_cfg)
+ break;
+ ++nodes;
+ pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
+ | IBSCTL_LVT_OFFSET_VALID);
+ pci_read_config_dword(cpu_cfg, IBSCTL, &value);
+ if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
+ pci_dev_put(cpu_cfg);
+ pr_debug("Failed to setup IBS LVT offset, IBSCTL = 0x%08x\n",
+ value);
+ return -EINVAL;
+ }
+ } while (1);
+
+ if (!nodes) {
+ pr_debug("No CPU node configured for IBS\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/*
+ * This runs only on the current cpu. We try to find an LVT offset and
+ * setup the local APIC. For this we must disable preemption. On
+ * success we initialize all nodes with this offset. This updates then
+ * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
+ * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
+ * is using the new offset.
+ */
+static void force_ibs_eilvt_setup(void)
+{
+ int offset;
+ int ret;
+
+ preempt_disable();
+ /* find the next free available EILVT entry, skip offset 0 */
+ for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
+ if (get_eilvt(offset))
+ break;
+ }
+ preempt_enable();
+
+ if (offset == APIC_EILVT_NR_MAX) {
+ pr_debug("No EILVT entry available\n");
+ return;
+ }
+
+ ret = setup_ibs_ctl(offset);
+ if (ret)
+ goto out;
+
+ if (!ibs_eilvt_valid())
+ goto out;
+
+ pr_info("IBS: LVT offset %d assigned\n", offset);
+
+ return;
+out:
+ preempt_disable();
+ put_eilvt(offset);
+ preempt_enable();
+ return;
+}
+
+static void ibs_eilvt_setup(void)
+{
+ /*
+ * Force LVT offset assignment for family 10h: The offsets are
+ * not assigned by the BIOS for this family, so the OS is
+ * responsible for doing it. If the OS assignment fails, fall
+ * back to BIOS settings and try to setup this.
+ */
+ if (boot_cpu_data.x86 == 0x10)
+ force_ibs_eilvt_setup();
+}
+
+static inline int get_ibs_lvt_offset(void)
+{
+ u64 val;
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ if (!(val & IBSCTL_LVT_OFFSET_VALID))
+ return -EINVAL;
+
+ return val & IBSCTL_LVT_OFFSET_MASK;
+}
+
+static void setup_APIC_ibs(void *dummy)
+{
+ int offset;
+
+ offset = get_ibs_lvt_offset();
+ if (offset < 0)
+ goto failed;
+
+ if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
+ return;
+failed:
+ pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
+ smp_processor_id());
+}
+
+static void clear_APIC_ibs(void *dummy)
+{
+ int offset;
+
+ offset = get_ibs_lvt_offset();
+ if (offset >= 0)
+ setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+}
+
+#ifdef CONFIG_PM
+
+static int perf_ibs_suspend(void)
+{
+ clear_APIC_ibs(NULL);
+ return 0;
+}
+
+static void perf_ibs_resume(void)
+{
+ ibs_eilvt_setup();
+ setup_APIC_ibs(NULL);
+}
+
+static struct syscore_ops perf_ibs_syscore_ops = {
+ .resume = perf_ibs_resume,
+ .suspend = perf_ibs_suspend,
+};
+
+static void perf_ibs_pm_init(void)
+{
+ register_syscore_ops(&perf_ibs_syscore_ops);
+}
+
+#else
+
+static inline void perf_ibs_pm_init(void) { }
+
+#endif
+
+static int
+perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_STARTING:
+ setup_APIC_ibs(NULL);
+ break;
+ case CPU_DYING:
+ clear_APIC_ibs(NULL);
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static __init int amd_ibs_init(void)
+{
+ u32 caps;
+ int ret = -EINVAL;
+
+ caps = __get_ibs_caps();
+ if (!caps)
+ return -ENODEV; /* ibs not supported by the cpu */
+
+ ibs_eilvt_setup();
+
+ if (!ibs_eilvt_valid())
+ goto out;
+
+ perf_ibs_pm_init();
+ cpu_notifier_register_begin();
+ ibs_caps = caps;
+ /* make ibs_caps visible to other cpus: */
+ smp_mb();
+ smp_call_function(setup_APIC_ibs, NULL, 1);
+ __perf_cpu_notifier(perf_ibs_cpu_notifier);
+ cpu_notifier_register_done();
+
+ ret = perf_event_ibs_init();
+out:
+ if (ret)
+ pr_err("Failed to setup IBS, %d\n", ret);
+ return ret;
+}
+
+/* Since we need the pci subsystem to init ibs we can't do this earlier: */
+device_initcall(amd_ibs_init);
diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
new file mode 100644
index 0000000..635e5eb
--- /dev/null
+++ b/arch/x86/events/amd/iommu.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Steven Kinney <Steven.Kinney@amd.com>
+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
+ *
+ * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/cpumask.h>
+#include <linux/slab.h>
+
+#include "../perf_event.h"
+#include "iommu.h"
+
+#define COUNTER_SHIFT 16
+
+#define _GET_BANK(ev) ((u8)(ev->hw.extra_reg.reg >> 8))
+#define _GET_CNTR(ev) ((u8)(ev->hw.extra_reg.reg))
+
+/* iommu pmu config masks */
+#define _GET_CSOURCE(ev) ((ev->hw.config & 0xFFULL))
+#define _GET_DEVID(ev) ((ev->hw.config >> 8) & 0xFFFFULL)
+#define _GET_PASID(ev) ((ev->hw.config >> 24) & 0xFFFFULL)
+#define _GET_DOMID(ev) ((ev->hw.config >> 40) & 0xFFFFULL)
+#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config) & 0xFFFFULL)
+#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
+#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
+
+static struct perf_amd_iommu __perf_iommu;
+
+struct perf_amd_iommu {
+ struct pmu pmu;
+ u8 max_banks;
+ u8 max_counters;
+ u64 cntr_assign_mask;
+ raw_spinlock_t lock;
+ const struct attribute_group *attr_groups[4];
+};
+
+#define format_group attr_groups[0]
+#define cpumask_group attr_groups[1]
+#define events_group attr_groups[2]
+#define null_group attr_groups[3]
+
+/*---------------------------------------------
+ * sysfs format attributes
+ *---------------------------------------------*/
+PMU_FORMAT_ATTR(csource, "config:0-7");
+PMU_FORMAT_ATTR(devid, "config:8-23");
+PMU_FORMAT_ATTR(pasid, "config:24-39");
+PMU_FORMAT_ATTR(domid, "config:40-55");
+PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
+PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
+PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
+
+static struct attribute *iommu_format_attrs[] = {
+ &format_attr_csource.attr,
+ &format_attr_devid.attr,
+ &format_attr_pasid.attr,
+ &format_attr_domid.attr,
+ &format_attr_devid_mask.attr,
+ &format_attr_pasid_mask.attr,
+ &format_attr_domid_mask.attr,
+ NULL,
+};
+
+static struct attribute_group amd_iommu_format_group = {
+ .name = "format",
+ .attrs = iommu_format_attrs,
+};
+
+/*---------------------------------------------
+ * sysfs events attributes
+ *---------------------------------------------*/
+struct amd_iommu_event_desc {
+ struct kobj_attribute attr;
+ const char *event;
+};
+
+static ssize_t _iommu_event_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct amd_iommu_event_desc *event =
+ container_of(attr, struct amd_iommu_event_desc, attr);
+ return sprintf(buf, "%s\n", event->event);
+}
+
+#define AMD_IOMMU_EVENT_DESC(_name, _event) \
+{ \
+ .attr = __ATTR(_name, 0444, _iommu_event_show, NULL), \
+ .event = _event, \
+}
+
+static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
+ AMD_IOMMU_EVENT_DESC(mem_pass_untrans, "csource=0x01"),
+ AMD_IOMMU_EVENT_DESC(mem_pass_pretrans, "csource=0x02"),
+ AMD_IOMMU_EVENT_DESC(mem_pass_excl, "csource=0x03"),
+ AMD_IOMMU_EVENT_DESC(mem_target_abort, "csource=0x04"),
+ AMD_IOMMU_EVENT_DESC(mem_trans_total, "csource=0x05"),
+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit, "csource=0x06"),
+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis, "csource=0x07"),
+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit, "csource=0x08"),
+ AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis, "csource=0x09"),
+ AMD_IOMMU_EVENT_DESC(mem_dte_hit, "csource=0x0a"),
+ AMD_IOMMU_EVENT_DESC(mem_dte_mis, "csource=0x0b"),
+ AMD_IOMMU_EVENT_DESC(page_tbl_read_tot, "csource=0x0c"),
+ AMD_IOMMU_EVENT_DESC(page_tbl_read_nst, "csource=0x0d"),
+ AMD_IOMMU_EVENT_DESC(page_tbl_read_gst, "csource=0x0e"),
+ AMD_IOMMU_EVENT_DESC(int_dte_hit, "csource=0x0f"),
+ AMD_IOMMU_EVENT_DESC(int_dte_mis, "csource=0x10"),
+ AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"),
+ AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"),
+ AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"),
+ { /* end: all zeroes */ },
+};
+
+/*---------------------------------------------
+ * sysfs cpumask attributes
+ *---------------------------------------------*/
+static cpumask_t iommu_cpumask;
+
+static ssize_t _iommu_cpumask_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
+}
+static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
+
+static struct attribute *iommu_cpumask_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group amd_iommu_cpumask_group = {
+ .attrs = iommu_cpumask_attrs,
+};
+
+/*---------------------------------------------*/
+
+static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
+{
+ unsigned long flags;
+ int shift, bank, cntr, retval;
+ int max_banks = perf_iommu->max_banks;
+ int max_cntrs = perf_iommu->max_counters;
+
+ raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+
+ for (bank = 0, shift = 0; bank < max_banks; bank++) {
+ for (cntr = 0; cntr < max_cntrs; cntr++) {
+ shift = bank + (bank*3) + cntr;
+ if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
+ continue;
+ } else {
+ perf_iommu->cntr_assign_mask |= (1ULL<<shift);
+ retval = ((u16)((u16)bank<<8) | (u8)(cntr));
+ goto out;
+ }
+ }
+ }
+ retval = -ENOSPC;
+out:
+ raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+ return retval;
+}
+
+static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
+ u8 bank, u8 cntr)
+{
+ unsigned long flags;
+ int max_banks, max_cntrs;
+ int shift = 0;
+
+ max_banks = perf_iommu->max_banks;
+ max_cntrs = perf_iommu->max_counters;
+
+ if ((bank > max_banks) || (cntr > max_cntrs))
+ return -EINVAL;
+
+ shift = bank + cntr + (bank*3);
+
+ raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+ perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
+ raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+
+ return 0;
+}
+
+static int perf_iommu_event_init(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_amd_iommu *perf_iommu;
+ u64 config, config1;
+
+ /* test the event attr type check for PMU enumeration */
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ /*
+ * IOMMU counters are shared across all cores.
+ * Therefore, it does not support per-process mode.
+ * Also, it does not support event sampling mode.
+ */
+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+ return -EINVAL;
+
+ /* IOMMU counters do not have usr/os/guest/host bits */
+ if (event->attr.exclude_user || event->attr.exclude_kernel ||
+ event->attr.exclude_host || event->attr.exclude_guest)
+ return -EINVAL;
+
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ perf_iommu = &__perf_iommu;
+
+ if (event->pmu != &perf_iommu->pmu)
+ return -ENOENT;
+
+ if (perf_iommu) {
+ config = event->attr.config;
+ config1 = event->attr.config1;
+ } else {
+ return -EINVAL;
+ }
+
+ /* integrate with iommu base devid (0000), assume one iommu */
+ perf_iommu->max_banks =
+ amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
+ perf_iommu->max_counters =
+ amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
+ if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
+ return -EINVAL;
+
+ /* update the hw_perf_event struct with the iommu config data */
+ hwc->config = config;
+ hwc->extra_reg.config = config1;
+
+ return 0;
+}
+
+static void perf_iommu_enable_event(struct perf_event *ev)
+{
+ u8 csource = _GET_CSOURCE(ev);
+ u16 devid = _GET_DEVID(ev);
+ u64 reg = 0ULL;
+
+ reg = csource;
+ amd_iommu_pc_get_set_reg_val(devid,
+ _GET_BANK(ev), _GET_CNTR(ev) ,
+ IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+
+ reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
+ if (reg)
+ reg |= (1UL << 31);
+ amd_iommu_pc_get_set_reg_val(devid,
+ _GET_BANK(ev), _GET_CNTR(ev) ,
+ IOMMU_PC_DEVID_MATCH_REG, &reg, true);
+
+ reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
+ if (reg)
+ reg |= (1UL << 31);
+ amd_iommu_pc_get_set_reg_val(devid,
+ _GET_BANK(ev), _GET_CNTR(ev) ,
+ IOMMU_PC_PASID_MATCH_REG, &reg, true);
+
+ reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
+ if (reg)
+ reg |= (1UL << 31);
+ amd_iommu_pc_get_set_reg_val(devid,
+ _GET_BANK(ev), _GET_CNTR(ev) ,
+ IOMMU_PC_DOMID_MATCH_REG, &reg, true);
+}
+
+static void perf_iommu_disable_event(struct perf_event *event)
+{
+ u64 reg = 0ULL;
+
+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+ _GET_BANK(event), _GET_CNTR(event),
+ IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+}
+
+static void perf_iommu_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ pr_debug("perf: amd_iommu:perf_iommu_start\n");
+ if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+ return;
+
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+ hwc->state = 0;
+
+ if (flags & PERF_EF_RELOAD) {
+ u64 prev_raw_count = local64_read(&hwc->prev_count);
+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+ _GET_BANK(event), _GET_CNTR(event),
+ IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
+ }
+
+ perf_iommu_enable_event(event);
+ perf_event_update_userpage(event);
+
+}
+
+static void perf_iommu_read(struct perf_event *event)
+{
+ u64 count = 0ULL;
+ u64 prev_raw_count = 0ULL;
+ u64 delta = 0ULL;
+ struct hw_perf_event *hwc = &event->hw;
+ pr_debug("perf: amd_iommu:perf_iommu_read\n");
+
+ amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+ _GET_BANK(event), _GET_CNTR(event),
+ IOMMU_PC_COUNTER_REG, &count, false);
+
+ /* IOMMU pc counter register is only 48 bits */
+ count &= 0xFFFFFFFFFFFFULL;
+
+ prev_raw_count = local64_read(&hwc->prev_count);
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ count) != prev_raw_count)
+ return;
+
+ /* Handling 48-bit counter overflowing */
+ delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
+ delta >>= COUNTER_SHIFT;
+ local64_add(delta, &event->count);
+
+}
+
+static void perf_iommu_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 config;
+
+ pr_debug("perf: amd_iommu:perf_iommu_stop\n");
+
+ if (hwc->state & PERF_HES_UPTODATE)
+ return;
+
+ perf_iommu_disable_event(event);
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+
+ if (hwc->state & PERF_HES_UPTODATE)
+ return;
+
+ config = hwc->config;
+ perf_iommu_read(event);
+ hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int perf_iommu_add(struct perf_event *event, int flags)
+{
+ int retval;
+ struct perf_amd_iommu *perf_iommu =
+ container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+ pr_debug("perf: amd_iommu:perf_iommu_add\n");
+ event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+ /* request an iommu bank/counter */
+ retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
+ if (retval != -ENOSPC)
+ event->hw.extra_reg.reg = (u16)retval;
+ else
+ return retval;
+
+ if (flags & PERF_EF_START)
+ perf_iommu_start(event, PERF_EF_RELOAD);
+
+ return 0;
+}
+
+static void perf_iommu_del(struct perf_event *event, int flags)
+{
+ struct perf_amd_iommu *perf_iommu =
+ container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+ pr_debug("perf: amd_iommu:perf_iommu_del\n");
+ perf_iommu_stop(event, PERF_EF_UPDATE);
+
+ /* clear the assigned iommu bank/counter */
+ clear_avail_iommu_bnk_cntr(perf_iommu,
+ _GET_BANK(event),
+ _GET_CNTR(event));
+
+ perf_event_update_userpage(event);
+}
+
+static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
+{
+ struct attribute **attrs;
+ struct attribute_group *attr_group;
+ int i = 0, j;
+
+ while (amd_iommu_v2_event_descs[i].attr.attr.name)
+ i++;
+
+ attr_group = kzalloc(sizeof(struct attribute *)
+ * (i + 1) + sizeof(*attr_group), GFP_KERNEL);
+ if (!attr_group)
+ return -ENOMEM;
+
+ attrs = (struct attribute **)(attr_group + 1);
+ for (j = 0; j < i; j++)
+ attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
+
+ attr_group->name = "events";
+ attr_group->attrs = attrs;
+ perf_iommu->events_group = attr_group;
+
+ return 0;
+}
+
+static __init void amd_iommu_pc_exit(void)
+{
+ if (__perf_iommu.events_group != NULL) {
+ kfree(__perf_iommu.events_group);
+ __perf_iommu.events_group = NULL;
+ }
+}
+
+static __init int _init_perf_amd_iommu(
+ struct perf_amd_iommu *perf_iommu, char *name)
+{
+ int ret;
+
+ raw_spin_lock_init(&perf_iommu->lock);
+
+ /* Init format attributes */
+ perf_iommu->format_group = &amd_iommu_format_group;
+
+ /* Init cpumask attributes to only core 0 */
+ cpumask_set_cpu(0, &iommu_cpumask);
+ perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
+
+ /* Init events attributes */
+ if (_init_events_attrs(perf_iommu) != 0)
+ pr_err("perf: amd_iommu: Only support raw events.\n");
+
+ /* Init null attributes */
+ perf_iommu->null_group = NULL;
+ perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
+
+ ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
+ if (ret) {
+ pr_err("perf: amd_iommu: Failed to initialized.\n");
+ amd_iommu_pc_exit();
+ } else {
+ pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
+ amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
+ amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
+ }
+
+ return ret;
+}
+
+static struct perf_amd_iommu __perf_iommu = {
+ .pmu = {
+ .event_init = perf_iommu_event_init,
+ .add = perf_iommu_add,
+ .del = perf_iommu_del,
+ .start = perf_iommu_start,
+ .stop = perf_iommu_stop,
+ .read = perf_iommu_read,
+ },
+ .max_banks = 0x00,
+ .max_counters = 0x00,
+ .cntr_assign_mask = 0ULL,
+ .format_group = NULL,
+ .cpumask_group = NULL,
+ .events_group = NULL,
+ .null_group = NULL,
+};
+
+static __init int amd_iommu_pc_init(void)
+{
+ /* Make sure the IOMMU PC resource is available */
+ if (!amd_iommu_pc_supported())
+ return -ENODEV;
+
+ _init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
+
+ return 0;
+}
+
+device_initcall(amd_iommu_pc_init);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.h b/arch/x86/events/amd/iommu.h
index 845d173..845d173 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_iommu.h
+++ b/arch/x86/events/amd/iommu.h
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
new file mode 100644
index 0000000..3db9569
--- /dev/null
+++ b/arch/x86/events/amd/uncore.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Jacob Shin <jacob.shin@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+
+#include <asm/cpufeature.h>
+#include <asm/perf_event.h>
+#include <asm/msr.h>
+
+#define NUM_COUNTERS_NB 4
+#define NUM_COUNTERS_L2 4
+#define MAX_COUNTERS NUM_COUNTERS_NB
+
+#define RDPMC_BASE_NB 6
+#define RDPMC_BASE_L2 10
+
+#define COUNTER_SHIFT 16
+
+struct amd_uncore {
+ int id;
+ int refcnt;
+ int cpu;
+ int num_counters;
+ int rdpmc_base;
+ u32 msr_base;
+ cpumask_t *active_mask;
+ struct pmu *pmu;
+ struct perf_event *events[MAX_COUNTERS];
+ struct amd_uncore *free_when_cpu_online;
+};
+
+static struct amd_uncore * __percpu *amd_uncore_nb;
+static struct amd_uncore * __percpu *amd_uncore_l2;
+
+static struct pmu amd_nb_pmu;
+static struct pmu amd_l2_pmu;
+
+static cpumask_t amd_nb_active_mask;
+static cpumask_t amd_l2_active_mask;
+
+static bool is_nb_event(struct perf_event *event)
+{
+ return event->pmu->type == amd_nb_pmu.type;
+}
+
+static bool is_l2_event(struct perf_event *event)
+{
+ return event->pmu->type == amd_l2_pmu.type;
+}
+
+static struct amd_uncore *event_to_amd_uncore(struct perf_event *event)
+{
+ if (is_nb_event(event) && amd_uncore_nb)
+ return *per_cpu_ptr(amd_uncore_nb, event->cpu);
+ else if (is_l2_event(event) && amd_uncore_l2)
+ return *per_cpu_ptr(amd_uncore_l2, event->cpu);
+
+ return NULL;
+}
+
+static void amd_uncore_read(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 prev, new;
+ s64 delta;
+
+ /*
+ * since we do not enable counter overflow interrupts,
+ * we do not have to worry about prev_count changing on us
+ */
+
+ prev = local64_read(&hwc->prev_count);
+ rdpmcl(hwc->event_base_rdpmc, new);
+ local64_set(&hwc->prev_count, new);
+ delta = (new << COUNTER_SHIFT) - (prev << COUNTER_SHIFT);
+ delta >>= COUNTER_SHIFT;
+ local64_add(delta, &event->count);
+}
+
+static void amd_uncore_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (flags & PERF_EF_RELOAD)
+ wrmsrl(hwc->event_base, (u64)local64_read(&hwc->prev_count));
+
+ hwc->state = 0;
+ wrmsrl(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE));
+ perf_event_update_userpage(event);
+}
+
+static void amd_uncore_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ wrmsrl(hwc->config_base, hwc->config);
+ hwc->state |= PERF_HES_STOPPED;
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ amd_uncore_read(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+}
+
+static int amd_uncore_add(struct perf_event *event, int flags)
+{
+ int i;
+ struct amd_uncore *uncore = event_to_amd_uncore(event);
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* are we already assigned? */
+ if (hwc->idx != -1 && uncore->events[hwc->idx] == event)
+ goto out;
+
+ for (i = 0; i < uncore->num_counters; i++) {
+ if (uncore->events[i] == event) {
+ hwc->idx = i;
+ goto out;
+ }
+ }
+
+ /* if not, take the first available counter */
+ hwc->idx = -1;
+ for (i = 0; i < uncore->num_counters; i++) {
+ if (cmpxchg(&uncore->events[i], NULL, event) == NULL) {
+ hwc->idx = i;
+ break;
+ }
+ }
+
+out:
+ if (hwc->idx == -1)
+ return -EBUSY;
+
+ hwc->config_base = uncore->msr_base + (2 * hwc->idx);
+ hwc->event_base = uncore->msr_base + 1 + (2 * hwc->idx);
+ hwc->event_base_rdpmc = uncore->rdpmc_base + hwc->idx;
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+ if (flags & PERF_EF_START)
+ amd_uncore_start(event, PERF_EF_RELOAD);
+
+ return 0;
+}
+
+static void amd_uncore_del(struct perf_event *event, int flags)
+{
+ int i;
+ struct amd_uncore *uncore = event_to_amd_uncore(event);
+ struct hw_perf_event *hwc = &event->hw;
+
+ amd_uncore_stop(event, PERF_EF_UPDATE);
+
+ for (i = 0; i < uncore->num_counters; i++) {
+ if (cmpxchg(&uncore->events[i], event, NULL) == event)
+ break;
+ }
+
+ hwc->idx = -1;
+}
+
+static int amd_uncore_event_init(struct perf_event *event)
+{
+ struct amd_uncore *uncore;
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ /*
+ * NB and L2 counters (MSRs) are shared across all cores that share the
+ * same NB / L2 cache. Interrupts can be directed to a single target
+ * core, however, event counts generated by processes running on other
+ * cores cannot be masked out. So we do not support sampling and
+ * per-thread events.
+ */
+ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+ return -EINVAL;
+
+ /* NB and L2 counters do not have usr/os/guest/host bits */
+ if (event->attr.exclude_user || event->attr.exclude_kernel ||
+ event->attr.exclude_host || event->attr.exclude_guest)
+ return -EINVAL;
+
+ /* and we do not enable counter overflow interrupts */
+ hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
+ hwc->idx = -1;
+
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ uncore = event_to_amd_uncore(event);
+ if (!uncore)
+ return -ENODEV;
+
+ /*
+ * since request can come in to any of the shared cores, we will remap
+ * to a single common cpu.
+ */
+ event->cpu = uncore->cpu;
+
+ return 0;
+}
+
+static ssize_t amd_uncore_attr_show_cpumask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ cpumask_t *active_mask;
+ struct pmu *pmu = dev_get_drvdata(dev);
+
+ if (pmu->type == amd_nb_pmu.type)
+ active_mask = &amd_nb_active_mask;
+ else if (pmu->type == amd_l2_pmu.type)
+ active_mask = &amd_l2_active_mask;
+ else
+ return 0;
+
+ return cpumap_print_to_pagebuf(true, buf, active_mask);
+}
+static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL);
+
+static struct attribute *amd_uncore_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group amd_uncore_attr_group = {
+ .attrs = amd_uncore_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7,32-35");
+PMU_FORMAT_ATTR(umask, "config:8-15");
+
+static struct attribute *amd_uncore_format_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ NULL,
+};
+
+static struct attribute_group amd_uncore_format_group = {
+ .name = "format",
+ .attrs = amd_uncore_format_attr,
+};
+
+static const struct attribute_group *amd_uncore_attr_groups[] = {
+ &amd_uncore_attr_group,
+ &amd_uncore_format_group,
+ NULL,
+};
+
+static struct pmu amd_nb_pmu = {
+ .attr_groups = amd_uncore_attr_groups,
+ .name = "amd_nb",
+ .event_init = amd_uncore_event_init,
+ .add = amd_uncore_add,
+ .del = amd_uncore_del,
+ .start = amd_uncore_start,
+ .stop = amd_uncore_stop,
+ .read = amd_uncore_read,
+};
+
+static struct pmu amd_l2_pmu = {
+ .attr_groups = amd_uncore_attr_groups,
+ .name = "amd_l2",
+ .event_init = amd_uncore_event_init,
+ .add = amd_uncore_add,
+ .del = amd_uncore_del,
+ .start = amd_uncore_start,
+ .stop = amd_uncore_stop,
+ .read = amd_uncore_read,
+};
+
+static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
+{
+ return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL,
+ cpu_to_node(cpu));
+}
+
+static int amd_uncore_cpu_up_prepare(unsigned int cpu)
+{
+ struct amd_uncore *uncore_nb = NULL, *uncore_l2;
+
+ if (amd_uncore_nb) {
+ uncore_nb = amd_uncore_alloc(cpu);
+ if (!uncore_nb)
+ goto fail;
+ uncore_nb->cpu = cpu;
+ uncore_nb->num_counters = NUM_COUNTERS_NB;
+ uncore_nb->rdpmc_base = RDPMC_BASE_NB;
+ uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL;
+ uncore_nb->active_mask = &amd_nb_active_mask;
+ uncore_nb->pmu = &amd_nb_pmu;
+ *per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb;
+ }
+
+ if (amd_uncore_l2) {
+ uncore_l2 = amd_uncore_alloc(cpu);
+ if (!uncore_l2)
+ goto fail;
+ uncore_l2->cpu = cpu;
+ uncore_l2->num_counters = NUM_COUNTERS_L2;
+ uncore_l2->rdpmc_base = RDPMC_BASE_L2;
+ uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL;
+ uncore_l2->active_mask = &amd_l2_active_mask;
+ uncore_l2->pmu = &amd_l2_pmu;
+ *per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2;
+ }
+
+ return 0;
+
+fail:
+ if (amd_uncore_nb)
+ *per_cpu_ptr(amd_uncore_nb, cpu) = NULL;
+ kfree(uncore_nb);
+ return -ENOMEM;
+}
+
+static struct amd_uncore *
+amd_uncore_find_online_sibling(struct amd_uncore *this,
+ struct amd_uncore * __percpu *uncores)
+{
+ unsigned int cpu;
+ struct amd_uncore *that;
+
+ for_each_online_cpu(cpu) {
+ that = *per_cpu_ptr(uncores, cpu);
+
+ if (!that)
+ continue;
+
+ if (this == that)
+ continue;
+
+ if (this->id == that->id) {
+ that->free_when_cpu_online = this;
+ this = that;
+ break;
+ }
+ }
+
+ this->refcnt++;
+ return this;
+}
+
+static void amd_uncore_cpu_starting(unsigned int cpu)
+{
+ unsigned int eax, ebx, ecx, edx;
+ struct amd_uncore *uncore;
+
+ if (amd_uncore_nb) {
+ uncore = *per_cpu_ptr(amd_uncore_nb, cpu);
+ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+ uncore->id = ecx & 0xff;
+
+ uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_nb);
+ *per_cpu_ptr(amd_uncore_nb, cpu) = uncore;
+ }
+
+ if (amd_uncore_l2) {
+ unsigned int apicid = cpu_data(cpu).apicid;
+ unsigned int nshared;
+
+ uncore = *per_cpu_ptr(amd_uncore_l2, cpu);
+ cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx);
+ nshared = ((eax >> 14) & 0xfff) + 1;
+ uncore->id = apicid - (apicid % nshared);
+
+ uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2);
+ *per_cpu_ptr(amd_uncore_l2, cpu) = uncore;
+ }
+}
+
+static void uncore_online(unsigned int cpu,
+ struct amd_uncore * __percpu *uncores)
+{
+ struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
+
+ kfree(uncore->free_when_cpu_online);
+ uncore->free_when_cpu_online = NULL;
+
+ if (cpu == uncore->cpu)
+ cpumask_set_cpu(cpu, uncore->active_mask);
+}
+
+static void amd_uncore_cpu_online(unsigned int cpu)
+{
+ if (amd_uncore_nb)
+ uncore_online(cpu, amd_uncore_nb);
+
+ if (amd_uncore_l2)
+ uncore_online(cpu, amd_uncore_l2);
+}
+
+static void uncore_down_prepare(unsigned int cpu,
+ struct amd_uncore * __percpu *uncores)
+{
+ unsigned int i;
+ struct amd_uncore *this = *per_cpu_ptr(uncores, cpu);
+
+ if (this->cpu != cpu)
+ return;
+
+ /* this cpu is going down, migrate to a shared sibling if possible */
+ for_each_online_cpu(i) {
+ struct amd_uncore *that = *per_cpu_ptr(uncores, i);
+
+ if (cpu == i)
+ continue;
+
+ if (this == that) {
+ perf_pmu_migrate_context(this->pmu, cpu, i);
+ cpumask_clear_cpu(cpu, that->active_mask);
+ cpumask_set_cpu(i, that->active_mask);
+ that->cpu = i;
+ break;
+ }
+ }
+}
+
+static void amd_uncore_cpu_down_prepare(unsigned int cpu)
+{
+ if (amd_uncore_nb)
+ uncore_down_prepare(cpu, amd_uncore_nb);
+
+ if (amd_uncore_l2)
+ uncore_down_prepare(cpu, amd_uncore_l2);
+}
+
+static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
+{
+ struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
+
+ if (cpu == uncore->cpu)
+ cpumask_clear_cpu(cpu, uncore->active_mask);
+
+ if (!--uncore->refcnt)
+ kfree(uncore);
+ *per_cpu_ptr(uncores, cpu) = NULL;
+}
+
+static void amd_uncore_cpu_dead(unsigned int cpu)
+{
+ if (amd_uncore_nb)
+ uncore_dead(cpu, amd_uncore_nb);
+
+ if (amd_uncore_l2)
+ uncore_dead(cpu, amd_uncore_l2);
+}
+
+static int
+amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
+ void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ if (amd_uncore_cpu_up_prepare(cpu))
+ return notifier_from_errno(-ENOMEM);
+ break;
+
+ case CPU_STARTING:
+ amd_uncore_cpu_starting(cpu);
+ break;
+
+ case CPU_ONLINE:
+ amd_uncore_cpu_online(cpu);
+ break;
+
+ case CPU_DOWN_PREPARE:
+ amd_uncore_cpu_down_prepare(cpu);
+ break;
+
+ case CPU_UP_CANCELED:
+ case CPU_DEAD:
+ amd_uncore_cpu_dead(cpu);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block amd_uncore_cpu_notifier_block = {
+ .notifier_call = amd_uncore_cpu_notifier,
+ .priority = CPU_PRI_PERF + 1,
+};
+
+static void __init init_cpu_already_online(void *dummy)
+{
+ unsigned int cpu = smp_processor_id();
+
+ amd_uncore_cpu_starting(cpu);
+ amd_uncore_cpu_online(cpu);
+}
+
+static void cleanup_cpu_online(void *dummy)
+{
+ unsigned int cpu = smp_processor_id();
+
+ amd_uncore_cpu_dead(cpu);
+}
+
+static int __init amd_uncore_init(void)
+{
+ unsigned int cpu, cpu2;
+ int ret = -ENODEV;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ goto fail_nodev;
+
+ if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
+ goto fail_nodev;
+
+ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) {
+ amd_uncore_nb = alloc_percpu(struct amd_uncore *);
+ if (!amd_uncore_nb) {
+ ret = -ENOMEM;
+ goto fail_nb;
+ }
+ ret = perf_pmu_register(&amd_nb_pmu, amd_nb_pmu.name, -1);
+ if (ret)
+ goto fail_nb;
+
+ pr_info("perf: AMD NB counters detected\n");
+ ret = 0;
+ }
+
+ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) {
+ amd_uncore_l2 = alloc_percpu(struct amd_uncore *);
+ if (!amd_uncore_l2) {
+ ret = -ENOMEM;
+ goto fail_l2;
+ }
+ ret = perf_pmu_register(&amd_l2_pmu, amd_l2_pmu.name, -1);
+ if (ret)
+ goto fail_l2;
+
+ pr_info("perf: AMD L2I counters detected\n");
+ ret = 0;
+ }
+
+ if (ret)
+ goto fail_nodev;
+
+ cpu_notifier_register_begin();
+
+ /* init cpus already online before registering for hotplug notifier */
+ for_each_online_cpu(cpu) {
+ ret = amd_uncore_cpu_up_prepare(cpu);
+ if (ret)
+ goto fail_online;
+ smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
+ }
+
+ __register_cpu_notifier(&amd_uncore_cpu_notifier_block);
+ cpu_notifier_register_done();
+
+ return 0;
+
+
+fail_online:
+ for_each_online_cpu(cpu2) {
+ if (cpu2 == cpu)
+ break;
+ smp_call_function_single(cpu, cleanup_cpu_online, NULL, 1);
+ }
+ cpu_notifier_register_done();
+
+ /* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */
+ amd_uncore_nb = amd_uncore_l2 = NULL;
+
+ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2))
+ perf_pmu_unregister(&amd_l2_pmu);
+fail_l2:
+ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB))
+ perf_pmu_unregister(&amd_nb_pmu);
+ if (amd_uncore_l2)
+ free_percpu(amd_uncore_l2);
+fail_nb:
+ if (amd_uncore_nb)
+ free_percpu(amd_uncore_nb);
+
+fail_nodev:
+ return ret;
+}
+device_initcall(amd_uncore_init);
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
new file mode 100644
index 0000000..9b6ad08
--- /dev/null
+++ b/arch/x86/events/core.c
@@ -0,0 +1,2442 @@
+/*
+ * Performance events x86 architecture code
+ *
+ * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ * Copyright (C) 2009 Jaswinder Singh Rajput
+ * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
+ * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ * Copyright (C) 2009 Google, Inc., Stephane Eranian
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+#include <linux/capability.h>
+#include <linux/notifier.h>
+#include <linux/hardirq.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/kdebug.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+
+#include <asm/apic.h>
+#include <asm/stacktrace.h>
+#include <asm/nmi.h>
+#include <asm/smp.h>
+#include <asm/alternative.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+#include <asm/timer.h>
+#include <asm/desc.h>
+#include <asm/ldt.h>
+
+#include "perf_event.h"
+
+struct x86_pmu x86_pmu __read_mostly;
+
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+ .enabled = 1,
+};
+
+struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE;
+
+u64 __read_mostly hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+u64 __read_mostly hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+/*
+ * Propagate event elapsed time into the generic event.
+ * Can only be executed on the CPU where the event is active.
+ * Returns the delta events processed.
+ */
+u64 x86_perf_event_update(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int shift = 64 - x86_pmu.cntval_bits;
+ u64 prev_raw_count, new_raw_count;
+ int idx = hwc->idx;
+ s64 delta;
+
+ if (idx == INTEL_PMC_IDX_FIXED_BTS)
+ return 0;
+
+ /*
+ * Careful: an NMI might modify the previous event value.
+ *
+ * Our tactic to handle this is to first atomically read and
+ * exchange a new raw count - then add that new-prev delta
+ * count to the generic event atomically:
+ */
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ rdpmcl(hwc->event_base_rdpmc, new_raw_count);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ /*
+ * Now we have the new raw value and have updated the prev
+ * timestamp already. We can now calculate the elapsed delta
+ * (event-)time and add that to the generic event.
+ *
+ * Careful, not all hw sign-extends above the physical width
+ * of the count.
+ */
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return new_raw_count;
+}
+
+/*
+ * Find and validate any extra registers to set up.
+ */
+static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg;
+ struct extra_reg *er;
+
+ reg = &event->hw.extra_reg;
+
+ if (!x86_pmu.extra_regs)
+ return 0;
+
+ for (er = x86_pmu.extra_regs; er->msr; er++) {
+ if (er->event != (config & er->config_mask))
+ continue;
+ if (event->attr.config1 & ~er->valid_mask)
+ return -EINVAL;
+ /* Check if the extra msrs can be safely accessed*/
+ if (!er->extra_msr_access)
+ return -ENXIO;
+
+ reg->idx = er->idx;
+ reg->config = event->attr.config1;
+ reg->reg = er->msr;
+ break;
+ }
+ return 0;
+}
+
+static atomic_t active_events;
+static atomic_t pmc_refcount;
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+static bool reserve_pmc_hardware(void)
+{
+ int i;
+
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
+ goto perfctr_fail;
+ }
+
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
+ goto eventsel_fail;
+ }
+
+ return true;
+
+eventsel_fail:
+ for (i--; i >= 0; i--)
+ release_evntsel_nmi(x86_pmu_config_addr(i));
+
+ i = x86_pmu.num_counters;
+
+perfctr_fail:
+ for (i--; i >= 0; i--)
+ release_perfctr_nmi(x86_pmu_event_addr(i));
+
+ return false;
+}
+
+static void release_pmc_hardware(void)
+{
+ int i;
+
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ release_perfctr_nmi(x86_pmu_event_addr(i));
+ release_evntsel_nmi(x86_pmu_config_addr(i));
+ }
+}
+
+#else
+
+static bool reserve_pmc_hardware(void) { return true; }
+static void release_pmc_hardware(void) {}
+
+#endif
+
+static bool check_hw_exists(void)
+{
+ u64 val, val_fail, val_new= ~0;
+ int i, reg, reg_fail, ret = 0;
+ int bios_fail = 0;
+ int reg_safe = -1;
+
+ /*
+ * Check to see if the BIOS enabled any of the counters, if so
+ * complain and bail.
+ */
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ reg = x86_pmu_config_addr(i);
+ ret = rdmsrl_safe(reg, &val);
+ if (ret)
+ goto msr_fail;
+ if (val & ARCH_PERFMON_EVENTSEL_ENABLE) {
+ bios_fail = 1;
+ val_fail = val;
+ reg_fail = reg;
+ } else {
+ reg_safe = i;
+ }
+ }
+
+ if (x86_pmu.num_counters_fixed) {
+ reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+ ret = rdmsrl_safe(reg, &val);
+ if (ret)
+ goto msr_fail;
+ for (i = 0; i < x86_pmu.num_counters_fixed; i++) {
+ if (val & (0x03 << i*4)) {
+ bios_fail = 1;
+ val_fail = val;
+ reg_fail = reg;
+ }
+ }
+ }
+
+ /*
+ * If all the counters are enabled, the below test will always
+ * fail. The tools will also become useless in this scenario.
+ * Just fail and disable the hardware counters.
+ */
+
+ if (reg_safe == -1) {
+ reg = reg_safe;
+ goto msr_fail;
+ }
+
+ /*
+ * Read the current value, change it and read it back to see if it
+ * matches, this is needed to detect certain hardware emulators
+ * (qemu/kvm) that don't trap on the MSR access and always return 0s.
+ */
+ reg = x86_pmu_event_addr(reg_safe);
+ if (rdmsrl_safe(reg, &val))
+ goto msr_fail;
+ val ^= 0xffffUL;
+ ret = wrmsrl_safe(reg, val);
+ ret |= rdmsrl_safe(reg, &val_new);
+ if (ret || val != val_new)
+ goto msr_fail;
+
+ /*
+ * We still allow the PMU driver to operate:
+ */
+ if (bios_fail) {
+ pr_cont("Broken BIOS detected, complain to your hardware vendor.\n");
+ pr_err(FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n",
+ reg_fail, val_fail);
+ }
+
+ return true;
+
+msr_fail:
+ pr_cont("Broken PMU hardware detected, using software events only.\n");
+ pr_info("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
+ boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR,
+ reg, val_new);
+
+ return false;
+}
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+ x86_release_hardware();
+ atomic_dec(&active_events);
+}
+
+void hw_perf_lbr_event_destroy(struct perf_event *event)
+{
+ hw_perf_event_destroy(event);
+
+ /* undo the lbr/bts event accounting */
+ x86_del_exclusive(x86_lbr_exclusive_lbr);
+}
+
+static inline int x86_pmu_initialized(void)
+{
+ return x86_pmu.handle_irq != NULL;
+}
+
+static inline int
+set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+ unsigned int cache_type, cache_op, cache_result;
+ u64 config, val;
+
+ config = attr->config;
+
+ 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;
+
+ val = hw_cache_event_ids[cache_type][cache_op][cache_result];
+
+ if (val == 0)
+ return -ENOENT;
+
+ if (val == -1)
+ return -EINVAL;
+
+ hwc->config |= val;
+ attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
+ return x86_pmu_extra_regs(val, event);
+}
+
+int x86_reserve_hardware(void)
+{
+ int err = 0;
+
+ if (!atomic_inc_not_zero(&pmc_refcount)) {
+ mutex_lock(&pmc_reserve_mutex);
+ if (atomic_read(&pmc_refcount) == 0) {
+ if (!reserve_pmc_hardware())
+ err = -EBUSY;
+ else
+ reserve_ds_buffers();
+ }
+ if (!err)
+ atomic_inc(&pmc_refcount);
+ mutex_unlock(&pmc_reserve_mutex);
+ }
+
+ return err;
+}
+
+void x86_release_hardware(void)
+{
+ if (atomic_dec_and_mutex_lock(&pmc_refcount, &pmc_reserve_mutex)) {
+ release_pmc_hardware();
+ release_ds_buffers();
+ mutex_unlock(&pmc_reserve_mutex);
+ }
+}
+
+/*
+ * Check if we can create event of a certain type (that no conflicting events
+ * are present).
+ */
+int x86_add_exclusive(unsigned int what)
+{
+ int i;
+
+ if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
+ mutex_lock(&pmc_reserve_mutex);
+ for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
+ if (i != what && atomic_read(&x86_pmu.lbr_exclusive[i]))
+ goto fail_unlock;
+ }
+ atomic_inc(&x86_pmu.lbr_exclusive[what]);
+ mutex_unlock(&pmc_reserve_mutex);
+ }
+
+ atomic_inc(&active_events);
+ return 0;
+
+fail_unlock:
+ mutex_unlock(&pmc_reserve_mutex);
+ return -EBUSY;
+}
+
+void x86_del_exclusive(unsigned int what)
+{
+ atomic_dec(&x86_pmu.lbr_exclusive[what]);
+ atomic_dec(&active_events);
+}
+
+int x86_setup_perfctr(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+ struct hw_perf_event *hwc = &event->hw;
+ u64 config;
+
+ if (!is_sampling_event(event)) {
+ hwc->sample_period = x86_pmu.max_period;
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+ }
+
+ if (attr->type == PERF_TYPE_RAW)
+ return x86_pmu_extra_regs(event->attr.config, event);
+
+ if (attr->type == PERF_TYPE_HW_CACHE)
+ return set_ext_hw_attr(hwc, event);
+
+ if (attr->config >= x86_pmu.max_events)
+ return -EINVAL;
+
+ /*
+ * The generic map:
+ */
+ config = x86_pmu.event_map(attr->config);
+
+ if (config == 0)
+ return -ENOENT;
+
+ if (config == -1LL)
+ return -EINVAL;
+
+ /*
+ * Branch tracing:
+ */
+ if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+ !attr->freq && hwc->sample_period == 1) {
+ /* BTS is not supported by this architecture. */
+ if (!x86_pmu.bts_active)
+ return -EOPNOTSUPP;
+
+ /* BTS is currently only allowed for user-mode. */
+ if (!attr->exclude_kernel)
+ return -EOPNOTSUPP;
+
+ /* disallow bts if conflicting events are present */
+ if (x86_add_exclusive(x86_lbr_exclusive_lbr))
+ return -EBUSY;
+
+ event->destroy = hw_perf_lbr_event_destroy;
+ }
+
+ hwc->config |= config;
+
+ return 0;
+}
+
+/*
+ * check that branch_sample_type is compatible with
+ * settings needed for precise_ip > 1 which implies
+ * using the LBR to capture ALL taken branches at the
+ * priv levels of the measurement
+ */
+static inline int precise_br_compat(struct perf_event *event)
+{
+ u64 m = event->attr.branch_sample_type;
+ u64 b = 0;
+
+ /* must capture all branches */
+ if (!(m & PERF_SAMPLE_BRANCH_ANY))
+ return 0;
+
+ m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
+
+ if (!event->attr.exclude_user)
+ b |= PERF_SAMPLE_BRANCH_USER;
+
+ if (!event->attr.exclude_kernel)
+ b |= PERF_SAMPLE_BRANCH_KERNEL;
+
+ /*
+ * ignore PERF_SAMPLE_BRANCH_HV, not supported on x86
+ */
+
+ return m == b;
+}
+
+int x86_pmu_hw_config(struct perf_event *event)
+{
+ if (event->attr.precise_ip) {
+ int precise = 0;
+
+ /* Support for constant skid */
+ if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
+ precise++;
+
+ /* Support for IP fixup */
+ if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
+ precise++;
+
+ if (x86_pmu.pebs_prec_dist)
+ precise++;
+ }
+
+ if (event->attr.precise_ip > precise)
+ return -EOPNOTSUPP;
+ }
+ /*
+ * check that PEBS LBR correction does not conflict with
+ * whatever the user is asking with attr->branch_sample_type
+ */
+ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
+ u64 *br_type = &event->attr.branch_sample_type;
+
+ if (has_branch_stack(event)) {
+ if (!precise_br_compat(event))
+ return -EOPNOTSUPP;
+
+ /* branch_sample_type is compatible */
+
+ } else {
+ /*
+ * user did not specify branch_sample_type
+ *
+ * For PEBS fixups, we capture all
+ * the branches at the priv level of the
+ * event.
+ */
+ *br_type = PERF_SAMPLE_BRANCH_ANY;
+
+ if (!event->attr.exclude_user)
+ *br_type |= PERF_SAMPLE_BRANCH_USER;
+
+ if (!event->attr.exclude_kernel)
+ *br_type |= PERF_SAMPLE_BRANCH_KERNEL;
+ }
+ }
+
+ if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK)
+ event->attach_state |= PERF_ATTACH_TASK_DATA;
+
+ /*
+ * Generate PMC IRQs:
+ * (keep 'enabled' bit clear for now)
+ */
+ event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
+
+ /*
+ * Count user and OS events unless requested not to
+ */
+ if (!event->attr.exclude_user)
+ event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
+ if (!event->attr.exclude_kernel)
+ event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
+
+ if (event->attr.type == PERF_TYPE_RAW)
+ event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+
+ if (event->attr.sample_period && x86_pmu.limit_period) {
+ if (x86_pmu.limit_period(event, event->attr.sample_period) >
+ event->attr.sample_period)
+ return -EINVAL;
+ }
+
+ return x86_setup_perfctr(event);
+}
+
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __x86_pmu_event_init(struct perf_event *event)
+{
+ int err;
+
+ if (!x86_pmu_initialized())
+ return -ENODEV;
+
+ err = x86_reserve_hardware();
+ if (err)
+ return err;
+
+ atomic_inc(&active_events);
+ event->destroy = hw_perf_event_destroy;
+
+ event->hw.idx = -1;
+ event->hw.last_cpu = -1;
+ event->hw.last_tag = ~0ULL;
+
+ /* mark unused */
+ event->hw.extra_reg.idx = EXTRA_REG_NONE;
+ event->hw.branch_reg.idx = EXTRA_REG_NONE;
+
+ return x86_pmu.hw_config(event);
+}
+
+void x86_pmu_disable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ u64 val;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+ rdmsrl(x86_pmu_config_addr(idx), val);
+ if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
+ continue;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+ wrmsrl(x86_pmu_config_addr(idx), val);
+ }
+}
+
+/*
+ * There may be PMI landing after enabled=0. The PMI hitting could be before or
+ * after disable_all.
+ *
+ * If PMI hits before disable_all, the PMU will be disabled in the NMI handler.
+ * It will not be re-enabled in the NMI handler again, because enabled=0. After
+ * handling the NMI, disable_all will be called, which will not change the
+ * state either. If PMI hits after disable_all, the PMU is already disabled
+ * before entering NMI handler. The NMI handler will not change the state
+ * either.
+ *
+ * So either situation is harmless.
+ */
+static void x86_pmu_disable(struct pmu *pmu)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (!x86_pmu_initialized())
+ return;
+
+ if (!cpuc->enabled)
+ return;
+
+ cpuc->n_added = 0;
+ cpuc->enabled = 0;
+ barrier();
+
+ x86_pmu.disable_all();
+}
+
+void x86_pmu_enable_all(int added)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+ }
+}
+
+static struct pmu pmu;
+
+static inline int is_x86_event(struct perf_event *event)
+{
+ return event->pmu == &pmu;
+}
+
+/*
+ * Event scheduler state:
+ *
+ * Assign events iterating over all events and counters, beginning
+ * with events with least weights first. Keep the current iterator
+ * state in struct sched_state.
+ */
+struct sched_state {
+ int weight;
+ int event; /* event index */
+ int counter; /* counter index */
+ int unassigned; /* number of events to be assigned left */
+ int nr_gp; /* number of GP counters used */
+ unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+};
+
+/* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */
+#define SCHED_STATES_MAX 2
+
+struct perf_sched {
+ int max_weight;
+ int max_events;
+ int max_gp;
+ int saved_states;
+ struct event_constraint **constraints;
+ struct sched_state state;
+ struct sched_state saved[SCHED_STATES_MAX];
+};
+
+/*
+ * Initialize interator that runs through all events and counters.
+ */
+static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints,
+ int num, int wmin, int wmax, int gpmax)
+{
+ int idx;
+
+ memset(sched, 0, sizeof(*sched));
+ sched->max_events = num;
+ sched->max_weight = wmax;
+ sched->max_gp = gpmax;
+ sched->constraints = constraints;
+
+ for (idx = 0; idx < num; idx++) {
+ if (constraints[idx]->weight == wmin)
+ break;
+ }
+
+ sched->state.event = idx; /* start with min weight */
+ sched->state.weight = wmin;
+ sched->state.unassigned = num;
+}
+
+static void perf_sched_save_state(struct perf_sched *sched)
+{
+ if (WARN_ON_ONCE(sched->saved_states >= SCHED_STATES_MAX))
+ return;
+
+ sched->saved[sched->saved_states] = sched->state;
+ sched->saved_states++;
+}
+
+static bool perf_sched_restore_state(struct perf_sched *sched)
+{
+ if (!sched->saved_states)
+ return false;
+
+ sched->saved_states--;
+ sched->state = sched->saved[sched->saved_states];
+
+ /* continue with next counter: */
+ clear_bit(sched->state.counter++, sched->state.used);
+
+ return true;
+}
+
+/*
+ * Select a counter for the current event to schedule. Return true on
+ * success.
+ */
+static bool __perf_sched_find_counter(struct perf_sched *sched)
+{
+ struct event_constraint *c;
+ int idx;
+
+ if (!sched->state.unassigned)
+ return false;
+
+ if (sched->state.event >= sched->max_events)
+ return false;
+
+ c = sched->constraints[sched->state.event];
+ /* Prefer fixed purpose counters */
+ if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
+ idx = INTEL_PMC_IDX_FIXED;
+ for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
+ if (!__test_and_set_bit(idx, sched->state.used))
+ goto done;
+ }
+ }
+
+ /* Grab the first unused counter starting with idx */
+ idx = sched->state.counter;
+ for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
+ if (!__test_and_set_bit(idx, sched->state.used)) {
+ if (sched->state.nr_gp++ >= sched->max_gp)
+ return false;
+
+ goto done;
+ }
+ }
+
+ return false;
+
+done:
+ sched->state.counter = idx;
+
+ if (c->overlap)
+ perf_sched_save_state(sched);
+
+ return true;
+}
+
+static bool perf_sched_find_counter(struct perf_sched *sched)
+{
+ while (!__perf_sched_find_counter(sched)) {
+ if (!perf_sched_restore_state(sched))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Go through all unassigned events and find the next one to schedule.
+ * Take events with the least weight first. Return true on success.
+ */
+static bool perf_sched_next_event(struct perf_sched *sched)
+{
+ struct event_constraint *c;
+
+ if (!sched->state.unassigned || !--sched->state.unassigned)
+ return false;
+
+ do {
+ /* next event */
+ sched->state.event++;
+ if (sched->state.event >= sched->max_events) {
+ /* next weight */
+ sched->state.event = 0;
+ sched->state.weight++;
+ if (sched->state.weight > sched->max_weight)
+ return false;
+ }
+ c = sched->constraints[sched->state.event];
+ } while (c->weight != sched->state.weight);
+
+ sched->state.counter = 0; /* start with first counter */
+
+ return true;
+}
+
+/*
+ * Assign a counter for each event.
+ */
+int perf_assign_events(struct event_constraint **constraints, int n,
+ int wmin, int wmax, int gpmax, int *assign)
+{
+ struct perf_sched sched;
+
+ perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
+
+ do {
+ if (!perf_sched_find_counter(&sched))
+ break; /* failed */
+ if (assign)
+ assign[sched.state.event] = sched.state.counter;
+ } while (perf_sched_next_event(&sched));
+
+ return sched.state.unassigned;
+}
+EXPORT_SYMBOL_GPL(perf_assign_events);
+
+int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+ struct event_constraint *c;
+ unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ struct perf_event *e;
+ int i, wmin, wmax, unsched = 0;
+ struct hw_perf_event *hwc;
+
+ bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+
+ if (x86_pmu.start_scheduling)
+ x86_pmu.start_scheduling(cpuc);
+
+ for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+ cpuc->event_constraint[i] = NULL;
+ c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]);
+ cpuc->event_constraint[i] = c;
+
+ wmin = min(wmin, c->weight);
+ wmax = max(wmax, c->weight);
+ }
+
+ /*
+ * fastpath, try to reuse previous register
+ */
+ for (i = 0; i < n; i++) {
+ hwc = &cpuc->event_list[i]->hw;
+ c = cpuc->event_constraint[i];
+
+ /* never assigned */
+ if (hwc->idx == -1)
+ break;
+
+ /* constraint still honored */
+ if (!test_bit(hwc->idx, c->idxmsk))
+ break;
+
+ /* not already used */
+ if (test_bit(hwc->idx, used_mask))
+ break;
+
+ __set_bit(hwc->idx, used_mask);
+ if (assign)
+ assign[i] = hwc->idx;
+ }
+
+ /* slow path */
+ if (i != n) {
+ int gpmax = x86_pmu.num_counters;
+
+ /*
+ * Do not allow scheduling of more than half the available
+ * generic counters.
+ *
+ * This helps avoid counter starvation of sibling thread by
+ * ensuring at most half the counters cannot be in exclusive
+ * mode. There is no designated counters for the limits. Any
+ * N/2 counters can be used. This helps with events with
+ * specific counter constraints.
+ */
+ if (is_ht_workaround_enabled() && !cpuc->is_fake &&
+ READ_ONCE(cpuc->excl_cntrs->exclusive_present))
+ gpmax /= 2;
+
+ unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
+ wmax, gpmax, assign);
+ }
+
+ /*
+ * In case of success (unsched = 0), mark events as committed,
+ * so we do not put_constraint() in case new events are added
+ * and fail to be scheduled
+ *
+ * We invoke the lower level commit callback to lock the resource
+ *
+ * We do not need to do all of this in case we are called to
+ * validate an event group (assign == NULL)
+ */
+ if (!unsched && assign) {
+ for (i = 0; i < n; i++) {
+ e = cpuc->event_list[i];
+ e->hw.flags |= PERF_X86_EVENT_COMMITTED;
+ if (x86_pmu.commit_scheduling)
+ x86_pmu.commit_scheduling(cpuc, i, assign[i]);
+ }
+ } else {
+ for (i = 0; i < n; i++) {
+ e = cpuc->event_list[i];
+ /*
+ * do not put_constraint() on comitted events,
+ * because they are good to go
+ */
+ if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
+ continue;
+
+ /*
+ * release events that failed scheduling
+ */
+ if (x86_pmu.put_event_constraints)
+ x86_pmu.put_event_constraints(cpuc, e);
+ }
+ }
+
+ if (x86_pmu.stop_scheduling)
+ x86_pmu.stop_scheduling(cpuc);
+
+ return unsched ? -EINVAL : 0;
+}
+
+/*
+ * dogrp: true if must collect siblings events (group)
+ * returns total number of events and error code
+ */
+static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
+{
+ struct perf_event *event;
+ int n, max_count;
+
+ max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
+
+ /* current number of events already accepted */
+ n = cpuc->n_events;
+
+ if (is_x86_event(leader)) {
+ if (n >= max_count)
+ return -EINVAL;
+ cpuc->event_list[n] = leader;
+ n++;
+ }
+ if (!dogrp)
+ return n;
+
+ list_for_each_entry(event, &leader->sibling_list, group_entry) {
+ if (!is_x86_event(event) ||
+ event->state <= PERF_EVENT_STATE_OFF)
+ continue;
+
+ if (n >= max_count)
+ return -EINVAL;
+
+ cpuc->event_list[n] = event;
+ n++;
+ }
+ return n;
+}
+
+static inline void x86_assign_hw_event(struct perf_event *event,
+ struct cpu_hw_events *cpuc, int i)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ hwc->idx = cpuc->assign[i];
+ hwc->last_cpu = smp_processor_id();
+ hwc->last_tag = ++cpuc->tags[i];
+
+ if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) {
+ hwc->config_base = 0;
+ hwc->event_base = 0;
+ } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
+ hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+ hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED);
+ hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30;
+ } else {
+ hwc->config_base = x86_pmu_config_addr(hwc->idx);
+ hwc->event_base = x86_pmu_event_addr(hwc->idx);
+ hwc->event_base_rdpmc = x86_pmu_rdpmc_index(hwc->idx);
+ }
+}
+
+static inline int match_prev_assignment(struct hw_perf_event *hwc,
+ struct cpu_hw_events *cpuc,
+ int i)
+{
+ return hwc->idx == cpuc->assign[i] &&
+ hwc->last_cpu == smp_processor_id() &&
+ hwc->last_tag == cpuc->tags[i];
+}
+
+static void x86_pmu_start(struct perf_event *event, int flags);
+
+static void x86_pmu_enable(struct pmu *pmu)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct perf_event *event;
+ struct hw_perf_event *hwc;
+ int i, added = cpuc->n_added;
+
+ if (!x86_pmu_initialized())
+ return;
+
+ if (cpuc->enabled)
+ return;
+
+ if (cpuc->n_added) {
+ int n_running = cpuc->n_events - cpuc->n_added;
+ /*
+ * apply assignment obtained either from
+ * hw_perf_group_sched_in() or x86_pmu_enable()
+ *
+ * step1: save events moving to new counters
+ */
+ for (i = 0; i < n_running; i++) {
+ event = cpuc->event_list[i];
+ hwc = &event->hw;
+
+ /*
+ * we can avoid reprogramming counter if:
+ * - assigned same counter as last time
+ * - running on same CPU as last time
+ * - no other event has used the counter since
+ */
+ if (hwc->idx == -1 ||
+ match_prev_assignment(hwc, cpuc, i))
+ continue;
+
+ /*
+ * Ensure we don't accidentally enable a stopped
+ * counter simply because we rescheduled.
+ */
+ if (hwc->state & PERF_HES_STOPPED)
+ hwc->state |= PERF_HES_ARCH;
+
+ x86_pmu_stop(event, PERF_EF_UPDATE);
+ }
+
+ /*
+ * step2: reprogram moved events into new counters
+ */
+ for (i = 0; i < cpuc->n_events; i++) {
+ event = cpuc->event_list[i];
+ hwc = &event->hw;
+
+ if (!match_prev_assignment(hwc, cpuc, i))
+ x86_assign_hw_event(event, cpuc, i);
+ else if (i < n_running)
+ continue;
+
+ if (hwc->state & PERF_HES_ARCH)
+ continue;
+
+ x86_pmu_start(event, PERF_EF_RELOAD);
+ }
+ cpuc->n_added = 0;
+ perf_events_lapic_init();
+ }
+
+ cpuc->enabled = 1;
+ barrier();
+
+ x86_pmu.enable_all(added);
+}
+
+static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
+
+/*
+ * Set the next IRQ period, based on the hwc->period_left value.
+ * To be called with the event disabled in hw:
+ */
+int x86_perf_event_set_period(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ s64 left = local64_read(&hwc->period_left);
+ s64 period = hwc->sample_period;
+ int ret = 0, idx = hwc->idx;
+
+ if (idx == INTEL_PMC_IDX_FIXED_BTS)
+ return 0;
+
+ /*
+ * If we are way outside a reasonable range then just skip forward:
+ */
+ 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;
+ }
+ /*
+ * Quirk: certain CPUs dont like it if just 1 hw_event is left:
+ */
+ if (unlikely(left < 2))
+ left = 2;
+
+ if (left > x86_pmu.max_period)
+ left = x86_pmu.max_period;
+
+ if (x86_pmu.limit_period)
+ left = x86_pmu.limit_period(event, left);
+
+ per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
+
+ if (!(hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) ||
+ local64_read(&hwc->prev_count) != (u64)-left) {
+ /*
+ * The hw event starts counting from this event offset,
+ * mark it to be able to extra future deltas:
+ */
+ local64_set(&hwc->prev_count, (u64)-left);
+
+ wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
+ }
+
+ /*
+ * Due to erratum on certan cpu we need
+ * a second write to be sure the register
+ * is updated properly
+ */
+ if (x86_pmu.perfctr_second_write) {
+ wrmsrl(hwc->event_base,
+ (u64)(-left) & x86_pmu.cntval_mask);
+ }
+
+ perf_event_update_userpage(event);
+
+ return ret;
+}
+
+void x86_pmu_enable_event(struct perf_event *event)
+{
+ if (__this_cpu_read(cpu_hw_events.enabled))
+ __x86_pmu_enable_event(&event->hw,
+ ARCH_PERFMON_EVENTSEL_ENABLE);
+}
+
+/*
+ * Add a single event to the PMU.
+ *
+ * The event is added to the group of enabled events
+ * but only if it can be scehduled with existing events.
+ */
+static int x86_pmu_add(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct hw_perf_event *hwc;
+ int assign[X86_PMC_IDX_MAX];
+ int n, n0, ret;
+
+ hwc = &event->hw;
+
+ n0 = cpuc->n_events;
+ ret = n = collect_events(cpuc, event, false);
+ if (ret < 0)
+ goto out;
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (!(flags & PERF_EF_START))
+ hwc->state |= PERF_HES_ARCH;
+
+ /*
+ * If group events scheduling transaction was started,
+ * skip the schedulability test here, it will be performed
+ * at commit time (->commit_txn) as a whole.
+ */
+ if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+ goto done_collect;
+
+ ret = x86_pmu.schedule_events(cpuc, n, assign);
+ if (ret)
+ goto out;
+ /*
+ * copy new assignment, now we know it is possible
+ * will be used by hw_perf_enable()
+ */
+ memcpy(cpuc->assign, assign, n*sizeof(int));
+
+done_collect:
+ /*
+ * Commit the collect_events() state. See x86_pmu_del() and
+ * x86_pmu_*_txn().
+ */
+ cpuc->n_events = n;
+ cpuc->n_added += n - n0;
+ cpuc->n_txn += n - n0;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static void x86_pmu_start(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx = event->hw.idx;
+
+ if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+ return;
+
+ if (WARN_ON_ONCE(idx == -1))
+ return;
+
+ if (flags & PERF_EF_RELOAD) {
+ WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+ x86_perf_event_set_period(event);
+ }
+
+ event->hw.state = 0;
+
+ cpuc->events[idx] = event;
+ __set_bit(idx, cpuc->active_mask);
+ __set_bit(idx, cpuc->running);
+ x86_pmu.enable(event);
+ perf_event_update_userpage(event);
+}
+
+void perf_event_print_debug(void)
+{
+ u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+ u64 pebs, debugctl;
+ struct cpu_hw_events *cpuc;
+ unsigned long flags;
+ int cpu, idx;
+
+ if (!x86_pmu.num_counters)
+ return;
+
+ local_irq_save(flags);
+
+ cpu = smp_processor_id();
+ cpuc = &per_cpu(cpu_hw_events, cpu);
+
+ if (x86_pmu.version >= 2) {
+ rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
+ rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+ rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
+ rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
+
+ pr_info("\n");
+ pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl);
+ pr_info("CPU#%d: status: %016llx\n", cpu, status);
+ pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow);
+ pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed);
+ if (x86_pmu.pebs_constraints) {
+ rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
+ pr_info("CPU#%d: pebs: %016llx\n", cpu, pebs);
+ }
+ if (x86_pmu.lbr_nr) {
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+ pr_info("CPU#%d: debugctl: %016llx\n", cpu, debugctl);
+ }
+ }
+ pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
+ rdmsrl(x86_pmu_event_addr(idx), pmc_count);
+
+ prev_left = per_cpu(pmc_prev_left[idx], cpu);
+
+ pr_info("CPU#%d: gen-PMC%d ctrl: %016llx\n",
+ cpu, idx, pmc_ctrl);
+ pr_info("CPU#%d: gen-PMC%d count: %016llx\n",
+ cpu, idx, pmc_count);
+ pr_info("CPU#%d: gen-PMC%d left: %016llx\n",
+ cpu, idx, prev_left);
+ }
+ for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
+ rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
+
+ pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
+ cpu, idx, pmc_count);
+ }
+ local_irq_restore(flags);
+}
+
+void x86_pmu_stop(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
+ x86_pmu.disable(event);
+ cpuc->events[hwc->idx] = NULL;
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+ }
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ /*
+ * Drain the remaining delta count out of a event
+ * that we are disabling:
+ */
+ x86_perf_event_update(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+}
+
+static void x86_pmu_del(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int i;
+
+ /*
+ * event is descheduled
+ */
+ event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
+
+ /*
+ * If we're called during a txn, we don't need to do anything.
+ * The events never got scheduled and ->cancel_txn will truncate
+ * the event_list.
+ *
+ * XXX assumes any ->del() called during a TXN will only be on
+ * an event added during that same TXN.
+ */
+ if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+ return;
+
+ /*
+ * Not a TXN, therefore cleanup properly.
+ */
+ x86_pmu_stop(event, PERF_EF_UPDATE);
+
+ for (i = 0; i < cpuc->n_events; i++) {
+ if (event == cpuc->event_list[i])
+ break;
+ }
+
+ if (WARN_ON_ONCE(i == cpuc->n_events)) /* called ->del() without ->add() ? */
+ return;
+
+ /* If we have a newly added event; make sure to decrease n_added. */
+ if (i >= cpuc->n_events - cpuc->n_added)
+ --cpuc->n_added;
+
+ if (x86_pmu.put_event_constraints)
+ x86_pmu.put_event_constraints(cpuc, event);
+
+ /* Delete the array entry. */
+ while (++i < cpuc->n_events) {
+ cpuc->event_list[i-1] = cpuc->event_list[i];
+ cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
+ }
+ --cpuc->n_events;
+
+ perf_event_update_userpage(event);
+}
+
+int x86_pmu_handle_irq(struct pt_regs *regs)
+{
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct perf_event *event;
+ int idx, handled = 0;
+ u64 val;
+
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ /*
+ * Some chipsets need to unmask the LVTPC in a particular spot
+ * inside the nmi handler. As a result, the unmasking was pushed
+ * into all the nmi handlers.
+ *
+ * This generic handler doesn't seem to have any issues where the
+ * unmasking occurs so it was left at the top.
+ */
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ if (!test_bit(idx, cpuc->active_mask)) {
+ /*
+ * Though we deactivated the counter some cpus
+ * might still deliver spurious interrupts still
+ * in flight. Catch them:
+ */
+ if (__test_and_clear_bit(idx, cpuc->running))
+ handled++;
+ continue;
+ }
+
+ event = cpuc->events[idx];
+
+ val = x86_perf_event_update(event);
+ if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
+ continue;
+
+ /*
+ * event overflow
+ */
+ handled++;
+ perf_sample_data_init(&data, 0, event->hw.last_period);
+
+ if (!x86_perf_event_set_period(event))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ x86_pmu_stop(event, 0);
+ }
+
+ if (handled)
+ inc_irq_stat(apic_perf_irqs);
+
+ return handled;
+}
+
+void perf_events_lapic_init(void)
+{
+ if (!x86_pmu.apic || !x86_pmu_initialized())
+ return;
+
+ /*
+ * Always use NMI for PMU
+ */
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
+}
+
+static int
+perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
+{
+ u64 start_clock;
+ u64 finish_clock;
+ int ret;
+
+ /*
+ * All PMUs/events that share this PMI handler should make sure to
+ * increment active_events for their events.
+ */
+ if (!atomic_read(&active_events))
+ return NMI_DONE;
+
+ start_clock = sched_clock();
+ ret = x86_pmu.handle_irq(regs);
+ finish_clock = sched_clock();
+
+ perf_sample_event_took(finish_clock - start_clock);
+
+ return ret;
+}
+NOKPROBE_SYMBOL(perf_event_nmi_handler);
+
+struct event_constraint emptyconstraint;
+struct event_constraint unconstrained;
+
+static int
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ int i, ret = NOTIFY_OK;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ for (i = 0 ; i < X86_PERF_KFREE_MAX; i++)
+ cpuc->kfree_on_online[i] = NULL;
+ if (x86_pmu.cpu_prepare)
+ ret = x86_pmu.cpu_prepare(cpu);
+ break;
+
+ case CPU_STARTING:
+ if (x86_pmu.cpu_starting)
+ x86_pmu.cpu_starting(cpu);
+ break;
+
+ case CPU_ONLINE:
+ for (i = 0 ; i < X86_PERF_KFREE_MAX; i++) {
+ kfree(cpuc->kfree_on_online[i]);
+ cpuc->kfree_on_online[i] = NULL;
+ }
+ break;
+
+ case CPU_DYING:
+ if (x86_pmu.cpu_dying)
+ x86_pmu.cpu_dying(cpu);
+ break;
+
+ case CPU_UP_CANCELED:
+ case CPU_DEAD:
+ if (x86_pmu.cpu_dead)
+ x86_pmu.cpu_dead(cpu);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void __init pmu_check_apic(void)
+{
+ if (cpu_has_apic)
+ return;
+
+ x86_pmu.apic = 0;
+ pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+ pr_info("no hardware sampling interrupt available.\n");
+
+ /*
+ * If we have a PMU initialized but no APIC
+ * interrupts, we cannot sample hardware
+ * events (user-space has to fall back and
+ * sample via a hrtimer based software event):
+ */
+ pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+
+}
+
+static struct attribute_group x86_pmu_format_group = {
+ .name = "format",
+ .attrs = NULL,
+};
+
+/*
+ * Remove all undefined events (x86_pmu.event_map(id) == 0)
+ * out of events_attr attributes.
+ */
+static void __init filter_events(struct attribute **attrs)
+{
+ struct device_attribute *d;
+ struct perf_pmu_events_attr *pmu_attr;
+ int offset = 0;
+ int i, j;
+
+ for (i = 0; attrs[i]; i++) {
+ d = (struct device_attribute *)attrs[i];
+ pmu_attr = container_of(d, struct perf_pmu_events_attr, attr);
+ /* str trumps id */
+ if (pmu_attr->event_str)
+ continue;
+ if (x86_pmu.event_map(i + offset))
+ continue;
+
+ for (j = i; attrs[j]; j++)
+ attrs[j] = attrs[j + 1];
+
+ /* Check the shifted attr. */
+ i--;
+
+ /*
+ * event_map() is index based, the attrs array is organized
+ * by increasing event index. If we shift the events, then
+ * we need to compensate for the event_map(), otherwise
+ * we are looking up the wrong event in the map
+ */
+ offset++;
+ }
+}
+
+/* Merge two pointer arrays */
+__init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
+{
+ struct attribute **new;
+ int j, i;
+
+ for (j = 0; a[j]; j++)
+ ;
+ for (i = 0; b[i]; i++)
+ j++;
+ j++;
+
+ new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
+ if (!new)
+ return NULL;
+
+ j = 0;
+ for (i = 0; a[i]; i++)
+ new[j++] = a[i];
+ for (i = 0; b[i]; i++)
+ new[j++] = b[i];
+ new[j] = NULL;
+
+ return new;
+}
+
+ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
+ char *page)
+{
+ struct perf_pmu_events_attr *pmu_attr = \
+ container_of(attr, struct perf_pmu_events_attr, attr);
+ u64 config = x86_pmu.event_map(pmu_attr->id);
+
+ /* string trumps id */
+ if (pmu_attr->event_str)
+ return sprintf(page, "%s", pmu_attr->event_str);
+
+ return x86_pmu.events_sysfs_show(page, config);
+}
+
+EVENT_ATTR(cpu-cycles, CPU_CYCLES );
+EVENT_ATTR(instructions, INSTRUCTIONS );
+EVENT_ATTR(cache-references, CACHE_REFERENCES );
+EVENT_ATTR(cache-misses, CACHE_MISSES );
+EVENT_ATTR(branch-instructions, BRANCH_INSTRUCTIONS );
+EVENT_ATTR(branch-misses, BRANCH_MISSES );
+EVENT_ATTR(bus-cycles, BUS_CYCLES );
+EVENT_ATTR(stalled-cycles-frontend, STALLED_CYCLES_FRONTEND );
+EVENT_ATTR(stalled-cycles-backend, STALLED_CYCLES_BACKEND );
+EVENT_ATTR(ref-cycles, REF_CPU_CYCLES );
+
+static struct attribute *empty_attrs;
+
+static struct attribute *events_attr[] = {
+ EVENT_PTR(CPU_CYCLES),
+ EVENT_PTR(INSTRUCTIONS),
+ EVENT_PTR(CACHE_REFERENCES),
+ EVENT_PTR(CACHE_MISSES),
+ EVENT_PTR(BRANCH_INSTRUCTIONS),
+ EVENT_PTR(BRANCH_MISSES),
+ EVENT_PTR(BUS_CYCLES),
+ EVENT_PTR(STALLED_CYCLES_FRONTEND),
+ EVENT_PTR(STALLED_CYCLES_BACKEND),
+ EVENT_PTR(REF_CPU_CYCLES),
+ NULL,
+};
+
+static struct attribute_group x86_pmu_events_group = {
+ .name = "events",
+ .attrs = events_attr,
+};
+
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
+{
+ u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
+ u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
+ bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE);
+ bool pc = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
+ bool any = (config & ARCH_PERFMON_EVENTSEL_ANY);
+ bool inv = (config & ARCH_PERFMON_EVENTSEL_INV);
+ ssize_t ret;
+
+ /*
+ * We have whole page size to spend and just little data
+ * to write, so we can safely use sprintf.
+ */
+ ret = sprintf(page, "event=0x%02llx", event);
+
+ if (umask)
+ ret += sprintf(page + ret, ",umask=0x%02llx", umask);
+
+ if (edge)
+ ret += sprintf(page + ret, ",edge");
+
+ if (pc)
+ ret += sprintf(page + ret, ",pc");
+
+ if (any)
+ ret += sprintf(page + ret, ",any");
+
+ if (inv)
+ ret += sprintf(page + ret, ",inv");
+
+ if (cmask)
+ ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
+
+ ret += sprintf(page + ret, "\n");
+
+ return ret;
+}
+
+static int __init init_hw_perf_events(void)
+{
+ struct x86_pmu_quirk *quirk;
+ int err;
+
+ pr_info("Performance Events: ");
+
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_INTEL:
+ err = intel_pmu_init();
+ break;
+ case X86_VENDOR_AMD:
+ err = amd_pmu_init();
+ break;
+ default:
+ err = -ENOTSUPP;
+ }
+ if (err != 0) {
+ pr_cont("no PMU driver, software events only.\n");
+ return 0;
+ }
+
+ pmu_check_apic();
+
+ /* sanity check that the hardware exists or is emulated */
+ if (!check_hw_exists())
+ return 0;
+
+ pr_cont("%s PMU driver.\n", x86_pmu.name);
+
+ x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
+
+ for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)
+ quirk->func();
+
+ if (!x86_pmu.intel_ctrl)
+ x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+
+ perf_events_lapic_init();
+ register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
+
+ unconstrained = (struct event_constraint)
+ __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
+ 0, x86_pmu.num_counters, 0, 0);
+
+ x86_pmu_format_group.attrs = x86_pmu.format_attrs;
+
+ if (x86_pmu.event_attrs)
+ x86_pmu_events_group.attrs = x86_pmu.event_attrs;
+
+ if (!x86_pmu.events_sysfs_show)
+ x86_pmu_events_group.attrs = &empty_attrs;
+ else
+ filter_events(x86_pmu_events_group.attrs);
+
+ if (x86_pmu.cpu_events) {
+ struct attribute **tmp;
+
+ tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
+ if (!WARN_ON(!tmp))
+ x86_pmu_events_group.attrs = tmp;
+ }
+
+ pr_info("... version: %d\n", x86_pmu.version);
+ pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
+ pr_info("... generic registers: %d\n", x86_pmu.num_counters);
+ pr_info("... value mask: %016Lx\n", x86_pmu.cntval_mask);
+ pr_info("... max period: %016Lx\n", x86_pmu.max_period);
+ pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed);
+ pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl);
+
+ perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+ perf_cpu_notifier(x86_pmu_notifier);
+
+ return 0;
+}
+early_initcall(init_hw_perf_events);
+
+static inline void x86_pmu_read(struct perf_event *event)
+{
+ x86_perf_event_update(event);
+}
+
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ *
+ * We only support PERF_PMU_TXN_ADD transactions. Save the
+ * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
+ * transactions.
+ */
+static void x86_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ WARN_ON_ONCE(cpuc->txn_flags); /* txn already in flight */
+
+ cpuc->txn_flags = txn_flags;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
+ perf_pmu_disable(pmu);
+ __this_cpu_write(cpu_hw_events.n_txn, 0);
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+static void x86_pmu_cancel_txn(struct pmu *pmu)
+{
+ unsigned int txn_flags;
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ WARN_ON_ONCE(!cpuc->txn_flags); /* no txn in flight */
+
+ txn_flags = cpuc->txn_flags;
+ cpuc->txn_flags = 0;
+ if (txn_flags & ~PERF_PMU_TXN_ADD)
+ return;
+
+ /*
+ * Truncate collected array by the number of events added in this
+ * transaction. See x86_pmu_add() and x86_pmu_*_txn().
+ */
+ __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn));
+ __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn));
+ perf_pmu_enable(pmu);
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ *
+ * Does not cancel the transaction on failure; expects the caller to do this.
+ */
+static int x86_pmu_commit_txn(struct pmu *pmu)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int assign[X86_PMC_IDX_MAX];
+ int n, ret;
+
+ WARN_ON_ONCE(!cpuc->txn_flags); /* no txn in flight */
+
+ if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
+ cpuc->txn_flags = 0;
+ return 0;
+ }
+
+ n = cpuc->n_events;
+
+ if (!x86_pmu_initialized())
+ return -EAGAIN;
+
+ ret = x86_pmu.schedule_events(cpuc, n, assign);
+ if (ret)
+ return ret;
+
+ /*
+ * copy new assignment, now we know it is possible
+ * will be used by hw_perf_enable()
+ */
+ memcpy(cpuc->assign, assign, n*sizeof(int));
+
+ cpuc->txn_flags = 0;
+ perf_pmu_enable(pmu);
+ return 0;
+}
+/*
+ * a fake_cpuc is used to validate event groups. Due to
+ * the extra reg logic, we need to also allocate a fake
+ * per_core and per_cpu structure. Otherwise, group events
+ * using extra reg may conflict without the kernel being
+ * able to catch this when the last event gets added to
+ * the group.
+ */
+static void free_fake_cpuc(struct cpu_hw_events *cpuc)
+{
+ kfree(cpuc->shared_regs);
+ kfree(cpuc);
+}
+
+static struct cpu_hw_events *allocate_fake_cpuc(void)
+{
+ struct cpu_hw_events *cpuc;
+ int cpu = raw_smp_processor_id();
+
+ cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL);
+ if (!cpuc)
+ return ERR_PTR(-ENOMEM);
+
+ /* only needed, if we have extra_regs */
+ if (x86_pmu.extra_regs) {
+ cpuc->shared_regs = allocate_shared_regs(cpu);
+ if (!cpuc->shared_regs)
+ goto error;
+ }
+ cpuc->is_fake = 1;
+ return cpuc;
+error:
+ free_fake_cpuc(cpuc);
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * validate that we can schedule this event
+ */
+static int validate_event(struct perf_event *event)
+{
+ struct cpu_hw_events *fake_cpuc;
+ struct event_constraint *c;
+ int ret = 0;
+
+ fake_cpuc = allocate_fake_cpuc();
+ if (IS_ERR(fake_cpuc))
+ return PTR_ERR(fake_cpuc);
+
+ c = x86_pmu.get_event_constraints(fake_cpuc, -1, event);
+
+ if (!c || !c->weight)
+ ret = -EINVAL;
+
+ if (x86_pmu.put_event_constraints)
+ x86_pmu.put_event_constraints(fake_cpuc, event);
+
+ free_fake_cpuc(fake_cpuc);
+
+ return ret;
+}
+
+/*
+ * validate a single event group
+ *
+ * validation include:
+ * - check events are compatible which each other
+ * - events do not compete for the same counter
+ * - number of events <= number of counters
+ *
+ * validation ensures the group can be loaded onto the
+ * PMU if it was the only group available.
+ */
+static int validate_group(struct perf_event *event)
+{
+ struct perf_event *leader = event->group_leader;
+ struct cpu_hw_events *fake_cpuc;
+ int ret = -EINVAL, n;
+
+ fake_cpuc = allocate_fake_cpuc();
+ if (IS_ERR(fake_cpuc))
+ return PTR_ERR(fake_cpuc);
+ /*
+ * the event is not yet connected with its
+ * siblings therefore we must first collect
+ * existing siblings, then add the new event
+ * before we can simulate the scheduling
+ */
+ n = collect_events(fake_cpuc, leader, true);
+ if (n < 0)
+ goto out;
+
+ fake_cpuc->n_events = n;
+ n = collect_events(fake_cpuc, event, false);
+ if (n < 0)
+ goto out;
+
+ fake_cpuc->n_events = n;
+
+ ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
+
+out:
+ free_fake_cpuc(fake_cpuc);
+ return ret;
+}
+
+static int x86_pmu_event_init(struct perf_event *event)
+{
+ struct pmu *tmp;
+ int err;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
+ err = __x86_pmu_event_init(event);
+ if (!err) {
+ /*
+ * we temporarily connect event to its pmu
+ * such that validate_group() can classify
+ * it as an x86 event using is_x86_event()
+ */
+ tmp = event->pmu;
+ event->pmu = &pmu;
+
+ if (event->group_leader != event)
+ err = validate_group(event);
+ else
+ err = validate_event(event);
+
+ event->pmu = tmp;
+ }
+ if (err) {
+ if (event->destroy)
+ event->destroy(event);
+ }
+
+ if (ACCESS_ONCE(x86_pmu.attr_rdpmc))
+ event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
+
+ return err;
+}
+
+static void refresh_pce(void *ignored)
+{
+ if (current->mm)
+ load_mm_cr4(current->mm);
+}
+
+static void x86_pmu_event_mapped(struct perf_event *event)
+{
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return;
+
+ if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
+ on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
+static void x86_pmu_event_unmapped(struct perf_event *event)
+{
+ if (!current->mm)
+ return;
+
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return;
+
+ if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
+ on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
+static int x86_pmu_event_idx(struct perf_event *event)
+{
+ int idx = event->hw.idx;
+
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return 0;
+
+ if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
+ idx -= INTEL_PMC_IDX_FIXED;
+ idx |= 1 << 30;
+ }
+
+ return idx + 1;
+}
+
+static ssize_t get_attr_rdpmc(struct device *cdev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
+}
+
+static ssize_t set_attr_rdpmc(struct device *cdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+ ssize_t ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ if (val > 2)
+ return -EINVAL;
+
+ if (x86_pmu.attr_rdpmc_broken)
+ return -ENOTSUPP;
+
+ if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) {
+ /*
+ * Changing into or out of always available, aka
+ * perf-event-bypassing mode. This path is extremely slow,
+ * but only root can trigger it, so it's okay.
+ */
+ if (val == 2)
+ static_key_slow_inc(&rdpmc_always_available);
+ else
+ static_key_slow_dec(&rdpmc_always_available);
+ on_each_cpu(refresh_pce, NULL, 1);
+ }
+
+ x86_pmu.attr_rdpmc = val;
+
+ return count;
+}
+
+static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
+
+static struct attribute *x86_pmu_attrs[] = {
+ &dev_attr_rdpmc.attr,
+ NULL,
+};
+
+static struct attribute_group x86_pmu_attr_group = {
+ .attrs = x86_pmu_attrs,
+};
+
+static const struct attribute_group *x86_pmu_attr_groups[] = {
+ &x86_pmu_attr_group,
+ &x86_pmu_format_group,
+ &x86_pmu_events_group,
+ NULL,
+};
+
+static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+ if (x86_pmu.sched_task)
+ x86_pmu.sched_task(ctx, sched_in);
+}
+
+void perf_check_microcode(void)
+{
+ if (x86_pmu.check_microcode)
+ x86_pmu.check_microcode();
+}
+EXPORT_SYMBOL_GPL(perf_check_microcode);
+
+static struct pmu pmu = {
+ .pmu_enable = x86_pmu_enable,
+ .pmu_disable = x86_pmu_disable,
+
+ .attr_groups = x86_pmu_attr_groups,
+
+ .event_init = x86_pmu_event_init,
+
+ .event_mapped = x86_pmu_event_mapped,
+ .event_unmapped = x86_pmu_event_unmapped,
+
+ .add = x86_pmu_add,
+ .del = x86_pmu_del,
+ .start = x86_pmu_start,
+ .stop = x86_pmu_stop,
+ .read = x86_pmu_read,
+
+ .start_txn = x86_pmu_start_txn,
+ .cancel_txn = x86_pmu_cancel_txn,
+ .commit_txn = x86_pmu_commit_txn,
+
+ .event_idx = x86_pmu_event_idx,
+ .sched_task = x86_pmu_sched_task,
+ .task_ctx_size = sizeof(struct x86_perf_task_context),
+};
+
+void arch_perf_update_userpage(struct perf_event *event,
+ struct perf_event_mmap_page *userpg, u64 now)
+{
+ struct cyc2ns_data *data;
+
+ userpg->cap_user_time = 0;
+ userpg->cap_user_time_zero = 0;
+ userpg->cap_user_rdpmc =
+ !!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
+ userpg->pmc_width = x86_pmu.cntval_bits;
+
+ if (!sched_clock_stable())
+ return;
+
+ data = cyc2ns_read_begin();
+
+ /*
+ * Internal timekeeping for enabled/running/stopped times
+ * is always in the local_clock domain.
+ */
+ userpg->cap_user_time = 1;
+ userpg->time_mult = data->cyc2ns_mul;
+ userpg->time_shift = data->cyc2ns_shift;
+ userpg->time_offset = data->cyc2ns_offset - now;
+
+ /*
+ * cap_user_time_zero doesn't make sense when we're using a different
+ * time base for the records.
+ */
+ if (event->clock == &local_clock) {
+ userpg->cap_user_time_zero = 1;
+ userpg->time_zero = data->cyc2ns_offset;
+ }
+
+ cyc2ns_read_end(data);
+}
+
+/*
+ * callchain support
+ */
+
+static int backtrace_stack(void *data, char *name)
+{
+ return 0;
+}
+
+static int backtrace_address(void *data, unsigned long addr, int reliable)
+{
+ struct perf_callchain_entry *entry = data;
+
+ return perf_callchain_store(entry, addr);
+}
+
+static const struct stacktrace_ops backtrace_ops = {
+ .stack = backtrace_stack,
+ .address = backtrace_address,
+ .walk_stack = print_context_stack_bp,
+};
+
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* TODO: We don't support guest os callchain now */
+ return;
+ }
+
+ perf_callchain_store(entry, regs->ip);
+
+ dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
+}
+
+static inline int
+valid_user_frame(const void __user *fp, unsigned long size)
+{
+ return (__range_not_ok(fp, size, TASK_SIZE) == 0);
+}
+
+static unsigned long get_segment_base(unsigned int segment)
+{
+ struct desc_struct *desc;
+ int idx = segment >> 3;
+
+ if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
+ struct ldt_struct *ldt;
+
+ if (idx > LDT_ENTRIES)
+ return 0;
+
+ /* IRQs are off, so this synchronizes with smp_store_release */
+ ldt = lockless_dereference(current->active_mm->context.ldt);
+ if (!ldt || idx > ldt->size)
+ return 0;
+
+ desc = &ldt->entries[idx];
+#else
+ return 0;
+#endif
+ } else {
+ if (idx > GDT_ENTRIES)
+ return 0;
+
+ desc = raw_cpu_ptr(gdt_page.gdt) + idx;
+ }
+
+ return get_desc_base(desc);
+}
+
+#ifdef CONFIG_IA32_EMULATION
+
+#include <asm/compat.h>
+
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+ /* 32-bit process in 64-bit kernel. */
+ unsigned long ss_base, cs_base;
+ struct stack_frame_ia32 frame;
+ const void __user *fp;
+
+ if (!test_thread_flag(TIF_IA32))
+ return 0;
+
+ cs_base = get_segment_base(regs->cs);
+ ss_base = get_segment_base(regs->ss);
+
+ fp = compat_ptr(ss_base + regs->bp);
+ pagefault_disable();
+ while (entry->nr < PERF_MAX_STACK_DEPTH) {
+ unsigned long bytes;
+ frame.next_frame = 0;
+ frame.return_address = 0;
+
+ if (!access_ok(VERIFY_READ, fp, 8))
+ break;
+
+ bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4);
+ if (bytes != 0)
+ break;
+ bytes = __copy_from_user_nmi(&frame.return_address, fp+4, 4);
+ if (bytes != 0)
+ break;
+
+ if (!valid_user_frame(fp, sizeof(frame)))
+ break;
+
+ perf_callchain_store(entry, cs_base + frame.return_address);
+ fp = compat_ptr(ss_base + frame.next_frame);
+ }
+ pagefault_enable();
+ return 1;
+}
+#else
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+ return 0;
+}
+#endif
+
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+ struct stack_frame frame;
+ const void __user *fp;
+
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* TODO: We don't support guest os callchain now */
+ return;
+ }
+
+ /*
+ * We don't know what to do with VM86 stacks.. ignore them for now.
+ */
+ if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
+ return;
+
+ fp = (void __user *)regs->bp;
+
+ perf_callchain_store(entry, regs->ip);
+
+ if (!current->mm)
+ return;
+
+ if (perf_callchain_user32(regs, entry))
+ return;
+
+ pagefault_disable();
+ while (entry->nr < PERF_MAX_STACK_DEPTH) {
+ unsigned long bytes;
+ frame.next_frame = NULL;
+ frame.return_address = 0;
+
+ if (!access_ok(VERIFY_READ, fp, 16))
+ break;
+
+ bytes = __copy_from_user_nmi(&frame.next_frame, fp, 8);
+ if (bytes != 0)
+ break;
+ bytes = __copy_from_user_nmi(&frame.return_address, fp+8, 8);
+ if (bytes != 0)
+ break;
+
+ if (!valid_user_frame(fp, sizeof(frame)))
+ break;
+
+ perf_callchain_store(entry, frame.return_address);
+ fp = (void __user *)frame.next_frame;
+ }
+ pagefault_enable();
+}
+
+/*
+ * Deal with code segment offsets for the various execution modes:
+ *
+ * VM86 - the good olde 16 bit days, where the linear address is
+ * 20 bits and we use regs->ip + 0x10 * regs->cs.
+ *
+ * IA32 - Where we need to look at GDT/LDT segment descriptor tables
+ * to figure out what the 32bit base address is.
+ *
+ * X32 - has TIF_X32 set, but is running in x86_64
+ *
+ * X86_64 - CS,DS,SS,ES are all zero based.
+ */
+static unsigned long code_segment_base(struct pt_regs *regs)
+{
+ /*
+ * For IA32 we look at the GDT/LDT segment base to convert the
+ * effective IP to a linear address.
+ */
+
+#ifdef CONFIG_X86_32
+ /*
+ * If we are in VM86 mode, add the segment offset to convert to a
+ * linear address.
+ */
+ if (regs->flags & X86_VM_MASK)
+ return 0x10 * regs->cs;
+
+ if (user_mode(regs) && regs->cs != __USER_CS)
+ return get_segment_base(regs->cs);
+#else
+ if (user_mode(regs) && !user_64bit_mode(regs) &&
+ regs->cs != __USER32_CS)
+ return get_segment_base(regs->cs);
+#endif
+ return 0;
+}
+
+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 regs->ip + code_segment_base(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;
+ }
+
+ if (regs->flags & PERF_EFLAGS_EXACT)
+ misc |= PERF_RECORD_MISC_EXACT_IP;
+
+ return misc;
+}
+
+void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
+{
+ cap->version = x86_pmu.version;
+ cap->num_counters_gp = x86_pmu.num_counters;
+ cap->num_counters_fixed = x86_pmu.num_counters_fixed;
+ cap->bit_width_gp = x86_pmu.cntval_bits;
+ cap->bit_width_fixed = x86_pmu.cntval_bits;
+ cap->events_mask = (unsigned int)x86_pmu.events_maskl;
+ cap->events_mask_len = x86_pmu.events_mask_len;
+}
+EXPORT_SYMBOL_GPL(perf_get_x86_pmu_capability);
diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
new file mode 100644
index 0000000..b99dc92
--- /dev/null
+++ b/arch/x86/events/intel/bts.c
@@ -0,0 +1,544 @@
+/*
+ * BTS PMU driver for perf
+ * Copyright (c) 2013-2014, 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.
+ */
+
+#undef DEBUG
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/coredump.h>
+
+#include <asm-generic/sizes.h>
+#include <asm/perf_event.h>
+
+#include "../perf_event.h"
+
+struct bts_ctx {
+ struct perf_output_handle handle;
+ struct debug_store ds_back;
+ int started;
+};
+
+static DEFINE_PER_CPU(struct bts_ctx, bts_ctx);
+
+#define BTS_RECORD_SIZE 24
+#define BTS_SAFETY_MARGIN 4080
+
+struct bts_phys {
+ struct page *page;
+ unsigned long size;
+ unsigned long offset;
+ unsigned long displacement;
+};
+
+struct bts_buffer {
+ size_t real_size; /* multiple of BTS_RECORD_SIZE */
+ unsigned int nr_pages;
+ unsigned int nr_bufs;
+ unsigned int cur_buf;
+ bool snapshot;
+ local_t data_size;
+ local_t lost;
+ local_t head;
+ unsigned long end;
+ void **data_pages;
+ struct bts_phys buf[0];
+};
+
+struct pmu bts_pmu;
+
+static size_t buf_size(struct page *page)
+{
+ return 1 << (PAGE_SHIFT + page_private(page));
+}
+
+static void *
+bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
+{
+ struct bts_buffer *buf;
+ struct page *page;
+ int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
+ unsigned long offset;
+ size_t size = nr_pages << PAGE_SHIFT;
+ int pg, nbuf, pad;
+
+ /* count all the high order buffers */
+ for (pg = 0, nbuf = 0; pg < nr_pages;) {
+ page = virt_to_page(pages[pg]);
+ if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
+ return NULL;
+ pg += 1 << page_private(page);
+ nbuf++;
+ }
+
+ /*
+ * to avoid interrupts in overwrite mode, only allow one physical
+ */
+ if (overwrite && nbuf > 1)
+ return NULL;
+
+ buf = kzalloc_node(offsetof(struct bts_buffer, buf[nbuf]), GFP_KERNEL, node);
+ if (!buf)
+ return NULL;
+
+ buf->nr_pages = nr_pages;
+ buf->nr_bufs = nbuf;
+ buf->snapshot = overwrite;
+ buf->data_pages = pages;
+ buf->real_size = size - size % BTS_RECORD_SIZE;
+
+ for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
+ unsigned int __nr_pages;
+
+ page = virt_to_page(pages[pg]);
+ __nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
+ buf->buf[nbuf].page = page;
+ buf->buf[nbuf].offset = offset;
+ buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
+ buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
+ pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
+ buf->buf[nbuf].size -= pad;
+
+ pg += __nr_pages;
+ offset += __nr_pages << PAGE_SHIFT;
+ }
+
+ return buf;
+}
+
+static void bts_buffer_free_aux(void *data)
+{
+ kfree(data);
+}
+
+static unsigned long bts_buffer_offset(struct bts_buffer *buf, unsigned int idx)
+{
+ return buf->buf[idx].offset + buf->buf[idx].displacement;
+}
+
+static void
+bts_config_buffer(struct bts_buffer *buf)
+{
+ int cpu = raw_smp_processor_id();
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ struct bts_phys *phys = &buf->buf[buf->cur_buf];
+ unsigned long index, thresh = 0, end = phys->size;
+ struct page *page = phys->page;
+
+ index = local_read(&buf->head);
+
+ if (!buf->snapshot) {
+ if (buf->end < phys->offset + buf_size(page))
+ end = buf->end - phys->offset - phys->displacement;
+
+ index -= phys->offset + phys->displacement;
+
+ if (end - index > BTS_SAFETY_MARGIN)
+ thresh = end - BTS_SAFETY_MARGIN;
+ else if (end - index > BTS_RECORD_SIZE)
+ thresh = end - BTS_RECORD_SIZE;
+ else
+ thresh = end;
+ }
+
+ ds->bts_buffer_base = (u64)(long)page_address(page) + phys->displacement;
+ ds->bts_index = ds->bts_buffer_base + index;
+ ds->bts_absolute_maximum = ds->bts_buffer_base + end;
+ ds->bts_interrupt_threshold = !buf->snapshot
+ ? ds->bts_buffer_base + thresh
+ : ds->bts_absolute_maximum + BTS_RECORD_SIZE;
+}
+
+static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head)
+{
+ unsigned long index = head - phys->offset;
+
+ memset(page_address(phys->page) + index, 0, phys->size - index);
+}
+
+static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
+{
+ if (buf->snapshot)
+ return false;
+
+ if (local_read(&buf->data_size) >= bts->handle.size ||
+ bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
+ return true;
+
+ return false;
+}
+
+static void bts_update(struct bts_ctx *bts)
+{
+ int cpu = raw_smp_processor_id();
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ struct bts_buffer *buf = perf_get_aux(&bts->handle);
+ unsigned long index = ds->bts_index - ds->bts_buffer_base, old, head;
+
+ if (!buf)
+ return;
+
+ head = index + bts_buffer_offset(buf, buf->cur_buf);
+ old = local_xchg(&buf->head, head);
+
+ if (!buf->snapshot) {
+ if (old == head)
+ return;
+
+ if (ds->bts_index >= ds->bts_absolute_maximum)
+ local_inc(&buf->lost);
+
+ /*
+ * old and head are always in the same physical buffer, so we
+ * can subtract them to get the data size.
+ */
+ local_add(head - old, &buf->data_size);
+ } else {
+ local_set(&buf->data_size, head);
+ }
+}
+
+static void __bts_event_start(struct perf_event *event)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+ struct bts_buffer *buf = perf_get_aux(&bts->handle);
+ u64 config = 0;
+
+ if (!buf || bts_buffer_is_full(buf, bts))
+ return;
+
+ event->hw.itrace_started = 1;
+ event->hw.state = 0;
+
+ if (!buf->snapshot)
+ config |= ARCH_PERFMON_EVENTSEL_INT;
+ if (!event->attr.exclude_kernel)
+ config |= ARCH_PERFMON_EVENTSEL_OS;
+ if (!event->attr.exclude_user)
+ config |= ARCH_PERFMON_EVENTSEL_USR;
+
+ bts_config_buffer(buf);
+
+ /*
+ * local barrier to make sure that ds configuration made it
+ * before we enable BTS
+ */
+ wmb();
+
+ intel_pmu_enable_bts(config);
+}
+
+static void bts_event_start(struct perf_event *event, int flags)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+ __bts_event_start(event);
+
+ /* PMI handler: this counter is running and likely generating PMIs */
+ ACCESS_ONCE(bts->started) = 1;
+}
+
+static void __bts_event_stop(struct perf_event *event)
+{
+ /*
+ * No extra synchronization is mandated by the documentation to have
+ * BTS data stores globally visible.
+ */
+ intel_pmu_disable_bts();
+
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
+ ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED;
+}
+
+static void bts_event_stop(struct perf_event *event, int flags)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+ /* PMI handler: don't restart this counter */
+ ACCESS_ONCE(bts->started) = 0;
+
+ __bts_event_stop(event);
+
+ if (flags & PERF_EF_UPDATE)
+ bts_update(bts);
+}
+
+void intel_bts_enable_local(void)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+ if (bts->handle.event && bts->started)
+ __bts_event_start(bts->handle.event);
+}
+
+void intel_bts_disable_local(void)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+
+ if (bts->handle.event)
+ __bts_event_stop(bts->handle.event);
+}
+
+static int
+bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
+{
+ unsigned long head, space, next_space, pad, gap, skip, wakeup;
+ unsigned int next_buf;
+ struct bts_phys *phys, *next_phys;
+ int ret;
+
+ if (buf->snapshot)
+ return 0;
+
+ head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
+ if (WARN_ON_ONCE(head != local_read(&buf->head)))
+ return -EINVAL;
+
+ phys = &buf->buf[buf->cur_buf];
+ space = phys->offset + phys->displacement + phys->size - head;
+ pad = space;
+ if (space > handle->size) {
+ space = handle->size;
+ space -= space % BTS_RECORD_SIZE;
+ }
+ if (space <= BTS_SAFETY_MARGIN) {
+ /* See if next phys buffer has more space */
+ next_buf = buf->cur_buf + 1;
+ if (next_buf >= buf->nr_bufs)
+ next_buf = 0;
+ next_phys = &buf->buf[next_buf];
+ gap = buf_size(phys->page) - phys->displacement - phys->size +
+ next_phys->displacement;
+ skip = pad + gap;
+ if (handle->size >= skip) {
+ next_space = next_phys->size;
+ if (next_space + skip > handle->size) {
+ next_space = handle->size - skip;
+ next_space -= next_space % BTS_RECORD_SIZE;
+ }
+ if (next_space > space || !space) {
+ if (pad)
+ bts_buffer_pad_out(phys, head);
+ ret = perf_aux_output_skip(handle, skip);
+ if (ret)
+ return ret;
+ /* Advance to next phys buffer */
+ phys = next_phys;
+ space = next_space;
+ head = phys->offset + phys->displacement;
+ /*
+ * After this, cur_buf and head won't match ds
+ * anymore, so we must not be racing with
+ * bts_update().
+ */
+ buf->cur_buf = next_buf;
+ local_set(&buf->head, head);
+ }
+ }
+ }
+
+ /* Don't go far beyond wakeup watermark */
+ wakeup = BTS_SAFETY_MARGIN + BTS_RECORD_SIZE + handle->wakeup -
+ handle->head;
+ if (space > wakeup) {
+ space = wakeup;
+ space -= space % BTS_RECORD_SIZE;
+ }
+
+ buf->end = head + space;
+
+ /*
+ * If we have no space, the lost notification would have been sent when
+ * we hit absolute_maximum - see bts_update()
+ */
+ if (!space)
+ return -ENOSPC;
+
+ return 0;
+}
+
+int intel_bts_interrupt(void)
+{
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+ struct perf_event *event = bts->handle.event;
+ struct bts_buffer *buf;
+ s64 old_head;
+ int err;
+
+ if (!event || !bts->started)
+ return 0;
+
+ buf = perf_get_aux(&bts->handle);
+ /*
+ * Skip snapshot counters: they don't use the interrupt, but
+ * there's no other way of telling, because the pointer will
+ * keep moving
+ */
+ if (!buf || buf->snapshot)
+ return 0;
+
+ old_head = local_read(&buf->head);
+ bts_update(bts);
+
+ /* no new data */
+ if (old_head == local_read(&buf->head))
+ return 0;
+
+ perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
+ !!local_xchg(&buf->lost, 0));
+
+ buf = perf_aux_output_begin(&bts->handle, event);
+ if (!buf)
+ return 1;
+
+ err = bts_buffer_reset(buf, &bts->handle);
+ if (err)
+ perf_aux_output_end(&bts->handle, 0, false);
+
+ return 1;
+}
+
+static void bts_event_del(struct perf_event *event, int mode)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+ struct bts_buffer *buf = perf_get_aux(&bts->handle);
+
+ bts_event_stop(event, PERF_EF_UPDATE);
+
+ if (buf) {
+ if (buf->snapshot)
+ bts->handle.head =
+ local_xchg(&buf->data_size,
+ buf->nr_pages << PAGE_SHIFT);
+ perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
+ !!local_xchg(&buf->lost, 0));
+ }
+
+ cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
+ cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
+ cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
+ cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
+}
+
+static int bts_event_add(struct perf_event *event, int mode)
+{
+ struct bts_buffer *buf;
+ struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int ret = -EBUSY;
+
+ event->hw.state = PERF_HES_STOPPED;
+
+ if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+ return -EBUSY;
+
+ if (bts->handle.event)
+ return -EBUSY;
+
+ buf = perf_aux_output_begin(&bts->handle, event);
+ if (!buf)
+ return -EINVAL;
+
+ ret = bts_buffer_reset(buf, &bts->handle);
+ if (ret) {
+ perf_aux_output_end(&bts->handle, 0, false);
+ return ret;
+ }
+
+ bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
+ bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
+ bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
+
+ if (mode & PERF_EF_START) {
+ bts_event_start(event, 0);
+ if (hwc->state & PERF_HES_STOPPED) {
+ bts_event_del(event, 0);
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+static void bts_event_destroy(struct perf_event *event)
+{
+ x86_release_hardware();
+ x86_del_exclusive(x86_lbr_exclusive_bts);
+}
+
+static int bts_event_init(struct perf_event *event)
+{
+ int ret;
+
+ if (event->attr.type != bts_pmu.type)
+ return -ENOENT;
+
+ if (x86_add_exclusive(x86_lbr_exclusive_bts))
+ return -EBUSY;
+
+ /*
+ * BTS leaks kernel addresses even when CPL0 tracing is
+ * disabled, so disallow intel_bts driver for unprivileged
+ * users on paranoid systems since it provides trace data
+ * to the user in a zero-copy fashion.
+ *
+ * Note that the default paranoia setting permits unprivileged
+ * users to profile the kernel.
+ */
+ if (event->attr.exclude_kernel && perf_paranoid_kernel() &&
+ !capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ ret = x86_reserve_hardware();
+ if (ret) {
+ x86_del_exclusive(x86_lbr_exclusive_bts);
+ return ret;
+ }
+
+ event->destroy = bts_event_destroy;
+
+ return 0;
+}
+
+static void bts_event_read(struct perf_event *event)
+{
+}
+
+static __init int bts_init(void)
+{
+ if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
+ return -ENODEV;
+
+ bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE;
+ bts_pmu.task_ctx_nr = perf_sw_context;
+ bts_pmu.event_init = bts_event_init;
+ bts_pmu.add = bts_event_add;
+ bts_pmu.del = bts_event_del;
+ bts_pmu.start = bts_event_start;
+ bts_pmu.stop = bts_event_stop;
+ bts_pmu.read = bts_event_read;
+ bts_pmu.setup_aux = bts_buffer_setup_aux;
+ bts_pmu.free_aux = bts_buffer_free_aux;
+
+ return perf_pmu_register(&bts_pmu, "intel_bts", -1);
+}
+arch_initcall(bts_init);
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
new file mode 100644
index 0000000..68fa55b
--- /dev/null
+++ b/arch/x86/events/intel/core.c
@@ -0,0 +1,3796 @@
+/*
+ * Per core/cpu state
+ *
+ * Used to coordinate shared registers between HT threads or
+ * among events on a single PMU.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/nmi.h>
+
+#include <asm/cpufeature.h>
+#include <asm/hardirq.h>
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+/*
+ * Intel PerfMon, used on Core and later.
+ */
+static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
+ [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
+ [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */
+};
+
+static struct event_constraint intel_core_event_constraints[] __read_mostly =
+{
+ INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+ INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+ INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+ INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+ INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+ INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_core2_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+ INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+ INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+ INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+ INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+ INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
+ INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
+ INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
+ INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
+ INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
+ INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
+ INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
+ INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
+ INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
+ INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
+ INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+ INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
+{
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
+ EVENT_EXTRA_END
+};
+
+static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
+ INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
+ INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+ INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_snb_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
+ INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+ INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
+ INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+
+ INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
+ INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
+ INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
+ INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+
+ INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
+{
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
+ EVENT_EXTRA_END
+};
+
+static struct event_constraint intel_v1_event_constraints[] __read_mostly =
+{
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_gen_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_slm_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_skl_event_constraints[] = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_UEVENT_CONSTRAINT(0x1c0, 0x2), /* INST_RETIRED.PREC_DIST */
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_knl_extra_regs[] __read_mostly = {
+ INTEL_UEVENT_EXTRA_REG(0x01b7,
+ MSR_OFFCORE_RSP_0, 0x7f9ffbffffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x02b7,
+ MSR_OFFCORE_RSP_1, 0x3f9ffbffffull, RSP_1),
+ EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+ EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+ EVENT_EXTRA_END
+};
+
+static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+ /*
+ * Note the low 8 bits eventsel code is not a continuous field, containing
+ * some #GPing bits. These are masked out.
+ */
+ INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
+ EVENT_EXTRA_END
+};
+
+EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
+EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
+
+struct attribute *nhm_events_attrs[] = {
+ EVENT_PTR(mem_ld_nhm),
+ NULL,
+};
+
+struct attribute *snb_events_attrs[] = {
+ EVENT_PTR(mem_ld_snb),
+ EVENT_PTR(mem_st_snb),
+ NULL,
+};
+
+static struct event_constraint intel_hsw_event_constraints[] = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_UEVENT_CONSTRAINT(0x148, 0x4), /* L1D_PEND_MISS.PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+ INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+ /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
+ /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+ INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
+ /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf),
+
+ INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_bdw_event_constraints[] = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ INTEL_UEVENT_CONSTRAINT(0x148, 0x4), /* L1D_PEND_MISS.PENDING */
+ INTEL_UBIT_EVENT_CONSTRAINT(0x8a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_MISS */
+ EVENT_CONSTRAINT_END
+};
+
+static u64 intel_pmu_event_map(int hw_event)
+{
+ return intel_perfmon_event_map[hw_event];
+}
+
+/*
+ * Notes on the events:
+ * - data reads do not include code reads (comparable to earlier tables)
+ * - data counts include speculative execution (except L1 write, dtlb, bpu)
+ * - remote node access includes remote memory, remote cache, remote mmio.
+ * - prefetches are not included in the counts.
+ * - icache miss does not include decoded icache
+ */
+
+#define SKL_DEMAND_DATA_RD BIT_ULL(0)
+#define SKL_DEMAND_RFO BIT_ULL(1)
+#define SKL_ANY_RESPONSE BIT_ULL(16)
+#define SKL_SUPPLIER_NONE BIT_ULL(17)
+#define SKL_L3_MISS_LOCAL_DRAM BIT_ULL(26)
+#define SKL_L3_MISS_REMOTE_HOP0_DRAM BIT_ULL(27)
+#define SKL_L3_MISS_REMOTE_HOP1_DRAM BIT_ULL(28)
+#define SKL_L3_MISS_REMOTE_HOP2P_DRAM BIT_ULL(29)
+#define SKL_L3_MISS (SKL_L3_MISS_LOCAL_DRAM| \
+ SKL_L3_MISS_REMOTE_HOP0_DRAM| \
+ SKL_L3_MISS_REMOTE_HOP1_DRAM| \
+ SKL_L3_MISS_REMOTE_HOP2P_DRAM)
+#define SKL_SPL_HIT BIT_ULL(30)
+#define SKL_SNOOP_NONE BIT_ULL(31)
+#define SKL_SNOOP_NOT_NEEDED BIT_ULL(32)
+#define SKL_SNOOP_MISS BIT_ULL(33)
+#define SKL_SNOOP_HIT_NO_FWD BIT_ULL(34)
+#define SKL_SNOOP_HIT_WITH_FWD BIT_ULL(35)
+#define SKL_SNOOP_HITM BIT_ULL(36)
+#define SKL_SNOOP_NON_DRAM BIT_ULL(37)
+#define SKL_ANY_SNOOP (SKL_SPL_HIT|SKL_SNOOP_NONE| \
+ SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
+ SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
+ SKL_SNOOP_HITM|SKL_SNOOP_NON_DRAM)
+#define SKL_DEMAND_READ SKL_DEMAND_DATA_RD
+#define SKL_SNOOP_DRAM (SKL_SNOOP_NONE| \
+ SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
+ SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
+ SKL_SNOOP_HITM|SKL_SPL_HIT)
+#define SKL_DEMAND_WRITE SKL_DEMAND_RFO
+#define SKL_LLC_ACCESS SKL_ANY_RESPONSE
+#define SKL_L3_MISS_REMOTE (SKL_L3_MISS_REMOTE_HOP0_DRAM| \
+ SKL_L3_MISS_REMOTE_HOP1_DRAM| \
+ SKL_L3_MISS_REMOTE_HOP2P_DRAM)
+
+static __initconst const u64 skl_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_INST_RETIRED.ALL_LOADS */
+ [ C(RESULT_MISS) ] = 0x151, /* L1D.REPLACEMENT */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_INST_RETIRED.ALL_STORES */
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x283, /* ICACHE_64B.MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_INST_RETIRED.ALL_LOADS */
+ [ C(RESULT_MISS) ] = 0x608, /* DTLB_LOAD_MISSES.WALK_COMPLETED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_INST_RETIRED.ALL_STORES */
+ [ C(RESULT_MISS) ] = 0x649, /* DTLB_STORE_MISSES.WALK_COMPLETED */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x2085, /* ITLB_MISSES.STLB_HIT */
+ [ C(RESULT_MISS) ] = 0xe85, /* ITLB_MISSES.WALK_COMPLETED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0xc4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [ C(RESULT_MISS) ] = 0xc5, /* BR_MISP_RETIRED.ALL_BRANCHES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+};
+
+static __initconst const u64 skl_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
+ SKL_LLC_ACCESS|SKL_ANY_SNOOP,
+ [ C(RESULT_MISS) ] = SKL_DEMAND_READ|
+ SKL_L3_MISS|SKL_ANY_SNOOP|
+ SKL_SUPPLIER_NONE,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
+ SKL_LLC_ACCESS|SKL_ANY_SNOOP,
+ [ C(RESULT_MISS) ] = SKL_DEMAND_WRITE|
+ SKL_L3_MISS|SKL_ANY_SNOOP|
+ SKL_SUPPLIER_NONE,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
+ SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
+ [ C(RESULT_MISS) ] = SKL_DEMAND_READ|
+ SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
+ SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
+ [ C(RESULT_MISS) ] = SKL_DEMAND_WRITE|
+ SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+};
+
+#define SNB_DMND_DATA_RD (1ULL << 0)
+#define SNB_DMND_RFO (1ULL << 1)
+#define SNB_DMND_IFETCH (1ULL << 2)
+#define SNB_DMND_WB (1ULL << 3)
+#define SNB_PF_DATA_RD (1ULL << 4)
+#define SNB_PF_RFO (1ULL << 5)
+#define SNB_PF_IFETCH (1ULL << 6)
+#define SNB_LLC_DATA_RD (1ULL << 7)
+#define SNB_LLC_RFO (1ULL << 8)
+#define SNB_LLC_IFETCH (1ULL << 9)
+#define SNB_BUS_LOCKS (1ULL << 10)
+#define SNB_STRM_ST (1ULL << 11)
+#define SNB_OTHER (1ULL << 15)
+#define SNB_RESP_ANY (1ULL << 16)
+#define SNB_NO_SUPP (1ULL << 17)
+#define SNB_LLC_HITM (1ULL << 18)
+#define SNB_LLC_HITE (1ULL << 19)
+#define SNB_LLC_HITS (1ULL << 20)
+#define SNB_LLC_HITF (1ULL << 21)
+#define SNB_LOCAL (1ULL << 22)
+#define SNB_REMOTE (0xffULL << 23)
+#define SNB_SNP_NONE (1ULL << 31)
+#define SNB_SNP_NOT_NEEDED (1ULL << 32)
+#define SNB_SNP_MISS (1ULL << 33)
+#define SNB_NO_FWD (1ULL << 34)
+#define SNB_SNP_FWD (1ULL << 35)
+#define SNB_HITM (1ULL << 36)
+#define SNB_NON_DRAM (1ULL << 37)
+
+#define SNB_DMND_READ (SNB_DMND_DATA_RD|SNB_LLC_DATA_RD)
+#define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO)
+#define SNB_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
+
+#define SNB_SNP_ANY (SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \
+ SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \
+ SNB_HITM)
+
+#define SNB_DRAM_ANY (SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY)
+#define SNB_DRAM_REMOTE (SNB_REMOTE|SNB_SNP_ANY)
+
+#define SNB_L3_ACCESS SNB_RESP_ANY
+#define SNB_L3_MISS (SNB_DRAM_ANY|SNB_NON_DRAM)
+
+static __initconst const u64 snb_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_L3_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_L3_MISS,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_DRAM_REMOTE,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE,
+ },
+ },
+};
+
+static __initconst const u64 snb_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */
+ [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */
+ [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_WRITE) ] = {
+ /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */
+ [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */
+ [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */
+ [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+
+};
+
+/*
+ * Notes on the events:
+ * - data reads do not include code reads (comparable to earlier tables)
+ * - data counts include speculative execution (except L1 write, dtlb, bpu)
+ * - remote node access includes remote memory, remote cache, remote mmio.
+ * - prefetches are not included in the counts because they are not
+ * reliably counted.
+ */
+
+#define HSW_DEMAND_DATA_RD BIT_ULL(0)
+#define HSW_DEMAND_RFO BIT_ULL(1)
+#define HSW_ANY_RESPONSE BIT_ULL(16)
+#define HSW_SUPPLIER_NONE BIT_ULL(17)
+#define HSW_L3_MISS_LOCAL_DRAM BIT_ULL(22)
+#define HSW_L3_MISS_REMOTE_HOP0 BIT_ULL(27)
+#define HSW_L3_MISS_REMOTE_HOP1 BIT_ULL(28)
+#define HSW_L3_MISS_REMOTE_HOP2P BIT_ULL(29)
+#define HSW_L3_MISS (HSW_L3_MISS_LOCAL_DRAM| \
+ HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
+ HSW_L3_MISS_REMOTE_HOP2P)
+#define HSW_SNOOP_NONE BIT_ULL(31)
+#define HSW_SNOOP_NOT_NEEDED BIT_ULL(32)
+#define HSW_SNOOP_MISS BIT_ULL(33)
+#define HSW_SNOOP_HIT_NO_FWD BIT_ULL(34)
+#define HSW_SNOOP_HIT_WITH_FWD BIT_ULL(35)
+#define HSW_SNOOP_HITM BIT_ULL(36)
+#define HSW_SNOOP_NON_DRAM BIT_ULL(37)
+#define HSW_ANY_SNOOP (HSW_SNOOP_NONE| \
+ HSW_SNOOP_NOT_NEEDED|HSW_SNOOP_MISS| \
+ HSW_SNOOP_HIT_NO_FWD|HSW_SNOOP_HIT_WITH_FWD| \
+ HSW_SNOOP_HITM|HSW_SNOOP_NON_DRAM)
+#define HSW_SNOOP_DRAM (HSW_ANY_SNOOP & ~HSW_SNOOP_NON_DRAM)
+#define HSW_DEMAND_READ HSW_DEMAND_DATA_RD
+#define HSW_DEMAND_WRITE HSW_DEMAND_RFO
+#define HSW_L3_MISS_REMOTE (HSW_L3_MISS_REMOTE_HOP0|\
+ HSW_L3_MISS_REMOTE_HOP1|HSW_L3_MISS_REMOTE_HOP2P)
+#define HSW_LLC_ACCESS HSW_ANY_RESPONSE
+
+#define BDW_L3_MISS_LOCAL BIT(26)
+#define BDW_L3_MISS (BDW_L3_MISS_LOCAL| \
+ HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
+ HSW_L3_MISS_REMOTE_HOP2P)
+
+
+static __initconst const u64 hsw_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
+ [ C(RESULT_MISS) ] = 0x151, /* L1D.REPLACEMENT */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x280, /* ICACHE.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
+ [ C(RESULT_MISS) ] = 0x108, /* DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
+ [ C(RESULT_MISS) ] = 0x149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x6085, /* ITLB_MISSES.STLB_HIT */
+ [ C(RESULT_MISS) ] = 0x185, /* ITLB_MISSES.MISS_CAUSES_A_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0xc4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [ C(RESULT_MISS) ] = 0xc5, /* BR_MISP_RETIRED.ALL_BRANCHES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+};
+
+static __initconst const u64 hsw_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
+ HSW_LLC_ACCESS,
+ [ C(RESULT_MISS) ] = HSW_DEMAND_READ|
+ HSW_L3_MISS|HSW_ANY_SNOOP,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
+ HSW_LLC_ACCESS,
+ [ C(RESULT_MISS) ] = HSW_DEMAND_WRITE|
+ HSW_L3_MISS|HSW_ANY_SNOOP,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
+ HSW_L3_MISS_LOCAL_DRAM|
+ HSW_SNOOP_DRAM,
+ [ C(RESULT_MISS) ] = HSW_DEMAND_READ|
+ HSW_L3_MISS_REMOTE|
+ HSW_SNOOP_DRAM,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
+ HSW_L3_MISS_LOCAL_DRAM|
+ HSW_SNOOP_DRAM,
+ [ C(RESULT_MISS) ] = HSW_DEMAND_WRITE|
+ HSW_L3_MISS_REMOTE|
+ HSW_SNOOP_DRAM,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+};
+
+static __initconst const u64 westmere_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
+ [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
+ [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
+ [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
+ [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ /*
+ * Use RFO, not WRITEBACK, because a write miss would typically occur
+ * on RFO.
+ */
+ [ C(OP_WRITE) ] = {
+ /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
+ [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
+ [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
+ [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+};
+
+/*
+ * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
+ * See IA32 SDM Vol 3B 30.6.1.3
+ */
+
+#define NHM_DMND_DATA_RD (1 << 0)
+#define NHM_DMND_RFO (1 << 1)
+#define NHM_DMND_IFETCH (1 << 2)
+#define NHM_DMND_WB (1 << 3)
+#define NHM_PF_DATA_RD (1 << 4)
+#define NHM_PF_DATA_RFO (1 << 5)
+#define NHM_PF_IFETCH (1 << 6)
+#define NHM_OFFCORE_OTHER (1 << 7)
+#define NHM_UNCORE_HIT (1 << 8)
+#define NHM_OTHER_CORE_HIT_SNP (1 << 9)
+#define NHM_OTHER_CORE_HITM (1 << 10)
+ /* reserved */
+#define NHM_REMOTE_CACHE_FWD (1 << 12)
+#define NHM_REMOTE_DRAM (1 << 13)
+#define NHM_LOCAL_DRAM (1 << 14)
+#define NHM_NON_DRAM (1 << 15)
+
+#define NHM_LOCAL (NHM_LOCAL_DRAM|NHM_REMOTE_CACHE_FWD)
+#define NHM_REMOTE (NHM_REMOTE_DRAM)
+
+#define NHM_DMND_READ (NHM_DMND_DATA_RD)
+#define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB)
+#define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
+
+#define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
+#define NHM_L3_MISS (NHM_NON_DRAM|NHM_LOCAL_DRAM|NHM_REMOTE_DRAM|NHM_REMOTE_CACHE_FWD)
+#define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS)
+
+static __initconst const u64 nehalem_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
+ [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
+ [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
+ [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_LOCAL|NHM_REMOTE,
+ [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_LOCAL|NHM_REMOTE,
+ [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_LOCAL|NHM_REMOTE,
+ [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE,
+ },
+ },
+};
+
+static __initconst const u64 nehalem_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
+ [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
+ [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
+ [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
+ [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ /*
+ * Use RFO, not WRITEBACK, because a write miss would typically occur
+ * on RFO.
+ */
+ [ C(OP_WRITE) ] = {
+ /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
+ [ C(RESULT_MISS) ] = 0x20c8, /* ITLB_MISS_RETIRED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+};
+
+static __initconst const u64 core2_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */
+ [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */
+ [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS */
+ [ C(RESULT_MISS) ] = 0x0081, /* L1I.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
+ [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
+ [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x0208, /* DTLB_MISSES.MISS_LD */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x0808, /* DTLB_MISSES.MISS_ST */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
+ [ C(RESULT_MISS) ] = 0x1282, /* ITLBMISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
+ [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+static __initconst const u64 atom_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
+ [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
+ [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
+ [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x0508, /* DTLB_MISSES.MISS_LD */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI (alias) */
+ [ C(RESULT_MISS) ] = 0x0608, /* DTLB_MISSES.MISS_ST */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
+ [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
+ [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+static struct extra_reg intel_slm_extra_regs[] __read_mostly =
+{
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x768005ffffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x368005ffffull, RSP_1),
+ EVENT_EXTRA_END
+};
+
+#define SLM_DMND_READ SNB_DMND_DATA_RD
+#define SLM_DMND_WRITE SNB_DMND_RFO
+#define SLM_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
+
+#define SLM_SNP_ANY (SNB_SNP_NONE|SNB_SNP_MISS|SNB_NO_FWD|SNB_HITM)
+#define SLM_LLC_ACCESS SNB_RESP_ANY
+#define SLM_LLC_MISS (SLM_SNP_ANY|SNB_NON_DRAM)
+
+static __initconst const u64 slm_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
+ [ C(RESULT_MISS) ] = SLM_DMND_WRITE|SLM_LLC_MISS,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = SLM_DMND_PREFETCH|SLM_LLC_ACCESS,
+ [ C(RESULT_MISS) ] = SLM_DMND_PREFETCH|SLM_LLC_MISS,
+ },
+ },
+};
+
+static __initconst const u64 slm_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x0104, /* LD_DCU_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0380, /* ICACHE.ACCESSES */
+ [ C(RESULT_MISS) ] = 0x0280, /* ICACGE.MISSES */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_WRITE) ] = {
+ /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ [ C(OP_PREFETCH) ] = {
+ /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
+ [ C(RESULT_MISS) ] = 0x01b7,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x0804, /* LD_DTLB_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
+ [ C(RESULT_MISS) ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
+ [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
+#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
+#define KNL_MCDRAM_LOCAL BIT_ULL(21)
+#define KNL_MCDRAM_FAR BIT_ULL(22)
+#define KNL_DDR_LOCAL BIT_ULL(23)
+#define KNL_DDR_FAR BIT_ULL(24)
+#define KNL_DRAM_ANY (KNL_MCDRAM_LOCAL | KNL_MCDRAM_FAR | \
+ KNL_DDR_LOCAL | KNL_DDR_FAR)
+#define KNL_L2_READ SLM_DMND_READ
+#define KNL_L2_WRITE SLM_DMND_WRITE
+#define KNL_L2_PREFETCH SLM_DMND_PREFETCH
+#define KNL_L2_ACCESS SLM_LLC_ACCESS
+#define KNL_L2_MISS (KNL_OT_L2_HITE | KNL_OT_L2_HITF | \
+ KNL_DRAM_ANY | SNB_SNP_ANY | \
+ SNB_NON_DRAM)
+
+static __initconst const u64 knl_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = KNL_L2_READ | KNL_L2_ACCESS,
+ [C(RESULT_MISS)] = 0,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = KNL_L2_WRITE | KNL_L2_ACCESS,
+ [C(RESULT_MISS)] = KNL_L2_WRITE | KNL_L2_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = KNL_L2_PREFETCH | KNL_L2_ACCESS,
+ [C(RESULT_MISS)] = KNL_L2_PREFETCH | KNL_L2_MISS,
+ },
+ },
+};
+
+/*
+ * Used from PMIs where the LBRs are already disabled.
+ *
+ * This function could be called consecutively. It is required to remain in
+ * disabled state if called consecutively.
+ *
+ * During consecutive calls, the same disable value will be written to related
+ * registers, so the PMU state remains unchanged. hw.state in
+ * intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive
+ * calls.
+ */
+static void __intel_pmu_disable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+ if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+ intel_pmu_disable_bts();
+ else
+ intel_bts_disable_local();
+
+ intel_pmu_pebs_disable_all();
+}
+
+static void intel_pmu_disable_all(void)
+{
+ __intel_pmu_disable_all();
+ intel_pmu_lbr_disable_all();
+}
+
+static void __intel_pmu_enable_all(int added, bool pmi)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ intel_pmu_pebs_enable_all();
+ intel_pmu_lbr_enable_all(pmi);
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
+ x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
+
+ if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
+ struct perf_event *event =
+ cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
+
+ if (WARN_ON_ONCE(!event))
+ return;
+
+ intel_pmu_enable_bts(event->hw.config);
+ } else
+ intel_bts_enable_local();
+}
+
+static void intel_pmu_enable_all(int added)
+{
+ __intel_pmu_enable_all(added, false);
+}
+
+/*
+ * Workaround for:
+ * Intel Errata AAK100 (model 26)
+ * Intel Errata AAP53 (model 30)
+ * Intel Errata BD53 (model 44)
+ *
+ * The official story:
+ * These chips need to be 'reset' when adding counters by programming the
+ * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
+ * in sequence on the same PMC or on different PMCs.
+ *
+ * In practise it appears some of these events do in fact count, and
+ * we need to programm all 4 events.
+ */
+static void intel_pmu_nhm_workaround(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ static const unsigned long nhm_magic[4] = {
+ 0x4300B5,
+ 0x4300D2,
+ 0x4300B1,
+ 0x4300B1
+ };
+ struct perf_event *event;
+ int i;
+
+ /*
+ * The Errata requires below steps:
+ * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
+ * 2) Configure 4 PERFEVTSELx with the magic events and clear
+ * the corresponding PMCx;
+ * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
+ * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
+ * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
+ */
+
+ /*
+ * The real steps we choose are a little different from above.
+ * A) To reduce MSR operations, we don't run step 1) as they
+ * are already cleared before this function is called;
+ * B) Call x86_perf_event_update to save PMCx before configuring
+ * PERFEVTSELx with magic number;
+ * C) With step 5), we do clear only when the PERFEVTSELx is
+ * not used currently.
+ * D) Call x86_perf_event_set_period to restore PMCx;
+ */
+
+ /* We always operate 4 pairs of PERF Counters */
+ for (i = 0; i < 4; i++) {
+ event = cpuc->events[i];
+ if (event)
+ x86_perf_event_update(event);
+ }
+
+ for (i = 0; i < 4; i++) {
+ wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
+ wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
+ }
+
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
+
+ for (i = 0; i < 4; i++) {
+ event = cpuc->events[i];
+
+ if (event) {
+ x86_perf_event_set_period(event);
+ __x86_pmu_enable_event(&event->hw,
+ ARCH_PERFMON_EVENTSEL_ENABLE);
+ } else
+ wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
+ }
+}
+
+static void intel_pmu_nhm_enable_all(int added)
+{
+ if (added)
+ intel_pmu_nhm_workaround();
+ intel_pmu_enable_all(added);
+}
+
+static inline u64 intel_pmu_get_status(void)
+{
+ u64 status;
+
+ rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+ return status;
+}
+
+static inline void intel_pmu_ack_status(u64 ack)
+{
+ wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
+{
+ int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
+ u64 ctrl_val, mask;
+
+ mask = 0xfULL << (idx * 4);
+
+ rdmsrl(hwc->config_base, ctrl_val);
+ ctrl_val &= ~mask;
+ wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static inline bool event_is_checkpointed(struct perf_event *event)
+{
+ return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
+}
+
+static void intel_pmu_disable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
+ intel_pmu_disable_bts();
+ intel_pmu_drain_bts_buffer();
+ return;
+ }
+
+ cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
+ cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
+ cpuc->intel_cp_status &= ~(1ull << hwc->idx);
+
+ /*
+ * must disable before any actual event
+ * because any event may be combined with LBR
+ */
+ if (needs_branch_stack(event))
+ intel_pmu_lbr_disable(event);
+
+ if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+ intel_pmu_disable_fixed(hwc);
+ return;
+ }
+
+ x86_pmu_disable_event(event);
+
+ if (unlikely(event->attr.precise_ip))
+ intel_pmu_pebs_disable(event);
+}
+
+static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
+{
+ int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
+ u64 ctrl_val, bits, mask;
+
+ /*
+ * Enable IRQ generation (0x8),
+ * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
+ * if requested:
+ */
+ bits = 0x8ULL;
+ if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
+ bits |= 0x2;
+ if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+ bits |= 0x1;
+
+ /*
+ * ANY bit is supported in v3 and up
+ */
+ if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
+ bits |= 0x4;
+
+ bits <<= (idx * 4);
+ mask = 0xfULL << (idx * 4);
+
+ rdmsrl(hwc->config_base, ctrl_val);
+ ctrl_val &= ~mask;
+ ctrl_val |= bits;
+ wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void intel_pmu_enable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
+ if (!__this_cpu_read(cpu_hw_events.enabled))
+ return;
+
+ intel_pmu_enable_bts(hwc->config);
+ return;
+ }
+ /*
+ * must enabled before any actual event
+ * because any event may be combined with LBR
+ */
+ if (needs_branch_stack(event))
+ intel_pmu_lbr_enable(event);
+
+ if (event->attr.exclude_host)
+ cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx);
+ if (event->attr.exclude_guest)
+ cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
+
+ if (unlikely(event_is_checkpointed(event)))
+ cpuc->intel_cp_status |= (1ull << hwc->idx);
+
+ if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+ intel_pmu_enable_fixed(hwc);
+ return;
+ }
+
+ if (unlikely(event->attr.precise_ip))
+ intel_pmu_pebs_enable(event);
+
+ __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+}
+
+/*
+ * Save and restart an expired event. Called by NMI contexts,
+ * so it has to be careful about preempting normal event ops:
+ */
+int intel_pmu_save_and_restart(struct perf_event *event)
+{
+ x86_perf_event_update(event);
+ /*
+ * For a checkpointed counter always reset back to 0. This
+ * avoids a situation where the counter overflows, aborts the
+ * transaction and is then set back to shortly before the
+ * overflow, and overflows and aborts again.
+ */
+ if (unlikely(event_is_checkpointed(event))) {
+ /* No race with NMIs because the counter should not be armed */
+ wrmsrl(event->hw.event_base, 0);
+ local64_set(&event->hw.prev_count, 0);
+ }
+ return x86_perf_event_set_period(event);
+}
+
+static void intel_pmu_reset(void)
+{
+ struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+ unsigned long flags;
+ int idx;
+
+ if (!x86_pmu.num_counters)
+ return;
+
+ local_irq_save(flags);
+
+ pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
+ wrmsrl_safe(x86_pmu_event_addr(idx), 0ull);
+ }
+ for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
+ wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
+
+ if (ds)
+ ds->bts_index = ds->bts_buffer_base;
+
+ /* Ack all overflows and disable fixed counters */
+ if (x86_pmu.version >= 2) {
+ intel_pmu_ack_status(intel_pmu_get_status());
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ }
+
+ /* Reset LBRs and LBR freezing */
+ if (x86_pmu.lbr_nr) {
+ update_debugctlmsr(get_debugctlmsr() &
+ ~(DEBUGCTLMSR_FREEZE_LBRS_ON_PMI|DEBUGCTLMSR_LBR));
+ }
+
+ local_irq_restore(flags);
+}
+
+/*
+ * This handler is triggered by the local APIC, so the APIC IRQ handling
+ * rules apply:
+ */
+static int intel_pmu_handle_irq(struct pt_regs *regs)
+{
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ int bit, loops;
+ u64 status;
+ int handled;
+
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ /*
+ * No known reason to not always do late ACK,
+ * but just in case do it opt-in.
+ */
+ if (!x86_pmu.late_ack)
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
+ __intel_pmu_disable_all();
+ handled = intel_pmu_drain_bts_buffer();
+ handled += intel_bts_interrupt();
+ status = intel_pmu_get_status();
+ if (!status)
+ goto done;
+
+ loops = 0;
+again:
+ intel_pmu_lbr_read();
+ intel_pmu_ack_status(status);
+ if (++loops > 100) {
+ static bool warned = false;
+ if (!warned) {
+ WARN(1, "perfevents: irq loop stuck!\n");
+ perf_event_print_debug();
+ warned = true;
+ }
+ intel_pmu_reset();
+ goto done;
+ }
+
+ inc_irq_stat(apic_perf_irqs);
+
+
+ /*
+ * Ignore a range of extra bits in status that do not indicate
+ * overflow by themselves.
+ */
+ status &= ~(GLOBAL_STATUS_COND_CHG |
+ GLOBAL_STATUS_ASIF |
+ GLOBAL_STATUS_LBRS_FROZEN);
+ if (!status)
+ goto done;
+
+ /*
+ * PEBS overflow sets bit 62 in the global status register
+ */
+ if (__test_and_clear_bit(62, (unsigned long *)&status)) {
+ handled++;
+ x86_pmu.drain_pebs(regs);
+ /*
+ * There are cases where, even though, the PEBS ovfl bit is set
+ * in GLOBAL_OVF_STATUS, the PEBS events may also have their
+ * overflow bits set for their counters. We must clear them
+ * here because they have been processed as exact samples in
+ * the drain_pebs() routine. They must not be processed again
+ * in the for_each_bit_set() loop for regular samples below.
+ */
+ status &= ~cpuc->pebs_enabled;
+ status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
+ }
+
+ /*
+ * Intel PT
+ */
+ if (__test_and_clear_bit(55, (unsigned long *)&status)) {
+ handled++;
+ intel_pt_interrupt();
+ }
+
+ /*
+ * Checkpointed counters can lead to 'spurious' PMIs because the
+ * rollback caused by the PMI will have cleared the overflow status
+ * bit. Therefore always force probe these counters.
+ */
+ status |= cpuc->intel_cp_status;
+
+ for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+ struct perf_event *event = cpuc->events[bit];
+
+ handled++;
+
+ if (!test_bit(bit, cpuc->active_mask))
+ continue;
+
+ if (!intel_pmu_save_and_restart(event))
+ continue;
+
+ perf_sample_data_init(&data, 0, event->hw.last_period);
+
+ if (has_branch_stack(event))
+ data.br_stack = &cpuc->lbr_stack;
+
+ if (perf_event_overflow(event, &data, regs))
+ x86_pmu_stop(event, 0);
+ }
+
+ /*
+ * Repeat if there is more work to be done:
+ */
+ status = intel_pmu_get_status();
+ if (status)
+ goto again;
+
+done:
+ /* Only restore PMU state when it's active. See x86_pmu_disable(). */
+ if (cpuc->enabled)
+ __intel_pmu_enable_all(0, true);
+
+ /*
+ * Only unmask the NMI after the overflow counters
+ * have been reset. This avoids spurious NMIs on
+ * Haswell CPUs.
+ */
+ if (x86_pmu.late_ack)
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
+ return handled;
+}
+
+static struct event_constraint *
+intel_bts_constraints(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned int hw_event, bts_event;
+
+ if (event->attr.freq)
+ return NULL;
+
+ hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
+ bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+
+ if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
+ return &bts_constraint;
+
+ return NULL;
+}
+
+static int intel_alt_er(int idx, u64 config)
+{
+ int alt_idx = idx;
+
+ if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
+ return idx;
+
+ if (idx == EXTRA_REG_RSP_0)
+ alt_idx = EXTRA_REG_RSP_1;
+
+ if (idx == EXTRA_REG_RSP_1)
+ alt_idx = EXTRA_REG_RSP_0;
+
+ if (config & ~x86_pmu.extra_regs[alt_idx].valid_mask)
+ return idx;
+
+ return alt_idx;
+}
+
+static void intel_fixup_er(struct perf_event *event, int idx)
+{
+ event->hw.extra_reg.idx = idx;
+
+ if (idx == EXTRA_REG_RSP_0) {
+ event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
+ event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
+ event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
+ } else if (idx == EXTRA_REG_RSP_1) {
+ event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
+ event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
+ event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
+ }
+}
+
+/*
+ * manage allocation of shared extra msr for certain events
+ *
+ * sharing can be:
+ * per-cpu: to be shared between the various events on a single PMU
+ * per-core: per-cpu + shared by HT threads
+ */
+static struct event_constraint *
+__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event,
+ struct hw_perf_event_extra *reg)
+{
+ struct event_constraint *c = &emptyconstraint;
+ struct er_account *era;
+ unsigned long flags;
+ int idx = reg->idx;
+
+ /*
+ * reg->alloc can be set due to existing state, so for fake cpuc we
+ * need to ignore this, otherwise we might fail to allocate proper fake
+ * state for this extra reg constraint. Also see the comment below.
+ */
+ if (reg->alloc && !cpuc->is_fake)
+ return NULL; /* call x86_get_event_constraint() */
+
+again:
+ era = &cpuc->shared_regs->regs[idx];
+ /*
+ * we use spin_lock_irqsave() to avoid lockdep issues when
+ * passing a fake cpuc
+ */
+ raw_spin_lock_irqsave(&era->lock, flags);
+
+ if (!atomic_read(&era->ref) || era->config == reg->config) {
+
+ /*
+ * If its a fake cpuc -- as per validate_{group,event}() we
+ * shouldn't touch event state and we can avoid doing so
+ * since both will only call get_event_constraints() once
+ * on each event, this avoids the need for reg->alloc.
+ *
+ * Not doing the ER fixup will only result in era->reg being
+ * wrong, but since we won't actually try and program hardware
+ * this isn't a problem either.
+ */
+ if (!cpuc->is_fake) {
+ if (idx != reg->idx)
+ intel_fixup_er(event, idx);
+
+ /*
+ * x86_schedule_events() can call get_event_constraints()
+ * multiple times on events in the case of incremental
+ * scheduling(). reg->alloc ensures we only do the ER
+ * allocation once.
+ */
+ reg->alloc = 1;
+ }
+
+ /* lock in msr value */
+ era->config = reg->config;
+ era->reg = reg->reg;
+
+ /* one more user */
+ atomic_inc(&era->ref);
+
+ /*
+ * need to call x86_get_event_constraint()
+ * to check if associated event has constraints
+ */
+ c = NULL;
+ } else {
+ idx = intel_alt_er(idx, reg->config);
+ if (idx != reg->idx) {
+ raw_spin_unlock_irqrestore(&era->lock, flags);
+ goto again;
+ }
+ }
+ raw_spin_unlock_irqrestore(&era->lock, flags);
+
+ return c;
+}
+
+static void
+__intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc,
+ struct hw_perf_event_extra *reg)
+{
+ struct er_account *era;
+
+ /*
+ * Only put constraint if extra reg was actually allocated. Also takes
+ * care of event which do not use an extra shared reg.
+ *
+ * Also, if this is a fake cpuc we shouldn't touch any event state
+ * (reg->alloc) and we don't care about leaving inconsistent cpuc state
+ * either since it'll be thrown out.
+ */
+ if (!reg->alloc || cpuc->is_fake)
+ return;
+
+ era = &cpuc->shared_regs->regs[reg->idx];
+
+ /* one fewer user */
+ atomic_dec(&era->ref);
+
+ /* allocate again next time */
+ reg->alloc = 0;
+}
+
+static struct event_constraint *
+intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct event_constraint *c = NULL, *d;
+ struct hw_perf_event_extra *xreg, *breg;
+
+ xreg = &event->hw.extra_reg;
+ if (xreg->idx != EXTRA_REG_NONE) {
+ c = __intel_shared_reg_get_constraints(cpuc, event, xreg);
+ if (c == &emptyconstraint)
+ return c;
+ }
+ breg = &event->hw.branch_reg;
+ if (breg->idx != EXTRA_REG_NONE) {
+ d = __intel_shared_reg_get_constraints(cpuc, event, breg);
+ if (d == &emptyconstraint) {
+ __intel_shared_reg_put_constraints(cpuc, xreg);
+ c = d;
+ }
+ }
+ return c;
+}
+
+struct event_constraint *
+x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct event_constraint *c;
+
+ if (x86_pmu.event_constraints) {
+ for_each_event_constraint(c, x86_pmu.event_constraints) {
+ if ((event->hw.config & c->cmask) == c->code) {
+ event->hw.flags |= c->flags;
+ return c;
+ }
+ }
+ }
+
+ return &unconstrained;
+}
+
+static struct event_constraint *
+__intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct event_constraint *c;
+
+ c = intel_bts_constraints(event);
+ if (c)
+ return c;
+
+ c = intel_shared_regs_constraints(cpuc, event);
+ if (c)
+ return c;
+
+ c = intel_pebs_constraints(event);
+ if (c)
+ return c;
+
+ return x86_get_event_constraints(cpuc, idx, event);
+}
+
+static void
+intel_start_scheduling(struct cpu_hw_events *cpuc)
+{
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+ struct intel_excl_states *xl;
+ int tid = cpuc->excl_thread_id;
+
+ /*
+ * nothing needed if in group validation mode
+ */
+ if (cpuc->is_fake || !is_ht_workaround_enabled())
+ return;
+
+ /*
+ * no exclusion needed
+ */
+ if (WARN_ON_ONCE(!excl_cntrs))
+ return;
+
+ xl = &excl_cntrs->states[tid];
+
+ xl->sched_started = true;
+ /*
+ * lock shared state until we are done scheduling
+ * in stop_event_scheduling()
+ * makes scheduling appear as a transaction
+ */
+ raw_spin_lock(&excl_cntrs->lock);
+}
+
+static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr)
+{
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+ struct event_constraint *c = cpuc->event_constraint[idx];
+ struct intel_excl_states *xl;
+ int tid = cpuc->excl_thread_id;
+
+ if (cpuc->is_fake || !is_ht_workaround_enabled())
+ return;
+
+ if (WARN_ON_ONCE(!excl_cntrs))
+ return;
+
+ if (!(c->flags & PERF_X86_EVENT_DYNAMIC))
+ return;
+
+ xl = &excl_cntrs->states[tid];
+
+ lockdep_assert_held(&excl_cntrs->lock);
+
+ if (c->flags & PERF_X86_EVENT_EXCL)
+ xl->state[cntr] = INTEL_EXCL_EXCLUSIVE;
+ else
+ xl->state[cntr] = INTEL_EXCL_SHARED;
+}
+
+static void
+intel_stop_scheduling(struct cpu_hw_events *cpuc)
+{
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+ struct intel_excl_states *xl;
+ int tid = cpuc->excl_thread_id;
+
+ /*
+ * nothing needed if in group validation mode
+ */
+ if (cpuc->is_fake || !is_ht_workaround_enabled())
+ return;
+ /*
+ * no exclusion needed
+ */
+ if (WARN_ON_ONCE(!excl_cntrs))
+ return;
+
+ xl = &excl_cntrs->states[tid];
+
+ xl->sched_started = false;
+ /*
+ * release shared state lock (acquired in intel_start_scheduling())
+ */
+ raw_spin_unlock(&excl_cntrs->lock);
+}
+
+static struct event_constraint *
+intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
+ int idx, struct event_constraint *c)
+{
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+ struct intel_excl_states *xlo;
+ int tid = cpuc->excl_thread_id;
+ int is_excl, i;
+
+ /*
+ * validating a group does not require
+ * enforcing cross-thread exclusion
+ */
+ if (cpuc->is_fake || !is_ht_workaround_enabled())
+ return c;
+
+ /*
+ * no exclusion needed
+ */
+ if (WARN_ON_ONCE(!excl_cntrs))
+ return c;
+
+ /*
+ * because we modify the constraint, we need
+ * to make a copy. Static constraints come
+ * from static const tables.
+ *
+ * only needed when constraint has not yet
+ * been cloned (marked dynamic)
+ */
+ if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) {
+ struct event_constraint *cx;
+
+ /*
+ * grab pre-allocated constraint entry
+ */
+ cx = &cpuc->constraint_list[idx];
+
+ /*
+ * initialize dynamic constraint
+ * with static constraint
+ */
+ *cx = *c;
+
+ /*
+ * mark constraint as dynamic, so we
+ * can free it later on
+ */
+ cx->flags |= PERF_X86_EVENT_DYNAMIC;
+ c = cx;
+ }
+
+ /*
+ * From here on, the constraint is dynamic.
+ * Either it was just allocated above, or it
+ * was allocated during a earlier invocation
+ * of this function
+ */
+
+ /*
+ * state of sibling HT
+ */
+ xlo = &excl_cntrs->states[tid ^ 1];
+
+ /*
+ * event requires exclusive counter access
+ * across HT threads
+ */
+ is_excl = c->flags & PERF_X86_EVENT_EXCL;
+ if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) {
+ event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT;
+ if (!cpuc->n_excl++)
+ WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1);
+ }
+
+ /*
+ * Modify static constraint with current dynamic
+ * state of thread
+ *
+ * EXCLUSIVE: sibling counter measuring exclusive event
+ * SHARED : sibling counter measuring non-exclusive event
+ * UNUSED : sibling counter unused
+ */
+ for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
+ /*
+ * exclusive event in sibling counter
+ * our corresponding counter cannot be used
+ * regardless of our event
+ */
+ if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
+ __clear_bit(i, c->idxmsk);
+ /*
+ * if measuring an exclusive event, sibling
+ * measuring non-exclusive, then counter cannot
+ * be used
+ */
+ if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
+ __clear_bit(i, c->idxmsk);
+ }
+
+ /*
+ * recompute actual bit weight for scheduling algorithm
+ */
+ c->weight = hweight64(c->idxmsk64);
+
+ /*
+ * if we return an empty mask, then switch
+ * back to static empty constraint to avoid
+ * the cost of freeing later on
+ */
+ if (c->weight == 0)
+ c = &emptyconstraint;
+
+ return c;
+}
+
+static struct event_constraint *
+intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct event_constraint *c1 = NULL;
+ struct event_constraint *c2;
+
+ if (idx >= 0) /* fake does < 0 */
+ c1 = cpuc->event_constraint[idx];
+
+ /*
+ * first time only
+ * - static constraint: no change across incremental scheduling calls
+ * - dynamic constraint: handled by intel_get_excl_constraints()
+ */
+ c2 = __intel_get_event_constraints(cpuc, idx, event);
+ if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) {
+ bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX);
+ c1->weight = c2->weight;
+ c2 = c1;
+ }
+
+ if (cpuc->excl_cntrs)
+ return intel_get_excl_constraints(cpuc, event, idx, c2);
+
+ return c2;
+}
+
+static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+ int tid = cpuc->excl_thread_id;
+ struct intel_excl_states *xl;
+
+ /*
+ * nothing needed if in group validation mode
+ */
+ if (cpuc->is_fake)
+ return;
+
+ if (WARN_ON_ONCE(!excl_cntrs))
+ return;
+
+ if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) {
+ hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT;
+ if (!--cpuc->n_excl)
+ WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0);
+ }
+
+ /*
+ * If event was actually assigned, then mark the counter state as
+ * unused now.
+ */
+ if (hwc->idx >= 0) {
+ xl = &excl_cntrs->states[tid];
+
+ /*
+ * put_constraint may be called from x86_schedule_events()
+ * which already has the lock held so here make locking
+ * conditional.
+ */
+ if (!xl->sched_started)
+ raw_spin_lock(&excl_cntrs->lock);
+
+ xl->state[hwc->idx] = INTEL_EXCL_UNUSED;
+
+ if (!xl->sched_started)
+ raw_spin_unlock(&excl_cntrs->lock);
+ }
+}
+
+static void
+intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg;
+
+ reg = &event->hw.extra_reg;
+ if (reg->idx != EXTRA_REG_NONE)
+ __intel_shared_reg_put_constraints(cpuc, reg);
+
+ reg = &event->hw.branch_reg;
+ if (reg->idx != EXTRA_REG_NONE)
+ __intel_shared_reg_put_constraints(cpuc, reg);
+}
+
+static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ intel_put_shared_regs_event_constraints(cpuc, event);
+
+ /*
+ * is PMU has exclusive counter restrictions, then
+ * all events are subject to and must call the
+ * put_excl_constraints() routine
+ */
+ if (cpuc->excl_cntrs)
+ intel_put_excl_constraints(cpuc, event);
+}
+
+static void intel_pebs_aliases_core2(struct perf_event *event)
+{
+ if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
+ /*
+ * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
+ * (0x003c) so that we can use it with PEBS.
+ *
+ * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
+ * PEBS capable. However we can use INST_RETIRED.ANY_P
+ * (0x00c0), which is a PEBS capable event, to get the same
+ * count.
+ *
+ * INST_RETIRED.ANY_P counts the number of cycles that retires
+ * CNTMASK instructions. By setting CNTMASK to a value (16)
+ * larger than the maximum number of instructions that can be
+ * retired per cycle (4) and then inverting the condition, we
+ * count all cycles that retire 16 or less instructions, which
+ * is every cycle.
+ *
+ * Thereby we gain a PEBS capable cycle counter.
+ */
+ u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16);
+
+ alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
+ event->hw.config = alt_config;
+ }
+}
+
+static void intel_pebs_aliases_snb(struct perf_event *event)
+{
+ if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
+ /*
+ * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
+ * (0x003c) so that we can use it with PEBS.
+ *
+ * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
+ * PEBS capable. However we can use UOPS_RETIRED.ALL
+ * (0x01c2), which is a PEBS capable event, to get the same
+ * count.
+ *
+ * UOPS_RETIRED.ALL counts the number of cycles that retires
+ * CNTMASK micro-ops. By setting CNTMASK to a value (16)
+ * larger than the maximum number of micro-ops that can be
+ * retired per cycle (4) and then inverting the condition, we
+ * count all cycles that retire 16 or less micro-ops, which
+ * is every cycle.
+ *
+ * Thereby we gain a PEBS capable cycle counter.
+ */
+ u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16);
+
+ alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
+ event->hw.config = alt_config;
+ }
+}
+
+static void intel_pebs_aliases_precdist(struct perf_event *event)
+{
+ if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
+ /*
+ * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
+ * (0x003c) so that we can use it with PEBS.
+ *
+ * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
+ * PEBS capable. However we can use INST_RETIRED.PREC_DIST
+ * (0x01c0), which is a PEBS capable event, to get the same
+ * count.
+ *
+ * The PREC_DIST event has special support to minimize sample
+ * shadowing effects. One drawback is that it can be
+ * only programmed on counter 1, but that seems like an
+ * acceptable trade off.
+ */
+ u64 alt_config = X86_CONFIG(.event=0xc0, .umask=0x01, .inv=1, .cmask=16);
+
+ alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
+ event->hw.config = alt_config;
+ }
+}
+
+static void intel_pebs_aliases_ivb(struct perf_event *event)
+{
+ if (event->attr.precise_ip < 3)
+ return intel_pebs_aliases_snb(event);
+ return intel_pebs_aliases_precdist(event);
+}
+
+static void intel_pebs_aliases_skl(struct perf_event *event)
+{
+ if (event->attr.precise_ip < 3)
+ return intel_pebs_aliases_core2(event);
+ return intel_pebs_aliases_precdist(event);
+}
+
+static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
+{
+ unsigned long flags = x86_pmu.free_running_flags;
+
+ if (event->attr.use_clockid)
+ flags &= ~PERF_SAMPLE_TIME;
+ return flags;
+}
+
+static int intel_pmu_hw_config(struct perf_event *event)
+{
+ int ret = x86_pmu_hw_config(event);
+
+ if (ret)
+ return ret;
+
+ if (event->attr.precise_ip) {
+ if (!event->attr.freq) {
+ event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
+ if (!(event->attr.sample_type &
+ ~intel_pmu_free_running_flags(event)))
+ event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
+ }
+ if (x86_pmu.pebs_aliases)
+ x86_pmu.pebs_aliases(event);
+ }
+
+ if (needs_branch_stack(event)) {
+ ret = intel_pmu_setup_lbr_filter(event);
+ if (ret)
+ return ret;
+
+ /*
+ * BTS is set up earlier in this path, so don't account twice
+ */
+ if (!intel_pmu_has_bts(event)) {
+ /* disallow lbr if conflicting events are present */
+ if (x86_add_exclusive(x86_lbr_exclusive_lbr))
+ return -EBUSY;
+
+ event->destroy = hw_perf_lbr_event_destroy;
+ }
+ }
+
+ if (event->attr.type != PERF_TYPE_RAW)
+ return 0;
+
+ if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
+ return 0;
+
+ if (x86_pmu.version < 3)
+ return -EINVAL;
+
+ if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
+
+ return 0;
+}
+
+struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
+{
+ if (x86_pmu.guest_get_msrs)
+ return x86_pmu.guest_get_msrs(nr);
+ *nr = 0;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(perf_guest_get_msrs);
+
+static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
+
+ arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
+ arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
+ arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
+ /*
+ * If PMU counter has PEBS enabled it is not enough to disable counter
+ * on a guest entry since PEBS memory write can overshoot guest entry
+ * and corrupt guest memory. Disabling PEBS solves the problem.
+ */
+ arr[1].msr = MSR_IA32_PEBS_ENABLE;
+ arr[1].host = cpuc->pebs_enabled;
+ arr[1].guest = 0;
+
+ *nr = 2;
+ return arr;
+}
+
+static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ struct perf_event *event = cpuc->events[idx];
+
+ arr[idx].msr = x86_pmu_config_addr(idx);
+ arr[idx].host = arr[idx].guest = 0;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ arr[idx].host = arr[idx].guest =
+ event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
+
+ if (event->attr.exclude_host)
+ arr[idx].host &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+ else if (event->attr.exclude_guest)
+ arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+ }
+
+ *nr = x86_pmu.num_counters;
+ return arr;
+}
+
+static void core_pmu_enable_event(struct perf_event *event)
+{
+ if (!event->attr.exclude_host)
+ x86_pmu_enable_event(event);
+}
+
+static void core_pmu_enable_all(int added)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
+
+ if (!test_bit(idx, cpuc->active_mask) ||
+ cpuc->events[idx]->attr.exclude_host)
+ continue;
+
+ __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+ }
+}
+
+static int hsw_hw_config(struct perf_event *event)
+{
+ int ret = intel_pmu_hw_config(event);
+
+ if (ret)
+ return ret;
+ if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
+ return 0;
+ event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
+
+ /*
+ * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
+ * PEBS or in ANY thread mode. Since the results are non-sensical forbid
+ * this combination.
+ */
+ if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
+ ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
+ event->attr.precise_ip > 0))
+ return -EOPNOTSUPP;
+
+ if (event_is_checkpointed(event)) {
+ /*
+ * Sampling of checkpointed events can cause situations where
+ * the CPU constantly aborts because of a overflow, which is
+ * then checkpointed back and ignored. Forbid checkpointing
+ * for sampling.
+ *
+ * But still allow a long sampling period, so that perf stat
+ * from KVM works.
+ */
+ if (event->attr.sample_period > 0 &&
+ event->attr.sample_period < 0x7fffffff)
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static struct event_constraint counter2_constraint =
+ EVENT_CONSTRAINT(0, 0x4, 0);
+
+static struct event_constraint *
+hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct event_constraint *c;
+
+ c = intel_get_event_constraints(cpuc, idx, event);
+
+ /* Handle special quirk on in_tx_checkpointed only in counter 2 */
+ if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
+ if (c->idxmsk64 & (1U << 2))
+ return &counter2_constraint;
+ return &emptyconstraint;
+ }
+
+ return c;
+}
+
+/*
+ * Broadwell:
+ *
+ * The INST_RETIRED.ALL period always needs to have lowest 6 bits cleared
+ * (BDM55) and it must not use a period smaller than 100 (BDM11). We combine
+ * the two to enforce a minimum period of 128 (the smallest value that has bits
+ * 0-5 cleared and >= 100).
+ *
+ * Because of how the code in x86_perf_event_set_period() works, the truncation
+ * of the lower 6 bits is 'harmless' as we'll occasionally add a longer period
+ * to make up for the 'lost' events due to carrying the 'error' in period_left.
+ *
+ * Therefore the effective (average) period matches the requested period,
+ * despite coarser hardware granularity.
+ */
+static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
+{
+ if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
+ X86_CONFIG(.event=0xc0, .umask=0x01)) {
+ if (left < 128)
+ left = 128;
+ left &= ~0x3fu;
+ }
+ return left;
+}
+
+PMU_FORMAT_ATTR(event, "config:0-7" );
+PMU_FORMAT_ATTR(umask, "config:8-15" );
+PMU_FORMAT_ATTR(edge, "config:18" );
+PMU_FORMAT_ATTR(pc, "config:19" );
+PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */
+PMU_FORMAT_ATTR(inv, "config:23" );
+PMU_FORMAT_ATTR(cmask, "config:24-31" );
+PMU_FORMAT_ATTR(in_tx, "config:32");
+PMU_FORMAT_ATTR(in_tx_cp, "config:33");
+
+static struct attribute *intel_arch_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_pc.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ NULL,
+};
+
+ssize_t intel_event_sysfs_show(char *page, u64 config)
+{
+ u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT);
+
+ return x86_event_sysfs_show(page, config, event);
+}
+
+struct intel_shared_regs *allocate_shared_regs(int cpu)
+{
+ struct intel_shared_regs *regs;
+ int i;
+
+ regs = kzalloc_node(sizeof(struct intel_shared_regs),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (regs) {
+ /*
+ * initialize the locks to keep lockdep happy
+ */
+ for (i = 0; i < EXTRA_REG_MAX; i++)
+ raw_spin_lock_init(&regs->regs[i].lock);
+
+ regs->core_id = -1;
+ }
+ return regs;
+}
+
+static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu)
+{
+ struct intel_excl_cntrs *c;
+
+ c = kzalloc_node(sizeof(struct intel_excl_cntrs),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (c) {
+ raw_spin_lock_init(&c->lock);
+ c->core_id = -1;
+ }
+ return c;
+}
+
+static int intel_pmu_cpu_prepare(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+ if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
+ cpuc->shared_regs = allocate_shared_regs(cpu);
+ if (!cpuc->shared_regs)
+ goto err;
+ }
+
+ if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
+ size_t sz = X86_PMC_IDX_MAX * sizeof(struct event_constraint);
+
+ cpuc->constraint_list = kzalloc(sz, GFP_KERNEL);
+ if (!cpuc->constraint_list)
+ goto err_shared_regs;
+
+ cpuc->excl_cntrs = allocate_excl_cntrs(cpu);
+ if (!cpuc->excl_cntrs)
+ goto err_constraint_list;
+
+ cpuc->excl_thread_id = 0;
+ }
+
+ return NOTIFY_OK;
+
+err_constraint_list:
+ kfree(cpuc->constraint_list);
+ cpuc->constraint_list = NULL;
+
+err_shared_regs:
+ kfree(cpuc->shared_regs);
+ cpuc->shared_regs = NULL;
+
+err:
+ return NOTIFY_BAD;
+}
+
+static void intel_pmu_cpu_starting(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ int core_id = topology_core_id(cpu);
+ int i;
+
+ init_debug_store_on_cpu(cpu);
+ /*
+ * Deal with CPUs that don't clear their LBRs on power-up.
+ */
+ intel_pmu_lbr_reset();
+
+ cpuc->lbr_sel = NULL;
+
+ if (!cpuc->shared_regs)
+ return;
+
+ if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) {
+ for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+ struct intel_shared_regs *pc;
+
+ pc = per_cpu(cpu_hw_events, i).shared_regs;
+ if (pc && pc->core_id == core_id) {
+ cpuc->kfree_on_online[0] = cpuc->shared_regs;
+ cpuc->shared_regs = pc;
+ break;
+ }
+ }
+ cpuc->shared_regs->core_id = core_id;
+ cpuc->shared_regs->refcnt++;
+ }
+
+ if (x86_pmu.lbr_sel_map)
+ cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
+
+ if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
+ for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+ struct intel_excl_cntrs *c;
+
+ c = per_cpu(cpu_hw_events, i).excl_cntrs;
+ if (c && c->core_id == core_id) {
+ cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
+ cpuc->excl_cntrs = c;
+ cpuc->excl_thread_id = 1;
+ break;
+ }
+ }
+ cpuc->excl_cntrs->core_id = core_id;
+ cpuc->excl_cntrs->refcnt++;
+ }
+}
+
+static void free_excl_cntrs(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ struct intel_excl_cntrs *c;
+
+ c = cpuc->excl_cntrs;
+ if (c) {
+ if (c->core_id == -1 || --c->refcnt == 0)
+ kfree(c);
+ cpuc->excl_cntrs = NULL;
+ kfree(cpuc->constraint_list);
+ cpuc->constraint_list = NULL;
+ }
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ struct intel_shared_regs *pc;
+
+ pc = cpuc->shared_regs;
+ if (pc) {
+ if (pc->core_id == -1 || --pc->refcnt == 0)
+ kfree(pc);
+ cpuc->shared_regs = NULL;
+ }
+
+ free_excl_cntrs(cpu);
+
+ fini_debug_store_on_cpu(cpu);
+}
+
+static void intel_pmu_sched_task(struct perf_event_context *ctx,
+ bool sched_in)
+{
+ if (x86_pmu.pebs_active)
+ intel_pmu_pebs_sched_task(ctx, sched_in);
+ if (x86_pmu.lbr_nr)
+ intel_pmu_lbr_sched_task(ctx, sched_in);
+}
+
+PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
+
+PMU_FORMAT_ATTR(ldlat, "config1:0-15");
+
+PMU_FORMAT_ATTR(frontend, "config1:0-23");
+
+static struct attribute *intel_arch3_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_pc.attr,
+ &format_attr_any.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ &format_attr_in_tx.attr,
+ &format_attr_in_tx_cp.attr,
+
+ &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
+ &format_attr_ldlat.attr, /* PEBS load latency */
+ NULL,
+};
+
+static struct attribute *skl_format_attr[] = {
+ &format_attr_frontend.attr,
+ NULL,
+};
+
+static __initconst const struct x86_pmu core_pmu = {
+ .name = "core",
+ .handle_irq = x86_pmu_handle_irq,
+ .disable_all = x86_pmu_disable_all,
+ .enable_all = core_pmu_enable_all,
+ .enable = core_pmu_enable_event,
+ .disable = x86_pmu_disable_event,
+ .hw_config = x86_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
+ .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
+ .event_map = intel_pmu_event_map,
+ .max_events = ARRAY_SIZE(intel_perfmon_event_map),
+ .apic = 1,
+ .free_running_flags = PEBS_FREERUNNING_FLAGS,
+
+ /*
+ * Intel PMCs cannot be accessed sanely above 32-bit width,
+ * so we install an artificial 1<<31 period regardless of
+ * the generic event period:
+ */
+ .max_period = (1ULL<<31) - 1,
+ .get_event_constraints = intel_get_event_constraints,
+ .put_event_constraints = intel_put_event_constraints,
+ .event_constraints = intel_core_event_constraints,
+ .guest_get_msrs = core_guest_get_msrs,
+ .format_attrs = intel_arch_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
+
+ /*
+ * Virtual (or funny metal) CPU can define x86_pmu.extra_regs
+ * together with PMU version 1 and thus be using core_pmu with
+ * shared_regs. We need following callbacks here to allocate
+ * it properly.
+ */
+ .cpu_prepare = intel_pmu_cpu_prepare,
+ .cpu_starting = intel_pmu_cpu_starting,
+ .cpu_dying = intel_pmu_cpu_dying,
+};
+
+static __initconst const struct x86_pmu intel_pmu = {
+ .name = "Intel",
+ .handle_irq = intel_pmu_handle_irq,
+ .disable_all = intel_pmu_disable_all,
+ .enable_all = intel_pmu_enable_all,
+ .enable = intel_pmu_enable_event,
+ .disable = intel_pmu_disable_event,
+ .hw_config = intel_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
+ .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
+ .event_map = intel_pmu_event_map,
+ .max_events = ARRAY_SIZE(intel_perfmon_event_map),
+ .apic = 1,
+ .free_running_flags = PEBS_FREERUNNING_FLAGS,
+ /*
+ * Intel PMCs cannot be accessed sanely above 32 bit width,
+ * so we install an artificial 1<<31 period regardless of
+ * the generic event period:
+ */
+ .max_period = (1ULL << 31) - 1,
+ .get_event_constraints = intel_get_event_constraints,
+ .put_event_constraints = intel_put_event_constraints,
+ .pebs_aliases = intel_pebs_aliases_core2,
+
+ .format_attrs = intel_arch3_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
+
+ .cpu_prepare = intel_pmu_cpu_prepare,
+ .cpu_starting = intel_pmu_cpu_starting,
+ .cpu_dying = intel_pmu_cpu_dying,
+ .guest_get_msrs = intel_guest_get_msrs,
+ .sched_task = intel_pmu_sched_task,
+};
+
+static __init void intel_clovertown_quirk(void)
+{
+ /*
+ * PEBS is unreliable due to:
+ *
+ * AJ67 - PEBS may experience CPL leaks
+ * AJ68 - PEBS PMI may be delayed by one event
+ * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+ * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+ *
+ * AJ67 could be worked around by restricting the OS/USR flags.
+ * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+ *
+ * AJ106 could possibly be worked around by not allowing LBR
+ * usage from PEBS, including the fixup.
+ * AJ68 could possibly be worked around by always programming
+ * a pebs_event_reset[0] value and coping with the lost events.
+ *
+ * But taken together it might just make sense to not enable PEBS on
+ * these chips.
+ */
+ pr_warn("PEBS disabled due to CPU errata\n");
+ x86_pmu.pebs = 0;
+ x86_pmu.pebs_constraints = NULL;
+}
+
+static int intel_snb_pebs_broken(int cpu)
+{
+ u32 rev = UINT_MAX; /* default to broken for unknown models */
+
+ switch (cpu_data(cpu).x86_model) {
+ case 42: /* SNB */
+ rev = 0x28;
+ break;
+
+ case 45: /* SNB-EP */
+ switch (cpu_data(cpu).x86_mask) {
+ case 6: rev = 0x618; break;
+ case 7: rev = 0x70c; break;
+ }
+ }
+
+ return (cpu_data(cpu).microcode < rev);
+}
+
+static void intel_snb_check_microcode(void)
+{
+ int pebs_broken = 0;
+ int cpu;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ if ((pebs_broken = intel_snb_pebs_broken(cpu)))
+ break;
+ }
+ put_online_cpus();
+
+ if (pebs_broken == x86_pmu.pebs_broken)
+ return;
+
+ /*
+ * Serialized by the microcode lock..
+ */
+ if (x86_pmu.pebs_broken) {
+ pr_info("PEBS enabled due to microcode update\n");
+ x86_pmu.pebs_broken = 0;
+ } else {
+ pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n");
+ x86_pmu.pebs_broken = 1;
+ }
+}
+
+/*
+ * Under certain circumstances, access certain MSR may cause #GP.
+ * The function tests if the input MSR can be safely accessed.
+ */
+static bool check_msr(unsigned long msr, u64 mask)
+{
+ u64 val_old, val_new, val_tmp;
+
+ /*
+ * Read the current value, change it and read it back to see if it
+ * matches, this is needed to detect certain hardware emulators
+ * (qemu/kvm) that don't trap on the MSR access and always return 0s.
+ */
+ if (rdmsrl_safe(msr, &val_old))
+ return false;
+
+ /*
+ * Only change the bits which can be updated by wrmsrl.
+ */
+ val_tmp = val_old ^ mask;
+ if (wrmsrl_safe(msr, val_tmp) ||
+ rdmsrl_safe(msr, &val_new))
+ return false;
+
+ if (val_new != val_tmp)
+ return false;
+
+ /* Here it's sure that the MSR can be safely accessed.
+ * Restore the old value and return.
+ */
+ wrmsrl(msr, val_old);
+
+ return true;
+}
+
+static __init void intel_sandybridge_quirk(void)
+{
+ x86_pmu.check_microcode = intel_snb_check_microcode;
+ intel_snb_check_microcode();
+}
+
+static const struct { int id; char *name; } intel_arch_events_map[] __initconst = {
+ { PERF_COUNT_HW_CPU_CYCLES, "cpu cycles" },
+ { PERF_COUNT_HW_INSTRUCTIONS, "instructions" },
+ { PERF_COUNT_HW_BUS_CYCLES, "bus cycles" },
+ { PERF_COUNT_HW_CACHE_REFERENCES, "cache references" },
+ { PERF_COUNT_HW_CACHE_MISSES, "cache misses" },
+ { PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "branch instructions" },
+ { PERF_COUNT_HW_BRANCH_MISSES, "branch misses" },
+};
+
+static __init void intel_arch_events_quirk(void)
+{
+ int bit;
+
+ /* disable event that reported as not presend by cpuid */
+ for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) {
+ intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0;
+ pr_warn("CPUID marked event: \'%s\' unavailable\n",
+ intel_arch_events_map[bit].name);
+ }
+}
+
+static __init void intel_nehalem_quirk(void)
+{
+ union cpuid10_ebx ebx;
+
+ ebx.full = x86_pmu.events_maskl;
+ if (ebx.split.no_branch_misses_retired) {
+ /*
+ * Erratum AAJ80 detected, we work it around by using
+ * the BR_MISP_EXEC.ANY event. This will over-count
+ * branch-misses, but it's still much better than the
+ * architectural event which is often completely bogus:
+ */
+ intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
+ ebx.split.no_branch_misses_retired = 0;
+ x86_pmu.events_maskl = ebx.full;
+ pr_info("CPU erratum AAJ80 worked around\n");
+ }
+}
+
+/*
+ * enable software workaround for errata:
+ * SNB: BJ122
+ * IVB: BV98
+ * HSW: HSD29
+ *
+ * Only needed when HT is enabled. However detecting
+ * if HT is enabled is difficult (model specific). So instead,
+ * we enable the workaround in the early boot, and verify if
+ * it is needed in a later initcall phase once we have valid
+ * topology information to check if HT is actually enabled
+ */
+static __init void intel_ht_bug(void)
+{
+ x86_pmu.flags |= PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED;
+
+ x86_pmu.start_scheduling = intel_start_scheduling;
+ x86_pmu.commit_scheduling = intel_commit_scheduling;
+ x86_pmu.stop_scheduling = intel_stop_scheduling;
+}
+
+EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82")
+
+/* Haswell special events */
+EVENT_ATTR_STR(tx-start, tx_start, "event=0xc9,umask=0x1");
+EVENT_ATTR_STR(tx-commit, tx_commit, "event=0xc9,umask=0x2");
+EVENT_ATTR_STR(tx-abort, tx_abort, "event=0xc9,umask=0x4");
+EVENT_ATTR_STR(tx-capacity, tx_capacity, "event=0x54,umask=0x2");
+EVENT_ATTR_STR(tx-conflict, tx_conflict, "event=0x54,umask=0x1");
+EVENT_ATTR_STR(el-start, el_start, "event=0xc8,umask=0x1");
+EVENT_ATTR_STR(el-commit, el_commit, "event=0xc8,umask=0x2");
+EVENT_ATTR_STR(el-abort, el_abort, "event=0xc8,umask=0x4");
+EVENT_ATTR_STR(el-capacity, el_capacity, "event=0x54,umask=0x2");
+EVENT_ATTR_STR(el-conflict, el_conflict, "event=0x54,umask=0x1");
+EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1");
+EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1");
+
+static struct attribute *hsw_events_attrs[] = {
+ EVENT_PTR(tx_start),
+ EVENT_PTR(tx_commit),
+ EVENT_PTR(tx_abort),
+ EVENT_PTR(tx_capacity),
+ EVENT_PTR(tx_conflict),
+ EVENT_PTR(el_start),
+ EVENT_PTR(el_commit),
+ EVENT_PTR(el_abort),
+ EVENT_PTR(el_capacity),
+ EVENT_PTR(el_conflict),
+ EVENT_PTR(cycles_t),
+ EVENT_PTR(cycles_ct),
+ EVENT_PTR(mem_ld_hsw),
+ EVENT_PTR(mem_st_hsw),
+ NULL
+};
+
+__init int intel_pmu_init(void)
+{
+ union cpuid10_edx edx;
+ union cpuid10_eax eax;
+ union cpuid10_ebx ebx;
+ struct event_constraint *c;
+ unsigned int unused;
+ struct extra_reg *er;
+ int version, i;
+
+ if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
+ switch (boot_cpu_data.x86) {
+ case 0x6:
+ return p6_pmu_init();
+ case 0xb:
+ return knc_pmu_init();
+ case 0xf:
+ return p4_pmu_init();
+ }
+ return -ENODEV;
+ }
+
+ /*
+ * Check whether the Architectural PerfMon supports
+ * Branch Misses Retired hw_event or not.
+ */
+ cpuid(10, &eax.full, &ebx.full, &unused, &edx.full);
+ if (eax.split.mask_length < ARCH_PERFMON_EVENTS_COUNT)
+ return -ENODEV;
+
+ version = eax.split.version_id;
+ if (version < 2)
+ x86_pmu = core_pmu;
+ else
+ x86_pmu = intel_pmu;
+
+ x86_pmu.version = version;
+ x86_pmu.num_counters = eax.split.num_counters;
+ x86_pmu.cntval_bits = eax.split.bit_width;
+ x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
+
+ x86_pmu.events_maskl = ebx.full;
+ x86_pmu.events_mask_len = eax.split.mask_length;
+
+ x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
+
+ /*
+ * Quirk: v2 perfmon does not report fixed-purpose events, so
+ * assume at least 3 events:
+ */
+ if (version > 1)
+ x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
+
+ if (boot_cpu_has(X86_FEATURE_PDCM)) {
+ u64 capabilities;
+
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
+ x86_pmu.intel_cap.capabilities = capabilities;
+ }
+
+ intel_ds_init();
+
+ x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
+
+ /*
+ * Install the hw-cache-events table:
+ */
+ switch (boot_cpu_data.x86_model) {
+ case 14: /* 65nm Core "Yonah" */
+ pr_cont("Core events, ");
+ break;
+
+ case 15: /* 65nm Core2 "Merom" */
+ x86_add_quirk(intel_clovertown_quirk);
+ case 22: /* 65nm Core2 "Merom-L" */
+ case 23: /* 45nm Core2 "Penryn" */
+ case 29: /* 45nm Core2 "Dunnington (MP) */
+ memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ intel_pmu_lbr_init_core();
+
+ x86_pmu.event_constraints = intel_core2_event_constraints;
+ x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
+ pr_cont("Core2 events, ");
+ break;
+
+ case 30: /* 45nm Nehalem */
+ case 26: /* 45nm Nehalem-EP */
+ case 46: /* 45nm Nehalem-EX */
+ memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_nhm();
+
+ x86_pmu.event_constraints = intel_nehalem_event_constraints;
+ x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
+ x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+ x86_pmu.extra_regs = intel_nehalem_extra_regs;
+
+ x86_pmu.cpu_events = nhm_events_attrs;
+
+ /* UOPS_ISSUED.STALLED_CYCLES */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+ X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+ /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+ X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+
+ intel_pmu_pebs_data_source_nhm();
+ x86_add_quirk(intel_nehalem_quirk);
+
+ pr_cont("Nehalem events, ");
+ break;
+
+ case 28: /* 45nm Atom "Pineview" */
+ case 38: /* 45nm Atom "Lincroft" */
+ case 39: /* 32nm Atom "Penwell" */
+ case 53: /* 32nm Atom "Cloverview" */
+ case 54: /* 32nm Atom "Cedarview" */
+ memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ intel_pmu_lbr_init_atom();
+
+ x86_pmu.event_constraints = intel_gen_event_constraints;
+ x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_core2;
+ pr_cont("Atom events, ");
+ break;
+
+ case 55: /* 22nm Atom "Silvermont" */
+ case 76: /* 14nm Atom "Airmont" */
+ case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+ memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_atom();
+
+ x86_pmu.event_constraints = intel_slm_event_constraints;
+ x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_slm_extra_regs;
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ pr_cont("Silvermont events, ");
+ break;
+
+ case 37: /* 32nm Westmere */
+ case 44: /* 32nm Westmere-EP */
+ case 47: /* 32nm Westmere-EX */
+ memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_nhm();
+
+ x86_pmu.event_constraints = intel_westmere_event_constraints;
+ x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+ x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_westmere_extra_regs;
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+
+ x86_pmu.cpu_events = nhm_events_attrs;
+
+ /* UOPS_ISSUED.STALLED_CYCLES */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+ X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+ /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+ X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+
+ intel_pmu_pebs_data_source_nhm();
+ pr_cont("Westmere events, ");
+ break;
+
+ case 42: /* 32nm SandyBridge */
+ case 45: /* 32nm SandyBridge-E/EN/EP */
+ x86_add_quirk(intel_sandybridge_quirk);
+ x86_add_quirk(intel_ht_bug);
+ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_snb();
+
+ x86_pmu.event_constraints = intel_snb_event_constraints;
+ x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+ if (boot_cpu_data.x86_model == 45)
+ x86_pmu.extra_regs = intel_snbep_extra_regs;
+ else
+ x86_pmu.extra_regs = intel_snb_extra_regs;
+
+
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.cpu_events = snb_events_attrs;
+
+ /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+ X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+ /* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
+ X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1);
+
+ pr_cont("SandyBridge events, ");
+ break;
+
+ case 58: /* 22nm IvyBridge */
+ case 62: /* 22nm IvyBridge-EP/EX */
+ x86_add_quirk(intel_ht_bug);
+ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ /* dTLB-load-misses on IVB is different than SNB */
+ hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
+
+ memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_snb();
+
+ x86_pmu.event_constraints = intel_ivb_event_constraints;
+ x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
+ x86_pmu.pebs_prec_dist = true;
+ if (boot_cpu_data.x86_model == 62)
+ x86_pmu.extra_regs = intel_snbep_extra_regs;
+ else
+ x86_pmu.extra_regs = intel_snb_extra_regs;
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.cpu_events = snb_events_attrs;
+
+ /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+ intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+ X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+
+ pr_cont("IvyBridge events, ");
+ break;
+
+
+ case 60: /* 22nm Haswell Core */
+ case 63: /* 22nm Haswell Server */
+ case 69: /* 22nm Haswell ULT */
+ case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+ x86_add_quirk(intel_ht_bug);
+ x86_pmu.late_ack = true;
+ memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_hsw();
+
+ x86_pmu.event_constraints = intel_hsw_event_constraints;
+ x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_snbep_extra_regs;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
+ x86_pmu.pebs_prec_dist = true;
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.hw_config = hsw_hw_config;
+ x86_pmu.get_event_constraints = hsw_get_event_constraints;
+ x86_pmu.cpu_events = hsw_events_attrs;
+ x86_pmu.lbr_double_abort = true;
+ pr_cont("Haswell events, ");
+ break;
+
+ case 61: /* 14nm Broadwell Core-M */
+ case 86: /* 14nm Broadwell Xeon D */
+ case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+ case 79: /* 14nm Broadwell Server */
+ x86_pmu.late_ack = true;
+ memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+
+ /* L3_MISS_LOCAL_DRAM is BIT(26) in Broadwell */
+ hw_cache_extra_regs[C(LL)][C(OP_READ)][C(RESULT_MISS)] = HSW_DEMAND_READ |
+ BDW_L3_MISS|HSW_SNOOP_DRAM;
+ hw_cache_extra_regs[C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = HSW_DEMAND_WRITE|BDW_L3_MISS|
+ HSW_SNOOP_DRAM;
+ hw_cache_extra_regs[C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = HSW_DEMAND_READ|
+ BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
+ hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
+ BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
+
+ intel_pmu_lbr_init_hsw();
+
+ x86_pmu.event_constraints = intel_bdw_event_constraints;
+ x86_pmu.pebs_constraints = intel_bdw_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_snbep_extra_regs;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
+ x86_pmu.pebs_prec_dist = true;
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.hw_config = hsw_hw_config;
+ x86_pmu.get_event_constraints = hsw_get_event_constraints;
+ x86_pmu.cpu_events = hsw_events_attrs;
+ x86_pmu.limit_period = bdw_limit_period;
+ pr_cont("Broadwell events, ");
+ break;
+
+ case 87: /* Knights Landing Xeon Phi */
+ memcpy(hw_cache_event_ids,
+ slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs,
+ knl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_knl();
+
+ x86_pmu.event_constraints = intel_slm_event_constraints;
+ x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_knl_extra_regs;
+
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ pr_cont("Knights Landing events, ");
+ break;
+
+ case 78: /* 14nm Skylake Mobile */
+ case 94: /* 14nm Skylake Desktop */
+ x86_pmu.late_ack = true;
+ memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_skl();
+
+ x86_pmu.event_constraints = intel_skl_event_constraints;
+ x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_skl_extra_regs;
+ x86_pmu.pebs_aliases = intel_pebs_aliases_skl;
+ x86_pmu.pebs_prec_dist = true;
+ /* all extra regs are per-cpu when HT is on */
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.hw_config = hsw_hw_config;
+ x86_pmu.get_event_constraints = hsw_get_event_constraints;
+ x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr,
+ skl_format_attr);
+ WARN_ON(!x86_pmu.format_attrs);
+ x86_pmu.cpu_events = hsw_events_attrs;
+ pr_cont("Skylake events, ");
+ break;
+
+ default:
+ switch (x86_pmu.version) {
+ case 1:
+ x86_pmu.event_constraints = intel_v1_event_constraints;
+ pr_cont("generic architected perfmon v1, ");
+ break;
+ default:
+ /*
+ * default constraints for v2 and up
+ */
+ x86_pmu.event_constraints = intel_gen_event_constraints;
+ pr_cont("generic architected perfmon, ");
+ break;
+ }
+ }
+
+ if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
+ WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
+ x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
+ x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
+ }
+ x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+
+ if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
+ WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
+ x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED);
+ x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
+ }
+
+ x86_pmu.intel_ctrl |=
+ ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
+
+ if (x86_pmu.event_constraints) {
+ /*
+ * event on fixed counter2 (REF_CYCLES) only works on this
+ * counter, so do not extend mask to generic counters
+ */
+ for_each_event_constraint(c, x86_pmu.event_constraints) {
+ if (c->cmask == FIXED_EVENT_FLAGS
+ && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) {
+ c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
+ }
+ c->idxmsk64 &=
+ ~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
+ c->weight = hweight64(c->idxmsk64);
+ }
+ }
+
+ /*
+ * Access LBR MSR may cause #GP under certain circumstances.
+ * E.g. KVM doesn't support LBR MSR
+ * Check all LBT MSR here.
+ * Disable LBR access if any LBR MSRs can not be accessed.
+ */
+ if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
+ x86_pmu.lbr_nr = 0;
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
+ check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
+ x86_pmu.lbr_nr = 0;
+ }
+
+ /*
+ * Access extra MSR may cause #GP under certain circumstances.
+ * E.g. KVM doesn't support offcore event
+ * Check all extra_regs here.
+ */
+ if (x86_pmu.extra_regs) {
+ for (er = x86_pmu.extra_regs; er->msr; er++) {
+ er->extra_msr_access = check_msr(er->msr, 0x11UL);
+ /* Disable LBR select mapping */
+ if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
+ x86_pmu.lbr_sel_map = NULL;
+ }
+ }
+
+ /* Support full width counters using alternative MSR range */
+ if (x86_pmu.intel_cap.full_width_write) {
+ x86_pmu.max_period = x86_pmu.cntval_mask;
+ x86_pmu.perfctr = MSR_IA32_PMC0;
+ pr_cont("full-width counters, ");
+ }
+
+ return 0;
+}
+
+/*
+ * HT bug: phase 2 init
+ * Called once we have valid topology information to check
+ * whether or not HT is enabled
+ * If HT is off, then we disable the workaround
+ */
+static __init int fixup_ht_bug(void)
+{
+ int cpu = smp_processor_id();
+ int w, c;
+ /*
+ * problem not present on this CPU model, nothing to do
+ */
+ if (!(x86_pmu.flags & PMU_FL_EXCL_ENABLED))
+ return 0;
+
+ w = cpumask_weight(topology_sibling_cpumask(cpu));
+ if (w > 1) {
+ pr_info("PMU erratum BJ122, BV98, HSD29 worked around, HT is on\n");
+ return 0;
+ }
+
+ if (lockup_detector_suspend() != 0) {
+ pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n");
+ return 0;
+ }
+
+ x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED);
+
+ x86_pmu.start_scheduling = NULL;
+ x86_pmu.commit_scheduling = NULL;
+ x86_pmu.stop_scheduling = NULL;
+
+ lockup_detector_resume();
+
+ get_online_cpus();
+
+ for_each_online_cpu(c) {
+ free_excl_cntrs(c);
+ }
+
+ put_online_cpus();
+ pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n");
+ return 0;
+}
+subsys_initcall(fixup_ht_bug)
diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c
new file mode 100644
index 0000000..93cb412
--- /dev/null
+++ b/arch/x86/events/intel/cqm.c
@@ -0,0 +1,1381 @@
+/*
+ * Intel Cache Quality-of-Service Monitoring (CQM) support.
+ *
+ * Based very, very heavily on work by Peter Zijlstra.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+#define MSR_IA32_PQR_ASSOC 0x0c8f
+#define MSR_IA32_QM_CTR 0x0c8e
+#define MSR_IA32_QM_EVTSEL 0x0c8d
+
+static u32 cqm_max_rmid = -1;
+static unsigned int cqm_l3_scale; /* supposedly cacheline size */
+
+/**
+ * struct intel_pqr_state - State cache for the PQR MSR
+ * @rmid: The cached Resource Monitoring ID
+ * @closid: The cached Class Of Service ID
+ * @rmid_usecnt: The usage counter for rmid
+ *
+ * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the
+ * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always
+ * contains both parts, so we need to cache them.
+ *
+ * The cache also helps to avoid pointless updates if the value does
+ * not change.
+ */
+struct intel_pqr_state {
+ u32 rmid;
+ u32 closid;
+ int rmid_usecnt;
+};
+
+/*
+ * The cached intel_pqr_state is strictly per CPU and can never be
+ * updated from a remote CPU. Both functions which modify the state
+ * (intel_cqm_event_start and intel_cqm_event_stop) are called with
+ * interrupts disabled, which is sufficient for the protection.
+ */
+static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
+
+/*
+ * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
+ * Also protects event->hw.cqm_rmid
+ *
+ * Hold either for stability, both for modification of ->hw.cqm_rmid.
+ */
+static DEFINE_MUTEX(cache_mutex);
+static DEFINE_RAW_SPINLOCK(cache_lock);
+
+/*
+ * Groups of events that have the same target(s), one RMID per group.
+ */
+static LIST_HEAD(cache_groups);
+
+/*
+ * Mask of CPUs for reading CQM values. We only need one per-socket.
+ */
+static cpumask_t cqm_cpumask;
+
+#define RMID_VAL_ERROR (1ULL << 63)
+#define RMID_VAL_UNAVAIL (1ULL << 62)
+
+#define QOS_L3_OCCUP_EVENT_ID (1 << 0)
+
+#define QOS_EVENT_MASK QOS_L3_OCCUP_EVENT_ID
+
+/*
+ * This is central to the rotation algorithm in __intel_cqm_rmid_rotate().
+ *
+ * This rmid is always free and is guaranteed to have an associated
+ * near-zero occupancy value, i.e. no cachelines are tagged with this
+ * RMID, once __intel_cqm_rmid_rotate() returns.
+ */
+static u32 intel_cqm_rotation_rmid;
+
+#define INVALID_RMID (-1)
+
+/*
+ * Is @rmid valid for programming the hardware?
+ *
+ * rmid 0 is reserved by the hardware for all non-monitored tasks, which
+ * means that we should never come across an rmid with that value.
+ * Likewise, an rmid value of -1 is used to indicate "no rmid currently
+ * assigned" and is used as part of the rotation code.
+ */
+static inline bool __rmid_valid(u32 rmid)
+{
+ if (!rmid || rmid == INVALID_RMID)
+ return false;
+
+ return true;
+}
+
+static u64 __rmid_read(u32 rmid)
+{
+ u64 val;
+
+ /*
+ * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt,
+ * it just says that to increase confusion.
+ */
+ wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid);
+ rdmsrl(MSR_IA32_QM_CTR, val);
+
+ /*
+ * Aside from the ERROR and UNAVAIL bits, assume this thing returns
+ * the number of cachelines tagged with @rmid.
+ */
+ return val;
+}
+
+enum rmid_recycle_state {
+ RMID_YOUNG = 0,
+ RMID_AVAILABLE,
+ RMID_DIRTY,
+};
+
+struct cqm_rmid_entry {
+ u32 rmid;
+ enum rmid_recycle_state state;
+ struct list_head list;
+ unsigned long queue_time;
+};
+
+/*
+ * cqm_rmid_free_lru - A least recently used list of RMIDs.
+ *
+ * Oldest entry at the head, newest (most recently used) entry at the
+ * tail. This list is never traversed, it's only used to keep track of
+ * the lru order. That is, we only pick entries of the head or insert
+ * them on the tail.
+ *
+ * All entries on the list are 'free', and their RMIDs are not currently
+ * in use. To mark an RMID as in use, remove its entry from the lru
+ * list.
+ *
+ *
+ * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs.
+ *
+ * This list is contains RMIDs that no one is currently using but that
+ * may have a non-zero occupancy value associated with them. The
+ * rotation worker moves RMIDs from the limbo list to the free list once
+ * the occupancy value drops below __intel_cqm_threshold.
+ *
+ * Both lists are protected by cache_mutex.
+ */
+static LIST_HEAD(cqm_rmid_free_lru);
+static LIST_HEAD(cqm_rmid_limbo_lru);
+
+/*
+ * We use a simple array of pointers so that we can lookup a struct
+ * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid()
+ * and __put_rmid() from having to worry about dealing with struct
+ * cqm_rmid_entry - they just deal with rmids, i.e. integers.
+ *
+ * Once this array is initialized it is read-only. No locks are required
+ * to access it.
+ *
+ * All entries for all RMIDs can be looked up in the this array at all
+ * times.
+ */
+static struct cqm_rmid_entry **cqm_rmid_ptrs;
+
+static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid)
+{
+ struct cqm_rmid_entry *entry;
+
+ entry = cqm_rmid_ptrs[rmid];
+ WARN_ON(entry->rmid != rmid);
+
+ return entry;
+}
+
+/*
+ * Returns < 0 on fail.
+ *
+ * We expect to be called with cache_mutex held.
+ */
+static u32 __get_rmid(void)
+{
+ struct cqm_rmid_entry *entry;
+
+ lockdep_assert_held(&cache_mutex);
+
+ if (list_empty(&cqm_rmid_free_lru))
+ return INVALID_RMID;
+
+ entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list);
+ list_del(&entry->list);
+
+ return entry->rmid;
+}
+
+static void __put_rmid(u32 rmid)
+{
+ struct cqm_rmid_entry *entry;
+
+ lockdep_assert_held(&cache_mutex);
+
+ WARN_ON(!__rmid_valid(rmid));
+ entry = __rmid_entry(rmid);
+
+ entry->queue_time = jiffies;
+ entry->state = RMID_YOUNG;
+
+ list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
+}
+
+static int intel_cqm_setup_rmid_cache(void)
+{
+ struct cqm_rmid_entry *entry;
+ unsigned int nr_rmids;
+ int r = 0;
+
+ nr_rmids = cqm_max_rmid + 1;
+ cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) *
+ nr_rmids, GFP_KERNEL);
+ if (!cqm_rmid_ptrs)
+ return -ENOMEM;
+
+ for (; r <= cqm_max_rmid; r++) {
+ struct cqm_rmid_entry *entry;
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ goto fail;
+
+ INIT_LIST_HEAD(&entry->list);
+ entry->rmid = r;
+ cqm_rmid_ptrs[r] = entry;
+
+ list_add_tail(&entry->list, &cqm_rmid_free_lru);
+ }
+
+ /*
+ * RMID 0 is special and is always allocated. It's used for all
+ * tasks that are not monitored.
+ */
+ entry = __rmid_entry(0);
+ list_del(&entry->list);
+
+ mutex_lock(&cache_mutex);
+ intel_cqm_rotation_rmid = __get_rmid();
+ mutex_unlock(&cache_mutex);
+
+ return 0;
+fail:
+ while (r--)
+ kfree(cqm_rmid_ptrs[r]);
+
+ kfree(cqm_rmid_ptrs);
+ return -ENOMEM;
+}
+
+/*
+ * Determine if @a and @b measure the same set of tasks.
+ *
+ * If @a and @b measure the same set of tasks then we want to share a
+ * single RMID.
+ */
+static bool __match_event(struct perf_event *a, struct perf_event *b)
+{
+ /* Per-cpu and task events don't mix */
+ if ((a->attach_state & PERF_ATTACH_TASK) !=
+ (b->attach_state & PERF_ATTACH_TASK))
+ return false;
+
+#ifdef CONFIG_CGROUP_PERF
+ if (a->cgrp != b->cgrp)
+ return false;
+#endif
+
+ /* If not task event, we're machine wide */
+ if (!(b->attach_state & PERF_ATTACH_TASK))
+ return true;
+
+ /*
+ * Events that target same task are placed into the same cache group.
+ */
+ if (a->hw.target == b->hw.target)
+ return true;
+
+ /*
+ * Are we an inherited event?
+ */
+ if (b->parent == a)
+ return true;
+
+ return false;
+}
+
+#ifdef CONFIG_CGROUP_PERF
+static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event)
+{
+ if (event->attach_state & PERF_ATTACH_TASK)
+ return perf_cgroup_from_task(event->hw.target, event->ctx);
+
+ return event->cgrp;
+}
+#endif
+
+/*
+ * Determine if @a's tasks intersect with @b's tasks
+ *
+ * There are combinations of events that we explicitly prohibit,
+ *
+ * PROHIBITS
+ * system-wide -> cgroup and task
+ * cgroup -> system-wide
+ * -> task in cgroup
+ * task -> system-wide
+ * -> task in cgroup
+ *
+ * Call this function before allocating an RMID.
+ */
+static bool __conflict_event(struct perf_event *a, struct perf_event *b)
+{
+#ifdef CONFIG_CGROUP_PERF
+ /*
+ * We can have any number of cgroups but only one system-wide
+ * event at a time.
+ */
+ if (a->cgrp && b->cgrp) {
+ struct perf_cgroup *ac = a->cgrp;
+ struct perf_cgroup *bc = b->cgrp;
+
+ /*
+ * This condition should have been caught in
+ * __match_event() and we should be sharing an RMID.
+ */
+ WARN_ON_ONCE(ac == bc);
+
+ if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
+ cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
+ return true;
+
+ return false;
+ }
+
+ if (a->cgrp || b->cgrp) {
+ struct perf_cgroup *ac, *bc;
+
+ /*
+ * cgroup and system-wide events are mutually exclusive
+ */
+ if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) ||
+ (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK)))
+ return true;
+
+ /*
+ * Ensure neither event is part of the other's cgroup
+ */
+ ac = event_to_cgroup(a);
+ bc = event_to_cgroup(b);
+ if (ac == bc)
+ return true;
+
+ /*
+ * Must have cgroup and non-intersecting task events.
+ */
+ if (!ac || !bc)
+ return false;
+
+ /*
+ * We have cgroup and task events, and the task belongs
+ * to a cgroup. Check for for overlap.
+ */
+ if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
+ cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
+ return true;
+
+ return false;
+ }
+#endif
+ /*
+ * If one of them is not a task, same story as above with cgroups.
+ */
+ if (!(a->attach_state & PERF_ATTACH_TASK) ||
+ !(b->attach_state & PERF_ATTACH_TASK))
+ return true;
+
+ /*
+ * Must be non-overlapping.
+ */
+ return false;
+}
+
+struct rmid_read {
+ u32 rmid;
+ atomic64_t value;
+};
+
+static void __intel_cqm_event_count(void *info);
+
+/*
+ * Exchange the RMID of a group of events.
+ */
+static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
+{
+ struct perf_event *event;
+ struct list_head *head = &group->hw.cqm_group_entry;
+ u32 old_rmid = group->hw.cqm_rmid;
+
+ lockdep_assert_held(&cache_mutex);
+
+ /*
+ * If our RMID is being deallocated, perform a read now.
+ */
+ if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) {
+ struct rmid_read rr = {
+ .value = ATOMIC64_INIT(0),
+ .rmid = old_rmid,
+ };
+
+ on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
+ &rr, 1);
+ local64_set(&group->count, atomic64_read(&rr.value));
+ }
+
+ raw_spin_lock_irq(&cache_lock);
+
+ group->hw.cqm_rmid = rmid;
+ list_for_each_entry(event, head, hw.cqm_group_entry)
+ event->hw.cqm_rmid = rmid;
+
+ raw_spin_unlock_irq(&cache_lock);
+
+ return old_rmid;
+}
+
+/*
+ * If we fail to assign a new RMID for intel_cqm_rotation_rmid because
+ * cachelines are still tagged with RMIDs in limbo, we progressively
+ * increment the threshold until we find an RMID in limbo with <=
+ * __intel_cqm_threshold lines tagged. This is designed to mitigate the
+ * problem where cachelines tagged with an RMID are not steadily being
+ * evicted.
+ *
+ * On successful rotations we decrease the threshold back towards zero.
+ *
+ * __intel_cqm_max_threshold provides an upper bound on the threshold,
+ * and is measured in bytes because it's exposed to userland.
+ */
+static unsigned int __intel_cqm_threshold;
+static unsigned int __intel_cqm_max_threshold;
+
+/*
+ * Test whether an RMID has a zero occupancy value on this cpu.
+ */
+static void intel_cqm_stable(void *arg)
+{
+ struct cqm_rmid_entry *entry;
+
+ list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
+ if (entry->state != RMID_AVAILABLE)
+ break;
+
+ if (__rmid_read(entry->rmid) > __intel_cqm_threshold)
+ entry->state = RMID_DIRTY;
+ }
+}
+
+/*
+ * If we have group events waiting for an RMID that don't conflict with
+ * events already running, assign @rmid.
+ */
+static bool intel_cqm_sched_in_event(u32 rmid)
+{
+ struct perf_event *leader, *event;
+
+ lockdep_assert_held(&cache_mutex);
+
+ leader = list_first_entry(&cache_groups, struct perf_event,
+ hw.cqm_groups_entry);
+ event = leader;
+
+ list_for_each_entry_continue(event, &cache_groups,
+ hw.cqm_groups_entry) {
+ if (__rmid_valid(event->hw.cqm_rmid))
+ continue;
+
+ if (__conflict_event(event, leader))
+ continue;
+
+ intel_cqm_xchg_rmid(event, rmid);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Initially use this constant for both the limbo queue time and the
+ * rotation timer interval, pmu::hrtimer_interval_ms.
+ *
+ * They don't need to be the same, but the two are related since if you
+ * rotate faster than you recycle RMIDs, you may run out of available
+ * RMIDs.
+ */
+#define RMID_DEFAULT_QUEUE_TIME 250 /* ms */
+
+static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME;
+
+/*
+ * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list
+ * @nr_available: number of freeable RMIDs on the limbo list
+ *
+ * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no
+ * cachelines are tagged with those RMIDs. After this we can reuse them
+ * and know that the current set of active RMIDs is stable.
+ *
+ * Return %true or %false depending on whether stabilization needs to be
+ * reattempted.
+ *
+ * If we return %true then @nr_available is updated to indicate the
+ * number of RMIDs on the limbo list that have been queued for the
+ * minimum queue time (RMID_AVAILABLE), but whose data occupancy values
+ * are above __intel_cqm_threshold.
+ */
+static bool intel_cqm_rmid_stabilize(unsigned int *available)
+{
+ struct cqm_rmid_entry *entry, *tmp;
+
+ lockdep_assert_held(&cache_mutex);
+
+ *available = 0;
+ list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
+ unsigned long min_queue_time;
+ unsigned long now = jiffies;
+
+ /*
+ * We hold RMIDs placed into limbo for a minimum queue
+ * time. Before the minimum queue time has elapsed we do
+ * not recycle RMIDs.
+ *
+ * The reasoning is that until a sufficient time has
+ * passed since we stopped using an RMID, any RMID
+ * placed onto the limbo list will likely still have
+ * data tagged in the cache, which means we'll probably
+ * fail to recycle it anyway.
+ *
+ * We can save ourselves an expensive IPI by skipping
+ * any RMIDs that have not been queued for the minimum
+ * time.
+ */
+ min_queue_time = entry->queue_time +
+ msecs_to_jiffies(__rmid_queue_time_ms);
+
+ if (time_after(min_queue_time, now))
+ break;
+
+ entry->state = RMID_AVAILABLE;
+ (*available)++;
+ }
+
+ /*
+ * Fast return if none of the RMIDs on the limbo list have been
+ * sitting on the queue for the minimum queue time.
+ */
+ if (!*available)
+ return false;
+
+ /*
+ * Test whether an RMID is free for each package.
+ */
+ on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true);
+
+ list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) {
+ /*
+ * Exhausted all RMIDs that have waited min queue time.
+ */
+ if (entry->state == RMID_YOUNG)
+ break;
+
+ if (entry->state == RMID_DIRTY)
+ continue;
+
+ list_del(&entry->list); /* remove from limbo */
+
+ /*
+ * The rotation RMID gets priority if it's
+ * currently invalid. In which case, skip adding
+ * the RMID to the the free lru.
+ */
+ if (!__rmid_valid(intel_cqm_rotation_rmid)) {
+ intel_cqm_rotation_rmid = entry->rmid;
+ continue;
+ }
+
+ /*
+ * If we have groups waiting for RMIDs, hand
+ * them one now provided they don't conflict.
+ */
+ if (intel_cqm_sched_in_event(entry->rmid))
+ continue;
+
+ /*
+ * Otherwise place it onto the free list.
+ */
+ list_add_tail(&entry->list, &cqm_rmid_free_lru);
+ }
+
+
+ return __rmid_valid(intel_cqm_rotation_rmid);
+}
+
+/*
+ * Pick a victim group and move it to the tail of the group list.
+ * @next: The first group without an RMID
+ */
+static void __intel_cqm_pick_and_rotate(struct perf_event *next)
+{
+ struct perf_event *rotor;
+ u32 rmid;
+
+ lockdep_assert_held(&cache_mutex);
+
+ rotor = list_first_entry(&cache_groups, struct perf_event,
+ hw.cqm_groups_entry);
+
+ /*
+ * The group at the front of the list should always have a valid
+ * RMID. If it doesn't then no groups have RMIDs assigned and we
+ * don't need to rotate the list.
+ */
+ if (next == rotor)
+ return;
+
+ rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID);
+ __put_rmid(rmid);
+
+ list_rotate_left(&cache_groups);
+}
+
+/*
+ * Deallocate the RMIDs from any events that conflict with @event, and
+ * place them on the back of the group list.
+ */
+static void intel_cqm_sched_out_conflicting_events(struct perf_event *event)
+{
+ struct perf_event *group, *g;
+ u32 rmid;
+
+ lockdep_assert_held(&cache_mutex);
+
+ list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) {
+ if (group == event)
+ continue;
+
+ rmid = group->hw.cqm_rmid;
+
+ /*
+ * Skip events that don't have a valid RMID.
+ */
+ if (!__rmid_valid(rmid))
+ continue;
+
+ /*
+ * No conflict? No problem! Leave the event alone.
+ */
+ if (!__conflict_event(group, event))
+ continue;
+
+ intel_cqm_xchg_rmid(group, INVALID_RMID);
+ __put_rmid(rmid);
+ }
+}
+
+/*
+ * Attempt to rotate the groups and assign new RMIDs.
+ *
+ * We rotate for two reasons,
+ * 1. To handle the scheduling of conflicting events
+ * 2. To recycle RMIDs
+ *
+ * Rotating RMIDs is complicated because the hardware doesn't give us
+ * any clues.
+ *
+ * There's problems with the hardware interface; when you change the
+ * task:RMID map cachelines retain their 'old' tags, giving a skewed
+ * picture. In order to work around this, we must always keep one free
+ * RMID - intel_cqm_rotation_rmid.
+ *
+ * Rotation works by taking away an RMID from a group (the old RMID),
+ * and assigning the free RMID to another group (the new RMID). We must
+ * then wait for the old RMID to not be used (no cachelines tagged).
+ * This ensure that all cachelines are tagged with 'active' RMIDs. At
+ * this point we can start reading values for the new RMID and treat the
+ * old RMID as the free RMID for the next rotation.
+ *
+ * Return %true or %false depending on whether we did any rotating.
+ */
+static bool __intel_cqm_rmid_rotate(void)
+{
+ struct perf_event *group, *start = NULL;
+ unsigned int threshold_limit;
+ unsigned int nr_needed = 0;
+ unsigned int nr_available;
+ bool rotated = false;
+
+ mutex_lock(&cache_mutex);
+
+again:
+ /*
+ * Fast path through this function if there are no groups and no
+ * RMIDs that need cleaning.
+ */
+ if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru))
+ goto out;
+
+ list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) {
+ if (!__rmid_valid(group->hw.cqm_rmid)) {
+ if (!start)
+ start = group;
+ nr_needed++;
+ }
+ }
+
+ /*
+ * We have some event groups, but they all have RMIDs assigned
+ * and no RMIDs need cleaning.
+ */
+ if (!nr_needed && list_empty(&cqm_rmid_limbo_lru))
+ goto out;
+
+ if (!nr_needed)
+ goto stabilize;
+
+ /*
+ * We have more event groups without RMIDs than available RMIDs,
+ * or we have event groups that conflict with the ones currently
+ * scheduled.
+ *
+ * We force deallocate the rmid of the group at the head of
+ * cache_groups. The first event group without an RMID then gets
+ * assigned intel_cqm_rotation_rmid. This ensures we always make
+ * forward progress.
+ *
+ * Rotate the cache_groups list so the previous head is now the
+ * tail.
+ */
+ __intel_cqm_pick_and_rotate(start);
+
+ /*
+ * If the rotation is going to succeed, reduce the threshold so
+ * that we don't needlessly reuse dirty RMIDs.
+ */
+ if (__rmid_valid(intel_cqm_rotation_rmid)) {
+ intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid);
+ intel_cqm_rotation_rmid = __get_rmid();
+
+ intel_cqm_sched_out_conflicting_events(start);
+
+ if (__intel_cqm_threshold)
+ __intel_cqm_threshold--;
+ }
+
+ rotated = true;
+
+stabilize:
+ /*
+ * We now need to stablize the RMID we freed above (if any) to
+ * ensure that the next time we rotate we have an RMID with zero
+ * occupancy value.
+ *
+ * Alternatively, if we didn't need to perform any rotation,
+ * we'll have a bunch of RMIDs in limbo that need stabilizing.
+ */
+ threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale;
+
+ while (intel_cqm_rmid_stabilize(&nr_available) &&
+ __intel_cqm_threshold < threshold_limit) {
+ unsigned int steal_limit;
+
+ /*
+ * Don't spin if nobody is actively waiting for an RMID,
+ * the rotation worker will be kicked as soon as an
+ * event needs an RMID anyway.
+ */
+ if (!nr_needed)
+ break;
+
+ /* Allow max 25% of RMIDs to be in limbo. */
+ steal_limit = (cqm_max_rmid + 1) / 4;
+
+ /*
+ * We failed to stabilize any RMIDs so our rotation
+ * logic is now stuck. In order to make forward progress
+ * we have a few options:
+ *
+ * 1. rotate ("steal") another RMID
+ * 2. increase the threshold
+ * 3. do nothing
+ *
+ * We do both of 1. and 2. until we hit the steal limit.
+ *
+ * The steal limit prevents all RMIDs ending up on the
+ * limbo list. This can happen if every RMID has a
+ * non-zero occupancy above threshold_limit, and the
+ * occupancy values aren't dropping fast enough.
+ *
+ * Note that there is prioritisation at work here - we'd
+ * rather increase the number of RMIDs on the limbo list
+ * than increase the threshold, because increasing the
+ * threshold skews the event data (because we reuse
+ * dirty RMIDs) - threshold bumps are a last resort.
+ */
+ if (nr_available < steal_limit)
+ goto again;
+
+ __intel_cqm_threshold++;
+ }
+
+out:
+ mutex_unlock(&cache_mutex);
+ return rotated;
+}
+
+static void intel_cqm_rmid_rotate(struct work_struct *work);
+
+static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate);
+
+static struct pmu intel_cqm_pmu;
+
+static void intel_cqm_rmid_rotate(struct work_struct *work)
+{
+ unsigned long delay;
+
+ __intel_cqm_rmid_rotate();
+
+ delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms);
+ schedule_delayed_work(&intel_cqm_rmid_work, delay);
+}
+
+/*
+ * Find a group and setup RMID.
+ *
+ * If we're part of a group, we use the group's RMID.
+ */
+static void intel_cqm_setup_event(struct perf_event *event,
+ struct perf_event **group)
+{
+ struct perf_event *iter;
+ bool conflict = false;
+ u32 rmid;
+
+ list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
+ rmid = iter->hw.cqm_rmid;
+
+ if (__match_event(iter, event)) {
+ /* All tasks in a group share an RMID */
+ event->hw.cqm_rmid = rmid;
+ *group = iter;
+ return;
+ }
+
+ /*
+ * We only care about conflicts for events that are
+ * actually scheduled in (and hence have a valid RMID).
+ */
+ if (__conflict_event(iter, event) && __rmid_valid(rmid))
+ conflict = true;
+ }
+
+ if (conflict)
+ rmid = INVALID_RMID;
+ else
+ rmid = __get_rmid();
+
+ event->hw.cqm_rmid = rmid;
+}
+
+static void intel_cqm_event_read(struct perf_event *event)
+{
+ unsigned long flags;
+ u32 rmid;
+ u64 val;
+
+ /*
+ * Task events are handled by intel_cqm_event_count().
+ */
+ if (event->cpu == -1)
+ return;
+
+ raw_spin_lock_irqsave(&cache_lock, flags);
+ rmid = event->hw.cqm_rmid;
+
+ if (!__rmid_valid(rmid))
+ goto out;
+
+ val = __rmid_read(rmid);
+
+ /*
+ * Ignore this reading on error states and do not update the value.
+ */
+ if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+ goto out;
+
+ local64_set(&event->count, val);
+out:
+ raw_spin_unlock_irqrestore(&cache_lock, flags);
+}
+
+static void __intel_cqm_event_count(void *info)
+{
+ struct rmid_read *rr = info;
+ u64 val;
+
+ val = __rmid_read(rr->rmid);
+
+ if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
+ return;
+
+ atomic64_add(val, &rr->value);
+}
+
+static inline bool cqm_group_leader(struct perf_event *event)
+{
+ return !list_empty(&event->hw.cqm_groups_entry);
+}
+
+static u64 intel_cqm_event_count(struct perf_event *event)
+{
+ unsigned long flags;
+ struct rmid_read rr = {
+ .value = ATOMIC64_INIT(0),
+ };
+
+ /*
+ * We only need to worry about task events. System-wide events
+ * are handled like usual, i.e. entirely with
+ * intel_cqm_event_read().
+ */
+ if (event->cpu != -1)
+ return __perf_event_count(event);
+
+ /*
+ * Only the group leader gets to report values. This stops us
+ * reporting duplicate values to userspace, and gives us a clear
+ * rule for which task gets to report the values.
+ *
+ * Note that it is impossible to attribute these values to
+ * specific packages - we forfeit that ability when we create
+ * task events.
+ */
+ if (!cqm_group_leader(event))
+ return 0;
+
+ /*
+ * Getting up-to-date values requires an SMP IPI which is not
+ * possible if we're being called in interrupt context. Return
+ * the cached values instead.
+ */
+ if (unlikely(in_interrupt()))
+ goto out;
+
+ /*
+ * Notice that we don't perform the reading of an RMID
+ * atomically, because we can't hold a spin lock across the
+ * IPIs.
+ *
+ * Speculatively perform the read, since @event might be
+ * assigned a different (possibly invalid) RMID while we're
+ * busying performing the IPI calls. It's therefore necessary to
+ * check @event's RMID afterwards, and if it has changed,
+ * discard the result of the read.
+ */
+ rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid);
+
+ if (!__rmid_valid(rr.rmid))
+ goto out;
+
+ on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1);
+
+ raw_spin_lock_irqsave(&cache_lock, flags);
+ if (event->hw.cqm_rmid == rr.rmid)
+ local64_set(&event->count, atomic64_read(&rr.value));
+ raw_spin_unlock_irqrestore(&cache_lock, flags);
+out:
+ return __perf_event_count(event);
+}
+
+static void intel_cqm_event_start(struct perf_event *event, int mode)
+{
+ struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+ u32 rmid = event->hw.cqm_rmid;
+
+ if (!(event->hw.cqm_state & PERF_HES_STOPPED))
+ return;
+
+ event->hw.cqm_state &= ~PERF_HES_STOPPED;
+
+ if (state->rmid_usecnt++) {
+ if (!WARN_ON_ONCE(state->rmid != rmid))
+ return;
+ } else {
+ WARN_ON_ONCE(state->rmid);
+ }
+
+ state->rmid = rmid;
+ wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid);
+}
+
+static void intel_cqm_event_stop(struct perf_event *event, int mode)
+{
+ struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
+
+ if (event->hw.cqm_state & PERF_HES_STOPPED)
+ return;
+
+ event->hw.cqm_state |= PERF_HES_STOPPED;
+
+ intel_cqm_event_read(event);
+
+ if (!--state->rmid_usecnt) {
+ state->rmid = 0;
+ wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid);
+ } else {
+ WARN_ON_ONCE(!state->rmid);
+ }
+}
+
+static int intel_cqm_event_add(struct perf_event *event, int mode)
+{
+ unsigned long flags;
+ u32 rmid;
+
+ raw_spin_lock_irqsave(&cache_lock, flags);
+
+ event->hw.cqm_state = PERF_HES_STOPPED;
+ rmid = event->hw.cqm_rmid;
+
+ if (__rmid_valid(rmid) && (mode & PERF_EF_START))
+ intel_cqm_event_start(event, mode);
+
+ raw_spin_unlock_irqrestore(&cache_lock, flags);
+
+ return 0;
+}
+
+static void intel_cqm_event_destroy(struct perf_event *event)
+{
+ struct perf_event *group_other = NULL;
+
+ mutex_lock(&cache_mutex);
+
+ /*
+ * If there's another event in this group...
+ */
+ if (!list_empty(&event->hw.cqm_group_entry)) {
+ group_other = list_first_entry(&event->hw.cqm_group_entry,
+ struct perf_event,
+ hw.cqm_group_entry);
+ list_del(&event->hw.cqm_group_entry);
+ }
+
+ /*
+ * And we're the group leader..
+ */
+ if (cqm_group_leader(event)) {
+ /*
+ * If there was a group_other, make that leader, otherwise
+ * destroy the group and return the RMID.
+ */
+ if (group_other) {
+ list_replace(&event->hw.cqm_groups_entry,
+ &group_other->hw.cqm_groups_entry);
+ } else {
+ u32 rmid = event->hw.cqm_rmid;
+
+ if (__rmid_valid(rmid))
+ __put_rmid(rmid);
+ list_del(&event->hw.cqm_groups_entry);
+ }
+ }
+
+ mutex_unlock(&cache_mutex);
+}
+
+static int intel_cqm_event_init(struct perf_event *event)
+{
+ struct perf_event *group = NULL;
+ bool rotate = false;
+
+ if (event->attr.type != intel_cqm_pmu.type)
+ return -ENOENT;
+
+ if (event->attr.config & ~QOS_EVENT_MASK)
+ return -EINVAL;
+
+ /* unsupported modes and filters */
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period) /* no sampling */
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&event->hw.cqm_group_entry);
+ INIT_LIST_HEAD(&event->hw.cqm_groups_entry);
+
+ event->destroy = intel_cqm_event_destroy;
+
+ mutex_lock(&cache_mutex);
+
+ /* Will also set rmid */
+ intel_cqm_setup_event(event, &group);
+
+ if (group) {
+ list_add_tail(&event->hw.cqm_group_entry,
+ &group->hw.cqm_group_entry);
+ } else {
+ list_add_tail(&event->hw.cqm_groups_entry,
+ &cache_groups);
+
+ /*
+ * All RMIDs are either in use or have recently been
+ * used. Kick the rotation worker to clean/free some.
+ *
+ * We only do this for the group leader, rather than for
+ * every event in a group to save on needless work.
+ */
+ if (!__rmid_valid(event->hw.cqm_rmid))
+ rotate = true;
+ }
+
+ mutex_unlock(&cache_mutex);
+
+ if (rotate)
+ schedule_delayed_work(&intel_cqm_rmid_work, 0);
+
+ return 0;
+}
+
+EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01");
+EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1");
+EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes");
+EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL);
+EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1");
+
+static struct attribute *intel_cqm_events_attr[] = {
+ EVENT_PTR(intel_cqm_llc),
+ EVENT_PTR(intel_cqm_llc_pkg),
+ EVENT_PTR(intel_cqm_llc_unit),
+ EVENT_PTR(intel_cqm_llc_scale),
+ EVENT_PTR(intel_cqm_llc_snapshot),
+ NULL,
+};
+
+static struct attribute_group intel_cqm_events_group = {
+ .name = "events",
+ .attrs = intel_cqm_events_attr,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7");
+static struct attribute *intel_cqm_formats_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group intel_cqm_format_group = {
+ .name = "format",
+ .attrs = intel_cqm_formats_attr,
+};
+
+static ssize_t
+max_recycle_threshold_show(struct device *dev, struct device_attribute *attr,
+ char *page)
+{
+ ssize_t rv;
+
+ mutex_lock(&cache_mutex);
+ rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold);
+ mutex_unlock(&cache_mutex);
+
+ return rv;
+}
+
+static ssize_t
+max_recycle_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned int bytes, cachelines;
+ int ret;
+
+ ret = kstrtouint(buf, 0, &bytes);
+ if (ret)
+ return ret;
+
+ mutex_lock(&cache_mutex);
+
+ __intel_cqm_max_threshold = bytes;
+ cachelines = bytes / cqm_l3_scale;
+
+ /*
+ * The new maximum takes effect immediately.
+ */
+ if (__intel_cqm_threshold > cachelines)
+ __intel_cqm_threshold = cachelines;
+
+ mutex_unlock(&cache_mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(max_recycle_threshold);
+
+static struct attribute *intel_cqm_attrs[] = {
+ &dev_attr_max_recycle_threshold.attr,
+ NULL,
+};
+
+static const struct attribute_group intel_cqm_group = {
+ .attrs = intel_cqm_attrs,
+};
+
+static const struct attribute_group *intel_cqm_attr_groups[] = {
+ &intel_cqm_events_group,
+ &intel_cqm_format_group,
+ &intel_cqm_group,
+ NULL,
+};
+
+static struct pmu intel_cqm_pmu = {
+ .hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME,
+ .attr_groups = intel_cqm_attr_groups,
+ .task_ctx_nr = perf_sw_context,
+ .event_init = intel_cqm_event_init,
+ .add = intel_cqm_event_add,
+ .del = intel_cqm_event_stop,
+ .start = intel_cqm_event_start,
+ .stop = intel_cqm_event_stop,
+ .read = intel_cqm_event_read,
+ .count = intel_cqm_event_count,
+};
+
+static inline void cqm_pick_event_reader(int cpu)
+{
+ int reader;
+
+ /* First online cpu in package becomes the reader */
+ reader = cpumask_any_and(&cqm_cpumask, topology_core_cpumask(cpu));
+ if (reader >= nr_cpu_ids)
+ cpumask_set_cpu(cpu, &cqm_cpumask);
+}
+
+static void intel_cqm_cpu_starting(unsigned int cpu)
+{
+ struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+ state->rmid = 0;
+ state->closid = 0;
+ state->rmid_usecnt = 0;
+
+ WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
+ WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
+}
+
+static void intel_cqm_cpu_exit(unsigned int cpu)
+{
+ int target;
+
+ /* Is @cpu the current cqm reader for this package ? */
+ if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
+ return;
+
+ /* Find another online reader in this package */
+ target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+
+ if (target < nr_cpu_ids)
+ cpumask_set_cpu(target, &cqm_cpumask);
+}
+
+static int intel_cqm_cpu_notifier(struct notifier_block *nb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_DOWN_PREPARE:
+ intel_cqm_cpu_exit(cpu);
+ break;
+ case CPU_STARTING:
+ intel_cqm_cpu_starting(cpu);
+ cqm_pick_event_reader(cpu);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static const struct x86_cpu_id intel_cqm_match[] = {
+ { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC },
+ {}
+};
+
+static int __init intel_cqm_init(void)
+{
+ char *str, scale[20];
+ int i, cpu, ret;
+
+ if (!x86_match_cpu(intel_cqm_match))
+ return -ENODEV;
+
+ cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale;
+
+ /*
+ * It's possible that not all resources support the same number
+ * of RMIDs. Instead of making scheduling much more complicated
+ * (where we have to match a task's RMID to a cpu that supports
+ * that many RMIDs) just find the minimum RMIDs supported across
+ * all cpus.
+ *
+ * Also, check that the scales match on all cpus.
+ */
+ cpu_notifier_register_begin();
+
+ for_each_online_cpu(cpu) {
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+ if (c->x86_cache_max_rmid < cqm_max_rmid)
+ cqm_max_rmid = c->x86_cache_max_rmid;
+
+ if (c->x86_cache_occ_scale != cqm_l3_scale) {
+ pr_err("Multiple LLC scale values, disabling\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ /*
+ * A reasonable upper limit on the max threshold is the number
+ * of lines tagged per RMID if all RMIDs have the same number of
+ * lines tagged in the LLC.
+ *
+ * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC.
+ */
+ __intel_cqm_max_threshold =
+ boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1);
+
+ snprintf(scale, sizeof(scale), "%u", cqm_l3_scale);
+ str = kstrdup(scale, GFP_KERNEL);
+ if (!str) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ event_attr_intel_cqm_llc_scale.event_str = str;
+
+ ret = intel_cqm_setup_rmid_cache();
+ if (ret)
+ goto out;
+
+ for_each_online_cpu(i) {
+ intel_cqm_cpu_starting(i);
+ cqm_pick_event_reader(i);
+ }
+
+ __perf_cpu_notifier(intel_cqm_cpu_notifier);
+
+ ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
+ if (ret)
+ pr_err("Intel CQM perf registration failed: %d\n", ret);
+ else
+ pr_info("Intel CQM monitoring enabled\n");
+
+out:
+ cpu_notifier_register_done();
+
+ return ret;
+}
+device_initcall(intel_cqm_init);
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
new file mode 100644
index 0000000..7946c42
--- /dev/null
+++ b/arch/x86/events/intel/cstate.c
@@ -0,0 +1,694 @@
+/*
+ * perf_event_intel_cstate.c: support cstate residency counters
+ *
+ * Copyright (C) 2015, Intel Corp.
+ * Author: Kan Liang (kan.liang@intel.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ */
+
+/*
+ * This file export cstate related free running (read-only) counters
+ * for perf. These counters may be use simultaneously by other tools,
+ * such as turbostat. However, it still make sense to implement them
+ * in perf. Because we can conveniently collect them together with
+ * other events, and allow to use them from tools without special MSR
+ * access code.
+ *
+ * The events only support system-wide mode counting. There is no
+ * sampling support because it is not supported by the hardware.
+ *
+ * According to counters' scope and category, two PMUs are registered
+ * with the perf_event core subsystem.
+ * - 'cstate_core': The counter is available for each physical core.
+ * The counters include CORE_C*_RESIDENCY.
+ * - 'cstate_pkg': The counter is available for each physical package.
+ * The counters include PKG_C*_RESIDENCY.
+ *
+ * All of these counters are specified in the Intel® 64 and IA-32
+ * Architectures Software Developer.s Manual Vol3b.
+ *
+ * Model specific counters:
+ * MSR_CORE_C1_RES: CORE C1 Residency Counter
+ * perf code: 0x00
+ * Available model: SLM,AMT
+ * Scope: Core (each processor core has a MSR)
+ * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
+ * perf code: 0x01
+ * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Scope: Core
+ * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
+ * perf code: 0x02
+ * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Scope: Core
+ * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
+ * perf code: 0x03
+ * Available model: SNB,IVB,HSW,BDW,SKL
+ * Scope: Core
+ * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter.
+ * perf code: 0x00
+ * Available model: SNB,IVB,HSW,BDW,SKL
+ * Scope: Package (physical package)
+ * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter.
+ * perf code: 0x01
+ * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Scope: Package (physical package)
+ * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter.
+ * perf code: 0x02
+ * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Scope: Package (physical package)
+ * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
+ * perf code: 0x03
+ * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Scope: Package (physical package)
+ * MSR_PKG_C8_RESIDENCY: Package C8 Residency Counter.
+ * perf code: 0x04
+ * Available model: HSW ULT only
+ * Scope: Package (physical package)
+ * MSR_PKG_C9_RESIDENCY: Package C9 Residency Counter.
+ * perf code: 0x05
+ * Available model: HSW ULT only
+ * Scope: Package (physical package)
+ * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
+ * perf code: 0x06
+ * Available model: HSW ULT only
+ * Scope: Package (physical package)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
+static ssize_t __cstate_##_var##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ char *page) \
+{ \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+} \
+static struct kobj_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __cstate_##_var##_show, NULL)
+
+static ssize_t cstate_get_attr_cpumask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+struct perf_cstate_msr {
+ u64 msr;
+ struct perf_pmu_events_attr *attr;
+ bool (*test)(int idx);
+};
+
+
+/* cstate_core PMU */
+
+static struct pmu cstate_core_pmu;
+static bool has_cstate_core;
+
+enum perf_cstate_core_id {
+ /*
+ * cstate_core events
+ */
+ PERF_CSTATE_CORE_C1_RES = 0,
+ PERF_CSTATE_CORE_C3_RES,
+ PERF_CSTATE_CORE_C6_RES,
+ PERF_CSTATE_CORE_C7_RES,
+
+ PERF_CSTATE_CORE_EVENT_MAX,
+};
+
+bool test_core(int idx)
+{
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+ boot_cpu_data.x86 != 6)
+ return false;
+
+ switch (boot_cpu_data.x86_model) {
+ case 30: /* 45nm Nehalem */
+ case 26: /* 45nm Nehalem-EP */
+ case 46: /* 45nm Nehalem-EX */
+
+ case 37: /* 32nm Westmere */
+ case 44: /* 32nm Westmere-EP */
+ case 47: /* 32nm Westmere-EX */
+ if (idx == PERF_CSTATE_CORE_C3_RES ||
+ idx == PERF_CSTATE_CORE_C6_RES)
+ return true;
+ break;
+ case 42: /* 32nm SandyBridge */
+ case 45: /* 32nm SandyBridge-E/EN/EP */
+
+ case 58: /* 22nm IvyBridge */
+ case 62: /* 22nm IvyBridge-EP/EX */
+
+ case 60: /* 22nm Haswell Core */
+ case 63: /* 22nm Haswell Server */
+ case 69: /* 22nm Haswell ULT */
+ case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+ case 61: /* 14nm Broadwell Core-M */
+ case 86: /* 14nm Broadwell Xeon D */
+ case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+ case 79: /* 14nm Broadwell Server */
+
+ case 78: /* 14nm Skylake Mobile */
+ case 94: /* 14nm Skylake Desktop */
+ if (idx == PERF_CSTATE_CORE_C3_RES ||
+ idx == PERF_CSTATE_CORE_C6_RES ||
+ idx == PERF_CSTATE_CORE_C7_RES)
+ return true;
+ break;
+ case 55: /* 22nm Atom "Silvermont" */
+ case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+ case 76: /* 14nm Atom "Airmont" */
+ if (idx == PERF_CSTATE_CORE_C1_RES ||
+ idx == PERF_CSTATE_CORE_C6_RES)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+PMU_EVENT_ATTR_STRING(c1-residency, evattr_cstate_core_c1, "event=0x00");
+PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_core_c3, "event=0x01");
+PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_core_c6, "event=0x02");
+PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_core_c7, "event=0x03");
+
+static struct perf_cstate_msr core_msr[] = {
+ [PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES, &evattr_cstate_core_c1, test_core, },
+ [PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY, &evattr_cstate_core_c3, test_core, },
+ [PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY, &evattr_cstate_core_c6, test_core, },
+ [PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY, &evattr_cstate_core_c7, test_core, },
+};
+
+static struct attribute *core_events_attrs[PERF_CSTATE_CORE_EVENT_MAX + 1] = {
+ NULL,
+};
+
+static struct attribute_group core_events_attr_group = {
+ .name = "events",
+ .attrs = core_events_attrs,
+};
+
+DEFINE_CSTATE_FORMAT_ATTR(core_event, event, "config:0-63");
+static struct attribute *core_format_attrs[] = {
+ &format_attr_core_event.attr,
+ NULL,
+};
+
+static struct attribute_group core_format_attr_group = {
+ .name = "format",
+ .attrs = core_format_attrs,
+};
+
+static cpumask_t cstate_core_cpu_mask;
+static DEVICE_ATTR(cpumask, S_IRUGO, cstate_get_attr_cpumask, NULL);
+
+static struct attribute *cstate_cpumask_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group cpumask_attr_group = {
+ .attrs = cstate_cpumask_attrs,
+};
+
+static const struct attribute_group *core_attr_groups[] = {
+ &core_events_attr_group,
+ &core_format_attr_group,
+ &cpumask_attr_group,
+ NULL,
+};
+
+/* cstate_core PMU end */
+
+
+/* cstate_pkg PMU */
+
+static struct pmu cstate_pkg_pmu;
+static bool has_cstate_pkg;
+
+enum perf_cstate_pkg_id {
+ /*
+ * cstate_pkg events
+ */
+ PERF_CSTATE_PKG_C2_RES = 0,
+ PERF_CSTATE_PKG_C3_RES,
+ PERF_CSTATE_PKG_C6_RES,
+ PERF_CSTATE_PKG_C7_RES,
+ PERF_CSTATE_PKG_C8_RES,
+ PERF_CSTATE_PKG_C9_RES,
+ PERF_CSTATE_PKG_C10_RES,
+
+ PERF_CSTATE_PKG_EVENT_MAX,
+};
+
+bool test_pkg(int idx)
+{
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+ boot_cpu_data.x86 != 6)
+ return false;
+
+ switch (boot_cpu_data.x86_model) {
+ case 30: /* 45nm Nehalem */
+ case 26: /* 45nm Nehalem-EP */
+ case 46: /* 45nm Nehalem-EX */
+
+ case 37: /* 32nm Westmere */
+ case 44: /* 32nm Westmere-EP */
+ case 47: /* 32nm Westmere-EX */
+ if (idx == PERF_CSTATE_CORE_C3_RES ||
+ idx == PERF_CSTATE_CORE_C6_RES ||
+ idx == PERF_CSTATE_CORE_C7_RES)
+ return true;
+ break;
+ case 42: /* 32nm SandyBridge */
+ case 45: /* 32nm SandyBridge-E/EN/EP */
+
+ case 58: /* 22nm IvyBridge */
+ case 62: /* 22nm IvyBridge-EP/EX */
+
+ case 60: /* 22nm Haswell Core */
+ case 63: /* 22nm Haswell Server */
+ case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+ case 61: /* 14nm Broadwell Core-M */
+ case 86: /* 14nm Broadwell Xeon D */
+ case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+ case 79: /* 14nm Broadwell Server */
+
+ case 78: /* 14nm Skylake Mobile */
+ case 94: /* 14nm Skylake Desktop */
+ if (idx == PERF_CSTATE_PKG_C2_RES ||
+ idx == PERF_CSTATE_PKG_C3_RES ||
+ idx == PERF_CSTATE_PKG_C6_RES ||
+ idx == PERF_CSTATE_PKG_C7_RES)
+ return true;
+ break;
+ case 55: /* 22nm Atom "Silvermont" */
+ case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+ case 76: /* 14nm Atom "Airmont" */
+ if (idx == PERF_CSTATE_CORE_C6_RES)
+ return true;
+ break;
+ case 69: /* 22nm Haswell ULT */
+ if (idx == PERF_CSTATE_PKG_C2_RES ||
+ idx == PERF_CSTATE_PKG_C3_RES ||
+ idx == PERF_CSTATE_PKG_C6_RES ||
+ idx == PERF_CSTATE_PKG_C7_RES ||
+ idx == PERF_CSTATE_PKG_C8_RES ||
+ idx == PERF_CSTATE_PKG_C9_RES ||
+ idx == PERF_CSTATE_PKG_C10_RES)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+PMU_EVENT_ATTR_STRING(c2-residency, evattr_cstate_pkg_c2, "event=0x00");
+PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_pkg_c3, "event=0x01");
+PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_pkg_c6, "event=0x02");
+PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_pkg_c7, "event=0x03");
+PMU_EVENT_ATTR_STRING(c8-residency, evattr_cstate_pkg_c8, "event=0x04");
+PMU_EVENT_ATTR_STRING(c9-residency, evattr_cstate_pkg_c9, "event=0x05");
+PMU_EVENT_ATTR_STRING(c10-residency, evattr_cstate_pkg_c10, "event=0x06");
+
+static struct perf_cstate_msr pkg_msr[] = {
+ [PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY, &evattr_cstate_pkg_c2, test_pkg, },
+ [PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY, &evattr_cstate_pkg_c3, test_pkg, },
+ [PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY, &evattr_cstate_pkg_c6, test_pkg, },
+ [PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY, &evattr_cstate_pkg_c7, test_pkg, },
+ [PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY, &evattr_cstate_pkg_c8, test_pkg, },
+ [PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY, &evattr_cstate_pkg_c9, test_pkg, },
+ [PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY, &evattr_cstate_pkg_c10, test_pkg, },
+};
+
+static struct attribute *pkg_events_attrs[PERF_CSTATE_PKG_EVENT_MAX + 1] = {
+ NULL,
+};
+
+static struct attribute_group pkg_events_attr_group = {
+ .name = "events",
+ .attrs = pkg_events_attrs,
+};
+
+DEFINE_CSTATE_FORMAT_ATTR(pkg_event, event, "config:0-63");
+static struct attribute *pkg_format_attrs[] = {
+ &format_attr_pkg_event.attr,
+ NULL,
+};
+static struct attribute_group pkg_format_attr_group = {
+ .name = "format",
+ .attrs = pkg_format_attrs,
+};
+
+static cpumask_t cstate_pkg_cpu_mask;
+
+static const struct attribute_group *pkg_attr_groups[] = {
+ &pkg_events_attr_group,
+ &pkg_format_attr_group,
+ &cpumask_attr_group,
+ NULL,
+};
+
+/* cstate_pkg PMU end*/
+
+static ssize_t cstate_get_attr_cpumask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct pmu *pmu = dev_get_drvdata(dev);
+
+ if (pmu == &cstate_core_pmu)
+ return cpumap_print_to_pagebuf(true, buf, &cstate_core_cpu_mask);
+ else if (pmu == &cstate_pkg_pmu)
+ return cpumap_print_to_pagebuf(true, buf, &cstate_pkg_cpu_mask);
+ else
+ return 0;
+}
+
+static int cstate_pmu_event_init(struct perf_event *event)
+{
+ u64 cfg = event->attr.config;
+ int ret = 0;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ /* unsupported modes and filters */
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period) /* no sampling */
+ return -EINVAL;
+
+ if (event->pmu == &cstate_core_pmu) {
+ if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
+ return -EINVAL;
+ if (!core_msr[cfg].attr)
+ return -EINVAL;
+ event->hw.event_base = core_msr[cfg].msr;
+ } else if (event->pmu == &cstate_pkg_pmu) {
+ if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
+ return -EINVAL;
+ if (!pkg_msr[cfg].attr)
+ return -EINVAL;
+ event->hw.event_base = pkg_msr[cfg].msr;
+ } else
+ return -ENOENT;
+
+ /* must be done before validate_group */
+ event->hw.config = cfg;
+ event->hw.idx = -1;
+
+ return ret;
+}
+
+static inline u64 cstate_pmu_read_counter(struct perf_event *event)
+{
+ u64 val;
+
+ rdmsrl(event->hw.event_base, val);
+ return val;
+}
+
+static void cstate_pmu_event_update(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 prev_raw_count, new_raw_count;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = cstate_pmu_read_counter(event);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ local64_add(new_raw_count - prev_raw_count, &event->count);
+}
+
+static void cstate_pmu_event_start(struct perf_event *event, int mode)
+{
+ local64_set(&event->hw.prev_count, cstate_pmu_read_counter(event));
+}
+
+static void cstate_pmu_event_stop(struct perf_event *event, int mode)
+{
+ cstate_pmu_event_update(event);
+}
+
+static void cstate_pmu_event_del(struct perf_event *event, int mode)
+{
+ cstate_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int cstate_pmu_event_add(struct perf_event *event, int mode)
+{
+ if (mode & PERF_EF_START)
+ cstate_pmu_event_start(event, mode);
+
+ return 0;
+}
+
+static void cstate_cpu_exit(int cpu)
+{
+ int i, id, target;
+
+ /* cpu exit for cstate core */
+ if (has_cstate_core) {
+ id = topology_core_id(cpu);
+ target = -1;
+
+ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+ if (id == topology_core_id(i)) {
+ target = i;
+ break;
+ }
+ }
+ if (cpumask_test_and_clear_cpu(cpu, &cstate_core_cpu_mask) && target >= 0)
+ cpumask_set_cpu(target, &cstate_core_cpu_mask);
+ WARN_ON(cpumask_empty(&cstate_core_cpu_mask));
+ if (target >= 0)
+ perf_pmu_migrate_context(&cstate_core_pmu, cpu, target);
+ }
+
+ /* cpu exit for cstate pkg */
+ if (has_cstate_pkg) {
+ id = topology_physical_package_id(cpu);
+ target = -1;
+
+ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+ if (id == topology_physical_package_id(i)) {
+ target = i;
+ break;
+ }
+ }
+ if (cpumask_test_and_clear_cpu(cpu, &cstate_pkg_cpu_mask) && target >= 0)
+ cpumask_set_cpu(target, &cstate_pkg_cpu_mask);
+ WARN_ON(cpumask_empty(&cstate_pkg_cpu_mask));
+ if (target >= 0)
+ perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target);
+ }
+}
+
+static void cstate_cpu_init(int cpu)
+{
+ int i, id;
+
+ /* cpu init for cstate core */
+ if (has_cstate_core) {
+ id = topology_core_id(cpu);
+ for_each_cpu(i, &cstate_core_cpu_mask) {
+ if (id == topology_core_id(i))
+ break;
+ }
+ if (i >= nr_cpu_ids)
+ cpumask_set_cpu(cpu, &cstate_core_cpu_mask);
+ }
+
+ /* cpu init for cstate pkg */
+ if (has_cstate_pkg) {
+ id = topology_physical_package_id(cpu);
+ for_each_cpu(i, &cstate_pkg_cpu_mask) {
+ if (id == topology_physical_package_id(i))
+ break;
+ }
+ if (i >= nr_cpu_ids)
+ cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask);
+ }
+}
+
+static int cstate_cpu_notifier(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ break;
+ case CPU_STARTING:
+ cstate_cpu_init(cpu);
+ break;
+ case CPU_UP_CANCELED:
+ case CPU_DYING:
+ break;
+ case CPU_ONLINE:
+ case CPU_DEAD:
+ break;
+ case CPU_DOWN_PREPARE:
+ cstate_cpu_exit(cpu);
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+/*
+ * Probe the cstate events and insert the available one into sysfs attrs
+ * Return false if there is no available events.
+ */
+static bool cstate_probe_msr(struct perf_cstate_msr *msr,
+ struct attribute **events_attrs,
+ int max_event_nr)
+{
+ int i, j = 0;
+ u64 val;
+
+ /* Probe the cstate events. */
+ for (i = 0; i < max_event_nr; i++) {
+ if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
+ msr[i].attr = NULL;
+ }
+
+ /* List remaining events in the sysfs attrs. */
+ for (i = 0; i < max_event_nr; i++) {
+ if (msr[i].attr)
+ events_attrs[j++] = &msr[i].attr->attr.attr;
+ }
+ events_attrs[j] = NULL;
+
+ return (j > 0) ? true : false;
+}
+
+static int __init cstate_init(void)
+{
+ /* SLM has different MSR for PKG C6 */
+ switch (boot_cpu_data.x86_model) {
+ case 55:
+ case 76:
+ case 77:
+ pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
+ }
+
+ if (cstate_probe_msr(core_msr, core_events_attrs, PERF_CSTATE_CORE_EVENT_MAX))
+ has_cstate_core = true;
+
+ if (cstate_probe_msr(pkg_msr, pkg_events_attrs, PERF_CSTATE_PKG_EVENT_MAX))
+ has_cstate_pkg = true;
+
+ return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
+}
+
+static void __init cstate_cpumask_init(void)
+{
+ int cpu;
+
+ cpu_notifier_register_begin();
+
+ for_each_online_cpu(cpu)
+ cstate_cpu_init(cpu);
+
+ __perf_cpu_notifier(cstate_cpu_notifier);
+
+ cpu_notifier_register_done();
+}
+
+static struct pmu cstate_core_pmu = {
+ .attr_groups = core_attr_groups,
+ .name = "cstate_core",
+ .task_ctx_nr = perf_invalid_context,
+ .event_init = cstate_pmu_event_init,
+ .add = cstate_pmu_event_add, /* must have */
+ .del = cstate_pmu_event_del, /* must have */
+ .start = cstate_pmu_event_start,
+ .stop = cstate_pmu_event_stop,
+ .read = cstate_pmu_event_update,
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static struct pmu cstate_pkg_pmu = {
+ .attr_groups = pkg_attr_groups,
+ .name = "cstate_pkg",
+ .task_ctx_nr = perf_invalid_context,
+ .event_init = cstate_pmu_event_init,
+ .add = cstate_pmu_event_add, /* must have */
+ .del = cstate_pmu_event_del, /* must have */
+ .start = cstate_pmu_event_start,
+ .stop = cstate_pmu_event_stop,
+ .read = cstate_pmu_event_update,
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static void __init cstate_pmus_register(void)
+{
+ int err;
+
+ if (has_cstate_core) {
+ err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
+ if (WARN_ON(err))
+ pr_info("Failed to register PMU %s error %d\n",
+ cstate_core_pmu.name, err);
+ }
+
+ if (has_cstate_pkg) {
+ err = perf_pmu_register(&cstate_pkg_pmu, cstate_pkg_pmu.name, -1);
+ if (WARN_ON(err))
+ pr_info("Failed to register PMU %s error %d\n",
+ cstate_pkg_pmu.name, err);
+ }
+}
+
+static int __init cstate_pmu_init(void)
+{
+ int err;
+
+ if (cpu_has_hypervisor)
+ return -ENODEV;
+
+ err = cstate_init();
+ if (err)
+ return err;
+
+ cstate_cpumask_init();
+
+ cstate_pmus_register();
+
+ return 0;
+}
+
+device_initcall(cstate_pmu_init);
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
new file mode 100644
index 0000000..ce7211a
--- /dev/null
+++ b/arch/x86/events/intel/ds.c
@@ -0,0 +1,1410 @@
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <asm/perf_event.h>
+#include <asm/insn.h>
+
+#include "../perf_event.h"
+
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE 24
+
+#define BTS_BUFFER_SIZE (PAGE_SIZE << 4)
+#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4)
+#define PEBS_FIXUP_SIZE PAGE_SIZE
+
+/*
+ * pebs_record_32 for p4 and core not supported
+
+struct pebs_record_32 {
+ u32 flags, ip;
+ u32 ax, bc, cx, dx;
+ u32 si, di, bp, sp;
+};
+
+ */
+
+union intel_x86_pebs_dse {
+ u64 val;
+ struct {
+ unsigned int ld_dse:4;
+ unsigned int ld_stlb_miss:1;
+ unsigned int ld_locked:1;
+ unsigned int ld_reserved:26;
+ };
+ struct {
+ unsigned int st_l1d_hit:1;
+ unsigned int st_reserved1:3;
+ unsigned int st_stlb_miss:1;
+ unsigned int st_locked:1;
+ unsigned int st_reserved2:26;
+ };
+};
+
+
+/*
+ * Map PEBS Load Latency Data Source encodings to generic
+ * memory data source information
+ */
+#define P(a, b) PERF_MEM_S(a, b)
+#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
+#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
+
+/* Version for Sandy Bridge and later */
+static u64 pebs_data_source[] = {
+ P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
+ OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */
+ OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
+ OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */
+ OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */
+ OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */
+ OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */
+ OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */
+ OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */
+ OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
+ OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */
+ OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */
+ OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
+ OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
+ OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */
+ OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
+};
+
+/* Patch up minor differences in the bits */
+void __init intel_pmu_pebs_data_source_nhm(void)
+{
+ pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT);
+ pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
+ pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
+}
+
+static u64 precise_store_data(u64 status)
+{
+ union intel_x86_pebs_dse dse;
+ u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2);
+
+ dse.val = status;
+
+ /*
+ * bit 4: TLB access
+ * 1 = stored missed 2nd level TLB
+ *
+ * so it either hit the walker or the OS
+ * otherwise hit 2nd level TLB
+ */
+ if (dse.st_stlb_miss)
+ val |= P(TLB, MISS);
+ else
+ val |= P(TLB, HIT);
+
+ /*
+ * bit 0: hit L1 data cache
+ * if not set, then all we know is that
+ * it missed L1D
+ */
+ if (dse.st_l1d_hit)
+ val |= P(LVL, HIT);
+ else
+ val |= P(LVL, MISS);
+
+ /*
+ * bit 5: Locked prefix
+ */
+ if (dse.st_locked)
+ val |= P(LOCK, LOCKED);
+
+ return val;
+}
+
+static u64 precise_datala_hsw(struct perf_event *event, u64 status)
+{
+ union perf_mem_data_src dse;
+
+ dse.val = PERF_MEM_NA;
+
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
+ dse.mem_op = PERF_MEM_OP_STORE;
+ else if (event->hw.flags & PERF_X86_EVENT_PEBS_LD_HSW)
+ dse.mem_op = PERF_MEM_OP_LOAD;
+
+ /*
+ * L1 info only valid for following events:
+ *
+ * MEM_UOPS_RETIRED.STLB_MISS_STORES
+ * MEM_UOPS_RETIRED.LOCK_STORES
+ * MEM_UOPS_RETIRED.SPLIT_STORES
+ * MEM_UOPS_RETIRED.ALL_STORES
+ */
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) {
+ if (status & 1)
+ dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
+ else
+ dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
+ }
+ return dse.val;
+}
+
+static u64 load_latency_data(u64 status)
+{
+ union intel_x86_pebs_dse dse;
+ u64 val;
+ int model = boot_cpu_data.x86_model;
+ int fam = boot_cpu_data.x86;
+
+ dse.val = status;
+
+ /*
+ * use the mapping table for bit 0-3
+ */
+ val = pebs_data_source[dse.ld_dse];
+
+ /*
+ * Nehalem models do not support TLB, Lock infos
+ */
+ if (fam == 0x6 && (model == 26 || model == 30
+ || model == 31 || model == 46)) {
+ val |= P(TLB, NA) | P(LOCK, NA);
+ return val;
+ }
+ /*
+ * bit 4: TLB access
+ * 0 = did not miss 2nd level TLB
+ * 1 = missed 2nd level TLB
+ */
+ if (dse.ld_stlb_miss)
+ val |= P(TLB, MISS) | P(TLB, L2);
+ else
+ val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
+
+ /*
+ * bit 5: locked prefix
+ */
+ if (dse.ld_locked)
+ val |= P(LOCK, LOCKED);
+
+ return val;
+}
+
+struct pebs_record_core {
+ u64 flags, ip;
+ u64 ax, bx, cx, dx;
+ u64 si, di, bp, sp;
+ u64 r8, r9, r10, r11;
+ u64 r12, r13, r14, r15;
+};
+
+struct pebs_record_nhm {
+ u64 flags, ip;
+ u64 ax, bx, cx, dx;
+ u64 si, di, bp, sp;
+ u64 r8, r9, r10, r11;
+ u64 r12, r13, r14, r15;
+ u64 status, dla, dse, lat;
+};
+
+/*
+ * Same as pebs_record_nhm, with two additional fields.
+ */
+struct pebs_record_hsw {
+ u64 flags, ip;
+ u64 ax, bx, cx, dx;
+ u64 si, di, bp, sp;
+ u64 r8, r9, r10, r11;
+ u64 r12, r13, r14, r15;
+ u64 status, dla, dse, lat;
+ u64 real_ip, tsx_tuning;
+};
+
+union hsw_tsx_tuning {
+ struct {
+ u32 cycles_last_block : 32,
+ hle_abort : 1,
+ rtm_abort : 1,
+ instruction_abort : 1,
+ non_instruction_abort : 1,
+ retry : 1,
+ data_conflict : 1,
+ capacity_writes : 1,
+ capacity_reads : 1;
+ };
+ u64 value;
+};
+
+#define PEBS_HSW_TSX_FLAGS 0xff00000000ULL
+
+/* Same as HSW, plus TSC */
+
+struct pebs_record_skl {
+ u64 flags, ip;
+ u64 ax, bx, cx, dx;
+ u64 si, di, bp, sp;
+ u64 r8, r9, r10, r11;
+ u64 r12, r13, r14, r15;
+ u64 status, dla, dse, lat;
+ u64 real_ip, tsx_tuning;
+ u64 tsc;
+};
+
+void init_debug_store_on_cpu(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds)
+ return;
+
+ wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+ (u32)((u64)(unsigned long)ds),
+ (u32)((u64)(unsigned long)ds >> 32));
+}
+
+void fini_debug_store_on_cpu(int cpu)
+{
+ if (!per_cpu(cpu_hw_events, cpu).ds)
+ return;
+
+ wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static DEFINE_PER_CPU(void *, insn_buffer);
+
+static int alloc_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max;
+ void *buffer, *ibuffer;
+
+ if (!x86_pmu.pebs)
+ return 0;
+
+ buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
+ if (unlikely(!buffer))
+ return -ENOMEM;
+
+ /*
+ * HSW+ already provides us the eventing ip; no need to allocate this
+ * buffer then.
+ */
+ if (x86_pmu.intel_cap.pebs_format < 2) {
+ ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
+ if (!ibuffer) {
+ kfree(buffer);
+ return -ENOMEM;
+ }
+ per_cpu(insn_buffer, cpu) = ibuffer;
+ }
+
+ max = x86_pmu.pebs_buffer_size / x86_pmu.pebs_record_size;
+
+ ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+ ds->pebs_index = ds->pebs_buffer_base;
+ ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+ max * x86_pmu.pebs_record_size;
+
+ return 0;
+}
+
+static void release_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.pebs)
+ return;
+
+ kfree(per_cpu(insn_buffer, cpu));
+ per_cpu(insn_buffer, cpu) = NULL;
+
+ kfree((void *)(unsigned long)ds->pebs_buffer_base);
+ ds->pebs_buffer_base = 0;
+}
+
+static int alloc_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max, thresh;
+ void *buffer;
+
+ if (!x86_pmu.bts)
+ return 0;
+
+ buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
+ if (unlikely(!buffer)) {
+ WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
+ return -ENOMEM;
+ }
+
+ max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+ thresh = max / 16;
+
+ ds->bts_buffer_base = (u64)(unsigned long)buffer;
+ ds->bts_index = ds->bts_buffer_base;
+ ds->bts_absolute_maximum = ds->bts_buffer_base +
+ max * BTS_RECORD_SIZE;
+ ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+ thresh * BTS_RECORD_SIZE;
+
+ return 0;
+}
+
+static void release_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.bts)
+ return;
+
+ kfree((void *)(unsigned long)ds->bts_buffer_base);
+ ds->bts_buffer_base = 0;
+}
+
+static int alloc_ds_buffer(int cpu)
+{
+ int node = cpu_to_node(cpu);
+ struct debug_store *ds;
+
+ ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node);
+ if (unlikely(!ds))
+ return -ENOMEM;
+
+ per_cpu(cpu_hw_events, cpu).ds = ds;
+
+ return 0;
+}
+
+static void release_ds_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds)
+ return;
+
+ per_cpu(cpu_hw_events, cpu).ds = NULL;
+ kfree(ds);
+}
+
+void release_ds_buffers(void)
+{
+ int cpu;
+
+ if (!x86_pmu.bts && !x86_pmu.pebs)
+ return;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu)
+ fini_debug_store_on_cpu(cpu);
+
+ for_each_possible_cpu(cpu) {
+ release_pebs_buffer(cpu);
+ release_bts_buffer(cpu);
+ release_ds_buffer(cpu);
+ }
+ put_online_cpus();
+}
+
+void reserve_ds_buffers(void)
+{
+ int bts_err = 0, pebs_err = 0;
+ int cpu;
+
+ x86_pmu.bts_active = 0;
+ x86_pmu.pebs_active = 0;
+
+ if (!x86_pmu.bts && !x86_pmu.pebs)
+ return;
+
+ if (!x86_pmu.bts)
+ bts_err = 1;
+
+ if (!x86_pmu.pebs)
+ pebs_err = 1;
+
+ get_online_cpus();
+
+ for_each_possible_cpu(cpu) {
+ if (alloc_ds_buffer(cpu)) {
+ bts_err = 1;
+ pebs_err = 1;
+ }
+
+ if (!bts_err && alloc_bts_buffer(cpu))
+ bts_err = 1;
+
+ if (!pebs_err && alloc_pebs_buffer(cpu))
+ pebs_err = 1;
+
+ if (bts_err && pebs_err)
+ break;
+ }
+
+ if (bts_err) {
+ for_each_possible_cpu(cpu)
+ release_bts_buffer(cpu);
+ }
+
+ if (pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_pebs_buffer(cpu);
+ }
+
+ if (bts_err && pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_ds_buffer(cpu);
+ } else {
+ if (x86_pmu.bts && !bts_err)
+ x86_pmu.bts_active = 1;
+
+ if (x86_pmu.pebs && !pebs_err)
+ x86_pmu.pebs_active = 1;
+
+ for_each_online_cpu(cpu)
+ init_debug_store_on_cpu(cpu);
+ }
+
+ put_online_cpus();
+}
+
+/*
+ * BTS
+ */
+
+struct event_constraint bts_constraint =
+ EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0);
+
+void intel_pmu_enable_bts(u64 config)
+{
+ unsigned long debugctlmsr;
+
+ debugctlmsr = get_debugctlmsr();
+
+ debugctlmsr |= DEBUGCTLMSR_TR;
+ debugctlmsr |= DEBUGCTLMSR_BTS;
+ if (config & ARCH_PERFMON_EVENTSEL_INT)
+ debugctlmsr |= DEBUGCTLMSR_BTINT;
+
+ if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+ debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
+
+ if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+ debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
+
+ update_debugctlmsr(debugctlmsr);
+}
+
+void intel_pmu_disable_bts(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ unsigned long debugctlmsr;
+
+ if (!cpuc->ds)
+ return;
+
+ debugctlmsr = get_debugctlmsr();
+
+ debugctlmsr &=
+ ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
+ DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
+
+ update_debugctlmsr(debugctlmsr);
+}
+
+int intel_pmu_drain_bts_buffer(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct debug_store *ds = cpuc->ds;
+ struct bts_record {
+ u64 from;
+ u64 to;
+ u64 flags;
+ };
+ struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
+ struct bts_record *at, *base, *top;
+ struct perf_output_handle handle;
+ struct perf_event_header header;
+ struct perf_sample_data data;
+ unsigned long skip = 0;
+ struct pt_regs regs;
+
+ if (!event)
+ return 0;
+
+ if (!x86_pmu.bts_active)
+ return 0;
+
+ base = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+ top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+ if (top <= base)
+ return 0;
+
+ memset(&regs, 0, sizeof(regs));
+
+ ds->bts_index = ds->bts_buffer_base;
+
+ perf_sample_data_init(&data, 0, event->hw.last_period);
+
+ /*
+ * BTS leaks kernel addresses in branches across the cpl boundary,
+ * such as traps or system calls, so unless the user is asking for
+ * kernel tracing (and right now it's not possible), we'd need to
+ * filter them out. But first we need to count how many of those we
+ * have in the current batch. This is an extra O(n) pass, however,
+ * it's much faster than the other one especially considering that
+ * n <= 2560 (BTS_BUFFER_SIZE / BTS_RECORD_SIZE * 15/16; see the
+ * alloc_bts_buffer()).
+ */
+ for (at = base; at < top; at++) {
+ /*
+ * Note that right now *this* BTS code only works if
+ * attr::exclude_kernel is set, but let's keep this extra
+ * check here in case that changes.
+ */
+ if (event->attr.exclude_kernel &&
+ (kernel_ip(at->from) || kernel_ip(at->to)))
+ skip++;
+ }
+
+ /*
+ * Prepare a generic sample, i.e. fill in the invariant fields.
+ * We will overwrite the from and to address before we output
+ * the sample.
+ */
+ perf_prepare_sample(&header, &data, event, &regs);
+
+ if (perf_output_begin(&handle, event, header.size *
+ (top - base - skip)))
+ return 1;
+
+ for (at = base; at < top; at++) {
+ /* Filter out any records that contain kernel addresses. */
+ if (event->attr.exclude_kernel &&
+ (kernel_ip(at->from) || kernel_ip(at->to)))
+ continue;
+
+ data.ip = at->from;
+ data.addr = at->to;
+
+ perf_output_sample(&handle, &header, &data, event);
+ }
+
+ perf_output_end(&handle);
+
+ /* There's new data available. */
+ event->hw.interrupts++;
+ event->pending_kill = POLL_IN;
+ return 1;
+}
+
+static inline void intel_pmu_drain_pebs_buffer(void)
+{
+ struct pt_regs regs;
+
+ x86_pmu.drain_pebs(&regs);
+}
+
+void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+ if (!sched_in)
+ intel_pmu_drain_pebs_buffer();
+}
+
+/*
+ * PEBS
+ */
+struct event_constraint intel_core2_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */
+ /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_atom_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */
+ /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_slm_pebs_event_constraints[] = {
+ /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1),
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_nehalem_pebs_event_constraints[] = {
+ INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf), /* INST_RETIRED.ANY */
+ INTEL_EVENT_CONSTRAINT(0xc2, 0xf), /* UOPS_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf), /* SSEX_UOPS_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf), /* MEM_LOAD_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf), /* FP_ASSIST.* */
+ /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_westmere_pebs_event_constraints[] = {
+ INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf), /* INSTR_RETIRED.* */
+ INTEL_EVENT_CONSTRAINT(0xc2, 0xf), /* UOPS_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf), /* SSEX_UOPS_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf), /* MEM_LOAD_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf), /* FP_ASSIST.* */
+ /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_snb_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+ INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
+ INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */
+ /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+ INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_ivb_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+ INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
+ INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */
+ /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+ /* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c0, 0x2),
+ INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+ INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_hsw_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+ INTEL_PLD_CONSTRAINT(0x01cd, 0xf), /* MEM_TRANS_RETIRED.* */
+ /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+ /* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c0, 0x2),
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd2, 0xf), /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd3, 0xf), /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint intel_bdw_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+ INTEL_PLD_CONSTRAINT(0x01cd, 0xf), /* MEM_TRANS_RETIRED.* */
+ /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
+ /* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c0, 0x2),
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf), /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf), /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+
+struct event_constraint intel_skl_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x2), /* INST_RETIRED.PREC_DIST */
+ /* INST_RETIRED.PREC_DIST, inv=1, cmask=16 (cycles:ppp). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c0, 0x2),
+ /* INST_RETIRED.TOTAL_CYCLES_PS (inv=1, cmask=16) (cycles:p). */
+ INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
+ INTEL_PLD_CONSTRAINT(0x1cd, 0xf), /* MEM_TRANS_RETIRED.* */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x22d0, 0xf), /* MEM_INST_RETIRED.LOCK_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf), /* MEM_LOAD_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf), /* MEM_LOAD_L3_HIT_RETIRED.* */
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf), /* MEM_LOAD_L3_MISS_RETIRED.* */
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+struct event_constraint *intel_pebs_constraints(struct perf_event *event)
+{
+ struct event_constraint *c;
+
+ if (!event->attr.precise_ip)
+ return NULL;
+
+ if (x86_pmu.pebs_constraints) {
+ for_each_event_constraint(c, x86_pmu.pebs_constraints) {
+ if ((event->hw.config & c->cmask) == c->code) {
+ event->hw.flags |= c->flags;
+ return c;
+ }
+ }
+ }
+
+ return &emptyconstraint;
+}
+
+static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc)
+{
+ return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1));
+}
+
+void intel_pmu_pebs_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ struct debug_store *ds = cpuc->ds;
+ bool first_pebs;
+ u64 threshold;
+
+ hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
+
+ first_pebs = !pebs_is_enabled(cpuc);
+ cpuc->pebs_enabled |= 1ULL << hwc->idx;
+
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+ cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
+ else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
+ cpuc->pebs_enabled |= 1ULL << 63;
+
+ /*
+ * When the event is constrained enough we can use a larger
+ * threshold and run the event with less frequent PMI.
+ */
+ if (hwc->flags & PERF_X86_EVENT_FREERUNNING) {
+ threshold = ds->pebs_absolute_maximum -
+ x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
+
+ if (first_pebs)
+ perf_sched_cb_inc(event->ctx->pmu);
+ } else {
+ threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
+
+ /*
+ * If not all events can use larger buffer,
+ * roll back to threshold = 1
+ */
+ if (!first_pebs &&
+ (ds->pebs_interrupt_threshold > threshold))
+ perf_sched_cb_dec(event->ctx->pmu);
+ }
+
+ /* Use auto-reload if possible to save a MSR write in the PMI */
+ if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
+ ds->pebs_event_reset[hwc->idx] =
+ (u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
+ }
+
+ if (first_pebs || ds->pebs_interrupt_threshold > threshold)
+ ds->pebs_interrupt_threshold = threshold;
+}
+
+void intel_pmu_pebs_disable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ struct debug_store *ds = cpuc->ds;
+ bool large_pebs = ds->pebs_interrupt_threshold >
+ ds->pebs_buffer_base + x86_pmu.pebs_record_size;
+
+ if (large_pebs)
+ intel_pmu_drain_pebs_buffer();
+
+ cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+
+ if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+ cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
+ else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
+ cpuc->pebs_enabled &= ~(1ULL << 63);
+
+ if (large_pebs && !pebs_is_enabled(cpuc))
+ perf_sched_cb_dec(event->ctx->pmu);
+
+ if (cpuc->enabled)
+ wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+
+ hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
+}
+
+void intel_pmu_pebs_enable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (cpuc->pebs_enabled)
+ wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+}
+
+void intel_pmu_pebs_disable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (cpuc->pebs_enabled)
+ wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
+}
+
+static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ unsigned long from = cpuc->lbr_entries[0].from;
+ unsigned long old_to, to = cpuc->lbr_entries[0].to;
+ unsigned long ip = regs->ip;
+ int is_64bit = 0;
+ void *kaddr;
+ int size;
+
+ /*
+ * We don't need to fixup if the PEBS assist is fault like
+ */
+ if (!x86_pmu.intel_cap.pebs_trap)
+ return 1;
+
+ /*
+ * No LBR entry, no basic block, no rewinding
+ */
+ if (!cpuc->lbr_stack.nr || !from || !to)
+ return 0;
+
+ /*
+ * Basic blocks should never cross user/kernel boundaries
+ */
+ if (kernel_ip(ip) != kernel_ip(to))
+ return 0;
+
+ /*
+ * unsigned math, either ip is before the start (impossible) or
+ * the basic block is larger than 1 page (sanity)
+ */
+ if ((ip - to) > PEBS_FIXUP_SIZE)
+ return 0;
+
+ /*
+ * We sampled a branch insn, rewind using the LBR stack
+ */
+ if (ip == to) {
+ set_linear_ip(regs, from);
+ return 1;
+ }
+
+ size = ip - to;
+ if (!kernel_ip(ip)) {
+ int bytes;
+ u8 *buf = this_cpu_read(insn_buffer);
+
+ /* 'size' must fit our buffer, see above */
+ bytes = copy_from_user_nmi(buf, (void __user *)to, size);
+ if (bytes != 0)
+ return 0;
+
+ kaddr = buf;
+ } else {
+ kaddr = (void *)to;
+ }
+
+ do {
+ struct insn insn;
+
+ old_to = to;
+
+#ifdef CONFIG_X86_64
+ is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
+#endif
+ insn_init(&insn, kaddr, size, is_64bit);
+ insn_get_length(&insn);
+ /*
+ * Make sure there was not a problem decoding the
+ * instruction and getting the length. This is
+ * doubly important because we have an infinite
+ * loop if insn.length=0.
+ */
+ if (!insn.length)
+ break;
+
+ to += insn.length;
+ kaddr += insn.length;
+ size -= insn.length;
+ } while (to < ip);
+
+ if (to == ip) {
+ set_linear_ip(regs, old_to);
+ return 1;
+ }
+
+ /*
+ * Even though we decoded the basic block, the instruction stream
+ * never matched the given IP, either the TO or the IP got corrupted.
+ */
+ return 0;
+}
+
+static inline u64 intel_hsw_weight(struct pebs_record_skl *pebs)
+{
+ if (pebs->tsx_tuning) {
+ union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
+ return tsx.cycles_last_block;
+ }
+ return 0;
+}
+
+static inline u64 intel_hsw_transaction(struct pebs_record_skl *pebs)
+{
+ u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
+
+ /* For RTM XABORTs also log the abort code from AX */
+ if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
+ txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
+ return txn;
+}
+
+static void setup_pebs_sample_data(struct perf_event *event,
+ struct pt_regs *iregs, void *__pebs,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+#define PERF_X86_EVENT_PEBS_HSW_PREC \
+ (PERF_X86_EVENT_PEBS_ST_HSW | \
+ PERF_X86_EVENT_PEBS_LD_HSW | \
+ PERF_X86_EVENT_PEBS_NA_HSW)
+ /*
+ * We cast to the biggest pebs_record but are careful not to
+ * unconditionally access the 'extra' entries.
+ */
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct pebs_record_skl *pebs = __pebs;
+ u64 sample_type;
+ int fll, fst, dsrc;
+ int fl = event->hw.flags;
+
+ if (pebs == NULL)
+ return;
+
+ sample_type = event->attr.sample_type;
+ dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
+
+ fll = fl & PERF_X86_EVENT_PEBS_LDLAT;
+ fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
+
+ perf_sample_data_init(data, 0, event->hw.last_period);
+
+ data->period = event->hw.last_period;
+
+ /*
+ * Use latency for weight (only avail with PEBS-LL)
+ */
+ if (fll && (sample_type & PERF_SAMPLE_WEIGHT))
+ data->weight = pebs->lat;
+
+ /*
+ * data.data_src encodes the data source
+ */
+ if (dsrc) {
+ u64 val = PERF_MEM_NA;
+ if (fll)
+ val = load_latency_data(pebs->dse);
+ else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
+ val = precise_datala_hsw(event, pebs->dse);
+ else if (fst)
+ val = precise_store_data(pebs->dse);
+ data->data_src.val = val;
+ }
+
+ /*
+ * We use the interrupt regs as a base because the PEBS record
+ * does not contain a full regs set, specifically it seems to
+ * lack segment descriptors, which get used by things like
+ * user_mode().
+ *
+ * In the simple case fix up only the IP and BP,SP regs, for
+ * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
+ * A possible PERF_SAMPLE_REGS will have to transfer all regs.
+ */
+ *regs = *iregs;
+ regs->flags = pebs->flags;
+ set_linear_ip(regs, pebs->ip);
+ regs->bp = pebs->bp;
+ regs->sp = pebs->sp;
+
+ if (sample_type & PERF_SAMPLE_REGS_INTR) {
+ regs->ax = pebs->ax;
+ regs->bx = pebs->bx;
+ regs->cx = pebs->cx;
+ regs->dx = pebs->dx;
+ regs->si = pebs->si;
+ regs->di = pebs->di;
+ regs->bp = pebs->bp;
+ regs->sp = pebs->sp;
+
+ regs->flags = pebs->flags;
+#ifndef CONFIG_X86_32
+ regs->r8 = pebs->r8;
+ regs->r9 = pebs->r9;
+ regs->r10 = pebs->r10;
+ regs->r11 = pebs->r11;
+ regs->r12 = pebs->r12;
+ regs->r13 = pebs->r13;
+ regs->r14 = pebs->r14;
+ regs->r15 = pebs->r15;
+#endif
+ }
+
+ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+ regs->ip = pebs->real_ip;
+ regs->flags |= PERF_EFLAGS_EXACT;
+ } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
+ regs->flags |= PERF_EFLAGS_EXACT;
+ else
+ regs->flags &= ~PERF_EFLAGS_EXACT;
+
+ if ((sample_type & PERF_SAMPLE_ADDR) &&
+ x86_pmu.intel_cap.pebs_format >= 1)
+ data->addr = pebs->dla;
+
+ if (x86_pmu.intel_cap.pebs_format >= 2) {
+ /* Only set the TSX weight when no memory weight. */
+ if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll)
+ data->weight = intel_hsw_weight(pebs);
+
+ if (sample_type & PERF_SAMPLE_TRANSACTION)
+ data->txn = intel_hsw_transaction(pebs);
+ }
+
+ /*
+ * v3 supplies an accurate time stamp, so we use that
+ * for the time stamp.
+ *
+ * We can only do this for the default trace clock.
+ */
+ if (x86_pmu.intel_cap.pebs_format >= 3 &&
+ event->attr.use_clockid == 0)
+ data->time = native_sched_clock_from_tsc(pebs->tsc);
+
+ if (has_branch_stack(event))
+ data->br_stack = &cpuc->lbr_stack;
+}
+
+static inline void *
+get_next_pebs_record_by_bit(void *base, void *top, int bit)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ void *at;
+ u64 pebs_status;
+
+ /*
+ * fmt0 does not have a status bitfield (does not use
+ * perf_record_nhm format)
+ */
+ if (x86_pmu.intel_cap.pebs_format < 1)
+ return base;
+
+ if (base == NULL)
+ return NULL;
+
+ for (at = base; at < top; at += x86_pmu.pebs_record_size) {
+ struct pebs_record_nhm *p = at;
+
+ if (test_bit(bit, (unsigned long *)&p->status)) {
+ /* PEBS v3 has accurate status bits */
+ if (x86_pmu.intel_cap.pebs_format >= 3)
+ return at;
+
+ if (p->status == (1 << bit))
+ return at;
+
+ /* clear non-PEBS bit and re-check */
+ pebs_status = p->status & cpuc->pebs_enabled;
+ pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
+ if (pebs_status == (1 << bit))
+ return at;
+ }
+ }
+ return NULL;
+}
+
+static void __intel_pmu_pebs_event(struct perf_event *event,
+ struct pt_regs *iregs,
+ void *base, void *top,
+ int bit, int count)
+{
+ struct perf_sample_data data;
+ struct pt_regs regs;
+ void *at = get_next_pebs_record_by_bit(base, top, bit);
+
+ if (!intel_pmu_save_and_restart(event) &&
+ !(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
+ return;
+
+ while (count > 1) {
+ setup_pebs_sample_data(event, iregs, at, &data, &regs);
+ perf_event_output(event, &data, &regs);
+ at += x86_pmu.pebs_record_size;
+ at = get_next_pebs_record_by_bit(at, top, bit);
+ count--;
+ }
+
+ setup_pebs_sample_data(event, iregs, at, &data, &regs);
+
+ /*
+ * All but the last records are processed.
+ * The last one is left to be able to call the overflow handler.
+ */
+ if (perf_event_overflow(event, &data, &regs)) {
+ x86_pmu_stop(event, 0);
+ return;
+ }
+
+}
+
+static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct debug_store *ds = cpuc->ds;
+ struct perf_event *event = cpuc->events[0]; /* PMC0 only */
+ struct pebs_record_core *at, *top;
+ int n;
+
+ if (!x86_pmu.pebs_active)
+ return;
+
+ at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
+ top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
+
+ /*
+ * Whatever else happens, drain the thing
+ */
+ ds->pebs_index = ds->pebs_buffer_base;
+
+ if (!test_bit(0, cpuc->active_mask))
+ return;
+
+ WARN_ON_ONCE(!event);
+
+ if (!event->attr.precise_ip)
+ return;
+
+ n = top - at;
+ if (n <= 0)
+ return;
+
+ __intel_pmu_pebs_event(event, iregs, at, top, 0, n);
+}
+
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct debug_store *ds = cpuc->ds;
+ struct perf_event *event;
+ void *base, *at, *top;
+ short counts[MAX_PEBS_EVENTS] = {};
+ short error[MAX_PEBS_EVENTS] = {};
+ int bit, i;
+
+ if (!x86_pmu.pebs_active)
+ return;
+
+ base = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+ top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+ ds->pebs_index = ds->pebs_buffer_base;
+
+ if (unlikely(base >= top))
+ return;
+
+ for (at = base; at < top; at += x86_pmu.pebs_record_size) {
+ struct pebs_record_nhm *p = at;
+ u64 pebs_status;
+
+ /* PEBS v3 has accurate status bits */
+ if (x86_pmu.intel_cap.pebs_format >= 3) {
+ for_each_set_bit(bit, (unsigned long *)&p->status,
+ MAX_PEBS_EVENTS)
+ counts[bit]++;
+
+ continue;
+ }
+
+ pebs_status = p->status & cpuc->pebs_enabled;
+ pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
+
+ /*
+ * On some CPUs the PEBS status can be zero when PEBS is
+ * racing with clearing of GLOBAL_STATUS.
+ *
+ * Normally we would drop that record, but in the
+ * case when there is only a single active PEBS event
+ * we can assume it's for that event.
+ */
+ if (!pebs_status && cpuc->pebs_enabled &&
+ !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1)))
+ pebs_status = cpuc->pebs_enabled;
+
+ bit = find_first_bit((unsigned long *)&pebs_status,
+ x86_pmu.max_pebs_events);
+ if (bit >= x86_pmu.max_pebs_events)
+ continue;
+
+ /*
+ * The PEBS hardware does not deal well with the situation
+ * when events happen near to each other and multiple bits
+ * are set. But it should happen rarely.
+ *
+ * If these events include one PEBS and multiple non-PEBS
+ * events, it doesn't impact PEBS record. The record will
+ * be handled normally. (slow path)
+ *
+ * If these events include two or more PEBS events, the
+ * records for the events can be collapsed into a single
+ * one, and it's not possible to reconstruct all events
+ * that caused the PEBS record. It's called collision.
+ * If collision happened, the record will be dropped.
+ */
+ if (p->status != (1ULL << bit)) {
+ for_each_set_bit(i, (unsigned long *)&pebs_status,
+ x86_pmu.max_pebs_events)
+ error[i]++;
+ continue;
+ }
+
+ counts[bit]++;
+ }
+
+ for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
+ if ((counts[bit] == 0) && (error[bit] == 0))
+ continue;
+
+ event = cpuc->events[bit];
+ WARN_ON_ONCE(!event);
+ WARN_ON_ONCE(!event->attr.precise_ip);
+
+ /* log dropped samples number */
+ if (error[bit])
+ perf_log_lost_samples(event, error[bit]);
+
+ if (counts[bit]) {
+ __intel_pmu_pebs_event(event, iregs, base,
+ top, bit, counts[bit]);
+ }
+ }
+}
+
+/*
+ * BTS, PEBS probe and setup
+ */
+
+void __init intel_ds_init(void)
+{
+ /*
+ * No support for 32bit formats
+ */
+ if (!boot_cpu_has(X86_FEATURE_DTES64))
+ return;
+
+ x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS);
+ x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
+ x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
+ if (x86_pmu.pebs) {
+ char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-';
+ int format = x86_pmu.intel_cap.pebs_format;
+
+ switch (format) {
+ case 0:
+ pr_cont("PEBS fmt0%c, ", pebs_type);
+ x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
+ /*
+ * Using >PAGE_SIZE buffers makes the WRMSR to
+ * PERF_GLOBAL_CTRL in intel_pmu_enable_all()
+ * mysteriously hang on Core2.
+ *
+ * As a workaround, we don't do this.
+ */
+ x86_pmu.pebs_buffer_size = PAGE_SIZE;
+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
+ break;
+
+ case 1:
+ pr_cont("PEBS fmt1%c, ", pebs_type);
+ x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+ break;
+
+ case 2:
+ pr_cont("PEBS fmt2%c, ", pebs_type);
+ x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+ break;
+
+ case 3:
+ pr_cont("PEBS fmt3%c, ", pebs_type);
+ x86_pmu.pebs_record_size =
+ sizeof(struct pebs_record_skl);
+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+ x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
+ break;
+
+ default:
+ pr_cont("no PEBS fmt%d%c, ", format, pebs_type);
+ x86_pmu.pebs = 0;
+ }
+ }
+}
+
+void perf_restore_debug_store(void)
+{
+ struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
+ if (!x86_pmu.bts && !x86_pmu.pebs)
+ return;
+
+ wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+}
diff --git a/arch/x86/events/intel/knc.c b/arch/x86/events/intel/knc.c
new file mode 100644
index 0000000..548d5f7
--- /dev/null
+++ b/arch/x86/events/intel/knc.c
@@ -0,0 +1,321 @@
+/* Driver for Intel Xeon Phi "Knights Corner" PMU */
+
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include <asm/hardirq.h>
+
+#include "../perf_event.h"
+
+static const u64 knc_perfmon_event_map[] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x002a,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x0016,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0028,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0029,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0012,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x002b,
+};
+
+static const u64 __initconst knc_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ /* On Xeon Phi event "0" is a valid DATA_READ */
+ /* (L1 Data Cache Reads) Instruction. */
+ /* We code this as ARCH_PERFMON_EVENTSEL_INT as this */
+ /* bit will always be set in x86_pmu_hw_config(). */
+ [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+ /* DATA_READ */
+ [ C(RESULT_MISS) ] = 0x0003, /* DATA_READ_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
+ [ C(RESULT_MISS) ] = 0x0004, /* DATA_WRITE_MISS */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0011, /* L1_DATA_PF1 */
+ [ C(RESULT_MISS) ] = 0x001c, /* L1_DATA_PF1_MISS */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
+ [ C(RESULT_MISS) ] = 0x000e, /* CODE_CACHE_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x10cb, /* L2_READ_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x10cc, /* L2_WRITE_HIT */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x10fc, /* L2_DATA_PF2 */
+ [ C(RESULT_MISS) ] = 0x10fe, /* L2_DATA_PF2_MISS */
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+ /* DATA_READ */
+ /* see note on L1 OP_READ */
+ [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
+ [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
+ [ C(RESULT_MISS) ] = 0x000d, /* CODE_PAGE_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0012, /* BRANCHES */
+ [ C(RESULT_MISS) ] = 0x002b, /* BRANCHES_MISPREDICTED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+
+static u64 knc_pmu_event_map(int hw_event)
+{
+ return knc_perfmon_event_map[hw_event];
+}
+
+static struct event_constraint knc_event_constraints[] =
+{
+ INTEL_EVENT_CONSTRAINT(0xc3, 0x1), /* HWP_L2HIT */
+ INTEL_EVENT_CONSTRAINT(0xc4, 0x1), /* HWP_L2MISS */
+ INTEL_EVENT_CONSTRAINT(0xc8, 0x1), /* L2_READ_HIT_E */
+ INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* L2_READ_HIT_M */
+ INTEL_EVENT_CONSTRAINT(0xca, 0x1), /* L2_READ_HIT_S */
+ INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* L2_READ_MISS */
+ INTEL_EVENT_CONSTRAINT(0xcc, 0x1), /* L2_WRITE_HIT */
+ INTEL_EVENT_CONSTRAINT(0xce, 0x1), /* L2_STRONGLY_ORDERED_STREAMING_VSTORES_MISS */
+ INTEL_EVENT_CONSTRAINT(0xcf, 0x1), /* L2_WEAKLY_ORDERED_STREAMING_VSTORE_MISS */
+ INTEL_EVENT_CONSTRAINT(0xd7, 0x1), /* L2_VICTIM_REQ_WITH_DATA */
+ INTEL_EVENT_CONSTRAINT(0xe3, 0x1), /* SNP_HITM_BUNIT */
+ INTEL_EVENT_CONSTRAINT(0xe6, 0x1), /* SNP_HIT_L2 */
+ INTEL_EVENT_CONSTRAINT(0xe7, 0x1), /* SNP_HITM_L2 */
+ INTEL_EVENT_CONSTRAINT(0xf1, 0x1), /* L2_DATA_READ_MISS_CACHE_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf2, 0x1), /* L2_DATA_WRITE_MISS_CACHE_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf6, 0x1), /* L2_DATA_READ_MISS_MEM_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf7, 0x1), /* L2_DATA_WRITE_MISS_MEM_FILL */
+ INTEL_EVENT_CONSTRAINT(0xfc, 0x1), /* L2_DATA_PF2 */
+ INTEL_EVENT_CONSTRAINT(0xfd, 0x1), /* L2_DATA_PF2_DROP */
+ INTEL_EVENT_CONSTRAINT(0xfe, 0x1), /* L2_DATA_PF2_MISS */
+ INTEL_EVENT_CONSTRAINT(0xff, 0x1), /* L2_DATA_HIT_INFLIGHT_PF2 */
+ EVENT_CONSTRAINT_END
+};
+
+#define MSR_KNC_IA32_PERF_GLOBAL_STATUS 0x0000002d
+#define MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL 0x0000002e
+#define MSR_KNC_IA32_PERF_GLOBAL_CTRL 0x0000002f
+
+#define KNC_ENABLE_COUNTER0 0x00000001
+#define KNC_ENABLE_COUNTER1 0x00000002
+
+static void knc_pmu_disable_all(void)
+{
+ u64 val;
+
+ rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+ val &= ~(KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+ wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static void knc_pmu_enable_all(int added)
+{
+ u64 val;
+
+ rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+ val |= (KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+ wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static inline void
+knc_pmu_disable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val;
+
+ val = hwc->config;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+
+ (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+static void knc_pmu_enable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val;
+
+ val = hwc->config;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+ (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+static inline u64 knc_pmu_get_status(void)
+{
+ u64 status;
+
+ rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status);
+
+ return status;
+}
+
+static inline void knc_pmu_ack_status(u64 ack)
+{
+ wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack);
+}
+
+static int knc_pmu_handle_irq(struct pt_regs *regs)
+{
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ int handled = 0;
+ int bit, loops;
+ u64 status;
+
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ knc_pmu_disable_all();
+
+ status = knc_pmu_get_status();
+ if (!status) {
+ knc_pmu_enable_all(0);
+ return handled;
+ }
+
+ loops = 0;
+again:
+ knc_pmu_ack_status(status);
+ if (++loops > 100) {
+ WARN_ONCE(1, "perf: irq loop stuck!\n");
+ perf_event_print_debug();
+ goto done;
+ }
+
+ inc_irq_stat(apic_perf_irqs);
+
+ for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+ struct perf_event *event = cpuc->events[bit];
+
+ handled++;
+
+ if (!test_bit(bit, cpuc->active_mask))
+ continue;
+
+ if (!intel_pmu_save_and_restart(event))
+ continue;
+
+ perf_sample_data_init(&data, 0, event->hw.last_period);
+
+ if (perf_event_overflow(event, &data, regs))
+ x86_pmu_stop(event, 0);
+ }
+
+ /*
+ * Repeat if there is more work to be done:
+ */
+ status = knc_pmu_get_status();
+ if (status)
+ goto again;
+
+done:
+ /* Only restore PMU state when it's active. See x86_pmu_disable(). */
+ if (cpuc->enabled)
+ knc_pmu_enable_all(0);
+
+ return handled;
+}
+
+
+PMU_FORMAT_ATTR(event, "config:0-7" );
+PMU_FORMAT_ATTR(umask, "config:8-15" );
+PMU_FORMAT_ATTR(edge, "config:18" );
+PMU_FORMAT_ATTR(inv, "config:23" );
+PMU_FORMAT_ATTR(cmask, "config:24-31" );
+
+static struct attribute *intel_knc_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ NULL,
+};
+
+static const struct x86_pmu knc_pmu __initconst = {
+ .name = "knc",
+ .handle_irq = knc_pmu_handle_irq,
+ .disable_all = knc_pmu_disable_all,
+ .enable_all = knc_pmu_enable_all,
+ .enable = knc_pmu_enable_event,
+ .disable = knc_pmu_disable_event,
+ .hw_config = x86_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_KNC_EVNTSEL0,
+ .perfctr = MSR_KNC_PERFCTR0,
+ .event_map = knc_pmu_event_map,
+ .max_events = ARRAY_SIZE(knc_perfmon_event_map),
+ .apic = 1,
+ .max_period = (1ULL << 39) - 1,
+ .version = 0,
+ .num_counters = 2,
+ .cntval_bits = 40,
+ .cntval_mask = (1ULL << 40) - 1,
+ .get_event_constraints = x86_get_event_constraints,
+ .event_constraints = knc_event_constraints,
+ .format_attrs = intel_knc_formats_attr,
+};
+
+__init int knc_pmu_init(void)
+{
+ x86_pmu = knc_pmu;
+
+ memcpy(hw_cache_event_ids, knc_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ return 0;
+}
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
new file mode 100644
index 0000000..69dd118
--- /dev/null
+++ b/arch/x86/events/intel/lbr.c
@@ -0,0 +1,1062 @@
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include <asm/perf_event.h>
+#include <asm/msr.h>
+#include <asm/insn.h>
+
+#include "../perf_event.h"
+
+enum {
+ LBR_FORMAT_32 = 0x00,
+ LBR_FORMAT_LIP = 0x01,
+ LBR_FORMAT_EIP = 0x02,
+ LBR_FORMAT_EIP_FLAGS = 0x03,
+ LBR_FORMAT_EIP_FLAGS2 = 0x04,
+ LBR_FORMAT_INFO = 0x05,
+ LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO,
+};
+
+static enum {
+ LBR_EIP_FLAGS = 1,
+ LBR_TSX = 2,
+} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
+ [LBR_FORMAT_EIP_FLAGS] = LBR_EIP_FLAGS,
+ [LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
+};
+
+/*
+ * Intel LBR_SELECT bits
+ * Intel Vol3a, April 2011, Section 16.7 Table 16-10
+ *
+ * Hardware branch filter (not available on all CPUs)
+ */
+#define LBR_KERNEL_BIT 0 /* do not capture at ring0 */
+#define LBR_USER_BIT 1 /* do not capture at ring > 0 */
+#define LBR_JCC_BIT 2 /* do not capture conditional branches */
+#define LBR_REL_CALL_BIT 3 /* do not capture relative calls */
+#define LBR_IND_CALL_BIT 4 /* do not capture indirect calls */
+#define LBR_RETURN_BIT 5 /* do not capture near returns */
+#define LBR_IND_JMP_BIT 6 /* do not capture indirect jumps */
+#define LBR_REL_JMP_BIT 7 /* do not capture relative jumps */
+#define LBR_FAR_BIT 8 /* do not capture far branches */
+#define LBR_CALL_STACK_BIT 9 /* enable call stack */
+
+/*
+ * Following bit only exists in Linux; we mask it out before writing it to
+ * the actual MSR. But it helps the constraint perf code to understand
+ * that this is a separate configuration.
+ */
+#define LBR_NO_INFO_BIT 63 /* don't read LBR_INFO. */
+
+#define LBR_KERNEL (1 << LBR_KERNEL_BIT)
+#define LBR_USER (1 << LBR_USER_BIT)
+#define LBR_JCC (1 << LBR_JCC_BIT)
+#define LBR_REL_CALL (1 << LBR_REL_CALL_BIT)
+#define LBR_IND_CALL (1 << LBR_IND_CALL_BIT)
+#define LBR_RETURN (1 << LBR_RETURN_BIT)
+#define LBR_REL_JMP (1 << LBR_REL_JMP_BIT)
+#define LBR_IND_JMP (1 << LBR_IND_JMP_BIT)
+#define LBR_FAR (1 << LBR_FAR_BIT)
+#define LBR_CALL_STACK (1 << LBR_CALL_STACK_BIT)
+#define LBR_NO_INFO (1ULL << LBR_NO_INFO_BIT)
+
+#define LBR_PLM (LBR_KERNEL | LBR_USER)
+
+#define LBR_SEL_MASK 0x1ff /* valid bits in LBR_SELECT */
+#define LBR_NOT_SUPP -1 /* LBR filter not supported */
+#define LBR_IGN 0 /* ignored */
+
+#define LBR_ANY \
+ (LBR_JCC |\
+ LBR_REL_CALL |\
+ LBR_IND_CALL |\
+ LBR_RETURN |\
+ LBR_REL_JMP |\
+ LBR_IND_JMP |\
+ LBR_FAR)
+
+#define LBR_FROM_FLAG_MISPRED (1ULL << 63)
+#define LBR_FROM_FLAG_IN_TX (1ULL << 62)
+#define LBR_FROM_FLAG_ABORT (1ULL << 61)
+
+/*
+ * x86control flow change classification
+ * x86control flow changes include branches, interrupts, traps, faults
+ */
+enum {
+ X86_BR_NONE = 0, /* unknown */
+
+ X86_BR_USER = 1 << 0, /* branch target is user */
+ X86_BR_KERNEL = 1 << 1, /* branch target is kernel */
+
+ X86_BR_CALL = 1 << 2, /* call */
+ X86_BR_RET = 1 << 3, /* return */
+ X86_BR_SYSCALL = 1 << 4, /* syscall */
+ X86_BR_SYSRET = 1 << 5, /* syscall return */
+ X86_BR_INT = 1 << 6, /* sw interrupt */
+ X86_BR_IRET = 1 << 7, /* return from interrupt */
+ X86_BR_JCC = 1 << 8, /* conditional */
+ X86_BR_JMP = 1 << 9, /* jump */
+ X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */
+ X86_BR_IND_CALL = 1 << 11,/* indirect calls */
+ X86_BR_ABORT = 1 << 12,/* transaction abort */
+ X86_BR_IN_TX = 1 << 13,/* in transaction */
+ X86_BR_NO_TX = 1 << 14,/* not in transaction */
+ X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
+ X86_BR_CALL_STACK = 1 << 16,/* call stack */
+ X86_BR_IND_JMP = 1 << 17,/* indirect jump */
+};
+
+#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
+#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
+
+#define X86_BR_ANY \
+ (X86_BR_CALL |\
+ X86_BR_RET |\
+ X86_BR_SYSCALL |\
+ X86_BR_SYSRET |\
+ X86_BR_INT |\
+ X86_BR_IRET |\
+ X86_BR_JCC |\
+ X86_BR_JMP |\
+ X86_BR_IRQ |\
+ X86_BR_ABORT |\
+ X86_BR_IND_CALL |\
+ X86_BR_IND_JMP |\
+ X86_BR_ZERO_CALL)
+
+#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
+
+#define X86_BR_ANY_CALL \
+ (X86_BR_CALL |\
+ X86_BR_IND_CALL |\
+ X86_BR_ZERO_CALL |\
+ X86_BR_SYSCALL |\
+ X86_BR_IRQ |\
+ X86_BR_INT)
+
+static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
+
+/*
+ * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
+ * otherwise it becomes near impossible to get a reliable stack.
+ */
+
+static void __intel_pmu_lbr_enable(bool pmi)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ u64 debugctl, lbr_select = 0, orig_debugctl;
+
+ /*
+ * No need to unfreeze manually, as v4 can do that as part
+ * of the GLOBAL_STATUS ack.
+ */
+ if (pmi && x86_pmu.version >= 4)
+ return;
+
+ /*
+ * No need to reprogram LBR_SELECT in a PMI, as it
+ * did not change.
+ */
+ if (cpuc->lbr_sel)
+ lbr_select = cpuc->lbr_sel->config & x86_pmu.lbr_sel_mask;
+ if (!pmi && cpuc->lbr_sel)
+ wrmsrl(MSR_LBR_SELECT, lbr_select);
+
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+ orig_debugctl = debugctl;
+ debugctl |= DEBUGCTLMSR_LBR;
+ /*
+ * LBR callstack does not work well with FREEZE_LBRS_ON_PMI.
+ * If FREEZE_LBRS_ON_PMI is set, PMI near call/return instructions
+ * may cause superfluous increase/decrease of LBR_TOS.
+ */
+ if (!(lbr_select & LBR_CALL_STACK))
+ debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
+ if (orig_debugctl != debugctl)
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void __intel_pmu_lbr_disable(void)
+{
+ u64 debugctl;
+
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+ debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void intel_pmu_lbr_reset_32(void)
+{
+ int i;
+
+ for (i = 0; i < x86_pmu.lbr_nr; i++)
+ wrmsrl(x86_pmu.lbr_from + i, 0);
+}
+
+static void intel_pmu_lbr_reset_64(void)
+{
+ int i;
+
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ wrmsrl(x86_pmu.lbr_from + i, 0);
+ wrmsrl(x86_pmu.lbr_to + i, 0);
+ if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+ wrmsrl(MSR_LBR_INFO_0 + i, 0);
+ }
+}
+
+void intel_pmu_lbr_reset(void)
+{
+ if (!x86_pmu.lbr_nr)
+ return;
+
+ if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+ intel_pmu_lbr_reset_32();
+ else
+ intel_pmu_lbr_reset_64();
+}
+
+/*
+ * TOS = most recently recorded branch
+ */
+static inline u64 intel_pmu_lbr_tos(void)
+{
+ u64 tos;
+
+ rdmsrl(x86_pmu.lbr_tos, tos);
+ return tos;
+}
+
+enum {
+ LBR_NONE,
+ LBR_VALID,
+};
+
+static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
+{
+ int i;
+ unsigned lbr_idx, mask;
+ u64 tos;
+
+ if (task_ctx->lbr_callstack_users == 0 ||
+ task_ctx->lbr_stack_state == LBR_NONE) {
+ intel_pmu_lbr_reset();
+ return;
+ }
+
+ mask = x86_pmu.lbr_nr - 1;
+ tos = task_ctx->tos;
+ for (i = 0; i < tos; i++) {
+ lbr_idx = (tos - i) & mask;
+ wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+ wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+ if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+ wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
+ }
+ wrmsrl(x86_pmu.lbr_tos, tos);
+ task_ctx->lbr_stack_state = LBR_NONE;
+}
+
+static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
+{
+ int i;
+ unsigned lbr_idx, mask;
+ u64 tos;
+
+ if (task_ctx->lbr_callstack_users == 0) {
+ task_ctx->lbr_stack_state = LBR_NONE;
+ return;
+ }
+
+ mask = x86_pmu.lbr_nr - 1;
+ tos = intel_pmu_lbr_tos();
+ for (i = 0; i < tos; i++) {
+ lbr_idx = (tos - i) & mask;
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+ rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
+ if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+ rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
+ }
+ task_ctx->tos = tos;
+ task_ctx->lbr_stack_state = LBR_VALID;
+}
+
+void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct x86_perf_task_context *task_ctx;
+
+ /*
+ * If LBR callstack feature is enabled and the stack was saved when
+ * the task was scheduled out, restore the stack. Otherwise flush
+ * the LBR stack.
+ */
+ task_ctx = ctx ? ctx->task_ctx_data : NULL;
+ if (task_ctx) {
+ if (sched_in) {
+ __intel_pmu_lbr_restore(task_ctx);
+ cpuc->lbr_context = ctx;
+ } else {
+ __intel_pmu_lbr_save(task_ctx);
+ }
+ return;
+ }
+
+ /*
+ * When sampling the branck stack in system-wide, it may be
+ * necessary to flush the stack on context switch. This happens
+ * when the branch stack does not tag its entries with the pid
+ * of the current task. Otherwise it becomes impossible to
+ * associate a branch entry with a task. This ambiguity is more
+ * likely to appear when the branch stack supports priv level
+ * filtering and the user sets it to monitor only at the user
+ * level (which could be a useful measurement in system-wide
+ * mode). In that case, the risk is high of having a branch
+ * stack with branch from multiple tasks.
+ */
+ if (sched_in) {
+ intel_pmu_lbr_reset();
+ cpuc->lbr_context = ctx;
+ }
+}
+
+static inline bool branch_user_callstack(unsigned br_sel)
+{
+ return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK);
+}
+
+void intel_pmu_lbr_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct x86_perf_task_context *task_ctx;
+
+ if (!x86_pmu.lbr_nr)
+ return;
+
+ /*
+ * Reset the LBR stack if we changed task context to
+ * avoid data leaks.
+ */
+ if (event->ctx->task && cpuc->lbr_context != event->ctx) {
+ intel_pmu_lbr_reset();
+ cpuc->lbr_context = event->ctx;
+ }
+ cpuc->br_sel = event->hw.branch_reg.reg;
+
+ if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
+ event->ctx->task_ctx_data) {
+ task_ctx = event->ctx->task_ctx_data;
+ task_ctx->lbr_callstack_users++;
+ }
+
+ cpuc->lbr_users++;
+ perf_sched_cb_inc(event->ctx->pmu);
+}
+
+void intel_pmu_lbr_disable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct x86_perf_task_context *task_ctx;
+
+ if (!x86_pmu.lbr_nr)
+ return;
+
+ if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
+ event->ctx->task_ctx_data) {
+ task_ctx = event->ctx->task_ctx_data;
+ task_ctx->lbr_callstack_users--;
+ }
+
+ cpuc->lbr_users--;
+ WARN_ON_ONCE(cpuc->lbr_users < 0);
+ perf_sched_cb_dec(event->ctx->pmu);
+
+ if (cpuc->enabled && !cpuc->lbr_users) {
+ __intel_pmu_lbr_disable();
+ /* avoid stale pointer */
+ cpuc->lbr_context = NULL;
+ }
+}
+
+void intel_pmu_lbr_enable_all(bool pmi)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (cpuc->lbr_users)
+ __intel_pmu_lbr_enable(pmi);
+}
+
+void intel_pmu_lbr_disable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (cpuc->lbr_users)
+ __intel_pmu_lbr_disable();
+}
+
+static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+{
+ unsigned long mask = x86_pmu.lbr_nr - 1;
+ u64 tos = intel_pmu_lbr_tos();
+ int i;
+
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ unsigned long lbr_idx = (tos - i) & mask;
+ union {
+ struct {
+ u32 from;
+ u32 to;
+ };
+ u64 lbr;
+ } msr_lastbranch;
+
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+
+ cpuc->lbr_entries[i].from = msr_lastbranch.from;
+ cpuc->lbr_entries[i].to = msr_lastbranch.to;
+ cpuc->lbr_entries[i].mispred = 0;
+ cpuc->lbr_entries[i].predicted = 0;
+ cpuc->lbr_entries[i].reserved = 0;
+ }
+ cpuc->lbr_stack.nr = i;
+}
+
+/*
+ * Due to lack of segmentation in Linux the effective address (offset)
+ * is the same as the linear address, allowing us to merge the LIP and EIP
+ * LBR formats.
+ */
+static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+{
+ bool need_info = false;
+ unsigned long mask = x86_pmu.lbr_nr - 1;
+ int lbr_format = x86_pmu.intel_cap.lbr_format;
+ u64 tos = intel_pmu_lbr_tos();
+ int i;
+ int out = 0;
+ int num = x86_pmu.lbr_nr;
+
+ if (cpuc->lbr_sel) {
+ need_info = !(cpuc->lbr_sel->config & LBR_NO_INFO);
+ if (cpuc->lbr_sel->config & LBR_CALL_STACK)
+ num = tos;
+ }
+
+ for (i = 0; i < num; i++) {
+ unsigned long lbr_idx = (tos - i) & mask;
+ u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
+ int skip = 0;
+ u16 cycles = 0;
+ int lbr_flags = lbr_desc[lbr_format];
+
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
+ rdmsrl(x86_pmu.lbr_to + lbr_idx, to);
+
+ if (lbr_format == LBR_FORMAT_INFO && need_info) {
+ u64 info;
+
+ rdmsrl(MSR_LBR_INFO_0 + lbr_idx, info);
+ mis = !!(info & LBR_INFO_MISPRED);
+ pred = !mis;
+ in_tx = !!(info & LBR_INFO_IN_TX);
+ abort = !!(info & LBR_INFO_ABORT);
+ cycles = (info & LBR_INFO_CYCLES);
+ }
+ if (lbr_flags & LBR_EIP_FLAGS) {
+ mis = !!(from & LBR_FROM_FLAG_MISPRED);
+ pred = !mis;
+ skip = 1;
+ }
+ if (lbr_flags & LBR_TSX) {
+ in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
+ abort = !!(from & LBR_FROM_FLAG_ABORT);
+ skip = 3;
+ }
+ from = (u64)((((s64)from) << skip) >> skip);
+
+ /*
+ * Some CPUs report duplicated abort records,
+ * with the second entry not having an abort bit set.
+ * Skip them here. This loop runs backwards,
+ * so we need to undo the previous record.
+ * If the abort just happened outside the window
+ * the extra entry cannot be removed.
+ */
+ if (abort && x86_pmu.lbr_double_abort && out > 0)
+ out--;
+
+ cpuc->lbr_entries[out].from = from;
+ cpuc->lbr_entries[out].to = to;
+ cpuc->lbr_entries[out].mispred = mis;
+ cpuc->lbr_entries[out].predicted = pred;
+ cpuc->lbr_entries[out].in_tx = in_tx;
+ cpuc->lbr_entries[out].abort = abort;
+ cpuc->lbr_entries[out].cycles = cycles;
+ cpuc->lbr_entries[out].reserved = 0;
+ out++;
+ }
+ cpuc->lbr_stack.nr = out;
+}
+
+void intel_pmu_lbr_read(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (!cpuc->lbr_users)
+ return;
+
+ if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+ intel_pmu_lbr_read_32(cpuc);
+ else
+ intel_pmu_lbr_read_64(cpuc);
+
+ intel_pmu_lbr_filter(cpuc);
+}
+
+/*
+ * SW filter is used:
+ * - in case there is no HW filter
+ * - in case the HW filter has errata or limitations
+ */
+static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
+{
+ u64 br_type = event->attr.branch_sample_type;
+ int mask = 0;
+
+ if (br_type & PERF_SAMPLE_BRANCH_USER)
+ mask |= X86_BR_USER;
+
+ if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
+ mask |= X86_BR_KERNEL;
+
+ /* we ignore BRANCH_HV here */
+
+ if (br_type & PERF_SAMPLE_BRANCH_ANY)
+ mask |= X86_BR_ANY;
+
+ if (br_type & PERF_SAMPLE_BRANCH_ANY_CALL)
+ mask |= X86_BR_ANY_CALL;
+
+ if (br_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+ mask |= X86_BR_RET | X86_BR_IRET | X86_BR_SYSRET;
+
+ if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
+ mask |= X86_BR_IND_CALL;
+
+ if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
+ mask |= X86_BR_ABORT;
+
+ if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
+ mask |= X86_BR_IN_TX;
+
+ if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
+ mask |= X86_BR_NO_TX;
+
+ if (br_type & PERF_SAMPLE_BRANCH_COND)
+ mask |= X86_BR_JCC;
+
+ if (br_type & PERF_SAMPLE_BRANCH_CALL_STACK) {
+ if (!x86_pmu_has_lbr_callstack())
+ return -EOPNOTSUPP;
+ if (mask & ~(X86_BR_USER | X86_BR_KERNEL))
+ return -EINVAL;
+ mask |= X86_BR_CALL | X86_BR_IND_CALL | X86_BR_RET |
+ X86_BR_CALL_STACK;
+ }
+
+ if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
+ mask |= X86_BR_IND_JMP;
+
+ if (br_type & PERF_SAMPLE_BRANCH_CALL)
+ mask |= X86_BR_CALL | X86_BR_ZERO_CALL;
+ /*
+ * stash actual user request into reg, it may
+ * be used by fixup code for some CPU
+ */
+ event->hw.branch_reg.reg = mask;
+ return 0;
+}
+
+/*
+ * setup the HW LBR filter
+ * Used only when available, may not be enough to disambiguate
+ * all branches, may need the help of the SW filter
+ */
+static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg;
+ u64 br_type = event->attr.branch_sample_type;
+ u64 mask = 0, v;
+ int i;
+
+ for (i = 0; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) {
+ if (!(br_type & (1ULL << i)))
+ continue;
+
+ v = x86_pmu.lbr_sel_map[i];
+ if (v == LBR_NOT_SUPP)
+ return -EOPNOTSUPP;
+
+ if (v != LBR_IGN)
+ mask |= v;
+ }
+
+ reg = &event->hw.branch_reg;
+ reg->idx = EXTRA_REG_LBR;
+
+ /*
+ * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate
+ * in suppress mode. So LBR_SELECT should be set to
+ * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK)
+ */
+ reg->config = mask ^ x86_pmu.lbr_sel_mask;
+
+ if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) &&
+ (br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) &&
+ (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO))
+ reg->config |= LBR_NO_INFO;
+
+ return 0;
+}
+
+int intel_pmu_setup_lbr_filter(struct perf_event *event)
+{
+ int ret = 0;
+
+ /*
+ * no LBR on this PMU
+ */
+ if (!x86_pmu.lbr_nr)
+ return -EOPNOTSUPP;
+
+ /*
+ * setup SW LBR filter
+ */
+ ret = intel_pmu_setup_sw_lbr_filter(event);
+ if (ret)
+ return ret;
+
+ /*
+ * setup HW LBR filter, if any
+ */
+ if (x86_pmu.lbr_sel_map)
+ ret = intel_pmu_setup_hw_lbr_filter(event);
+
+ return ret;
+}
+
+/*
+ * return the type of control flow change at address "from"
+ * intruction is not necessarily a branch (in case of interrupt).
+ *
+ * The branch type returned also includes the priv level of the
+ * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
+ *
+ * If a branch type is unknown OR the instruction cannot be
+ * decoded (e.g., text page not present), then X86_BR_NONE is
+ * returned.
+ */
+static int branch_type(unsigned long from, unsigned long to, int abort)
+{
+ struct insn insn;
+ void *addr;
+ int bytes_read, bytes_left;
+ int ret = X86_BR_NONE;
+ int ext, to_plm, from_plm;
+ u8 buf[MAX_INSN_SIZE];
+ int is64 = 0;
+
+ to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
+ from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
+
+ /*
+ * maybe zero if lbr did not fill up after a reset by the time
+ * we get a PMU interrupt
+ */
+ if (from == 0 || to == 0)
+ return X86_BR_NONE;
+
+ if (abort)
+ return X86_BR_ABORT | to_plm;
+
+ if (from_plm == X86_BR_USER) {
+ /*
+ * can happen if measuring at the user level only
+ * and we interrupt in a kernel thread, e.g., idle.
+ */
+ if (!current->mm)
+ return X86_BR_NONE;
+
+ /* may fail if text not present */
+ bytes_left = copy_from_user_nmi(buf, (void __user *)from,
+ MAX_INSN_SIZE);
+ bytes_read = MAX_INSN_SIZE - bytes_left;
+ if (!bytes_read)
+ return X86_BR_NONE;
+
+ addr = buf;
+ } else {
+ /*
+ * The LBR logs any address in the IP, even if the IP just
+ * faulted. This means userspace can control the from address.
+ * Ensure we don't blindy read any address by validating it is
+ * a known text address.
+ */
+ if (kernel_text_address(from)) {
+ addr = (void *)from;
+ /*
+ * Assume we can get the maximum possible size
+ * when grabbing kernel data. This is not
+ * _strictly_ true since we could possibly be
+ * executing up next to a memory hole, but
+ * it is very unlikely to be a problem.
+ */
+ bytes_read = MAX_INSN_SIZE;
+ } else {
+ return X86_BR_NONE;
+ }
+ }
+
+ /*
+ * decoder needs to know the ABI especially
+ * on 64-bit systems running 32-bit apps
+ */
+#ifdef CONFIG_X86_64
+ is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
+#endif
+ insn_init(&insn, addr, bytes_read, is64);
+ insn_get_opcode(&insn);
+ if (!insn.opcode.got)
+ return X86_BR_ABORT;
+
+ switch (insn.opcode.bytes[0]) {
+ case 0xf:
+ switch (insn.opcode.bytes[1]) {
+ case 0x05: /* syscall */
+ case 0x34: /* sysenter */
+ ret = X86_BR_SYSCALL;
+ break;
+ case 0x07: /* sysret */
+ case 0x35: /* sysexit */
+ ret = X86_BR_SYSRET;
+ break;
+ case 0x80 ... 0x8f: /* conditional */
+ ret = X86_BR_JCC;
+ break;
+ default:
+ ret = X86_BR_NONE;
+ }
+ break;
+ case 0x70 ... 0x7f: /* conditional */
+ ret = X86_BR_JCC;
+ break;
+ case 0xc2: /* near ret */
+ case 0xc3: /* near ret */
+ case 0xca: /* far ret */
+ case 0xcb: /* far ret */
+ ret = X86_BR_RET;
+ break;
+ case 0xcf: /* iret */
+ ret = X86_BR_IRET;
+ break;
+ case 0xcc ... 0xce: /* int */
+ ret = X86_BR_INT;
+ break;
+ case 0xe8: /* call near rel */
+ insn_get_immediate(&insn);
+ if (insn.immediate1.value == 0) {
+ /* zero length call */
+ ret = X86_BR_ZERO_CALL;
+ break;
+ }
+ case 0x9a: /* call far absolute */
+ ret = X86_BR_CALL;
+ break;
+ case 0xe0 ... 0xe3: /* loop jmp */
+ ret = X86_BR_JCC;
+ break;
+ case 0xe9 ... 0xeb: /* jmp */
+ ret = X86_BR_JMP;
+ break;
+ case 0xff: /* call near absolute, call far absolute ind */
+ insn_get_modrm(&insn);
+ ext = (insn.modrm.bytes[0] >> 3) & 0x7;
+ switch (ext) {
+ case 2: /* near ind call */
+ case 3: /* far ind call */
+ ret = X86_BR_IND_CALL;
+ break;
+ case 4:
+ case 5:
+ ret = X86_BR_IND_JMP;
+ break;
+ }
+ break;
+ default:
+ ret = X86_BR_NONE;
+ }
+ /*
+ * interrupts, traps, faults (and thus ring transition) may
+ * occur on any instructions. Thus, to classify them correctly,
+ * we need to first look at the from and to priv levels. If they
+ * are different and to is in the kernel, then it indicates
+ * a ring transition. If the from instruction is not a ring
+ * transition instr (syscall, systenter, int), then it means
+ * it was a irq, trap or fault.
+ *
+ * we have no way of detecting kernel to kernel faults.
+ */
+ if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
+ && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
+ ret = X86_BR_IRQ;
+
+ /*
+ * branch priv level determined by target as
+ * is done by HW when LBR_SELECT is implemented
+ */
+ if (ret != X86_BR_NONE)
+ ret |= to_plm;
+
+ return ret;
+}
+
+/*
+ * implement actual branch filter based on user demand.
+ * Hardware may not exactly satisfy that request, thus
+ * we need to inspect opcodes. Mismatched branches are
+ * discarded. Therefore, the number of branches returned
+ * in PERF_SAMPLE_BRANCH_STACK sample may vary.
+ */
+static void
+intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
+{
+ u64 from, to;
+ int br_sel = cpuc->br_sel;
+ int i, j, type;
+ bool compress = false;
+
+ /* if sampling all branches, then nothing to filter */
+ if ((br_sel & X86_BR_ALL) == X86_BR_ALL)
+ return;
+
+ for (i = 0; i < cpuc->lbr_stack.nr; i++) {
+
+ from = cpuc->lbr_entries[i].from;
+ to = cpuc->lbr_entries[i].to;
+
+ type = branch_type(from, to, cpuc->lbr_entries[i].abort);
+ if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
+ if (cpuc->lbr_entries[i].in_tx)
+ type |= X86_BR_IN_TX;
+ else
+ type |= X86_BR_NO_TX;
+ }
+
+ /* if type does not correspond, then discard */
+ if (type == X86_BR_NONE || (br_sel & type) != type) {
+ cpuc->lbr_entries[i].from = 0;
+ compress = true;
+ }
+ }
+
+ if (!compress)
+ return;
+
+ /* remove all entries with from=0 */
+ for (i = 0; i < cpuc->lbr_stack.nr; ) {
+ if (!cpuc->lbr_entries[i].from) {
+ j = i;
+ while (++j < cpuc->lbr_stack.nr)
+ cpuc->lbr_entries[j-1] = cpuc->lbr_entries[j];
+ cpuc->lbr_stack.nr--;
+ if (!cpuc->lbr_entries[i].from)
+ continue;
+ }
+ i++;
+ }
+}
+
+/*
+ * Map interface branch filters onto LBR filters
+ */
+static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+ [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
+ [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
+ [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
+ [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
+ [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_REL_JMP
+ | LBR_IND_JMP | LBR_FAR,
+ /*
+ * NHM/WSM erratum: must include REL_JMP+IND_JMP to get CALL branches
+ */
+ [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] =
+ LBR_REL_CALL | LBR_IND_CALL | LBR_REL_JMP | LBR_IND_JMP | LBR_FAR,
+ /*
+ * NHM/WSM erratum: must include IND_JMP to capture IND_CALL
+ */
+ [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
+ [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
+};
+
+static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+ [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
+ [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
+ [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
+ [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
+ [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_FAR,
+ [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
+ | LBR_FAR,
+ [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
+ [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
+ [PERF_SAMPLE_BRANCH_CALL_SHIFT] = LBR_REL_CALL,
+};
+
+static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
+ [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
+ [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
+ [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
+ [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
+ [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_FAR,
+ [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
+ | LBR_FAR,
+ [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
+ [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
+ [PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
+ | LBR_RETURN | LBR_CALL_STACK,
+ [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
+ [PERF_SAMPLE_BRANCH_CALL_SHIFT] = LBR_REL_CALL,
+};
+
+/* core */
+void __init intel_pmu_lbr_init_core(void)
+{
+ x86_pmu.lbr_nr = 4;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
+
+ /*
+ * SW branch filter usage:
+ * - compensate for lack of HW filter
+ */
+ pr_cont("4-deep LBR, ");
+}
+
+/* nehalem/westmere */
+void __init intel_pmu_lbr_init_nhm(void)
+{
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
+
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
+
+ /*
+ * SW branch filter usage:
+ * - workaround LBR_SEL errata (see above)
+ * - support syscall, sysret capture.
+ * That requires LBR_FAR but that means far
+ * jmp need to be filtered out
+ */
+ pr_cont("16-deep LBR, ");
+}
+
+/* sandy bridge */
+void __init intel_pmu_lbr_init_snb(void)
+{
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
+
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = snb_lbr_sel_map;
+
+ /*
+ * SW branch filter usage:
+ * - support syscall, sysret capture.
+ * That requires LBR_FAR but that means far
+ * jmp need to be filtered out
+ */
+ pr_cont("16-deep LBR, ");
+}
+
+/* haswell */
+void intel_pmu_lbr_init_hsw(void)
+{
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
+
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
+
+ pr_cont("16-deep LBR, ");
+}
+
+/* skylake */
+__init void intel_pmu_lbr_init_skl(void)
+{
+ x86_pmu.lbr_nr = 32;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
+
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
+
+ /*
+ * SW branch filter usage:
+ * - support syscall, sysret capture.
+ * That requires LBR_FAR but that means far
+ * jmp need to be filtered out
+ */
+ pr_cont("32-deep LBR, ");
+}
+
+/* atom */
+void __init intel_pmu_lbr_init_atom(void)
+{
+ /*
+ * only models starting at stepping 10 seems
+ * to have an operational LBR which can freeze
+ * on PMU interrupt
+ */
+ if (boot_cpu_data.x86_model == 28
+ && boot_cpu_data.x86_mask < 10) {
+ pr_cont("LBR disabled due to erratum");
+ return;
+ }
+
+ x86_pmu.lbr_nr = 8;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
+
+ /*
+ * SW branch filter usage:
+ * - compensate for lack of HW filter
+ */
+ pr_cont("8-deep LBR, ");
+}
+
+/* Knights Landing */
+void intel_pmu_lbr_init_knl(void)
+{
+ x86_pmu.lbr_nr = 8;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
+
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = snb_lbr_sel_map;
+
+ pr_cont("8-deep LBR, ");
+}
diff --git a/arch/x86/events/intel/p4.c b/arch/x86/events/intel/p4.c
new file mode 100644
index 0000000..0a5ede1
--- /dev/null
+++ b/arch/x86/events/intel/p4.c
@@ -0,0 +1,1376 @@
+/*
+ * Netburst Performance Events (P4, old Xeon)
+ *
+ * Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
+ * Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+
+#include <asm/perf_event_p4.h>
+#include <asm/hardirq.h>
+#include <asm/apic.h>
+
+#include "../perf_event.h"
+
+#define P4_CNTR_LIMIT 3
+/*
+ * array indices: 0,1 - HT threads, used with HT enabled cpu
+ */
+struct p4_event_bind {
+ unsigned int opcode; /* Event code and ESCR selector */
+ unsigned int escr_msr[2]; /* ESCR MSR for this event */
+ unsigned int escr_emask; /* valid ESCR EventMask bits */
+ unsigned int shared; /* event is shared across threads */
+ char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */
+};
+
+struct p4_pebs_bind {
+ unsigned int metric_pebs;
+ unsigned int metric_vert;
+};
+
+/* it sets P4_PEBS_ENABLE_UOP_TAG as well */
+#define P4_GEN_PEBS_BIND(name, pebs, vert) \
+ [P4_PEBS_METRIC__##name] = { \
+ .metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG, \
+ .metric_vert = vert, \
+ }
+
+/*
+ * note we have P4_PEBS_ENABLE_UOP_TAG always set here
+ *
+ * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of
+ * event configuration to find out which values are to be
+ * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT
+ * resgisters
+ */
+static struct p4_pebs_bind p4_pebs_bind_map[] = {
+ P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired, 0x0000001, 0x0000001),
+ P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired, 0x0000002, 0x0000001),
+ P4_GEN_PEBS_BIND(dtlb_load_miss_retired, 0x0000004, 0x0000001),
+ P4_GEN_PEBS_BIND(dtlb_store_miss_retired, 0x0000004, 0x0000002),
+ P4_GEN_PEBS_BIND(dtlb_all_miss_retired, 0x0000004, 0x0000003),
+ P4_GEN_PEBS_BIND(tagged_mispred_branch, 0x0018000, 0x0000010),
+ P4_GEN_PEBS_BIND(mob_load_replay_retired, 0x0000200, 0x0000001),
+ P4_GEN_PEBS_BIND(split_load_retired, 0x0000400, 0x0000001),
+ P4_GEN_PEBS_BIND(split_store_retired, 0x0000400, 0x0000002),
+};
+
+/*
+ * Note that we don't use CCCR1 here, there is an
+ * exception for P4_BSQ_ALLOCATION but we just have
+ * no workaround
+ *
+ * consider this binding as resources which particular
+ * event may borrow, it doesn't contain EventMask,
+ * Tags and friends -- they are left to a caller
+ */
+static struct p4_event_bind p4_event_bind_map[] = {
+ [P4_EVENT_TC_DELIVER_MODE] = {
+ .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
+ .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID),
+ .shared = 1,
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_BPU_FETCH_REQUEST] = {
+ .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
+ .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_ITLB_REFERENCE] = {
+ .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
+ .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_MEMORY_CANCEL] = {
+ .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
+ .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF),
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_MEMORY_COMPLETE] = {
+ .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
+ .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC),
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_LOAD_PORT_REPLAY] = {
+ .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
+ .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD),
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_STORE_PORT_REPLAY] = {
+ .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
+ .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST),
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_MOB_LOAD_REPLAY] = {
+ .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
+ .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_PAGE_WALK_TYPE] = {
+ .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
+ .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS),
+ .shared = 1,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_BSQ_CACHE_REFERENCE] = {
+ .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
+ .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_IOQ_ALLOCATION] = {
+ .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */
+ .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
+ .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH),
+ .cntr = { {2, -1, -1}, {3, -1, -1} },
+ },
+ [P4_EVENT_FSB_DATA_ACTIVITY] = {
+ .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER),
+ .shared = 1,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */
+ .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
+ .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2),
+ .cntr = { {0, -1, -1}, {1, -1, -1} },
+ },
+ [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */
+ .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
+ .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2),
+ .cntr = { {2, -1, -1}, {3, -1, -1} },
+ },
+ [P4_EVENT_SSE_INPUT_ASSIST] = {
+ .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_PACKED_SP_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_PACKED_DP_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_SCALAR_SP_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_SCALAR_DP_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_64BIT_MMX_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_128BIT_MMX_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_X87_FP_UOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP),
+ .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_TC_MISC] = {
+ .opcode = P4_OPCODE(P4_EVENT_TC_MISC),
+ .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH),
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_GLOBAL_POWER_EVENTS] = {
+ .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING),
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_TC_MS_XFER] = {
+ .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER),
+ .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC),
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_UOP_QUEUE_WRITES] = {
+ .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
+ .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM),
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
+ .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
+ .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT),
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_RETIRED_BRANCH_TYPE] = {
+ .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
+ .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT),
+ .cntr = { {4, 5, -1}, {6, 7, -1} },
+ },
+ [P4_EVENT_RESOURCE_STALL] = {
+ .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
+ .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_WC_BUFFER] = {
+ .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER),
+ .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS),
+ .shared = 1,
+ .cntr = { {8, 9, -1}, {10, 11, -1} },
+ },
+ [P4_EVENT_B2B_CYCLES] = {
+ .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_BNR] = {
+ .opcode = P4_OPCODE(P4_EVENT_BNR),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_SNOOP] = {
+ .opcode = P4_OPCODE(P4_EVENT_SNOOP),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_RESPONSE] = {
+ .opcode = P4_OPCODE(P4_EVENT_RESPONSE),
+ .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+ .escr_emask = 0,
+ .cntr = { {0, -1, -1}, {2, -1, -1} },
+ },
+ [P4_EVENT_FRONT_END_EVENT] = {
+ .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_EXECUTION_EVENT] = {
+ .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_REPLAY_EVENT] = {
+ .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_INSTR_RETIRED] = {
+ .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
+ .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_UOPS_RETIRED] = {
+ .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
+ .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_UOP_TYPE] = {
+ .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE),
+ .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_BRANCH_RETIRED] = {
+ .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_MISPRED_BRANCH_RETIRED] = {
+ .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
+ .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_X87_ASSIST] = {
+ .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_MACHINE_CLEAR] = {
+ .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
+ .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+ [P4_EVENT_INSTR_COMPLETED] = {
+ .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
+ .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+ .escr_emask =
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS),
+ .cntr = { {12, 13, 16}, {14, 15, 17} },
+ },
+};
+
+#define P4_GEN_CACHE_EVENT(event, bit, metric) \
+ p4_config_pack_escr(P4_ESCR_EVENT(event) | \
+ P4_ESCR_EMASK_BIT(event, bit)) | \
+ p4_config_pack_cccr(metric | \
+ P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
+
+static __initconst const u64 p4_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+ P4_PEBS_METRIC__1stl_cache_load_miss_retired),
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+ P4_PEBS_METRIC__2ndl_cache_load_miss_retired),
+ },
+},
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+ P4_PEBS_METRIC__dtlb_load_miss_retired),
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+ P4_PEBS_METRIC__dtlb_store_miss_retired),
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
+ P4_PEBS_METRIC__none),
+ [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
+ P4_PEBS_METRIC__none),
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+/*
+ * Because of Netburst being quite restricted in how many
+ * identical events may run simultaneously, we introduce event aliases,
+ * ie the different events which have the same functionality but
+ * utilize non-intersected resources (ESCR/CCCR/counter registers).
+ *
+ * This allow us to relax restrictions a bit and run two or more
+ * identical events together.
+ *
+ * Never set any custom internal bits such as P4_CONFIG_HT,
+ * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are
+ * either up to date automatically or not applicable at all.
+ */
+struct p4_event_alias {
+ u64 original;
+ u64 alternative;
+} p4_event_aliases[] = {
+ {
+ /*
+ * Non-halted cycles can be substituted with non-sleeping cycles (see
+ * Intel SDM Vol3b for details). We need this alias to be able
+ * to run nmi-watchdog and 'perf top' (or any other user space tool
+ * which is interested in running PERF_COUNT_HW_CPU_CYCLES)
+ * simultaneously.
+ */
+ .original =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
+ .alternative =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_EXECUTION_EVENT) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)|
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)|
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)|
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)|
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3))|
+ p4_config_pack_cccr(P4_CCCR_THRESHOLD(15) | P4_CCCR_COMPLEMENT |
+ P4_CCCR_COMPARE),
+ },
+};
+
+static u64 p4_get_alias_event(u64 config)
+{
+ u64 config_match;
+ int i;
+
+ /*
+ * Only event with special mark is allowed,
+ * we're to be sure it didn't come as malformed
+ * RAW event.
+ */
+ if (!(config & P4_CONFIG_ALIASABLE))
+ return 0;
+
+ config_match = config & P4_CONFIG_EVENT_ALIAS_MASK;
+
+ for (i = 0; i < ARRAY_SIZE(p4_event_aliases); i++) {
+ if (config_match == p4_event_aliases[i].original) {
+ config_match = p4_event_aliases[i].alternative;
+ break;
+ } else if (config_match == p4_event_aliases[i].alternative) {
+ config_match = p4_event_aliases[i].original;
+ break;
+ }
+ }
+
+ if (i >= ARRAY_SIZE(p4_event_aliases))
+ return 0;
+
+ return config_match | (config & P4_CONFIG_EVENT_ALIAS_IMMUTABLE_BITS);
+}
+
+static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
+ /* non-halted CPU clocks */
+ [PERF_COUNT_HW_CPU_CYCLES] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)) |
+ P4_CONFIG_ALIASABLE,
+
+ /*
+ * retired instructions
+ * in a sake of simplicity we don't use the FSB tagging
+ */
+ [PERF_COUNT_HW_INSTRUCTIONS] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
+
+ /* cache hits */
+ [PERF_COUNT_HW_CACHE_REFERENCES] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
+
+ /* cache misses */
+ [PERF_COUNT_HW_CACHE_MISSES] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
+
+ /* branch instructions retired */
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
+
+ /* mispredicted branches retired */
+ [PERF_COUNT_HW_BRANCH_MISSES] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
+
+ /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */
+ [PERF_COUNT_HW_BUS_CYCLES] =
+ p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
+ P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)) |
+ p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
+};
+
+static struct p4_event_bind *p4_config_get_bind(u64 config)
+{
+ unsigned int evnt = p4_config_unpack_event(config);
+ struct p4_event_bind *bind = NULL;
+
+ if (evnt < ARRAY_SIZE(p4_event_bind_map))
+ bind = &p4_event_bind_map[evnt];
+
+ return bind;
+}
+
+static u64 p4_pmu_event_map(int hw_event)
+{
+ struct p4_event_bind *bind;
+ unsigned int esel;
+ u64 config;
+
+ config = p4_general_events[hw_event];
+ bind = p4_config_get_bind(config);
+ esel = P4_OPCODE_ESEL(bind->opcode);
+ config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+
+ return config;
+}
+
+/* check cpu model specifics */
+static bool p4_event_match_cpu_model(unsigned int event_idx)
+{
+ /* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */
+ if (event_idx == P4_EVENT_INSTR_COMPLETED) {
+ if (boot_cpu_data.x86_model != 3 &&
+ boot_cpu_data.x86_model != 4 &&
+ boot_cpu_data.x86_model != 6)
+ return false;
+ }
+
+ /*
+ * For info
+ * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2
+ */
+
+ return true;
+}
+
+static int p4_validate_raw_event(struct perf_event *event)
+{
+ unsigned int v, emask;
+
+ /* User data may have out-of-bound event index */
+ v = p4_config_unpack_event(event->attr.config);
+ if (v >= ARRAY_SIZE(p4_event_bind_map))
+ return -EINVAL;
+
+ /* It may be unsupported: */
+ if (!p4_event_match_cpu_model(v))
+ return -EINVAL;
+
+ /*
+ * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as
+ * in Architectural Performance Monitoring, it means not
+ * on _which_ logical cpu to count but rather _when_, ie it
+ * depends on logical cpu state -- count event if one cpu active,
+ * none, both or any, so we just allow user to pass any value
+ * desired.
+ *
+ * In turn we always set Tx_OS/Tx_USR bits bound to logical
+ * cpu without their propagation to another cpu
+ */
+
+ /*
+ * if an event is shared across the logical threads
+ * the user needs special permissions to be able to use it
+ */
+ if (p4_ht_active() && p4_event_bind_map[v].shared) {
+ if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ }
+
+ /* ESCR EventMask bits may be invalid */
+ emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK;
+ if (emask & ~p4_event_bind_map[v].escr_emask)
+ return -EINVAL;
+
+ /*
+ * it may have some invalid PEBS bits
+ */
+ if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE))
+ return -EINVAL;
+
+ v = p4_config_unpack_metric(event->attr.config);
+ if (v >= ARRAY_SIZE(p4_pebs_bind_map))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int p4_hw_config(struct perf_event *event)
+{
+ int cpu = get_cpu();
+ int rc = 0;
+ u32 escr, cccr;
+
+ /*
+ * the reason we use cpu that early is that: if we get scheduled
+ * first time on the same cpu -- we will not need swap thread
+ * specific flags in config (and will save some cpu cycles)
+ */
+
+ cccr = p4_default_cccr_conf(cpu);
+ escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
+ event->attr.exclude_user);
+ event->hw.config = p4_config_pack_escr(escr) |
+ p4_config_pack_cccr(cccr);
+
+ if (p4_ht_active() && p4_ht_thread(cpu))
+ event->hw.config = p4_set_ht_bit(event->hw.config);
+
+ if (event->attr.type == PERF_TYPE_RAW) {
+ struct p4_event_bind *bind;
+ unsigned int esel;
+ /*
+ * Clear bits we reserve to be managed by kernel itself
+ * and never allowed from a user space
+ */
+ event->attr.config &= P4_CONFIG_MASK;
+
+ rc = p4_validate_raw_event(event);
+ if (rc)
+ goto out;
+
+ /*
+ * Note that for RAW events we allow user to use P4_CCCR_RESERVED
+ * bits since we keep additional info here (for cache events and etc)
+ */
+ event->hw.config |= event->attr.config;
+ bind = p4_config_get_bind(event->attr.config);
+ if (!bind) {
+ rc = -EINVAL;
+ goto out;
+ }
+ esel = P4_OPCODE_ESEL(bind->opcode);
+ event->hw.config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+ }
+
+ rc = x86_setup_perfctr(event);
+out:
+ put_cpu();
+ return rc;
+}
+
+static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
+{
+ u64 v;
+
+ /* an official way for overflow indication */
+ rdmsrl(hwc->config_base, v);
+ if (v & P4_CCCR_OVF) {
+ wrmsrl(hwc->config_base, v & ~P4_CCCR_OVF);
+ return 1;
+ }
+
+ /*
+ * In some circumstances the overflow might issue an NMI but did
+ * not set P4_CCCR_OVF bit. Because a counter holds a negative value
+ * we simply check for high bit being set, if it's cleared it means
+ * the counter has reached zero value and continued counting before
+ * real NMI signal was received:
+ */
+ rdmsrl(hwc->event_base, v);
+ if (!(v & ARCH_P4_UNFLAGGED_BIT))
+ return 1;
+
+ return 0;
+}
+
+static void p4_pmu_disable_pebs(void)
+{
+ /*
+ * FIXME
+ *
+ * It's still allowed that two threads setup same cache
+ * events so we can't simply clear metrics until we knew
+ * no one is depending on us, so we need kind of counter
+ * for "ReplayEvent" users.
+ *
+ * What is more complex -- RAW events, if user (for some
+ * reason) will pass some cache event metric with improper
+ * event opcode -- it's fine from hardware point of view
+ * but completely nonsense from "meaning" of such action.
+ *
+ * So at moment let leave metrics turned on forever -- it's
+ * ok for now but need to be revisited!
+ *
+ * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, 0);
+ * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, 0);
+ */
+}
+
+static inline void p4_pmu_disable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ /*
+ * If event gets disabled while counter is in overflowed
+ * state we need to clear P4_CCCR_OVF, otherwise interrupt get
+ * asserted again and again
+ */
+ (void)wrmsrl_safe(hwc->config_base,
+ p4_config_unpack_cccr(hwc->config) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
+}
+
+static void p4_pmu_disable_all(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ struct perf_event *event = cpuc->events[idx];
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+ p4_pmu_disable_event(event);
+ }
+
+ p4_pmu_disable_pebs();
+}
+
+/* configuration must be valid */
+static void p4_pmu_enable_pebs(u64 config)
+{
+ struct p4_pebs_bind *bind;
+ unsigned int idx;
+
+ BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK);
+
+ idx = p4_config_unpack_metric(config);
+ if (idx == P4_PEBS_METRIC__none)
+ return;
+
+ bind = &p4_pebs_bind_map[idx];
+
+ (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs);
+ (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert);
+}
+
+static void p4_pmu_enable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int thread = p4_ht_config_thread(hwc->config);
+ u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
+ unsigned int idx = p4_config_unpack_event(hwc->config);
+ struct p4_event_bind *bind;
+ u64 escr_addr, cccr;
+
+ bind = &p4_event_bind_map[idx];
+ escr_addr = bind->escr_msr[thread];
+
+ /*
+ * - we dont support cascaded counters yet
+ * - and counter 1 is broken (erratum)
+ */
+ WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
+ WARN_ON_ONCE(hwc->idx == 1);
+
+ /* we need a real Event value */
+ escr_conf &= ~P4_ESCR_EVENT_MASK;
+ escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
+
+ cccr = p4_config_unpack_cccr(hwc->config);
+
+ /*
+ * it could be Cache event so we need to write metrics
+ * into additional MSRs
+ */
+ p4_pmu_enable_pebs(hwc->config);
+
+ (void)wrmsrl_safe(escr_addr, escr_conf);
+ (void)wrmsrl_safe(hwc->config_base,
+ (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
+}
+
+static void p4_pmu_enable_all(int added)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int idx;
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ struct perf_event *event = cpuc->events[idx];
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+ p4_pmu_enable_event(event);
+ }
+}
+
+static int p4_pmu_handle_irq(struct pt_regs *regs)
+{
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct perf_event *event;
+ struct hw_perf_event *hwc;
+ int idx, handled = 0;
+ u64 val;
+
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ int overflow;
+
+ if (!test_bit(idx, cpuc->active_mask)) {
+ /* catch in-flight IRQs */
+ if (__test_and_clear_bit(idx, cpuc->running))
+ handled++;
+ continue;
+ }
+
+ event = cpuc->events[idx];
+ hwc = &event->hw;
+
+ WARN_ON_ONCE(hwc->idx != idx);
+
+ /* it might be unflagged overflow */
+ overflow = p4_pmu_clear_cccr_ovf(hwc);
+
+ val = x86_perf_event_update(event);
+ if (!overflow && (val & (1ULL << (x86_pmu.cntval_bits - 1))))
+ continue;
+
+ handled += overflow;
+
+ /* event overflow for sure */
+ perf_sample_data_init(&data, 0, hwc->last_period);
+
+ if (!x86_perf_event_set_period(event))
+ continue;
+
+
+ if (perf_event_overflow(event, &data, regs))
+ x86_pmu_stop(event, 0);
+ }
+
+ if (handled)
+ inc_irq_stat(apic_perf_irqs);
+
+ /*
+ * When dealing with the unmasking of the LVTPC on P4 perf hw, it has
+ * been observed that the OVF bit flag has to be cleared first _before_
+ * the LVTPC can be unmasked.
+ *
+ * The reason is the NMI line will continue to be asserted while the OVF
+ * bit is set. This causes a second NMI to generate if the LVTPC is
+ * unmasked before the OVF bit is cleared, leading to unknown NMI
+ * messages.
+ */
+ apic_write(APIC_LVTPC, APIC_DM_NMI);
+
+ return handled;
+}
+
+/*
+ * swap thread specific fields according to a thread
+ * we are going to run on
+ */
+static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
+{
+ u32 escr, cccr;
+
+ /*
+ * we either lucky and continue on same cpu or no HT support
+ */
+ if (!p4_should_swap_ts(hwc->config, cpu))
+ return;
+
+ /*
+ * the event is migrated from an another logical
+ * cpu, so we need to swap thread specific flags
+ */
+
+ escr = p4_config_unpack_escr(hwc->config);
+ cccr = p4_config_unpack_cccr(hwc->config);
+
+ if (p4_ht_thread(cpu)) {
+ cccr &= ~P4_CCCR_OVF_PMI_T0;
+ cccr |= P4_CCCR_OVF_PMI_T1;
+ if (escr & P4_ESCR_T0_OS) {
+ escr &= ~P4_ESCR_T0_OS;
+ escr |= P4_ESCR_T1_OS;
+ }
+ if (escr & P4_ESCR_T0_USR) {
+ escr &= ~P4_ESCR_T0_USR;
+ escr |= P4_ESCR_T1_USR;
+ }
+ hwc->config = p4_config_pack_escr(escr);
+ hwc->config |= p4_config_pack_cccr(cccr);
+ hwc->config |= P4_CONFIG_HT;
+ } else {
+ cccr &= ~P4_CCCR_OVF_PMI_T1;
+ cccr |= P4_CCCR_OVF_PMI_T0;
+ if (escr & P4_ESCR_T1_OS) {
+ escr &= ~P4_ESCR_T1_OS;
+ escr |= P4_ESCR_T0_OS;
+ }
+ if (escr & P4_ESCR_T1_USR) {
+ escr &= ~P4_ESCR_T1_USR;
+ escr |= P4_ESCR_T0_USR;
+ }
+ hwc->config = p4_config_pack_escr(escr);
+ hwc->config |= p4_config_pack_cccr(cccr);
+ hwc->config &= ~P4_CONFIG_HT;
+ }
+}
+
+/*
+ * ESCR address hashing is tricky, ESCRs are not sequential
+ * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and
+ * the metric between any ESCRs is laid in range [0xa0,0xe1]
+ *
+ * so we make ~70% filled hashtable
+ */
+
+#define P4_ESCR_MSR_BASE 0x000003a0
+#define P4_ESCR_MSR_MAX 0x000003e1
+#define P4_ESCR_MSR_TABLE_SIZE (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
+#define P4_ESCR_MSR_IDX(msr) (msr - P4_ESCR_MSR_BASE)
+#define P4_ESCR_MSR_TABLE_ENTRY(msr) [P4_ESCR_MSR_IDX(msr)] = msr
+
+static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
+ P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
+};
+
+static int p4_get_escr_idx(unsigned int addr)
+{
+ unsigned int idx = P4_ESCR_MSR_IDX(addr);
+
+ if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE ||
+ !p4_escr_table[idx] ||
+ p4_escr_table[idx] != addr)) {
+ WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
+ return -1;
+ }
+
+ return idx;
+}
+
+static int p4_next_cntr(int thread, unsigned long *used_mask,
+ struct p4_event_bind *bind)
+{
+ int i, j;
+
+ for (i = 0; i < P4_CNTR_LIMIT; i++) {
+ j = bind->cntr[thread][i];
+ if (j != -1 && !test_bit(j, used_mask))
+ return j;
+ }
+
+ return -1;
+}
+
+static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+ unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
+ int cpu = smp_processor_id();
+ struct hw_perf_event *hwc;
+ struct p4_event_bind *bind;
+ unsigned int i, thread, num;
+ int cntr_idx, escr_idx;
+ u64 config_alias;
+ int pass;
+
+ bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+ bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
+
+ for (i = 0, num = n; i < n; i++, num--) {
+
+ hwc = &cpuc->event_list[i]->hw;
+ thread = p4_ht_thread(cpu);
+ pass = 0;
+
+again:
+ /*
+ * It's possible to hit a circular lock
+ * between original and alternative events
+ * if both are scheduled already.
+ */
+ if (pass > 2)
+ goto done;
+
+ bind = p4_config_get_bind(hwc->config);
+ escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
+ if (unlikely(escr_idx == -1))
+ goto done;
+
+ if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
+ cntr_idx = hwc->idx;
+ if (assign)
+ assign[i] = hwc->idx;
+ goto reserve;
+ }
+
+ cntr_idx = p4_next_cntr(thread, used_mask, bind);
+ if (cntr_idx == -1 || test_bit(escr_idx, escr_mask)) {
+ /*
+ * Check whether an event alias is still available.
+ */
+ config_alias = p4_get_alias_event(hwc->config);
+ if (!config_alias)
+ goto done;
+ hwc->config = config_alias;
+ pass++;
+ goto again;
+ }
+ /*
+ * Perf does test runs to see if a whole group can be assigned
+ * together succesfully. There can be multiple rounds of this.
+ * Unfortunately, p4_pmu_swap_config_ts touches the hwc->config
+ * bits, such that the next round of group assignments will
+ * cause the above p4_should_swap_ts to pass instead of fail.
+ * This leads to counters exclusive to thread0 being used by
+ * thread1.
+ *
+ * Solve this with a cheap hack, reset the idx back to -1 to
+ * force a new lookup (p4_next_cntr) to get the right counter
+ * for the right thread.
+ *
+ * This probably doesn't comply with the general spirit of how
+ * perf wants to work, but P4 is special. :-(
+ */
+ if (p4_should_swap_ts(hwc->config, cpu))
+ hwc->idx = -1;
+ p4_pmu_swap_config_ts(hwc, cpu);
+ if (assign)
+ assign[i] = cntr_idx;
+reserve:
+ set_bit(cntr_idx, used_mask);
+ set_bit(escr_idx, escr_mask);
+ }
+
+done:
+ return num ? -EINVAL : 0;
+}
+
+PMU_FORMAT_ATTR(cccr, "config:0-31" );
+PMU_FORMAT_ATTR(escr, "config:32-62");
+PMU_FORMAT_ATTR(ht, "config:63" );
+
+static struct attribute *intel_p4_formats_attr[] = {
+ &format_attr_cccr.attr,
+ &format_attr_escr.attr,
+ &format_attr_ht.attr,
+ NULL,
+};
+
+static __initconst const struct x86_pmu p4_pmu = {
+ .name = "Netburst P4/Xeon",
+ .handle_irq = p4_pmu_handle_irq,
+ .disable_all = p4_pmu_disable_all,
+ .enable_all = p4_pmu_enable_all,
+ .enable = p4_pmu_enable_event,
+ .disable = p4_pmu_disable_event,
+ .eventsel = MSR_P4_BPU_CCCR0,
+ .perfctr = MSR_P4_BPU_PERFCTR0,
+ .event_map = p4_pmu_event_map,
+ .max_events = ARRAY_SIZE(p4_general_events),
+ .get_event_constraints = x86_get_event_constraints,
+ /*
+ * IF HT disabled we may need to use all
+ * ARCH_P4_MAX_CCCR counters simulaneously
+ * though leave it restricted at moment assuming
+ * HT is on
+ */
+ .num_counters = ARCH_P4_MAX_CCCR,
+ .apic = 1,
+ .cntval_bits = ARCH_P4_CNTRVAL_BITS,
+ .cntval_mask = ARCH_P4_CNTRVAL_MASK,
+ .max_period = (1ULL << (ARCH_P4_CNTRVAL_BITS - 1)) - 1,
+ .hw_config = p4_hw_config,
+ .schedule_events = p4_pmu_schedule_events,
+ /*
+ * This handles erratum N15 in intel doc 249199-029,
+ * the counter may not be updated correctly on write
+ * so we need a second write operation to do the trick
+ * (the official workaround didn't work)
+ *
+ * the former idea is taken from OProfile code
+ */
+ .perfctr_second_write = 1,
+
+ .format_attrs = intel_p4_formats_attr,
+};
+
+__init int p4_pmu_init(void)
+{
+ unsigned int low, high;
+ int i, reg;
+
+ /* If we get stripped -- indexing fails */
+ BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC);
+
+ rdmsr(MSR_IA32_MISC_ENABLE, low, high);
+ if (!(low & (1 << 7))) {
+ pr_cont("unsupported Netburst CPU model %d ",
+ boot_cpu_data.x86_model);
+ return -ENODEV;
+ }
+
+ memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ pr_cont("Netburst events, ");
+
+ x86_pmu = p4_pmu;
+
+ /*
+ * Even though the counters are configured to interrupt a particular
+ * logical processor when an overflow happens, testing has shown that
+ * on kdump kernels (which uses a single cpu), thread1's counter
+ * continues to run and will report an NMI on thread0. Due to the
+ * overflow bug, this leads to a stream of unknown NMIs.
+ *
+ * Solve this by zero'ing out the registers to mimic a reset.
+ */
+ for (i = 0; i < x86_pmu.num_counters; i++) {
+ reg = x86_pmu_config_addr(i);
+ wrmsrl_safe(reg, 0ULL);
+ }
+
+ return 0;
+}
diff --git a/arch/x86/events/intel/p6.c b/arch/x86/events/intel/p6.c
new file mode 100644
index 0000000..1f5c47a
--- /dev/null
+++ b/arch/x86/events/intel/p6.c
@@ -0,0 +1,279 @@
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include "../perf_event.h"
+
+/*
+ * Not sure about some of these
+ */
+static const u64 p6_perfmon_event_map[] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */
+ [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */
+
+};
+
+static const u64 __initconst p6_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */
+ [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */
+ [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */
+ [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */
+ [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+static u64 p6_pmu_event_map(int hw_event)
+{
+ return p6_perfmon_event_map[hw_event];
+}
+
+/*
+ * Event setting that is specified not to count anything.
+ * We use this to effectively disable a counter.
+ *
+ * L2_RQSTS with 0 MESI unit mask.
+ */
+#define P6_NOP_EVENT 0x0000002EULL
+
+static struct event_constraint p6_event_constraints[] =
+{
+ INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */
+ INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
+ INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
+ INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
+ INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
+ INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
+ EVENT_CONSTRAINT_END
+};
+
+static void p6_pmu_disable_all(void)
+{
+ u64 val;
+
+ /* p6 only has one enable register */
+ rdmsrl(MSR_P6_EVNTSEL0, val);
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+ wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static void p6_pmu_enable_all(int added)
+{
+ unsigned long val;
+
+ /* p6 only has one enable register */
+ rdmsrl(MSR_P6_EVNTSEL0, val);
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+ wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static inline void
+p6_pmu_disable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val = P6_NOP_EVENT;
+
+ (void)wrmsrl_safe(hwc->config_base, val);
+}
+
+static void p6_pmu_enable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val;
+
+ val = hwc->config;
+
+ /*
+ * p6 only has a global event enable, set on PerfEvtSel0
+ * We "disable" events by programming P6_NOP_EVENT
+ * and we rely on p6_pmu_enable_all() being called
+ * to actually enable the events.
+ */
+
+ (void)wrmsrl_safe(hwc->config_base, val);
+}
+
+PMU_FORMAT_ATTR(event, "config:0-7" );
+PMU_FORMAT_ATTR(umask, "config:8-15" );
+PMU_FORMAT_ATTR(edge, "config:18" );
+PMU_FORMAT_ATTR(pc, "config:19" );
+PMU_FORMAT_ATTR(inv, "config:23" );
+PMU_FORMAT_ATTR(cmask, "config:24-31" );
+
+static struct attribute *intel_p6_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_pc.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ NULL,
+};
+
+static __initconst const struct x86_pmu p6_pmu = {
+ .name = "p6",
+ .handle_irq = x86_pmu_handle_irq,
+ .disable_all = p6_pmu_disable_all,
+ .enable_all = p6_pmu_enable_all,
+ .enable = p6_pmu_enable_event,
+ .disable = p6_pmu_disable_event,
+ .hw_config = x86_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_P6_EVNTSEL0,
+ .perfctr = MSR_P6_PERFCTR0,
+ .event_map = p6_pmu_event_map,
+ .max_events = ARRAY_SIZE(p6_perfmon_event_map),
+ .apic = 1,
+ .max_period = (1ULL << 31) - 1,
+ .version = 0,
+ .num_counters = 2,
+ /*
+ * Events have 40 bits implemented. However they are designed such
+ * that bits [32-39] are sign extensions of bit 31. As such the
+ * effective width of a event for P6-like PMU is 32 bits only.
+ *
+ * See IA-32 Intel Architecture Software developer manual Vol 3B
+ */
+ .cntval_bits = 32,
+ .cntval_mask = (1ULL << 32) - 1,
+ .get_event_constraints = x86_get_event_constraints,
+ .event_constraints = p6_event_constraints,
+
+ .format_attrs = intel_p6_formats_attr,
+ .events_sysfs_show = intel_event_sysfs_show,
+
+};
+
+static __init void p6_pmu_rdpmc_quirk(void)
+{
+ if (boot_cpu_data.x86_mask < 9) {
+ /*
+ * PPro erratum 26; fixed in stepping 9 and above.
+ */
+ pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n");
+ x86_pmu.attr_rdpmc_broken = 1;
+ x86_pmu.attr_rdpmc = 0;
+ }
+}
+
+__init int p6_pmu_init(void)
+{
+ x86_pmu = p6_pmu;
+
+ switch (boot_cpu_data.x86_model) {
+ case 1: /* Pentium Pro */
+ x86_add_quirk(p6_pmu_rdpmc_quirk);
+ break;
+
+ case 3: /* Pentium II - Klamath */
+ case 5: /* Pentium II - Deschutes */
+ case 6: /* Pentium II - Mendocino */
+ break;
+
+ case 7: /* Pentium III - Katmai */
+ case 8: /* Pentium III - Coppermine */
+ case 10: /* Pentium III Xeon */
+ case 11: /* Pentium III - Tualatin */
+ break;
+
+ case 9: /* Pentium M - Banias */
+ case 13: /* Pentium M - Dothan */
+ break;
+
+ default:
+ pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model);
+ return -ENODEV;
+ }
+
+ memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ return 0;
+}
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
new file mode 100644
index 0000000..6af7cf7
--- /dev/null
+++ b/arch/x86/events/intel/pt.c
@@ -0,0 +1,1188 @@
+/*
+ * Intel(R) Processor Trace PMU driver for perf
+ * Copyright (c) 2013-2014, 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.
+ *
+ * Intel PT is specified in the Intel Architecture Instruction Set Extensions
+ * Programming Reference:
+ * http://software.intel.com/en-us/intel-isa-extensions
+ */
+
+#undef DEBUG
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include <asm/perf_event.h>
+#include <asm/insn.h>
+#include <asm/io.h>
+#include <asm/intel_pt.h>
+
+#include "../perf_event.h"
+#include "pt.h"
+
+static DEFINE_PER_CPU(struct pt, pt_ctx);
+
+static struct pt_pmu pt_pmu;
+
+enum cpuid_regs {
+ CR_EAX = 0,
+ CR_ECX,
+ CR_EDX,
+ CR_EBX
+};
+
+/*
+ * Capabilities of Intel PT hardware, such as number of address bits or
+ * supported output schemes, are cached and exported to userspace as "caps"
+ * attribute group of pt pmu device
+ * (/sys/bus/event_source/devices/intel_pt/caps/) so that userspace can store
+ * relevant bits together with intel_pt traces.
+ *
+ * These are necessary for both trace decoding (payloads_lip, contains address
+ * width encoded in IP-related packets), and event configuration (bitmasks with
+ * permitted values for certain bit fields).
+ */
+#define PT_CAP(_n, _l, _r, _m) \
+ [PT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l, \
+ .reg = _r, .mask = _m }
+
+static struct pt_cap_desc {
+ const char *name;
+ u32 leaf;
+ u8 reg;
+ u32 mask;
+} pt_caps[] = {
+ PT_CAP(max_subleaf, 0, CR_EAX, 0xffffffff),
+ PT_CAP(cr3_filtering, 0, CR_EBX, BIT(0)),
+ PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)),
+ PT_CAP(mtc, 0, CR_EBX, BIT(3)),
+ PT_CAP(topa_output, 0, CR_ECX, BIT(0)),
+ PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)),
+ PT_CAP(single_range_output, 0, CR_ECX, BIT(2)),
+ PT_CAP(payloads_lip, 0, CR_ECX, BIT(31)),
+ PT_CAP(mtc_periods, 1, CR_EAX, 0xffff0000),
+ PT_CAP(cycle_thresholds, 1, CR_EBX, 0xffff),
+ PT_CAP(psb_periods, 1, CR_EBX, 0xffff0000),
+};
+
+static u32 pt_cap_get(enum pt_capabilities cap)
+{
+ struct pt_cap_desc *cd = &pt_caps[cap];
+ u32 c = pt_pmu.caps[cd->leaf * PT_CPUID_REGS_NUM + cd->reg];
+ unsigned int shift = __ffs(cd->mask);
+
+ return (c & cd->mask) >> shift;
+}
+
+static ssize_t pt_cap_show(struct device *cdev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct dev_ext_attribute *ea =
+ container_of(attr, struct dev_ext_attribute, attr);
+ enum pt_capabilities cap = (long)ea->var;
+
+ return snprintf(buf, PAGE_SIZE, "%x\n", pt_cap_get(cap));
+}
+
+static struct attribute_group pt_cap_group = {
+ .name = "caps",
+};
+
+PMU_FORMAT_ATTR(cyc, "config:1" );
+PMU_FORMAT_ATTR(mtc, "config:9" );
+PMU_FORMAT_ATTR(tsc, "config:10" );
+PMU_FORMAT_ATTR(noretcomp, "config:11" );
+PMU_FORMAT_ATTR(mtc_period, "config:14-17" );
+PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" );
+PMU_FORMAT_ATTR(psb_period, "config:24-27" );
+
+static struct attribute *pt_formats_attr[] = {
+ &format_attr_cyc.attr,
+ &format_attr_mtc.attr,
+ &format_attr_tsc.attr,
+ &format_attr_noretcomp.attr,
+ &format_attr_mtc_period.attr,
+ &format_attr_cyc_thresh.attr,
+ &format_attr_psb_period.attr,
+ NULL,
+};
+
+static struct attribute_group pt_format_group = {
+ .name = "format",
+ .attrs = pt_formats_attr,
+};
+
+static const struct attribute_group *pt_attr_groups[] = {
+ &pt_cap_group,
+ &pt_format_group,
+ NULL,
+};
+
+static int __init pt_pmu_hw_init(void)
+{
+ struct dev_ext_attribute *de_attrs;
+ struct attribute **attrs;
+ size_t size;
+ int ret;
+ long i;
+
+ attrs = NULL;
+
+ for (i = 0; i < PT_CPUID_LEAVES; i++) {
+ cpuid_count(20, i,
+ &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM],
+ &pt_pmu.caps[CR_EBX + i*PT_CPUID_REGS_NUM],
+ &pt_pmu.caps[CR_ECX + i*PT_CPUID_REGS_NUM],
+ &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]);
+ }
+
+ ret = -ENOMEM;
+ size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
+ attrs = kzalloc(size, GFP_KERNEL);
+ if (!attrs)
+ goto fail;
+
+ size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
+ de_attrs = kzalloc(size, GFP_KERNEL);
+ if (!de_attrs)
+ goto fail;
+
+ for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
+ struct dev_ext_attribute *de_attr = de_attrs + i;
+
+ de_attr->attr.attr.name = pt_caps[i].name;
+
+ sysfs_attr_init(&de_attr->attr.attr);
+
+ de_attr->attr.attr.mode = S_IRUGO;
+ de_attr->attr.show = pt_cap_show;
+ de_attr->var = (void *)i;
+
+ attrs[i] = &de_attr->attr.attr;
+ }
+
+ pt_cap_group.attrs = attrs;
+
+ return 0;
+
+fail:
+ kfree(attrs);
+
+ return ret;
+}
+
+#define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC | \
+ RTIT_CTL_CYC_THRESH | \
+ RTIT_CTL_PSB_FREQ)
+
+#define RTIT_CTL_MTC (RTIT_CTL_MTC_EN | \
+ RTIT_CTL_MTC_RANGE)
+
+#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \
+ RTIT_CTL_DISRETC | \
+ RTIT_CTL_CYC_PSB | \
+ RTIT_CTL_MTC)
+
+static bool pt_event_valid(struct perf_event *event)
+{
+ u64 config = event->attr.config;
+ u64 allowed, requested;
+
+ if ((config & PT_CONFIG_MASK) != config)
+ return false;
+
+ if (config & RTIT_CTL_CYC_PSB) {
+ if (!pt_cap_get(PT_CAP_psb_cyc))
+ return false;
+
+ allowed = pt_cap_get(PT_CAP_psb_periods);
+ requested = (config & RTIT_CTL_PSB_FREQ) >>
+ RTIT_CTL_PSB_FREQ_OFFSET;
+ if (requested && (!(allowed & BIT(requested))))
+ return false;
+
+ allowed = pt_cap_get(PT_CAP_cycle_thresholds);
+ requested = (config & RTIT_CTL_CYC_THRESH) >>
+ RTIT_CTL_CYC_THRESH_OFFSET;
+ if (requested && (!(allowed & BIT(requested))))
+ return false;
+ }
+
+ if (config & RTIT_CTL_MTC) {
+ /*
+ * In the unlikely case that CPUID lists valid mtc periods,
+ * but not the mtc capability, drop out here.
+ *
+ * Spec says that setting mtc period bits while mtc bit in
+ * CPUID is 0 will #GP, so better safe than sorry.
+ */
+ if (!pt_cap_get(PT_CAP_mtc))
+ return false;
+
+ allowed = pt_cap_get(PT_CAP_mtc_periods);
+ if (!allowed)
+ return false;
+
+ requested = (config & RTIT_CTL_MTC_RANGE) >>
+ RTIT_CTL_MTC_RANGE_OFFSET;
+
+ if (!(allowed & BIT(requested)))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * PT configuration helpers
+ * These all are cpu affine and operate on a local PT
+ */
+
+static void pt_config(struct perf_event *event)
+{
+ u64 reg;
+
+ if (!event->hw.itrace_started) {
+ event->hw.itrace_started = 1;
+ wrmsrl(MSR_IA32_RTIT_STATUS, 0);
+ }
+
+ reg = RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
+
+ if (!event->attr.exclude_kernel)
+ reg |= RTIT_CTL_OS;
+ if (!event->attr.exclude_user)
+ reg |= RTIT_CTL_USR;
+
+ reg |= (event->attr.config & PT_CONFIG_MASK);
+
+ wrmsrl(MSR_IA32_RTIT_CTL, reg);
+}
+
+static void pt_config_start(bool start)
+{
+ u64 ctl;
+
+ rdmsrl(MSR_IA32_RTIT_CTL, ctl);
+ if (start)
+ ctl |= RTIT_CTL_TRACEEN;
+ else
+ ctl &= ~RTIT_CTL_TRACEEN;
+ wrmsrl(MSR_IA32_RTIT_CTL, ctl);
+
+ /*
+ * A wrmsr that disables trace generation serializes other PT
+ * registers and causes all data packets to be written to memory,
+ * but a fence is required for the data to become globally visible.
+ *
+ * The below WMB, separating data store and aux_head store matches
+ * the consumer's RMB that separates aux_head load and data load.
+ */
+ if (!start)
+ wmb();
+}
+
+static void pt_config_buffer(void *buf, unsigned int topa_idx,
+ unsigned int output_off)
+{
+ u64 reg;
+
+ wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, virt_to_phys(buf));
+
+ reg = 0x7f | ((u64)topa_idx << 7) | ((u64)output_off << 32);
+
+ wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
+}
+
+/*
+ * Keep ToPA table-related metadata on the same page as the actual table,
+ * taking up a few words from the top
+ */
+
+#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1)
+
+/**
+ * struct topa - page-sized ToPA table with metadata at the top
+ * @table: actual ToPA table entries, as understood by PT hardware
+ * @list: linkage to struct pt_buffer's list of tables
+ * @phys: physical address of this page
+ * @offset: offset of the first entry in this table in the buffer
+ * @size: total size of all entries in this table
+ * @last: index of the last initialized entry in this table
+ */
+struct topa {
+ struct topa_entry table[TENTS_PER_PAGE];
+ struct list_head list;
+ u64 phys;
+ u64 offset;
+ size_t size;
+ int last;
+};
+
+/* make -1 stand for the last table entry */
+#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)])
+
+/**
+ * topa_alloc() - allocate page-sized ToPA table
+ * @cpu: CPU on which to allocate.
+ * @gfp: Allocation flags.
+ *
+ * Return: On success, return the pointer to ToPA table page.
+ */
+static struct topa *topa_alloc(int cpu, gfp_t gfp)
+{
+ int node = cpu_to_node(cpu);
+ struct topa *topa;
+ struct page *p;
+
+ p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
+ if (!p)
+ return NULL;
+
+ topa = page_address(p);
+ topa->last = 0;
+ topa->phys = page_to_phys(p);
+
+ /*
+ * In case of singe-entry ToPA, always put the self-referencing END
+ * link as the 2nd entry in the table
+ */
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries)) {
+ TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT;
+ TOPA_ENTRY(topa, 1)->end = 1;
+ }
+
+ return topa;
+}
+
+/**
+ * topa_free() - free a page-sized ToPA table
+ * @topa: Table to deallocate.
+ */
+static void topa_free(struct topa *topa)
+{
+ free_page((unsigned long)topa);
+}
+
+/**
+ * topa_insert_table() - insert a ToPA table into a buffer
+ * @buf: PT buffer that's being extended.
+ * @topa: New topa table to be inserted.
+ *
+ * If it's the first table in this buffer, set up buffer's pointers
+ * accordingly; otherwise, add a END=1 link entry to @topa to the current
+ * "last" table and adjust the last table pointer to @topa.
+ */
+static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
+{
+ struct topa *last = buf->last;
+
+ list_add_tail(&topa->list, &buf->tables);
+
+ if (!buf->first) {
+ buf->first = buf->last = buf->cur = topa;
+ return;
+ }
+
+ topa->offset = last->offset + last->size;
+ buf->last = topa;
+
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+ return;
+
+ BUG_ON(last->last != TENTS_PER_PAGE - 1);
+
+ TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT;
+ TOPA_ENTRY(last, -1)->end = 1;
+}
+
+/**
+ * topa_table_full() - check if a ToPA table is filled up
+ * @topa: ToPA table.
+ */
+static bool topa_table_full(struct topa *topa)
+{
+ /* single-entry ToPA is a special case */
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+ return !!topa->last;
+
+ return topa->last == TENTS_PER_PAGE - 1;
+}
+
+/**
+ * topa_insert_pages() - create a list of ToPA tables
+ * @buf: PT buffer being initialized.
+ * @gfp: Allocation flags.
+ *
+ * This initializes a list of ToPA tables with entries from
+ * the data_pages provided by rb_alloc_aux().
+ *
+ * Return: 0 on success or error code.
+ */
+static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
+{
+ struct topa *topa = buf->last;
+ int order = 0;
+ struct page *p;
+
+ p = virt_to_page(buf->data_pages[buf->nr_pages]);
+ if (PagePrivate(p))
+ order = page_private(p);
+
+ if (topa_table_full(topa)) {
+ topa = topa_alloc(buf->cpu, gfp);
+ if (!topa)
+ return -ENOMEM;
+
+ topa_insert_table(buf, topa);
+ }
+
+ TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
+ TOPA_ENTRY(topa, -1)->size = order;
+ if (!buf->snapshot && !pt_cap_get(PT_CAP_topa_multiple_entries)) {
+ TOPA_ENTRY(topa, -1)->intr = 1;
+ TOPA_ENTRY(topa, -1)->stop = 1;
+ }
+
+ topa->last++;
+ topa->size += sizes(order);
+
+ buf->nr_pages += 1ul << order;
+
+ return 0;
+}
+
+/**
+ * pt_topa_dump() - print ToPA tables and their entries
+ * @buf: PT buffer.
+ */
+static void pt_topa_dump(struct pt_buffer *buf)
+{
+ struct topa *topa;
+
+ list_for_each_entry(topa, &buf->tables, list) {
+ int i;
+
+ pr_debug("# table @%p (%016Lx), off %llx size %zx\n", topa->table,
+ topa->phys, topa->offset, topa->size);
+ for (i = 0; i < TENTS_PER_PAGE; i++) {
+ pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
+ &topa->table[i],
+ (unsigned long)topa->table[i].base << TOPA_SHIFT,
+ sizes(topa->table[i].size),
+ topa->table[i].end ? 'E' : ' ',
+ topa->table[i].intr ? 'I' : ' ',
+ topa->table[i].stop ? 'S' : ' ',
+ *(u64 *)&topa->table[i]);
+ if ((pt_cap_get(PT_CAP_topa_multiple_entries) &&
+ topa->table[i].stop) ||
+ topa->table[i].end)
+ break;
+ }
+ }
+}
+
+/**
+ * pt_buffer_advance() - advance to the next output region
+ * @buf: PT buffer.
+ *
+ * Advance the current pointers in the buffer to the next ToPA entry.
+ */
+static void pt_buffer_advance(struct pt_buffer *buf)
+{
+ buf->output_off = 0;
+ buf->cur_idx++;
+
+ if (buf->cur_idx == buf->cur->last) {
+ if (buf->cur == buf->last)
+ buf->cur = buf->first;
+ else
+ buf->cur = list_entry(buf->cur->list.next, struct topa,
+ list);
+ buf->cur_idx = 0;
+ }
+}
+
+/**
+ * pt_update_head() - calculate current offsets and sizes
+ * @pt: Per-cpu pt context.
+ *
+ * Update buffer's current write pointer position and data size.
+ */
+static void pt_update_head(struct pt *pt)
+{
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
+ u64 topa_idx, base, old;
+
+ /* offset of the first region in this table from the beginning of buf */
+ base = buf->cur->offset + buf->output_off;
+
+ /* offset of the current output region within this table */
+ for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
+ base += sizes(buf->cur->table[topa_idx].size);
+
+ if (buf->snapshot) {
+ local_set(&buf->data_size, base);
+ } else {
+ old = (local64_xchg(&buf->head, base) &
+ ((buf->nr_pages << PAGE_SHIFT) - 1));
+ if (base < old)
+ base += buf->nr_pages << PAGE_SHIFT;
+
+ local_add(base - old, &buf->data_size);
+ }
+}
+
+/**
+ * pt_buffer_region() - obtain current output region's address
+ * @buf: PT buffer.
+ */
+static void *pt_buffer_region(struct pt_buffer *buf)
+{
+ return phys_to_virt(buf->cur->table[buf->cur_idx].base << TOPA_SHIFT);
+}
+
+/**
+ * pt_buffer_region_size() - obtain current output region's size
+ * @buf: PT buffer.
+ */
+static size_t pt_buffer_region_size(struct pt_buffer *buf)
+{
+ return sizes(buf->cur->table[buf->cur_idx].size);
+}
+
+/**
+ * pt_handle_status() - take care of possible status conditions
+ * @pt: Per-cpu pt context.
+ */
+static void pt_handle_status(struct pt *pt)
+{
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
+ int advance = 0;
+ u64 status;
+
+ rdmsrl(MSR_IA32_RTIT_STATUS, status);
+
+ if (status & RTIT_STATUS_ERROR) {
+ pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
+ pt_topa_dump(buf);
+ status &= ~RTIT_STATUS_ERROR;
+ }
+
+ if (status & RTIT_STATUS_STOPPED) {
+ status &= ~RTIT_STATUS_STOPPED;
+
+ /*
+ * On systems that only do single-entry ToPA, hitting STOP
+ * means we are already losing data; need to let the decoder
+ * know.
+ */
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
+ buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+ local_inc(&buf->lost);
+ advance++;
+ }
+ }
+
+ /*
+ * Also on single-entry ToPA implementations, interrupt will come
+ * before the output reaches its output region's boundary.
+ */
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries) && !buf->snapshot &&
+ pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
+ void *head = pt_buffer_region(buf);
+
+ /* everything within this margin needs to be zeroed out */
+ memset(head + buf->output_off, 0,
+ pt_buffer_region_size(buf) -
+ buf->output_off);
+ advance++;
+ }
+
+ if (advance)
+ pt_buffer_advance(buf);
+
+ wrmsrl(MSR_IA32_RTIT_STATUS, status);
+}
+
+/**
+ * pt_read_offset() - translate registers into buffer pointers
+ * @buf: PT buffer.
+ *
+ * Set buffer's output pointers from MSR values.
+ */
+static void pt_read_offset(struct pt_buffer *buf)
+{
+ u64 offset, base_topa;
+
+ rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base_topa);
+ buf->cur = phys_to_virt(base_topa);
+
+ rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
+ /* offset within current output region */
+ buf->output_off = offset >> 32;
+ /* index of current output region within this table */
+ buf->cur_idx = (offset & 0xffffff80) >> 7;
+}
+
+/**
+ * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry
+ * @buf: PT buffer.
+ * @pg: Page offset in the buffer.
+ *
+ * When advancing to the next output region (ToPA entry), given a page offset
+ * into the buffer, we need to find the offset of the first page in the next
+ * region.
+ */
+static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg)
+{
+ struct topa_entry *te = buf->topa_index[pg];
+
+ /* one region */
+ if (buf->first == buf->last && buf->first->last == 1)
+ return pg;
+
+ do {
+ pg++;
+ pg &= buf->nr_pages - 1;
+ } while (buf->topa_index[pg] == te);
+
+ return pg;
+}
+
+/**
+ * pt_buffer_reset_markers() - place interrupt and stop bits in the buffer
+ * @buf: PT buffer.
+ * @handle: Current output handle.
+ *
+ * Place INT and STOP marks to prevent overwriting old data that the consumer
+ * hasn't yet collected and waking up the consumer after a certain fraction of
+ * the buffer has filled up. Only needed and sensible for non-snapshot counters.
+ *
+ * This obviously relies on buf::head to figure out buffer markers, so it has
+ * to be called after pt_buffer_reset_offsets() and before the hardware tracing
+ * is enabled.
+ */
+static int pt_buffer_reset_markers(struct pt_buffer *buf,
+ struct perf_output_handle *handle)
+
+{
+ unsigned long head = local64_read(&buf->head);
+ unsigned long idx, npages, wakeup;
+
+ /* can't stop in the middle of an output region */
+ if (buf->output_off + handle->size + 1 <
+ sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
+ return -EINVAL;
+
+
+ /* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+ return 0;
+
+ /* clear STOP and INT from current entry */
+ buf->topa_index[buf->stop_pos]->stop = 0;
+ buf->topa_index[buf->intr_pos]->intr = 0;
+
+ /* how many pages till the STOP marker */
+ npages = handle->size >> PAGE_SHIFT;
+
+ /* if it's on a page boundary, fill up one more page */
+ if (!offset_in_page(head + handle->size + 1))
+ npages++;
+
+ idx = (head >> PAGE_SHIFT) + npages;
+ idx &= buf->nr_pages - 1;
+ buf->stop_pos = idx;
+
+ wakeup = handle->wakeup >> PAGE_SHIFT;
+
+ /* in the worst case, wake up the consumer one page before hard stop */
+ idx = (head >> PAGE_SHIFT) + npages - 1;
+ if (idx > wakeup)
+ idx = wakeup;
+
+ idx &= buf->nr_pages - 1;
+ buf->intr_pos = idx;
+
+ buf->topa_index[buf->stop_pos]->stop = 1;
+ buf->topa_index[buf->intr_pos]->intr = 1;
+
+ return 0;
+}
+
+/**
+ * pt_buffer_setup_topa_index() - build topa_index[] table of regions
+ * @buf: PT buffer.
+ *
+ * topa_index[] references output regions indexed by offset into the
+ * buffer for purposes of quick reverse lookup.
+ */
+static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
+{
+ struct topa *cur = buf->first, *prev = buf->last;
+ struct topa_entry *te_cur = TOPA_ENTRY(cur, 0),
+ *te_prev = TOPA_ENTRY(prev, prev->last - 1);
+ int pg = 0, idx = 0;
+
+ while (pg < buf->nr_pages) {
+ int tidx;
+
+ /* pages within one topa entry */
+ for (tidx = 0; tidx < 1 << te_cur->size; tidx++, pg++)
+ buf->topa_index[pg] = te_prev;
+
+ te_prev = te_cur;
+
+ if (idx == cur->last - 1) {
+ /* advance to next topa table */
+ idx = 0;
+ cur = list_entry(cur->list.next, struct topa, list);
+ } else {
+ idx++;
+ }
+ te_cur = TOPA_ENTRY(cur, idx);
+ }
+
+}
+
+/**
+ * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
+ * @buf: PT buffer.
+ * @head: Write pointer (aux_head) from AUX buffer.
+ *
+ * Find the ToPA table and entry corresponding to given @head and set buffer's
+ * "current" pointers accordingly. This is done after we have obtained the
+ * current aux_head position from a successful call to perf_aux_output_begin()
+ * to make sure the hardware is writing to the right place.
+ *
+ * This function modifies buf::{cur,cur_idx,output_off} that will be programmed
+ * into PT msrs when the tracing is enabled and buf::head and buf::data_size,
+ * which are used to determine INT and STOP markers' locations by a subsequent
+ * call to pt_buffer_reset_markers().
+ */
+static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
+{
+ int pg;
+
+ if (buf->snapshot)
+ head &= (buf->nr_pages << PAGE_SHIFT) - 1;
+
+ pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
+ pg = pt_topa_next_entry(buf, pg);
+
+ buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK);
+ buf->cur_idx = ((unsigned long)buf->topa_index[pg] -
+ (unsigned long)buf->cur) / sizeof(struct topa_entry);
+ buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1);
+
+ local64_set(&buf->head, head);
+ local_set(&buf->data_size, 0);
+}
+
+/**
+ * pt_buffer_fini_topa() - deallocate ToPA structure of a buffer
+ * @buf: PT buffer.
+ */
+static void pt_buffer_fini_topa(struct pt_buffer *buf)
+{
+ struct topa *topa, *iter;
+
+ list_for_each_entry_safe(topa, iter, &buf->tables, list) {
+ /*
+ * right now, this is in free_aux() path only, so
+ * no need to unlink this table from the list
+ */
+ topa_free(topa);
+ }
+}
+
+/**
+ * pt_buffer_init_topa() - initialize ToPA table for pt buffer
+ * @buf: PT buffer.
+ * @size: Total size of all regions within this ToPA.
+ * @gfp: Allocation flags.
+ */
+static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
+ gfp_t gfp)
+{
+ struct topa *topa;
+ int err;
+
+ topa = topa_alloc(buf->cpu, gfp);
+ if (!topa)
+ return -ENOMEM;
+
+ topa_insert_table(buf, topa);
+
+ while (buf->nr_pages < nr_pages) {
+ err = topa_insert_pages(buf, gfp);
+ if (err) {
+ pt_buffer_fini_topa(buf);
+ return -ENOMEM;
+ }
+ }
+
+ pt_buffer_setup_topa_index(buf);
+
+ /* link last table to the first one, unless we're double buffering */
+ if (pt_cap_get(PT_CAP_topa_multiple_entries)) {
+ TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT;
+ TOPA_ENTRY(buf->last, -1)->end = 1;
+ }
+
+ pt_topa_dump(buf);
+ return 0;
+}
+
+/**
+ * pt_buffer_setup_aux() - set up topa tables for a PT buffer
+ * @cpu: Cpu on which to allocate, -1 means current.
+ * @pages: Array of pointers to buffer pages passed from perf core.
+ * @nr_pages: Number of pages in the buffer.
+ * @snapshot: If this is a snapshot/overwrite counter.
+ *
+ * This is a pmu::setup_aux callback that sets up ToPA tables and all the
+ * bookkeeping for an AUX buffer.
+ *
+ * Return: Our private PT buffer structure.
+ */
+static void *
+pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot)
+{
+ struct pt_buffer *buf;
+ int node, ret;
+
+ if (!nr_pages)
+ return NULL;
+
+ if (cpu == -1)
+ cpu = raw_smp_processor_id();
+ node = cpu_to_node(cpu);
+
+ buf = kzalloc_node(offsetof(struct pt_buffer, topa_index[nr_pages]),
+ GFP_KERNEL, node);
+ if (!buf)
+ return NULL;
+
+ buf->cpu = cpu;
+ buf->snapshot = snapshot;
+ buf->data_pages = pages;
+
+ INIT_LIST_HEAD(&buf->tables);
+
+ ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL);
+ if (ret) {
+ kfree(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+/**
+ * pt_buffer_free_aux() - perf AUX deallocation path callback
+ * @data: PT buffer.
+ */
+static void pt_buffer_free_aux(void *data)
+{
+ struct pt_buffer *buf = data;
+
+ pt_buffer_fini_topa(buf);
+ kfree(buf);
+}
+
+/**
+ * pt_buffer_is_full() - check if the buffer is full
+ * @buf: PT buffer.
+ * @pt: Per-cpu pt handle.
+ *
+ * If the user hasn't read data from the output region that aux_head
+ * points to, the buffer is considered full: the user needs to read at
+ * least this region and update aux_tail to point past it.
+ */
+static bool pt_buffer_is_full(struct pt_buffer *buf, struct pt *pt)
+{
+ if (buf->snapshot)
+ return false;
+
+ if (local_read(&buf->data_size) >= pt->handle.size)
+ return true;
+
+ return false;
+}
+
+/**
+ * intel_pt_interrupt() - PT PMI handler
+ */
+void intel_pt_interrupt(void)
+{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+ struct pt_buffer *buf;
+ struct perf_event *event = pt->handle.event;
+
+ /*
+ * There may be a dangling PT bit in the interrupt status register
+ * after PT has been disabled by pt_event_stop(). Make sure we don't
+ * do anything (particularly, re-enable) for this event here.
+ */
+ if (!ACCESS_ONCE(pt->handle_nmi))
+ return;
+
+ pt_config_start(false);
+
+ if (!event)
+ return;
+
+ buf = perf_get_aux(&pt->handle);
+ if (!buf)
+ return;
+
+ pt_read_offset(buf);
+
+ pt_handle_status(pt);
+
+ pt_update_head(pt);
+
+ perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
+ local_xchg(&buf->lost, 0));
+
+ if (!event->hw.state) {
+ int ret;
+
+ buf = perf_aux_output_begin(&pt->handle, event);
+ if (!buf) {
+ event->hw.state = PERF_HES_STOPPED;
+ return;
+ }
+
+ pt_buffer_reset_offsets(buf, pt->handle.head);
+ /* snapshot counters don't use PMI, so it's safe */
+ ret = pt_buffer_reset_markers(buf, &pt->handle);
+ if (ret) {
+ perf_aux_output_end(&pt->handle, 0, true);
+ return;
+ }
+
+ pt_config_buffer(buf->cur->table, buf->cur_idx,
+ buf->output_off);
+ pt_config(event);
+ }
+}
+
+/*
+ * PMU callbacks
+ */
+
+static void pt_event_start(struct perf_event *event, int mode)
+{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
+
+ if (!buf || pt_buffer_is_full(buf, pt)) {
+ event->hw.state = PERF_HES_STOPPED;
+ return;
+ }
+
+ ACCESS_ONCE(pt->handle_nmi) = 1;
+ event->hw.state = 0;
+
+ pt_config_buffer(buf->cur->table, buf->cur_idx,
+ buf->output_off);
+ pt_config(event);
+}
+
+static void pt_event_stop(struct perf_event *event, int mode)
+{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+
+ /*
+ * Protect against the PMI racing with disabling wrmsr,
+ * see comment in intel_pt_interrupt().
+ */
+ ACCESS_ONCE(pt->handle_nmi) = 0;
+ pt_config_start(false);
+
+ if (event->hw.state == PERF_HES_STOPPED)
+ return;
+
+ event->hw.state = PERF_HES_STOPPED;
+
+ if (mode & PERF_EF_UPDATE) {
+ struct pt_buffer *buf = perf_get_aux(&pt->handle);
+
+ if (!buf)
+ return;
+
+ if (WARN_ON_ONCE(pt->handle.event != event))
+ return;
+
+ pt_read_offset(buf);
+
+ pt_handle_status(pt);
+
+ pt_update_head(pt);
+ }
+}
+
+static void pt_event_del(struct perf_event *event, int mode)
+{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+ struct pt_buffer *buf;
+
+ pt_event_stop(event, PERF_EF_UPDATE);
+
+ buf = perf_get_aux(&pt->handle);
+
+ if (buf) {
+ if (buf->snapshot)
+ pt->handle.head =
+ local_xchg(&buf->data_size,
+ buf->nr_pages << PAGE_SHIFT);
+ perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
+ local_xchg(&buf->lost, 0));
+ }
+}
+
+static int pt_event_add(struct perf_event *event, int mode)
+{
+ struct pt_buffer *buf;
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+ struct hw_perf_event *hwc = &event->hw;
+ int ret = -EBUSY;
+
+ if (pt->handle.event)
+ goto fail;
+
+ buf = perf_aux_output_begin(&pt->handle, event);
+ ret = -EINVAL;
+ if (!buf)
+ goto fail_stop;
+
+ pt_buffer_reset_offsets(buf, pt->handle.head);
+ if (!buf->snapshot) {
+ ret = pt_buffer_reset_markers(buf, &pt->handle);
+ if (ret)
+ goto fail_end_stop;
+ }
+
+ if (mode & PERF_EF_START) {
+ pt_event_start(event, 0);
+ ret = -EBUSY;
+ if (hwc->state == PERF_HES_STOPPED)
+ goto fail_end_stop;
+ } else {
+ hwc->state = PERF_HES_STOPPED;
+ }
+
+ return 0;
+
+fail_end_stop:
+ perf_aux_output_end(&pt->handle, 0, true);
+fail_stop:
+ hwc->state = PERF_HES_STOPPED;
+fail:
+ return ret;
+}
+
+static void pt_event_read(struct perf_event *event)
+{
+}
+
+static void pt_event_destroy(struct perf_event *event)
+{
+ x86_del_exclusive(x86_lbr_exclusive_pt);
+}
+
+static int pt_event_init(struct perf_event *event)
+{
+ if (event->attr.type != pt_pmu.pmu.type)
+ return -ENOENT;
+
+ if (!pt_event_valid(event))
+ return -EINVAL;
+
+ if (x86_add_exclusive(x86_lbr_exclusive_pt))
+ return -EBUSY;
+
+ event->destroy = pt_event_destroy;
+
+ return 0;
+}
+
+void cpu_emergency_stop_pt(void)
+{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
+
+ if (pt->handle.event)
+ pt_event_stop(pt->handle.event, PERF_EF_UPDATE);
+}
+
+static __init int pt_init(void)
+{
+ int ret, cpu, prior_warn = 0;
+
+ BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
+
+ if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
+ return -ENODEV;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ u64 ctl;
+
+ ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
+ if (!ret && (ctl & RTIT_CTL_TRACEEN))
+ prior_warn++;
+ }
+ put_online_cpus();
+
+ if (prior_warn) {
+ x86_add_exclusive(x86_lbr_exclusive_pt);
+ pr_warn("PT is enabled at boot time, doing nothing\n");
+
+ return -EBUSY;
+ }
+
+ ret = pt_pmu_hw_init();
+ if (ret)
+ return ret;
+
+ if (!pt_cap_get(PT_CAP_topa_output)) {
+ pr_warn("ToPA output is not supported on this CPU\n");
+ return -ENODEV;
+ }
+
+ if (!pt_cap_get(PT_CAP_topa_multiple_entries))
+ pt_pmu.pmu.capabilities =
+ PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_SW_DOUBLEBUF;
+
+ pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+ pt_pmu.pmu.attr_groups = pt_attr_groups;
+ pt_pmu.pmu.task_ctx_nr = perf_sw_context;
+ pt_pmu.pmu.event_init = pt_event_init;
+ pt_pmu.pmu.add = pt_event_add;
+ pt_pmu.pmu.del = pt_event_del;
+ pt_pmu.pmu.start = pt_event_start;
+ pt_pmu.pmu.stop = pt_event_stop;
+ pt_pmu.pmu.read = pt_event_read;
+ pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
+ pt_pmu.pmu.free_aux = pt_buffer_free_aux;
+ ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
+
+ return ret;
+}
+arch_initcall(pt_init);
diff --git a/arch/x86/kernel/cpu/intel_pt.h b/arch/x86/events/intel/pt.h
index 336878a..336878a 100644
--- a/arch/x86/kernel/cpu/intel_pt.h
+++ b/arch/x86/events/intel/pt.h
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
new file mode 100644
index 0000000..b834a3f
--- /dev/null
+++ b/arch/x86/events/intel/rapl.c
@@ -0,0 +1,767 @@
+/*
+ * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
+ * Copyright (C) 2013 Google, Inc., Stephane Eranian
+ *
+ * Intel RAPL interface is specified in the IA-32 Manual Vol3b
+ * section 14.7.1 (September 2013)
+ *
+ * RAPL provides more controls than just reporting energy consumption
+ * however here we only expose the 3 energy consumption free running
+ * counters (pp0, pkg, dram).
+ *
+ * Each of those counters increments in a power unit defined by the
+ * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
+ * but it can vary.
+ *
+ * Counter to rapl events mappings:
+ *
+ * pp0 counter: consumption of all physical cores (power plane 0)
+ * event: rapl_energy_cores
+ * perf code: 0x1
+ *
+ * pkg counter: consumption of the whole processor package
+ * event: rapl_energy_pkg
+ * perf code: 0x2
+ *
+ * dram counter: consumption of the dram domain (servers only)
+ * event: rapl_energy_dram
+ * perf code: 0x3
+ *
+ * dram counter: consumption of the builtin-gpu domain (client only)
+ * event: rapl_energy_gpu
+ * perf code: 0x4
+ *
+ * We manage those counters as free running (read-only). They may be
+ * use simultaneously by other tools, such as turbostat.
+ *
+ * The events only support system-wide mode counting. There is no
+ * sampling support because it does not make sense and is not
+ * supported by the RAPL hardware.
+ *
+ * Because we want to avoid floating-point operations in the kernel,
+ * the events are all reported in fixed point arithmetic (32.32).
+ * Tools must adjust the counts to convert them to Watts using
+ * the duration of the measurement. Tools may use a function such as
+ * ldexp(raw_count, -32);
+ */
+
+#define pr_fmt(fmt) "RAPL PMU: " fmt
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <asm/cpu_device_id.h>
+#include "../perf_event.h"
+
+/*
+ * RAPL energy status counters
+ */
+#define RAPL_IDX_PP0_NRG_STAT 0 /* all cores */
+#define INTEL_RAPL_PP0 0x1 /* pseudo-encoding */
+#define RAPL_IDX_PKG_NRG_STAT 1 /* entire package */
+#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
+#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
+#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
+#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
+#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
+
+#define NR_RAPL_DOMAINS 0x4
+static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
+ "pp0-core",
+ "package",
+ "dram",
+ "pp1-gpu",
+};
+
+/* Clients have PP0, PKG */
+#define RAPL_IDX_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\
+ 1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_PP1_NRG_STAT)
+
+/* Servers have PP0, PKG, RAM */
+#define RAPL_IDX_SRV (1<<RAPL_IDX_PP0_NRG_STAT|\
+ 1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_RAM_NRG_STAT)
+
+/* Servers have PP0, PKG, RAM, PP1 */
+#define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\
+ 1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_RAM_NRG_STAT|\
+ 1<<RAPL_IDX_PP1_NRG_STAT)
+
+/* Knights Landing has PKG, RAM */
+#define RAPL_IDX_KNL (1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_RAM_NRG_STAT)
+
+/*
+ * event code: LSB 8 bits, passed in attr->config
+ * any other bit is reserved
+ */
+#define RAPL_EVENT_MASK 0xFFULL
+
+#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \
+static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ char *page) \
+{ \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+} \
+static struct kobj_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
+
+#define RAPL_CNTR_WIDTH 32
+
+#define RAPL_EVENT_ATTR_STR(_name, v, str) \
+static struct perf_pmu_events_attr event_attr_##v = { \
+ .attr = __ATTR(_name, 0444, perf_event_sysfs_show, NULL), \
+ .id = 0, \
+ .event_str = str, \
+};
+
+struct rapl_pmu {
+ raw_spinlock_t lock;
+ int n_active;
+ int cpu;
+ struct list_head active_list;
+ struct pmu *pmu;
+ ktime_t timer_interval;
+ struct hrtimer hrtimer;
+};
+
+struct rapl_pmus {
+ struct pmu pmu;
+ unsigned int maxpkg;
+ struct rapl_pmu *pmus[];
+};
+
+ /* 1/2^hw_unit Joule */
+static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;
+static struct rapl_pmus *rapl_pmus;
+static cpumask_t rapl_cpu_mask;
+static unsigned int rapl_cntr_mask;
+static u64 rapl_timer_ms;
+
+static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
+{
+ return rapl_pmus->pmus[topology_logical_package_id(cpu)];
+}
+
+static inline u64 rapl_read_counter(struct perf_event *event)
+{
+ u64 raw;
+ rdmsrl(event->hw.event_base, raw);
+ return raw;
+}
+
+static inline u64 rapl_scale(u64 v, int cfg)
+{
+ if (cfg > NR_RAPL_DOMAINS) {
+ pr_warn("Invalid domain %d, failed to scale data\n", cfg);
+ return v;
+ }
+ /*
+ * scale delta to smallest unit (1/2^32)
+ * users must then scale back: count * 1/(1e9*2^32) to get Joules
+ * or use ldexp(count, -32).
+ * Watts = Joules/Time delta
+ */
+ return v << (32 - rapl_hw_unit[cfg - 1]);
+}
+
+static u64 rapl_event_update(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 prev_raw_count, new_raw_count;
+ s64 delta, sdelta;
+ int shift = RAPL_CNTR_WIDTH;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ rdmsrl(event->hw.event_base, new_raw_count);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count) {
+ cpu_relax();
+ goto again;
+ }
+
+ /*
+ * Now we have the new raw value and have updated the prev
+ * timestamp already. We can now calculate the elapsed delta
+ * (event-)time and add that to the generic event.
+ *
+ * Careful, not all hw sign-extends above the physical width
+ * of the count.
+ */
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ sdelta = rapl_scale(delta, event->hw.config);
+
+ local64_add(sdelta, &event->count);
+
+ return new_raw_count;
+}
+
+static void rapl_start_hrtimer(struct rapl_pmu *pmu)
+{
+ hrtimer_start(&pmu->hrtimer, pmu->timer_interval,
+ HRTIMER_MODE_REL_PINNED);
+}
+
+static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
+{
+ struct rapl_pmu *pmu = container_of(hrtimer, struct rapl_pmu, hrtimer);
+ struct perf_event *event;
+ unsigned long flags;
+
+ if (!pmu->n_active)
+ return HRTIMER_NORESTART;
+
+ raw_spin_lock_irqsave(&pmu->lock, flags);
+
+ list_for_each_entry(event, &pmu->active_list, active_entry)
+ rapl_event_update(event);
+
+ raw_spin_unlock_irqrestore(&pmu->lock, flags);
+
+ hrtimer_forward_now(hrtimer, pmu->timer_interval);
+
+ return HRTIMER_RESTART;
+}
+
+static void rapl_hrtimer_init(struct rapl_pmu *pmu)
+{
+ struct hrtimer *hr = &pmu->hrtimer;
+
+ hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hr->function = rapl_hrtimer_handle;
+}
+
+static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
+ struct perf_event *event)
+{
+ if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+ return;
+
+ event->hw.state = 0;
+
+ list_add_tail(&event->active_entry, &pmu->active_list);
+
+ local64_set(&event->hw.prev_count, rapl_read_counter(event));
+
+ pmu->n_active++;
+ if (pmu->n_active == 1)
+ rapl_start_hrtimer(pmu);
+}
+
+static void rapl_pmu_event_start(struct perf_event *event, int mode)
+{
+ struct rapl_pmu *pmu = event->pmu_private;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu->lock, flags);
+ __rapl_pmu_event_start(pmu, event);
+ raw_spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static void rapl_pmu_event_stop(struct perf_event *event, int mode)
+{
+ struct rapl_pmu *pmu = event->pmu_private;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu->lock, flags);
+
+ /* mark event as deactivated and stopped */
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ WARN_ON_ONCE(pmu->n_active <= 0);
+ pmu->n_active--;
+ if (pmu->n_active == 0)
+ hrtimer_cancel(&pmu->hrtimer);
+
+ list_del(&event->active_entry);
+
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+ }
+
+ /* check if update of sw counter is necessary */
+ if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ /*
+ * Drain the remaining delta count out of a event
+ * that we are disabling:
+ */
+ rapl_event_update(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+
+ raw_spin_unlock_irqrestore(&pmu->lock, flags);
+}
+
+static int rapl_pmu_event_add(struct perf_event *event, int mode)
+{
+ struct rapl_pmu *pmu = event->pmu_private;
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu->lock, flags);
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+ if (mode & PERF_EF_START)
+ __rapl_pmu_event_start(pmu, event);
+
+ raw_spin_unlock_irqrestore(&pmu->lock, flags);
+
+ return 0;
+}
+
+static void rapl_pmu_event_del(struct perf_event *event, int flags)
+{
+ rapl_pmu_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int rapl_pmu_event_init(struct perf_event *event)
+{
+ u64 cfg = event->attr.config & RAPL_EVENT_MASK;
+ int bit, msr, ret = 0;
+ struct rapl_pmu *pmu;
+
+ /* only look at RAPL events */
+ if (event->attr.type != rapl_pmus->pmu.type)
+ return -ENOENT;
+
+ /* check only supported bits are set */
+ if (event->attr.config & ~RAPL_EVENT_MASK)
+ return -EINVAL;
+
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ /*
+ * check event is known (determines counter)
+ */
+ switch (cfg) {
+ case INTEL_RAPL_PP0:
+ bit = RAPL_IDX_PP0_NRG_STAT;
+ msr = MSR_PP0_ENERGY_STATUS;
+ break;
+ case INTEL_RAPL_PKG:
+ bit = RAPL_IDX_PKG_NRG_STAT;
+ msr = MSR_PKG_ENERGY_STATUS;
+ break;
+ case INTEL_RAPL_RAM:
+ bit = RAPL_IDX_RAM_NRG_STAT;
+ msr = MSR_DRAM_ENERGY_STATUS;
+ break;
+ case INTEL_RAPL_PP1:
+ bit = RAPL_IDX_PP1_NRG_STAT;
+ msr = MSR_PP1_ENERGY_STATUS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* check event supported */
+ if (!(rapl_cntr_mask & (1 << bit)))
+ return -EINVAL;
+
+ /* unsupported modes and filters */
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period) /* no sampling */
+ return -EINVAL;
+
+ /* must be done before validate_group */
+ pmu = cpu_to_rapl_pmu(event->cpu);
+ event->cpu = pmu->cpu;
+ event->pmu_private = pmu;
+ event->hw.event_base = msr;
+ event->hw.config = cfg;
+ event->hw.idx = bit;
+
+ return ret;
+}
+
+static void rapl_pmu_event_read(struct perf_event *event)
+{
+ rapl_event_update(event);
+}
+
+static ssize_t rapl_get_attr_cpumask(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
+
+static struct attribute *rapl_pmu_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group rapl_pmu_attr_group = {
+ .attrs = rapl_pmu_attrs,
+};
+
+RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
+RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02");
+RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
+RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04");
+
+RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules");
+RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules");
+
+/*
+ * we compute in 0.23 nJ increments regardless of MSR
+ */
+RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
+RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10");
+
+static struct attribute *rapl_events_srv_attr[] = {
+ EVENT_PTR(rapl_cores),
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_ram),
+
+ EVENT_PTR(rapl_cores_unit),
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_ram_unit),
+
+ EVENT_PTR(rapl_cores_scale),
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_ram_scale),
+ NULL,
+};
+
+static struct attribute *rapl_events_cln_attr[] = {
+ EVENT_PTR(rapl_cores),
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_gpu),
+
+ EVENT_PTR(rapl_cores_unit),
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_gpu_unit),
+
+ EVENT_PTR(rapl_cores_scale),
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_gpu_scale),
+ NULL,
+};
+
+static struct attribute *rapl_events_hsw_attr[] = {
+ EVENT_PTR(rapl_cores),
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_gpu),
+ EVENT_PTR(rapl_ram),
+
+ EVENT_PTR(rapl_cores_unit),
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_gpu_unit),
+ EVENT_PTR(rapl_ram_unit),
+
+ EVENT_PTR(rapl_cores_scale),
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_gpu_scale),
+ EVENT_PTR(rapl_ram_scale),
+ NULL,
+};
+
+static struct attribute *rapl_events_knl_attr[] = {
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_ram),
+
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_ram_unit),
+
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_ram_scale),
+ NULL,
+};
+
+static struct attribute_group rapl_pmu_events_group = {
+ .name = "events",
+ .attrs = NULL, /* patched at runtime */
+};
+
+DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
+static struct attribute *rapl_formats_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group rapl_pmu_format_group = {
+ .name = "format",
+ .attrs = rapl_formats_attr,
+};
+
+const struct attribute_group *rapl_attr_groups[] = {
+ &rapl_pmu_attr_group,
+ &rapl_pmu_format_group,
+ &rapl_pmu_events_group,
+ NULL,
+};
+
+static void rapl_cpu_exit(int cpu)
+{
+ struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
+ int target;
+
+ /* Check if exiting cpu is used for collecting rapl events */
+ if (!cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask))
+ return;
+
+ pmu->cpu = -1;
+ /* Find a new cpu to collect rapl events */
+ target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+
+ /* Migrate rapl events to the new target */
+ if (target < nr_cpu_ids) {
+ cpumask_set_cpu(target, &rapl_cpu_mask);
+ pmu->cpu = target;
+ perf_pmu_migrate_context(pmu->pmu, cpu, target);
+ }
+}
+
+static void rapl_cpu_init(int cpu)
+{
+ struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
+ int target;
+
+ /*
+ * Check if there is an online cpu in the package which collects rapl
+ * events already.
+ */
+ target = cpumask_any_and(&rapl_cpu_mask, topology_core_cpumask(cpu));
+ if (target < nr_cpu_ids)
+ return;
+
+ cpumask_set_cpu(cpu, &rapl_cpu_mask);
+ pmu->cpu = cpu;
+}
+
+static int rapl_cpu_prepare(int cpu)
+{
+ struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
+
+ if (pmu)
+ return 0;
+
+ pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
+ if (!pmu)
+ return -ENOMEM;
+
+ raw_spin_lock_init(&pmu->lock);
+ INIT_LIST_HEAD(&pmu->active_list);
+ pmu->pmu = &rapl_pmus->pmu;
+ pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
+ pmu->cpu = -1;
+ rapl_hrtimer_init(pmu);
+ rapl_pmus->pmus[topology_logical_package_id(cpu)] = pmu;
+ return 0;
+}
+
+static int rapl_cpu_notifier(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ rapl_cpu_prepare(cpu);
+ break;
+
+ case CPU_DOWN_FAILED:
+ case CPU_ONLINE:
+ rapl_cpu_init(cpu);
+ break;
+
+ case CPU_DOWN_PREPARE:
+ rapl_cpu_exit(cpu);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static int rapl_check_hw_unit(bool apply_quirk)
+{
+ u64 msr_rapl_power_unit_bits;
+ int i;
+
+ /* protect rdmsrl() to handle virtualization */
+ if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+ return -1;
+ for (i = 0; i < NR_RAPL_DOMAINS; i++)
+ rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
+
+ /*
+ * DRAM domain on HSW server and KNL has fixed energy unit which can be
+ * different than the unit from power unit MSR. See
+ * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
+ * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
+ */
+ if (apply_quirk)
+ rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
+
+ /*
+ * Calculate the timer rate:
+ * Use reference of 200W for scaling the timeout to avoid counter
+ * overflows. 200W = 200 Joules/sec
+ * Divide interval by 2 to avoid lockstep (2 * 100)
+ * if hw unit is 32, then we use 2 ms 1/200/2
+ */
+ rapl_timer_ms = 2;
+ if (rapl_hw_unit[0] < 32) {
+ rapl_timer_ms = (1000 / (2 * 100));
+ rapl_timer_ms *= (1ULL << (32 - rapl_hw_unit[0] - 1));
+ }
+ return 0;
+}
+
+static void __init rapl_advertise(void)
+{
+ int i;
+
+ pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n",
+ hweight32(rapl_cntr_mask), rapl_timer_ms);
+
+ for (i = 0; i < NR_RAPL_DOMAINS; i++) {
+ if (rapl_cntr_mask & (1 << i)) {
+ pr_info("hw unit of domain %s 2^-%d Joules\n",
+ rapl_domain_names[i], rapl_hw_unit[i]);
+ }
+ }
+}
+
+static int __init rapl_prepare_cpus(void)
+{
+ unsigned int cpu, pkg;
+ int ret;
+
+ for_each_online_cpu(cpu) {
+ pkg = topology_logical_package_id(cpu);
+ if (rapl_pmus->pmus[pkg])
+ continue;
+
+ ret = rapl_cpu_prepare(cpu);
+ if (ret)
+ return ret;
+ rapl_cpu_init(cpu);
+ }
+ return 0;
+}
+
+static void __init cleanup_rapl_pmus(void)
+{
+ int i;
+
+ for (i = 0; i < rapl_pmus->maxpkg; i++)
+ kfree(rapl_pmus->pmus + i);
+ kfree(rapl_pmus);
+}
+
+static int __init init_rapl_pmus(void)
+{
+ int maxpkg = topology_max_packages();
+ size_t size;
+
+ size = sizeof(*rapl_pmus) + maxpkg * sizeof(struct rapl_pmu *);
+ rapl_pmus = kzalloc(size, GFP_KERNEL);
+ if (!rapl_pmus)
+ return -ENOMEM;
+
+ rapl_pmus->maxpkg = maxpkg;
+ rapl_pmus->pmu.attr_groups = rapl_attr_groups;
+ rapl_pmus->pmu.task_ctx_nr = perf_invalid_context;
+ rapl_pmus->pmu.event_init = rapl_pmu_event_init;
+ rapl_pmus->pmu.add = rapl_pmu_event_add;
+ rapl_pmus->pmu.del = rapl_pmu_event_del;
+ rapl_pmus->pmu.start = rapl_pmu_event_start;
+ rapl_pmus->pmu.stop = rapl_pmu_event_stop;
+ rapl_pmus->pmu.read = rapl_pmu_event_read;
+ return 0;
+}
+
+static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
+ [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
+ [1] = {},
+};
+
+static int __init rapl_pmu_init(void)
+{
+ bool apply_quirk = false;
+ int ret;
+
+ if (!x86_match_cpu(rapl_cpu_match))
+ return -ENODEV;
+
+ switch (boot_cpu_data.x86_model) {
+ case 42: /* Sandy Bridge */
+ case 58: /* Ivy Bridge */
+ rapl_cntr_mask = RAPL_IDX_CLN;
+ rapl_pmu_events_group.attrs = rapl_events_cln_attr;
+ break;
+ case 63: /* Haswell-Server */
+ apply_quirk = true;
+ rapl_cntr_mask = RAPL_IDX_SRV;
+ rapl_pmu_events_group.attrs = rapl_events_srv_attr;
+ break;
+ case 60: /* Haswell */
+ case 69: /* Haswell-Celeron */
+ case 61: /* Broadwell */
+ rapl_cntr_mask = RAPL_IDX_HSW;
+ rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
+ break;
+ case 45: /* Sandy Bridge-EP */
+ case 62: /* IvyTown */
+ rapl_cntr_mask = RAPL_IDX_SRV;
+ rapl_pmu_events_group.attrs = rapl_events_srv_attr;
+ break;
+ case 87: /* Knights Landing */
+ apply_quirk = true;
+ rapl_cntr_mask = RAPL_IDX_KNL;
+ rapl_pmu_events_group.attrs = rapl_events_knl_attr;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ret = rapl_check_hw_unit(apply_quirk);
+ if (ret)
+ return ret;
+
+ ret = init_rapl_pmus();
+ if (ret)
+ return ret;
+
+ cpu_notifier_register_begin();
+
+ ret = rapl_prepare_cpus();
+ if (ret)
+ goto out;
+
+ ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1);
+ if (ret)
+ goto out;
+
+ __perf_cpu_notifier(rapl_cpu_notifier);
+ cpu_notifier_register_done();
+ rapl_advertise();
+ return 0;
+
+out:
+ pr_warn("Initialization failed (%d), disabled\n", ret);
+ cleanup_rapl_pmus();
+ cpu_notifier_register_done();
+ return ret;
+}
+device_initcall(rapl_pmu_init);
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
new file mode 100644
index 0000000..7012d18
--- /dev/null
+++ b/arch/x86/events/intel/uncore.c
@@ -0,0 +1,1412 @@
+#include "uncore.h"
+
+static struct intel_uncore_type *empty_uncore[] = { NULL, };
+struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
+struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
+
+static bool pcidrv_registered;
+struct pci_driver *uncore_pci_driver;
+/* pci bus to socket mapping */
+DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
+struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
+struct pci_extra_dev *uncore_extra_pci_dev;
+static int max_packages;
+
+/* mask of cpus that collect uncore events */
+static cpumask_t uncore_cpu_mask;
+
+/* constraint for the fixed counter */
+static struct event_constraint uncore_constraint_fixed =
+ EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
+struct event_constraint uncore_constraint_empty =
+ EVENT_CONSTRAINT(0, 0, 0);
+
+static int uncore_pcibus_to_physid(struct pci_bus *bus)
+{
+ struct pci2phy_map *map;
+ int phys_id = -1;
+
+ raw_spin_lock(&pci2phy_map_lock);
+ list_for_each_entry(map, &pci2phy_map_head, list) {
+ if (map->segment == pci_domain_nr(bus)) {
+ phys_id = map->pbus_to_physid[bus->number];
+ break;
+ }
+ }
+ raw_spin_unlock(&pci2phy_map_lock);
+
+ return phys_id;
+}
+
+static void uncore_free_pcibus_map(void)
+{
+ struct pci2phy_map *map, *tmp;
+
+ list_for_each_entry_safe(map, tmp, &pci2phy_map_head, list) {
+ list_del(&map->list);
+ kfree(map);
+ }
+}
+
+struct pci2phy_map *__find_pci2phy_map(int segment)
+{
+ struct pci2phy_map *map, *alloc = NULL;
+ int i;
+
+ lockdep_assert_held(&pci2phy_map_lock);
+
+lookup:
+ list_for_each_entry(map, &pci2phy_map_head, list) {
+ if (map->segment == segment)
+ goto end;
+ }
+
+ if (!alloc) {
+ raw_spin_unlock(&pci2phy_map_lock);
+ alloc = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
+ raw_spin_lock(&pci2phy_map_lock);
+
+ if (!alloc)
+ return NULL;
+
+ goto lookup;
+ }
+
+ map = alloc;
+ alloc = NULL;
+ map->segment = segment;
+ for (i = 0; i < 256; i++)
+ map->pbus_to_physid[i] = -1;
+ list_add_tail(&map->list, &pci2phy_map_head);
+
+end:
+ kfree(alloc);
+ return map;
+}
+
+ssize_t uncore_event_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct uncore_event_desc *event =
+ container_of(attr, struct uncore_event_desc, attr);
+ return sprintf(buf, "%s", event->config);
+}
+
+struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
+{
+ return pmu->boxes[topology_logical_package_id(cpu)];
+}
+
+u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ u64 count;
+
+ rdmsrl(event->hw.event_base, count);
+
+ return count;
+}
+
+/*
+ * generic get constraint function for shared match/mask registers.
+ */
+struct event_constraint *
+uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ unsigned long flags;
+ bool ok = false;
+
+ /*
+ * reg->alloc can be set due to existing state, so for fake box we
+ * need to ignore this, otherwise we might fail to allocate proper
+ * fake state for this extra reg constraint.
+ */
+ if (reg1->idx == EXTRA_REG_NONE ||
+ (!uncore_box_is_fake(box) && reg1->alloc))
+ return NULL;
+
+ er = &box->shared_regs[reg1->idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (!atomic_read(&er->ref) ||
+ (er->config1 == reg1->config && er->config2 == reg2->config)) {
+ atomic_inc(&er->ref);
+ er->config1 = reg1->config;
+ er->config2 = reg2->config;
+ ok = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ if (ok) {
+ if (!uncore_box_is_fake(box))
+ reg1->alloc = 1;
+ return NULL;
+ }
+
+ return &uncore_constraint_empty;
+}
+
+void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+
+ /*
+ * Only put constraint if extra reg was actually allocated. Also
+ * takes care of event which do not use an extra shared reg.
+ *
+ * Also, if this is a fake box we shouldn't touch any event state
+ * (reg->alloc) and we don't care about leaving inconsistent box
+ * state either since it will be thrown out.
+ */
+ if (uncore_box_is_fake(box) || !reg1->alloc)
+ return;
+
+ er = &box->shared_regs[reg1->idx];
+ atomic_dec(&er->ref);
+ reg1->alloc = 0;
+}
+
+u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ u64 config;
+
+ er = &box->shared_regs[idx];
+
+ raw_spin_lock_irqsave(&er->lock, flags);
+ config = er->config;
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return config;
+}
+
+static void uncore_assign_hw_event(struct intel_uncore_box *box,
+ struct perf_event *event, int idx)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ hwc->idx = idx;
+ hwc->last_tag = ++box->tags[idx];
+
+ if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
+ hwc->event_base = uncore_fixed_ctr(box);
+ hwc->config_base = uncore_fixed_ctl(box);
+ return;
+ }
+
+ hwc->config_base = uncore_event_ctl(box, hwc->idx);
+ hwc->event_base = uncore_perf_ctr(box, hwc->idx);
+}
+
+void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
+{
+ u64 prev_count, new_count, delta;
+ int shift;
+
+ if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
+ shift = 64 - uncore_fixed_ctr_bits(box);
+ else
+ shift = 64 - uncore_perf_ctr_bits(box);
+
+ /* the hrtimer might modify the previous event value */
+again:
+ prev_count = local64_read(&event->hw.prev_count);
+ new_count = uncore_read_counter(box, event);
+ if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
+ goto again;
+
+ delta = (new_count << shift) - (prev_count << shift);
+ delta >>= shift;
+
+ local64_add(delta, &event->count);
+}
+
+/*
+ * The overflow interrupt is unavailable for SandyBridge-EP, is broken
+ * for SandyBridge. So we use hrtimer to periodically poll the counter
+ * to avoid overflow.
+ */
+static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
+{
+ struct intel_uncore_box *box;
+ struct perf_event *event;
+ unsigned long flags;
+ int bit;
+
+ box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
+ if (!box->n_active || box->cpu != smp_processor_id())
+ return HRTIMER_NORESTART;
+ /*
+ * disable local interrupt to prevent uncore_pmu_event_start/stop
+ * to interrupt the update process
+ */
+ local_irq_save(flags);
+
+ /*
+ * handle boxes with an active event list as opposed to active
+ * counters
+ */
+ list_for_each_entry(event, &box->active_list, active_entry) {
+ uncore_perf_event_update(box, event);
+ }
+
+ for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
+ uncore_perf_event_update(box, box->events[bit]);
+
+ local_irq_restore(flags);
+
+ hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
+ return HRTIMER_RESTART;
+}
+
+void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
+{
+ hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
+ HRTIMER_MODE_REL_PINNED);
+}
+
+void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
+{
+ hrtimer_cancel(&box->hrtimer);
+}
+
+static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
+{
+ hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ box->hrtimer.function = uncore_pmu_hrtimer;
+}
+
+static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
+ int node)
+{
+ int i, size, numshared = type->num_shared_regs ;
+ struct intel_uncore_box *box;
+
+ size = sizeof(*box) + numshared * sizeof(struct intel_uncore_extra_reg);
+
+ box = kzalloc_node(size, GFP_KERNEL, node);
+ if (!box)
+ return NULL;
+
+ for (i = 0; i < numshared; i++)
+ raw_spin_lock_init(&box->shared_regs[i].lock);
+
+ uncore_pmu_init_hrtimer(box);
+ box->cpu = -1;
+ box->pci_phys_id = -1;
+ box->pkgid = -1;
+
+ /* set default hrtimer timeout */
+ box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
+
+ INIT_LIST_HEAD(&box->active_list);
+
+ return box;
+}
+
+/*
+ * Using uncore_pmu_event_init pmu event_init callback
+ * as a detection point for uncore events.
+ */
+static int uncore_pmu_event_init(struct perf_event *event);
+
+static bool is_uncore_event(struct perf_event *event)
+{
+ return event->pmu->event_init == uncore_pmu_event_init;
+}
+
+static int
+uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader,
+ bool dogrp)
+{
+ struct perf_event *event;
+ int n, max_count;
+
+ max_count = box->pmu->type->num_counters;
+ if (box->pmu->type->fixed_ctl)
+ max_count++;
+
+ if (box->n_events >= max_count)
+ return -EINVAL;
+
+ n = box->n_events;
+
+ if (is_uncore_event(leader)) {
+ box->event_list[n] = leader;
+ n++;
+ }
+
+ if (!dogrp)
+ return n;
+
+ list_for_each_entry(event, &leader->sibling_list, group_entry) {
+ if (!is_uncore_event(event) ||
+ event->state <= PERF_EVENT_STATE_OFF)
+ continue;
+
+ if (n >= max_count)
+ return -EINVAL;
+
+ box->event_list[n] = event;
+ n++;
+ }
+ return n;
+}
+
+static struct event_constraint *
+uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_type *type = box->pmu->type;
+ struct event_constraint *c;
+
+ if (type->ops->get_constraint) {
+ c = type->ops->get_constraint(box, event);
+ if (c)
+ return c;
+ }
+
+ if (event->attr.config == UNCORE_FIXED_EVENT)
+ return &uncore_constraint_fixed;
+
+ if (type->constraints) {
+ for_each_event_constraint(c, type->constraints) {
+ if ((event->hw.config & c->cmask) == c->code)
+ return c;
+ }
+ }
+
+ return &type->unconstrainted;
+}
+
+static void uncore_put_event_constraint(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ if (box->pmu->type->ops->put_constraint)
+ box->pmu->type->ops->put_constraint(box, event);
+}
+
+static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
+{
+ unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
+ struct event_constraint *c;
+ int i, wmin, wmax, ret = 0;
+ struct hw_perf_event *hwc;
+
+ bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
+
+ for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+ c = uncore_get_event_constraint(box, box->event_list[i]);
+ box->event_constraint[i] = c;
+ wmin = min(wmin, c->weight);
+ wmax = max(wmax, c->weight);
+ }
+
+ /* fastpath, try to reuse previous register */
+ for (i = 0; i < n; i++) {
+ hwc = &box->event_list[i]->hw;
+ c = box->event_constraint[i];
+
+ /* never assigned */
+ if (hwc->idx == -1)
+ break;
+
+ /* constraint still honored */
+ if (!test_bit(hwc->idx, c->idxmsk))
+ break;
+
+ /* not already used */
+ if (test_bit(hwc->idx, used_mask))
+ break;
+
+ __set_bit(hwc->idx, used_mask);
+ if (assign)
+ assign[i] = hwc->idx;
+ }
+ /* slow path */
+ if (i != n)
+ ret = perf_assign_events(box->event_constraint, n,
+ wmin, wmax, n, assign);
+
+ if (!assign || ret) {
+ for (i = 0; i < n; i++)
+ uncore_put_event_constraint(box, box->event_list[i]);
+ }
+ return ret ? -EINVAL : 0;
+}
+
+static void uncore_pmu_event_start(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ int idx = event->hw.idx;
+
+ if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+ return;
+
+ if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
+ return;
+
+ event->hw.state = 0;
+ box->events[idx] = event;
+ box->n_active++;
+ __set_bit(idx, box->active_mask);
+
+ local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
+ uncore_enable_event(box, event);
+
+ if (box->n_active == 1) {
+ uncore_enable_box(box);
+ uncore_pmu_start_hrtimer(box);
+ }
+}
+
+static void uncore_pmu_event_stop(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
+ uncore_disable_event(box, event);
+ box->n_active--;
+ box->events[hwc->idx] = NULL;
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+
+ if (box->n_active == 0) {
+ uncore_disable_box(box);
+ uncore_pmu_cancel_hrtimer(box);
+ }
+ }
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ /*
+ * Drain the remaining delta count out of a event
+ * that we are disabling:
+ */
+ uncore_perf_event_update(box, event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+}
+
+static int uncore_pmu_event_add(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ struct hw_perf_event *hwc = &event->hw;
+ int assign[UNCORE_PMC_IDX_MAX];
+ int i, n, ret;
+
+ if (!box)
+ return -ENODEV;
+
+ ret = n = uncore_collect_events(box, event, false);
+ if (ret < 0)
+ return ret;
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (!(flags & PERF_EF_START))
+ hwc->state |= PERF_HES_ARCH;
+
+ ret = uncore_assign_events(box, assign, n);
+ if (ret)
+ return ret;
+
+ /* save events moving to new counters */
+ for (i = 0; i < box->n_events; i++) {
+ event = box->event_list[i];
+ hwc = &event->hw;
+
+ if (hwc->idx == assign[i] &&
+ hwc->last_tag == box->tags[assign[i]])
+ continue;
+ /*
+ * Ensure we don't accidentally enable a stopped
+ * counter simply because we rescheduled.
+ */
+ if (hwc->state & PERF_HES_STOPPED)
+ hwc->state |= PERF_HES_ARCH;
+
+ uncore_pmu_event_stop(event, PERF_EF_UPDATE);
+ }
+
+ /* reprogram moved events into new counters */
+ for (i = 0; i < n; i++) {
+ event = box->event_list[i];
+ hwc = &event->hw;
+
+ if (hwc->idx != assign[i] ||
+ hwc->last_tag != box->tags[assign[i]])
+ uncore_assign_hw_event(box, event, assign[i]);
+ else if (i < box->n_events)
+ continue;
+
+ if (hwc->state & PERF_HES_ARCH)
+ continue;
+
+ uncore_pmu_event_start(event, 0);
+ }
+ box->n_events = n;
+
+ return 0;
+}
+
+static void uncore_pmu_event_del(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ int i;
+
+ uncore_pmu_event_stop(event, PERF_EF_UPDATE);
+
+ for (i = 0; i < box->n_events; i++) {
+ if (event == box->event_list[i]) {
+ uncore_put_event_constraint(box, event);
+
+ for (++i; i < box->n_events; i++)
+ box->event_list[i - 1] = box->event_list[i];
+
+ --box->n_events;
+ break;
+ }
+ }
+
+ event->hw.idx = -1;
+ event->hw.last_tag = ~0ULL;
+}
+
+void uncore_pmu_event_read(struct perf_event *event)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ uncore_perf_event_update(box, event);
+}
+
+/*
+ * validation ensures the group can be loaded onto the
+ * PMU if it was the only group available.
+ */
+static int uncore_validate_group(struct intel_uncore_pmu *pmu,
+ struct perf_event *event)
+{
+ struct perf_event *leader = event->group_leader;
+ struct intel_uncore_box *fake_box;
+ int ret = -EINVAL, n;
+
+ fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
+ if (!fake_box)
+ return -ENOMEM;
+
+ fake_box->pmu = pmu;
+ /*
+ * the event is not yet connected with its
+ * siblings therefore we must first collect
+ * existing siblings, then add the new event
+ * before we can simulate the scheduling
+ */
+ n = uncore_collect_events(fake_box, leader, true);
+ if (n < 0)
+ goto out;
+
+ fake_box->n_events = n;
+ n = uncore_collect_events(fake_box, event, false);
+ if (n < 0)
+ goto out;
+
+ fake_box->n_events = n;
+
+ ret = uncore_assign_events(fake_box, NULL, n);
+out:
+ kfree(fake_box);
+ return ret;
+}
+
+static int uncore_pmu_event_init(struct perf_event *event)
+{
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ struct hw_perf_event *hwc = &event->hw;
+ int ret;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ pmu = uncore_event_to_pmu(event);
+ /* no device found for this pmu */
+ if (pmu->func_id < 0)
+ return -ENOENT;
+
+ /*
+ * Uncore PMU does measure at all privilege level all the time.
+ * So it doesn't make sense to specify any exclude bits.
+ */
+ if (event->attr.exclude_user || event->attr.exclude_kernel ||
+ event->attr.exclude_hv || event->attr.exclude_idle)
+ return -EINVAL;
+
+ /* Sampling not supported yet */
+ if (hwc->sample_period)
+ return -EINVAL;
+
+ /*
+ * Place all uncore events for a particular physical package
+ * onto a single cpu
+ */
+ if (event->cpu < 0)
+ return -EINVAL;
+ box = uncore_pmu_to_box(pmu, event->cpu);
+ if (!box || box->cpu < 0)
+ return -EINVAL;
+ event->cpu = box->cpu;
+ event->pmu_private = box;
+
+ event->hw.idx = -1;
+ event->hw.last_tag = ~0ULL;
+ event->hw.extra_reg.idx = EXTRA_REG_NONE;
+ event->hw.branch_reg.idx = EXTRA_REG_NONE;
+
+ if (event->attr.config == UNCORE_FIXED_EVENT) {
+ /* no fixed counter */
+ if (!pmu->type->fixed_ctl)
+ return -EINVAL;
+ /*
+ * if there is only one fixed counter, only the first pmu
+ * can access the fixed counter
+ */
+ if (pmu->type->single_fixed && pmu->pmu_idx > 0)
+ return -EINVAL;
+
+ /* fixed counters have event field hardcoded to zero */
+ hwc->config = 0ULL;
+ } else {
+ hwc->config = event->attr.config & pmu->type->event_mask;
+ if (pmu->type->ops->hw_config) {
+ ret = pmu->type->ops->hw_config(box, event);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (event->group_leader != event)
+ ret = uncore_validate_group(pmu, event);
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static ssize_t uncore_get_attr_cpumask(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
+
+static struct attribute *uncore_pmu_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group uncore_pmu_attr_group = {
+ .attrs = uncore_pmu_attrs,
+};
+
+static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
+{
+ int ret;
+
+ if (!pmu->type->pmu) {
+ pmu->pmu = (struct pmu) {
+ .attr_groups = pmu->type->attr_groups,
+ .task_ctx_nr = perf_invalid_context,
+ .event_init = uncore_pmu_event_init,
+ .add = uncore_pmu_event_add,
+ .del = uncore_pmu_event_del,
+ .start = uncore_pmu_event_start,
+ .stop = uncore_pmu_event_stop,
+ .read = uncore_pmu_event_read,
+ };
+ } else {
+ pmu->pmu = *pmu->type->pmu;
+ pmu->pmu.attr_groups = pmu->type->attr_groups;
+ }
+
+ if (pmu->type->num_boxes == 1) {
+ if (strlen(pmu->type->name) > 0)
+ sprintf(pmu->name, "uncore_%s", pmu->type->name);
+ else
+ sprintf(pmu->name, "uncore");
+ } else {
+ sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
+ pmu->pmu_idx);
+ }
+
+ ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
+ if (!ret)
+ pmu->registered = true;
+ return ret;
+}
+
+static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
+{
+ if (!pmu->registered)
+ return;
+ perf_pmu_unregister(&pmu->pmu);
+ pmu->registered = false;
+}
+
+static void __init __uncore_exit_boxes(struct intel_uncore_type *type, int cpu)
+{
+ struct intel_uncore_pmu *pmu = type->pmus;
+ struct intel_uncore_box *box;
+ int i, pkg;
+
+ if (pmu) {
+ pkg = topology_physical_package_id(cpu);
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ box = pmu->boxes[pkg];
+ if (box)
+ uncore_box_exit(box);
+ }
+ }
+}
+
+static void __init uncore_exit_boxes(void *dummy)
+{
+ struct intel_uncore_type **types;
+
+ for (types = uncore_msr_uncores; *types; types++)
+ __uncore_exit_boxes(*types++, smp_processor_id());
+}
+
+static void uncore_free_boxes(struct intel_uncore_pmu *pmu)
+{
+ int pkg;
+
+ for (pkg = 0; pkg < max_packages; pkg++)
+ kfree(pmu->boxes[pkg]);
+ kfree(pmu->boxes);
+}
+
+static void __init uncore_type_exit(struct intel_uncore_type *type)
+{
+ struct intel_uncore_pmu *pmu = type->pmus;
+ int i;
+
+ if (pmu) {
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ uncore_pmu_unregister(pmu);
+ uncore_free_boxes(pmu);
+ }
+ kfree(type->pmus);
+ type->pmus = NULL;
+ }
+ kfree(type->events_group);
+ type->events_group = NULL;
+}
+
+static void __init uncore_types_exit(struct intel_uncore_type **types)
+{
+ for (; *types; types++)
+ uncore_type_exit(*types);
+}
+
+static int __init uncore_type_init(struct intel_uncore_type *type, bool setid)
+{
+ struct intel_uncore_pmu *pmus;
+ struct attribute_group *attr_group;
+ struct attribute **attrs;
+ size_t size;
+ int i, j;
+
+ pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
+ if (!pmus)
+ return -ENOMEM;
+
+ size = max_packages * sizeof(struct intel_uncore_box *);
+
+ for (i = 0; i < type->num_boxes; i++) {
+ pmus[i].func_id = setid ? i : -1;
+ pmus[i].pmu_idx = i;
+ pmus[i].type = type;
+ pmus[i].boxes = kzalloc(size, GFP_KERNEL);
+ if (!pmus[i].boxes)
+ return -ENOMEM;
+ }
+
+ type->pmus = pmus;
+ type->unconstrainted = (struct event_constraint)
+ __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
+ 0, type->num_counters, 0, 0);
+
+ if (type->event_descs) {
+ for (i = 0; type->event_descs[i].attr.attr.name; i++);
+
+ attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
+ sizeof(*attr_group), GFP_KERNEL);
+ if (!attr_group)
+ return -ENOMEM;
+
+ attrs = (struct attribute **)(attr_group + 1);
+ attr_group->name = "events";
+ attr_group->attrs = attrs;
+
+ for (j = 0; j < i; j++)
+ attrs[j] = &type->event_descs[j].attr.attr;
+
+ type->events_group = attr_group;
+ }
+
+ type->pmu_group = &uncore_pmu_attr_group;
+ return 0;
+}
+
+static int __init
+uncore_types_init(struct intel_uncore_type **types, bool setid)
+{
+ int ret;
+
+ for (; *types; types++) {
+ ret = uncore_type_init(*types, setid);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ * add a pci uncore device
+ */
+static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct intel_uncore_type *type;
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ int phys_id, pkg, ret;
+
+ phys_id = uncore_pcibus_to_physid(pdev->bus);
+ if (phys_id < 0)
+ return -ENODEV;
+
+ pkg = topology_phys_to_logical_pkg(phys_id);
+ if (WARN_ON_ONCE(pkg < 0))
+ return -EINVAL;
+
+ if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
+ int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
+
+ uncore_extra_pci_dev[pkg].dev[idx] = pdev;
+ pci_set_drvdata(pdev, NULL);
+ return 0;
+ }
+
+ type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
+ /*
+ * for performance monitoring unit with multiple boxes,
+ * each box has a different function id.
+ */
+ pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
+ /* Knights Landing uses a common PCI device ID for multiple instances of
+ * an uncore PMU device type. There is only one entry per device type in
+ * the knl_uncore_pci_ids table inspite of multiple devices present for
+ * some device types. Hence PCI device idx would be 0 for all devices.
+ * So increment pmu pointer to point to an unused array element.
+ */
+ if (boot_cpu_data.x86_model == 87) {
+ while (pmu->func_id >= 0)
+ pmu++;
+ }
+
+ if (WARN_ON_ONCE(pmu->boxes[pkg] != NULL))
+ return -EINVAL;
+
+ box = uncore_alloc_box(type, NUMA_NO_NODE);
+ if (!box)
+ return -ENOMEM;
+
+ if (pmu->func_id < 0)
+ pmu->func_id = pdev->devfn;
+ else
+ WARN_ON_ONCE(pmu->func_id != pdev->devfn);
+
+ atomic_inc(&box->refcnt);
+ box->pci_phys_id = phys_id;
+ box->pkgid = pkg;
+ box->pci_dev = pdev;
+ box->pmu = pmu;
+ uncore_box_init(box);
+ pci_set_drvdata(pdev, box);
+
+ pmu->boxes[pkg] = box;
+ if (atomic_inc_return(&pmu->activeboxes) > 1)
+ return 0;
+
+ /* First active box registers the pmu */
+ ret = uncore_pmu_register(pmu);
+ if (ret) {
+ pci_set_drvdata(pdev, NULL);
+ pmu->boxes[pkg] = NULL;
+ uncore_box_exit(box);
+ kfree(box);
+ }
+ return ret;
+}
+
+static void uncore_pci_remove(struct pci_dev *pdev)
+{
+ struct intel_uncore_box *box = pci_get_drvdata(pdev);
+ struct intel_uncore_pmu *pmu;
+ int i, phys_id, pkg;
+
+ phys_id = uncore_pcibus_to_physid(pdev->bus);
+ pkg = topology_phys_to_logical_pkg(phys_id);
+
+ box = pci_get_drvdata(pdev);
+ if (!box) {
+ for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
+ if (uncore_extra_pci_dev[pkg].dev[i] == pdev) {
+ uncore_extra_pci_dev[pkg].dev[i] = NULL;
+ break;
+ }
+ }
+ WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
+ return;
+ }
+
+ pmu = box->pmu;
+ if (WARN_ON_ONCE(phys_id != box->pci_phys_id))
+ return;
+
+ pci_set_drvdata(pdev, NULL);
+ pmu->boxes[pkg] = NULL;
+ if (atomic_dec_return(&pmu->activeboxes) == 0)
+ uncore_pmu_unregister(pmu);
+ uncore_box_exit(box);
+ kfree(box);
+}
+
+static int __init uncore_pci_init(void)
+{
+ size_t size;
+ int ret;
+
+ switch (boot_cpu_data.x86_model) {
+ case 45: /* Sandy Bridge-EP */
+ ret = snbep_uncore_pci_init();
+ break;
+ case 62: /* Ivy Bridge-EP */
+ ret = ivbep_uncore_pci_init();
+ break;
+ case 63: /* Haswell-EP */
+ ret = hswep_uncore_pci_init();
+ break;
+ case 79: /* BDX-EP */
+ case 86: /* BDX-DE */
+ ret = bdx_uncore_pci_init();
+ break;
+ case 42: /* Sandy Bridge */
+ ret = snb_uncore_pci_init();
+ break;
+ case 58: /* Ivy Bridge */
+ ret = ivb_uncore_pci_init();
+ break;
+ case 60: /* Haswell */
+ case 69: /* Haswell Celeron */
+ ret = hsw_uncore_pci_init();
+ break;
+ case 61: /* Broadwell */
+ ret = bdw_uncore_pci_init();
+ break;
+ case 87: /* Knights Landing */
+ ret = knl_uncore_pci_init();
+ break;
+ case 94: /* SkyLake */
+ ret = skl_uncore_pci_init();
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ if (ret)
+ return ret;
+
+ size = max_packages * sizeof(struct pci_extra_dev);
+ uncore_extra_pci_dev = kzalloc(size, GFP_KERNEL);
+ if (!uncore_extra_pci_dev) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = uncore_types_init(uncore_pci_uncores, false);
+ if (ret)
+ goto errtype;
+
+ uncore_pci_driver->probe = uncore_pci_probe;
+ uncore_pci_driver->remove = uncore_pci_remove;
+
+ ret = pci_register_driver(uncore_pci_driver);
+ if (ret)
+ goto errtype;
+
+ pcidrv_registered = true;
+ return 0;
+
+errtype:
+ uncore_types_exit(uncore_pci_uncores);
+ kfree(uncore_extra_pci_dev);
+ uncore_extra_pci_dev = NULL;
+ uncore_free_pcibus_map();
+err:
+ uncore_pci_uncores = empty_uncore;
+ return ret;
+}
+
+static void __init uncore_pci_exit(void)
+{
+ if (pcidrv_registered) {
+ pcidrv_registered = false;
+ pci_unregister_driver(uncore_pci_driver);
+ uncore_types_exit(uncore_pci_uncores);
+ kfree(uncore_extra_pci_dev);
+ uncore_free_pcibus_map();
+ }
+}
+
+static void uncore_cpu_dying(int cpu)
+{
+ struct intel_uncore_type *type, **types = uncore_msr_uncores;
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ int i, pkg;
+
+ pkg = topology_logical_package_id(cpu);
+ for (; *types; types++) {
+ type = *types;
+ pmu = type->pmus;
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ box = pmu->boxes[pkg];
+ if (box && atomic_dec_return(&box->refcnt) == 0)
+ uncore_box_exit(box);
+ }
+ }
+}
+
+static void uncore_cpu_starting(int cpu, bool init)
+{
+ struct intel_uncore_type *type, **types = uncore_msr_uncores;
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ int i, pkg, ncpus = 1;
+
+ if (init) {
+ /*
+ * On init we get the number of online cpus in the package
+ * and set refcount for all of them.
+ */
+ ncpus = cpumask_weight(topology_core_cpumask(cpu));
+ }
+
+ pkg = topology_logical_package_id(cpu);
+ for (; *types; types++) {
+ type = *types;
+ pmu = type->pmus;
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ box = pmu->boxes[pkg];
+ if (!box)
+ continue;
+ /* The first cpu on a package activates the box */
+ if (atomic_add_return(ncpus, &box->refcnt) == ncpus)
+ uncore_box_init(box);
+ }
+ }
+}
+
+static int uncore_cpu_prepare(int cpu)
+{
+ struct intel_uncore_type *type, **types = uncore_msr_uncores;
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ int i, pkg;
+
+ pkg = topology_logical_package_id(cpu);
+ for (; *types; types++) {
+ type = *types;
+ pmu = type->pmus;
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ if (pmu->boxes[pkg])
+ continue;
+ /* First cpu of a package allocates the box */
+ box = uncore_alloc_box(type, cpu_to_node(cpu));
+ if (!box)
+ return -ENOMEM;
+ box->pmu = pmu;
+ box->pkgid = pkg;
+ pmu->boxes[pkg] = box;
+ }
+ }
+ return 0;
+}
+
+static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
+ int new_cpu)
+{
+ struct intel_uncore_pmu *pmu = type->pmus;
+ struct intel_uncore_box *box;
+ int i, pkg;
+
+ pkg = topology_logical_package_id(old_cpu < 0 ? new_cpu : old_cpu);
+ for (i = 0; i < type->num_boxes; i++, pmu++) {
+ box = pmu->boxes[pkg];
+ if (!box)
+ continue;
+
+ if (old_cpu < 0) {
+ WARN_ON_ONCE(box->cpu != -1);
+ box->cpu = new_cpu;
+ continue;
+ }
+
+ WARN_ON_ONCE(box->cpu != old_cpu);
+ box->cpu = -1;
+ if (new_cpu < 0)
+ continue;
+
+ uncore_pmu_cancel_hrtimer(box);
+ perf_pmu_migrate_context(&pmu->pmu, old_cpu, new_cpu);
+ box->cpu = new_cpu;
+ }
+}
+
+static void uncore_change_context(struct intel_uncore_type **uncores,
+ int old_cpu, int new_cpu)
+{
+ for (; *uncores; uncores++)
+ uncore_change_type_ctx(*uncores, old_cpu, new_cpu);
+}
+
+static void uncore_event_exit_cpu(int cpu)
+{
+ int target;
+
+ /* Check if exiting cpu is used for collecting uncore events */
+ if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
+ return;
+
+ /* Find a new cpu to collect uncore events */
+ target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+
+ /* Migrate uncore events to the new target */
+ if (target < nr_cpu_ids)
+ cpumask_set_cpu(target, &uncore_cpu_mask);
+ else
+ target = -1;
+
+ uncore_change_context(uncore_msr_uncores, cpu, target);
+ uncore_change_context(uncore_pci_uncores, cpu, target);
+}
+
+static void uncore_event_init_cpu(int cpu)
+{
+ int target;
+
+ /*
+ * Check if there is an online cpu in the package
+ * which collects uncore events already.
+ */
+ target = cpumask_any_and(&uncore_cpu_mask, topology_core_cpumask(cpu));
+ if (target < nr_cpu_ids)
+ return;
+
+ cpumask_set_cpu(cpu, &uncore_cpu_mask);
+
+ uncore_change_context(uncore_msr_uncores, -1, cpu);
+ uncore_change_context(uncore_pci_uncores, -1, cpu);
+}
+
+static int uncore_cpu_notifier(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ return notifier_from_errno(uncore_cpu_prepare(cpu));
+
+ case CPU_STARTING:
+ uncore_cpu_starting(cpu, false);
+ case CPU_DOWN_FAILED:
+ uncore_event_init_cpu(cpu);
+ break;
+
+ case CPU_UP_CANCELED:
+ case CPU_DYING:
+ uncore_cpu_dying(cpu);
+ break;
+
+ case CPU_DOWN_PREPARE:
+ uncore_event_exit_cpu(cpu);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block uncore_cpu_nb = {
+ .notifier_call = uncore_cpu_notifier,
+ /*
+ * to migrate uncore events, our notifier should be executed
+ * before perf core's notifier.
+ */
+ .priority = CPU_PRI_PERF + 1,
+};
+
+static int __init type_pmu_register(struct intel_uncore_type *type)
+{
+ int i, ret;
+
+ for (i = 0; i < type->num_boxes; i++) {
+ ret = uncore_pmu_register(&type->pmus[i]);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int __init uncore_msr_pmus_register(void)
+{
+ struct intel_uncore_type **types = uncore_msr_uncores;
+ int ret;
+
+ for (; *types; types++) {
+ ret = type_pmu_register(*types);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int __init uncore_cpu_init(void)
+{
+ int ret;
+
+ switch (boot_cpu_data.x86_model) {
+ case 26: /* Nehalem */
+ case 30:
+ case 37: /* Westmere */
+ case 44:
+ nhm_uncore_cpu_init();
+ break;
+ case 42: /* Sandy Bridge */
+ case 58: /* Ivy Bridge */
+ case 60: /* Haswell */
+ case 69: /* Haswell */
+ case 70: /* Haswell */
+ case 61: /* Broadwell */
+ case 71: /* Broadwell */
+ snb_uncore_cpu_init();
+ break;
+ case 45: /* Sandy Bridge-EP */
+ snbep_uncore_cpu_init();
+ break;
+ case 46: /* Nehalem-EX */
+ case 47: /* Westmere-EX aka. Xeon E7 */
+ nhmex_uncore_cpu_init();
+ break;
+ case 62: /* Ivy Bridge-EP */
+ ivbep_uncore_cpu_init();
+ break;
+ case 63: /* Haswell-EP */
+ hswep_uncore_cpu_init();
+ break;
+ case 79: /* BDX-EP */
+ case 86: /* BDX-DE */
+ bdx_uncore_cpu_init();
+ break;
+ case 87: /* Knights Landing */
+ knl_uncore_cpu_init();
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ret = uncore_types_init(uncore_msr_uncores, true);
+ if (ret)
+ goto err;
+
+ ret = uncore_msr_pmus_register();
+ if (ret)
+ goto err;
+ return 0;
+err:
+ uncore_types_exit(uncore_msr_uncores);
+ uncore_msr_uncores = empty_uncore;
+ return ret;
+}
+
+static void __init uncore_cpu_setup(void *dummy)
+{
+ uncore_cpu_starting(smp_processor_id(), true);
+}
+
+/* Lazy to avoid allocation of a few bytes for the normal case */
+static __initdata DECLARE_BITMAP(packages, MAX_LOCAL_APIC);
+
+static int __init uncore_cpumask_init(bool msr)
+{
+ unsigned int cpu;
+
+ for_each_online_cpu(cpu) {
+ unsigned int pkg = topology_logical_package_id(cpu);
+ int ret;
+
+ if (test_and_set_bit(pkg, packages))
+ continue;
+ /*
+ * The first online cpu of each package allocates and takes
+ * the refcounts for all other online cpus in that package.
+ * If msrs are not enabled no allocation is required.
+ */
+ if (msr) {
+ ret = uncore_cpu_prepare(cpu);
+ if (ret)
+ return ret;
+ }
+ uncore_event_init_cpu(cpu);
+ smp_call_function_single(cpu, uncore_cpu_setup, NULL, 1);
+ }
+ __register_cpu_notifier(&uncore_cpu_nb);
+ return 0;
+}
+
+static int __init intel_uncore_init(void)
+{
+ int pret, cret, ret;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+ return -ENODEV;
+
+ if (cpu_has_hypervisor)
+ return -ENODEV;
+
+ max_packages = topology_max_packages();
+
+ pret = uncore_pci_init();
+ cret = uncore_cpu_init();
+
+ if (cret && pret)
+ return -ENODEV;
+
+ cpu_notifier_register_begin();
+ ret = uncore_cpumask_init(!cret);
+ if (ret)
+ goto err;
+ cpu_notifier_register_done();
+ return 0;
+
+err:
+ /* Undo box->init_box() */
+ on_each_cpu_mask(&uncore_cpu_mask, uncore_exit_boxes, NULL, 1);
+ uncore_types_exit(uncore_msr_uncores);
+ uncore_pci_exit();
+ cpu_notifier_register_done();
+ return ret;
+}
+device_initcall(intel_uncore_init);
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
new file mode 100644
index 0000000..79766b9
--- /dev/null
+++ b/arch/x86/events/intel/uncore.h
@@ -0,0 +1,378 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <asm/apicdef.h>
+
+#include <linux/perf_event.h>
+#include "../perf_event.h"
+
+#define UNCORE_PMU_NAME_LEN 32
+#define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC)
+#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC)
+
+#define UNCORE_FIXED_EVENT 0xff
+#define UNCORE_PMC_IDX_MAX_GENERIC 8
+#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC
+#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1)
+
+#define UNCORE_PCI_DEV_DATA(type, idx) ((type << 8) | idx)
+#define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff)
+#define UNCORE_PCI_DEV_IDX(data) (data & 0xff)
+#define UNCORE_EXTRA_PCI_DEV 0xff
+#define UNCORE_EXTRA_PCI_DEV_MAX 3
+
+#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
+
+struct pci_extra_dev {
+ struct pci_dev *dev[UNCORE_EXTRA_PCI_DEV_MAX];
+};
+
+struct intel_uncore_ops;
+struct intel_uncore_pmu;
+struct intel_uncore_box;
+struct uncore_event_desc;
+
+struct intel_uncore_type {
+ const char *name;
+ int num_counters;
+ int num_boxes;
+ int perf_ctr_bits;
+ int fixed_ctr_bits;
+ unsigned perf_ctr;
+ unsigned event_ctl;
+ unsigned event_mask;
+ unsigned fixed_ctr;
+ unsigned fixed_ctl;
+ unsigned box_ctl;
+ unsigned msr_offset;
+ unsigned num_shared_regs:8;
+ unsigned single_fixed:1;
+ unsigned pair_ctr_ctl:1;
+ unsigned *msr_offsets;
+ struct event_constraint unconstrainted;
+ struct event_constraint *constraints;
+ struct intel_uncore_pmu *pmus;
+ struct intel_uncore_ops *ops;
+ struct uncore_event_desc *event_descs;
+ const struct attribute_group *attr_groups[4];
+ struct pmu *pmu; /* for custom pmu ops */
+};
+
+#define pmu_group attr_groups[0]
+#define format_group attr_groups[1]
+#define events_group attr_groups[2]
+
+struct intel_uncore_ops {
+ void (*init_box)(struct intel_uncore_box *);
+ void (*exit_box)(struct intel_uncore_box *);
+ void (*disable_box)(struct intel_uncore_box *);
+ void (*enable_box)(struct intel_uncore_box *);
+ void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
+ void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
+ u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
+ int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
+ struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
+ struct perf_event *);
+ void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
+};
+
+struct intel_uncore_pmu {
+ struct pmu pmu;
+ char name[UNCORE_PMU_NAME_LEN];
+ int pmu_idx;
+ int func_id;
+ bool registered;
+ atomic_t activeboxes;
+ struct intel_uncore_type *type;
+ struct intel_uncore_box **boxes;
+};
+
+struct intel_uncore_extra_reg {
+ raw_spinlock_t lock;
+ u64 config, config1, config2;
+ atomic_t ref;
+};
+
+struct intel_uncore_box {
+ int pci_phys_id;
+ int pkgid;
+ int n_active; /* number of active events */
+ int n_events;
+ int cpu; /* cpu to collect events */
+ unsigned long flags;
+ atomic_t refcnt;
+ struct perf_event *events[UNCORE_PMC_IDX_MAX];
+ struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
+ struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX];
+ unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
+ u64 tags[UNCORE_PMC_IDX_MAX];
+ struct pci_dev *pci_dev;
+ struct intel_uncore_pmu *pmu;
+ u64 hrtimer_duration; /* hrtimer timeout for this box */
+ struct hrtimer hrtimer;
+ struct list_head list;
+ struct list_head active_list;
+ void *io_addr;
+ struct intel_uncore_extra_reg shared_regs[0];
+};
+
+#define UNCORE_BOX_FLAG_INITIATED 0
+
+struct uncore_event_desc {
+ struct kobj_attribute attr;
+ const char *config;
+};
+
+struct pci2phy_map {
+ struct list_head list;
+ int segment;
+ int pbus_to_physid[256];
+};
+
+struct pci2phy_map *__find_pci2phy_map(int segment);
+
+ssize_t uncore_event_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf);
+
+#define INTEL_UNCORE_EVENT_DESC(_name, _config) \
+{ \
+ .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \
+ .config = _config, \
+}
+
+#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
+static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ char *page) \
+{ \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+} \
+static struct kobj_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
+
+static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
+{
+ return box->pmu->type->box_ctl;
+}
+
+static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
+{
+ return box->pmu->type->fixed_ctl;
+}
+
+static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
+{
+ return box->pmu->type->fixed_ctr;
+}
+
+static inline
+unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
+{
+ return idx * 4 + box->pmu->type->event_ctl;
+}
+
+static inline
+unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+ return idx * 8 + box->pmu->type->perf_ctr;
+}
+
+static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
+{
+ struct intel_uncore_pmu *pmu = box->pmu;
+ return pmu->type->msr_offsets ?
+ pmu->type->msr_offsets[pmu->pmu_idx] :
+ pmu->type->msr_offset * pmu->pmu_idx;
+}
+
+static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
+{
+ if (!box->pmu->type->box_ctl)
+ return 0;
+ return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
+}
+
+static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
+{
+ if (!box->pmu->type->fixed_ctl)
+ return 0;
+ return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
+}
+
+static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
+{
+ return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
+{
+ return box->pmu->type->event_ctl +
+ (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+ uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+ return box->pmu->type->perf_ctr +
+ (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+ uncore_msr_box_offset(box);
+}
+
+static inline
+unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
+{
+ if (box->pci_dev)
+ return uncore_pci_fixed_ctl(box);
+ else
+ return uncore_msr_fixed_ctl(box);
+}
+
+static inline
+unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
+{
+ if (box->pci_dev)
+ return uncore_pci_fixed_ctr(box);
+ else
+ return uncore_msr_fixed_ctr(box);
+}
+
+static inline
+unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
+{
+ if (box->pci_dev)
+ return uncore_pci_event_ctl(box, idx);
+ else
+ return uncore_msr_event_ctl(box, idx);
+}
+
+static inline
+unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
+{
+ if (box->pci_dev)
+ return uncore_pci_perf_ctr(box, idx);
+ else
+ return uncore_msr_perf_ctr(box, idx);
+}
+
+static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
+{
+ return box->pmu->type->perf_ctr_bits;
+}
+
+static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
+{
+ return box->pmu->type->fixed_ctr_bits;
+}
+
+static inline int uncore_num_counters(struct intel_uncore_box *box)
+{
+ return box->pmu->type->num_counters;
+}
+
+static inline void uncore_disable_box(struct intel_uncore_box *box)
+{
+ if (box->pmu->type->ops->disable_box)
+ box->pmu->type->ops->disable_box(box);
+}
+
+static inline void uncore_enable_box(struct intel_uncore_box *box)
+{
+ if (box->pmu->type->ops->enable_box)
+ box->pmu->type->ops->enable_box(box);
+}
+
+static inline void uncore_disable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ box->pmu->type->ops->disable_event(box, event);
+}
+
+static inline void uncore_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ box->pmu->type->ops->enable_event(box, event);
+}
+
+static inline u64 uncore_read_counter(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ return box->pmu->type->ops->read_counter(box, event);
+}
+
+static inline void uncore_box_init(struct intel_uncore_box *box)
+{
+ if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
+ if (box->pmu->type->ops->init_box)
+ box->pmu->type->ops->init_box(box);
+ }
+}
+
+static inline void uncore_box_exit(struct intel_uncore_box *box)
+{
+ if (test_and_clear_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
+ if (box->pmu->type->ops->exit_box)
+ box->pmu->type->ops->exit_box(box);
+ }
+}
+
+static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
+{
+ return (box->pkgid < 0);
+}
+
+static inline struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
+{
+ return container_of(event->pmu, struct intel_uncore_pmu, pmu);
+}
+
+static inline struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
+{
+ return event->pmu_private;
+}
+
+struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
+u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
+void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
+void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
+void uncore_pmu_event_read(struct perf_event *event);
+void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event);
+struct event_constraint *
+uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
+void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
+u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
+
+extern struct intel_uncore_type **uncore_msr_uncores;
+extern struct intel_uncore_type **uncore_pci_uncores;
+extern struct pci_driver *uncore_pci_driver;
+extern raw_spinlock_t pci2phy_map_lock;
+extern struct list_head pci2phy_map_head;
+extern struct pci_extra_dev *uncore_extra_pci_dev;
+extern struct event_constraint uncore_constraint_empty;
+
+/* perf_event_intel_uncore_snb.c */
+int snb_uncore_pci_init(void);
+int ivb_uncore_pci_init(void);
+int hsw_uncore_pci_init(void);
+int bdw_uncore_pci_init(void);
+int skl_uncore_pci_init(void);
+void snb_uncore_cpu_init(void);
+void nhm_uncore_cpu_init(void);
+int snb_pci2phy_map_init(int devid);
+
+/* perf_event_intel_uncore_snbep.c */
+int snbep_uncore_pci_init(void);
+void snbep_uncore_cpu_init(void);
+int ivbep_uncore_pci_init(void);
+void ivbep_uncore_cpu_init(void);
+int hswep_uncore_pci_init(void);
+void hswep_uncore_cpu_init(void);
+int bdx_uncore_pci_init(void);
+void bdx_uncore_cpu_init(void);
+int knl_uncore_pci_init(void);
+void knl_uncore_cpu_init(void);
+
+/* perf_event_intel_uncore_nhmex.c */
+void nhmex_uncore_cpu_init(void);
diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c
new file mode 100644
index 0000000..cda5693
--- /dev/null
+++ b/arch/x86/events/intel/uncore_nhmex.c
@@ -0,0 +1,1227 @@
+/* Nehalem-EX/Westmere-EX uncore support */
+#include "uncore.h"
+
+/* NHM-EX event control */
+#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff
+#define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00
+#define NHMEX_PMON_CTL_EN_BIT0 (1 << 0)
+#define NHMEX_PMON_CTL_EDGE_DET (1 << 18)
+#define NHMEX_PMON_CTL_PMI_EN (1 << 20)
+#define NHMEX_PMON_CTL_EN_BIT22 (1 << 22)
+#define NHMEX_PMON_CTL_INVERT (1 << 23)
+#define NHMEX_PMON_CTL_TRESH_MASK 0xff000000
+#define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_PMON_CTL_UMASK_MASK | \
+ NHMEX_PMON_CTL_EDGE_DET | \
+ NHMEX_PMON_CTL_INVERT | \
+ NHMEX_PMON_CTL_TRESH_MASK)
+
+/* NHM-EX Ubox */
+#define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00
+#define NHMEX_U_MSR_PMON_CTR 0xc11
+#define NHMEX_U_MSR_PMON_EV_SEL 0xc10
+
+#define NHMEX_U_PMON_GLOBAL_EN (1 << 0)
+#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e
+#define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28)
+#define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29)
+#define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31)
+
+#define NHMEX_U_PMON_RAW_EVENT_MASK \
+ (NHMEX_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_PMON_CTL_EDGE_DET)
+
+/* NHM-EX Cbox */
+#define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00
+#define NHMEX_C0_MSR_PMON_CTR0 0xd11
+#define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10
+#define NHMEX_C_MSR_OFFSET 0x20
+
+/* NHM-EX Bbox */
+#define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20
+#define NHMEX_B0_MSR_PMON_CTR0 0xc31
+#define NHMEX_B0_MSR_PMON_CTL0 0xc30
+#define NHMEX_B_MSR_OFFSET 0x40
+#define NHMEX_B0_MSR_MATCH 0xe45
+#define NHMEX_B0_MSR_MASK 0xe46
+#define NHMEX_B1_MSR_MATCH 0xe4d
+#define NHMEX_B1_MSR_MASK 0xe4e
+
+#define NHMEX_B_PMON_CTL_EN (1 << 0)
+#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1
+#define NHMEX_B_PMON_CTL_EV_SEL_MASK \
+ (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_B_PMON_CTR_SHIFT 6
+#define NHMEX_B_PMON_CTR_MASK \
+ (0x3 << NHMEX_B_PMON_CTR_SHIFT)
+#define NHMEX_B_PMON_RAW_EVENT_MASK \
+ (NHMEX_B_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_B_PMON_CTR_MASK)
+
+/* NHM-EX Sbox */
+#define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40
+#define NHMEX_S0_MSR_PMON_CTR0 0xc51
+#define NHMEX_S0_MSR_PMON_CTL0 0xc50
+#define NHMEX_S_MSR_OFFSET 0x80
+#define NHMEX_S0_MSR_MM_CFG 0xe48
+#define NHMEX_S0_MSR_MATCH 0xe49
+#define NHMEX_S0_MSR_MASK 0xe4a
+#define NHMEX_S1_MSR_MM_CFG 0xe58
+#define NHMEX_S1_MSR_MATCH 0xe59
+#define NHMEX_S1_MSR_MASK 0xe5a
+
+#define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63)
+#define NHMEX_S_EVENT_TO_R_PROG_EV 0
+
+/* NHM-EX Mbox */
+#define NHMEX_M0_MSR_GLOBAL_CTL 0xca0
+#define NHMEX_M0_MSR_PMU_DSP 0xca5
+#define NHMEX_M0_MSR_PMU_ISS 0xca6
+#define NHMEX_M0_MSR_PMU_MAP 0xca7
+#define NHMEX_M0_MSR_PMU_MSC_THR 0xca8
+#define NHMEX_M0_MSR_PMU_PGT 0xca9
+#define NHMEX_M0_MSR_PMU_PLD 0xcaa
+#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab
+#define NHMEX_M0_MSR_PMU_CTL0 0xcb0
+#define NHMEX_M0_MSR_PMU_CNT0 0xcb1
+#define NHMEX_M_MSR_OFFSET 0x40
+#define NHMEX_M0_MSR_PMU_MM_CFG 0xe54
+#define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c
+
+#define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63)
+#define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_SHIFT 34
+
+#define NHMEX_M_PMON_CTL_EN (1 << 0)
+#define NHMEX_M_PMON_CTL_PMI_EN (1 << 1)
+#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2
+#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \
+ (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \
+ (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6)
+#define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7)
+#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9
+#define NHMEX_M_PMON_CTL_INC_SEL_MASK \
+ (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \
+ (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
+#define NHMEX_M_PMON_RAW_EVENT_MASK \
+ (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \
+ NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \
+ NHMEX_M_PMON_CTL_WRAP_MODE | \
+ NHMEX_M_PMON_CTL_FLAG_MODE | \
+ NHMEX_M_PMON_CTL_INC_SEL_MASK | \
+ NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
+
+#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23))
+#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (11 + 3 * (n)))
+
+#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24))
+#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (12 + 3 * (n)))
+
+/*
+ * use the 9~13 bits to select event If the 7th bit is not set,
+ * otherwise use the 19~21 bits to select event.
+ */
+#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_EXTAR_REG(c, r) \
+ EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+ MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
+#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
+ EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+ MBOX_SET_FLAG_SEL_MASK, \
+ (u64)-1, NHMEX_M_##r)
+
+/* NHM-EX Rbox */
+#define NHMEX_R_MSR_GLOBAL_CTL 0xe00
+#define NHMEX_R_MSR_PMON_CTL0 0xe10
+#define NHMEX_R_MSR_PMON_CNT0 0xe11
+#define NHMEX_R_MSR_OFFSET 0x20
+
+#define NHMEX_R_MSR_PORTN_QLX_CFG(n) \
+ ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n))
+#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \
+ (((n) < 4 ? 0 : 0x10) + (n) * 4)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \
+ (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \
+ (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)
+
+#define NHMEX_R_PMON_CTL_EN (1 << 0)
+#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1
+#define NHMEX_R_PMON_CTL_EV_SEL_MASK \
+ (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_R_PMON_CTL_PMI_EN (1 << 6)
+#define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK
+
+/* NHM-EX Wbox */
+#define NHMEX_W_MSR_GLOBAL_CTL 0xc80
+#define NHMEX_W_MSR_PMON_CNT0 0xc90
+#define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91
+#define NHMEX_W_MSR_PMON_FIXED_CTR 0x394
+#define NHMEX_W_MSR_PMON_FIXED_CTL 0x395
+
+#define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31)
+
+#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
+ ((1ULL << (n)) - 1)))
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
+DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
+
+static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
+}
+
+static void nhmex_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, 0);
+}
+
+static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+ u64 config;
+
+ if (msr) {
+ rdmsrl(msr, config);
+ config &= ~((1ULL << uncore_num_counters(box)) - 1);
+ /* WBox has a fixed counter */
+ if (uncore_msr_fixed_ctl(box))
+ config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
+ wrmsrl(msr, config);
+ }
+}
+
+static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+ u64 config;
+
+ if (msr) {
+ rdmsrl(msr, config);
+ config |= (1ULL << uncore_num_counters(box)) - 1;
+ /* WBox has a fixed counter */
+ if (uncore_msr_fixed_ctl(box))
+ config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
+ wrmsrl(msr, config);
+ }
+}
+
+static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ wrmsrl(event->hw.config_base, 0);
+}
+
+static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
+ else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+ else
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+#define NHMEX_UNCORE_OPS_COMMON_INIT() \
+ .init_box = nhmex_uncore_msr_init_box, \
+ .exit_box = nhmex_uncore_msr_exit_box, \
+ .disable_box = nhmex_uncore_msr_disable_box, \
+ .enable_box = nhmex_uncore_msr_enable_box, \
+ .disable_event = nhmex_uncore_msr_disable_event, \
+ .read_counter = uncore_msr_read_counter
+
+static struct intel_uncore_ops nhmex_uncore_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_uncore_msr_enable_event,
+};
+
+static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_edge.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_ubox_formats_attr,
+};
+
+static struct intel_uncore_type nhmex_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 1,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_U_MSR_PMON_EV_SEL,
+ .perf_ctr = NHMEX_U_MSR_PMON_CTR,
+ .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_ubox_format_group
+};
+
+static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_cbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_cbox_formats_attr,
+};
+
+/* msr offset for each instance of cbox */
+static unsigned nhmex_cbox_msr_offsets[] = {
+ 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
+};
+
+static struct intel_uncore_type nhmex_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 6,
+ .num_boxes = 10,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0,
+ .perf_ctr = NHMEX_C0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
+ .msr_offsets = nhmex_cbox_msr_offsets,
+ .pair_ctr_ctl = 1,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_cbox_format_group
+};
+
+static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type nhmex_uncore_wbox = {
+ .name = "wbox",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_W_MSR_PMON_CNT0,
+ .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0,
+ .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR,
+ .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_W_MSR_GLOBAL_CTL,
+ .pair_ctr_ctl = 1,
+ .event_descs = nhmex_uncore_wbox_events,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_cbox_format_group
+};
+
+static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int ctr, ev_sel;
+
+ ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
+ NHMEX_B_PMON_CTR_SHIFT;
+ ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
+ NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
+
+ /* events that do not use the match/mask registers */
+ if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
+ (ctr == 2 && ev_sel != 0x4) || ctr == 3)
+ return 0;
+
+ if (box->pmu->pmu_idx == 0)
+ reg1->reg = NHMEX_B0_MSR_MATCH;
+ else
+ reg1->reg = NHMEX_B1_MSR_MATCH;
+ reg1->idx = 0;
+ reg1->config = event->attr.config1;
+ reg2->config = event->attr.config2;
+ return 0;
+}
+
+static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ wrmsrl(reg1->reg, reg1->config);
+ wrmsrl(reg1->reg + 1, reg2->config);
+ }
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+ (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
+}
+
+/*
+ * The Bbox has 4 counters, but each counter monitors different events.
+ * Use bits 6-7 in the event config to select counter.
+ */
+static struct event_constraint nhmex_uncore_bbox_constraints[] = {
+ EVENT_CONSTRAINT(0 , 1, 0xc0),
+ EVENT_CONSTRAINT(0x40, 2, 0xc0),
+ EVENT_CONSTRAINT(0x80, 4, 0xc0),
+ EVENT_CONSTRAINT(0xc0, 8, 0xc0),
+ EVENT_CONSTRAINT_END,
+};
+
+static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
+ &format_attr_event5.attr,
+ &format_attr_counter.attr,
+ &format_attr_match.attr,
+ &format_attr_mask.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_bbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_bbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_bbox_msr_enable_event,
+ .hw_config = nhmex_bbox_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_bbox = {
+ .name = "bbox",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_B0_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_B0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL,
+ .msr_offset = NHMEX_B_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 1,
+ .constraints = nhmex_uncore_bbox_constraints,
+ .ops = &nhmex_uncore_bbox_ops,
+ .format_group = &nhmex_uncore_bbox_format_group
+};
+
+static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ /* only TO_R_PROG_EV event uses the match/mask register */
+ if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
+ NHMEX_S_EVENT_TO_R_PROG_EV)
+ return 0;
+
+ if (box->pmu->pmu_idx == 0)
+ reg1->reg = NHMEX_S0_MSR_MM_CFG;
+ else
+ reg1->reg = NHMEX_S1_MSR_MM_CFG;
+ reg1->idx = 0;
+ reg1->config = event->attr.config1;
+ reg2->config = event->attr.config2;
+ return 0;
+}
+
+static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ wrmsrl(reg1->reg, 0);
+ wrmsrl(reg1->reg + 1, reg1->config);
+ wrmsrl(reg1->reg + 2, reg2->config);
+ wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
+ }
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+}
+
+static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_match.attr,
+ &format_attr_mask.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_sbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_sbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_sbox_msr_enable_event,
+ .hw_config = nhmex_sbox_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_sbox = {
+ .name = "sbox",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_S0_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_S0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL,
+ .msr_offset = NHMEX_S_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 1,
+ .ops = &nhmex_uncore_sbox_ops,
+ .format_group = &nhmex_uncore_sbox_format_group
+};
+
+enum {
+ EXTRA_REG_NHMEX_M_FILTER,
+ EXTRA_REG_NHMEX_M_DSP,
+ EXTRA_REG_NHMEX_M_ISS,
+ EXTRA_REG_NHMEX_M_MAP,
+ EXTRA_REG_NHMEX_M_MSC_THR,
+ EXTRA_REG_NHMEX_M_PGT,
+ EXTRA_REG_NHMEX_M_PLD,
+ EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
+};
+
+static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
+ MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
+ MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
+ MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
+ MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
+ /* event 0xa uses two extra registers */
+ MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
+ MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
+ MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
+ /* events 0xd ~ 0x10 use the same extra register */
+ MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
+ EVENT_EXTRA_END
+};
+
+/* Nehalem-EX or Westmere-EX ? */
+static bool uncore_nhmex;
+
+static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ bool ret = false;
+ u64 mask;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ er = &box->shared_regs[idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (!atomic_read(&er->ref) || er->config == config) {
+ atomic_inc(&er->ref);
+ er->config = config;
+ ret = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return ret;
+ }
+ /*
+ * The ZDP_CTL_FVC MSR has 4 fields which are used to control
+ * events 0xd ~ 0x10. Besides these 4 fields, there are additional
+ * fields which are shared.
+ */
+ idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ if (WARN_ON_ONCE(idx >= 4))
+ return false;
+
+ /* mask of the shared fields */
+ if (uncore_nhmex)
+ mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
+ else
+ mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+
+ raw_spin_lock_irqsave(&er->lock, flags);
+ /* add mask of the non-shared field if it's in use */
+ if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
+ if (uncore_nhmex)
+ mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ else
+ mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ }
+
+ if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
+ atomic_add(1 << (idx * 8), &er->ref);
+ if (uncore_nhmex)
+ mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
+ NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ else
+ mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
+ WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ er->config &= ~mask;
+ er->config |= (config & mask);
+ ret = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return ret;
+}
+
+static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ er = &box->shared_regs[idx];
+ atomic_dec(&er->ref);
+ return;
+ }
+
+ idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+ atomic_sub(1 << (idx * 8), &er->ref);
+}
+
+static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
+ u64 config = reg1->config;
+
+ /* get the non-shared control bits and shift them */
+ idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ if (uncore_nhmex)
+ config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ else
+ config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ if (new_idx > orig_idx) {
+ idx = new_idx - orig_idx;
+ config <<= 3 * idx;
+ } else {
+ idx = orig_idx - new_idx;
+ config >>= 3 * idx;
+ }
+
+ /* add the shared control bits back */
+ if (uncore_nhmex)
+ config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+ else
+ config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+ config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+ if (modify) {
+ /* adjust the main event selector */
+ if (new_idx > orig_idx)
+ hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+ else
+ hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+ reg1->config = config;
+ reg1->idx = ~0xff | new_idx;
+ }
+ return config;
+}
+
+static struct event_constraint *
+nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ int i, idx[2], alloc = 0;
+ u64 config1 = reg1->config;
+
+ idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
+ idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
+again:
+ for (i = 0; i < 2; i++) {
+ if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
+ idx[i] = 0xff;
+
+ if (idx[i] == 0xff)
+ continue;
+
+ if (!nhmex_mbox_get_shared_reg(box, idx[i],
+ __BITS_VALUE(config1, i, 32)))
+ goto fail;
+ alloc |= (0x1 << i);
+ }
+
+ /* for the match/mask registers */
+ if (reg2->idx != EXTRA_REG_NONE &&
+ (uncore_box_is_fake(box) || !reg2->alloc) &&
+ !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
+ goto fail;
+
+ /*
+ * If it's a fake box -- as per validate_{group,event}() we
+ * shouldn't touch event state and we can avoid doing so
+ * since both will only call get_event_constraints() once
+ * on each event, this avoids the need for reg->alloc.
+ */
+ if (!uncore_box_is_fake(box)) {
+ if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
+ nhmex_mbox_alter_er(event, idx[0], true);
+ reg1->alloc |= alloc;
+ if (reg2->idx != EXTRA_REG_NONE)
+ reg2->alloc = 1;
+ }
+ return NULL;
+fail:
+ if (idx[0] != 0xff && !(alloc & 0x1) &&
+ idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ /*
+ * events 0xd ~ 0x10 are functional identical, but are
+ * controlled by different fields in the ZDP_CTL_FVC
+ * register. If we failed to take one field, try the
+ * rest 3 choices.
+ */
+ BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
+ idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ idx[0] = (idx[0] + 1) % 4;
+ idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
+ config1 = nhmex_mbox_alter_er(event, idx[0], false);
+ goto again;
+ }
+ }
+
+ if (alloc & 0x1)
+ nhmex_mbox_put_shared_reg(box, idx[0]);
+ if (alloc & 0x2)
+ nhmex_mbox_put_shared_reg(box, idx[1]);
+ return &uncore_constraint_empty;
+}
+
+static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+
+ if (uncore_box_is_fake(box))
+ return;
+
+ if (reg1->alloc & 0x1)
+ nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
+ if (reg1->alloc & 0x2)
+ nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
+ reg1->alloc = 0;
+
+ if (reg2->alloc) {
+ nhmex_mbox_put_shared_reg(box, reg2->idx);
+ reg2->alloc = 0;
+ }
+}
+
+static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
+{
+ if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+ return er->idx;
+ return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
+}
+
+static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_type *type = box->pmu->type;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ struct extra_reg *er;
+ unsigned msr;
+ int reg_idx = 0;
+ /*
+ * The mbox events may require 2 extra MSRs at the most. But only
+ * the lower 32 bits in these MSRs are significant, so we can use
+ * config1 to pass two MSRs' config.
+ */
+ for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ if (event->attr.config1 & ~er->valid_mask)
+ return -EINVAL;
+
+ msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
+ if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
+ return -EINVAL;
+
+ /* always use the 32~63 bits to pass the PLD config */
+ if (er->idx == EXTRA_REG_NHMEX_M_PLD)
+ reg_idx = 1;
+ else if (WARN_ON_ONCE(reg_idx > 0))
+ return -EINVAL;
+
+ reg1->idx &= ~(0xff << (reg_idx * 8));
+ reg1->reg &= ~(0xffff << (reg_idx * 16));
+ reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
+ reg1->reg |= msr << (reg_idx * 16);
+ reg1->config = event->attr.config1;
+ reg_idx++;
+ }
+ /*
+ * The mbox only provides ability to perform address matching
+ * for the PLD events.
+ */
+ if (reg_idx == 2) {
+ reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
+ if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
+ reg2->config = event->attr.config2;
+ else
+ reg2->config = ~0ULL;
+ if (box->pmu->pmu_idx == 0)
+ reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
+ else
+ reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
+ }
+ return 0;
+}
+
+static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ u64 config;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+ return box->shared_regs[idx].config;
+
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ config = er->config;
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+ return config;
+}
+
+static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int idx;
+
+ idx = __BITS_VALUE(reg1->idx, 0, 8);
+ if (idx != 0xff)
+ wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
+ nhmex_mbox_shared_reg_config(box, idx));
+ idx = __BITS_VALUE(reg1->idx, 1, 8);
+ if (idx != 0xff)
+ wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
+ nhmex_mbox_shared_reg_config(box, idx));
+
+ if (reg2->idx != EXTRA_REG_NONE) {
+ wrmsrl(reg2->reg, 0);
+ if (reg2->config != ~0ULL) {
+ wrmsrl(reg2->reg + 1,
+ reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
+ wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
+ (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
+ wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
+ }
+ }
+
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3");
+DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5");
+DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6");
+DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7");
+DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13");
+DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61");
+DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63");
+
+static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
+ &format_attr_count_mode.attr,
+ &format_attr_storage_mode.attr,
+ &format_attr_wrap_mode.attr,
+ &format_attr_flag_mode.attr,
+ &format_attr_inc_sel.attr,
+ &format_attr_set_flag_sel.attr,
+ &format_attr_filter_cfg_en.attr,
+ &format_attr_filter_match.attr,
+ &format_attr_filter_mask.attr,
+ &format_attr_dsp.attr,
+ &format_attr_thr.attr,
+ &format_attr_fvc.attr,
+ &format_attr_pgt.attr,
+ &format_attr_map.attr,
+ &format_attr_iss.attr,
+ &format_attr_pld.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_mbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_mbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
+ { /* end: all zeroes */ },
+};
+
+static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_mbox_msr_enable_event,
+ .hw_config = nhmex_mbox_hw_config,
+ .get_constraint = nhmex_mbox_get_constraint,
+ .put_constraint = nhmex_mbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_mbox = {
+ .name = "mbox",
+ .num_counters = 6,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_M0_MSR_PMU_CTL0,
+ .perf_ctr = NHMEX_M0_MSR_PMU_CNT0,
+ .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL,
+ .msr_offset = NHMEX_M_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 8,
+ .event_descs = nhmex_uncore_mbox_events,
+ .ops = &nhmex_uncore_mbox_ops,
+ .format_group = &nhmex_uncore_mbox_format_group,
+};
+
+static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+ /* adjust the main event selector and extra register index */
+ if (reg1->idx % 2) {
+ reg1->idx--;
+ hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ } else {
+ reg1->idx++;
+ hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ }
+
+ /* adjust extra register config */
+ switch (reg1->idx % 6) {
+ case 2:
+ /* shift the 8~15 bits to the 0~7 bits */
+ reg1->config >>= 8;
+ break;
+ case 3:
+ /* shift the 0~7 bits to the 8~15 bits */
+ reg1->config <<= 8;
+ break;
+ }
+}
+
+/*
+ * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
+ * An event set consists of 6 events, the 3rd and 4th events in
+ * an event set use the same extra register. So an event set uses
+ * 5 extra registers.
+ */
+static struct event_constraint *
+nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ int idx, er_idx;
+ u64 config1;
+ bool ok = false;
+
+ if (!uncore_box_is_fake(box) && reg1->alloc)
+ return NULL;
+
+ idx = reg1->idx % 6;
+ config1 = reg1->config;
+again:
+ er_idx = idx;
+ /* the 3rd and 4th events use the same extra register */
+ if (er_idx > 2)
+ er_idx--;
+ er_idx += (reg1->idx / 6) * 5;
+
+ er = &box->shared_regs[er_idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (idx < 2) {
+ if (!atomic_read(&er->ref) || er->config == reg1->config) {
+ atomic_inc(&er->ref);
+ er->config = reg1->config;
+ ok = true;
+ }
+ } else if (idx == 2 || idx == 3) {
+ /*
+ * these two events use different fields in a extra register,
+ * the 0~7 bits and the 8~15 bits respectively.
+ */
+ u64 mask = 0xff << ((idx - 2) * 8);
+ if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
+ !((er->config ^ config1) & mask)) {
+ atomic_add(1 << ((idx - 2) * 8), &er->ref);
+ er->config &= ~mask;
+ er->config |= config1 & mask;
+ ok = true;
+ }
+ } else {
+ if (!atomic_read(&er->ref) ||
+ (er->config == (hwc->config >> 32) &&
+ er->config1 == reg1->config &&
+ er->config2 == reg2->config)) {
+ atomic_inc(&er->ref);
+ er->config = (hwc->config >> 32);
+ er->config1 = reg1->config;
+ er->config2 = reg2->config;
+ ok = true;
+ }
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ if (!ok) {
+ /*
+ * The Rbox events are always in pairs. The paired
+ * events are functional identical, but use different
+ * extra registers. If we failed to take an extra
+ * register, try the alternative.
+ */
+ idx ^= 1;
+ if (idx != reg1->idx % 6) {
+ if (idx == 2)
+ config1 >>= 8;
+ else if (idx == 3)
+ config1 <<= 8;
+ goto again;
+ }
+ } else {
+ if (!uncore_box_is_fake(box)) {
+ if (idx != reg1->idx % 6)
+ nhmex_rbox_alter_er(box, event);
+ reg1->alloc = 1;
+ }
+ return NULL;
+ }
+ return &uncore_constraint_empty;
+}
+
+static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ int idx, er_idx;
+
+ if (uncore_box_is_fake(box) || !reg1->alloc)
+ return;
+
+ idx = reg1->idx % 6;
+ er_idx = idx;
+ if (er_idx > 2)
+ er_idx--;
+ er_idx += (reg1->idx / 6) * 5;
+
+ er = &box->shared_regs[er_idx];
+ if (idx == 2 || idx == 3)
+ atomic_sub(1 << ((idx - 2) * 8), &er->ref);
+ else
+ atomic_dec(&er->ref);
+
+ reg1->alloc = 0;
+}
+
+static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ int idx;
+
+ idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
+ NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ if (idx >= 0x18)
+ return -EINVAL;
+
+ reg1->idx = idx;
+ reg1->config = event->attr.config1;
+
+ switch (idx % 6) {
+ case 4:
+ case 5:
+ hwc->config |= event->attr.config & (~0ULL << 32);
+ reg2->config = event->attr.config2;
+ break;
+ }
+ return 0;
+}
+
+static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int idx, port;
+
+ idx = reg1->idx;
+ port = idx / 6 + box->pmu->pmu_idx * 4;
+
+ switch (idx % 6) {
+ case 0:
+ wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
+ break;
+ case 1:
+ wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
+ break;
+ case 2:
+ case 3:
+ wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
+ uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
+ break;
+ case 4:
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
+ hwc->config >> 32);
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
+ break;
+ case 5:
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
+ hwc->config >> 32);
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
+ wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
+ break;
+ }
+
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+ (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
+DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
+
+static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
+ &format_attr_event5.attr,
+ &format_attr_xbr_mm_cfg.attr,
+ &format_attr_xbr_match.attr,
+ &format_attr_xbr_mask.attr,
+ &format_attr_qlx_cfg.attr,
+ &format_attr_iperf_cfg.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_rbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_rbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_rbox_msr_enable_event,
+ .hw_config = nhmex_rbox_hw_config,
+ .get_constraint = nhmex_rbox_get_constraint,
+ .put_constraint = nhmex_rbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_rbox = {
+ .name = "rbox",
+ .num_counters = 8,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_R_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_R_MSR_PMON_CNT0,
+ .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_R_MSR_GLOBAL_CTL,
+ .msr_offset = NHMEX_R_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 20,
+ .event_descs = nhmex_uncore_rbox_events,
+ .ops = &nhmex_uncore_rbox_ops,
+ .format_group = &nhmex_uncore_rbox_format_group
+};
+
+static struct intel_uncore_type *nhmex_msr_uncores[] = {
+ &nhmex_uncore_ubox,
+ &nhmex_uncore_cbox,
+ &nhmex_uncore_bbox,
+ &nhmex_uncore_sbox,
+ &nhmex_uncore_mbox,
+ &nhmex_uncore_rbox,
+ &nhmex_uncore_wbox,
+ NULL,
+};
+
+void nhmex_uncore_cpu_init(void)
+{
+ if (boot_cpu_data.x86_model == 46)
+ uncore_nhmex = true;
+ else
+ nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
+ if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ uncore_msr_uncores = nhmex_msr_uncores;
+}
+/* end of Nehalem-EX uncore support */
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
new file mode 100644
index 0000000..96531d2
--- /dev/null
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -0,0 +1,731 @@
+/* Nehalem/SandBridge/Haswell uncore support */
+#include "uncore.h"
+
+/* Uncore IMC PCI IDs */
+#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
+#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154
+#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150
+#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00
+#define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04
+#define PCI_DEVICE_ID_INTEL_BDW_IMC 0x1604
+#define PCI_DEVICE_ID_INTEL_SKL_IMC 0x191f
+
+/* SNB event control */
+#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
+#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00
+#define SNB_UNC_CTL_EDGE_DET (1 << 18)
+#define SNB_UNC_CTL_EN (1 << 22)
+#define SNB_UNC_CTL_INVERT (1 << 23)
+#define SNB_UNC_CTL_CMASK_MASK 0x1f000000
+#define NHM_UNC_CTL_CMASK_MASK 0xff000000
+#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0)
+
+#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
+ SNB_UNC_CTL_UMASK_MASK | \
+ SNB_UNC_CTL_EDGE_DET | \
+ SNB_UNC_CTL_INVERT | \
+ SNB_UNC_CTL_CMASK_MASK)
+
+#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
+ SNB_UNC_CTL_UMASK_MASK | \
+ SNB_UNC_CTL_EDGE_DET | \
+ SNB_UNC_CTL_INVERT | \
+ NHM_UNC_CTL_CMASK_MASK)
+
+/* SNB global control register */
+#define SNB_UNC_PERF_GLOBAL_CTL 0x391
+#define SNB_UNC_FIXED_CTR_CTRL 0x394
+#define SNB_UNC_FIXED_CTR 0x395
+
+/* SNB uncore global control */
+#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1)
+#define SNB_UNC_GLOBAL_CTL_EN (1 << 29)
+
+/* SNB Cbo register */
+#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700
+#define SNB_UNC_CBO_0_PER_CTR0 0x706
+#define SNB_UNC_CBO_MSR_OFFSET 0x10
+
+/* SNB ARB register */
+#define SNB_UNC_ARB_PER_CTR0 0x3b0
+#define SNB_UNC_ARB_PERFEVTSEL0 0x3b2
+#define SNB_UNC_ARB_MSR_OFFSET 0x10
+
+/* NHM global control register */
+#define NHM_UNC_PERF_GLOBAL_CTL 0x391
+#define NHM_UNC_FIXED_CTR 0x394
+#define NHM_UNC_FIXED_CTR_CTRL 0x395
+
+/* NHM uncore global control */
+#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1)
+#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32)
+
+/* NHM uncore register */
+#define NHM_UNC_PERFEVTSEL0 0x3c0
+#define NHM_UNC_UNCORE_PMC0 0x3b0
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
+DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
+
+/* Sandy Bridge uncore support */
+static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (hwc->idx < UNCORE_PMC_IDX_FIXED)
+ wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
+ else
+ wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
+}
+
+static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ wrmsrl(event->hw.config_base, 0);
+}
+
+static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+ if (box->pmu->pmu_idx == 0) {
+ wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
+ SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
+ }
+}
+
+static void snb_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ if (box->pmu->pmu_idx == 0)
+ wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, 0);
+}
+
+static struct uncore_event_desc snb_uncore_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+ { /* end: all zeroes */ },
+};
+
+static struct attribute *snb_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask5.attr,
+ NULL,
+};
+
+static struct attribute_group snb_uncore_format_group = {
+ .name = "format",
+ .attrs = snb_uncore_formats_attr,
+};
+
+static struct intel_uncore_ops snb_uncore_msr_ops = {
+ .init_box = snb_uncore_msr_init_box,
+ .exit_box = snb_uncore_msr_exit_box,
+ .disable_event = snb_uncore_msr_disable_event,
+ .enable_event = snb_uncore_msr_enable_event,
+ .read_counter = uncore_msr_read_counter,
+};
+
+static struct event_constraint snb_uncore_arb_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type snb_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 2,
+ .num_boxes = 4,
+ .perf_ctr_bits = 44,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = SNB_UNC_CBO_0_PER_CTR0,
+ .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
+ .fixed_ctr = SNB_UNC_FIXED_CTR,
+ .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
+ .single_fixed = 1,
+ .event_mask = SNB_UNC_RAW_EVENT_MASK,
+ .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
+ .ops = &snb_uncore_msr_ops,
+ .format_group = &snb_uncore_format_group,
+ .event_descs = snb_uncore_events,
+};
+
+static struct intel_uncore_type snb_uncore_arb = {
+ .name = "arb",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .perf_ctr = SNB_UNC_ARB_PER_CTR0,
+ .event_ctl = SNB_UNC_ARB_PERFEVTSEL0,
+ .event_mask = SNB_UNC_RAW_EVENT_MASK,
+ .msr_offset = SNB_UNC_ARB_MSR_OFFSET,
+ .constraints = snb_uncore_arb_constraints,
+ .ops = &snb_uncore_msr_ops,
+ .format_group = &snb_uncore_format_group,
+};
+
+static struct intel_uncore_type *snb_msr_uncores[] = {
+ &snb_uncore_cbox,
+ &snb_uncore_arb,
+ NULL,
+};
+
+void snb_uncore_cpu_init(void)
+{
+ uncore_msr_uncores = snb_msr_uncores;
+ if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+}
+
+enum {
+ SNB_PCI_UNCORE_IMC,
+};
+
+static struct uncore_event_desc snb_uncore_imc_events[] = {
+ INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"),
+ INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
+
+ INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
+ INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
+
+ { /* end: all zeroes */ },
+};
+
+#define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff
+#define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48
+
+/* page size multiple covering all config regs */
+#define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000
+
+#define SNB_UNCORE_PCI_IMC_DATA_READS 0x1
+#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050
+#define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2
+#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054
+#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE
+
+static struct attribute *snb_uncore_imc_formats_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group snb_uncore_imc_format_group = {
+ .name = "format",
+ .attrs = snb_uncore_imc_formats_attr,
+};
+
+static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
+ resource_size_t addr;
+ u32 pci_dword;
+
+ pci_read_config_dword(pdev, where, &pci_dword);
+ addr = pci_dword;
+
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ pci_read_config_dword(pdev, where + 4, &pci_dword);
+ addr |= ((resource_size_t)pci_dword << 32);
+#endif
+
+ addr &= ~(PAGE_SIZE - 1);
+
+ box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE);
+ box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
+}
+
+static void snb_uncore_imc_exit_box(struct intel_uncore_box *box)
+{
+ iounmap(box->io_addr);
+}
+
+static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
+{}
+
+static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
+{}
+
+static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{}
+
+static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{}
+
+static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ return (u64)*(unsigned int *)(box->io_addr + hwc->event_base);
+}
+
+/*
+ * custom event_init() function because we define our own fixed, free
+ * running counters, so we do not want to conflict with generic uncore
+ * logic. Also simplifies processing
+ */
+static int snb_uncore_imc_event_init(struct perf_event *event)
+{
+ struct intel_uncore_pmu *pmu;
+ struct intel_uncore_box *box;
+ struct hw_perf_event *hwc = &event->hw;
+ u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
+ int idx, base;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ pmu = uncore_event_to_pmu(event);
+ /* no device found for this pmu */
+ if (pmu->func_id < 0)
+ return -ENOENT;
+
+ /* Sampling not supported yet */
+ if (hwc->sample_period)
+ return -EINVAL;
+
+ /* unsupported modes and filters */
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period) /* no sampling */
+ return -EINVAL;
+
+ /*
+ * Place all uncore events for a particular physical package
+ * onto a single cpu
+ */
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ /* check only supported bits are set */
+ if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
+ return -EINVAL;
+
+ box = uncore_pmu_to_box(pmu, event->cpu);
+ if (!box || box->cpu < 0)
+ return -EINVAL;
+
+ event->cpu = box->cpu;
+ event->pmu_private = box;
+
+ event->hw.idx = -1;
+ event->hw.last_tag = ~0ULL;
+ event->hw.extra_reg.idx = EXTRA_REG_NONE;
+ event->hw.branch_reg.idx = EXTRA_REG_NONE;
+ /*
+ * check event is known (whitelist, determines counter)
+ */
+ switch (cfg) {
+ case SNB_UNCORE_PCI_IMC_DATA_READS:
+ base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
+ idx = UNCORE_PMC_IDX_FIXED;
+ break;
+ case SNB_UNCORE_PCI_IMC_DATA_WRITES:
+ base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
+ idx = UNCORE_PMC_IDX_FIXED + 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* must be done before validate_group */
+ event->hw.event_base = base;
+ event->hw.config = cfg;
+ event->hw.idx = idx;
+
+ /* no group validation needed, we have free running counters */
+
+ return 0;
+}
+
+static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ return 0;
+}
+
+static void snb_uncore_imc_event_start(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ u64 count;
+
+ if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+ return;
+
+ event->hw.state = 0;
+ box->n_active++;
+
+ list_add_tail(&event->active_entry, &box->active_list);
+
+ count = snb_uncore_imc_read_counter(box, event);
+ local64_set(&event->hw.prev_count, count);
+
+ if (box->n_active == 1)
+ uncore_pmu_start_hrtimer(box);
+}
+
+static void snb_uncore_imc_event_stop(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ box->n_active--;
+
+ WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+ hwc->state |= PERF_HES_STOPPED;
+
+ list_del(&event->active_entry);
+
+ if (box->n_active == 0)
+ uncore_pmu_cancel_hrtimer(box);
+ }
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ /*
+ * Drain the remaining delta count out of a event
+ * that we are disabling:
+ */
+ uncore_perf_event_update(box, event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+}
+
+static int snb_uncore_imc_event_add(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!box)
+ return -ENODEV;
+
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (!(flags & PERF_EF_START))
+ hwc->state |= PERF_HES_ARCH;
+
+ snb_uncore_imc_event_start(event, 0);
+
+ box->n_events++;
+
+ return 0;
+}
+
+static void snb_uncore_imc_event_del(struct perf_event *event, int flags)
+{
+ struct intel_uncore_box *box = uncore_event_to_box(event);
+ int i;
+
+ snb_uncore_imc_event_stop(event, PERF_EF_UPDATE);
+
+ for (i = 0; i < box->n_events; i++) {
+ if (event == box->event_list[i]) {
+ --box->n_events;
+ break;
+ }
+ }
+}
+
+int snb_pci2phy_map_init(int devid)
+{
+ struct pci_dev *dev = NULL;
+ struct pci2phy_map *map;
+ int bus, segment;
+
+ dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
+ if (!dev)
+ return -ENOTTY;
+
+ bus = dev->bus->number;
+ segment = pci_domain_nr(dev->bus);
+
+ raw_spin_lock(&pci2phy_map_lock);
+ map = __find_pci2phy_map(segment);
+ if (!map) {
+ raw_spin_unlock(&pci2phy_map_lock);
+ pci_dev_put(dev);
+ return -ENOMEM;
+ }
+ map->pbus_to_physid[bus] = 0;
+ raw_spin_unlock(&pci2phy_map_lock);
+
+ pci_dev_put(dev);
+
+ return 0;
+}
+
+static struct pmu snb_uncore_imc_pmu = {
+ .task_ctx_nr = perf_invalid_context,
+ .event_init = snb_uncore_imc_event_init,
+ .add = snb_uncore_imc_event_add,
+ .del = snb_uncore_imc_event_del,
+ .start = snb_uncore_imc_event_start,
+ .stop = snb_uncore_imc_event_stop,
+ .read = uncore_pmu_event_read,
+};
+
+static struct intel_uncore_ops snb_uncore_imc_ops = {
+ .init_box = snb_uncore_imc_init_box,
+ .exit_box = snb_uncore_imc_exit_box,
+ .enable_box = snb_uncore_imc_enable_box,
+ .disable_box = snb_uncore_imc_disable_box,
+ .disable_event = snb_uncore_imc_disable_event,
+ .enable_event = snb_uncore_imc_enable_event,
+ .hw_config = snb_uncore_imc_hw_config,
+ .read_counter = snb_uncore_imc_read_counter,
+};
+
+static struct intel_uncore_type snb_uncore_imc = {
+ .name = "imc",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .fixed_ctr_bits = 32,
+ .fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE,
+ .event_descs = snb_uncore_imc_events,
+ .format_group = &snb_uncore_imc_format_group,
+ .perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
+ .event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK,
+ .ops = &snb_uncore_imc_ops,
+ .pmu = &snb_uncore_imc_pmu,
+};
+
+static struct intel_uncore_type *snb_pci_uncores[] = {
+ [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc,
+ NULL,
+};
+
+static const struct pci_device_id snb_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
+static const struct pci_device_id ivb_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_E3_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
+static const struct pci_device_id hsw_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
+static const struct pci_device_id bdw_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
+static const struct pci_device_id skl_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
+static struct pci_driver snb_uncore_pci_driver = {
+ .name = "snb_uncore",
+ .id_table = snb_uncore_pci_ids,
+};
+
+static struct pci_driver ivb_uncore_pci_driver = {
+ .name = "ivb_uncore",
+ .id_table = ivb_uncore_pci_ids,
+};
+
+static struct pci_driver hsw_uncore_pci_driver = {
+ .name = "hsw_uncore",
+ .id_table = hsw_uncore_pci_ids,
+};
+
+static struct pci_driver bdw_uncore_pci_driver = {
+ .name = "bdw_uncore",
+ .id_table = bdw_uncore_pci_ids,
+};
+
+static struct pci_driver skl_uncore_pci_driver = {
+ .name = "skl_uncore",
+ .id_table = skl_uncore_pci_ids,
+};
+
+struct imc_uncore_pci_dev {
+ __u32 pci_id;
+ struct pci_driver *driver;
+};
+#define IMC_DEV(a, d) \
+ { .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
+
+static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
+ IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
+ IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */
+ IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
+ IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */
+ IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */
+ IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */
+ IMC_DEV(SKL_IMC, &skl_uncore_pci_driver), /* 6th Gen Core */
+ { /* end marker */ }
+};
+
+
+#define for_each_imc_pci_id(x, t) \
+ for (x = (t); (x)->pci_id; x++)
+
+static struct pci_driver *imc_uncore_find_dev(void)
+{
+ const struct imc_uncore_pci_dev *p;
+ int ret;
+
+ for_each_imc_pci_id(p, desktop_imc_pci_ids) {
+ ret = snb_pci2phy_map_init(p->pci_id);
+ if (ret == 0)
+ return p->driver;
+ }
+ return NULL;
+}
+
+static int imc_uncore_pci_init(void)
+{
+ struct pci_driver *imc_drv = imc_uncore_find_dev();
+
+ if (!imc_drv)
+ return -ENODEV;
+
+ uncore_pci_uncores = snb_pci_uncores;
+ uncore_pci_driver = imc_drv;
+
+ return 0;
+}
+
+int snb_uncore_pci_init(void)
+{
+ return imc_uncore_pci_init();
+}
+
+int ivb_uncore_pci_init(void)
+{
+ return imc_uncore_pci_init();
+}
+int hsw_uncore_pci_init(void)
+{
+ return imc_uncore_pci_init();
+}
+
+int bdw_uncore_pci_init(void)
+{
+ return imc_uncore_pci_init();
+}
+
+int skl_uncore_pci_init(void)
+{
+ return imc_uncore_pci_init();
+}
+
+/* end of Sandy Bridge uncore support */
+
+/* Nehalem uncore support */
+static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
+}
+
+static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
+}
+
+static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (hwc->idx < UNCORE_PMC_IDX_FIXED)
+ wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
+ else
+ wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
+}
+
+static struct attribute *nhm_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask8.attr,
+ NULL,
+};
+
+static struct attribute_group nhm_uncore_format_group = {
+ .name = "format",
+ .attrs = nhm_uncore_formats_attr,
+};
+
+static struct uncore_event_desc nhm_uncore_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+ INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"),
+ INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"),
+ INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhm_uncore_msr_ops = {
+ .disable_box = nhm_uncore_msr_disable_box,
+ .enable_box = nhm_uncore_msr_enable_box,
+ .disable_event = snb_uncore_msr_disable_event,
+ .enable_event = nhm_uncore_msr_enable_event,
+ .read_counter = uncore_msr_read_counter,
+};
+
+static struct intel_uncore_type nhm_uncore = {
+ .name = "",
+ .num_counters = 8,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .event_ctl = NHM_UNC_PERFEVTSEL0,
+ .perf_ctr = NHM_UNC_UNCORE_PMC0,
+ .fixed_ctr = NHM_UNC_FIXED_CTR,
+ .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL,
+ .event_mask = NHM_UNC_RAW_EVENT_MASK,
+ .event_descs = nhm_uncore_events,
+ .ops = &nhm_uncore_msr_ops,
+ .format_group = &nhm_uncore_format_group,
+};
+
+static struct intel_uncore_type *nhm_msr_uncores[] = {
+ &nhm_uncore,
+ NULL,
+};
+
+void nhm_uncore_cpu_init(void)
+{
+ uncore_msr_uncores = nhm_msr_uncores;
+}
+
+/* end of Nehalem uncore support */
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
new file mode 100644
index 0000000..93f6bd9
--- /dev/null
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -0,0 +1,3135 @@
+/* SandyBridge-EP/IvyTown uncore support */
+#include "uncore.h"
+
+/* SNB-EP Box level control */
+#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0)
+#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1)
+#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8)
+#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16)
+#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \
+ SNBEP_PMON_BOX_CTL_RST_CTRS | \
+ SNBEP_PMON_BOX_CTL_FRZ_EN)
+/* SNB-EP event control */
+#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff
+#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00
+#define SNBEP_PMON_CTL_RST (1 << 17)
+#define SNBEP_PMON_CTL_EDGE_DET (1 << 18)
+#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21)
+#define SNBEP_PMON_CTL_EN (1 << 22)
+#define SNBEP_PMON_CTL_INVERT (1 << 23)
+#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000
+#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PMON_CTL_UMASK_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_PMON_CTL_INVERT | \
+ SNBEP_PMON_CTL_TRESH_MASK)
+
+/* SNB-EP Ubox event control */
+#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000
+#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PMON_CTL_UMASK_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_PMON_CTL_INVERT | \
+ SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
+
+#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19)
+#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_CBO_PMON_CTL_TID_EN)
+
+/* SNB-EP PCU event control */
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000
+#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30)
+#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31)
+#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_PMON_CTL_EV_SEL_EXT | \
+ SNBEP_PMON_CTL_INVERT | \
+ SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+
+#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_PMON_CTL_EV_SEL_EXT)
+
+/* SNB-EP pci control register */
+#define SNBEP_PCI_PMON_BOX_CTL 0xf4
+#define SNBEP_PCI_PMON_CTL0 0xd8
+/* SNB-EP pci counter register */
+#define SNBEP_PCI_PMON_CTR0 0xa0
+
+/* SNB-EP home agent register */
+#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40
+#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44
+#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48
+/* SNB-EP memory controller register */
+#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0
+#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0
+/* SNB-EP QPI register */
+#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228
+#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c
+#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238
+#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c
+
+/* SNB-EP Ubox register */
+#define SNBEP_U_MSR_PMON_CTR0 0xc16
+#define SNBEP_U_MSR_PMON_CTL0 0xc10
+
+#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08
+#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09
+
+/* SNB-EP Cbo register */
+#define SNBEP_C0_MSR_PMON_CTR0 0xd16
+#define SNBEP_C0_MSR_PMON_CTL0 0xd10
+#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04
+#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14
+#define SNBEP_CBO_MSR_OFFSET 0x20
+
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID 0x1f
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID 0x3fc00
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE 0x7c0000
+#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC 0xff800000
+
+#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) { \
+ .event = (e), \
+ .msr = SNBEP_C0_MSR_PMON_BOX_FILTER, \
+ .config_mask = (m), \
+ .idx = (i) \
+}
+
+/* SNB-EP PCU register */
+#define SNBEP_PCU_MSR_PMON_CTR0 0xc36
+#define SNBEP_PCU_MSR_PMON_CTL0 0xc30
+#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24
+#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34
+#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff
+#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc
+#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd
+
+/* IVBEP event control */
+#define IVBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \
+ SNBEP_PMON_BOX_CTL_RST_CTRS)
+#define IVBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PMON_CTL_UMASK_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_PMON_CTL_TRESH_MASK)
+/* IVBEP Ubox */
+#define IVBEP_U_MSR_PMON_GLOBAL_CTL 0xc00
+#define IVBEP_U_PMON_GLOBAL_FRZ_ALL (1 << 31)
+#define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29)
+
+#define IVBEP_U_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PMON_CTL_UMASK_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
+/* IVBEP Cbo */
+#define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK (IVBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_CBO_PMON_CTL_TID_EN)
+
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62)
+#define IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC (0x1ULL << 63)
+
+/* IVBEP home agent */
+#define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16)
+#define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK \
+ (IVBEP_PMON_RAW_EVENT_MASK | \
+ IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST)
+/* IVBEP PCU */
+#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_CTL_EV_SEL_MASK | \
+ SNBEP_PMON_CTL_EV_SEL_EXT | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+/* IVBEP QPI */
+#define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK \
+ (IVBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_PMON_CTL_EV_SEL_EXT)
+
+#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
+ ((1ULL << (n)) - 1)))
+
+/* Haswell-EP Ubox */
+#define HSWEP_U_MSR_PMON_CTR0 0x709
+#define HSWEP_U_MSR_PMON_CTL0 0x705
+#define HSWEP_U_MSR_PMON_FILTER 0x707
+
+#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL 0x703
+#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTR 0x704
+
+#define HSWEP_U_MSR_PMON_BOX_FILTER_TID (0x1 << 0)
+#define HSWEP_U_MSR_PMON_BOX_FILTER_CID (0x1fULL << 1)
+#define HSWEP_U_MSR_PMON_BOX_FILTER_MASK \
+ (HSWEP_U_MSR_PMON_BOX_FILTER_TID | \
+ HSWEP_U_MSR_PMON_BOX_FILTER_CID)
+
+/* Haswell-EP CBo */
+#define HSWEP_C0_MSR_PMON_CTR0 0xe08
+#define HSWEP_C0_MSR_PMON_CTL0 0xe01
+#define HSWEP_C0_MSR_PMON_BOX_CTL 0xe00
+#define HSWEP_C0_MSR_PMON_BOX_FILTER0 0xe05
+#define HSWEP_CBO_MSR_OFFSET 0x10
+
+
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_TID (0x3fULL << 0)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 6)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE (0x7fULL << 17)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62)
+#define HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC (0x1ULL << 63)
+
+
+/* Haswell-EP Sbox */
+#define HSWEP_S0_MSR_PMON_CTR0 0x726
+#define HSWEP_S0_MSR_PMON_CTL0 0x721
+#define HSWEP_S0_MSR_PMON_BOX_CTL 0x720
+#define HSWEP_SBOX_MSR_OFFSET 0xa
+#define HSWEP_S_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_CBO_PMON_CTL_TID_EN)
+
+/* Haswell-EP PCU */
+#define HSWEP_PCU_MSR_PMON_CTR0 0x717
+#define HSWEP_PCU_MSR_PMON_CTL0 0x711
+#define HSWEP_PCU_MSR_PMON_BOX_CTL 0x710
+#define HSWEP_PCU_MSR_PMON_BOX_FILTER 0x715
+
+/* KNL Ubox */
+#define KNL_U_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_U_MSR_PMON_RAW_EVENT_MASK | \
+ SNBEP_CBO_PMON_CTL_TID_EN)
+/* KNL CHA */
+#define KNL_CHA_MSR_OFFSET 0xc
+#define KNL_CHA_MSR_PMON_CTL_QOR (1 << 16)
+#define KNL_CHA_MSR_PMON_RAW_EVENT_MASK \
+ (SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK | \
+ KNL_CHA_MSR_PMON_CTL_QOR)
+#define KNL_CHA_MSR_PMON_BOX_FILTER_TID 0x1ff
+#define KNL_CHA_MSR_PMON_BOX_FILTER_STATE (7 << 18)
+#define KNL_CHA_MSR_PMON_BOX_FILTER_OP (0xfffffe2aULL << 32)
+
+/* KNL EDC/MC UCLK */
+#define KNL_UCLK_MSR_PMON_CTR0_LOW 0x400
+#define KNL_UCLK_MSR_PMON_CTL0 0x420
+#define KNL_UCLK_MSR_PMON_BOX_CTL 0x430
+#define KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW 0x44c
+#define KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL 0x454
+#define KNL_PMON_FIXED_CTL_EN 0x1
+
+/* KNL EDC */
+#define KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW 0xa00
+#define KNL_EDC0_ECLK_MSR_PMON_CTL0 0xa20
+#define KNL_EDC0_ECLK_MSR_PMON_BOX_CTL 0xa30
+#define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW 0xa3c
+#define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL 0xa44
+
+/* KNL MC */
+#define KNL_MC0_CH0_MSR_PMON_CTR0_LOW 0xb00
+#define KNL_MC0_CH0_MSR_PMON_CTL0 0xb20
+#define KNL_MC0_CH0_MSR_PMON_BOX_CTL 0xb30
+#define KNL_MC0_CH0_MSR_PMON_FIXED_LOW 0xb3c
+#define KNL_MC0_CH0_MSR_PMON_FIXED_CTL 0xb44
+
+/* KNL IRP */
+#define KNL_IRP_PCI_PMON_BOX_CTL 0xf0
+#define KNL_IRP_PCI_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
+ KNL_CHA_MSR_PMON_CTL_QOR)
+/* KNL PCU */
+#define KNL_PCU_PMON_CTL_EV_SEL_MASK 0x0000007f
+#define KNL_PCU_PMON_CTL_USE_OCC_CTR (1 << 7)
+#define KNL_PCU_MSR_PMON_CTL_TRESH_MASK 0x3f000000
+#define KNL_PCU_MSR_PMON_RAW_EVENT_MASK \
+ (KNL_PCU_PMON_CTL_EV_SEL_MASK | \
+ KNL_PCU_PMON_CTL_USE_OCC_CTR | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
+ SNBEP_PMON_CTL_EDGE_DET | \
+ SNBEP_CBO_PMON_CTL_TID_EN | \
+ SNBEP_PMON_CTL_EV_SEL_EXT | \
+ SNBEP_PMON_CTL_INVERT | \
+ KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
+ SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
+DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
+DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
+DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
+DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
+DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
+DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
+DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
+DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
+DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
+DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
+DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
+DEFINE_UNCORE_FORMAT_ATTR(filter_tid4, filter_tid, "config1:0-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
+DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
+DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20");
+DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
+DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60");
+DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
+DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
+DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
+DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
+DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
+DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
+DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
+DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
+DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
+
+static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int box_ctl = uncore_pci_box_ctl(box);
+ u32 config = 0;
+
+ if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+ config |= SNBEP_PMON_BOX_CTL_FRZ;
+ pci_write_config_dword(pdev, box_ctl, config);
+ }
+}
+
+static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int box_ctl = uncore_pci_box_ctl(box);
+ u32 config = 0;
+
+ if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+ config &= ~SNBEP_PMON_BOX_CTL_FRZ;
+ pci_write_config_dword(pdev, box_ctl, config);
+ }
+}
+
+static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+
+ pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+
+ pci_write_config_dword(pdev, hwc->config_base, hwc->config);
+}
+
+static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+ u64 count = 0;
+
+ pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
+ pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
+
+ return count;
+}
+
+static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int box_ctl = uncore_pci_box_ctl(box);
+
+ pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
+}
+
+static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+ u64 config;
+ unsigned msr;
+
+ msr = uncore_msr_box_ctl(box);
+ if (msr) {
+ rdmsrl(msr, config);
+ config |= SNBEP_PMON_BOX_CTL_FRZ;
+ wrmsrl(msr, config);
+ }
+}
+
+static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+ u64 config;
+ unsigned msr;
+
+ msr = uncore_msr_box_ctl(box);
+ if (msr) {
+ rdmsrl(msr, config);
+ config &= ~SNBEP_PMON_BOX_CTL_FRZ;
+ wrmsrl(msr, config);
+ }
+}
+
+static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE)
+ wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
+
+ wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ wrmsrl(hwc->config_base, hwc->config);
+}
+
+static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+
+ if (msr)
+ wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
+}
+
+static struct attribute *snbep_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute *snbep_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh5.attr,
+ NULL,
+};
+
+static struct attribute *snbep_uncore_cbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_filter_tid.attr,
+ &format_attr_filter_nid.attr,
+ &format_attr_filter_state.attr,
+ &format_attr_filter_opc.attr,
+ NULL,
+};
+
+static struct attribute *snbep_uncore_pcu_formats_attr[] = {
+ &format_attr_event_ext.attr,
+ &format_attr_occ_sel.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh5.attr,
+ &format_attr_occ_invert.attr,
+ &format_attr_occ_edge.attr,
+ &format_attr_filter_band0.attr,
+ &format_attr_filter_band1.attr,
+ &format_attr_filter_band2.attr,
+ &format_attr_filter_band3.attr,
+ NULL,
+};
+
+static struct attribute *snbep_uncore_qpi_formats_attr[] = {
+ &format_attr_event_ext.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_match_rds.attr,
+ &format_attr_match_rnid30.attr,
+ &format_attr_match_rnid4.attr,
+ &format_attr_match_dnid.attr,
+ &format_attr_match_mc.attr,
+ &format_attr_match_opc.attr,
+ &format_attr_match_vnw.attr,
+ &format_attr_match0.attr,
+ &format_attr_match1.attr,
+ &format_attr_mask_rds.attr,
+ &format_attr_mask_rnid30.attr,
+ &format_attr_mask_rnid4.attr,
+ &format_attr_mask_dnid.attr,
+ &format_attr_mask_mc.attr,
+ &format_attr_mask_opc.attr,
+ &format_attr_mask_vnw.attr,
+ &format_attr_mask0.attr,
+ &format_attr_mask1.attr,
+ NULL,
+};
+
+static struct uncore_event_desc snbep_uncore_imc_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
+ { /* end: all zeroes */ },
+};
+
+static struct uncore_event_desc snbep_uncore_qpi_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"),
+ INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
+ INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"),
+ INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"),
+ { /* end: all zeroes */ },
+};
+
+static struct attribute_group snbep_uncore_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_ubox_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_cbox_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_cbox_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_pcu_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_pcu_formats_attr,
+};
+
+static struct attribute_group snbep_uncore_qpi_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_qpi_formats_attr,
+};
+
+#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
+ .disable_box = snbep_uncore_msr_disable_box, \
+ .enable_box = snbep_uncore_msr_enable_box, \
+ .disable_event = snbep_uncore_msr_disable_event, \
+ .enable_event = snbep_uncore_msr_enable_event, \
+ .read_counter = uncore_msr_read_counter
+
+#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
+ __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \
+ .init_box = snbep_uncore_msr_init_box \
+
+static struct intel_uncore_ops snbep_uncore_msr_ops = {
+ SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+};
+
+#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \
+ .init_box = snbep_uncore_pci_init_box, \
+ .disable_box = snbep_uncore_pci_disable_box, \
+ .enable_box = snbep_uncore_pci_enable_box, \
+ .disable_event = snbep_uncore_pci_disable_event, \
+ .read_counter = snbep_uncore_pci_read_counter
+
+static struct intel_uncore_ops snbep_uncore_pci_ops = {
+ SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+ .enable_event = snbep_uncore_pci_enable_event, \
+};
+
+static struct event_constraint snbep_uncore_cbox_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
+ UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
+ UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
+ UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
+ EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type snbep_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = SNBEP_U_MSR_PMON_CTR0,
+ .event_ctl = SNBEP_U_MSR_PMON_CTL0,
+ .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
+ .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
+ .ops = &snbep_uncore_msr_ops,
+ .format_group = &snbep_uncore_ubox_format_group,
+};
+
+static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
+ SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+ SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
+ EVENT_EXTRA_END
+};
+
+static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+ int i;
+
+ if (uncore_box_is_fake(box))
+ return;
+
+ for (i = 0; i < 5; i++) {
+ if (reg1->alloc & (0x1 << i))
+ atomic_sub(1 << (i * 6), &er->ref);
+ }
+ reg1->alloc = 0;
+}
+
+static struct event_constraint *
+__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
+ u64 (*cbox_filter_mask)(int fields))
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+ int i, alloc = 0;
+ unsigned long flags;
+ u64 mask;
+
+ if (reg1->idx == EXTRA_REG_NONE)
+ return NULL;
+
+ raw_spin_lock_irqsave(&er->lock, flags);
+ for (i = 0; i < 5; i++) {
+ if (!(reg1->idx & (0x1 << i)))
+ continue;
+ if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
+ continue;
+
+ mask = cbox_filter_mask(0x1 << i);
+ if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
+ !((reg1->config ^ er->config) & mask)) {
+ atomic_add(1 << (i * 6), &er->ref);
+ er->config &= ~mask;
+ er->config |= reg1->config & mask;
+ alloc |= (0x1 << i);
+ } else {
+ break;
+ }
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+ if (i < 5)
+ goto fail;
+
+ if (!uncore_box_is_fake(box))
+ reg1->alloc |= alloc;
+
+ return NULL;
+fail:
+ for (; i >= 0; i--) {
+ if (alloc & (0x1 << i))
+ atomic_sub(1 << (i * 6), &er->ref);
+ }
+ return &uncore_constraint_empty;
+}
+
+static u64 snbep_cbox_filter_mask(int fields)
+{
+ u64 mask = 0;
+
+ if (fields & 0x1)
+ mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
+ if (fields & 0x2)
+ mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
+ if (fields & 0x4)
+ mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+ if (fields & 0x8)
+ mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+
+ return mask;
+}
+
+static struct event_constraint *
+snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
+}
+
+static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct extra_reg *er;
+ int idx = 0;
+
+ for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ idx |= er->idx;
+ }
+
+ if (idx) {
+ reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
+ SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+ reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
+ reg1->idx = idx;
+ }
+ return 0;
+}
+
+static struct intel_uncore_ops snbep_uncore_cbox_ops = {
+ SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .hw_config = snbep_cbox_hw_config,
+ .get_constraint = snbep_cbox_get_constraint,
+ .put_constraint = snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type snbep_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 4,
+ .num_boxes = 8,
+ .perf_ctr_bits = 44,
+ .event_ctl = SNBEP_C0_MSR_PMON_CTL0,
+ .perf_ctr = SNBEP_C0_MSR_PMON_CTR0,
+ .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL,
+ .msr_offset = SNBEP_CBO_MSR_OFFSET,
+ .num_shared_regs = 1,
+ .constraints = snbep_uncore_cbox_constraints,
+ .ops = &snbep_uncore_cbox_ops,
+ .format_group = &snbep_uncore_cbox_format_group,
+};
+
+static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ u64 config = reg1->config;
+
+ if (new_idx > reg1->idx)
+ config <<= 8 * (new_idx - reg1->idx);
+ else
+ config >>= 8 * (reg1->idx - new_idx);
+
+ if (modify) {
+ hwc->config += new_idx - reg1->idx;
+ reg1->config = config;
+ reg1->idx = new_idx;
+ }
+ return config;
+}
+
+static struct event_constraint *
+snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+ unsigned long flags;
+ int idx = reg1->idx;
+ u64 mask, config1 = reg1->config;
+ bool ok = false;
+
+ if (reg1->idx == EXTRA_REG_NONE ||
+ (!uncore_box_is_fake(box) && reg1->alloc))
+ return NULL;
+again:
+ mask = 0xffULL << (idx * 8);
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
+ !((config1 ^ er->config) & mask)) {
+ atomic_add(1 << (idx * 8), &er->ref);
+ er->config &= ~mask;
+ er->config |= config1 & mask;
+ ok = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ if (!ok) {
+ idx = (idx + 1) % 4;
+ if (idx != reg1->idx) {
+ config1 = snbep_pcu_alter_er(event, idx, false);
+ goto again;
+ }
+ return &uncore_constraint_empty;
+ }
+
+ if (!uncore_box_is_fake(box)) {
+ if (idx != reg1->idx)
+ snbep_pcu_alter_er(event, idx, true);
+ reg1->alloc = 1;
+ }
+ return NULL;
+}
+
+static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct intel_uncore_extra_reg *er = &box->shared_regs[0];
+
+ if (uncore_box_is_fake(box) || !reg1->alloc)
+ return;
+
+ atomic_sub(1 << (reg1->idx * 8), &er->ref);
+ reg1->alloc = 0;
+}
+
+static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
+
+ if (ev_sel >= 0xb && ev_sel <= 0xe) {
+ reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
+ reg1->idx = ev_sel - 0xb;
+ reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
+ }
+ return 0;
+}
+
+static struct intel_uncore_ops snbep_uncore_pcu_ops = {
+ SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .hw_config = snbep_pcu_hw_config,
+ .get_constraint = snbep_pcu_get_constraint,
+ .put_constraint = snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type snbep_uncore_pcu = {
+ .name = "pcu",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0,
+ .event_ctl = SNBEP_PCU_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &snbep_uncore_pcu_ops,
+ .format_group = &snbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *snbep_msr_uncores[] = {
+ &snbep_uncore_ubox,
+ &snbep_uncore_cbox,
+ &snbep_uncore_pcu,
+ NULL,
+};
+
+void snbep_uncore_cpu_init(void)
+{
+ if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ uncore_msr_uncores = snbep_msr_uncores;
+}
+
+enum {
+ SNBEP_PCI_QPI_PORT0_FILTER,
+ SNBEP_PCI_QPI_PORT1_FILTER,
+ HSWEP_PCI_PCU_3,
+};
+
+static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
+ reg1->idx = 0;
+ reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
+ reg1->config = event->attr.config1;
+ reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
+ reg2->config = event->attr.config2;
+ }
+ return 0;
+}
+
+static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
+ int pkg = topology_phys_to_logical_pkg(box->pci_phys_id);
+ struct pci_dev *filter_pdev = uncore_extra_pci_dev[pkg].dev[idx];
+
+ if (filter_pdev) {
+ pci_write_config_dword(filter_pdev, reg1->reg,
+ (u32)reg1->config);
+ pci_write_config_dword(filter_pdev, reg1->reg + 4,
+ (u32)(reg1->config >> 32));
+ pci_write_config_dword(filter_pdev, reg2->reg,
+ (u32)reg2->config);
+ pci_write_config_dword(filter_pdev, reg2->reg + 4,
+ (u32)(reg2->config >> 32));
+ }
+ }
+
+ pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops snbep_uncore_qpi_ops = {
+ SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
+ .enable_event = snbep_qpi_enable_event,
+ .hw_config = snbep_qpi_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+#define SNBEP_UNCORE_PCI_COMMON_INIT() \
+ .perf_ctr = SNBEP_PCI_PMON_CTR0, \
+ .event_ctl = SNBEP_PCI_PMON_CTL0, \
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \
+ .ops = &snbep_uncore_pci_ops, \
+ .format_group = &snbep_uncore_format_group
+
+static struct intel_uncore_type snbep_uncore_ha = {
+ .name = "ha",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_imc = {
+ .name = "imc",
+ .num_counters = 4,
+ .num_boxes = 4,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+ .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+ .event_descs = snbep_uncore_imc_events,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_qpi = {
+ .name = "qpi",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &snbep_uncore_qpi_ops,
+ .event_descs = snbep_uncore_qpi_events,
+ .format_group = &snbep_uncore_qpi_format_group,
+};
+
+
+static struct intel_uncore_type snbep_uncore_r2pcie = {
+ .name = "r2pcie",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .constraints = snbep_uncore_r2pcie_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type snbep_uncore_r3qpi = {
+ .name = "r3qpi",
+ .num_counters = 3,
+ .num_boxes = 2,
+ .perf_ctr_bits = 44,
+ .constraints = snbep_uncore_r3qpi_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+ SNBEP_PCI_UNCORE_HA,
+ SNBEP_PCI_UNCORE_IMC,
+ SNBEP_PCI_UNCORE_QPI,
+ SNBEP_PCI_UNCORE_R2PCIE,
+ SNBEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *snbep_pci_uncores[] = {
+ [SNBEP_PCI_UNCORE_HA] = &snbep_uncore_ha,
+ [SNBEP_PCI_UNCORE_IMC] = &snbep_uncore_imc,
+ [SNBEP_PCI_UNCORE_QPI] = &snbep_uncore_qpi,
+ [SNBEP_PCI_UNCORE_R2PCIE] = &snbep_uncore_r2pcie,
+ [SNBEP_PCI_UNCORE_R3QPI] = &snbep_uncore_r3qpi,
+ NULL,
+};
+
+static const struct pci_device_id snbep_uncore_pci_ids[] = {
+ { /* Home Agent */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
+ },
+ { /* MC Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
+ },
+ { /* MC Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
+ },
+ { /* MC Channel 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
+ },
+ { /* MC Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
+ },
+ { /* QPI Port 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
+ },
+ { /* QPI Port 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
+ },
+ { /* R2PCIe */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
+ },
+ { /* R3QPI Link 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
+ },
+ { /* R3QPI Link 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT0_FILTER),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT1_FILTER),
+ },
+ { /* end: all zeroes */ }
+};
+
+static struct pci_driver snbep_uncore_pci_driver = {
+ .name = "snbep_uncore",
+ .id_table = snbep_uncore_pci_ids,
+};
+
+/*
+ * build pci bus to socket mapping
+ */
+static int snbep_pci2phy_map_init(int devid)
+{
+ struct pci_dev *ubox_dev = NULL;
+ int i, bus, nodeid, segment;
+ struct pci2phy_map *map;
+ int err = 0;
+ u32 config = 0;
+
+ while (1) {
+ /* find the UBOX device */
+ ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
+ if (!ubox_dev)
+ break;
+ bus = ubox_dev->bus->number;
+ /* get the Node ID of the local register */
+ err = pci_read_config_dword(ubox_dev, 0x40, &config);
+ if (err)
+ break;
+ nodeid = config;
+ /* get the Node ID mapping */
+ err = pci_read_config_dword(ubox_dev, 0x54, &config);
+ if (err)
+ break;
+
+ segment = pci_domain_nr(ubox_dev->bus);
+ raw_spin_lock(&pci2phy_map_lock);
+ map = __find_pci2phy_map(segment);
+ if (!map) {
+ raw_spin_unlock(&pci2phy_map_lock);
+ err = -ENOMEM;
+ break;
+ }
+
+ /*
+ * every three bits in the Node ID mapping register maps
+ * to a particular node.
+ */
+ for (i = 0; i < 8; i++) {
+ if (nodeid == ((config >> (3 * i)) & 0x7)) {
+ map->pbus_to_physid[bus] = i;
+ break;
+ }
+ }
+ raw_spin_unlock(&pci2phy_map_lock);
+ }
+
+ if (!err) {
+ /*
+ * For PCI bus with no UBOX device, find the next bus
+ * that has UBOX device and use its mapping.
+ */
+ raw_spin_lock(&pci2phy_map_lock);
+ list_for_each_entry(map, &pci2phy_map_head, list) {
+ i = -1;
+ for (bus = 255; bus >= 0; bus--) {
+ if (map->pbus_to_physid[bus] >= 0)
+ i = map->pbus_to_physid[bus];
+ else
+ map->pbus_to_physid[bus] = i;
+ }
+ }
+ raw_spin_unlock(&pci2phy_map_lock);
+ }
+
+ pci_dev_put(ubox_dev);
+
+ return err ? pcibios_err_to_errno(err) : 0;
+}
+
+int snbep_uncore_pci_init(void)
+{
+ int ret = snbep_pci2phy_map_init(0x3ce0);
+ if (ret)
+ return ret;
+ uncore_pci_uncores = snbep_pci_uncores;
+ uncore_pci_driver = &snbep_uncore_pci_driver;
+ return 0;
+}
+/* end of Sandy Bridge-EP uncore support */
+
+/* IvyTown uncore support */
+static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+ if (msr)
+ wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
+}
+
+static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+
+ pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
+}
+
+#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT() \
+ .init_box = ivbep_uncore_msr_init_box, \
+ .disable_box = snbep_uncore_msr_disable_box, \
+ .enable_box = snbep_uncore_msr_enable_box, \
+ .disable_event = snbep_uncore_msr_disable_event, \
+ .enable_event = snbep_uncore_msr_enable_event, \
+ .read_counter = uncore_msr_read_counter
+
+static struct intel_uncore_ops ivbep_uncore_msr_ops = {
+ IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+};
+
+static struct intel_uncore_ops ivbep_uncore_pci_ops = {
+ .init_box = ivbep_uncore_pci_init_box,
+ .disable_box = snbep_uncore_pci_disable_box,
+ .enable_box = snbep_uncore_pci_enable_box,
+ .disable_event = snbep_uncore_pci_disable_event,
+ .enable_event = snbep_uncore_pci_enable_event,
+ .read_counter = snbep_uncore_pci_read_counter,
+};
+
+#define IVBEP_UNCORE_PCI_COMMON_INIT() \
+ .perf_ctr = SNBEP_PCI_PMON_CTR0, \
+ .event_ctl = SNBEP_PCI_PMON_CTL0, \
+ .event_mask = IVBEP_PMON_RAW_EVENT_MASK, \
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \
+ .ops = &ivbep_uncore_pci_ops, \
+ .format_group = &ivbep_uncore_format_group
+
+static struct attribute *ivbep_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh5.attr,
+ NULL,
+};
+
+static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_filter_tid.attr,
+ &format_attr_filter_link.attr,
+ &format_attr_filter_state2.attr,
+ &format_attr_filter_nid2.attr,
+ &format_attr_filter_opc2.attr,
+ &format_attr_filter_nc.attr,
+ &format_attr_filter_c6.attr,
+ &format_attr_filter_isoc.attr,
+ NULL,
+};
+
+static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
+ &format_attr_event_ext.attr,
+ &format_attr_occ_sel.attr,
+ &format_attr_edge.attr,
+ &format_attr_thresh5.attr,
+ &format_attr_occ_invert.attr,
+ &format_attr_occ_edge.attr,
+ &format_attr_filter_band0.attr,
+ &format_attr_filter_band1.attr,
+ &format_attr_filter_band2.attr,
+ &format_attr_filter_band3.attr,
+ NULL,
+};
+
+static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
+ &format_attr_event_ext.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_match_rds.attr,
+ &format_attr_match_rnid30.attr,
+ &format_attr_match_rnid4.attr,
+ &format_attr_match_dnid.attr,
+ &format_attr_match_mc.attr,
+ &format_attr_match_opc.attr,
+ &format_attr_match_vnw.attr,
+ &format_attr_match0.attr,
+ &format_attr_match1.attr,
+ &format_attr_mask_rds.attr,
+ &format_attr_mask_rnid30.attr,
+ &format_attr_mask_rnid4.attr,
+ &format_attr_mask_dnid.attr,
+ &format_attr_mask_mc.attr,
+ &format_attr_mask_opc.attr,
+ &format_attr_mask_vnw.attr,
+ &format_attr_mask0.attr,
+ &format_attr_mask1.attr,
+ NULL,
+};
+
+static struct attribute_group ivbep_uncore_format_group = {
+ .name = "format",
+ .attrs = ivbep_uncore_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = ivbep_uncore_ubox_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_cbox_format_group = {
+ .name = "format",
+ .attrs = ivbep_uncore_cbox_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_pcu_format_group = {
+ .name = "format",
+ .attrs = ivbep_uncore_pcu_formats_attr,
+};
+
+static struct attribute_group ivbep_uncore_qpi_format_group = {
+ .name = "format",
+ .attrs = ivbep_uncore_qpi_formats_attr,
+};
+
+static struct intel_uncore_type ivbep_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = SNBEP_U_MSR_PMON_CTR0,
+ .event_ctl = SNBEP_U_MSR_PMON_CTL0,
+ .event_mask = IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
+ .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
+ .ops = &ivbep_uncore_msr_ops,
+ .format_group = &ivbep_uncore_ubox_format_group,
+};
+
+static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
+ SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+ SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
+ EVENT_EXTRA_END
+};
+
+static u64 ivbep_cbox_filter_mask(int fields)
+{
+ u64 mask = 0;
+
+ if (fields & 0x1)
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
+ if (fields & 0x2)
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
+ if (fields & 0x4)
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+ if (fields & 0x8)
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
+ if (fields & 0x10) {
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
+ mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
+ }
+
+ return mask;
+}
+
+static struct event_constraint *
+ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
+}
+
+static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct extra_reg *er;
+ int idx = 0;
+
+ for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ idx |= er->idx;
+ }
+
+ if (idx) {
+ reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
+ SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+ reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
+ reg1->idx = idx;
+ }
+ return 0;
+}
+
+static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ u64 filter = uncore_shared_reg_config(box, 0);
+ wrmsrl(reg1->reg, filter & 0xffffffff);
+ wrmsrl(reg1->reg + 6, filter >> 32);
+ }
+
+ wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
+ .init_box = ivbep_uncore_msr_init_box,
+ .disable_box = snbep_uncore_msr_disable_box,
+ .enable_box = snbep_uncore_msr_enable_box,
+ .disable_event = snbep_uncore_msr_disable_event,
+ .enable_event = ivbep_cbox_enable_event,
+ .read_counter = uncore_msr_read_counter,
+ .hw_config = ivbep_cbox_hw_config,
+ .get_constraint = ivbep_cbox_get_constraint,
+ .put_constraint = snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 4,
+ .num_boxes = 15,
+ .perf_ctr_bits = 44,
+ .event_ctl = SNBEP_C0_MSR_PMON_CTL0,
+ .perf_ctr = SNBEP_C0_MSR_PMON_CTR0,
+ .event_mask = IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL,
+ .msr_offset = SNBEP_CBO_MSR_OFFSET,
+ .num_shared_regs = 1,
+ .constraints = snbep_uncore_cbox_constraints,
+ .ops = &ivbep_uncore_cbox_ops,
+ .format_group = &ivbep_uncore_cbox_format_group,
+};
+
+static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
+ IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .hw_config = snbep_pcu_hw_config,
+ .get_constraint = snbep_pcu_get_constraint,
+ .put_constraint = snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_pcu = {
+ .name = "pcu",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0,
+ .event_ctl = SNBEP_PCU_MSR_PMON_CTL0,
+ .event_mask = IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &ivbep_uncore_pcu_ops,
+ .format_group = &ivbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *ivbep_msr_uncores[] = {
+ &ivbep_uncore_ubox,
+ &ivbep_uncore_cbox,
+ &ivbep_uncore_pcu,
+ NULL,
+};
+
+void ivbep_uncore_cpu_init(void)
+{
+ if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ uncore_msr_uncores = ivbep_msr_uncores;
+}
+
+static struct intel_uncore_type ivbep_uncore_ha = {
+ .name = "ha",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type ivbep_uncore_imc = {
+ .name = "imc",
+ .num_counters = 4,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+ .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+ .event_descs = snbep_uncore_imc_events,
+ IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+/* registers in IRP boxes are not properly aligned */
+static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
+static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
+
+static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+
+ pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
+ hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+
+ pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
+}
+
+static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+ u64 count = 0;
+
+ pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+ pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+ return count;
+}
+
+static struct intel_uncore_ops ivbep_uncore_irp_ops = {
+ .init_box = ivbep_uncore_pci_init_box,
+ .disable_box = snbep_uncore_pci_disable_box,
+ .enable_box = snbep_uncore_pci_enable_box,
+ .disable_event = ivbep_uncore_irp_disable_event,
+ .enable_event = ivbep_uncore_irp_enable_event,
+ .read_counter = ivbep_uncore_irp_read_counter,
+};
+
+static struct intel_uncore_type ivbep_uncore_irp = {
+ .name = "irp",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_mask = IVBEP_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .ops = &ivbep_uncore_irp_ops,
+ .format_group = &ivbep_uncore_format_group,
+};
+
+static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
+ .init_box = ivbep_uncore_pci_init_box,
+ .disable_box = snbep_uncore_pci_disable_box,
+ .enable_box = snbep_uncore_pci_enable_box,
+ .disable_event = snbep_uncore_pci_disable_event,
+ .enable_event = snbep_qpi_enable_event,
+ .read_counter = snbep_uncore_pci_read_counter,
+ .hw_config = snbep_qpi_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type ivbep_uncore_qpi = {
+ .name = "qpi",
+ .num_counters = 4,
+ .num_boxes = 3,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &ivbep_uncore_qpi_ops,
+ .format_group = &ivbep_uncore_qpi_format_group,
+};
+
+static struct intel_uncore_type ivbep_uncore_r2pcie = {
+ .name = "r2pcie",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .constraints = snbep_uncore_r2pcie_constraints,
+ IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type ivbep_uncore_r3qpi = {
+ .name = "r3qpi",
+ .num_counters = 3,
+ .num_boxes = 2,
+ .perf_ctr_bits = 44,
+ .constraints = snbep_uncore_r3qpi_constraints,
+ IVBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+ IVBEP_PCI_UNCORE_HA,
+ IVBEP_PCI_UNCORE_IMC,
+ IVBEP_PCI_UNCORE_IRP,
+ IVBEP_PCI_UNCORE_QPI,
+ IVBEP_PCI_UNCORE_R2PCIE,
+ IVBEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *ivbep_pci_uncores[] = {
+ [IVBEP_PCI_UNCORE_HA] = &ivbep_uncore_ha,
+ [IVBEP_PCI_UNCORE_IMC] = &ivbep_uncore_imc,
+ [IVBEP_PCI_UNCORE_IRP] = &ivbep_uncore_irp,
+ [IVBEP_PCI_UNCORE_QPI] = &ivbep_uncore_qpi,
+ [IVBEP_PCI_UNCORE_R2PCIE] = &ivbep_uncore_r2pcie,
+ [IVBEP_PCI_UNCORE_R3QPI] = &ivbep_uncore_r3qpi,
+ NULL,
+};
+
+static const struct pci_device_id ivbep_uncore_pci_ids[] = {
+ { /* Home Agent 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
+ },
+ { /* Home Agent 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
+ },
+ { /* MC0 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
+ },
+ { /* MC0 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
+ },
+ { /* MC0 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
+ },
+ { /* MC0 Channel 4 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
+ },
+ { /* MC1 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
+ },
+ { /* MC1 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
+ },
+ { /* MC1 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
+ },
+ { /* MC1 Channel 4 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
+ },
+ { /* IRP */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
+ },
+ { /* QPI0 Port 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
+ },
+ { /* QPI0 Port 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
+ },
+ { /* QPI1 Port 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
+ },
+ { /* R2PCIe */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
+ },
+ { /* R3QPI0 Link 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
+ },
+ { /* R3QPI0 Link 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
+ },
+ { /* R3QPI1 Link 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
+ .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT0_FILTER),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT1_FILTER),
+ },
+ { /* end: all zeroes */ }
+};
+
+static struct pci_driver ivbep_uncore_pci_driver = {
+ .name = "ivbep_uncore",
+ .id_table = ivbep_uncore_pci_ids,
+};
+
+int ivbep_uncore_pci_init(void)
+{
+ int ret = snbep_pci2phy_map_init(0x0e1e);
+ if (ret)
+ return ret;
+ uncore_pci_uncores = ivbep_pci_uncores;
+ uncore_pci_driver = &ivbep_uncore_pci_driver;
+ return 0;
+}
+/* end of IvyTown uncore support */
+
+/* KNL uncore support */
+static struct attribute *knl_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh5.attr,
+ NULL,
+};
+
+static struct attribute_group knl_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = knl_uncore_ubox_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = HSWEP_U_MSR_PMON_CTR0,
+ .event_ctl = HSWEP_U_MSR_PMON_CTL0,
+ .event_mask = KNL_U_MSR_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+ .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+ .ops = &snbep_uncore_msr_ops,
+ .format_group = &knl_uncore_ubox_format_group,
+};
+
+static struct attribute *knl_uncore_cha_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_qor.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_filter_tid4.attr,
+ &format_attr_filter_link3.attr,
+ &format_attr_filter_state4.attr,
+ &format_attr_filter_local.attr,
+ &format_attr_filter_all_op.attr,
+ &format_attr_filter_nnm.attr,
+ &format_attr_filter_opc3.attr,
+ &format_attr_filter_nc.attr,
+ &format_attr_filter_isoc.attr,
+ NULL,
+};
+
+static struct attribute_group knl_uncore_cha_format_group = {
+ .name = "format",
+ .attrs = knl_uncore_cha_formats_attr,
+};
+
+static struct event_constraint knl_uncore_cha_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg knl_uncore_cha_extra_regs[] = {
+ SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+ SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x3d, 0xff, 0x2),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x4),
+ EVENT_EXTRA_END
+};
+
+static u64 knl_cha_filter_mask(int fields)
+{
+ u64 mask = 0;
+
+ if (fields & 0x1)
+ mask |= KNL_CHA_MSR_PMON_BOX_FILTER_TID;
+ if (fields & 0x2)
+ mask |= KNL_CHA_MSR_PMON_BOX_FILTER_STATE;
+ if (fields & 0x4)
+ mask |= KNL_CHA_MSR_PMON_BOX_FILTER_OP;
+ return mask;
+}
+
+static struct event_constraint *
+knl_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ return __snbep_cbox_get_constraint(box, event, knl_cha_filter_mask);
+}
+
+static int knl_cha_hw_config(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct extra_reg *er;
+ int idx = 0;
+
+ for (er = knl_uncore_cha_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ idx |= er->idx;
+ }
+
+ if (idx) {
+ reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
+ KNL_CHA_MSR_OFFSET * box->pmu->pmu_idx;
+ reg1->config = event->attr.config1 & knl_cha_filter_mask(idx);
+ reg1->idx = idx;
+ }
+ return 0;
+}
+
+static void hswep_cbox_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event);
+
+static struct intel_uncore_ops knl_uncore_cha_ops = {
+ .init_box = snbep_uncore_msr_init_box,
+ .disable_box = snbep_uncore_msr_disable_box,
+ .enable_box = snbep_uncore_msr_enable_box,
+ .disable_event = snbep_uncore_msr_disable_event,
+ .enable_event = hswep_cbox_enable_event,
+ .read_counter = uncore_msr_read_counter,
+ .hw_config = knl_cha_hw_config,
+ .get_constraint = knl_cha_get_constraint,
+ .put_constraint = snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type knl_uncore_cha = {
+ .name = "cha",
+ .num_counters = 4,
+ .num_boxes = 38,
+ .perf_ctr_bits = 48,
+ .event_ctl = HSWEP_C0_MSR_PMON_CTL0,
+ .perf_ctr = HSWEP_C0_MSR_PMON_CTR0,
+ .event_mask = KNL_CHA_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL,
+ .msr_offset = KNL_CHA_MSR_OFFSET,
+ .num_shared_regs = 1,
+ .constraints = knl_uncore_cha_constraints,
+ .ops = &knl_uncore_cha_ops,
+ .format_group = &knl_uncore_cha_format_group,
+};
+
+static struct attribute *knl_uncore_pcu_formats_attr[] = {
+ &format_attr_event2.attr,
+ &format_attr_use_occ_ctr.attr,
+ &format_attr_occ_sel.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh6.attr,
+ &format_attr_occ_invert.attr,
+ &format_attr_occ_edge_det.attr,
+ NULL,
+};
+
+static struct attribute_group knl_uncore_pcu_format_group = {
+ .name = "format",
+ .attrs = knl_uncore_pcu_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_pcu = {
+ .name = "pcu",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = HSWEP_PCU_MSR_PMON_CTR0,
+ .event_ctl = HSWEP_PCU_MSR_PMON_CTL0,
+ .event_mask = KNL_PCU_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_PCU_MSR_PMON_BOX_CTL,
+ .ops = &snbep_uncore_msr_ops,
+ .format_group = &knl_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *knl_msr_uncores[] = {
+ &knl_uncore_ubox,
+ &knl_uncore_cha,
+ &knl_uncore_pcu,
+ NULL,
+};
+
+void knl_uncore_cpu_init(void)
+{
+ uncore_msr_uncores = knl_msr_uncores;
+}
+
+static void knl_uncore_imc_enable_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int box_ctl = uncore_pci_box_ctl(box);
+
+ pci_write_config_dword(pdev, box_ctl, 0);
+}
+
+static void knl_uncore_imc_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+
+ if ((event->attr.config & SNBEP_PMON_CTL_EV_SEL_MASK)
+ == UNCORE_FIXED_EVENT)
+ pci_write_config_dword(pdev, hwc->config_base,
+ hwc->config | KNL_PMON_FIXED_CTL_EN);
+ else
+ pci_write_config_dword(pdev, hwc->config_base,
+ hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops knl_uncore_imc_ops = {
+ .init_box = snbep_uncore_pci_init_box,
+ .disable_box = snbep_uncore_pci_disable_box,
+ .enable_box = knl_uncore_imc_enable_box,
+ .read_counter = snbep_uncore_pci_read_counter,
+ .enable_event = knl_uncore_imc_enable_event,
+ .disable_event = snbep_uncore_pci_disable_event,
+};
+
+static struct intel_uncore_type knl_uncore_imc_uclk = {
+ .name = "imc_uclk",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = KNL_UCLK_MSR_PMON_CTR0_LOW,
+ .event_ctl = KNL_UCLK_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
+ .fixed_ctl = KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
+ .box_ctl = KNL_UCLK_MSR_PMON_BOX_CTL,
+ .ops = &knl_uncore_imc_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_imc_dclk = {
+ .name = "imc",
+ .num_counters = 4,
+ .num_boxes = 6,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = KNL_MC0_CH0_MSR_PMON_CTR0_LOW,
+ .event_ctl = KNL_MC0_CH0_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = KNL_MC0_CH0_MSR_PMON_FIXED_LOW,
+ .fixed_ctl = KNL_MC0_CH0_MSR_PMON_FIXED_CTL,
+ .box_ctl = KNL_MC0_CH0_MSR_PMON_BOX_CTL,
+ .ops = &knl_uncore_imc_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_edc_uclk = {
+ .name = "edc_uclk",
+ .num_counters = 4,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = KNL_UCLK_MSR_PMON_CTR0_LOW,
+ .event_ctl = KNL_UCLK_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
+ .fixed_ctl = KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
+ .box_ctl = KNL_UCLK_MSR_PMON_BOX_CTL,
+ .ops = &knl_uncore_imc_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type knl_uncore_edc_eclk = {
+ .name = "edc_eclk",
+ .num_counters = 4,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW,
+ .event_ctl = KNL_EDC0_ECLK_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW,
+ .fixed_ctl = KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL,
+ .box_ctl = KNL_EDC0_ECLK_MSR_PMON_BOX_CTL,
+ .ops = &knl_uncore_imc_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct event_constraint knl_uncore_m2pcie_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type knl_uncore_m2pcie = {
+ .name = "m2pcie",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .constraints = knl_uncore_m2pcie_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct attribute *knl_uncore_irp_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_qor.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute_group knl_uncore_irp_format_group = {
+ .name = "format",
+ .attrs = knl_uncore_irp_formats_attr,
+};
+
+static struct intel_uncore_type knl_uncore_irp = {
+ .name = "irp",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = KNL_IRP_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = KNL_IRP_PCI_PMON_BOX_CTL,
+ .ops = &snbep_uncore_pci_ops,
+ .format_group = &knl_uncore_irp_format_group,
+};
+
+enum {
+ KNL_PCI_UNCORE_MC_UCLK,
+ KNL_PCI_UNCORE_MC_DCLK,
+ KNL_PCI_UNCORE_EDC_UCLK,
+ KNL_PCI_UNCORE_EDC_ECLK,
+ KNL_PCI_UNCORE_M2PCIE,
+ KNL_PCI_UNCORE_IRP,
+};
+
+static struct intel_uncore_type *knl_pci_uncores[] = {
+ [KNL_PCI_UNCORE_MC_UCLK] = &knl_uncore_imc_uclk,
+ [KNL_PCI_UNCORE_MC_DCLK] = &knl_uncore_imc_dclk,
+ [KNL_PCI_UNCORE_EDC_UCLK] = &knl_uncore_edc_uclk,
+ [KNL_PCI_UNCORE_EDC_ECLK] = &knl_uncore_edc_eclk,
+ [KNL_PCI_UNCORE_M2PCIE] = &knl_uncore_m2pcie,
+ [KNL_PCI_UNCORE_IRP] = &knl_uncore_irp,
+ NULL,
+};
+
+/*
+ * KNL uses a common PCI device ID for multiple instances of an Uncore PMU
+ * device type. prior to KNL, each instance of a PMU device type had a unique
+ * device ID.
+ *
+ * PCI Device ID Uncore PMU Devices
+ * ----------------------------------
+ * 0x7841 MC0 UClk, MC1 UClk
+ * 0x7843 MC0 DClk CH 0, MC0 DClk CH 1, MC0 DClk CH 2,
+ * MC1 DClk CH 0, MC1 DClk CH 1, MC1 DClk CH 2
+ * 0x7833 EDC0 UClk, EDC1 UClk, EDC2 UClk, EDC3 UClk,
+ * EDC4 UClk, EDC5 UClk, EDC6 UClk, EDC7 UClk
+ * 0x7835 EDC0 EClk, EDC1 EClk, EDC2 EClk, EDC3 EClk,
+ * EDC4 EClk, EDC5 EClk, EDC6 EClk, EDC7 EClk
+ * 0x7817 M2PCIe
+ * 0x7814 IRP
+*/
+
+static const struct pci_device_id knl_uncore_pci_ids[] = {
+ { /* MC UClk */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_MC_UCLK, 0),
+ },
+ { /* MC DClk Channel */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_MC_DCLK, 0),
+ },
+ { /* EDC UClk */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_EDC_UCLK, 0),
+ },
+ { /* EDC EClk */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_EDC_ECLK, 0),
+ },
+ { /* M2PCIe */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7817),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_M2PCIE, 0),
+ },
+ { /* IRP */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7814),
+ .driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_IRP, 0),
+ },
+ { /* end: all zeroes */ }
+};
+
+static struct pci_driver knl_uncore_pci_driver = {
+ .name = "knl_uncore",
+ .id_table = knl_uncore_pci_ids,
+};
+
+int knl_uncore_pci_init(void)
+{
+ int ret;
+
+ /* All KNL PCI based PMON units are on the same PCI bus except IRP */
+ ret = snb_pci2phy_map_init(0x7814); /* IRP */
+ if (ret)
+ return ret;
+ ret = snb_pci2phy_map_init(0x7817); /* M2PCIe */
+ if (ret)
+ return ret;
+ uncore_pci_uncores = knl_pci_uncores;
+ uncore_pci_driver = &knl_uncore_pci_driver;
+ return 0;
+}
+
+/* end of KNL uncore support */
+
+/* Haswell-EP uncore support */
+static struct attribute *hswep_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh5.attr,
+ &format_attr_filter_tid2.attr,
+ &format_attr_filter_cid.attr,
+ NULL,
+};
+
+static struct attribute_group hswep_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = hswep_uncore_ubox_formats_attr,
+};
+
+static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ reg1->reg = HSWEP_U_MSR_PMON_FILTER;
+ reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
+ reg1->idx = 0;
+ return 0;
+}
+
+static struct intel_uncore_ops hswep_uncore_ubox_ops = {
+ SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .hw_config = hswep_ubox_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 44,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = HSWEP_U_MSR_PMON_CTR0,
+ .event_ctl = HSWEP_U_MSR_PMON_CTL0,
+ .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+ .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+ .num_shared_regs = 1,
+ .ops = &hswep_uncore_ubox_ops,
+ .format_group = &hswep_uncore_ubox_format_group,
+};
+
+static struct attribute *hswep_uncore_cbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_filter_tid3.attr,
+ &format_attr_filter_link2.attr,
+ &format_attr_filter_state3.attr,
+ &format_attr_filter_nid2.attr,
+ &format_attr_filter_opc2.attr,
+ &format_attr_filter_nc.attr,
+ &format_attr_filter_c6.attr,
+ &format_attr_filter_isoc.attr,
+ NULL,
+};
+
+static struct attribute_group hswep_uncore_cbox_format_group = {
+ .name = "format",
+ .attrs = hswep_uncore_cbox_formats_attr,
+};
+
+static struct event_constraint hswep_uncore_cbox_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
+ SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
+ SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
+ EVENT_EXTRA_END
+};
+
+static u64 hswep_cbox_filter_mask(int fields)
+{
+ u64 mask = 0;
+ if (fields & 0x1)
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
+ if (fields & 0x2)
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
+ if (fields & 0x4)
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
+ if (fields & 0x8)
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
+ if (fields & 0x10) {
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
+ mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
+ }
+ return mask;
+}
+
+static struct event_constraint *
+hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
+}
+
+static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct extra_reg *er;
+ int idx = 0;
+
+ for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ idx |= er->idx;
+ }
+
+ if (idx) {
+ reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
+ HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
+ reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
+ reg1->idx = idx;
+ }
+ return 0;
+}
+
+static void hswep_cbox_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ u64 filter = uncore_shared_reg_config(box, 0);
+ wrmsrl(reg1->reg, filter & 0xffffffff);
+ wrmsrl(reg1->reg + 1, filter >> 32);
+ }
+
+ wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
+}
+
+static struct intel_uncore_ops hswep_uncore_cbox_ops = {
+ .init_box = snbep_uncore_msr_init_box,
+ .disable_box = snbep_uncore_msr_disable_box,
+ .enable_box = snbep_uncore_msr_enable_box,
+ .disable_event = snbep_uncore_msr_disable_event,
+ .enable_event = hswep_cbox_enable_event,
+ .read_counter = uncore_msr_read_counter,
+ .hw_config = hswep_cbox_hw_config,
+ .get_constraint = hswep_cbox_get_constraint,
+ .put_constraint = snbep_cbox_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 4,
+ .num_boxes = 18,
+ .perf_ctr_bits = 48,
+ .event_ctl = HSWEP_C0_MSR_PMON_CTL0,
+ .perf_ctr = HSWEP_C0_MSR_PMON_CTR0,
+ .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL,
+ .msr_offset = HSWEP_CBO_MSR_OFFSET,
+ .num_shared_regs = 1,
+ .constraints = hswep_uncore_cbox_constraints,
+ .ops = &hswep_uncore_cbox_ops,
+ .format_group = &hswep_uncore_cbox_format_group,
+};
+
+/*
+ * Write SBOX Initialization register bit by bit to avoid spurious #GPs
+ */
+static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+
+ if (msr) {
+ u64 init = SNBEP_PMON_BOX_CTL_INT;
+ u64 flags = 0;
+ int i;
+
+ for_each_set_bit(i, (unsigned long *)&init, 64) {
+ flags |= (1ULL << i);
+ wrmsrl(msr, flags);
+ }
+ }
+}
+
+static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
+ __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .init_box = hswep_uncore_sbox_msr_init_box
+};
+
+static struct attribute *hswep_uncore_sbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_tid_en.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute_group hswep_uncore_sbox_format_group = {
+ .name = "format",
+ .attrs = hswep_uncore_sbox_formats_attr,
+};
+
+static struct intel_uncore_type hswep_uncore_sbox = {
+ .name = "sbox",
+ .num_counters = 4,
+ .num_boxes = 4,
+ .perf_ctr_bits = 44,
+ .event_ctl = HSWEP_S0_MSR_PMON_CTL0,
+ .perf_ctr = HSWEP_S0_MSR_PMON_CTR0,
+ .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL,
+ .msr_offset = HSWEP_SBOX_MSR_OFFSET,
+ .ops = &hswep_uncore_sbox_msr_ops,
+ .format_group = &hswep_uncore_sbox_format_group,
+};
+
+static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
+
+ if (ev_sel >= 0xb && ev_sel <= 0xe) {
+ reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
+ reg1->idx = ev_sel - 0xb;
+ reg1->config = event->attr.config1 & (0xff << reg1->idx);
+ }
+ return 0;
+}
+
+static struct intel_uncore_ops hswep_uncore_pcu_ops = {
+ SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+ .hw_config = hswep_pcu_hw_config,
+ .get_constraint = snbep_pcu_get_constraint,
+ .put_constraint = snbep_pcu_put_constraint,
+};
+
+static struct intel_uncore_type hswep_uncore_pcu = {
+ .name = "pcu",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = HSWEP_PCU_MSR_PMON_CTR0,
+ .event_ctl = HSWEP_PCU_MSR_PMON_CTL0,
+ .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_PCU_MSR_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &hswep_uncore_pcu_ops,
+ .format_group = &snbep_uncore_pcu_format_group,
+};
+
+static struct intel_uncore_type *hswep_msr_uncores[] = {
+ &hswep_uncore_ubox,
+ &hswep_uncore_cbox,
+ &hswep_uncore_sbox,
+ &hswep_uncore_pcu,
+ NULL,
+};
+
+void hswep_uncore_cpu_init(void)
+{
+ int pkg = topology_phys_to_logical_pkg(0);
+
+ if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+
+ /* Detect 6-8 core systems with only two SBOXes */
+ if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
+ u32 capid4;
+
+ pci_read_config_dword(uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3],
+ 0x94, &capid4);
+ if (((capid4 >> 6) & 0x3) == 0)
+ hswep_uncore_sbox.num_boxes = 2;
+ }
+
+ uncore_msr_uncores = hswep_msr_uncores;
+}
+
+static struct intel_uncore_type hswep_uncore_ha = {
+ .name = "ha",
+ .num_counters = 5,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct uncore_event_desc hswep_uncore_imc_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x00,umask=0x00"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
+ INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type hswep_uncore_imc = {
+ .name = "imc",
+ .num_counters = 5,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+ .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+ .event_descs = hswep_uncore_imc_events,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
+
+static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ struct hw_perf_event *hwc = &event->hw;
+ u64 count = 0;
+
+ pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+ pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+ return count;
+}
+
+static struct intel_uncore_ops hswep_uncore_irp_ops = {
+ .init_box = snbep_uncore_pci_init_box,
+ .disable_box = snbep_uncore_pci_disable_box,
+ .enable_box = snbep_uncore_pci_enable_box,
+ .disable_event = ivbep_uncore_irp_disable_event,
+ .enable_event = ivbep_uncore_irp_enable_event,
+ .read_counter = hswep_uncore_irp_read_counter,
+};
+
+static struct intel_uncore_type hswep_uncore_irp = {
+ .name = "irp",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .ops = &hswep_uncore_irp_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type hswep_uncore_qpi = {
+ .name = "qpi",
+ .num_counters = 5,
+ .num_boxes = 3,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &snbep_uncore_qpi_ops,
+ .format_group = &snbep_uncore_qpi_format_group,
+};
+
+static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type hswep_uncore_r2pcie = {
+ .name = "r2pcie",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .constraints = hswep_uncore_r2pcie_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type hswep_uncore_r3qpi = {
+ .name = "r3qpi",
+ .num_counters = 4,
+ .num_boxes = 3,
+ .perf_ctr_bits = 44,
+ .constraints = hswep_uncore_r3qpi_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+ HSWEP_PCI_UNCORE_HA,
+ HSWEP_PCI_UNCORE_IMC,
+ HSWEP_PCI_UNCORE_IRP,
+ HSWEP_PCI_UNCORE_QPI,
+ HSWEP_PCI_UNCORE_R2PCIE,
+ HSWEP_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *hswep_pci_uncores[] = {
+ [HSWEP_PCI_UNCORE_HA] = &hswep_uncore_ha,
+ [HSWEP_PCI_UNCORE_IMC] = &hswep_uncore_imc,
+ [HSWEP_PCI_UNCORE_IRP] = &hswep_uncore_irp,
+ [HSWEP_PCI_UNCORE_QPI] = &hswep_uncore_qpi,
+ [HSWEP_PCI_UNCORE_R2PCIE] = &hswep_uncore_r2pcie,
+ [HSWEP_PCI_UNCORE_R3QPI] = &hswep_uncore_r3qpi,
+ NULL,
+};
+
+static const struct pci_device_id hswep_uncore_pci_ids[] = {
+ { /* Home Agent 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
+ },
+ { /* Home Agent 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
+ },
+ { /* MC0 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
+ },
+ { /* MC0 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
+ },
+ { /* MC0 Channel 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
+ },
+ { /* MC0 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
+ },
+ { /* MC1 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
+ },
+ { /* MC1 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
+ },
+ { /* MC1 Channel 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
+ },
+ { /* MC1 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
+ },
+ { /* IRP */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
+ },
+ { /* QPI0 Port 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
+ },
+ { /* QPI0 Port 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
+ },
+ { /* QPI1 Port 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
+ },
+ { /* R2PCIe */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
+ },
+ { /* R3QPI0 Link 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
+ },
+ { /* R3QPI0 Link 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
+ },
+ { /* R3QPI1 Link 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
+ .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT0_FILTER),
+ },
+ { /* QPI Port 1 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ SNBEP_PCI_QPI_PORT1_FILTER),
+ },
+ { /* PCU.3 (for Capability registers) */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+ HSWEP_PCI_PCU_3),
+ },
+ { /* end: all zeroes */ }
+};
+
+static struct pci_driver hswep_uncore_pci_driver = {
+ .name = "hswep_uncore",
+ .id_table = hswep_uncore_pci_ids,
+};
+
+int hswep_uncore_pci_init(void)
+{
+ int ret = snbep_pci2phy_map_init(0x2f1e);
+ if (ret)
+ return ret;
+ uncore_pci_uncores = hswep_pci_uncores;
+ uncore_pci_driver = &hswep_uncore_pci_driver;
+ return 0;
+}
+/* end of Haswell-EP uncore support */
+
+/* BDX uncore support */
+
+static struct intel_uncore_type bdx_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .perf_ctr = HSWEP_U_MSR_PMON_CTR0,
+ .event_ctl = HSWEP_U_MSR_PMON_CTL0,
+ .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
+ .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
+ .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
+ .num_shared_regs = 1,
+ .ops = &ivbep_uncore_msr_ops,
+ .format_group = &ivbep_uncore_ubox_format_group,
+};
+
+static struct event_constraint bdx_uncore_cbox_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 4,
+ .num_boxes = 24,
+ .perf_ctr_bits = 48,
+ .event_ctl = HSWEP_C0_MSR_PMON_CTL0,
+ .perf_ctr = HSWEP_C0_MSR_PMON_CTR0,
+ .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL,
+ .msr_offset = HSWEP_CBO_MSR_OFFSET,
+ .num_shared_regs = 1,
+ .constraints = bdx_uncore_cbox_constraints,
+ .ops = &hswep_uncore_cbox_ops,
+ .format_group = &hswep_uncore_cbox_format_group,
+};
+
+static struct intel_uncore_type bdx_uncore_sbox = {
+ .name = "sbox",
+ .num_counters = 4,
+ .num_boxes = 4,
+ .perf_ctr_bits = 48,
+ .event_ctl = HSWEP_S0_MSR_PMON_CTL0,
+ .perf_ctr = HSWEP_S0_MSR_PMON_CTR0,
+ .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+ .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL,
+ .msr_offset = HSWEP_SBOX_MSR_OFFSET,
+ .ops = &hswep_uncore_sbox_msr_ops,
+ .format_group = &hswep_uncore_sbox_format_group,
+};
+
+#define BDX_MSR_UNCORE_SBOX 3
+
+static struct intel_uncore_type *bdx_msr_uncores[] = {
+ &bdx_uncore_ubox,
+ &bdx_uncore_cbox,
+ &hswep_uncore_pcu,
+ &bdx_uncore_sbox,
+ NULL,
+};
+
+void bdx_uncore_cpu_init(void)
+{
+ if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+ bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ uncore_msr_uncores = bdx_msr_uncores;
+
+ /* BDX-DE doesn't have SBOX */
+ if (boot_cpu_data.x86_model == 86)
+ uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
+}
+
+static struct intel_uncore_type bdx_uncore_ha = {
+ .name = "ha",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type bdx_uncore_imc = {
+ .name = "imc",
+ .num_counters = 5,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
+ .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
+ .event_descs = hswep_uncore_imc_events,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct intel_uncore_type bdx_uncore_irp = {
+ .name = "irp",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .ops = &hswep_uncore_irp_ops,
+ .format_group = &snbep_uncore_format_group,
+};
+
+static struct intel_uncore_type bdx_uncore_qpi = {
+ .name = "qpi",
+ .num_counters = 4,
+ .num_boxes = 3,
+ .perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .num_shared_regs = 1,
+ .ops = &snbep_uncore_qpi_ops,
+ .format_group = &snbep_uncore_qpi_format_group,
+};
+
+static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_r2pcie = {
+ .name = "r2pcie",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .constraints = bdx_uncore_r2pcie_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type bdx_uncore_r3qpi = {
+ .name = "r3qpi",
+ .num_counters = 3,
+ .num_boxes = 3,
+ .perf_ctr_bits = 48,
+ .constraints = bdx_uncore_r3qpi_constraints,
+ SNBEP_UNCORE_PCI_COMMON_INIT(),
+};
+
+enum {
+ BDX_PCI_UNCORE_HA,
+ BDX_PCI_UNCORE_IMC,
+ BDX_PCI_UNCORE_IRP,
+ BDX_PCI_UNCORE_QPI,
+ BDX_PCI_UNCORE_R2PCIE,
+ BDX_PCI_UNCORE_R3QPI,
+};
+
+static struct intel_uncore_type *bdx_pci_uncores[] = {
+ [BDX_PCI_UNCORE_HA] = &bdx_uncore_ha,
+ [BDX_PCI_UNCORE_IMC] = &bdx_uncore_imc,
+ [BDX_PCI_UNCORE_IRP] = &bdx_uncore_irp,
+ [BDX_PCI_UNCORE_QPI] = &bdx_uncore_qpi,
+ [BDX_PCI_UNCORE_R2PCIE] = &bdx_uncore_r2pcie,
+ [BDX_PCI_UNCORE_R3QPI] = &bdx_uncore_r3qpi,
+ NULL,
+};
+
+static const struct pci_device_id bdx_uncore_pci_ids[] = {
+ { /* Home Agent 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
+ },
+ { /* Home Agent 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f38),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 1),
+ },
+ { /* MC0 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
+ },
+ { /* MC0 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
+ },
+ { /* MC0 Channel 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb4),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 2),
+ },
+ { /* MC0 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb5),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 3),
+ },
+ { /* MC1 Channel 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd0),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 4),
+ },
+ { /* MC1 Channel 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd1),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 5),
+ },
+ { /* MC1 Channel 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd4),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 6),
+ },
+ { /* MC1 Channel 3 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd5),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 7),
+ },
+ { /* IRP */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
+ },
+ { /* QPI0 Port 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f32),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 0),
+ },
+ { /* QPI0 Port 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f33),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 1),
+ },
+ { /* QPI1 Port 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3a),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 2),
+ },
+ { /* R2PCIe */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
+ },
+ { /* R3QPI0 Link 0 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f36),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 0),
+ },
+ { /* R3QPI0 Link 1 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f37),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 1),
+ },
+ { /* R3QPI1 Link 2 */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3e),
+ .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 2),
+ },
+ { /* QPI Port 0 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f86),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 0),
+ },
+ { /* QPI Port 1 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f96),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 1),
+ },
+ { /* QPI Port 2 filter */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
+ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 2),
+ },
+ { /* end: all zeroes */ }
+};
+
+static struct pci_driver bdx_uncore_pci_driver = {
+ .name = "bdx_uncore",
+ .id_table = bdx_uncore_pci_ids,
+};
+
+int bdx_uncore_pci_init(void)
+{
+ int ret = snbep_pci2phy_map_init(0x6f1e);
+
+ if (ret)
+ return ret;
+ uncore_pci_uncores = bdx_pci_uncores;
+ uncore_pci_driver = &bdx_uncore_pci_driver;
+ return 0;
+}
+
+/* end of BDX uncore support */
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
new file mode 100644
index 0000000..ec863b9
--- /dev/null
+++ b/arch/x86/events/msr.c
@@ -0,0 +1,241 @@
+#include <linux/perf_event.h>
+
+enum perf_msr_id {
+ PERF_MSR_TSC = 0,
+ PERF_MSR_APERF = 1,
+ PERF_MSR_MPERF = 2,
+ PERF_MSR_PPERF = 3,
+ PERF_MSR_SMI = 4,
+
+ PERF_MSR_EVENT_MAX,
+};
+
+static bool test_aperfmperf(int idx)
+{
+ return boot_cpu_has(X86_FEATURE_APERFMPERF);
+}
+
+static bool test_intel(int idx)
+{
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+ boot_cpu_data.x86 != 6)
+ return false;
+
+ switch (boot_cpu_data.x86_model) {
+ case 30: /* 45nm Nehalem */
+ case 26: /* 45nm Nehalem-EP */
+ case 46: /* 45nm Nehalem-EX */
+
+ case 37: /* 32nm Westmere */
+ case 44: /* 32nm Westmere-EP */
+ case 47: /* 32nm Westmere-EX */
+
+ case 42: /* 32nm SandyBridge */
+ case 45: /* 32nm SandyBridge-E/EN/EP */
+
+ case 58: /* 22nm IvyBridge */
+ case 62: /* 22nm IvyBridge-EP/EX */
+
+ case 60: /* 22nm Haswell Core */
+ case 63: /* 22nm Haswell Server */
+ case 69: /* 22nm Haswell ULT */
+ case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
+
+ case 61: /* 14nm Broadwell Core-M */
+ case 86: /* 14nm Broadwell Xeon D */
+ case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
+ case 79: /* 14nm Broadwell Server */
+
+ case 55: /* 22nm Atom "Silvermont" */
+ case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
+ case 76: /* 14nm Atom "Airmont" */
+ if (idx == PERF_MSR_SMI)
+ return true;
+ break;
+
+ case 78: /* 14nm Skylake Mobile */
+ case 94: /* 14nm Skylake Desktop */
+ if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+struct perf_msr {
+ u64 msr;
+ struct perf_pmu_events_attr *attr;
+ bool (*test)(int idx);
+};
+
+PMU_EVENT_ATTR_STRING(tsc, evattr_tsc, "event=0x00");
+PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
+PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
+PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
+PMU_EVENT_ATTR_STRING(smi, evattr_smi, "event=0x04");
+
+static struct perf_msr msr[] = {
+ [PERF_MSR_TSC] = { 0, &evattr_tsc, NULL, },
+ [PERF_MSR_APERF] = { MSR_IA32_APERF, &evattr_aperf, test_aperfmperf, },
+ [PERF_MSR_MPERF] = { MSR_IA32_MPERF, &evattr_mperf, test_aperfmperf, },
+ [PERF_MSR_PPERF] = { MSR_PPERF, &evattr_pperf, test_intel, },
+ [PERF_MSR_SMI] = { MSR_SMI_COUNT, &evattr_smi, test_intel, },
+};
+
+static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
+ NULL,
+};
+
+static struct attribute_group events_attr_group = {
+ .name = "events",
+ .attrs = events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-63");
+static struct attribute *format_attrs[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+static struct attribute_group format_attr_group = {
+ .name = "format",
+ .attrs = format_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+ &events_attr_group,
+ &format_attr_group,
+ NULL,
+};
+
+static int msr_event_init(struct perf_event *event)
+{
+ u64 cfg = event->attr.config;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ if (cfg >= PERF_MSR_EVENT_MAX)
+ return -EINVAL;
+
+ /* unsupported modes and filters */
+ if (event->attr.exclude_user ||
+ event->attr.exclude_kernel ||
+ event->attr.exclude_hv ||
+ event->attr.exclude_idle ||
+ event->attr.exclude_host ||
+ event->attr.exclude_guest ||
+ event->attr.sample_period) /* no sampling */
+ return -EINVAL;
+
+ if (!msr[cfg].attr)
+ return -EINVAL;
+
+ event->hw.idx = -1;
+ event->hw.event_base = msr[cfg].msr;
+ event->hw.config = cfg;
+
+ return 0;
+}
+
+static inline u64 msr_read_counter(struct perf_event *event)
+{
+ u64 now;
+
+ if (event->hw.event_base)
+ rdmsrl(event->hw.event_base, now);
+ else
+ rdtscll(now);
+
+ return now;
+}
+static void msr_event_update(struct perf_event *event)
+{
+ u64 prev, now;
+ s64 delta;
+
+ /* Careful, an NMI might modify the previous event value. */
+again:
+ prev = local64_read(&event->hw.prev_count);
+ now = msr_read_counter(event);
+
+ if (local64_cmpxchg(&event->hw.prev_count, prev, now) != prev)
+ goto again;
+
+ delta = now - prev;
+ if (unlikely(event->hw.event_base == MSR_SMI_COUNT))
+ delta = sign_extend64(delta, 31);
+
+ local64_add(now - prev, &event->count);
+}
+
+static void msr_event_start(struct perf_event *event, int flags)
+{
+ u64 now;
+
+ now = msr_read_counter(event);
+ local64_set(&event->hw.prev_count, now);
+}
+
+static void msr_event_stop(struct perf_event *event, int flags)
+{
+ msr_event_update(event);
+}
+
+static void msr_event_del(struct perf_event *event, int flags)
+{
+ msr_event_stop(event, PERF_EF_UPDATE);
+}
+
+static int msr_event_add(struct perf_event *event, int flags)
+{
+ if (flags & PERF_EF_START)
+ msr_event_start(event, flags);
+
+ return 0;
+}
+
+static struct pmu pmu_msr = {
+ .task_ctx_nr = perf_sw_context,
+ .attr_groups = attr_groups,
+ .event_init = msr_event_init,
+ .add = msr_event_add,
+ .del = msr_event_del,
+ .start = msr_event_start,
+ .stop = msr_event_stop,
+ .read = msr_event_update,
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
+};
+
+static int __init msr_init(void)
+{
+ int i, j = 0;
+
+ if (!boot_cpu_has(X86_FEATURE_TSC)) {
+ pr_cont("no MSR PMU driver.\n");
+ return 0;
+ }
+
+ /* Probe the MSRs. */
+ for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
+ u64 val;
+
+ /*
+ * Virt sucks arse; you cannot tell if a R/O MSR is present :/
+ */
+ if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
+ msr[i].attr = NULL;
+ }
+
+ /* List remaining MSRs in the sysfs attrs. */
+ for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
+ if (msr[i].attr)
+ events_attrs[j++] = &msr[i].attr->attr.attr;
+ }
+ events_attrs[j] = NULL;
+
+ perf_pmu_register(&pmu_msr, "msr", -1);
+
+ return 0;
+}
+device_initcall(msr_init);
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
new file mode 100644
index 0000000..68155ca
--- /dev/null
+++ b/arch/x86/events/perf_event.h
@@ -0,0 +1,960 @@
+/*
+ * Performance events x86 architecture header
+ *
+ * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ * Copyright (C) 2009 Jaswinder Singh Rajput
+ * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
+ * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ * Copyright (C) 2009 Google, Inc., Stephane Eranian
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+
+/* To enable MSR tracing please use the generic trace points. */
+
+/*
+ * | NHM/WSM | SNB |
+ * register -------------------------------
+ * | HT | no HT | HT | no HT |
+ *-----------------------------------------
+ * offcore | core | core | cpu | core |
+ * lbr_sel | core | core | cpu | core |
+ * ld_lat | cpu | core | cpu | core |
+ *-----------------------------------------
+ *
+ * Given that there is a small number of shared regs,
+ * we can pre-allocate their slot in the per-cpu
+ * per-core reg tables.
+ */
+enum extra_reg_type {
+ EXTRA_REG_NONE = -1, /* not used */
+
+ EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */
+ EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */
+ EXTRA_REG_LBR = 2, /* lbr_select */
+ EXTRA_REG_LDLAT = 3, /* ld_lat_threshold */
+ EXTRA_REG_FE = 4, /* fe_* */
+
+ EXTRA_REG_MAX /* number of entries needed */
+};
+
+struct event_constraint {
+ union {
+ unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ u64 idxmsk64;
+ };
+ u64 code;
+ u64 cmask;
+ int weight;
+ int overlap;
+ int flags;
+};
+/*
+ * struct hw_perf_event.flags flags
+ */
+#define PERF_X86_EVENT_PEBS_LDLAT 0x0001 /* ld+ldlat data address sampling */
+#define PERF_X86_EVENT_PEBS_ST 0x0002 /* st data address sampling */
+#define PERF_X86_EVENT_PEBS_ST_HSW 0x0004 /* haswell style datala, store */
+#define PERF_X86_EVENT_COMMITTED 0x0008 /* event passed commit_txn */
+#define PERF_X86_EVENT_PEBS_LD_HSW 0x0010 /* haswell style datala, load */
+#define PERF_X86_EVENT_PEBS_NA_HSW 0x0020 /* haswell style datala, unknown */
+#define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */
+#define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */
+#define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */
+#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */
+#define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */
+#define PERF_X86_EVENT_FREERUNNING 0x0800 /* use freerunning PEBS */
+
+
+struct amd_nb {
+ int nb_id; /* NorthBridge id */
+ int refcnt; /* reference count */
+ struct perf_event *owners[X86_PMC_IDX_MAX];
+ struct event_constraint event_constraints[X86_PMC_IDX_MAX];
+};
+
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS 8
+
+/*
+ * Flags PEBS can handle without an PMI.
+ *
+ * TID can only be handled by flushing at context switch.
+ *
+ */
+#define PEBS_FREERUNNING_FLAGS \
+ (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
+ PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
+ PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
+ PERF_SAMPLE_TRANSACTION)
+
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+ u64 bts_buffer_base;
+ u64 bts_index;
+ u64 bts_absolute_maximum;
+ u64 bts_interrupt_threshold;
+ u64 pebs_buffer_base;
+ u64 pebs_index;
+ u64 pebs_absolute_maximum;
+ u64 pebs_interrupt_threshold;
+ u64 pebs_event_reset[MAX_PEBS_EVENTS];
+};
+
+/*
+ * Per register state.
+ */
+struct er_account {
+ raw_spinlock_t lock; /* per-core: protect structure */
+ u64 config; /* extra MSR config */
+ u64 reg; /* extra MSR number */
+ atomic_t ref; /* reference count */
+};
+
+/*
+ * Per core/cpu state
+ *
+ * Used to coordinate shared registers between HT threads or
+ * among events on a single PMU.
+ */
+struct intel_shared_regs {
+ struct er_account regs[EXTRA_REG_MAX];
+ int refcnt; /* per-core: #HT threads */
+ unsigned core_id; /* per-core: core id */
+};
+
+enum intel_excl_state_type {
+ INTEL_EXCL_UNUSED = 0, /* counter is unused */
+ INTEL_EXCL_SHARED = 1, /* counter can be used by both threads */
+ INTEL_EXCL_EXCLUSIVE = 2, /* counter can be used by one thread only */
+};
+
+struct intel_excl_states {
+ enum intel_excl_state_type state[X86_PMC_IDX_MAX];
+ bool sched_started; /* true if scheduling has started */
+};
+
+struct intel_excl_cntrs {
+ raw_spinlock_t lock;
+
+ struct intel_excl_states states[2];
+
+ union {
+ u16 has_exclusive[2];
+ u32 exclusive_present;
+ };
+
+ int refcnt; /* per-core: #HT threads */
+ unsigned core_id; /* per-core: core id */
+};
+
+#define MAX_LBR_ENTRIES 32
+
+enum {
+ X86_PERF_KFREE_SHARED = 0,
+ X86_PERF_KFREE_EXCL = 1,
+ X86_PERF_KFREE_MAX
+};
+
+struct cpu_hw_events {
+ /*
+ * Generic x86 PMC bits
+ */
+ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
+ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ int enabled;
+
+ int n_events; /* the # of events in the below arrays */
+ int n_added; /* the # last events in the below arrays;
+ they've never been enabled yet */
+ int n_txn; /* the # last events in the below arrays;
+ added in the current transaction */
+ int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
+ u64 tags[X86_PMC_IDX_MAX];
+
+ struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
+ struct event_constraint *event_constraint[X86_PMC_IDX_MAX];
+
+ int n_excl; /* the number of exclusive events */
+
+ unsigned int txn_flags;
+ int is_fake;
+
+ /*
+ * Intel DebugStore bits
+ */
+ struct debug_store *ds;
+ u64 pebs_enabled;
+
+ /*
+ * Intel LBR bits
+ */
+ int lbr_users;
+ void *lbr_context;
+ struct perf_branch_stack lbr_stack;
+ struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
+ struct er_account *lbr_sel;
+ u64 br_sel;
+
+ /*
+ * Intel host/guest exclude bits
+ */
+ u64 intel_ctrl_guest_mask;
+ u64 intel_ctrl_host_mask;
+ struct perf_guest_switch_msr guest_switch_msrs[X86_PMC_IDX_MAX];
+
+ /*
+ * Intel checkpoint mask
+ */
+ u64 intel_cp_status;
+
+ /*
+ * manage shared (per-core, per-cpu) registers
+ * used on Intel NHM/WSM/SNB
+ */
+ struct intel_shared_regs *shared_regs;
+ /*
+ * manage exclusive counter access between hyperthread
+ */
+ struct event_constraint *constraint_list; /* in enable order */
+ struct intel_excl_cntrs *excl_cntrs;
+ int excl_thread_id; /* 0 or 1 */
+
+ /*
+ * AMD specific bits
+ */
+ struct amd_nb *amd_nb;
+ /* Inverted mask of bits to clear in the perf_ctr ctrl registers */
+ u64 perf_ctr_virt_mask;
+
+ void *kfree_on_online[X86_PERF_KFREE_MAX];
+};
+
+#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
+ { .idxmsk64 = (n) }, \
+ .code = (c), \
+ .cmask = (m), \
+ .weight = (w), \
+ .overlap = (o), \
+ .flags = f, \
+}
+
+#define EVENT_CONSTRAINT(c, n, m) \
+ __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
+
+#define INTEL_EXCLEVT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT, HWEIGHT(n),\
+ 0, PERF_X86_EVENT_EXCL)
+
+/*
+ * The overlap flag marks event constraints with overlapping counter
+ * masks. This is the case if the counter mask of such an event is not
+ * a subset of any other counter mask of a constraint with an equal or
+ * higher weight, e.g.:
+ *
+ * c_overlaps = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
+ * c_another1 = EVENT_CONSTRAINT(0, 0x07, 0);
+ * c_another2 = EVENT_CONSTRAINT(0, 0x38, 0);
+ *
+ * The event scheduler may not select the correct counter in the first
+ * cycle because it needs to know which subsequent events will be
+ * scheduled. It may fail to schedule the events then. So we set the
+ * overlap flag for such constraints to give the scheduler a hint which
+ * events to select for counter rescheduling.
+ *
+ * Care must be taken as the rescheduling algorithm is O(n!) which
+ * will increase scheduling cycles for an over-commited system
+ * dramatically. The number of such EVENT_CONSTRAINT_OVERLAP() macros
+ * and its counter masks must be kept at a minimum.
+ */
+#define EVENT_CONSTRAINT_OVERLAP(c, n, m) \
+ __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)
+
+/*
+ * Constraint on the Event code.
+ */
+#define INTEL_EVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
+
+/*
+ * Constraint on the Event code + UMask + fixed-mask
+ *
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ * - inv
+ * - edge
+ * - cnt-mask
+ * - in_tx
+ * - in_tx_checkpointed
+ * The other filters are supported by fixed counters.
+ * The any-thread option is supported starting with v3.
+ */
+#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
+#define FIXED_EVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
+
+/*
+ * Constraint on the Event code + UMask
+ */
+#define INTEL_UEVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
+
+/* Constraint on specific umask bit only + event */
+#define INTEL_UBIT_EVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT|(c))
+
+/* Like UEVENT_CONSTRAINT, but match flags too */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+
+#define INTEL_EXCLUEVT_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_EXCL)
+
+#define INTEL_PLD_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT)
+
+#define INTEL_PST_CONSTRAINT(c, n) \
+ __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
+
+/* Event constraint, but match on all event flags too. */
+#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
+ EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+
+/* Check only flags, but allow all event/umask */
+#define INTEL_ALL_EVENT_CONSTRAINT(code, n) \
+ EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS)
+
+/* Check flags and event code, and set the HSW store flag */
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_ST(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
+
+/* Check flags and event code, and set the HSW load flag */
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, \
+ PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW store flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
+
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, \
+ PERF_X86_EVENT_PEBS_ST_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW load flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
+
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, \
+ PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
+
+/* Check flags and event code/umask, and set the HSW N/A flag */
+#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \
+ __EVENT_CONSTRAINT(code, n, \
+ INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
+ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW)
+
+
+/*
+ * We define the end marker as having a weight of -1
+ * to enable blacklisting of events using a counter bitmask
+ * of zero and thus a weight of zero.
+ * The end marker has a weight that cannot possibly be
+ * obtained from counting the bits in the bitmask.
+ */
+#define EVENT_CONSTRAINT_END { .weight = -1 }
+
+/*
+ * Check for end marker with weight == -1
+ */
+#define for_each_event_constraint(e, c) \
+ for ((e) = (c); (e)->weight != -1; (e)++)
+
+/*
+ * Extra registers for specific events.
+ *
+ * Some events need large masks and require external MSRs.
+ * Those extra MSRs end up being shared for all events on
+ * a PMU and sometimes between PMU of sibling HT threads.
+ * In either case, the kernel needs to handle conflicting
+ * accesses to those extra, shared, regs. The data structure
+ * to manage those registers is stored in cpu_hw_event.
+ */
+struct extra_reg {
+ unsigned int event;
+ unsigned int msr;
+ u64 config_mask;
+ u64 valid_mask;
+ int idx; /* per_xxx->regs[] reg index */
+ bool extra_msr_access;
+};
+
+#define EVENT_EXTRA_REG(e, ms, m, vm, i) { \
+ .event = (e), \
+ .msr = (ms), \
+ .config_mask = (m), \
+ .valid_mask = (vm), \
+ .idx = EXTRA_REG_##i, \
+ .extra_msr_access = true, \
+ }
+
+#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \
+ EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
+
+#define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \
+ EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
+ ARCH_PERFMON_EVENTSEL_UMASK, vm, idx)
+
+#define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \
+ INTEL_UEVENT_EXTRA_REG(c, \
+ MSR_PEBS_LD_LAT_THRESHOLD, \
+ 0xffff, \
+ LDLAT)
+
+#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
+
+union perf_capabilities {
+ struct {
+ u64 lbr_format:6;
+ u64 pebs_trap:1;
+ u64 pebs_arch_reg:1;
+ u64 pebs_format:4;
+ u64 smm_freeze:1;
+ /*
+ * PMU supports separate counter range for writing
+ * values > 32bit.
+ */
+ u64 full_width_write:1;
+ };
+ u64 capabilities;
+};
+
+struct x86_pmu_quirk {
+ struct x86_pmu_quirk *next;
+ void (*func)(void);
+};
+
+union x86_pmu_config {
+ struct {
+ u64 event:8,
+ umask:8,
+ usr:1,
+ os:1,
+ edge:1,
+ pc:1,
+ interrupt:1,
+ __reserved1:1,
+ en:1,
+ inv:1,
+ cmask:8,
+ event2:4,
+ __reserved2:4,
+ go:1,
+ ho:1;
+ } bits;
+ u64 value;
+};
+
+#define X86_CONFIG(args...) ((union x86_pmu_config){.bits = {args}}).value
+
+enum {
+ x86_lbr_exclusive_lbr,
+ x86_lbr_exclusive_bts,
+ x86_lbr_exclusive_pt,
+ x86_lbr_exclusive_max,
+};
+
+/*
+ * struct x86_pmu - generic x86 pmu
+ */
+struct x86_pmu {
+ /*
+ * Generic x86 PMC bits
+ */
+ const char *name;
+ int version;
+ int (*handle_irq)(struct pt_regs *);
+ void (*disable_all)(void);
+ void (*enable_all)(int added);
+ void (*enable)(struct perf_event *);
+ void (*disable)(struct perf_event *);
+ int (*hw_config)(struct perf_event *event);
+ int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
+ unsigned eventsel;
+ unsigned perfctr;
+ int (*addr_offset)(int index, bool eventsel);
+ int (*rdpmc_index)(int index);
+ u64 (*event_map)(int);
+ int max_events;
+ int num_counters;
+ int num_counters_fixed;
+ int cntval_bits;
+ u64 cntval_mask;
+ union {
+ unsigned long events_maskl;
+ unsigned long events_mask[BITS_TO_LONGS(ARCH_PERFMON_EVENTS_COUNT)];
+ };
+ int events_mask_len;
+ int apic;
+ u64 max_period;
+ struct event_constraint *
+ (*get_event_constraints)(struct cpu_hw_events *cpuc,
+ int idx,
+ struct perf_event *event);
+
+ void (*put_event_constraints)(struct cpu_hw_events *cpuc,
+ struct perf_event *event);
+
+ void (*start_scheduling)(struct cpu_hw_events *cpuc);
+
+ void (*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr);
+
+ void (*stop_scheduling)(struct cpu_hw_events *cpuc);
+
+ struct event_constraint *event_constraints;
+ struct x86_pmu_quirk *quirks;
+ int perfctr_second_write;
+ bool late_ack;
+ unsigned (*limit_period)(struct perf_event *event, unsigned l);
+
+ /*
+ * sysfs attrs
+ */
+ int attr_rdpmc_broken;
+ int attr_rdpmc;
+ struct attribute **format_attrs;
+ struct attribute **event_attrs;
+
+ ssize_t (*events_sysfs_show)(char *page, u64 config);
+ struct attribute **cpu_events;
+
+ /*
+ * CPU Hotplug hooks
+ */
+ int (*cpu_prepare)(int cpu);
+ void (*cpu_starting)(int cpu);
+ void (*cpu_dying)(int cpu);
+ void (*cpu_dead)(int cpu);
+
+ void (*check_microcode)(void);
+ void (*sched_task)(struct perf_event_context *ctx,
+ bool sched_in);
+
+ /*
+ * Intel Arch Perfmon v2+
+ */
+ u64 intel_ctrl;
+ union perf_capabilities intel_cap;
+
+ /*
+ * Intel DebugStore bits
+ */
+ unsigned int bts :1,
+ bts_active :1,
+ pebs :1,
+ pebs_active :1,
+ pebs_broken :1,
+ pebs_prec_dist :1;
+ int pebs_record_size;
+ int pebs_buffer_size;
+ void (*drain_pebs)(struct pt_regs *regs);
+ struct event_constraint *pebs_constraints;
+ void (*pebs_aliases)(struct perf_event *event);
+ int max_pebs_events;
+ unsigned long free_running_flags;
+
+ /*
+ * Intel LBR
+ */
+ unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
+ int lbr_nr; /* hardware stack size */
+ u64 lbr_sel_mask; /* LBR_SELECT valid bits */
+ const int *lbr_sel_map; /* lbr_select mappings */
+ bool lbr_double_abort; /* duplicated lbr aborts */
+
+ /*
+ * Intel PT/LBR/BTS are exclusive
+ */
+ atomic_t lbr_exclusive[x86_lbr_exclusive_max];
+
+ /*
+ * Extra registers for events
+ */
+ struct extra_reg *extra_regs;
+ unsigned int flags;
+
+ /*
+ * Intel host/guest support (KVM)
+ */
+ struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
+};
+
+struct x86_perf_task_context {
+ u64 lbr_from[MAX_LBR_ENTRIES];
+ u64 lbr_to[MAX_LBR_ENTRIES];
+ u64 lbr_info[MAX_LBR_ENTRIES];
+ int tos;
+ int lbr_callstack_users;
+ int lbr_stack_state;
+};
+
+#define x86_add_quirk(func_) \
+do { \
+ static struct x86_pmu_quirk __quirk __initdata = { \
+ .func = func_, \
+ }; \
+ __quirk.next = x86_pmu.quirks; \
+ x86_pmu.quirks = &__quirk; \
+} while (0)
+
+/*
+ * x86_pmu flags
+ */
+#define PMU_FL_NO_HT_SHARING 0x1 /* no hyper-threading resource sharing */
+#define PMU_FL_HAS_RSP_1 0x2 /* has 2 equivalent offcore_rsp regs */
+#define PMU_FL_EXCL_CNTRS 0x4 /* has exclusive counter requirements */
+#define PMU_FL_EXCL_ENABLED 0x8 /* exclusive counter active */
+
+#define EVENT_VAR(_id) event_attr_##_id
+#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
+
+#define EVENT_ATTR(_name, _id) \
+static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
+ .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
+ .id = PERF_COUNT_HW_##_id, \
+ .event_str = NULL, \
+};
+
+#define EVENT_ATTR_STR(_name, v, str) \
+static struct perf_pmu_events_attr event_attr_##v = { \
+ .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
+ .id = 0, \
+ .event_str = str, \
+};
+
+extern struct x86_pmu x86_pmu __read_mostly;
+
+static inline bool x86_pmu_has_lbr_callstack(void)
+{
+ return x86_pmu.lbr_sel_map &&
+ x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
+}
+
+DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+int x86_perf_event_set_period(struct perf_event *event);
+
+/*
+ * Generalized hw caching related hw_event table, filled
+ * in on a per model basis. A value of 0 means
+ * 'not supported', -1 means 'hw_event makes no sense on
+ * this CPU', any other value means the raw hw_event
+ * ID.
+ */
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+extern u64 __read_mostly hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+extern u64 __read_mostly hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+u64 x86_perf_event_update(struct perf_event *event);
+
+static inline unsigned int x86_pmu_config_addr(int index)
+{
+ return x86_pmu.eventsel + (x86_pmu.addr_offset ?
+ x86_pmu.addr_offset(index, true) : index);
+}
+
+static inline unsigned int x86_pmu_event_addr(int index)
+{
+ return x86_pmu.perfctr + (x86_pmu.addr_offset ?
+ x86_pmu.addr_offset(index, false) : index);
+}
+
+static inline int x86_pmu_rdpmc_index(int index)
+{
+ return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
+}
+
+int x86_add_exclusive(unsigned int what);
+
+void x86_del_exclusive(unsigned int what);
+
+int x86_reserve_hardware(void);
+
+void x86_release_hardware(void);
+
+void hw_perf_lbr_event_destroy(struct perf_event *event);
+
+int x86_setup_perfctr(struct perf_event *event);
+
+int x86_pmu_hw_config(struct perf_event *event);
+
+void x86_pmu_disable_all(void);
+
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
+ u64 enable_mask)
+{
+ u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
+
+ if (hwc->extra_reg.reg)
+ wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
+ wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
+}
+
+void x86_pmu_enable_all(int added);
+
+int perf_assign_events(struct event_constraint **constraints, int n,
+ int wmin, int wmax, int gpmax, int *assign);
+int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
+
+void x86_pmu_stop(struct perf_event *event, int flags);
+
+static inline void x86_pmu_disable_event(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ wrmsrl(hwc->config_base, hwc->config);
+}
+
+void x86_pmu_enable_event(struct perf_event *event);
+
+int x86_pmu_handle_irq(struct pt_regs *regs);
+
+extern struct event_constraint emptyconstraint;
+
+extern struct event_constraint unconstrained;
+
+static inline bool kernel_ip(unsigned long ip)
+{
+#ifdef CONFIG_X86_32
+ return ip > PAGE_OFFSET;
+#else
+ return (long)ip < 0;
+#endif
+}
+
+/*
+ * Not all PMUs provide the right context information to place the reported IP
+ * into full context. Specifically segment registers are typically not
+ * supplied.
+ *
+ * Assuming the address is a linear address (it is for IBS), we fake the CS and
+ * vm86 mode using the known zero-based code segment and 'fix up' the registers
+ * to reflect this.
+ *
+ * Intel PEBS/LBR appear to typically provide the effective address, nothing
+ * much we can do about that but pray and treat it like a linear address.
+ */
+static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
+{
+ regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
+ if (regs->flags & X86_VM_MASK)
+ regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
+ regs->ip = ip;
+}
+
+ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
+ssize_t intel_event_sysfs_show(char *page, u64 config);
+
+struct attribute **merge_attr(struct attribute **a, struct attribute **b);
+
+#ifdef CONFIG_CPU_SUP_AMD
+
+int amd_pmu_init(void);
+
+#else /* CONFIG_CPU_SUP_AMD */
+
+static inline int amd_pmu_init(void)
+{
+ return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_AMD */
+
+#ifdef CONFIG_CPU_SUP_INTEL
+
+static inline bool intel_pmu_has_bts(struct perf_event *event)
+{
+ if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+ !event->attr.freq && event->hw.sample_period == 1)
+ return true;
+
+ return false;
+}
+
+int intel_pmu_save_and_restart(struct perf_event *event);
+
+struct event_constraint *
+x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event);
+
+struct intel_shared_regs *allocate_shared_regs(int cpu);
+
+int intel_pmu_init(void);
+
+void init_debug_store_on_cpu(int cpu);
+
+void fini_debug_store_on_cpu(int cpu);
+
+void release_ds_buffers(void);
+
+void reserve_ds_buffers(void);
+
+extern struct event_constraint bts_constraint;
+
+void intel_pmu_enable_bts(u64 config);
+
+void intel_pmu_disable_bts(void);
+
+int intel_pmu_drain_bts_buffer(void);
+
+extern struct event_constraint intel_core2_pebs_event_constraints[];
+
+extern struct event_constraint intel_atom_pebs_event_constraints[];
+
+extern struct event_constraint intel_slm_pebs_event_constraints[];
+
+extern struct event_constraint intel_nehalem_pebs_event_constraints[];
+
+extern struct event_constraint intel_westmere_pebs_event_constraints[];
+
+extern struct event_constraint intel_snb_pebs_event_constraints[];
+
+extern struct event_constraint intel_ivb_pebs_event_constraints[];
+
+extern struct event_constraint intel_hsw_pebs_event_constraints[];
+
+extern struct event_constraint intel_bdw_pebs_event_constraints[];
+
+extern struct event_constraint intel_skl_pebs_event_constraints[];
+
+struct event_constraint *intel_pebs_constraints(struct perf_event *event);
+
+void intel_pmu_pebs_enable(struct perf_event *event);
+
+void intel_pmu_pebs_disable(struct perf_event *event);
+
+void intel_pmu_pebs_enable_all(void);
+
+void intel_pmu_pebs_disable_all(void);
+
+void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in);
+
+void intel_ds_init(void);
+
+void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
+
+void intel_pmu_lbr_reset(void);
+
+void intel_pmu_lbr_enable(struct perf_event *event);
+
+void intel_pmu_lbr_disable(struct perf_event *event);
+
+void intel_pmu_lbr_enable_all(bool pmi);
+
+void intel_pmu_lbr_disable_all(void);
+
+void intel_pmu_lbr_read(void);
+
+void intel_pmu_lbr_init_core(void);
+
+void intel_pmu_lbr_init_nhm(void);
+
+void intel_pmu_lbr_init_atom(void);
+
+void intel_pmu_lbr_init_snb(void);
+
+void intel_pmu_lbr_init_hsw(void);
+
+void intel_pmu_lbr_init_skl(void);
+
+void intel_pmu_lbr_init_knl(void);
+
+void intel_pmu_pebs_data_source_nhm(void);
+
+int intel_pmu_setup_lbr_filter(struct perf_event *event);
+
+void intel_pt_interrupt(void);
+
+int intel_bts_interrupt(void);
+
+void intel_bts_enable_local(void);
+
+void intel_bts_disable_local(void);
+
+int p4_pmu_init(void);
+
+int p6_pmu_init(void);
+
+int knc_pmu_init(void);
+
+ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
+ char *page);
+
+static inline int is_ht_workaround_enabled(void)
+{
+ return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
+}
+
+#else /* CONFIG_CPU_SUP_INTEL */
+
+static inline void reserve_ds_buffers(void)
+{
+}
+
+static inline void release_ds_buffers(void)
+{
+}
+
+static inline int intel_pmu_init(void)
+{
+ return 0;
+}
+
+static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
+{
+ return NULL;
+}
+
+static inline int is_ht_workaround_enabled(void)
+{
+ return 0;
+}
+#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index a0a19b7..0552884 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -26,7 +26,7 @@
#include <asm/ptrace.h>
#include <asm/ia32_unistd.h>
#include <asm/user32.h>
-#include <asm/sigcontext32.h>
+#include <uapi/asm/sigcontext.h>
#include <asm/proto.h>
#include <asm/vdso.h>
#include <asm/sigframe.h>
@@ -68,7 +68,7 @@
}
static int ia32_restore_sigcontext(struct pt_regs *regs,
- struct sigcontext_ia32 __user *sc)
+ struct sigcontext_32 __user *sc)
{
unsigned int tmpflags, err = 0;
void __user *buf;
@@ -170,7 +170,7 @@ badframe:
* Set up a signal frame.
*/
-static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
+static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc,
void __user *fpstate,
struct pt_regs *regs, unsigned int mask)
{
@@ -234,7 +234,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
unsigned long fx_aligned, math_size;
sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
- *fpstate = (struct _fpstate_ia32 __user *) sp;
+ *fpstate = (struct _fpstate_32 __user *) sp;
if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
math_size) < 0)
return (void __user *) -1L;
@@ -289,7 +289,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
/* Return stub is in 32bit vsyscall page */
if (current->mm->context.vdso)
restorer = current->mm->context.vdso +
- selected_vdso32->sym___kernel_sigreturn;
+ vdso_image_32.sym___kernel_sigreturn;
else
restorer = &frame->retcode;
}
@@ -368,7 +368,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
restorer = ksig->ka.sa.sa_restorer;
else
restorer = current->mm->context.vdso +
- selected_vdso32->sym___kernel_rt_sigreturn;
+ vdso_image_32.sym___kernel_rt_sigreturn;
put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
/*
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 3a45668..94c18eb 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -32,6 +32,10 @@
#include <asm/mpspec.h>
#include <asm/realmode.h>
+#ifdef CONFIG_ACPI_APEI
+# include <asm/pgtable_types.h>
+#endif
+
#ifdef CONFIG_ACPI
extern int acpi_lapic;
extern int acpi_ioapic;
@@ -147,4 +151,23 @@ extern int x86_acpi_numa_init(void);
#define acpi_unlazy_tlb(x) leave_mm(x)
+#ifdef CONFIG_ACPI_APEI
+static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
+{
+ /*
+ * We currently have no way to look up the EFI memory map
+ * attributes for a region in a consistent way, because the
+ * memmap is discarded after efi_free_boot_services(). So if
+ * you call efi_mem_attributes() during boot and at runtime,
+ * you could theoretically see different attributes.
+ *
+ * Since we are yet to see any x86 platforms that require
+ * anything other than PAGE_KERNEL (some arm64 platforms
+ * require the equivalent of PAGE_KERNEL_NOCACHE), return that
+ * until we know differently.
+ */
+ return PAGE_KERNEL;
+}
+#endif
+
#endif /* _ASM_X86_ACPI_H */
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 7bfc85b..99afb66 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -152,12 +152,6 @@ static inline int alternatives_text_reserved(void *start, void *end)
".popsection"
/*
- * This must be included *after* the definition of ALTERNATIVE due to
- * <asm/arch_hweight.h>
- */
-#include <asm/cpufeature.h>
-
-/*
* Alternative instructions for different CPU types or capabilities.
*
* This allows to use optimized instructions even on generic binary
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index 1a5da2e..5e828da 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -27,15 +27,23 @@ struct amd_l3_cache {
};
struct threshold_block {
- unsigned int block;
- unsigned int bank;
- unsigned int cpu;
- u32 address;
- u16 interrupt_enable;
- bool interrupt_capable;
- u16 threshold_limit;
- struct kobject kobj;
- struct list_head miscj;
+ unsigned int block; /* Number within bank */
+ unsigned int bank; /* MCA bank the block belongs to */
+ unsigned int cpu; /* CPU which controls MCA bank */
+ u32 address; /* MSR address for the block */
+ u16 interrupt_enable; /* Enable/Disable APIC interrupt */
+ bool interrupt_capable; /* Bank can generate an interrupt. */
+
+ u16 threshold_limit; /*
+ * Value upon which threshold
+ * interrupt is generated.
+ */
+
+ struct kobject kobj; /* sysfs object */
+ struct list_head miscj; /*
+ * List of threshold blocks
+ * within a bank.
+ */
};
struct threshold_bank {
@@ -81,7 +89,7 @@ static inline struct amd_northbridge *node_to_amd_nb(int node)
return (node < amd_northbridges.num) ? &amd_northbridges.nb[node] : NULL;
}
-static inline u16 amd_get_node_id(struct pci_dev *pdev)
+static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
{
struct pci_dev *misc;
int i;
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index ebf6d5e..0899cfc 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -6,7 +6,6 @@
#include <asm/alternative.h>
#include <asm/cpufeature.h>
-#include <asm/processor.h>
#include <asm/apicdef.h>
#include <linux/atomic.h>
#include <asm/fixmap.h>
@@ -23,6 +22,11 @@
#define APIC_VERBOSE 1
#define APIC_DEBUG 2
+/* Macros for apic_extnmi which controls external NMI masking */
+#define APIC_EXTNMI_BSP 0 /* Default */
+#define APIC_EXTNMI_ALL 1
+#define APIC_EXTNMI_NONE 2
+
/*
* Define the default level of output to be very little
* This can be turned up by using apic=verbose for more
@@ -115,6 +119,59 @@ static inline bool apic_is_x2apic_enabled(void)
return msr & X2APIC_ENABLE;
}
+extern void enable_IR_x2apic(void);
+
+extern int get_physical_broadcast(void);
+
+extern int lapic_get_maxlvt(void);
+extern void clear_local_APIC(void);
+extern void disconnect_bsp_APIC(int virt_wire_setup);
+extern void disable_local_APIC(void);
+extern void lapic_shutdown(void);
+extern void sync_Arb_IDs(void);
+extern void init_bsp_APIC(void);
+extern void setup_local_APIC(void);
+extern void init_apic_mappings(void);
+void register_lapic_address(unsigned long address);
+extern void setup_boot_APIC_clock(void);
+extern void setup_secondary_APIC_clock(void);
+extern int APIC_init_uniprocessor(void);
+
+#ifdef CONFIG_X86_64
+static inline int apic_force_enable(unsigned long addr)
+{
+ return -1;
+}
+#else
+extern int apic_force_enable(unsigned long addr);
+#endif
+
+extern int apic_bsp_setup(bool upmode);
+extern void apic_ap_setup(void);
+
+/*
+ * On 32bit this is mach-xxx local
+ */
+#ifdef CONFIG_X86_64
+extern int apic_is_clustered_box(void);
+#else
+static inline int apic_is_clustered_box(void)
+{
+ return 0;
+}
+#endif
+
+extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
+
+#else /* !CONFIG_X86_LOCAL_APIC */
+static inline void lapic_shutdown(void) { }
+#define local_apic_timer_c2_ok 1
+static inline void init_apic_mappings(void) { }
+static inline void disable_local_APIC(void) { }
+# define setup_boot_APIC_clock x86_init_noop
+# define setup_secondary_APIC_clock x86_init_noop
+#endif /* !CONFIG_X86_LOCAL_APIC */
+
#ifdef CONFIG_X86_X2APIC
/*
* Make previous memory operations globally visible before
@@ -186,67 +243,14 @@ static inline int x2apic_enabled(void)
}
#define x2apic_supported() (cpu_has_x2apic)
-#else
+#else /* !CONFIG_X86_X2APIC */
static inline void check_x2apic(void) { }
static inline void x2apic_setup(void) { }
static inline int x2apic_enabled(void) { return 0; }
#define x2apic_mode (0)
#define x2apic_supported() (0)
-#endif
-
-extern void enable_IR_x2apic(void);
-
-extern int get_physical_broadcast(void);
-
-extern int lapic_get_maxlvt(void);
-extern void clear_local_APIC(void);
-extern void disconnect_bsp_APIC(int virt_wire_setup);
-extern void disable_local_APIC(void);
-extern void lapic_shutdown(void);
-extern void sync_Arb_IDs(void);
-extern void init_bsp_APIC(void);
-extern void setup_local_APIC(void);
-extern void init_apic_mappings(void);
-void register_lapic_address(unsigned long address);
-extern void setup_boot_APIC_clock(void);
-extern void setup_secondary_APIC_clock(void);
-extern int APIC_init_uniprocessor(void);
-
-#ifdef CONFIG_X86_64
-static inline int apic_force_enable(unsigned long addr)
-{
- return -1;
-}
-#else
-extern int apic_force_enable(unsigned long addr);
-#endif
-
-extern int apic_bsp_setup(bool upmode);
-extern void apic_ap_setup(void);
-
-/*
- * On 32bit this is mach-xxx local
- */
-#ifdef CONFIG_X86_64
-extern int apic_is_clustered_box(void);
-#else
-static inline int apic_is_clustered_box(void)
-{
- return 0;
-}
-#endif
-
-extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
-
-#else /* !CONFIG_X86_LOCAL_APIC */
-static inline void lapic_shutdown(void) { }
-#define local_apic_timer_c2_ok 1
-static inline void init_apic_mappings(void) { }
-static inline void disable_local_APIC(void) { }
-# define setup_boot_APIC_clock x86_init_noop
-# define setup_secondary_APIC_clock x86_init_noop
-#endif /* !CONFIG_X86_LOCAL_APIC */
+#endif /* !CONFIG_X86_X2APIC */
#ifdef CONFIG_X86_64
#define SET_APIC_ID(x) (apic->set_apic_id(x))
@@ -303,6 +307,7 @@ struct apic {
unsigned int *apicid);
/* ipi */
+ void (*send_IPI)(int cpu, int vector);
void (*send_IPI_mask)(const struct cpumask *mask, int vector);
void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
int vector);
diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h
index 259a7c1..02e799f 100644
--- a/arch/x86/include/asm/arch_hweight.h
+++ b/arch/x86/include/asm/arch_hweight.h
@@ -1,6 +1,8 @@
#ifndef _ASM_X86_HWEIGHT_H
#define _ASM_X86_HWEIGHT_H
+#include <asm/cpufeatures.h>
+
#ifdef CONFIG_64BIT
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 189679a..f5063b6 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -44,19 +44,22 @@
/* Exception table entry */
#ifdef __ASSEMBLY__
-# define _ASM_EXTABLE(from,to) \
+# define _ASM_EXTABLE_HANDLE(from, to, handler) \
.pushsection "__ex_table","a" ; \
- .balign 8 ; \
+ .balign 4 ; \
.long (from) - . ; \
.long (to) - . ; \
+ .long (handler) - . ; \
.popsection
-# define _ASM_EXTABLE_EX(from,to) \
- .pushsection "__ex_table","a" ; \
- .balign 8 ; \
- .long (from) - . ; \
- .long (to) - . + 0x7ffffff0 ; \
- .popsection
+# define _ASM_EXTABLE(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
+
+# define _ASM_EXTABLE_FAULT(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
+
+# define _ASM_EXTABLE_EX(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
# define _ASM_NOKPROBE(entry) \
.pushsection "_kprobe_blacklist","aw" ; \
@@ -89,19 +92,24 @@
.endm
#else
-# define _ASM_EXTABLE(from,to) \
+# define _EXPAND_EXTABLE_HANDLE(x) #x
+# define _ASM_EXTABLE_HANDLE(from, to, handler) \
" .pushsection \"__ex_table\",\"a\"\n" \
- " .balign 8\n" \
+ " .balign 4\n" \
" .long (" #from ") - .\n" \
" .long (" #to ") - .\n" \
+ " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \
" .popsection\n"
-# define _ASM_EXTABLE_EX(from,to) \
- " .pushsection \"__ex_table\",\"a\"\n" \
- " .balign 8\n" \
- " .long (" #from ") - .\n" \
- " .long (" #to ") - . + 0x7ffffff0\n" \
- " .popsection\n"
+# define _ASM_EXTABLE(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
+
+# define _ASM_EXTABLE_FAULT(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
+
+# define _ASM_EXTABLE_EX(from, to) \
+ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
+
/* For C file, we already have NOKPROBE_SYMBOL macro */
#endif
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index fb52aa6..3e86742 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -3,7 +3,6 @@
#include <linux/compiler.h>
#include <linux/types.h>
-#include <asm/processor.h>
#include <asm/alternative.h>
#include <asm/cmpxchg.h>
#include <asm/rmwcc.h>
@@ -24,7 +23,7 @@
*/
static __always_inline int atomic_read(const atomic_t *v)
{
- return ACCESS_ONCE((v)->counter);
+ return READ_ONCE((v)->counter);
}
/**
@@ -36,7 +35,7 @@ static __always_inline int atomic_read(const atomic_t *v)
*/
static __always_inline void atomic_set(atomic_t *v, int i)
{
- v->counter = i;
+ WRITE_ONCE(v->counter, i);
}
/**
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index a11c30b..a984111 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -3,7 +3,6 @@
#include <linux/compiler.h>
#include <linux/types.h>
-#include <asm/processor.h>
//#include <asm/cmpxchg.h>
/* An 64bit atomic type */
diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h
index 50e33ef..0373510 100644
--- a/arch/x86/include/asm/atomic64_64.h
+++ b/arch/x86/include/asm/atomic64_64.h
@@ -18,7 +18,7 @@
*/
static inline long atomic64_read(const atomic64_t *v)
{
- return ACCESS_ONCE((v)->counter);
+ return READ_ONCE((v)->counter);
}
/**
@@ -30,7 +30,7 @@ static inline long atomic64_read(const atomic64_t *v)
*/
static inline void atomic64_set(atomic64_t *v, long i)
{
- v->counter = i;
+ WRITE_ONCE(v->counter, i);
}
/**
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
index 0681d25..bfb28ca 100644
--- a/arch/x86/include/asm/barrier.h
+++ b/arch/x86/include/asm/barrier.h
@@ -6,18 +6,17 @@
/*
* Force strict CPU ordering.
- * And yes, this is required on UP too when we're talking
+ * And yes, this might be required on UP too when we're talking
* to devices.
*/
#ifdef CONFIG_X86_32
-/*
- * Some non-Intel clones support out of order store. wmb() ceases to be a
- * nop for these.
- */
-#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
-#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
-#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+#define mb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "mfence", \
+ X86_FEATURE_XMM2) ::: "memory", "cc")
+#define rmb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "lfence", \
+ X86_FEATURE_XMM2) ::: "memory", "cc")
+#define wmb() asm volatile(ALTERNATIVE("lock; addl $0,0(%%esp)", "sfence", \
+ X86_FEATURE_XMM2) ::: "memory", "cc")
#else
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
@@ -31,20 +30,10 @@
#endif
#define dma_wmb() barrier()
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() dma_rmb()
-#define smp_wmb() barrier()
-#define smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
-#else /* !SMP */
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
-#endif /* SMP */
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
+#define __smp_mb() mb()
+#define __smp_rmb() dma_rmb()
+#define __smp_wmb() barrier()
+#define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
#if defined(CONFIG_X86_PPRO_FENCE)
@@ -53,31 +42,31 @@
* model and we should fall back to full barriers.
*/
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
- smp_mb(); \
+ __smp_mb(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
- smp_mb(); \
+ __smp_mb(); \
___p1; \
})
#else /* regular x86 TSO memory ordering */
-#define smp_store_release(p, v) \
+#define __smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
barrier(); \
WRITE_ONCE(*p, v); \
} while (0)
-#define smp_load_acquire(p) \
+#define __smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
@@ -88,7 +77,9 @@ do { \
#endif
/* Atomic operations are already serializing on x86 */
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
+
+#include <asm-generic/barrier.h>
#endif /* _ASM_X86_BARRIER_H */
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index cfe3b95..7766d1c 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -91,7 +91,7 @@ set_bit(long nr, volatile unsigned long *addr)
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-static inline void __set_bit(long nr, volatile unsigned long *addr)
+static __always_inline void __set_bit(long nr, volatile unsigned long *addr)
{
asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
}
@@ -128,13 +128,13 @@ clear_bit(long nr, volatile unsigned long *addr)
* clear_bit() is atomic and implies release semantics before the memory
* operation. It can be used for an unlock.
*/
-static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
+static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
{
barrier();
clear_bit(nr, addr);
}
-static inline void __clear_bit(long nr, volatile unsigned long *addr)
+static __always_inline void __clear_bit(long nr, volatile unsigned long *addr)
{
asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
}
@@ -151,7 +151,7 @@ static inline void __clear_bit(long nr, volatile unsigned long *addr)
* No memory barrier is required here, because x86 cannot reorder stores past
* older loads. Same principle as spin_unlock.
*/
-static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
+static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
{
barrier();
__clear_bit(nr, addr);
@@ -166,7 +166,7 @@ static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-static inline void __change_bit(long nr, volatile unsigned long *addr)
+static __always_inline void __change_bit(long nr, volatile unsigned long *addr)
{
asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
}
@@ -180,7 +180,7 @@ static inline void __change_bit(long nr, volatile unsigned long *addr)
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-static inline void change_bit(long nr, volatile unsigned long *addr)
+static __always_inline void change_bit(long nr, volatile unsigned long *addr)
{
if (IS_IMMEDIATE(nr)) {
asm volatile(LOCK_PREFIX "xorb %1,%0"
@@ -201,7 +201,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr)
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static inline int test_and_set_bit(long nr, volatile unsigned long *addr)
+static __always_inline int test_and_set_bit(long nr, volatile unsigned long *addr)
{
GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c");
}
@@ -228,7 +228,7 @@ test_and_set_bit_lock(long nr, volatile unsigned long *addr)
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-static inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
+static __always_inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
{
int oldbit;
@@ -247,7 +247,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
+static __always_inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
{
GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c");
}
@@ -268,7 +268,7 @@ static inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
* accessed from a hypervisor on the same CPU if running in a VM: don't change
* this without also updating arch/x86/kernel/kvm.c
*/
-static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
+static __always_inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
{
int oldbit;
@@ -280,7 +280,7 @@ static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
}
/* WARNING: non atomic and it can be reordered! */
-static inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
+static __always_inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
{
int oldbit;
@@ -300,7 +300,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static inline int test_and_change_bit(long nr, volatile unsigned long *addr)
+static __always_inline int test_and_change_bit(long nr, volatile unsigned long *addr)
{
GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c");
}
@@ -311,7 +311,7 @@ static __always_inline int constant_test_bit(long nr, const volatile unsigned lo
(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
}
-static inline int variable_test_bit(long nr, volatile const unsigned long *addr)
+static __always_inline int variable_test_bit(long nr, volatile const unsigned long *addr)
{
int oldbit;
@@ -343,7 +343,7 @@ static int test_bit(int nr, const volatile unsigned long *addr);
*
* Undefined if no bit exists, so code should check against 0 first.
*/
-static inline unsigned long __ffs(unsigned long word)
+static __always_inline unsigned long __ffs(unsigned long word)
{
asm("rep; bsf %1,%0"
: "=r" (word)
@@ -357,7 +357,7 @@ static inline unsigned long __ffs(unsigned long word)
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
-static inline unsigned long ffz(unsigned long word)
+static __always_inline unsigned long ffz(unsigned long word)
{
asm("rep; bsf %1,%0"
: "=r" (word)
@@ -371,7 +371,7 @@ static inline unsigned long ffz(unsigned long word)
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
-static inline unsigned long __fls(unsigned long word)
+static __always_inline unsigned long __fls(unsigned long word)
{
asm("bsr %1,%0"
: "=r" (word)
@@ -393,7 +393,7 @@ static inline unsigned long __fls(unsigned long word)
* set bit if value is nonzero. The first (least significant) bit
* is at position 1.
*/
-static inline int ffs(int x)
+static __always_inline int ffs(int x)
{
int r;
@@ -434,7 +434,7 @@ static inline int ffs(int x)
* set bit if value is nonzero. The last (most significant) bit is
* at position 32.
*/
-static inline int fls(int x)
+static __always_inline int fls(int x)
{
int r;
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
index 4fa687a..6b8d6e8 100644
--- a/arch/x86/include/asm/boot.h
+++ b/arch/x86/include/asm/boot.h
@@ -27,7 +27,7 @@
#define BOOT_HEAP_SIZE 0x400000
#else /* !CONFIG_KERNEL_BZIP2 */
-#define BOOT_HEAP_SIZE 0x8000
+#define BOOT_HEAP_SIZE 0x10000
#endif /* !CONFIG_KERNEL_BZIP2 */
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index e63aa38..61518cf 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -91,16 +91,10 @@ void clflush_cache_range(void *addr, unsigned int size);
#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)
-#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void);
extern const int rodata_test_data;
extern int kernel_set_to_readonly;
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
#ifdef CONFIG_DEBUG_RODATA_TEST
int rodata_test(void);
diff --git a/arch/x86/include/asm/calgary.h b/arch/x86/include/asm/calgary.h
index 0d467b3..a8303eb 100644
--- a/arch/x86/include/asm/calgary.h
+++ b/arch/x86/include/asm/calgary.h
@@ -31,7 +31,7 @@
#include <asm/types.h>
struct iommu_table {
- struct cal_chipset_ops *chip_ops; /* chipset specific funcs */
+ const struct cal_chipset_ops *chip_ops; /* chipset specific funcs */
unsigned long it_base; /* mapped address of tce table */
unsigned long it_hint; /* Hint for next alloc */
unsigned long *it_map; /* A simple allocation bitmap for now */
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index f50de69..532f85e 100644
--- a/arch/x86/include/asm/checksum_32.h
+++ b/arch/x86/include/asm/checksum_32.h
@@ -112,8 +112,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
asm("addl %1, %0 ;\n"
@@ -131,8 +130,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
@@ -151,8 +149,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
asm("addl 0(%1), %0 ;\n"
"adcl 4(%1), %0 ;\n"
diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h
index cd00e17..c020ee7 100644
--- a/arch/x86/include/asm/checksum_64.h
+++ b/arch/x86/include/asm/checksum_64.h
@@ -84,8 +84,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
* 32bit unfolded.
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
asm(" addl %1, %0\n"
" adcl %2, %0\n"
@@ -110,8 +110,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* complemented and ready to be filled in.
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
@@ -177,7 +177,7 @@ struct in6_addr;
#define _HAVE_ARCH_IPV6_CSUM 1
extern __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum);
+ __u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
diff --git a/arch/x86/include/asm/clocksource.h b/arch/x86/include/asm/clocksource.h
index eda81dc..d194266 100644
--- a/arch/x86/include/asm/clocksource.h
+++ b/arch/x86/include/asm/clocksource.h
@@ -3,10 +3,11 @@
#ifndef _ASM_X86_CLOCKSOURCE_H
#define _ASM_X86_CLOCKSOURCE_H
-#define VCLOCK_NONE 0 /* No vDSO clock available. */
-#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */
-#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */
-#define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */
+#define VCLOCK_NONE 0 /* No vDSO clock available. */
+#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */
+#define VCLOCK_HPET 2 /* vDSO should use vread_hpet. */
+#define VCLOCK_PVCLOCK 3 /* vDSO should use vread_pvclock. */
+#define VCLOCK_MAX 3
struct arch_clocksource_data {
int vclock_mode;
diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
index ad19841..9733361 100644
--- a/arch/x86/include/asm/cmpxchg.h
+++ b/arch/x86/include/asm/cmpxchg.h
@@ -2,6 +2,7 @@
#define ASM_X86_CMPXCHG_H
#include <linux/compiler.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative.h> /* Provides LOCK_PREFIX */
/*
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index f7e1429..e4959d0 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -109,6 +109,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
#endif
-#define system_has_cmpxchg_double() cpu_has_cx8
+#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8)
#endif /* _ASM_X86_CMPXCHG_32_H */
diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h
index 1af9469..caa23a3 100644
--- a/arch/x86/include/asm/cmpxchg_64.h
+++ b/arch/x86/include/asm/cmpxchg_64.h
@@ -18,6 +18,6 @@ static inline void set_64bit(volatile u64 *ptr, u64 val)
cmpxchg_local((ptr), (o), (n)); \
})
-#define system_has_cmpxchg_double() cpu_has_cx16
+#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16)
#endif /* _ASM_X86_CMPXCHG_64_H */
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index bf2caa1..678637a 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -36,4 +36,7 @@ extern int _debug_hotplug_cpu(int cpu, int action);
int mwait_usable(const struct cpuinfo_x86 *);
+unsigned int x86_family(unsigned int sig);
+unsigned int x86_model(unsigned int sig);
+unsigned int x86_stepping(unsigned int sig);
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 9727b3b..68e4e82 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -1,280 +1,33 @@
-/*
- * Defines x86 CPU feature bits
- */
#ifndef _ASM_X86_CPUFEATURE_H
#define _ASM_X86_CPUFEATURE_H
-#ifndef _ASM_X86_REQUIRED_FEATURES_H
-#include <asm/required-features.h>
-#endif
-
-#ifndef _ASM_X86_DISABLED_FEATURES_H
-#include <asm/disabled-features.h>
-#endif
-
-#define NCAPINTS 13 /* N 32-bit words worth of info */
-#define NBUGINTS 1 /* N 32-bit bug flags */
-
-/*
- * Note: If the comment begins with a quoted string, that string is used
- * in /proc/cpuinfo instead of the macro name. If the string is "",
- * this feature bit is not displayed in /proc/cpuinfo at all.
- */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
-#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
-#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
-#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */
- /* (plus FCMOVcc, FCOMI with FPU) */
-#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
-#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
-#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
-#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
-#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
-#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
-#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
-#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */
-#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
-#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
-#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* cpu types for specific tunings: */
-#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
-#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */
-#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
-#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
-#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
-#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */
-/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */
-#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
-#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */
-#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */
-#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
-#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
-#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
-/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */
-#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
-#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
-#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
-#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
-#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
-/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
-#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
-#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
-#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
-#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
-#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
-#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
-#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */
-#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
-#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
-#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */
-#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
-#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
-#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
-#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
-#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */
-#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
-#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
-#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
-#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
-#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */
-#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
-#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */
-#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
-#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */
-#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */
-#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */
-#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
-#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
-#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
-#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
-#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */
-#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */
-#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
-#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
-#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
-#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
-#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
-
-/*
- * Auxiliary flags: Linux defined - For features scattered in various
- * CPUID levels like 0x6, 0xA etc, word 7
- */
-#define X86_FEATURE_IDA ( 7*32+ 0) /* Intel Dynamic Acceleration */
-#define X86_FEATURE_ARAT ( 7*32+ 1) /* Always Running APIC Timer */
-#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
-#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
-#define X86_FEATURE_PLN ( 7*32+ 5) /* Intel Power Limit Notification */
-#define X86_FEATURE_PTS ( 7*32+ 6) /* Intel Package Thermal Status */
-#define X86_FEATURE_DTHERM ( 7*32+ 7) /* Digital Thermal Sensor */
-#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
-#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
-#define X86_FEATURE_HWP ( 7*32+ 10) /* "hwp" Intel HWP */
-#define X86_FEATURE_HWP_NOTIFY ( 7*32+ 11) /* Intel HWP_NOTIFY */
-#define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12) /* Intel HWP_ACT_WINDOW */
-#define X86_FEATURE_HWP_EPP ( 7*32+13) /* Intel HWP_EPP */
-#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */
-#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
-
-/* Virtualization flags: Linux defined, word 8 */
-#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
-#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
-#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
-#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */
-#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */
-#define X86_FEATURE_NPT ( 8*32+ 5) /* AMD Nested Page Table support */
-#define X86_FEATURE_LBRV ( 8*32+ 6) /* AMD LBR Virtualization support */
-#define X86_FEATURE_SVML ( 8*32+ 7) /* "svm_lock" AMD SVM locking MSR */
-#define X86_FEATURE_NRIPS ( 8*32+ 8) /* "nrip_save" AMD SVM next_rip save */
-#define X86_FEATURE_TSCRATEMSR ( 8*32+ 9) /* "tsc_scale" AMD TSC scaling support */
-#define X86_FEATURE_VMCBCLEAN ( 8*32+10) /* "vmcb_clean" AMD VMCB clean bits support */
-#define X86_FEATURE_FLUSHBYASID ( 8*32+11) /* AMD flush-by-ASID support */
-#define X86_FEATURE_DECODEASSISTS ( 8*32+12) /* AMD Decode Assists support */
-#define X86_FEATURE_PAUSEFILTER ( 8*32+13) /* AMD filtered pause intercept */
-#define X86_FEATURE_PFTHRESHOLD ( 8*32+14) /* AMD pause filter threshold */
-#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */
-
-
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
-#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
-#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */
-#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
-#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
-#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
-#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
-#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
-#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
-#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
-#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
-#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
-#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
-#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
-#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
-#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
-#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */
-#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
-#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
-#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
-#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
-#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
-#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
-
-/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
-#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */
-#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */
-#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
-#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
-
-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
-#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
-
-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
-#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
-
-/*
- * BUG word(s)
- */
-#define X86_BUG(x) (NCAPINTS*32 + (x))
-
-#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
-#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
-#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
-#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
-#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
-#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
-#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
-#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
-#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+#include <asm/processor.h>
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
#include <asm/asm.h>
#include <linux/bitops.h>
+enum cpuid_leafs
+{
+ CPUID_1_EDX = 0,
+ CPUID_8000_0001_EDX,
+ CPUID_8086_0001_EDX,
+ CPUID_LNX_1,
+ CPUID_1_ECX,
+ CPUID_C000_0001_EDX,
+ CPUID_8000_0001_ECX,
+ CPUID_LNX_2,
+ CPUID_LNX_3,
+ CPUID_7_0_EBX,
+ CPUID_D_1_EAX,
+ CPUID_F_0_EDX,
+ CPUID_F_1_EDX,
+ CPUID_8000_0008_EBX,
+ CPUID_6_EAX,
+ CPUID_8000_000A_EDX,
+};
+
#ifdef CONFIG_X86_FEATURE_NAMES
extern const char * const x86_cap_flags[NCAPINTS*32];
extern const char * const x86_power_flags[32];
@@ -335,8 +88,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
* is not relevant.
*/
#define cpu_feature_enabled(bit) \
- (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : \
- cpu_has(&boot_cpu_data, bit))
+ (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
@@ -352,155 +104,39 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
} while (0)
#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU)
-#define cpu_has_de boot_cpu_has(X86_FEATURE_DE)
#define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE)
#define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC)
#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE)
#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC)
-#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP)
-#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR)
-#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX)
#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR)
#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM)
#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
-#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
-#define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3)
#define cpu_has_aes boot_cpu_has(X86_FEATURE_AES)
#define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX)
#define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2)
-#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
-#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
-#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)
-#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN)
-#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT)
-#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN)
-#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2)
-#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN)
-#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE)
-#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN)
-#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM)
-#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN)
-#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS)
-#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS)
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH)
-#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS)
#define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES)
#define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
#define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT)
-#define cpu_has_xmm4_1 boot_cpu_has(X86_FEATURE_XMM4_1)
-#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2)
#define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC)
#define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE)
-#define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT)
#define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES)
#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE)
#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
-#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ)
-#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE)
-#define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB)
-#define cpu_has_perfctr_l2 boot_cpu_has(X86_FEATURE_PERFCTR_L2)
-#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8)
-#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16)
-#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU)
-#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT)
-#define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT)
-
-#if __GNUC__ >= 4
-extern void warn_pre_alternatives(void);
-extern bool __static_cpu_has_safe(u16 bit);
+/*
+ * Do not add any more of those clumsy macros - use static_cpu_has() for
+ * fast paths and boot_cpu_has() otherwise!
+ */
+#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS)
/*
* Static testing of CPU features. Used the same as boot_cpu_has().
- * These are only valid after alternatives have run, but will statically
- * patch the target code for additional performance.
+ * These will statically patch the target code for additional
+ * performance.
*/
-static __always_inline __pure bool __static_cpu_has(u16 bit)
+static __always_inline __pure bool _static_cpu_has(u16 bit)
{
-#ifdef CC_HAVE_ASM_GOTO
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-
- /*
- * Catch too early usage of this before alternatives
- * have run.
- */
- asm_volatile_goto("1: jmp %l[t_warn]\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- " .long 1b - .\n"
- " .long 0\n" /* no replacement */
- " .word %P0\n" /* 1: do replace */
- " .byte 2b - 1b\n" /* source len */
- " .byte 0\n" /* replacement len */
- " .byte 0\n" /* pad len */
- ".previous\n"
- /* skipping size check since replacement size = 0 */
- : : "i" (X86_FEATURE_ALWAYS) : : t_warn);
-
-#endif
-
- asm_volatile_goto("1: jmp %l[t_no]\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- " .long 1b - .\n"
- " .long 0\n" /* no replacement */
- " .word %P0\n" /* feature bit */
- " .byte 2b - 1b\n" /* source len */
- " .byte 0\n" /* replacement len */
- " .byte 0\n" /* pad len */
- ".previous\n"
- /* skipping size check since replacement size = 0 */
- : : "i" (bit) : : t_no);
- return true;
- t_no:
- return false;
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
- t_warn:
- warn_pre_alternatives();
- return false;
-#endif
-
-#else /* CC_HAVE_ASM_GOTO */
-
- u8 flag;
- /* Open-coded due to __stringify() in ALTERNATIVE() */
- asm volatile("1: movb $0,%0\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- " .long 1b - .\n"
- " .long 3f - .\n"
- " .word %P1\n" /* feature bit */
- " .byte 2b - 1b\n" /* source len */
- " .byte 4f - 3f\n" /* replacement len */
- " .byte 0\n" /* pad len */
- ".previous\n"
- ".section .discard,\"aw\",@progbits\n"
- " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
- ".previous\n"
- ".section .altinstr_replacement,\"ax\"\n"
- "3: movb $1,%0\n"
- "4:\n"
- ".previous\n"
- : "=qm" (flag) : "i" (bit));
- return flag;
-
-#endif /* CC_HAVE_ASM_GOTO */
-}
-
-#define static_cpu_has(bit) \
-( \
- __builtin_constant_p(boot_cpu_has(bit)) ? \
- boot_cpu_has(bit) : \
- __builtin_constant_p(bit) ? \
- __static_cpu_has(bit) : \
- boot_cpu_has(bit) \
-)
-
-static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
-{
-#ifdef CC_HAVE_ASM_GOTO
- asm_volatile_goto("1: jmp %l[t_dynamic]\n"
+ asm_volatile_goto("1: jmp 6f\n"
"2:\n"
".skip -(((5f-4f) - (2b-1b)) > 0) * "
"((5f-4f) - (2b-1b)),0x90\n"
@@ -525,66 +161,34 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
" .byte 0\n" /* repl len */
" .byte 0\n" /* pad len */
".previous\n"
- : : "i" (bit), "i" (X86_FEATURE_ALWAYS)
- : : t_dynamic, t_no);
+ ".section .altinstr_aux,\"ax\"\n"
+ "6:\n"
+ " testb %[bitnum],%[cap_byte]\n"
+ " jnz %l[t_yes]\n"
+ " jmp %l[t_no]\n"
+ ".previous\n"
+ : : "i" (bit), "i" (X86_FEATURE_ALWAYS),
+ [bitnum] "i" (1 << (bit & 7)),
+ [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
+ : : t_yes, t_no);
+ t_yes:
return true;
t_no:
return false;
- t_dynamic:
- return __static_cpu_has_safe(bit);
-#else
- u8 flag;
- /* Open-coded due to __stringify() in ALTERNATIVE() */
- asm volatile("1: movb $2,%0\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- " .long 1b - .\n" /* src offset */
- " .long 3f - .\n" /* repl offset */
- " .word %P2\n" /* always replace */
- " .byte 2b - 1b\n" /* source len */
- " .byte 4f - 3f\n" /* replacement len */
- " .byte 0\n" /* pad len */
- ".previous\n"
- ".section .discard,\"aw\",@progbits\n"
- " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
- ".previous\n"
- ".section .altinstr_replacement,\"ax\"\n"
- "3: movb $0,%0\n"
- "4:\n"
- ".previous\n"
- ".section .altinstructions,\"a\"\n"
- " .long 1b - .\n" /* src offset */
- " .long 5f - .\n" /* repl offset */
- " .word %P1\n" /* feature bit */
- " .byte 4b - 3b\n" /* src len */
- " .byte 6f - 5f\n" /* repl len */
- " .byte 0\n" /* pad len */
- ".previous\n"
- ".section .discard,\"aw\",@progbits\n"
- " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */
- ".previous\n"
- ".section .altinstr_replacement,\"ax\"\n"
- "5: movb $1,%0\n"
- "6:\n"
- ".previous\n"
- : "=qm" (flag)
- : "i" (bit), "i" (X86_FEATURE_ALWAYS));
- return (flag == 2 ? __static_cpu_has_safe(bit) : flag);
-#endif /* CC_HAVE_ASM_GOTO */
}
-#define static_cpu_has_safe(bit) \
+#define static_cpu_has(bit) \
( \
__builtin_constant_p(boot_cpu_has(bit)) ? \
boot_cpu_has(bit) : \
- _static_cpu_has_safe(bit) \
+ _static_cpu_has(bit) \
)
#else
/*
- * gcc 3.x is too stupid to do the static test; fall back to dynamic.
+ * Fall back to dynamic for gcc versions which don't support asm goto. Should be
+ * a minority now anyway.
*/
#define static_cpu_has(bit) boot_cpu_has(bit)
-#define static_cpu_has_safe(bit) boot_cpu_has(bit)
#endif
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
@@ -592,7 +196,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit))
#define static_cpu_has_bug(bit) static_cpu_has((bit))
-#define static_cpu_has_bug_safe(bit) static_cpu_has_safe((bit))
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
#define MAX_CPU_FEATURES (NCAPINTS * 32)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
new file mode 100644
index 0000000..074b760
--- /dev/null
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -0,0 +1,300 @@
+#ifndef _ASM_X86_CPUFEATURES_H
+#define _ASM_X86_CPUFEATURES_H
+
+#ifndef _ASM_X86_REQUIRED_FEATURES_H
+#include <asm/required-features.h>
+#endif
+
+#ifndef _ASM_X86_DISABLED_FEATURES_H
+#include <asm/disabled-features.h>
+#endif
+
+/*
+ * Defines x86 CPU feature bits
+ */
+#define NCAPINTS 16 /* N 32-bit words worth of info */
+#define NBUGINTS 1 /* N 32-bit bug flags */
+
+/*
+ * Note: If the comment begins with a quoted string, that string is used
+ * in /proc/cpuinfo instead of the macro name. If the string is "",
+ * this feature bit is not displayed in /proc/cpuinfo at all.
+ */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
+#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
+#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
+#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
+#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
+#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
+#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
+#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
+#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
+#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
+#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
+#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
+#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
+#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */
+ /* (plus FCMOVcc, FCOMI with FPU) */
+#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
+#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
+#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
+#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
+#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
+#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
+#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
+#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
+#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
+#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
+#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
+#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
+#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
+
+/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* Don't duplicate feature flags which are redundant with Intel! */
+#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */
+#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
+#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
+#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
+#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
+#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */
+
+/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
+#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
+#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
+
+/* Other features, Linux-defined mapping, word 3 */
+/* This range is used for feature bits which conflict or are synthesized */
+#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
+/* cpu types for specific tunings: */
+#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
+#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */
+#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
+#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
+#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
+#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */
+#define X86_FEATURE_ART ( 3*32+10) /* Platform has always running timer (ART) */
+#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
+#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
+#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
+#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */
+#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */
+#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
+#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
+#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
+/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */
+#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
+#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
+#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
+#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
+#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
+/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
+#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
+#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
+#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
+#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
+#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
+#define X86_FEATURE_MCE_RECOVERY ( 3*32+31) /* cpu has recoverable machine checks */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
+#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
+#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */
+#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
+#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
+#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */
+#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
+#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
+#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
+#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
+#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */
+#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */
+#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
+#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
+#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
+#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
+#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */
+#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
+#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */
+#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
+#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */
+#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */
+#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */
+#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
+#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
+#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
+#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
+#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
+#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
+#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
+
+/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
+#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
+#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
+#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
+#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
+#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
+#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */
+#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
+#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */
+#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
+#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
+#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
+#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
+#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
+
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc, word 7.
+ *
+ * Reuse free bits when adding new feature flags!
+ */
+
+#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
+#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
+
+#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
+#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
+
+#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
+
+/* Virtualization flags: Linux defined, word 8 */
+#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
+#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
+#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
+#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */
+#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */
+
+#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */
+#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
+
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
+#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */
+#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
+#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
+#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
+#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
+#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
+#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
+#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
+#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
+#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
+#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
+#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
+#define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
+#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
+#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
+#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
+#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */
+#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
+#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
+#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
+#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
+#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
+#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
+#define X86_FEATURE_AVX512BW ( 9*32+30) /* AVX-512 BW (Byte/Word granular) Instructions */
+#define X86_FEATURE_AVX512VL ( 9*32+31) /* AVX-512 VL (128/256 Vector Length) Extensions */
+
+/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
+#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */
+#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */
+#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
+#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
+
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
+#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
+
+/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
+#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
+
+/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
+#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
+
+/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
+#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
+#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */
+#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */
+#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */
+#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */
+#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */
+#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
+#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
+#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
+
+/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */
+#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
+#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */
+#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */
+#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */
+#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */
+#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
+#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
+#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
+#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
+#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
+#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
+
+/*
+ * BUG word(s)
+ */
+#define X86_BUG(x) (NCAPINTS*32 + (x))
+
+#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
+#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
+#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
+#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
+#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
+#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
+#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
+#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
+#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+
+#ifdef CONFIG_X86_32
+/*
+ * 64-bit kernels don't use X86_BUG_ESPFIX. Make the define conditional
+ * to avoid confusion.
+ */
+#define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */
+#endif
+
+#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index 278441f..eb5deb4 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -98,4 +98,27 @@ struct desc_ptr {
#endif /* !__ASSEMBLY__ */
+/* Access rights as returned by LAR */
+#define AR_TYPE_RODATA (0 * (1 << 9))
+#define AR_TYPE_RWDATA (1 * (1 << 9))
+#define AR_TYPE_RODATA_EXPDOWN (2 * (1 << 9))
+#define AR_TYPE_RWDATA_EXPDOWN (3 * (1 << 9))
+#define AR_TYPE_XOCODE (4 * (1 << 9))
+#define AR_TYPE_XRCODE (5 * (1 << 9))
+#define AR_TYPE_XOCODE_CONF (6 * (1 << 9))
+#define AR_TYPE_XRCODE_CONF (7 * (1 << 9))
+#define AR_TYPE_MASK (7 * (1 << 9))
+
+#define AR_DPL0 (0 * (1 << 13))
+#define AR_DPL3 (3 * (1 << 13))
+#define AR_DPL_MASK (3 * (1 << 13))
+
+#define AR_A (1 << 8) /* "Accessed" */
+#define AR_S (1 << 12) /* If clear, "System" segment */
+#define AR_P (1 << 15) /* "Present" */
+#define AR_AVL (1 << 20) /* "AVaiLable" (no HW effect) */
+#define AR_L (1 << 21) /* "Long mode" for code segments */
+#define AR_DB (1 << 22) /* D/B, effect depends on type */
+#define AR_G (1 << 23) /* "Granularity" (limit in pages) */
+
#endif /* _ASM_X86_DESC_DEFS_H */
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 03dd729..684ed6c 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -10,6 +10,16 @@ struct dev_archdata {
#endif
};
+#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
+struct dma_domain {
+ struct list_head node;
+ struct dma_map_ops *dma_ops;
+ int domain_nr;
+};
+void add_dma_domain(struct dma_domain *domain);
+void del_dma_domain(struct dma_domain *domain);
+#endif
+
struct pdev_archdata {
};
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 953b726..3a27b93 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -46,8 +46,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
#define HAVE_ARCH_DMA_SUPPORTED 1
extern int dma_supported(struct device *hwdev, u64 mask);
-#include <asm-generic/dma-mapping-common.h>
-
extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_addr, gfp_t flag,
struct dma_attrs *attrs);
diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h
index 535192f..3c69fed 100644
--- a/arch/x86/include/asm/dmi.h
+++ b/arch/x86/include/asm/dmi.h
@@ -15,7 +15,7 @@ static __always_inline __init void *dmi_alloc(unsigned len)
/* Use early IO mappings for DMI because it's initialized early */
#define dmi_early_remap early_ioremap
#define dmi_early_unmap early_iounmap
-#define dmi_remap ioremap
+#define dmi_remap ioremap_cache
#define dmi_unmap iounmap
#endif /* _ASM_X86_DMI_H */
diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h
new file mode 100644
index 0000000..b7a1ab8
--- /dev/null
+++ b/arch/x86/include/asm/dwarf2.h
@@ -0,0 +1,84 @@
+#ifndef _ASM_X86_DWARF2_H
+#define _ASM_X86_DWARF2_H
+
+#ifndef __ASSEMBLY__
+#warning "asm/dwarf2.h should be only included in pure assembly files"
+#endif
+
+/*
+ * Macros for dwarf2 CFI unwind table entries.
+ * See "as.info" for details on these pseudo ops. Unfortunately
+ * they are only supported in very new binutils, so define them
+ * away for older version.
+ */
+
+#ifdef CONFIG_AS_CFI
+
+#define CFI_STARTPROC .cfi_startproc
+#define CFI_ENDPROC .cfi_endproc
+#define CFI_DEF_CFA .cfi_def_cfa
+#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
+#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
+#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
+#define CFI_OFFSET .cfi_offset
+#define CFI_REL_OFFSET .cfi_rel_offset
+#define CFI_REGISTER .cfi_register
+#define CFI_RESTORE .cfi_restore
+#define CFI_REMEMBER_STATE .cfi_remember_state
+#define CFI_RESTORE_STATE .cfi_restore_state
+#define CFI_UNDEFINED .cfi_undefined
+#define CFI_ESCAPE .cfi_escape
+
+#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
+#define CFI_SIGNAL_FRAME .cfi_signal_frame
+#else
+#define CFI_SIGNAL_FRAME
+#endif
+
+#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)
+#ifndef BUILD_VDSO
+ /*
+ * Emit CFI data in .debug_frame sections, not .eh_frame sections.
+ * The latter we currently just discard since we don't do DWARF
+ * unwinding at runtime. So only the offline DWARF information is
+ * useful to anyone. Note we should not use this directive if
+ * vmlinux.lds.S gets changed so it doesn't discard .eh_frame.
+ */
+ .cfi_sections .debug_frame
+#else
+ /*
+ * For the vDSO, emit both runtime unwind information and debug
+ * symbols for the .dbg file.
+ */
+ .cfi_sections .eh_frame, .debug_frame
+#endif
+#endif
+
+#else
+
+/*
+ * Due to the structure of pre-exisiting code, don't use assembler line
+ * comment character # to ignore the arguments. Instead, use a dummy macro.
+ */
+.macro cfi_ignore a=0, b=0, c=0, d=0
+.endm
+
+#define CFI_STARTPROC cfi_ignore
+#define CFI_ENDPROC cfi_ignore
+#define CFI_DEF_CFA cfi_ignore
+#define CFI_DEF_CFA_REGISTER cfi_ignore
+#define CFI_DEF_CFA_OFFSET cfi_ignore
+#define CFI_ADJUST_CFA_OFFSET cfi_ignore
+#define CFI_OFFSET cfi_ignore
+#define CFI_REL_OFFSET cfi_ignore
+#define CFI_REGISTER cfi_ignore
+#define CFI_RESTORE cfi_ignore
+#define CFI_REMEMBER_STATE cfi_ignore
+#define CFI_RESTORE_STATE cfi_ignore
+#define CFI_UNDEFINED cfi_ignore
+#define CFI_ESCAPE cfi_ignore
+#define CFI_SIGNAL_FRAME cfi_ignore
+
+#endif
+
+#endif /* _ASM_X86_DWARF2_H */
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index ae68be9..08b1f2f 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -25,6 +25,8 @@
#define EFI32_LOADER_SIGNATURE "EL32"
#define EFI64_LOADER_SIGNATURE "EL64"
+#define MAX_CMDLINE_ADDRESS UINT_MAX
+
#ifdef CONFIG_X86_32
@@ -105,6 +107,7 @@ extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
extern int __init efi_memblock_x86_reserve_range(void);
extern pgd_t * __init efi_call_phys_prolog(void);
extern void __init efi_call_phys_epilog(pgd_t *save_pgd);
+extern void __init efi_print_memmap(void);
extern void __init efi_unmap_memmap(void);
extern void __init efi_memory_uc(u64 addr, unsigned long size);
extern void __init efi_map_region(efi_memory_desc_t *md);
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 141c561..15340e3 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -171,11 +171,11 @@ do { \
static inline void elf_common_init(struct thread_struct *t,
struct pt_regs *regs, const u16 ds)
{
- /* Commented-out registers are cleared in stub_execve */
- /*regs->ax = regs->bx =*/ regs->cx = regs->dx = 0;
- regs->si = regs->di /*= regs->bp*/ = 0;
+ /* ax gets execve's return value. */
+ /*regs->ax = */ regs->bx = regs->cx = regs->dx = 0;
+ regs->si = regs->di = regs->bp = 0;
regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
- /*regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;*/
+ regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
t->fs = t->gs = 0;
t->fsindex = t->gsindex = 0;
t->ds = t->es = ds;
@@ -256,7 +256,7 @@ extern int force_personality32;
instruction set this CPU supports. This could be done in user space,
but it's not easy, and we've already done it here. */
-#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
+#define ELF_HWCAP (boot_cpu_data.x86_capability[CPUID_1_EDX])
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
@@ -328,7 +328,7 @@ else \
#define VDSO_ENTRY \
((unsigned long)current->mm->context.vdso + \
- selected_vdso32->sym___kernel_vsyscall)
+ vdso_image_32.sym___kernel_vsyscall)
struct linux_binprm;
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index f80d700..8554f96 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -19,7 +19,6 @@
#include <asm/acpi.h>
#include <asm/apicdef.h>
#include <asm/page.h>
-#include <asm/pvclock.h>
#ifdef CONFIG_X86_32
#include <linux/threads.h>
#include <asm/kmap_types.h>
@@ -72,10 +71,6 @@ enum fixed_addresses {
#ifdef CONFIG_X86_VSYSCALL_EMULATION
VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,
#endif
-#ifdef CONFIG_PARAVIRT_CLOCK
- PVCLOCK_FIXMAP_BEGIN,
- PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
-#endif
#endif
FIX_DBGP_BASE,
FIX_EARLYCON_MEM_BASE,
@@ -143,7 +138,7 @@ extern void reserve_top_address(unsigned long reserve);
extern int fixmaps_set;
extern pte_t *kmap_pte;
-extern pgprot_t kmap_prot;
+#define kmap_prot PAGE_KERNEL
extern pte_t *pkmap_page_table;
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index 3c3550c..a212434 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -17,6 +17,7 @@
#include <asm/user.h>
#include <asm/fpu/api.h>
#include <asm/fpu/xstate.h>
+#include <asm/cpufeature.h>
/*
* High level FPU state handling functions:
@@ -42,6 +43,7 @@ extern void fpu__init_cpu_xstate(void);
extern void fpu__init_system(struct cpuinfo_x86 *c);
extern void fpu__init_check_bugs(void);
extern void fpu__resume_cpu(void);
+extern u64 fpu__get_supported_xfeatures_mask(void);
/*
* Debugging facility:
@@ -57,22 +59,22 @@ extern void fpu__resume_cpu(void);
*/
static __always_inline __pure bool use_eager_fpu(void)
{
- return static_cpu_has_safe(X86_FEATURE_EAGER_FPU);
+ return static_cpu_has(X86_FEATURE_EAGER_FPU);
}
static __always_inline __pure bool use_xsaveopt(void)
{
- return static_cpu_has_safe(X86_FEATURE_XSAVEOPT);
+ return static_cpu_has(X86_FEATURE_XSAVEOPT);
}
static __always_inline __pure bool use_xsave(void)
{
- return static_cpu_has_safe(X86_FEATURE_XSAVE);
+ return static_cpu_has(X86_FEATURE_XSAVE);
}
static __always_inline __pure bool use_fxsr(void)
{
- return static_cpu_has_safe(X86_FEATURE_FXSR);
+ return static_cpu_has(X86_FEATURE_FXSR);
}
/*
@@ -224,18 +226,67 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu)
#define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f"
#define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f"
-/* xstate instruction fault handler: */
-#define xstate_fault(__err) \
- \
- ".section .fixup,\"ax\"\n" \
- \
- "3: movl $-2,%[_err]\n" \
- " jmp 2b\n" \
- \
- ".previous\n" \
- \
- _ASM_EXTABLE(1b, 3b) \
- : [_err] "=r" (__err)
+#define XSTATE_OP(op, st, lmask, hmask, err) \
+ asm volatile("1:" op "\n\t" \
+ "xor %[err], %[err]\n" \
+ "2:\n\t" \
+ ".pushsection .fixup,\"ax\"\n\t" \
+ "3: movl $-2,%[err]\n\t" \
+ "jmp 2b\n\t" \
+ ".popsection\n\t" \
+ _ASM_EXTABLE(1b, 3b) \
+ : [err] "=r" (err) \
+ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
+ : "memory")
+
+/*
+ * If XSAVES is enabled, it replaces XSAVEOPT because it supports a compact
+ * format and supervisor states in addition to modified optimization in
+ * XSAVEOPT.
+ *
+ * Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT
+ * supports modified optimization which is not supported by XSAVE.
+ *
+ * We use XSAVE as a fallback.
+ *
+ * The 661 label is defined in the ALTERNATIVE* macros as the address of the
+ * original instruction which gets replaced. We need to use it here as the
+ * address of the instruction where we might get an exception at.
+ */
+#define XSTATE_XSAVE(st, lmask, hmask, err) \
+ asm volatile(ALTERNATIVE_2(XSAVE, \
+ XSAVEOPT, X86_FEATURE_XSAVEOPT, \
+ XSAVES, X86_FEATURE_XSAVES) \
+ "\n" \
+ "xor %[err], %[err]\n" \
+ "3:\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "4: movl $-2, %[err]\n" \
+ "jmp 3b\n" \
+ ".popsection\n" \
+ _ASM_EXTABLE(661b, 4b) \
+ : [err] "=r" (err) \
+ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
+ : "memory")
+
+/*
+ * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact
+ * XSAVE area format.
+ */
+#define XSTATE_XRESTORE(st, lmask, hmask, err) \
+ asm volatile(ALTERNATIVE(XRSTOR, \
+ XRSTORS, X86_FEATURE_XSAVES) \
+ "\n" \
+ "xor %[err], %[err]\n" \
+ "3:\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "4: movl $-2, %[err]\n" \
+ "jmp 3b\n" \
+ ".popsection\n" \
+ _ASM_EXTABLE(661b, 4b) \
+ : [err] "=r" (err) \
+ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
+ : "memory")
/*
* This function is called only during boot time when x86 caps are not set
@@ -246,22 +297,14 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate)
u64 mask = -1;
u32 lmask = mask;
u32 hmask = mask >> 32;
- int err = 0;
+ int err;
WARN_ON(system_state != SYSTEM_BOOTING);
- if (boot_cpu_has(X86_FEATURE_XSAVES))
- asm volatile("1:"XSAVES"\n\t"
- "2:\n\t"
- xstate_fault(err)
- : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err)
- : "memory");
+ if (static_cpu_has(X86_FEATURE_XSAVES))
+ XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
else
- asm volatile("1:"XSAVE"\n\t"
- "2:\n\t"
- xstate_fault(err)
- : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err)
- : "memory");
+ XSTATE_OP(XSAVE, xstate, lmask, hmask, err);
/* We should never fault when copying to a kernel buffer: */
WARN_ON_FPU(err);
@@ -276,22 +319,14 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate)
u64 mask = -1;
u32 lmask = mask;
u32 hmask = mask >> 32;
- int err = 0;
+ int err;
WARN_ON(system_state != SYSTEM_BOOTING);
- if (boot_cpu_has(X86_FEATURE_XSAVES))
- asm volatile("1:"XRSTORS"\n\t"
- "2:\n\t"
- xstate_fault(err)
- : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err)
- : "memory");
+ if (static_cpu_has(X86_FEATURE_XSAVES))
+ XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
else
- asm volatile("1:"XRSTOR"\n\t"
- "2:\n\t"
- xstate_fault(err)
- : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err)
- : "memory");
+ XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
/* We should never fault when copying from a kernel buffer: */
WARN_ON_FPU(err);
@@ -305,33 +340,11 @@ static inline void copy_xregs_to_kernel(struct xregs_state *xstate)
u64 mask = -1;
u32 lmask = mask;
u32 hmask = mask >> 32;
- int err = 0;
+ int err;
WARN_ON(!alternatives_patched);
- /*
- * If xsaves is enabled, xsaves replaces xsaveopt because
- * it supports compact format and supervisor states in addition to
- * modified optimization in xsaveopt.
- *
- * Otherwise, if xsaveopt is enabled, xsaveopt replaces xsave
- * because xsaveopt supports modified optimization which is not
- * supported by xsave.
- *
- * If none of xsaves and xsaveopt is enabled, use xsave.
- */
- alternative_input_2(
- "1:"XSAVE,
- XSAVEOPT,
- X86_FEATURE_XSAVEOPT,
- XSAVES,
- X86_FEATURE_XSAVES,
- [xstate] "D" (xstate), "a" (lmask), "d" (hmask) :
- "memory");
- asm volatile("2:\n\t"
- xstate_fault(err)
- : "0" (err)
- : "memory");
+ XSTATE_XSAVE(xstate, lmask, hmask, err);
/* We should never fault when copying to a kernel buffer: */
WARN_ON_FPU(err);
@@ -344,23 +357,9 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask)
{
u32 lmask = mask;
u32 hmask = mask >> 32;
- int err = 0;
+ int err;
- /*
- * Use xrstors to restore context if it is enabled. xrstors supports
- * compacted format of xsave area which is not supported by xrstor.
- */
- alternative_input(
- "1: " XRSTOR,
- XRSTORS,
- X86_FEATURE_XSAVES,
- "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask)
- : "memory");
-
- asm volatile("2:\n"
- xstate_fault(err)
- : "0" (err)
- : "memory");
+ XSTATE_XRESTORE(xstate, lmask, hmask, err);
/* We should never fault when copying from a kernel buffer: */
WARN_ON_FPU(err);
@@ -388,12 +387,10 @@ static inline int copy_xregs_to_user(struct xregs_state __user *buf)
if (unlikely(err))
return -EFAULT;
- __asm__ __volatile__(ASM_STAC "\n"
- "1:"XSAVE"\n"
- "2: " ASM_CLAC "\n"
- xstate_fault(err)
- : "D" (buf), "a" (-1), "d" (-1), "0" (err)
- : "memory");
+ stac();
+ XSTATE_OP(XSAVE, buf, -1, -1, err);
+ clac();
+
return err;
}
@@ -405,14 +402,12 @@ static inline int copy_user_to_xregs(struct xregs_state __user *buf, u64 mask)
struct xregs_state *xstate = ((__force struct xregs_state *)buf);
u32 lmask = mask;
u32 hmask = mask >> 32;
- int err = 0;
-
- __asm__ __volatile__(ASM_STAC "\n"
- "1:"XRSTOR"\n"
- "2: " ASM_CLAC "\n"
- xstate_fault(err)
- : "D" (xstate), "a" (lmask), "d" (hmask), "0" (err)
- : "memory"); /* memory required? */
+ int err;
+
+ stac();
+ XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
+ clac();
+
return err;
}
@@ -466,7 +461,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate)
* pending. Clear the x87 state here by setting it to fixed values.
* "m" is a random variable that should be in L1.
*/
- if (unlikely(static_cpu_has_bug_safe(X86_BUG_FXSAVE_LEAK))) {
+ if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) {
asm volatile(
"fnclex\n\t"
"emms\n\t"
@@ -595,7 +590,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu)
* If the task has used the math, pre-load the FPU on xsave processors
* or if the past 5 consecutive context-switches used math.
*/
- fpu.preload = new_fpu->fpstate_active &&
+ fpu.preload = static_cpu_has(X86_FEATURE_FPU) &&
+ new_fpu->fpstate_active &&
(use_eager_fpu() || new_fpu->counter > 5);
if (old_fpu->fpregs_active) {
diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h
index 7358e9d..0e970d0 100644
--- a/arch/x86/include/asm/fpu/signal.h
+++ b/arch/x86/include/asm/fpu/signal.h
@@ -5,7 +5,7 @@
#define _ASM_X86_FPU_SIGNAL_H
#ifdef CONFIG_X86_64
-# include <asm/sigcontext32.h>
+# include <uapi/asm/sigcontext.h>
# include <asm/user32.h>
struct ksignal;
int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h
index c49c517..1c6f6ac 100644
--- a/arch/x86/include/asm/fpu/types.h
+++ b/arch/x86/include/asm/fpu/types.h
@@ -95,63 +95,122 @@ struct swregs_state {
/*
* List of XSAVE features Linux knows about:
*/
-enum xfeature_bit {
- XSTATE_BIT_FP,
- XSTATE_BIT_SSE,
- XSTATE_BIT_YMM,
- XSTATE_BIT_BNDREGS,
- XSTATE_BIT_BNDCSR,
- XSTATE_BIT_OPMASK,
- XSTATE_BIT_ZMM_Hi256,
- XSTATE_BIT_Hi16_ZMM,
-
- XFEATURES_NR_MAX,
+enum xfeature {
+ XFEATURE_FP,
+ XFEATURE_SSE,
+ /*
+ * Values above here are "legacy states".
+ * Those below are "extended states".
+ */
+ XFEATURE_YMM,
+ XFEATURE_BNDREGS,
+ XFEATURE_BNDCSR,
+ XFEATURE_OPMASK,
+ XFEATURE_ZMM_Hi256,
+ XFEATURE_Hi16_ZMM,
+
+ XFEATURE_MAX,
};
-#define XSTATE_FP (1 << XSTATE_BIT_FP)
-#define XSTATE_SSE (1 << XSTATE_BIT_SSE)
-#define XSTATE_YMM (1 << XSTATE_BIT_YMM)
-#define XSTATE_BNDREGS (1 << XSTATE_BIT_BNDREGS)
-#define XSTATE_BNDCSR (1 << XSTATE_BIT_BNDCSR)
-#define XSTATE_OPMASK (1 << XSTATE_BIT_OPMASK)
-#define XSTATE_ZMM_Hi256 (1 << XSTATE_BIT_ZMM_Hi256)
-#define XSTATE_Hi16_ZMM (1 << XSTATE_BIT_Hi16_ZMM)
+#define XFEATURE_MASK_FP (1 << XFEATURE_FP)
+#define XFEATURE_MASK_SSE (1 << XFEATURE_SSE)
+#define XFEATURE_MASK_YMM (1 << XFEATURE_YMM)
+#define XFEATURE_MASK_BNDREGS (1 << XFEATURE_BNDREGS)
+#define XFEATURE_MASK_BNDCSR (1 << XFEATURE_BNDCSR)
+#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)
+#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)
+#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM)
+
+#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
+#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \
+ | XFEATURE_MASK_ZMM_Hi256 \
+ | XFEATURE_MASK_Hi16_ZMM)
+
+#define FIRST_EXTENDED_XFEATURE XFEATURE_YMM
-#define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE)
-#define XSTATE_AVX512 (XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+struct reg_128_bit {
+ u8 regbytes[128/8];
+};
+struct reg_256_bit {
+ u8 regbytes[256/8];
+};
+struct reg_512_bit {
+ u8 regbytes[512/8];
+};
/*
+ * State component 2:
+ *
* There are 16x 256-bit AVX registers named YMM0-YMM15.
* The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
- * and are stored in 'struct fxregs_state::xmm_space[]'.
+ * and are stored in 'struct fxregs_state::xmm_space[]' in the
+ * "legacy" area.
*
- * The high 128 bits are stored here:
- * 16x 128 bits == 256 bytes.
+ * The high 128 bits are stored here.
*/
struct ymmh_struct {
- u8 ymmh_space[256];
-};
-
-/* We don't support LWP yet: */
-struct lwp_struct {
- u8 reserved[128];
-};
+ struct reg_128_bit hi_ymm[16];
+} __packed;
/* Intel MPX support: */
-struct bndreg {
+
+struct mpx_bndreg {
u64 lower_bound;
u64 upper_bound;
} __packed;
+/*
+ * State component 3 is used for the 4 128-bit bounds registers
+ */
+struct mpx_bndreg_state {
+ struct mpx_bndreg bndreg[4];
+} __packed;
-struct bndcsr {
+/*
+ * State component 4 is used for the 64-bit user-mode MPX
+ * configuration register BNDCFGU and the 64-bit MPX status
+ * register BNDSTATUS. We call the pair "BNDCSR".
+ */
+struct mpx_bndcsr {
u64 bndcfgu;
u64 bndstatus;
} __packed;
-struct mpx_struct {
- struct bndreg bndreg[4];
- struct bndcsr bndcsr;
-};
+/*
+ * The BNDCSR state is padded out to be 64-bytes in size.
+ */
+struct mpx_bndcsr_state {
+ union {
+ struct mpx_bndcsr bndcsr;
+ u8 pad_to_64_bytes[64];
+ };
+} __packed;
+
+/* AVX-512 Components: */
+
+/*
+ * State component 5 is used for the 8 64-bit opmask registers
+ * k0-k7 (opmask state).
+ */
+struct avx_512_opmask_state {
+ u64 opmask_reg[8];
+} __packed;
+
+/*
+ * State component 6 is used for the upper 256 bits of the
+ * registers ZMM0-ZMM15. These 16 256-bit values are denoted
+ * ZMM0_H-ZMM15_H (ZMM_Hi256 state).
+ */
+struct avx_512_zmm_uppers_state {
+ struct reg_256_bit zmm_upper[16];
+} __packed;
+
+/*
+ * State component 7 is used for the 16 512-bit registers
+ * ZMM16-ZMM31 (Hi16_ZMM state).
+ */
+struct avx_512_hi16_state {
+ struct reg_512_bit hi16_zmm[16];
+} __packed;
struct xstate_header {
u64 xfeatures;
@@ -159,22 +218,19 @@ struct xstate_header {
u64 reserved[6];
} __attribute__((packed));
-/* New processor state extensions should be added here: */
-#define XSTATE_RESERVE (sizeof(struct ymmh_struct) + \
- sizeof(struct lwp_struct) + \
- sizeof(struct mpx_struct) )
/*
* This is our most modern FPU state format, as saved by the XSAVE
* and restored by the XRSTOR instructions.
*
* It consists of a legacy fxregs portion, an xstate header and
- * subsequent fixed size areas as defined by the xstate header.
- * Not all CPUs support all the extensions.
+ * subsequent areas as defined by the xstate header. Not all CPUs
+ * support all the extensions, so the size of the extended area
+ * can vary quite a bit between CPUs.
*/
struct xregs_state {
struct fxregs_state i387;
struct xstate_header header;
- u8 __reserved[XSTATE_RESERVE];
+ u8 extended_state_area[0];
} __attribute__ ((packed, aligned (64)));
/*
@@ -182,7 +238,9 @@ struct xregs_state {
* put together, so that we can pick the right one runtime.
*
* The size of the structure is determined by the largest
- * member - which is the xsave area:
+ * member - which is the xsave area. The padding is there
+ * to ensure that statically-allocated task_structs (just
+ * the init_task today) have enough space.
*/
union fpregs_state {
struct fregs_state fsave;
diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index 4656b25..f23cd8c 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -6,7 +6,7 @@
#include <linux/uaccess.h>
/* Bit 63 of XCR0 is reserved for future expansion */
-#define XSTATE_EXTEND_MASK (~(XSTATE_FPSSE | (1ULL << 63)))
+#define XFEATURE_MASK_EXTEND (~(XFEATURE_MASK_FPSSE | (1ULL << 63)))
#define XSTATE_CPUID 0x0000000d
@@ -19,14 +19,18 @@
#define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
/* Supported features which support lazy state saving */
-#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
- | XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
+#define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \
+ XFEATURE_MASK_SSE | \
+ XFEATURE_MASK_YMM | \
+ XFEATURE_MASK_OPMASK | \
+ XFEATURE_MASK_ZMM_Hi256 | \
+ XFEATURE_MASK_Hi16_ZMM)
/* Supported features which require eager state saving */
-#define XSTATE_EAGER (XSTATE_BNDREGS | XSTATE_BNDCSR)
+#define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR)
/* All currently supported features */
-#define XCNTXT_MASK (XSTATE_LAZY | XSTATE_EAGER)
+#define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER)
#ifdef CONFIG_X86_64
#define REX_PREFIX "0x48, "
@@ -40,6 +44,7 @@ extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
+void fpu__xstate_clear_all_cpu_caps(void);
void *get_xsave_addr(struct xregs_state *xsave, int xstate);
const void *get_xsave_field_ptr(int xstate_field);
diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h
index 793179c..6e4d170 100644
--- a/arch/x86/include/asm/frame.h
+++ b/arch/x86/include/asm/frame.h
@@ -1,23 +1,44 @@
-#ifdef __ASSEMBLY__
+#ifndef _ASM_X86_FRAME_H
+#define _ASM_X86_FRAME_H
#include <asm/asm.h>
-/* The annotation hides the frame from the unwinder and makes it look
- like a ordinary ebp save/restore. This avoids some special cases for
- frame pointer later */
+/*
+ * These are stack frame creation macros. They should be used by every
+ * callable non-leaf asm function to make kernel stack traces more reliable.
+ */
+
#ifdef CONFIG_FRAME_POINTER
- .macro FRAME
- __ASM_SIZE(push,) %__ASM_REG(bp)
- __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp)
- .endm
- .macro ENDFRAME
- __ASM_SIZE(pop,) %__ASM_REG(bp)
- .endm
-#else
- .macro FRAME
- .endm
- .macro ENDFRAME
- .endm
-#endif
-
-#endif /* __ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+
+.macro FRAME_BEGIN
+ push %_ASM_BP
+ _ASM_MOV %_ASM_SP, %_ASM_BP
+.endm
+
+.macro FRAME_END
+ pop %_ASM_BP
+.endm
+
+#else /* !__ASSEMBLY__ */
+
+#define FRAME_BEGIN \
+ "push %" _ASM_BP "\n" \
+ _ASM_MOV "%" _ASM_SP ", %" _ASM_BP "\n"
+
+#define FRAME_END "pop %" _ASM_BP "\n"
+
+#endif /* __ASSEMBLY__ */
+
+#define FRAME_OFFSET __ASM_SEL(4, 8)
+
+#else /* !CONFIG_FRAME_POINTER */
+
+#define FRAME_BEGIN
+#define FRAME_END
+#define FRAME_OFFSET 0
+
+#endif /* CONFIG_FRAME_POINTER */
+
+#endif /* _ASM_X86_FRAME_H */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/x86/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h
index 04e9d02..1c0b437 100644
--- a/arch/x86/include/asm/highmem.h
+++ b/arch/x86/include/asm/highmem.h
@@ -68,7 +68,6 @@ void *kmap_atomic(struct page *page);
void __kunmap_atomic(void *kvaddr);
void *kmap_atomic_pfn(unsigned long pfn);
void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
-struct page *kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() do { } while (0)
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 5fa9fb0..cc285ec 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -63,10 +63,10 @@
/* hpet memory map physical address */
extern unsigned long hpet_address;
extern unsigned long force_hpet_address;
-extern int boot_hpet_disable;
+extern bool boot_hpet_disable;
extern u8 hpet_blockid;
-extern int hpet_force_user;
-extern u8 hpet_msi_disable;
+extern bool hpet_force_user;
+extern bool hpet_msi_disable;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
extern void hpet_disable(void);
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 1e3408e..1815b73 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -130,6 +130,11 @@ struct irq_alloc_info {
char *uv_name;
};
#endif
+#if IS_ENABLED(CONFIG_VMD)
+ struct {
+ struct msi_desc *desc;
+ };
+#endif
};
};
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index ccffa53..39bcefc 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -60,6 +60,7 @@ struct legacy_pic {
void (*mask_all)(void);
void (*restore_mask)(void);
void (*init)(int auto_eoi);
+ int (*probe)(void);
int (*irq_pending)(unsigned int irq);
void (*make_irq)(unsigned int irq);
};
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 2801976..a9bdf55 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -10,7 +10,7 @@
* 32 bit structures for IA32 support.
*/
-#include <asm/sigcontext32.h>
+#include <uapi/asm/sigcontext.h>
/* signal.h */
@@ -18,7 +18,7 @@ struct ucontext_ia32 {
unsigned int uc_flags;
unsigned int uc_link;
compat_stack_t uc_stack;
- struct sigcontext_ia32 uc_mcontext;
+ struct sigcontext_32 uc_mcontext;
compat_sigset_t uc_sigmask; /* mask last for extensibility */
};
diff --git a/arch/x86/include/asm/imr.h b/arch/x86/include/asm/imr.h
index cd2ce40..ebea2c9 100644
--- a/arch/x86/include/asm/imr.h
+++ b/arch/x86/include/asm/imr.h
@@ -53,7 +53,7 @@
#define IMR_MASK (IMR_ALIGN - 1)
int imr_add_range(phys_addr_t base, size_t size,
- unsigned int rmask, unsigned int wmask, bool lock);
+ unsigned int rmask, unsigned int wmask);
int imr_remove_range(phys_addr_t base, size_t size);
diff --git a/arch/x86/include/asm/intel_pt.h b/arch/x86/include/asm/intel_pt.h
new file mode 100644
index 0000000..e1a4117
--- /dev/null
+++ b/arch/x86/include/asm/intel_pt.h
@@ -0,0 +1,10 @@
+#ifndef _ASM_X86_INTEL_PT_H
+#define _ASM_X86_INTEL_PT_H
+
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+void cpu_emergency_stop_pt(void);
+#else
+static inline void cpu_emergency_stop_pt(void) {}
+#endif
+
+#endif /* _ASM_X86_INTEL_PT_H */
diff --git a/arch/x86/include/asm/intel_punit_ipc.h b/arch/x86/include/asm/intel_punit_ipc.h
new file mode 100644
index 0000000..201eb9d
--- /dev/null
+++ b/arch/x86/include/asm/intel_punit_ipc.h
@@ -0,0 +1,101 @@
+#ifndef _ASM_X86_INTEL_PUNIT_IPC_H_
+#define _ASM_X86_INTEL_PUNIT_IPC_H_
+
+/*
+ * Three types of 8bit P-Unit IPC commands are supported,
+ * bit[7:6]: [00]: BIOS; [01]: GTD; [10]: ISPD.
+ */
+typedef enum {
+ BIOS_IPC = 0,
+ GTDRIVER_IPC,
+ ISPDRIVER_IPC,
+ RESERVED_IPC,
+} IPC_TYPE;
+
+#define IPC_TYPE_OFFSET 6
+#define IPC_PUNIT_BIOS_CMD_BASE (BIOS_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_GTD_CMD_BASE (GTDDRIVER_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_ISPD_CMD_BASE (ISPDRIVER_IPC << IPC_TYPE_OFFSET)
+#define IPC_PUNIT_CMD_TYPE_MASK (RESERVED_IPC << IPC_TYPE_OFFSET)
+
+/* BIOS => Pcode commands */
+#define IPC_PUNIT_BIOS_ZERO (IPC_PUNIT_BIOS_CMD_BASE | 0x00)
+#define IPC_PUNIT_BIOS_VR_INTERFACE (IPC_PUNIT_BIOS_CMD_BASE | 0x01)
+#define IPC_PUNIT_BIOS_READ_PCS (IPC_PUNIT_BIOS_CMD_BASE | 0x02)
+#define IPC_PUNIT_BIOS_WRITE_PCS (IPC_PUNIT_BIOS_CMD_BASE | 0x03)
+#define IPC_PUNIT_BIOS_READ_PCU_CONFIG (IPC_PUNIT_BIOS_CMD_BASE | 0x04)
+#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG (IPC_PUNIT_BIOS_CMD_BASE | 0x05)
+#define IPC_PUNIT_BIOS_READ_PL1_SETTING (IPC_PUNIT_BIOS_CMD_BASE | 0x06)
+#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING (IPC_PUNIT_BIOS_CMD_BASE | 0x07)
+#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM (IPC_PUNIT_BIOS_CMD_BASE | 0x08)
+#define IPC_PUNIT_BIOS_READ_TELE_INFO (IPC_PUNIT_BIOS_CMD_BASE | 0x09)
+#define IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0a)
+#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0b)
+#define IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0c)
+#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0d)
+#define IPC_PUNIT_BIOS_READ_TELE_TRACE (IPC_PUNIT_BIOS_CMD_BASE | 0x0e)
+#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE (IPC_PUNIT_BIOS_CMD_BASE | 0x0f)
+#define IPC_PUNIT_BIOS_READ_TELE_EVENT (IPC_PUNIT_BIOS_CMD_BASE | 0x10)
+#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT (IPC_PUNIT_BIOS_CMD_BASE | 0x11)
+#define IPC_PUNIT_BIOS_READ_MODULE_TEMP (IPC_PUNIT_BIOS_CMD_BASE | 0x12)
+#define IPC_PUNIT_BIOS_RESERVED (IPC_PUNIT_BIOS_CMD_BASE | 0x13)
+#define IPC_PUNIT_BIOS_READ_VOLTAGE_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x14)
+#define IPC_PUNIT_BIOS_WRITE_VOLTAGE_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x15)
+#define IPC_PUNIT_BIOS_READ_RATIO_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x16)
+#define IPC_PUNIT_BIOS_WRITE_RATIO_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x17)
+#define IPC_PUNIT_BIOS_READ_VF_GL_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x18)
+#define IPC_PUNIT_BIOS_WRITE_VF_GL_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x19)
+#define IPC_PUNIT_BIOS_READ_FM_SOC_TEMP_THRESH (IPC_PUNIT_BIOS_CMD_BASE | 0x1a)
+#define IPC_PUNIT_BIOS_WRITE_FM_SOC_TEMP_THRESH (IPC_PUNIT_BIOS_CMD_BASE | 0x1b)
+
+/* GT Driver => Pcode commands */
+#define IPC_PUNIT_GTD_ZERO (IPC_PUNIT_GTD_CMD_BASE | 0x00)
+#define IPC_PUNIT_GTD_CONFIG (IPC_PUNIT_GTD_CMD_BASE | 0x01)
+#define IPC_PUNIT_GTD_READ_ICCP_LIC_CDYN_SCAL (IPC_PUNIT_GTD_CMD_BASE | 0x02)
+#define IPC_PUNIT_GTD_WRITE_ICCP_LIC_CDYN_SCAL (IPC_PUNIT_GTD_CMD_BASE | 0x03)
+#define IPC_PUNIT_GTD_GET_WM_VAL (IPC_PUNIT_GTD_CMD_BASE | 0x06)
+#define IPC_PUNIT_GTD_WRITE_CONFIG_WISHREQ (IPC_PUNIT_GTD_CMD_BASE | 0x07)
+#define IPC_PUNIT_GTD_READ_REQ_DUTY_CYCLE (IPC_PUNIT_GTD_CMD_BASE | 0x16)
+#define IPC_PUNIT_GTD_DIS_VOL_FREQ_CHG_REQUEST (IPC_PUNIT_GTD_CMD_BASE | 0x17)
+#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_CTRL (IPC_PUNIT_GTD_CMD_BASE | 0x1a)
+#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_TUNING (IPC_PUNIT_GTD_CMD_BASE | 0x1c)
+
+/* ISP Driver => Pcode commands */
+#define IPC_PUNIT_ISPD_ZERO (IPC_PUNIT_ISPD_CMD_BASE | 0x00)
+#define IPC_PUNIT_ISPD_CONFIG (IPC_PUNIT_ISPD_CMD_BASE | 0x01)
+#define IPC_PUNIT_ISPD_GET_ISP_LTR_VAL (IPC_PUNIT_ISPD_CMD_BASE | 0x02)
+#define IPC_PUNIT_ISPD_ACCESS_IU_FREQ_BOUNDS (IPC_PUNIT_ISPD_CMD_BASE | 0x03)
+#define IPC_PUNIT_ISPD_READ_CDYN_LEVEL (IPC_PUNIT_ISPD_CMD_BASE | 0x04)
+#define IPC_PUNIT_ISPD_WRITE_CDYN_LEVEL (IPC_PUNIT_ISPD_CMD_BASE | 0x05)
+
+/* Error codes */
+#define IPC_PUNIT_ERR_SUCCESS 0
+#define IPC_PUNIT_ERR_INVALID_CMD 1
+#define IPC_PUNIT_ERR_INVALID_PARAMETER 2
+#define IPC_PUNIT_ERR_CMD_TIMEOUT 3
+#define IPC_PUNIT_ERR_CMD_LOCKED 4
+#define IPC_PUNIT_ERR_INVALID_VR_ID 5
+#define IPC_PUNIT_ERR_VR_ERR 6
+
+#if IS_ENABLED(CONFIG_INTEL_PUNIT_IPC)
+
+int intel_punit_ipc_simple_command(int cmd, int para1, int para2);
+int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out);
+
+#else
+
+static inline int intel_punit_ipc_simple_command(int cmd,
+ int para1, int para2)
+{
+ return -ENODEV;
+}
+
+static inline int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2,
+ u32 *in, u32 *out)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_INTEL_PUNIT_IPC */
+
+#endif
diff --git a/arch/x86/include/asm/intel_telemetry.h b/arch/x86/include/asm/intel_telemetry.h
new file mode 100644
index 0000000..ed65fe7
--- /dev/null
+++ b/arch/x86/include/asm/intel_telemetry.h
@@ -0,0 +1,147 @@
+/*
+ * Intel SOC Telemetry Driver Header File
+ * Copyright (C) 2015, Intel 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.
+ *
+ */
+#ifndef INTEL_TELEMETRY_H
+#define INTEL_TELEMETRY_H
+
+#define TELEM_MAX_EVENTS_SRAM 28
+#define TELEM_MAX_OS_ALLOCATED_EVENTS 20
+
+enum telemetry_unit {
+ TELEM_PSS = 0,
+ TELEM_IOSS,
+ TELEM_UNIT_NONE
+};
+
+struct telemetry_evtlog {
+ u32 telem_evtid;
+ u64 telem_evtlog;
+};
+
+struct telemetry_evtconfig {
+ /* Array of Event-IDs to Enable */
+ u32 *evtmap;
+
+ /* Number of Events (<29) in evtmap */
+ u8 num_evts;
+
+ /* Sampling period */
+ u8 period;
+};
+
+struct telemetry_evtmap {
+ const char *name;
+ u32 evt_id;
+};
+
+struct telemetry_unit_config {
+ struct telemetry_evtmap *telem_evts;
+ void __iomem *regmap;
+ u32 ssram_base_addr;
+ u8 ssram_evts_used;
+ u8 curr_period;
+ u8 max_period;
+ u8 min_period;
+ u32 ssram_size;
+
+};
+
+struct telemetry_plt_config {
+ struct telemetry_unit_config pss_config;
+ struct telemetry_unit_config ioss_config;
+ struct mutex telem_trace_lock;
+ struct mutex telem_lock;
+ bool telem_in_use;
+};
+
+struct telemetry_core_ops {
+ int (*get_sampling_period)(u8 *pss_min_period, u8 *pss_max_period,
+ u8 *ioss_min_period, u8 *ioss_max_period);
+
+ int (*get_eventconfig)(struct telemetry_evtconfig *pss_evtconfig,
+ struct telemetry_evtconfig *ioss_evtconfig,
+ int pss_len, int ioss_len);
+
+ int (*update_events)(struct telemetry_evtconfig pss_evtconfig,
+ struct telemetry_evtconfig ioss_evtconfig);
+
+ int (*set_sampling_period)(u8 pss_period, u8 ioss_period);
+
+ int (*get_trace_verbosity)(enum telemetry_unit telem_unit,
+ u32 *verbosity);
+
+ int (*set_trace_verbosity)(enum telemetry_unit telem_unit,
+ u32 verbosity);
+
+ int (*raw_read_eventlog)(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog,
+ int len, int log_all_evts);
+
+ int (*read_eventlog)(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog,
+ int len, int log_all_evts);
+
+ int (*add_events)(u8 num_pss_evts, u8 num_ioss_evts,
+ u32 *pss_evtmap, u32 *ioss_evtmap);
+
+ int (*reset_events)(void);
+};
+
+int telemetry_set_pltdata(struct telemetry_core_ops *ops,
+ struct telemetry_plt_config *pltconfig);
+
+int telemetry_clear_pltdata(void);
+
+int telemetry_pltconfig_valid(void);
+
+int telemetry_get_evtname(enum telemetry_unit telem_unit,
+ const char **name, int len);
+
+int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
+ struct telemetry_evtconfig ioss_evtconfig);
+
+int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+ u32 *pss_evtmap, u32 *ioss_evtmap);
+
+int telemetry_reset_events(void);
+
+int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_config,
+ struct telemetry_evtconfig *ioss_config,
+ int pss_len, int ioss_len);
+
+int telemetry_read_events(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_raw_read_events(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_read_eventlog(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
+ struct telemetry_evtlog *evtlog, int len);
+
+int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
+ u8 *ioss_min_period, u8 *ioss_max_period);
+
+int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period);
+
+int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit,
+ u32 verbosity);
+
+int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
+ u32 *verbosity);
+
+#endif /* INTEL_TELEMETRY_H */
diff --git a/arch/x86/include/asm/iosf_mbi.h b/arch/x86/include/asm/iosf_mbi.h
index b72ad0f..b41ee16 100644
--- a/arch/x86/include/asm/iosf_mbi.h
+++ b/arch/x86/include/asm/iosf_mbi.h
@@ -1,5 +1,5 @@
/*
- * iosf_mbi.h: Intel OnChip System Fabric MailBox access support
+ * Intel OnChip System Fabric MailBox access support
*/
#ifndef IOSF_MBI_SYMS_H
@@ -16,6 +16,18 @@
#define MBI_MASK_LO 0x000000FF
#define MBI_ENABLE 0xF0
+/* IOSF SB read/write opcodes */
+#define MBI_MMIO_READ 0x00
+#define MBI_MMIO_WRITE 0x01
+#define MBI_CFG_READ 0x04
+#define MBI_CFG_WRITE 0x05
+#define MBI_CR_READ 0x06
+#define MBI_CR_WRITE 0x07
+#define MBI_REG_READ 0x10
+#define MBI_REG_WRITE 0x11
+#define MBI_ESRAM_READ 0x12
+#define MBI_ESRAM_WRITE 0x13
+
/* Baytrail available units */
#define BT_MBI_UNIT_AUNIT 0x00
#define BT_MBI_UNIT_SMC 0x01
@@ -28,50 +40,13 @@
#define BT_MBI_UNIT_SATA 0xA3
#define BT_MBI_UNIT_PCIE 0xA6
-/* Baytrail read/write opcodes */
-#define BT_MBI_AUNIT_READ 0x10
-#define BT_MBI_AUNIT_WRITE 0x11
-#define BT_MBI_SMC_READ 0x10
-#define BT_MBI_SMC_WRITE 0x11
-#define BT_MBI_CPU_READ 0x10
-#define BT_MBI_CPU_WRITE 0x11
-#define BT_MBI_BUNIT_READ 0x10
-#define BT_MBI_BUNIT_WRITE 0x11
-#define BT_MBI_PMC_READ 0x06
-#define BT_MBI_PMC_WRITE 0x07
-#define BT_MBI_GFX_READ 0x00
-#define BT_MBI_GFX_WRITE 0x01
-#define BT_MBI_SMIO_READ 0x06
-#define BT_MBI_SMIO_WRITE 0x07
-#define BT_MBI_USB_READ 0x06
-#define BT_MBI_USB_WRITE 0x07
-#define BT_MBI_SATA_READ 0x00
-#define BT_MBI_SATA_WRITE 0x01
-#define BT_MBI_PCIE_READ 0x00
-#define BT_MBI_PCIE_WRITE 0x01
-
/* Quark available units */
#define QRK_MBI_UNIT_HBA 0x00
#define QRK_MBI_UNIT_HB 0x03
#define QRK_MBI_UNIT_RMU 0x04
#define QRK_MBI_UNIT_MM 0x05
-#define QRK_MBI_UNIT_MMESRAM 0x05
#define QRK_MBI_UNIT_SOC 0x31
-/* Quark read/write opcodes */
-#define QRK_MBI_HBA_READ 0x10
-#define QRK_MBI_HBA_WRITE 0x11
-#define QRK_MBI_HB_READ 0x10
-#define QRK_MBI_HB_WRITE 0x11
-#define QRK_MBI_RMU_READ 0x10
-#define QRK_MBI_RMU_WRITE 0x11
-#define QRK_MBI_MM_READ 0x10
-#define QRK_MBI_MM_WRITE 0x11
-#define QRK_MBI_MMESRAM_READ 0x12
-#define QRK_MBI_MMESRAM_WRITE 0x13
-#define QRK_MBI_SOC_READ 0x06
-#define QRK_MBI_SOC_WRITE 0x07
-
#if IS_ENABLED(CONFIG_IOSF_MBI)
bool iosf_mbi_available(void);
diff --git a/arch/x86/include/asm/ipi.h b/arch/x86/include/asm/ipi.h
index 615fa90..a4fe16e 100644
--- a/arch/x86/include/asm/ipi.h
+++ b/arch/x86/include/asm/ipi.h
@@ -57,68 +57,16 @@ static inline void __xapic_wait_icr_idle(void)
cpu_relax();
}
-static inline void
-__default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
-{
- /*
- * Subtle. In the case of the 'never do double writes' workaround
- * we have to lock out interrupts to be safe. As we don't care
- * of the value read we use an atomic rmw access to avoid costly
- * cli/sti. Otherwise we use an even cheaper single atomic write
- * to the APIC.
- */
- unsigned int cfg;
-
- /*
- * Wait for idle.
- */
- __xapic_wait_icr_idle();
-
- /*
- * No need to touch the target chip field
- */
- cfg = __prepare_ICR(shortcut, vector, dest);
-
- /*
- * Send the IPI. The write to APIC_ICR fires this off.
- */
- native_apic_mem_write(APIC_ICR, cfg);
-}
+void __default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest);
/*
* This is used to send an IPI with no shorthand notation (the destination is
* specified in bits 56 to 63 of the ICR).
*/
-static inline void
- __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
-{
- unsigned long cfg;
-
- /*
- * Wait for idle.
- */
- if (unlikely(vector == NMI_VECTOR))
- safe_apic_wait_icr_idle();
- else
- __xapic_wait_icr_idle();
-
- /*
- * prepare target chip field
- */
- cfg = __prepare_ICR2(mask);
- native_apic_mem_write(APIC_ICR2, cfg);
-
- /*
- * program the ICR
- */
- cfg = __prepare_ICR(0, vector, dest);
-
- /*
- * Send the IPI. The write to APIC_ICR fires this off.
- */
- native_apic_mem_write(APIC_ICR, cfg);
-}
+void __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest);
+extern void default_send_IPI_single(int cpu, int vector);
+extern void default_send_IPI_single_phys(int cpu, int vector);
extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
int vector);
extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 881b476..e7de5c9 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -23,11 +23,13 @@ extern void irq_ctx_init(int cpu);
#define __ARCH_HAS_DO_SOFTIRQ
+struct irq_desc;
+
#ifdef CONFIG_HOTPLUG_CPU
#include <linux/cpumask.h>
extern int check_irq_vectors_for_cpu_disable(void);
extern void fixup_irqs(void);
-extern void irq_force_complete_move(int);
+extern void irq_force_complete_move(struct irq_desc *desc);
#endif
#ifdef CONFIG_HAVE_KVM
@@ -37,7 +39,6 @@ extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));
extern void (*x86_platform_ipi_callback)(void);
extern void native_init_IRQ(void);
-struct irq_desc;
extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
extern __visible unsigned int do_IRQ(struct pt_regs *regs);
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 046c7fb..a210eba 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -33,6 +33,11 @@ enum irq_remap_cap {
IRQ_POSTING_CAP = 0,
};
+struct vcpu_data {
+ u64 pi_desc_addr; /* Physical address of PI Descriptor */
+ u32 vector; /* Guest vector of the interrupt */
+};
+
#ifdef CONFIG_IRQ_REMAP
extern bool irq_remapping_cap(enum irq_remap_cap cap);
@@ -58,11 +63,6 @@ static inline struct irq_domain *arch_get_ir_parent_domain(void)
return x86_vector_domain;
}
-struct vcpu_data {
- u64 pi_desc_addr; /* Physical address of PI Descriptor */
- u32 vector; /* Guest vector of the interrupt */
-};
-
#else /* CONFIG_IRQ_REMAP */
static inline bool irq_remapping_cap(enum irq_remap_cap cap) { return 0; }
diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h
index 78162f8..d0afb05 100644
--- a/arch/x86/include/asm/irq_work.h
+++ b/arch/x86/include/asm/irq_work.h
@@ -1,7 +1,7 @@
#ifndef _ASM_IRQ_WORK_H
#define _ASM_IRQ_WORK_H
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
static inline bool arch_irq_work_has_interrupt(void)
{
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 5daeca3..adc54c1 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -1,12 +1,18 @@
#ifndef _ASM_X86_JUMP_LABEL_H
#define _ASM_X86_JUMP_LABEL_H
-#ifndef __ASSEMBLY__
-
-#include <linux/stringify.h>
-#include <linux/types.h>
-#include <asm/nops.h>
-#include <asm/asm.h>
+#ifndef HAVE_JUMP_LABEL
+/*
+ * For better or for worse, if jump labels (the gcc extension) are missing,
+ * then the entire static branch patching infrastructure is compiled out.
+ * If that happens, the code in here will malfunction. Raise a compiler
+ * error instead.
+ *
+ * In theory, jump labels and the static branch patching infrastructure
+ * could be decoupled to fix this.
+ */
+#error asm/jump_label.h included on a non-jump-label kernel
+#endif
#define JUMP_LABEL_NOP_SIZE 5
@@ -16,6 +22,14 @@
# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC
#endif
+#include <asm/asm.h>
+#include <asm/nops.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
asm_volatile_goto("1:"
@@ -59,5 +73,40 @@ struct jump_entry {
jump_label_t key;
};
-#endif /* __ASSEMBLY__ */
+#else /* __ASSEMBLY__ */
+
+.macro STATIC_JUMP_IF_TRUE target, key, def
+.Lstatic_jump_\@:
+ .if \def
+ /* Equivalent to "jmp.d32 \target" */
+ .byte 0xe9
+ .long \target - .Lstatic_jump_after_\@
+.Lstatic_jump_after_\@:
+ .else
+ .byte STATIC_KEY_INIT_NOP
+ .endif
+ .pushsection __jump_table, "aw"
+ _ASM_ALIGN
+ _ASM_PTR .Lstatic_jump_\@, \target, \key
+ .popsection
+.endm
+
+.macro STATIC_JUMP_IF_FALSE target, key, def
+.Lstatic_jump_\@:
+ .if \def
+ .byte STATIC_KEY_INIT_NOP
+ .else
+ /* Equivalent to "jmp.d32 \target" */
+ .byte 0xe9
+ .long \target - .Lstatic_jump_after_\@
+.Lstatic_jump_after_\@:
+ .endif
+ .pushsection __jump_table, "aw"
+ _ASM_ALIGN
+ _ASM_PTR .Lstatic_jump_\@, \target, \key + 1
+ .popsection
+.endm
+
+#endif /* __ASSEMBLY__ */
+
#endif
diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h
index b130d59..e5f5dc9 100644
--- a/arch/x86/include/asm/kdebug.h
+++ b/arch/x86/include/asm/kdebug.h
@@ -29,11 +29,5 @@ extern void show_trace(struct task_struct *t, struct pt_regs *regs,
extern void __show_regs(struct pt_regs *regs, int all);
extern unsigned long oops_begin(void);
extern void oops_end(unsigned long, struct pt_regs *, int signr);
-#ifdef CONFIG_KEXEC_CORE
-extern int in_crash_kexec;
-#else
-/* no crash dump is ever in progress if no crash kernel can be kexec'd */
-#define in_crash_kexec 0
-#endif
#endif /* _ASM_X86_KDEBUG_H */
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index e16466e..e9cd7be 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -112,6 +112,16 @@ struct x86_emulate_ops {
struct x86_exception *fault);
/*
+ * read_phys: Read bytes of standard (non-emulated/special) memory.
+ * Used for descriptor reading.
+ * @addr: [IN ] Physical address from which to read.
+ * @val: [OUT] Value read from memory.
+ * @bytes: [IN ] Number of bytes to read from memory.
+ */
+ int (*read_phys)(struct x86_emulate_ctxt *ctxt, unsigned long addr,
+ void *val, unsigned int bytes);
+
+ /*
* write_std: Write bytes of standard (non-emulated/special) memory.
* Used for descriptor writing.
* @addr: [IN ] Linear address to which to write.
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3a36ee7..01c8b50 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -24,12 +24,15 @@
#include <linux/perf_event.h>
#include <linux/pvclock_gtod.h>
#include <linux/clocksource.h>
+#include <linux/irqbypass.h>
+#include <linux/hyperv.h>
#include <asm/pvclock-abi.h>
#include <asm/desc.h>
#include <asm/mtrr.h>
#include <asm/msr-index.h>
#include <asm/asm.h>
+#include <asm/kvm_page_track.h>
#define KVM_MAX_VCPUS 255
#define KVM_SOFT_MAX_VCPUS 160
@@ -44,6 +47,31 @@
#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS
+/* x86-specific vcpu->requests bit members */
+#define KVM_REQ_MIGRATE_TIMER 8
+#define KVM_REQ_REPORT_TPR_ACCESS 9
+#define KVM_REQ_TRIPLE_FAULT 10
+#define KVM_REQ_MMU_SYNC 11
+#define KVM_REQ_CLOCK_UPDATE 12
+#define KVM_REQ_DEACTIVATE_FPU 13
+#define KVM_REQ_EVENT 14
+#define KVM_REQ_APF_HALT 15
+#define KVM_REQ_STEAL_UPDATE 16
+#define KVM_REQ_NMI 17
+#define KVM_REQ_PMU 18
+#define KVM_REQ_PMI 19
+#define KVM_REQ_SMI 20
+#define KVM_REQ_MASTERCLOCK_UPDATE 21
+#define KVM_REQ_MCLOCK_INPROGRESS 22
+#define KVM_REQ_SCAN_IOAPIC 23
+#define KVM_REQ_GLOBAL_CLOCK_UPDATE 24
+#define KVM_REQ_APIC_PAGE_RELOAD 25
+#define KVM_REQ_HV_CRASH 26
+#define KVM_REQ_IOAPIC_EOI_EXIT 27
+#define KVM_REQ_HV_RESET 28
+#define KVM_REQ_HV_EXIT 29
+#define KVM_REQ_HV_STIMER 30
+
#define CR0_RESERVED_BITS \
(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
| X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
@@ -176,6 +204,8 @@ enum {
*/
#define KVM_APIC_PV_EOI_PENDING 1
+struct kvm_kernel_irq_routing_entry;
+
/*
* We don't want allocation failures within the mmu code, so we preallocate
* enough memory for a single page fault in a cache.
@@ -185,6 +215,14 @@ struct kvm_mmu_memory_cache {
void *objects[KVM_NR_MEM_OBJS];
};
+/*
+ * the pages used as guest page table on soft mmu are tracked by
+ * kvm_memory_slot.arch.gfn_track which is 16 bits, so the role bits used
+ * by indirect shadow page can not be more than 15 bits.
+ *
+ * Currently, we used 14 bits that are @level, @cr4_pae, @quadrant, @access,
+ * @nxe, @cr0_wp, @smep_andnot_wp and @smap_andnot_wp.
+ */
union kvm_mmu_page_role {
unsigned word;
struct {
@@ -210,6 +248,10 @@ union kvm_mmu_page_role {
};
};
+struct kvm_rmap_head {
+ unsigned long val;
+};
+
struct kvm_mmu_page {
struct list_head link;
struct hlist_node hash_link;
@@ -227,7 +269,7 @@ struct kvm_mmu_page {
bool unsync;
int root_count; /* Currently serving as active root */
unsigned int unsync_children;
- unsigned long parent_ptes; /* Reverse mapping for parent_pte */
+ struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
/* The page is obsolete if mmu_valid_gen != kvm->arch.mmu_valid_gen. */
unsigned long mmu_valid_gen;
@@ -243,7 +285,7 @@ struct kvm_mmu_page {
#endif
/* Number of writes since the last time traversal visited this page. */
- int write_flooding_count;
+ atomic_t write_flooding_count;
};
struct kvm_pio_request {
@@ -305,12 +347,8 @@ struct kvm_mmu {
struct rsvd_bits_validate guest_rsvd_check;
- /*
- * Bitmap: bit set = last pte in walk
- * index[0:1]: level (zero-based)
- * index[2]: pte.ps
- */
- u8 last_pte_bitmap;
+ /* Can have large pages at levels 2..last_nonleaf_level-1. */
+ u8 last_nonleaf_level;
bool nx;
@@ -371,9 +409,38 @@ struct kvm_mtrr {
struct list_head head;
};
+/* Hyper-V SynIC timer */
+struct kvm_vcpu_hv_stimer {
+ struct hrtimer timer;
+ int index;
+ u64 config;
+ u64 count;
+ u64 exp_time;
+ struct hv_message msg;
+ bool msg_pending;
+};
+
+/* Hyper-V synthetic interrupt controller (SynIC)*/
+struct kvm_vcpu_hv_synic {
+ u64 version;
+ u64 control;
+ u64 msg_page;
+ u64 evt_page;
+ atomic64_t sint[HV_SYNIC_SINT_COUNT];
+ atomic_t sint_to_gsi[HV_SYNIC_SINT_COUNT];
+ DECLARE_BITMAP(auto_eoi_bitmap, 256);
+ DECLARE_BITMAP(vec_bitmap, 256);
+ bool active;
+};
+
/* Hyper-V per vcpu emulation context */
struct kvm_vcpu_hv {
u64 hv_vapic;
+ s64 runtime_offset;
+ struct kvm_vcpu_hv_synic synic;
+ struct kvm_hyperv_exit exit;
+ struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
+ DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
};
struct kvm_vcpu_arch {
@@ -396,6 +463,8 @@ struct kvm_vcpu_arch {
u64 efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
+ bool apicv_active;
+ DECLARE_BITMAP(ioapic_handled_vectors, 256);
unsigned long apic_attention;
int32_t apic_arb_prio;
int mp_state;
@@ -434,7 +503,6 @@ struct kvm_vcpu_arch {
struct kvm_mmu_memory_cache mmu_page_header_cache;
struct fpu guest_fpu;
- bool eager_fpu;
u64 xcr0;
u64 guest_supported_xcr0;
u32 guest_xstate_size;
@@ -500,6 +568,7 @@ struct kvm_vcpu_arch {
u32 virtual_tsc_mult;
u32 virtual_tsc_khz;
s64 ia32_tsc_adjust_msr;
+ u64 tsc_scaling_ratio;
atomic_t nmi_queued; /* unprocessed asynchronous NMIs */
unsigned nmi_pending; /* NMI queued after currently running handler */
@@ -573,15 +642,19 @@ struct kvm_vcpu_arch {
struct {
bool pv_unhalted;
} pv;
+
+ int pending_ioapic_eoi;
+ int pending_external_vector;
};
struct kvm_lpage_info {
- int write_count;
+ int disallow_lpage;
};
struct kvm_arch_memory_slot {
- unsigned long *rmap[KVM_NR_PAGE_SIZES];
+ struct kvm_rmap_head *rmap[KVM_NR_PAGE_SIZES];
struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
+ unsigned short *gfn_track[KVM_PAGE_TRACK_MAX];
};
/*
@@ -626,6 +699,8 @@ struct kvm_arch {
*/
struct list_head active_mmu_pages;
struct list_head zapped_obsolete_pages;
+ struct kvm_page_track_notifier_node mmu_sp_tracker;
+ struct kvm_page_track_notifier_head track_notifier_head;
struct list_head assigned_dev_head;
struct iommu_domain *iommu_domain;
@@ -683,6 +758,11 @@ struct kvm_arch {
u32 bsp_vcpu_id;
u64 disabled_quirks;
+
+ bool irqchip_split;
+ u8 nr_reserved_ioapic_pins;
+
+ bool disabled_lapic_found;
};
struct kvm_vm_stat {
@@ -766,7 +846,7 @@ struct kvm_x86_ops {
void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
- void (*update_db_bp_intercept)(struct kvm_vcpu *vcpu);
+ void (*update_bp_intercept)(struct kvm_vcpu *vcpu);
int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -819,7 +899,8 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
- int (*vm_has_apicv)(struct kvm *kvm);
+ bool (*get_enable_apicv)(void);
+ void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(struct kvm *kvm, int isr);
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
@@ -833,7 +914,7 @@ struct kvm_x86_ops {
int (*get_lpage_level)(void);
bool (*rdtscp_supported)(void);
bool (*invpcid_supported)(void);
- void (*adjust_tsc_offset)(struct kvm_vcpu *vcpu, s64 adjustment, bool host);
+ void (*adjust_tsc_offset_guest)(struct kvm_vcpu *vcpu, s64 adjustment);
void (*set_tdp_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
@@ -841,11 +922,9 @@ struct kvm_x86_ops {
bool (*has_wbinvd_exit)(void);
- void (*set_tsc_khz)(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale);
u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
- u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc);
u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu, u64 host_tsc);
void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
@@ -887,6 +966,20 @@ struct kvm_x86_ops {
gfn_t offset, unsigned long mask);
/* pmu operations of sub-arch */
const struct kvm_pmu_ops *pmu_ops;
+
+ /*
+ * Architecture specific hooks for vCPU blocking due to
+ * HLT instruction.
+ * Returns for .pre_block():
+ * - 0 means continue to block the vCPU.
+ * - 1 means we cannot block the vCPU since some event
+ * happens during this period, such as, 'ON' bit in
+ * posted-interrupts descriptor is set.
+ */
+ int (*pre_block)(struct kvm_vcpu *vcpu);
+ void (*post_block)(struct kvm_vcpu *vcpu);
+ int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set);
};
struct kvm_arch_async_pf {
@@ -898,23 +991,14 @@ struct kvm_arch_async_pf {
extern struct kvm_x86_ops *kvm_x86_ops;
-static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
- s64 adjustment)
-{
- kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
-}
-
-static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
-{
- kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
-}
-
int kvm_mmu_module_init(void);
void kvm_mmu_module_exit(void);
void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
int kvm_mmu_create(struct kvm_vcpu *vcpu);
void kvm_mmu_setup(struct kvm_vcpu *vcpu);
+void kvm_mmu_init_vm(struct kvm *kvm);
+void kvm_mmu_uninit_vm(struct kvm *kvm);
void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
u64 dirty_mask, u64 nx_mask, u64 x_mask);
@@ -961,10 +1045,12 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu);
/* control of guest tsc rate supported? */
extern bool kvm_has_tsc_control;
-/* minimum supported tsc_khz for guests */
-extern u32 kvm_min_guest_tsc_khz;
/* maximum supported tsc_khz for guests */
extern u32 kvm_max_guest_tsc_khz;
+/* number of bits of the fractional part of the TSC scaling ratio */
+extern u8 kvm_tsc_scaling_ratio_frac_bits;
+/* maximum allowed value of TSC scaling ratio */
+extern u64 kvm_max_tsc_scaling_ratio;
enum emulation_result {
EMULATE_DONE, /* no further processing */
@@ -1052,8 +1138,6 @@ void kvm_pic_clear_all(struct kvm_pic *pic, int irq_source_id);
void kvm_inject_nmi(struct kvm_vcpu *vcpu);
-void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
- const u8 *new, int bytes);
int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn);
int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
@@ -1071,6 +1155,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
struct x86_exception *exception);
+void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu);
+
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code,
@@ -1210,9 +1296,15 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
void kvm_define_shared_msr(unsigned index, u32 msr);
int kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc);
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc);
+
unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu);
bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip);
+void kvm_make_mclock_inprogress_request(struct kvm *kvm);
+void kvm_make_scan_ioapic_request(struct kvm *kvm);
+
void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
struct kvm_async_pf *work);
void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
@@ -1231,4 +1323,13 @@ int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size);
bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
+bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
+ struct kvm_vcpu **dest_vcpu);
+
+void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm_lapic_irq *irq);
+
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
new file mode 100644
index 0000000..c2b8d24
--- /dev/null
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -0,0 +1,61 @@
+#ifndef _ASM_X86_KVM_PAGE_TRACK_H
+#define _ASM_X86_KVM_PAGE_TRACK_H
+
+enum kvm_page_track_mode {
+ KVM_PAGE_TRACK_WRITE,
+ KVM_PAGE_TRACK_MAX,
+};
+
+/*
+ * The notifier represented by @kvm_page_track_notifier_node is linked into
+ * the head which will be notified when guest is triggering the track event.
+ *
+ * Write access on the head is protected by kvm->mmu_lock, read access
+ * is protected by track_srcu.
+ */
+struct kvm_page_track_notifier_head {
+ struct srcu_struct track_srcu;
+ struct hlist_head track_notifier_list;
+};
+
+struct kvm_page_track_notifier_node {
+ struct hlist_node node;
+
+ /*
+ * It is called when guest is writing the write-tracked page
+ * and write emulation is finished at that time.
+ *
+ * @vcpu: the vcpu where the write access happened.
+ * @gpa: the physical address written by guest.
+ * @new: the data was written to the address.
+ * @bytes: the written length.
+ */
+ void (*track_write)(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
+ int bytes);
+};
+
+void kvm_page_track_init(struct kvm *kvm);
+
+void kvm_page_track_free_memslot(struct kvm_memory_slot *free,
+ struct kvm_memory_slot *dont);
+int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+ unsigned long npages);
+
+void kvm_slot_page_track_add_page(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn,
+ enum kvm_page_track_mode mode);
+void kvm_slot_page_track_remove_page(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn,
+ enum kvm_page_track_mode mode);
+bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
+ enum kvm_page_track_mode mode);
+
+void
+kvm_page_track_register_notifier(struct kvm *kvm,
+ struct kvm_page_track_notifier_node *n);
+void
+kvm_page_track_unregister_notifier(struct kvm *kvm,
+ struct kvm_page_track_notifier_node *n);
+void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
+ int bytes);
+#endif
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index c1adf33..bc62e7c 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -17,15 +17,8 @@ static inline bool kvm_check_and_clear_guest_paused(void)
}
#endif /* CONFIG_KVM_GUEST */
-#ifdef CONFIG_DEBUG_RODATA
#define KVM_HYPERCALL \
ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL)
-#else
-/* On AMD processors, vmcall will generate a trap that we will
- * then rewrite to the appropriate instruction.
- */
-#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
-#endif
/* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
* instruction. The hypervisor may replace it with something else but only the
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index 3bbc07a..73d0c9b 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -12,7 +12,9 @@
#define GUEST_PL 1
/* Page for Switcher text itself, then two pages per cpu */
-#define TOTAL_SWITCHER_PAGES (1 + 2 * nr_cpu_ids)
+#define SWITCHER_TEXT_PAGES (1)
+#define SWITCHER_STACK_PAGES (2 * nr_cpu_ids)
+#define TOTAL_SWITCHER_PAGES (SWITCHER_TEXT_PAGES + SWITCHER_STACK_PAGES)
/* Where we map the Switcher, in both Host and Guest. */
extern unsigned long switcher_addr;
diff --git a/arch/x86/include/asm/livepatch.h b/arch/x86/include/asm/livepatch.h
index 19c099a..7e68f95 100644
--- a/arch/x86/include/asm/livepatch.h
+++ b/arch/x86/include/asm/livepatch.h
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <linux/ftrace.h>
-#ifdef CONFIG_LIVEPATCH
static inline int klp_check_compiler_support(void)
{
#ifndef CC_USING_FENTRY
@@ -40,8 +39,5 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip)
{
regs->ip = ip;
}
-#else
-#error Live patching support is disabled; check CONFIG_LIVEPATCH
-#endif
#endif /* _ASM_X86_LIVEPATCH_H */
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 2dbc0bf..92b6f65 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -40,8 +40,20 @@
#define MCI_STATUS_AR (1ULL<<55) /* Action required */
/* AMD-specific bits */
-#define MCI_STATUS_DEFERRED (1ULL<<44) /* declare an uncorrected error */
+#define MCI_STATUS_DEFERRED (1ULL<<44) /* uncorrected error, deferred exception */
#define MCI_STATUS_POISON (1ULL<<43) /* access poisonous data */
+#define MCI_STATUS_TCC (1ULL<<55) /* Task context corrupt */
+
+/*
+ * McaX field if set indicates a given bank supports MCA extensions:
+ * - Deferred error interrupt type is specifiable by bank.
+ * - MCx_MISC0[BlkPtr] field indicates presence of extended MISC registers,
+ * But should not be used to determine MSR numbers.
+ * - TCC bit is present in MCx_STATUS.
+ */
+#define MCI_CONFIG_MCAX 0x1
+#define MCI_IPID_MCATYPE 0xFFFF0000
+#define MCI_IPID_HWID 0xFFF
/*
* Note that the full MCACOD field of IA32_MCi_STATUS MSR is
@@ -91,6 +103,16 @@
#define MCE_LOG_LEN 32
#define MCE_LOG_SIGNATURE "MACHINECHECK"
+/* AMD Scalable MCA */
+#define MSR_AMD64_SMCA_MC0_MISC0 0xc0002003
+#define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004
+#define MSR_AMD64_SMCA_MC0_IPID 0xc0002005
+#define MSR_AMD64_SMCA_MC0_MISC1 0xc000200a
+#define MSR_AMD64_SMCA_MCx_MISC(x) (MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_CONFIG(x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_IPID(x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x))
+#define MSR_AMD64_SMCA_MCx_MISCy(x, y) ((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))
+
/*
* This structure contains all data related to the MCE log. Also
* carries a signature to make it easier to find from external
@@ -113,6 +135,7 @@ struct mca_config {
bool ignore_ce;
bool disabled;
bool ser;
+ bool recovery;
bool bios_cmci_threshold;
u8 banks;
s8 bootlog;
@@ -123,19 +146,27 @@ struct mca_config {
};
struct mce_vendor_flags {
- /*
- * overflow recovery cpuid bit indicates that overflow
- * conditions are not fatal
- */
- __u64 overflow_recov : 1,
-
- /*
- * SUCCOR stands for S/W UnCorrectable error COntainment
- * and Recovery. It indicates support for data poisoning
- * in HW and deferred error interrupts.
- */
- succor : 1,
- __reserved_0 : 62;
+ /*
+ * Indicates that overflow conditions are not fatal, when set.
+ */
+ __u64 overflow_recov : 1,
+
+ /*
+ * (AMD) SUCCOR stands for S/W UnCorrectable error COntainment and
+ * Recovery. It indicates support for data poisoning in HW and deferred
+ * error interrupts.
+ */
+ succor : 1,
+
+ /*
+ * (AMD) SMCA: This bit indicates support for Scalable MCA which expands
+ * the register space for each MCA bank and also increases number of
+ * banks. Also, to accommodate the new banks and registers, the MCA
+ * register space is moved to a new MSR range.
+ */
+ smca : 1,
+
+ __reserved_0 : 61;
};
extern struct mce_vendor_flags mce_flags;
@@ -279,4 +310,49 @@ struct cper_sec_mem_err;
extern void apei_mce_report_mem_error(int corrected,
struct cper_sec_mem_err *mem_err);
+/*
+ * Enumerate new IP types and HWID values in AMD processors which support
+ * Scalable MCA.
+ */
+#ifdef CONFIG_X86_MCE_AMD
+enum amd_ip_types {
+ SMCA_F17H_CORE = 0, /* Core errors */
+ SMCA_DF, /* Data Fabric */
+ SMCA_UMC, /* Unified Memory Controller */
+ SMCA_PB, /* Parameter Block */
+ SMCA_PSP, /* Platform Security Processor */
+ SMCA_SMU, /* System Management Unit */
+ N_AMD_IP_TYPES
+};
+
+struct amd_hwid {
+ const char *name;
+ unsigned int hwid;
+};
+
+extern struct amd_hwid amd_hwids[N_AMD_IP_TYPES];
+
+enum amd_core_mca_blocks {
+ SMCA_LS = 0, /* Load Store */
+ SMCA_IF, /* Instruction Fetch */
+ SMCA_L2_CACHE, /* L2 cache */
+ SMCA_DE, /* Decoder unit */
+ RES, /* Reserved */
+ SMCA_EX, /* Execution unit */
+ SMCA_FP, /* Floating Point */
+ SMCA_L3_CACHE, /* L3 cache */
+ N_CORE_MCA_BLOCKS
+};
+
+extern const char * const amd_core_mcablock_names[N_CORE_MCA_BLOCKS];
+
+enum amd_df_mca_blocks {
+ SMCA_CS = 0, /* Coherent Slave */
+ SMCA_PIE, /* Power management, Interrupts, etc */
+ N_DF_BLOCKS
+};
+
+extern const char * const amd_df_mcablock_names[N_DF_BLOCKS];
+#endif
+
#endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index 9e6278c..9d3a96c 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -1,7 +1,9 @@
#ifndef _ASM_X86_MICROCODE_H
#define _ASM_X86_MICROCODE_H
+#include <asm/cpu.h>
#include <linux/earlycpio.h>
+#include <linux/initrd.h>
#define native_rdmsr(msr, val1, val2) \
do { \
@@ -27,7 +29,6 @@ struct cpu_signature {
struct device;
enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
-extern bool dis_ucode_ldr;
struct microcode_ops {
enum ucode_state (*request_microcode_user) (int cpu,
@@ -55,6 +56,12 @@ struct ucode_cpu_info {
};
extern struct ucode_cpu_info ucode_cpu_info[];
+#ifdef CONFIG_MICROCODE
+int __init microcode_init(void);
+#else
+static inline int __init microcode_init(void) { return 0; };
+#endif
+
#ifdef CONFIG_MICROCODE_INTEL
extern struct microcode_ops * __init init_intel_microcode(void);
#else
@@ -75,7 +82,6 @@ static inline struct microcode_ops * __init init_amd_microcode(void)
static inline void __exit exit_amd_microcode(void) {}
#endif
-#ifdef CONFIG_MICROCODE_EARLY
#define MAX_UCODE_COUNT 128
#define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
@@ -91,14 +97,14 @@ static inline void __exit exit_amd_microcode(void) {}
/*
* In early loading microcode phase on BSP, boot_cpu_data is not set up yet.
- * x86_vendor() gets vendor id for BSP.
+ * x86_cpuid_vendor() gets vendor id for BSP.
*
* In 32 bit AP case, accessing boot_cpu_data needs linear address. To simplify
- * coding, we still use x86_vendor() to get vendor id for AP.
+ * coding, we still use x86_cpuid_vendor() to get vendor id for AP.
*
- * x86_vendor() gets vendor information directly from CPUID.
+ * x86_cpuid_vendor() gets vendor information directly from CPUID.
*/
-static inline int x86_vendor(void)
+static inline int x86_cpuid_vendor(void)
{
u32 eax = 0x00000000;
u32 ebx, ecx = 0, edx;
@@ -114,58 +120,53 @@ static inline int x86_vendor(void)
return X86_VENDOR_UNKNOWN;
}
-static inline unsigned int __x86_family(unsigned int sig)
-{
- unsigned int x86;
-
- x86 = (sig >> 8) & 0xf;
-
- if (x86 == 0xf)
- x86 += (sig >> 20) & 0xff;
-
- return x86;
-}
-
-static inline unsigned int x86_family(void)
+static inline unsigned int x86_cpuid_family(void)
{
u32 eax = 0x00000001;
u32 ebx, ecx = 0, edx;
native_cpuid(&eax, &ebx, &ecx, &edx);
- return __x86_family(eax);
-}
-
-static inline unsigned int x86_model(unsigned int sig)
-{
- unsigned int x86, model;
-
- x86 = __x86_family(sig);
-
- model = (sig >> 4) & 0xf;
-
- if (x86 == 0x6 || x86 == 0xf)
- model += ((sig >> 16) & 0xf) << 4;
-
- return model;
+ return x86_family(eax);
}
+#ifdef CONFIG_MICROCODE
extern void __init load_ucode_bsp(void);
extern void load_ucode_ap(void);
extern int __init save_microcode_in_initrd(void);
void reload_early_microcode(void);
extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
#else
-static inline void __init load_ucode_bsp(void) {}
-static inline void load_ucode_ap(void) {}
-static inline int __init save_microcode_in_initrd(void)
+static inline void __init load_ucode_bsp(void) { }
+static inline void load_ucode_ap(void) { }
+static inline int __init save_microcode_in_initrd(void) { return 0; }
+static inline void reload_early_microcode(void) { }
+static inline bool
+get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; }
+#endif
+
+static inline unsigned long get_initrd_start(void)
{
+#ifdef CONFIG_BLK_DEV_INITRD
+ return initrd_start;
+#else
return 0;
+#endif
}
-static inline void reload_early_microcode(void) {}
-static inline bool get_builtin_firmware(struct cpio_data *cd, const char *name)
+
+static inline unsigned long get_initrd_start_addr(void)
{
- return false;
-}
+#ifdef CONFIG_BLK_DEV_INITRD
+#ifdef CONFIG_X86_32
+ unsigned long *initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+
+ return (unsigned long)__pa_nodebug(*initrd_start_p);
+#else
+ return get_initrd_start();
#endif
+#else /* CONFIG_BLK_DEV_INITRD */
+ return 0;
+#endif
+}
+
#endif /* _ASM_X86_MICROCODE_H */
diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index ac6d328..adfc847 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -64,7 +64,7 @@ extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, s
#define PATCH_MAX_SIZE PAGE_SIZE
extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
-#ifdef CONFIG_MICROCODE_AMD_EARLY
+#ifdef CONFIG_MICROCODE_AMD
extern void __init load_ucode_amd_bsp(unsigned int family);
extern void load_ucode_amd_ap(void);
extern int __init save_microcode_in_initrd_amd(void);
@@ -76,4 +76,5 @@ static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
void reload_ucode_amd(void) {}
#endif
+extern bool check_current_patch_level(u32 *rev, bool early);
#endif /* _ASM_X86_MICROCODE_AMD_H */
diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index 7991c60..603417f 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -40,7 +40,6 @@ struct extended_sigtable {
#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
-#define DWSIZE (sizeof(u32))
#define get_totalsize(mc) \
(((struct microcode_intel *)mc)->hdr.datasize ? \
@@ -57,7 +56,7 @@ extern int has_newer_microcode(void *mc, unsigned int csig, int cpf, int rev);
extern int microcode_sanity_check(void *mc, int print_err);
extern int find_matching_signature(void *mc, unsigned int csig, int cpf);
-#ifdef CONFIG_MICROCODE_INTEL_EARLY
+#ifdef CONFIG_MICROCODE_INTEL
extern void __init load_ucode_intel_bsp(void);
extern void load_ucode_intel_ap(void);
extern void show_ucode_info_early(void);
@@ -71,13 +70,9 @@ static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL;
static inline void reload_ucode_intel(void) {}
#endif
-#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
+#ifdef CONFIG_HOTPLUG_CPU
extern int save_mc_for_early(u8 *mc);
#else
-static inline int save_mc_for_early(u8 *mc)
-{
- return 0;
-}
+static inline int save_mc_for_early(u8 *mc) { return 0; }
#endif
-
#endif /* _ASM_X86_MICROCODE_INTEL_H */
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h
index 55234d5..1ea0bae 100644
--- a/arch/x86/include/asm/mmu.h
+++ b/arch/x86/include/asm/mmu.h
@@ -19,7 +19,8 @@ typedef struct {
#endif
struct mutex lock;
- void __user *vdso;
+ void __user *vdso; /* vdso base address */
+ const struct vdso_image *vdso_image; /* vdso image in use */
atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */
} mm_context_t;
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 379cd36..bfd9b2a 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -116,8 +116,36 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
#endif
cpumask_set_cpu(cpu, mm_cpumask(next));
- /* Re-load page tables */
+ /*
+ * Re-load page tables.
+ *
+ * This logic has an ordering constraint:
+ *
+ * CPU 0: Write to a PTE for 'next'
+ * CPU 0: load bit 1 in mm_cpumask. if nonzero, send IPI.
+ * CPU 1: set bit 1 in next's mm_cpumask
+ * CPU 1: load from the PTE that CPU 0 writes (implicit)
+ *
+ * We need to prevent an outcome in which CPU 1 observes
+ * the new PTE value and CPU 0 observes bit 1 clear in
+ * mm_cpumask. (If that occurs, then the IPI will never
+ * be sent, and CPU 0's TLB will contain a stale entry.)
+ *
+ * The bad outcome can occur if either CPU's load is
+ * reordered before that CPU's store, so both CPUs must
+ * execute full barriers to prevent this from happening.
+ *
+ * Thus, switch_mm needs a full barrier between the
+ * store to mm_cpumask and any operation that could load
+ * from next->pgd. TLB fills are special and can happen
+ * due to instruction fetches or for no reason at all,
+ * and neither LOCK nor MFENCE orders them.
+ * Fortunately, load_cr3() is serializing and gives the
+ * ordering guarantee we need.
+ *
+ */
load_cr3(next->pgd);
+
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
/* Stop flush ipis for the previous mm */
@@ -156,10 +184,14 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* schedule, protecting us from simultaneous changes.
*/
cpumask_set_cpu(cpu, mm_cpumask(next));
+
/*
* We were in lazy tlb mode and leave_mm disabled
* tlb flush IPI delivery. We must reload CR3
* to make sure to use no freed page tables.
+ *
+ * As above, load_cr3() is serializing and orders TLB
+ * fills with respect to the mm_cpumask write.
*/
load_cr3(next->pgd);
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..eb4b09b 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
#ifndef _ASM_X86_MSI_H
#define _ASM_X86_MSI_H
#include <asm/hw_irq.h>
+#include <asm/irqdomain.h>
typedef struct irq_alloc_info msi_alloc_info_t;
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+ msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
#endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index b8c14bb..2da46ac 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -1,7 +1,12 @@
#ifndef _ASM_X86_MSR_INDEX_H
#define _ASM_X86_MSR_INDEX_H
-/* CPU model specific register (MSR) numbers */
+/*
+ * CPU model specific register (MSR) numbers.
+ *
+ * Do not add new entries to this file unless the definitions are shared
+ * between multiple compilation units.
+ */
/* x86-64 specific MSRs */
#define MSR_EFER 0xc0000080 /* extended feature register */
@@ -35,7 +40,7 @@
#define MSR_IA32_PERFCTR0 0x000000c1
#define MSR_IA32_PERFCTR1 0x000000c2
#define MSR_FSB_FREQ 0x000000cd
-#define MSR_NHM_PLATFORM_INFO 0x000000ce
+#define MSR_PLATFORM_INFO 0x000000ce
#define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2
#define NHM_C3_AUTO_DEMOTE (1UL << 25)
@@ -44,7 +49,6 @@
#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
-#define MSR_PLATFORM_INFO 0x000000ce
#define MSR_MTRRcap 0x000000fe
#define MSR_IA32_BBL_CR_CTL 0x00000119
#define MSR_IA32_BBL_CR_CTL3 0x0000011e
@@ -206,6 +210,13 @@
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
+/* Config TDP MSRs */
+#define MSR_CONFIG_TDP_NOMINAL 0x00000648
+#define MSR_CONFIG_TDP_LEVEL1 0x00000649
+#define MSR_CONFIG_TDP_LEVEL2 0x0000064A
+#define MSR_CONFIG_TDP_CONTROL 0x0000064B
+#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
+
/* Hardware P state interface */
#define MSR_PPERF 0x0000064e
#define MSR_PERF_LIMIT_REASONS 0x0000064f
@@ -224,10 +235,10 @@
#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11)
/* IA32_HWP_CAPABILITIES */
-#define HWP_HIGHEST_PERF(x) (x & 0xff)
-#define HWP_GUARANTEED_PERF(x) ((x & (0xff << 8)) >>8)
-#define HWP_MOSTEFFICIENT_PERF(x) ((x & (0xff << 16)) >>16)
-#define HWP_LOWEST_PERF(x) ((x & (0xff << 24)) >>24)
+#define HWP_HIGHEST_PERF(x) (((x) >> 0) & 0xff)
+#define HWP_GUARANTEED_PERF(x) (((x) >> 8) & 0xff)
+#define HWP_MOSTEFFICIENT_PERF(x) (((x) >> 16) & 0xff)
+#define HWP_LOWEST_PERF(x) (((x) >> 24) & 0xff)
/* IA32_HWP_REQUEST */
#define HWP_MIN_PERF(x) (x & 0xff)
@@ -315,6 +326,7 @@
#define MSR_F15H_PERF_CTR 0xc0010201
#define MSR_F15H_NB_PERF_CTL 0xc0010240
#define MSR_F15H_NB_PERF_CTR 0xc0010241
+#define MSR_F15H_IC_CFG 0xc0011021
/* Fam 10h MSRs */
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h
new file mode 100644
index 0000000..7567225
--- /dev/null
+++ b/arch/x86/include/asm/msr-trace.h
@@ -0,0 +1,57 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE msr-trace
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH asm/
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+ TP_PROTO(unsigned msr, u64 val, int failed),
+ TP_ARGS(msr, val, failed),
+ TP_STRUCT__entry(
+ __field( unsigned, msr )
+ __field( u64, val )
+ __field( int, failed )
+ ),
+ TP_fast_assign(
+ __entry->msr = msr;
+ __entry->val = val;
+ __entry->failed = failed;
+ ),
+ TP_printk("%x, value %llx%s",
+ __entry->msr,
+ __entry->val,
+ __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+ TP_PROTO(unsigned msr, u64 val, int failed),
+ TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+ TP_PROTO(unsigned msr, u64 val, int failed),
+ TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+ TP_PROTO(unsigned msr, u64 val, int failed),
+ TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..93fb7c1 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -32,6 +32,16 @@ struct msr_regs_info {
int err;
};
+struct saved_msr {
+ bool valid;
+ struct msr_info info;
+};
+
+struct saved_msrs {
+ unsigned int num;
+ struct saved_msr *array;
+};
+
static inline unsigned long long native_read_tscp(unsigned int *aux)
{
unsigned long low, high;
@@ -57,11 +67,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
#define EAX_EDX_RET(val, low, high) "=A" (val)
#endif
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
static inline unsigned long long native_read_msr(unsigned int msr)
{
DECLARE_ARGS(val, low, high);
asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+ if (msr_tracepoint_active(__tracepoint_read_msr))
+ do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
return EAX_EDX_VAL(val, low, high);
}
@@ -78,6 +111,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
_ASM_EXTABLE(2b, 3b)
: [err] "=r" (*err), EAX_EDX_RET(val, low, high)
: "c" (msr), [fault] "i" (-EIO));
+ if (msr_tracepoint_active(__tracepoint_read_msr))
+ do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
return EAX_EDX_VAL(val, low, high);
}
@@ -85,6 +120,8 @@ static inline void native_write_msr(unsigned int msr,
unsigned low, unsigned high)
{
asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+ if (msr_tracepoint_active(__tracepoint_read_msr))
+ do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
}
/* Can be uninlined because referenced by paravirt */
@@ -102,6 +139,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
: "c" (msr), "0" (low), "d" (high),
[fault] "i" (-EIO)
: "memory");
+ if (msr_tracepoint_active(__tracepoint_read_msr))
+ do_trace_write_msr(msr, ((u64)high << 32 | low), err);
return err;
}
@@ -160,6 +199,8 @@ static inline unsigned long long native_read_pmc(int counter)
DECLARE_ARGS(val, low, high);
asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+ if (msr_tracepoint_active(__tracepoint_rdpmc))
+ do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
return EAX_EDX_VAL(val, low, high);
}
@@ -190,7 +231,7 @@ static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
static inline void wrmsrl(unsigned msr, u64 val)
{
- native_write_msr(msr, (u32)val, (u32)(val >> 32));
+ native_write_msr(msr, (u32)(val & 0xffffffffULL), (u32)(val >> 32));
}
/* wrmsr with exception handling */
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
index c70689b..0deeb2d 100644
--- a/arch/x86/include/asm/mwait.h
+++ b/arch/x86/include/asm/mwait.h
@@ -3,6 +3,8 @@
#include <linux/sched.h>
+#include <asm/cpufeature.h>
+
#define MWAIT_SUBSTATE_MASK 0xf
#define MWAIT_CSTATE_MASK 0xf
#define MWAIT_SUBSTATE_SIZE 4
diff --git a/arch/x86/include/asm/numachip/numachip.h b/arch/x86/include/asm/numachip/numachip.h
index 1c6f7f6..c64373a 100644
--- a/arch/x86/include/asm/numachip/numachip.h
+++ b/arch/x86/include/asm/numachip/numachip.h
@@ -14,6 +14,7 @@
#ifndef _ASM_X86_NUMACHIP_NUMACHIP_H
#define _ASM_X86_NUMACHIP_NUMACHIP_H
+extern u8 numachip_system;
extern int __init pci_numachip_init(void);
#endif /* _ASM_X86_NUMACHIP_NUMACHIP_H */
diff --git a/arch/x86/include/asm/numachip/numachip_csr.h b/arch/x86/include/asm/numachip/numachip_csr.h
index 660f843..29719ee 100644
--- a/arch/x86/include/asm/numachip/numachip_csr.h
+++ b/arch/x86/include/asm/numachip/numachip_csr.h
@@ -14,12 +14,8 @@
#ifndef _ASM_X86_NUMACHIP_NUMACHIP_CSR_H
#define _ASM_X86_NUMACHIP_NUMACHIP_CSR_H
-#include <linux/numa.h>
-#include <linux/percpu.h>
+#include <linux/smp.h>
#include <linux/io.h>
-#include <linux/swab.h>
-#include <asm/types.h>
-#include <asm/processor.h>
#define CSR_NODE_SHIFT 16
#define CSR_NODE_BITS(p) (((unsigned long)(p)) << CSR_NODE_SHIFT)
@@ -27,11 +23,8 @@
/* 32K CSR space, b15 indicates geo/non-geo */
#define CSR_OFFSET_MASK 0x7fffUL
-
-/* Global CSR space covers all 4K possible nodes with 64K CSR space per node */
-#define NUMACHIP_GCSR_BASE 0x3fff00000000ULL
-#define NUMACHIP_GCSR_LIM 0x3fff0fffffffULL
-#define NUMACHIP_GCSR_SIZE (NUMACHIP_GCSR_LIM - NUMACHIP_GCSR_BASE + 1)
+#define CSR_G0_NODE_IDS (0x008 + (0 << 12))
+#define CSR_G3_EXT_IRQ_GEN (0x030 + (3 << 12))
/*
* Local CSR space starts in global CSR space with "nodeid" = 0xfff0, however
@@ -41,12 +34,7 @@
#define NUMACHIP_LCSR_BASE 0x3ffffe000000ULL
#define NUMACHIP_LCSR_LIM 0x3fffffffffffULL
#define NUMACHIP_LCSR_SIZE (NUMACHIP_LCSR_LIM - NUMACHIP_LCSR_BASE + 1)
-
-static inline void *gcsr_address(int node, unsigned long offset)
-{
- return __va(NUMACHIP_GCSR_BASE | (1UL << 15) |
- CSR_NODE_BITS(node & CSR_NODE_MASK) | (offset & CSR_OFFSET_MASK));
-}
+#define NUMACHIP_LAPIC_BITS 8
static inline void *lcsr_address(unsigned long offset)
{
@@ -54,114 +42,57 @@ static inline void *lcsr_address(unsigned long offset)
CSR_NODE_BITS(0xfff0) | (offset & CSR_OFFSET_MASK));
}
-static inline unsigned int read_gcsr(int node, unsigned long offset)
+static inline unsigned int read_lcsr(unsigned long offset)
{
- return swab32(readl(gcsr_address(node, offset)));
+ return swab32(readl(lcsr_address(offset)));
}
-static inline void write_gcsr(int node, unsigned long offset, unsigned int val)
+static inline void write_lcsr(unsigned long offset, unsigned int val)
{
- writel(swab32(val), gcsr_address(node, offset));
+ writel(swab32(val), lcsr_address(offset));
}
-static inline unsigned int read_lcsr(unsigned long offset)
+/*
+ * On NumaChip2, local CSR space is 16MB and starts at fixed offset below 4G
+ */
+
+#define NUMACHIP2_LCSR_BASE 0xf0000000UL
+#define NUMACHIP2_LCSR_SIZE 0x1000000UL
+#define NUMACHIP2_APIC_ICR 0x100000
+#define NUMACHIP2_TIMER_DEADLINE 0x200000
+#define NUMACHIP2_TIMER_INT 0x200008
+#define NUMACHIP2_TIMER_NOW 0x200018
+#define NUMACHIP2_TIMER_RESET 0x200020
+
+static inline void __iomem *numachip2_lcsr_address(unsigned long offset)
{
- return swab32(readl(lcsr_address(offset)));
+ return (void __iomem *)__va(NUMACHIP2_LCSR_BASE |
+ (offset & (NUMACHIP2_LCSR_SIZE - 1)));
}
-static inline void write_lcsr(unsigned long offset, unsigned int val)
+static inline u32 numachip2_read32_lcsr(unsigned long offset)
{
- writel(swab32(val), lcsr_address(offset));
+ return readl(numachip2_lcsr_address(offset));
}
-/* ========================================================================= */
-/* CSR_G0_STATE_CLEAR */
-/* ========================================================================= */
-
-#define CSR_G0_STATE_CLEAR (0x000 + (0 << 12))
-union numachip_csr_g0_state_clear {
- unsigned int v;
- struct numachip_csr_g0_state_clear_s {
- unsigned int _state:2;
- unsigned int _rsvd_2_6:5;
- unsigned int _lost:1;
- unsigned int _rsvd_8_31:24;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G0_NODE_IDS */
-/* ========================================================================= */
+static inline u64 numachip2_read64_lcsr(unsigned long offset)
+{
+ return readq(numachip2_lcsr_address(offset));
+}
-#define CSR_G0_NODE_IDS (0x008 + (0 << 12))
-union numachip_csr_g0_node_ids {
- unsigned int v;
- struct numachip_csr_g0_node_ids_s {
- unsigned int _initialid:16;
- unsigned int _nodeid:12;
- unsigned int _rsvd_28_31:4;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G3_EXT_IRQ_GEN */
-/* ========================================================================= */
+static inline void numachip2_write32_lcsr(unsigned long offset, u32 val)
+{
+ writel(val, numachip2_lcsr_address(offset));
+}
-#define CSR_G3_EXT_IRQ_GEN (0x030 + (3 << 12))
-union numachip_csr_g3_ext_irq_gen {
- unsigned int v;
- struct numachip_csr_g3_ext_irq_gen_s {
- unsigned int _vector:8;
- unsigned int _msgtype:3;
- unsigned int _index:5;
- unsigned int _destination_apic_id:16;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G3_EXT_IRQ_STATUS */
-/* ========================================================================= */
-
-#define CSR_G3_EXT_IRQ_STATUS (0x034 + (3 << 12))
-union numachip_csr_g3_ext_irq_status {
- unsigned int v;
- struct numachip_csr_g3_ext_irq_status_s {
- unsigned int _result:32;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G3_EXT_IRQ_DEST */
-/* ========================================================================= */
-
-#define CSR_G3_EXT_IRQ_DEST (0x038 + (3 << 12))
-union numachip_csr_g3_ext_irq_dest {
- unsigned int v;
- struct numachip_csr_g3_ext_irq_dest_s {
- unsigned int _irq:8;
- unsigned int _rsvd_8_31:24;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G3_NC_ATT_MAP_SELECT */
-/* ========================================================================= */
-
-#define CSR_G3_NC_ATT_MAP_SELECT (0x7fc + (3 << 12))
-union numachip_csr_g3_nc_att_map_select {
- unsigned int v;
- struct numachip_csr_g3_nc_att_map_select_s {
- unsigned int _upper_address_bits:4;
- unsigned int _select_ram:4;
- unsigned int _rsvd_8_31:24;
- } s;
-};
-
-/* ========================================================================= */
-/* CSR_G3_NC_ATT_MAP_SELECT_0-255 */
-/* ========================================================================= */
-
-#define CSR_G3_NC_ATT_MAP_SELECT_0 (0x800 + (3 << 12))
+static inline void numachip2_write64_lcsr(unsigned long offset, u64 val)
+{
+ writeq(val, numachip2_lcsr_address(offset));
+}
-#endif /* _ASM_X86_NUMACHIP_NUMACHIP_CSR_H */
+static inline unsigned int numachip2_timer(void)
+{
+ return (smp_processor_id() % 48) << 6;
+}
+#endif /* _ASM_X86_NUMACHIP_NUMACHIP_CSR_H */
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index 4edd53b..4928cf0 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -26,9 +26,6 @@
#define MCE_STACK 4
#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */
-#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
-#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
-
/*
* Set __PAGE_OFFSET to the most negative possible address +
* PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index c7c712f..7bd0099 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -5,20 +5,25 @@
#include <linux/types.h>
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
+#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
+
+#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
+#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
-/* Cast PAGE_MASK to a signed type so that it is sign-extended if
+/* Cast *PAGE_MASK to a signed type so that it is sign-extended if
virtual addresses are 32-bits but physical addresses are larger
(ie, 32-bit PAE). */
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
-
-#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
-#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
+#define PHYSICAL_PMD_PAGE_MASK (((signed long)PMD_PAGE_MASK) & __PHYSICAL_MASK)
+#define PHYSICAL_PUD_PAGE_MASK (((signed long)PUD_PAGE_MASK) & __PHYSICAL_MASK)
#define HPAGE_SHIFT PMD_SHIFT
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 10d0596..f619250 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -19,6 +19,12 @@ static inline int paravirt_enabled(void)
return pv_info.paravirt_enabled;
}
+static inline int paravirt_has_feature(unsigned int feature)
+{
+ WARN_ON_ONCE(!pv_info.paravirt_enabled);
+ return (pv_info.features & feature);
+}
+
static inline void load_sp0(struct tss_struct *tss,
struct thread_struct *thread)
{
@@ -285,15 +291,6 @@ static inline void slow_down_io(void)
#endif
}
-#ifdef CONFIG_SMP
-static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
- unsigned long start_esp)
-{
- PVOP_VCALL3(pv_apic_ops.startup_ipi_hook,
- phys_apicid, start_eip, start_esp);
-}
-#endif
-
static inline void paravirt_activate_mm(struct mm_struct *prev,
struct mm_struct *next)
{
@@ -375,23 +372,6 @@ static inline void pte_update(struct mm_struct *mm, unsigned long addr,
{
PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep);
}
-static inline void pmd_update(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp)
-{
- PVOP_VCALL3(pv_mmu_ops.pmd_update, mm, addr, pmdp);
-}
-
-static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
- PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep);
-}
-
-static inline void pmd_update_defer(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp)
-{
- PVOP_VCALL3(pv_mmu_ops.pmd_update_defer, mm, addr, pmdp);
-}
static inline pte_t __pte(pteval_t val)
{
@@ -922,23 +902,11 @@ extern void default_banner(void);
call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \
PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
-#define USERGS_SYSRET32 \
- PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \
- CLBR_NONE, \
- jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret32))
-
#ifdef CONFIG_X86_32
#define GET_CR0_INTO_EAX \
push %ecx; push %edx; \
call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
pop %edx; pop %ecx
-
-#define ENABLE_INTERRUPTS_SYSEXIT \
- PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
- CLBR_NONE, \
- jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
-
-
#else /* !CONFIG_X86_32 */
/*
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 31247b5..77db561 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -70,9 +70,14 @@ struct pv_info {
#endif
int paravirt_enabled;
+ unsigned int features; /* valid only if paravirt_enabled is set */
const char *name;
};
+#define paravirt_has(x) paravirt_has_feature(PV_SUPPORTED_##x)
+/* Supported features */
+#define PV_SUPPORTED_RTC (1<<0)
+
struct pv_init_ops {
/*
* Patch may replace one of the defined code sequences with
@@ -157,15 +162,6 @@ struct pv_cpu_ops {
u64 (*read_pmc)(int counter);
-#ifdef CONFIG_X86_32
- /*
- * Atomically enable interrupts and return to userspace. This
- * is only used in 32-bit kernels. 64-bit kernels use
- * usergs_sysret32 instead.
- */
- void (*irq_enable_sysexit)(void);
-#endif
-
/*
* Switch to usermode gs and return to 64-bit usermode using
* sysret. Only used in 64-bit kernels to return to 64-bit
@@ -174,14 +170,6 @@ struct pv_cpu_ops {
*/
void (*usergs_sysret64)(void);
- /*
- * Switch to usermode gs and return to 32-bit usermode using
- * sysret. Used to return to 32-on-64 compat processes.
- * Other usermode register state, including %esp, must already
- * be restored.
- */
- void (*usergs_sysret32)(void);
-
/* Normal iret. Jump to this with the standard iret stack
frame set up. */
void (*iret)(void);
@@ -215,14 +203,6 @@ struct pv_irq_ops {
#endif
};
-struct pv_apic_ops {
-#ifdef CONFIG_X86_LOCAL_APIC
- void (*startup_ipi_hook)(int phys_apicid,
- unsigned long start_eip,
- unsigned long start_esp);
-#endif
-};
-
struct pv_mmu_ops {
unsigned long (*read_cr2)(void);
void (*write_cr2)(unsigned long);
@@ -274,12 +254,6 @@ struct pv_mmu_ops {
pmd_t *pmdp, pmd_t pmdval);
void (*pte_update)(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
- void (*pte_update_defer)(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep);
- void (*pmd_update)(struct mm_struct *mm, unsigned long addr,
- pmd_t *pmdp);
- void (*pmd_update_defer)(struct mm_struct *mm,
- unsigned long addr, pmd_t *pmdp);
pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
@@ -354,7 +328,6 @@ struct paravirt_patch_template {
struct pv_time_ops pv_time_ops;
struct pv_cpu_ops pv_cpu_ops;
struct pv_irq_ops pv_irq_ops;
- struct pv_apic_ops pv_apic_ops;
struct pv_mmu_ops pv_mmu_ops;
struct pv_lock_ops pv_lock_ops;
};
@@ -364,7 +337,6 @@ extern struct pv_init_ops pv_init_ops;
extern struct pv_time_ops pv_time_ops;
extern struct pv_cpu_ops pv_cpu_ops;
extern struct pv_irq_ops pv_irq_ops;
-extern struct pv_apic_ops pv_apic_ops;
extern struct pv_mmu_ops pv_mmu_ops;
extern struct pv_lock_ops pv_lock_ops;
@@ -402,10 +374,8 @@ extern struct pv_lock_ops pv_lock_ops;
__visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \
asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name))
-unsigned paravirt_patch_nop(void);
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
-unsigned paravirt_patch_ignore(unsigned len);
unsigned paravirt_patch_call(void *insnbuf,
const void *target, u16 tgt_clobbers,
unsigned long addr, u16 site_clobbers,
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..9ab7507 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
#ifdef CONFIG_X86_64
void *iommu; /* IOMMU private data */
#endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+ void *fwnode; /* IRQ domain for MSI assignment */
+#endif
};
extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
static inline int pci_domain_nr(struct pci_bus *bus)
{
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
}
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+ struct pci_sysdata *sd = bus->sysdata;
+
+ return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode _pci_root_bus_fwnode
+#endif
+
/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
@@ -105,9 +120,6 @@ void native_restore_msi_irqs(struct pci_dev *dev);
#include <asm/pci_64.h>
#endif
-/* implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
/* generic pci stuff */
#include <asm-generic/pci.h>
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index fa1195d..d08eacd2 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_irq)(struct pci_dev *dev);
+extern bool mp_should_keep_irq(struct device *dev);
+
struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val);
@@ -151,11 +153,11 @@ extern struct list_head pci_mmcfg_list;
#define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20)
/*
- * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
- * on their northbrige except through the * %eax register. As such, you MUST
- * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
- * accessor functions.
- * In fact just use pci_config_*, nothing else please.
+ * On AMD Fam10h CPUs, all PCI MMIO configuration space accesses must use
+ * %eax. No other source or target registers may be used. The following
+ * mmio_config_* accessors enforce this. See "BIOS and Kernel Developer's
+ * Guide (BKDG) For AMD Family 10h Processors", rev. 3.48, sec 2.11.1,
+ * "MMIO Configuration Coding Requirements".
*/
static inline unsigned char mmio_config_readb(void __iomem *pos)
{
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 7bcb861..5a2ed3e 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -165,6 +165,7 @@ struct x86_pmu_capability {
#define GLOBAL_STATUS_ASIF BIT_ULL(60)
#define GLOBAL_STATUS_COUNTERS_FROZEN BIT_ULL(59)
#define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(58)
+#define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(55)
/*
* IBS cpuid feature detection
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 867da5b..0687c47 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -19,6 +19,13 @@
#include <asm/x86_init.h>
void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_checkwx(void);
+
+#ifdef CONFIG_DEBUG_WX
+#define debug_checkwx() ptdump_walk_pgd_level_checkwx()
+#else
+#define debug_checkwx() do { } while (0)
+#endif
/*
* ZERO_PAGE is a global shared page that is always zero: used
@@ -62,9 +69,6 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page);
#define pmd_clear(pmd) native_pmd_clear(pmd)
#define pte_update(mm, addr, ptep) do { } while (0)
-#define pte_update_defer(mm, addr, ptep) do { } while (0)
-#define pmd_update(mm, addr, ptep) do { } while (0)
-#define pmd_update_defer(mm, addr, ptep) do { } while (0)
#define pgd_val(x) native_pgd_val(x)
#define __pgd(x) native_make_pgd(x)
@@ -142,12 +146,12 @@ static inline unsigned long pte_pfn(pte_t pte)
static inline unsigned long pmd_pfn(pmd_t pmd)
{
- return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
+ return (pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT;
}
static inline unsigned long pud_pfn(pud_t pud)
{
- return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT;
+ return (pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT;
}
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
@@ -158,20 +162,22 @@ static inline int pmd_large(pmd_t pte)
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-static inline int pmd_trans_splitting(pmd_t pmd)
-{
- return pmd_val(pmd) & _PAGE_SPLITTING;
-}
-
static inline int pmd_trans_huge(pmd_t pmd)
{
- return pmd_val(pmd) & _PAGE_PSE;
+ return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
}
static inline int has_transparent_hugepage(void)
{
return cpu_has_pse;
}
+
+#ifdef __HAVE_ARCH_PTE_DEVMAP
+static inline int pmd_devmap(pmd_t pmd)
+{
+ return !!(pmd_val(pmd) & _PAGE_DEVMAP);
+}
+#endif
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
static inline pte_t pte_set_flags(pte_t pte, pteval_t set)
@@ -248,6 +254,11 @@ static inline pte_t pte_mkspecial(pte_t pte)
return pte_set_flags(pte, _PAGE_SPECIAL);
}
+static inline pte_t pte_mkdevmap(pte_t pte)
+{
+ return pte_set_flags(pte, _PAGE_SPECIAL|_PAGE_DEVMAP);
+}
+
static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
{
pmdval_t v = native_pmd_val(pmd);
@@ -267,6 +278,11 @@ static inline pmd_t pmd_mkold(pmd_t pmd)
return pmd_clear_flags(pmd, _PAGE_ACCESSED);
}
+static inline pmd_t pmd_mkclean(pmd_t pmd)
+{
+ return pmd_clear_flags(pmd, _PAGE_DIRTY);
+}
+
static inline pmd_t pmd_wrprotect(pmd_t pmd)
{
return pmd_clear_flags(pmd, _PAGE_RW);
@@ -277,6 +293,11 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
return pmd_set_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
}
+static inline pmd_t pmd_mkdevmap(pmd_t pmd)
+{
+ return pmd_set_flags(pmd, _PAGE_DEVMAP);
+}
+
static inline pmd_t pmd_mkhuge(pmd_t pmd)
{
return pmd_set_flags(pmd, _PAGE_PSE);
@@ -318,6 +339,16 @@ static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY);
}
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+ return pte_clear_flags(pte, _PAGE_SOFT_DIRTY);
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+ return pmd_clear_flags(pmd, _PAGE_SOFT_DIRTY);
+}
+
#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
/*
@@ -379,7 +410,9 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
return __pgprot(preservebits | addbits);
}
-#define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK)
+#define pte_pgprot(x) __pgprot(pte_flags(x))
+#define pmd_pgprot(x) __pgprot(pmd_flags(x))
+#define pud_pgprot(x) __pgprot(pud_flags(x))
#define canon_pgprot(p) __pgprot(massage_pgprot(p))
@@ -446,6 +479,13 @@ static inline int pte_present(pte_t a)
return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
}
+#ifdef __HAVE_ARCH_PTE_DEVMAP
+static inline int pte_devmap(pte_t a)
+{
+ return (pte_flags(a) & _PAGE_DEVMAP) == _PAGE_DEVMAP;
+}
+#endif
+
#define pte_accessible pte_accessible
static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
{
@@ -502,14 +542,15 @@ static inline int pmd_none(pmd_t pmd)
static inline unsigned long pmd_page_vaddr(pmd_t pmd)
{
- return (unsigned long)__va(pmd_val(pmd) & PTE_PFN_MASK);
+ return (unsigned long)__va(pmd_val(pmd) & pmd_pfn_mask(pmd));
}
/*
* Currently stuck as a macro due to indirect forward reference to
* linux/mmzone.h's __section_mem_map_addr() definition:
*/
-#define pmd_page(pmd) pfn_to_page((pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT)
+#define pmd_page(pmd) \
+ pfn_to_page((pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT)
/*
* the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
@@ -570,14 +611,15 @@ static inline int pud_present(pud_t pud)
static inline unsigned long pud_page_vaddr(pud_t pud)
{
- return (unsigned long)__va((unsigned long)pud_val(pud) & PTE_PFN_MASK);
+ return (unsigned long)__va(pud_val(pud) & pud_pfn_mask(pud));
}
/*
* Currently stuck as a macro due to indirect forward reference to
* linux/mmzone.h's __section_mem_map_addr() definition:
*/
-#define pud_page(pud) pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
+#define pud_page(pud) \
+ pfn_to_page((pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT)
/* Find an entry in the second-level page table.. */
static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
@@ -710,14 +752,9 @@ static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr,
* updates should either be sets, clears, or set_pte_atomic for P->P
* transitions, which means this hook should only be called for user PTEs.
* This hook implies a P->P protection or access change has taken place, which
- * requires a subsequent TLB flush. The notification can optionally be delayed
- * until the TLB flush event by using the pte_update_defer form of the
- * interface, but care must be taken to assure that the flush happens while
- * still holding the same page table lock so that the shadow and primary pages
- * do not become out of sync on SMP.
+ * requires a subsequent TLB flush.
*/
#define pte_update(mm, addr, ptep) do { } while (0)
-#define pte_update_defer(mm, addr, ptep) do { } while (0)
#endif
/*
@@ -795,10 +832,6 @@ extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp);
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-extern void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long addr, pmd_t *pmdp);
-
#define __HAVE_ARCH_PMD_WRITE
static inline int pmd_write(pmd_t pmd)
{
@@ -809,9 +842,7 @@ static inline int pmd_write(pmd_t pmd)
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp)
{
- pmd_t pmd = native_pmdp_get_and_clear(pmdp);
- pmd_update(mm, addr, pmdp);
- return pmd;
+ return native_pmdp_get_and_clear(pmdp);
}
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -819,7 +850,6 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pmd_t *pmdp)
{
clear_bit(_PAGE_BIT_RW, (unsigned long *)pmdp);
- pmd_update(mm, addr, pmdp);
}
/*
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 13f310b..4432ab7 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -22,10 +22,11 @@
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
-#define _PAGE_BIT_SPLITTING _PAGE_BIT_SOFTW2 /* only valid on a PSE pmd */
#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
-#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
+#define _PAGE_BIT_SOFTW4 58 /* available for programmer */
+#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
+#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
/* If _PAGE_BIT_PRESENT is clear, we use these: */
/* - if the user mapped it with PROT_NONE; pte_present gives true */
@@ -46,7 +47,6 @@
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
-#define _PAGE_SPLITTING (_AT(pteval_t, 1) << _PAGE_BIT_SPLITTING)
#define __HAVE_ARCH_PTE_SPECIAL
#ifdef CONFIG_KMEMCHECK
@@ -85,8 +85,11 @@
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
+#define _PAGE_DEVMAP (_AT(u64, 1) << _PAGE_BIT_DEVMAP)
+#define __HAVE_ARCH_PTE_DEVMAP
#else
#define _PAGE_NX (_AT(pteval_t, 0))
+#define _PAGE_DEVMAP (_AT(pteval_t, 0))
#endif
#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
@@ -209,10 +212,10 @@ enum page_cache_mode {
#include <linux/types.h>
-/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
+/* Extracts the PFN from a (pte|pmd|pud|pgd)val_t of a 4KB page */
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
-/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
+/* Extracts the flags from a (pte|pmd|pud|pgd)val_t of a 4KB page */
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
@@ -276,14 +279,40 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
}
#endif
+static inline pudval_t pud_pfn_mask(pud_t pud)
+{
+ if (native_pud_val(pud) & _PAGE_PSE)
+ return PHYSICAL_PUD_PAGE_MASK;
+ else
+ return PTE_PFN_MASK;
+}
+
+static inline pudval_t pud_flags_mask(pud_t pud)
+{
+ return ~pud_pfn_mask(pud);
+}
+
static inline pudval_t pud_flags(pud_t pud)
{
- return native_pud_val(pud) & PTE_FLAGS_MASK;
+ return native_pud_val(pud) & pud_flags_mask(pud);
+}
+
+static inline pmdval_t pmd_pfn_mask(pmd_t pmd)
+{
+ if (native_pmd_val(pmd) & _PAGE_PSE)
+ return PHYSICAL_PMD_PAGE_MASK;
+ else
+ return PTE_PFN_MASK;
+}
+
+static inline pmdval_t pmd_flags_mask(pmd_t pmd)
+{
+ return ~pmd_pfn_mask(pmd);
}
static inline pmdval_t pmd_flags(pmd_t pmd)
{
- return native_pmd_val(pmd) & PTE_FLAGS_MASK;
+ return native_pmd_val(pmd) & pmd_flags_mask(pmd);
}
static inline pte_t native_make_pte(pteval_t val)
@@ -337,20 +366,18 @@ static inline enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
}
static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot)
{
+ pgprotval_t val = pgprot_val(pgprot);
pgprot_t new;
- unsigned long val;
- val = pgprot_val(pgprot);
pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
return new;
}
static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot)
{
+ pgprotval_t val = pgprot_val(pgprot);
pgprot_t new;
- unsigned long val;
- val = pgprot_val(pgprot);
pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
((val & _PAGE_PAT_LARGE) >>
(_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h
index 7249e6d..5973a2f 100644
--- a/arch/x86/include/asm/platform_sst_audio.h
+++ b/arch/x86/include/asm/platform_sst_audio.h
@@ -55,6 +55,7 @@ enum sst_audio_device_id_mrfld {
PIPE_MEDIA0_IN = 0x8F,
PIPE_MEDIA1_IN = 0x90,
PIPE_MEDIA2_IN = 0x91,
+ PIPE_MEDIA3_IN = 0x9C,
PIPE_RSVD = 0xFF,
};
diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h
index d8ce3ec..bf8b35d 100644
--- a/arch/x86/include/asm/pmem.h
+++ b/arch/x86/include/asm/pmem.h
@@ -67,18 +67,19 @@ static inline void arch_wmb_pmem(void)
}
/**
- * __arch_wb_cache_pmem - write back a cache range with CLWB
+ * arch_wb_cache_pmem - write back a cache range with CLWB
* @vaddr: virtual start address
* @size: number of bytes to write back
*
* Write back a cache range using the CLWB (cache line write back)
* instruction. This function requires explicit ordering with an
- * arch_wmb_pmem() call. This API is internal to the x86 PMEM implementation.
+ * arch_wmb_pmem() call.
*/
-static inline void __arch_wb_cache_pmem(void *vaddr, size_t size)
+static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
{
u16 x86_clflush_size = boot_cpu_data.x86_clflush_size;
unsigned long clflush_mask = x86_clflush_size - 1;
+ void *vaddr = (void __force *)addr;
void *vend = vaddr + size;
void *p;
@@ -115,7 +116,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
len = copy_from_iter_nocache(vaddr, bytes, i);
if (__iter_needs_pmem_wb(i))
- __arch_wb_cache_pmem(vaddr, bytes);
+ arch_wb_cache_pmem(addr, bytes);
return len;
}
@@ -132,13 +133,13 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size)
{
void *vaddr = (void __force *)addr;
- /* TODO: implement the zeroing via non-temporal writes */
- if (size == PAGE_SIZE && ((unsigned long)vaddr & ~PAGE_MASK) == 0)
- clear_page(vaddr);
- else
- memset(vaddr, 0, size);
+ memset(vaddr, 0, size);
+ arch_wb_cache_pmem(addr, size);
+}
- __arch_wb_cache_pmem(vaddr, size);
+static inline void arch_invalidate_pmem(void __pmem *addr, size_t size)
+{
+ clflush_cache_range((void __force *) addr, size);
}
static inline bool __arch_has_wmb_pmem(void)
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index b12f810..01bcde8 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -30,12 +30,9 @@ static __always_inline void preempt_count_set(int pc)
/*
* must be macros to avoid header recursion hell
*/
-#define init_task_preempt_count(p) do { \
- task_thread_info(p)->saved_preempt_count = PREEMPT_DISABLED; \
-} while (0)
+#define init_task_preempt_count(p) do { } while (0)
#define init_idle_preempt_count(p, cpu) do { \
- task_thread_info(p)->saved_preempt_count = PREEMPT_ENABLED; \
per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \
} while (0)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 19577dd..983738a 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -11,9 +11,9 @@ struct vm86;
#include <asm/math_emu.h>
#include <asm/segment.h>
#include <asm/types.h>
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
#include <asm/current.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/page.h>
#include <asm/pgtable_types.h>
#include <asm/percpu.h>
@@ -24,7 +24,6 @@ struct vm86;
#include <asm/fpu/types.h>
#include <linux/personality.h>
-#include <linux/cpumask.h>
#include <linux/cache.h>
#include <linux/threads.h>
#include <linux/math64.h>
@@ -129,6 +128,8 @@ struct cpuinfo_x86 {
u16 booted_cores;
/* Physical processor id: */
u16 phys_proc_id;
+ /* Logical processor id: */
+ u16 logical_proc_id;
/* Core id: */
u16 cpu_core_id;
/* Compute unit id */
@@ -298,10 +299,13 @@ struct tss_struct {
*/
unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
+#ifdef CONFIG_X86_32
/*
- * Space for the temporary SYSENTER stack:
+ * Space for the temporary SYSENTER stack.
*/
+ unsigned long SYSENTER_stack_canary;
unsigned long SYSENTER_stack[64];
+#endif
} ____cacheline_aligned;
@@ -472,6 +476,7 @@ static inline unsigned long current_top_of_stack(void)
#else
#define __cpuid native_cpuid
#define paravirt_enabled() 0
+#define paravirt_has(x) 0
static inline void load_sp0(struct tss_struct *tss,
struct thread_struct *thread)
@@ -556,12 +561,12 @@ static inline unsigned int cpuid_edx(unsigned int op)
}
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-static inline void rep_nop(void)
+static __always_inline void rep_nop(void)
{
asm volatile("rep; nop" ::: "memory");
}
-static inline void cpu_relax(void)
+static __always_inline void cpu_relax(void)
{
rep_nop();
}
@@ -765,7 +770,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
* Return saved PC of a blocked thread.
* What is this good for? it will be always the scheduler or ret_from_fork.
*/
-#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8))
+#define thread_saved_pc(t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8))
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
extern unsigned long KSTK_ESP(struct task_struct *task);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index a4a7728..9b9b30b1 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -7,12 +7,23 @@
void syscall_init(void);
+#ifdef CONFIG_X86_64
void entry_SYSCALL_64(void);
-void entry_SYSCALL_compat(void);
+#endif
+
+#ifdef CONFIG_X86_32
void entry_INT80_32(void);
-void entry_INT80_compat(void);
void entry_SYSENTER_32(void);
+void __begin_SYSENTER_singlestep_region(void);
+void __end_SYSENTER_singlestep_region(void);
+#endif
+
+#ifdef CONFIG_IA32_EMULATION
void entry_SYSENTER_compat(void);
+void __end_entry_SYSENTER_compat(void);
+void entry_SYSCALL_compat(void);
+void entry_INT80_compat(void);
+#endif
void x86_configure_nx(void);
void x86_report_nx(void);
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index 7a6bed5..fdcc040 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -4,6 +4,15 @@
#include <linux/clocksource.h>
#include <asm/pvclock-abi.h>
+#ifdef CONFIG_KVM_GUEST
+extern struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void);
+#else
+static inline struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
+{
+ return NULL;
+}
+#endif
+
/* some helper functions for xen and kvm pv clock sources */
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
@@ -91,10 +100,5 @@ struct pvclock_vsyscall_time_info {
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
-#define PVCLOCK_VSYSCALL_NR_PAGES (((NR_CPUS-1)/(PAGE_SIZE/PVTI_SIZE))+1)
-
-int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
- int size);
-struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu);
#endif /* _ASM_X86_PVCLOCK_H */
diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h
index b002e71..9f92c18 100644
--- a/arch/x86/include/asm/qspinlock_paravirt.h
+++ b/arch/x86/include/asm/qspinlock_paravirt.h
@@ -1,6 +1,65 @@
#ifndef __ASM_QSPINLOCK_PARAVIRT_H
#define __ASM_QSPINLOCK_PARAVIRT_H
+/*
+ * For x86-64, PV_CALLEE_SAVE_REGS_THUNK() saves and restores 8 64-bit
+ * registers. For i386, however, only 1 32-bit register needs to be saved
+ * and restored. So an optimized version of __pv_queued_spin_unlock() is
+ * hand-coded for 64-bit, but it isn't worthwhile to do it for 32-bit.
+ */
+#ifdef CONFIG_64BIT
+
+PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath);
+#define __pv_queued_spin_unlock __pv_queued_spin_unlock
+#define PV_UNLOCK "__raw_callee_save___pv_queued_spin_unlock"
+#define PV_UNLOCK_SLOWPATH "__raw_callee_save___pv_queued_spin_unlock_slowpath"
+
+/*
+ * Optimized assembly version of __raw_callee_save___pv_queued_spin_unlock
+ * which combines the registers saving trunk and the body of the following
+ * C code:
+ *
+ * void __pv_queued_spin_unlock(struct qspinlock *lock)
+ * {
+ * struct __qspinlock *l = (void *)lock;
+ * u8 lockval = cmpxchg(&l->locked, _Q_LOCKED_VAL, 0);
+ *
+ * if (likely(lockval == _Q_LOCKED_VAL))
+ * return;
+ * pv_queued_spin_unlock_slowpath(lock, lockval);
+ * }
+ *
+ * For x86-64,
+ * rdi = lock (first argument)
+ * rsi = lockval (second argument)
+ * rdx = internal variable (set to 0)
+ */
+asm (".pushsection .text;"
+ ".globl " PV_UNLOCK ";"
+ ".align 4,0x90;"
+ PV_UNLOCK ": "
+ "push %rdx;"
+ "mov $0x1,%eax;"
+ "xor %edx,%edx;"
+ "lock cmpxchg %dl,(%rdi);"
+ "cmp $0x1,%al;"
+ "jne .slowpath;"
+ "pop %rdx;"
+ "ret;"
+ ".slowpath: "
+ "push %rsi;"
+ "movzbl %al,%esi;"
+ "call " PV_UNLOCK_SLOWPATH ";"
+ "pop %rsi;"
+ "pop %rdx;"
+ "ret;"
+ ".size " PV_UNLOCK ", .-" PV_UNLOCK ";"
+ ".popsection");
+
+#else /* CONFIG_64BIT */
+
+extern void __pv_queued_spin_unlock(struct qspinlock *lock);
PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock);
+#endif /* CONFIG_64BIT */
#endif
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index a82c4f1..2cb1cc2 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -25,5 +25,6 @@ void __noreturn machine_real_restart(unsigned int type);
typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
void nmi_shootdown_cpus(nmi_shootdown_cb callback);
+void run_crash_ipi_callback(struct pt_regs *regs);
#endif /* _ASM_X86_REBOOT_H */
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index 0a52424..13b6cdd 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -7,7 +7,7 @@
extern char __brk_base[], __brk_limit[];
extern struct exception_table_entry __stop___ex_table[];
-#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+#if defined(CONFIG_X86_64)
extern char __end_rodata_hpage_align[];
#endif
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index 9dfce4e..e6cd2c4 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -1,79 +1,8 @@
#ifndef _ASM_X86_SIGCONTEXT_H
#define _ASM_X86_SIGCONTEXT_H
-#include <uapi/asm/sigcontext.h>
-
-#ifdef __i386__
-struct sigcontext {
- unsigned short gs, __gsh;
- unsigned short fs, __fsh;
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned long di;
- unsigned long si;
- unsigned long bp;
- unsigned long sp;
- unsigned long bx;
- unsigned long dx;
- unsigned long cx;
- unsigned long ax;
- unsigned long trapno;
- unsigned long err;
- unsigned long ip;
- unsigned short cs, __csh;
- unsigned long flags;
- unsigned long sp_at_signal;
- unsigned short ss, __ssh;
+/* This is a legacy header - all kernel code includes <uapi/asm/sigcontext.h> directly. */
- /*
- * fpstate is really (struct _fpstate *) or (struct _xstate *)
- * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
- * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
- * of extended memory layout. See comments at the definition of
- * (struct _fpx_sw_bytes)
- */
- void __user *fpstate; /* zero when no FPU/extended context */
- unsigned long oldmask;
- unsigned long cr2;
-};
-#else /* __i386__ */
-struct sigcontext {
- unsigned long r8;
- unsigned long r9;
- unsigned long r10;
- unsigned long r11;
- unsigned long r12;
- unsigned long r13;
- unsigned long r14;
- unsigned long r15;
- unsigned long di;
- unsigned long si;
- unsigned long bp;
- unsigned long bx;
- unsigned long dx;
- unsigned long ax;
- unsigned long cx;
- unsigned long sp;
- unsigned long ip;
- unsigned long flags;
- unsigned short cs;
- unsigned short gs;
- unsigned short fs;
- unsigned short __pad0;
- unsigned long err;
- unsigned long trapno;
- unsigned long oldmask;
- unsigned long cr2;
+#include <uapi/asm/sigcontext.h>
- /*
- * fpstate is really (struct _fpstate *) or (struct _xstate *)
- * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
- * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
- * of extended memory layout. See comments at the definition of
- * (struct _fpx_sw_bytes)
- */
- void __user *fpstate; /* zero when no FPU/extended context */
- unsigned long reserved1[8];
-};
-#endif /* !__i386__ */
#endif /* _ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h
index 1f3175b..34edd16 100644
--- a/arch/x86/include/asm/sigframe.h
+++ b/arch/x86/include/asm/sigframe.h
@@ -1,7 +1,7 @@
#ifndef _ASM_X86_SIGFRAME_H
#define _ASM_X86_SIGFRAME_H
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
#include <asm/siginfo.h>
#include <asm/ucontext.h>
#include <linux/compat.h>
@@ -9,8 +9,6 @@
#ifdef CONFIG_X86_32
#define sigframe_ia32 sigframe
#define rt_sigframe_ia32 rt_sigframe
-#define sigcontext_ia32 sigcontext
-#define _fpstate_ia32 _fpstate
#define ucontext_ia32 ucontext
#else /* !CONFIG_X86_32 */
@@ -24,7 +22,7 @@
struct sigframe_ia32 {
u32 pretcode;
int sig;
- struct sigcontext_ia32 sc;
+ struct sigcontext_32 sc;
/*
* fpstate is unused. fpstate is moved/allocated after
* retcode[] below. This movement allows to have the FP state and the
@@ -33,7 +31,7 @@ struct sigframe_ia32 {
* the offset of extramask[] in the sigframe and thus prevent any
* legacy application accessing/modifying it.
*/
- struct _fpstate_ia32 fpstate_unused;
+ struct _fpstate_32 fpstate_unused;
#ifdef CONFIG_IA32_EMULATION
unsigned int extramask[_COMPAT_NSIG_WORDS-1];
#else /* !CONFIG_IA32_EMULATION */
diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h
index 89db467..452c88b 100644
--- a/arch/x86/include/asm/sighandling.h
+++ b/arch/x86/include/asm/sighandling.h
@@ -13,7 +13,6 @@
X86_EFLAGS_CF | X86_EFLAGS_RF)
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
-int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc);
int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
struct pt_regs *regs, unsigned long mask);
diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h
index c481be7..2138c9a 100644
--- a/arch/x86/include/asm/signal.h
+++ b/arch/x86/include/asm/signal.h
@@ -34,7 +34,7 @@ extern void do_signal(struct pt_regs *regs);
#define __ARCH_HAS_SA_RESTORER
-#include <asm/sigcontext.h>
+#include <uapi/asm/sigcontext.h>
#ifdef __i386__
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
index ba665eb..db33330 100644
--- a/arch/x86/include/asm/smap.h
+++ b/arch/x86/include/asm/smap.h
@@ -15,7 +15,7 @@
#include <linux/stringify.h>
#include <asm/nops.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
/* "Raw" instruction opcodes */
#define __ASM_CLAC .byte 0x0f,0x01,0xca
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 222a6a3..20a3de5 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -16,20 +16,10 @@
#endif
#include <asm/thread_info.h>
#include <asm/cpumask.h>
-#include <asm/cpufeature.h>
extern int smp_num_siblings;
extern unsigned int num_processors;
-static inline bool cpu_has_ht_siblings(void)
-{
- bool has_siblings = false;
-#ifdef CONFIG_SMP
- has_siblings = cpu_has_ht && smp_num_siblings > 1;
-#endif
- return has_siblings;
-}
-
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
/* cpus sharing the last level cache: */
@@ -74,9 +64,6 @@ struct smp_ops {
extern void set_cpu_sibling_map(int cpu);
#ifdef CONFIG_SMP
-#ifndef CONFIG_PARAVIRT
-#define startup_ipi_hook(phys_apicid, start_eip, start_esp) do { } while (0)
-#endif
extern struct smp_ops smp_ops;
static inline void smp_send_stop(void)
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 70bbe39..7c247e7 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -37,7 +37,7 @@ print_context_stack_bp(struct thread_info *tinfo,
/* Generic stack tracer with callbacks */
struct stacktrace_ops {
- void (*address)(void *data, unsigned long address, int reliable);
+ int (*address)(void *data, unsigned long address, int reliable);
/* On negative return stop dumping */
int (*stack)(void *data, char *name);
walk_stack_t walk_stack;
diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
index ff8b9a1..ca6ba36 100644
--- a/arch/x86/include/asm/string_64.h
+++ b/arch/x86/include/asm/string_64.h
@@ -78,6 +78,19 @@ int strcmp(const char *cs, const char *ct);
#define memset(s, c, n) __memset(s, c, n)
#endif
+/**
+ * memcpy_mcsafe - copy memory with indication if a machine check happened
+ *
+ * @dst: destination address
+ * @src: source address
+ * @cnt: number of bytes to copy
+ *
+ * Low level memory copy function that catches machine checks
+ *
+ * Return true for success, false for fail
+ */
+bool memcpy_mcsafe(void *dst, const void *src, size_t cnt);
+
#endif /* __KERNEL__ */
#endif /* _ASM_X86_STRING_64_H */
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
index d1793f0..8e9dbe7 100644
--- a/arch/x86/include/asm/suspend_32.h
+++ b/arch/x86/include/asm/suspend_32.h
@@ -15,6 +15,7 @@ struct saved_context {
unsigned long cr0, cr2, cr3, cr4;
u64 misc_enable;
bool misc_enable_saved;
+ struct saved_msrs saved_msrs;
struct desc_ptr gdt_desc;
struct desc_ptr idt;
u16 ldt;
diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h
index 7ebf0eb..6136a18 100644
--- a/arch/x86/include/asm/suspend_64.h
+++ b/arch/x86/include/asm/suspend_64.h
@@ -24,6 +24,7 @@ struct saved_context {
unsigned long cr0, cr2, cr3, cr4, cr8;
u64 misc_enable;
bool misc_enable_saved;
+ struct saved_msrs saved_msrs;
unsigned long efer;
u16 gdt_pad; /* Unused */
struct desc_ptr gdt_desc;
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index d7f3b3b..751bf4b 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -79,12 +79,12 @@ do { \
#else /* CONFIG_X86_32 */
/* frame pointer must be last for get_wchan */
-#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
-#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"
+#define SAVE_CONTEXT "pushq %%rbp ; movq %%rsi,%%rbp\n\t"
+#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp\t"
#define __EXTRA_CLOBBER \
, "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
- "r12", "r13", "r14", "r15"
+ "r12", "r13", "r14", "r15", "flags"
#ifdef CONFIG_CC_STACKPROTECTOR
#define __switch_canary \
@@ -100,7 +100,11 @@ do { \
#define __switch_canary_iparam
#endif /* CC_STACKPROTECTOR */
-/* Save restore flags to clear handle leaking NT */
+/*
+ * There is no need to save or restore flags, because flags are always
+ * clean in kernel mode, with the possible exception of IOPL. Kernel IOPL
+ * has no effect.
+ */
#define switch_to(prev, next, last) \
asm volatile(SAVE_CONTEXT \
"movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index d6a756a..999b7cd 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -20,9 +20,21 @@
#include <asm/thread_info.h> /* for TS_COMPAT */
#include <asm/unistd.h>
-typedef void (*sys_call_ptr_t)(void);
+typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
extern const sys_call_ptr_t sys_call_table[];
+#if defined(CONFIG_X86_32)
+#define ia32_sys_call_table sys_call_table
+#define __NR_syscall_compat_max __NR_syscall_max
+#define IA32_NR_syscalls NR_syscalls
+#endif
+
+#if defined(CONFIG_IA32_EMULATION)
+extern const sys_call_ptr_t ia32_sys_call_table[];
+#endif
+
/*
* Only the low 32 bits of orig_ax are meaningful, so we return int.
* This importantly ignores the high bits on 64-bit, so comparisons
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 8afdc3e..8286669 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -49,7 +49,7 @@
*/
#ifndef __ASSEMBLY__
struct task_struct;
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <linux/atomic.h>
struct thread_info {
@@ -57,9 +57,7 @@ struct thread_info {
__u32 flags; /* low level flags */
__u32 status; /* thread synchronous flags */
__u32 cpu; /* current CPU */
- int saved_preempt_count;
mm_segment_t addr_limit;
- void __user *sysenter_return;
unsigned int sig_on_uaccess_error:1;
unsigned int uaccess_err:1; /* uaccess failed */
};
@@ -69,7 +67,6 @@ struct thread_info {
.task = &tsk, \
.flags = 0, \
.cpu = 0, \
- .saved_preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
}
@@ -137,10 +134,13 @@ struct thread_info {
#define _TIF_ADDR32 (1 << TIF_ADDR32)
#define _TIF_X32 (1 << TIF_X32)
-/* work to do in syscall_trace_enter() */
+/*
+ * work to do in syscall_trace_enter(). Also includes TIF_NOHZ for
+ * enter_from_user_mode()
+ */
#define _TIF_WORK_SYSCALL_ENTRY \
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \
- _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT | \
+ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
_TIF_NOHZ)
/* work to do on any return to user space */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 6df2029..c24b422 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -5,8 +5,57 @@
#include <linux/sched.h>
#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/special_insns.h>
+static inline void __invpcid(unsigned long pcid, unsigned long addr,
+ unsigned long type)
+{
+ struct { u64 d[2]; } desc = { { pcid, addr } };
+
+ /*
+ * The memory clobber is because the whole point is to invalidate
+ * stale TLB entries and, especially if we're flushing global
+ * mappings, we don't want the compiler to reorder any subsequent
+ * memory accesses before the TLB flush.
+ *
+ * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and
+ * invpcid (%rcx), %rax in long mode.
+ */
+ asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"
+ : : "m" (desc), "a" (type), "c" (&desc) : "memory");
+}
+
+#define INVPCID_TYPE_INDIV_ADDR 0
+#define INVPCID_TYPE_SINGLE_CTXT 1
+#define INVPCID_TYPE_ALL_INCL_GLOBAL 2
+#define INVPCID_TYPE_ALL_NON_GLOBAL 3
+
+/* Flush all mappings for a given pcid and addr, not including globals. */
+static inline void invpcid_flush_one(unsigned long pcid,
+ unsigned long addr)
+{
+ __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
+}
+
+/* Flush all mappings for a given PCID, not including globals. */
+static inline void invpcid_flush_single_context(unsigned long pcid)
+{
+ __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
+}
+
+/* Flush all mappings, including globals, for all PCIDs. */
+static inline void invpcid_flush_all(void)
+{
+ __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
+}
+
+/* Flush all mappings for all PCIDs except globals. */
+static inline void invpcid_flush_all_nonglobals(void)
+{
+ __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
+}
+
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
@@ -104,6 +153,15 @@ static inline void __native_flush_tlb_global(void)
{
unsigned long flags;
+ if (static_cpu_has(X86_FEATURE_INVPCID)) {
+ /*
+ * Using INVPCID is considerably faster than a pair of writes
+ * to CR4 sandwiched inside an IRQ flag save/restore.
+ */
+ invpcid_flush_all();
+ return;
+ }
+
/*
* Read-modify-write to CR4 - protect it from preemption and
* from interrupts. (Use the raw variant because this code can
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 0fb4648..7f991bd5 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -119,12 +119,23 @@ static inline void setup_node_to_cpumask_map(void) { }
extern const struct cpumask *cpu_coregroup_mask(int cpu);
+#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#ifdef ENABLE_TOPO_DEFINES
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
+
+extern unsigned int __max_logical_packages;
+#define topology_max_packages() (__max_logical_packages)
+int topology_update_package_map(unsigned int apicid, unsigned int cpu);
+extern int topology_phys_to_logical_pkg(unsigned int pkg);
+#else
+#define topology_max_packages() (1)
+static inline int
+topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
+static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
#endif
static inline void arch_fix_phys_package_id(int num, u32 slot)
diff --git a/arch/x86/include/asm/trace/mpx.h b/arch/x86/include/asm/trace/mpx.h
index 173dd3b..0f492fc 100644
--- a/arch/x86/include/asm/trace/mpx.h
+++ b/arch/x86/include/asm/trace/mpx.h
@@ -11,7 +11,7 @@
TRACE_EVENT(mpx_bounds_register_exception,
TP_PROTO(void *addr_referenced,
- const struct bndreg *bndreg),
+ const struct mpx_bndreg *bndreg),
TP_ARGS(addr_referenced, bndreg),
TP_STRUCT__entry(
@@ -44,7 +44,7 @@ TRACE_EVENT(mpx_bounds_register_exception,
TRACE_EVENT(bounds_exception_mpx,
- TP_PROTO(const struct bndcsr *bndcsr),
+ TP_PROTO(const struct mpx_bndcsr *bndcsr),
TP_ARGS(bndcsr),
TP_STRUCT__entry(
@@ -116,7 +116,8 @@ TRACE_EVENT(mpx_new_bounds_table,
/*
* This gets used outside of MPX-specific code, so we need a stub.
*/
-static inline void trace_bounds_exception_mpx(const struct bndcsr *bndcsr)
+static inline
+void trace_bounds_exception_mpx(const struct mpx_bndcsr *bndcsr)
{
}
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 6d7c547..174c421 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -29,6 +29,8 @@ static inline cycles_t get_cycles(void)
return rdtsc();
}
+extern struct system_counterval_t convert_art_to_tsc(cycle_t art);
+
extern void tsc_init(void);
extern void mark_tsc_unstable(char *reason);
extern int unsynchronized_tsc(void);
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a8df874..c0f27d7 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -51,13 +51,13 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
* limit, not add it to the address).
*/
if (__builtin_constant_p(size))
- return addr > limit - size;
+ return unlikely(addr > limit - size);
/* Arbitrary sizes? Be careful about overflow */
addr += size;
- if (addr < size)
+ if (unlikely(addr < size))
return true;
- return addr > limit;
+ return unlikely(addr > limit);
}
#define __range_not_ok(addr, size, limit) \
@@ -90,12 +90,11 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
likely(!__range_not_ok(addr, size, user_addr_max()))
/*
- * The exception table consists of pairs of addresses relative to the
- * exception table enty itself: 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.
+ * The exception table consists of triples of addresses relative to the
+ * exception table entry itself. The first address is of an instruction
+ * that is allowed to fault, the second is the target at which the program
+ * should continue. The third is a handler function to deal with the fault
+ * caused by the instruction in the first field.
*
* 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,
@@ -104,13 +103,14 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
*/
struct exception_table_entry {
- int insn, fixup;
+ int insn, fixup, handler;
};
/* This is not the generic standard exception_table_entry format */
#define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE
-extern int fixup_exception(struct pt_regs *regs);
+extern int fixup_exception(struct pt_regs *regs, int trapnr);
+extern bool ex_has_fault_handler(unsigned long ip);
extern int early_fixup_exception(unsigned long *ip);
/*
@@ -134,6 +134,9 @@ extern int __get_user_4(void);
extern int __get_user_8(void);
extern int __get_user_bad(void);
+#define __uaccess_begin() stac()
+#define __uaccess_end() clac()
+
/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
@@ -182,7 +185,7 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
: "=a" (__ret_gu), "=r" (__val_gu) \
: "0" (ptr), "i" (sizeof(*(ptr)))); \
(x) = (__force __typeof__(*(ptr))) __val_gu; \
- __ret_gu; \
+ __builtin_expect(__ret_gu, 0); \
})
#define __put_user_x(size, x, ptr, __ret_pu) \
@@ -193,10 +196,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
#ifdef CONFIG_X86_32
#define __put_user_asm_u64(x, addr, err, errret) \
- asm volatile(ASM_STAC "\n" \
+ asm volatile("\n" \
"1: movl %%eax,0(%2)\n" \
"2: movl %%edx,4(%2)\n" \
- "3: " ASM_CLAC "\n" \
+ "3:" \
".section .fixup,\"ax\"\n" \
"4: movl %3,%0\n" \
" jmp 3b\n" \
@@ -207,10 +210,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
: "A" (x), "r" (addr), "i" (errret), "0" (err))
#define __put_user_asm_ex_u64(x, addr) \
- asm volatile(ASM_STAC "\n" \
+ asm volatile("\n" \
"1: movl %%eax,0(%1)\n" \
"2: movl %%edx,4(%1)\n" \
- "3: " ASM_CLAC "\n" \
+ "3:" \
_ASM_EXTABLE_EX(1b, 2b) \
_ASM_EXTABLE_EX(2b, 3b) \
: : "A" (x), "r" (addr))
@@ -278,7 +281,7 @@ extern void __put_user_8(void);
__put_user_x(X, __pu_val, ptr, __ret_pu); \
break; \
} \
- __ret_pu; \
+ __builtin_expect(__ret_pu, 0); \
})
#define __put_user_size(x, ptr, size, retval, errret) \
@@ -304,6 +307,10 @@ do { \
} \
} while (0)
+/*
+ * This doesn't do __uaccess_begin/end - the exception handling
+ * around it must do that.
+ */
#define __put_user_size_ex(x, ptr, size) \
do { \
__chk_user_ptr(ptr); \
@@ -358,9 +365,9 @@ do { \
} while (0)
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
- asm volatile(ASM_STAC "\n" \
+ asm volatile("\n" \
"1: mov"itype" %2,%"rtype"1\n" \
- "2: " ASM_CLAC "\n" \
+ "2:\n" \
".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
" xor"itype" %"rtype"1,%"rtype"1\n" \
@@ -370,6 +377,10 @@ do { \
: "=r" (err), ltype(x) \
: "m" (__m(addr)), "i" (errret), "0" (err))
+/*
+ * This doesn't do __uaccess_begin/end - the exception handling
+ * around it must do that.
+ */
#define __get_user_size_ex(x, ptr, size) \
do { \
__chk_user_ptr(ptr); \
@@ -400,17 +411,21 @@ do { \
#define __put_user_nocheck(x, ptr, size) \
({ \
int __pu_err; \
+ __uaccess_begin(); \
__put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
- __pu_err; \
+ __uaccess_end(); \
+ __builtin_expect(__pu_err, 0); \
})
#define __get_user_nocheck(x, ptr, size) \
({ \
int __gu_err; \
unsigned long __gu_val; \
+ __uaccess_begin(); \
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
+ __uaccess_end(); \
(x) = (__force __typeof__(*(ptr)))__gu_val; \
- __gu_err; \
+ __builtin_expect(__gu_err, 0); \
})
/* FIXME: this hack is definitely wrong -AK */
@@ -423,9 +438,9 @@ struct __large_struct { unsigned long buf[100]; };
* aliasing issues.
*/
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
- asm volatile(ASM_STAC "\n" \
+ asm volatile("\n" \
"1: mov"itype" %"rtype"1,%2\n" \
- "2: " ASM_CLAC "\n" \
+ "2:\n" \
".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
" jmp 2b\n" \
@@ -445,11 +460,11 @@ struct __large_struct { unsigned long buf[100]; };
*/
#define uaccess_try do { \
current_thread_info()->uaccess_err = 0; \
- stac(); \
+ __uaccess_begin(); \
barrier();
#define uaccess_catch(err) \
- clac(); \
+ __uaccess_end(); \
(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
} while (0)
@@ -547,12 +562,13 @@ extern void __cmpxchg_wrong_size(void)
__typeof__(ptr) __uval = (uval); \
__typeof__(*(ptr)) __old = (old); \
__typeof__(*(ptr)) __new = (new); \
+ __uaccess_begin(); \
switch (size) { \
case 1: \
{ \
- asm volatile("\t" ASM_STAC "\n" \
+ asm volatile("\n" \
"1:\t" LOCK_PREFIX "cmpxchgb %4, %2\n" \
- "2:\t" ASM_CLAC "\n" \
+ "2:\n" \
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
@@ -566,9 +582,9 @@ extern void __cmpxchg_wrong_size(void)
} \
case 2: \
{ \
- asm volatile("\t" ASM_STAC "\n" \
+ asm volatile("\n" \
"1:\t" LOCK_PREFIX "cmpxchgw %4, %2\n" \
- "2:\t" ASM_CLAC "\n" \
+ "2:\n" \
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
@@ -582,9 +598,9 @@ extern void __cmpxchg_wrong_size(void)
} \
case 4: \
{ \
- asm volatile("\t" ASM_STAC "\n" \
+ asm volatile("\n" \
"1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n" \
- "2:\t" ASM_CLAC "\n" \
+ "2:\n" \
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
@@ -601,9 +617,9 @@ extern void __cmpxchg_wrong_size(void)
if (!IS_ENABLED(CONFIG_X86_64)) \
__cmpxchg_wrong_size(); \
\
- asm volatile("\t" ASM_STAC "\n" \
+ asm volatile("\n" \
"1:\t" LOCK_PREFIX "cmpxchgq %4, %2\n" \
- "2:\t" ASM_CLAC "\n" \
+ "2:\n" \
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
@@ -618,6 +634,7 @@ extern void __cmpxchg_wrong_size(void)
default: \
__cmpxchg_wrong_size(); \
} \
+ __uaccess_end(); \
*__uval = __old; \
__ret; \
})
@@ -745,5 +762,39 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
#undef __copy_from_user_overflow
#undef __copy_to_user_overflow
+/*
+ * We rely on the nested NMI work to allow atomic faults from the NMI path; the
+ * nested NMI paths are careful to preserve CR2.
+ *
+ * Caller must use pagefault_enable/disable, or run in interrupt context,
+ * and also do a uaccess_ok() check
+ */
+#define __copy_from_user_nmi __copy_from_user_inatomic
+
+/*
+ * The "unsafe" user accesses aren't really "unsafe", but the naming
+ * is a big fat warning: you have to not only do the access_ok()
+ * checking before using them, but you have to surround them with the
+ * user_access_begin/end() pair.
+ */
+#define user_access_begin() __uaccess_begin()
+#define user_access_end() __uaccess_end()
+
+#define unsafe_put_user(x, ptr) \
+({ \
+ int __pu_err; \
+ __put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \
+ __builtin_expect(__pu_err, 0); \
+})
+
+#define unsafe_get_user(x, ptr) \
+({ \
+ int __gu_err; \
+ unsigned long __gu_val; \
+ __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT); \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
+ __builtin_expect(__gu_err, 0); \
+})
+
#endif /* _ASM_X86_UACCESS_H */
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index f5dcb52..3fe0eac 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -48,20 +48,28 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
switch (n) {
case 1:
+ __uaccess_begin();
__put_user_size(*(u8 *)from, (u8 __user *)to,
1, ret, 1);
+ __uaccess_end();
return ret;
case 2:
+ __uaccess_begin();
__put_user_size(*(u16 *)from, (u16 __user *)to,
2, ret, 2);
+ __uaccess_end();
return ret;
case 4:
+ __uaccess_begin();
__put_user_size(*(u32 *)from, (u32 __user *)to,
4, ret, 4);
+ __uaccess_end();
return ret;
case 8:
+ __uaccess_begin();
__put_user_size(*(u64 *)from, (u64 __user *)to,
8, ret, 8);
+ __uaccess_end();
return ret;
}
}
@@ -103,13 +111,19 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
switch (n) {
case 1:
+ __uaccess_begin();
__get_user_size(*(u8 *)to, from, 1, ret, 1);
+ __uaccess_end();
return ret;
case 2:
+ __uaccess_begin();
__get_user_size(*(u16 *)to, from, 2, ret, 2);
+ __uaccess_end();
return ret;
case 4:
+ __uaccess_begin();
__get_user_size(*(u32 *)to, from, 4, ret, 4);
+ __uaccess_end();
return ret;
}
}
@@ -148,13 +162,19 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
switch (n) {
case 1:
+ __uaccess_begin();
__get_user_size(*(u8 *)to, from, 1, ret, 1);
+ __uaccess_end();
return ret;
case 2:
+ __uaccess_begin();
__get_user_size(*(u16 *)to, from, 2, ret, 2);
+ __uaccess_end();
return ret;
case 4:
+ __uaccess_begin();
__get_user_size(*(u32 *)to, from, 4, ret, 4);
+ __uaccess_end();
return ret;
}
}
@@ -170,13 +190,19 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
switch (n) {
case 1:
+ __uaccess_begin();
__get_user_size(*(u8 *)to, from, 1, ret, 1);
+ __uaccess_end();
return ret;
case 2:
+ __uaccess_begin();
__get_user_size(*(u16 *)to, from, 2, ret, 2);
+ __uaccess_end();
return ret;
case 4:
+ __uaccess_begin();
__get_user_size(*(u32 *)to, from, 4, ret, 4);
+ __uaccess_end();
return ret;
}
}
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index f2f9b39..3076986 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -8,7 +8,7 @@
#include <linux/errno.h>
#include <linux/lockdep.h>
#include <asm/alternative.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/page.h>
/*
@@ -56,35 +56,49 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
if (!__builtin_constant_p(size))
return copy_user_generic(dst, (__force void *)src, size);
switch (size) {
- case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
+ case 1:
+ __uaccess_begin();
+ __get_user_asm(*(u8 *)dst, (u8 __user *)src,
ret, "b", "b", "=q", 1);
+ __uaccess_end();
return ret;
- case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
+ case 2:
+ __uaccess_begin();
+ __get_user_asm(*(u16 *)dst, (u16 __user *)src,
ret, "w", "w", "=r", 2);
+ __uaccess_end();
return ret;
- case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
+ case 4:
+ __uaccess_begin();
+ __get_user_asm(*(u32 *)dst, (u32 __user *)src,
ret, "l", "k", "=r", 4);
+ __uaccess_end();
return ret;
- case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
+ case 8:
+ __uaccess_begin();
+ __get_user_asm(*(u64 *)dst, (u64 __user *)src,
ret, "q", "", "=r", 8);
+ __uaccess_end();
return ret;
case 10:
+ __uaccess_begin();
__get_user_asm(*(u64 *)dst, (u64 __user *)src,
ret, "q", "", "=r", 10);
- if (unlikely(ret))
- return ret;
- __get_user_asm(*(u16 *)(8 + (char *)dst),
- (u16 __user *)(8 + (char __user *)src),
- ret, "w", "w", "=r", 2);
+ if (likely(!ret))
+ __get_user_asm(*(u16 *)(8 + (char *)dst),
+ (u16 __user *)(8 + (char __user *)src),
+ ret, "w", "w", "=r", 2);
+ __uaccess_end();
return ret;
case 16:
+ __uaccess_begin();
__get_user_asm(*(u64 *)dst, (u64 __user *)src,
ret, "q", "", "=r", 16);
- if (unlikely(ret))
- return ret;
- __get_user_asm(*(u64 *)(8 + (char *)dst),
- (u64 __user *)(8 + (char __user *)src),
- ret, "q", "", "=r", 8);
+ if (likely(!ret))
+ __get_user_asm(*(u64 *)(8 + (char *)dst),
+ (u64 __user *)(8 + (char __user *)src),
+ ret, "q", "", "=r", 8);
+ __uaccess_end();
return ret;
default:
return copy_user_generic(dst, (__force void *)src, size);
@@ -106,35 +120,51 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size)
if (!__builtin_constant_p(size))
return copy_user_generic((__force void *)dst, src, size);
switch (size) {
- case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
+ case 1:
+ __uaccess_begin();
+ __put_user_asm(*(u8 *)src, (u8 __user *)dst,
ret, "b", "b", "iq", 1);
+ __uaccess_end();
return ret;
- case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
+ case 2:
+ __uaccess_begin();
+ __put_user_asm(*(u16 *)src, (u16 __user *)dst,
ret, "w", "w", "ir", 2);
+ __uaccess_end();
return ret;
- case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
+ case 4:
+ __uaccess_begin();
+ __put_user_asm(*(u32 *)src, (u32 __user *)dst,
ret, "l", "k", "ir", 4);
+ __uaccess_end();
return ret;
- case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
+ case 8:
+ __uaccess_begin();
+ __put_user_asm(*(u64 *)src, (u64 __user *)dst,
ret, "q", "", "er", 8);
+ __uaccess_end();
return ret;
case 10:
+ __uaccess_begin();
__put_user_asm(*(u64 *)src, (u64 __user *)dst,
ret, "q", "", "er", 10);
- if (unlikely(ret))
- return ret;
- asm("":::"memory");
- __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
- ret, "w", "w", "ir", 2);
+ if (likely(!ret)) {
+ asm("":::"memory");
+ __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
+ ret, "w", "w", "ir", 2);
+ }
+ __uaccess_end();
return ret;
case 16:
+ __uaccess_begin();
__put_user_asm(*(u64 *)src, (u64 __user *)dst,
ret, "q", "", "er", 16);
- if (unlikely(ret))
- return ret;
- asm("":::"memory");
- __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
- ret, "q", "", "er", 8);
+ if (likely(!ret)) {
+ asm("":::"memory");
+ __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
+ ret, "q", "", "er", 8);
+ }
+ __uaccess_end();
return ret;
default:
return copy_user_generic((__force void *)dst, src, size);
@@ -160,39 +190,47 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
switch (size) {
case 1: {
u8 tmp;
+ __uaccess_begin();
__get_user_asm(tmp, (u8 __user *)src,
ret, "b", "b", "=q", 1);
if (likely(!ret))
__put_user_asm(tmp, (u8 __user *)dst,
ret, "b", "b", "iq", 1);
+ __uaccess_end();
return ret;
}
case 2: {
u16 tmp;
+ __uaccess_begin();
__get_user_asm(tmp, (u16 __user *)src,
ret, "w", "w", "=r", 2);
if (likely(!ret))
__put_user_asm(tmp, (u16 __user *)dst,
ret, "w", "w", "ir", 2);
+ __uaccess_end();
return ret;
}
case 4: {
u32 tmp;
+ __uaccess_begin();
__get_user_asm(tmp, (u32 __user *)src,
ret, "l", "k", "=r", 4);
if (likely(!ret))
__put_user_asm(tmp, (u32 __user *)dst,
ret, "l", "k", "ir", 4);
+ __uaccess_end();
return ret;
}
case 8: {
u64 tmp;
+ __uaccess_begin();
__get_user_asm(tmp, (u64 __user *)src,
ret, "q", "", "=r", 8);
if (likely(!ret))
__put_user_asm(tmp, (u64 __user *)dst,
ret, "q", "", "er", 8);
+ __uaccess_end();
return ret;
}
default:
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index a00ad8f..ea707478 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -609,7 +609,7 @@ struct uv_cpu_nmi_s {
DECLARE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi);
-#define uv_hub_nmi (uv_cpu_nmi.hub)
+#define uv_hub_nmi this_cpu_read(uv_cpu_nmi.hub)
#define uv_cpu_nmi_per(cpu) (per_cpu(uv_cpu_nmi, cpu))
#define uv_hub_nmi_per(cpu) (uv_cpu_nmi_per(cpu).hub)
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index 8021bd2..43dc55b 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -13,20 +13,18 @@ struct vdso_image {
void *data;
unsigned long size; /* Always a multiple of PAGE_SIZE */
- /* text_mapping.pages is big enough for data/size page pointers */
- struct vm_special_mapping text_mapping;
-
unsigned long alt, alt_len;
long sym_vvar_start; /* Negative offset to the vvar area */
long sym_vvar_page;
long sym_hpet_page;
+ long sym_pvclock_page;
long sym_VDSO32_NOTE_MASK;
long sym___kernel_sigreturn;
long sym___kernel_rt_sigreturn;
long sym___kernel_vsyscall;
- long sym_VDSO32_SYSENTER_RETURN;
+ long sym_int80_landing_pad;
};
#ifdef CONFIG_X86_64
@@ -38,13 +36,7 @@ extern const struct vdso_image vdso_image_x32;
#endif
#if defined CONFIG_X86_32 || defined CONFIG_COMPAT
-extern const struct vdso_image vdso_image_32_int80;
-#ifdef CONFIG_COMPAT
-extern const struct vdso_image vdso_image_32_syscall;
-#endif
-extern const struct vdso_image vdso_image_32_sysenter;
-
-extern const struct vdso_image *selected_vdso32;
+extern const struct vdso_image vdso_image_32;
#endif
extern void __init init_vdso_image(const struct vdso_image *image);
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index f556c48..e728699 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -37,6 +37,12 @@ struct vsyscall_gtod_data {
};
extern struct vsyscall_gtod_data vsyscall_gtod_data;
+extern int vclocks_used;
+static inline bool vclock_was_used(int vclock)
+{
+ return READ_ONCE(vclocks_used) & (1 << vclock);
+}
+
static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s)
{
unsigned ret;
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 448b7ca..14c63c7 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -72,7 +72,8 @@
#define SECONDARY_EXEC_SHADOW_VMCS 0x00004000
#define SECONDARY_EXEC_ENABLE_PML 0x00020000
#define SECONDARY_EXEC_XSAVES 0x00100000
-
+#define SECONDARY_EXEC_PCOMMIT 0x00200000
+#define SECONDARY_EXEC_TSC_SCALING 0x02000000
#define PIN_BASED_EXT_INTR_MASK 0x00000001
#define PIN_BASED_NMI_EXITING 0x00000008
@@ -167,6 +168,8 @@ enum vmcs_field {
VMWRITE_BITMAP = 0x00002028,
XSS_EXIT_BITMAP = 0x0000202C,
XSS_EXIT_BITMAP_HIGH = 0x0000202D,
+ TSC_MULTIPLIER = 0x00002032,
+ TSC_MULTIPLIER_HIGH = 0x00002033,
GUEST_PHYSICAL_ADDRESS = 0x00002400,
GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
VMCS_LINK_POINTER = 0x00002800,
@@ -416,6 +419,7 @@ enum vmcs_field {
#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
+#define VMX_VPID_INVVPID_BIT (1ull << 0) /* (32 - 32) */
#define VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT (1ull << 9) /* (41 - 32) */
#define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT (1ull << 10) /* (42 - 32) */
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 48d34d2..1ae89a2 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -1,7 +1,6 @@
#ifndef _ASM_X86_PLATFORM_H
#define _ASM_X86_PLATFORM_H
-#include <asm/pgtable_types.h>
#include <asm/bootparam.h>
struct mpc_bus;
@@ -83,13 +82,11 @@ struct x86_init_paging {
* struct x86_init_timers - platform specific timer setup
* @setup_perpcu_clockev: set up the per cpu clock event device for the
* boot cpu
- * @tsc_pre_init: platform function called before TSC init
* @timer_init: initialize the platform timer (default PIT/HPET)
* @wallclock_init: init the wallclock device
*/
struct x86_init_timers {
void (*setup_percpu_clockev)(void);
- void (*tsc_pre_init)(void);
void (*timer_init)(void);
void (*wallclock_init)(void);
};
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 4c20dd3..3bcdcc8 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -310,10 +310,10 @@ HYPERVISOR_mca(struct xen_mc *mc_op)
}
static inline int
-HYPERVISOR_dom0_op(struct xen_platform_op *platform_op)
+HYPERVISOR_platform_op(struct xen_platform_op *op)
{
- platform_op->interface_version = XENPF_INTERFACE_VERSION;
- return _hypercall1(int, dom0_op, platform_op);
+ op->interface_version = XENPF_INTERFACE_VERSION;
+ return _hypercall1(int, platform_op, op);
}
static inline int
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index d866959..8b2d4be 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -57,4 +57,9 @@ static inline bool xen_x2apic_para_available(void)
}
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+void xen_arch_register_cpu(int num);
+void xen_arch_unregister_cpu(int num);
+#endif
+
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 0679e11..f5fb840 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -12,7 +12,7 @@
#include <asm/pgtable.h>
#include <xen/interface/xen.h>
-#include <xen/grant_table.h>
+#include <xen/interface/grant_table.h>
#include <xen/features.h>
/* Xen machine address */
@@ -43,6 +43,8 @@ extern unsigned long *xen_p2m_addr;
extern unsigned long xen_p2m_size;
extern unsigned long xen_max_p2m_pfn;
+extern int xen_alloc_p2m_entry(unsigned long pfn);
+
extern unsigned long get_phys_to_machine(unsigned long pfn);
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
@@ -296,8 +298,8 @@ void make_lowmem_page_readwrite(void *vaddr);
#define xen_unmap(cookie) iounmap((cookie))
static inline bool xen_arch_need_swiotlb(struct device *dev,
- unsigned long pfn,
- unsigned long bfn)
+ phys_addr_t phys,
+ dma_addr_t dev_addr)
{
return false;
}
diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
index 968d57d..f320ee3 100644
--- a/arch/x86/include/asm/xen/pci.h
+++ b/arch/x86/include/asm/xen/pci.h
@@ -57,7 +57,7 @@ static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
{
if (xen_pci_frontend && xen_pci_frontend->enable_msi)
return xen_pci_frontend->enable_msi(dev, vectors);
- return -ENODEV;
+ return -ENOSYS;
}
static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
{
@@ -69,7 +69,7 @@ static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
{
if (xen_pci_frontend && xen_pci_frontend->enable_msix)
return xen_pci_frontend->enable_msix(dev, vectors, nvec);
- return -ENODEV;
+ return -ENOSYS;
}
static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev)
{
diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h
index 5a08bc8..c54beb4 100644
--- a/arch/x86/include/asm/xor_32.h
+++ b/arch/x86/include/asm/xor_32.h
@@ -553,7 +553,7 @@ do { \
if (cpu_has_xmm) { \
xor_speed(&xor_block_pIII_sse); \
xor_speed(&xor_block_sse_pf64); \
- } else if (cpu_has_mmx) { \
+ } else if (boot_cpu_has(X86_FEATURE_MMX)) { \
xor_speed(&xor_block_pII_mmx); \
xor_speed(&xor_block_p5_mmx); \
} else { \
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index f0412c5..9b1a918 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -153,6 +153,12 @@
/* MSR used to provide vcpu index */
#define HV_X64_MSR_VP_INDEX 0x40000002
+/* MSR used to reset the guest OS. */
+#define HV_X64_MSR_RESET 0x40000003
+
+/* MSR used to provide vcpu runtime in 100ns units */
+#define HV_X64_MSR_VP_RUNTIME 0x40000010
+
/* MSR used to read the per-partition time reference counter */
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
@@ -220,7 +226,9 @@
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
/* Declare the various hypercall operations. */
-#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_POST_MESSAGE 0x005c
+#define HVCALL_SIGNAL_EVENT 0x005d
#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
@@ -251,4 +259,108 @@ typedef struct _HV_REFERENCE_TSC_PAGE {
__s64 tsc_offset;
} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT (16)
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1 (0x1)
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+
+#define HV_SYNIC_STIMER_COUNT (4)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE (256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+ HVMSG_NONE = 0x00000000,
+
+ /* Memory access messages. */
+ HVMSG_UNMAPPED_GPA = 0x80000000,
+ HVMSG_GPA_INTERCEPT = 0x80000001,
+
+ /* Timer notification messages. */
+ HVMSG_TIMER_EXPIRED = 0x80000010,
+
+ /* Error messages. */
+ HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
+ HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
+ HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
+
+ /* Trace buffer complete messages. */
+ HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
+
+ /* Platform-specific processor intercept messages. */
+ HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
+ HVMSG_X64_MSR_INTERCEPT = 0x80010001,
+ HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
+ HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
+ HVMSG_X64_APIC_EOI = 0x80010004,
+ HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+ __u8 asu8;
+ struct {
+ __u8 msg_pending:1;
+ __u8 reserved:7;
+ };
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+ __u32 asu32;
+ struct {
+ __u32 id:24;
+ __u32 reserved:8;
+ } u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+ __u32 message_type;
+ __u8 payload_size;
+ union hv_message_flags message_flags;
+ __u8 reserved[2];
+ union {
+ __u64 sender;
+ union hv_port_id port;
+ };
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+ struct hv_message_header header;
+ union {
+ __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+ } u;
+};
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+ struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+ __u32 timer_index;
+ __u32 reserved;
+ __u64 expiration_time; /* When the timer expired */
+ __u64 delivery_time; /* When the message was delivered */
+};
+
+#define HV_STIMER_ENABLE (1ULL << 0)
+#define HV_STIMER_PERIODIC (1ULL << 1)
+#define HV_STIMER_LAZY (1ULL << 2)
+#define HV_STIMER_AUTOENABLE (1ULL << 3)
+#define HV_STIMER_SINT(config) (__u8)(((config) >> 16) & 0x0F)
+
#endif
diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h
index 76880ed..2184943 100644
--- a/arch/x86/include/uapi/asm/mce.h
+++ b/arch/x86/include/uapi/asm/mce.h
@@ -2,7 +2,7 @@
#define _UAPI_ASM_X86_MCE_H
#include <linux/types.h>
-#include <asm/ioctls.h>
+#include <linux/ioctl.h>
/* Fields are zero when not available */
struct mce {
@@ -16,7 +16,7 @@ struct mce {
__u8 cpuvendor; /* cpu vendor as encoded in system.h */
__u8 inject_flags; /* software inject flags */
__u8 severity;
- __u8 usable_addr;
+ __u8 pad;
__u32 cpuid; /* CPUID 1 EAX */
__u8 cs; /* code segment */
__u8 bank; /* machine check bank */
diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h
index 40836a9..62d4111 100644
--- a/arch/x86/include/uapi/asm/sigcontext.h
+++ b/arch/x86/include/uapi/asm/sigcontext.h
@@ -1,221 +1,388 @@
#ifndef _UAPI_ASM_X86_SIGCONTEXT_H
#define _UAPI_ASM_X86_SIGCONTEXT_H
+/*
+ * Linux signal context definitions. The sigcontext includes a complex
+ * hierarchy of CPU and FPU state, available to user-space (on the stack) when
+ * a signal handler is executed.
+ *
+ * As over the years this ABI grew from its very simple roots towards
+ * supporting more and more CPU state organically, some of the details (which
+ * were rather clever hacks back in the days) became a bit quirky by today.
+ *
+ * The current ABI includes flexible provisions for future extensions, so we
+ * won't have to grow new quirks for quite some time. Promise!
+ */
+
#include <linux/compiler.h>
#include <linux/types.h>
-#define FP_XSTATE_MAGIC1 0x46505853U
-#define FP_XSTATE_MAGIC2 0x46505845U
-#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2)
+#define FP_XSTATE_MAGIC1 0x46505853U
+#define FP_XSTATE_MAGIC2 0x46505845U
+#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2)
/*
- * bytes 464..511 in the current 512byte layout of fxsave/fxrstor frame
- * are reserved for SW usage. On cpu's supporting xsave/xrstor, these bytes
- * are used to extended the fpstate pointer in the sigcontext, which now
- * includes the extended state information along with fpstate information.
+ * Bytes 464..511 in the current 512-byte layout of the FXSAVE/FXRSTOR frame
+ * are reserved for SW usage. On CPUs supporting XSAVE/XRSTOR, these bytes are
+ * used to extend the fpstate pointer in the sigcontext, which now includes the
+ * extended state information along with fpstate information.
+ *
+ * If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then there's a
+ * sw_reserved.extended_size bytes large extended context area present. (The
+ * last 32-bit word of this extended area (at the
+ * fpstate+extended_size-FP_XSTATE_MAGIC2_SIZE address) is set to
+ * FP_XSTATE_MAGIC2 so that you can sanity check your size calculations.)
*
- * Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved
- * area and FP_XSTATE_MAGIC2 at the end of memory layout
- * (extended_size - FP_XSTATE_MAGIC2_SIZE) indicates the presence of the
- * extended state information in the memory layout pointed by the fpstate
- * pointer in sigcontext.
+ * This extended area typically grows with newer CPUs that have larger and
+ * larger XSAVE areas.
*/
struct _fpx_sw_bytes {
- __u32 magic1; /* FP_XSTATE_MAGIC1 */
- __u32 extended_size; /* total size of the layout referred by
- * fpstate pointer in the sigcontext.
- */
- __u64 xfeatures;
- /* feature bit mask (including fp/sse/extended
- * state) that is present in the memory
- * layout.
- */
- __u32 xstate_size; /* actual xsave state size, based on the
- * features saved in the layout.
- * 'extended_size' will be greater than
- * 'xstate_size'.
- */
- __u32 padding[7]; /* for future use. */
+ /*
+ * If set to FP_XSTATE_MAGIC1 then this is an xstate context.
+ * 0 if a legacy frame.
+ */
+ __u32 magic1;
+
+ /*
+ * Total size of the fpstate area:
+ *
+ * - if magic1 == 0 then it's sizeof(struct _fpstate)
+ * - if magic1 == FP_XSTATE_MAGIC1 then it's sizeof(struct _xstate)
+ * plus extensions (if any)
+ */
+ __u32 extended_size;
+
+ /*
+ * Feature bit mask (including FP/SSE/extended state) that is present
+ * in the memory layout:
+ */
+ __u64 xfeatures;
+
+ /*
+ * Actual XSAVE state size, based on the xfeatures saved in the layout.
+ * 'extended_size' is greater than 'xstate_size':
+ */
+ __u32 xstate_size;
+
+ /* For future use: */
+ __u32 padding[7];
};
-#ifdef __i386__
/*
- * As documented in the iBCS2 standard..
- *
- * The first part of "struct _fpstate" is just the normal i387
- * hardware setup, the extra "status" word is used to save the
- * coprocessor status word before entering the handler.
+ * As documented in the iBCS2 standard:
*
- * Pentium III FXSR, SSE support
- * Gareth Hughes <gareth@valinux.com>, May 2000
+ * The first part of "struct _fpstate" is just the normal i387 hardware setup,
+ * the extra "status" word is used to save the coprocessor status word before
+ * entering the handler.
*
- * The FPU state data structure has had to grow to accommodate the
- * extended FPU state required by the Streaming SIMD Extensions.
- * There is no documented standard to accomplish this at the moment.
+ * The FPU state data structure has had to grow to accommodate the extended FPU
+ * state required by the Streaming SIMD Extensions. There is no documented
+ * standard to accomplish this at the moment.
*/
+
+/* 10-byte legacy floating point register: */
struct _fpreg {
- unsigned short significand[4];
- unsigned short exponent;
+ __u16 significand[4];
+ __u16 exponent;
};
+/* 16-byte floating point register: */
struct _fpxreg {
- unsigned short significand[4];
- unsigned short exponent;
- unsigned short padding[3];
+ __u16 significand[4];
+ __u16 exponent;
+ __u16 padding[3];
};
+/* 16-byte XMM register: */
struct _xmmreg {
- unsigned long element[4];
+ __u32 element[4];
};
-struct _fpstate {
- /* Regular FPU environment */
- unsigned long cw;
- unsigned long sw;
- unsigned long tag;
- unsigned long ipoff;
- unsigned long cssel;
- unsigned long dataoff;
- unsigned long datasel;
- struct _fpreg _st[8];
- unsigned short status;
- unsigned short magic; /* 0xffff = regular FPU data only */
+#define X86_FXSR_MAGIC 0x0000
+
+/*
+ * The 32-bit FPU frame:
+ */
+struct _fpstate_32 {
+ /* Legacy FPU environment: */
+ __u32 cw;
+ __u32 sw;
+ __u32 tag;
+ __u32 ipoff;
+ __u32 cssel;
+ __u32 dataoff;
+ __u32 datasel;
+ struct _fpreg _st[8];
+ __u16 status;
+ __u16 magic; /* 0xffff: regular FPU data only */
+ /* 0x0000: FXSR FPU data */
/* FXSR FPU environment */
- unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */
- unsigned long mxcsr;
- unsigned long reserved;
- struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
- struct _xmmreg _xmm[8];
- unsigned long padding1[44];
+ __u32 _fxsr_env[6]; /* FXSR FPU env is ignored */
+ __u32 mxcsr;
+ __u32 reserved;
+ struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
+ struct _xmmreg _xmm[8]; /* First 8 XMM registers */
+ union {
+ __u32 padding1[44]; /* Second 8 XMM registers plus padding */
+ __u32 padding[44]; /* Alias name for old user-space */
+ };
union {
- unsigned long padding2[12];
- struct _fpx_sw_bytes sw_reserved; /* represents the extended
- * state info */
+ __u32 padding2[12];
+ struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
};
};
-#define X86_FXSR_MAGIC 0x0000
-
-#ifndef __KERNEL__
/*
- * User-space might still rely on the old definition:
+ * The 64-bit FPU frame. (FXSAVE format and later)
+ *
+ * Note1: If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then the structure is
+ * larger: 'struct _xstate'. Note that 'struct _xstate' embedds
+ * 'struct _fpstate' so that you can always assume the _fpstate portion
+ * exists so that you can check the magic value.
+ *
+ * Note2: Reserved fields may someday contain valuable data. Always
+ * save/restore them when you change signal frames.
*/
-struct sigcontext {
- unsigned short gs, __gsh;
- unsigned short fs, __fsh;
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned long edi;
- unsigned long esi;
- unsigned long ebp;
- unsigned long esp;
- unsigned long ebx;
- unsigned long edx;
- unsigned long ecx;
- unsigned long eax;
- unsigned long trapno;
- unsigned long err;
- unsigned long eip;
- unsigned short cs, __csh;
- unsigned long eflags;
- unsigned long esp_at_signal;
- unsigned short ss, __ssh;
- struct _fpstate __user *fpstate;
- unsigned long oldmask;
- unsigned long cr2;
-};
-#endif /* !__KERNEL__ */
-
-#else /* __i386__ */
-
-/* FXSAVE frame */
-/* Note: reserved1/2 may someday contain valuable data. Always save/restore
- them when you change signal frames. */
-struct _fpstate {
- __u16 cwd;
- __u16 swd;
- __u16 twd; /* Note this is not the same as the
- 32bit/x87/FSAVE twd */
- __u16 fop;
- __u64 rip;
- __u64 rdp;
- __u32 mxcsr;
- __u32 mxcsr_mask;
- __u32 st_space[32]; /* 8*16 bytes for each FP-reg */
- __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */
- __u32 reserved2[12];
+struct _fpstate_64 {
+ __u16 cwd;
+ __u16 swd;
+ /* Note this is not the same as the 32-bit/x87/FSAVE twd: */
+ __u16 twd;
+ __u16 fop;
+ __u64 rip;
+ __u64 rdp;
+ __u32 mxcsr;
+ __u32 mxcsr_mask;
+ __u32 st_space[32]; /* 8x FP registers, 16 bytes each */
+ __u32 xmm_space[64]; /* 16x XMM registers, 16 bytes each */
+ __u32 reserved2[12];
union {
- __u32 reserved3[12];
- struct _fpx_sw_bytes sw_reserved; /* represents the extended
- * state information */
+ __u32 reserved3[12];
+ struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
};
};
-#ifndef __KERNEL__
-/*
- * User-space might still rely on the old definition:
- */
-struct sigcontext {
- __u64 r8;
- __u64 r9;
- __u64 r10;
- __u64 r11;
- __u64 r12;
- __u64 r13;
- __u64 r14;
- __u64 r15;
- __u64 rdi;
- __u64 rsi;
- __u64 rbp;
- __u64 rbx;
- __u64 rdx;
- __u64 rax;
- __u64 rcx;
- __u64 rsp;
- __u64 rip;
- __u64 eflags; /* RFLAGS */
- __u16 cs;
- __u16 gs;
- __u16 fs;
- __u16 __pad0;
- __u64 err;
- __u64 trapno;
- __u64 oldmask;
- __u64 cr2;
- struct _fpstate __user *fpstate; /* zero when no FPU context */
-#ifdef __ILP32__
- __u32 __fpstate_pad;
+#ifdef __i386__
+# define _fpstate _fpstate_32
+#else
+# define _fpstate _fpstate_64
#endif
- __u64 reserved1[8];
-};
-#endif /* !__KERNEL__ */
-
-#endif /* !__i386__ */
struct _header {
- __u64 xfeatures;
- __u64 reserved1[2];
- __u64 reserved2[5];
+ __u64 xfeatures;
+ __u64 reserved1[2];
+ __u64 reserved2[5];
};
struct _ymmh_state {
- /* 16 * 16 bytes for each YMMH-reg */
- __u32 ymmh_space[64];
+ /* 16x YMM registers, 16 bytes each: */
+ __u32 ymmh_space[64];
};
/*
- * Extended state pointed by the fpstate pointer in the sigcontext.
- * In addition to the fpstate, information encoded in the xstate_hdr
- * indicates the presence of other extended state information
- * supported by the processor and OS.
+ * Extended state pointed to by sigcontext::fpstate.
+ *
+ * In addition to the fpstate, information encoded in _xstate::xstate_hdr
+ * indicates the presence of other extended state information supported
+ * by the CPU and kernel:
*/
struct _xstate {
- struct _fpstate fpstate;
- struct _header xstate_hdr;
- struct _ymmh_state ymmh;
- /* new processor state extensions go here */
+ struct _fpstate fpstate;
+ struct _header xstate_hdr;
+ struct _ymmh_state ymmh;
+ /* New processor state extensions go here: */
+};
+
+/*
+ * The 32-bit signal frame:
+ */
+struct sigcontext_32 {
+ __u16 gs, __gsh;
+ __u16 fs, __fsh;
+ __u16 es, __esh;
+ __u16 ds, __dsh;
+ __u32 di;
+ __u32 si;
+ __u32 bp;
+ __u32 sp;
+ __u32 bx;
+ __u32 dx;
+ __u32 cx;
+ __u32 ax;
+ __u32 trapno;
+ __u32 err;
+ __u32 ip;
+ __u16 cs, __csh;
+ __u32 flags;
+ __u32 sp_at_signal;
+ __u16 ss, __ssh;
+
+ /*
+ * fpstate is really (struct _fpstate *) or (struct _xstate *)
+ * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
+ * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
+ * of extended memory layout. See comments at the definition of
+ * (struct _fpx_sw_bytes)
+ */
+ __u32 fpstate; /* Zero when no FPU/extended context */
+ __u32 oldmask;
+ __u32 cr2;
+};
+
+/*
+ * The 64-bit signal frame:
+ */
+struct sigcontext_64 {
+ __u64 r8;
+ __u64 r9;
+ __u64 r10;
+ __u64 r11;
+ __u64 r12;
+ __u64 r13;
+ __u64 r14;
+ __u64 r15;
+ __u64 di;
+ __u64 si;
+ __u64 bp;
+ __u64 bx;
+ __u64 dx;
+ __u64 ax;
+ __u64 cx;
+ __u64 sp;
+ __u64 ip;
+ __u64 flags;
+ __u16 cs;
+ __u16 gs;
+ __u16 fs;
+ __u16 ss;
+ __u64 err;
+ __u64 trapno;
+ __u64 oldmask;
+ __u64 cr2;
+
+ /*
+ * fpstate is really (struct _fpstate *) or (struct _xstate *)
+ * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
+ * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
+ * of extended memory layout. See comments at the definition of
+ * (struct _fpx_sw_bytes)
+ */
+ __u64 fpstate; /* Zero when no FPU/extended context */
+ __u64 reserved1[8];
+};
+
+/*
+ * Create the real 'struct sigcontext' type:
+ */
+#ifdef __KERNEL__
+# ifdef __i386__
+# define sigcontext sigcontext_32
+# else
+# define sigcontext sigcontext_64
+# endif
+#endif
+
+/*
+ * The old user-space sigcontext definition, just in case user-space still
+ * relies on it. The kernel definition (in asm/sigcontext.h) has unified
+ * field names but otherwise the same layout.
+ */
+#ifndef __KERNEL__
+
+#define _fpstate_ia32 _fpstate_32
+#define sigcontext_ia32 sigcontext_32
+
+
+# ifdef __i386__
+struct sigcontext {
+ __u16 gs, __gsh;
+ __u16 fs, __fsh;
+ __u16 es, __esh;
+ __u16 ds, __dsh;
+ __u32 edi;
+ __u32 esi;
+ __u32 ebp;
+ __u32 esp;
+ __u32 ebx;
+ __u32 edx;
+ __u32 ecx;
+ __u32 eax;
+ __u32 trapno;
+ __u32 err;
+ __u32 eip;
+ __u16 cs, __csh;
+ __u32 eflags;
+ __u32 esp_at_signal;
+ __u16 ss, __ssh;
+ struct _fpstate __user *fpstate;
+ __u32 oldmask;
+ __u32 cr2;
+};
+# else /* __x86_64__: */
+struct sigcontext {
+ __u64 r8;
+ __u64 r9;
+ __u64 r10;
+ __u64 r11;
+ __u64 r12;
+ __u64 r13;
+ __u64 r14;
+ __u64 r15;
+ __u64 rdi;
+ __u64 rsi;
+ __u64 rbp;
+ __u64 rbx;
+ __u64 rdx;
+ __u64 rax;
+ __u64 rcx;
+ __u64 rsp;
+ __u64 rip;
+ __u64 eflags; /* RFLAGS */
+ __u16 cs;
+
+ /*
+ * Prior to 2.5.64 ("[PATCH] x86-64 updates for 2.5.64-bk3"),
+ * Linux saved and restored fs and gs in these slots. This
+ * was counterproductive, as fsbase and gsbase were never
+ * saved, so arch_prctl was presumably unreliable.
+ *
+ * These slots should never be reused without extreme caution:
+ *
+ * - Some DOSEMU versions stash fs and gs in these slots manually,
+ * thus overwriting anything the kernel expects to be preserved
+ * in these slots.
+ *
+ * - If these slots are ever needed for any other purpose,
+ * there is some risk that very old 64-bit binaries could get
+ * confused. I doubt that many such binaries still work,
+ * though, since the same patch in 2.5.64 also removed the
+ * 64-bit set_thread_area syscall, so it appears that there
+ * is no TLS API beyond modify_ldt that works in both pre-
+ * and post-2.5.64 kernels.
+ *
+ * If the kernel ever adds explicit fs, gs, fsbase, and gsbase
+ * save/restore, it will most likely need to be opt-in and use
+ * different context slots.
+ */
+ __u16 gs;
+ __u16 fs;
+ union {
+ __u16 ss; /* If UC_SIGCONTEXT_SS */
+ __u16 __pad0; /* Alias name for old (!UC_SIGCONTEXT_SS) user-space */
+ };
+ __u64 err;
+ __u64 trapno;
+ __u64 oldmask;
+ __u64 cr2;
+ struct _fpstate __user *fpstate; /* Zero when no FPU context */
+# ifdef __ILP32__
+ __u32 __fpstate_pad;
+# endif
+ __u64 reserved1[8];
};
+# endif /* __x86_64__ */
+#endif /* !__KERNEL__ */
#endif /* _UAPI_ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/uapi/asm/sigcontext32.h b/arch/x86/include/uapi/asm/sigcontext32.h
index ad1478c..a92b0f0 100644
--- a/arch/x86/include/uapi/asm/sigcontext32.h
+++ b/arch/x86/include/uapi/asm/sigcontext32.h
@@ -1,77 +1,8 @@
#ifndef _ASM_X86_SIGCONTEXT32_H
#define _ASM_X86_SIGCONTEXT32_H
-#include <linux/types.h>
+/* This is a legacy file - all the type definitions are in sigcontext.h: */
-/* signal context for 32bit programs. */
-
-#define X86_FXSR_MAGIC 0x0000
-
-struct _fpreg {
- unsigned short significand[4];
- unsigned short exponent;
-};
-
-struct _fpxreg {
- unsigned short significand[4];
- unsigned short exponent;
- unsigned short padding[3];
-};
-
-struct _xmmreg {
- __u32 element[4];
-};
-
-/* FSAVE frame with extensions */
-struct _fpstate_ia32 {
- /* Regular FPU environment */
- __u32 cw;
- __u32 sw;
- __u32 tag; /* not compatible to 64bit twd */
- __u32 ipoff;
- __u32 cssel;
- __u32 dataoff;
- __u32 datasel;
- struct _fpreg _st[8];
- unsigned short status;
- unsigned short magic; /* 0xffff = regular FPU data only */
-
- /* FXSR FPU environment */
- __u32 _fxsr_env[6];
- __u32 mxcsr;
- __u32 reserved;
- struct _fpxreg _fxsr_st[8];
- struct _xmmreg _xmm[8]; /* It's actually 16 */
- __u32 padding[44];
- union {
- __u32 padding2[12];
- struct _fpx_sw_bytes sw_reserved;
- };
-};
-
-struct sigcontext_ia32 {
- unsigned short gs, __gsh;
- unsigned short fs, __fsh;
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned int di;
- unsigned int si;
- unsigned int bp;
- unsigned int sp;
- unsigned int bx;
- unsigned int dx;
- unsigned int cx;
- unsigned int ax;
- unsigned int trapno;
- unsigned int err;
- unsigned int ip;
- unsigned short cs, __csh;
- unsigned int flags;
- unsigned int sp_at_signal;
- unsigned short ss, __ssh;
- unsigned int fpstate; /* really (struct _fpstate_ia32 *) */
- unsigned int oldmask;
- unsigned int cr2;
-};
+#include <asm/sigcontext.h>
#endif /* _ASM_X86_SIGCONTEXT32_H */
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index b5d7640..8a4add8 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -100,6 +100,7 @@
{ SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
{ SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
{ SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
+ { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, \
{ SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
{ SVM_EXIT_INTR, "interrupt" }, \
{ SVM_EXIT_NMI, "nmi" }, \
diff --git a/arch/x86/include/uapi/asm/ucontext.h b/arch/x86/include/uapi/asm/ucontext.h
index b7c29c8..e3d1ec9 100644
--- a/arch/x86/include/uapi/asm/ucontext.h
+++ b/arch/x86/include/uapi/asm/ucontext.h
@@ -1,11 +1,54 @@
#ifndef _ASM_X86_UCONTEXT_H
#define _ASM_X86_UCONTEXT_H
-#define UC_FP_XSTATE 0x1 /* indicates the presence of extended state
- * information in the memory layout pointed
- * by the fpstate pointer in the ucontext's
- * sigcontext struct (uc_mcontext).
- */
+/*
+ * Indicates the presence of extended state information in the memory
+ * layout pointed by the fpstate pointer in the ucontext's sigcontext
+ * struct (uc_mcontext).
+ */
+#define UC_FP_XSTATE 0x1
+
+#ifdef __x86_64__
+/*
+ * UC_SIGCONTEXT_SS will be set when delivering 64-bit or x32 signals on
+ * kernels that save SS in the sigcontext. All kernels that set
+ * UC_SIGCONTEXT_SS will correctly restore at least the low 32 bits of esp
+ * regardless of SS (i.e. they implement espfix).
+ *
+ * Kernels that set UC_SIGCONTEXT_SS will also set UC_STRICT_RESTORE_SS
+ * when delivering a signal that came from 64-bit code.
+ *
+ * Sigreturn restores SS as follows:
+ *
+ * if (saved SS is valid || UC_STRICT_RESTORE_SS is set ||
+ * saved CS is not 64-bit)
+ * new SS = saved SS (will fail IRET and signal if invalid)
+ * else
+ * new SS = a flat 32-bit data segment
+ *
+ * This behavior serves three purposes:
+ *
+ * - Legacy programs that construct a 64-bit sigcontext from scratch
+ * with zero or garbage in the SS slot (e.g. old CRIU) and call
+ * sigreturn will still work.
+ *
+ * - Old DOSEMU versions sometimes catch a signal from a segmented
+ * context, delete the old SS segment (with modify_ldt), and change
+ * the saved CS to a 64-bit segment. These DOSEMU versions expect
+ * sigreturn to send them back to 64-bit mode without killing them,
+ * despite the fact that the SS selector when the signal was raised is
+ * no longer valid. UC_STRICT_RESTORE_SS will be clear, so the kernel
+ * will fix up SS for these DOSEMU versions.
+ *
+ * - Old and new programs that catch a signal and return without
+ * modifying the saved context will end up in exactly the state they
+ * started in, even if they were running in a segmented context when
+ * the signal was raised.. Old kernels would lose track of the
+ * previous SS value.
+ */
+#define UC_SIGCONTEXT_SS 0x2
+#define UC_STRICT_RESTORE_SS 0x4
+#endif
#include <asm-generic/ucontext.h>
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h
index 37fee27..5b15d94 100644
--- a/arch/x86/include/uapi/asm/vmx.h
+++ b/arch/x86/include/uapi/asm/vmx.h
@@ -78,6 +78,7 @@
#define EXIT_REASON_PML_FULL 62
#define EXIT_REASON_XSAVES 63
#define EXIT_REASON_XRSTORS 64
+#define EXIT_REASON_PCOMMIT 65
#define VMX_EXIT_REASONS \
{ EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
@@ -126,7 +127,8 @@
{ EXIT_REASON_INVVPID, "INVVPID" }, \
{ EXIT_REASON_INVPCID, "INVPCID" }, \
{ EXIT_REASON_XSAVES, "XSAVES" }, \
- { EXIT_REASON_XRSTORS, "XRSTORS" }
+ { EXIT_REASON_XRSTORS, "XRSTORS" }, \
+ { EXIT_REASON_PCOMMIT, "PCOMMIT" }
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ded848c..e759076 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -976,6 +976,8 @@ static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
int x2count = 0;
+ int ret;
+ struct acpi_subtable_proc madt_proc[2];
if (!cpu_has_apic)
return -ENODEV;
@@ -999,10 +1001,22 @@ static int __init acpi_parse_madt_lapic_entries(void)
acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) {
- x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
- acpi_parse_x2apic, MAX_LOCAL_APIC);
- count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
- acpi_parse_lapic, MAX_LOCAL_APIC);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+ madt_proc[0].handler = acpi_parse_lapic;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+ madt_proc[1].handler = acpi_parse_x2apic;
+ ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+ if (ret < 0) {
+ printk(KERN_ERR PREFIX
+ "Error parsing LAPIC/X2APIC entries\n");
+ return ret;
+ }
+
+ x2count = madt_proc[0].count;
+ count = madt_proc[1].count;
}
if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index d1daead..adb3eaf 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -16,6 +16,7 @@
#include <asm/cacheflush.h>
#include <asm/realmode.h>
+#include <linux/ftrace.h>
#include "../../realmode/rm/wakeup.h"
#include "sleep.h"
@@ -107,7 +108,13 @@ int x86_acpi_suspend_lowlevel(void)
saved_magic = 0x123456789abcdef0L;
#endif /* CONFIG_64BIT */
+ /*
+ * Pause/unpause graph tracing around do_suspend_lowlevel as it has
+ * inconsistent call/return info after it jumps to the wakeup vector.
+ */
+ pause_graph_tracing();
do_suspend_lowlevel();
+ unpause_graph_tracing();
return 0;
}
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 6e85f71..0a2bb1f 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -227,19 +227,11 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp)
return 0;
}
-static int gart_fix_e820 __initdata = 1;
+static bool gart_fix_e820 __initdata = true;
static int __init parse_gart_mem(char *p)
{
- if (!p)
- return -EINVAL;
-
- if (!strncmp(p, "off", 3))
- gart_fix_e820 = 0;
- else if (!strncmp(p, "on", 2))
- gart_fix_e820 = 1;
-
- return 0;
+ return kstrtobool(p, &gart_fix_e820);
}
early_param("gart_fix_e820", parse_gart_mem);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 24e94ce..531b961 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -82,6 +82,12 @@ physid_mask_t phys_cpu_present_map;
static unsigned int disabled_cpu_apicid __read_mostly = BAD_APICID;
/*
+ * This variable controls which CPUs receive external NMIs. By default,
+ * external NMIs are delivered only to the BSP.
+ */
+static int apic_extnmi = APIC_EXTNMI_BSP;
+
+/*
* Map cpu index to physical APIC ID
*/
DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid, BAD_APICID);
@@ -1161,6 +1167,8 @@ void __init init_bsp_APIC(void)
value = APIC_DM_NMI;
if (!lapic_is_integrated()) /* 82489DX */
value |= APIC_LVT_LEVEL_TRIGGER;
+ if (apic_extnmi == APIC_EXTNMI_NONE)
+ value |= APIC_LVT_MASKED;
apic_write(APIC_LVT1, value);
}
@@ -1378,9 +1386,11 @@ void setup_local_APIC(void)
apic_write(APIC_LVT0, value);
/*
- * only the BP should see the LINT1 NMI signal, obviously.
+ * Only the BSP sees the LINT1 NMI signal by default. This can be
+ * modified by apic_extnmi= boot option.
*/
- if (!cpu)
+ if ((!cpu && apic_extnmi != APIC_EXTNMI_NONE) ||
+ apic_extnmi == APIC_EXTNMI_ALL)
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
@@ -1431,7 +1441,7 @@ enum {
};
static int x2apic_state;
-static inline void __x2apic_disable(void)
+static void __x2apic_disable(void)
{
u64 msr;
@@ -1447,7 +1457,7 @@ static inline void __x2apic_disable(void)
printk_once(KERN_INFO "x2apic disabled\n");
}
-static inline void __x2apic_enable(void)
+static void __x2apic_enable(void)
{
u64 msr;
@@ -1807,7 +1817,7 @@ int apic_version[MAX_LOCAL_APIC];
/*
* This interrupt should _never_ happen with our APIC/SMP architecture
*/
-static inline void __smp_spurious_interrupt(u8 vector)
+static void __smp_spurious_interrupt(u8 vector)
{
u32 v;
@@ -1848,7 +1858,7 @@ __visible void smp_trace_spurious_interrupt(struct pt_regs *regs)
/*
* This interrupt should never happen with our APIC/SMP architecture
*/
-static inline void __smp_error_interrupt(struct pt_regs *regs)
+static void __smp_error_interrupt(struct pt_regs *regs)
{
u32 v;
u32 i = 0;
@@ -2068,6 +2078,20 @@ int generic_processor_info(int apicid, int version)
cpu = cpumask_next_zero(-1, cpu_present_mask);
/*
+ * This can happen on physical hotplug. The sanity check at boot time
+ * is done from native_smp_prepare_cpus() after num_possible_cpus() is
+ * established.
+ */
+ if (topology_update_package_map(apicid, cpu) < 0) {
+ int thiscpu = max + disabled_cpus;
+
+ pr_warning("ACPI: Package limit reached. Processor %d/0x%x ignored.\n",
+ thiscpu, apicid);
+ disabled_cpus++;
+ return -ENOSPC;
+ }
+
+ /*
* Validate version
*/
if (version == 0x0) {
@@ -2270,6 +2294,7 @@ static struct {
unsigned int apic_tmict;
unsigned int apic_tdcr;
unsigned int apic_thmr;
+ unsigned int apic_cmci;
} apic_pm_state;
static int lapic_suspend(void)
@@ -2299,6 +2324,10 @@ static int lapic_suspend(void)
if (maxlvt >= 5)
apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
#endif
+#ifdef CONFIG_X86_MCE_INTEL
+ if (maxlvt >= 6)
+ apic_pm_state.apic_cmci = apic_read(APIC_LVTCMCI);
+#endif
local_irq_save(flags);
disable_local_APIC();
@@ -2355,10 +2384,14 @@ static void lapic_resume(void)
apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_INTEL)
+#ifdef CONFIG_X86_THERMAL_VECTOR
if (maxlvt >= 5)
apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
#endif
+#ifdef CONFIG_X86_MCE_INTEL
+ if (maxlvt >= 6)
+ apic_write(APIC_LVTCMCI, apic_pm_state.apic_cmci);
+#endif
if (maxlvt >= 4)
apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
@@ -2548,3 +2581,23 @@ static int __init apic_set_disabled_cpu_apicid(char *arg)
return 0;
}
early_param("disable_cpu_apicid", apic_set_disabled_cpu_apicid);
+
+static int __init apic_set_extnmi(char *arg)
+{
+ if (!arg)
+ return -EINVAL;
+
+ if (!strncmp("all", arg, 3))
+ apic_extnmi = APIC_EXTNMI_ALL;
+ else if (!strncmp("none", arg, 4))
+ apic_extnmi = APIC_EXTNMI_NONE;
+ else if (!strncmp("bsp", arg, 3))
+ apic_extnmi = APIC_EXTNMI_BSP;
+ else {
+ pr_warn("Unknown external NMI delivery mode `%s' ignored\n", arg);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+early_param("apic_extnmi", apic_set_extnmi);
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index f92ab36..76f89e2 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -53,7 +53,7 @@ void flat_init_apic_ldr(void)
apic_write(APIC_LDR, val);
}
-static inline void _flat_send_IPI_mask(unsigned long mask, int vector)
+static void _flat_send_IPI_mask(unsigned long mask, int vector)
{
unsigned long flags;
@@ -185,6 +185,7 @@ static struct apic apic_flat = {
.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
+ .send_IPI = default_send_IPI_single,
.send_IPI_mask = flat_send_IPI_mask,
.send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself,
.send_IPI_allbutself = flat_send_IPI_allbutself,
@@ -230,17 +231,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return 0;
}
-static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector)
-{
- default_send_IPI_mask_sequence_phys(cpumask, vector);
-}
-
-static void physflat_send_IPI_mask_allbutself(const struct cpumask *cpumask,
- int vector)
-{
- default_send_IPI_mask_allbutself_phys(cpumask, vector);
-}
-
static void physflat_send_IPI_allbutself(int vector)
{
default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
@@ -248,7 +238,7 @@ static void physflat_send_IPI_allbutself(int vector)
static void physflat_send_IPI_all(int vector)
{
- physflat_send_IPI_mask(cpu_online_mask, vector);
+ default_send_IPI_mask_sequence_phys(cpu_online_mask, vector);
}
static int physflat_probe(void)
@@ -292,8 +282,9 @@ static struct apic apic_physflat = {
.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
- .send_IPI_mask = physflat_send_IPI_mask,
- .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself,
+ .send_IPI = default_send_IPI_single_phys,
+ .send_IPI_mask = default_send_IPI_mask_sequence_phys,
+ .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_phys,
.send_IPI_allbutself = physflat_send_IPI_allbutself,
.send_IPI_all = physflat_send_IPI_all,
.send_IPI_self = apic_send_IPI_self,
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
index 0d96749..331a7a0 100644
--- a/arch/x86/kernel/apic/apic_noop.c
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -30,6 +30,7 @@
#include <asm/e820.h>
static void noop_init_apic_ldr(void) { }
+static void noop_send_IPI(int cpu, int vector) { }
static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { }
static void noop_send_IPI_allbutself(int vector) { }
@@ -144,6 +145,7 @@ struct apic apic_noop = {
.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
+ .send_IPI = noop_send_IPI,
.send_IPI_mask = noop_send_IPI_mask,
.send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself,
.send_IPI_allbutself = noop_send_IPI_allbutself,
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index b548fd3..ab5c2c6 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -11,35 +11,26 @@
*
*/
-#include <linux/errno.h>
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ctype.h>
#include <linux/init.h>
-#include <linux/hardirq.h>
-#include <linux/delay.h>
#include <asm/numachip/numachip.h>
#include <asm/numachip/numachip_csr.h>
-#include <asm/smp.h>
-#include <asm/apic.h>
#include <asm/ipi.h>
#include <asm/apic_flat_64.h>
#include <asm/pgtable.h>
+#include <asm/pci_x86.h>
-static int numachip_system __read_mostly;
+u8 numachip_system __read_mostly;
+static const struct apic apic_numachip1;
+static const struct apic apic_numachip2;
+static void (*numachip_apic_icr_write)(int apicid, unsigned int val) __read_mostly;
-static const struct apic apic_numachip;
-
-static unsigned int get_apic_id(unsigned long x)
+static unsigned int numachip1_get_apic_id(unsigned long x)
{
unsigned long value;
unsigned int id = (x >> 24) & 0xff;
- if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+ if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
rdmsrl(MSR_FAM10H_NODE_ID, value);
id |= (value << 2) & 0xff00;
}
@@ -47,7 +38,7 @@ static unsigned int get_apic_id(unsigned long x)
return id;
}
-static unsigned long set_apic_id(unsigned int id)
+static unsigned long numachip1_set_apic_id(unsigned int id)
{
unsigned long x;
@@ -55,9 +46,17 @@ static unsigned long set_apic_id(unsigned int id)
return x;
}
-static unsigned int read_xapic_id(void)
+static unsigned int numachip2_get_apic_id(unsigned long x)
+{
+ u64 mcfg;
+
+ rdmsrl(MSR_FAM10H_MMIO_CONF_BASE, mcfg);
+ return ((mcfg >> (28 - 8)) & 0xfff00) | (x >> 24);
+}
+
+static unsigned long numachip2_set_apic_id(unsigned int id)
{
- return get_apic_id(apic_read(APIC_ID));
+ return id << 24;
}
static int numachip_apic_id_valid(int apicid)
@@ -68,7 +67,7 @@ static int numachip_apic_id_valid(int apicid)
static int numachip_apic_id_registered(void)
{
- return physid_isset(read_xapic_id(), phys_cpu_present_map);
+ return 1;
}
static int numachip_phys_pkg_id(int initial_apic_id, int index_msb)
@@ -76,36 +75,48 @@ static int numachip_phys_pkg_id(int initial_apic_id, int index_msb)
return initial_apic_id >> index_msb;
}
-static int numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+static void numachip1_apic_icr_write(int apicid, unsigned int val)
{
- union numachip_csr_g3_ext_irq_gen int_gen;
-
- int_gen.s._destination_apic_id = phys_apicid;
- int_gen.s._vector = 0;
- int_gen.s._msgtype = APIC_DM_INIT >> 8;
- int_gen.s._index = 0;
-
- write_lcsr(CSR_G3_EXT_IRQ_GEN, int_gen.v);
+ write_lcsr(CSR_G3_EXT_IRQ_GEN, (apicid << 16) | val);
+}
- int_gen.s._msgtype = APIC_DM_STARTUP >> 8;
- int_gen.s._vector = start_rip >> 12;
+static void numachip2_apic_icr_write(int apicid, unsigned int val)
+{
+ numachip2_write32_lcsr(NUMACHIP2_APIC_ICR, (apicid << 12) | val);
+}
- write_lcsr(CSR_G3_EXT_IRQ_GEN, int_gen.v);
+static int numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+{
+ numachip_apic_icr_write(phys_apicid, APIC_DM_INIT);
+ numachip_apic_icr_write(phys_apicid, APIC_DM_STARTUP |
+ (start_rip >> 12));
return 0;
}
static void numachip_send_IPI_one(int cpu, int vector)
{
- union numachip_csr_g3_ext_irq_gen int_gen;
- int apicid = per_cpu(x86_cpu_to_apicid, cpu);
-
- int_gen.s._destination_apic_id = apicid;
- int_gen.s._vector = vector;
- int_gen.s._msgtype = (vector == NMI_VECTOR ? APIC_DM_NMI : APIC_DM_FIXED) >> 8;
- int_gen.s._index = 0;
+ int local_apicid, apicid = per_cpu(x86_cpu_to_apicid, cpu);
+ unsigned int dmode;
+
+ preempt_disable();
+ local_apicid = __this_cpu_read(x86_cpu_to_apicid);
+
+ /* Send via local APIC where non-local part matches */
+ if (!((apicid ^ local_apicid) >> NUMACHIP_LAPIC_BITS)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __default_send_IPI_dest_field(apicid, vector,
+ APIC_DEST_PHYSICAL);
+ local_irq_restore(flags);
+ preempt_enable();
+ return;
+ }
+ preempt_enable();
- write_lcsr(CSR_G3_EXT_IRQ_GEN, int_gen.v);
+ dmode = (vector == NMI_VECTOR) ? APIC_DM_NMI : APIC_DM_FIXED;
+ numachip_apic_icr_write(apicid, dmode | vector);
}
static void numachip_send_IPI_mask(const struct cpumask *mask, int vector)
@@ -149,9 +160,14 @@ static void numachip_send_IPI_self(int vector)
apic_write(APIC_SELF_IPI, vector);
}
-static int __init numachip_probe(void)
+static int __init numachip1_probe(void)
{
- return apic == &apic_numachip;
+ return apic == &apic_numachip1;
+}
+
+static int __init numachip2_probe(void)
+{
+ return apic == &apic_numachip2;
}
static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
@@ -162,7 +178,7 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
this_cpu_write(cpu_llc_id, node);
/* Account for nodes per socket in multi-core-module processors */
- if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+ if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
rdmsrl(MSR_FAM10H_NODE_ID, val);
nodes = ((val >> 3) & 7) + 1;
}
@@ -172,11 +188,19 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
static int __init numachip_system_init(void)
{
- if (!numachip_system)
+ /* Map the LCSR area and set up the apic_icr_write function */
+ switch (numachip_system) {
+ case 1:
+ init_extra_mapping_uc(NUMACHIP_LCSR_BASE, NUMACHIP_LCSR_SIZE);
+ numachip_apic_icr_write = numachip1_apic_icr_write;
+ break;
+ case 2:
+ init_extra_mapping_uc(NUMACHIP2_LCSR_BASE, NUMACHIP2_LCSR_SIZE);
+ numachip_apic_icr_write = numachip2_apic_icr_write;
+ break;
+ default:
return 0;
-
- init_extra_mapping_uc(NUMACHIP_LCSR_BASE, NUMACHIP_LCSR_SIZE);
- init_extra_mapping_uc(NUMACHIP_GCSR_BASE, NUMACHIP_GCSR_SIZE);
+ }
x86_cpuinit.fixup_cpu_id = fixup_cpu_id;
x86_init.pci.arch_init = pci_numachip_init;
@@ -185,21 +209,95 @@ static int __init numachip_system_init(void)
}
early_initcall(numachip_system_init);
-static int numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int numachip1_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
- if (!strncmp(oem_id, "NUMASC", 6)) {
- numachip_system = 1;
- return 1;
- }
+ if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
+ (strncmp(oem_table_id, "NCONNECT", 8) != 0))
+ return 0;
- return 0;
+ numachip_system = 1;
+
+ return 1;
+}
+
+static int numachip2_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
+ (strncmp(oem_table_id, "NCONECT2", 8) != 0))
+ return 0;
+
+ numachip_system = 2;
+
+ return 1;
+}
+
+/* APIC IPIs are queued */
+static void numachip_apic_wait_icr_idle(void)
+{
}
-static const struct apic apic_numachip __refconst = {
+/* APIC NMI IPIs are queued */
+static u32 numachip_safe_apic_wait_icr_idle(void)
+{
+ return 0;
+}
+static const struct apic apic_numachip1 __refconst = {
.name = "NumaConnect system",
- .probe = numachip_probe,
- .acpi_madt_oem_check = numachip_acpi_madt_oem_check,
+ .probe = numachip1_probe,
+ .acpi_madt_oem_check = numachip1_acpi_madt_oem_check,
+ .apic_id_valid = numachip_apic_id_valid,
+ .apic_id_registered = numachip_apic_id_registered,
+
+ .irq_delivery_mode = dest_Fixed,
+ .irq_dest_mode = 0, /* physical */
+
+ .target_cpus = online_target_cpus,
+ .disable_esr = 0,
+ .dest_logical = 0,
+ .check_apicid_used = NULL,
+
+ .vector_allocation_domain = default_vector_allocation_domain,
+ .init_apic_ldr = flat_init_apic_ldr,
+
+ .ioapic_phys_id_map = NULL,
+ .setup_apic_routing = NULL,
+ .cpu_present_to_apicid = default_cpu_present_to_apicid,
+ .apicid_to_cpu_present = NULL,
+ .check_phys_apicid_present = default_check_phys_apicid_present,
+ .phys_pkg_id = numachip_phys_pkg_id,
+
+ .get_apic_id = numachip1_get_apic_id,
+ .set_apic_id = numachip1_set_apic_id,
+ .apic_id_mask = 0xffU << 24,
+
+ .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
+
+ .send_IPI = numachip_send_IPI_one,
+ .send_IPI_mask = numachip_send_IPI_mask,
+ .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself,
+ .send_IPI_allbutself = numachip_send_IPI_allbutself,
+ .send_IPI_all = numachip_send_IPI_all,
+ .send_IPI_self = numachip_send_IPI_self,
+
+ .wakeup_secondary_cpu = numachip_wakeup_secondary,
+ .inquire_remote_apic = NULL, /* REMRD not supported */
+
+ .read = native_apic_mem_read,
+ .write = native_apic_mem_write,
+ .eoi_write = native_apic_mem_write,
+ .icr_read = native_apic_icr_read,
+ .icr_write = native_apic_icr_write,
+ .wait_icr_idle = numachip_apic_wait_icr_idle,
+ .safe_wait_icr_idle = numachip_safe_apic_wait_icr_idle,
+};
+
+apic_driver(apic_numachip1);
+
+static const struct apic apic_numachip2 __refconst = {
+ .name = "NumaConnect2 system",
+ .probe = numachip2_probe,
+ .acpi_madt_oem_check = numachip2_acpi_madt_oem_check,
.apic_id_valid = numachip_apic_id_valid,
.apic_id_registered = numachip_apic_id_registered,
@@ -221,12 +319,13 @@ static const struct apic apic_numachip __refconst = {
.check_phys_apicid_present = default_check_phys_apicid_present,
.phys_pkg_id = numachip_phys_pkg_id,
- .get_apic_id = get_apic_id,
- .set_apic_id = set_apic_id,
+ .get_apic_id = numachip2_get_apic_id,
+ .set_apic_id = numachip2_set_apic_id,
.apic_id_mask = 0xffU << 24,
.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
+ .send_IPI = numachip_send_IPI_one,
.send_IPI_mask = numachip_send_IPI_mask,
.send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself,
.send_IPI_allbutself = numachip_send_IPI_allbutself,
@@ -241,8 +340,8 @@ static const struct apic apic_numachip __refconst = {
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
- .wait_icr_idle = native_apic_wait_icr_idle,
- .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
+ .wait_icr_idle = numachip_apic_wait_icr_idle,
+ .safe_wait_icr_idle = numachip_safe_apic_wait_icr_idle,
};
-apic_driver(apic_numachip);
+apic_driver(apic_numachip2);
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index 971cf88..cf9bd896 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -96,11 +96,6 @@ static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
return cpuid_apic >> index_msb;
}
-static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector)
-{
- default_send_IPI_mask_sequence_phys(mask, vector);
-}
-
static void bigsmp_send_IPI_allbutself(int vector)
{
default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
@@ -108,7 +103,7 @@ static void bigsmp_send_IPI_allbutself(int vector)
static void bigsmp_send_IPI_all(int vector)
{
- bigsmp_send_IPI_mask(cpu_online_mask, vector);
+ default_send_IPI_mask_sequence_phys(cpu_online_mask, vector);
}
static int dmi_bigsmp; /* can be set by dmi scanners */
@@ -180,7 +175,8 @@ static struct apic apic_bigsmp = {
.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
- .send_IPI_mask = bigsmp_send_IPI_mask,
+ .send_IPI = default_send_IPI_single_phys,
+ .send_IPI_mask = default_send_IPI_mask_sequence_phys,
.send_IPI_mask_allbutself = NULL,
.send_IPI_allbutself = bigsmp_send_IPI_allbutself,
.send_IPI_all = bigsmp_send_IPI_all,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4f28215..fdb0fbf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -529,7 +529,7 @@ static void __eoi_ioapic_pin(int apic, int pin, int vector)
}
}
-void eoi_ioapic_pin(int vector, struct mp_chip_data *data)
+static void eoi_ioapic_pin(int vector, struct mp_chip_data *data)
{
unsigned long flags;
struct irq_pin_list *entry;
@@ -2521,6 +2521,7 @@ void __init setup_ioapic_dest(void)
{
int pin, ioapic, irq, irq_entry;
const struct cpumask *mask;
+ struct irq_desc *desc;
struct irq_data *idata;
struct irq_chip *chip;
@@ -2536,7 +2537,9 @@ void __init setup_ioapic_dest(void)
if (irq < 0 || !mp_init_irq_at_boot(ioapic, irq))
continue;
- idata = irq_get_irq_data(irq);
+ desc = irq_to_desc(irq);
+ raw_spin_lock_irq(&desc->lock);
+ idata = irq_desc_get_irq_data(desc);
/*
* Honour affinities which have been set in early boot
@@ -2550,6 +2553,7 @@ void __init setup_ioapic_dest(void)
/* Might be lapic_chip for irq 0 */
if (chip->irq_set_affinity)
chip->irq_set_affinity(idata, mask, false);
+ raw_spin_unlock_irq(&desc->lock);
}
}
#endif
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c
index 6207156..28bde88 100644
--- a/arch/x86/kernel/apic/ipi.c
+++ b/arch/x86/kernel/apic/ipi.c
@@ -18,6 +18,76 @@
#include <asm/proto.h>
#include <asm/ipi.h>
+void __default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
+{
+ /*
+ * Subtle. In the case of the 'never do double writes' workaround
+ * we have to lock out interrupts to be safe. As we don't care
+ * of the value read we use an atomic rmw access to avoid costly
+ * cli/sti. Otherwise we use an even cheaper single atomic write
+ * to the APIC.
+ */
+ unsigned int cfg;
+
+ /*
+ * Wait for idle.
+ */
+ __xapic_wait_icr_idle();
+
+ /*
+ * No need to touch the target chip field
+ */
+ cfg = __prepare_ICR(shortcut, vector, dest);
+
+ /*
+ * Send the IPI. The write to APIC_ICR fires this off.
+ */
+ native_apic_mem_write(APIC_ICR, cfg);
+}
+
+/*
+ * This is used to send an IPI with no shorthand notation (the destination is
+ * specified in bits 56 to 63 of the ICR).
+ */
+void __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
+{
+ unsigned long cfg;
+
+ /*
+ * Wait for idle.
+ */
+ if (unlikely(vector == NMI_VECTOR))
+ safe_apic_wait_icr_idle();
+ else
+ __xapic_wait_icr_idle();
+
+ /*
+ * prepare target chip field
+ */
+ cfg = __prepare_ICR2(mask);
+ native_apic_mem_write(APIC_ICR2, cfg);
+
+ /*
+ * program the ICR
+ */
+ cfg = __prepare_ICR(0, vector, dest);
+
+ /*
+ * Send the IPI. The write to APIC_ICR fires this off.
+ */
+ native_apic_mem_write(APIC_ICR, cfg);
+}
+
+void default_send_IPI_single_phys(int cpu, int vector)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, cpu),
+ vector, APIC_DEST_PHYSICAL);
+ local_irq_restore(flags);
+}
+
void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector)
{
unsigned long query_cpu;
@@ -55,6 +125,14 @@ void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
local_irq_restore(flags);
}
+/*
+ * Helper function for APICs which insist on cpumasks
+ */
+void default_send_IPI_single(int cpu, int vector)
+{
+ apic->send_IPI_mask(cpumask_of(cpu), vector);
+}
+
#ifdef CONFIG_X86_32
void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..ade2532 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
return arg->msi_hwirq;
}
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
- int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+ msi_alloc_info_t *arg)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
return 0;
}
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
{
arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
}
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
static struct msi_domain_ops pci_msi_domain_ops = {
.get_hwirq = pci_msi_get_hwirq,
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 7694ae6..f316e34 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -105,6 +105,7 @@ static struct apic apic_default = {
.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
+ .send_IPI = default_send_IPI_single,
.send_IPI_mask = default_send_IPI_mask_logical,
.send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical,
.send_IPI_allbutself = default_send_IPI_allbutself,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 836d11b..3b670df 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,8 +29,9 @@ struct apic_chip_data {
};
struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
static DEFINE_RAW_SPINLOCK(vector_lock);
-static cpumask_var_t vector_cpumask;
+static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask;
static struct irq_chip lapic_controller;
#ifdef CONFIG_X86_IO_APIC
static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY];
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
return data ? &data->cfg : NULL;
}
+EXPORT_SYMBOL_GPL(irqd_cfg);
struct irq_cfg *irq_cfg(unsigned int irq)
{
@@ -116,35 +118,47 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d,
*/
static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START;
static int current_offset = VECTOR_OFFSET_START % 16;
- int cpu, err;
+ int cpu, vector;
- if (d->move_in_progress)
+ /*
+ * If there is still a move in progress or the previous move has not
+ * been cleaned up completely, tell the caller to come back later.
+ */
+ if (d->move_in_progress ||
+ cpumask_intersects(d->old_domain, cpu_online_mask))
return -EBUSY;
/* Only try and allocate irqs on cpus that are present */
- err = -ENOSPC;
cpumask_clear(d->old_domain);
+ cpumask_clear(searched_cpumask);
cpu = cpumask_first_and(mask, cpu_online_mask);
while (cpu < nr_cpu_ids) {
- int new_cpu, vector, offset;
+ int new_cpu, offset;
+ /* Get the possible target cpus for @mask/@cpu from the apic */
apic->vector_allocation_domain(cpu, vector_cpumask, mask);
+ /*
+ * Clear the offline cpus from @vector_cpumask for searching
+ * and verify whether the result overlaps with @mask. If true,
+ * then the call to apic->cpu_mask_to_apicid_and() will
+ * succeed as well. If not, no point in trying to find a
+ * vector in this mask.
+ */
+ cpumask_and(vector_searchmask, vector_cpumask, cpu_online_mask);
+ if (!cpumask_intersects(vector_searchmask, mask))
+ goto next_cpu;
+
if (cpumask_subset(vector_cpumask, d->domain)) {
- err = 0;
if (cpumask_equal(vector_cpumask, d->domain))
- break;
+ goto success;
/*
- * New cpumask using the vector is a proper subset of
- * the current in use mask. So cleanup the vector
- * allocation for the members that are not used anymore.
+ * Mark the cpus which are not longer in the mask for
+ * cleanup.
*/
- cpumask_andnot(d->old_domain, d->domain,
- vector_cpumask);
- d->move_in_progress =
- cpumask_intersects(d->old_domain, cpu_online_mask);
- cpumask_and(d->domain, d->domain, vector_cpumask);
- break;
+ cpumask_andnot(d->old_domain, d->domain, vector_cpumask);
+ vector = d->cfg.vector;
+ goto update;
}
vector = current_vector;
@@ -156,45 +170,60 @@ next:
vector = FIRST_EXTERNAL_VECTOR + offset;
}
- if (unlikely(current_vector == vector)) {
- cpumask_or(d->old_domain, d->old_domain,
- vector_cpumask);
- cpumask_andnot(vector_cpumask, mask, d->old_domain);
- cpu = cpumask_first_and(vector_cpumask,
- cpu_online_mask);
- continue;
- }
+ /* If the search wrapped around, try the next cpu */
+ if (unlikely(current_vector == vector))
+ goto next_cpu;
if (test_bit(vector, used_vectors))
goto next;
- for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
+ for_each_cpu(new_cpu, vector_searchmask) {
if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector]))
goto next;
}
/* Found one! */
current_vector = vector;
current_offset = offset;
- if (d->cfg.vector) {
+ /* Schedule the old vector for cleanup on all cpus */
+ if (d->cfg.vector)
cpumask_copy(d->old_domain, d->domain);
- d->move_in_progress =
- cpumask_intersects(d->old_domain, cpu_online_mask);
- }
- for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask)
+ for_each_cpu(new_cpu, vector_searchmask)
per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq);
- d->cfg.vector = vector;
- cpumask_copy(d->domain, vector_cpumask);
- err = 0;
- break;
- }
+ goto update;
- if (!err) {
- /* cache destination APIC IDs into cfg->dest_apicid */
- err = apic->cpu_mask_to_apicid_and(mask, d->domain,
- &d->cfg.dest_apicid);
+next_cpu:
+ /*
+ * We exclude the current @vector_cpumask from the requested
+ * @mask and try again with the next online cpu in the
+ * result. We cannot modify @mask, so we use @vector_cpumask
+ * as a temporary buffer here as it will be reassigned when
+ * calling apic->vector_allocation_domain() above.
+ */
+ cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask);
+ cpumask_andnot(vector_cpumask, mask, searched_cpumask);
+ cpu = cpumask_first_and(vector_cpumask, cpu_online_mask);
+ continue;
}
+ return -ENOSPC;
- return err;
+update:
+ /*
+ * Exclude offline cpus from the cleanup mask and set the
+ * move_in_progress flag when the result is not empty.
+ */
+ cpumask_and(d->old_domain, d->old_domain, cpu_online_mask);
+ d->move_in_progress = !cpumask_empty(d->old_domain);
+ d->cfg.vector = vector;
+ cpumask_copy(d->domain, vector_cpumask);
+success:
+ /*
+ * Cache destination APIC IDs into cfg->dest_apicid. This cannot fail
+ * as we already established, that mask & d->domain & cpu_online_mask
+ * is not empty.
+ */
+ BUG_ON(apic->cpu_mask_to_apicid_and(mask, d->domain,
+ &d->cfg.dest_apicid));
+ return 0;
}
static int assign_irq_vector(int irq, struct apic_chip_data *data,
@@ -224,10 +253,8 @@ static int assign_irq_vector_policy(int irq, int node,
static void clear_irq_vector(int irq, struct apic_chip_data *data)
{
struct irq_desc *desc;
- unsigned long flags;
int cpu, vector;
- raw_spin_lock_irqsave(&vector_lock, flags);
BUG_ON(!data->cfg.vector);
vector = data->cfg.vector;
@@ -237,10 +264,13 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
data->cfg.vector = 0;
cpumask_clear(data->domain);
- if (likely(!data->move_in_progress)) {
- raw_spin_unlock_irqrestore(&vector_lock, flags);
+ /*
+ * If move is in progress or the old_domain mask is not empty,
+ * i.e. the cleanup IPI has not been processed yet, we need to remove
+ * the old references to desc from all cpus vector tables.
+ */
+ if (!data->move_in_progress && cpumask_empty(data->old_domain))
return;
- }
desc = irq_to_desc(irq);
for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) {
@@ -253,7 +283,6 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
}
}
data->move_in_progress = 0;
- raw_spin_unlock_irqrestore(&vector_lock, flags);
}
void init_irq_alloc_info(struct irq_alloc_info *info,
@@ -274,19 +303,24 @@ void copy_irq_alloc_info(struct irq_alloc_info *dst, struct irq_alloc_info *src)
static void x86_vector_free_irqs(struct irq_domain *domain,
unsigned int virq, unsigned int nr_irqs)
{
+ struct apic_chip_data *apic_data;
struct irq_data *irq_data;
+ unsigned long flags;
int i;
for (i = 0; i < nr_irqs; i++) {
irq_data = irq_domain_get_irq_data(x86_vector_domain, virq + i);
if (irq_data && irq_data->chip_data) {
+ raw_spin_lock_irqsave(&vector_lock, flags);
clear_irq_vector(virq + i, irq_data->chip_data);
- free_apic_chip_data(irq_data->chip_data);
+ apic_data = irq_data->chip_data;
+ irq_domain_reset_irq_data(irq_data);
+ raw_spin_unlock_irqrestore(&vector_lock, flags);
+ free_apic_chip_data(apic_data);
#ifdef CONFIG_X86_IO_APIC
if (virq + i < nr_legacy_irqs())
legacy_irq_data[virq + i] = NULL;
#endif
- irq_domain_reset_irq_data(irq_data);
}
}
}
@@ -361,7 +395,11 @@ int __init arch_probe_nr_irqs(void)
if (nr < nr_irqs)
nr_irqs = nr;
- return nr_legacy_irqs();
+ /*
+ * We don't know if PIC is present at this point so we need to do
+ * probe() to get the right number of legacy IRQs.
+ */
+ return legacy_pic->probe();
}
#ifdef CONFIG_X86_IO_APIC
@@ -400,6 +438,8 @@ int __init arch_early_irq_init(void)
arch_init_htirq_domain(x86_vector_domain);
BUG_ON(!alloc_cpumask_var(&vector_cpumask, GFP_KERNEL));
+ BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL));
+ BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL));
return arch_early_ioapic_init();
}
@@ -488,14 +528,7 @@ static int apic_set_affinity(struct irq_data *irq_data,
return -EINVAL;
err = assign_irq_vector(irq, data, dest);
- if (err) {
- if (assign_irq_vector(irq, data,
- irq_data_get_affinity_mask(irq_data)))
- pr_err("Failed to recover vector for irq %d\n", irq);
- return err;
- }
-
- return IRQ_SET_MASK_OK;
+ return err ? err : IRQ_SET_MASK_OK;
}
static struct irq_chip lapic_controller = {
@@ -507,20 +540,12 @@ static struct irq_chip lapic_controller = {
#ifdef CONFIG_SMP
static void __send_cleanup_vector(struct apic_chip_data *data)
{
- cpumask_var_t cleanup_mask;
-
- if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
- unsigned int i;
-
- for_each_cpu_and(i, data->old_domain, cpu_online_mask)
- apic->send_IPI_mask(cpumask_of(i),
- IRQ_MOVE_CLEANUP_VECTOR);
- } else {
- cpumask_and(cleanup_mask, data->old_domain, cpu_online_mask);
- apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
- free_cpumask_var(cleanup_mask);
- }
+ raw_spin_lock(&vector_lock);
+ cpumask_and(data->old_domain, data->old_domain, cpu_online_mask);
data->move_in_progress = 0;
+ if (!cpumask_empty(data->old_domain))
+ apic->send_IPI_mask(data->old_domain, IRQ_MOVE_CLEANUP_VECTOR);
+ raw_spin_unlock(&vector_lock);
}
void send_cleanup_vector(struct irq_cfg *cfg)
@@ -564,12 +589,25 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
goto unlock;
/*
- * Check if the irq migration is in progress. If so, we
- * haven't received the cleanup request yet for this irq.
+ * Nothing to cleanup if irq migration is in progress
+ * or this cpu is not set in the cleanup mask.
*/
- if (data->move_in_progress)
+ if (data->move_in_progress ||
+ !cpumask_test_cpu(me, data->old_domain))
goto unlock;
+ /*
+ * We have two cases to handle here:
+ * 1) vector is unchanged but the target mask got reduced
+ * 2) vector and the target mask has changed
+ *
+ * #1 is obvious, but in #2 we have two vectors with the same
+ * irq descriptor: the old and the new vector. So we need to
+ * make sure that we only cleanup the old vector. The new
+ * vector has the current @vector number in the config and
+ * this cpu is part of the target mask. We better leave that
+ * one alone.
+ */
if (vector == data->cfg.vector &&
cpumask_test_cpu(me, data->domain))
goto unlock;
@@ -587,6 +625,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
goto unlock;
}
__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
+ cpumask_clear_cpu(me, data->old_domain);
unlock:
raw_spin_unlock(&desc->lock);
}
@@ -615,12 +654,48 @@ void irq_complete_move(struct irq_cfg *cfg)
__irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
}
-void irq_force_complete_move(int irq)
+/*
+ * Called with @desc->lock held and interrupts disabled.
+ */
+void irq_force_complete_move(struct irq_desc *desc)
{
- struct irq_cfg *cfg = irq_cfg(irq);
+ struct irq_data *irqdata = irq_desc_get_irq_data(desc);
+ struct apic_chip_data *data = apic_chip_data(irqdata);
+ struct irq_cfg *cfg = data ? &data->cfg : NULL;
- if (cfg)
- __irq_complete_move(cfg, cfg->vector);
+ if (!cfg)
+ return;
+
+ __irq_complete_move(cfg, cfg->vector);
+
+ /*
+ * This is tricky. If the cleanup of @data->old_domain has not been
+ * done yet, then the following setaffinity call will fail with
+ * -EBUSY. This can leave the interrupt in a stale state.
+ *
+ * The cleanup cannot make progress because we hold @desc->lock. So in
+ * case @data->old_domain is not yet cleaned up, we need to drop the
+ * lock and acquire it again. @desc cannot go away, because the
+ * hotplug code holds the sparse irq lock.
+ */
+ raw_spin_lock(&vector_lock);
+ /* Clean out all offline cpus (including ourself) first. */
+ cpumask_and(data->old_domain, data->old_domain, cpu_online_mask);
+ while (!cpumask_empty(data->old_domain)) {
+ raw_spin_unlock(&vector_lock);
+ raw_spin_unlock(&desc->lock);
+ cpu_relax();
+ raw_spin_lock(&desc->lock);
+ /*
+ * Reevaluate apic_chip_data. It might have been cleared after
+ * we dropped @desc->lock.
+ */
+ data = apic_chip_data(irqdata);
+ if (!data)
+ return;
+ raw_spin_lock(&vector_lock);
+ }
+ raw_spin_unlock(&vector_lock);
}
#endif
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index cc8311c..aca8b75 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -23,6 +23,14 @@ static inline u32 x2apic_cluster(int cpu)
return per_cpu(x86_cpu_to_logical_apicid, cpu) >> 16;
}
+static void x2apic_send_IPI(int cpu, int vector)
+{
+ u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu);
+
+ x2apic_wrmsr_fence();
+ __x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL);
+}
+
static void
__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
{
@@ -266,6 +274,7 @@ static struct apic apic_x2apic_cluster = {
.cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and,
+ .send_IPI = x2apic_send_IPI,
.send_IPI_mask = x2apic_send_IPI_mask,
.send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself,
.send_IPI_allbutself = x2apic_send_IPI_allbutself,
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c
index 662e915..a1242e2 100644
--- a/arch/x86/kernel/apic/x2apic_phys.c
+++ b/arch/x86/kernel/apic/x2apic_phys.c
@@ -36,6 +36,14 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return x2apic_enabled() && (x2apic_phys || x2apic_fadt_phys());
}
+static void x2apic_send_IPI(int cpu, int vector)
+{
+ u32 dest = per_cpu(x86_cpu_to_apicid, cpu);
+
+ x2apic_wrmsr_fence();
+ __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL);
+}
+
static void
__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
{
@@ -122,6 +130,7 @@ static struct apic apic_x2apic_phys = {
.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
+ .send_IPI = x2apic_send_IPI,
.send_IPI_mask = x2apic_send_IPI_mask,
.send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself,
.send_IPI_allbutself = x2apic_send_IPI_allbutself,
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 4a13946..624db005 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -406,6 +406,7 @@ static struct apic __refdata apic_x2apic_uv_x = {
.cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and,
+ .send_IPI = uv_send_IPI_one,
.send_IPI_mask = uv_send_IPI_mask,
.send_IPI_mask_allbutself = uv_send_IPI_mask_allbutself,
.send_IPI_allbutself = uv_send_IPI_allbutself,
@@ -888,7 +889,10 @@ void __init uv_system_init(void)
return;
}
pr_info("UV: Found %s hub\n", hub);
- map_low_mmrs();
+
+ /* We now only need to map the MMRs on UV1 */
+ if (is_uv1_hub())
+ map_low_mmrs();
m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR );
m_val = m_n_config.s.m_skt;
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 8e3d22a1..5c04246 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -43,18 +43,15 @@ void common(void) {
#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
BLANK();
- OFFSET(IA32_SIGCONTEXT_ax, sigcontext_ia32, ax);
- OFFSET(IA32_SIGCONTEXT_bx, sigcontext_ia32, bx);
- OFFSET(IA32_SIGCONTEXT_cx, sigcontext_ia32, cx);
- OFFSET(IA32_SIGCONTEXT_dx, sigcontext_ia32, dx);
- OFFSET(IA32_SIGCONTEXT_si, sigcontext_ia32, si);
- OFFSET(IA32_SIGCONTEXT_di, sigcontext_ia32, di);
- OFFSET(IA32_SIGCONTEXT_bp, sigcontext_ia32, bp);
- OFFSET(IA32_SIGCONTEXT_sp, sigcontext_ia32, sp);
- OFFSET(IA32_SIGCONTEXT_ip, sigcontext_ia32, ip);
-
- BLANK();
- OFFSET(TI_sysenter_return, thread_info, sysenter_return);
+ OFFSET(IA32_SIGCONTEXT_ax, sigcontext_32, ax);
+ OFFSET(IA32_SIGCONTEXT_bx, sigcontext_32, bx);
+ OFFSET(IA32_SIGCONTEXT_cx, sigcontext_32, cx);
+ OFFSET(IA32_SIGCONTEXT_dx, sigcontext_32, dx);
+ OFFSET(IA32_SIGCONTEXT_si, sigcontext_32, si);
+ OFFSET(IA32_SIGCONTEXT_di, sigcontext_32, di);
+ OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
+ OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
+ OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
BLANK();
OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
@@ -62,15 +59,11 @@ void common(void) {
#ifdef CONFIG_PARAVIRT
BLANK();
- OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
-#ifdef CONFIG_X86_32
- OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
-#endif
OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
#endif
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 6ce3902..ecdc1d2 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -7,7 +7,7 @@
#include <linux/lguest.h>
#include "../../../drivers/lguest/lg.h"
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_32.h>
};
@@ -52,6 +52,11 @@ void foo(void)
DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) -
offsetofend(struct tss_struct, SYSENTER_stack));
+ /* Offset from cpu_tss to SYSENTER_stack */
+ OFFSET(CPU_TSS_SYSENTER_stack, tss_struct, SYSENTER_stack);
+ /* Size of SYSENTER_stack */
+ DEFINE(SIZEOF_SYSENTER_stack, sizeof(((struct tss_struct *)0)->SYSENTER_stack));
+
#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE)
BLANK();
OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index d8f42f9..d875f97 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -4,17 +4,11 @@
#include <asm/ia32.h>
-#define __SYSCALL_64(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1,
-#ifdef CONFIG_X86_X32_ABI
-# define __SYSCALL_X32(nr, sym, compat) [nr] = 1,
-#else
-# define __SYSCALL_X32(nr, sym, compat) /* nothing */
-#endif
+#define __SYSCALL_64(nr, sym, qual) [nr] = 1,
static char syscalls_64[] = {
#include <asm/syscalls_64.h>
};
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls_ia32[] = {
#include <asm/syscalls_32.h>
};
@@ -23,7 +17,6 @@ int main(void)
{
#ifdef CONFIG_PARAVIRT
OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame);
- OFFSET(PV_CPU_usergs_sysret32, pv_cpu_ops, usergs_sysret32);
OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64);
OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
BLANK();
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 4eb065c..0d373d7 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -30,32 +30,11 @@ obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o
obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o
-obj-$(CONFIG_PERF_EVENTS) += perf_event.o
-
-ifdef CONFIG_PERF_EVENTS
-obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o perf_event_amd_uncore.o
-ifdef CONFIG_AMD_IOMMU
-obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o
-endif
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o perf_event_intel_cqm.o
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_pt.o perf_event_intel_bts.o
-
-obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \
- perf_event_intel_uncore_snb.o \
- perf_event_intel_uncore_snbep.o \
- perf_event_intel_uncore_nhmex.o
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_msr.o
-obj-$(CONFIG_CPU_SUP_AMD) += perf_event_msr.o
-endif
-
-
obj-$(CONFIG_X86_MCE) += mcheck/
obj-$(CONFIG_MTRR) += mtrr/
obj-$(CONFIG_MICROCODE) += microcode/
-obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o
+obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
@@ -63,7 +42,7 @@ ifdef CONFIG_X86_FEATURE_NAMES
quiet_cmd_mkcapflags = MKCAP $@
cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
-cpufeature = $(src)/../../include/asm/cpufeature.h
+cpufeature = $(src)/../../include/asm/cpufeatures.h
targets += capflags.c
$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 4a70fc6..97c59fd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -117,7 +117,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
void (*f_vide)(void);
u64 d, d2;
- printk(KERN_INFO "AMD K6 stepping B detected - ");
+ pr_info("AMD K6 stepping B detected - ");
/*
* It looks like AMD fixed the 2.6.2 bug and improved indirect
@@ -133,10 +133,9 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
d = d2-d;
if (d > 20*K6_BUG_LOOP)
- printk(KERN_CONT
- "system stability may be impaired when more than 32 MB are used.\n");
+ pr_cont("system stability may be impaired when more than 32 MB are used.\n");
else
- printk(KERN_CONT "probably OK (after B9730xxxx).\n");
+ pr_cont("probably OK (after B9730xxxx).\n");
}
/* K6 with old style WHCR */
@@ -154,7 +153,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
local_irq_restore(flags);
- printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
+ pr_info("Enabling old style K6 write allocation for %d Mb\n",
mbytes);
}
return;
@@ -175,7 +174,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
wbinvd();
wrmsr(MSR_K6_WHCR, l, h);
local_irq_restore(flags);
- printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
+ pr_info("Enabling new style K6 write allocation for %d Mb\n",
mbytes);
}
@@ -202,7 +201,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
*/
if (c->x86_model >= 6 && c->x86_model <= 10) {
if (!cpu_has(c, X86_FEATURE_XMM)) {
- printk(KERN_INFO "Enabling disabled K7/SSE Support.\n");
+ pr_info("Enabling disabled K7/SSE Support.\n");
msr_clear_bit(MSR_K7_HWCR, 15);
set_cpu_cap(c, X86_FEATURE_XMM);
}
@@ -216,9 +215,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
rdmsr(MSR_K7_CLK_CTL, l, h);
if ((l & 0xfff00000) != 0x20000000) {
- printk(KERN_INFO
- "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
- l, ((l & 0x000fffff)|0x20000000));
+ pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
+ l, ((l & 0x000fffff)|0x20000000));
wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
}
}
@@ -304,7 +302,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
int cpu = smp_processor_id();
/* get information required for multi-node processors */
- if (cpu_has_topoext) {
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
u32 eax, ebx, ecx, edx;
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
@@ -352,6 +350,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP
unsigned bits;
int cpu = smp_processor_id();
+ unsigned int socket_id, core_complex_id;
bits = c->x86_coreid_bits;
/* Low order bits define the core id (index of core in socket) */
@@ -361,6 +360,18 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
/* use socket ID also for last level cache */
per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
amd_get_topology(c);
+
+ /*
+ * Fix percpu cpu_llc_id here as LLC topology is different
+ * for Fam17h systems.
+ */
+ if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
+ return;
+
+ socket_id = (c->apicid >> bits) - 1;
+ core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3;
+
+ per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id;
#endif
}
@@ -421,8 +432,7 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
*/
int ht_nodeid = c->initial_apicid;
- if (ht_nodeid >= 0 &&
- __apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
+ if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
node = __apicid_to_node[ht_nodeid];
/* Pick a nearby node */
if (!node_online(node))
@@ -473,7 +483,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
unsigned long pfn = tseg >> PAGE_SHIFT;
- printk(KERN_DEBUG "tseg: %010llx\n", tseg);
+ pr_debug("tseg: %010llx\n", tseg);
if (pfn_range_is_mapped(pfn, pfn + 1))
set_memory_4k((unsigned long)__va(tseg), 1);
}
@@ -488,8 +498,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
rdmsrl(MSR_K7_HWCR, val);
if (!(val & BIT(24)))
- printk(KERN_WARNING FW_BUG "TSC doesn't count "
- "with P0 frequency!\n");
+ pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
}
}
@@ -665,9 +674,9 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
* Disable it on the affected CPUs.
*/
if ((c->x86_model >= 0x02) && (c->x86_model < 0x20)) {
- if (!rdmsrl_safe(0xc0011021, &value) && !(value & 0x1E)) {
+ if (!rdmsrl_safe(MSR_F15H_IC_CFG, &value) && !(value & 0x1E)) {
value |= 0x1E;
- wrmsrl_safe(0xc0011021, value);
+ wrmsrl_safe(MSR_F15H_IC_CFG, value);
}
}
}
@@ -909,7 +918,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
void set_dr_addr_mask(unsigned long mask, int dr)
{
- if (!cpu_has_bpext)
+ if (!boot_cpu_has(X86_FEATURE_BPEXT))
return;
switch (dr) {
diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c
index 04f0fe5..a972ac4 100644
--- a/arch/x86/kernel/cpu/bugs_64.c
+++ b/arch/x86/kernel/cpu/bugs_64.c
@@ -15,7 +15,7 @@ void __init check_bugs(void)
{
identify_boot_cpu();
#if !defined(CONFIG_SMP)
- printk(KERN_INFO "CPU: ");
+ pr_info("CPU: ");
print_cpu_info(&boot_cpu_data);
#endif
alternative_instructions();
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index d8fba5c..1661d8e 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -1,7 +1,7 @@
#include <linux/bitops.h>
#include <linux/kernel.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/e820.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
@@ -29,7 +29,7 @@ static void init_c3(struct cpuinfo_x86 *c)
rdmsr(MSR_VIA_FCR, lo, hi);
lo |= ACE_FCR; /* enable ACE unit */
wrmsr(MSR_VIA_FCR, lo, hi);
- printk(KERN_INFO "CPU: Enabled ACE h/w crypto\n");
+ pr_info("CPU: Enabled ACE h/w crypto\n");
}
/* enable RNG unit, if present and disabled */
@@ -37,13 +37,13 @@ static void init_c3(struct cpuinfo_x86 *c)
rdmsr(MSR_VIA_RNG, lo, hi);
lo |= RNG_ENABLE; /* enable RNG unit */
wrmsr(MSR_VIA_RNG, lo, hi);
- printk(KERN_INFO "CPU: Enabled h/w RNG\n");
+ pr_info("CPU: Enabled h/w RNG\n");
}
/* store Centaur Extended Feature Flags as
* word 5 of the CPU capability bit array
*/
- c->x86_capability[5] = cpuid_edx(0xC0000001);
+ c->x86_capability[CPUID_C000_0001_EDX] = cpuid_edx(0xC0000001);
}
#ifdef CONFIG_X86_32
/* Cyrix III family needs CX8 & PGE explicitly enabled. */
@@ -130,7 +130,7 @@ static void init_centaur(struct cpuinfo_x86 *c)
name = "C6";
fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
fcr_clr = DPDC;
- printk(KERN_NOTICE "Disabling bugged TSC.\n");
+ pr_notice("Disabling bugged TSC.\n");
clear_cpu_cap(c, X86_FEATURE_TSC);
break;
case 8:
@@ -163,11 +163,11 @@ static void init_centaur(struct cpuinfo_x86 *c)
newlo = (lo|fcr_set) & (~fcr_clr);
if (newlo != lo) {
- printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n",
+ pr_info("Centaur FCR was 0x%X now 0x%X\n",
lo, newlo);
wrmsr(MSR_IDT_FCR1, newlo, hi);
} else {
- printk(KERN_INFO "Centaur FCR is 0x%X\n", lo);
+ pr_info("Centaur FCR is 0x%X\n", lo);
}
/* Emulate MTRRs using Centaur's MCR. */
set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index de22ea7..249461f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -162,6 +162,22 @@ static int __init x86_mpx_setup(char *s)
}
__setup("nompx", x86_mpx_setup);
+static int __init x86_noinvpcid_setup(char *s)
+{
+ /* noinvpcid doesn't accept parameters */
+ if (s)
+ return -EINVAL;
+
+ /* do not emit a message if the feature is not present */
+ if (!boot_cpu_has(X86_FEATURE_INVPCID))
+ return 0;
+
+ setup_clear_cpu_cap(X86_FEATURE_INVPCID);
+ pr_info("noinvpcid: INVPCID feature disabled\n");
+ return 0;
+}
+early_param("noinvpcid", x86_noinvpcid_setup);
+
#ifdef CONFIG_X86_32
static int cachesize_override = -1;
static int disable_x86_serial_nr = 1;
@@ -228,7 +244,7 @@ static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
lo |= 0x200000;
wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
- printk(KERN_NOTICE "CPU serial number disabled.\n");
+ pr_notice("CPU serial number disabled.\n");
clear_cpu_cap(c, X86_FEATURE_PN);
/* Disabling the serial number may affect the cpuid level */
@@ -273,10 +289,9 @@ __setup("nosmap", setup_disable_smap);
static __always_inline void setup_smap(struct cpuinfo_x86 *c)
{
- unsigned long eflags;
+ unsigned long eflags = native_save_fl();
/* This should have been cleared long ago */
- raw_local_save_flags(eflags);
BUG_ON(eflags & X86_EFLAGS_AC);
if (cpu_has(c, X86_FEATURE_SMAP)) {
@@ -330,9 +345,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
if (!warn)
continue;
- printk(KERN_WARNING
- "CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n",
- x86_cap_flag(df->feature), df->level);
+ pr_warn("CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n",
+ x86_cap_flag(df->feature), df->level);
}
}
@@ -511,7 +525,7 @@ void detect_ht(struct cpuinfo_x86 *c)
smp_num_siblings = (ebx & 0xff0000) >> 16;
if (smp_num_siblings == 1) {
- printk_once(KERN_INFO "CPU0: Hyper-Threading is disabled\n");
+ pr_info_once("CPU0: Hyper-Threading is disabled\n");
goto out;
}
@@ -532,10 +546,10 @@ void detect_ht(struct cpuinfo_x86 *c)
out:
if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) {
- printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
- c->phys_proc_id);
- printk(KERN_INFO "CPU: Processor Core ID: %d\n",
- c->cpu_core_id);
+ pr_info("CPU: Physical Processor ID: %d\n",
+ c->phys_proc_id);
+ pr_info("CPU: Processor Core ID: %d\n",
+ c->cpu_core_id);
printed = 1;
}
#endif
@@ -560,9 +574,8 @@ static void get_cpu_vendor(struct cpuinfo_x86 *c)
}
}
- printk_once(KERN_ERR
- "CPU: vendor_id '%s' unknown, using generic init.\n" \
- "CPU: Your system may be unstable.\n", v);
+ pr_err_once("CPU: vendor_id '%s' unknown, using generic init.\n" \
+ "CPU: Your system may be unstable.\n", v);
c->x86_vendor = X86_VENDOR_UNKNOWN;
this_cpu = &default_cpu;
@@ -582,14 +595,9 @@ void cpu_detect(struct cpuinfo_x86 *c)
u32 junk, tfms, cap0, misc;
cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
- c->x86 = (tfms >> 8) & 0xf;
- c->x86_model = (tfms >> 4) & 0xf;
- c->x86_mask = tfms & 0xf;
-
- if (c->x86 == 0xf)
- c->x86 += (tfms >> 20) & 0xff;
- if (c->x86 >= 0x6)
- c->x86_model += ((tfms >> 16) & 0xf) << 4;
+ c->x86 = x86_family(tfms);
+ c->x86_model = x86_model(tfms);
+ c->x86_mask = x86_stepping(tfms);
if (cap0 & (1<<19)) {
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
@@ -600,50 +608,47 @@ void cpu_detect(struct cpuinfo_x86 *c)
void get_cpu_cap(struct cpuinfo_x86 *c)
{
- u32 tfms, xlvl;
- u32 ebx;
+ u32 eax, ebx, ecx, edx;
/* Intel-defined flags: level 0x00000001 */
if (c->cpuid_level >= 0x00000001) {
- u32 capability, excap;
+ cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
- cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
- c->x86_capability[0] = capability;
- c->x86_capability[4] = excap;
+ c->x86_capability[CPUID_1_ECX] = ecx;
+ c->x86_capability[CPUID_1_EDX] = edx;
}
/* Additional Intel-defined flags: level 0x00000007 */
if (c->cpuid_level >= 0x00000007) {
- u32 eax, ebx, ecx, edx;
-
cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
- c->x86_capability[9] = ebx;
+ c->x86_capability[CPUID_7_0_EBX] = ebx;
+
+ c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006);
}
/* Extended state features: level 0x0000000d */
if (c->cpuid_level >= 0x0000000d) {
- u32 eax, ebx, ecx, edx;
-
cpuid_count(0x0000000d, 1, &eax, &ebx, &ecx, &edx);
- c->x86_capability[10] = eax;
+ c->x86_capability[CPUID_D_1_EAX] = eax;
}
/* Additional Intel-defined flags: level 0x0000000F */
if (c->cpuid_level >= 0x0000000F) {
- u32 eax, ebx, ecx, edx;
/* QoS sub-leaf, EAX=0Fh, ECX=0 */
cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx);
- c->x86_capability[11] = edx;
+ c->x86_capability[CPUID_F_0_EDX] = edx;
+
if (cpu_has(c, X86_FEATURE_CQM_LLC)) {
/* will be overridden if occupancy monitoring exists */
c->x86_cache_max_rmid = ebx;
/* QoS sub-leaf, EAX=0Fh, ECX=1 */
cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
- c->x86_capability[12] = edx;
+ c->x86_capability[CPUID_F_1_EDX] = edx;
+
if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) {
c->x86_cache_max_rmid = ecx;
c->x86_cache_occ_scale = ebx;
@@ -655,21 +660,24 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
}
/* AMD-defined flags: level 0x80000001 */
- xlvl = cpuid_eax(0x80000000);
- c->extended_cpuid_level = xlvl;
+ eax = cpuid_eax(0x80000000);
+ c->extended_cpuid_level = eax;
+
+ if ((eax & 0xffff0000) == 0x80000000) {
+ if (eax >= 0x80000001) {
+ cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
- if ((xlvl & 0xffff0000) == 0x80000000) {
- if (xlvl >= 0x80000001) {
- c->x86_capability[1] = cpuid_edx(0x80000001);
- c->x86_capability[6] = cpuid_ecx(0x80000001);
+ c->x86_capability[CPUID_8000_0001_ECX] = ecx;
+ c->x86_capability[CPUID_8000_0001_EDX] = edx;
}
}
if (c->extended_cpuid_level >= 0x80000008) {
- u32 eax = cpuid_eax(0x80000008);
+ cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
c->x86_virt_bits = (eax >> 8) & 0xff;
c->x86_phys_bits = eax & 0xff;
+ c->x86_capability[CPUID_8000_0008_EBX] = ebx;
}
#ifdef CONFIG_X86_32
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
@@ -679,6 +687,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
if (c->extended_cpuid_level >= 0x80000007)
c->x86_power = cpuid_edx(0x80000007);
+ if (c->extended_cpuid_level >= 0x8000000a)
+ c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
+
init_scattered_cpuid_features(c);
}
@@ -763,7 +774,7 @@ void __init early_cpu_init(void)
int count = 0;
#ifdef CONFIG_PROCESSOR_SELECT
- printk(KERN_INFO "KERNEL supported cpus:\n");
+ pr_info("KERNEL supported cpus:\n");
#endif
for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
@@ -781,7 +792,7 @@ void __init early_cpu_init(void)
for (j = 0; j < 2; j++) {
if (!cpudev->c_ident[j])
continue;
- printk(KERN_INFO " %s %s\n", cpudev->c_vendor,
+ pr_info(" %s %s\n", cpudev->c_vendor,
cpudev->c_ident[j]);
}
}
@@ -806,6 +817,31 @@ static void detect_nopl(struct cpuinfo_x86 *c)
#else
set_cpu_cap(c, X86_FEATURE_NOPL);
#endif
+
+ /*
+ * ESPFIX is a strange bug. All real CPUs have it. Paravirt
+ * systems that run Linux at CPL > 0 may or may not have the
+ * issue, but, even if they have the issue, there's absolutely
+ * nothing we can do about it because we can't use the real IRET
+ * instruction.
+ *
+ * NB: For the time being, only 32-bit kernels support
+ * X86_BUG_ESPFIX as such. 64-bit kernels directly choose
+ * whether to apply espfix using paravirt hooks. If any
+ * non-paravirt system ever shows up that does *not* have the
+ * ESPFIX issue, we can change this.
+ */
+#ifdef CONFIG_X86_32
+#ifdef CONFIG_PARAVIRT
+ do {
+ extern void native_iret(void);
+ if (pv_cpu_ops.iret == native_iret)
+ set_cpu_bug(c, X86_BUG_ESPFIX);
+ } while (0);
+#else
+ set_cpu_bug(c, X86_BUG_ESPFIX);
+#endif
+#endif
}
static void generic_identify(struct cpuinfo_x86 *c)
@@ -980,6 +1016,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_NUMA
numa_add_cpu(smp_processor_id());
#endif
+ /* The boot/hotplug time assigment got cleared, restore it */
+ c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id);
}
/*
@@ -1064,7 +1102,7 @@ static void __print_cpu_msr(void)
for (index = index_min; index < index_max; index++) {
if (rdmsrl_safe(index, &val))
continue;
- printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
+ pr_info(" MSR%08x: %016llx\n", index, val);
}
}
}
@@ -1103,19 +1141,19 @@ void print_cpu_info(struct cpuinfo_x86 *c)
}
if (vendor && !strstr(c->x86_model_id, vendor))
- printk(KERN_CONT "%s ", vendor);
+ pr_cont("%s ", vendor);
if (c->x86_model_id[0])
- printk(KERN_CONT "%s", c->x86_model_id);
+ pr_cont("%s", c->x86_model_id);
else
- printk(KERN_CONT "%d86", c->x86);
+ pr_cont("%d86", c->x86);
- printk(KERN_CONT " (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
+ pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
if (c->x86_mask || c->cpuid_level >= 0)
- printk(KERN_CONT ", stepping: 0x%x)\n", c->x86_mask);
+ pr_cont(", stepping: 0x%x)\n", c->x86_mask);
else
- printk(KERN_CONT ")\n");
+ pr_cont(")\n");
print_cpu_msr(c);
}
@@ -1185,7 +1223,7 @@ void syscall_init(void)
* They both write to the same internal register. STAR allows to
* set CS/DS but only a 32bit target. LSTAR sets the 64bit rip.
*/
- wrmsrl(MSR_STAR, ((u64)__USER32_CS)<<48 | ((u64)__KERNEL_CS)<<32);
+ wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);
#ifdef CONFIG_IA32_EMULATION
@@ -1441,9 +1479,11 @@ void cpu_init(void)
show_ucode_info_early();
- printk(KERN_INFO "Initializing CPU#%d\n", cpu);
+ pr_info("Initializing CPU#%d\n", cpu);
- if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de)
+ if (cpu_feature_enabled(X86_FEATURE_VME) ||
+ cpu_has_tsc ||
+ boot_cpu_has(X86_FEATURE_DE))
cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
load_current_idt();
@@ -1476,20 +1516,6 @@ void cpu_init(void)
}
#endif
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-void warn_pre_alternatives(void)
-{
- WARN(1, "You're using static_cpu_has before alternatives have run!\n");
-}
-EXPORT_SYMBOL_GPL(warn_pre_alternatives);
-#endif
-
-inline bool __static_cpu_has_safe(u16 bit)
-{
- return boot_cpu_has(bit);
-}
-EXPORT_SYMBOL_GPL(__static_cpu_has_safe);
-
static void bsp_resume(void)
{
if (this_cpu->c_bsp_resume)
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index aaf152e..6adef9c 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -8,6 +8,7 @@
#include <linux/timer.h>
#include <asm/pci-direct.h>
#include <asm/tsc.h>
+#include <asm/cpufeature.h>
#include "cpu.h"
@@ -103,7 +104,7 @@ static void check_cx686_slop(struct cpuinfo_x86 *c)
local_irq_restore(flags);
if (ccr5 & 2) { /* possible wrong calibration done */
- printk(KERN_INFO "Recalibrating delay loop with SLOP bit reset\n");
+ pr_info("Recalibrating delay loop with SLOP bit reset\n");
calibrate_delay();
c->loops_per_jiffy = loops_per_jiffy;
}
@@ -115,7 +116,7 @@ static void set_cx86_reorder(void)
{
u8 ccr3;
- printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
+ pr_info("Enable Memory access reorder on Cyrix/NSC processor.\n");
ccr3 = getCx86(CX86_CCR3);
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
@@ -128,7 +129,7 @@ static void set_cx86_reorder(void)
static void set_cx86_memwb(void)
{
- printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
+ pr_info("Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
/* CCR2 bit 2: unlock NW bit */
setCx86_old(CX86_CCR2, getCx86_old(CX86_CCR2) & ~0x04);
@@ -268,7 +269,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)
* VSA1 we work around however.
*/
- printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n");
+ pr_info("Working around Cyrix MediaGX virtual DMA bugs.\n");
isa_dma_bridge_buggy = 2;
/* We do this before the PCI layer is running. However we
@@ -426,7 +427,7 @@ static void cyrix_identify(struct cpuinfo_x86 *c)
if (dir0 == 5 || dir0 == 3) {
unsigned char ccr3;
unsigned long flags;
- printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
+ pr_info("Enabling CPUID on Cyrix processor.\n");
local_irq_save(flags);
ccr3 = getCx86(CX86_CCR3);
/* enable MAPEN */
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index d820d8e..73d391a 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -56,7 +56,7 @@ detect_hypervisor_vendor(void)
}
if (max_pri)
- printk(KERN_INFO "Hypervisor detected: %s\n", x86_hyper->name);
+ pr_info("Hypervisor detected: %s\n", x86_hyper->name);
}
void init_hypervisor(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 98a13db..1f7fdb9 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -8,7 +8,7 @@
#include <linux/module.h>
#include <linux/uaccess.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/pgtable.h>
#include <asm/msr.h>
#include <asm/bugs.h>
@@ -61,7 +61,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
*/
if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 &&
c->microcode < 0x20e) {
- printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
+ pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
clear_cpu_cap(c, X86_FEATURE_PSE);
}
@@ -97,6 +97,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
switch (c->x86_model) {
case 0x27: /* Penwell */
case 0x35: /* Cloverview */
+ case 0x4a: /* Merrifield */
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
break;
default:
@@ -139,7 +140,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
- printk(KERN_INFO "Disabled fast string operations\n");
+ pr_info("Disabled fast string operations\n");
setup_clear_cpu_cap(X86_FEATURE_REP_GOOD);
setup_clear_cpu_cap(X86_FEATURE_ERMS);
}
@@ -159,6 +160,19 @@ static void early_init_intel(struct cpuinfo_x86 *c)
pr_info("Disabling PGE capability bit\n");
setup_clear_cpu_cap(X86_FEATURE_PGE);
}
+
+ if (c->cpuid_level >= 0x00000001) {
+ u32 eax, ebx, ecx, edx;
+
+ cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
+ /*
+ * If HTT (EDX[28]) is set EBX[16:23] contain the number of
+ * apicids which are reserved per package. Store the resulting
+ * shift value for the package management code.
+ */
+ if (edx & (1U << 28))
+ c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
+ }
}
#ifdef CONFIG_X86_32
@@ -175,7 +189,7 @@ int ppro_with_ram_bug(void)
boot_cpu_data.x86 == 6 &&
boot_cpu_data.x86_model == 1 &&
boot_cpu_data.x86_mask < 8) {
- printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n");
+ pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n");
return 1;
}
return 0;
@@ -224,7 +238,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
set_cpu_bug(c, X86_BUG_F00F);
if (!f00f_workaround_enabled) {
- printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
+ pr_notice("Intel Pentium with F0 0F bug - workaround enabled.\n");
f00f_workaround_enabled = 1;
}
}
@@ -243,7 +257,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
* Forcefully enable PAE if kernel parameter "forcepae" is present.
*/
if (forcepae) {
- printk(KERN_WARNING "PAE forced!\n");
+ pr_warn("PAE forced!\n");
set_cpu_cap(c, X86_FEATURE_PAE);
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);
}
@@ -444,7 +458,8 @@ static void init_intel(struct cpuinfo_x86 *c)
if (cpu_has_xmm2)
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
- if (cpu_has_ds) {
+
+ if (boot_cpu_has(X86_FEATURE_DS)) {
unsigned int l1;
rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
if (!(l1 & (1<<11)))
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index be4febc..de6626c 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -14,7 +14,7 @@
#include <linux/sysfs.h>
#include <linux/pci.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/amd_nb.h>
#include <asm/smp.h>
@@ -157,7 +157,7 @@ struct _cpuid4_info_regs {
struct amd_northbridge *nb;
};
-unsigned short num_cache_leaves;
+static unsigned short num_cache_leaves;
/* AMD doesn't have CPUID4. Emulate it here to report the same
information to the user. This makes some assumptions about the machine:
@@ -326,7 +326,7 @@ static void amd_calc_l3_indices(struct amd_northbridge *nb)
*
* @returns: the disabled index if used or negative value if slot free.
*/
-int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot)
+static int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot)
{
unsigned int reg = 0;
@@ -403,8 +403,8 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu,
*
* @return: 0 on success, error status on failure
*/
-int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot,
- unsigned long index)
+static int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu,
+ unsigned slot, unsigned long index)
{
int ret = 0;
@@ -444,7 +444,7 @@ static ssize_t store_cache_disable(struct cacheinfo *this_leaf,
err = amd_set_l3_disable_slot(nb, cpu, slot, val);
if (err) {
if (err == -EEXIST)
- pr_warning("L3 slot %d in use/index already disabled!\n",
+ pr_warn("L3 slot %d in use/index already disabled!\n",
slot);
return err;
}
@@ -591,7 +591,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf)
unsigned edx;
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
- if (cpu_has_topoext)
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT))
cpuid_count(0x8000001d, index, &eax.full,
&ebx.full, &ecx.full, &edx);
else
@@ -637,7 +637,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
void init_amd_cacheinfo(struct cpuinfo_x86 *c)
{
- if (cpu_has_topoext) {
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
num_cache_leaves = find_num_cache_leaves(c);
} else if (c->extended_cpuid_level >= 0x80000006) {
if (cpuid_edx(0x80000006) & 0xf000)
@@ -809,7 +809,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
struct cacheinfo *this_leaf;
int i, sibling;
- if (cpu_has_topoext) {
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
unsigned int apicid, nshared, first, last;
this_leaf = this_cpu_ci->info_list + index;
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index afa9f0d..fbb5e90 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -1,5 +1,5 @@
#include <asm/cpu_device_id.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 4cfba43..517619e 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -115,7 +115,7 @@ static int raise_local(void)
int cpu = m->extcpu;
if (m->inject_flags & MCJ_EXCEPTION) {
- printk(KERN_INFO "Triggering MCE exception on CPU %d\n", cpu);
+ pr_info("Triggering MCE exception on CPU %d\n", cpu);
switch (context) {
case MCJ_CTX_IRQ:
/*
@@ -128,15 +128,15 @@ static int raise_local(void)
raise_exception(m, NULL);
break;
default:
- printk(KERN_INFO "Invalid MCE context\n");
+ pr_info("Invalid MCE context\n");
ret = -EINVAL;
}
- printk(KERN_INFO "MCE exception done on CPU %d\n", cpu);
+ pr_info("MCE exception done on CPU %d\n", cpu);
} else if (m->status) {
- printk(KERN_INFO "Starting machine check poll CPU %d\n", cpu);
+ pr_info("Starting machine check poll CPU %d\n", cpu);
raise_poll(m);
mce_notify_irq();
- printk(KERN_INFO "Machine check poll done on CPU %d\n", cpu);
+ pr_info("Machine check poll done on CPU %d\n", cpu);
} else
m->finished = 0;
@@ -183,8 +183,7 @@ static void raise_mce(struct mce *m)
start = jiffies;
while (!cpumask_empty(mce_inject_cpumask)) {
if (!time_before(jiffies, start + 2*HZ)) {
- printk(KERN_ERR
- "Timeout waiting for mce inject %lx\n",
+ pr_err("Timeout waiting for mce inject %lx\n",
*cpumask_bits(mce_inject_cpumask));
break;
}
@@ -241,7 +240,7 @@ static int inject_init(void)
{
if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
return -ENOMEM;
- printk(KERN_INFO "Machine check injector initialized\n");
+ pr_info("Machine check injector initialized\n");
register_mce_write_callback(mce_write);
register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
"mce_notify");
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 9c682c2..5119766 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/debugfs.h>
#include <asm/mce.h>
+#include <asm/uaccess.h>
#include "mce-internal.h"
@@ -29,7 +30,7 @@
* panic situations)
*/
-enum context { IN_KERNEL = 1, IN_USER = 2 };
+enum context { IN_KERNEL = 1, IN_USER = 2, IN_KERNEL_RECOV = 3 };
enum ser { SER_REQUIRED = 1, NO_SER = 2 };
enum exception { EXCP_CONTEXT = 1, NO_EXCP = 2 };
@@ -48,6 +49,7 @@ static struct severity {
#define MCESEV(s, m, c...) { .sev = MCE_ ## s ## _SEVERITY, .msg = m, ## c }
#define KERNEL .context = IN_KERNEL
#define USER .context = IN_USER
+#define KERNEL_RECOV .context = IN_KERNEL_RECOV
#define SER .ser = SER_REQUIRED
#define NOSER .ser = NO_SER
#define EXCP .excp = EXCP_CONTEXT
@@ -87,6 +89,10 @@ static struct severity {
EXCP, KERNEL, MCGMASK(MCG_STATUS_RIPV, 0)
),
MCESEV(
+ PANIC, "In kernel and no restart IP",
+ EXCP, KERNEL_RECOV, MCGMASK(MCG_STATUS_RIPV, 0)
+ ),
+ MCESEV(
DEFERRED, "Deferred error",
NOSER, MASK(MCI_STATUS_UC|MCI_STATUS_DEFERRED|MCI_STATUS_POISON, MCI_STATUS_DEFERRED)
),
@@ -123,6 +129,11 @@ static struct severity {
MCGMASK(MCG_STATUS_RIPV|MCG_STATUS_EIPV, MCG_STATUS_RIPV)
),
MCESEV(
+ AR, "Action required: data load in error recoverable area of kernel",
+ SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
+ KERNEL_RECOV
+ ),
+ MCESEV(
AR, "Action required: data load error in a user process",
SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
USER
@@ -170,6 +181,9 @@ static struct severity {
) /* always matches. keep at end */
};
+#define mc_recoverable(mcg) (((mcg) & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) == \
+ (MCG_STATUS_RIPV|MCG_STATUS_EIPV))
+
/*
* If mcgstatus indicated that ip/cs on the stack were
* no good, then "m->cs" will be zero and we will have
@@ -183,7 +197,11 @@ static struct severity {
*/
static int error_context(struct mce *m)
{
- return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
+ if ((m->cs & 3) == 3)
+ return IN_USER;
+ if (mc_recoverable(m->mcgstatus) && ex_has_fault_handler(m->ip))
+ return IN_KERNEL_RECOV;
+ return IN_KERNEL;
}
/*
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 9d014b82..f0c921b 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -114,7 +114,6 @@ static struct work_struct mce_work;
static struct irq_work mce_irq_work;
static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
-static int mce_usable_address(struct mce *m);
/*
* CPU/chipset specific EDAC code can register a notifier call here to print
@@ -475,6 +474,28 @@ static void mce_report_event(struct pt_regs *regs)
irq_work_queue(&mce_irq_work);
}
+/*
+ * Check if the address reported by the CPU is in a format we can parse.
+ * It would be possible to add code for most other cases, but all would
+ * be somewhat complicated (e.g. segment offset would require an instruction
+ * parser). So only support physical addresses up to page granuality for now.
+ */
+static int mce_usable_address(struct mce *m)
+{
+ if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
+ return 0;
+
+ /* Checks after this one are Intel-specific: */
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+ return 1;
+
+ if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT)
+ return 0;
+ if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS)
+ return 0;
+ return 1;
+}
+
static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
@@ -484,7 +505,7 @@ static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
if (!mce)
return NOTIFY_DONE;
- if (mce->usable_addr && (mce->severity == MCE_AO_SEVERITY)) {
+ if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
pfn = mce->addr >> PAGE_SHIFT;
memory_failure(pfn, MCE_VECTOR, 0);
}
@@ -522,10 +543,10 @@ static bool memory_error(struct mce *m)
struct cpuinfo_x86 *c = &boot_cpu_data;
if (c->x86_vendor == X86_VENDOR_AMD) {
- /*
- * coming soon
- */
- return false;
+ /* ErrCodeExt[20:16] */
+ u8 xec = (m->status >> 16) & 0x1f;
+
+ return (xec == 0x0 || xec == 0x8);
} else if (c->x86_vendor == X86_VENDOR_INTEL) {
/*
* Intel SDM Volume 3B - 15.9.2 Compound Error Codes
@@ -567,7 +588,7 @@ DEFINE_PER_CPU(unsigned, mce_poll_count);
*/
bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
{
- bool error_logged = false;
+ bool error_seen = false;
struct mce m;
int severity;
int i;
@@ -601,6 +622,8 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
(m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC)))
continue;
+ error_seen = true;
+
mce_read_aux(&m, i);
if (!(flags & MCP_TIMESTAMP))
@@ -608,27 +631,24 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
severity = mce_severity(&m, mca_cfg.tolerant, NULL, false);
- /*
- * In the cases where we don't have a valid address after all,
- * do not add it into the ring buffer.
- */
- if (severity == MCE_DEFERRED_SEVERITY && memory_error(&m)) {
- if (m.status & MCI_STATUS_ADDRV) {
+ if (severity == MCE_DEFERRED_SEVERITY && memory_error(&m))
+ if (m.status & MCI_STATUS_ADDRV)
m.severity = severity;
- m.usable_addr = mce_usable_address(&m);
-
- if (!mce_gen_pool_add(&m))
- mce_schedule_work();
- }
- }
/*
* Don't get the IP here because it's unlikely to
* have anything to do with the actual error location.
*/
- if (!(flags & MCP_DONTLOG) && !mca_cfg.dont_log_ce) {
- error_logged = true;
+ if (!(flags & MCP_DONTLOG) && !mca_cfg.dont_log_ce)
mce_log(&m);
+ else if (mce_usable_address(&m)) {
+ /*
+ * Although we skipped logging this, we still want
+ * to take action. Add to the pool so the registered
+ * notifiers will see it.
+ */
+ if (!mce_gen_pool_add(&m))
+ mce_schedule_work();
}
/*
@@ -644,7 +664,7 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
sync_core();
- return error_logged;
+ return error_seen;
}
EXPORT_SYMBOL_GPL(machine_check_poll);
@@ -931,23 +951,6 @@ reset:
return ret;
}
-/*
- * Check if the address reported by the CPU is in a format we can parse.
- * It would be possible to add code for most other cases, but all would
- * be somewhat complicated (e.g. segment offset would require an instruction
- * parser). So only support physical addresses up to page granuality for now.
- */
-static int mce_usable_address(struct mce *m)
-{
- if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV))
- return 0;
- if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT)
- return 0;
- if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS)
- return 0;
- return 1;
-}
-
static void mce_clear_state(unsigned long *toclear)
{
int i;
@@ -958,6 +961,20 @@ static void mce_clear_state(unsigned long *toclear)
}
}
+static int do_memory_failure(struct mce *m)
+{
+ int flags = MF_ACTION_REQUIRED;
+ int ret;
+
+ pr_err("Uncorrected hardware memory error in user-access at %llx", m->addr);
+ if (!(m->mcgstatus & MCG_STATUS_RIPV))
+ flags |= MF_MUST_KILL;
+ ret = memory_failure(m->addr >> PAGE_SHIFT, MCE_VECTOR, flags);
+ if (ret)
+ pr_err("Memory error not recovered");
+ return ret;
+}
+
/*
* The actual machine check handler. This only handles real
* exceptions when something got corrupted coming in through int 18.
@@ -995,10 +1012,19 @@ void do_machine_check(struct pt_regs *regs, long error_code)
DECLARE_BITMAP(toclear, MAX_NR_BANKS);
DECLARE_BITMAP(valid_banks, MAX_NR_BANKS);
char *msg = "Unknown";
- u64 recover_paddr = ~0ull;
- int flags = MF_ACTION_REQUIRED;
int lmce = 0;
+ /* If this CPU is offline, just bail out. */
+ if (cpu_is_offline(smp_processor_id())) {
+ u64 mcgstatus;
+
+ mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
+ if (mcgstatus & MCG_STATUS_RIPV) {
+ mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
+ return;
+ }
+ }
+
ist_enter(regs);
this_cpu_inc(mce_exception_count);
@@ -1089,7 +1115,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
/* assuming valid severity level != 0 */
m.severity = severity;
- m.usable_addr = mce_usable_address(&m);
mce_log(&m);
@@ -1123,22 +1148,13 @@ void do_machine_check(struct pt_regs *regs, long error_code)
}
/*
- * At insane "tolerant" levels we take no action. Otherwise
- * we only die if we have no other choice. For less serious
- * issues we try to recover, or limit damage to the current
- * process.
+ * If tolerant is at an insane level we drop requests to kill
+ * processes and continue even when there is no way out.
*/
- if (cfg->tolerant < 3) {
- if (no_way_out)
- mce_panic("Fatal machine check on current CPU", &m, msg);
- if (worst == MCE_AR_SEVERITY) {
- recover_paddr = m.addr;
- if (!(m.mcgstatus & MCG_STATUS_RIPV))
- flags |= MF_MUST_KILL;
- } else if (kill_it) {
- force_sig(SIGBUS, current);
- }
- }
+ if (cfg->tolerant == 3)
+ kill_it = 0;
+ else if (no_way_out)
+ mce_panic("Fatal machine check on current CPU", &m, msg);
if (worst > 0)
mce_report_event(regs);
@@ -1146,25 +1162,24 @@ void do_machine_check(struct pt_regs *regs, long error_code)
out:
sync_core();
- if (recover_paddr == ~0ull)
- goto done;
+ if (worst != MCE_AR_SEVERITY && !kill_it)
+ goto out_ist;
- pr_err("Uncorrected hardware memory error in user-access at %llx",
- recover_paddr);
- /*
- * We must call memory_failure() here even if the current process is
- * doomed. We still need to mark the page as poisoned and alert any
- * other users of the page.
- */
- ist_begin_non_atomic(regs);
- local_irq_enable();
- if (memory_failure(recover_paddr >> PAGE_SHIFT, MCE_VECTOR, flags) < 0) {
- pr_err("Memory error not recovered");
- force_sig(SIGBUS, current);
+ /* Fault was in user mode and we need to take some action */
+ if ((m.cs & 3) == 3) {
+ ist_begin_non_atomic(regs);
+ local_irq_enable();
+
+ if (kill_it || do_memory_failure(&m))
+ force_sig(SIGBUS, current);
+ local_irq_disable();
+ ist_end_non_atomic();
+ } else {
+ if (!fixup_exception(regs, X86_TRAP_MC))
+ mce_panic("Failed kernel mode recovery", &m, NULL);
}
- local_irq_disable();
- ist_end_non_atomic();
-done:
+
+out_ist:
ist_exit(regs);
}
EXPORT_SYMBOL_GPL(do_machine_check);
@@ -1563,6 +1578,17 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
if (c->x86 == 6 && c->x86_model == 45)
quirk_no_way_out = quirk_sandybridge_ifu;
+ /*
+ * MCG_CAP.MCG_SER_P is necessary but not sufficient to know
+ * whether this processor will actually generate recoverable
+ * machine checks. Check to see if this is an E7 model Xeon.
+ * We can't do a model number check because E5 and E7 use the
+ * same model number. E5 doesn't support recovery, E7 does.
+ */
+ if (mca_cfg.recovery || (mca_cfg.ser &&
+ !strncmp(c->x86_model_id,
+ "Intel(R) Xeon(R) CPU E7-", 24)))
+ set_cpu_cap(c, X86_FEATURE_MCE_RECOVERY);
}
if (cfg->monarch_timeout < 0)
cfg->monarch_timeout = 0;
@@ -1586,6 +1612,8 @@ static int __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
winchip_mcheck_init(c);
return 1;
break;
+ default:
+ return 0;
}
return 0;
@@ -1602,9 +1630,11 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
case X86_VENDOR_AMD: {
u32 ebx = cpuid_ebx(0x80000007);
- mce_amd_feature_init(c);
mce_flags.overflow_recov = !!(ebx & BIT(0));
mce_flags.succor = !!(ebx & BIT(1));
+ mce_flags.smca = !!(ebx & BIT(3));
+ mce_amd_feature_init(c);
+
break;
}
@@ -2011,6 +2041,8 @@ static int __init mcheck_enable(char *str)
cfg->bootlog = (str[0] == 'b');
else if (!strcmp(str, "bios_cmci_threshold"))
cfg->bios_cmci_threshold = true;
+ else if (!strcmp(str, "recovery"))
+ cfg->recovery = true;
else if (isdigit(str[0])) {
if (get_option(&str, &cfg->tolerant) == 2)
get_option(&str, &(cfg->monarch_timeout));
@@ -2042,7 +2074,7 @@ int __init mcheck_init(void)
* Disable machine checks on suspend and shutdown. We can't really handle
* them later.
*/
-static int mce_disable_error_reporting(void)
+static void mce_disable_error_reporting(void)
{
int i;
@@ -2052,17 +2084,32 @@ static int mce_disable_error_reporting(void)
if (b->init)
wrmsrl(MSR_IA32_MCx_CTL(i), 0);
}
- return 0;
+ return;
+}
+
+static void vendor_disable_error_reporting(void)
+{
+ /*
+ * Don't clear on Intel CPUs. Some of these MSRs are socket-wide.
+ * Disabling them for just a single offlined CPU is bad, since it will
+ * inhibit reporting for all shared resources on the socket like the
+ * last level cache (LLC), the integrated memory controller (iMC), etc.
+ */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ return;
+
+ mce_disable_error_reporting();
}
static int mce_syscore_suspend(void)
{
- return mce_disable_error_reporting();
+ vendor_disable_error_reporting();
+ return 0;
}
static void mce_syscore_shutdown(void)
{
- mce_disable_error_reporting();
+ vendor_disable_error_reporting();
}
/*
@@ -2342,19 +2389,14 @@ static void mce_device_remove(unsigned int cpu)
static void mce_disable_cpu(void *h)
{
unsigned long action = *(unsigned long *)h;
- int i;
if (!mce_available(raw_cpu_ptr(&cpu_info)))
return;
if (!(action & CPU_TASKS_FROZEN))
cmci_clear();
- for (i = 0; i < mca_cfg.banks; i++) {
- struct mce_bank *b = &mce_banks[i];
- if (b->init)
- wrmsrl(MSR_IA32_MCx_CTL(i), 0);
- }
+ vendor_disable_error_reporting();
}
static void mce_reenable_cpu(void *h)
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index e99b150..9d656fd 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -1,5 +1,5 @@
/*
- * (c) 2005-2015 Advanced Micro Devices, Inc.
+ * (c) 2005-2016 Advanced Micro Devices, Inc.
* Your use of this code is subject to the terms and conditions of the
* GNU general public license version 2. See "COPYING" or
* http://www.gnu.org/licenses/gpl.html
@@ -28,7 +28,7 @@
#include <asm/msr.h>
#include <asm/trace/irq_vectors.h>
-#define NR_BLOCKS 9
+#define NR_BLOCKS 5
#define THRESHOLD_MAX 0xFFF
#define INT_TYPE_APIC 0x00020000
#define MASK_VALID_HI 0x80000000
@@ -49,6 +49,19 @@
#define DEF_LVT_OFF 0x2
#define DEF_INT_TYPE_APIC 0x2
+/* Scalable MCA: */
+
+/* Threshold LVT offset is at MSR0xC0000410[15:12] */
+#define SMCA_THR_LVT_OFF 0xF000
+
+/*
+ * OS is required to set the MCAX bit to acknowledge that it is now using the
+ * new MSR ranges and new registers under each bank. It also means that the OS
+ * will configure deferred errors in the new MCx_CONFIG register. If the bit is
+ * not set, uncorrectable errors will cause a system panic.
+ */
+#define SMCA_MCAX_EN_OFF 0x1
+
static const char * const th_names[] = {
"load_store",
"insn_fetch",
@@ -58,6 +71,35 @@ static const char * const th_names[] = {
"execution_unit",
};
+/* Define HWID to IP type mappings for Scalable MCA */
+struct amd_hwid amd_hwids[] = {
+ [SMCA_F17H_CORE] = { "f17h_core", 0xB0 },
+ [SMCA_DF] = { "data_fabric", 0x2E },
+ [SMCA_UMC] = { "umc", 0x96 },
+ [SMCA_PB] = { "param_block", 0x5 },
+ [SMCA_PSP] = { "psp", 0xFF },
+ [SMCA_SMU] = { "smu", 0x1 },
+};
+EXPORT_SYMBOL_GPL(amd_hwids);
+
+const char * const amd_core_mcablock_names[] = {
+ [SMCA_LS] = "load_store",
+ [SMCA_IF] = "insn_fetch",
+ [SMCA_L2_CACHE] = "l2_cache",
+ [SMCA_DE] = "decode_unit",
+ [RES] = "",
+ [SMCA_EX] = "execution_unit",
+ [SMCA_FP] = "floating_point",
+ [SMCA_L3_CACHE] = "l3_cache",
+};
+EXPORT_SYMBOL_GPL(amd_core_mcablock_names);
+
+const char * const amd_df_mcablock_names[] = {
+ [SMCA_CS] = "coherent_slave",
+ [SMCA_PIE] = "pie",
+};
+EXPORT_SYMBOL_GPL(amd_df_mcablock_names);
+
static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks);
static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
@@ -84,6 +126,13 @@ struct thresh_restart {
static inline bool is_shared_bank(int bank)
{
+ /*
+ * Scalable MCA provides for only one core to have access to the MSRs of
+ * a shared bank.
+ */
+ if (mce_flags.smca)
+ return false;
+
/* Bank 4 is for northbridge reporting and is thus shared */
return (bank == 4);
}
@@ -135,6 +184,14 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
}
if (apic != msr) {
+ /*
+ * On SMCA CPUs, LVT offset is programmed at a different MSR, and
+ * the BIOS provides the value. The original field where LVT offset
+ * was set is reserved. Return early here:
+ */
+ if (mce_flags.smca)
+ return 0;
+
pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
"for bank %d, block %d (MSR%08X=0x%x%08x)\n",
b->cpu, apic, b->bank, b->block, b->address, hi, lo);
@@ -144,10 +201,7 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
return 1;
};
-/*
- * Called via smp_call_function_single(), must be called with correct
- * cpu affinity.
- */
+/* Reprogram MCx_MISC MSR behind this threshold bank. */
static void threshold_restart_bank(void *_tr)
{
struct thresh_restart *tr = _tr;
@@ -247,27 +301,116 @@ static void deferred_error_interrupt_enable(struct cpuinfo_x86 *c)
wrmsr(MSR_CU_DEF_ERR, low, high);
}
+static u32 get_block_address(u32 current_addr, u32 low, u32 high,
+ unsigned int bank, unsigned int block)
+{
+ u32 addr = 0, offset = 0;
+
+ if (mce_flags.smca) {
+ if (!block) {
+ addr = MSR_AMD64_SMCA_MCx_MISC(bank);
+ } else {
+ /*
+ * For SMCA enabled processors, BLKPTR field of the
+ * first MISC register (MCx_MISC0) indicates presence of
+ * additional MISC register set (MISC1-4).
+ */
+ u32 low, high;
+
+ if (rdmsr_safe(MSR_AMD64_SMCA_MCx_CONFIG(bank), &low, &high))
+ return addr;
+
+ if (!(low & MCI_CONFIG_MCAX))
+ return addr;
+
+ if (!rdmsr_safe(MSR_AMD64_SMCA_MCx_MISC(bank), &low, &high) &&
+ (low & MASK_BLKPTR_LO))
+ addr = MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1);
+ }
+ return addr;
+ }
+
+ /* Fall back to method we used for older processors: */
+ switch (block) {
+ case 0:
+ addr = MSR_IA32_MCx_MISC(bank);
+ break;
+ case 1:
+ offset = ((low & MASK_BLKPTR_LO) >> 21);
+ if (offset)
+ addr = MCG_XBLK_ADDR + offset;
+ break;
+ default:
+ addr = ++current_addr;
+ }
+ return addr;
+}
+
+static int
+prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
+ int offset, u32 misc_high)
+{
+ unsigned int cpu = smp_processor_id();
+ struct threshold_block b;
+ int new;
+
+ if (!block)
+ per_cpu(bank_map, cpu) |= (1 << bank);
+
+ memset(&b, 0, sizeof(b));
+ b.cpu = cpu;
+ b.bank = bank;
+ b.block = block;
+ b.address = addr;
+ b.interrupt_capable = lvt_interrupt_supported(bank, misc_high);
+
+ if (!b.interrupt_capable)
+ goto done;
+
+ b.interrupt_enable = 1;
+
+ if (mce_flags.smca) {
+ u32 smca_low, smca_high;
+ u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(bank);
+
+ if (!rdmsr_safe(smca_addr, &smca_low, &smca_high)) {
+ smca_high |= SMCA_MCAX_EN_OFF;
+ wrmsr(smca_addr, smca_low, smca_high);
+ }
+
+ /* Gather LVT offset for thresholding: */
+ if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
+ goto out;
+
+ new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
+ } else {
+ new = (misc_high & MASK_LVTOFF_HI) >> 20;
+ }
+
+ offset = setup_APIC_mce_threshold(offset, new);
+
+ if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
+ mce_threshold_vector = amd_threshold_interrupt;
+
+done:
+ mce_threshold_block_init(&b, offset);
+
+out:
+ return offset;
+}
+
/* cpu init entry point, called from mce.c with preempt off */
void mce_amd_feature_init(struct cpuinfo_x86 *c)
{
- struct threshold_block b;
- unsigned int cpu = smp_processor_id();
u32 low = 0, high = 0, address = 0;
unsigned int bank, block;
- int offset = -1, new;
+ int offset = -1;
for (bank = 0; bank < mca_cfg.banks; ++bank) {
for (block = 0; block < NR_BLOCKS; ++block) {
- if (block == 0)
- address = MSR_IA32_MCx_MISC(bank);
- else if (block == 1) {
- address = (low & MASK_BLKPTR_LO) >> 21;
- if (!address)
- break;
-
- address += MCG_XBLK_ADDR;
- } else
- ++address;
+ address = get_block_address(address, low, high, bank, block);
+ if (!address)
+ break;
if (rdmsr_safe(address, &low, &high))
break;
@@ -279,29 +422,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
(high & MASK_LOCKED_HI))
continue;
- if (!block)
- per_cpu(bank_map, cpu) |= (1 << bank);
-
- memset(&b, 0, sizeof(b));
- b.cpu = cpu;
- b.bank = bank;
- b.block = block;
- b.address = address;
- b.interrupt_capable = lvt_interrupt_supported(bank, high);
-
- if (!b.interrupt_capable)
- goto init;
-
- b.interrupt_enable = 1;
- new = (high & MASK_LVTOFF_HI) >> 20;
- offset = setup_APIC_mce_threshold(offset, new);
-
- if ((offset == new) &&
- (mce_threshold_vector != amd_threshold_interrupt))
- mce_threshold_vector = amd_threshold_interrupt;
-
-init:
- mce_threshold_block_init(&b, offset);
+ offset = prepare_threshold_block(bank, block, address, offset, high);
}
}
@@ -394,16 +515,9 @@ static void amd_threshold_interrupt(void)
if (!(per_cpu(bank_map, cpu) & (1 << bank)))
continue;
for (block = 0; block < NR_BLOCKS; ++block) {
- if (block == 0) {
- address = MSR_IA32_MCx_MISC(bank);
- } else if (block == 1) {
- address = (low & MASK_BLKPTR_LO) >> 21;
- if (!address)
- break;
- address += MCG_XBLK_ADDR;
- } else {
- ++address;
- }
+ address = get_block_address(address, low, high, bank, block);
+ if (!address)
+ break;
if (rdmsr_safe(address, &low, &high))
break;
@@ -623,16 +737,11 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
if (err)
goto out_free;
recurse:
- if (!block) {
- address = (low & MASK_BLKPTR_LO) >> 21;
- if (!address)
- return 0;
- address += MCG_XBLK_ADDR;
- } else {
- ++address;
- }
+ address = get_block_address(address, low, high, bank, ++block);
+ if (!address)
+ return 0;
- err = allocate_threshold_blocks(cpu, bank, ++block, address);
+ err = allocate_threshold_blocks(cpu, bank, block, address);
if (err)
goto out_free;
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
index 12402e1..2a0717b 100644
--- a/arch/x86/kernel/cpu/mcheck/p5.c
+++ b/arch/x86/kernel/cpu/mcheck/p5.c
@@ -26,14 +26,12 @@ static void pentium_machine_check(struct pt_regs *regs, long error_code)
rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
- printk(KERN_EMERG
- "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n",
- smp_processor_id(), loaddr, lotype);
+ pr_emerg("CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n",
+ smp_processor_id(), loaddr, lotype);
if (lotype & (1<<5)) {
- printk(KERN_EMERG
- "CPU#%d: Possible thermal failure (CPU on fire ?).\n",
- smp_processor_id());
+ pr_emerg("CPU#%d: Possible thermal failure (CPU on fire ?).\n",
+ smp_processor_id());
}
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
@@ -61,12 +59,10 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
/* Read registers before enabling: */
rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
- printk(KERN_INFO
- "Intel old style machine check architecture supported.\n");
+ pr_info("Intel old style machine check architecture supported.\n");
/* Enable MCE: */
cr4_set_bits(X86_CR4_MCE);
- printk(KERN_INFO
- "Intel old style machine check reporting enabled on CPU#%d.\n",
- smp_processor_id());
+ pr_info("Intel old style machine check reporting enabled on CPU#%d.\n",
+ smp_processor_id());
}
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 1af51b1..0b445c2 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -190,7 +190,7 @@ static int therm_throt_process(bool new_event, int event, int level)
/* if we just entered the thermal event */
if (new_event) {
if (event == THERMAL_THROTTLING_EVENT)
- printk(KERN_CRIT "CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
+ pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n",
this_cpu,
level == CORE_LEVEL ? "Core" : "Package",
state->count);
@@ -198,8 +198,7 @@ static int therm_throt_process(bool new_event, int event, int level)
}
if (old_event) {
if (event == THERMAL_THROTTLING_EVENT)
- printk(KERN_INFO "CPU%d: %s temperature/speed normal\n",
- this_cpu,
+ pr_info("CPU%d: %s temperature/speed normal\n", this_cpu,
level == CORE_LEVEL ? "Core" : "Package");
return 1;
}
@@ -417,8 +416,8 @@ static void intel_thermal_interrupt(void)
static void unexpected_thermal_interrupt(void)
{
- printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n",
- smp_processor_id());
+ pr_err("CPU%d: Unexpected LVT thermal interrupt!\n",
+ smp_processor_id());
}
static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
@@ -499,15 +498,7 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
if (system_state == SYSTEM_BOOTING)
- printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n", cpu);
- return;
- }
-
- /* Check whether a vector already exists */
- if (h & APIC_VECTOR_MASK) {
- printk(KERN_DEBUG
- "CPU%d: Thermal LVT vector (%#x) already installed\n",
- cpu, (h & APIC_VECTOR_MASK));
+ pr_debug("CPU%d: Thermal monitoring handled by SMI\n", cpu);
return;
}
@@ -565,8 +556,8 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
l = apic_read(APIC_LVTTHMR);
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
- printk_once(KERN_INFO "CPU0: Thermal monitoring enabled (%s)\n",
- tm2 ? "TM2" : "TM1");
+ pr_info_once("CPU0: Thermal monitoring enabled (%s)\n",
+ tm2 ? "TM2" : "TM1");
/* enable thermal throttle processing */
atomic_set(&therm_throt_en, 1);
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c
index 7245980..fcf9ae9 100644
--- a/arch/x86/kernel/cpu/mcheck/threshold.c
+++ b/arch/x86/kernel/cpu/mcheck/threshold.c
@@ -12,8 +12,8 @@
static void default_threshold_interrupt(void)
{
- printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n",
- THRESHOLD_APIC_VECTOR);
+ pr_err("Unexpected threshold interrupt at vector %x\n",
+ THRESHOLD_APIC_VECTOR);
}
void (*mce_threshold_vector)(void) = default_threshold_interrupt;
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c
index 01dd870..c6a722e 100644
--- a/arch/x86/kernel/cpu/mcheck/winchip.c
+++ b/arch/x86/kernel/cpu/mcheck/winchip.c
@@ -17,7 +17,7 @@ static void winchip_machine_check(struct pt_regs *regs, long error_code)
{
ist_enter(regs);
- printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
+ pr_emerg("CPU0: Machine Check Exception.\n");
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
ist_exit(regs);
@@ -39,6 +39,5 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
cr4_set_bits(X86_CR4_MCE);
- printk(KERN_INFO
- "Winchip machine check reporting enabled on CPU#0.\n");
+ pr_info("Winchip machine check reporting enabled on CPU#0.\n");
}
diff --git a/arch/x86/kernel/cpu/microcode/Makefile b/arch/x86/kernel/cpu/microcode/Makefile
index 285c854..220b1a5 100644
--- a/arch/x86/kernel/cpu/microcode/Makefile
+++ b/arch/x86/kernel/cpu/microcode/Makefile
@@ -2,6 +2,3 @@ microcode-y := core.o
obj-$(CONFIG_MICROCODE) += microcode.o
microcode-$(CONFIG_MICROCODE_INTEL) += intel.o intel_lib.o
microcode-$(CONFIG_MICROCODE_AMD) += amd.o
-obj-$(CONFIG_MICROCODE_EARLY) += core_early.o
-obj-$(CONFIG_MICROCODE_INTEL_EARLY) += intel_early.o
-obj-$(CONFIG_MICROCODE_AMD_EARLY) += amd_early.o
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 12829c3..8581963 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -1,5 +1,9 @@
/*
* AMD CPU Microcode Update Driver for Linux
+ *
+ * This driver allows to upgrade microcode on F10h AMD
+ * CPUs and later.
+ *
* Copyright (C) 2008-2011 Advanced Micro Devices Inc.
*
* Author: Peter Oruba <peter.oruba@amd.com>
@@ -7,34 +11,31 @@
* Based on work by:
* Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
*
- * Maintainers:
- * Andreas Herrmann <herrmann.der.user@googlemail.com>
- * Borislav Petkov <bp@alien8.de>
+ * early loader:
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
*
- * This driver allows to upgrade microcode on F10h AMD
- * CPUs and later.
+ * Author: Jacob Shin <jacob.shin@amd.com>
+ * Fixes: Borislav Petkov <bp@suse.de>
*
* Licensed under the terms of the GNU General Public
* License version 2. See file COPYING for details.
*/
+#define pr_fmt(fmt) "microcode: " fmt
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
+#include <linux/earlycpio.h>
#include <linux/firmware.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
+#include <linux/initrd.h>
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/pci.h>
+#include <asm/microcode_amd.h>
#include <asm/microcode.h>
#include <asm/processor.h>
+#include <asm/setup.h>
+#include <asm/cpu.h>
#include <asm/msr.h>
-#include <asm/microcode_amd.h>
-
-MODULE_DESCRIPTION("AMD Microcode Update Driver");
-MODULE_AUTHOR("Peter Oruba");
-MODULE_LICENSE("GPL v2");
static struct equiv_cpu_entry *equiv_cpu_table;
@@ -47,6 +48,427 @@ struct ucode_patch {
static LIST_HEAD(pcache);
+/*
+ * This points to the current valid container of microcode patches which we will
+ * save from the initrd before jettisoning its contents.
+ */
+static u8 *container;
+static size_t container_size;
+
+static u32 ucode_new_rev;
+u8 amd_ucode_patch[PATCH_MAX_SIZE];
+static u16 this_equiv_id;
+
+static struct cpio_data ucode_cpio;
+
+/*
+ * Microcode patch container file is prepended to the initrd in cpio format.
+ * See Documentation/x86/early-microcode.txt
+ */
+static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
+
+static struct cpio_data __init find_ucode_in_initrd(void)
+{
+ long offset = 0;
+ char *path;
+ void *start;
+ size_t size;
+
+#ifdef CONFIG_X86_32
+ struct boot_params *p;
+
+ /*
+ * On 32-bit, early load occurs before paging is turned on so we need
+ * to use physical addresses.
+ */
+ p = (struct boot_params *)__pa_nodebug(&boot_params);
+ path = (char *)__pa_nodebug(ucode_path);
+ start = (void *)p->hdr.ramdisk_image;
+ size = p->hdr.ramdisk_size;
+#else
+ path = ucode_path;
+ start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
+ size = boot_params.hdr.ramdisk_size;
+#endif
+
+ return find_cpio_data(path, start, size, &offset);
+}
+
+static size_t compute_container_size(u8 *data, u32 total_size)
+{
+ size_t size = 0;
+ u32 *header = (u32 *)data;
+
+ if (header[0] != UCODE_MAGIC ||
+ header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
+ header[2] == 0) /* size */
+ return size;
+
+ size = header[2] + CONTAINER_HDR_SZ;
+ total_size -= size;
+ data += size;
+
+ while (total_size) {
+ u16 patch_size;
+
+ header = (u32 *)data;
+
+ if (header[0] != UCODE_UCODE_TYPE)
+ break;
+
+ /*
+ * Sanity-check patch size.
+ */
+ patch_size = header[1];
+ if (patch_size > PATCH_MAX_SIZE)
+ break;
+
+ size += patch_size + SECTION_HDR_SIZE;
+ data += patch_size + SECTION_HDR_SIZE;
+ total_size -= patch_size + SECTION_HDR_SIZE;
+ }
+
+ return size;
+}
+
+/*
+ * Early load occurs before we can vmalloc(). So we look for the microcode
+ * patch container file in initrd, traverse equivalent cpu table, look for a
+ * matching microcode patch, and update, all in initrd memory in place.
+ * When vmalloc() is available for use later -- on 64-bit during first AP load,
+ * and on 32-bit during save_microcode_in_initrd_amd() -- we can call
+ * load_microcode_amd() to save equivalent cpu table and microcode patches in
+ * kernel heap memory.
+ */
+static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
+{
+ struct equiv_cpu_entry *eq;
+ size_t *cont_sz;
+ u32 *header;
+ u8 *data, **cont;
+ u8 (*patch)[PATCH_MAX_SIZE];
+ u16 eq_id = 0;
+ int offset, left;
+ u32 rev, eax, ebx, ecx, edx;
+ u32 *new_rev;
+
+#ifdef CONFIG_X86_32
+ new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
+ cont_sz = (size_t *)__pa_nodebug(&container_size);
+ cont = (u8 **)__pa_nodebug(&container);
+ patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
+#else
+ new_rev = &ucode_new_rev;
+ cont_sz = &container_size;
+ cont = &container;
+ patch = &amd_ucode_patch;
+#endif
+
+ data = ucode;
+ left = size;
+ header = (u32 *)data;
+
+ /* find equiv cpu table */
+ if (header[0] != UCODE_MAGIC ||
+ header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
+ header[2] == 0) /* size */
+ return;
+
+ eax = 0x00000001;
+ ecx = 0;
+ native_cpuid(&eax, &ebx, &ecx, &edx);
+
+ while (left > 0) {
+ eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
+
+ *cont = data;
+
+ /* Advance past the container header */
+ offset = header[2] + CONTAINER_HDR_SZ;
+ data += offset;
+ left -= offset;
+
+ eq_id = find_equiv_id(eq, eax);
+ if (eq_id) {
+ this_equiv_id = eq_id;
+ *cont_sz = compute_container_size(*cont, left + offset);
+
+ /*
+ * truncate how much we need to iterate over in the
+ * ucode update loop below
+ */
+ left = *cont_sz - offset;
+ break;
+ }
+
+ /*
+ * support multiple container files appended together. if this
+ * one does not have a matching equivalent cpu entry, we fast
+ * forward to the next container file.
+ */
+ while (left > 0) {
+ header = (u32 *)data;
+ if (header[0] == UCODE_MAGIC &&
+ header[1] == UCODE_EQUIV_CPU_TABLE_TYPE)
+ break;
+
+ offset = header[1] + SECTION_HDR_SIZE;
+ data += offset;
+ left -= offset;
+ }
+
+ /* mark where the next microcode container file starts */
+ offset = data - (u8 *)ucode;
+ ucode = data;
+ }
+
+ if (!eq_id) {
+ *cont = NULL;
+ *cont_sz = 0;
+ return;
+ }
+
+ if (check_current_patch_level(&rev, true))
+ return;
+
+ while (left > 0) {
+ struct microcode_amd *mc;
+
+ header = (u32 *)data;
+ if (header[0] != UCODE_UCODE_TYPE || /* type */
+ header[1] == 0) /* size */
+ break;
+
+ mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
+
+ if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) {
+
+ if (!__apply_microcode_amd(mc)) {
+ rev = mc->hdr.patch_id;
+ *new_rev = rev;
+
+ if (save_patch)
+ memcpy(patch, mc,
+ min_t(u32, header[1], PATCH_MAX_SIZE));
+ }
+ }
+
+ offset = header[1] + SECTION_HDR_SIZE;
+ data += offset;
+ left -= offset;
+ }
+}
+
+static bool __init load_builtin_amd_microcode(struct cpio_data *cp,
+ unsigned int family)
+{
+#ifdef CONFIG_X86_64
+ char fw_name[36] = "amd-ucode/microcode_amd.bin";
+
+ if (family >= 0x15)
+ snprintf(fw_name, sizeof(fw_name),
+ "amd-ucode/microcode_amd_fam%.2xh.bin", family);
+
+ return get_builtin_firmware(cp, fw_name);
+#else
+ return false;
+#endif
+}
+
+void __init load_ucode_amd_bsp(unsigned int family)
+{
+ struct cpio_data cp;
+ void **data;
+ size_t *size;
+
+#ifdef CONFIG_X86_32
+ data = (void **)__pa_nodebug(&ucode_cpio.data);
+ size = (size_t *)__pa_nodebug(&ucode_cpio.size);
+#else
+ data = &ucode_cpio.data;
+ size = &ucode_cpio.size;
+#endif
+
+ cp = find_ucode_in_initrd();
+ if (!cp.data) {
+ if (!load_builtin_amd_microcode(&cp, family))
+ return;
+ }
+
+ *data = cp.data;
+ *size = cp.size;
+
+ apply_ucode_in_initrd(cp.data, cp.size, true);
+}
+
+#ifdef CONFIG_X86_32
+/*
+ * On 32-bit, since AP's early load occurs before paging is turned on, we
+ * cannot traverse cpu_equiv_table and pcache in kernel heap memory. So during
+ * cold boot, AP will apply_ucode_in_initrd() just like the BSP. During
+ * save_microcode_in_initrd_amd() BSP's patch is copied to amd_ucode_patch,
+ * which is used upon resume from suspend.
+ */
+void load_ucode_amd_ap(void)
+{
+ struct microcode_amd *mc;
+ size_t *usize;
+ void **ucode;
+
+ mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
+ if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
+ __apply_microcode_amd(mc);
+ return;
+ }
+
+ ucode = (void *)__pa_nodebug(&container);
+ usize = (size_t *)__pa_nodebug(&container_size);
+
+ if (!*ucode || !*usize)
+ return;
+
+ apply_ucode_in_initrd(*ucode, *usize, false);
+}
+
+static void __init collect_cpu_sig_on_bsp(void *arg)
+{
+ unsigned int cpu = smp_processor_id();
+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+
+ uci->cpu_sig.sig = cpuid_eax(0x00000001);
+}
+
+static void __init get_bsp_sig(void)
+{
+ unsigned int bsp = boot_cpu_data.cpu_index;
+ struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
+
+ if (!uci->cpu_sig.sig)
+ smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
+}
+#else
+void load_ucode_amd_ap(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct equiv_cpu_entry *eq;
+ struct microcode_amd *mc;
+ u32 rev, eax;
+ u16 eq_id;
+
+ /* Exit if called on the BSP. */
+ if (!cpu)
+ return;
+
+ if (!container)
+ return;
+
+ /*
+ * 64-bit runs with paging enabled, thus early==false.
+ */
+ if (check_current_patch_level(&rev, false))
+ return;
+
+ eax = cpuid_eax(0x00000001);
+ eq = (struct equiv_cpu_entry *)(container + CONTAINER_HDR_SZ);
+
+ eq_id = find_equiv_id(eq, eax);
+ if (!eq_id)
+ return;
+
+ if (eq_id == this_equiv_id) {
+ mc = (struct microcode_amd *)amd_ucode_patch;
+
+ if (mc && rev < mc->hdr.patch_id) {
+ if (!__apply_microcode_amd(mc))
+ ucode_new_rev = mc->hdr.patch_id;
+ }
+
+ } else {
+ if (!ucode_cpio.data)
+ return;
+
+ /*
+ * AP has a different equivalence ID than BSP, looks like
+ * mixed-steppings silicon so go through the ucode blob anew.
+ */
+ apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
+ }
+}
+#endif
+
+int __init save_microcode_in_initrd_amd(void)
+{
+ unsigned long cont;
+ int retval = 0;
+ enum ucode_state ret;
+ u8 *cont_va;
+ u32 eax;
+
+ if (!container)
+ return -EINVAL;
+
+#ifdef CONFIG_X86_32
+ get_bsp_sig();
+ cont = (unsigned long)container;
+ cont_va = __va(container);
+#else
+ /*
+ * We need the physical address of the container for both bitness since
+ * boot_params.hdr.ramdisk_image is a physical address.
+ */
+ cont = __pa(container);
+ cont_va = container;
+#endif
+
+ /*
+ * Take into account the fact that the ramdisk might get relocated and
+ * therefore we need to recompute the container's position in virtual
+ * memory space.
+ */
+ if (relocated_ramdisk)
+ container = (u8 *)(__va(relocated_ramdisk) +
+ (cont - boot_params.hdr.ramdisk_image));
+ else
+ container = cont_va;
+
+ eax = cpuid_eax(0x00000001);
+ eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+
+ ret = load_microcode_amd(smp_processor_id(), eax, container, container_size);
+ if (ret != UCODE_OK)
+ retval = -EINVAL;
+
+ /*
+ * This will be freed any msec now, stash patches for the current
+ * family and switch to patch cache for cpu hotplug, etc later.
+ */
+ container = NULL;
+ container_size = 0;
+
+ return retval;
+}
+
+void reload_ucode_amd(void)
+{
+ struct microcode_amd *mc;
+ u32 rev;
+
+ /*
+ * early==false because this is a syscore ->resume path and by
+ * that time paging is long enabled.
+ */
+ if (check_current_patch_level(&rev, false))
+ return;
+
+ mc = (struct microcode_amd *)amd_ucode_patch;
+
+ if (mc && rev < mc->hdr.patch_id) {
+ if (!__apply_microcode_amd(mc)) {
+ ucode_new_rev = mc->hdr.patch_id;
+ pr_info("reload patch_level=0x%08x\n", ucode_new_rev);
+ }
+ }
+}
static u16 __find_equiv_id(unsigned int cpu)
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
@@ -177,6 +599,53 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
return patch_size;
}
+/*
+ * Those patch levels cannot be updated to newer ones and thus should be final.
+ */
+static u32 final_levels[] = {
+ 0x01000098,
+ 0x0100009f,
+ 0x010000af,
+ 0, /* T-101 terminator */
+};
+
+/*
+ * Check the current patch level on this CPU.
+ *
+ * @rev: Use it to return the patch level. It is set to 0 in the case of
+ * error.
+ *
+ * Returns:
+ * - true: if update should stop
+ * - false: otherwise
+ */
+bool check_current_patch_level(u32 *rev, bool early)
+{
+ u32 lvl, dummy, i;
+ bool ret = false;
+ u32 *levels;
+
+ native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+
+ if (IS_ENABLED(CONFIG_X86_32) && early)
+ levels = (u32 *)__pa_nodebug(&final_levels);
+ else
+ levels = final_levels;
+
+ for (i = 0; levels[i]; i++) {
+ if (lvl == levels[i]) {
+ lvl = 0;
+ ret = true;
+ break;
+ }
+ }
+
+ if (rev)
+ *rev = lvl;
+
+ return ret;
+}
+
int __apply_microcode_amd(struct microcode_amd *mc_amd)
{
u32 rev, dummy;
@@ -197,7 +666,7 @@ int apply_microcode_amd(int cpu)
struct microcode_amd *mc_amd;
struct ucode_cpu_info *uci;
struct ucode_patch *p;
- u32 rev, dummy;
+ u32 rev;
BUG_ON(raw_smp_processor_id() != cpu);
@@ -210,7 +679,8 @@ int apply_microcode_amd(int cpu)
mc_amd = p->data;
uci->mc = p->data;
- rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+ if (check_current_patch_level(&rev, false))
+ return -1;
/* need to apply patch? */
if (rev >= mc_amd->hdr.patch_id) {
@@ -318,15 +788,13 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover)
return -EINVAL;
}
- patch->data = kzalloc(patch_size, GFP_KERNEL);
+ patch->data = kmemdup(fw + SECTION_HDR_SIZE, patch_size, GFP_KERNEL);
if (!patch->data) {
pr_err("Patch data allocation failure.\n");
kfree(patch);
return -EINVAL;
}
- /* All looks ok, copy patch... */
- memcpy(patch->data, fw + SECTION_HDR_SIZE, patch_size);
INIT_LIST_HEAD(&patch->plist);
patch->patch_id = mc_hdr->patch_id;
patch->equiv_cpu = proc_id;
@@ -387,7 +855,7 @@ enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t s
if (ret != UCODE_OK)
cleanup();
-#if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32)
+#ifdef CONFIG_X86_32
/* save BSP's matching patch for early load */
if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
struct ucode_patch *p = find_patch(cpu);
@@ -475,13 +943,17 @@ static struct microcode_ops microcode_amd_ops = {
struct microcode_ops * __init init_amd_microcode(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = &boot_cpu_data;
if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
- pr_warning("AMD CPU family 0x%x not supported\n", c->x86);
+ pr_warn("AMD CPU family 0x%x not supported\n", c->x86);
return NULL;
}
+ if (ucode_new_rev)
+ pr_info_once("microcode updated early to new patch_level=0x%08x\n",
+ ucode_new_rev);
+
return &microcode_amd_ops;
}
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c
deleted file mode 100644
index e8a215a..0000000
--- a/arch/x86/kernel/cpu/microcode/amd_early.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Jacob Shin <jacob.shin@amd.com>
- * Fixes: Borislav Petkov <bp@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/earlycpio.h>
-#include <linux/initrd.h>
-
-#include <asm/cpu.h>
-#include <asm/setup.h>
-#include <asm/microcode_amd.h>
-
-/*
- * This points to the current valid container of microcode patches which we will
- * save from the initrd before jettisoning its contents.
- */
-static u8 *container;
-static size_t container_size;
-
-static u32 ucode_new_rev;
-u8 amd_ucode_patch[PATCH_MAX_SIZE];
-static u16 this_equiv_id;
-
-static struct cpio_data ucode_cpio;
-
-/*
- * Microcode patch container file is prepended to the initrd in cpio format.
- * See Documentation/x86/early-microcode.txt
- */
-static __initdata char ucode_path[] = "kernel/x86/microcode/AuthenticAMD.bin";
-
-static struct cpio_data __init find_ucode_in_initrd(void)
-{
- long offset = 0;
- char *path;
- void *start;
- size_t size;
-
-#ifdef CONFIG_X86_32
- struct boot_params *p;
-
- /*
- * On 32-bit, early load occurs before paging is turned on so we need
- * to use physical addresses.
- */
- p = (struct boot_params *)__pa_nodebug(&boot_params);
- path = (char *)__pa_nodebug(ucode_path);
- start = (void *)p->hdr.ramdisk_image;
- size = p->hdr.ramdisk_size;
-#else
- path = ucode_path;
- start = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
- size = boot_params.hdr.ramdisk_size;
-#endif
-
- return find_cpio_data(path, start, size, &offset);
-}
-
-static size_t compute_container_size(u8 *data, u32 total_size)
-{
- size_t size = 0;
- u32 *header = (u32 *)data;
-
- if (header[0] != UCODE_MAGIC ||
- header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
- header[2] == 0) /* size */
- return size;
-
- size = header[2] + CONTAINER_HDR_SZ;
- total_size -= size;
- data += size;
-
- while (total_size) {
- u16 patch_size;
-
- header = (u32 *)data;
-
- if (header[0] != UCODE_UCODE_TYPE)
- break;
-
- /*
- * Sanity-check patch size.
- */
- patch_size = header[1];
- if (patch_size > PATCH_MAX_SIZE)
- break;
-
- size += patch_size + SECTION_HDR_SIZE;
- data += patch_size + SECTION_HDR_SIZE;
- total_size -= patch_size + SECTION_HDR_SIZE;
- }
-
- return size;
-}
-
-/*
- * Early load occurs before we can vmalloc(). So we look for the microcode
- * patch container file in initrd, traverse equivalent cpu table, look for a
- * matching microcode patch, and update, all in initrd memory in place.
- * When vmalloc() is available for use later -- on 64-bit during first AP load,
- * and on 32-bit during save_microcode_in_initrd_amd() -- we can call
- * load_microcode_amd() to save equivalent cpu table and microcode patches in
- * kernel heap memory.
- */
-static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
-{
- struct equiv_cpu_entry *eq;
- size_t *cont_sz;
- u32 *header;
- u8 *data, **cont;
- u8 (*patch)[PATCH_MAX_SIZE];
- u16 eq_id = 0;
- int offset, left;
- u32 rev, eax, ebx, ecx, edx;
- u32 *new_rev;
-
-#ifdef CONFIG_X86_32
- new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
- cont_sz = (size_t *)__pa_nodebug(&container_size);
- cont = (u8 **)__pa_nodebug(&container);
- patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
-#else
- new_rev = &ucode_new_rev;
- cont_sz = &container_size;
- cont = &container;
- patch = &amd_ucode_patch;
-#endif
-
- data = ucode;
- left = size;
- header = (u32 *)data;
-
- /* find equiv cpu table */
- if (header[0] != UCODE_MAGIC ||
- header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
- header[2] == 0) /* size */
- return;
-
- eax = 0x00000001;
- ecx = 0;
- native_cpuid(&eax, &ebx, &ecx, &edx);
-
- while (left > 0) {
- eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
-
- *cont = data;
-
- /* Advance past the container header */
- offset = header[2] + CONTAINER_HDR_SZ;
- data += offset;
- left -= offset;
-
- eq_id = find_equiv_id(eq, eax);
- if (eq_id) {
- this_equiv_id = eq_id;
- *cont_sz = compute_container_size(*cont, left + offset);
-
- /*
- * truncate how much we need to iterate over in the
- * ucode update loop below
- */
- left = *cont_sz - offset;
- break;
- }
-
- /*
- * support multiple container files appended together. if this
- * one does not have a matching equivalent cpu entry, we fast
- * forward to the next container file.
- */
- while (left > 0) {
- header = (u32 *)data;
- if (header[0] == UCODE_MAGIC &&
- header[1] == UCODE_EQUIV_CPU_TABLE_TYPE)
- break;
-
- offset = header[1] + SECTION_HDR_SIZE;
- data += offset;
- left -= offset;
- }
-
- /* mark where the next microcode container file starts */
- offset = data - (u8 *)ucode;
- ucode = data;
- }
-
- if (!eq_id) {
- *cont = NULL;
- *cont_sz = 0;
- return;
- }
-
- /* find ucode and update if needed */
-
- native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
-
- while (left > 0) {
- struct microcode_amd *mc;
-
- header = (u32 *)data;
- if (header[0] != UCODE_UCODE_TYPE || /* type */
- header[1] == 0) /* size */
- break;
-
- mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
-
- if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id) {
-
- if (!__apply_microcode_amd(mc)) {
- rev = mc->hdr.patch_id;
- *new_rev = rev;
-
- if (save_patch)
- memcpy(patch, mc,
- min_t(u32, header[1], PATCH_MAX_SIZE));
- }
- }
-
- offset = header[1] + SECTION_HDR_SIZE;
- data += offset;
- left -= offset;
- }
-}
-
-static bool __init load_builtin_amd_microcode(struct cpio_data *cp,
- unsigned int family)
-{
-#ifdef CONFIG_X86_64
- char fw_name[36] = "amd-ucode/microcode_amd.bin";
-
- if (family >= 0x15)
- snprintf(fw_name, sizeof(fw_name),
- "amd-ucode/microcode_amd_fam%.2xh.bin", family);
-
- return get_builtin_firmware(cp, fw_name);
-#else
- return false;
-#endif
-}
-
-void __init load_ucode_amd_bsp(unsigned int family)
-{
- struct cpio_data cp;
- void **data;
- size_t *size;
-
-#ifdef CONFIG_X86_32
- data = (void **)__pa_nodebug(&ucode_cpio.data);
- size = (size_t *)__pa_nodebug(&ucode_cpio.size);
-#else
- data = &ucode_cpio.data;
- size = &ucode_cpio.size;
-#endif
-
- cp = find_ucode_in_initrd();
- if (!cp.data) {
- if (!load_builtin_amd_microcode(&cp, family))
- return;
- }
-
- *data = cp.data;
- *size = cp.size;
-
- apply_ucode_in_initrd(cp.data, cp.size, true);
-}
-
-#ifdef CONFIG_X86_32
-/*
- * On 32-bit, since AP's early load occurs before paging is turned on, we
- * cannot traverse cpu_equiv_table and pcache in kernel heap memory. So during
- * cold boot, AP will apply_ucode_in_initrd() just like the BSP. During
- * save_microcode_in_initrd_amd() BSP's patch is copied to amd_ucode_patch,
- * which is used upon resume from suspend.
- */
-void load_ucode_amd_ap(void)
-{
- struct microcode_amd *mc;
- size_t *usize;
- void **ucode;
-
- mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
- if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
- __apply_microcode_amd(mc);
- return;
- }
-
- ucode = (void *)__pa_nodebug(&container);
- usize = (size_t *)__pa_nodebug(&container_size);
-
- if (!*ucode || !*usize)
- return;
-
- apply_ucode_in_initrd(*ucode, *usize, false);
-}
-
-static void __init collect_cpu_sig_on_bsp(void *arg)
-{
- unsigned int cpu = smp_processor_id();
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-
- uci->cpu_sig.sig = cpuid_eax(0x00000001);
-}
-
-static void __init get_bsp_sig(void)
-{
- unsigned int bsp = boot_cpu_data.cpu_index;
- struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
-
- if (!uci->cpu_sig.sig)
- smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
-}
-#else
-void load_ucode_amd_ap(void)
-{
- unsigned int cpu = smp_processor_id();
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- struct equiv_cpu_entry *eq;
- struct microcode_amd *mc;
- u32 rev, eax;
- u16 eq_id;
-
- /* Exit if called on the BSP. */
- if (!cpu)
- return;
-
- if (!container)
- return;
-
- rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
-
- uci->cpu_sig.rev = rev;
- uci->cpu_sig.sig = eax;
-
- eax = cpuid_eax(0x00000001);
- eq = (struct equiv_cpu_entry *)(container + CONTAINER_HDR_SZ);
-
- eq_id = find_equiv_id(eq, eax);
- if (!eq_id)
- return;
-
- if (eq_id == this_equiv_id) {
- mc = (struct microcode_amd *)amd_ucode_patch;
-
- if (mc && rev < mc->hdr.patch_id) {
- if (!__apply_microcode_amd(mc))
- ucode_new_rev = mc->hdr.patch_id;
- }
-
- } else {
- if (!ucode_cpio.data)
- return;
-
- /*
- * AP has a different equivalence ID than BSP, looks like
- * mixed-steppings silicon so go through the ucode blob anew.
- */
- apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
- }
-}
-#endif
-
-int __init save_microcode_in_initrd_amd(void)
-{
- unsigned long cont;
- int retval = 0;
- enum ucode_state ret;
- u8 *cont_va;
- u32 eax;
-
- if (!container)
- return -EINVAL;
-
-#ifdef CONFIG_X86_32
- get_bsp_sig();
- cont = (unsigned long)container;
- cont_va = __va(container);
-#else
- /*
- * We need the physical address of the container for both bitness since
- * boot_params.hdr.ramdisk_image is a physical address.
- */
- cont = __pa(container);
- cont_va = container;
-#endif
-
- /*
- * Take into account the fact that the ramdisk might get relocated and
- * therefore we need to recompute the container's position in virtual
- * memory space.
- */
- if (relocated_ramdisk)
- container = (u8 *)(__va(relocated_ramdisk) +
- (cont - boot_params.hdr.ramdisk_image));
- else
- container = cont_va;
-
- if (ucode_new_rev)
- pr_info("microcode: updated early to new patch_level=0x%08x\n",
- ucode_new_rev);
-
- eax = cpuid_eax(0x00000001);
- eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
-
- ret = load_microcode_amd(smp_processor_id(), eax, container, container_size);
- if (ret != UCODE_OK)
- retval = -EINVAL;
-
- /*
- * This will be freed any msec now, stash patches for the current
- * family and switch to patch cache for cpu hotplug, etc later.
- */
- container = NULL;
- container_size = 0;
-
- return retval;
-}
-
-void reload_ucode_amd(void)
-{
- struct microcode_amd *mc;
- u32 rev, eax;
-
- rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
-
- mc = (struct microcode_amd *)amd_ucode_patch;
-
- if (mc && rev < mc->hdr.patch_id) {
- if (!__apply_microcode_amd(mc)) {
- ucode_new_rev = mc->hdr.patch_id;
- pr_info("microcode: reload patch_level=0x%08x\n",
- ucode_new_rev);
- }
- }
-}
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 9e3f3c7..ac360bf 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -5,6 +5,12 @@
* 2006 Shaohua Li <shaohua.li@intel.com>
* 2013-2015 Borislav Petkov <bp@alien8.de>
*
+ * X86 CPU microcode early update for Linux:
+ *
+ * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
+ * H Peter Anvin" <hpa@zytor.com>
+ * (C) 2015 Borislav Petkov <bp@alien8.de>
+ *
* This driver allows to upgrade microcode on x86 processors.
*
* This program is free software; you can redistribute it and/or
@@ -13,34 +19,31 @@
* 2 of the License, or (at your option) any later version.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define pr_fmt(fmt) "microcode: " fmt
#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
#include <linux/miscdevice.h>
#include <linux/capability.h>
+#include <linux/firmware.h>
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/cpu.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/syscore_ops.h>
-#include <asm/microcode.h>
-#include <asm/processor.h>
+#include <asm/microcode_intel.h>
#include <asm/cpu_device_id.h>
+#include <asm/microcode_amd.h>
#include <asm/perf_event.h>
+#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/cmdline.h>
-MODULE_DESCRIPTION("Microcode Update Driver");
-MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
-MODULE_LICENSE("GPL");
-
-#define MICROCODE_VERSION "2.00"
+#define MICROCODE_VERSION "2.01"
static struct microcode_ops *microcode_ops;
-
-bool dis_ucode_ldr;
-module_param(dis_ucode_ldr, bool, 0);
+static bool dis_ucode_ldr;
/*
* Synchronization.
@@ -68,6 +71,151 @@ struct cpu_info_ctx {
int err;
};
+static bool __init check_loader_disabled_bsp(void)
+{
+ static const char *__dis_opt_str = "dis_ucode_ldr";
+
+#ifdef CONFIG_X86_32
+ const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
+ const char *option = (const char *)__pa_nodebug(__dis_opt_str);
+ bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr);
+
+#else /* CONFIG_X86_64 */
+ const char *cmdline = boot_command_line;
+ const char *option = __dis_opt_str;
+ bool *res = &dis_ucode_ldr;
+#endif
+
+ if (cmdline_find_option_bool(cmdline, option))
+ *res = true;
+
+ return *res;
+}
+
+extern struct builtin_fw __start_builtin_fw[];
+extern struct builtin_fw __end_builtin_fw[];
+
+bool get_builtin_firmware(struct cpio_data *cd, const char *name)
+{
+#ifdef CONFIG_FW_LOADER
+ struct builtin_fw *b_fw;
+
+ for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+ if (!strcmp(name, b_fw->name)) {
+ cd->size = b_fw->size;
+ cd->data = b_fw->data;
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+void __init load_ucode_bsp(void)
+{
+ int vendor;
+ unsigned int family;
+
+ if (check_loader_disabled_bsp())
+ return;
+
+ if (!have_cpuid_p())
+ return;
+
+ vendor = x86_cpuid_vendor();
+ family = x86_cpuid_family();
+
+ switch (vendor) {
+ case X86_VENDOR_INTEL:
+ if (family >= 6)
+ load_ucode_intel_bsp();
+ break;
+ case X86_VENDOR_AMD:
+ if (family >= 0x10)
+ load_ucode_amd_bsp(family);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool check_loader_disabled_ap(void)
+{
+#ifdef CONFIG_X86_32
+ return *((bool *)__pa_nodebug(&dis_ucode_ldr));
+#else
+ return dis_ucode_ldr;
+#endif
+}
+
+void load_ucode_ap(void)
+{
+ int vendor, family;
+
+ if (check_loader_disabled_ap())
+ return;
+
+ if (!have_cpuid_p())
+ return;
+
+ vendor = x86_cpuid_vendor();
+ family = x86_cpuid_family();
+
+ switch (vendor) {
+ case X86_VENDOR_INTEL:
+ if (family >= 6)
+ load_ucode_intel_ap();
+ break;
+ case X86_VENDOR_AMD:
+ if (family >= 0x10)
+ load_ucode_amd_ap();
+ break;
+ default:
+ break;
+ }
+}
+
+int __init save_microcode_in_initrd(void)
+{
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+
+ switch (c->x86_vendor) {
+ case X86_VENDOR_INTEL:
+ if (c->x86 >= 6)
+ save_microcode_in_initrd_intel();
+ break;
+ case X86_VENDOR_AMD:
+ if (c->x86 >= 0x10)
+ save_microcode_in_initrd_amd();
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void reload_early_microcode(void)
+{
+ int vendor, family;
+
+ vendor = x86_cpuid_vendor();
+ family = x86_cpuid_family();
+
+ switch (vendor) {
+ case X86_VENDOR_INTEL:
+ if (family >= 6)
+ reload_ucode_intel();
+ break;
+ case X86_VENDOR_AMD:
+ if (family >= 0x10)
+ reload_ucode_amd();
+ break;
+ default:
+ break;
+ }
+}
+
static void collect_cpu_info_local(void *arg)
{
struct cpu_info_ctx *ctx = arg;
@@ -210,9 +358,6 @@ static void __exit microcode_dev_exit(void)
{
misc_deregister(&microcode_dev);
}
-
-MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
-MODULE_ALIAS("devname:cpu/microcode");
#else
#define microcode_dev_init() 0
#define microcode_dev_exit() do { } while (0)
@@ -327,7 +472,7 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
enum ucode_state ustate;
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- if (uci && uci->valid)
+ if (uci->valid)
return UCODE_OK;
if (collect_cpu_info(cpu))
@@ -463,20 +608,6 @@ static struct notifier_block mc_cpu_notifier = {
.notifier_call = mc_cpu_callback,
};
-#ifdef MODULE
-/* Autoload on Intel and AMD systems */
-static const struct x86_cpu_id __initconst microcode_id[] = {
-#ifdef CONFIG_MICROCODE_INTEL
- { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, },
-#endif
-#ifdef CONFIG_MICROCODE_AMD
- { X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, },
-#endif
- {}
-};
-MODULE_DEVICE_TABLE(x86cpu, microcode_id);
-#endif
-
static struct attribute *cpu_root_microcode_attrs[] = {
&dev_attr_reload.attr,
NULL
@@ -487,12 +618,12 @@ static struct attribute_group cpu_root_microcode_group = {
.attrs = cpu_root_microcode_attrs,
};
-static int __init microcode_init(void)
+int __init microcode_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = &boot_cpu_data;
int error;
- if (paravirt_enabled() || dis_ucode_ldr)
+ if (dis_ucode_ldr)
return -EINVAL;
if (c->x86_vendor == X86_VENDOR_INTEL)
@@ -560,35 +691,4 @@ static int __init microcode_init(void)
return error;
}
-module_init(microcode_init);
-
-static void __exit microcode_exit(void)
-{
- struct cpuinfo_x86 *c = &cpu_data(0);
-
- microcode_dev_exit();
-
- unregister_hotcpu_notifier(&mc_cpu_notifier);
- unregister_syscore_ops(&mc_syscore_ops);
-
- sysfs_remove_group(&cpu_subsys.dev_root->kobj,
- &cpu_root_microcode_group);
-
- get_online_cpus();
- mutex_lock(&microcode_mutex);
-
- subsys_interface_unregister(&mc_cpu_interface);
-
- mutex_unlock(&microcode_mutex);
- put_online_cpus();
-
- platform_device_unregister(microcode_pdev);
-
- microcode_ops = NULL;
-
- if (c->x86_vendor == X86_VENDOR_AMD)
- exit_amd_microcode();
-
- pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n");
-}
-module_exit(microcode_exit);
+late_initcall(microcode_init);
diff --git a/arch/x86/kernel/cpu/microcode/core_early.c b/arch/x86/kernel/cpu/microcode/core_early.c
deleted file mode 100644
index 8ebc421..0000000
--- a/arch/x86/kernel/cpu/microcode/core_early.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * X86 CPU microcode early update for Linux
- *
- * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
- * H Peter Anvin" <hpa@zytor.com>
- * (C) 2015 Borislav Petkov <bp@alien8.de>
- *
- * This driver allows to early upgrade microcode on Intel processors
- * belonging to IA-32 family - PentiumPro, Pentium II,
- * Pentium III, Xeon, Pentium 4, etc.
- *
- * Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture
- * Software Developer's Manual.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the 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/firmware.h>
-#include <asm/microcode.h>
-#include <asm/microcode_intel.h>
-#include <asm/microcode_amd.h>
-#include <asm/processor.h>
-#include <asm/cmdline.h>
-
-static bool __init check_loader_disabled_bsp(void)
-{
-#ifdef CONFIG_X86_32
- const char *cmdline = (const char *)__pa_nodebug(boot_command_line);
- const char *opt = "dis_ucode_ldr";
- const char *option = (const char *)__pa_nodebug(opt);
- bool *res = (bool *)__pa_nodebug(&dis_ucode_ldr);
-
-#else /* CONFIG_X86_64 */
- const char *cmdline = boot_command_line;
- const char *option = "dis_ucode_ldr";
- bool *res = &dis_ucode_ldr;
-#endif
-
- if (cmdline_find_option_bool(cmdline, option))
- *res = true;
-
- return *res;
-}
-
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
-
-bool get_builtin_firmware(struct cpio_data *cd, const char *name)
-{
-#ifdef CONFIG_FW_LOADER
- struct builtin_fw *b_fw;
-
- for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
- if (!strcmp(name, b_fw->name)) {
- cd->size = b_fw->size;
- cd->data = b_fw->data;
- return true;
- }
- }
-#endif
- return false;
-}
-
-void __init load_ucode_bsp(void)
-{
- int vendor;
- unsigned int family;
-
- if (check_loader_disabled_bsp())
- return;
-
- if (!have_cpuid_p())
- return;
-
- vendor = x86_vendor();
- family = x86_family();
-
- switch (vendor) {
- case X86_VENDOR_INTEL:
- if (family >= 6)
- load_ucode_intel_bsp();
- break;
- case X86_VENDOR_AMD:
- if (family >= 0x10)
- load_ucode_amd_bsp(family);
- break;
- default:
- break;
- }
-}
-
-static bool check_loader_disabled_ap(void)
-{
-#ifdef CONFIG_X86_32
- return *((bool *)__pa_nodebug(&dis_ucode_ldr));
-#else
- return dis_ucode_ldr;
-#endif
-}
-
-void load_ucode_ap(void)
-{
- int vendor, family;
-
- if (check_loader_disabled_ap())
- return;
-
- if (!have_cpuid_p())
- return;
-
- vendor = x86_vendor();
- family = x86_family();
-
- switch (vendor) {
- case X86_VENDOR_INTEL:
- if (family >= 6)
- load_ucode_intel_ap();
- break;
- case X86_VENDOR_AMD:
- if (family >= 0x10)
- load_ucode_amd_ap();
- break;
- default:
- break;
- }
-}
-
-int __init save_microcode_in_initrd(void)
-{
- struct cpuinfo_x86 *c = &boot_cpu_data;
-
- switch (c->x86_vendor) {
- case X86_VENDOR_INTEL:
- if (c->x86 >= 6)
- save_microcode_in_initrd_intel();
- break;
- case X86_VENDOR_AMD:
- if (c->x86 >= 0x10)
- save_microcode_in_initrd_amd();
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-void reload_early_microcode(void)
-{
- int vendor, family;
-
- vendor = x86_vendor();
- family = x86_family();
-
- switch (vendor) {
- case X86_VENDOR_INTEL:
- if (family >= 6)
- reload_ucode_intel();
- break;
- case X86_VENDOR_AMD:
- if (family >= 0x10)
- reload_ucode_amd();
- break;
- default:
- break;
- }
-}
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 969dc17..cbb3cf0 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -4,27 +4,793 @@
* Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
* 2006 Shaohua Li <shaohua.li@intel.com>
*
+ * Intel CPU microcode early update for Linux
+ *
+ * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
+ * H Peter Anvin" <hpa@zytor.com>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the 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
+/*
+ * This needs to be before all headers so that pr_debug in printk.h doesn't turn
+ * printk calls into no_printk().
+ *
+ *#define DEBUG
+ */
+#define pr_fmt(fmt) "microcode: " fmt
+#include <linux/earlycpio.h>
#include <linux/firmware.h>
#include <linux/uaccess.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/vmalloc.h>
+#include <linux/initrd.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/mm.h>
#include <asm/microcode_intel.h>
#include <asm/processor.h>
+#include <asm/tlbflush.h>
+#include <asm/setup.h>
#include <asm/msr.h>
-MODULE_DESCRIPTION("Microcode Update Driver");
-MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
-MODULE_LICENSE("GPL");
+/*
+ * Temporary microcode blobs pointers storage. We note here the pointers to
+ * microcode blobs we've got from whatever storage (detached initrd, builtin).
+ * Later on, we put those into final storage mc_saved_data.mc_saved.
+ */
+static unsigned long mc_tmp_ptrs[MAX_UCODE_COUNT];
+
+static struct mc_saved_data {
+ unsigned int num_saved;
+ struct microcode_intel **mc_saved;
+} mc_saved_data;
+
+static enum ucode_state
+load_microcode_early(struct microcode_intel **saved,
+ unsigned int num_saved, struct ucode_cpu_info *uci)
+{
+ struct microcode_intel *ucode_ptr, *new_mc = NULL;
+ struct microcode_header_intel *mc_hdr;
+ int new_rev, ret, i;
+
+ new_rev = uci->cpu_sig.rev;
+
+ for (i = 0; i < num_saved; i++) {
+ ucode_ptr = saved[i];
+ mc_hdr = (struct microcode_header_intel *)ucode_ptr;
+
+ ret = has_newer_microcode(ucode_ptr,
+ uci->cpu_sig.sig,
+ uci->cpu_sig.pf,
+ new_rev);
+ if (!ret)
+ continue;
+
+ new_rev = mc_hdr->rev;
+ new_mc = ucode_ptr;
+ }
+
+ if (!new_mc)
+ return UCODE_NFOUND;
+
+ uci->mc = (struct microcode_intel *)new_mc;
+ return UCODE_OK;
+}
+
+static inline void
+copy_ptrs(struct microcode_intel **mc_saved, unsigned long *mc_ptrs,
+ unsigned long off, int num_saved)
+{
+ int i;
+
+ for (i = 0; i < num_saved; i++)
+ mc_saved[i] = (struct microcode_intel *)(mc_ptrs[i] + off);
+}
+
+#ifdef CONFIG_X86_32
+static void
+microcode_phys(struct microcode_intel **mc_saved_tmp, struct mc_saved_data *mcs)
+{
+ int i;
+ struct microcode_intel ***mc_saved;
+
+ mc_saved = (struct microcode_intel ***)__pa_nodebug(&mcs->mc_saved);
+
+ for (i = 0; i < mcs->num_saved; i++) {
+ struct microcode_intel *p;
+
+ p = *(struct microcode_intel **)__pa_nodebug(mcs->mc_saved + i);
+ mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
+ }
+}
+#endif
+
+static enum ucode_state
+load_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+ unsigned long offset, struct ucode_cpu_info *uci)
+{
+ struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
+ unsigned int count = mcs->num_saved;
+
+ if (!mcs->mc_saved) {
+ copy_ptrs(mc_saved_tmp, mc_ptrs, offset, count);
+
+ return load_microcode_early(mc_saved_tmp, count, uci);
+ } else {
+#ifdef CONFIG_X86_32
+ microcode_phys(mc_saved_tmp, mcs);
+ return load_microcode_early(mc_saved_tmp, count, uci);
+#else
+ return load_microcode_early(mcs->mc_saved, count, uci);
+#endif
+ }
+}
+
+/*
+ * Given CPU signature and a microcode patch, this function finds if the
+ * microcode patch has matching family and model with the CPU.
+ */
+static enum ucode_state
+matching_model_microcode(struct microcode_header_intel *mc_header,
+ unsigned long sig)
+{
+ unsigned int fam, model;
+ unsigned int fam_ucode, model_ucode;
+ struct extended_sigtable *ext_header;
+ unsigned long total_size = get_totalsize(mc_header);
+ unsigned long data_size = get_datasize(mc_header);
+ int ext_sigcount, i;
+ struct extended_signature *ext_sig;
+
+ fam = x86_family(sig);
+ model = x86_model(sig);
+
+ fam_ucode = x86_family(mc_header->sig);
+ model_ucode = x86_model(mc_header->sig);
+
+ if (fam == fam_ucode && model == model_ucode)
+ return UCODE_OK;
+
+ /* Look for ext. headers: */
+ if (total_size <= data_size + MC_HEADER_SIZE)
+ return UCODE_NFOUND;
+
+ ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE;
+ ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
+ ext_sigcount = ext_header->count;
+
+ for (i = 0; i < ext_sigcount; i++) {
+ fam_ucode = x86_family(ext_sig->sig);
+ model_ucode = x86_model(ext_sig->sig);
+
+ if (fam == fam_ucode && model == model_ucode)
+ return UCODE_OK;
+
+ ext_sig++;
+ }
+ return UCODE_NFOUND;
+}
+
+static int
+save_microcode(struct mc_saved_data *mcs,
+ struct microcode_intel **mc_saved_src,
+ unsigned int num_saved)
+{
+ int i, j;
+ struct microcode_intel **saved_ptr;
+ int ret;
+
+ if (!num_saved)
+ return -EINVAL;
+
+ /*
+ * Copy new microcode data.
+ */
+ saved_ptr = kcalloc(num_saved, sizeof(struct microcode_intel *), GFP_KERNEL);
+ if (!saved_ptr)
+ return -ENOMEM;
+
+ for (i = 0; i < num_saved; i++) {
+ struct microcode_header_intel *mc_hdr;
+ struct microcode_intel *mc;
+ unsigned long size;
+
+ if (!mc_saved_src[i]) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ mc = mc_saved_src[i];
+ mc_hdr = &mc->hdr;
+ size = get_totalsize(mc_hdr);
+
+ saved_ptr[i] = kmemdup(mc, size, GFP_KERNEL);
+ if (!saved_ptr[i]) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ }
+
+ /*
+ * Point to newly saved microcode.
+ */
+ mcs->mc_saved = saved_ptr;
+ mcs->num_saved = num_saved;
+
+ return 0;
+
+err:
+ for (j = 0; j <= i; j++)
+ kfree(saved_ptr[j]);
+ kfree(saved_ptr);
+
+ return ret;
+}
+
+/*
+ * A microcode patch in ucode_ptr is saved into mc_saved
+ * - if it has matching signature and newer revision compared to an existing
+ * patch mc_saved.
+ * - or if it is a newly discovered microcode patch.
+ *
+ * The microcode patch should have matching model with CPU.
+ *
+ * Returns: The updated number @num_saved of saved microcode patches.
+ */
+static unsigned int _save_mc(struct microcode_intel **mc_saved,
+ u8 *ucode_ptr, unsigned int num_saved)
+{
+ struct microcode_header_intel *mc_hdr, *mc_saved_hdr;
+ unsigned int sig, pf;
+ int found = 0, i;
+
+ mc_hdr = (struct microcode_header_intel *)ucode_ptr;
+
+ for (i = 0; i < num_saved; i++) {
+ mc_saved_hdr = (struct microcode_header_intel *)mc_saved[i];
+ sig = mc_saved_hdr->sig;
+ pf = mc_saved_hdr->pf;
+
+ if (!find_matching_signature(ucode_ptr, sig, pf))
+ continue;
+
+ found = 1;
+
+ if (mc_hdr->rev <= mc_saved_hdr->rev)
+ continue;
+
+ /*
+ * Found an older ucode saved earlier. Replace it with
+ * this newer one.
+ */
+ mc_saved[i] = (struct microcode_intel *)ucode_ptr;
+ break;
+ }
+
+ /* Newly detected microcode, save it to memory. */
+ if (i >= num_saved && !found)
+ mc_saved[num_saved++] = (struct microcode_intel *)ucode_ptr;
+
+ return num_saved;
+}
+
+/*
+ * Get microcode matching with BSP's model. Only CPUs with the same model as
+ * BSP can stay in the platform.
+ */
+static enum ucode_state __init
+get_matching_model_microcode(unsigned long start, void *data, size_t size,
+ struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+ struct ucode_cpu_info *uci)
+{
+ struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
+ struct microcode_header_intel *mc_header;
+ unsigned int num_saved = mcs->num_saved;
+ enum ucode_state state = UCODE_OK;
+ unsigned int leftover = size;
+ u8 *ucode_ptr = data;
+ unsigned int mc_size;
+ int i;
+
+ while (leftover && num_saved < ARRAY_SIZE(mc_saved_tmp)) {
+
+ if (leftover < sizeof(mc_header))
+ break;
+
+ mc_header = (struct microcode_header_intel *)ucode_ptr;
+
+ mc_size = get_totalsize(mc_header);
+ if (!mc_size || mc_size > leftover ||
+ microcode_sanity_check(ucode_ptr, 0) < 0)
+ break;
+
+ leftover -= mc_size;
+
+ /*
+ * Since APs with same family and model as the BSP may boot in
+ * the platform, we need to find and save microcode patches
+ * with the same family and model as the BSP.
+ */
+ if (matching_model_microcode(mc_header, uci->cpu_sig.sig) != UCODE_OK) {
+ ucode_ptr += mc_size;
+ continue;
+ }
+
+ num_saved = _save_mc(mc_saved_tmp, ucode_ptr, num_saved);
+
+ ucode_ptr += mc_size;
+ }
+
+ if (leftover) {
+ state = UCODE_ERROR;
+ return state;
+ }
+
+ if (!num_saved) {
+ state = UCODE_NFOUND;
+ return state;
+ }
+
+ for (i = 0; i < num_saved; i++)
+ mc_ptrs[i] = (unsigned long)mc_saved_tmp[i] - start;
+
+ mcs->num_saved = num_saved;
+
+ return state;
+}
+
+static int collect_cpu_info_early(struct ucode_cpu_info *uci)
+{
+ unsigned int val[2];
+ unsigned int family, model;
+ struct cpu_signature csig;
+ unsigned int eax, ebx, ecx, edx;
+
+ csig.sig = 0;
+ csig.pf = 0;
+ csig.rev = 0;
+
+ memset(uci, 0, sizeof(*uci));
+
+ eax = 0x00000001;
+ ecx = 0;
+ native_cpuid(&eax, &ebx, &ecx, &edx);
+ csig.sig = eax;
+
+ family = x86_family(csig.sig);
+ model = x86_model(csig.sig);
+
+ if ((model >= 5) || (family > 6)) {
+ /* get processor flags from MSR 0x17 */
+ native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
+ csig.pf = 1 << ((val[1] >> 18) & 7);
+ }
+ native_wrmsrl(MSR_IA32_UCODE_REV, 0);
+
+ /* As documented in the SDM: Do a CPUID 1 here */
+ sync_core();
+
+ /* get the current revision from MSR 0x8B */
+ native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+
+ csig.rev = val[1];
+
+ uci->cpu_sig = csig;
+ uci->valid = 1;
+
+ return 0;
+}
+
+static void show_saved_mc(void)
+{
+#ifdef DEBUG
+ int i, j;
+ unsigned int sig, pf, rev, total_size, data_size, date;
+ struct ucode_cpu_info uci;
+
+ if (!mc_saved_data.num_saved) {
+ pr_debug("no microcode data saved.\n");
+ return;
+ }
+ pr_debug("Total microcode saved: %d\n", mc_saved_data.num_saved);
+
+ collect_cpu_info_early(&uci);
+
+ sig = uci.cpu_sig.sig;
+ pf = uci.cpu_sig.pf;
+ rev = uci.cpu_sig.rev;
+ pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev);
+
+ for (i = 0; i < mc_saved_data.num_saved; i++) {
+ struct microcode_header_intel *mc_saved_header;
+ struct extended_sigtable *ext_header;
+ int ext_sigcount;
+ struct extended_signature *ext_sig;
+
+ mc_saved_header = (struct microcode_header_intel *)
+ mc_saved_data.mc_saved[i];
+ sig = mc_saved_header->sig;
+ pf = mc_saved_header->pf;
+ rev = mc_saved_header->rev;
+ total_size = get_totalsize(mc_saved_header);
+ data_size = get_datasize(mc_saved_header);
+ date = mc_saved_header->date;
+
+ pr_debug("mc_saved[%d]: sig=0x%x, pf=0x%x, rev=0x%x, toal size=0x%x, date = %04x-%02x-%02x\n",
+ i, sig, pf, rev, total_size,
+ date & 0xffff,
+ date >> 24,
+ (date >> 16) & 0xff);
+
+ /* Look for ext. headers: */
+ if (total_size <= data_size + MC_HEADER_SIZE)
+ continue;
+
+ ext_header = (void *) mc_saved_header + data_size + MC_HEADER_SIZE;
+ ext_sigcount = ext_header->count;
+ ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
+
+ for (j = 0; j < ext_sigcount; j++) {
+ sig = ext_sig->sig;
+ pf = ext_sig->pf;
+
+ pr_debug("\tExtended[%d]: sig=0x%x, pf=0x%x\n",
+ j, sig, pf);
+
+ ext_sig++;
+ }
+
+ }
+#endif
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static DEFINE_MUTEX(x86_cpu_microcode_mutex);
+/*
+ * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
+ * hot added or resumes.
+ *
+ * Please make sure this mc should be a valid microcode patch before calling
+ * this function.
+ */
+int save_mc_for_early(u8 *mc)
+{
+ struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
+ unsigned int mc_saved_count_init;
+ unsigned int num_saved;
+ struct microcode_intel **mc_saved;
+ int ret = 0;
+ int i;
+
+ /*
+ * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
+ * hotplug.
+ */
+ mutex_lock(&x86_cpu_microcode_mutex);
+
+ mc_saved_count_init = mc_saved_data.num_saved;
+ num_saved = mc_saved_data.num_saved;
+ mc_saved = mc_saved_data.mc_saved;
+
+ if (mc_saved && num_saved)
+ memcpy(mc_saved_tmp, mc_saved,
+ num_saved * sizeof(struct microcode_intel *));
+ /*
+ * Save the microcode patch mc in mc_save_tmp structure if it's a newer
+ * version.
+ */
+ num_saved = _save_mc(mc_saved_tmp, mc, num_saved);
+
+ /*
+ * Save the mc_save_tmp in global mc_saved_data.
+ */
+ ret = save_microcode(&mc_saved_data, mc_saved_tmp, num_saved);
+ if (ret) {
+ pr_err("Cannot save microcode patch.\n");
+ goto out;
+ }
+
+ show_saved_mc();
+
+ /*
+ * Free old saved microcode data.
+ */
+ if (mc_saved) {
+ for (i = 0; i < mc_saved_count_init; i++)
+ kfree(mc_saved[i]);
+ kfree(mc_saved);
+ }
+
+out:
+ mutex_unlock(&x86_cpu_microcode_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(save_mc_for_early);
+#endif
+
+static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
+{
+#ifdef CONFIG_X86_64
+ unsigned int eax = 0x00000001, ebx, ecx = 0, edx;
+ char name[30];
+
+ native_cpuid(&eax, &ebx, &ecx, &edx);
+
+ sprintf(name, "intel-ucode/%02x-%02x-%02x",
+ x86_family(eax), x86_model(eax), x86_stepping(eax));
+
+ return get_builtin_firmware(cp, name);
+#else
+ return false;
+#endif
+}
+
+static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
+static __init enum ucode_state
+scan_microcode(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+ unsigned long start, unsigned long size,
+ struct ucode_cpu_info *uci)
+{
+ struct cpio_data cd;
+ long offset = 0;
+#ifdef CONFIG_X86_32
+ char *p = (char *)__pa_nodebug(ucode_name);
+#else
+ char *p = ucode_name;
+#endif
+
+ cd.data = NULL;
+ cd.size = 0;
+
+ /* try built-in microcode if no initrd */
+ if (!size) {
+ if (!load_builtin_intel_microcode(&cd))
+ return UCODE_ERROR;
+ } else {
+ cd = find_cpio_data(p, (void *)start, size, &offset);
+ if (!cd.data)
+ return UCODE_ERROR;
+ }
+
+ return get_matching_model_microcode(start, cd.data, cd.size,
+ mcs, mc_ptrs, uci);
+}
+
+/*
+ * Print ucode update info.
+ */
+static void
+print_ucode_info(struct ucode_cpu_info *uci, unsigned int date)
+{
+ pr_info_once("microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n",
+ uci->cpu_sig.rev,
+ date & 0xffff,
+ date >> 24,
+ (date >> 16) & 0xff);
+}
+
+#ifdef CONFIG_X86_32
+
+static int delay_ucode_info;
+static int current_mc_date;
+
+/*
+ * Print early updated ucode info after printk works. This is delayed info dump.
+ */
+void show_ucode_info_early(void)
+{
+ struct ucode_cpu_info uci;
+
+ if (delay_ucode_info) {
+ collect_cpu_info_early(&uci);
+ print_ucode_info(&uci, current_mc_date);
+ delay_ucode_info = 0;
+ }
+}
+
+/*
+ * At this point, we can not call printk() yet. Keep microcode patch number in
+ * mc_saved_data.mc_saved and delay printing microcode info in
+ * show_ucode_info_early() until printk() works.
+ */
+static void print_ucode(struct ucode_cpu_info *uci)
+{
+ struct microcode_intel *mc;
+ int *delay_ucode_info_p;
+ int *current_mc_date_p;
+
+ mc = uci->mc;
+ if (!mc)
+ return;
+
+ delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
+ current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);
+
+ *delay_ucode_info_p = 1;
+ *current_mc_date_p = mc->hdr.date;
+}
+#else
+
+/*
+ * Flush global tlb. We only do this in x86_64 where paging has been enabled
+ * already and PGE should be enabled as well.
+ */
+static inline void flush_tlb_early(void)
+{
+ __native_flush_tlb_global_irq_disabled();
+}
+
+static inline void print_ucode(struct ucode_cpu_info *uci)
+{
+ struct microcode_intel *mc;
+
+ mc = uci->mc;
+ if (!mc)
+ return;
+
+ print_ucode_info(uci, mc->hdr.date);
+}
+#endif
+
+static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
+{
+ struct microcode_intel *mc;
+ unsigned int val[2];
+
+ mc = uci->mc;
+ if (!mc)
+ return 0;
+
+ /* write microcode via MSR 0x79 */
+ native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
+ native_wrmsrl(MSR_IA32_UCODE_REV, 0);
+
+ /* As documented in the SDM: Do a CPUID 1 here */
+ sync_core();
+
+ /* get the current revision from MSR 0x8B */
+ native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+ if (val[1] != mc->hdr.rev)
+ return -1;
+
+#ifdef CONFIG_X86_64
+ /* Flush global tlb. This is precaution. */
+ flush_tlb_early();
+#endif
+ uci->cpu_sig.rev = val[1];
+
+ if (early)
+ print_ucode(uci);
+ else
+ print_ucode_info(uci, mc->hdr.date);
+
+ return 0;
+}
+
+/*
+ * This function converts microcode patch offsets previously stored in
+ * mc_tmp_ptrs to pointers and stores the pointers in mc_saved_data.
+ */
+int __init save_microcode_in_initrd_intel(void)
+{
+ unsigned int count = mc_saved_data.num_saved;
+ struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
+ int ret = 0;
+
+ if (!count)
+ return ret;
+
+ copy_ptrs(mc_saved, mc_tmp_ptrs, get_initrd_start(), count);
+
+ ret = save_microcode(&mc_saved_data, mc_saved, count);
+ if (ret)
+ pr_err("Cannot save microcode patches from initrd.\n");
+
+ show_saved_mc();
+
+ return ret;
+}
+
+static void __init
+_load_ucode_intel_bsp(struct mc_saved_data *mcs, unsigned long *mc_ptrs,
+ unsigned long start, unsigned long size)
+{
+ struct ucode_cpu_info uci;
+ enum ucode_state ret;
+
+ collect_cpu_info_early(&uci);
+
+ ret = scan_microcode(mcs, mc_ptrs, start, size, &uci);
+ if (ret != UCODE_OK)
+ return;
+
+ ret = load_microcode(mcs, mc_ptrs, start, &uci);
+ if (ret != UCODE_OK)
+ return;
+
+ apply_microcode_early(&uci, true);
+}
+
+void __init load_ucode_intel_bsp(void)
+{
+ u64 start, size;
+#ifdef CONFIG_X86_32
+ struct boot_params *p;
+
+ p = (struct boot_params *)__pa_nodebug(&boot_params);
+ size = p->hdr.ramdisk_size;
+
+ /*
+ * Set start only if we have an initrd image. We cannot use initrd_start
+ * because it is not set that early yet.
+ */
+ start = (size ? p->hdr.ramdisk_image : 0);
+
+ _load_ucode_intel_bsp((struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
+ (unsigned long *)__pa_nodebug(&mc_tmp_ptrs),
+ start, size);
+#else
+ size = boot_params.hdr.ramdisk_size;
+ start = (size ? boot_params.hdr.ramdisk_image + PAGE_OFFSET : 0);
+
+ _load_ucode_intel_bsp(&mc_saved_data, mc_tmp_ptrs, start, size);
+#endif
+}
+
+void load_ucode_intel_ap(void)
+{
+ unsigned long *mcs_tmp_p;
+ struct mc_saved_data *mcs_p;
+ struct ucode_cpu_info uci;
+ enum ucode_state ret;
+#ifdef CONFIG_X86_32
+
+ mcs_tmp_p = (unsigned long *)__pa_nodebug(mc_tmp_ptrs);
+ mcs_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+#else
+ mcs_tmp_p = mc_tmp_ptrs;
+ mcs_p = &mc_saved_data;
+#endif
+
+ /*
+ * If there is no valid ucode previously saved in memory, no need to
+ * update ucode on this AP.
+ */
+ if (!mcs_p->num_saved)
+ return;
+
+ collect_cpu_info_early(&uci);
+ ret = load_microcode(mcs_p, mcs_tmp_p, get_initrd_start_addr(), &uci);
+ if (ret != UCODE_OK)
+ return;
+
+ apply_microcode_early(&uci, true);
+}
+
+void reload_ucode_intel(void)
+{
+ struct ucode_cpu_info uci;
+ enum ucode_state ret;
+
+ if (!mc_saved_data.num_saved)
+ return;
+
+ collect_cpu_info_early(&uci);
+
+ ret = load_microcode_early(mc_saved_data.mc_saved,
+ mc_saved_data.num_saved, &uci);
+ if (ret != UCODE_OK)
+ return;
+
+ apply_microcode_early(&uci, false);
+}
static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
{
@@ -52,7 +818,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
* return 0 - no update found
* return 1 - found update
*/
-static int get_matching_mc(struct microcode_intel *mc_intel, int cpu)
+static int get_matching_mc(struct microcode_intel *mc, int cpu)
{
struct cpu_signature cpu_sig;
unsigned int csig, cpf, crev;
@@ -63,39 +829,36 @@ static int get_matching_mc(struct microcode_intel *mc_intel, int cpu)
cpf = cpu_sig.pf;
crev = cpu_sig.rev;
- return has_newer_microcode(mc_intel, csig, cpf, crev);
+ return has_newer_microcode(mc, csig, cpf, crev);
}
static int apply_microcode_intel(int cpu)
{
- struct microcode_intel *mc_intel;
+ struct microcode_intel *mc;
struct ucode_cpu_info *uci;
+ struct cpuinfo_x86 *c;
unsigned int val[2];
- int cpu_num = raw_smp_processor_id();
- struct cpuinfo_x86 *c = &cpu_data(cpu_num);
-
- uci = ucode_cpu_info + cpu;
- mc_intel = uci->mc;
/* We should bind the task to the CPU */
- BUG_ON(cpu_num != cpu);
+ if (WARN_ON(raw_smp_processor_id() != cpu))
+ return -1;
- if (mc_intel == NULL)
+ uci = ucode_cpu_info + cpu;
+ mc = uci->mc;
+ if (!mc)
return 0;
/*
* Microcode on this CPU could be updated earlier. Only apply the
- * microcode patch in mc_intel when it is newer than the one on this
+ * microcode patch in mc when it is newer than the one on this
* CPU.
*/
- if (get_matching_mc(mc_intel, cpu) == 0)
+ if (!get_matching_mc(mc, cpu))
return 0;
/* write microcode via MSR 0x79 */
- wrmsr(MSR_IA32_UCODE_WRITE,
- (unsigned long) mc_intel->bits,
- (unsigned long) mc_intel->bits >> 16 >> 16);
- wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+ wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
+ wrmsrl(MSR_IA32_UCODE_REV, 0);
/* As documented in the SDM: Do a CPUID 1 here */
sync_core();
@@ -103,16 +866,19 @@ static int apply_microcode_intel(int cpu)
/* get the current revision from MSR 0x8B */
rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
- if (val[1] != mc_intel->hdr.rev) {
+ if (val[1] != mc->hdr.rev) {
pr_err("CPU%d update to revision 0x%x failed\n",
- cpu_num, mc_intel->hdr.rev);
+ cpu, mc->hdr.rev);
return -1;
}
+
pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x\n",
- cpu_num, val[1],
- mc_intel->hdr.date & 0xffff,
- mc_intel->hdr.date >> 24,
- (mc_intel->hdr.date >> 16) & 0xff);
+ cpu, val[1],
+ mc->hdr.date & 0xffff,
+ mc->hdr.date >> 24,
+ (mc->hdr.date >> 16) & 0xff);
+
+ c = &cpu_data(cpu);
uci->cpu_sig.rev = val[1];
c->microcode = val[1];
@@ -264,7 +1030,7 @@ static struct microcode_ops microcode_intel_ops = {
struct microcode_ops * __init init_intel_microcode(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = &boot_cpu_data;
if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
cpu_has(c, X86_FEATURE_IA64)) {
diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c
deleted file mode 100644
index 37ea89c..0000000
--- a/arch/x86/kernel/cpu/microcode/intel_early.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Intel CPU microcode early update for Linux
- *
- * Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
- * H Peter Anvin" <hpa@zytor.com>
- *
- * This allows to early upgrade microcode on Intel processors
- * belonging to IA-32 family - PentiumPro, Pentium II,
- * Pentium III, Xeon, Pentium 4, etc.
- *
- * Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture
- * Software Developer's Manual.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/*
- * This needs to be before all headers so that pr_debug in printk.h doesn't turn
- * printk calls into no_printk().
- *
- *#define DEBUG
- */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/earlycpio.h>
-#include <linux/initrd.h>
-#include <linux/cpu.h>
-#include <asm/msr.h>
-#include <asm/microcode_intel.h>
-#include <asm/processor.h>
-#include <asm/tlbflush.h>
-#include <asm/setup.h>
-
-#undef pr_fmt
-#define pr_fmt(fmt) "microcode: " fmt
-
-static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT];
-static struct mc_saved_data {
- unsigned int mc_saved_count;
- struct microcode_intel **mc_saved;
-} mc_saved_data;
-
-static enum ucode_state
-load_microcode_early(struct microcode_intel **saved,
- unsigned int num_saved, struct ucode_cpu_info *uci)
-{
- struct microcode_intel *ucode_ptr, *new_mc = NULL;
- struct microcode_header_intel *mc_hdr;
- int new_rev, ret, i;
-
- new_rev = uci->cpu_sig.rev;
-
- for (i = 0; i < num_saved; i++) {
- ucode_ptr = saved[i];
- mc_hdr = (struct microcode_header_intel *)ucode_ptr;
-
- ret = has_newer_microcode(ucode_ptr,
- uci->cpu_sig.sig,
- uci->cpu_sig.pf,
- new_rev);
- if (!ret)
- continue;
-
- new_rev = mc_hdr->rev;
- new_mc = ucode_ptr;
- }
-
- if (!new_mc)
- return UCODE_NFOUND;
-
- uci->mc = (struct microcode_intel *)new_mc;
- return UCODE_OK;
-}
-
-static inline void
-copy_initrd_ptrs(struct microcode_intel **mc_saved, unsigned long *initrd,
- unsigned long off, int num_saved)
-{
- int i;
-
- for (i = 0; i < num_saved; i++)
- mc_saved[i] = (struct microcode_intel *)(initrd[i] + off);
-}
-
-#ifdef CONFIG_X86_32
-static void
-microcode_phys(struct microcode_intel **mc_saved_tmp,
- struct mc_saved_data *mc_saved_data)
-{
- int i;
- struct microcode_intel ***mc_saved;
-
- mc_saved = (struct microcode_intel ***)
- __pa_nodebug(&mc_saved_data->mc_saved);
- for (i = 0; i < mc_saved_data->mc_saved_count; i++) {
- struct microcode_intel *p;
-
- p = *(struct microcode_intel **)
- __pa_nodebug(mc_saved_data->mc_saved + i);
- mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
- }
-}
-#endif
-
-static enum ucode_state
-load_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
- unsigned long initrd_start, struct ucode_cpu_info *uci)
-{
- struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
- unsigned int count = mc_saved_data->mc_saved_count;
-
- if (!mc_saved_data->mc_saved) {
- copy_initrd_ptrs(mc_saved_tmp, initrd, initrd_start, count);
-
- return load_microcode_early(mc_saved_tmp, count, uci);
- } else {
-#ifdef CONFIG_X86_32
- microcode_phys(mc_saved_tmp, mc_saved_data);
- return load_microcode_early(mc_saved_tmp, count, uci);
-#else
- return load_microcode_early(mc_saved_data->mc_saved,
- count, uci);
-#endif
- }
-}
-
-/*
- * Given CPU signature and a microcode patch, this function finds if the
- * microcode patch has matching family and model with the CPU.
- */
-static enum ucode_state
-matching_model_microcode(struct microcode_header_intel *mc_header,
- unsigned long sig)
-{
- unsigned int fam, model;
- unsigned int fam_ucode, model_ucode;
- struct extended_sigtable *ext_header;
- unsigned long total_size = get_totalsize(mc_header);
- unsigned long data_size = get_datasize(mc_header);
- int ext_sigcount, i;
- struct extended_signature *ext_sig;
-
- fam = __x86_family(sig);
- model = x86_model(sig);
-
- fam_ucode = __x86_family(mc_header->sig);
- model_ucode = x86_model(mc_header->sig);
-
- if (fam == fam_ucode && model == model_ucode)
- return UCODE_OK;
-
- /* Look for ext. headers: */
- if (total_size <= data_size + MC_HEADER_SIZE)
- return UCODE_NFOUND;
-
- ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE;
- ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
- ext_sigcount = ext_header->count;
-
- for (i = 0; i < ext_sigcount; i++) {
- fam_ucode = __x86_family(ext_sig->sig);
- model_ucode = x86_model(ext_sig->sig);
-
- if (fam == fam_ucode && model == model_ucode)
- return UCODE_OK;
-
- ext_sig++;
- }
- return UCODE_NFOUND;
-}
-
-static int
-save_microcode(struct mc_saved_data *mc_saved_data,
- struct microcode_intel **mc_saved_src,
- unsigned int mc_saved_count)
-{
- int i, j;
- struct microcode_intel **saved_ptr;
- int ret;
-
- if (!mc_saved_count)
- return -EINVAL;
-
- /*
- * Copy new microcode data.
- */
- saved_ptr = kcalloc(mc_saved_count, sizeof(struct microcode_intel *), GFP_KERNEL);
- if (!saved_ptr)
- return -ENOMEM;
-
- for (i = 0; i < mc_saved_count; i++) {
- struct microcode_header_intel *mc_hdr;
- struct microcode_intel *mc;
- unsigned long size;
-
- if (!mc_saved_src[i]) {
- ret = -EINVAL;
- goto err;
- }
-
- mc = mc_saved_src[i];
- mc_hdr = &mc->hdr;
- size = get_totalsize(mc_hdr);
-
- saved_ptr[i] = kmalloc(size, GFP_KERNEL);
- if (!saved_ptr[i]) {
- ret = -ENOMEM;
- goto err;
- }
-
- memcpy(saved_ptr[i], mc, size);
- }
-
- /*
- * Point to newly saved microcode.
- */
- mc_saved_data->mc_saved = saved_ptr;
- mc_saved_data->mc_saved_count = mc_saved_count;
-
- return 0;
-
-err:
- for (j = 0; j <= i; j++)
- kfree(saved_ptr[j]);
- kfree(saved_ptr);
-
- return ret;
-}
-
-/*
- * A microcode patch in ucode_ptr is saved into mc_saved
- * - if it has matching signature and newer revision compared to an existing
- * patch mc_saved.
- * - or if it is a newly discovered microcode patch.
- *
- * The microcode patch should have matching model with CPU.
- *
- * Returns: The updated number @num_saved of saved microcode patches.
- */
-static unsigned int _save_mc(struct microcode_intel **mc_saved,
- u8 *ucode_ptr, unsigned int num_saved)
-{
- struct microcode_header_intel *mc_hdr, *mc_saved_hdr;
- unsigned int sig, pf;
- int found = 0, i;
-
- mc_hdr = (struct microcode_header_intel *)ucode_ptr;
-
- for (i = 0; i < num_saved; i++) {
- mc_saved_hdr = (struct microcode_header_intel *)mc_saved[i];
- sig = mc_saved_hdr->sig;
- pf = mc_saved_hdr->pf;
-
- if (!find_matching_signature(ucode_ptr, sig, pf))
- continue;
-
- found = 1;
-
- if (mc_hdr->rev <= mc_saved_hdr->rev)
- continue;
-
- /*
- * Found an older ucode saved earlier. Replace it with
- * this newer one.
- */
- mc_saved[i] = (struct microcode_intel *)ucode_ptr;
- break;
- }
-
- /* Newly detected microcode, save it to memory. */
- if (i >= num_saved && !found)
- mc_saved[num_saved++] = (struct microcode_intel *)ucode_ptr;
-
- return num_saved;
-}
-
-/*
- * Get microcode matching with BSP's model. Only CPUs with the same model as
- * BSP can stay in the platform.
- */
-static enum ucode_state __init
-get_matching_model_microcode(int cpu, unsigned long start,
- void *data, size_t size,
- struct mc_saved_data *mc_saved_data,
- unsigned long *mc_saved_in_initrd,
- struct ucode_cpu_info *uci)
-{
- u8 *ucode_ptr = data;
- unsigned int leftover = size;
- enum ucode_state state = UCODE_OK;
- unsigned int mc_size;
- struct microcode_header_intel *mc_header;
- struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
- unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
- int i;
-
- while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) {
-
- if (leftover < sizeof(mc_header))
- break;
-
- mc_header = (struct microcode_header_intel *)ucode_ptr;
-
- mc_size = get_totalsize(mc_header);
- if (!mc_size || mc_size > leftover ||
- microcode_sanity_check(ucode_ptr, 0) < 0)
- break;
-
- leftover -= mc_size;
-
- /*
- * Since APs with same family and model as the BSP may boot in
- * the platform, we need to find and save microcode patches
- * with the same family and model as the BSP.
- */
- if (matching_model_microcode(mc_header, uci->cpu_sig.sig) !=
- UCODE_OK) {
- ucode_ptr += mc_size;
- continue;
- }
-
- mc_saved_count = _save_mc(mc_saved_tmp, ucode_ptr, mc_saved_count);
-
- ucode_ptr += mc_size;
- }
-
- if (leftover) {
- state = UCODE_ERROR;
- goto out;
- }
-
- if (mc_saved_count == 0) {
- state = UCODE_NFOUND;
- goto out;
- }
-
- for (i = 0; i < mc_saved_count; i++)
- mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start;
-
- mc_saved_data->mc_saved_count = mc_saved_count;
-out:
- return state;
-}
-
-static int collect_cpu_info_early(struct ucode_cpu_info *uci)
-{
- unsigned int val[2];
- unsigned int family, model;
- struct cpu_signature csig;
- unsigned int eax, ebx, ecx, edx;
-
- csig.sig = 0;
- csig.pf = 0;
- csig.rev = 0;
-
- memset(uci, 0, sizeof(*uci));
-
- eax = 0x00000001;
- ecx = 0;
- native_cpuid(&eax, &ebx, &ecx, &edx);
- csig.sig = eax;
-
- family = __x86_family(csig.sig);
- model = x86_model(csig.sig);
-
- if ((model >= 5) || (family > 6)) {
- /* get processor flags from MSR 0x17 */
- native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
- csig.pf = 1 << ((val[1] >> 18) & 7);
- }
- native_wrmsr(MSR_IA32_UCODE_REV, 0, 0);
-
- /* As documented in the SDM: Do a CPUID 1 here */
- sync_core();
-
- /* get the current revision from MSR 0x8B */
- native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
-
- csig.rev = val[1];
-
- uci->cpu_sig = csig;
- uci->valid = 1;
-
- return 0;
-}
-
-#ifdef DEBUG
-static void show_saved_mc(void)
-{
- int i, j;
- unsigned int sig, pf, rev, total_size, data_size, date;
- struct ucode_cpu_info uci;
-
- if (mc_saved_data.mc_saved_count == 0) {
- pr_debug("no microcode data saved.\n");
- return;
- }
- pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count);
-
- collect_cpu_info_early(&uci);
-
- sig = uci.cpu_sig.sig;
- pf = uci.cpu_sig.pf;
- rev = uci.cpu_sig.rev;
- pr_debug("CPU: sig=0x%x, pf=0x%x, rev=0x%x\n", sig, pf, rev);
-
- for (i = 0; i < mc_saved_data.mc_saved_count; i++) {
- struct microcode_header_intel *mc_saved_header;
- struct extended_sigtable *ext_header;
- int ext_sigcount;
- struct extended_signature *ext_sig;
-
- mc_saved_header = (struct microcode_header_intel *)
- mc_saved_data.mc_saved[i];
- sig = mc_saved_header->sig;
- pf = mc_saved_header->pf;
- rev = mc_saved_header->rev;
- total_size = get_totalsize(mc_saved_header);
- data_size = get_datasize(mc_saved_header);
- date = mc_saved_header->date;
-
- pr_debug("mc_saved[%d]: sig=0x%x, pf=0x%x, rev=0x%x, toal size=0x%x, date = %04x-%02x-%02x\n",
- i, sig, pf, rev, total_size,
- date & 0xffff,
- date >> 24,
- (date >> 16) & 0xff);
-
- /* Look for ext. headers: */
- if (total_size <= data_size + MC_HEADER_SIZE)
- continue;
-
- ext_header = (void *) mc_saved_header + data_size + MC_HEADER_SIZE;
- ext_sigcount = ext_header->count;
- ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
-
- for (j = 0; j < ext_sigcount; j++) {
- sig = ext_sig->sig;
- pf = ext_sig->pf;
-
- pr_debug("\tExtended[%d]: sig=0x%x, pf=0x%x\n",
- j, sig, pf);
-
- ext_sig++;
- }
-
- }
-}
-#else
-static inline void show_saved_mc(void)
-{
-}
-#endif
-
-#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
-static DEFINE_MUTEX(x86_cpu_microcode_mutex);
-/*
- * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
- * hot added or resumes.
- *
- * Please make sure this mc should be a valid microcode patch before calling
- * this function.
- */
-int save_mc_for_early(u8 *mc)
-{
- struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
- unsigned int mc_saved_count_init;
- unsigned int mc_saved_count;
- struct microcode_intel **mc_saved;
- int ret = 0;
- int i;
-
- /*
- * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
- * hotplug.
- */
- mutex_lock(&x86_cpu_microcode_mutex);
-
- mc_saved_count_init = mc_saved_data.mc_saved_count;
- mc_saved_count = mc_saved_data.mc_saved_count;
- mc_saved = mc_saved_data.mc_saved;
-
- if (mc_saved && mc_saved_count)
- memcpy(mc_saved_tmp, mc_saved,
- mc_saved_count * sizeof(struct microcode_intel *));
- /*
- * Save the microcode patch mc in mc_save_tmp structure if it's a newer
- * version.
- */
- mc_saved_count = _save_mc(mc_saved_tmp, mc, mc_saved_count);
-
- /*
- * Save the mc_save_tmp in global mc_saved_data.
- */
- ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count);
- if (ret) {
- pr_err("Cannot save microcode patch.\n");
- goto out;
- }
-
- show_saved_mc();
-
- /*
- * Free old saved microcode data.
- */
- if (mc_saved) {
- for (i = 0; i < mc_saved_count_init; i++)
- kfree(mc_saved[i]);
- kfree(mc_saved);
- }
-
-out:
- mutex_unlock(&x86_cpu_microcode_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(save_mc_for_early);
-#endif
-
-static bool __init load_builtin_intel_microcode(struct cpio_data *cp)
-{
-#ifdef CONFIG_X86_64
- unsigned int eax = 0x00000001, ebx, ecx = 0, edx;
- unsigned int family, model, stepping;
- char name[30];
-
- native_cpuid(&eax, &ebx, &ecx, &edx);
-
- family = __x86_family(eax);
- model = x86_model(eax);
- stepping = eax & 0xf;
-
- sprintf(name, "intel-ucode/%02x-%02x-%02x", family, model, stepping);
-
- return get_builtin_firmware(cp, name);
-#else
- return false;
-#endif
-}
-
-static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
-static __init enum ucode_state
-scan_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
- unsigned long start, unsigned long size,
- struct ucode_cpu_info *uci)
-{
- struct cpio_data cd;
- long offset = 0;
-#ifdef CONFIG_X86_32
- char *p = (char *)__pa_nodebug(ucode_name);
-#else
- char *p = ucode_name;
-#endif
-
- cd.data = NULL;
- cd.size = 0;
-
- cd = find_cpio_data(p, (void *)start, size, &offset);
- if (!cd.data) {
- if (!load_builtin_intel_microcode(&cd))
- return UCODE_ERROR;
- }
-
- return get_matching_model_microcode(0, start, cd.data, cd.size,
- mc_saved_data, initrd, uci);
-}
-
-/*
- * Print ucode update info.
- */
-static void
-print_ucode_info(struct ucode_cpu_info *uci, unsigned int date)
-{
- int cpu = smp_processor_id();
-
- pr_info("CPU%d microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n",
- cpu,
- uci->cpu_sig.rev,
- date & 0xffff,
- date >> 24,
- (date >> 16) & 0xff);
-}
-
-#ifdef CONFIG_X86_32
-
-static int delay_ucode_info;
-static int current_mc_date;
-
-/*
- * Print early updated ucode info after printk works. This is delayed info dump.
- */
-void show_ucode_info_early(void)
-{
- struct ucode_cpu_info uci;
-
- if (delay_ucode_info) {
- collect_cpu_info_early(&uci);
- print_ucode_info(&uci, current_mc_date);
- delay_ucode_info = 0;
- }
-}
-
-/*
- * At this point, we can not call printk() yet. Keep microcode patch number in
- * mc_saved_data.mc_saved and delay printing microcode info in
- * show_ucode_info_early() until printk() works.
- */
-static void print_ucode(struct ucode_cpu_info *uci)
-{
- struct microcode_intel *mc_intel;
- int *delay_ucode_info_p;
- int *current_mc_date_p;
-
- mc_intel = uci->mc;
- if (mc_intel == NULL)
- return;
-
- delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
- current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);
-
- *delay_ucode_info_p = 1;
- *current_mc_date_p = mc_intel->hdr.date;
-}
-#else
-
-/*
- * Flush global tlb. We only do this in x86_64 where paging has been enabled
- * already and PGE should be enabled as well.
- */
-static inline void flush_tlb_early(void)
-{
- __native_flush_tlb_global_irq_disabled();
-}
-
-static inline void print_ucode(struct ucode_cpu_info *uci)
-{
- struct microcode_intel *mc_intel;
-
- mc_intel = uci->mc;
- if (mc_intel == NULL)
- return;
-
- print_ucode_info(uci, mc_intel->hdr.date);
-}
-#endif
-
-static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
-{
- struct microcode_intel *mc_intel;
- unsigned int val[2];
-
- mc_intel = uci->mc;
- if (mc_intel == NULL)
- return 0;
-
- /* write microcode via MSR 0x79 */
- native_wrmsr(MSR_IA32_UCODE_WRITE,
- (unsigned long) mc_intel->bits,
- (unsigned long) mc_intel->bits >> 16 >> 16);
- native_wrmsr(MSR_IA32_UCODE_REV, 0, 0);
-
- /* As documented in the SDM: Do a CPUID 1 here */
- sync_core();
-
- /* get the current revision from MSR 0x8B */
- native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
- if (val[1] != mc_intel->hdr.rev)
- return -1;
-
-#ifdef CONFIG_X86_64
- /* Flush global tlb. This is precaution. */
- flush_tlb_early();
-#endif
- uci->cpu_sig.rev = val[1];
-
- if (early)
- print_ucode(uci);
- else
- print_ucode_info(uci, mc_intel->hdr.date);
-
- return 0;
-}
-
-/*
- * This function converts microcode patch offsets previously stored in
- * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data.
- */
-int __init save_microcode_in_initrd_intel(void)
-{
- unsigned int count = mc_saved_data.mc_saved_count;
- struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
- int ret = 0;
-
- if (count == 0)
- return ret;
-
- copy_initrd_ptrs(mc_saved, mc_saved_in_initrd, initrd_start, count);
- ret = save_microcode(&mc_saved_data, mc_saved, count);
- if (ret)
- pr_err("Cannot save microcode patches from initrd.\n");
-
- show_saved_mc();
-
- return ret;
-}
-
-static void __init
-_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data,
- unsigned long *initrd,
- unsigned long start, unsigned long size)
-{
- struct ucode_cpu_info uci;
- enum ucode_state ret;
-
- collect_cpu_info_early(&uci);
-
- ret = scan_microcode(mc_saved_data, initrd, start, size, &uci);
- if (ret != UCODE_OK)
- return;
-
- ret = load_microcode(mc_saved_data, initrd, start, &uci);
- if (ret != UCODE_OK)
- return;
-
- apply_microcode_early(&uci, true);
-}
-
-void __init load_ucode_intel_bsp(void)
-{
- u64 start, size;
-#ifdef CONFIG_X86_32
- struct boot_params *p;
-
- p = (struct boot_params *)__pa_nodebug(&boot_params);
- start = p->hdr.ramdisk_image;
- size = p->hdr.ramdisk_size;
-
- _load_ucode_intel_bsp(
- (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
- (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
- start, size);
-#else
- start = boot_params.hdr.ramdisk_image + PAGE_OFFSET;
- size = boot_params.hdr.ramdisk_size;
-
- _load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd, start, size);
-#endif
-}
-
-void load_ucode_intel_ap(void)
-{
- struct mc_saved_data *mc_saved_data_p;
- struct ucode_cpu_info uci;
- unsigned long *mc_saved_in_initrd_p;
- unsigned long initrd_start_addr;
- enum ucode_state ret;
-#ifdef CONFIG_X86_32
- unsigned long *initrd_start_p;
-
- mc_saved_in_initrd_p =
- (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
- mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
- initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
- initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
-#else
- mc_saved_data_p = &mc_saved_data;
- mc_saved_in_initrd_p = mc_saved_in_initrd;
- initrd_start_addr = initrd_start;
-#endif
-
- /*
- * If there is no valid ucode previously saved in memory, no need to
- * update ucode on this AP.
- */
- if (mc_saved_data_p->mc_saved_count == 0)
- return;
-
- collect_cpu_info_early(&uci);
- ret = load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
- initrd_start_addr, &uci);
-
- if (ret != UCODE_OK)
- return;
-
- apply_microcode_early(&uci, true);
-}
-
-void reload_ucode_intel(void)
-{
- struct ucode_cpu_info uci;
- enum ucode_state ret;
-
- if (!mc_saved_data.mc_saved_count)
- return;
-
- collect_cpu_info_early(&uci);
-
- ret = load_microcode_early(mc_saved_data.mc_saved,
- mc_saved_data.mc_saved_count, &uci);
- if (ret != UCODE_OK)
- return;
-
- apply_microcode_early(&uci, false);
-}
diff --git a/arch/x86/kernel/cpu/microcode/intel_lib.c b/arch/x86/kernel/cpu/microcode/intel_lib.c
index 1883d25..2ce1a7d 100644
--- a/arch/x86/kernel/cpu/microcode/intel_lib.c
+++ b/arch/x86/kernel/cpu/microcode/intel_lib.c
@@ -25,7 +25,6 @@
#include <linux/firmware.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
-#include <linux/module.h>
#include <asm/microcode_intel.h>
#include <asm/processor.h>
@@ -50,7 +49,7 @@ int microcode_sanity_check(void *mc, int print_err)
unsigned long total_size, data_size, ext_table_size;
struct microcode_header_intel *mc_header = mc;
struct extended_sigtable *ext_header = NULL;
- int sum, orig_sum, ext_sigcount = 0, i;
+ u32 sum, orig_sum, ext_sigcount = 0, i;
struct extended_signature *ext_sig;
total_size = get_totalsize(mc_header);
@@ -58,69 +57,85 @@ int microcode_sanity_check(void *mc, int print_err)
if (data_size + MC_HEADER_SIZE > total_size) {
if (print_err)
- pr_err("error! Bad data size in microcode data file\n");
+ pr_err("Error: bad microcode data file size.\n");
return -EINVAL;
}
if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
if (print_err)
- pr_err("error! Unknown microcode update format\n");
+ pr_err("Error: invalid/unknown microcode update format.\n");
return -EINVAL;
}
+
ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
if (ext_table_size) {
+ u32 ext_table_sum = 0;
+ u32 *ext_tablep;
+
if ((ext_table_size < EXT_HEADER_SIZE)
|| ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
if (print_err)
- pr_err("error! Small exttable size in microcode data file\n");
+ pr_err("Error: truncated extended signature table.\n");
return -EINVAL;
}
+
ext_header = mc + MC_HEADER_SIZE + data_size;
if (ext_table_size != exttable_size(ext_header)) {
if (print_err)
- pr_err("error! Bad exttable size in microcode data file\n");
+ pr_err("Error: extended signature table size mismatch.\n");
return -EFAULT;
}
+
ext_sigcount = ext_header->count;
- }
- /* check extended table checksum */
- if (ext_table_size) {
- int ext_table_sum = 0;
- int *ext_tablep = (int *)ext_header;
+ /*
+ * Check extended table checksum: the sum of all dwords that
+ * comprise a valid table must be 0.
+ */
+ ext_tablep = (u32 *)ext_header;
- i = ext_table_size / DWSIZE;
+ i = ext_table_size / sizeof(u32);
while (i--)
ext_table_sum += ext_tablep[i];
+
if (ext_table_sum) {
if (print_err)
- pr_warn("aborting, bad extended signature table checksum\n");
+ pr_warn("Bad extended signature table checksum, aborting.\n");
return -EINVAL;
}
}
- /* calculate the checksum */
+ /*
+ * Calculate the checksum of update data and header. The checksum of
+ * valid update data and header including the extended signature table
+ * must be 0.
+ */
orig_sum = 0;
- i = (MC_HEADER_SIZE + data_size) / DWSIZE;
+ i = (MC_HEADER_SIZE + data_size) / sizeof(u32);
while (i--)
- orig_sum += ((int *)mc)[i];
+ orig_sum += ((u32 *)mc)[i];
+
if (orig_sum) {
if (print_err)
- pr_err("aborting, bad checksum\n");
+ pr_err("Bad microcode data checksum, aborting.\n");
return -EINVAL;
}
+
if (!ext_table_size)
return 0;
- /* check extended signature checksum */
+
+ /*
+ * Check extended signature checksum: 0 => valid.
+ */
for (i = 0; i < ext_sigcount; i++) {
ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
EXT_SIGNATURE_SIZE * i;
- sum = orig_sum
- - (mc_header->sig + mc_header->pf + mc_header->cksum)
- + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
+
+ sum = (mc_header->sig + mc_header->pf + mc_header->cksum) -
+ (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
if (sum) {
if (print_err)
- pr_err("aborting, bad checksum\n");
+ pr_err("Bad extended signature checksum, aborting.\n");
return -EINVAL;
}
}
diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh
index 3f20710..6988c74 100644
--- a/arch/x86/kernel/cpu/mkcapflags.sh
+++ b/arch/x86/kernel/cpu/mkcapflags.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h
+# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h
#
IN=$1
@@ -49,8 +49,8 @@ dump_array()
trap 'rm "$OUT"' EXIT
(
- echo "#ifndef _ASM_X86_CPUFEATURE_H"
- echo "#include <asm/cpufeature.h>"
+ echo "#ifndef _ASM_X86_CPUFEATURES_H"
+ echo "#include <asm/cpufeatures.h>"
echo "#endif"
echo ""
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 20e242e..4e7c693 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -161,8 +161,8 @@ static void __init ms_hyperv_init_platform(void)
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
- printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
- ms_hyperv.features, ms_hyperv.hints);
+ pr_info("HyperV: features 0x%x, hints 0x%x\n",
+ ms_hyperv.features, ms_hyperv.hints);
#ifdef CONFIG_X86_LOCAL_APIC
if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
@@ -174,8 +174,8 @@ static void __init ms_hyperv_init_platform(void)
rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
lapic_timer_frequency = hv_lapic_frequency;
- printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n",
- lapic_timer_frequency);
+ pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
+ lapic_timer_frequency);
}
#endif
diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c
index 316fe3e..3d68993 100644
--- a/arch/x86/kernel/cpu/mtrr/centaur.c
+++ b/arch/x86/kernel/cpu/mtrr/centaur.c
@@ -103,7 +103,7 @@ centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int t
*/
if (type != MTRR_TYPE_WRCOMB &&
(centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
- pr_warning("mtrr: only write-combining%s supported\n",
+ pr_warn("mtrr: only write-combining%s supported\n",
centaur_mcr_type ? " and uncacheable are" : " is");
return -EINVAL;
}
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 70d7c93..31e951c 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -57,9 +57,9 @@ static int __initdata nr_range;
static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
static int __initdata debug_print;
-#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)
+#define Dprintk(x...) do { if (debug_print) pr_debug(x); } while (0)
-#define BIOS_BUG_MSG KERN_WARNING \
+#define BIOS_BUG_MSG \
"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
static int __init
@@ -81,9 +81,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
base, base + size);
}
if (debug_print) {
- printk(KERN_DEBUG "After WB checking\n");
+ pr_debug("After WB checking\n");
for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+ pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
@@ -101,7 +101,7 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) &&
(mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) {
/* Var MTRR contains UC entry below 1M? Skip it: */
- printk(BIOS_BUG_MSG, i);
+ pr_warn(BIOS_BUG_MSG, i);
if (base + size <= (1<<(20-PAGE_SHIFT)))
continue;
size -= (1<<(20-PAGE_SHIFT)) - base;
@@ -114,11 +114,11 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
extra_remove_base + extra_remove_size);
if (debug_print) {
- printk(KERN_DEBUG "After UC checking\n");
+ pr_debug("After UC checking\n");
for (i = 0; i < RANGE_NUM; i++) {
if (!range[i].end)
continue;
- printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+ pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
}
@@ -126,9 +126,9 @@ x86_get_mtrr_mem_range(struct range *range, int nr_range,
/* sort the ranges */
nr_range = clean_sort_range(range, RANGE_NUM);
if (debug_print) {
- printk(KERN_DEBUG "After sorting\n");
+ pr_debug("After sorting\n");
for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
+ pr_debug("MTRR MAP PFN: %016llx - %016llx\n",
range[i].start, range[i].end);
}
@@ -544,7 +544,7 @@ static void __init print_out_mtrr_range_state(void)
start_base = to_size_factor(start_base, &start_factor),
type = range_state[i].type;
- printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
+ pr_debug("reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
i, start_base, start_factor,
size_base, size_factor,
(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
@@ -593,9 +593,16 @@ mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
unsigned long x_remove_base,
unsigned long x_remove_size, int i)
{
- static struct range range_new[RANGE_NUM];
+ /*
+ * range_new should really be an automatic variable, but
+ * putting 4096 bytes on the stack is frowned upon, to put it
+ * mildly. It is safe to make it a static __initdata variable,
+ * since mtrr_calc_range_state is only called during init and
+ * there's no way it will call itself recursively.
+ */
+ static struct range range_new[RANGE_NUM] __initdata;
unsigned long range_sums_new;
- static int nr_range_new;
+ int nr_range_new;
int num_reg;
/* Convert ranges to var ranges state: */
@@ -706,7 +713,7 @@ int __init mtrr_cleanup(unsigned address_bits)
return 0;
/* Print original var MTRRs at first, for debugging: */
- printk(KERN_DEBUG "original variable MTRRs\n");
+ pr_debug("original variable MTRRs\n");
print_out_mtrr_range_state();
memset(range, 0, sizeof(range));
@@ -726,7 +733,7 @@ int __init mtrr_cleanup(unsigned address_bits)
x_remove_base, x_remove_size);
range_sums = sum_ranges(range, nr_range);
- printk(KERN_INFO "total RAM covered: %ldM\n",
+ pr_info("total RAM covered: %ldM\n",
range_sums >> (20 - PAGE_SHIFT));
if (mtrr_chunk_size && mtrr_gran_size) {
@@ -738,12 +745,11 @@ int __init mtrr_cleanup(unsigned address_bits)
if (!result[i].bad) {
set_var_mtrr_all(address_bits);
- printk(KERN_DEBUG "New variable MTRRs\n");
+ pr_debug("New variable MTRRs\n");
print_out_mtrr_range_state();
return 1;
}
- printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
- "will find optimal one\n");
+ pr_info("invalid mtrr_gran_size or mtrr_chunk_size, will find optimal one\n");
}
i = 0;
@@ -761,7 +767,7 @@ int __init mtrr_cleanup(unsigned address_bits)
x_remove_base, x_remove_size, i);
if (debug_print) {
mtrr_print_out_one_result(i);
- printk(KERN_INFO "\n");
+ pr_info("\n");
}
i++;
@@ -772,7 +778,7 @@ int __init mtrr_cleanup(unsigned address_bits)
index_good = mtrr_search_optimal_index();
if (index_good != -1) {
- printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
+ pr_info("Found optimal setting for mtrr clean up\n");
i = index_good;
mtrr_print_out_one_result(i);
@@ -783,7 +789,7 @@ int __init mtrr_cleanup(unsigned address_bits)
gran_size <<= 10;
x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
set_var_mtrr_all(address_bits);
- printk(KERN_DEBUG "New variable MTRRs\n");
+ pr_debug("New variable MTRRs\n");
print_out_mtrr_range_state();
return 1;
} else {
@@ -792,8 +798,8 @@ int __init mtrr_cleanup(unsigned address_bits)
mtrr_print_out_one_result(i);
}
- printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
- printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
+ pr_info("mtrr_cleanup: can not find optimal value\n");
+ pr_info("please specify mtrr_gran_size/mtrr_chunk_size\n");
return 0;
}
@@ -911,7 +917,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
/* kvm/qemu doesn't have mtrr set right, don't trim them all: */
if (!highest_pfn) {
- printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
+ pr_info("CPU MTRRs all blank - virtualized system.\n");
return 0;
}
@@ -966,7 +972,8 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
end_pfn);
if (total_trim_size) {
- pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20);
+ pr_warn("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n",
+ total_trim_size >> 20);
if (!changed_by_mtrr_cleanup)
WARN_ON(1);
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 3b533cf..fcbcb2f 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -55,7 +55,7 @@ static inline void k8_check_syscfg_dram_mod_en(void)
rdmsr(MSR_K8_SYSCFG, lo, hi);
if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
- printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
+ pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
" not cleared by BIOS, clearing this bit\n",
smp_processor_id());
lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
@@ -349,7 +349,7 @@ static void get_fixed_ranges(mtrr_type *frs)
void mtrr_save_fixed_ranges(void *info)
{
- if (cpu_has_mtrr)
+ if (boot_cpu_has(X86_FEATURE_MTRR))
get_fixed_ranges(mtrr_state.fixed_ranges);
}
@@ -501,14 +501,14 @@ void __init mtrr_state_warn(void)
if (!mask)
return;
if (mask & MTRR_CHANGE_MASK_FIXED)
- pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
+ pr_warn("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_VARIABLE)
- pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n");
+ pr_warn("mtrr: your CPUs had inconsistent variable MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_DEFTYPE)
- pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
+ pr_warn("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
- printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n");
- printk(KERN_INFO "mtrr: corrected configuration.\n");
+ pr_info("mtrr: probably your BIOS does not setup all CPUs.\n");
+ pr_info("mtrr: corrected configuration.\n");
}
/*
@@ -519,8 +519,7 @@ void __init mtrr_state_warn(void)
void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
{
if (wrmsr_safe(msr, a, b) < 0) {
- printk(KERN_ERR
- "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
+ pr_err("MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
smp_processor_id(), msr, a, b);
}
}
@@ -607,7 +606,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
tmp |= ~((1ULL<<(hi - 1)) - 1);
if (tmp != mask) {
- printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
+ pr_warn("mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
mask = tmp;
}
@@ -858,13 +857,13 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
boot_cpu_data.x86_model == 1 &&
boot_cpu_data.x86_mask <= 7) {
if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
- pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
+ pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
return -EINVAL;
}
if (!(base + size < 0x70000 || base > 0x7003F) &&
(type == MTRR_TYPE_WRCOMB
|| type == MTRR_TYPE_WRBACK)) {
- pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
+ pr_warn("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
return -EINVAL;
}
}
@@ -878,7 +877,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
lbase = lbase >> 1, last = last >> 1)
;
if (lbase != last) {
- pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
+ pr_warn("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
return -EINVAL;
}
return 0;
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index f891b47..10f8d47 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -47,7 +47,7 @@
#include <linux/smp.h>
#include <linux/syscore_ops.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/e820.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
@@ -300,24 +300,24 @@ int mtrr_add_page(unsigned long base, unsigned long size,
return error;
if (type >= MTRR_NUM_TYPES) {
- pr_warning("mtrr: type: %u invalid\n", type);
+ pr_warn("mtrr: type: %u invalid\n", type);
return -EINVAL;
}
/* If the type is WC, check that this processor supports it */
if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
- pr_warning("mtrr: your processor doesn't support write-combining\n");
+ pr_warn("mtrr: your processor doesn't support write-combining\n");
return -ENOSYS;
}
if (!size) {
- pr_warning("mtrr: zero sized request\n");
+ pr_warn("mtrr: zero sized request\n");
return -EINVAL;
}
if ((base | (base + size - 1)) >>
(boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) {
- pr_warning("mtrr: base or size exceeds the MTRR width\n");
+ pr_warn("mtrr: base or size exceeds the MTRR width\n");
return -EINVAL;
}
@@ -348,7 +348,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
} else if (types_compatible(type, ltype))
continue;
}
- pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
+ pr_warn("mtrr: 0x%lx000,0x%lx000 overlaps existing"
" 0x%lx000,0x%lx000\n", base, size, lbase,
lsize);
goto out;
@@ -357,7 +357,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
if (ltype != type) {
if (types_compatible(type, ltype))
continue;
- pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
+ pr_warn("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
base, size, mtrr_attrib_to_str(ltype),
mtrr_attrib_to_str(type));
goto out;
@@ -395,7 +395,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
static int mtrr_check(unsigned long base, unsigned long size)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
- pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
+ pr_warn("mtrr: size and base must be multiples of 4 kiB\n");
pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
dump_stack();
return -1;
@@ -493,16 +493,16 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
}
}
if (reg >= max) {
- pr_warning("mtrr: register: %d too big\n", reg);
+ pr_warn("mtrr: register: %d too big\n", reg);
goto out;
}
mtrr_if->get(reg, &lbase, &lsize, &ltype);
if (lsize < 1) {
- pr_warning("mtrr: MTRR %d not used\n", reg);
+ pr_warn("mtrr: MTRR %d not used\n", reg);
goto out;
}
if (mtrr_usage_table[reg] < 1) {
- pr_warning("mtrr: reg: %d has count=0\n", reg);
+ pr_warn("mtrr: reg: %d has count=0\n", reg);
goto out;
}
if (--mtrr_usage_table[reg] < 1)
@@ -682,7 +682,7 @@ void __init mtrr_bp_init(void)
phys_addr = 32;
- if (cpu_has_mtrr) {
+ if (boot_cpu_has(X86_FEATURE_MTRR)) {
mtrr_if = &generic_mtrr_ops;
size_or_mask = SIZE_OR_MASK_BITS(36);
size_and_mask = 0x00f00000;
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
deleted file mode 100644
index 66dd3fe9..0000000
--- a/arch/x86/kernel/cpu/perf_event.c
+++ /dev/null
@@ -1,2373 +0,0 @@
-/*
- * Performance events x86 architecture code
- *
- * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- * Copyright (C) 2009 Jaswinder Singh Rajput
- * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
- * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
- * Copyright (C) 2009 Google, Inc., Stephane Eranian
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-#include <linux/capability.h>
-#include <linux/notifier.h>
-#include <linux/hardirq.h>
-#include <linux/kprobes.h>
-#include <linux/module.h>
-#include <linux/kdebug.h>
-#include <linux/sched.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/cpu.h>
-#include <linux/bitops.h>
-#include <linux/device.h>
-
-#include <asm/apic.h>
-#include <asm/stacktrace.h>
-#include <asm/nmi.h>
-#include <asm/smp.h>
-#include <asm/alternative.h>
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
-#include <asm/timer.h>
-#include <asm/desc.h>
-#include <asm/ldt.h>
-
-#include "perf_event.h"
-
-struct x86_pmu x86_pmu __read_mostly;
-
-DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
- .enabled = 1,
-};
-
-struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE;
-
-u64 __read_mostly hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-u64 __read_mostly hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-
-/*
- * Propagate event elapsed time into the generic event.
- * Can only be executed on the CPU where the event is active.
- * Returns the delta events processed.
- */
-u64 x86_perf_event_update(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int shift = 64 - x86_pmu.cntval_bits;
- u64 prev_raw_count, new_raw_count;
- int idx = hwc->idx;
- s64 delta;
-
- if (idx == INTEL_PMC_IDX_FIXED_BTS)
- return 0;
-
- /*
- * Careful: an NMI might modify the previous event value.
- *
- * Our tactic to handle this is to first atomically read and
- * exchange a new raw count - then add that new-prev delta
- * count to the generic event atomically:
- */
-again:
- prev_raw_count = local64_read(&hwc->prev_count);
- rdpmcl(hwc->event_base_rdpmc, new_raw_count);
-
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count)
- goto again;
-
- /*
- * Now we have the new raw value and have updated the prev
- * timestamp already. We can now calculate the elapsed delta
- * (event-)time and add that to the generic event.
- *
- * Careful, not all hw sign-extends above the physical width
- * of the count.
- */
- delta = (new_raw_count << shift) - (prev_raw_count << shift);
- delta >>= shift;
-
- local64_add(delta, &event->count);
- local64_sub(delta, &hwc->period_left);
-
- return new_raw_count;
-}
-
-/*
- * Find and validate any extra registers to set up.
- */
-static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg;
- struct extra_reg *er;
-
- reg = &event->hw.extra_reg;
-
- if (!x86_pmu.extra_regs)
- return 0;
-
- for (er = x86_pmu.extra_regs; er->msr; er++) {
- if (er->event != (config & er->config_mask))
- continue;
- if (event->attr.config1 & ~er->valid_mask)
- return -EINVAL;
- /* Check if the extra msrs can be safely accessed*/
- if (!er->extra_msr_access)
- return -ENXIO;
-
- reg->idx = er->idx;
- reg->config = event->attr.config1;
- reg->reg = er->msr;
- break;
- }
- return 0;
-}
-
-static atomic_t active_events;
-static atomic_t pmc_refcount;
-static DEFINE_MUTEX(pmc_reserve_mutex);
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-static bool reserve_pmc_hardware(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.num_counters; i++) {
- if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
- goto perfctr_fail;
- }
-
- for (i = 0; i < x86_pmu.num_counters; i++) {
- if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
- goto eventsel_fail;
- }
-
- return true;
-
-eventsel_fail:
- for (i--; i >= 0; i--)
- release_evntsel_nmi(x86_pmu_config_addr(i));
-
- i = x86_pmu.num_counters;
-
-perfctr_fail:
- for (i--; i >= 0; i--)
- release_perfctr_nmi(x86_pmu_event_addr(i));
-
- return false;
-}
-
-static void release_pmc_hardware(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.num_counters; i++) {
- release_perfctr_nmi(x86_pmu_event_addr(i));
- release_evntsel_nmi(x86_pmu_config_addr(i));
- }
-}
-
-#else
-
-static bool reserve_pmc_hardware(void) { return true; }
-static void release_pmc_hardware(void) {}
-
-#endif
-
-static bool check_hw_exists(void)
-{
- u64 val, val_fail, val_new= ~0;
- int i, reg, reg_fail, ret = 0;
- int bios_fail = 0;
- int reg_safe = -1;
-
- /*
- * Check to see if the BIOS enabled any of the counters, if so
- * complain and bail.
- */
- for (i = 0; i < x86_pmu.num_counters; i++) {
- reg = x86_pmu_config_addr(i);
- ret = rdmsrl_safe(reg, &val);
- if (ret)
- goto msr_fail;
- if (val & ARCH_PERFMON_EVENTSEL_ENABLE) {
- bios_fail = 1;
- val_fail = val;
- reg_fail = reg;
- } else {
- reg_safe = i;
- }
- }
-
- if (x86_pmu.num_counters_fixed) {
- reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
- ret = rdmsrl_safe(reg, &val);
- if (ret)
- goto msr_fail;
- for (i = 0; i < x86_pmu.num_counters_fixed; i++) {
- if (val & (0x03 << i*4)) {
- bios_fail = 1;
- val_fail = val;
- reg_fail = reg;
- }
- }
- }
-
- /*
- * If all the counters are enabled, the below test will always
- * fail. The tools will also become useless in this scenario.
- * Just fail and disable the hardware counters.
- */
-
- if (reg_safe == -1) {
- reg = reg_safe;
- goto msr_fail;
- }
-
- /*
- * Read the current value, change it and read it back to see if it
- * matches, this is needed to detect certain hardware emulators
- * (qemu/kvm) that don't trap on the MSR access and always return 0s.
- */
- reg = x86_pmu_event_addr(reg_safe);
- if (rdmsrl_safe(reg, &val))
- goto msr_fail;
- val ^= 0xffffUL;
- ret = wrmsrl_safe(reg, val);
- ret |= rdmsrl_safe(reg, &val_new);
- if (ret || val != val_new)
- goto msr_fail;
-
- /*
- * We still allow the PMU driver to operate:
- */
- if (bios_fail) {
- printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n");
- printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
- }
-
- return true;
-
-msr_fail:
- printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
- printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n",
- boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR,
- reg, val_new);
-
- return false;
-}
-
-static void hw_perf_event_destroy(struct perf_event *event)
-{
- x86_release_hardware();
- atomic_dec(&active_events);
-}
-
-void hw_perf_lbr_event_destroy(struct perf_event *event)
-{
- hw_perf_event_destroy(event);
-
- /* undo the lbr/bts event accounting */
- x86_del_exclusive(x86_lbr_exclusive_lbr);
-}
-
-static inline int x86_pmu_initialized(void)
-{
- return x86_pmu.handle_irq != NULL;
-}
-
-static inline int
-set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
-{
- struct perf_event_attr *attr = &event->attr;
- unsigned int cache_type, cache_op, cache_result;
- u64 config, val;
-
- config = attr->config;
-
- 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;
-
- val = hw_cache_event_ids[cache_type][cache_op][cache_result];
-
- if (val == 0)
- return -ENOENT;
-
- if (val == -1)
- return -EINVAL;
-
- hwc->config |= val;
- attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
- return x86_pmu_extra_regs(val, event);
-}
-
-int x86_reserve_hardware(void)
-{
- int err = 0;
-
- if (!atomic_inc_not_zero(&pmc_refcount)) {
- mutex_lock(&pmc_reserve_mutex);
- if (atomic_read(&pmc_refcount) == 0) {
- if (!reserve_pmc_hardware())
- err = -EBUSY;
- else
- reserve_ds_buffers();
- }
- if (!err)
- atomic_inc(&pmc_refcount);
- mutex_unlock(&pmc_reserve_mutex);
- }
-
- return err;
-}
-
-void x86_release_hardware(void)
-{
- if (atomic_dec_and_mutex_lock(&pmc_refcount, &pmc_reserve_mutex)) {
- release_pmc_hardware();
- release_ds_buffers();
- mutex_unlock(&pmc_reserve_mutex);
- }
-}
-
-/*
- * Check if we can create event of a certain type (that no conflicting events
- * are present).
- */
-int x86_add_exclusive(unsigned int what)
-{
- int i;
-
- if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
- mutex_lock(&pmc_reserve_mutex);
- for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
- if (i != what && atomic_read(&x86_pmu.lbr_exclusive[i]))
- goto fail_unlock;
- }
- atomic_inc(&x86_pmu.lbr_exclusive[what]);
- mutex_unlock(&pmc_reserve_mutex);
- }
-
- atomic_inc(&active_events);
- return 0;
-
-fail_unlock:
- mutex_unlock(&pmc_reserve_mutex);
- return -EBUSY;
-}
-
-void x86_del_exclusive(unsigned int what)
-{
- atomic_dec(&x86_pmu.lbr_exclusive[what]);
- atomic_dec(&active_events);
-}
-
-int x86_setup_perfctr(struct perf_event *event)
-{
- struct perf_event_attr *attr = &event->attr;
- struct hw_perf_event *hwc = &event->hw;
- u64 config;
-
- if (!is_sampling_event(event)) {
- hwc->sample_period = x86_pmu.max_period;
- hwc->last_period = hwc->sample_period;
- local64_set(&hwc->period_left, hwc->sample_period);
- }
-
- if (attr->type == PERF_TYPE_RAW)
- return x86_pmu_extra_regs(event->attr.config, event);
-
- if (attr->type == PERF_TYPE_HW_CACHE)
- return set_ext_hw_attr(hwc, event);
-
- if (attr->config >= x86_pmu.max_events)
- return -EINVAL;
-
- /*
- * The generic map:
- */
- config = x86_pmu.event_map(attr->config);
-
- if (config == 0)
- return -ENOENT;
-
- if (config == -1LL)
- return -EINVAL;
-
- /*
- * Branch tracing:
- */
- if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
- !attr->freq && hwc->sample_period == 1) {
- /* BTS is not supported by this architecture. */
- if (!x86_pmu.bts_active)
- return -EOPNOTSUPP;
-
- /* BTS is currently only allowed for user-mode. */
- if (!attr->exclude_kernel)
- return -EOPNOTSUPP;
-
- /* disallow bts if conflicting events are present */
- if (x86_add_exclusive(x86_lbr_exclusive_lbr))
- return -EBUSY;
-
- event->destroy = hw_perf_lbr_event_destroy;
- }
-
- hwc->config |= config;
-
- return 0;
-}
-
-/*
- * check that branch_sample_type is compatible with
- * settings needed for precise_ip > 1 which implies
- * using the LBR to capture ALL taken branches at the
- * priv levels of the measurement
- */
-static inline int precise_br_compat(struct perf_event *event)
-{
- u64 m = event->attr.branch_sample_type;
- u64 b = 0;
-
- /* must capture all branches */
- if (!(m & PERF_SAMPLE_BRANCH_ANY))
- return 0;
-
- m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
-
- if (!event->attr.exclude_user)
- b |= PERF_SAMPLE_BRANCH_USER;
-
- if (!event->attr.exclude_kernel)
- b |= PERF_SAMPLE_BRANCH_KERNEL;
-
- /*
- * ignore PERF_SAMPLE_BRANCH_HV, not supported on x86
- */
-
- return m == b;
-}
-
-int x86_pmu_hw_config(struct perf_event *event)
-{
- if (event->attr.precise_ip) {
- int precise = 0;
-
- /* Support for constant skid */
- if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
- precise++;
-
- /* Support for IP fixup */
- if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
- precise++;
- }
-
- if (event->attr.precise_ip > precise)
- return -EOPNOTSUPP;
- }
- /*
- * check that PEBS LBR correction does not conflict with
- * whatever the user is asking with attr->branch_sample_type
- */
- if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
- u64 *br_type = &event->attr.branch_sample_type;
-
- if (has_branch_stack(event)) {
- if (!precise_br_compat(event))
- return -EOPNOTSUPP;
-
- /* branch_sample_type is compatible */
-
- } else {
- /*
- * user did not specify branch_sample_type
- *
- * For PEBS fixups, we capture all
- * the branches at the priv level of the
- * event.
- */
- *br_type = PERF_SAMPLE_BRANCH_ANY;
-
- if (!event->attr.exclude_user)
- *br_type |= PERF_SAMPLE_BRANCH_USER;
-
- if (!event->attr.exclude_kernel)
- *br_type |= PERF_SAMPLE_BRANCH_KERNEL;
- }
- }
-
- if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK)
- event->attach_state |= PERF_ATTACH_TASK_DATA;
-
- /*
- * Generate PMC IRQs:
- * (keep 'enabled' bit clear for now)
- */
- event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
-
- /*
- * Count user and OS events unless requested not to
- */
- if (!event->attr.exclude_user)
- event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
- if (!event->attr.exclude_kernel)
- event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
-
- if (event->attr.type == PERF_TYPE_RAW)
- event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
-
- if (event->attr.sample_period && x86_pmu.limit_period) {
- if (x86_pmu.limit_period(event, event->attr.sample_period) >
- event->attr.sample_period)
- return -EINVAL;
- }
-
- return x86_setup_perfctr(event);
-}
-
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __x86_pmu_event_init(struct perf_event *event)
-{
- int err;
-
- if (!x86_pmu_initialized())
- return -ENODEV;
-
- err = x86_reserve_hardware();
- if (err)
- return err;
-
- atomic_inc(&active_events);
- event->destroy = hw_perf_event_destroy;
-
- event->hw.idx = -1;
- event->hw.last_cpu = -1;
- event->hw.last_tag = ~0ULL;
-
- /* mark unused */
- event->hw.extra_reg.idx = EXTRA_REG_NONE;
- event->hw.branch_reg.idx = EXTRA_REG_NONE;
-
- return x86_pmu.hw_config(event);
-}
-
-void x86_pmu_disable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- u64 val;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
- rdmsrl(x86_pmu_config_addr(idx), val);
- if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
- continue;
- val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
- wrmsrl(x86_pmu_config_addr(idx), val);
- }
-}
-
-static void x86_pmu_disable(struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (!x86_pmu_initialized())
- return;
-
- if (!cpuc->enabled)
- return;
-
- cpuc->n_added = 0;
- cpuc->enabled = 0;
- barrier();
-
- x86_pmu.disable_all();
-}
-
-void x86_pmu_enable_all(int added)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
- }
-}
-
-static struct pmu pmu;
-
-static inline int is_x86_event(struct perf_event *event)
-{
- return event->pmu == &pmu;
-}
-
-/*
- * Event scheduler state:
- *
- * Assign events iterating over all events and counters, beginning
- * with events with least weights first. Keep the current iterator
- * state in struct sched_state.
- */
-struct sched_state {
- int weight;
- int event; /* event index */
- int counter; /* counter index */
- int unassigned; /* number of events to be assigned left */
- int nr_gp; /* number of GP counters used */
- unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-};
-
-/* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */
-#define SCHED_STATES_MAX 2
-
-struct perf_sched {
- int max_weight;
- int max_events;
- int max_gp;
- int saved_states;
- struct event_constraint **constraints;
- struct sched_state state;
- struct sched_state saved[SCHED_STATES_MAX];
-};
-
-/*
- * Initialize interator that runs through all events and counters.
- */
-static void perf_sched_init(struct perf_sched *sched, struct event_constraint **constraints,
- int num, int wmin, int wmax, int gpmax)
-{
- int idx;
-
- memset(sched, 0, sizeof(*sched));
- sched->max_events = num;
- sched->max_weight = wmax;
- sched->max_gp = gpmax;
- sched->constraints = constraints;
-
- for (idx = 0; idx < num; idx++) {
- if (constraints[idx]->weight == wmin)
- break;
- }
-
- sched->state.event = idx; /* start with min weight */
- sched->state.weight = wmin;
- sched->state.unassigned = num;
-}
-
-static void perf_sched_save_state(struct perf_sched *sched)
-{
- if (WARN_ON_ONCE(sched->saved_states >= SCHED_STATES_MAX))
- return;
-
- sched->saved[sched->saved_states] = sched->state;
- sched->saved_states++;
-}
-
-static bool perf_sched_restore_state(struct perf_sched *sched)
-{
- if (!sched->saved_states)
- return false;
-
- sched->saved_states--;
- sched->state = sched->saved[sched->saved_states];
-
- /* continue with next counter: */
- clear_bit(sched->state.counter++, sched->state.used);
-
- return true;
-}
-
-/*
- * Select a counter for the current event to schedule. Return true on
- * success.
- */
-static bool __perf_sched_find_counter(struct perf_sched *sched)
-{
- struct event_constraint *c;
- int idx;
-
- if (!sched->state.unassigned)
- return false;
-
- if (sched->state.event >= sched->max_events)
- return false;
-
- c = sched->constraints[sched->state.event];
- /* Prefer fixed purpose counters */
- if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
- idx = INTEL_PMC_IDX_FIXED;
- for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
- if (!__test_and_set_bit(idx, sched->state.used))
- goto done;
- }
- }
-
- /* Grab the first unused counter starting with idx */
- idx = sched->state.counter;
- for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
- if (!__test_and_set_bit(idx, sched->state.used)) {
- if (sched->state.nr_gp++ >= sched->max_gp)
- return false;
-
- goto done;
- }
- }
-
- return false;
-
-done:
- sched->state.counter = idx;
-
- if (c->overlap)
- perf_sched_save_state(sched);
-
- return true;
-}
-
-static bool perf_sched_find_counter(struct perf_sched *sched)
-{
- while (!__perf_sched_find_counter(sched)) {
- if (!perf_sched_restore_state(sched))
- return false;
- }
-
- return true;
-}
-
-/*
- * Go through all unassigned events and find the next one to schedule.
- * Take events with the least weight first. Return true on success.
- */
-static bool perf_sched_next_event(struct perf_sched *sched)
-{
- struct event_constraint *c;
-
- if (!sched->state.unassigned || !--sched->state.unassigned)
- return false;
-
- do {
- /* next event */
- sched->state.event++;
- if (sched->state.event >= sched->max_events) {
- /* next weight */
- sched->state.event = 0;
- sched->state.weight++;
- if (sched->state.weight > sched->max_weight)
- return false;
- }
- c = sched->constraints[sched->state.event];
- } while (c->weight != sched->state.weight);
-
- sched->state.counter = 0; /* start with first counter */
-
- return true;
-}
-
-/*
- * Assign a counter for each event.
- */
-int perf_assign_events(struct event_constraint **constraints, int n,
- int wmin, int wmax, int gpmax, int *assign)
-{
- struct perf_sched sched;
-
- perf_sched_init(&sched, constraints, n, wmin, wmax, gpmax);
-
- do {
- if (!perf_sched_find_counter(&sched))
- break; /* failed */
- if (assign)
- assign[sched.state.event] = sched.state.counter;
- } while (perf_sched_next_event(&sched));
-
- return sched.state.unassigned;
-}
-EXPORT_SYMBOL_GPL(perf_assign_events);
-
-int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
-{
- struct event_constraint *c;
- unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- struct perf_event *e;
- int i, wmin, wmax, unsched = 0;
- struct hw_perf_event *hwc;
-
- bitmap_zero(used_mask, X86_PMC_IDX_MAX);
-
- if (x86_pmu.start_scheduling)
- x86_pmu.start_scheduling(cpuc);
-
- for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
- cpuc->event_constraint[i] = NULL;
- c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]);
- cpuc->event_constraint[i] = c;
-
- wmin = min(wmin, c->weight);
- wmax = max(wmax, c->weight);
- }
-
- /*
- * fastpath, try to reuse previous register
- */
- for (i = 0; i < n; i++) {
- hwc = &cpuc->event_list[i]->hw;
- c = cpuc->event_constraint[i];
-
- /* never assigned */
- if (hwc->idx == -1)
- break;
-
- /* constraint still honored */
- if (!test_bit(hwc->idx, c->idxmsk))
- break;
-
- /* not already used */
- if (test_bit(hwc->idx, used_mask))
- break;
-
- __set_bit(hwc->idx, used_mask);
- if (assign)
- assign[i] = hwc->idx;
- }
-
- /* slow path */
- if (i != n) {
- int gpmax = x86_pmu.num_counters;
-
- /*
- * Do not allow scheduling of more than half the available
- * generic counters.
- *
- * This helps avoid counter starvation of sibling thread by
- * ensuring at most half the counters cannot be in exclusive
- * mode. There is no designated counters for the limits. Any
- * N/2 counters can be used. This helps with events with
- * specific counter constraints.
- */
- if (is_ht_workaround_enabled() && !cpuc->is_fake &&
- READ_ONCE(cpuc->excl_cntrs->exclusive_present))
- gpmax /= 2;
-
- unsched = perf_assign_events(cpuc->event_constraint, n, wmin,
- wmax, gpmax, assign);
- }
-
- /*
- * In case of success (unsched = 0), mark events as committed,
- * so we do not put_constraint() in case new events are added
- * and fail to be scheduled
- *
- * We invoke the lower level commit callback to lock the resource
- *
- * We do not need to do all of this in case we are called to
- * validate an event group (assign == NULL)
- */
- if (!unsched && assign) {
- for (i = 0; i < n; i++) {
- e = cpuc->event_list[i];
- e->hw.flags |= PERF_X86_EVENT_COMMITTED;
- if (x86_pmu.commit_scheduling)
- x86_pmu.commit_scheduling(cpuc, i, assign[i]);
- }
- } else {
- for (i = 0; i < n; i++) {
- e = cpuc->event_list[i];
- /*
- * do not put_constraint() on comitted events,
- * because they are good to go
- */
- if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
- continue;
-
- /*
- * release events that failed scheduling
- */
- if (x86_pmu.put_event_constraints)
- x86_pmu.put_event_constraints(cpuc, e);
- }
- }
-
- if (x86_pmu.stop_scheduling)
- x86_pmu.stop_scheduling(cpuc);
-
- return unsched ? -EINVAL : 0;
-}
-
-/*
- * dogrp: true if must collect siblings events (group)
- * returns total number of events and error code
- */
-static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
-{
- struct perf_event *event;
- int n, max_count;
-
- max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
-
- /* current number of events already accepted */
- n = cpuc->n_events;
-
- if (is_x86_event(leader)) {
- if (n >= max_count)
- return -EINVAL;
- cpuc->event_list[n] = leader;
- n++;
- }
- if (!dogrp)
- return n;
-
- list_for_each_entry(event, &leader->sibling_list, group_entry) {
- if (!is_x86_event(event) ||
- event->state <= PERF_EVENT_STATE_OFF)
- continue;
-
- if (n >= max_count)
- return -EINVAL;
-
- cpuc->event_list[n] = event;
- n++;
- }
- return n;
-}
-
-static inline void x86_assign_hw_event(struct perf_event *event,
- struct cpu_hw_events *cpuc, int i)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- hwc->idx = cpuc->assign[i];
- hwc->last_cpu = smp_processor_id();
- hwc->last_tag = ++cpuc->tags[i];
-
- if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) {
- hwc->config_base = 0;
- hwc->event_base = 0;
- } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
- hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
- hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED);
- hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30;
- } else {
- hwc->config_base = x86_pmu_config_addr(hwc->idx);
- hwc->event_base = x86_pmu_event_addr(hwc->idx);
- hwc->event_base_rdpmc = x86_pmu_rdpmc_index(hwc->idx);
- }
-}
-
-static inline int match_prev_assignment(struct hw_perf_event *hwc,
- struct cpu_hw_events *cpuc,
- int i)
-{
- return hwc->idx == cpuc->assign[i] &&
- hwc->last_cpu == smp_processor_id() &&
- hwc->last_tag == cpuc->tags[i];
-}
-
-static void x86_pmu_start(struct perf_event *event, int flags);
-
-static void x86_pmu_enable(struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct perf_event *event;
- struct hw_perf_event *hwc;
- int i, added = cpuc->n_added;
-
- if (!x86_pmu_initialized())
- return;
-
- if (cpuc->enabled)
- return;
-
- if (cpuc->n_added) {
- int n_running = cpuc->n_events - cpuc->n_added;
- /*
- * apply assignment obtained either from
- * hw_perf_group_sched_in() or x86_pmu_enable()
- *
- * step1: save events moving to new counters
- */
- for (i = 0; i < n_running; i++) {
- event = cpuc->event_list[i];
- hwc = &event->hw;
-
- /*
- * we can avoid reprogramming counter if:
- * - assigned same counter as last time
- * - running on same CPU as last time
- * - no other event has used the counter since
- */
- if (hwc->idx == -1 ||
- match_prev_assignment(hwc, cpuc, i))
- continue;
-
- /*
- * Ensure we don't accidentally enable a stopped
- * counter simply because we rescheduled.
- */
- if (hwc->state & PERF_HES_STOPPED)
- hwc->state |= PERF_HES_ARCH;
-
- x86_pmu_stop(event, PERF_EF_UPDATE);
- }
-
- /*
- * step2: reprogram moved events into new counters
- */
- for (i = 0; i < cpuc->n_events; i++) {
- event = cpuc->event_list[i];
- hwc = &event->hw;
-
- if (!match_prev_assignment(hwc, cpuc, i))
- x86_assign_hw_event(event, cpuc, i);
- else if (i < n_running)
- continue;
-
- if (hwc->state & PERF_HES_ARCH)
- continue;
-
- x86_pmu_start(event, PERF_EF_RELOAD);
- }
- cpuc->n_added = 0;
- perf_events_lapic_init();
- }
-
- cpuc->enabled = 1;
- barrier();
-
- x86_pmu.enable_all(added);
-}
-
-static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
-
-/*
- * Set the next IRQ period, based on the hwc->period_left value.
- * To be called with the event disabled in hw:
- */
-int x86_perf_event_set_period(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- s64 left = local64_read(&hwc->period_left);
- s64 period = hwc->sample_period;
- int ret = 0, idx = hwc->idx;
-
- if (idx == INTEL_PMC_IDX_FIXED_BTS)
- return 0;
-
- /*
- * If we are way outside a reasonable range then just skip forward:
- */
- 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;
- }
- /*
- * Quirk: certain CPUs dont like it if just 1 hw_event is left:
- */
- if (unlikely(left < 2))
- left = 2;
-
- if (left > x86_pmu.max_period)
- left = x86_pmu.max_period;
-
- if (x86_pmu.limit_period)
- left = x86_pmu.limit_period(event, left);
-
- per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
-
- if (!(hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) ||
- local64_read(&hwc->prev_count) != (u64)-left) {
- /*
- * The hw event starts counting from this event offset,
- * mark it to be able to extra future deltas:
- */
- local64_set(&hwc->prev_count, (u64)-left);
-
- wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
- }
-
- /*
- * Due to erratum on certan cpu we need
- * a second write to be sure the register
- * is updated properly
- */
- if (x86_pmu.perfctr_second_write) {
- wrmsrl(hwc->event_base,
- (u64)(-left) & x86_pmu.cntval_mask);
- }
-
- perf_event_update_userpage(event);
-
- return ret;
-}
-
-void x86_pmu_enable_event(struct perf_event *event)
-{
- if (__this_cpu_read(cpu_hw_events.enabled))
- __x86_pmu_enable_event(&event->hw,
- ARCH_PERFMON_EVENTSEL_ENABLE);
-}
-
-/*
- * Add a single event to the PMU.
- *
- * The event is added to the group of enabled events
- * but only if it can be scehduled with existing events.
- */
-static int x86_pmu_add(struct perf_event *event, int flags)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct hw_perf_event *hwc;
- int assign[X86_PMC_IDX_MAX];
- int n, n0, ret;
-
- hwc = &event->hw;
-
- n0 = cpuc->n_events;
- ret = n = collect_events(cpuc, event, false);
- if (ret < 0)
- goto out;
-
- hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
- if (!(flags & PERF_EF_START))
- hwc->state |= PERF_HES_ARCH;
-
- /*
- * If group events scheduling transaction was started,
- * skip the schedulability test here, it will be performed
- * at commit time (->commit_txn) as a whole.
- */
- if (cpuc->group_flag & PERF_EVENT_TXN)
- goto done_collect;
-
- ret = x86_pmu.schedule_events(cpuc, n, assign);
- if (ret)
- goto out;
- /*
- * copy new assignment, now we know it is possible
- * will be used by hw_perf_enable()
- */
- memcpy(cpuc->assign, assign, n*sizeof(int));
-
-done_collect:
- /*
- * Commit the collect_events() state. See x86_pmu_del() and
- * x86_pmu_*_txn().
- */
- cpuc->n_events = n;
- cpuc->n_added += n - n0;
- cpuc->n_txn += n - n0;
-
- ret = 0;
-out:
- return ret;
-}
-
-static void x86_pmu_start(struct perf_event *event, int flags)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx = event->hw.idx;
-
- if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
- return;
-
- if (WARN_ON_ONCE(idx == -1))
- return;
-
- if (flags & PERF_EF_RELOAD) {
- WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
- x86_perf_event_set_period(event);
- }
-
- event->hw.state = 0;
-
- cpuc->events[idx] = event;
- __set_bit(idx, cpuc->active_mask);
- __set_bit(idx, cpuc->running);
- x86_pmu.enable(event);
- perf_event_update_userpage(event);
-}
-
-void perf_event_print_debug(void)
-{
- u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
- u64 pebs, debugctl;
- struct cpu_hw_events *cpuc;
- unsigned long flags;
- int cpu, idx;
-
- if (!x86_pmu.num_counters)
- return;
-
- local_irq_save(flags);
-
- cpu = smp_processor_id();
- cpuc = &per_cpu(cpu_hw_events, cpu);
-
- if (x86_pmu.version >= 2) {
- rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
- rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
- rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
- rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
-
- pr_info("\n");
- pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl);
- pr_info("CPU#%d: status: %016llx\n", cpu, status);
- pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow);
- pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed);
- if (x86_pmu.pebs_constraints) {
- rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
- pr_info("CPU#%d: pebs: %016llx\n", cpu, pebs);
- }
- if (x86_pmu.lbr_nr) {
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
- pr_info("CPU#%d: debugctl: %016llx\n", cpu, debugctl);
- }
- }
- pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
- rdmsrl(x86_pmu_event_addr(idx), pmc_count);
-
- prev_left = per_cpu(pmc_prev_left[idx], cpu);
-
- pr_info("CPU#%d: gen-PMC%d ctrl: %016llx\n",
- cpu, idx, pmc_ctrl);
- pr_info("CPU#%d: gen-PMC%d count: %016llx\n",
- cpu, idx, pmc_count);
- pr_info("CPU#%d: gen-PMC%d left: %016llx\n",
- cpu, idx, prev_left);
- }
- for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
- rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
-
- pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
- cpu, idx, pmc_count);
- }
- local_irq_restore(flags);
-}
-
-void x86_pmu_stop(struct perf_event *event, int flags)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
-
- if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) {
- x86_pmu.disable(event);
- cpuc->events[hwc->idx] = NULL;
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
- }
-
- if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
- /*
- * Drain the remaining delta count out of a event
- * that we are disabling:
- */
- x86_perf_event_update(event);
- hwc->state |= PERF_HES_UPTODATE;
- }
-}
-
-static void x86_pmu_del(struct perf_event *event, int flags)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int i;
-
- /*
- * event is descheduled
- */
- event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
-
- /*
- * If we're called during a txn, we don't need to do anything.
- * The events never got scheduled and ->cancel_txn will truncate
- * the event_list.
- *
- * XXX assumes any ->del() called during a TXN will only be on
- * an event added during that same TXN.
- */
- if (cpuc->group_flag & PERF_EVENT_TXN)
- return;
-
- /*
- * Not a TXN, therefore cleanup properly.
- */
- x86_pmu_stop(event, PERF_EF_UPDATE);
-
- for (i = 0; i < cpuc->n_events; i++) {
- if (event == cpuc->event_list[i])
- break;
- }
-
- if (WARN_ON_ONCE(i == cpuc->n_events)) /* called ->del() without ->add() ? */
- return;
-
- /* If we have a newly added event; make sure to decrease n_added. */
- if (i >= cpuc->n_events - cpuc->n_added)
- --cpuc->n_added;
-
- if (x86_pmu.put_event_constraints)
- x86_pmu.put_event_constraints(cpuc, event);
-
- /* Delete the array entry. */
- while (++i < cpuc->n_events) {
- cpuc->event_list[i-1] = cpuc->event_list[i];
- cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
- }
- --cpuc->n_events;
-
- perf_event_update_userpage(event);
-}
-
-int x86_pmu_handle_irq(struct pt_regs *regs)
-{
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct perf_event *event;
- int idx, handled = 0;
- u64 val;
-
- cpuc = this_cpu_ptr(&cpu_hw_events);
-
- /*
- * Some chipsets need to unmask the LVTPC in a particular spot
- * inside the nmi handler. As a result, the unmasking was pushed
- * into all the nmi handlers.
- *
- * This generic handler doesn't seem to have any issues where the
- * unmasking occurs so it was left at the top.
- */
- apic_write(APIC_LVTPC, APIC_DM_NMI);
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- if (!test_bit(idx, cpuc->active_mask)) {
- /*
- * Though we deactivated the counter some cpus
- * might still deliver spurious interrupts still
- * in flight. Catch them:
- */
- if (__test_and_clear_bit(idx, cpuc->running))
- handled++;
- continue;
- }
-
- event = cpuc->events[idx];
-
- val = x86_perf_event_update(event);
- if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
- continue;
-
- /*
- * event overflow
- */
- handled++;
- perf_sample_data_init(&data, 0, event->hw.last_period);
-
- if (!x86_perf_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- x86_pmu_stop(event, 0);
- }
-
- if (handled)
- inc_irq_stat(apic_perf_irqs);
-
- return handled;
-}
-
-void perf_events_lapic_init(void)
-{
- if (!x86_pmu.apic || !x86_pmu_initialized())
- return;
-
- /*
- * Always use NMI for PMU
- */
- apic_write(APIC_LVTPC, APIC_DM_NMI);
-}
-
-static int
-perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
-{
- u64 start_clock;
- u64 finish_clock;
- int ret;
-
- /*
- * All PMUs/events that share this PMI handler should make sure to
- * increment active_events for their events.
- */
- if (!atomic_read(&active_events))
- return NMI_DONE;
-
- start_clock = sched_clock();
- ret = x86_pmu.handle_irq(regs);
- finish_clock = sched_clock();
-
- perf_sample_event_took(finish_clock - start_clock);
-
- return ret;
-}
-NOKPROBE_SYMBOL(perf_event_nmi_handler);
-
-struct event_constraint emptyconstraint;
-struct event_constraint unconstrained;
-
-static int
-x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
- unsigned int cpu = (long)hcpu;
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- int i, ret = NOTIFY_OK;
-
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_UP_PREPARE:
- for (i = 0 ; i < X86_PERF_KFREE_MAX; i++)
- cpuc->kfree_on_online[i] = NULL;
- if (x86_pmu.cpu_prepare)
- ret = x86_pmu.cpu_prepare(cpu);
- break;
-
- case CPU_STARTING:
- if (x86_pmu.cpu_starting)
- x86_pmu.cpu_starting(cpu);
- break;
-
- case CPU_ONLINE:
- for (i = 0 ; i < X86_PERF_KFREE_MAX; i++) {
- kfree(cpuc->kfree_on_online[i]);
- cpuc->kfree_on_online[i] = NULL;
- }
- break;
-
- case CPU_DYING:
- if (x86_pmu.cpu_dying)
- x86_pmu.cpu_dying(cpu);
- break;
-
- case CPU_UP_CANCELED:
- case CPU_DEAD:
- if (x86_pmu.cpu_dead)
- x86_pmu.cpu_dead(cpu);
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-static void __init pmu_check_apic(void)
-{
- if (cpu_has_apic)
- return;
-
- x86_pmu.apic = 0;
- pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
- pr_info("no hardware sampling interrupt available.\n");
-
- /*
- * If we have a PMU initialized but no APIC
- * interrupts, we cannot sample hardware
- * events (user-space has to fall back and
- * sample via a hrtimer based software event):
- */
- pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
-
-}
-
-static struct attribute_group x86_pmu_format_group = {
- .name = "format",
- .attrs = NULL,
-};
-
-/*
- * Remove all undefined events (x86_pmu.event_map(id) == 0)
- * out of events_attr attributes.
- */
-static void __init filter_events(struct attribute **attrs)
-{
- struct device_attribute *d;
- struct perf_pmu_events_attr *pmu_attr;
- int i, j;
-
- for (i = 0; attrs[i]; i++) {
- d = (struct device_attribute *)attrs[i];
- pmu_attr = container_of(d, struct perf_pmu_events_attr, attr);
- /* str trumps id */
- if (pmu_attr->event_str)
- continue;
- if (x86_pmu.event_map(i))
- continue;
-
- for (j = i; attrs[j]; j++)
- attrs[j] = attrs[j + 1];
-
- /* Check the shifted attr. */
- i--;
- }
-}
-
-/* Merge two pointer arrays */
-__init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
-{
- struct attribute **new;
- int j, i;
-
- for (j = 0; a[j]; j++)
- ;
- for (i = 0; b[i]; i++)
- j++;
- j++;
-
- new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL);
- if (!new)
- return NULL;
-
- j = 0;
- for (i = 0; a[i]; i++)
- new[j++] = a[i];
- for (i = 0; b[i]; i++)
- new[j++] = b[i];
- new[j] = NULL;
-
- return new;
-}
-
-ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
- char *page)
-{
- struct perf_pmu_events_attr *pmu_attr = \
- container_of(attr, struct perf_pmu_events_attr, attr);
- u64 config = x86_pmu.event_map(pmu_attr->id);
-
- /* string trumps id */
- if (pmu_attr->event_str)
- return sprintf(page, "%s", pmu_attr->event_str);
-
- return x86_pmu.events_sysfs_show(page, config);
-}
-
-EVENT_ATTR(cpu-cycles, CPU_CYCLES );
-EVENT_ATTR(instructions, INSTRUCTIONS );
-EVENT_ATTR(cache-references, CACHE_REFERENCES );
-EVENT_ATTR(cache-misses, CACHE_MISSES );
-EVENT_ATTR(branch-instructions, BRANCH_INSTRUCTIONS );
-EVENT_ATTR(branch-misses, BRANCH_MISSES );
-EVENT_ATTR(bus-cycles, BUS_CYCLES );
-EVENT_ATTR(stalled-cycles-frontend, STALLED_CYCLES_FRONTEND );
-EVENT_ATTR(stalled-cycles-backend, STALLED_CYCLES_BACKEND );
-EVENT_ATTR(ref-cycles, REF_CPU_CYCLES );
-
-static struct attribute *empty_attrs;
-
-static struct attribute *events_attr[] = {
- EVENT_PTR(CPU_CYCLES),
- EVENT_PTR(INSTRUCTIONS),
- EVENT_PTR(CACHE_REFERENCES),
- EVENT_PTR(CACHE_MISSES),
- EVENT_PTR(BRANCH_INSTRUCTIONS),
- EVENT_PTR(BRANCH_MISSES),
- EVENT_PTR(BUS_CYCLES),
- EVENT_PTR(STALLED_CYCLES_FRONTEND),
- EVENT_PTR(STALLED_CYCLES_BACKEND),
- EVENT_PTR(REF_CPU_CYCLES),
- NULL,
-};
-
-static struct attribute_group x86_pmu_events_group = {
- .name = "events",
- .attrs = events_attr,
-};
-
-ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
-{
- u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
- u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
- bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE);
- bool pc = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL);
- bool any = (config & ARCH_PERFMON_EVENTSEL_ANY);
- bool inv = (config & ARCH_PERFMON_EVENTSEL_INV);
- ssize_t ret;
-
- /*
- * We have whole page size to spend and just little data
- * to write, so we can safely use sprintf.
- */
- ret = sprintf(page, "event=0x%02llx", event);
-
- if (umask)
- ret += sprintf(page + ret, ",umask=0x%02llx", umask);
-
- if (edge)
- ret += sprintf(page + ret, ",edge");
-
- if (pc)
- ret += sprintf(page + ret, ",pc");
-
- if (any)
- ret += sprintf(page + ret, ",any");
-
- if (inv)
- ret += sprintf(page + ret, ",inv");
-
- if (cmask)
- ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
-
- ret += sprintf(page + ret, "\n");
-
- return ret;
-}
-
-static int __init init_hw_perf_events(void)
-{
- struct x86_pmu_quirk *quirk;
- int err;
-
- pr_info("Performance Events: ");
-
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- err = intel_pmu_init();
- break;
- case X86_VENDOR_AMD:
- err = amd_pmu_init();
- break;
- default:
- err = -ENOTSUPP;
- }
- if (err != 0) {
- pr_cont("no PMU driver, software events only.\n");
- return 0;
- }
-
- pmu_check_apic();
-
- /* sanity check that the hardware exists or is emulated */
- if (!check_hw_exists())
- return 0;
-
- pr_cont("%s PMU driver.\n", x86_pmu.name);
-
- x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
-
- for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)
- quirk->func();
-
- if (!x86_pmu.intel_ctrl)
- x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
-
- perf_events_lapic_init();
- register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
-
- unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
- 0, x86_pmu.num_counters, 0, 0);
-
- x86_pmu_format_group.attrs = x86_pmu.format_attrs;
-
- if (x86_pmu.event_attrs)
- x86_pmu_events_group.attrs = x86_pmu.event_attrs;
-
- if (!x86_pmu.events_sysfs_show)
- x86_pmu_events_group.attrs = &empty_attrs;
- else
- filter_events(x86_pmu_events_group.attrs);
-
- if (x86_pmu.cpu_events) {
- struct attribute **tmp;
-
- tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
- if (!WARN_ON(!tmp))
- x86_pmu_events_group.attrs = tmp;
- }
-
- pr_info("... version: %d\n", x86_pmu.version);
- pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
- pr_info("... generic registers: %d\n", x86_pmu.num_counters);
- pr_info("... value mask: %016Lx\n", x86_pmu.cntval_mask);
- pr_info("... max period: %016Lx\n", x86_pmu.max_period);
- pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed);
- pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl);
-
- perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
- perf_cpu_notifier(x86_pmu_notifier);
-
- return 0;
-}
-early_initcall(init_hw_perf_events);
-
-static inline void x86_pmu_read(struct perf_event *event)
-{
- x86_perf_event_update(event);
-}
-
-/*
- * Start group events scheduling transaction
- * Set the flag to make pmu::enable() not perform the
- * schedulability test, it will be performed at commit time
- */
-static void x86_pmu_start_txn(struct pmu *pmu)
-{
- perf_pmu_disable(pmu);
- __this_cpu_or(cpu_hw_events.group_flag, PERF_EVENT_TXN);
- __this_cpu_write(cpu_hw_events.n_txn, 0);
-}
-
-/*
- * Stop group events scheduling transaction
- * Clear the flag and pmu::enable() will perform the
- * schedulability test.
- */
-static void x86_pmu_cancel_txn(struct pmu *pmu)
-{
- __this_cpu_and(cpu_hw_events.group_flag, ~PERF_EVENT_TXN);
- /*
- * Truncate collected array by the number of events added in this
- * transaction. See x86_pmu_add() and x86_pmu_*_txn().
- */
- __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn));
- __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn));
- perf_pmu_enable(pmu);
-}
-
-/*
- * Commit group events scheduling transaction
- * Perform the group schedulability test as a whole
- * Return 0 if success
- *
- * Does not cancel the transaction on failure; expects the caller to do this.
- */
-static int x86_pmu_commit_txn(struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int assign[X86_PMC_IDX_MAX];
- int n, ret;
-
- n = cpuc->n_events;
-
- if (!x86_pmu_initialized())
- return -EAGAIN;
-
- ret = x86_pmu.schedule_events(cpuc, n, assign);
- if (ret)
- return ret;
-
- /*
- * copy new assignment, now we know it is possible
- * will be used by hw_perf_enable()
- */
- memcpy(cpuc->assign, assign, n*sizeof(int));
-
- cpuc->group_flag &= ~PERF_EVENT_TXN;
- perf_pmu_enable(pmu);
- return 0;
-}
-/*
- * a fake_cpuc is used to validate event groups. Due to
- * the extra reg logic, we need to also allocate a fake
- * per_core and per_cpu structure. Otherwise, group events
- * using extra reg may conflict without the kernel being
- * able to catch this when the last event gets added to
- * the group.
- */
-static void free_fake_cpuc(struct cpu_hw_events *cpuc)
-{
- kfree(cpuc->shared_regs);
- kfree(cpuc);
-}
-
-static struct cpu_hw_events *allocate_fake_cpuc(void)
-{
- struct cpu_hw_events *cpuc;
- int cpu = raw_smp_processor_id();
-
- cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL);
- if (!cpuc)
- return ERR_PTR(-ENOMEM);
-
- /* only needed, if we have extra_regs */
- if (x86_pmu.extra_regs) {
- cpuc->shared_regs = allocate_shared_regs(cpu);
- if (!cpuc->shared_regs)
- goto error;
- }
- cpuc->is_fake = 1;
- return cpuc;
-error:
- free_fake_cpuc(cpuc);
- return ERR_PTR(-ENOMEM);
-}
-
-/*
- * validate that we can schedule this event
- */
-static int validate_event(struct perf_event *event)
-{
- struct cpu_hw_events *fake_cpuc;
- struct event_constraint *c;
- int ret = 0;
-
- fake_cpuc = allocate_fake_cpuc();
- if (IS_ERR(fake_cpuc))
- return PTR_ERR(fake_cpuc);
-
- c = x86_pmu.get_event_constraints(fake_cpuc, -1, event);
-
- if (!c || !c->weight)
- ret = -EINVAL;
-
- if (x86_pmu.put_event_constraints)
- x86_pmu.put_event_constraints(fake_cpuc, event);
-
- free_fake_cpuc(fake_cpuc);
-
- return ret;
-}
-
-/*
- * validate a single event group
- *
- * validation include:
- * - check events are compatible which each other
- * - events do not compete for the same counter
- * - number of events <= number of counters
- *
- * validation ensures the group can be loaded onto the
- * PMU if it was the only group available.
- */
-static int validate_group(struct perf_event *event)
-{
- struct perf_event *leader = event->group_leader;
- struct cpu_hw_events *fake_cpuc;
- int ret = -EINVAL, n;
-
- fake_cpuc = allocate_fake_cpuc();
- if (IS_ERR(fake_cpuc))
- return PTR_ERR(fake_cpuc);
- /*
- * the event is not yet connected with its
- * siblings therefore we must first collect
- * existing siblings, then add the new event
- * before we can simulate the scheduling
- */
- n = collect_events(fake_cpuc, leader, true);
- if (n < 0)
- goto out;
-
- fake_cpuc->n_events = n;
- n = collect_events(fake_cpuc, event, false);
- if (n < 0)
- goto out;
-
- fake_cpuc->n_events = n;
-
- ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
-
-out:
- free_fake_cpuc(fake_cpuc);
- return ret;
-}
-
-static int x86_pmu_event_init(struct perf_event *event)
-{
- struct pmu *tmp;
- int err;
-
- switch (event->attr.type) {
- case PERF_TYPE_RAW:
- case PERF_TYPE_HARDWARE:
- case PERF_TYPE_HW_CACHE:
- break;
-
- default:
- return -ENOENT;
- }
-
- err = __x86_pmu_event_init(event);
- if (!err) {
- /*
- * we temporarily connect event to its pmu
- * such that validate_group() can classify
- * it as an x86 event using is_x86_event()
- */
- tmp = event->pmu;
- event->pmu = &pmu;
-
- if (event->group_leader != event)
- err = validate_group(event);
- else
- err = validate_event(event);
-
- event->pmu = tmp;
- }
- if (err) {
- if (event->destroy)
- event->destroy(event);
- }
-
- if (ACCESS_ONCE(x86_pmu.attr_rdpmc))
- event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
-
- return err;
-}
-
-static void refresh_pce(void *ignored)
-{
- if (current->mm)
- load_mm_cr4(current->mm);
-}
-
-static void x86_pmu_event_mapped(struct perf_event *event)
-{
- if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
- return;
-
- if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
- on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
-}
-
-static void x86_pmu_event_unmapped(struct perf_event *event)
-{
- if (!current->mm)
- return;
-
- if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
- return;
-
- if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
- on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
-}
-
-static int x86_pmu_event_idx(struct perf_event *event)
-{
- int idx = event->hw.idx;
-
- if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
- return 0;
-
- if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
- idx -= INTEL_PMC_IDX_FIXED;
- idx |= 1 << 30;
- }
-
- return idx + 1;
-}
-
-static ssize_t get_attr_rdpmc(struct device *cdev,
- struct device_attribute *attr,
- char *buf)
-{
- return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
-}
-
-static ssize_t set_attr_rdpmc(struct device *cdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned long val;
- ssize_t ret;
-
- ret = kstrtoul(buf, 0, &val);
- if (ret)
- return ret;
-
- if (val > 2)
- return -EINVAL;
-
- if (x86_pmu.attr_rdpmc_broken)
- return -ENOTSUPP;
-
- if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) {
- /*
- * Changing into or out of always available, aka
- * perf-event-bypassing mode. This path is extremely slow,
- * but only root can trigger it, so it's okay.
- */
- if (val == 2)
- static_key_slow_inc(&rdpmc_always_available);
- else
- static_key_slow_dec(&rdpmc_always_available);
- on_each_cpu(refresh_pce, NULL, 1);
- }
-
- x86_pmu.attr_rdpmc = val;
-
- return count;
-}
-
-static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
-
-static struct attribute *x86_pmu_attrs[] = {
- &dev_attr_rdpmc.attr,
- NULL,
-};
-
-static struct attribute_group x86_pmu_attr_group = {
- .attrs = x86_pmu_attrs,
-};
-
-static const struct attribute_group *x86_pmu_attr_groups[] = {
- &x86_pmu_attr_group,
- &x86_pmu_format_group,
- &x86_pmu_events_group,
- NULL,
-};
-
-static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
- if (x86_pmu.sched_task)
- x86_pmu.sched_task(ctx, sched_in);
-}
-
-void perf_check_microcode(void)
-{
- if (x86_pmu.check_microcode)
- x86_pmu.check_microcode();
-}
-EXPORT_SYMBOL_GPL(perf_check_microcode);
-
-static struct pmu pmu = {
- .pmu_enable = x86_pmu_enable,
- .pmu_disable = x86_pmu_disable,
-
- .attr_groups = x86_pmu_attr_groups,
-
- .event_init = x86_pmu_event_init,
-
- .event_mapped = x86_pmu_event_mapped,
- .event_unmapped = x86_pmu_event_unmapped,
-
- .add = x86_pmu_add,
- .del = x86_pmu_del,
- .start = x86_pmu_start,
- .stop = x86_pmu_stop,
- .read = x86_pmu_read,
-
- .start_txn = x86_pmu_start_txn,
- .cancel_txn = x86_pmu_cancel_txn,
- .commit_txn = x86_pmu_commit_txn,
-
- .event_idx = x86_pmu_event_idx,
- .sched_task = x86_pmu_sched_task,
- .task_ctx_size = sizeof(struct x86_perf_task_context),
-};
-
-void arch_perf_update_userpage(struct perf_event *event,
- struct perf_event_mmap_page *userpg, u64 now)
-{
- struct cyc2ns_data *data;
-
- userpg->cap_user_time = 0;
- userpg->cap_user_time_zero = 0;
- userpg->cap_user_rdpmc =
- !!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
- userpg->pmc_width = x86_pmu.cntval_bits;
-
- if (!sched_clock_stable())
- return;
-
- data = cyc2ns_read_begin();
-
- /*
- * Internal timekeeping for enabled/running/stopped times
- * is always in the local_clock domain.
- */
- userpg->cap_user_time = 1;
- userpg->time_mult = data->cyc2ns_mul;
- userpg->time_shift = data->cyc2ns_shift;
- userpg->time_offset = data->cyc2ns_offset - now;
-
- /*
- * cap_user_time_zero doesn't make sense when we're using a different
- * time base for the records.
- */
- if (event->clock == &local_clock) {
- userpg->cap_user_time_zero = 1;
- userpg->time_zero = data->cyc2ns_offset;
- }
-
- cyc2ns_read_end(data);
-}
-
-/*
- * callchain support
- */
-
-static int backtrace_stack(void *data, char *name)
-{
- return 0;
-}
-
-static void backtrace_address(void *data, unsigned long addr, int reliable)
-{
- struct perf_callchain_entry *entry = data;
-
- perf_callchain_store(entry, addr);
-}
-
-static const struct stacktrace_ops backtrace_ops = {
- .stack = backtrace_stack,
- .address = backtrace_address,
- .walk_stack = print_context_stack_bp,
-};
-
-void
-perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
-{
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
- /* TODO: We don't support guest os callchain now */
- return;
- }
-
- perf_callchain_store(entry, regs->ip);
-
- dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
-}
-
-static inline int
-valid_user_frame(const void __user *fp, unsigned long size)
-{
- return (__range_not_ok(fp, size, TASK_SIZE) == 0);
-}
-
-static unsigned long get_segment_base(unsigned int segment)
-{
- struct desc_struct *desc;
- int idx = segment >> 3;
-
- if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
-#ifdef CONFIG_MODIFY_LDT_SYSCALL
- struct ldt_struct *ldt;
-
- if (idx > LDT_ENTRIES)
- return 0;
-
- /* IRQs are off, so this synchronizes with smp_store_release */
- ldt = lockless_dereference(current->active_mm->context.ldt);
- if (!ldt || idx > ldt->size)
- return 0;
-
- desc = &ldt->entries[idx];
-#else
- return 0;
-#endif
- } else {
- if (idx > GDT_ENTRIES)
- return 0;
-
- desc = raw_cpu_ptr(gdt_page.gdt) + idx;
- }
-
- return get_desc_base(desc);
-}
-
-#ifdef CONFIG_IA32_EMULATION
-
-#include <asm/compat.h>
-
-static inline int
-perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
- /* 32-bit process in 64-bit kernel. */
- unsigned long ss_base, cs_base;
- struct stack_frame_ia32 frame;
- const void __user *fp;
-
- if (!test_thread_flag(TIF_IA32))
- return 0;
-
- cs_base = get_segment_base(regs->cs);
- ss_base = get_segment_base(regs->ss);
-
- fp = compat_ptr(ss_base + regs->bp);
- while (entry->nr < PERF_MAX_STACK_DEPTH) {
- unsigned long bytes;
- frame.next_frame = 0;
- frame.return_address = 0;
-
- bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
- if (bytes != 0)
- break;
-
- if (!valid_user_frame(fp, sizeof(frame)))
- break;
-
- perf_callchain_store(entry, cs_base + frame.return_address);
- fp = compat_ptr(ss_base + frame.next_frame);
- }
- return 1;
-}
-#else
-static inline int
-perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
- return 0;
-}
-#endif
-
-void
-perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
-{
- struct stack_frame frame;
- const void __user *fp;
-
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
- /* TODO: We don't support guest os callchain now */
- return;
- }
-
- /*
- * We don't know what to do with VM86 stacks.. ignore them for now.
- */
- if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
- return;
-
- fp = (void __user *)regs->bp;
-
- perf_callchain_store(entry, regs->ip);
-
- if (!current->mm)
- return;
-
- if (perf_callchain_user32(regs, entry))
- return;
-
- while (entry->nr < PERF_MAX_STACK_DEPTH) {
- unsigned long bytes;
- frame.next_frame = NULL;
- frame.return_address = 0;
-
- bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
- if (bytes != 0)
- break;
-
- if (!valid_user_frame(fp, sizeof(frame)))
- break;
-
- perf_callchain_store(entry, frame.return_address);
- fp = frame.next_frame;
- }
-}
-
-/*
- * Deal with code segment offsets for the various execution modes:
- *
- * VM86 - the good olde 16 bit days, where the linear address is
- * 20 bits and we use regs->ip + 0x10 * regs->cs.
- *
- * IA32 - Where we need to look at GDT/LDT segment descriptor tables
- * to figure out what the 32bit base address is.
- *
- * X32 - has TIF_X32 set, but is running in x86_64
- *
- * X86_64 - CS,DS,SS,ES are all zero based.
- */
-static unsigned long code_segment_base(struct pt_regs *regs)
-{
- /*
- * For IA32 we look at the GDT/LDT segment base to convert the
- * effective IP to a linear address.
- */
-
-#ifdef CONFIG_X86_32
- /*
- * If we are in VM86 mode, add the segment offset to convert to a
- * linear address.
- */
- if (regs->flags & X86_VM_MASK)
- return 0x10 * regs->cs;
-
- if (user_mode(regs) && regs->cs != __USER_CS)
- return get_segment_base(regs->cs);
-#else
- if (user_mode(regs) && !user_64bit_mode(regs) &&
- regs->cs != __USER32_CS)
- return get_segment_base(regs->cs);
-#endif
- return 0;
-}
-
-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 regs->ip + code_segment_base(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;
- }
-
- if (regs->flags & PERF_EFLAGS_EXACT)
- misc |= PERF_RECORD_MISC_EXACT_IP;
-
- return misc;
-}
-
-void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
-{
- cap->version = x86_pmu.version;
- cap->num_counters_gp = x86_pmu.num_counters;
- cap->num_counters_fixed = x86_pmu.num_counters_fixed;
- cap->bit_width_gp = x86_pmu.cntval_bits;
- cap->bit_width_fixed = x86_pmu.cntval_bits;
- cap->events_mask = (unsigned int)x86_pmu.events_maskl;
- cap->events_mask_len = x86_pmu.events_mask_len;
-}
-EXPORT_SYMBOL_GPL(perf_get_x86_pmu_capability);
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
deleted file mode 100644
index 165be83..0000000
--- a/arch/x86/kernel/cpu/perf_event.h
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Performance events x86 architecture header
- *
- * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- * Copyright (C) 2009 Jaswinder Singh Rajput
- * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
- * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
- * Copyright (C) 2009 Google, Inc., Stephane Eranian
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) \
-do { \
- unsigned int _msr = (msr); \
- u64 _val = (val); \
- trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \
- (unsigned long long)(_val)); \
- native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \
-} while (0)
-#endif
-
-/*
- * | NHM/WSM | SNB |
- * register -------------------------------
- * | HT | no HT | HT | no HT |
- *-----------------------------------------
- * offcore | core | core | cpu | core |
- * lbr_sel | core | core | cpu | core |
- * ld_lat | cpu | core | cpu | core |
- *-----------------------------------------
- *
- * Given that there is a small number of shared regs,
- * we can pre-allocate their slot in the per-cpu
- * per-core reg tables.
- */
-enum extra_reg_type {
- EXTRA_REG_NONE = -1, /* not used */
-
- EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */
- EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */
- EXTRA_REG_LBR = 2, /* lbr_select */
- EXTRA_REG_LDLAT = 3, /* ld_lat_threshold */
- EXTRA_REG_FE = 4, /* fe_* */
-
- EXTRA_REG_MAX /* number of entries needed */
-};
-
-struct event_constraint {
- union {
- unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- u64 idxmsk64;
- };
- u64 code;
- u64 cmask;
- int weight;
- int overlap;
- int flags;
-};
-/*
- * struct hw_perf_event.flags flags
- */
-#define PERF_X86_EVENT_PEBS_LDLAT 0x0001 /* ld+ldlat data address sampling */
-#define PERF_X86_EVENT_PEBS_ST 0x0002 /* st data address sampling */
-#define PERF_X86_EVENT_PEBS_ST_HSW 0x0004 /* haswell style datala, store */
-#define PERF_X86_EVENT_COMMITTED 0x0008 /* event passed commit_txn */
-#define PERF_X86_EVENT_PEBS_LD_HSW 0x0010 /* haswell style datala, load */
-#define PERF_X86_EVENT_PEBS_NA_HSW 0x0020 /* haswell style datala, unknown */
-#define PERF_X86_EVENT_EXCL 0x0040 /* HT exclusivity on counter */
-#define PERF_X86_EVENT_DYNAMIC 0x0080 /* dynamic alloc'd constraint */
-#define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */
-#define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */
-#define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */
-#define PERF_X86_EVENT_FREERUNNING 0x0800 /* use freerunning PEBS */
-
-
-struct amd_nb {
- int nb_id; /* NorthBridge id */
- int refcnt; /* reference count */
- struct perf_event *owners[X86_PMC_IDX_MAX];
- struct event_constraint event_constraints[X86_PMC_IDX_MAX];
-};
-
-/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS 8
-
-/*
- * Flags PEBS can handle without an PMI.
- *
- * TID can only be handled by flushing at context switch.
- *
- */
-#define PEBS_FREERUNNING_FLAGS \
- (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
- PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
- PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
- PERF_SAMPLE_TRANSACTION)
-
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
- u64 bts_buffer_base;
- u64 bts_index;
- u64 bts_absolute_maximum;
- u64 bts_interrupt_threshold;
- u64 pebs_buffer_base;
- u64 pebs_index;
- u64 pebs_absolute_maximum;
- u64 pebs_interrupt_threshold;
- u64 pebs_event_reset[MAX_PEBS_EVENTS];
-};
-
-/*
- * Per register state.
- */
-struct er_account {
- raw_spinlock_t lock; /* per-core: protect structure */
- u64 config; /* extra MSR config */
- u64 reg; /* extra MSR number */
- atomic_t ref; /* reference count */
-};
-
-/*
- * Per core/cpu state
- *
- * Used to coordinate shared registers between HT threads or
- * among events on a single PMU.
- */
-struct intel_shared_regs {
- struct er_account regs[EXTRA_REG_MAX];
- int refcnt; /* per-core: #HT threads */
- unsigned core_id; /* per-core: core id */
-};
-
-enum intel_excl_state_type {
- INTEL_EXCL_UNUSED = 0, /* counter is unused */
- INTEL_EXCL_SHARED = 1, /* counter can be used by both threads */
- INTEL_EXCL_EXCLUSIVE = 2, /* counter can be used by one thread only */
-};
-
-struct intel_excl_states {
- enum intel_excl_state_type state[X86_PMC_IDX_MAX];
- bool sched_started; /* true if scheduling has started */
-};
-
-struct intel_excl_cntrs {
- raw_spinlock_t lock;
-
- struct intel_excl_states states[2];
-
- union {
- u16 has_exclusive[2];
- u32 exclusive_present;
- };
-
- int refcnt; /* per-core: #HT threads */
- unsigned core_id; /* per-core: core id */
-};
-
-#define MAX_LBR_ENTRIES 32
-
-enum {
- X86_PERF_KFREE_SHARED = 0,
- X86_PERF_KFREE_EXCL = 1,
- X86_PERF_KFREE_MAX
-};
-
-struct cpu_hw_events {
- /*
- * Generic x86 PMC bits
- */
- struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
- unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- int enabled;
-
- int n_events; /* the # of events in the below arrays */
- int n_added; /* the # last events in the below arrays;
- they've never been enabled yet */
- int n_txn; /* the # last events in the below arrays;
- added in the current transaction */
- int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
- u64 tags[X86_PMC_IDX_MAX];
-
- struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
- struct event_constraint *event_constraint[X86_PMC_IDX_MAX];
-
- int n_excl; /* the number of exclusive events */
-
- unsigned int group_flag;
- int is_fake;
-
- /*
- * Intel DebugStore bits
- */
- struct debug_store *ds;
- u64 pebs_enabled;
-
- /*
- * Intel LBR bits
- */
- int lbr_users;
- void *lbr_context;
- struct perf_branch_stack lbr_stack;
- struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
- struct er_account *lbr_sel;
- u64 br_sel;
-
- /*
- * Intel host/guest exclude bits
- */
- u64 intel_ctrl_guest_mask;
- u64 intel_ctrl_host_mask;
- struct perf_guest_switch_msr guest_switch_msrs[X86_PMC_IDX_MAX];
-
- /*
- * Intel checkpoint mask
- */
- u64 intel_cp_status;
-
- /*
- * manage shared (per-core, per-cpu) registers
- * used on Intel NHM/WSM/SNB
- */
- struct intel_shared_regs *shared_regs;
- /*
- * manage exclusive counter access between hyperthread
- */
- struct event_constraint *constraint_list; /* in enable order */
- struct intel_excl_cntrs *excl_cntrs;
- int excl_thread_id; /* 0 or 1 */
-
- /*
- * AMD specific bits
- */
- struct amd_nb *amd_nb;
- /* Inverted mask of bits to clear in the perf_ctr ctrl registers */
- u64 perf_ctr_virt_mask;
-
- void *kfree_on_online[X86_PERF_KFREE_MAX];
-};
-
-#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
- { .idxmsk64 = (n) }, \
- .code = (c), \
- .cmask = (m), \
- .weight = (w), \
- .overlap = (o), \
- .flags = f, \
-}
-
-#define EVENT_CONSTRAINT(c, n, m) \
- __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
-
-#define INTEL_EXCLEVT_CONSTRAINT(c, n) \
- __EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT, HWEIGHT(n),\
- 0, PERF_X86_EVENT_EXCL)
-
-/*
- * The overlap flag marks event constraints with overlapping counter
- * masks. This is the case if the counter mask of such an event is not
- * a subset of any other counter mask of a constraint with an equal or
- * higher weight, e.g.:
- *
- * c_overlaps = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
- * c_another1 = EVENT_CONSTRAINT(0, 0x07, 0);
- * c_another2 = EVENT_CONSTRAINT(0, 0x38, 0);
- *
- * The event scheduler may not select the correct counter in the first
- * cycle because it needs to know which subsequent events will be
- * scheduled. It may fail to schedule the events then. So we set the
- * overlap flag for such constraints to give the scheduler a hint which
- * events to select for counter rescheduling.
- *
- * Care must be taken as the rescheduling algorithm is O(n!) which
- * will increase scheduling cycles for an over-commited system
- * dramatically. The number of such EVENT_CONSTRAINT_OVERLAP() macros
- * and its counter masks must be kept at a minimum.
- */
-#define EVENT_CONSTRAINT_OVERLAP(c, n, m) \
- __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)
-
-/*
- * Constraint on the Event code.
- */
-#define INTEL_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
-
-/*
- * Constraint on the Event code + UMask + fixed-mask
- *
- * filter mask to validate fixed counter events.
- * the following filters disqualify for fixed counters:
- * - inv
- * - edge
- * - cnt-mask
- * - in_tx
- * - in_tx_checkpointed
- * The other filters are supported by fixed counters.
- * The any-thread option is supported starting with v3.
- */
-#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
-#define FIXED_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
-
-/*
- * Constraint on the Event code + UMask
- */
-#define INTEL_UEVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
-
-/* Like UEVENT_CONSTRAINT, but match flags too */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
-
-#define INTEL_EXCLUEVT_CONSTRAINT(c, n) \
- __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
- HWEIGHT(n), 0, PERF_X86_EVENT_EXCL)
-
-#define INTEL_PLD_CONSTRAINT(c, n) \
- __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT)
-
-#define INTEL_PST_CONSTRAINT(c, n) \
- __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
-
-/* Event constraint, but match on all event flags too. */
-#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
-
-/* Check only flags, but allow all event/umask */
-#define INTEL_ALL_EVENT_CONSTRAINT(code, n) \
- EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS)
-
-/* Check flags and event code, and set the HSW store flag */
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_ST(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
-
-/* Check flags and event code, and set the HSW load flag */
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
-
-#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, \
- PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW store flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
-
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, \
- PERF_X86_EVENT_PEBS_ST_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW load flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
-
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \
- HWEIGHT(n), 0, \
- PERF_X86_EVENT_PEBS_LD_HSW|PERF_X86_EVENT_EXCL)
-
-/* Check flags and event code/umask, and set the HSW N/A flag */
-#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \
- __EVENT_CONSTRAINT(code, n, \
- INTEL_ARCH_EVENT_MASK|INTEL_ARCH_EVENT_MASK, \
- HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW)
-
-
-/*
- * We define the end marker as having a weight of -1
- * to enable blacklisting of events using a counter bitmask
- * of zero and thus a weight of zero.
- * The end marker has a weight that cannot possibly be
- * obtained from counting the bits in the bitmask.
- */
-#define EVENT_CONSTRAINT_END { .weight = -1 }
-
-/*
- * Check for end marker with weight == -1
- */
-#define for_each_event_constraint(e, c) \
- for ((e) = (c); (e)->weight != -1; (e)++)
-
-/*
- * Extra registers for specific events.
- *
- * Some events need large masks and require external MSRs.
- * Those extra MSRs end up being shared for all events on
- * a PMU and sometimes between PMU of sibling HT threads.
- * In either case, the kernel needs to handle conflicting
- * accesses to those extra, shared, regs. The data structure
- * to manage those registers is stored in cpu_hw_event.
- */
-struct extra_reg {
- unsigned int event;
- unsigned int msr;
- u64 config_mask;
- u64 valid_mask;
- int idx; /* per_xxx->regs[] reg index */
- bool extra_msr_access;
-};
-
-#define EVENT_EXTRA_REG(e, ms, m, vm, i) { \
- .event = (e), \
- .msr = (ms), \
- .config_mask = (m), \
- .valid_mask = (vm), \
- .idx = EXTRA_REG_##i, \
- .extra_msr_access = true, \
- }
-
-#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \
- EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
-
-#define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \
- EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
- ARCH_PERFMON_EVENTSEL_UMASK, vm, idx)
-
-#define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \
- INTEL_UEVENT_EXTRA_REG(c, \
- MSR_PEBS_LD_LAT_THRESHOLD, \
- 0xffff, \
- LDLAT)
-
-#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
-
-union perf_capabilities {
- struct {
- u64 lbr_format:6;
- u64 pebs_trap:1;
- u64 pebs_arch_reg:1;
- u64 pebs_format:4;
- u64 smm_freeze:1;
- /*
- * PMU supports separate counter range for writing
- * values > 32bit.
- */
- u64 full_width_write:1;
- };
- u64 capabilities;
-};
-
-struct x86_pmu_quirk {
- struct x86_pmu_quirk *next;
- void (*func)(void);
-};
-
-union x86_pmu_config {
- struct {
- u64 event:8,
- umask:8,
- usr:1,
- os:1,
- edge:1,
- pc:1,
- interrupt:1,
- __reserved1:1,
- en:1,
- inv:1,
- cmask:8,
- event2:4,
- __reserved2:4,
- go:1,
- ho:1;
- } bits;
- u64 value;
-};
-
-#define X86_CONFIG(args...) ((union x86_pmu_config){.bits = {args}}).value
-
-enum {
- x86_lbr_exclusive_lbr,
- x86_lbr_exclusive_bts,
- x86_lbr_exclusive_pt,
- x86_lbr_exclusive_max,
-};
-
-/*
- * struct x86_pmu - generic x86 pmu
- */
-struct x86_pmu {
- /*
- * Generic x86 PMC bits
- */
- const char *name;
- int version;
- int (*handle_irq)(struct pt_regs *);
- void (*disable_all)(void);
- void (*enable_all)(int added);
- void (*enable)(struct perf_event *);
- void (*disable)(struct perf_event *);
- int (*hw_config)(struct perf_event *event);
- int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
- unsigned eventsel;
- unsigned perfctr;
- int (*addr_offset)(int index, bool eventsel);
- int (*rdpmc_index)(int index);
- u64 (*event_map)(int);
- int max_events;
- int num_counters;
- int num_counters_fixed;
- int cntval_bits;
- u64 cntval_mask;
- union {
- unsigned long events_maskl;
- unsigned long events_mask[BITS_TO_LONGS(ARCH_PERFMON_EVENTS_COUNT)];
- };
- int events_mask_len;
- int apic;
- u64 max_period;
- struct event_constraint *
- (*get_event_constraints)(struct cpu_hw_events *cpuc,
- int idx,
- struct perf_event *event);
-
- void (*put_event_constraints)(struct cpu_hw_events *cpuc,
- struct perf_event *event);
-
- void (*start_scheduling)(struct cpu_hw_events *cpuc);
-
- void (*commit_scheduling)(struct cpu_hw_events *cpuc, int idx, int cntr);
-
- void (*stop_scheduling)(struct cpu_hw_events *cpuc);
-
- struct event_constraint *event_constraints;
- struct x86_pmu_quirk *quirks;
- int perfctr_second_write;
- bool late_ack;
- unsigned (*limit_period)(struct perf_event *event, unsigned l);
-
- /*
- * sysfs attrs
- */
- int attr_rdpmc_broken;
- int attr_rdpmc;
- struct attribute **format_attrs;
- struct attribute **event_attrs;
-
- ssize_t (*events_sysfs_show)(char *page, u64 config);
- struct attribute **cpu_events;
-
- /*
- * CPU Hotplug hooks
- */
- int (*cpu_prepare)(int cpu);
- void (*cpu_starting)(int cpu);
- void (*cpu_dying)(int cpu);
- void (*cpu_dead)(int cpu);
-
- void (*check_microcode)(void);
- void (*sched_task)(struct perf_event_context *ctx,
- bool sched_in);
-
- /*
- * Intel Arch Perfmon v2+
- */
- u64 intel_ctrl;
- union perf_capabilities intel_cap;
-
- /*
- * Intel DebugStore bits
- */
- unsigned int bts :1,
- bts_active :1,
- pebs :1,
- pebs_active :1,
- pebs_broken :1;
- int pebs_record_size;
- void (*drain_pebs)(struct pt_regs *regs);
- struct event_constraint *pebs_constraints;
- void (*pebs_aliases)(struct perf_event *event);
- int max_pebs_events;
- unsigned long free_running_flags;
-
- /*
- * Intel LBR
- */
- unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
- int lbr_nr; /* hardware stack size */
- u64 lbr_sel_mask; /* LBR_SELECT valid bits */
- const int *lbr_sel_map; /* lbr_select mappings */
- bool lbr_double_abort; /* duplicated lbr aborts */
-
- /*
- * Intel PT/LBR/BTS are exclusive
- */
- atomic_t lbr_exclusive[x86_lbr_exclusive_max];
-
- /*
- * Extra registers for events
- */
- struct extra_reg *extra_regs;
- unsigned int flags;
-
- /*
- * Intel host/guest support (KVM)
- */
- struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
-};
-
-struct x86_perf_task_context {
- u64 lbr_from[MAX_LBR_ENTRIES];
- u64 lbr_to[MAX_LBR_ENTRIES];
- u64 lbr_info[MAX_LBR_ENTRIES];
- int lbr_callstack_users;
- int lbr_stack_state;
-};
-
-#define x86_add_quirk(func_) \
-do { \
- static struct x86_pmu_quirk __quirk __initdata = { \
- .func = func_, \
- }; \
- __quirk.next = x86_pmu.quirks; \
- x86_pmu.quirks = &__quirk; \
-} while (0)
-
-/*
- * x86_pmu flags
- */
-#define PMU_FL_NO_HT_SHARING 0x1 /* no hyper-threading resource sharing */
-#define PMU_FL_HAS_RSP_1 0x2 /* has 2 equivalent offcore_rsp regs */
-#define PMU_FL_EXCL_CNTRS 0x4 /* has exclusive counter requirements */
-#define PMU_FL_EXCL_ENABLED 0x8 /* exclusive counter active */
-
-#define EVENT_VAR(_id) event_attr_##_id
-#define EVENT_PTR(_id) &event_attr_##_id.attr.attr
-
-#define EVENT_ATTR(_name, _id) \
-static struct perf_pmu_events_attr EVENT_VAR(_id) = { \
- .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
- .id = PERF_COUNT_HW_##_id, \
- .event_str = NULL, \
-};
-
-#define EVENT_ATTR_STR(_name, v, str) \
-static struct perf_pmu_events_attr event_attr_##v = { \
- .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \
- .id = 0, \
- .event_str = str, \
-};
-
-extern struct x86_pmu x86_pmu __read_mostly;
-
-static inline bool x86_pmu_has_lbr_callstack(void)
-{
- return x86_pmu.lbr_sel_map &&
- x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
-}
-
-DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
-
-int x86_perf_event_set_period(struct perf_event *event);
-
-/*
- * Generalized hw caching related hw_event table, filled
- * in on a per model basis. A value of 0 means
- * 'not supported', -1 means 'hw_event makes no sense on
- * this CPU', any other value means the raw hw_event
- * ID.
- */
-
-#define C(x) PERF_COUNT_HW_CACHE_##x
-
-extern u64 __read_mostly hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-extern u64 __read_mostly hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-
-u64 x86_perf_event_update(struct perf_event *event);
-
-static inline unsigned int x86_pmu_config_addr(int index)
-{
- return x86_pmu.eventsel + (x86_pmu.addr_offset ?
- x86_pmu.addr_offset(index, true) : index);
-}
-
-static inline unsigned int x86_pmu_event_addr(int index)
-{
- return x86_pmu.perfctr + (x86_pmu.addr_offset ?
- x86_pmu.addr_offset(index, false) : index);
-}
-
-static inline int x86_pmu_rdpmc_index(int index)
-{
- return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
-}
-
-int x86_add_exclusive(unsigned int what);
-
-void x86_del_exclusive(unsigned int what);
-
-int x86_reserve_hardware(void);
-
-void x86_release_hardware(void);
-
-void hw_perf_lbr_event_destroy(struct perf_event *event);
-
-int x86_setup_perfctr(struct perf_event *event);
-
-int x86_pmu_hw_config(struct perf_event *event);
-
-void x86_pmu_disable_all(void);
-
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
- u64 enable_mask)
-{
- u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
-
- if (hwc->extra_reg.reg)
- wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
- wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
-}
-
-void x86_pmu_enable_all(int added);
-
-int perf_assign_events(struct event_constraint **constraints, int n,
- int wmin, int wmax, int gpmax, int *assign);
-int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
-
-void x86_pmu_stop(struct perf_event *event, int flags);
-
-static inline void x86_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- wrmsrl(hwc->config_base, hwc->config);
-}
-
-void x86_pmu_enable_event(struct perf_event *event);
-
-int x86_pmu_handle_irq(struct pt_regs *regs);
-
-extern struct event_constraint emptyconstraint;
-
-extern struct event_constraint unconstrained;
-
-static inline bool kernel_ip(unsigned long ip)
-{
-#ifdef CONFIG_X86_32
- return ip > PAGE_OFFSET;
-#else
- return (long)ip < 0;
-#endif
-}
-
-/*
- * Not all PMUs provide the right context information to place the reported IP
- * into full context. Specifically segment registers are typically not
- * supplied.
- *
- * Assuming the address is a linear address (it is for IBS), we fake the CS and
- * vm86 mode using the known zero-based code segment and 'fix up' the registers
- * to reflect this.
- *
- * Intel PEBS/LBR appear to typically provide the effective address, nothing
- * much we can do about that but pray and treat it like a linear address.
- */
-static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
-{
- regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
- if (regs->flags & X86_VM_MASK)
- regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
- regs->ip = ip;
-}
-
-ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
-ssize_t intel_event_sysfs_show(char *page, u64 config);
-
-struct attribute **merge_attr(struct attribute **a, struct attribute **b);
-
-#ifdef CONFIG_CPU_SUP_AMD
-
-int amd_pmu_init(void);
-
-#else /* CONFIG_CPU_SUP_AMD */
-
-static inline int amd_pmu_init(void)
-{
- return 0;
-}
-
-#endif /* CONFIG_CPU_SUP_AMD */
-
-#ifdef CONFIG_CPU_SUP_INTEL
-
-static inline bool intel_pmu_has_bts(struct perf_event *event)
-{
- if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
- !event->attr.freq && event->hw.sample_period == 1)
- return true;
-
- return false;
-}
-
-int intel_pmu_save_and_restart(struct perf_event *event);
-
-struct event_constraint *
-x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event);
-
-struct intel_shared_regs *allocate_shared_regs(int cpu);
-
-int intel_pmu_init(void);
-
-void init_debug_store_on_cpu(int cpu);
-
-void fini_debug_store_on_cpu(int cpu);
-
-void release_ds_buffers(void);
-
-void reserve_ds_buffers(void);
-
-extern struct event_constraint bts_constraint;
-
-void intel_pmu_enable_bts(u64 config);
-
-void intel_pmu_disable_bts(void);
-
-int intel_pmu_drain_bts_buffer(void);
-
-extern struct event_constraint intel_core2_pebs_event_constraints[];
-
-extern struct event_constraint intel_atom_pebs_event_constraints[];
-
-extern struct event_constraint intel_slm_pebs_event_constraints[];
-
-extern struct event_constraint intel_nehalem_pebs_event_constraints[];
-
-extern struct event_constraint intel_westmere_pebs_event_constraints[];
-
-extern struct event_constraint intel_snb_pebs_event_constraints[];
-
-extern struct event_constraint intel_ivb_pebs_event_constraints[];
-
-extern struct event_constraint intel_hsw_pebs_event_constraints[];
-
-extern struct event_constraint intel_skl_pebs_event_constraints[];
-
-struct event_constraint *intel_pebs_constraints(struct perf_event *event);
-
-void intel_pmu_pebs_enable(struct perf_event *event);
-
-void intel_pmu_pebs_disable(struct perf_event *event);
-
-void intel_pmu_pebs_enable_all(void);
-
-void intel_pmu_pebs_disable_all(void);
-
-void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in);
-
-void intel_ds_init(void);
-
-void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
-
-void intel_pmu_lbr_reset(void);
-
-void intel_pmu_lbr_enable(struct perf_event *event);
-
-void intel_pmu_lbr_disable(struct perf_event *event);
-
-void intel_pmu_lbr_enable_all(bool pmi);
-
-void intel_pmu_lbr_disable_all(void);
-
-void intel_pmu_lbr_read(void);
-
-void intel_pmu_lbr_init_core(void);
-
-void intel_pmu_lbr_init_nhm(void);
-
-void intel_pmu_lbr_init_atom(void);
-
-void intel_pmu_lbr_init_snb(void);
-
-void intel_pmu_lbr_init_hsw(void);
-
-void intel_pmu_lbr_init_skl(void);
-
-int intel_pmu_setup_lbr_filter(struct perf_event *event);
-
-void intel_pt_interrupt(void);
-
-int intel_bts_interrupt(void);
-
-void intel_bts_enable_local(void);
-
-void intel_bts_disable_local(void);
-
-int p4_pmu_init(void);
-
-int p6_pmu_init(void);
-
-int knc_pmu_init(void);
-
-ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
- char *page);
-
-static inline int is_ht_workaround_enabled(void)
-{
- return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
-}
-
-#else /* CONFIG_CPU_SUP_INTEL */
-
-static inline void reserve_ds_buffers(void)
-{
-}
-
-static inline void release_ds_buffers(void)
-{
-}
-
-static inline int intel_pmu_init(void)
-{
- return 0;
-}
-
-static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
-{
- return NULL;
-}
-
-static inline int is_ht_workaround_enabled(void)
-{
- return 0;
-}
-#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
deleted file mode 100644
index 1cee5d2..0000000
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ /dev/null
@@ -1,731 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/export.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/apicdef.h>
-
-#include "perf_event.h"
-
-static __initconst const u64 amd_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
- [ C(RESULT_MISS) ] = 0x0141, /* Data Cache Misses */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts */
- [ C(RESULT_MISS) ] = 0x0167, /* Data Prefetcher :cancelled */
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches */
- [ C(RESULT_MISS) ] = 0x0081, /* Instruction cache misses */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
- [ C(RESULT_MISS) ] = 0x037E, /* L2 Cache Misses : IC+DC */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */
- [ C(RESULT_MISS) ] = 0x0746, /* L1_DTLB_AND_L2_DLTB_MISS.ALL */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes */
- [ C(RESULT_MISS) ] = 0x0385, /* L1_ITLB_AND_L2_ITLB_MISS.ALL */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr. */
- [ C(RESULT_MISS) ] = 0x00c3, /* Retired Mispredicted BI */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0xb8e9, /* CPU Request to Memory, l+r */
- [ C(RESULT_MISS) ] = 0x98e9, /* CPU Request to Memory, r */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-/*
- * AMD Performance Monitor K7 and later.
- */
-static const u64 amd_perfmon_event_map[] =
-{
- [PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
- [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
- [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
- [PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
- [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x00d1, /* "Dispatch stalls" event */
-};
-
-static u64 amd_pmu_event_map(int hw_event)
-{
- return amd_perfmon_event_map[hw_event];
-}
-
-/*
- * Previously calculated offsets
- */
-static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
-static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;
-
-/*
- * Legacy CPUs:
- * 4 counters starting at 0xc0010000 each offset by 1
- *
- * CPUs with core performance counter extensions:
- * 6 counters starting at 0xc0010200 each offset by 2
- */
-static inline int amd_pmu_addr_offset(int index, bool eventsel)
-{
- int offset;
-
- if (!index)
- return index;
-
- if (eventsel)
- offset = event_offsets[index];
- else
- offset = count_offsets[index];
-
- if (offset)
- return offset;
-
- if (!cpu_has_perfctr_core)
- offset = index;
- else
- offset = index << 1;
-
- if (eventsel)
- event_offsets[index] = offset;
- else
- count_offsets[index] = offset;
-
- return offset;
-}
-
-static int amd_core_hw_config(struct perf_event *event)
-{
- if (event->attr.exclude_host && event->attr.exclude_guest)
- /*
- * When HO == GO == 1 the hardware treats that as GO == HO == 0
- * and will count in both modes. We don't want to count in that
- * case so we emulate no-counting by setting US = OS = 0.
- */
- event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR |
- ARCH_PERFMON_EVENTSEL_OS);
- else if (event->attr.exclude_host)
- event->hw.config |= AMD64_EVENTSEL_GUESTONLY;
- else if (event->attr.exclude_guest)
- event->hw.config |= AMD64_EVENTSEL_HOSTONLY;
-
- return 0;
-}
-
-/*
- * AMD64 events are detected based on their event codes.
- */
-static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc)
-{
- return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff);
-}
-
-static inline int amd_is_nb_event(struct hw_perf_event *hwc)
-{
- return (hwc->config & 0xe0) == 0xe0;
-}
-
-static inline int amd_has_nb(struct cpu_hw_events *cpuc)
-{
- struct amd_nb *nb = cpuc->amd_nb;
-
- return nb && nb->nb_id != -1;
-}
-
-static int amd_pmu_hw_config(struct perf_event *event)
-{
- int ret;
-
- /* pass precise event sampling to ibs: */
- if (event->attr.precise_ip && get_ibs_caps())
- return -ENOENT;
-
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
-
- ret = x86_pmu_hw_config(event);
- if (ret)
- return ret;
-
- if (event->attr.type == PERF_TYPE_RAW)
- event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
-
- return amd_core_hw_config(event);
-}
-
-static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct amd_nb *nb = cpuc->amd_nb;
- int i;
-
- /*
- * need to scan whole list because event may not have
- * been assigned during scheduling
- *
- * no race condition possible because event can only
- * be removed on one CPU at a time AND PMU is disabled
- * when we come here
- */
- for (i = 0; i < x86_pmu.num_counters; i++) {
- if (cmpxchg(nb->owners + i, event, NULL) == event)
- break;
- }
-}
-
- /*
- * AMD64 NorthBridge events need special treatment because
- * counter access needs to be synchronized across all cores
- * of a package. Refer to BKDG section 3.12
- *
- * NB events are events measuring L3 cache, Hypertransport
- * traffic. They are identified by an event code >= 0xe00.
- * They measure events on the NorthBride which is shared
- * by all cores on a package. NB events are counted on a
- * shared set of counters. When a NB event is programmed
- * in a counter, the data actually comes from a shared
- * counter. Thus, access to those counters needs to be
- * synchronized.
- *
- * We implement the synchronization such that no two cores
- * can be measuring NB events using the same counters. Thus,
- * we maintain a per-NB allocation table. The available slot
- * is propagated using the event_constraint structure.
- *
- * We provide only one choice for each NB event based on
- * the fact that only NB events have restrictions. Consequently,
- * if a counter is available, there is a guarantee the NB event
- * will be assigned to it. If no slot is available, an empty
- * constraint is returned and scheduling will eventually fail
- * for this event.
- *
- * Note that all cores attached the same NB compete for the same
- * counters to host NB events, this is why we use atomic ops. Some
- * multi-chip CPUs may have more than one NB.
- *
- * Given that resources are allocated (cmpxchg), they must be
- * eventually freed for others to use. This is accomplished by
- * calling __amd_put_nb_event_constraints()
- *
- * Non NB events are not impacted by this restriction.
- */
-static struct event_constraint *
-__amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
- struct event_constraint *c)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct amd_nb *nb = cpuc->amd_nb;
- struct perf_event *old;
- int idx, new = -1;
-
- if (!c)
- c = &unconstrained;
-
- if (cpuc->is_fake)
- return c;
-
- /*
- * detect if already present, if so reuse
- *
- * cannot merge with actual allocation
- * because of possible holes
- *
- * event can already be present yet not assigned (in hwc->idx)
- * because of successive calls to x86_schedule_events() from
- * hw_perf_group_sched_in() without hw_perf_enable()
- */
- for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
- if (new == -1 || hwc->idx == idx)
- /* assign free slot, prefer hwc->idx */
- old = cmpxchg(nb->owners + idx, NULL, event);
- else if (nb->owners[idx] == event)
- /* event already present */
- old = event;
- else
- continue;
-
- if (old && old != event)
- continue;
-
- /* reassign to this slot */
- if (new != -1)
- cmpxchg(nb->owners + new, event, NULL);
- new = idx;
-
- /* already present, reuse */
- if (old == event)
- break;
- }
-
- if (new == -1)
- return &emptyconstraint;
-
- return &nb->event_constraints[new];
-}
-
-static struct amd_nb *amd_alloc_nb(int cpu)
-{
- struct amd_nb *nb;
- int i;
-
- nb = kzalloc_node(sizeof(struct amd_nb), GFP_KERNEL, cpu_to_node(cpu));
- if (!nb)
- return NULL;
-
- nb->nb_id = -1;
-
- /*
- * initialize all possible NB constraints
- */
- for (i = 0; i < x86_pmu.num_counters; i++) {
- __set_bit(i, nb->event_constraints[i].idxmsk);
- nb->event_constraints[i].weight = 1;
- }
- return nb;
-}
-
-static int amd_pmu_cpu_prepare(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-
- WARN_ON_ONCE(cpuc->amd_nb);
-
- if (boot_cpu_data.x86_max_cores < 2)
- return NOTIFY_OK;
-
- cpuc->amd_nb = amd_alloc_nb(cpu);
- if (!cpuc->amd_nb)
- return NOTIFY_BAD;
-
- return NOTIFY_OK;
-}
-
-static void amd_pmu_cpu_starting(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
- struct amd_nb *nb;
- int i, nb_id;
-
- cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
-
- if (boot_cpu_data.x86_max_cores < 2)
- return;
-
- nb_id = amd_get_nb_id(cpu);
- WARN_ON_ONCE(nb_id == BAD_APICID);
-
- for_each_online_cpu(i) {
- nb = per_cpu(cpu_hw_events, i).amd_nb;
- if (WARN_ON_ONCE(!nb))
- continue;
-
- if (nb->nb_id == nb_id) {
- *onln = cpuc->amd_nb;
- cpuc->amd_nb = nb;
- break;
- }
- }
-
- cpuc->amd_nb->nb_id = nb_id;
- cpuc->amd_nb->refcnt++;
-}
-
-static void amd_pmu_cpu_dead(int cpu)
-{
- struct cpu_hw_events *cpuhw;
-
- if (boot_cpu_data.x86_max_cores < 2)
- return;
-
- cpuhw = &per_cpu(cpu_hw_events, cpu);
-
- if (cpuhw->amd_nb) {
- struct amd_nb *nb = cpuhw->amd_nb;
-
- if (nb->nb_id == -1 || --nb->refcnt == 0)
- kfree(nb);
-
- cpuhw->amd_nb = NULL;
- }
-}
-
-static struct event_constraint *
-amd_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- /*
- * if not NB event or no NB, then no constraints
- */
- if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw)))
- return &unconstrained;
-
- return __amd_get_nb_event_constraints(cpuc, event, NULL);
-}
-
-static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- if (amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))
- __amd_put_nb_event_constraints(cpuc, event);
-}
-
-PMU_FORMAT_ATTR(event, "config:0-7,32-35");
-PMU_FORMAT_ATTR(umask, "config:8-15" );
-PMU_FORMAT_ATTR(edge, "config:18" );
-PMU_FORMAT_ATTR(inv, "config:23" );
-PMU_FORMAT_ATTR(cmask, "config:24-31" );
-
-static struct attribute *amd_format_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_cmask.attr,
- NULL,
-};
-
-/* AMD Family 15h */
-
-#define AMD_EVENT_TYPE_MASK 0x000000F0ULL
-
-#define AMD_EVENT_FP 0x00000000ULL ... 0x00000010ULL
-#define AMD_EVENT_LS 0x00000020ULL ... 0x00000030ULL
-#define AMD_EVENT_DC 0x00000040ULL ... 0x00000050ULL
-#define AMD_EVENT_CU 0x00000060ULL ... 0x00000070ULL
-#define AMD_EVENT_IC_DE 0x00000080ULL ... 0x00000090ULL
-#define AMD_EVENT_EX_LS 0x000000C0ULL
-#define AMD_EVENT_DE 0x000000D0ULL
-#define AMD_EVENT_NB 0x000000E0ULL ... 0x000000F0ULL
-
-/*
- * AMD family 15h event code/PMC mappings:
- *
- * type = event_code & 0x0F0:
- *
- * 0x000 FP PERF_CTL[5:3]
- * 0x010 FP PERF_CTL[5:3]
- * 0x020 LS PERF_CTL[5:0]
- * 0x030 LS PERF_CTL[5:0]
- * 0x040 DC PERF_CTL[5:0]
- * 0x050 DC PERF_CTL[5:0]
- * 0x060 CU PERF_CTL[2:0]
- * 0x070 CU PERF_CTL[2:0]
- * 0x080 IC/DE PERF_CTL[2:0]
- * 0x090 IC/DE PERF_CTL[2:0]
- * 0x0A0 ---
- * 0x0B0 ---
- * 0x0C0 EX/LS PERF_CTL[5:0]
- * 0x0D0 DE PERF_CTL[2:0]
- * 0x0E0 NB NB_PERF_CTL[3:0]
- * 0x0F0 NB NB_PERF_CTL[3:0]
- *
- * Exceptions:
- *
- * 0x000 FP PERF_CTL[3], PERF_CTL[5:3] (*)
- * 0x003 FP PERF_CTL[3]
- * 0x004 FP PERF_CTL[3], PERF_CTL[5:3] (*)
- * 0x00B FP PERF_CTL[3]
- * 0x00D FP PERF_CTL[3]
- * 0x023 DE PERF_CTL[2:0]
- * 0x02D LS PERF_CTL[3]
- * 0x02E LS PERF_CTL[3,0]
- * 0x031 LS PERF_CTL[2:0] (**)
- * 0x043 CU PERF_CTL[2:0]
- * 0x045 CU PERF_CTL[2:0]
- * 0x046 CU PERF_CTL[2:0]
- * 0x054 CU PERF_CTL[2:0]
- * 0x055 CU PERF_CTL[2:0]
- * 0x08F IC PERF_CTL[0]
- * 0x187 DE PERF_CTL[0]
- * 0x188 DE PERF_CTL[0]
- * 0x0DB EX PERF_CTL[5:0]
- * 0x0DC LS PERF_CTL[5:0]
- * 0x0DD LS PERF_CTL[5:0]
- * 0x0DE LS PERF_CTL[5:0]
- * 0x0DF LS PERF_CTL[5:0]
- * 0x1C0 EX PERF_CTL[5:3]
- * 0x1D6 EX PERF_CTL[5:0]
- * 0x1D8 EX PERF_CTL[5:0]
- *
- * (*) depending on the umask all FPU counters may be used
- * (**) only one unitmask enabled at a time
- */
-
-static struct event_constraint amd_f15_PMC0 = EVENT_CONSTRAINT(0, 0x01, 0);
-static struct event_constraint amd_f15_PMC20 = EVENT_CONSTRAINT(0, 0x07, 0);
-static struct event_constraint amd_f15_PMC3 = EVENT_CONSTRAINT(0, 0x08, 0);
-static struct event_constraint amd_f15_PMC30 = EVENT_CONSTRAINT_OVERLAP(0, 0x09, 0);
-static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0);
-static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0);
-
-static struct event_constraint *
-amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- unsigned int event_code = amd_get_event_code(hwc);
-
- switch (event_code & AMD_EVENT_TYPE_MASK) {
- case AMD_EVENT_FP:
- switch (event_code) {
- case 0x000:
- if (!(hwc->config & 0x0000F000ULL))
- break;
- if (!(hwc->config & 0x00000F00ULL))
- break;
- return &amd_f15_PMC3;
- case 0x004:
- if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
- break;
- return &amd_f15_PMC3;
- case 0x003:
- case 0x00B:
- case 0x00D:
- return &amd_f15_PMC3;
- }
- return &amd_f15_PMC53;
- case AMD_EVENT_LS:
- case AMD_EVENT_DC:
- case AMD_EVENT_EX_LS:
- switch (event_code) {
- case 0x023:
- case 0x043:
- case 0x045:
- case 0x046:
- case 0x054:
- case 0x055:
- return &amd_f15_PMC20;
- case 0x02D:
- return &amd_f15_PMC3;
- case 0x02E:
- return &amd_f15_PMC30;
- case 0x031:
- if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1)
- return &amd_f15_PMC20;
- return &emptyconstraint;
- case 0x1C0:
- return &amd_f15_PMC53;
- default:
- return &amd_f15_PMC50;
- }
- case AMD_EVENT_CU:
- case AMD_EVENT_IC_DE:
- case AMD_EVENT_DE:
- switch (event_code) {
- case 0x08F:
- case 0x187:
- case 0x188:
- return &amd_f15_PMC0;
- case 0x0DB ... 0x0DF:
- case 0x1D6:
- case 0x1D8:
- return &amd_f15_PMC50;
- default:
- return &amd_f15_PMC20;
- }
- case AMD_EVENT_NB:
- /* moved to perf_event_amd_uncore.c */
- return &emptyconstraint;
- default:
- return &emptyconstraint;
- }
-}
-
-static ssize_t amd_event_sysfs_show(char *page, u64 config)
-{
- u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
- (config & AMD64_EVENTSEL_EVENT) >> 24;
-
- return x86_event_sysfs_show(page, config, event);
-}
-
-static __initconst const struct x86_pmu amd_pmu = {
- .name = "AMD",
- .handle_irq = x86_pmu_handle_irq,
- .disable_all = x86_pmu_disable_all,
- .enable_all = x86_pmu_enable_all,
- .enable = x86_pmu_enable_event,
- .disable = x86_pmu_disable_event,
- .hw_config = amd_pmu_hw_config,
- .schedule_events = x86_schedule_events,
- .eventsel = MSR_K7_EVNTSEL0,
- .perfctr = MSR_K7_PERFCTR0,
- .addr_offset = amd_pmu_addr_offset,
- .event_map = amd_pmu_event_map,
- .max_events = ARRAY_SIZE(amd_perfmon_event_map),
- .num_counters = AMD64_NUM_COUNTERS,
- .cntval_bits = 48,
- .cntval_mask = (1ULL << 48) - 1,
- .apic = 1,
- /* use highest bit to detect overflow */
- .max_period = (1ULL << 47) - 1,
- .get_event_constraints = amd_get_event_constraints,
- .put_event_constraints = amd_put_event_constraints,
-
- .format_attrs = amd_format_attr,
- .events_sysfs_show = amd_event_sysfs_show,
-
- .cpu_prepare = amd_pmu_cpu_prepare,
- .cpu_starting = amd_pmu_cpu_starting,
- .cpu_dead = amd_pmu_cpu_dead,
-};
-
-static int __init amd_core_pmu_init(void)
-{
- if (!cpu_has_perfctr_core)
- return 0;
-
- switch (boot_cpu_data.x86) {
- case 0x15:
- pr_cont("Fam15h ");
- x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
- break;
-
- default:
- pr_err("core perfctr but no constraints; unknown hardware!\n");
- return -ENODEV;
- }
-
- /*
- * If core performance counter extensions exists, we must use
- * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
- * amd_pmu_addr_offset().
- */
- x86_pmu.eventsel = MSR_F15H_PERF_CTL;
- x86_pmu.perfctr = MSR_F15H_PERF_CTR;
- x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
-
- pr_cont("core perfctr, ");
- return 0;
-}
-
-__init int amd_pmu_init(void)
-{
- int ret;
-
- /* Performance-monitoring supported from K7 and later: */
- if (boot_cpu_data.x86 < 6)
- return -ENODEV;
-
- x86_pmu = amd_pmu;
-
- ret = amd_core_pmu_init();
- if (ret)
- return ret;
-
- /* Events are common for all AMDs */
- memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- return 0;
-}
-
-void amd_pmu_enable_virt(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- cpuc->perf_ctr_virt_mask = 0;
-
- /* Reload all events */
- x86_pmu_disable_all();
- x86_pmu_enable_all(0);
-}
-EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
-
-void amd_pmu_disable_virt(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- /*
- * We only mask out the Host-only bit so that host-only counting works
- * when SVM is disabled. If someone sets up a guest-only counter when
- * SVM is disabled the Guest-only bits still gets set and the counter
- * will not count anything.
- */
- cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
-
- /* Reload all events */
- x86_pmu_disable_all();
- x86_pmu_enable_all(0);
-}
-EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
deleted file mode 100644
index 989d3c2..0000000
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/*
- * Performance events - AMD IBS
- *
- * Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ptrace.h>
-#include <linux/syscore_ops.h>
-
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-static u32 ibs_caps;
-
-#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
-
-#include <linux/kprobes.h>
-#include <linux/hardirq.h>
-
-#include <asm/nmi.h>
-
-#define IBS_FETCH_CONFIG_MASK (IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
-#define IBS_OP_CONFIG_MASK IBS_OP_MAX_CNT
-
-enum ibs_states {
- IBS_ENABLED = 0,
- IBS_STARTED = 1,
- IBS_STOPPING = 2,
-
- IBS_MAX_STATES,
-};
-
-struct cpu_perf_ibs {
- struct perf_event *event;
- unsigned long state[BITS_TO_LONGS(IBS_MAX_STATES)];
-};
-
-struct perf_ibs {
- struct pmu pmu;
- unsigned int msr;
- u64 config_mask;
- u64 cnt_mask;
- u64 enable_mask;
- u64 valid_mask;
- u64 max_period;
- unsigned long offset_mask[1];
- int offset_max;
- struct cpu_perf_ibs __percpu *pcpu;
-
- struct attribute **format_attrs;
- struct attribute_group format_group;
- const struct attribute_group *attr_groups[2];
-
- u64 (*get_count)(u64 config);
-};
-
-struct perf_ibs_data {
- u32 size;
- union {
- u32 data[0]; /* data buffer starts here */
- u32 caps;
- };
- u64 regs[MSR_AMD64_IBS_REG_COUNT_MAX];
-};
-
-static int
-perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
-{
- s64 left = local64_read(&hwc->period_left);
- s64 period = hwc->sample_period;
- int overflow = 0;
-
- /*
- * If we are way outside a reasonable range then just skip forward:
- */
- if (unlikely(left <= -period)) {
- left = period;
- local64_set(&hwc->period_left, left);
- hwc->last_period = period;
- overflow = 1;
- }
-
- if (unlikely(left < (s64)min)) {
- left += period;
- local64_set(&hwc->period_left, left);
- hwc->last_period = period;
- overflow = 1;
- }
-
- /*
- * If the hw period that triggers the sw overflow is too short
- * we might hit the irq handler. This biases the results.
- * Thus we shorten the next-to-last period and set the last
- * period to the max period.
- */
- if (left > max) {
- left -= max;
- if (left > max)
- left = max;
- else if (left < min)
- left = min;
- }
-
- *hw_period = (u64)left;
-
- return overflow;
-}
-
-static int
-perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
-{
- struct hw_perf_event *hwc = &event->hw;
- int shift = 64 - width;
- u64 prev_raw_count;
- u64 delta;
-
- /*
- * Careful: an NMI might modify the previous event value.
- *
- * Our tactic to handle this is to first atomically read and
- * exchange a new raw count - then add that new-prev delta
- * count to the generic event atomically:
- */
- prev_raw_count = local64_read(&hwc->prev_count);
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count)
- return 0;
-
- /*
- * Now we have the new raw value and have updated the prev
- * timestamp already. We can now calculate the elapsed delta
- * (event-)time and add that to the generic event.
- *
- * Careful, not all hw sign-extends above the physical width
- * of the count.
- */
- delta = (new_raw_count << shift) - (prev_raw_count << shift);
- delta >>= shift;
-
- local64_add(delta, &event->count);
- local64_sub(delta, &hwc->period_left);
-
- return 1;
-}
-
-static struct perf_ibs perf_ibs_fetch;
-static struct perf_ibs perf_ibs_op;
-
-static struct perf_ibs *get_ibs_pmu(int type)
-{
- if (perf_ibs_fetch.pmu.type == type)
- return &perf_ibs_fetch;
- if (perf_ibs_op.pmu.type == type)
- return &perf_ibs_op;
- return NULL;
-}
-
-/*
- * Use IBS for precise event sampling:
- *
- * perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count
- * perf record -a -e r076:p ... # same as -e cpu-cycles:p
- * perf record -a -e r0C1:p ... # use ibs op counting micro-ops
- *
- * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
- * MSRC001_1033) is used to select either cycle or micro-ops counting
- * mode.
- *
- * The rip of IBS samples has skid 0. Thus, IBS supports precise
- * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
- * rip is invalid when IBS was not able to record the rip correctly.
- * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
- *
- */
-static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
-{
- switch (event->attr.precise_ip) {
- case 0:
- return -ENOENT;
- case 1:
- case 2:
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- switch (event->attr.type) {
- case PERF_TYPE_HARDWARE:
- switch (event->attr.config) {
- case PERF_COUNT_HW_CPU_CYCLES:
- *config = 0;
- return 0;
- }
- break;
- case PERF_TYPE_RAW:
- switch (event->attr.config) {
- case 0x0076:
- *config = 0;
- return 0;
- case 0x00C1:
- *config = IBS_OP_CNT_CTL;
- return 0;
- }
- break;
- default:
- return -ENOENT;
- }
-
- return -EOPNOTSUPP;
-}
-
-static const struct perf_event_attr ibs_notsupp = {
- .exclude_user = 1,
- .exclude_kernel = 1,
- .exclude_hv = 1,
- .exclude_idle = 1,
- .exclude_host = 1,
- .exclude_guest = 1,
-};
-
-static int perf_ibs_init(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct perf_ibs *perf_ibs;
- u64 max_cnt, config;
- int ret;
-
- perf_ibs = get_ibs_pmu(event->attr.type);
- if (perf_ibs) {
- config = event->attr.config;
- } else {
- perf_ibs = &perf_ibs_op;
- ret = perf_ibs_precise_event(event, &config);
- if (ret)
- return ret;
- }
-
- if (event->pmu != &perf_ibs->pmu)
- return -ENOENT;
-
- if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
- return -EINVAL;
-
- if (config & ~perf_ibs->config_mask)
- return -EINVAL;
-
- if (hwc->sample_period) {
- if (config & perf_ibs->cnt_mask)
- /* raw max_cnt may not be set */
- return -EINVAL;
- if (!event->attr.sample_freq && hwc->sample_period & 0x0f)
- /*
- * lower 4 bits can not be set in ibs max cnt,
- * but allowing it in case we adjust the
- * sample period to set a frequency.
- */
- return -EINVAL;
- hwc->sample_period &= ~0x0FULL;
- if (!hwc->sample_period)
- hwc->sample_period = 0x10;
- } else {
- max_cnt = config & perf_ibs->cnt_mask;
- config &= ~perf_ibs->cnt_mask;
- event->attr.sample_period = max_cnt << 4;
- hwc->sample_period = event->attr.sample_period;
- }
-
- if (!hwc->sample_period)
- return -EINVAL;
-
- /*
- * If we modify hwc->sample_period, we also need to update
- * hwc->last_period and hwc->period_left.
- */
- hwc->last_period = hwc->sample_period;
- local64_set(&hwc->period_left, hwc->sample_period);
-
- hwc->config_base = perf_ibs->msr;
- hwc->config = config;
-
- return 0;
-}
-
-static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
- struct hw_perf_event *hwc, u64 *period)
-{
- int overflow;
-
- /* ignore lower 4 bits in min count: */
- overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
- local64_set(&hwc->prev_count, 0);
-
- return overflow;
-}
-
-static u64 get_ibs_fetch_count(u64 config)
-{
- return (config & IBS_FETCH_CNT) >> 12;
-}
-
-static u64 get_ibs_op_count(u64 config)
-{
- u64 count = 0;
-
- if (config & IBS_OP_VAL)
- count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */
-
- if (ibs_caps & IBS_CAPS_RDWROPCNT)
- count += (config & IBS_OP_CUR_CNT) >> 32;
-
- return count;
-}
-
-static void
-perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
- u64 *config)
-{
- u64 count = perf_ibs->get_count(*config);
-
- /*
- * Set width to 64 since we do not overflow on max width but
- * instead on max count. In perf_ibs_set_period() we clear
- * prev count manually on overflow.
- */
- while (!perf_event_try_update(event, count, 64)) {
- rdmsrl(event->hw.config_base, *config);
- count = perf_ibs->get_count(*config);
- }
-}
-
-static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
- struct hw_perf_event *hwc, u64 config)
-{
- wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
-}
-
-/*
- * Erratum #420 Instruction-Based Sampling Engine May Generate
- * Interrupt that Cannot Be Cleared:
- *
- * Must clear counter mask first, then clear the enable bit. See
- * Revision Guide for AMD Family 10h Processors, Publication #41322.
- */
-static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
- struct hw_perf_event *hwc, u64 config)
-{
- config &= ~perf_ibs->cnt_mask;
- wrmsrl(hwc->config_base, config);
- config &= ~perf_ibs->enable_mask;
- wrmsrl(hwc->config_base, config);
-}
-
-/*
- * We cannot restore the ibs pmu state, so we always needs to update
- * the event while stopping it and then reset the state when starting
- * again. Thus, ignoring PERF_EF_RELOAD and PERF_EF_UPDATE flags in
- * perf_ibs_start()/perf_ibs_stop() and instead always do it.
- */
-static void perf_ibs_start(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
- struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
- u64 period;
-
- if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
- return;
-
- WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
- hwc->state = 0;
-
- perf_ibs_set_period(perf_ibs, hwc, &period);
- set_bit(IBS_STARTED, pcpu->state);
- perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
-
- perf_event_update_userpage(event);
-}
-
-static void perf_ibs_stop(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
- struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
- u64 config;
- int stopping;
-
- stopping = test_and_clear_bit(IBS_STARTED, pcpu->state);
-
- if (!stopping && (hwc->state & PERF_HES_UPTODATE))
- return;
-
- rdmsrl(hwc->config_base, config);
-
- if (stopping) {
- set_bit(IBS_STOPPING, pcpu->state);
- perf_ibs_disable_event(perf_ibs, hwc, config);
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
- }
-
- if (hwc->state & PERF_HES_UPTODATE)
- return;
-
- /*
- * Clear valid bit to not count rollovers on update, rollovers
- * are only updated in the irq handler.
- */
- config &= ~perf_ibs->valid_mask;
-
- perf_ibs_event_update(perf_ibs, event, &config);
- hwc->state |= PERF_HES_UPTODATE;
-}
-
-static int perf_ibs_add(struct perf_event *event, int flags)
-{
- struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
- struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-
- if (test_and_set_bit(IBS_ENABLED, pcpu->state))
- return -ENOSPC;
-
- event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
- pcpu->event = event;
-
- if (flags & PERF_EF_START)
- perf_ibs_start(event, PERF_EF_RELOAD);
-
- return 0;
-}
-
-static void perf_ibs_del(struct perf_event *event, int flags)
-{
- struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
- struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
-
- if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
- return;
-
- perf_ibs_stop(event, PERF_EF_UPDATE);
-
- pcpu->event = NULL;
-
- perf_event_update_userpage(event);
-}
-
-static void perf_ibs_read(struct perf_event *event) { }
-
-PMU_FORMAT_ATTR(rand_en, "config:57");
-PMU_FORMAT_ATTR(cnt_ctl, "config:19");
-
-static struct attribute *ibs_fetch_format_attrs[] = {
- &format_attr_rand_en.attr,
- NULL,
-};
-
-static struct attribute *ibs_op_format_attrs[] = {
- NULL, /* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
- NULL,
-};
-
-static struct perf_ibs perf_ibs_fetch = {
- .pmu = {
- .task_ctx_nr = perf_invalid_context,
-
- .event_init = perf_ibs_init,
- .add = perf_ibs_add,
- .del = perf_ibs_del,
- .start = perf_ibs_start,
- .stop = perf_ibs_stop,
- .read = perf_ibs_read,
- },
- .msr = MSR_AMD64_IBSFETCHCTL,
- .config_mask = IBS_FETCH_CONFIG_MASK,
- .cnt_mask = IBS_FETCH_MAX_CNT,
- .enable_mask = IBS_FETCH_ENABLE,
- .valid_mask = IBS_FETCH_VAL,
- .max_period = IBS_FETCH_MAX_CNT << 4,
- .offset_mask = { MSR_AMD64_IBSFETCH_REG_MASK },
- .offset_max = MSR_AMD64_IBSFETCH_REG_COUNT,
- .format_attrs = ibs_fetch_format_attrs,
-
- .get_count = get_ibs_fetch_count,
-};
-
-static struct perf_ibs perf_ibs_op = {
- .pmu = {
- .task_ctx_nr = perf_invalid_context,
-
- .event_init = perf_ibs_init,
- .add = perf_ibs_add,
- .del = perf_ibs_del,
- .start = perf_ibs_start,
- .stop = perf_ibs_stop,
- .read = perf_ibs_read,
- },
- .msr = MSR_AMD64_IBSOPCTL,
- .config_mask = IBS_OP_CONFIG_MASK,
- .cnt_mask = IBS_OP_MAX_CNT,
- .enable_mask = IBS_OP_ENABLE,
- .valid_mask = IBS_OP_VAL,
- .max_period = IBS_OP_MAX_CNT << 4,
- .offset_mask = { MSR_AMD64_IBSOP_REG_MASK },
- .offset_max = MSR_AMD64_IBSOP_REG_COUNT,
- .format_attrs = ibs_op_format_attrs,
-
- .get_count = get_ibs_op_count,
-};
-
-static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
-{
- struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
- struct perf_event *event = pcpu->event;
- struct hw_perf_event *hwc = &event->hw;
- struct perf_sample_data data;
- struct perf_raw_record raw;
- struct pt_regs regs;
- struct perf_ibs_data ibs_data;
- int offset, size, check_rip, offset_max, throttle = 0;
- unsigned int msr;
- u64 *buf, *config, period;
-
- if (!test_bit(IBS_STARTED, pcpu->state)) {
- /*
- * Catch spurious interrupts after stopping IBS: After
- * disabling IBS there could be still incoming NMIs
- * with samples that even have the valid bit cleared.
- * Mark all this NMIs as handled.
- */
- return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0;
- }
-
- msr = hwc->config_base;
- buf = ibs_data.regs;
- rdmsrl(msr, *buf);
- if (!(*buf++ & perf_ibs->valid_mask))
- return 0;
-
- config = &ibs_data.regs[0];
- perf_ibs_event_update(perf_ibs, event, config);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!perf_ibs_set_period(perf_ibs, hwc, &period))
- goto out; /* no sw counter overflow */
-
- ibs_data.caps = ibs_caps;
- size = 1;
- offset = 1;
- check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
- if (event->attr.sample_type & PERF_SAMPLE_RAW)
- offset_max = perf_ibs->offset_max;
- else if (check_rip)
- offset_max = 2;
- else
- offset_max = 1;
- do {
- rdmsrl(msr + offset, *buf++);
- size++;
- offset = find_next_bit(perf_ibs->offset_mask,
- perf_ibs->offset_max,
- offset + 1);
- } while (offset < offset_max);
- if (event->attr.sample_type & PERF_SAMPLE_RAW) {
- /*
- * Read IbsBrTarget and IbsOpData4 separately
- * depending on their availability.
- * Can't add to offset_max as they are staggered
- */
- if (ibs_caps & IBS_CAPS_BRNTRGT) {
- rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
- size++;
- }
- if (ibs_caps & IBS_CAPS_OPDATA4) {
- rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
- size++;
- }
- }
- ibs_data.size = sizeof(u64) * size;
-
- regs = *iregs;
- if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
- regs.flags &= ~PERF_EFLAGS_EXACT;
- } else {
- set_linear_ip(&regs, ibs_data.regs[1]);
- regs.flags |= PERF_EFLAGS_EXACT;
- }
-
- if (event->attr.sample_type & PERF_SAMPLE_RAW) {
- raw.size = sizeof(u32) + ibs_data.size;
- raw.data = ibs_data.data;
- data.raw = &raw;
- }
-
- throttle = perf_event_overflow(event, &data, &regs);
-out:
- if (throttle)
- perf_ibs_disable_event(perf_ibs, hwc, *config);
- else
- perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
-
- perf_event_update_userpage(event);
-
- return 1;
-}
-
-static int
-perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
-{
- int handled = 0;
-
- handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
- handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
-
- if (handled)
- inc_irq_stat(apic_perf_irqs);
-
- return handled;
-}
-NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
-
-static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
-{
- struct cpu_perf_ibs __percpu *pcpu;
- int ret;
-
- pcpu = alloc_percpu(struct cpu_perf_ibs);
- if (!pcpu)
- return -ENOMEM;
-
- perf_ibs->pcpu = pcpu;
-
- /* register attributes */
- if (perf_ibs->format_attrs[0]) {
- memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
- perf_ibs->format_group.name = "format";
- perf_ibs->format_group.attrs = perf_ibs->format_attrs;
-
- memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
- perf_ibs->attr_groups[0] = &perf_ibs->format_group;
- perf_ibs->pmu.attr_groups = perf_ibs->attr_groups;
- }
-
- ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
- if (ret) {
- perf_ibs->pcpu = NULL;
- free_percpu(pcpu);
- }
-
- return ret;
-}
-
-static __init int perf_event_ibs_init(void)
-{
- struct attribute **attr = ibs_op_format_attrs;
-
- if (!ibs_caps)
- return -ENODEV; /* ibs not supported by the cpu */
-
- perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
-
- if (ibs_caps & IBS_CAPS_OPCNT) {
- perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
- *attr++ = &format_attr_cnt_ctl.attr;
- }
- perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
-
- register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
- printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
-
- return 0;
-}
-
-#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
-
-static __init int perf_event_ibs_init(void) { return 0; }
-
-#endif
-
-/* IBS - apic initialization, for perf and oprofile */
-
-static __init u32 __get_ibs_caps(void)
-{
- u32 caps;
- unsigned int max_level;
-
- if (!boot_cpu_has(X86_FEATURE_IBS))
- return 0;
-
- /* check IBS cpuid feature flags */
- max_level = cpuid_eax(0x80000000);
- if (max_level < IBS_CPUID_FEATURES)
- return IBS_CAPS_DEFAULT;
-
- caps = cpuid_eax(IBS_CPUID_FEATURES);
- if (!(caps & IBS_CAPS_AVAIL))
- /* cpuid flags not valid */
- return IBS_CAPS_DEFAULT;
-
- return caps;
-}
-
-u32 get_ibs_caps(void)
-{
- return ibs_caps;
-}
-
-EXPORT_SYMBOL(get_ibs_caps);
-
-static inline int get_eilvt(int offset)
-{
- return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
-}
-
-static inline int put_eilvt(int offset)
-{
- return !setup_APIC_eilvt(offset, 0, 0, 1);
-}
-
-/*
- * Check and reserve APIC extended interrupt LVT offset for IBS if available.
- */
-static inline int ibs_eilvt_valid(void)
-{
- int offset;
- u64 val;
- int valid = 0;
-
- preempt_disable();
-
- rdmsrl(MSR_AMD64_IBSCTL, val);
- offset = val & IBSCTL_LVT_OFFSET_MASK;
-
- if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
- pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
- smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
- goto out;
- }
-
- if (!get_eilvt(offset)) {
- pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
- smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
- goto out;
- }
-
- valid = 1;
-out:
- preempt_enable();
-
- return valid;
-}
-
-static int setup_ibs_ctl(int ibs_eilvt_off)
-{
- struct pci_dev *cpu_cfg;
- int nodes;
- u32 value = 0;
-
- nodes = 0;
- cpu_cfg = NULL;
- do {
- cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_10H_NB_MISC,
- cpu_cfg);
- if (!cpu_cfg)
- break;
- ++nodes;
- pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
- | IBSCTL_LVT_OFFSET_VALID);
- pci_read_config_dword(cpu_cfg, IBSCTL, &value);
- if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
- pci_dev_put(cpu_cfg);
- printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
- "IBSCTL = 0x%08x\n", value);
- return -EINVAL;
- }
- } while (1);
-
- if (!nodes) {
- printk(KERN_DEBUG "No CPU node configured for IBS\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/*
- * This runs only on the current cpu. We try to find an LVT offset and
- * setup the local APIC. For this we must disable preemption. On
- * success we initialize all nodes with this offset. This updates then
- * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
- * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
- * is using the new offset.
- */
-static void force_ibs_eilvt_setup(void)
-{
- int offset;
- int ret;
-
- preempt_disable();
- /* find the next free available EILVT entry, skip offset 0 */
- for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
- if (get_eilvt(offset))
- break;
- }
- preempt_enable();
-
- if (offset == APIC_EILVT_NR_MAX) {
- printk(KERN_DEBUG "No EILVT entry available\n");
- return;
- }
-
- ret = setup_ibs_ctl(offset);
- if (ret)
- goto out;
-
- if (!ibs_eilvt_valid())
- goto out;
-
- pr_info("IBS: LVT offset %d assigned\n", offset);
-
- return;
-out:
- preempt_disable();
- put_eilvt(offset);
- preempt_enable();
- return;
-}
-
-static void ibs_eilvt_setup(void)
-{
- /*
- * Force LVT offset assignment for family 10h: The offsets are
- * not assigned by the BIOS for this family, so the OS is
- * responsible for doing it. If the OS assignment fails, fall
- * back to BIOS settings and try to setup this.
- */
- if (boot_cpu_data.x86 == 0x10)
- force_ibs_eilvt_setup();
-}
-
-static inline int get_ibs_lvt_offset(void)
-{
- u64 val;
-
- rdmsrl(MSR_AMD64_IBSCTL, val);
- if (!(val & IBSCTL_LVT_OFFSET_VALID))
- return -EINVAL;
-
- return val & IBSCTL_LVT_OFFSET_MASK;
-}
-
-static void setup_APIC_ibs(void *dummy)
-{
- int offset;
-
- offset = get_ibs_lvt_offset();
- if (offset < 0)
- goto failed;
-
- if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
- return;
-failed:
- pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
- smp_processor_id());
-}
-
-static void clear_APIC_ibs(void *dummy)
-{
- int offset;
-
- offset = get_ibs_lvt_offset();
- if (offset >= 0)
- setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
-}
-
-#ifdef CONFIG_PM
-
-static int perf_ibs_suspend(void)
-{
- clear_APIC_ibs(NULL);
- return 0;
-}
-
-static void perf_ibs_resume(void)
-{
- ibs_eilvt_setup();
- setup_APIC_ibs(NULL);
-}
-
-static struct syscore_ops perf_ibs_syscore_ops = {
- .resume = perf_ibs_resume,
- .suspend = perf_ibs_suspend,
-};
-
-static void perf_ibs_pm_init(void)
-{
- register_syscore_ops(&perf_ibs_syscore_ops);
-}
-
-#else
-
-static inline void perf_ibs_pm_init(void) { }
-
-#endif
-
-static int
-perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_STARTING:
- setup_APIC_ibs(NULL);
- break;
- case CPU_DYING:
- clear_APIC_ibs(NULL);
- break;
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static __init int amd_ibs_init(void)
-{
- u32 caps;
- int ret = -EINVAL;
-
- caps = __get_ibs_caps();
- if (!caps)
- return -ENODEV; /* ibs not supported by the cpu */
-
- ibs_eilvt_setup();
-
- if (!ibs_eilvt_valid())
- goto out;
-
- perf_ibs_pm_init();
- cpu_notifier_register_begin();
- ibs_caps = caps;
- /* make ibs_caps visible to other cpus: */
- smp_mb();
- smp_call_function(setup_APIC_ibs, NULL, 1);
- __perf_cpu_notifier(perf_ibs_cpu_notifier);
- cpu_notifier_register_done();
-
- ret = perf_event_ibs_init();
-out:
- if (ret)
- pr_err("Failed to setup IBS, %d\n", ret);
- return ret;
-}
-
-/* Since we need the pci subsystem to init ibs we can't do this earlier: */
-device_initcall(amd_ibs_init);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c b/arch/x86/kernel/cpu/perf_event_amd_iommu.c
deleted file mode 100644
index 97242a9..0000000
--- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Steven Kinney <Steven.Kinney@amd.com>
- * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
- *
- * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/perf_event.h>
-#include <linux/module.h>
-#include <linux/cpumask.h>
-#include <linux/slab.h>
-
-#include "perf_event.h"
-#include "perf_event_amd_iommu.h"
-
-#define COUNTER_SHIFT 16
-
-#define _GET_BANK(ev) ((u8)(ev->hw.extra_reg.reg >> 8))
-#define _GET_CNTR(ev) ((u8)(ev->hw.extra_reg.reg))
-
-/* iommu pmu config masks */
-#define _GET_CSOURCE(ev) ((ev->hw.config & 0xFFULL))
-#define _GET_DEVID(ev) ((ev->hw.config >> 8) & 0xFFFFULL)
-#define _GET_PASID(ev) ((ev->hw.config >> 24) & 0xFFFFULL)
-#define _GET_DOMID(ev) ((ev->hw.config >> 40) & 0xFFFFULL)
-#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config) & 0xFFFFULL)
-#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
-#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
-
-static struct perf_amd_iommu __perf_iommu;
-
-struct perf_amd_iommu {
- struct pmu pmu;
- u8 max_banks;
- u8 max_counters;
- u64 cntr_assign_mask;
- raw_spinlock_t lock;
- const struct attribute_group *attr_groups[4];
-};
-
-#define format_group attr_groups[0]
-#define cpumask_group attr_groups[1]
-#define events_group attr_groups[2]
-#define null_group attr_groups[3]
-
-/*---------------------------------------------
- * sysfs format attributes
- *---------------------------------------------*/
-PMU_FORMAT_ATTR(csource, "config:0-7");
-PMU_FORMAT_ATTR(devid, "config:8-23");
-PMU_FORMAT_ATTR(pasid, "config:24-39");
-PMU_FORMAT_ATTR(domid, "config:40-55");
-PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
-PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
-PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
-
-static struct attribute *iommu_format_attrs[] = {
- &format_attr_csource.attr,
- &format_attr_devid.attr,
- &format_attr_pasid.attr,
- &format_attr_domid.attr,
- &format_attr_devid_mask.attr,
- &format_attr_pasid_mask.attr,
- &format_attr_domid_mask.attr,
- NULL,
-};
-
-static struct attribute_group amd_iommu_format_group = {
- .name = "format",
- .attrs = iommu_format_attrs,
-};
-
-/*---------------------------------------------
- * sysfs events attributes
- *---------------------------------------------*/
-struct amd_iommu_event_desc {
- struct kobj_attribute attr;
- const char *event;
-};
-
-static ssize_t _iommu_event_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- struct amd_iommu_event_desc *event =
- container_of(attr, struct amd_iommu_event_desc, attr);
- return sprintf(buf, "%s\n", event->event);
-}
-
-#define AMD_IOMMU_EVENT_DESC(_name, _event) \
-{ \
- .attr = __ATTR(_name, 0444, _iommu_event_show, NULL), \
- .event = _event, \
-}
-
-static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
- AMD_IOMMU_EVENT_DESC(mem_pass_untrans, "csource=0x01"),
- AMD_IOMMU_EVENT_DESC(mem_pass_pretrans, "csource=0x02"),
- AMD_IOMMU_EVENT_DESC(mem_pass_excl, "csource=0x03"),
- AMD_IOMMU_EVENT_DESC(mem_target_abort, "csource=0x04"),
- AMD_IOMMU_EVENT_DESC(mem_trans_total, "csource=0x05"),
- AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit, "csource=0x06"),
- AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis, "csource=0x07"),
- AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit, "csource=0x08"),
- AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis, "csource=0x09"),
- AMD_IOMMU_EVENT_DESC(mem_dte_hit, "csource=0x0a"),
- AMD_IOMMU_EVENT_DESC(mem_dte_mis, "csource=0x0b"),
- AMD_IOMMU_EVENT_DESC(page_tbl_read_tot, "csource=0x0c"),
- AMD_IOMMU_EVENT_DESC(page_tbl_read_nst, "csource=0x0d"),
- AMD_IOMMU_EVENT_DESC(page_tbl_read_gst, "csource=0x0e"),
- AMD_IOMMU_EVENT_DESC(int_dte_hit, "csource=0x0f"),
- AMD_IOMMU_EVENT_DESC(int_dte_mis, "csource=0x10"),
- AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"),
- AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"),
- AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"),
- { /* end: all zeroes */ },
-};
-
-/*---------------------------------------------
- * sysfs cpumask attributes
- *---------------------------------------------*/
-static cpumask_t iommu_cpumask;
-
-static ssize_t _iommu_cpumask_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
-}
-static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
-
-static struct attribute *iommu_cpumask_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static struct attribute_group amd_iommu_cpumask_group = {
- .attrs = iommu_cpumask_attrs,
-};
-
-/*---------------------------------------------*/
-
-static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
-{
- unsigned long flags;
- int shift, bank, cntr, retval;
- int max_banks = perf_iommu->max_banks;
- int max_cntrs = perf_iommu->max_counters;
-
- raw_spin_lock_irqsave(&perf_iommu->lock, flags);
-
- for (bank = 0, shift = 0; bank < max_banks; bank++) {
- for (cntr = 0; cntr < max_cntrs; cntr++) {
- shift = bank + (bank*3) + cntr;
- if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
- continue;
- } else {
- perf_iommu->cntr_assign_mask |= (1ULL<<shift);
- retval = ((u16)((u16)bank<<8) | (u8)(cntr));
- goto out;
- }
- }
- }
- retval = -ENOSPC;
-out:
- raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
- return retval;
-}
-
-static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
- u8 bank, u8 cntr)
-{
- unsigned long flags;
- int max_banks, max_cntrs;
- int shift = 0;
-
- max_banks = perf_iommu->max_banks;
- max_cntrs = perf_iommu->max_counters;
-
- if ((bank > max_banks) || (cntr > max_cntrs))
- return -EINVAL;
-
- shift = bank + cntr + (bank*3);
-
- raw_spin_lock_irqsave(&perf_iommu->lock, flags);
- perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
- raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
-
- return 0;
-}
-
-static int perf_iommu_event_init(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct perf_amd_iommu *perf_iommu;
- u64 config, config1;
-
- /* test the event attr type check for PMU enumeration */
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- /*
- * IOMMU counters are shared across all cores.
- * Therefore, it does not support per-process mode.
- * Also, it does not support event sampling mode.
- */
- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
- return -EINVAL;
-
- /* IOMMU counters do not have usr/os/guest/host bits */
- if (event->attr.exclude_user || event->attr.exclude_kernel ||
- event->attr.exclude_host || event->attr.exclude_guest)
- return -EINVAL;
-
- if (event->cpu < 0)
- return -EINVAL;
-
- perf_iommu = &__perf_iommu;
-
- if (event->pmu != &perf_iommu->pmu)
- return -ENOENT;
-
- if (perf_iommu) {
- config = event->attr.config;
- config1 = event->attr.config1;
- } else {
- return -EINVAL;
- }
-
- /* integrate with iommu base devid (0000), assume one iommu */
- perf_iommu->max_banks =
- amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
- perf_iommu->max_counters =
- amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
- if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
- return -EINVAL;
-
- /* update the hw_perf_event struct with the iommu config data */
- hwc->config = config;
- hwc->extra_reg.config = config1;
-
- return 0;
-}
-
-static void perf_iommu_enable_event(struct perf_event *ev)
-{
- u8 csource = _GET_CSOURCE(ev);
- u16 devid = _GET_DEVID(ev);
- u64 reg = 0ULL;
-
- reg = csource;
- amd_iommu_pc_get_set_reg_val(devid,
- _GET_BANK(ev), _GET_CNTR(ev) ,
- IOMMU_PC_COUNTER_SRC_REG, &reg, true);
-
- reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
- if (reg)
- reg |= (1UL << 31);
- amd_iommu_pc_get_set_reg_val(devid,
- _GET_BANK(ev), _GET_CNTR(ev) ,
- IOMMU_PC_DEVID_MATCH_REG, &reg, true);
-
- reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
- if (reg)
- reg |= (1UL << 31);
- amd_iommu_pc_get_set_reg_val(devid,
- _GET_BANK(ev), _GET_CNTR(ev) ,
- IOMMU_PC_PASID_MATCH_REG, &reg, true);
-
- reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
- if (reg)
- reg |= (1UL << 31);
- amd_iommu_pc_get_set_reg_val(devid,
- _GET_BANK(ev), _GET_CNTR(ev) ,
- IOMMU_PC_DOMID_MATCH_REG, &reg, true);
-}
-
-static void perf_iommu_disable_event(struct perf_event *event)
-{
- u64 reg = 0ULL;
-
- amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
- _GET_BANK(event), _GET_CNTR(event),
- IOMMU_PC_COUNTER_SRC_REG, &reg, true);
-}
-
-static void perf_iommu_start(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- pr_debug("perf: amd_iommu:perf_iommu_start\n");
- if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
- return;
-
- WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
- hwc->state = 0;
-
- if (flags & PERF_EF_RELOAD) {
- u64 prev_raw_count = local64_read(&hwc->prev_count);
- amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
- _GET_BANK(event), _GET_CNTR(event),
- IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
- }
-
- perf_iommu_enable_event(event);
- perf_event_update_userpage(event);
-
-}
-
-static void perf_iommu_read(struct perf_event *event)
-{
- u64 count = 0ULL;
- u64 prev_raw_count = 0ULL;
- u64 delta = 0ULL;
- struct hw_perf_event *hwc = &event->hw;
- pr_debug("perf: amd_iommu:perf_iommu_read\n");
-
- amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
- _GET_BANK(event), _GET_CNTR(event),
- IOMMU_PC_COUNTER_REG, &count, false);
-
- /* IOMMU pc counter register is only 48 bits */
- count &= 0xFFFFFFFFFFFFULL;
-
- prev_raw_count = local64_read(&hwc->prev_count);
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- count) != prev_raw_count)
- return;
-
- /* Handling 48-bit counter overflowing */
- delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
- delta >>= COUNTER_SHIFT;
- local64_add(delta, &event->count);
-
-}
-
-static void perf_iommu_stop(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 config;
-
- pr_debug("perf: amd_iommu:perf_iommu_stop\n");
-
- if (hwc->state & PERF_HES_UPTODATE)
- return;
-
- perf_iommu_disable_event(event);
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
-
- if (hwc->state & PERF_HES_UPTODATE)
- return;
-
- config = hwc->config;
- perf_iommu_read(event);
- hwc->state |= PERF_HES_UPTODATE;
-}
-
-static int perf_iommu_add(struct perf_event *event, int flags)
-{
- int retval;
- struct perf_amd_iommu *perf_iommu =
- container_of(event->pmu, struct perf_amd_iommu, pmu);
-
- pr_debug("perf: amd_iommu:perf_iommu_add\n");
- event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
- /* request an iommu bank/counter */
- retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
- if (retval != -ENOSPC)
- event->hw.extra_reg.reg = (u16)retval;
- else
- return retval;
-
- if (flags & PERF_EF_START)
- perf_iommu_start(event, PERF_EF_RELOAD);
-
- return 0;
-}
-
-static void perf_iommu_del(struct perf_event *event, int flags)
-{
- struct perf_amd_iommu *perf_iommu =
- container_of(event->pmu, struct perf_amd_iommu, pmu);
-
- pr_debug("perf: amd_iommu:perf_iommu_del\n");
- perf_iommu_stop(event, PERF_EF_UPDATE);
-
- /* clear the assigned iommu bank/counter */
- clear_avail_iommu_bnk_cntr(perf_iommu,
- _GET_BANK(event),
- _GET_CNTR(event));
-
- perf_event_update_userpage(event);
-}
-
-static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
-{
- struct attribute **attrs;
- struct attribute_group *attr_group;
- int i = 0, j;
-
- while (amd_iommu_v2_event_descs[i].attr.attr.name)
- i++;
-
- attr_group = kzalloc(sizeof(struct attribute *)
- * (i + 1) + sizeof(*attr_group), GFP_KERNEL);
- if (!attr_group)
- return -ENOMEM;
-
- attrs = (struct attribute **)(attr_group + 1);
- for (j = 0; j < i; j++)
- attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
-
- attr_group->name = "events";
- attr_group->attrs = attrs;
- perf_iommu->events_group = attr_group;
-
- return 0;
-}
-
-static __init void amd_iommu_pc_exit(void)
-{
- if (__perf_iommu.events_group != NULL) {
- kfree(__perf_iommu.events_group);
- __perf_iommu.events_group = NULL;
- }
-}
-
-static __init int _init_perf_amd_iommu(
- struct perf_amd_iommu *perf_iommu, char *name)
-{
- int ret;
-
- raw_spin_lock_init(&perf_iommu->lock);
-
- /* Init format attributes */
- perf_iommu->format_group = &amd_iommu_format_group;
-
- /* Init cpumask attributes to only core 0 */
- cpumask_set_cpu(0, &iommu_cpumask);
- perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
-
- /* Init events attributes */
- if (_init_events_attrs(perf_iommu) != 0)
- pr_err("perf: amd_iommu: Only support raw events.\n");
-
- /* Init null attributes */
- perf_iommu->null_group = NULL;
- perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
-
- ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
- if (ret) {
- pr_err("perf: amd_iommu: Failed to initialized.\n");
- amd_iommu_pc_exit();
- } else {
- pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
- amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
- amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
- }
-
- return ret;
-}
-
-static struct perf_amd_iommu __perf_iommu = {
- .pmu = {
- .event_init = perf_iommu_event_init,
- .add = perf_iommu_add,
- .del = perf_iommu_del,
- .start = perf_iommu_start,
- .stop = perf_iommu_stop,
- .read = perf_iommu_read,
- },
- .max_banks = 0x00,
- .max_counters = 0x00,
- .cntr_assign_mask = 0ULL,
- .format_group = NULL,
- .cpumask_group = NULL,
- .events_group = NULL,
- .null_group = NULL,
-};
-
-static __init int amd_iommu_pc_init(void)
-{
- /* Make sure the IOMMU PC resource is available */
- if (!amd_iommu_pc_supported())
- return -ENODEV;
-
- _init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
-
- return 0;
-}
-
-device_initcall(amd_iommu_pc_init);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c
deleted file mode 100644
index cc6cedb..0000000
--- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2013 Advanced Micro Devices, Inc.
- *
- * Author: Jacob Shin <jacob.shin@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/perf_event.h>
-#include <linux/percpu.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-
-#include <asm/cpufeature.h>
-#include <asm/perf_event.h>
-#include <asm/msr.h>
-
-#define NUM_COUNTERS_NB 4
-#define NUM_COUNTERS_L2 4
-#define MAX_COUNTERS NUM_COUNTERS_NB
-
-#define RDPMC_BASE_NB 6
-#define RDPMC_BASE_L2 10
-
-#define COUNTER_SHIFT 16
-
-struct amd_uncore {
- int id;
- int refcnt;
- int cpu;
- int num_counters;
- int rdpmc_base;
- u32 msr_base;
- cpumask_t *active_mask;
- struct pmu *pmu;
- struct perf_event *events[MAX_COUNTERS];
- struct amd_uncore *free_when_cpu_online;
-};
-
-static struct amd_uncore * __percpu *amd_uncore_nb;
-static struct amd_uncore * __percpu *amd_uncore_l2;
-
-static struct pmu amd_nb_pmu;
-static struct pmu amd_l2_pmu;
-
-static cpumask_t amd_nb_active_mask;
-static cpumask_t amd_l2_active_mask;
-
-static bool is_nb_event(struct perf_event *event)
-{
- return event->pmu->type == amd_nb_pmu.type;
-}
-
-static bool is_l2_event(struct perf_event *event)
-{
- return event->pmu->type == amd_l2_pmu.type;
-}
-
-static struct amd_uncore *event_to_amd_uncore(struct perf_event *event)
-{
- if (is_nb_event(event) && amd_uncore_nb)
- return *per_cpu_ptr(amd_uncore_nb, event->cpu);
- else if (is_l2_event(event) && amd_uncore_l2)
- return *per_cpu_ptr(amd_uncore_l2, event->cpu);
-
- return NULL;
-}
-
-static void amd_uncore_read(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 prev, new;
- s64 delta;
-
- /*
- * since we do not enable counter overflow interrupts,
- * we do not have to worry about prev_count changing on us
- */
-
- prev = local64_read(&hwc->prev_count);
- rdpmcl(hwc->event_base_rdpmc, new);
- local64_set(&hwc->prev_count, new);
- delta = (new << COUNTER_SHIFT) - (prev << COUNTER_SHIFT);
- delta >>= COUNTER_SHIFT;
- local64_add(delta, &event->count);
-}
-
-static void amd_uncore_start(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- if (flags & PERF_EF_RELOAD)
- wrmsrl(hwc->event_base, (u64)local64_read(&hwc->prev_count));
-
- hwc->state = 0;
- wrmsrl(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE));
- perf_event_update_userpage(event);
-}
-
-static void amd_uncore_stop(struct perf_event *event, int flags)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- wrmsrl(hwc->config_base, hwc->config);
- hwc->state |= PERF_HES_STOPPED;
-
- if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
- amd_uncore_read(event);
- hwc->state |= PERF_HES_UPTODATE;
- }
-}
-
-static int amd_uncore_add(struct perf_event *event, int flags)
-{
- int i;
- struct amd_uncore *uncore = event_to_amd_uncore(event);
- struct hw_perf_event *hwc = &event->hw;
-
- /* are we already assigned? */
- if (hwc->idx != -1 && uncore->events[hwc->idx] == event)
- goto out;
-
- for (i = 0; i < uncore->num_counters; i++) {
- if (uncore->events[i] == event) {
- hwc->idx = i;
- goto out;
- }
- }
-
- /* if not, take the first available counter */
- hwc->idx = -1;
- for (i = 0; i < uncore->num_counters; i++) {
- if (cmpxchg(&uncore->events[i], NULL, event) == NULL) {
- hwc->idx = i;
- break;
- }
- }
-
-out:
- if (hwc->idx == -1)
- return -EBUSY;
-
- hwc->config_base = uncore->msr_base + (2 * hwc->idx);
- hwc->event_base = uncore->msr_base + 1 + (2 * hwc->idx);
- hwc->event_base_rdpmc = uncore->rdpmc_base + hwc->idx;
- hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
- if (flags & PERF_EF_START)
- amd_uncore_start(event, PERF_EF_RELOAD);
-
- return 0;
-}
-
-static void amd_uncore_del(struct perf_event *event, int flags)
-{
- int i;
- struct amd_uncore *uncore = event_to_amd_uncore(event);
- struct hw_perf_event *hwc = &event->hw;
-
- amd_uncore_stop(event, PERF_EF_UPDATE);
-
- for (i = 0; i < uncore->num_counters; i++) {
- if (cmpxchg(&uncore->events[i], event, NULL) == event)
- break;
- }
-
- hwc->idx = -1;
-}
-
-static int amd_uncore_event_init(struct perf_event *event)
-{
- struct amd_uncore *uncore;
- struct hw_perf_event *hwc = &event->hw;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- /*
- * NB and L2 counters (MSRs) are shared across all cores that share the
- * same NB / L2 cache. Interrupts can be directed to a single target
- * core, however, event counts generated by processes running on other
- * cores cannot be masked out. So we do not support sampling and
- * per-thread events.
- */
- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
- return -EINVAL;
-
- /* NB and L2 counters do not have usr/os/guest/host bits */
- if (event->attr.exclude_user || event->attr.exclude_kernel ||
- event->attr.exclude_host || event->attr.exclude_guest)
- return -EINVAL;
-
- /* and we do not enable counter overflow interrupts */
- hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
- hwc->idx = -1;
-
- if (event->cpu < 0)
- return -EINVAL;
-
- uncore = event_to_amd_uncore(event);
- if (!uncore)
- return -ENODEV;
-
- /*
- * since request can come in to any of the shared cores, we will remap
- * to a single common cpu.
- */
- event->cpu = uncore->cpu;
-
- return 0;
-}
-
-static ssize_t amd_uncore_attr_show_cpumask(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- cpumask_t *active_mask;
- struct pmu *pmu = dev_get_drvdata(dev);
-
- if (pmu->type == amd_nb_pmu.type)
- active_mask = &amd_nb_active_mask;
- else if (pmu->type == amd_l2_pmu.type)
- active_mask = &amd_l2_active_mask;
- else
- return 0;
-
- return cpumap_print_to_pagebuf(true, buf, active_mask);
-}
-static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL);
-
-static struct attribute *amd_uncore_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static struct attribute_group amd_uncore_attr_group = {
- .attrs = amd_uncore_attrs,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-7,32-35");
-PMU_FORMAT_ATTR(umask, "config:8-15");
-
-static struct attribute *amd_uncore_format_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- NULL,
-};
-
-static struct attribute_group amd_uncore_format_group = {
- .name = "format",
- .attrs = amd_uncore_format_attr,
-};
-
-static const struct attribute_group *amd_uncore_attr_groups[] = {
- &amd_uncore_attr_group,
- &amd_uncore_format_group,
- NULL,
-};
-
-static struct pmu amd_nb_pmu = {
- .attr_groups = amd_uncore_attr_groups,
- .name = "amd_nb",
- .event_init = amd_uncore_event_init,
- .add = amd_uncore_add,
- .del = amd_uncore_del,
- .start = amd_uncore_start,
- .stop = amd_uncore_stop,
- .read = amd_uncore_read,
-};
-
-static struct pmu amd_l2_pmu = {
- .attr_groups = amd_uncore_attr_groups,
- .name = "amd_l2",
- .event_init = amd_uncore_event_init,
- .add = amd_uncore_add,
- .del = amd_uncore_del,
- .start = amd_uncore_start,
- .stop = amd_uncore_stop,
- .read = amd_uncore_read,
-};
-
-static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
-{
- return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL,
- cpu_to_node(cpu));
-}
-
-static int amd_uncore_cpu_up_prepare(unsigned int cpu)
-{
- struct amd_uncore *uncore_nb = NULL, *uncore_l2;
-
- if (amd_uncore_nb) {
- uncore_nb = amd_uncore_alloc(cpu);
- if (!uncore_nb)
- goto fail;
- uncore_nb->cpu = cpu;
- uncore_nb->num_counters = NUM_COUNTERS_NB;
- uncore_nb->rdpmc_base = RDPMC_BASE_NB;
- uncore_nb->msr_base = MSR_F15H_NB_PERF_CTL;
- uncore_nb->active_mask = &amd_nb_active_mask;
- uncore_nb->pmu = &amd_nb_pmu;
- *per_cpu_ptr(amd_uncore_nb, cpu) = uncore_nb;
- }
-
- if (amd_uncore_l2) {
- uncore_l2 = amd_uncore_alloc(cpu);
- if (!uncore_l2)
- goto fail;
- uncore_l2->cpu = cpu;
- uncore_l2->num_counters = NUM_COUNTERS_L2;
- uncore_l2->rdpmc_base = RDPMC_BASE_L2;
- uncore_l2->msr_base = MSR_F16H_L2I_PERF_CTL;
- uncore_l2->active_mask = &amd_l2_active_mask;
- uncore_l2->pmu = &amd_l2_pmu;
- *per_cpu_ptr(amd_uncore_l2, cpu) = uncore_l2;
- }
-
- return 0;
-
-fail:
- kfree(uncore_nb);
- return -ENOMEM;
-}
-
-static struct amd_uncore *
-amd_uncore_find_online_sibling(struct amd_uncore *this,
- struct amd_uncore * __percpu *uncores)
-{
- unsigned int cpu;
- struct amd_uncore *that;
-
- for_each_online_cpu(cpu) {
- that = *per_cpu_ptr(uncores, cpu);
-
- if (!that)
- continue;
-
- if (this == that)
- continue;
-
- if (this->id == that->id) {
- that->free_when_cpu_online = this;
- this = that;
- break;
- }
- }
-
- this->refcnt++;
- return this;
-}
-
-static void amd_uncore_cpu_starting(unsigned int cpu)
-{
- unsigned int eax, ebx, ecx, edx;
- struct amd_uncore *uncore;
-
- if (amd_uncore_nb) {
- uncore = *per_cpu_ptr(amd_uncore_nb, cpu);
- cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
- uncore->id = ecx & 0xff;
-
- uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_nb);
- *per_cpu_ptr(amd_uncore_nb, cpu) = uncore;
- }
-
- if (amd_uncore_l2) {
- unsigned int apicid = cpu_data(cpu).apicid;
- unsigned int nshared;
-
- uncore = *per_cpu_ptr(amd_uncore_l2, cpu);
- cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx);
- nshared = ((eax >> 14) & 0xfff) + 1;
- uncore->id = apicid - (apicid % nshared);
-
- uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2);
- *per_cpu_ptr(amd_uncore_l2, cpu) = uncore;
- }
-}
-
-static void uncore_online(unsigned int cpu,
- struct amd_uncore * __percpu *uncores)
-{
- struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
-
- kfree(uncore->free_when_cpu_online);
- uncore->free_when_cpu_online = NULL;
-
- if (cpu == uncore->cpu)
- cpumask_set_cpu(cpu, uncore->active_mask);
-}
-
-static void amd_uncore_cpu_online(unsigned int cpu)
-{
- if (amd_uncore_nb)
- uncore_online(cpu, amd_uncore_nb);
-
- if (amd_uncore_l2)
- uncore_online(cpu, amd_uncore_l2);
-}
-
-static void uncore_down_prepare(unsigned int cpu,
- struct amd_uncore * __percpu *uncores)
-{
- unsigned int i;
- struct amd_uncore *this = *per_cpu_ptr(uncores, cpu);
-
- if (this->cpu != cpu)
- return;
-
- /* this cpu is going down, migrate to a shared sibling if possible */
- for_each_online_cpu(i) {
- struct amd_uncore *that = *per_cpu_ptr(uncores, i);
-
- if (cpu == i)
- continue;
-
- if (this == that) {
- perf_pmu_migrate_context(this->pmu, cpu, i);
- cpumask_clear_cpu(cpu, that->active_mask);
- cpumask_set_cpu(i, that->active_mask);
- that->cpu = i;
- break;
- }
- }
-}
-
-static void amd_uncore_cpu_down_prepare(unsigned int cpu)
-{
- if (amd_uncore_nb)
- uncore_down_prepare(cpu, amd_uncore_nb);
-
- if (amd_uncore_l2)
- uncore_down_prepare(cpu, amd_uncore_l2);
-}
-
-static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
-{
- struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
-
- if (cpu == uncore->cpu)
- cpumask_clear_cpu(cpu, uncore->active_mask);
-
- if (!--uncore->refcnt)
- kfree(uncore);
- *per_cpu_ptr(uncores, cpu) = NULL;
-}
-
-static void amd_uncore_cpu_dead(unsigned int cpu)
-{
- if (amd_uncore_nb)
- uncore_dead(cpu, amd_uncore_nb);
-
- if (amd_uncore_l2)
- uncore_dead(cpu, amd_uncore_l2);
-}
-
-static int
-amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
- void *hcpu)
-{
- unsigned int cpu = (long)hcpu;
-
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_UP_PREPARE:
- if (amd_uncore_cpu_up_prepare(cpu))
- return notifier_from_errno(-ENOMEM);
- break;
-
- case CPU_STARTING:
- amd_uncore_cpu_starting(cpu);
- break;
-
- case CPU_ONLINE:
- amd_uncore_cpu_online(cpu);
- break;
-
- case CPU_DOWN_PREPARE:
- amd_uncore_cpu_down_prepare(cpu);
- break;
-
- case CPU_UP_CANCELED:
- case CPU_DEAD:
- amd_uncore_cpu_dead(cpu);
- break;
-
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block amd_uncore_cpu_notifier_block = {
- .notifier_call = amd_uncore_cpu_notifier,
- .priority = CPU_PRI_PERF + 1,
-};
-
-static void __init init_cpu_already_online(void *dummy)
-{
- unsigned int cpu = smp_processor_id();
-
- amd_uncore_cpu_starting(cpu);
- amd_uncore_cpu_online(cpu);
-}
-
-static void cleanup_cpu_online(void *dummy)
-{
- unsigned int cpu = smp_processor_id();
-
- amd_uncore_cpu_dead(cpu);
-}
-
-static int __init amd_uncore_init(void)
-{
- unsigned int cpu, cpu2;
- int ret = -ENODEV;
-
- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
- goto fail_nodev;
-
- if (!cpu_has_topoext)
- goto fail_nodev;
-
- if (cpu_has_perfctr_nb) {
- amd_uncore_nb = alloc_percpu(struct amd_uncore *);
- if (!amd_uncore_nb) {
- ret = -ENOMEM;
- goto fail_nb;
- }
- ret = perf_pmu_register(&amd_nb_pmu, amd_nb_pmu.name, -1);
- if (ret)
- goto fail_nb;
-
- printk(KERN_INFO "perf: AMD NB counters detected\n");
- ret = 0;
- }
-
- if (cpu_has_perfctr_l2) {
- amd_uncore_l2 = alloc_percpu(struct amd_uncore *);
- if (!amd_uncore_l2) {
- ret = -ENOMEM;
- goto fail_l2;
- }
- ret = perf_pmu_register(&amd_l2_pmu, amd_l2_pmu.name, -1);
- if (ret)
- goto fail_l2;
-
- printk(KERN_INFO "perf: AMD L2I counters detected\n");
- ret = 0;
- }
-
- if (ret)
- goto fail_nodev;
-
- cpu_notifier_register_begin();
-
- /* init cpus already online before registering for hotplug notifier */
- for_each_online_cpu(cpu) {
- ret = amd_uncore_cpu_up_prepare(cpu);
- if (ret)
- goto fail_online;
- smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
- }
-
- __register_cpu_notifier(&amd_uncore_cpu_notifier_block);
- cpu_notifier_register_done();
-
- return 0;
-
-
-fail_online:
- for_each_online_cpu(cpu2) {
- if (cpu2 == cpu)
- break;
- smp_call_function_single(cpu, cleanup_cpu_online, NULL, 1);
- }
- cpu_notifier_register_done();
-
- /* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */
- amd_uncore_nb = amd_uncore_l2 = NULL;
- if (cpu_has_perfctr_l2)
- perf_pmu_unregister(&amd_l2_pmu);
-fail_l2:
- if (cpu_has_perfctr_nb)
- perf_pmu_unregister(&amd_nb_pmu);
- if (amd_uncore_l2)
- free_percpu(amd_uncore_l2);
-fail_nb:
- if (amd_uncore_nb)
- free_percpu(amd_uncore_nb);
-
-fail_nodev:
- return ret;
-}
-device_initcall(amd_uncore_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
deleted file mode 100644
index f63360b..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ /dev/null
@@ -1,3669 +0,0 @@
-/*
- * Per core/cpu state
- *
- * Used to coordinate shared registers between HT threads or
- * among events on a single PMU.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/stddef.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/nmi.h>
-
-#include <asm/cpufeature.h>
-#include <asm/hardirq.h>
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-/*
- * Intel PerfMon, used on Core and later.
- */
-static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
-{
- [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
- [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
- [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
- [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
- [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
- [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
- [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */
-};
-
-static struct event_constraint intel_core_event_constraints[] __read_mostly =
-{
- INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
- INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
- INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
- INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
- INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
- INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_core2_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
- INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
- INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
- INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
- INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
- INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
- INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
- INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
- INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
- INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
- INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
- INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
- INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
- INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
- INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
- INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
- INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
- EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
-{
- /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
- INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
- EVENT_EXTRA_END
-};
-
-static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
- INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
- INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
- INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_snb_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
- INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x06a3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
- INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
- INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
- INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
- INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */
- INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
-
- INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
- INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
- INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
- INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
- INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
-
- INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
- EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
-{
- /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
- INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1),
- INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b),
- EVENT_EXTRA_END
-};
-
-static struct event_constraint intel_v1_event_constraints[] __read_mostly =
-{
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_gen_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_slm_event_constraints[] __read_mostly =
-{
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_skl_event_constraints[] = {
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_UEVENT_CONSTRAINT(0x1c0, 0x2), /* INST_RETIRED.PREC_DIST */
- EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
- /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0),
- INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1),
- INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
- EVENT_EXTRA_END
-};
-
-static struct extra_reg intel_snbep_extra_regs[] __read_mostly = {
- /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
- INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
- INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
- EVENT_EXTRA_END
-};
-
-static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0),
- INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1),
- INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
- /*
- * Note the low 8 bits eventsel code is not a continuous field, containing
- * some #GPing bits. These are masked out.
- */
- INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
- EVENT_EXTRA_END
-};
-
-EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
-EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
-
-struct attribute *nhm_events_attrs[] = {
- EVENT_PTR(mem_ld_nhm),
- NULL,
-};
-
-struct attribute *snb_events_attrs[] = {
- EVENT_PTR(mem_ld_snb),
- EVENT_PTR(mem_st_snb),
- NULL,
-};
-
-static struct event_constraint intel_hsw_event_constraints[] = {
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.* */
- INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
- INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
- /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4),
- /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
- INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
- /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
- INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf),
-
- INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
-
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_bdw_event_constraints[] = {
- FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
- FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
- FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
- INTEL_UEVENT_CONSTRAINT(0x148, 0x4), /* L1D_PEND_MISS.PENDING */
- INTEL_UEVENT_CONSTRAINT(0x8a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_MISS */
- EVENT_CONSTRAINT_END
-};
-
-static u64 intel_pmu_event_map(int hw_event)
-{
- return intel_perfmon_event_map[hw_event];
-}
-
-/*
- * Notes on the events:
- * - data reads do not include code reads (comparable to earlier tables)
- * - data counts include speculative execution (except L1 write, dtlb, bpu)
- * - remote node access includes remote memory, remote cache, remote mmio.
- * - prefetches are not included in the counts.
- * - icache miss does not include decoded icache
- */
-
-#define SKL_DEMAND_DATA_RD BIT_ULL(0)
-#define SKL_DEMAND_RFO BIT_ULL(1)
-#define SKL_ANY_RESPONSE BIT_ULL(16)
-#define SKL_SUPPLIER_NONE BIT_ULL(17)
-#define SKL_L3_MISS_LOCAL_DRAM BIT_ULL(26)
-#define SKL_L3_MISS_REMOTE_HOP0_DRAM BIT_ULL(27)
-#define SKL_L3_MISS_REMOTE_HOP1_DRAM BIT_ULL(28)
-#define SKL_L3_MISS_REMOTE_HOP2P_DRAM BIT_ULL(29)
-#define SKL_L3_MISS (SKL_L3_MISS_LOCAL_DRAM| \
- SKL_L3_MISS_REMOTE_HOP0_DRAM| \
- SKL_L3_MISS_REMOTE_HOP1_DRAM| \
- SKL_L3_MISS_REMOTE_HOP2P_DRAM)
-#define SKL_SPL_HIT BIT_ULL(30)
-#define SKL_SNOOP_NONE BIT_ULL(31)
-#define SKL_SNOOP_NOT_NEEDED BIT_ULL(32)
-#define SKL_SNOOP_MISS BIT_ULL(33)
-#define SKL_SNOOP_HIT_NO_FWD BIT_ULL(34)
-#define SKL_SNOOP_HIT_WITH_FWD BIT_ULL(35)
-#define SKL_SNOOP_HITM BIT_ULL(36)
-#define SKL_SNOOP_NON_DRAM BIT_ULL(37)
-#define SKL_ANY_SNOOP (SKL_SPL_HIT|SKL_SNOOP_NONE| \
- SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
- SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
- SKL_SNOOP_HITM|SKL_SNOOP_NON_DRAM)
-#define SKL_DEMAND_READ SKL_DEMAND_DATA_RD
-#define SKL_SNOOP_DRAM (SKL_SNOOP_NONE| \
- SKL_SNOOP_NOT_NEEDED|SKL_SNOOP_MISS| \
- SKL_SNOOP_HIT_NO_FWD|SKL_SNOOP_HIT_WITH_FWD| \
- SKL_SNOOP_HITM|SKL_SPL_HIT)
-#define SKL_DEMAND_WRITE SKL_DEMAND_RFO
-#define SKL_LLC_ACCESS SKL_ANY_RESPONSE
-#define SKL_L3_MISS_REMOTE (SKL_L3_MISS_REMOTE_HOP0_DRAM| \
- SKL_L3_MISS_REMOTE_HOP1_DRAM| \
- SKL_L3_MISS_REMOTE_HOP2P_DRAM)
-
-static __initconst const u64 skl_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_INST_RETIRED.ALL_LOADS */
- [ C(RESULT_MISS) ] = 0x151, /* L1D.REPLACEMENT */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_INST_RETIRED.ALL_STORES */
- [ C(RESULT_MISS) ] = 0x0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x283, /* ICACHE_64B.MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_INST_RETIRED.ALL_LOADS */
- [ C(RESULT_MISS) ] = 0x608, /* DTLB_LOAD_MISSES.WALK_COMPLETED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_INST_RETIRED.ALL_STORES */
- [ C(RESULT_MISS) ] = 0x649, /* DTLB_STORE_MISSES.WALK_COMPLETED */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x2085, /* ITLB_MISSES.STLB_HIT */
- [ C(RESULT_MISS) ] = 0xe85, /* ITLB_MISSES.WALK_COMPLETED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0xc4, /* BR_INST_RETIRED.ALL_BRANCHES */
- [ C(RESULT_MISS) ] = 0xc5, /* BR_MISP_RETIRED.ALL_BRANCHES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
-};
-
-static __initconst const u64 skl_hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
- SKL_LLC_ACCESS|SKL_ANY_SNOOP,
- [ C(RESULT_MISS) ] = SKL_DEMAND_READ|
- SKL_L3_MISS|SKL_ANY_SNOOP|
- SKL_SUPPLIER_NONE,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
- SKL_LLC_ACCESS|SKL_ANY_SNOOP,
- [ C(RESULT_MISS) ] = SKL_DEMAND_WRITE|
- SKL_L3_MISS|SKL_ANY_SNOOP|
- SKL_SUPPLIER_NONE,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = SKL_DEMAND_READ|
- SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
- [ C(RESULT_MISS) ] = SKL_DEMAND_READ|
- SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = SKL_DEMAND_WRITE|
- SKL_L3_MISS_LOCAL_DRAM|SKL_SNOOP_DRAM,
- [ C(RESULT_MISS) ] = SKL_DEMAND_WRITE|
- SKL_L3_MISS_REMOTE|SKL_SNOOP_DRAM,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
-};
-
-#define SNB_DMND_DATA_RD (1ULL << 0)
-#define SNB_DMND_RFO (1ULL << 1)
-#define SNB_DMND_IFETCH (1ULL << 2)
-#define SNB_DMND_WB (1ULL << 3)
-#define SNB_PF_DATA_RD (1ULL << 4)
-#define SNB_PF_RFO (1ULL << 5)
-#define SNB_PF_IFETCH (1ULL << 6)
-#define SNB_LLC_DATA_RD (1ULL << 7)
-#define SNB_LLC_RFO (1ULL << 8)
-#define SNB_LLC_IFETCH (1ULL << 9)
-#define SNB_BUS_LOCKS (1ULL << 10)
-#define SNB_STRM_ST (1ULL << 11)
-#define SNB_OTHER (1ULL << 15)
-#define SNB_RESP_ANY (1ULL << 16)
-#define SNB_NO_SUPP (1ULL << 17)
-#define SNB_LLC_HITM (1ULL << 18)
-#define SNB_LLC_HITE (1ULL << 19)
-#define SNB_LLC_HITS (1ULL << 20)
-#define SNB_LLC_HITF (1ULL << 21)
-#define SNB_LOCAL (1ULL << 22)
-#define SNB_REMOTE (0xffULL << 23)
-#define SNB_SNP_NONE (1ULL << 31)
-#define SNB_SNP_NOT_NEEDED (1ULL << 32)
-#define SNB_SNP_MISS (1ULL << 33)
-#define SNB_NO_FWD (1ULL << 34)
-#define SNB_SNP_FWD (1ULL << 35)
-#define SNB_HITM (1ULL << 36)
-#define SNB_NON_DRAM (1ULL << 37)
-
-#define SNB_DMND_READ (SNB_DMND_DATA_RD|SNB_LLC_DATA_RD)
-#define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO)
-#define SNB_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
-
-#define SNB_SNP_ANY (SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \
- SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \
- SNB_HITM)
-
-#define SNB_DRAM_ANY (SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY)
-#define SNB_DRAM_REMOTE (SNB_REMOTE|SNB_SNP_ANY)
-
-#define SNB_L3_ACCESS SNB_RESP_ANY
-#define SNB_L3_MISS (SNB_DRAM_ANY|SNB_NON_DRAM)
-
-static __initconst const u64 snb_hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS,
- [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_L3_MISS,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS,
- [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_L3_MISS,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,
- [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY,
- [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_DRAM_REMOTE,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY,
- [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY,
- [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE,
- },
- },
-};
-
-static __initconst const u64 snb_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */
- [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */
- [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_WRITE) ] = {
- /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */
- [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */
- [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */
- [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
- [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
-
-};
-
-/*
- * Notes on the events:
- * - data reads do not include code reads (comparable to earlier tables)
- * - data counts include speculative execution (except L1 write, dtlb, bpu)
- * - remote node access includes remote memory, remote cache, remote mmio.
- * - prefetches are not included in the counts because they are not
- * reliably counted.
- */
-
-#define HSW_DEMAND_DATA_RD BIT_ULL(0)
-#define HSW_DEMAND_RFO BIT_ULL(1)
-#define HSW_ANY_RESPONSE BIT_ULL(16)
-#define HSW_SUPPLIER_NONE BIT_ULL(17)
-#define HSW_L3_MISS_LOCAL_DRAM BIT_ULL(22)
-#define HSW_L3_MISS_REMOTE_HOP0 BIT_ULL(27)
-#define HSW_L3_MISS_REMOTE_HOP1 BIT_ULL(28)
-#define HSW_L3_MISS_REMOTE_HOP2P BIT_ULL(29)
-#define HSW_L3_MISS (HSW_L3_MISS_LOCAL_DRAM| \
- HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
- HSW_L3_MISS_REMOTE_HOP2P)
-#define HSW_SNOOP_NONE BIT_ULL(31)
-#define HSW_SNOOP_NOT_NEEDED BIT_ULL(32)
-#define HSW_SNOOP_MISS BIT_ULL(33)
-#define HSW_SNOOP_HIT_NO_FWD BIT_ULL(34)
-#define HSW_SNOOP_HIT_WITH_FWD BIT_ULL(35)
-#define HSW_SNOOP_HITM BIT_ULL(36)
-#define HSW_SNOOP_NON_DRAM BIT_ULL(37)
-#define HSW_ANY_SNOOP (HSW_SNOOP_NONE| \
- HSW_SNOOP_NOT_NEEDED|HSW_SNOOP_MISS| \
- HSW_SNOOP_HIT_NO_FWD|HSW_SNOOP_HIT_WITH_FWD| \
- HSW_SNOOP_HITM|HSW_SNOOP_NON_DRAM)
-#define HSW_SNOOP_DRAM (HSW_ANY_SNOOP & ~HSW_SNOOP_NON_DRAM)
-#define HSW_DEMAND_READ HSW_DEMAND_DATA_RD
-#define HSW_DEMAND_WRITE HSW_DEMAND_RFO
-#define HSW_L3_MISS_REMOTE (HSW_L3_MISS_REMOTE_HOP0|\
- HSW_L3_MISS_REMOTE_HOP1|HSW_L3_MISS_REMOTE_HOP2P)
-#define HSW_LLC_ACCESS HSW_ANY_RESPONSE
-
-#define BDW_L3_MISS_LOCAL BIT(26)
-#define BDW_L3_MISS (BDW_L3_MISS_LOCAL| \
- HSW_L3_MISS_REMOTE_HOP0|HSW_L3_MISS_REMOTE_HOP1| \
- HSW_L3_MISS_REMOTE_HOP2P)
-
-
-static __initconst const u64 hsw_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
- [ C(RESULT_MISS) ] = 0x151, /* L1D.REPLACEMENT */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
- [ C(RESULT_MISS) ] = 0x0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x280, /* ICACHE.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
- [ C(RESULT_MISS) ] = 0x108, /* DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
- [ C(RESULT_MISS) ] = 0x149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x6085, /* ITLB_MISSES.STLB_HIT */
- [ C(RESULT_MISS) ] = 0x185, /* ITLB_MISSES.MISS_CAUSES_A_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0xc4, /* BR_INST_RETIRED.ALL_BRANCHES */
- [ C(RESULT_MISS) ] = 0xc5, /* BR_MISP_RETIRED.ALL_BRANCHES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- [ C(RESULT_MISS) ] = 0x1b7, /* OFFCORE_RESPONSE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
-};
-
-static __initconst const u64 hsw_hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
- HSW_LLC_ACCESS,
- [ C(RESULT_MISS) ] = HSW_DEMAND_READ|
- HSW_L3_MISS|HSW_ANY_SNOOP,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
- HSW_LLC_ACCESS,
- [ C(RESULT_MISS) ] = HSW_DEMAND_WRITE|
- HSW_L3_MISS|HSW_ANY_SNOOP,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = HSW_DEMAND_READ|
- HSW_L3_MISS_LOCAL_DRAM|
- HSW_SNOOP_DRAM,
- [ C(RESULT_MISS) ] = HSW_DEMAND_READ|
- HSW_L3_MISS_REMOTE|
- HSW_SNOOP_DRAM,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = HSW_DEMAND_WRITE|
- HSW_L3_MISS_LOCAL_DRAM|
- HSW_SNOOP_DRAM,
- [ C(RESULT_MISS) ] = HSW_DEMAND_WRITE|
- HSW_L3_MISS_REMOTE|
- HSW_SNOOP_DRAM,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
-};
-
-static __initconst const u64 westmere_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
- [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
- [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
- [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
- [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- /*
- * Use RFO, not WRITEBACK, because a write miss would typically occur
- * on RFO.
- */
- [ C(OP_WRITE) ] = {
- /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
- [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
- [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
- [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
- [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
-};
-
-/*
- * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
- * See IA32 SDM Vol 3B 30.6.1.3
- */
-
-#define NHM_DMND_DATA_RD (1 << 0)
-#define NHM_DMND_RFO (1 << 1)
-#define NHM_DMND_IFETCH (1 << 2)
-#define NHM_DMND_WB (1 << 3)
-#define NHM_PF_DATA_RD (1 << 4)
-#define NHM_PF_DATA_RFO (1 << 5)
-#define NHM_PF_IFETCH (1 << 6)
-#define NHM_OFFCORE_OTHER (1 << 7)
-#define NHM_UNCORE_HIT (1 << 8)
-#define NHM_OTHER_CORE_HIT_SNP (1 << 9)
-#define NHM_OTHER_CORE_HITM (1 << 10)
- /* reserved */
-#define NHM_REMOTE_CACHE_FWD (1 << 12)
-#define NHM_REMOTE_DRAM (1 << 13)
-#define NHM_LOCAL_DRAM (1 << 14)
-#define NHM_NON_DRAM (1 << 15)
-
-#define NHM_LOCAL (NHM_LOCAL_DRAM|NHM_REMOTE_CACHE_FWD)
-#define NHM_REMOTE (NHM_REMOTE_DRAM)
-
-#define NHM_DMND_READ (NHM_DMND_DATA_RD)
-#define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB)
-#define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
-
-#define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
-#define NHM_L3_MISS (NHM_NON_DRAM|NHM_LOCAL_DRAM|NHM_REMOTE_DRAM|NHM_REMOTE_CACHE_FWD)
-#define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS)
-
-static __initconst const u64 nehalem_hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
- [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
- [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
- [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_LOCAL|NHM_REMOTE,
- [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_LOCAL|NHM_REMOTE,
- [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_LOCAL|NHM_REMOTE,
- [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE,
- },
- },
-};
-
-static __initconst const u64 nehalem_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
- [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
- [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
- [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
- [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- /*
- * Use RFO, not WRITEBACK, because a write miss would typically occur
- * on RFO.
- */
- [ C(OP_WRITE) ] = {
- /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
- [ C(RESULT_MISS) ] = 0x20c8, /* ITLB_MISS_RETIRED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
- [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
-};
-
-static __initconst const u64 core2_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */
- [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */
- [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS */
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS */
- [ C(RESULT_MISS) ] = 0x0081, /* L1I.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
- [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
- [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x0208, /* DTLB_MISSES.MISS_LD */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x0808, /* DTLB_MISSES.MISS_ST */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
- [ C(RESULT_MISS) ] = 0x1282, /* ITLBMISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
- [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-static __initconst const u64 atom_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
- [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
- [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
- [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x0508, /* DTLB_MISSES.MISS_LD */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI (alias) */
- [ C(RESULT_MISS) ] = 0x0608, /* DTLB_MISSES.MISS_ST */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
- [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
- [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-static struct extra_reg intel_slm_extra_regs[] __read_mostly =
-{
- /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
- INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x768005ffffull, RSP_0),
- INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x368005ffffull, RSP_1),
- EVENT_EXTRA_END
-};
-
-#define SLM_DMND_READ SNB_DMND_DATA_RD
-#define SLM_DMND_WRITE SNB_DMND_RFO
-#define SLM_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
-
-#define SLM_SNP_ANY (SNB_SNP_NONE|SNB_SNP_MISS|SNB_NO_FWD|SNB_HITM)
-#define SLM_LLC_ACCESS SNB_RESP_ANY
-#define SLM_LLC_MISS (SLM_SNP_ANY|SNB_NON_DRAM)
-
-static __initconst const u64 slm_hw_cache_extra_regs
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
- [ C(RESULT_MISS) ] = SLM_DMND_WRITE|SLM_LLC_MISS,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = SLM_DMND_PREFETCH|SLM_LLC_ACCESS,
- [ C(RESULT_MISS) ] = SLM_DMND_PREFETCH|SLM_LLC_MISS,
- },
- },
-};
-
-static __initconst const u64 slm_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0x0104, /* LD_DCU_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0380, /* ICACHE.ACCESSES */
- [ C(RESULT_MISS) ] = 0x0280, /* ICACGE.MISSES */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_WRITE) ] = {
- /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- [ C(OP_PREFETCH) ] = {
- /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
- [ C(RESULT_ACCESS) ] = 0x01b7,
- /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
- [ C(RESULT_MISS) ] = 0x01b7,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0x0804, /* LD_DTLB_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
- [ C(RESULT_MISS) ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
- [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-/*
- * Use from PMIs where the LBRs are already disabled.
- */
-static void __intel_pmu_disable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-
- if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
- intel_pmu_disable_bts();
- else
- intel_bts_disable_local();
-
- intel_pmu_pebs_disable_all();
-}
-
-static void intel_pmu_disable_all(void)
-{
- __intel_pmu_disable_all();
- intel_pmu_lbr_disable_all();
-}
-
-static void __intel_pmu_enable_all(int added, bool pmi)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- intel_pmu_pebs_enable_all();
- intel_pmu_lbr_enable_all(pmi);
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
- x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
-
- if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
- struct perf_event *event =
- cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
-
- if (WARN_ON_ONCE(!event))
- return;
-
- intel_pmu_enable_bts(event->hw.config);
- } else
- intel_bts_enable_local();
-}
-
-static void intel_pmu_enable_all(int added)
-{
- __intel_pmu_enable_all(added, false);
-}
-
-/*
- * Workaround for:
- * Intel Errata AAK100 (model 26)
- * Intel Errata AAP53 (model 30)
- * Intel Errata BD53 (model 44)
- *
- * The official story:
- * These chips need to be 'reset' when adding counters by programming the
- * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
- * in sequence on the same PMC or on different PMCs.
- *
- * In practise it appears some of these events do in fact count, and
- * we need to programm all 4 events.
- */
-static void intel_pmu_nhm_workaround(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- static const unsigned long nhm_magic[4] = {
- 0x4300B5,
- 0x4300D2,
- 0x4300B1,
- 0x4300B1
- };
- struct perf_event *event;
- int i;
-
- /*
- * The Errata requires below steps:
- * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
- * 2) Configure 4 PERFEVTSELx with the magic events and clear
- * the corresponding PMCx;
- * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
- * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
- * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
- */
-
- /*
- * The real steps we choose are a little different from above.
- * A) To reduce MSR operations, we don't run step 1) as they
- * are already cleared before this function is called;
- * B) Call x86_perf_event_update to save PMCx before configuring
- * PERFEVTSELx with magic number;
- * C) With step 5), we do clear only when the PERFEVTSELx is
- * not used currently.
- * D) Call x86_perf_event_set_period to restore PMCx;
- */
-
- /* We always operate 4 pairs of PERF Counters */
- for (i = 0; i < 4; i++) {
- event = cpuc->events[i];
- if (event)
- x86_perf_event_update(event);
- }
-
- for (i = 0; i < 4; i++) {
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
- wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
- }
-
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
-
- for (i = 0; i < 4; i++) {
- event = cpuc->events[i];
-
- if (event) {
- x86_perf_event_set_period(event);
- __x86_pmu_enable_event(&event->hw,
- ARCH_PERFMON_EVENTSEL_ENABLE);
- } else
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
- }
-}
-
-static void intel_pmu_nhm_enable_all(int added)
-{
- if (added)
- intel_pmu_nhm_workaround();
- intel_pmu_enable_all(added);
-}
-
-static inline u64 intel_pmu_get_status(void)
-{
- u64 status;
-
- rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
-
- return status;
-}
-
-static inline void intel_pmu_ack_status(u64 ack)
-{
- wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
-}
-
-static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
-{
- int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
- u64 ctrl_val, mask;
-
- mask = 0xfULL << (idx * 4);
-
- rdmsrl(hwc->config_base, ctrl_val);
- ctrl_val &= ~mask;
- wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static inline bool event_is_checkpointed(struct perf_event *event)
-{
- return (event->hw.config & HSW_IN_TX_CHECKPOINTED) != 0;
-}
-
-static void intel_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
- intel_pmu_disable_bts();
- intel_pmu_drain_bts_buffer();
- return;
- }
-
- cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
- cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
- cpuc->intel_cp_status &= ~(1ull << hwc->idx);
-
- /*
- * must disable before any actual event
- * because any event may be combined with LBR
- */
- if (needs_branch_stack(event))
- intel_pmu_lbr_disable(event);
-
- if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
- intel_pmu_disable_fixed(hwc);
- return;
- }
-
- x86_pmu_disable_event(event);
-
- if (unlikely(event->attr.precise_ip))
- intel_pmu_pebs_disable(event);
-}
-
-static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
-{
- int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
- u64 ctrl_val, bits, mask;
-
- /*
- * Enable IRQ generation (0x8),
- * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
- * if requested:
- */
- bits = 0x8ULL;
- if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
- bits |= 0x2;
- if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
- bits |= 0x1;
-
- /*
- * ANY bit is supported in v3 and up
- */
- if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
- bits |= 0x4;
-
- bits <<= (idx * 4);
- mask = 0xfULL << (idx * 4);
-
- rdmsrl(hwc->config_base, ctrl_val);
- ctrl_val &= ~mask;
- ctrl_val |= bits;
- wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static void intel_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
- if (!__this_cpu_read(cpu_hw_events.enabled))
- return;
-
- intel_pmu_enable_bts(hwc->config);
- return;
- }
- /*
- * must enabled before any actual event
- * because any event may be combined with LBR
- */
- if (needs_branch_stack(event))
- intel_pmu_lbr_enable(event);
-
- if (event->attr.exclude_host)
- cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx);
- if (event->attr.exclude_guest)
- cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
-
- if (unlikely(event_is_checkpointed(event)))
- cpuc->intel_cp_status |= (1ull << hwc->idx);
-
- if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
- intel_pmu_enable_fixed(hwc);
- return;
- }
-
- if (unlikely(event->attr.precise_ip))
- intel_pmu_pebs_enable(event);
-
- __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
-}
-
-/*
- * Save and restart an expired event. Called by NMI contexts,
- * so it has to be careful about preempting normal event ops:
- */
-int intel_pmu_save_and_restart(struct perf_event *event)
-{
- x86_perf_event_update(event);
- /*
- * For a checkpointed counter always reset back to 0. This
- * avoids a situation where the counter overflows, aborts the
- * transaction and is then set back to shortly before the
- * overflow, and overflows and aborts again.
- */
- if (unlikely(event_is_checkpointed(event))) {
- /* No race with NMIs because the counter should not be armed */
- wrmsrl(event->hw.event_base, 0);
- local64_set(&event->hw.prev_count, 0);
- }
- return x86_perf_event_set_period(event);
-}
-
-static void intel_pmu_reset(void)
-{
- struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
- unsigned long flags;
- int idx;
-
- if (!x86_pmu.num_counters)
- return;
-
- local_irq_save(flags);
-
- pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
- wrmsrl_safe(x86_pmu_event_addr(idx), 0ull);
- }
- for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
- wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-
- if (ds)
- ds->bts_index = ds->bts_buffer_base;
-
- /* Ack all overflows and disable fixed counters */
- if (x86_pmu.version >= 2) {
- intel_pmu_ack_status(intel_pmu_get_status());
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
- }
-
- /* Reset LBRs and LBR freezing */
- if (x86_pmu.lbr_nr) {
- update_debugctlmsr(get_debugctlmsr() &
- ~(DEBUGCTLMSR_FREEZE_LBRS_ON_PMI|DEBUGCTLMSR_LBR));
- }
-
- local_irq_restore(flags);
-}
-
-/*
- * This handler is triggered by the local APIC, so the APIC IRQ handling
- * rules apply:
- */
-static int intel_pmu_handle_irq(struct pt_regs *regs)
-{
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- int bit, loops;
- u64 status;
- int handled;
-
- cpuc = this_cpu_ptr(&cpu_hw_events);
-
- /*
- * No known reason to not always do late ACK,
- * but just in case do it opt-in.
- */
- if (!x86_pmu.late_ack)
- apic_write(APIC_LVTPC, APIC_DM_NMI);
- __intel_pmu_disable_all();
- handled = intel_pmu_drain_bts_buffer();
- handled += intel_bts_interrupt();
- status = intel_pmu_get_status();
- if (!status)
- goto done;
-
- loops = 0;
-again:
- intel_pmu_lbr_read();
- intel_pmu_ack_status(status);
- if (++loops > 100) {
- static bool warned = false;
- if (!warned) {
- WARN(1, "perfevents: irq loop stuck!\n");
- perf_event_print_debug();
- warned = true;
- }
- intel_pmu_reset();
- goto done;
- }
-
- inc_irq_stat(apic_perf_irqs);
-
-
- /*
- * Ignore a range of extra bits in status that do not indicate
- * overflow by themselves.
- */
- status &= ~(GLOBAL_STATUS_COND_CHG |
- GLOBAL_STATUS_ASIF |
- GLOBAL_STATUS_LBRS_FROZEN);
- if (!status)
- goto done;
-
- /*
- * PEBS overflow sets bit 62 in the global status register
- */
- if (__test_and_clear_bit(62, (unsigned long *)&status)) {
- handled++;
- x86_pmu.drain_pebs(regs);
- }
-
- /*
- * Intel PT
- */
- if (__test_and_clear_bit(55, (unsigned long *)&status)) {
- handled++;
- intel_pt_interrupt();
- }
-
- /*
- * Checkpointed counters can lead to 'spurious' PMIs because the
- * rollback caused by the PMI will have cleared the overflow status
- * bit. Therefore always force probe these counters.
- */
- status |= cpuc->intel_cp_status;
-
- for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
- struct perf_event *event = cpuc->events[bit];
-
- handled++;
-
- if (!test_bit(bit, cpuc->active_mask))
- continue;
-
- if (!intel_pmu_save_and_restart(event))
- continue;
-
- perf_sample_data_init(&data, 0, event->hw.last_period);
-
- if (has_branch_stack(event))
- data.br_stack = &cpuc->lbr_stack;
-
- if (perf_event_overflow(event, &data, regs))
- x86_pmu_stop(event, 0);
- }
-
- /*
- * Repeat if there is more work to be done:
- */
- status = intel_pmu_get_status();
- if (status)
- goto again;
-
-done:
- __intel_pmu_enable_all(0, true);
- /*
- * Only unmask the NMI after the overflow counters
- * have been reset. This avoids spurious NMIs on
- * Haswell CPUs.
- */
- if (x86_pmu.late_ack)
- apic_write(APIC_LVTPC, APIC_DM_NMI);
- return handled;
-}
-
-static struct event_constraint *
-intel_bts_constraints(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- unsigned int hw_event, bts_event;
-
- if (event->attr.freq)
- return NULL;
-
- hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
- bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
-
- if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
- return &bts_constraint;
-
- return NULL;
-}
-
-static int intel_alt_er(int idx, u64 config)
-{
- int alt_idx;
- if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
- return idx;
-
- if (idx == EXTRA_REG_RSP_0)
- alt_idx = EXTRA_REG_RSP_1;
-
- if (idx == EXTRA_REG_RSP_1)
- alt_idx = EXTRA_REG_RSP_0;
-
- if (config & ~x86_pmu.extra_regs[alt_idx].valid_mask)
- return idx;
-
- return alt_idx;
-}
-
-static void intel_fixup_er(struct perf_event *event, int idx)
-{
- event->hw.extra_reg.idx = idx;
-
- if (idx == EXTRA_REG_RSP_0) {
- event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
- event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
- event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
- } else if (idx == EXTRA_REG_RSP_1) {
- event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
- event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
- event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
- }
-}
-
-/*
- * manage allocation of shared extra msr for certain events
- *
- * sharing can be:
- * per-cpu: to be shared between the various events on a single PMU
- * per-core: per-cpu + shared by HT threads
- */
-static struct event_constraint *
-__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event,
- struct hw_perf_event_extra *reg)
-{
- struct event_constraint *c = &emptyconstraint;
- struct er_account *era;
- unsigned long flags;
- int idx = reg->idx;
-
- /*
- * reg->alloc can be set due to existing state, so for fake cpuc we
- * need to ignore this, otherwise we might fail to allocate proper fake
- * state for this extra reg constraint. Also see the comment below.
- */
- if (reg->alloc && !cpuc->is_fake)
- return NULL; /* call x86_get_event_constraint() */
-
-again:
- era = &cpuc->shared_regs->regs[idx];
- /*
- * we use spin_lock_irqsave() to avoid lockdep issues when
- * passing a fake cpuc
- */
- raw_spin_lock_irqsave(&era->lock, flags);
-
- if (!atomic_read(&era->ref) || era->config == reg->config) {
-
- /*
- * If its a fake cpuc -- as per validate_{group,event}() we
- * shouldn't touch event state and we can avoid doing so
- * since both will only call get_event_constraints() once
- * on each event, this avoids the need for reg->alloc.
- *
- * Not doing the ER fixup will only result in era->reg being
- * wrong, but since we won't actually try and program hardware
- * this isn't a problem either.
- */
- if (!cpuc->is_fake) {
- if (idx != reg->idx)
- intel_fixup_er(event, idx);
-
- /*
- * x86_schedule_events() can call get_event_constraints()
- * multiple times on events in the case of incremental
- * scheduling(). reg->alloc ensures we only do the ER
- * allocation once.
- */
- reg->alloc = 1;
- }
-
- /* lock in msr value */
- era->config = reg->config;
- era->reg = reg->reg;
-
- /* one more user */
- atomic_inc(&era->ref);
-
- /*
- * need to call x86_get_event_constraint()
- * to check if associated event has constraints
- */
- c = NULL;
- } else {
- idx = intel_alt_er(idx, reg->config);
- if (idx != reg->idx) {
- raw_spin_unlock_irqrestore(&era->lock, flags);
- goto again;
- }
- }
- raw_spin_unlock_irqrestore(&era->lock, flags);
-
- return c;
-}
-
-static void
-__intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc,
- struct hw_perf_event_extra *reg)
-{
- struct er_account *era;
-
- /*
- * Only put constraint if extra reg was actually allocated. Also takes
- * care of event which do not use an extra shared reg.
- *
- * Also, if this is a fake cpuc we shouldn't touch any event state
- * (reg->alloc) and we don't care about leaving inconsistent cpuc state
- * either since it'll be thrown out.
- */
- if (!reg->alloc || cpuc->is_fake)
- return;
-
- era = &cpuc->shared_regs->regs[reg->idx];
-
- /* one fewer user */
- atomic_dec(&era->ref);
-
- /* allocate again next time */
- reg->alloc = 0;
-}
-
-static struct event_constraint *
-intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct event_constraint *c = NULL, *d;
- struct hw_perf_event_extra *xreg, *breg;
-
- xreg = &event->hw.extra_reg;
- if (xreg->idx != EXTRA_REG_NONE) {
- c = __intel_shared_reg_get_constraints(cpuc, event, xreg);
- if (c == &emptyconstraint)
- return c;
- }
- breg = &event->hw.branch_reg;
- if (breg->idx != EXTRA_REG_NONE) {
- d = __intel_shared_reg_get_constraints(cpuc, event, breg);
- if (d == &emptyconstraint) {
- __intel_shared_reg_put_constraints(cpuc, xreg);
- c = d;
- }
- }
- return c;
-}
-
-struct event_constraint *
-x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- struct event_constraint *c;
-
- if (x86_pmu.event_constraints) {
- for_each_event_constraint(c, x86_pmu.event_constraints) {
- if ((event->hw.config & c->cmask) == c->code) {
- event->hw.flags |= c->flags;
- return c;
- }
- }
- }
-
- return &unconstrained;
-}
-
-static struct event_constraint *
-__intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- struct event_constraint *c;
-
- c = intel_bts_constraints(event);
- if (c)
- return c;
-
- c = intel_shared_regs_constraints(cpuc, event);
- if (c)
- return c;
-
- c = intel_pebs_constraints(event);
- if (c)
- return c;
-
- return x86_get_event_constraints(cpuc, idx, event);
-}
-
-static void
-intel_start_scheduling(struct cpu_hw_events *cpuc)
-{
- struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
- struct intel_excl_states *xl;
- int tid = cpuc->excl_thread_id;
-
- /*
- * nothing needed if in group validation mode
- */
- if (cpuc->is_fake || !is_ht_workaround_enabled())
- return;
-
- /*
- * no exclusion needed
- */
- if (WARN_ON_ONCE(!excl_cntrs))
- return;
-
- xl = &excl_cntrs->states[tid];
-
- xl->sched_started = true;
- /*
- * lock shared state until we are done scheduling
- * in stop_event_scheduling()
- * makes scheduling appear as a transaction
- */
- raw_spin_lock(&excl_cntrs->lock);
-}
-
-static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cntr)
-{
- struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
- struct event_constraint *c = cpuc->event_constraint[idx];
- struct intel_excl_states *xl;
- int tid = cpuc->excl_thread_id;
-
- if (cpuc->is_fake || !is_ht_workaround_enabled())
- return;
-
- if (WARN_ON_ONCE(!excl_cntrs))
- return;
-
- if (!(c->flags & PERF_X86_EVENT_DYNAMIC))
- return;
-
- xl = &excl_cntrs->states[tid];
-
- lockdep_assert_held(&excl_cntrs->lock);
-
- if (c->flags & PERF_X86_EVENT_EXCL)
- xl->state[cntr] = INTEL_EXCL_EXCLUSIVE;
- else
- xl->state[cntr] = INTEL_EXCL_SHARED;
-}
-
-static void
-intel_stop_scheduling(struct cpu_hw_events *cpuc)
-{
- struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
- struct intel_excl_states *xl;
- int tid = cpuc->excl_thread_id;
-
- /*
- * nothing needed if in group validation mode
- */
- if (cpuc->is_fake || !is_ht_workaround_enabled())
- return;
- /*
- * no exclusion needed
- */
- if (WARN_ON_ONCE(!excl_cntrs))
- return;
-
- xl = &excl_cntrs->states[tid];
-
- xl->sched_started = false;
- /*
- * release shared state lock (acquired in intel_start_scheduling())
- */
- raw_spin_unlock(&excl_cntrs->lock);
-}
-
-static struct event_constraint *
-intel_get_excl_constraints(struct cpu_hw_events *cpuc, struct perf_event *event,
- int idx, struct event_constraint *c)
-{
- struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
- struct intel_excl_states *xlo;
- int tid = cpuc->excl_thread_id;
- int is_excl, i;
-
- /*
- * validating a group does not require
- * enforcing cross-thread exclusion
- */
- if (cpuc->is_fake || !is_ht_workaround_enabled())
- return c;
-
- /*
- * no exclusion needed
- */
- if (WARN_ON_ONCE(!excl_cntrs))
- return c;
-
- /*
- * because we modify the constraint, we need
- * to make a copy. Static constraints come
- * from static const tables.
- *
- * only needed when constraint has not yet
- * been cloned (marked dynamic)
- */
- if (!(c->flags & PERF_X86_EVENT_DYNAMIC)) {
- struct event_constraint *cx;
-
- /*
- * grab pre-allocated constraint entry
- */
- cx = &cpuc->constraint_list[idx];
-
- /*
- * initialize dynamic constraint
- * with static constraint
- */
- *cx = *c;
-
- /*
- * mark constraint as dynamic, so we
- * can free it later on
- */
- cx->flags |= PERF_X86_EVENT_DYNAMIC;
- c = cx;
- }
-
- /*
- * From here on, the constraint is dynamic.
- * Either it was just allocated above, or it
- * was allocated during a earlier invocation
- * of this function
- */
-
- /*
- * state of sibling HT
- */
- xlo = &excl_cntrs->states[tid ^ 1];
-
- /*
- * event requires exclusive counter access
- * across HT threads
- */
- is_excl = c->flags & PERF_X86_EVENT_EXCL;
- if (is_excl && !(event->hw.flags & PERF_X86_EVENT_EXCL_ACCT)) {
- event->hw.flags |= PERF_X86_EVENT_EXCL_ACCT;
- if (!cpuc->n_excl++)
- WRITE_ONCE(excl_cntrs->has_exclusive[tid], 1);
- }
-
- /*
- * Modify static constraint with current dynamic
- * state of thread
- *
- * EXCLUSIVE: sibling counter measuring exclusive event
- * SHARED : sibling counter measuring non-exclusive event
- * UNUSED : sibling counter unused
- */
- for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
- /*
- * exclusive event in sibling counter
- * our corresponding counter cannot be used
- * regardless of our event
- */
- if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
- __clear_bit(i, c->idxmsk);
- /*
- * if measuring an exclusive event, sibling
- * measuring non-exclusive, then counter cannot
- * be used
- */
- if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
- __clear_bit(i, c->idxmsk);
- }
-
- /*
- * recompute actual bit weight for scheduling algorithm
- */
- c->weight = hweight64(c->idxmsk64);
-
- /*
- * if we return an empty mask, then switch
- * back to static empty constraint to avoid
- * the cost of freeing later on
- */
- if (c->weight == 0)
- c = &emptyconstraint;
-
- return c;
-}
-
-static struct event_constraint *
-intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- struct event_constraint *c1 = NULL;
- struct event_constraint *c2;
-
- if (idx >= 0) /* fake does < 0 */
- c1 = cpuc->event_constraint[idx];
-
- /*
- * first time only
- * - static constraint: no change across incremental scheduling calls
- * - dynamic constraint: handled by intel_get_excl_constraints()
- */
- c2 = __intel_get_event_constraints(cpuc, idx, event);
- if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) {
- bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX);
- c1->weight = c2->weight;
- c2 = c1;
- }
-
- if (cpuc->excl_cntrs)
- return intel_get_excl_constraints(cpuc, event, idx, c2);
-
- return c2;
-}
-
-static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
- int tid = cpuc->excl_thread_id;
- struct intel_excl_states *xl;
-
- /*
- * nothing needed if in group validation mode
- */
- if (cpuc->is_fake)
- return;
-
- if (WARN_ON_ONCE(!excl_cntrs))
- return;
-
- if (hwc->flags & PERF_X86_EVENT_EXCL_ACCT) {
- hwc->flags &= ~PERF_X86_EVENT_EXCL_ACCT;
- if (!--cpuc->n_excl)
- WRITE_ONCE(excl_cntrs->has_exclusive[tid], 0);
- }
-
- /*
- * If event was actually assigned, then mark the counter state as
- * unused now.
- */
- if (hwc->idx >= 0) {
- xl = &excl_cntrs->states[tid];
-
- /*
- * put_constraint may be called from x86_schedule_events()
- * which already has the lock held so here make locking
- * conditional.
- */
- if (!xl->sched_started)
- raw_spin_lock(&excl_cntrs->lock);
-
- xl->state[hwc->idx] = INTEL_EXCL_UNUSED;
-
- if (!xl->sched_started)
- raw_spin_unlock(&excl_cntrs->lock);
- }
-}
-
-static void
-intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct hw_perf_event_extra *reg;
-
- reg = &event->hw.extra_reg;
- if (reg->idx != EXTRA_REG_NONE)
- __intel_shared_reg_put_constraints(cpuc, reg);
-
- reg = &event->hw.branch_reg;
- if (reg->idx != EXTRA_REG_NONE)
- __intel_shared_reg_put_constraints(cpuc, reg);
-}
-
-static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- intel_put_shared_regs_event_constraints(cpuc, event);
-
- /*
- * is PMU has exclusive counter restrictions, then
- * all events are subject to and must call the
- * put_excl_constraints() routine
- */
- if (cpuc->excl_cntrs)
- intel_put_excl_constraints(cpuc, event);
-}
-
-static void intel_pebs_aliases_core2(struct perf_event *event)
-{
- if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
- /*
- * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
- * (0x003c) so that we can use it with PEBS.
- *
- * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
- * PEBS capable. However we can use INST_RETIRED.ANY_P
- * (0x00c0), which is a PEBS capable event, to get the same
- * count.
- *
- * INST_RETIRED.ANY_P counts the number of cycles that retires
- * CNTMASK instructions. By setting CNTMASK to a value (16)
- * larger than the maximum number of instructions that can be
- * retired per cycle (4) and then inverting the condition, we
- * count all cycles that retire 16 or less instructions, which
- * is every cycle.
- *
- * Thereby we gain a PEBS capable cycle counter.
- */
- u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16);
-
- alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
- event->hw.config = alt_config;
- }
-}
-
-static void intel_pebs_aliases_snb(struct perf_event *event)
-{
- if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
- /*
- * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
- * (0x003c) so that we can use it with PEBS.
- *
- * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
- * PEBS capable. However we can use UOPS_RETIRED.ALL
- * (0x01c2), which is a PEBS capable event, to get the same
- * count.
- *
- * UOPS_RETIRED.ALL counts the number of cycles that retires
- * CNTMASK micro-ops. By setting CNTMASK to a value (16)
- * larger than the maximum number of micro-ops that can be
- * retired per cycle (4) and then inverting the condition, we
- * count all cycles that retire 16 or less micro-ops, which
- * is every cycle.
- *
- * Thereby we gain a PEBS capable cycle counter.
- */
- u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16);
-
- alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
- event->hw.config = alt_config;
- }
-}
-
-static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
-{
- unsigned long flags = x86_pmu.free_running_flags;
-
- if (event->attr.use_clockid)
- flags &= ~PERF_SAMPLE_TIME;
- return flags;
-}
-
-static int intel_pmu_hw_config(struct perf_event *event)
-{
- int ret = x86_pmu_hw_config(event);
-
- if (ret)
- return ret;
-
- if (event->attr.precise_ip) {
- if (!event->attr.freq) {
- event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
- if (!(event->attr.sample_type &
- ~intel_pmu_free_running_flags(event)))
- event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
- }
- if (x86_pmu.pebs_aliases)
- x86_pmu.pebs_aliases(event);
- }
-
- if (needs_branch_stack(event)) {
- ret = intel_pmu_setup_lbr_filter(event);
- if (ret)
- return ret;
-
- /*
- * BTS is set up earlier in this path, so don't account twice
- */
- if (!intel_pmu_has_bts(event)) {
- /* disallow lbr if conflicting events are present */
- if (x86_add_exclusive(x86_lbr_exclusive_lbr))
- return -EBUSY;
-
- event->destroy = hw_perf_lbr_event_destroy;
- }
- }
-
- if (event->attr.type != PERF_TYPE_RAW)
- return 0;
-
- if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
- return 0;
-
- if (x86_pmu.version < 3)
- return -EINVAL;
-
- if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
- return -EACCES;
-
- event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
-
- return 0;
-}
-
-struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
-{
- if (x86_pmu.guest_get_msrs)
- return x86_pmu.guest_get_msrs(nr);
- *nr = 0;
- return NULL;
-}
-EXPORT_SYMBOL_GPL(perf_guest_get_msrs);
-
-static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
-
- arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
- arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
- arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
- /*
- * If PMU counter has PEBS enabled it is not enough to disable counter
- * on a guest entry since PEBS memory write can overshoot guest entry
- * and corrupt guest memory. Disabling PEBS solves the problem.
- */
- arr[1].msr = MSR_IA32_PEBS_ENABLE;
- arr[1].host = cpuc->pebs_enabled;
- arr[1].guest = 0;
-
- *nr = 2;
- return arr;
-}
-
-static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct perf_event *event = cpuc->events[idx];
-
- arr[idx].msr = x86_pmu_config_addr(idx);
- arr[idx].host = arr[idx].guest = 0;
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- arr[idx].host = arr[idx].guest =
- event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
-
- if (event->attr.exclude_host)
- arr[idx].host &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
- else if (event->attr.exclude_guest)
- arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
- }
-
- *nr = x86_pmu.num_counters;
- return arr;
-}
-
-static void core_pmu_enable_event(struct perf_event *event)
-{
- if (!event->attr.exclude_host)
- x86_pmu_enable_event(event);
-}
-
-static void core_pmu_enable_all(int added)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
-
- if (!test_bit(idx, cpuc->active_mask) ||
- cpuc->events[idx]->attr.exclude_host)
- continue;
-
- __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
- }
-}
-
-static int hsw_hw_config(struct perf_event *event)
-{
- int ret = intel_pmu_hw_config(event);
-
- if (ret)
- return ret;
- if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
- return 0;
- event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
-
- /*
- * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
- * PEBS or in ANY thread mode. Since the results are non-sensical forbid
- * this combination.
- */
- if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
- ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
- event->attr.precise_ip > 0))
- return -EOPNOTSUPP;
-
- if (event_is_checkpointed(event)) {
- /*
- * Sampling of checkpointed events can cause situations where
- * the CPU constantly aborts because of a overflow, which is
- * then checkpointed back and ignored. Forbid checkpointing
- * for sampling.
- *
- * But still allow a long sampling period, so that perf stat
- * from KVM works.
- */
- if (event->attr.sample_period > 0 &&
- event->attr.sample_period < 0x7fffffff)
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static struct event_constraint counter2_constraint =
- EVENT_CONSTRAINT(0, 0x4, 0);
-
-static struct event_constraint *
-hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
- struct perf_event *event)
-{
- struct event_constraint *c;
-
- c = intel_get_event_constraints(cpuc, idx, event);
-
- /* Handle special quirk on in_tx_checkpointed only in counter 2 */
- if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
- if (c->idxmsk64 & (1U << 2))
- return &counter2_constraint;
- return &emptyconstraint;
- }
-
- return c;
-}
-
-/*
- * Broadwell:
- *
- * The INST_RETIRED.ALL period always needs to have lowest 6 bits cleared
- * (BDM55) and it must not use a period smaller than 100 (BDM11). We combine
- * the two to enforce a minimum period of 128 (the smallest value that has bits
- * 0-5 cleared and >= 100).
- *
- * Because of how the code in x86_perf_event_set_period() works, the truncation
- * of the lower 6 bits is 'harmless' as we'll occasionally add a longer period
- * to make up for the 'lost' events due to carrying the 'error' in period_left.
- *
- * Therefore the effective (average) period matches the requested period,
- * despite coarser hardware granularity.
- */
-static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
-{
- if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
- X86_CONFIG(.event=0xc0, .umask=0x01)) {
- if (left < 128)
- left = 128;
- left &= ~0x3fu;
- }
- return left;
-}
-
-PMU_FORMAT_ATTR(event, "config:0-7" );
-PMU_FORMAT_ATTR(umask, "config:8-15" );
-PMU_FORMAT_ATTR(edge, "config:18" );
-PMU_FORMAT_ATTR(pc, "config:19" );
-PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */
-PMU_FORMAT_ATTR(inv, "config:23" );
-PMU_FORMAT_ATTR(cmask, "config:24-31" );
-PMU_FORMAT_ATTR(in_tx, "config:32");
-PMU_FORMAT_ATTR(in_tx_cp, "config:33");
-
-static struct attribute *intel_arch_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_pc.attr,
- &format_attr_inv.attr,
- &format_attr_cmask.attr,
- NULL,
-};
-
-ssize_t intel_event_sysfs_show(char *page, u64 config)
-{
- u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT);
-
- return x86_event_sysfs_show(page, config, event);
-}
-
-struct intel_shared_regs *allocate_shared_regs(int cpu)
-{
- struct intel_shared_regs *regs;
- int i;
-
- regs = kzalloc_node(sizeof(struct intel_shared_regs),
- GFP_KERNEL, cpu_to_node(cpu));
- if (regs) {
- /*
- * initialize the locks to keep lockdep happy
- */
- for (i = 0; i < EXTRA_REG_MAX; i++)
- raw_spin_lock_init(&regs->regs[i].lock);
-
- regs->core_id = -1;
- }
- return regs;
-}
-
-static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu)
-{
- struct intel_excl_cntrs *c;
-
- c = kzalloc_node(sizeof(struct intel_excl_cntrs),
- GFP_KERNEL, cpu_to_node(cpu));
- if (c) {
- raw_spin_lock_init(&c->lock);
- c->core_id = -1;
- }
- return c;
-}
-
-static int intel_pmu_cpu_prepare(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-
- if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
- cpuc->shared_regs = allocate_shared_regs(cpu);
- if (!cpuc->shared_regs)
- goto err;
- }
-
- if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
- size_t sz = X86_PMC_IDX_MAX * sizeof(struct event_constraint);
-
- cpuc->constraint_list = kzalloc(sz, GFP_KERNEL);
- if (!cpuc->constraint_list)
- goto err_shared_regs;
-
- cpuc->excl_cntrs = allocate_excl_cntrs(cpu);
- if (!cpuc->excl_cntrs)
- goto err_constraint_list;
-
- cpuc->excl_thread_id = 0;
- }
-
- return NOTIFY_OK;
-
-err_constraint_list:
- kfree(cpuc->constraint_list);
- cpuc->constraint_list = NULL;
-
-err_shared_regs:
- kfree(cpuc->shared_regs);
- cpuc->shared_regs = NULL;
-
-err:
- return NOTIFY_BAD;
-}
-
-static void intel_pmu_cpu_starting(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- int core_id = topology_core_id(cpu);
- int i;
-
- init_debug_store_on_cpu(cpu);
- /*
- * Deal with CPUs that don't clear their LBRs on power-up.
- */
- intel_pmu_lbr_reset();
-
- cpuc->lbr_sel = NULL;
-
- if (!cpuc->shared_regs)
- return;
-
- if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) {
- void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED];
-
- for_each_cpu(i, topology_sibling_cpumask(cpu)) {
- struct intel_shared_regs *pc;
-
- pc = per_cpu(cpu_hw_events, i).shared_regs;
- if (pc && pc->core_id == core_id) {
- *onln = cpuc->shared_regs;
- cpuc->shared_regs = pc;
- break;
- }
- }
- cpuc->shared_regs->core_id = core_id;
- cpuc->shared_regs->refcnt++;
- }
-
- if (x86_pmu.lbr_sel_map)
- cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
-
- if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
- for_each_cpu(i, topology_sibling_cpumask(cpu)) {
- struct intel_excl_cntrs *c;
-
- c = per_cpu(cpu_hw_events, i).excl_cntrs;
- if (c && c->core_id == core_id) {
- cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
- cpuc->excl_cntrs = c;
- cpuc->excl_thread_id = 1;
- break;
- }
- }
- cpuc->excl_cntrs->core_id = core_id;
- cpuc->excl_cntrs->refcnt++;
- }
-}
-
-static void free_excl_cntrs(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- struct intel_excl_cntrs *c;
-
- c = cpuc->excl_cntrs;
- if (c) {
- if (c->core_id == -1 || --c->refcnt == 0)
- kfree(c);
- cpuc->excl_cntrs = NULL;
- kfree(cpuc->constraint_list);
- cpuc->constraint_list = NULL;
- }
-}
-
-static void intel_pmu_cpu_dying(int cpu)
-{
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- struct intel_shared_regs *pc;
-
- pc = cpuc->shared_regs;
- if (pc) {
- if (pc->core_id == -1 || --pc->refcnt == 0)
- kfree(pc);
- cpuc->shared_regs = NULL;
- }
-
- free_excl_cntrs(cpu);
-
- fini_debug_store_on_cpu(cpu);
-}
-
-static void intel_pmu_sched_task(struct perf_event_context *ctx,
- bool sched_in)
-{
- if (x86_pmu.pebs_active)
- intel_pmu_pebs_sched_task(ctx, sched_in);
- if (x86_pmu.lbr_nr)
- intel_pmu_lbr_sched_task(ctx, sched_in);
-}
-
-PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
-
-PMU_FORMAT_ATTR(ldlat, "config1:0-15");
-
-PMU_FORMAT_ATTR(frontend, "config1:0-23");
-
-static struct attribute *intel_arch3_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_pc.attr,
- &format_attr_any.attr,
- &format_attr_inv.attr,
- &format_attr_cmask.attr,
- &format_attr_in_tx.attr,
- &format_attr_in_tx_cp.attr,
-
- &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
- &format_attr_ldlat.attr, /* PEBS load latency */
- NULL,
-};
-
-static struct attribute *skl_format_attr[] = {
- &format_attr_frontend.attr,
- NULL,
-};
-
-static __initconst const struct x86_pmu core_pmu = {
- .name = "core",
- .handle_irq = x86_pmu_handle_irq,
- .disable_all = x86_pmu_disable_all,
- .enable_all = core_pmu_enable_all,
- .enable = core_pmu_enable_event,
- .disable = x86_pmu_disable_event,
- .hw_config = x86_pmu_hw_config,
- .schedule_events = x86_schedule_events,
- .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
- .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
- .event_map = intel_pmu_event_map,
- .max_events = ARRAY_SIZE(intel_perfmon_event_map),
- .apic = 1,
- .free_running_flags = PEBS_FREERUNNING_FLAGS,
-
- /*
- * Intel PMCs cannot be accessed sanely above 32-bit width,
- * so we install an artificial 1<<31 period regardless of
- * the generic event period:
- */
- .max_period = (1ULL<<31) - 1,
- .get_event_constraints = intel_get_event_constraints,
- .put_event_constraints = intel_put_event_constraints,
- .event_constraints = intel_core_event_constraints,
- .guest_get_msrs = core_guest_get_msrs,
- .format_attrs = intel_arch_formats_attr,
- .events_sysfs_show = intel_event_sysfs_show,
-
- /*
- * Virtual (or funny metal) CPU can define x86_pmu.extra_regs
- * together with PMU version 1 and thus be using core_pmu with
- * shared_regs. We need following callbacks here to allocate
- * it properly.
- */
- .cpu_prepare = intel_pmu_cpu_prepare,
- .cpu_starting = intel_pmu_cpu_starting,
- .cpu_dying = intel_pmu_cpu_dying,
-};
-
-static __initconst const struct x86_pmu intel_pmu = {
- .name = "Intel",
- .handle_irq = intel_pmu_handle_irq,
- .disable_all = intel_pmu_disable_all,
- .enable_all = intel_pmu_enable_all,
- .enable = intel_pmu_enable_event,
- .disable = intel_pmu_disable_event,
- .hw_config = intel_pmu_hw_config,
- .schedule_events = x86_schedule_events,
- .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
- .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
- .event_map = intel_pmu_event_map,
- .max_events = ARRAY_SIZE(intel_perfmon_event_map),
- .apic = 1,
- .free_running_flags = PEBS_FREERUNNING_FLAGS,
- /*
- * Intel PMCs cannot be accessed sanely above 32 bit width,
- * so we install an artificial 1<<31 period regardless of
- * the generic event period:
- */
- .max_period = (1ULL << 31) - 1,
- .get_event_constraints = intel_get_event_constraints,
- .put_event_constraints = intel_put_event_constraints,
- .pebs_aliases = intel_pebs_aliases_core2,
-
- .format_attrs = intel_arch3_formats_attr,
- .events_sysfs_show = intel_event_sysfs_show,
-
- .cpu_prepare = intel_pmu_cpu_prepare,
- .cpu_starting = intel_pmu_cpu_starting,
- .cpu_dying = intel_pmu_cpu_dying,
- .guest_get_msrs = intel_guest_get_msrs,
- .sched_task = intel_pmu_sched_task,
-};
-
-static __init void intel_clovertown_quirk(void)
-{
- /*
- * PEBS is unreliable due to:
- *
- * AJ67 - PEBS may experience CPL leaks
- * AJ68 - PEBS PMI may be delayed by one event
- * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
- * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
- *
- * AJ67 could be worked around by restricting the OS/USR flags.
- * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
- *
- * AJ106 could possibly be worked around by not allowing LBR
- * usage from PEBS, including the fixup.
- * AJ68 could possibly be worked around by always programming
- * a pebs_event_reset[0] value and coping with the lost events.
- *
- * But taken together it might just make sense to not enable PEBS on
- * these chips.
- */
- pr_warn("PEBS disabled due to CPU errata\n");
- x86_pmu.pebs = 0;
- x86_pmu.pebs_constraints = NULL;
-}
-
-static int intel_snb_pebs_broken(int cpu)
-{
- u32 rev = UINT_MAX; /* default to broken for unknown models */
-
- switch (cpu_data(cpu).x86_model) {
- case 42: /* SNB */
- rev = 0x28;
- break;
-
- case 45: /* SNB-EP */
- switch (cpu_data(cpu).x86_mask) {
- case 6: rev = 0x618; break;
- case 7: rev = 0x70c; break;
- }
- }
-
- return (cpu_data(cpu).microcode < rev);
-}
-
-static void intel_snb_check_microcode(void)
-{
- int pebs_broken = 0;
- int cpu;
-
- get_online_cpus();
- for_each_online_cpu(cpu) {
- if ((pebs_broken = intel_snb_pebs_broken(cpu)))
- break;
- }
- put_online_cpus();
-
- if (pebs_broken == x86_pmu.pebs_broken)
- return;
-
- /*
- * Serialized by the microcode lock..
- */
- if (x86_pmu.pebs_broken) {
- pr_info("PEBS enabled due to microcode update\n");
- x86_pmu.pebs_broken = 0;
- } else {
- pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n");
- x86_pmu.pebs_broken = 1;
- }
-}
-
-/*
- * Under certain circumstances, access certain MSR may cause #GP.
- * The function tests if the input MSR can be safely accessed.
- */
-static bool check_msr(unsigned long msr, u64 mask)
-{
- u64 val_old, val_new, val_tmp;
-
- /*
- * Read the current value, change it and read it back to see if it
- * matches, this is needed to detect certain hardware emulators
- * (qemu/kvm) that don't trap on the MSR access and always return 0s.
- */
- if (rdmsrl_safe(msr, &val_old))
- return false;
-
- /*
- * Only change the bits which can be updated by wrmsrl.
- */
- val_tmp = val_old ^ mask;
- if (wrmsrl_safe(msr, val_tmp) ||
- rdmsrl_safe(msr, &val_new))
- return false;
-
- if (val_new != val_tmp)
- return false;
-
- /* Here it's sure that the MSR can be safely accessed.
- * Restore the old value and return.
- */
- wrmsrl(msr, val_old);
-
- return true;
-}
-
-static __init void intel_sandybridge_quirk(void)
-{
- x86_pmu.check_microcode = intel_snb_check_microcode;
- intel_snb_check_microcode();
-}
-
-static const struct { int id; char *name; } intel_arch_events_map[] __initconst = {
- { PERF_COUNT_HW_CPU_CYCLES, "cpu cycles" },
- { PERF_COUNT_HW_INSTRUCTIONS, "instructions" },
- { PERF_COUNT_HW_BUS_CYCLES, "bus cycles" },
- { PERF_COUNT_HW_CACHE_REFERENCES, "cache references" },
- { PERF_COUNT_HW_CACHE_MISSES, "cache misses" },
- { PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "branch instructions" },
- { PERF_COUNT_HW_BRANCH_MISSES, "branch misses" },
-};
-
-static __init void intel_arch_events_quirk(void)
-{
- int bit;
-
- /* disable event that reported as not presend by cpuid */
- for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) {
- intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0;
- pr_warn("CPUID marked event: \'%s\' unavailable\n",
- intel_arch_events_map[bit].name);
- }
-}
-
-static __init void intel_nehalem_quirk(void)
-{
- union cpuid10_ebx ebx;
-
- ebx.full = x86_pmu.events_maskl;
- if (ebx.split.no_branch_misses_retired) {
- /*
- * Erratum AAJ80 detected, we work it around by using
- * the BR_MISP_EXEC.ANY event. This will over-count
- * branch-misses, but it's still much better than the
- * architectural event which is often completely bogus:
- */
- intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
- ebx.split.no_branch_misses_retired = 0;
- x86_pmu.events_maskl = ebx.full;
- pr_info("CPU erratum AAJ80 worked around\n");
- }
-}
-
-/*
- * enable software workaround for errata:
- * SNB: BJ122
- * IVB: BV98
- * HSW: HSD29
- *
- * Only needed when HT is enabled. However detecting
- * if HT is enabled is difficult (model specific). So instead,
- * we enable the workaround in the early boot, and verify if
- * it is needed in a later initcall phase once we have valid
- * topology information to check if HT is actually enabled
- */
-static __init void intel_ht_bug(void)
-{
- x86_pmu.flags |= PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED;
-
- x86_pmu.start_scheduling = intel_start_scheduling;
- x86_pmu.commit_scheduling = intel_commit_scheduling;
- x86_pmu.stop_scheduling = intel_stop_scheduling;
-}
-
-EVENT_ATTR_STR(mem-loads, mem_ld_hsw, "event=0xcd,umask=0x1,ldlat=3");
-EVENT_ATTR_STR(mem-stores, mem_st_hsw, "event=0xd0,umask=0x82")
-
-/* Haswell special events */
-EVENT_ATTR_STR(tx-start, tx_start, "event=0xc9,umask=0x1");
-EVENT_ATTR_STR(tx-commit, tx_commit, "event=0xc9,umask=0x2");
-EVENT_ATTR_STR(tx-abort, tx_abort, "event=0xc9,umask=0x4");
-EVENT_ATTR_STR(tx-capacity, tx_capacity, "event=0x54,umask=0x2");
-EVENT_ATTR_STR(tx-conflict, tx_conflict, "event=0x54,umask=0x1");
-EVENT_ATTR_STR(el-start, el_start, "event=0xc8,umask=0x1");
-EVENT_ATTR_STR(el-commit, el_commit, "event=0xc8,umask=0x2");
-EVENT_ATTR_STR(el-abort, el_abort, "event=0xc8,umask=0x4");
-EVENT_ATTR_STR(el-capacity, el_capacity, "event=0x54,umask=0x2");
-EVENT_ATTR_STR(el-conflict, el_conflict, "event=0x54,umask=0x1");
-EVENT_ATTR_STR(cycles-t, cycles_t, "event=0x3c,in_tx=1");
-EVENT_ATTR_STR(cycles-ct, cycles_ct, "event=0x3c,in_tx=1,in_tx_cp=1");
-
-static struct attribute *hsw_events_attrs[] = {
- EVENT_PTR(tx_start),
- EVENT_PTR(tx_commit),
- EVENT_PTR(tx_abort),
- EVENT_PTR(tx_capacity),
- EVENT_PTR(tx_conflict),
- EVENT_PTR(el_start),
- EVENT_PTR(el_commit),
- EVENT_PTR(el_abort),
- EVENT_PTR(el_capacity),
- EVENT_PTR(el_conflict),
- EVENT_PTR(cycles_t),
- EVENT_PTR(cycles_ct),
- EVENT_PTR(mem_ld_hsw),
- EVENT_PTR(mem_st_hsw),
- NULL
-};
-
-__init int intel_pmu_init(void)
-{
- union cpuid10_edx edx;
- union cpuid10_eax eax;
- union cpuid10_ebx ebx;
- struct event_constraint *c;
- unsigned int unused;
- struct extra_reg *er;
- int version, i;
-
- if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
- switch (boot_cpu_data.x86) {
- case 0x6:
- return p6_pmu_init();
- case 0xb:
- return knc_pmu_init();
- case 0xf:
- return p4_pmu_init();
- }
- return -ENODEV;
- }
-
- /*
- * Check whether the Architectural PerfMon supports
- * Branch Misses Retired hw_event or not.
- */
- cpuid(10, &eax.full, &ebx.full, &unused, &edx.full);
- if (eax.split.mask_length < ARCH_PERFMON_EVENTS_COUNT)
- return -ENODEV;
-
- version = eax.split.version_id;
- if (version < 2)
- x86_pmu = core_pmu;
- else
- x86_pmu = intel_pmu;
-
- x86_pmu.version = version;
- x86_pmu.num_counters = eax.split.num_counters;
- x86_pmu.cntval_bits = eax.split.bit_width;
- x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
-
- x86_pmu.events_maskl = ebx.full;
- x86_pmu.events_mask_len = eax.split.mask_length;
-
- x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
-
- /*
- * Quirk: v2 perfmon does not report fixed-purpose events, so
- * assume at least 3 events:
- */
- if (version > 1)
- x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
-
- if (boot_cpu_has(X86_FEATURE_PDCM)) {
- u64 capabilities;
-
- rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
- x86_pmu.intel_cap.capabilities = capabilities;
- }
-
- intel_ds_init();
-
- x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
-
- /*
- * Install the hw-cache-events table:
- */
- switch (boot_cpu_data.x86_model) {
- case 14: /* 65nm Core "Yonah" */
- pr_cont("Core events, ");
- break;
-
- case 15: /* 65nm Core2 "Merom" */
- x86_add_quirk(intel_clovertown_quirk);
- case 22: /* 65nm Core2 "Merom-L" */
- case 23: /* 45nm Core2 "Penryn" */
- case 29: /* 45nm Core2 "Dunnington (MP) */
- memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- intel_pmu_lbr_init_core();
-
- x86_pmu.event_constraints = intel_core2_event_constraints;
- x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
- pr_cont("Core2 events, ");
- break;
-
- case 30: /* 45nm Nehalem */
- case 26: /* 45nm Nehalem-EP */
- case 46: /* 45nm Nehalem-EX */
- memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
- sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_nhm();
-
- x86_pmu.event_constraints = intel_nehalem_event_constraints;
- x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
- x86_pmu.enable_all = intel_pmu_nhm_enable_all;
- x86_pmu.extra_regs = intel_nehalem_extra_regs;
-
- x86_pmu.cpu_events = nhm_events_attrs;
-
- /* UOPS_ISSUED.STALLED_CYCLES */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
- X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
- /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
- X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
-
- x86_add_quirk(intel_nehalem_quirk);
-
- pr_cont("Nehalem events, ");
- break;
-
- case 28: /* 45nm Atom "Pineview" */
- case 38: /* 45nm Atom "Lincroft" */
- case 39: /* 32nm Atom "Penwell" */
- case 53: /* 32nm Atom "Cloverview" */
- case 54: /* 32nm Atom "Cedarview" */
- memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- intel_pmu_lbr_init_atom();
-
- x86_pmu.event_constraints = intel_gen_event_constraints;
- x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
- pr_cont("Atom events, ");
- break;
-
- case 55: /* 22nm Atom "Silvermont" */
- case 76: /* 14nm Atom "Airmont" */
- case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
- memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
- sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_atom();
-
- x86_pmu.event_constraints = intel_slm_event_constraints;
- x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
- x86_pmu.extra_regs = intel_slm_extra_regs;
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- pr_cont("Silvermont events, ");
- break;
-
- case 37: /* 32nm Westmere */
- case 44: /* 32nm Westmere-EP */
- case 47: /* 32nm Westmere-EX */
- memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
- sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_nhm();
-
- x86_pmu.event_constraints = intel_westmere_event_constraints;
- x86_pmu.enable_all = intel_pmu_nhm_enable_all;
- x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
- x86_pmu.extra_regs = intel_westmere_extra_regs;
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
-
- x86_pmu.cpu_events = nhm_events_attrs;
-
- /* UOPS_ISSUED.STALLED_CYCLES */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
- X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
- /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
- X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
-
- pr_cont("Westmere events, ");
- break;
-
- case 42: /* 32nm SandyBridge */
- case 45: /* 32nm SandyBridge-E/EN/EP */
- x86_add_quirk(intel_sandybridge_quirk);
- x86_add_quirk(intel_ht_bug);
- memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
- sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_snb();
-
- x86_pmu.event_constraints = intel_snb_event_constraints;
- x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
- x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- if (boot_cpu_data.x86_model == 45)
- x86_pmu.extra_regs = intel_snbep_extra_regs;
- else
- x86_pmu.extra_regs = intel_snb_extra_regs;
-
-
- /* all extra regs are per-cpu when HT is on */
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
- x86_pmu.cpu_events = snb_events_attrs;
-
- /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
- X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
- /* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
- X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1);
-
- pr_cont("SandyBridge events, ");
- break;
-
- case 58: /* 22nm IvyBridge */
- case 62: /* 22nm IvyBridge-EP/EX */
- x86_add_quirk(intel_ht_bug);
- memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
- /* dTLB-load-misses on IVB is different than SNB */
- hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
-
- memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
- sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_snb();
-
- x86_pmu.event_constraints = intel_ivb_event_constraints;
- x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
- x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- if (boot_cpu_data.x86_model == 62)
- x86_pmu.extra_regs = intel_snbep_extra_regs;
- else
- x86_pmu.extra_regs = intel_snb_extra_regs;
- /* all extra regs are per-cpu when HT is on */
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
- x86_pmu.cpu_events = snb_events_attrs;
-
- /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
- intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
- X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
-
- pr_cont("IvyBridge events, ");
- break;
-
-
- case 60: /* 22nm Haswell Core */
- case 63: /* 22nm Haswell Server */
- case 69: /* 22nm Haswell ULT */
- case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
- x86_add_quirk(intel_ht_bug);
- x86_pmu.late_ack = true;
- memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-
- intel_pmu_lbr_init_hsw();
-
- x86_pmu.event_constraints = intel_hsw_event_constraints;
- x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
- x86_pmu.extra_regs = intel_snbep_extra_regs;
- x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- /* all extra regs are per-cpu when HT is on */
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
- x86_pmu.hw_config = hsw_hw_config;
- x86_pmu.get_event_constraints = hsw_get_event_constraints;
- x86_pmu.cpu_events = hsw_events_attrs;
- x86_pmu.lbr_double_abort = true;
- pr_cont("Haswell events, ");
- break;
-
- case 61: /* 14nm Broadwell Core-M */
- case 86: /* 14nm Broadwell Xeon D */
- case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
- case 79: /* 14nm Broadwell Server */
- x86_pmu.late_ack = true;
- memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
-
- /* L3_MISS_LOCAL_DRAM is BIT(26) in Broadwell */
- hw_cache_extra_regs[C(LL)][C(OP_READ)][C(RESULT_MISS)] = HSW_DEMAND_READ |
- BDW_L3_MISS|HSW_SNOOP_DRAM;
- hw_cache_extra_regs[C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = HSW_DEMAND_WRITE|BDW_L3_MISS|
- HSW_SNOOP_DRAM;
- hw_cache_extra_regs[C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = HSW_DEMAND_READ|
- BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
- hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
- BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
-
- intel_pmu_lbr_init_hsw();
-
- x86_pmu.event_constraints = intel_bdw_event_constraints;
- x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
- x86_pmu.extra_regs = intel_snbep_extra_regs;
- x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- /* all extra regs are per-cpu when HT is on */
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
- x86_pmu.hw_config = hsw_hw_config;
- x86_pmu.get_event_constraints = hsw_get_event_constraints;
- x86_pmu.cpu_events = hsw_events_attrs;
- x86_pmu.limit_period = bdw_limit_period;
- pr_cont("Broadwell events, ");
- break;
-
- case 78: /* 14nm Skylake Mobile */
- case 94: /* 14nm Skylake Desktop */
- x86_pmu.late_ack = true;
- memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
- memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
- intel_pmu_lbr_init_skl();
-
- x86_pmu.event_constraints = intel_skl_event_constraints;
- x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
- x86_pmu.extra_regs = intel_skl_extra_regs;
- x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
- /* all extra regs are per-cpu when HT is on */
- x86_pmu.flags |= PMU_FL_HAS_RSP_1;
- x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
-
- x86_pmu.hw_config = hsw_hw_config;
- x86_pmu.get_event_constraints = hsw_get_event_constraints;
- x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr,
- skl_format_attr);
- WARN_ON(!x86_pmu.format_attrs);
- x86_pmu.cpu_events = hsw_events_attrs;
- pr_cont("Skylake events, ");
- break;
-
- default:
- switch (x86_pmu.version) {
- case 1:
- x86_pmu.event_constraints = intel_v1_event_constraints;
- pr_cont("generic architected perfmon v1, ");
- break;
- default:
- /*
- * default constraints for v2 and up
- */
- x86_pmu.event_constraints = intel_gen_event_constraints;
- pr_cont("generic architected perfmon, ");
- break;
- }
- }
-
- if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
- WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
- x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
- x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
- }
- x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
-
- if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
- WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
- x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED);
- x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
- }
-
- x86_pmu.intel_ctrl |=
- ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
-
- if (x86_pmu.event_constraints) {
- /*
- * event on fixed counter2 (REF_CYCLES) only works on this
- * counter, so do not extend mask to generic counters
- */
- for_each_event_constraint(c, x86_pmu.event_constraints) {
- if (c->cmask == FIXED_EVENT_FLAGS
- && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) {
- c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
- }
- c->idxmsk64 &=
- ~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
- c->weight = hweight64(c->idxmsk64);
- }
- }
-
- /*
- * Access LBR MSR may cause #GP under certain circumstances.
- * E.g. KVM doesn't support LBR MSR
- * Check all LBT MSR here.
- * Disable LBR access if any LBR MSRs can not be accessed.
- */
- if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
- x86_pmu.lbr_nr = 0;
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
- check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
- x86_pmu.lbr_nr = 0;
- }
-
- /*
- * Access extra MSR may cause #GP under certain circumstances.
- * E.g. KVM doesn't support offcore event
- * Check all extra_regs here.
- */
- if (x86_pmu.extra_regs) {
- for (er = x86_pmu.extra_regs; er->msr; er++) {
- er->extra_msr_access = check_msr(er->msr, 0x11UL);
- /* Disable LBR select mapping */
- if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
- x86_pmu.lbr_sel_map = NULL;
- }
- }
-
- /* Support full width counters using alternative MSR range */
- if (x86_pmu.intel_cap.full_width_write) {
- x86_pmu.max_period = x86_pmu.cntval_mask;
- x86_pmu.perfctr = MSR_IA32_PMC0;
- pr_cont("full-width counters, ");
- }
-
- return 0;
-}
-
-/*
- * HT bug: phase 2 init
- * Called once we have valid topology information to check
- * whether or not HT is enabled
- * If HT is off, then we disable the workaround
- */
-static __init int fixup_ht_bug(void)
-{
- int cpu = smp_processor_id();
- int w, c;
- /*
- * problem not present on this CPU model, nothing to do
- */
- if (!(x86_pmu.flags & PMU_FL_EXCL_ENABLED))
- return 0;
-
- w = cpumask_weight(topology_sibling_cpumask(cpu));
- if (w > 1) {
- pr_info("PMU erratum BJ122, BV98, HSD29 worked around, HT is on\n");
- return 0;
- }
-
- if (lockup_detector_suspend() != 0) {
- pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n");
- return 0;
- }
-
- x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED);
-
- x86_pmu.start_scheduling = NULL;
- x86_pmu.commit_scheduling = NULL;
- x86_pmu.stop_scheduling = NULL;
-
- lockup_detector_resume();
-
- get_online_cpus();
-
- for_each_online_cpu(c) {
- free_excl_cntrs(c);
- }
-
- put_online_cpus();
- pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n");
- return 0;
-}
-subsys_initcall(fixup_ht_bug)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_bts.c b/arch/x86/kernel/cpu/perf_event_intel_bts.c
deleted file mode 100644
index d1c0f25..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_bts.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * BTS PMU driver for perf
- * Copyright (c) 2013-2014, 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.
- */
-
-#undef DEBUG
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/bitops.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/coredump.h>
-
-#include <asm-generic/sizes.h>
-#include <asm/perf_event.h>
-
-#include "perf_event.h"
-
-struct bts_ctx {
- struct perf_output_handle handle;
- struct debug_store ds_back;
- int started;
-};
-
-static DEFINE_PER_CPU(struct bts_ctx, bts_ctx);
-
-#define BTS_RECORD_SIZE 24
-#define BTS_SAFETY_MARGIN 4080
-
-struct bts_phys {
- struct page *page;
- unsigned long size;
- unsigned long offset;
- unsigned long displacement;
-};
-
-struct bts_buffer {
- size_t real_size; /* multiple of BTS_RECORD_SIZE */
- unsigned int nr_pages;
- unsigned int nr_bufs;
- unsigned int cur_buf;
- bool snapshot;
- local_t data_size;
- local_t lost;
- local_t head;
- unsigned long end;
- void **data_pages;
- struct bts_phys buf[0];
-};
-
-struct pmu bts_pmu;
-
-static size_t buf_size(struct page *page)
-{
- return 1 << (PAGE_SHIFT + page_private(page));
-}
-
-static void *
-bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
-{
- struct bts_buffer *buf;
- struct page *page;
- int node = (cpu == -1) ? cpu : cpu_to_node(cpu);
- unsigned long offset;
- size_t size = nr_pages << PAGE_SHIFT;
- int pg, nbuf, pad;
-
- /* count all the high order buffers */
- for (pg = 0, nbuf = 0; pg < nr_pages;) {
- page = virt_to_page(pages[pg]);
- if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
- return NULL;
- pg += 1 << page_private(page);
- nbuf++;
- }
-
- /*
- * to avoid interrupts in overwrite mode, only allow one physical
- */
- if (overwrite && nbuf > 1)
- return NULL;
-
- buf = kzalloc_node(offsetof(struct bts_buffer, buf[nbuf]), GFP_KERNEL, node);
- if (!buf)
- return NULL;
-
- buf->nr_pages = nr_pages;
- buf->nr_bufs = nbuf;
- buf->snapshot = overwrite;
- buf->data_pages = pages;
- buf->real_size = size - size % BTS_RECORD_SIZE;
-
- for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
- unsigned int __nr_pages;
-
- page = virt_to_page(pages[pg]);
- __nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
- buf->buf[nbuf].page = page;
- buf->buf[nbuf].offset = offset;
- buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
- buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
- pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
- buf->buf[nbuf].size -= pad;
-
- pg += __nr_pages;
- offset += __nr_pages << PAGE_SHIFT;
- }
-
- return buf;
-}
-
-static void bts_buffer_free_aux(void *data)
-{
- kfree(data);
-}
-
-static unsigned long bts_buffer_offset(struct bts_buffer *buf, unsigned int idx)
-{
- return buf->buf[idx].offset + buf->buf[idx].displacement;
-}
-
-static void
-bts_config_buffer(struct bts_buffer *buf)
-{
- int cpu = raw_smp_processor_id();
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
- struct bts_phys *phys = &buf->buf[buf->cur_buf];
- unsigned long index, thresh = 0, end = phys->size;
- struct page *page = phys->page;
-
- index = local_read(&buf->head);
-
- if (!buf->snapshot) {
- if (buf->end < phys->offset + buf_size(page))
- end = buf->end - phys->offset - phys->displacement;
-
- index -= phys->offset + phys->displacement;
-
- if (end - index > BTS_SAFETY_MARGIN)
- thresh = end - BTS_SAFETY_MARGIN;
- else if (end - index > BTS_RECORD_SIZE)
- thresh = end - BTS_RECORD_SIZE;
- else
- thresh = end;
- }
-
- ds->bts_buffer_base = (u64)(long)page_address(page) + phys->displacement;
- ds->bts_index = ds->bts_buffer_base + index;
- ds->bts_absolute_maximum = ds->bts_buffer_base + end;
- ds->bts_interrupt_threshold = !buf->snapshot
- ? ds->bts_buffer_base + thresh
- : ds->bts_absolute_maximum + BTS_RECORD_SIZE;
-}
-
-static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head)
-{
- unsigned long index = head - phys->offset;
-
- memset(page_address(phys->page) + index, 0, phys->size - index);
-}
-
-static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
-{
- if (buf->snapshot)
- return false;
-
- if (local_read(&buf->data_size) >= bts->handle.size ||
- bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
- return true;
-
- return false;
-}
-
-static void bts_update(struct bts_ctx *bts)
-{
- int cpu = raw_smp_processor_id();
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
- struct bts_buffer *buf = perf_get_aux(&bts->handle);
- unsigned long index = ds->bts_index - ds->bts_buffer_base, old, head;
-
- if (!buf)
- return;
-
- head = index + bts_buffer_offset(buf, buf->cur_buf);
- old = local_xchg(&buf->head, head);
-
- if (!buf->snapshot) {
- if (old == head)
- return;
-
- if (ds->bts_index >= ds->bts_absolute_maximum)
- local_inc(&buf->lost);
-
- /*
- * old and head are always in the same physical buffer, so we
- * can subtract them to get the data size.
- */
- local_add(head - old, &buf->data_size);
- } else {
- local_set(&buf->data_size, head);
- }
-}
-
-static void __bts_event_start(struct perf_event *event)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
- struct bts_buffer *buf = perf_get_aux(&bts->handle);
- u64 config = 0;
-
- if (!buf || bts_buffer_is_full(buf, bts))
- return;
-
- event->hw.itrace_started = 1;
- event->hw.state = 0;
-
- if (!buf->snapshot)
- config |= ARCH_PERFMON_EVENTSEL_INT;
- if (!event->attr.exclude_kernel)
- config |= ARCH_PERFMON_EVENTSEL_OS;
- if (!event->attr.exclude_user)
- config |= ARCH_PERFMON_EVENTSEL_USR;
-
- bts_config_buffer(buf);
-
- /*
- * local barrier to make sure that ds configuration made it
- * before we enable BTS
- */
- wmb();
-
- intel_pmu_enable_bts(config);
-}
-
-static void bts_event_start(struct perf_event *event, int flags)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
- __bts_event_start(event);
-
- /* PMI handler: this counter is running and likely generating PMIs */
- ACCESS_ONCE(bts->started) = 1;
-}
-
-static void __bts_event_stop(struct perf_event *event)
-{
- /*
- * No extra synchronization is mandated by the documentation to have
- * BTS data stores globally visible.
- */
- intel_pmu_disable_bts();
-
- if (event->hw.state & PERF_HES_STOPPED)
- return;
-
- ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED;
-}
-
-static void bts_event_stop(struct perf_event *event, int flags)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
- /* PMI handler: don't restart this counter */
- ACCESS_ONCE(bts->started) = 0;
-
- __bts_event_stop(event);
-
- if (flags & PERF_EF_UPDATE)
- bts_update(bts);
-}
-
-void intel_bts_enable_local(void)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
- if (bts->handle.event && bts->started)
- __bts_event_start(bts->handle.event);
-}
-
-void intel_bts_disable_local(void)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
-
- if (bts->handle.event)
- __bts_event_stop(bts->handle.event);
-}
-
-static int
-bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle)
-{
- unsigned long head, space, next_space, pad, gap, skip, wakeup;
- unsigned int next_buf;
- struct bts_phys *phys, *next_phys;
- int ret;
-
- if (buf->snapshot)
- return 0;
-
- head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
- if (WARN_ON_ONCE(head != local_read(&buf->head)))
- return -EINVAL;
-
- phys = &buf->buf[buf->cur_buf];
- space = phys->offset + phys->displacement + phys->size - head;
- pad = space;
- if (space > handle->size) {
- space = handle->size;
- space -= space % BTS_RECORD_SIZE;
- }
- if (space <= BTS_SAFETY_MARGIN) {
- /* See if next phys buffer has more space */
- next_buf = buf->cur_buf + 1;
- if (next_buf >= buf->nr_bufs)
- next_buf = 0;
- next_phys = &buf->buf[next_buf];
- gap = buf_size(phys->page) - phys->displacement - phys->size +
- next_phys->displacement;
- skip = pad + gap;
- if (handle->size >= skip) {
- next_space = next_phys->size;
- if (next_space + skip > handle->size) {
- next_space = handle->size - skip;
- next_space -= next_space % BTS_RECORD_SIZE;
- }
- if (next_space > space || !space) {
- if (pad)
- bts_buffer_pad_out(phys, head);
- ret = perf_aux_output_skip(handle, skip);
- if (ret)
- return ret;
- /* Advance to next phys buffer */
- phys = next_phys;
- space = next_space;
- head = phys->offset + phys->displacement;
- /*
- * After this, cur_buf and head won't match ds
- * anymore, so we must not be racing with
- * bts_update().
- */
- buf->cur_buf = next_buf;
- local_set(&buf->head, head);
- }
- }
- }
-
- /* Don't go far beyond wakeup watermark */
- wakeup = BTS_SAFETY_MARGIN + BTS_RECORD_SIZE + handle->wakeup -
- handle->head;
- if (space > wakeup) {
- space = wakeup;
- space -= space % BTS_RECORD_SIZE;
- }
-
- buf->end = head + space;
-
- /*
- * If we have no space, the lost notification would have been sent when
- * we hit absolute_maximum - see bts_update()
- */
- if (!space)
- return -ENOSPC;
-
- return 0;
-}
-
-int intel_bts_interrupt(void)
-{
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
- struct perf_event *event = bts->handle.event;
- struct bts_buffer *buf;
- s64 old_head;
- int err;
-
- if (!event || !bts->started)
- return 0;
-
- buf = perf_get_aux(&bts->handle);
- /*
- * Skip snapshot counters: they don't use the interrupt, but
- * there's no other way of telling, because the pointer will
- * keep moving
- */
- if (!buf || buf->snapshot)
- return 0;
-
- old_head = local_read(&buf->head);
- bts_update(bts);
-
- /* no new data */
- if (old_head == local_read(&buf->head))
- return 0;
-
- perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
- !!local_xchg(&buf->lost, 0));
-
- buf = perf_aux_output_begin(&bts->handle, event);
- if (!buf)
- return 1;
-
- err = bts_buffer_reset(buf, &bts->handle);
- if (err)
- perf_aux_output_end(&bts->handle, 0, false);
-
- return 1;
-}
-
-static void bts_event_del(struct perf_event *event, int mode)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
- struct bts_buffer *buf = perf_get_aux(&bts->handle);
-
- bts_event_stop(event, PERF_EF_UPDATE);
-
- if (buf) {
- if (buf->snapshot)
- bts->handle.head =
- local_xchg(&buf->data_size,
- buf->nr_pages << PAGE_SHIFT);
- perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
- !!local_xchg(&buf->lost, 0));
- }
-
- cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
- cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
- cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
- cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
-}
-
-static int bts_event_add(struct perf_event *event, int mode)
-{
- struct bts_buffer *buf;
- struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
- int ret = -EBUSY;
-
- event->hw.state = PERF_HES_STOPPED;
-
- if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
- return -EBUSY;
-
- if (bts->handle.event)
- return -EBUSY;
-
- buf = perf_aux_output_begin(&bts->handle, event);
- if (!buf)
- return -EINVAL;
-
- ret = bts_buffer_reset(buf, &bts->handle);
- if (ret) {
- perf_aux_output_end(&bts->handle, 0, false);
- return ret;
- }
-
- bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
- bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
- bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
-
- if (mode & PERF_EF_START) {
- bts_event_start(event, 0);
- if (hwc->state & PERF_HES_STOPPED) {
- bts_event_del(event, 0);
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-static void bts_event_destroy(struct perf_event *event)
-{
- x86_release_hardware();
- x86_del_exclusive(x86_lbr_exclusive_bts);
-}
-
-static int bts_event_init(struct perf_event *event)
-{
- int ret;
-
- if (event->attr.type != bts_pmu.type)
- return -ENOENT;
-
- if (x86_add_exclusive(x86_lbr_exclusive_bts))
- return -EBUSY;
-
- ret = x86_reserve_hardware();
- if (ret) {
- x86_del_exclusive(x86_lbr_exclusive_bts);
- return ret;
- }
-
- event->destroy = bts_event_destroy;
-
- return 0;
-}
-
-static void bts_event_read(struct perf_event *event)
-{
-}
-
-static __init int bts_init(void)
-{
- if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
- return -ENODEV;
-
- bts_pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE;
- bts_pmu.task_ctx_nr = perf_sw_context;
- bts_pmu.event_init = bts_event_init;
- bts_pmu.add = bts_event_add;
- bts_pmu.del = bts_event_del;
- bts_pmu.start = bts_event_start;
- bts_pmu.stop = bts_event_stop;
- bts_pmu.read = bts_event_read;
- bts_pmu.setup_aux = bts_buffer_setup_aux;
- bts_pmu.free_aux = bts_buffer_free_aux;
-
- return perf_pmu_register(&bts_pmu, "intel_bts", -1);
-}
-arch_initcall(bts_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_cqm.c b/arch/x86/kernel/cpu/perf_event_intel_cqm.c
deleted file mode 100644
index 377e8f8..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c
+++ /dev/null
@@ -1,1391 +0,0 @@
-/*
- * Intel Cache Quality-of-Service Monitoring (CQM) support.
- *
- * Based very, very heavily on work by Peter Zijlstra.
- */
-
-#include <linux/perf_event.h>
-#include <linux/slab.h>
-#include <asm/cpu_device_id.h>
-#include "perf_event.h"
-
-#define MSR_IA32_PQR_ASSOC 0x0c8f
-#define MSR_IA32_QM_CTR 0x0c8e
-#define MSR_IA32_QM_EVTSEL 0x0c8d
-
-static u32 cqm_max_rmid = -1;
-static unsigned int cqm_l3_scale; /* supposedly cacheline size */
-
-/**
- * struct intel_pqr_state - State cache for the PQR MSR
- * @rmid: The cached Resource Monitoring ID
- * @closid: The cached Class Of Service ID
- * @rmid_usecnt: The usage counter for rmid
- *
- * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the
- * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always
- * contains both parts, so we need to cache them.
- *
- * The cache also helps to avoid pointless updates if the value does
- * not change.
- */
-struct intel_pqr_state {
- u32 rmid;
- u32 closid;
- int rmid_usecnt;
-};
-
-/*
- * The cached intel_pqr_state is strictly per CPU and can never be
- * updated from a remote CPU. Both functions which modify the state
- * (intel_cqm_event_start and intel_cqm_event_stop) are called with
- * interrupts disabled, which is sufficient for the protection.
- */
-static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
-
-/*
- * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
- * Also protects event->hw.cqm_rmid
- *
- * Hold either for stability, both for modification of ->hw.cqm_rmid.
- */
-static DEFINE_MUTEX(cache_mutex);
-static DEFINE_RAW_SPINLOCK(cache_lock);
-
-/*
- * Groups of events that have the same target(s), one RMID per group.
- */
-static LIST_HEAD(cache_groups);
-
-/*
- * Mask of CPUs for reading CQM values. We only need one per-socket.
- */
-static cpumask_t cqm_cpumask;
-
-#define RMID_VAL_ERROR (1ULL << 63)
-#define RMID_VAL_UNAVAIL (1ULL << 62)
-
-#define QOS_L3_OCCUP_EVENT_ID (1 << 0)
-
-#define QOS_EVENT_MASK QOS_L3_OCCUP_EVENT_ID
-
-/*
- * This is central to the rotation algorithm in __intel_cqm_rmid_rotate().
- *
- * This rmid is always free and is guaranteed to have an associated
- * near-zero occupancy value, i.e. no cachelines are tagged with this
- * RMID, once __intel_cqm_rmid_rotate() returns.
- */
-static u32 intel_cqm_rotation_rmid;
-
-#define INVALID_RMID (-1)
-
-/*
- * Is @rmid valid for programming the hardware?
- *
- * rmid 0 is reserved by the hardware for all non-monitored tasks, which
- * means that we should never come across an rmid with that value.
- * Likewise, an rmid value of -1 is used to indicate "no rmid currently
- * assigned" and is used as part of the rotation code.
- */
-static inline bool __rmid_valid(u32 rmid)
-{
- if (!rmid || rmid == INVALID_RMID)
- return false;
-
- return true;
-}
-
-static u64 __rmid_read(u32 rmid)
-{
- u64 val;
-
- /*
- * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt,
- * it just says that to increase confusion.
- */
- wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid);
- rdmsrl(MSR_IA32_QM_CTR, val);
-
- /*
- * Aside from the ERROR and UNAVAIL bits, assume this thing returns
- * the number of cachelines tagged with @rmid.
- */
- return val;
-}
-
-enum rmid_recycle_state {
- RMID_YOUNG = 0,
- RMID_AVAILABLE,
- RMID_DIRTY,
-};
-
-struct cqm_rmid_entry {
- u32 rmid;
- enum rmid_recycle_state state;
- struct list_head list;
- unsigned long queue_time;
-};
-
-/*
- * cqm_rmid_free_lru - A least recently used list of RMIDs.
- *
- * Oldest entry at the head, newest (most recently used) entry at the
- * tail. This list is never traversed, it's only used to keep track of
- * the lru order. That is, we only pick entries of the head or insert
- * them on the tail.
- *
- * All entries on the list are 'free', and their RMIDs are not currently
- * in use. To mark an RMID as in use, remove its entry from the lru
- * list.
- *
- *
- * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs.
- *
- * This list is contains RMIDs that no one is currently using but that
- * may have a non-zero occupancy value associated with them. The
- * rotation worker moves RMIDs from the limbo list to the free list once
- * the occupancy value drops below __intel_cqm_threshold.
- *
- * Both lists are protected by cache_mutex.
- */
-static LIST_HEAD(cqm_rmid_free_lru);
-static LIST_HEAD(cqm_rmid_limbo_lru);
-
-/*
- * We use a simple array of pointers so that we can lookup a struct
- * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid()
- * and __put_rmid() from having to worry about dealing with struct
- * cqm_rmid_entry - they just deal with rmids, i.e. integers.
- *
- * Once this array is initialized it is read-only. No locks are required
- * to access it.
- *
- * All entries for all RMIDs can be looked up in the this array at all
- * times.
- */
-static struct cqm_rmid_entry **cqm_rmid_ptrs;
-
-static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid)
-{
- struct cqm_rmid_entry *entry;
-
- entry = cqm_rmid_ptrs[rmid];
- WARN_ON(entry->rmid != rmid);
-
- return entry;
-}
-
-/*
- * Returns < 0 on fail.
- *
- * We expect to be called with cache_mutex held.
- */
-static u32 __get_rmid(void)
-{
- struct cqm_rmid_entry *entry;
-
- lockdep_assert_held(&cache_mutex);
-
- if (list_empty(&cqm_rmid_free_lru))
- return INVALID_RMID;
-
- entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list);
- list_del(&entry->list);
-
- return entry->rmid;
-}
-
-static void __put_rmid(u32 rmid)
-{
- struct cqm_rmid_entry *entry;
-
- lockdep_assert_held(&cache_mutex);
-
- WARN_ON(!__rmid_valid(rmid));
- entry = __rmid_entry(rmid);
-
- entry->queue_time = jiffies;
- entry->state = RMID_YOUNG;
-
- list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
-}
-
-static int intel_cqm_setup_rmid_cache(void)
-{
- struct cqm_rmid_entry *entry;
- unsigned int nr_rmids;
- int r = 0;
-
- nr_rmids = cqm_max_rmid + 1;
- cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) *
- nr_rmids, GFP_KERNEL);
- if (!cqm_rmid_ptrs)
- return -ENOMEM;
-
- for (; r <= cqm_max_rmid; r++) {
- struct cqm_rmid_entry *entry;
-
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- goto fail;
-
- INIT_LIST_HEAD(&entry->list);
- entry->rmid = r;
- cqm_rmid_ptrs[r] = entry;
-
- list_add_tail(&entry->list, &cqm_rmid_free_lru);
- }
-
- /*
- * RMID 0 is special and is always allocated. It's used for all
- * tasks that are not monitored.
- */
- entry = __rmid_entry(0);
- list_del(&entry->list);
-
- mutex_lock(&cache_mutex);
- intel_cqm_rotation_rmid = __get_rmid();
- mutex_unlock(&cache_mutex);
-
- return 0;
-fail:
- while (r--)
- kfree(cqm_rmid_ptrs[r]);
-
- kfree(cqm_rmid_ptrs);
- return -ENOMEM;
-}
-
-/*
- * Determine if @a and @b measure the same set of tasks.
- *
- * If @a and @b measure the same set of tasks then we want to share a
- * single RMID.
- */
-static bool __match_event(struct perf_event *a, struct perf_event *b)
-{
- /* Per-cpu and task events don't mix */
- if ((a->attach_state & PERF_ATTACH_TASK) !=
- (b->attach_state & PERF_ATTACH_TASK))
- return false;
-
-#ifdef CONFIG_CGROUP_PERF
- if (a->cgrp != b->cgrp)
- return false;
-#endif
-
- /* If not task event, we're machine wide */
- if (!(b->attach_state & PERF_ATTACH_TASK))
- return true;
-
- /*
- * Events that target same task are placed into the same cache group.
- */
- if (a->hw.target == b->hw.target)
- return true;
-
- /*
- * Are we an inherited event?
- */
- if (b->parent == a)
- return true;
-
- return false;
-}
-
-#ifdef CONFIG_CGROUP_PERF
-static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event)
-{
- if (event->attach_state & PERF_ATTACH_TASK)
- return perf_cgroup_from_task(event->hw.target);
-
- return event->cgrp;
-}
-#endif
-
-/*
- * Determine if @a's tasks intersect with @b's tasks
- *
- * There are combinations of events that we explicitly prohibit,
- *
- * PROHIBITS
- * system-wide -> cgroup and task
- * cgroup -> system-wide
- * -> task in cgroup
- * task -> system-wide
- * -> task in cgroup
- *
- * Call this function before allocating an RMID.
- */
-static bool __conflict_event(struct perf_event *a, struct perf_event *b)
-{
-#ifdef CONFIG_CGROUP_PERF
- /*
- * We can have any number of cgroups but only one system-wide
- * event at a time.
- */
- if (a->cgrp && b->cgrp) {
- struct perf_cgroup *ac = a->cgrp;
- struct perf_cgroup *bc = b->cgrp;
-
- /*
- * This condition should have been caught in
- * __match_event() and we should be sharing an RMID.
- */
- WARN_ON_ONCE(ac == bc);
-
- if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
- cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
- return true;
-
- return false;
- }
-
- if (a->cgrp || b->cgrp) {
- struct perf_cgroup *ac, *bc;
-
- /*
- * cgroup and system-wide events are mutually exclusive
- */
- if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) ||
- (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK)))
- return true;
-
- /*
- * Ensure neither event is part of the other's cgroup
- */
- ac = event_to_cgroup(a);
- bc = event_to_cgroup(b);
- if (ac == bc)
- return true;
-
- /*
- * Must have cgroup and non-intersecting task events.
- */
- if (!ac || !bc)
- return false;
-
- /*
- * We have cgroup and task events, and the task belongs
- * to a cgroup. Check for for overlap.
- */
- if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) ||
- cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup))
- return true;
-
- return false;
- }
-#endif
- /*
- * If one of them is not a task, same story as above with cgroups.
- */
- if (!(a->attach_state & PERF_ATTACH_TASK) ||
- !(b->attach_state & PERF_ATTACH_TASK))
- return true;
-
- /*
- * Must be non-overlapping.
- */
- return false;
-}
-
-struct rmid_read {
- u32 rmid;
- atomic64_t value;
-};
-
-static void __intel_cqm_event_count(void *info);
-
-/*
- * Exchange the RMID of a group of events.
- */
-static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
-{
- struct perf_event *event;
- struct list_head *head = &group->hw.cqm_group_entry;
- u32 old_rmid = group->hw.cqm_rmid;
-
- lockdep_assert_held(&cache_mutex);
-
- /*
- * If our RMID is being deallocated, perform a read now.
- */
- if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) {
- struct rmid_read rr = {
- .value = ATOMIC64_INIT(0),
- .rmid = old_rmid,
- };
-
- on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count,
- &rr, 1);
- local64_set(&group->count, atomic64_read(&rr.value));
- }
-
- raw_spin_lock_irq(&cache_lock);
-
- group->hw.cqm_rmid = rmid;
- list_for_each_entry(event, head, hw.cqm_group_entry)
- event->hw.cqm_rmid = rmid;
-
- raw_spin_unlock_irq(&cache_lock);
-
- return old_rmid;
-}
-
-/*
- * If we fail to assign a new RMID for intel_cqm_rotation_rmid because
- * cachelines are still tagged with RMIDs in limbo, we progressively
- * increment the threshold until we find an RMID in limbo with <=
- * __intel_cqm_threshold lines tagged. This is designed to mitigate the
- * problem where cachelines tagged with an RMID are not steadily being
- * evicted.
- *
- * On successful rotations we decrease the threshold back towards zero.
- *
- * __intel_cqm_max_threshold provides an upper bound on the threshold,
- * and is measured in bytes because it's exposed to userland.
- */
-static unsigned int __intel_cqm_threshold;
-static unsigned int __intel_cqm_max_threshold;
-
-/*
- * Test whether an RMID has a zero occupancy value on this cpu.
- */
-static void intel_cqm_stable(void *arg)
-{
- struct cqm_rmid_entry *entry;
-
- list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
- if (entry->state != RMID_AVAILABLE)
- break;
-
- if (__rmid_read(entry->rmid) > __intel_cqm_threshold)
- entry->state = RMID_DIRTY;
- }
-}
-
-/*
- * If we have group events waiting for an RMID that don't conflict with
- * events already running, assign @rmid.
- */
-static bool intel_cqm_sched_in_event(u32 rmid)
-{
- struct perf_event *leader, *event;
-
- lockdep_assert_held(&cache_mutex);
-
- leader = list_first_entry(&cache_groups, struct perf_event,
- hw.cqm_groups_entry);
- event = leader;
-
- list_for_each_entry_continue(event, &cache_groups,
- hw.cqm_groups_entry) {
- if (__rmid_valid(event->hw.cqm_rmid))
- continue;
-
- if (__conflict_event(event, leader))
- continue;
-
- intel_cqm_xchg_rmid(event, rmid);
- return true;
- }
-
- return false;
-}
-
-/*
- * Initially use this constant for both the limbo queue time and the
- * rotation timer interval, pmu::hrtimer_interval_ms.
- *
- * They don't need to be the same, but the two are related since if you
- * rotate faster than you recycle RMIDs, you may run out of available
- * RMIDs.
- */
-#define RMID_DEFAULT_QUEUE_TIME 250 /* ms */
-
-static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME;
-
-/*
- * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list
- * @nr_available: number of freeable RMIDs on the limbo list
- *
- * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no
- * cachelines are tagged with those RMIDs. After this we can reuse them
- * and know that the current set of active RMIDs is stable.
- *
- * Return %true or %false depending on whether stabilization needs to be
- * reattempted.
- *
- * If we return %true then @nr_available is updated to indicate the
- * number of RMIDs on the limbo list that have been queued for the
- * minimum queue time (RMID_AVAILABLE), but whose data occupancy values
- * are above __intel_cqm_threshold.
- */
-static bool intel_cqm_rmid_stabilize(unsigned int *available)
-{
- struct cqm_rmid_entry *entry, *tmp;
-
- lockdep_assert_held(&cache_mutex);
-
- *available = 0;
- list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) {
- unsigned long min_queue_time;
- unsigned long now = jiffies;
-
- /*
- * We hold RMIDs placed into limbo for a minimum queue
- * time. Before the minimum queue time has elapsed we do
- * not recycle RMIDs.
- *
- * The reasoning is that until a sufficient time has
- * passed since we stopped using an RMID, any RMID
- * placed onto the limbo list will likely still have
- * data tagged in the cache, which means we'll probably
- * fail to recycle it anyway.
- *
- * We can save ourselves an expensive IPI by skipping
- * any RMIDs that have not been queued for the minimum
- * time.
- */
- min_queue_time = entry->queue_time +
- msecs_to_jiffies(__rmid_queue_time_ms);
-
- if (time_after(min_queue_time, now))
- break;
-
- entry->state = RMID_AVAILABLE;
- (*available)++;
- }
-
- /*
- * Fast return if none of the RMIDs on the limbo list have been
- * sitting on the queue for the minimum queue time.
- */
- if (!*available)
- return false;
-
- /*
- * Test whether an RMID is free for each package.
- */
- on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true);
-
- list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) {
- /*
- * Exhausted all RMIDs that have waited min queue time.
- */
- if (entry->state == RMID_YOUNG)
- break;
-
- if (entry->state == RMID_DIRTY)
- continue;
-
- list_del(&entry->list); /* remove from limbo */
-
- /*
- * The rotation RMID gets priority if it's
- * currently invalid. In which case, skip adding
- * the RMID to the the free lru.
- */
- if (!__rmid_valid(intel_cqm_rotation_rmid)) {
- intel_cqm_rotation_rmid = entry->rmid;
- continue;
- }
-
- /*
- * If we have groups waiting for RMIDs, hand
- * them one now provided they don't conflict.
- */
- if (intel_cqm_sched_in_event(entry->rmid))
- continue;
-
- /*
- * Otherwise place it onto the free list.
- */
- list_add_tail(&entry->list, &cqm_rmid_free_lru);
- }
-
-
- return __rmid_valid(intel_cqm_rotation_rmid);
-}
-
-/*
- * Pick a victim group and move it to the tail of the group list.
- * @next: The first group without an RMID
- */
-static void __intel_cqm_pick_and_rotate(struct perf_event *next)
-{
- struct perf_event *rotor;
- u32 rmid;
-
- lockdep_assert_held(&cache_mutex);
-
- rotor = list_first_entry(&cache_groups, struct perf_event,
- hw.cqm_groups_entry);
-
- /*
- * The group at the front of the list should always have a valid
- * RMID. If it doesn't then no groups have RMIDs assigned and we
- * don't need to rotate the list.
- */
- if (next == rotor)
- return;
-
- rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID);
- __put_rmid(rmid);
-
- list_rotate_left(&cache_groups);
-}
-
-/*
- * Deallocate the RMIDs from any events that conflict with @event, and
- * place them on the back of the group list.
- */
-static void intel_cqm_sched_out_conflicting_events(struct perf_event *event)
-{
- struct perf_event *group, *g;
- u32 rmid;
-
- lockdep_assert_held(&cache_mutex);
-
- list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) {
- if (group == event)
- continue;
-
- rmid = group->hw.cqm_rmid;
-
- /*
- * Skip events that don't have a valid RMID.
- */
- if (!__rmid_valid(rmid))
- continue;
-
- /*
- * No conflict? No problem! Leave the event alone.
- */
- if (!__conflict_event(group, event))
- continue;
-
- intel_cqm_xchg_rmid(group, INVALID_RMID);
- __put_rmid(rmid);
- }
-}
-
-/*
- * Attempt to rotate the groups and assign new RMIDs.
- *
- * We rotate for two reasons,
- * 1. To handle the scheduling of conflicting events
- * 2. To recycle RMIDs
- *
- * Rotating RMIDs is complicated because the hardware doesn't give us
- * any clues.
- *
- * There's problems with the hardware interface; when you change the
- * task:RMID map cachelines retain their 'old' tags, giving a skewed
- * picture. In order to work around this, we must always keep one free
- * RMID - intel_cqm_rotation_rmid.
- *
- * Rotation works by taking away an RMID from a group (the old RMID),
- * and assigning the free RMID to another group (the new RMID). We must
- * then wait for the old RMID to not be used (no cachelines tagged).
- * This ensure that all cachelines are tagged with 'active' RMIDs. At
- * this point we can start reading values for the new RMID and treat the
- * old RMID as the free RMID for the next rotation.
- *
- * Return %true or %false depending on whether we did any rotating.
- */
-static bool __intel_cqm_rmid_rotate(void)
-{
- struct perf_event *group, *start = NULL;
- unsigned int threshold_limit;
- unsigned int nr_needed = 0;
- unsigned int nr_available;
- bool rotated = false;
-
- mutex_lock(&cache_mutex);
-
-again:
- /*
- * Fast path through this function if there are no groups and no
- * RMIDs that need cleaning.
- */
- if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru))
- goto out;
-
- list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) {
- if (!__rmid_valid(group->hw.cqm_rmid)) {
- if (!start)
- start = group;
- nr_needed++;
- }
- }
-
- /*
- * We have some event groups, but they all have RMIDs assigned
- * and no RMIDs need cleaning.
- */
- if (!nr_needed && list_empty(&cqm_rmid_limbo_lru))
- goto out;
-
- if (!nr_needed)
- goto stabilize;
-
- /*
- * We have more event groups without RMIDs than available RMIDs,
- * or we have event groups that conflict with the ones currently
- * scheduled.
- *
- * We force deallocate the rmid of the group at the head of
- * cache_groups. The first event group without an RMID then gets
- * assigned intel_cqm_rotation_rmid. This ensures we always make
- * forward progress.
- *
- * Rotate the cache_groups list so the previous head is now the
- * tail.
- */
- __intel_cqm_pick_and_rotate(start);
-
- /*
- * If the rotation is going to succeed, reduce the threshold so
- * that we don't needlessly reuse dirty RMIDs.
- */
- if (__rmid_valid(intel_cqm_rotation_rmid)) {
- intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid);
- intel_cqm_rotation_rmid = __get_rmid();
-
- intel_cqm_sched_out_conflicting_events(start);
-
- if (__intel_cqm_threshold)
- __intel_cqm_threshold--;
- }
-
- rotated = true;
-
-stabilize:
- /*
- * We now need to stablize the RMID we freed above (if any) to
- * ensure that the next time we rotate we have an RMID with zero
- * occupancy value.
- *
- * Alternatively, if we didn't need to perform any rotation,
- * we'll have a bunch of RMIDs in limbo that need stabilizing.
- */
- threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale;
-
- while (intel_cqm_rmid_stabilize(&nr_available) &&
- __intel_cqm_threshold < threshold_limit) {
- unsigned int steal_limit;
-
- /*
- * Don't spin if nobody is actively waiting for an RMID,
- * the rotation worker will be kicked as soon as an
- * event needs an RMID anyway.
- */
- if (!nr_needed)
- break;
-
- /* Allow max 25% of RMIDs to be in limbo. */
- steal_limit = (cqm_max_rmid + 1) / 4;
-
- /*
- * We failed to stabilize any RMIDs so our rotation
- * logic is now stuck. In order to make forward progress
- * we have a few options:
- *
- * 1. rotate ("steal") another RMID
- * 2. increase the threshold
- * 3. do nothing
- *
- * We do both of 1. and 2. until we hit the steal limit.
- *
- * The steal limit prevents all RMIDs ending up on the
- * limbo list. This can happen if every RMID has a
- * non-zero occupancy above threshold_limit, and the
- * occupancy values aren't dropping fast enough.
- *
- * Note that there is prioritisation at work here - we'd
- * rather increase the number of RMIDs on the limbo list
- * than increase the threshold, because increasing the
- * threshold skews the event data (because we reuse
- * dirty RMIDs) - threshold bumps are a last resort.
- */
- if (nr_available < steal_limit)
- goto again;
-
- __intel_cqm_threshold++;
- }
-
-out:
- mutex_unlock(&cache_mutex);
- return rotated;
-}
-
-static void intel_cqm_rmid_rotate(struct work_struct *work);
-
-static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate);
-
-static struct pmu intel_cqm_pmu;
-
-static void intel_cqm_rmid_rotate(struct work_struct *work)
-{
- unsigned long delay;
-
- __intel_cqm_rmid_rotate();
-
- delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms);
- schedule_delayed_work(&intel_cqm_rmid_work, delay);
-}
-
-/*
- * Find a group and setup RMID.
- *
- * If we're part of a group, we use the group's RMID.
- */
-static void intel_cqm_setup_event(struct perf_event *event,
- struct perf_event **group)
-{
- struct perf_event *iter;
- bool conflict = false;
- u32 rmid;
-
- list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
- rmid = iter->hw.cqm_rmid;
-
- if (__match_event(iter, event)) {
- /* All tasks in a group share an RMID */
- event->hw.cqm_rmid = rmid;
- *group = iter;
- return;
- }
-
- /*
- * We only care about conflicts for events that are
- * actually scheduled in (and hence have a valid RMID).
- */
- if (__conflict_event(iter, event) && __rmid_valid(rmid))
- conflict = true;
- }
-
- if (conflict)
- rmid = INVALID_RMID;
- else
- rmid = __get_rmid();
-
- event->hw.cqm_rmid = rmid;
-}
-
-static void intel_cqm_event_read(struct perf_event *event)
-{
- unsigned long flags;
- u32 rmid;
- u64 val;
-
- /*
- * Task events are handled by intel_cqm_event_count().
- */
- if (event->cpu == -1)
- return;
-
- raw_spin_lock_irqsave(&cache_lock, flags);
- rmid = event->hw.cqm_rmid;
-
- if (!__rmid_valid(rmid))
- goto out;
-
- val = __rmid_read(rmid);
-
- /*
- * Ignore this reading on error states and do not update the value.
- */
- if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
- goto out;
-
- local64_set(&event->count, val);
-out:
- raw_spin_unlock_irqrestore(&cache_lock, flags);
-}
-
-static void __intel_cqm_event_count(void *info)
-{
- struct rmid_read *rr = info;
- u64 val;
-
- val = __rmid_read(rr->rmid);
-
- if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
- return;
-
- atomic64_add(val, &rr->value);
-}
-
-static inline bool cqm_group_leader(struct perf_event *event)
-{
- return !list_empty(&event->hw.cqm_groups_entry);
-}
-
-static u64 intel_cqm_event_count(struct perf_event *event)
-{
- unsigned long flags;
- struct rmid_read rr = {
- .value = ATOMIC64_INIT(0),
- };
-
- /*
- * We only need to worry about task events. System-wide events
- * are handled like usual, i.e. entirely with
- * intel_cqm_event_read().
- */
- if (event->cpu != -1)
- return __perf_event_count(event);
-
- /*
- * Only the group leader gets to report values. This stops us
- * reporting duplicate values to userspace, and gives us a clear
- * rule for which task gets to report the values.
- *
- * Note that it is impossible to attribute these values to
- * specific packages - we forfeit that ability when we create
- * task events.
- */
- if (!cqm_group_leader(event))
- return 0;
-
- /*
- * Getting up-to-date values requires an SMP IPI which is not
- * possible if we're being called in interrupt context. Return
- * the cached values instead.
- */
- if (unlikely(in_interrupt()))
- goto out;
-
- /*
- * Notice that we don't perform the reading of an RMID
- * atomically, because we can't hold a spin lock across the
- * IPIs.
- *
- * Speculatively perform the read, since @event might be
- * assigned a different (possibly invalid) RMID while we're
- * busying performing the IPI calls. It's therefore necessary to
- * check @event's RMID afterwards, and if it has changed,
- * discard the result of the read.
- */
- rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid);
-
- if (!__rmid_valid(rr.rmid))
- goto out;
-
- on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1);
-
- raw_spin_lock_irqsave(&cache_lock, flags);
- if (event->hw.cqm_rmid == rr.rmid)
- local64_set(&event->count, atomic64_read(&rr.value));
- raw_spin_unlock_irqrestore(&cache_lock, flags);
-out:
- return __perf_event_count(event);
-}
-
-static void intel_cqm_event_start(struct perf_event *event, int mode)
-{
- struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
- u32 rmid = event->hw.cqm_rmid;
-
- if (!(event->hw.cqm_state & PERF_HES_STOPPED))
- return;
-
- event->hw.cqm_state &= ~PERF_HES_STOPPED;
-
- if (state->rmid_usecnt++) {
- if (!WARN_ON_ONCE(state->rmid != rmid))
- return;
- } else {
- WARN_ON_ONCE(state->rmid);
- }
-
- state->rmid = rmid;
- wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid);
-}
-
-static void intel_cqm_event_stop(struct perf_event *event, int mode)
-{
- struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
-
- if (event->hw.cqm_state & PERF_HES_STOPPED)
- return;
-
- event->hw.cqm_state |= PERF_HES_STOPPED;
-
- intel_cqm_event_read(event);
-
- if (!--state->rmid_usecnt) {
- state->rmid = 0;
- wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid);
- } else {
- WARN_ON_ONCE(!state->rmid);
- }
-}
-
-static int intel_cqm_event_add(struct perf_event *event, int mode)
-{
- unsigned long flags;
- u32 rmid;
-
- raw_spin_lock_irqsave(&cache_lock, flags);
-
- event->hw.cqm_state = PERF_HES_STOPPED;
- rmid = event->hw.cqm_rmid;
-
- if (__rmid_valid(rmid) && (mode & PERF_EF_START))
- intel_cqm_event_start(event, mode);
-
- raw_spin_unlock_irqrestore(&cache_lock, flags);
-
- return 0;
-}
-
-static void intel_cqm_event_destroy(struct perf_event *event)
-{
- struct perf_event *group_other = NULL;
-
- mutex_lock(&cache_mutex);
-
- /*
- * If there's another event in this group...
- */
- if (!list_empty(&event->hw.cqm_group_entry)) {
- group_other = list_first_entry(&event->hw.cqm_group_entry,
- struct perf_event,
- hw.cqm_group_entry);
- list_del(&event->hw.cqm_group_entry);
- }
-
- /*
- * And we're the group leader..
- */
- if (cqm_group_leader(event)) {
- /*
- * If there was a group_other, make that leader, otherwise
- * destroy the group and return the RMID.
- */
- if (group_other) {
- list_replace(&event->hw.cqm_groups_entry,
- &group_other->hw.cqm_groups_entry);
- } else {
- u32 rmid = event->hw.cqm_rmid;
-
- if (__rmid_valid(rmid))
- __put_rmid(rmid);
- list_del(&event->hw.cqm_groups_entry);
- }
- }
-
- mutex_unlock(&cache_mutex);
-}
-
-static int intel_cqm_event_init(struct perf_event *event)
-{
- struct perf_event *group = NULL;
- bool rotate = false;
-
- if (event->attr.type != intel_cqm_pmu.type)
- return -ENOENT;
-
- if (event->attr.config & ~QOS_EVENT_MASK)
- return -EINVAL;
-
- /* unsupported modes and filters */
- if (event->attr.exclude_user ||
- event->attr.exclude_kernel ||
- event->attr.exclude_hv ||
- event->attr.exclude_idle ||
- event->attr.exclude_host ||
- event->attr.exclude_guest ||
- event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- INIT_LIST_HEAD(&event->hw.cqm_group_entry);
- INIT_LIST_HEAD(&event->hw.cqm_groups_entry);
-
- event->destroy = intel_cqm_event_destroy;
-
- mutex_lock(&cache_mutex);
-
- /* Will also set rmid */
- intel_cqm_setup_event(event, &group);
-
- if (group) {
- list_add_tail(&event->hw.cqm_group_entry,
- &group->hw.cqm_group_entry);
- } else {
- list_add_tail(&event->hw.cqm_groups_entry,
- &cache_groups);
-
- /*
- * All RMIDs are either in use or have recently been
- * used. Kick the rotation worker to clean/free some.
- *
- * We only do this for the group leader, rather than for
- * every event in a group to save on needless work.
- */
- if (!__rmid_valid(event->hw.cqm_rmid))
- rotate = true;
- }
-
- mutex_unlock(&cache_mutex);
-
- if (rotate)
- schedule_delayed_work(&intel_cqm_rmid_work, 0);
-
- return 0;
-}
-
-EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01");
-EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1");
-EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes");
-EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL);
-EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1");
-
-static struct attribute *intel_cqm_events_attr[] = {
- EVENT_PTR(intel_cqm_llc),
- EVENT_PTR(intel_cqm_llc_pkg),
- EVENT_PTR(intel_cqm_llc_unit),
- EVENT_PTR(intel_cqm_llc_scale),
- EVENT_PTR(intel_cqm_llc_snapshot),
- NULL,
-};
-
-static struct attribute_group intel_cqm_events_group = {
- .name = "events",
- .attrs = intel_cqm_events_attr,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-7");
-static struct attribute *intel_cqm_formats_attr[] = {
- &format_attr_event.attr,
- NULL,
-};
-
-static struct attribute_group intel_cqm_format_group = {
- .name = "format",
- .attrs = intel_cqm_formats_attr,
-};
-
-static ssize_t
-max_recycle_threshold_show(struct device *dev, struct device_attribute *attr,
- char *page)
-{
- ssize_t rv;
-
- mutex_lock(&cache_mutex);
- rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold);
- mutex_unlock(&cache_mutex);
-
- return rv;
-}
-
-static ssize_t
-max_recycle_threshold_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int bytes, cachelines;
- int ret;
-
- ret = kstrtouint(buf, 0, &bytes);
- if (ret)
- return ret;
-
- mutex_lock(&cache_mutex);
-
- __intel_cqm_max_threshold = bytes;
- cachelines = bytes / cqm_l3_scale;
-
- /*
- * The new maximum takes effect immediately.
- */
- if (__intel_cqm_threshold > cachelines)
- __intel_cqm_threshold = cachelines;
-
- mutex_unlock(&cache_mutex);
-
- return count;
-}
-
-static DEVICE_ATTR_RW(max_recycle_threshold);
-
-static struct attribute *intel_cqm_attrs[] = {
- &dev_attr_max_recycle_threshold.attr,
- NULL,
-};
-
-static const struct attribute_group intel_cqm_group = {
- .attrs = intel_cqm_attrs,
-};
-
-static const struct attribute_group *intel_cqm_attr_groups[] = {
- &intel_cqm_events_group,
- &intel_cqm_format_group,
- &intel_cqm_group,
- NULL,
-};
-
-static struct pmu intel_cqm_pmu = {
- .hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME,
- .attr_groups = intel_cqm_attr_groups,
- .task_ctx_nr = perf_sw_context,
- .event_init = intel_cqm_event_init,
- .add = intel_cqm_event_add,
- .del = intel_cqm_event_stop,
- .start = intel_cqm_event_start,
- .stop = intel_cqm_event_stop,
- .read = intel_cqm_event_read,
- .count = intel_cqm_event_count,
-};
-
-static inline void cqm_pick_event_reader(int cpu)
-{
- int phys_id = topology_physical_package_id(cpu);
- int i;
-
- for_each_cpu(i, &cqm_cpumask) {
- if (phys_id == topology_physical_package_id(i))
- return; /* already got reader for this socket */
- }
-
- cpumask_set_cpu(cpu, &cqm_cpumask);
-}
-
-static void intel_cqm_cpu_starting(unsigned int cpu)
-{
- struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
- struct cpuinfo_x86 *c = &cpu_data(cpu);
-
- state->rmid = 0;
- state->closid = 0;
- state->rmid_usecnt = 0;
-
- WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
- WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
-}
-
-static void intel_cqm_cpu_exit(unsigned int cpu)
-{
- int phys_id = topology_physical_package_id(cpu);
- int i;
-
- /*
- * Is @cpu a designated cqm reader?
- */
- if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
- return;
-
- for_each_online_cpu(i) {
- if (i == cpu)
- continue;
-
- if (phys_id == topology_physical_package_id(i)) {
- cpumask_set_cpu(i, &cqm_cpumask);
- break;
- }
- }
-}
-
-static int intel_cqm_cpu_notifier(struct notifier_block *nb,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
-
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_DOWN_PREPARE:
- intel_cqm_cpu_exit(cpu);
- break;
- case CPU_STARTING:
- intel_cqm_cpu_starting(cpu);
- cqm_pick_event_reader(cpu);
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static const struct x86_cpu_id intel_cqm_match[] = {
- { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC },
- {}
-};
-
-static int __init intel_cqm_init(void)
-{
- char *str, scale[20];
- int i, cpu, ret;
-
- if (!x86_match_cpu(intel_cqm_match))
- return -ENODEV;
-
- cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale;
-
- /*
- * It's possible that not all resources support the same number
- * of RMIDs. Instead of making scheduling much more complicated
- * (where we have to match a task's RMID to a cpu that supports
- * that many RMIDs) just find the minimum RMIDs supported across
- * all cpus.
- *
- * Also, check that the scales match on all cpus.
- */
- cpu_notifier_register_begin();
-
- for_each_online_cpu(cpu) {
- struct cpuinfo_x86 *c = &cpu_data(cpu);
-
- if (c->x86_cache_max_rmid < cqm_max_rmid)
- cqm_max_rmid = c->x86_cache_max_rmid;
-
- if (c->x86_cache_occ_scale != cqm_l3_scale) {
- pr_err("Multiple LLC scale values, disabling\n");
- ret = -EINVAL;
- goto out;
- }
- }
-
- /*
- * A reasonable upper limit on the max threshold is the number
- * of lines tagged per RMID if all RMIDs have the same number of
- * lines tagged in the LLC.
- *
- * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC.
- */
- __intel_cqm_max_threshold =
- boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1);
-
- snprintf(scale, sizeof(scale), "%u", cqm_l3_scale);
- str = kstrdup(scale, GFP_KERNEL);
- if (!str) {
- ret = -ENOMEM;
- goto out;
- }
-
- event_attr_intel_cqm_llc_scale.event_str = str;
-
- ret = intel_cqm_setup_rmid_cache();
- if (ret)
- goto out;
-
- for_each_online_cpu(i) {
- intel_cqm_cpu_starting(i);
- cqm_pick_event_reader(i);
- }
-
- __perf_cpu_notifier(intel_cqm_cpu_notifier);
-
- ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
- if (ret)
- pr_err("Intel CQM perf registration failed: %d\n", ret);
- else
- pr_info("Intel CQM monitoring enabled\n");
-
-out:
- cpu_notifier_register_done();
-
- return ret;
-}
-device_initcall(intel_cqm_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
deleted file mode 100644
index 84f236a..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-#include <linux/bitops.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include <asm/perf_event.h>
-#include <asm/insn.h>
-
-#include "perf_event.h"
-
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE 24
-
-#define BTS_BUFFER_SIZE (PAGE_SIZE << 4)
-#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4)
-#define PEBS_FIXUP_SIZE PAGE_SIZE
-
-/*
- * pebs_record_32 for p4 and core not supported
-
-struct pebs_record_32 {
- u32 flags, ip;
- u32 ax, bc, cx, dx;
- u32 si, di, bp, sp;
-};
-
- */
-
-union intel_x86_pebs_dse {
- u64 val;
- struct {
- unsigned int ld_dse:4;
- unsigned int ld_stlb_miss:1;
- unsigned int ld_locked:1;
- unsigned int ld_reserved:26;
- };
- struct {
- unsigned int st_l1d_hit:1;
- unsigned int st_reserved1:3;
- unsigned int st_stlb_miss:1;
- unsigned int st_locked:1;
- unsigned int st_reserved2:26;
- };
-};
-
-
-/*
- * Map PEBS Load Latency Data Source encodings to generic
- * memory data source information
- */
-#define P(a, b) PERF_MEM_S(a, b)
-#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
-#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
-
-static const u64 pebs_data_source[] = {
- P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
- OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */
- OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
- OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */
- OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */
- OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */
- OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */
- OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */
- OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */
- OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
- OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */
- OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */
- OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
- OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
- OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */
- OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
-};
-
-static u64 precise_store_data(u64 status)
-{
- union intel_x86_pebs_dse dse;
- u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2);
-
- dse.val = status;
-
- /*
- * bit 4: TLB access
- * 1 = stored missed 2nd level TLB
- *
- * so it either hit the walker or the OS
- * otherwise hit 2nd level TLB
- */
- if (dse.st_stlb_miss)
- val |= P(TLB, MISS);
- else
- val |= P(TLB, HIT);
-
- /*
- * bit 0: hit L1 data cache
- * if not set, then all we know is that
- * it missed L1D
- */
- if (dse.st_l1d_hit)
- val |= P(LVL, HIT);
- else
- val |= P(LVL, MISS);
-
- /*
- * bit 5: Locked prefix
- */
- if (dse.st_locked)
- val |= P(LOCK, LOCKED);
-
- return val;
-}
-
-static u64 precise_datala_hsw(struct perf_event *event, u64 status)
-{
- union perf_mem_data_src dse;
-
- dse.val = PERF_MEM_NA;
-
- if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
- dse.mem_op = PERF_MEM_OP_STORE;
- else if (event->hw.flags & PERF_X86_EVENT_PEBS_LD_HSW)
- dse.mem_op = PERF_MEM_OP_LOAD;
-
- /*
- * L1 info only valid for following events:
- *
- * MEM_UOPS_RETIRED.STLB_MISS_STORES
- * MEM_UOPS_RETIRED.LOCK_STORES
- * MEM_UOPS_RETIRED.SPLIT_STORES
- * MEM_UOPS_RETIRED.ALL_STORES
- */
- if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) {
- if (status & 1)
- dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
- else
- dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
- }
- return dse.val;
-}
-
-static u64 load_latency_data(u64 status)
-{
- union intel_x86_pebs_dse dse;
- u64 val;
- int model = boot_cpu_data.x86_model;
- int fam = boot_cpu_data.x86;
-
- dse.val = status;
-
- /*
- * use the mapping table for bit 0-3
- */
- val = pebs_data_source[dse.ld_dse];
-
- /*
- * Nehalem models do not support TLB, Lock infos
- */
- if (fam == 0x6 && (model == 26 || model == 30
- || model == 31 || model == 46)) {
- val |= P(TLB, NA) | P(LOCK, NA);
- return val;
- }
- /*
- * bit 4: TLB access
- * 0 = did not miss 2nd level TLB
- * 1 = missed 2nd level TLB
- */
- if (dse.ld_stlb_miss)
- val |= P(TLB, MISS) | P(TLB, L2);
- else
- val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
-
- /*
- * bit 5: locked prefix
- */
- if (dse.ld_locked)
- val |= P(LOCK, LOCKED);
-
- return val;
-}
-
-struct pebs_record_core {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
-};
-
-struct pebs_record_nhm {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
- u64 status, dla, dse, lat;
-};
-
-/*
- * Same as pebs_record_nhm, with two additional fields.
- */
-struct pebs_record_hsw {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
- u64 status, dla, dse, lat;
- u64 real_ip, tsx_tuning;
-};
-
-union hsw_tsx_tuning {
- struct {
- u32 cycles_last_block : 32,
- hle_abort : 1,
- rtm_abort : 1,
- instruction_abort : 1,
- non_instruction_abort : 1,
- retry : 1,
- data_conflict : 1,
- capacity_writes : 1,
- capacity_reads : 1;
- };
- u64 value;
-};
-
-#define PEBS_HSW_TSX_FLAGS 0xff00000000ULL
-
-/* Same as HSW, plus TSC */
-
-struct pebs_record_skl {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
- u64 status, dla, dse, lat;
- u64 real_ip, tsx_tuning;
- u64 tsc;
-};
-
-void init_debug_store_on_cpu(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- return;
-
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
- (u32)((u64)(unsigned long)ds),
- (u32)((u64)(unsigned long)ds >> 32));
-}
-
-void fini_debug_store_on_cpu(int cpu)
-{
- if (!per_cpu(cpu_hw_events, cpu).ds)
- return;
-
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static DEFINE_PER_CPU(void *, insn_buffer);
-
-static int alloc_pebs_buffer(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
- int node = cpu_to_node(cpu);
- int max;
- void *buffer, *ibuffer;
-
- if (!x86_pmu.pebs)
- return 0;
-
- buffer = kzalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL, node);
- if (unlikely(!buffer))
- return -ENOMEM;
-
- /*
- * HSW+ already provides us the eventing ip; no need to allocate this
- * buffer then.
- */
- if (x86_pmu.intel_cap.pebs_format < 2) {
- ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
- if (!ibuffer) {
- kfree(buffer);
- return -ENOMEM;
- }
- per_cpu(insn_buffer, cpu) = ibuffer;
- }
-
- max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
-
- ds->pebs_buffer_base = (u64)(unsigned long)buffer;
- ds->pebs_index = ds->pebs_buffer_base;
- ds->pebs_absolute_maximum = ds->pebs_buffer_base +
- max * x86_pmu.pebs_record_size;
-
- return 0;
-}
-
-static void release_pebs_buffer(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds || !x86_pmu.pebs)
- return;
-
- kfree(per_cpu(insn_buffer, cpu));
- per_cpu(insn_buffer, cpu) = NULL;
-
- kfree((void *)(unsigned long)ds->pebs_buffer_base);
- ds->pebs_buffer_base = 0;
-}
-
-static int alloc_bts_buffer(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
- int node = cpu_to_node(cpu);
- int max, thresh;
- void *buffer;
-
- if (!x86_pmu.bts)
- return 0;
-
- buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
- if (unlikely(!buffer)) {
- WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
- return -ENOMEM;
- }
-
- max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
- thresh = max / 16;
-
- ds->bts_buffer_base = (u64)(unsigned long)buffer;
- ds->bts_index = ds->bts_buffer_base;
- ds->bts_absolute_maximum = ds->bts_buffer_base +
- max * BTS_RECORD_SIZE;
- ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
- thresh * BTS_RECORD_SIZE;
-
- return 0;
-}
-
-static void release_bts_buffer(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds || !x86_pmu.bts)
- return;
-
- kfree((void *)(unsigned long)ds->bts_buffer_base);
- ds->bts_buffer_base = 0;
-}
-
-static int alloc_ds_buffer(int cpu)
-{
- int node = cpu_to_node(cpu);
- struct debug_store *ds;
-
- ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node);
- if (unlikely(!ds))
- return -ENOMEM;
-
- per_cpu(cpu_hw_events, cpu).ds = ds;
-
- return 0;
-}
-
-static void release_ds_buffer(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- return;
-
- per_cpu(cpu_hw_events, cpu).ds = NULL;
- kfree(ds);
-}
-
-void release_ds_buffers(void)
-{
- int cpu;
-
- if (!x86_pmu.bts && !x86_pmu.pebs)
- return;
-
- get_online_cpus();
- for_each_online_cpu(cpu)
- fini_debug_store_on_cpu(cpu);
-
- for_each_possible_cpu(cpu) {
- release_pebs_buffer(cpu);
- release_bts_buffer(cpu);
- release_ds_buffer(cpu);
- }
- put_online_cpus();
-}
-
-void reserve_ds_buffers(void)
-{
- int bts_err = 0, pebs_err = 0;
- int cpu;
-
- x86_pmu.bts_active = 0;
- x86_pmu.pebs_active = 0;
-
- if (!x86_pmu.bts && !x86_pmu.pebs)
- return;
-
- if (!x86_pmu.bts)
- bts_err = 1;
-
- if (!x86_pmu.pebs)
- pebs_err = 1;
-
- get_online_cpus();
-
- for_each_possible_cpu(cpu) {
- if (alloc_ds_buffer(cpu)) {
- bts_err = 1;
- pebs_err = 1;
- }
-
- if (!bts_err && alloc_bts_buffer(cpu))
- bts_err = 1;
-
- if (!pebs_err && alloc_pebs_buffer(cpu))
- pebs_err = 1;
-
- if (bts_err && pebs_err)
- break;
- }
-
- if (bts_err) {
- for_each_possible_cpu(cpu)
- release_bts_buffer(cpu);
- }
-
- if (pebs_err) {
- for_each_possible_cpu(cpu)
- release_pebs_buffer(cpu);
- }
-
- if (bts_err && pebs_err) {
- for_each_possible_cpu(cpu)
- release_ds_buffer(cpu);
- } else {
- if (x86_pmu.bts && !bts_err)
- x86_pmu.bts_active = 1;
-
- if (x86_pmu.pebs && !pebs_err)
- x86_pmu.pebs_active = 1;
-
- for_each_online_cpu(cpu)
- init_debug_store_on_cpu(cpu);
- }
-
- put_online_cpus();
-}
-
-/*
- * BTS
- */
-
-struct event_constraint bts_constraint =
- EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0);
-
-void intel_pmu_enable_bts(u64 config)
-{
- unsigned long debugctlmsr;
-
- debugctlmsr = get_debugctlmsr();
-
- debugctlmsr |= DEBUGCTLMSR_TR;
- debugctlmsr |= DEBUGCTLMSR_BTS;
- if (config & ARCH_PERFMON_EVENTSEL_INT)
- debugctlmsr |= DEBUGCTLMSR_BTINT;
-
- if (!(config & ARCH_PERFMON_EVENTSEL_OS))
- debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
-
- if (!(config & ARCH_PERFMON_EVENTSEL_USR))
- debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
-
- update_debugctlmsr(debugctlmsr);
-}
-
-void intel_pmu_disable_bts(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- unsigned long debugctlmsr;
-
- if (!cpuc->ds)
- return;
-
- debugctlmsr = get_debugctlmsr();
-
- debugctlmsr &=
- ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
- DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
-
- update_debugctlmsr(debugctlmsr);
-}
-
-int intel_pmu_drain_bts_buffer(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct bts_record {
- u64 from;
- u64 to;
- u64 flags;
- };
- struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
- struct bts_record *at, *top;
- struct perf_output_handle handle;
- struct perf_event_header header;
- struct perf_sample_data data;
- struct pt_regs regs;
-
- if (!event)
- return 0;
-
- if (!x86_pmu.bts_active)
- return 0;
-
- at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
- top = (struct bts_record *)(unsigned long)ds->bts_index;
-
- if (top <= at)
- return 0;
-
- memset(&regs, 0, sizeof(regs));
-
- ds->bts_index = ds->bts_buffer_base;
-
- perf_sample_data_init(&data, 0, event->hw.last_period);
-
- /*
- * Prepare a generic sample, i.e. fill in the invariant fields.
- * We will overwrite the from and to address before we output
- * the sample.
- */
- perf_prepare_sample(&header, &data, event, &regs);
-
- if (perf_output_begin(&handle, event, header.size * (top - at)))
- return 1;
-
- for (; at < top; at++) {
- data.ip = at->from;
- data.addr = at->to;
-
- perf_output_sample(&handle, &header, &data, event);
- }
-
- perf_output_end(&handle);
-
- /* There's new data available. */
- event->hw.interrupts++;
- event->pending_kill = POLL_IN;
- return 1;
-}
-
-static inline void intel_pmu_drain_pebs_buffer(void)
-{
- struct pt_regs regs;
-
- x86_pmu.drain_pebs(&regs);
-}
-
-void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
- if (!sched_in)
- intel_pmu_drain_pebs_buffer();
-}
-
-/*
- * PEBS
- */
-struct event_constraint intel_core2_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */
- /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_atom_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */
- /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x01),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_slm_pebs_event_constraints[] = {
- /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1),
- /* Allow all events as PEBS with no flags */
- INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_nehalem_pebs_event_constraints[] = {
- INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf), /* INST_RETIRED.ANY */
- INTEL_EVENT_CONSTRAINT(0xc2, 0xf), /* UOPS_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf), /* SSEX_UOPS_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf), /* MEM_LOAD_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf), /* FP_ASSIST.* */
- /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_westmere_pebs_event_constraints[] = {
- INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xf), /* INSTR_RETIRED.* */
- INTEL_EVENT_CONSTRAINT(0xc2, 0xf), /* UOPS_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xc7, 0xf), /* SSEX_UOPS_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xcb, 0xf), /* MEM_LOAD_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT(0xf7, 0xf), /* FP_ASSIST.* */
- /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x0f),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_snb_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
- INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
- INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */
- /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
- INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
- /* Allow all events as PEBS with no flags */
- INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_ivb_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
- INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
- INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */
- /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
- INTEL_EXCLEVT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
- INTEL_EXCLEVT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
- /* Allow all events as PEBS with no flags */
- INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_hsw_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
- INTEL_PLD_CONSTRAINT(0x01cd, 0xf), /* MEM_TRANS_RETIRED.* */
- /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XLD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_XST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd2, 0xf), /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(0xd3, 0xf), /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */
- /* Allow all events as PEBS with no flags */
- INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint intel_skl_pebs_event_constraints[] = {
- INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x2), /* INST_RETIRED.PREC_DIST */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
- /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
- INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
- INTEL_PLD_CONSTRAINT(0x1cd, 0xf), /* MEM_TRANS_RETIRED.* */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x22d0, 0xf), /* MEM_INST_RETIRED.LOCK_STORES */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */
- INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf), /* MEM_LOAD_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf), /* MEM_LOAD_L3_HIT_RETIRED.* */
- INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf), /* MEM_LOAD_L3_MISS_RETIRED.* */
- /* Allow all events as PEBS with no flags */
- INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
- EVENT_CONSTRAINT_END
-};
-
-struct event_constraint *intel_pebs_constraints(struct perf_event *event)
-{
- struct event_constraint *c;
-
- if (!event->attr.precise_ip)
- return NULL;
-
- if (x86_pmu.pebs_constraints) {
- for_each_event_constraint(c, x86_pmu.pebs_constraints) {
- if ((event->hw.config & c->cmask) == c->code) {
- event->hw.flags |= c->flags;
- return c;
- }
- }
- }
-
- return &emptyconstraint;
-}
-
-static inline bool pebs_is_enabled(struct cpu_hw_events *cpuc)
-{
- return (cpuc->pebs_enabled & ((1ULL << MAX_PEBS_EVENTS) - 1));
-}
-
-void intel_pmu_pebs_enable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
- struct debug_store *ds = cpuc->ds;
- bool first_pebs;
- u64 threshold;
-
- hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
-
- first_pebs = !pebs_is_enabled(cpuc);
- cpuc->pebs_enabled |= 1ULL << hwc->idx;
-
- if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
- cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
- else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
- cpuc->pebs_enabled |= 1ULL << 63;
-
- /*
- * When the event is constrained enough we can use a larger
- * threshold and run the event with less frequent PMI.
- */
- if (hwc->flags & PERF_X86_EVENT_FREERUNNING) {
- threshold = ds->pebs_absolute_maximum -
- x86_pmu.max_pebs_events * x86_pmu.pebs_record_size;
-
- if (first_pebs)
- perf_sched_cb_inc(event->ctx->pmu);
- } else {
- threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
-
- /*
- * If not all events can use larger buffer,
- * roll back to threshold = 1
- */
- if (!first_pebs &&
- (ds->pebs_interrupt_threshold > threshold))
- perf_sched_cb_dec(event->ctx->pmu);
- }
-
- /* Use auto-reload if possible to save a MSR write in the PMI */
- if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
- ds->pebs_event_reset[hwc->idx] =
- (u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
- }
-
- if (first_pebs || ds->pebs_interrupt_threshold > threshold)
- ds->pebs_interrupt_threshold = threshold;
-}
-
-void intel_pmu_pebs_disable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
- struct debug_store *ds = cpuc->ds;
- bool large_pebs = ds->pebs_interrupt_threshold >
- ds->pebs_buffer_base + x86_pmu.pebs_record_size;
-
- if (large_pebs)
- intel_pmu_drain_pebs_buffer();
-
- cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
-
- if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
- cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
- else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
- cpuc->pebs_enabled &= ~(1ULL << 63);
-
- if (large_pebs && !pebs_is_enabled(cpuc))
- perf_sched_cb_dec(event->ctx->pmu);
-
- if (cpuc->enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-
- hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
-}
-
-void intel_pmu_pebs_enable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (cpuc->pebs_enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-}
-
-void intel_pmu_pebs_disable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (cpuc->pebs_enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
-}
-
-static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- unsigned long from = cpuc->lbr_entries[0].from;
- unsigned long old_to, to = cpuc->lbr_entries[0].to;
- unsigned long ip = regs->ip;
- int is_64bit = 0;
- void *kaddr;
- int size;
-
- /*
- * We don't need to fixup if the PEBS assist is fault like
- */
- if (!x86_pmu.intel_cap.pebs_trap)
- return 1;
-
- /*
- * No LBR entry, no basic block, no rewinding
- */
- if (!cpuc->lbr_stack.nr || !from || !to)
- return 0;
-
- /*
- * Basic blocks should never cross user/kernel boundaries
- */
- if (kernel_ip(ip) != kernel_ip(to))
- return 0;
-
- /*
- * unsigned math, either ip is before the start (impossible) or
- * the basic block is larger than 1 page (sanity)
- */
- if ((ip - to) > PEBS_FIXUP_SIZE)
- return 0;
-
- /*
- * We sampled a branch insn, rewind using the LBR stack
- */
- if (ip == to) {
- set_linear_ip(regs, from);
- return 1;
- }
-
- size = ip - to;
- if (!kernel_ip(ip)) {
- int bytes;
- u8 *buf = this_cpu_read(insn_buffer);
-
- /* 'size' must fit our buffer, see above */
- bytes = copy_from_user_nmi(buf, (void __user *)to, size);
- if (bytes != 0)
- return 0;
-
- kaddr = buf;
- } else {
- kaddr = (void *)to;
- }
-
- do {
- struct insn insn;
-
- old_to = to;
-
-#ifdef CONFIG_X86_64
- is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
-#endif
- insn_init(&insn, kaddr, size, is_64bit);
- insn_get_length(&insn);
- /*
- * Make sure there was not a problem decoding the
- * instruction and getting the length. This is
- * doubly important because we have an infinite
- * loop if insn.length=0.
- */
- if (!insn.length)
- break;
-
- to += insn.length;
- kaddr += insn.length;
- size -= insn.length;
- } while (to < ip);
-
- if (to == ip) {
- set_linear_ip(regs, old_to);
- return 1;
- }
-
- /*
- * Even though we decoded the basic block, the instruction stream
- * never matched the given IP, either the TO or the IP got corrupted.
- */
- return 0;
-}
-
-static inline u64 intel_hsw_weight(struct pebs_record_skl *pebs)
-{
- if (pebs->tsx_tuning) {
- union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
- return tsx.cycles_last_block;
- }
- return 0;
-}
-
-static inline u64 intel_hsw_transaction(struct pebs_record_skl *pebs)
-{
- u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
-
- /* For RTM XABORTs also log the abort code from AX */
- if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
- txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
- return txn;
-}
-
-static void setup_pebs_sample_data(struct perf_event *event,
- struct pt_regs *iregs, void *__pebs,
- struct perf_sample_data *data,
- struct pt_regs *regs)
-{
-#define PERF_X86_EVENT_PEBS_HSW_PREC \
- (PERF_X86_EVENT_PEBS_ST_HSW | \
- PERF_X86_EVENT_PEBS_LD_HSW | \
- PERF_X86_EVENT_PEBS_NA_HSW)
- /*
- * We cast to the biggest pebs_record but are careful not to
- * unconditionally access the 'extra' entries.
- */
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct pebs_record_skl *pebs = __pebs;
- u64 sample_type;
- int fll, fst, dsrc;
- int fl = event->hw.flags;
-
- if (pebs == NULL)
- return;
-
- sample_type = event->attr.sample_type;
- dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
-
- fll = fl & PERF_X86_EVENT_PEBS_LDLAT;
- fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
-
- perf_sample_data_init(data, 0, event->hw.last_period);
-
- data->period = event->hw.last_period;
-
- /*
- * Use latency for weight (only avail with PEBS-LL)
- */
- if (fll && (sample_type & PERF_SAMPLE_WEIGHT))
- data->weight = pebs->lat;
-
- /*
- * data.data_src encodes the data source
- */
- if (dsrc) {
- u64 val = PERF_MEM_NA;
- if (fll)
- val = load_latency_data(pebs->dse);
- else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
- val = precise_datala_hsw(event, pebs->dse);
- else if (fst)
- val = precise_store_data(pebs->dse);
- data->data_src.val = val;
- }
-
- /*
- * We use the interrupt regs as a base because the PEBS record
- * does not contain a full regs set, specifically it seems to
- * lack segment descriptors, which get used by things like
- * user_mode().
- *
- * In the simple case fix up only the IP and BP,SP regs, for
- * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
- * A possible PERF_SAMPLE_REGS will have to transfer all regs.
- */
- *regs = *iregs;
- regs->flags = pebs->flags;
- set_linear_ip(regs, pebs->ip);
- regs->bp = pebs->bp;
- regs->sp = pebs->sp;
-
- if (sample_type & PERF_SAMPLE_REGS_INTR) {
- regs->ax = pebs->ax;
- regs->bx = pebs->bx;
- regs->cx = pebs->cx;
- regs->dx = pebs->dx;
- regs->si = pebs->si;
- regs->di = pebs->di;
- regs->bp = pebs->bp;
- regs->sp = pebs->sp;
-
- regs->flags = pebs->flags;
-#ifndef CONFIG_X86_32
- regs->r8 = pebs->r8;
- regs->r9 = pebs->r9;
- regs->r10 = pebs->r10;
- regs->r11 = pebs->r11;
- regs->r12 = pebs->r12;
- regs->r13 = pebs->r13;
- regs->r14 = pebs->r14;
- regs->r15 = pebs->r15;
-#endif
- }
-
- if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
- regs->ip = pebs->real_ip;
- regs->flags |= PERF_EFLAGS_EXACT;
- } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
- regs->flags |= PERF_EFLAGS_EXACT;
- else
- regs->flags &= ~PERF_EFLAGS_EXACT;
-
- if ((sample_type & PERF_SAMPLE_ADDR) &&
- x86_pmu.intel_cap.pebs_format >= 1)
- data->addr = pebs->dla;
-
- if (x86_pmu.intel_cap.pebs_format >= 2) {
- /* Only set the TSX weight when no memory weight. */
- if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll)
- data->weight = intel_hsw_weight(pebs);
-
- if (sample_type & PERF_SAMPLE_TRANSACTION)
- data->txn = intel_hsw_transaction(pebs);
- }
-
- /*
- * v3 supplies an accurate time stamp, so we use that
- * for the time stamp.
- *
- * We can only do this for the default trace clock.
- */
- if (x86_pmu.intel_cap.pebs_format >= 3 &&
- event->attr.use_clockid == 0)
- data->time = native_sched_clock_from_tsc(pebs->tsc);
-
- if (has_branch_stack(event))
- data->br_stack = &cpuc->lbr_stack;
-}
-
-static inline void *
-get_next_pebs_record_by_bit(void *base, void *top, int bit)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- void *at;
- u64 pebs_status;
-
- if (base == NULL)
- return NULL;
-
- for (at = base; at < top; at += x86_pmu.pebs_record_size) {
- struct pebs_record_nhm *p = at;
-
- if (test_bit(bit, (unsigned long *)&p->status)) {
- /* PEBS v3 has accurate status bits */
- if (x86_pmu.intel_cap.pebs_format >= 3)
- return at;
-
- if (p->status == (1 << bit))
- return at;
-
- /* clear non-PEBS bit and re-check */
- pebs_status = p->status & cpuc->pebs_enabled;
- pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
- if (pebs_status == (1 << bit))
- return at;
- }
- }
- return NULL;
-}
-
-static void __intel_pmu_pebs_event(struct perf_event *event,
- struct pt_regs *iregs,
- void *base, void *top,
- int bit, int count)
-{
- struct perf_sample_data data;
- struct pt_regs regs;
- void *at = get_next_pebs_record_by_bit(base, top, bit);
-
- if (!intel_pmu_save_and_restart(event) &&
- !(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
- return;
-
- while (count > 1) {
- setup_pebs_sample_data(event, iregs, at, &data, &regs);
- perf_event_output(event, &data, &regs);
- at += x86_pmu.pebs_record_size;
- at = get_next_pebs_record_by_bit(at, top, bit);
- count--;
- }
-
- setup_pebs_sample_data(event, iregs, at, &data, &regs);
-
- /*
- * All but the last records are processed.
- * The last one is left to be able to call the overflow handler.
- */
- if (perf_event_overflow(event, &data, &regs)) {
- x86_pmu_stop(event, 0);
- return;
- }
-
-}
-
-static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct perf_event *event = cpuc->events[0]; /* PMC0 only */
- struct pebs_record_core *at, *top;
- int n;
-
- if (!x86_pmu.pebs_active)
- return;
-
- at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
- top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
-
- /*
- * Whatever else happens, drain the thing
- */
- ds->pebs_index = ds->pebs_buffer_base;
-
- if (!test_bit(0, cpuc->active_mask))
- return;
-
- WARN_ON_ONCE(!event);
-
- if (!event->attr.precise_ip)
- return;
-
- n = (top - at) / x86_pmu.pebs_record_size;
- if (n <= 0)
- return;
-
- __intel_pmu_pebs_event(event, iregs, at, top, 0, n);
-}
-
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct perf_event *event;
- void *base, *at, *top;
- short counts[MAX_PEBS_EVENTS] = {};
- short error[MAX_PEBS_EVENTS] = {};
- int bit, i;
-
- if (!x86_pmu.pebs_active)
- return;
-
- base = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
- top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
-
- ds->pebs_index = ds->pebs_buffer_base;
-
- if (unlikely(base >= top))
- return;
-
- for (at = base; at < top; at += x86_pmu.pebs_record_size) {
- struct pebs_record_nhm *p = at;
- u64 pebs_status;
-
- /* PEBS v3 has accurate status bits */
- if (x86_pmu.intel_cap.pebs_format >= 3) {
- for_each_set_bit(bit, (unsigned long *)&p->status,
- MAX_PEBS_EVENTS)
- counts[bit]++;
-
- continue;
- }
-
- pebs_status = p->status & cpuc->pebs_enabled;
- pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
-
- bit = find_first_bit((unsigned long *)&pebs_status,
- x86_pmu.max_pebs_events);
- if (WARN(bit >= x86_pmu.max_pebs_events,
- "PEBS record without PEBS event! status=%Lx pebs_enabled=%Lx active_mask=%Lx",
- (unsigned long long)p->status, (unsigned long long)cpuc->pebs_enabled,
- *(unsigned long long *)cpuc->active_mask))
- continue;
-
- /*
- * The PEBS hardware does not deal well with the situation
- * when events happen near to each other and multiple bits
- * are set. But it should happen rarely.
- *
- * If these events include one PEBS and multiple non-PEBS
- * events, it doesn't impact PEBS record. The record will
- * be handled normally. (slow path)
- *
- * If these events include two or more PEBS events, the
- * records for the events can be collapsed into a single
- * one, and it's not possible to reconstruct all events
- * that caused the PEBS record. It's called collision.
- * If collision happened, the record will be dropped.
- */
- if (p->status != (1ULL << bit)) {
- for_each_set_bit(i, (unsigned long *)&pebs_status,
- x86_pmu.max_pebs_events)
- error[i]++;
- continue;
- }
-
- counts[bit]++;
- }
-
- for (bit = 0; bit < x86_pmu.max_pebs_events; bit++) {
- if ((counts[bit] == 0) && (error[bit] == 0))
- continue;
-
- event = cpuc->events[bit];
- WARN_ON_ONCE(!event);
- WARN_ON_ONCE(!event->attr.precise_ip);
-
- /* log dropped samples number */
- if (error[bit])
- perf_log_lost_samples(event, error[bit]);
-
- if (counts[bit]) {
- __intel_pmu_pebs_event(event, iregs, base,
- top, bit, counts[bit]);
- }
- }
-}
-
-/*
- * BTS, PEBS probe and setup
- */
-
-void __init intel_ds_init(void)
-{
- /*
- * No support for 32bit formats
- */
- if (!boot_cpu_has(X86_FEATURE_DTES64))
- return;
-
- x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS);
- x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
- if (x86_pmu.pebs) {
- char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-';
- int format = x86_pmu.intel_cap.pebs_format;
-
- switch (format) {
- case 0:
- printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
- x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
- break;
-
- case 1:
- printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
- x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
- break;
-
- case 2:
- pr_cont("PEBS fmt2%c, ", pebs_type);
- x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
- break;
-
- case 3:
- pr_cont("PEBS fmt3%c, ", pebs_type);
- x86_pmu.pebs_record_size =
- sizeof(struct pebs_record_skl);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
- x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
- break;
-
- default:
- printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
- x86_pmu.pebs = 0;
- }
- }
-}
-
-void perf_restore_debug_store(void)
-{
- struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
-
- if (!x86_pmu.bts && !x86_pmu.pebs)
- return;
-
- wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
-}
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
deleted file mode 100644
index b2c9475..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include <asm/perf_event.h>
-#include <asm/msr.h>
-#include <asm/insn.h>
-
-#include "perf_event.h"
-
-enum {
- LBR_FORMAT_32 = 0x00,
- LBR_FORMAT_LIP = 0x01,
- LBR_FORMAT_EIP = 0x02,
- LBR_FORMAT_EIP_FLAGS = 0x03,
- LBR_FORMAT_EIP_FLAGS2 = 0x04,
- LBR_FORMAT_INFO = 0x05,
- LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO,
-};
-
-static enum {
- LBR_EIP_FLAGS = 1,
- LBR_TSX = 2,
-} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
- [LBR_FORMAT_EIP_FLAGS] = LBR_EIP_FLAGS,
- [LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
-};
-
-/*
- * Intel LBR_SELECT bits
- * Intel Vol3a, April 2011, Section 16.7 Table 16-10
- *
- * Hardware branch filter (not available on all CPUs)
- */
-#define LBR_KERNEL_BIT 0 /* do not capture at ring0 */
-#define LBR_USER_BIT 1 /* do not capture at ring > 0 */
-#define LBR_JCC_BIT 2 /* do not capture conditional branches */
-#define LBR_REL_CALL_BIT 3 /* do not capture relative calls */
-#define LBR_IND_CALL_BIT 4 /* do not capture indirect calls */
-#define LBR_RETURN_BIT 5 /* do not capture near returns */
-#define LBR_IND_JMP_BIT 6 /* do not capture indirect jumps */
-#define LBR_REL_JMP_BIT 7 /* do not capture relative jumps */
-#define LBR_FAR_BIT 8 /* do not capture far branches */
-#define LBR_CALL_STACK_BIT 9 /* enable call stack */
-
-#define LBR_KERNEL (1 << LBR_KERNEL_BIT)
-#define LBR_USER (1 << LBR_USER_BIT)
-#define LBR_JCC (1 << LBR_JCC_BIT)
-#define LBR_REL_CALL (1 << LBR_REL_CALL_BIT)
-#define LBR_IND_CALL (1 << LBR_IND_CALL_BIT)
-#define LBR_RETURN (1 << LBR_RETURN_BIT)
-#define LBR_REL_JMP (1 << LBR_REL_JMP_BIT)
-#define LBR_IND_JMP (1 << LBR_IND_JMP_BIT)
-#define LBR_FAR (1 << LBR_FAR_BIT)
-#define LBR_CALL_STACK (1 << LBR_CALL_STACK_BIT)
-
-#define LBR_PLM (LBR_KERNEL | LBR_USER)
-
-#define LBR_SEL_MASK 0x1ff /* valid bits in LBR_SELECT */
-#define LBR_NOT_SUPP -1 /* LBR filter not supported */
-#define LBR_IGN 0 /* ignored */
-
-#define LBR_ANY \
- (LBR_JCC |\
- LBR_REL_CALL |\
- LBR_IND_CALL |\
- LBR_RETURN |\
- LBR_REL_JMP |\
- LBR_IND_JMP |\
- LBR_FAR)
-
-#define LBR_FROM_FLAG_MISPRED (1ULL << 63)
-#define LBR_FROM_FLAG_IN_TX (1ULL << 62)
-#define LBR_FROM_FLAG_ABORT (1ULL << 61)
-
-/*
- * x86control flow change classification
- * x86control flow changes include branches, interrupts, traps, faults
- */
-enum {
- X86_BR_NONE = 0, /* unknown */
-
- X86_BR_USER = 1 << 0, /* branch target is user */
- X86_BR_KERNEL = 1 << 1, /* branch target is kernel */
-
- X86_BR_CALL = 1 << 2, /* call */
- X86_BR_RET = 1 << 3, /* return */
- X86_BR_SYSCALL = 1 << 4, /* syscall */
- X86_BR_SYSRET = 1 << 5, /* syscall return */
- X86_BR_INT = 1 << 6, /* sw interrupt */
- X86_BR_IRET = 1 << 7, /* return from interrupt */
- X86_BR_JCC = 1 << 8, /* conditional */
- X86_BR_JMP = 1 << 9, /* jump */
- X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */
- X86_BR_IND_CALL = 1 << 11,/* indirect calls */
- X86_BR_ABORT = 1 << 12,/* transaction abort */
- X86_BR_IN_TX = 1 << 13,/* in transaction */
- X86_BR_NO_TX = 1 << 14,/* not in transaction */
- X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
- X86_BR_CALL_STACK = 1 << 16,/* call stack */
- X86_BR_IND_JMP = 1 << 17,/* indirect jump */
-};
-
-#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
-#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
-
-#define X86_BR_ANY \
- (X86_BR_CALL |\
- X86_BR_RET |\
- X86_BR_SYSCALL |\
- X86_BR_SYSRET |\
- X86_BR_INT |\
- X86_BR_IRET |\
- X86_BR_JCC |\
- X86_BR_JMP |\
- X86_BR_IRQ |\
- X86_BR_ABORT |\
- X86_BR_IND_CALL |\
- X86_BR_IND_JMP |\
- X86_BR_ZERO_CALL)
-
-#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
-
-#define X86_BR_ANY_CALL \
- (X86_BR_CALL |\
- X86_BR_IND_CALL |\
- X86_BR_ZERO_CALL |\
- X86_BR_SYSCALL |\
- X86_BR_IRQ |\
- X86_BR_INT)
-
-static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
-
-/*
- * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
- * otherwise it becomes near impossible to get a reliable stack.
- */
-
-static void __intel_pmu_lbr_enable(bool pmi)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- u64 debugctl, lbr_select = 0, orig_debugctl;
-
- /*
- * No need to unfreeze manually, as v4 can do that as part
- * of the GLOBAL_STATUS ack.
- */
- if (pmi && x86_pmu.version >= 4)
- return;
-
- /*
- * No need to reprogram LBR_SELECT in a PMI, as it
- * did not change.
- */
- if (cpuc->lbr_sel && !pmi) {
- lbr_select = cpuc->lbr_sel->config;
- wrmsrl(MSR_LBR_SELECT, lbr_select);
- }
-
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
- orig_debugctl = debugctl;
- debugctl |= DEBUGCTLMSR_LBR;
- /*
- * LBR callstack does not work well with FREEZE_LBRS_ON_PMI.
- * If FREEZE_LBRS_ON_PMI is set, PMI near call/return instructions
- * may cause superfluous increase/decrease of LBR_TOS.
- */
- if (!(lbr_select & LBR_CALL_STACK))
- debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
- if (orig_debugctl != debugctl)
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void __intel_pmu_lbr_disable(void)
-{
- u64 debugctl;
-
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
- debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void intel_pmu_lbr_reset_32(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++)
- wrmsrl(x86_pmu.lbr_from + i, 0);
-}
-
-static void intel_pmu_lbr_reset_64(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- wrmsrl(x86_pmu.lbr_from + i, 0);
- wrmsrl(x86_pmu.lbr_to + i, 0);
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
- wrmsrl(MSR_LBR_INFO_0 + i, 0);
- }
-}
-
-void intel_pmu_lbr_reset(void)
-{
- if (!x86_pmu.lbr_nr)
- return;
-
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
- intel_pmu_lbr_reset_32();
- else
- intel_pmu_lbr_reset_64();
-}
-
-/*
- * TOS = most recently recorded branch
- */
-static inline u64 intel_pmu_lbr_tos(void)
-{
- u64 tos;
-
- rdmsrl(x86_pmu.lbr_tos, tos);
- return tos;
-}
-
-enum {
- LBR_NONE,
- LBR_VALID,
-};
-
-static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
-{
- int i;
- unsigned lbr_idx, mask;
- u64 tos;
-
- if (task_ctx->lbr_callstack_users == 0 ||
- task_ctx->lbr_stack_state == LBR_NONE) {
- intel_pmu_lbr_reset();
- return;
- }
-
- mask = x86_pmu.lbr_nr - 1;
- tos = intel_pmu_lbr_tos();
- for (i = 0; i < tos; i++) {
- lbr_idx = (tos - i) & mask;
- wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
- wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
- wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
- }
- task_ctx->lbr_stack_state = LBR_NONE;
-}
-
-static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
-{
- int i;
- unsigned lbr_idx, mask;
- u64 tos;
-
- if (task_ctx->lbr_callstack_users == 0) {
- task_ctx->lbr_stack_state = LBR_NONE;
- return;
- }
-
- mask = x86_pmu.lbr_nr - 1;
- tos = intel_pmu_lbr_tos();
- for (i = 0; i < tos; i++) {
- lbr_idx = (tos - i) & mask;
- rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
- rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
- rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
- }
- task_ctx->lbr_stack_state = LBR_VALID;
-}
-
-void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct x86_perf_task_context *task_ctx;
-
- /*
- * If LBR callstack feature is enabled and the stack was saved when
- * the task was scheduled out, restore the stack. Otherwise flush
- * the LBR stack.
- */
- task_ctx = ctx ? ctx->task_ctx_data : NULL;
- if (task_ctx) {
- if (sched_in) {
- __intel_pmu_lbr_restore(task_ctx);
- cpuc->lbr_context = ctx;
- } else {
- __intel_pmu_lbr_save(task_ctx);
- }
- return;
- }
-
- /*
- * When sampling the branck stack in system-wide, it may be
- * necessary to flush the stack on context switch. This happens
- * when the branch stack does not tag its entries with the pid
- * of the current task. Otherwise it becomes impossible to
- * associate a branch entry with a task. This ambiguity is more
- * likely to appear when the branch stack supports priv level
- * filtering and the user sets it to monitor only at the user
- * level (which could be a useful measurement in system-wide
- * mode). In that case, the risk is high of having a branch
- * stack with branch from multiple tasks.
- */
- if (sched_in) {
- intel_pmu_lbr_reset();
- cpuc->lbr_context = ctx;
- }
-}
-
-static inline bool branch_user_callstack(unsigned br_sel)
-{
- return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK);
-}
-
-void intel_pmu_lbr_enable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct x86_perf_task_context *task_ctx;
-
- if (!x86_pmu.lbr_nr)
- return;
-
- /*
- * Reset the LBR stack if we changed task context to
- * avoid data leaks.
- */
- if (event->ctx->task && cpuc->lbr_context != event->ctx) {
- intel_pmu_lbr_reset();
- cpuc->lbr_context = event->ctx;
- }
- cpuc->br_sel = event->hw.branch_reg.reg;
-
- if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
- event->ctx->task_ctx_data) {
- task_ctx = event->ctx->task_ctx_data;
- task_ctx->lbr_callstack_users++;
- }
-
- cpuc->lbr_users++;
- perf_sched_cb_inc(event->ctx->pmu);
-}
-
-void intel_pmu_lbr_disable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- struct x86_perf_task_context *task_ctx;
-
- if (!x86_pmu.lbr_nr)
- return;
-
- if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
- event->ctx->task_ctx_data) {
- task_ctx = event->ctx->task_ctx_data;
- task_ctx->lbr_callstack_users--;
- }
-
- cpuc->lbr_users--;
- WARN_ON_ONCE(cpuc->lbr_users < 0);
- perf_sched_cb_dec(event->ctx->pmu);
-
- if (cpuc->enabled && !cpuc->lbr_users) {
- __intel_pmu_lbr_disable();
- /* avoid stale pointer */
- cpuc->lbr_context = NULL;
- }
-}
-
-void intel_pmu_lbr_enable_all(bool pmi)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (cpuc->lbr_users)
- __intel_pmu_lbr_enable(pmi);
-}
-
-void intel_pmu_lbr_disable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (cpuc->lbr_users)
- __intel_pmu_lbr_disable();
-}
-
-static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
-{
- unsigned long mask = x86_pmu.lbr_nr - 1;
- u64 tos = intel_pmu_lbr_tos();
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- unsigned long lbr_idx = (tos - i) & mask;
- union {
- struct {
- u32 from;
- u32 to;
- };
- u64 lbr;
- } msr_lastbranch;
-
- rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
-
- cpuc->lbr_entries[i].from = msr_lastbranch.from;
- cpuc->lbr_entries[i].to = msr_lastbranch.to;
- cpuc->lbr_entries[i].mispred = 0;
- cpuc->lbr_entries[i].predicted = 0;
- cpuc->lbr_entries[i].reserved = 0;
- }
- cpuc->lbr_stack.nr = i;
-}
-
-/*
- * Due to lack of segmentation in Linux the effective address (offset)
- * is the same as the linear address, allowing us to merge the LIP and EIP
- * LBR formats.
- */
-static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
-{
- unsigned long mask = x86_pmu.lbr_nr - 1;
- int lbr_format = x86_pmu.intel_cap.lbr_format;
- u64 tos = intel_pmu_lbr_tos();
- int i;
- int out = 0;
- int num = x86_pmu.lbr_nr;
-
- if (cpuc->lbr_sel->config & LBR_CALL_STACK)
- num = tos;
-
- for (i = 0; i < num; i++) {
- unsigned long lbr_idx = (tos - i) & mask;
- u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
- int skip = 0;
- u16 cycles = 0;
- int lbr_flags = lbr_desc[lbr_format];
-
- rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
- rdmsrl(x86_pmu.lbr_to + lbr_idx, to);
-
- if (lbr_format == LBR_FORMAT_INFO) {
- u64 info;
-
- rdmsrl(MSR_LBR_INFO_0 + lbr_idx, info);
- mis = !!(info & LBR_INFO_MISPRED);
- pred = !mis;
- in_tx = !!(info & LBR_INFO_IN_TX);
- abort = !!(info & LBR_INFO_ABORT);
- cycles = (info & LBR_INFO_CYCLES);
- }
- if (lbr_flags & LBR_EIP_FLAGS) {
- mis = !!(from & LBR_FROM_FLAG_MISPRED);
- pred = !mis;
- skip = 1;
- }
- if (lbr_flags & LBR_TSX) {
- in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
- abort = !!(from & LBR_FROM_FLAG_ABORT);
- skip = 3;
- }
- from = (u64)((((s64)from) << skip) >> skip);
-
- /*
- * Some CPUs report duplicated abort records,
- * with the second entry not having an abort bit set.
- * Skip them here. This loop runs backwards,
- * so we need to undo the previous record.
- * If the abort just happened outside the window
- * the extra entry cannot be removed.
- */
- if (abort && x86_pmu.lbr_double_abort && out > 0)
- out--;
-
- cpuc->lbr_entries[out].from = from;
- cpuc->lbr_entries[out].to = to;
- cpuc->lbr_entries[out].mispred = mis;
- cpuc->lbr_entries[out].predicted = pred;
- cpuc->lbr_entries[out].in_tx = in_tx;
- cpuc->lbr_entries[out].abort = abort;
- cpuc->lbr_entries[out].cycles = cycles;
- cpuc->lbr_entries[out].reserved = 0;
- out++;
- }
- cpuc->lbr_stack.nr = out;
-}
-
-void intel_pmu_lbr_read(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-
- if (!cpuc->lbr_users)
- return;
-
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
- intel_pmu_lbr_read_32(cpuc);
- else
- intel_pmu_lbr_read_64(cpuc);
-
- intel_pmu_lbr_filter(cpuc);
-}
-
-/*
- * SW filter is used:
- * - in case there is no HW filter
- * - in case the HW filter has errata or limitations
- */
-static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
-{
- u64 br_type = event->attr.branch_sample_type;
- int mask = 0;
-
- if (br_type & PERF_SAMPLE_BRANCH_USER)
- mask |= X86_BR_USER;
-
- if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
- mask |= X86_BR_KERNEL;
-
- /* we ignore BRANCH_HV here */
-
- if (br_type & PERF_SAMPLE_BRANCH_ANY)
- mask |= X86_BR_ANY;
-
- if (br_type & PERF_SAMPLE_BRANCH_ANY_CALL)
- mask |= X86_BR_ANY_CALL;
-
- if (br_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
- mask |= X86_BR_RET | X86_BR_IRET | X86_BR_SYSRET;
-
- if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
- mask |= X86_BR_IND_CALL;
-
- if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
- mask |= X86_BR_ABORT;
-
- if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
- mask |= X86_BR_IN_TX;
-
- if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
- mask |= X86_BR_NO_TX;
-
- if (br_type & PERF_SAMPLE_BRANCH_COND)
- mask |= X86_BR_JCC;
-
- if (br_type & PERF_SAMPLE_BRANCH_CALL_STACK) {
- if (!x86_pmu_has_lbr_callstack())
- return -EOPNOTSUPP;
- if (mask & ~(X86_BR_USER | X86_BR_KERNEL))
- return -EINVAL;
- mask |= X86_BR_CALL | X86_BR_IND_CALL | X86_BR_RET |
- X86_BR_CALL_STACK;
- }
-
- if (br_type & PERF_SAMPLE_BRANCH_IND_JUMP)
- mask |= X86_BR_IND_JMP;
-
- /*
- * stash actual user request into reg, it may
- * be used by fixup code for some CPU
- */
- event->hw.branch_reg.reg = mask;
- return 0;
-}
-
-/*
- * setup the HW LBR filter
- * Used only when available, may not be enough to disambiguate
- * all branches, may need the help of the SW filter
- */
-static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
-{
- struct hw_perf_event_extra *reg;
- u64 br_type = event->attr.branch_sample_type;
- u64 mask = 0, v;
- int i;
-
- for (i = 0; i < PERF_SAMPLE_BRANCH_MAX_SHIFT; i++) {
- if (!(br_type & (1ULL << i)))
- continue;
-
- v = x86_pmu.lbr_sel_map[i];
- if (v == LBR_NOT_SUPP)
- return -EOPNOTSUPP;
-
- if (v != LBR_IGN)
- mask |= v;
- }
- reg = &event->hw.branch_reg;
- reg->idx = EXTRA_REG_LBR;
-
- /*
- * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate
- * in suppress mode. So LBR_SELECT should be set to
- * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK)
- */
- reg->config = mask ^ x86_pmu.lbr_sel_mask;
-
- return 0;
-}
-
-int intel_pmu_setup_lbr_filter(struct perf_event *event)
-{
- int ret = 0;
-
- /*
- * no LBR on this PMU
- */
- if (!x86_pmu.lbr_nr)
- return -EOPNOTSUPP;
-
- /*
- * setup SW LBR filter
- */
- ret = intel_pmu_setup_sw_lbr_filter(event);
- if (ret)
- return ret;
-
- /*
- * setup HW LBR filter, if any
- */
- if (x86_pmu.lbr_sel_map)
- ret = intel_pmu_setup_hw_lbr_filter(event);
-
- return ret;
-}
-
-/*
- * return the type of control flow change at address "from"
- * intruction is not necessarily a branch (in case of interrupt).
- *
- * The branch type returned also includes the priv level of the
- * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
- *
- * If a branch type is unknown OR the instruction cannot be
- * decoded (e.g., text page not present), then X86_BR_NONE is
- * returned.
- */
-static int branch_type(unsigned long from, unsigned long to, int abort)
-{
- struct insn insn;
- void *addr;
- int bytes_read, bytes_left;
- int ret = X86_BR_NONE;
- int ext, to_plm, from_plm;
- u8 buf[MAX_INSN_SIZE];
- int is64 = 0;
-
- to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
- from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
-
- /*
- * maybe zero if lbr did not fill up after a reset by the time
- * we get a PMU interrupt
- */
- if (from == 0 || to == 0)
- return X86_BR_NONE;
-
- if (abort)
- return X86_BR_ABORT | to_plm;
-
- if (from_plm == X86_BR_USER) {
- /*
- * can happen if measuring at the user level only
- * and we interrupt in a kernel thread, e.g., idle.
- */
- if (!current->mm)
- return X86_BR_NONE;
-
- /* may fail if text not present */
- bytes_left = copy_from_user_nmi(buf, (void __user *)from,
- MAX_INSN_SIZE);
- bytes_read = MAX_INSN_SIZE - bytes_left;
- if (!bytes_read)
- return X86_BR_NONE;
-
- addr = buf;
- } else {
- /*
- * The LBR logs any address in the IP, even if the IP just
- * faulted. This means userspace can control the from address.
- * Ensure we don't blindy read any address by validating it is
- * a known text address.
- */
- if (kernel_text_address(from)) {
- addr = (void *)from;
- /*
- * Assume we can get the maximum possible size
- * when grabbing kernel data. This is not
- * _strictly_ true since we could possibly be
- * executing up next to a memory hole, but
- * it is very unlikely to be a problem.
- */
- bytes_read = MAX_INSN_SIZE;
- } else {
- return X86_BR_NONE;
- }
- }
-
- /*
- * decoder needs to know the ABI especially
- * on 64-bit systems running 32-bit apps
- */
-#ifdef CONFIG_X86_64
- is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
-#endif
- insn_init(&insn, addr, bytes_read, is64);
- insn_get_opcode(&insn);
- if (!insn.opcode.got)
- return X86_BR_ABORT;
-
- switch (insn.opcode.bytes[0]) {
- case 0xf:
- switch (insn.opcode.bytes[1]) {
- case 0x05: /* syscall */
- case 0x34: /* sysenter */
- ret = X86_BR_SYSCALL;
- break;
- case 0x07: /* sysret */
- case 0x35: /* sysexit */
- ret = X86_BR_SYSRET;
- break;
- case 0x80 ... 0x8f: /* conditional */
- ret = X86_BR_JCC;
- break;
- default:
- ret = X86_BR_NONE;
- }
- break;
- case 0x70 ... 0x7f: /* conditional */
- ret = X86_BR_JCC;
- break;
- case 0xc2: /* near ret */
- case 0xc3: /* near ret */
- case 0xca: /* far ret */
- case 0xcb: /* far ret */
- ret = X86_BR_RET;
- break;
- case 0xcf: /* iret */
- ret = X86_BR_IRET;
- break;
- case 0xcc ... 0xce: /* int */
- ret = X86_BR_INT;
- break;
- case 0xe8: /* call near rel */
- insn_get_immediate(&insn);
- if (insn.immediate1.value == 0) {
- /* zero length call */
- ret = X86_BR_ZERO_CALL;
- break;
- }
- case 0x9a: /* call far absolute */
- ret = X86_BR_CALL;
- break;
- case 0xe0 ... 0xe3: /* loop jmp */
- ret = X86_BR_JCC;
- break;
- case 0xe9 ... 0xeb: /* jmp */
- ret = X86_BR_JMP;
- break;
- case 0xff: /* call near absolute, call far absolute ind */
- insn_get_modrm(&insn);
- ext = (insn.modrm.bytes[0] >> 3) & 0x7;
- switch (ext) {
- case 2: /* near ind call */
- case 3: /* far ind call */
- ret = X86_BR_IND_CALL;
- break;
- case 4:
- case 5:
- ret = X86_BR_IND_JMP;
- break;
- }
- break;
- default:
- ret = X86_BR_NONE;
- }
- /*
- * interrupts, traps, faults (and thus ring transition) may
- * occur on any instructions. Thus, to classify them correctly,
- * we need to first look at the from and to priv levels. If they
- * are different and to is in the kernel, then it indicates
- * a ring transition. If the from instruction is not a ring
- * transition instr (syscall, systenter, int), then it means
- * it was a irq, trap or fault.
- *
- * we have no way of detecting kernel to kernel faults.
- */
- if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
- && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
- ret = X86_BR_IRQ;
-
- /*
- * branch priv level determined by target as
- * is done by HW when LBR_SELECT is implemented
- */
- if (ret != X86_BR_NONE)
- ret |= to_plm;
-
- return ret;
-}
-
-/*
- * implement actual branch filter based on user demand.
- * Hardware may not exactly satisfy that request, thus
- * we need to inspect opcodes. Mismatched branches are
- * discarded. Therefore, the number of branches returned
- * in PERF_SAMPLE_BRANCH_STACK sample may vary.
- */
-static void
-intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
-{
- u64 from, to;
- int br_sel = cpuc->br_sel;
- int i, j, type;
- bool compress = false;
-
- /* if sampling all branches, then nothing to filter */
- if ((br_sel & X86_BR_ALL) == X86_BR_ALL)
- return;
-
- for (i = 0; i < cpuc->lbr_stack.nr; i++) {
-
- from = cpuc->lbr_entries[i].from;
- to = cpuc->lbr_entries[i].to;
-
- type = branch_type(from, to, cpuc->lbr_entries[i].abort);
- if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
- if (cpuc->lbr_entries[i].in_tx)
- type |= X86_BR_IN_TX;
- else
- type |= X86_BR_NO_TX;
- }
-
- /* if type does not correspond, then discard */
- if (type == X86_BR_NONE || (br_sel & type) != type) {
- cpuc->lbr_entries[i].from = 0;
- compress = true;
- }
- }
-
- if (!compress)
- return;
-
- /* remove all entries with from=0 */
- for (i = 0; i < cpuc->lbr_stack.nr; ) {
- if (!cpuc->lbr_entries[i].from) {
- j = i;
- while (++j < cpuc->lbr_stack.nr)
- cpuc->lbr_entries[j-1] = cpuc->lbr_entries[j];
- cpuc->lbr_stack.nr--;
- if (!cpuc->lbr_entries[i].from)
- continue;
- }
- i++;
- }
-}
-
-/*
- * Map interface branch filters onto LBR filters
- */
-static const int nhm_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
- [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
- [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
- [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
- [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
- [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_REL_JMP
- | LBR_IND_JMP | LBR_FAR,
- /*
- * NHM/WSM erratum: must include REL_JMP+IND_JMP to get CALL branches
- */
- [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] =
- LBR_REL_CALL | LBR_IND_CALL | LBR_REL_JMP | LBR_IND_JMP | LBR_FAR,
- /*
- * NHM/WSM erratum: must include IND_JMP to capture IND_CALL
- */
- [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL | LBR_IND_JMP,
- [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
- [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
-};
-
-static const int snb_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
- [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
- [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
- [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
- [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
- [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_FAR,
- [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
- | LBR_FAR,
- [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
- [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
- [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
-};
-
-static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
- [PERF_SAMPLE_BRANCH_ANY_SHIFT] = LBR_ANY,
- [PERF_SAMPLE_BRANCH_USER_SHIFT] = LBR_USER,
- [PERF_SAMPLE_BRANCH_KERNEL_SHIFT] = LBR_KERNEL,
- [PERF_SAMPLE_BRANCH_HV_SHIFT] = LBR_IGN,
- [PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT] = LBR_RETURN | LBR_FAR,
- [PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
- | LBR_FAR,
- [PERF_SAMPLE_BRANCH_IND_CALL_SHIFT] = LBR_IND_CALL,
- [PERF_SAMPLE_BRANCH_COND_SHIFT] = LBR_JCC,
- [PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] = LBR_REL_CALL | LBR_IND_CALL
- | LBR_RETURN | LBR_CALL_STACK,
- [PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT] = LBR_IND_JMP,
-};
-
-/* core */
-void __init intel_pmu_lbr_init_core(void)
-{
- x86_pmu.lbr_nr = 4;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
- x86_pmu.lbr_to = MSR_LBR_CORE_TO;
-
- /*
- * SW branch filter usage:
- * - compensate for lack of HW filter
- */
- pr_cont("4-deep LBR, ");
-}
-
-/* nehalem/westmere */
-void __init intel_pmu_lbr_init_nhm(void)
-{
- x86_pmu.lbr_nr = 16;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
- x86_pmu.lbr_to = MSR_LBR_NHM_TO;
-
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
-
- /*
- * SW branch filter usage:
- * - workaround LBR_SEL errata (see above)
- * - support syscall, sysret capture.
- * That requires LBR_FAR but that means far
- * jmp need to be filtered out
- */
- pr_cont("16-deep LBR, ");
-}
-
-/* sandy bridge */
-void __init intel_pmu_lbr_init_snb(void)
-{
- x86_pmu.lbr_nr = 16;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
- x86_pmu.lbr_to = MSR_LBR_NHM_TO;
-
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = snb_lbr_sel_map;
-
- /*
- * SW branch filter usage:
- * - support syscall, sysret capture.
- * That requires LBR_FAR but that means far
- * jmp need to be filtered out
- */
- pr_cont("16-deep LBR, ");
-}
-
-/* haswell */
-void intel_pmu_lbr_init_hsw(void)
-{
- x86_pmu.lbr_nr = 16;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
- x86_pmu.lbr_to = MSR_LBR_NHM_TO;
-
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
-
- pr_cont("16-deep LBR, ");
-}
-
-/* skylake */
-__init void intel_pmu_lbr_init_skl(void)
-{
- x86_pmu.lbr_nr = 32;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
- x86_pmu.lbr_to = MSR_LBR_NHM_TO;
-
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
-
- /*
- * SW branch filter usage:
- * - support syscall, sysret capture.
- * That requires LBR_FAR but that means far
- * jmp need to be filtered out
- */
- pr_cont("32-deep LBR, ");
-}
-
-/* atom */
-void __init intel_pmu_lbr_init_atom(void)
-{
- /*
- * only models starting at stepping 10 seems
- * to have an operational LBR which can freeze
- * on PMU interrupt
- */
- if (boot_cpu_data.x86_model == 28
- && boot_cpu_data.x86_mask < 10) {
- pr_cont("LBR disabled due to erratum");
- return;
- }
-
- x86_pmu.lbr_nr = 8;
- x86_pmu.lbr_tos = MSR_LBR_TOS;
- x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
- x86_pmu.lbr_to = MSR_LBR_CORE_TO;
-
- /*
- * SW branch filter usage:
- * - compensate for lack of HW filter
- */
- pr_cont("8-deep LBR, ");
-}
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c
deleted file mode 100644
index 4216928..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_pt.c
+++ /dev/null
@@ -1,1178 +0,0 @@
-/*
- * Intel(R) Processor Trace PMU driver for perf
- * Copyright (c) 2013-2014, 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.
- *
- * Intel PT is specified in the Intel Architecture Instruction Set Extensions
- * Programming Reference:
- * http://software.intel.com/en-us/intel-isa-extensions
- */
-
-#undef DEBUG
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-
-#include <asm/perf_event.h>
-#include <asm/insn.h>
-#include <asm/io.h>
-
-#include "perf_event.h"
-#include "intel_pt.h"
-
-static DEFINE_PER_CPU(struct pt, pt_ctx);
-
-static struct pt_pmu pt_pmu;
-
-enum cpuid_regs {
- CR_EAX = 0,
- CR_ECX,
- CR_EDX,
- CR_EBX
-};
-
-/*
- * Capabilities of Intel PT hardware, such as number of address bits or
- * supported output schemes, are cached and exported to userspace as "caps"
- * attribute group of pt pmu device
- * (/sys/bus/event_source/devices/intel_pt/caps/) so that userspace can store
- * relevant bits together with intel_pt traces.
- *
- * These are necessary for both trace decoding (payloads_lip, contains address
- * width encoded in IP-related packets), and event configuration (bitmasks with
- * permitted values for certain bit fields).
- */
-#define PT_CAP(_n, _l, _r, _m) \
- [PT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l, \
- .reg = _r, .mask = _m }
-
-static struct pt_cap_desc {
- const char *name;
- u32 leaf;
- u8 reg;
- u32 mask;
-} pt_caps[] = {
- PT_CAP(max_subleaf, 0, CR_EAX, 0xffffffff),
- PT_CAP(cr3_filtering, 0, CR_EBX, BIT(0)),
- PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)),
- PT_CAP(mtc, 0, CR_EBX, BIT(3)),
- PT_CAP(topa_output, 0, CR_ECX, BIT(0)),
- PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)),
- PT_CAP(single_range_output, 0, CR_ECX, BIT(2)),
- PT_CAP(payloads_lip, 0, CR_ECX, BIT(31)),
- PT_CAP(mtc_periods, 1, CR_EAX, 0xffff0000),
- PT_CAP(cycle_thresholds, 1, CR_EBX, 0xffff),
- PT_CAP(psb_periods, 1, CR_EBX, 0xffff0000),
-};
-
-static u32 pt_cap_get(enum pt_capabilities cap)
-{
- struct pt_cap_desc *cd = &pt_caps[cap];
- u32 c = pt_pmu.caps[cd->leaf * PT_CPUID_REGS_NUM + cd->reg];
- unsigned int shift = __ffs(cd->mask);
-
- return (c & cd->mask) >> shift;
-}
-
-static ssize_t pt_cap_show(struct device *cdev,
- struct device_attribute *attr,
- char *buf)
-{
- struct dev_ext_attribute *ea =
- container_of(attr, struct dev_ext_attribute, attr);
- enum pt_capabilities cap = (long)ea->var;
-
- return snprintf(buf, PAGE_SIZE, "%x\n", pt_cap_get(cap));
-}
-
-static struct attribute_group pt_cap_group = {
- .name = "caps",
-};
-
-PMU_FORMAT_ATTR(cyc, "config:1" );
-PMU_FORMAT_ATTR(mtc, "config:9" );
-PMU_FORMAT_ATTR(tsc, "config:10" );
-PMU_FORMAT_ATTR(noretcomp, "config:11" );
-PMU_FORMAT_ATTR(mtc_period, "config:14-17" );
-PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" );
-PMU_FORMAT_ATTR(psb_period, "config:24-27" );
-
-static struct attribute *pt_formats_attr[] = {
- &format_attr_cyc.attr,
- &format_attr_mtc.attr,
- &format_attr_tsc.attr,
- &format_attr_noretcomp.attr,
- &format_attr_mtc_period.attr,
- &format_attr_cyc_thresh.attr,
- &format_attr_psb_period.attr,
- NULL,
-};
-
-static struct attribute_group pt_format_group = {
- .name = "format",
- .attrs = pt_formats_attr,
-};
-
-static const struct attribute_group *pt_attr_groups[] = {
- &pt_cap_group,
- &pt_format_group,
- NULL,
-};
-
-static int __init pt_pmu_hw_init(void)
-{
- struct dev_ext_attribute *de_attrs;
- struct attribute **attrs;
- size_t size;
- int ret;
- long i;
-
- attrs = NULL;
- ret = -ENODEV;
- if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
- goto fail;
-
- for (i = 0; i < PT_CPUID_LEAVES; i++) {
- cpuid_count(20, i,
- &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM],
- &pt_pmu.caps[CR_EBX + i*PT_CPUID_REGS_NUM],
- &pt_pmu.caps[CR_ECX + i*PT_CPUID_REGS_NUM],
- &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]);
- }
-
- ret = -ENOMEM;
- size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
- attrs = kzalloc(size, GFP_KERNEL);
- if (!attrs)
- goto fail;
-
- size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
- de_attrs = kzalloc(size, GFP_KERNEL);
- if (!de_attrs)
- goto fail;
-
- for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
- struct dev_ext_attribute *de_attr = de_attrs + i;
-
- de_attr->attr.attr.name = pt_caps[i].name;
-
- sysfs_attr_init(&de_attr->attr.attr);
-
- de_attr->attr.attr.mode = S_IRUGO;
- de_attr->attr.show = pt_cap_show;
- de_attr->var = (void *)i;
-
- attrs[i] = &de_attr->attr.attr;
- }
-
- pt_cap_group.attrs = attrs;
-
- return 0;
-
-fail:
- kfree(attrs);
-
- return ret;
-}
-
-#define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC | \
- RTIT_CTL_CYC_THRESH | \
- RTIT_CTL_PSB_FREQ)
-
-#define RTIT_CTL_MTC (RTIT_CTL_MTC_EN | \
- RTIT_CTL_MTC_RANGE)
-
-#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \
- RTIT_CTL_DISRETC | \
- RTIT_CTL_CYC_PSB | \
- RTIT_CTL_MTC)
-
-static bool pt_event_valid(struct perf_event *event)
-{
- u64 config = event->attr.config;
- u64 allowed, requested;
-
- if ((config & PT_CONFIG_MASK) != config)
- return false;
-
- if (config & RTIT_CTL_CYC_PSB) {
- if (!pt_cap_get(PT_CAP_psb_cyc))
- return false;
-
- allowed = pt_cap_get(PT_CAP_psb_periods);
- requested = (config & RTIT_CTL_PSB_FREQ) >>
- RTIT_CTL_PSB_FREQ_OFFSET;
- if (requested && (!(allowed & BIT(requested))))
- return false;
-
- allowed = pt_cap_get(PT_CAP_cycle_thresholds);
- requested = (config & RTIT_CTL_CYC_THRESH) >>
- RTIT_CTL_CYC_THRESH_OFFSET;
- if (requested && (!(allowed & BIT(requested))))
- return false;
- }
-
- if (config & RTIT_CTL_MTC) {
- /*
- * In the unlikely case that CPUID lists valid mtc periods,
- * but not the mtc capability, drop out here.
- *
- * Spec says that setting mtc period bits while mtc bit in
- * CPUID is 0 will #GP, so better safe than sorry.
- */
- if (!pt_cap_get(PT_CAP_mtc))
- return false;
-
- allowed = pt_cap_get(PT_CAP_mtc_periods);
- if (!allowed)
- return false;
-
- requested = (config & RTIT_CTL_MTC_RANGE) >>
- RTIT_CTL_MTC_RANGE_OFFSET;
-
- if (!(allowed & BIT(requested)))
- return false;
- }
-
- return true;
-}
-
-/*
- * PT configuration helpers
- * These all are cpu affine and operate on a local PT
- */
-
-static void pt_config(struct perf_event *event)
-{
- u64 reg;
-
- if (!event->hw.itrace_started) {
- event->hw.itrace_started = 1;
- wrmsrl(MSR_IA32_RTIT_STATUS, 0);
- }
-
- reg = RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN;
-
- if (!event->attr.exclude_kernel)
- reg |= RTIT_CTL_OS;
- if (!event->attr.exclude_user)
- reg |= RTIT_CTL_USR;
-
- reg |= (event->attr.config & PT_CONFIG_MASK);
-
- wrmsrl(MSR_IA32_RTIT_CTL, reg);
-}
-
-static void pt_config_start(bool start)
-{
- u64 ctl;
-
- rdmsrl(MSR_IA32_RTIT_CTL, ctl);
- if (start)
- ctl |= RTIT_CTL_TRACEEN;
- else
- ctl &= ~RTIT_CTL_TRACEEN;
- wrmsrl(MSR_IA32_RTIT_CTL, ctl);
-
- /*
- * A wrmsr that disables trace generation serializes other PT
- * registers and causes all data packets to be written to memory,
- * but a fence is required for the data to become globally visible.
- *
- * The below WMB, separating data store and aux_head store matches
- * the consumer's RMB that separates aux_head load and data load.
- */
- if (!start)
- wmb();
-}
-
-static void pt_config_buffer(void *buf, unsigned int topa_idx,
- unsigned int output_off)
-{
- u64 reg;
-
- wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, virt_to_phys(buf));
-
- reg = 0x7f | ((u64)topa_idx << 7) | ((u64)output_off << 32);
-
- wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
-}
-
-/*
- * Keep ToPA table-related metadata on the same page as the actual table,
- * taking up a few words from the top
- */
-
-#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1)
-
-/**
- * struct topa - page-sized ToPA table with metadata at the top
- * @table: actual ToPA table entries, as understood by PT hardware
- * @list: linkage to struct pt_buffer's list of tables
- * @phys: physical address of this page
- * @offset: offset of the first entry in this table in the buffer
- * @size: total size of all entries in this table
- * @last: index of the last initialized entry in this table
- */
-struct topa {
- struct topa_entry table[TENTS_PER_PAGE];
- struct list_head list;
- u64 phys;
- u64 offset;
- size_t size;
- int last;
-};
-
-/* make -1 stand for the last table entry */
-#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)])
-
-/**
- * topa_alloc() - allocate page-sized ToPA table
- * @cpu: CPU on which to allocate.
- * @gfp: Allocation flags.
- *
- * Return: On success, return the pointer to ToPA table page.
- */
-static struct topa *topa_alloc(int cpu, gfp_t gfp)
-{
- int node = cpu_to_node(cpu);
- struct topa *topa;
- struct page *p;
-
- p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
- if (!p)
- return NULL;
-
- topa = page_address(p);
- topa->last = 0;
- topa->phys = page_to_phys(p);
-
- /*
- * In case of singe-entry ToPA, always put the self-referencing END
- * link as the 2nd entry in the table
- */
- if (!pt_cap_get(PT_CAP_topa_multiple_entries)) {
- TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT;
- TOPA_ENTRY(topa, 1)->end = 1;
- }
-
- return topa;
-}
-
-/**
- * topa_free() - free a page-sized ToPA table
- * @topa: Table to deallocate.
- */
-static void topa_free(struct topa *topa)
-{
- free_page((unsigned long)topa);
-}
-
-/**
- * topa_insert_table() - insert a ToPA table into a buffer
- * @buf: PT buffer that's being extended.
- * @topa: New topa table to be inserted.
- *
- * If it's the first table in this buffer, set up buffer's pointers
- * accordingly; otherwise, add a END=1 link entry to @topa to the current
- * "last" table and adjust the last table pointer to @topa.
- */
-static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
-{
- struct topa *last = buf->last;
-
- list_add_tail(&topa->list, &buf->tables);
-
- if (!buf->first) {
- buf->first = buf->last = buf->cur = topa;
- return;
- }
-
- topa->offset = last->offset + last->size;
- buf->last = topa;
-
- if (!pt_cap_get(PT_CAP_topa_multiple_entries))
- return;
-
- BUG_ON(last->last != TENTS_PER_PAGE - 1);
-
- TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT;
- TOPA_ENTRY(last, -1)->end = 1;
-}
-
-/**
- * topa_table_full() - check if a ToPA table is filled up
- * @topa: ToPA table.
- */
-static bool topa_table_full(struct topa *topa)
-{
- /* single-entry ToPA is a special case */
- if (!pt_cap_get(PT_CAP_topa_multiple_entries))
- return !!topa->last;
-
- return topa->last == TENTS_PER_PAGE - 1;
-}
-
-/**
- * topa_insert_pages() - create a list of ToPA tables
- * @buf: PT buffer being initialized.
- * @gfp: Allocation flags.
- *
- * This initializes a list of ToPA tables with entries from
- * the data_pages provided by rb_alloc_aux().
- *
- * Return: 0 on success or error code.
- */
-static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
-{
- struct topa *topa = buf->last;
- int order = 0;
- struct page *p;
-
- p = virt_to_page(buf->data_pages[buf->nr_pages]);
- if (PagePrivate(p))
- order = page_private(p);
-
- if (topa_table_full(topa)) {
- topa = topa_alloc(buf->cpu, gfp);
- if (!topa)
- return -ENOMEM;
-
- topa_insert_table(buf, topa);
- }
-
- TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
- TOPA_ENTRY(topa, -1)->size = order;
- if (!buf->snapshot && !pt_cap_get(PT_CAP_topa_multiple_entries)) {
- TOPA_ENTRY(topa, -1)->intr = 1;
- TOPA_ENTRY(topa, -1)->stop = 1;
- }
-
- topa->last++;
- topa->size += sizes(order);
-
- buf->nr_pages += 1ul << order;
-
- return 0;
-}
-
-/**
- * pt_topa_dump() - print ToPA tables and their entries
- * @buf: PT buffer.
- */
-static void pt_topa_dump(struct pt_buffer *buf)
-{
- struct topa *topa;
-
- list_for_each_entry(topa, &buf->tables, list) {
- int i;
-
- pr_debug("# table @%p (%016Lx), off %llx size %zx\n", topa->table,
- topa->phys, topa->offset, topa->size);
- for (i = 0; i < TENTS_PER_PAGE; i++) {
- pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
- &topa->table[i],
- (unsigned long)topa->table[i].base << TOPA_SHIFT,
- sizes(topa->table[i].size),
- topa->table[i].end ? 'E' : ' ',
- topa->table[i].intr ? 'I' : ' ',
- topa->table[i].stop ? 'S' : ' ',
- *(u64 *)&topa->table[i]);
- if ((pt_cap_get(PT_CAP_topa_multiple_entries) &&
- topa->table[i].stop) ||
- topa->table[i].end)
- break;
- }
- }
-}
-
-/**
- * pt_buffer_advance() - advance to the next output region
- * @buf: PT buffer.
- *
- * Advance the current pointers in the buffer to the next ToPA entry.
- */
-static void pt_buffer_advance(struct pt_buffer *buf)
-{
- buf->output_off = 0;
- buf->cur_idx++;
-
- if (buf->cur_idx == buf->cur->last) {
- if (buf->cur == buf->last)
- buf->cur = buf->first;
- else
- buf->cur = list_entry(buf->cur->list.next, struct topa,
- list);
- buf->cur_idx = 0;
- }
-}
-
-/**
- * pt_update_head() - calculate current offsets and sizes
- * @pt: Per-cpu pt context.
- *
- * Update buffer's current write pointer position and data size.
- */
-static void pt_update_head(struct pt *pt)
-{
- struct pt_buffer *buf = perf_get_aux(&pt->handle);
- u64 topa_idx, base, old;
-
- /* offset of the first region in this table from the beginning of buf */
- base = buf->cur->offset + buf->output_off;
-
- /* offset of the current output region within this table */
- for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
- base += sizes(buf->cur->table[topa_idx].size);
-
- if (buf->snapshot) {
- local_set(&buf->data_size, base);
- } else {
- old = (local64_xchg(&buf->head, base) &
- ((buf->nr_pages << PAGE_SHIFT) - 1));
- if (base < old)
- base += buf->nr_pages << PAGE_SHIFT;
-
- local_add(base - old, &buf->data_size);
- }
-}
-
-/**
- * pt_buffer_region() - obtain current output region's address
- * @buf: PT buffer.
- */
-static void *pt_buffer_region(struct pt_buffer *buf)
-{
- return phys_to_virt(buf->cur->table[buf->cur_idx].base << TOPA_SHIFT);
-}
-
-/**
- * pt_buffer_region_size() - obtain current output region's size
- * @buf: PT buffer.
- */
-static size_t pt_buffer_region_size(struct pt_buffer *buf)
-{
- return sizes(buf->cur->table[buf->cur_idx].size);
-}
-
-/**
- * pt_handle_status() - take care of possible status conditions
- * @pt: Per-cpu pt context.
- */
-static void pt_handle_status(struct pt *pt)
-{
- struct pt_buffer *buf = perf_get_aux(&pt->handle);
- int advance = 0;
- u64 status;
-
- rdmsrl(MSR_IA32_RTIT_STATUS, status);
-
- if (status & RTIT_STATUS_ERROR) {
- pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
- pt_topa_dump(buf);
- status &= ~RTIT_STATUS_ERROR;
- }
-
- if (status & RTIT_STATUS_STOPPED) {
- status &= ~RTIT_STATUS_STOPPED;
-
- /*
- * On systems that only do single-entry ToPA, hitting STOP
- * means we are already losing data; need to let the decoder
- * know.
- */
- if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
- buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
- local_inc(&buf->lost);
- advance++;
- }
- }
-
- /*
- * Also on single-entry ToPA implementations, interrupt will come
- * before the output reaches its output region's boundary.
- */
- if (!pt_cap_get(PT_CAP_topa_multiple_entries) && !buf->snapshot &&
- pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
- void *head = pt_buffer_region(buf);
-
- /* everything within this margin needs to be zeroed out */
- memset(head + buf->output_off, 0,
- pt_buffer_region_size(buf) -
- buf->output_off);
- advance++;
- }
-
- if (advance)
- pt_buffer_advance(buf);
-
- wrmsrl(MSR_IA32_RTIT_STATUS, status);
-}
-
-/**
- * pt_read_offset() - translate registers into buffer pointers
- * @buf: PT buffer.
- *
- * Set buffer's output pointers from MSR values.
- */
-static void pt_read_offset(struct pt_buffer *buf)
-{
- u64 offset, base_topa;
-
- rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base_topa);
- buf->cur = phys_to_virt(base_topa);
-
- rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
- /* offset within current output region */
- buf->output_off = offset >> 32;
- /* index of current output region within this table */
- buf->cur_idx = (offset & 0xffffff80) >> 7;
-}
-
-/**
- * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry
- * @buf: PT buffer.
- * @pg: Page offset in the buffer.
- *
- * When advancing to the next output region (ToPA entry), given a page offset
- * into the buffer, we need to find the offset of the first page in the next
- * region.
- */
-static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg)
-{
- struct topa_entry *te = buf->topa_index[pg];
-
- /* one region */
- if (buf->first == buf->last && buf->first->last == 1)
- return pg;
-
- do {
- pg++;
- pg &= buf->nr_pages - 1;
- } while (buf->topa_index[pg] == te);
-
- return pg;
-}
-
-/**
- * pt_buffer_reset_markers() - place interrupt and stop bits in the buffer
- * @buf: PT buffer.
- * @handle: Current output handle.
- *
- * Place INT and STOP marks to prevent overwriting old data that the consumer
- * hasn't yet collected and waking up the consumer after a certain fraction of
- * the buffer has filled up. Only needed and sensible for non-snapshot counters.
- *
- * This obviously relies on buf::head to figure out buffer markers, so it has
- * to be called after pt_buffer_reset_offsets() and before the hardware tracing
- * is enabled.
- */
-static int pt_buffer_reset_markers(struct pt_buffer *buf,
- struct perf_output_handle *handle)
-
-{
- unsigned long head = local64_read(&buf->head);
- unsigned long idx, npages, wakeup;
-
- /* can't stop in the middle of an output region */
- if (buf->output_off + handle->size + 1 <
- sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size))
- return -EINVAL;
-
-
- /* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
- if (!pt_cap_get(PT_CAP_topa_multiple_entries))
- return 0;
-
- /* clear STOP and INT from current entry */
- buf->topa_index[buf->stop_pos]->stop = 0;
- buf->topa_index[buf->intr_pos]->intr = 0;
-
- /* how many pages till the STOP marker */
- npages = handle->size >> PAGE_SHIFT;
-
- /* if it's on a page boundary, fill up one more page */
- if (!offset_in_page(head + handle->size + 1))
- npages++;
-
- idx = (head >> PAGE_SHIFT) + npages;
- idx &= buf->nr_pages - 1;
- buf->stop_pos = idx;
-
- wakeup = handle->wakeup >> PAGE_SHIFT;
-
- /* in the worst case, wake up the consumer one page before hard stop */
- idx = (head >> PAGE_SHIFT) + npages - 1;
- if (idx > wakeup)
- idx = wakeup;
-
- idx &= buf->nr_pages - 1;
- buf->intr_pos = idx;
-
- buf->topa_index[buf->stop_pos]->stop = 1;
- buf->topa_index[buf->intr_pos]->intr = 1;
-
- return 0;
-}
-
-/**
- * pt_buffer_setup_topa_index() - build topa_index[] table of regions
- * @buf: PT buffer.
- *
- * topa_index[] references output regions indexed by offset into the
- * buffer for purposes of quick reverse lookup.
- */
-static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
-{
- struct topa *cur = buf->first, *prev = buf->last;
- struct topa_entry *te_cur = TOPA_ENTRY(cur, 0),
- *te_prev = TOPA_ENTRY(prev, prev->last - 1);
- int pg = 0, idx = 0;
-
- while (pg < buf->nr_pages) {
- int tidx;
-
- /* pages within one topa entry */
- for (tidx = 0; tidx < 1 << te_cur->size; tidx++, pg++)
- buf->topa_index[pg] = te_prev;
-
- te_prev = te_cur;
-
- if (idx == cur->last - 1) {
- /* advance to next topa table */
- idx = 0;
- cur = list_entry(cur->list.next, struct topa, list);
- } else {
- idx++;
- }
- te_cur = TOPA_ENTRY(cur, idx);
- }
-
-}
-
-/**
- * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
- * @buf: PT buffer.
- * @head: Write pointer (aux_head) from AUX buffer.
- *
- * Find the ToPA table and entry corresponding to given @head and set buffer's
- * "current" pointers accordingly. This is done after we have obtained the
- * current aux_head position from a successful call to perf_aux_output_begin()
- * to make sure the hardware is writing to the right place.
- *
- * This function modifies buf::{cur,cur_idx,output_off} that will be programmed
- * into PT msrs when the tracing is enabled and buf::head and buf::data_size,
- * which are used to determine INT and STOP markers' locations by a subsequent
- * call to pt_buffer_reset_markers().
- */
-static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
-{
- int pg;
-
- if (buf->snapshot)
- head &= (buf->nr_pages << PAGE_SHIFT) - 1;
-
- pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
- pg = pt_topa_next_entry(buf, pg);
-
- buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK);
- buf->cur_idx = ((unsigned long)buf->topa_index[pg] -
- (unsigned long)buf->cur) / sizeof(struct topa_entry);
- buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1);
-
- local64_set(&buf->head, head);
- local_set(&buf->data_size, 0);
-}
-
-/**
- * pt_buffer_fini_topa() - deallocate ToPA structure of a buffer
- * @buf: PT buffer.
- */
-static void pt_buffer_fini_topa(struct pt_buffer *buf)
-{
- struct topa *topa, *iter;
-
- list_for_each_entry_safe(topa, iter, &buf->tables, list) {
- /*
- * right now, this is in free_aux() path only, so
- * no need to unlink this table from the list
- */
- topa_free(topa);
- }
-}
-
-/**
- * pt_buffer_init_topa() - initialize ToPA table for pt buffer
- * @buf: PT buffer.
- * @size: Total size of all regions within this ToPA.
- * @gfp: Allocation flags.
- */
-static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
- gfp_t gfp)
-{
- struct topa *topa;
- int err;
-
- topa = topa_alloc(buf->cpu, gfp);
- if (!topa)
- return -ENOMEM;
-
- topa_insert_table(buf, topa);
-
- while (buf->nr_pages < nr_pages) {
- err = topa_insert_pages(buf, gfp);
- if (err) {
- pt_buffer_fini_topa(buf);
- return -ENOMEM;
- }
- }
-
- pt_buffer_setup_topa_index(buf);
-
- /* link last table to the first one, unless we're double buffering */
- if (pt_cap_get(PT_CAP_topa_multiple_entries)) {
- TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT;
- TOPA_ENTRY(buf->last, -1)->end = 1;
- }
-
- pt_topa_dump(buf);
- return 0;
-}
-
-/**
- * pt_buffer_setup_aux() - set up topa tables for a PT buffer
- * @cpu: Cpu on which to allocate, -1 means current.
- * @pages: Array of pointers to buffer pages passed from perf core.
- * @nr_pages: Number of pages in the buffer.
- * @snapshot: If this is a snapshot/overwrite counter.
- *
- * This is a pmu::setup_aux callback that sets up ToPA tables and all the
- * bookkeeping for an AUX buffer.
- *
- * Return: Our private PT buffer structure.
- */
-static void *
-pt_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool snapshot)
-{
- struct pt_buffer *buf;
- int node, ret;
-
- if (!nr_pages)
- return NULL;
-
- if (cpu == -1)
- cpu = raw_smp_processor_id();
- node = cpu_to_node(cpu);
-
- buf = kzalloc_node(offsetof(struct pt_buffer, topa_index[nr_pages]),
- GFP_KERNEL, node);
- if (!buf)
- return NULL;
-
- buf->cpu = cpu;
- buf->snapshot = snapshot;
- buf->data_pages = pages;
-
- INIT_LIST_HEAD(&buf->tables);
-
- ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL);
- if (ret) {
- kfree(buf);
- return NULL;
- }
-
- return buf;
-}
-
-/**
- * pt_buffer_free_aux() - perf AUX deallocation path callback
- * @data: PT buffer.
- */
-static void pt_buffer_free_aux(void *data)
-{
- struct pt_buffer *buf = data;
-
- pt_buffer_fini_topa(buf);
- kfree(buf);
-}
-
-/**
- * pt_buffer_is_full() - check if the buffer is full
- * @buf: PT buffer.
- * @pt: Per-cpu pt handle.
- *
- * If the user hasn't read data from the output region that aux_head
- * points to, the buffer is considered full: the user needs to read at
- * least this region and update aux_tail to point past it.
- */
-static bool pt_buffer_is_full(struct pt_buffer *buf, struct pt *pt)
-{
- if (buf->snapshot)
- return false;
-
- if (local_read(&buf->data_size) >= pt->handle.size)
- return true;
-
- return false;
-}
-
-/**
- * intel_pt_interrupt() - PT PMI handler
- */
-void intel_pt_interrupt(void)
-{
- struct pt *pt = this_cpu_ptr(&pt_ctx);
- struct pt_buffer *buf;
- struct perf_event *event = pt->handle.event;
-
- /*
- * There may be a dangling PT bit in the interrupt status register
- * after PT has been disabled by pt_event_stop(). Make sure we don't
- * do anything (particularly, re-enable) for this event here.
- */
- if (!ACCESS_ONCE(pt->handle_nmi))
- return;
-
- pt_config_start(false);
-
- if (!event)
- return;
-
- buf = perf_get_aux(&pt->handle);
- if (!buf)
- return;
-
- pt_read_offset(buf);
-
- pt_handle_status(pt);
-
- pt_update_head(pt);
-
- perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
- local_xchg(&buf->lost, 0));
-
- if (!event->hw.state) {
- int ret;
-
- buf = perf_aux_output_begin(&pt->handle, event);
- if (!buf) {
- event->hw.state = PERF_HES_STOPPED;
- return;
- }
-
- pt_buffer_reset_offsets(buf, pt->handle.head);
- /* snapshot counters don't use PMI, so it's safe */
- ret = pt_buffer_reset_markers(buf, &pt->handle);
- if (ret) {
- perf_aux_output_end(&pt->handle, 0, true);
- return;
- }
-
- pt_config_buffer(buf->cur->table, buf->cur_idx,
- buf->output_off);
- pt_config(event);
- }
-}
-
-/*
- * PMU callbacks
- */
-
-static void pt_event_start(struct perf_event *event, int mode)
-{
- struct pt *pt = this_cpu_ptr(&pt_ctx);
- struct pt_buffer *buf = perf_get_aux(&pt->handle);
-
- if (!buf || pt_buffer_is_full(buf, pt)) {
- event->hw.state = PERF_HES_STOPPED;
- return;
- }
-
- ACCESS_ONCE(pt->handle_nmi) = 1;
- event->hw.state = 0;
-
- pt_config_buffer(buf->cur->table, buf->cur_idx,
- buf->output_off);
- pt_config(event);
-}
-
-static void pt_event_stop(struct perf_event *event, int mode)
-{
- struct pt *pt = this_cpu_ptr(&pt_ctx);
-
- /*
- * Protect against the PMI racing with disabling wrmsr,
- * see comment in intel_pt_interrupt().
- */
- ACCESS_ONCE(pt->handle_nmi) = 0;
- pt_config_start(false);
-
- if (event->hw.state == PERF_HES_STOPPED)
- return;
-
- event->hw.state = PERF_HES_STOPPED;
-
- if (mode & PERF_EF_UPDATE) {
- struct pt_buffer *buf = perf_get_aux(&pt->handle);
-
- if (!buf)
- return;
-
- if (WARN_ON_ONCE(pt->handle.event != event))
- return;
-
- pt_read_offset(buf);
-
- pt_handle_status(pt);
-
- pt_update_head(pt);
- }
-}
-
-static void pt_event_del(struct perf_event *event, int mode)
-{
- struct pt *pt = this_cpu_ptr(&pt_ctx);
- struct pt_buffer *buf;
-
- pt_event_stop(event, PERF_EF_UPDATE);
-
- buf = perf_get_aux(&pt->handle);
-
- if (buf) {
- if (buf->snapshot)
- pt->handle.head =
- local_xchg(&buf->data_size,
- buf->nr_pages << PAGE_SHIFT);
- perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0),
- local_xchg(&buf->lost, 0));
- }
-}
-
-static int pt_event_add(struct perf_event *event, int mode)
-{
- struct pt_buffer *buf;
- struct pt *pt = this_cpu_ptr(&pt_ctx);
- struct hw_perf_event *hwc = &event->hw;
- int ret = -EBUSY;
-
- if (pt->handle.event)
- goto fail;
-
- buf = perf_aux_output_begin(&pt->handle, event);
- ret = -EINVAL;
- if (!buf)
- goto fail_stop;
-
- pt_buffer_reset_offsets(buf, pt->handle.head);
- if (!buf->snapshot) {
- ret = pt_buffer_reset_markers(buf, &pt->handle);
- if (ret)
- goto fail_end_stop;
- }
-
- if (mode & PERF_EF_START) {
- pt_event_start(event, 0);
- ret = -EBUSY;
- if (hwc->state == PERF_HES_STOPPED)
- goto fail_end_stop;
- } else {
- hwc->state = PERF_HES_STOPPED;
- }
-
- return 0;
-
-fail_end_stop:
- perf_aux_output_end(&pt->handle, 0, true);
-fail_stop:
- hwc->state = PERF_HES_STOPPED;
-fail:
- return ret;
-}
-
-static void pt_event_read(struct perf_event *event)
-{
-}
-
-static void pt_event_destroy(struct perf_event *event)
-{
- x86_del_exclusive(x86_lbr_exclusive_pt);
-}
-
-static int pt_event_init(struct perf_event *event)
-{
- if (event->attr.type != pt_pmu.pmu.type)
- return -ENOENT;
-
- if (!pt_event_valid(event))
- return -EINVAL;
-
- if (x86_add_exclusive(x86_lbr_exclusive_pt))
- return -EBUSY;
-
- event->destroy = pt_event_destroy;
-
- return 0;
-}
-
-static __init int pt_init(void)
-{
- int ret, cpu, prior_warn = 0;
-
- BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
- get_online_cpus();
- for_each_online_cpu(cpu) {
- u64 ctl;
-
- ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
- if (!ret && (ctl & RTIT_CTL_TRACEEN))
- prior_warn++;
- }
- put_online_cpus();
-
- if (prior_warn) {
- x86_add_exclusive(x86_lbr_exclusive_pt);
- pr_warn("PT is enabled at boot time, doing nothing\n");
-
- return -EBUSY;
- }
-
- ret = pt_pmu_hw_init();
- if (ret)
- return ret;
-
- if (!pt_cap_get(PT_CAP_topa_output)) {
- pr_warn("ToPA output is not supported on this CPU\n");
- return -ENODEV;
- }
-
- if (!pt_cap_get(PT_CAP_topa_multiple_entries))
- pt_pmu.pmu.capabilities =
- PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_SW_DOUBLEBUF;
-
- pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
- pt_pmu.pmu.attr_groups = pt_attr_groups;
- pt_pmu.pmu.task_ctx_nr = perf_sw_context;
- pt_pmu.pmu.event_init = pt_event_init;
- pt_pmu.pmu.add = pt_event_add;
- pt_pmu.pmu.del = pt_event_del;
- pt_pmu.pmu.start = pt_event_start;
- pt_pmu.pmu.stop = pt_event_stop;
- pt_pmu.pmu.read = pt_event_read;
- pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
- pt_pmu.pmu.free_aux = pt_buffer_free_aux;
- ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
-
- return ret;
-}
-arch_initcall(pt_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
deleted file mode 100644
index 81431c0..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
- * Copyright (C) 2013 Google, Inc., Stephane Eranian
- *
- * Intel RAPL interface is specified in the IA-32 Manual Vol3b
- * section 14.7.1 (September 2013)
- *
- * RAPL provides more controls than just reporting energy consumption
- * however here we only expose the 3 energy consumption free running
- * counters (pp0, pkg, dram).
- *
- * Each of those counters increments in a power unit defined by the
- * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
- * but it can vary.
- *
- * Counter to rapl events mappings:
- *
- * pp0 counter: consumption of all physical cores (power plane 0)
- * event: rapl_energy_cores
- * perf code: 0x1
- *
- * pkg counter: consumption of the whole processor package
- * event: rapl_energy_pkg
- * perf code: 0x2
- *
- * dram counter: consumption of the dram domain (servers only)
- * event: rapl_energy_dram
- * perf code: 0x3
- *
- * dram counter: consumption of the builtin-gpu domain (client only)
- * event: rapl_energy_gpu
- * perf code: 0x4
- *
- * We manage those counters as free running (read-only). They may be
- * use simultaneously by other tools, such as turbostat.
- *
- * The events only support system-wide mode counting. There is no
- * sampling support because it does not make sense and is not
- * supported by the RAPL hardware.
- *
- * Because we want to avoid floating-point operations in the kernel,
- * the events are all reported in fixed point arithmetic (32.32).
- * Tools must adjust the counts to convert them to Watts using
- * the duration of the measurement. Tools may use a function such as
- * ldexp(raw_count, -32);
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/perf_event.h>
-#include <asm/cpu_device_id.h>
-#include "perf_event.h"
-
-/*
- * RAPL energy status counters
- */
-#define RAPL_IDX_PP0_NRG_STAT 0 /* all cores */
-#define INTEL_RAPL_PP0 0x1 /* pseudo-encoding */
-#define RAPL_IDX_PKG_NRG_STAT 1 /* entire package */
-#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
-#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
-#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
-#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
-
-#define NR_RAPL_DOMAINS 0x4
-static const char *rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
- "pp0-core",
- "package",
- "dram",
- "pp1-gpu",
-};
-
-/* Clients have PP0, PKG */
-#define RAPL_IDX_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\
- 1<<RAPL_IDX_PKG_NRG_STAT|\
- 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM */
-#define RAPL_IDX_SRV (1<<RAPL_IDX_PP0_NRG_STAT|\
- 1<<RAPL_IDX_PKG_NRG_STAT|\
- 1<<RAPL_IDX_RAM_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM, PP1 */
-#define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\
- 1<<RAPL_IDX_PKG_NRG_STAT|\
- 1<<RAPL_IDX_RAM_NRG_STAT|\
- 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* Knights Landing has PKG, RAM */
-#define RAPL_IDX_KNL (1<<RAPL_IDX_PKG_NRG_STAT|\
- 1<<RAPL_IDX_RAM_NRG_STAT)
-
-/*
- * event code: LSB 8 bits, passed in attr->config
- * any other bit is reserved
- */
-#define RAPL_EVENT_MASK 0xFFULL
-
-#define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \
-static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
- struct kobj_attribute *attr, \
- char *page) \
-{ \
- BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
- return sprintf(page, _format "\n"); \
-} \
-static struct kobj_attribute format_attr_##_var = \
- __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
-
-#define RAPL_EVENT_DESC(_name, _config) \
-{ \
- .attr = __ATTR(_name, 0444, rapl_event_show, NULL), \
- .config = _config, \
-}
-
-#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
-
-#define RAPL_EVENT_ATTR_STR(_name, v, str) \
-static struct perf_pmu_events_attr event_attr_##v = { \
- .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \
- .id = 0, \
- .event_str = str, \
-};
-
-struct rapl_pmu {
- spinlock_t lock;
- int n_active; /* number of active events */
- struct list_head active_list;
- struct pmu *pmu; /* pointer to rapl_pmu_class */
- ktime_t timer_interval; /* in ktime_t unit */
- struct hrtimer hrtimer;
-};
-
-static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly; /* 1/2^hw_unit Joule */
-static struct pmu rapl_pmu_class;
-static cpumask_t rapl_cpu_mask;
-static int rapl_cntr_mask;
-
-static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
-static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
-
-static struct x86_pmu_quirk *rapl_quirks;
-static inline u64 rapl_read_counter(struct perf_event *event)
-{
- u64 raw;
- rdmsrl(event->hw.event_base, raw);
- return raw;
-}
-
-#define rapl_add_quirk(func_) \
-do { \
- static struct x86_pmu_quirk __quirk __initdata = { \
- .func = func_, \
- }; \
- __quirk.next = rapl_quirks; \
- rapl_quirks = &__quirk; \
-} while (0)
-
-static inline u64 rapl_scale(u64 v, int cfg)
-{
- if (cfg > NR_RAPL_DOMAINS) {
- pr_warn("invalid domain %d, failed to scale data\n", cfg);
- return v;
- }
- /*
- * scale delta to smallest unit (1/2^32)
- * users must then scale back: count * 1/(1e9*2^32) to get Joules
- * or use ldexp(count, -32).
- * Watts = Joules/Time delta
- */
- return v << (32 - rapl_hw_unit[cfg - 1]);
-}
-
-static u64 rapl_event_update(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 prev_raw_count, new_raw_count;
- s64 delta, sdelta;
- int shift = RAPL_CNTR_WIDTH;
-
-again:
- prev_raw_count = local64_read(&hwc->prev_count);
- rdmsrl(event->hw.event_base, new_raw_count);
-
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count) {
- cpu_relax();
- goto again;
- }
-
- /*
- * Now we have the new raw value and have updated the prev
- * timestamp already. We can now calculate the elapsed delta
- * (event-)time and add that to the generic event.
- *
- * Careful, not all hw sign-extends above the physical width
- * of the count.
- */
- delta = (new_raw_count << shift) - (prev_raw_count << shift);
- delta >>= shift;
-
- sdelta = rapl_scale(delta, event->hw.config);
-
- local64_add(sdelta, &event->count);
-
- return new_raw_count;
-}
-
-static void rapl_start_hrtimer(struct rapl_pmu *pmu)
-{
- hrtimer_start(&pmu->hrtimer, pmu->timer_interval,
- HRTIMER_MODE_REL_PINNED);
-}
-
-static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
-{
- hrtimer_cancel(&pmu->hrtimer);
-}
-
-static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
-{
- struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
- struct perf_event *event;
- unsigned long flags;
-
- if (!pmu->n_active)
- return HRTIMER_NORESTART;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- list_for_each_entry(event, &pmu->active_list, active_entry) {
- rapl_event_update(event);
- }
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-
- hrtimer_forward_now(hrtimer, pmu->timer_interval);
-
- return HRTIMER_RESTART;
-}
-
-static void rapl_hrtimer_init(struct rapl_pmu *pmu)
-{
- struct hrtimer *hr = &pmu->hrtimer;
-
- hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hr->function = rapl_hrtimer_handle;
-}
-
-static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
- struct perf_event *event)
-{
- if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
- return;
-
- event->hw.state = 0;
-
- list_add_tail(&event->active_entry, &pmu->active_list);
-
- local64_set(&event->hw.prev_count, rapl_read_counter(event));
-
- pmu->n_active++;
- if (pmu->n_active == 1)
- rapl_start_hrtimer(pmu);
-}
-
-static void rapl_pmu_event_start(struct perf_event *event, int mode)
-{
- struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
- unsigned long flags;
-
- spin_lock_irqsave(&pmu->lock, flags);
- __rapl_pmu_event_start(pmu, event);
- spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static void rapl_pmu_event_stop(struct perf_event *event, int mode)
-{
- struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
- struct hw_perf_event *hwc = &event->hw;
- unsigned long flags;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- /* mark event as deactivated and stopped */
- if (!(hwc->state & PERF_HES_STOPPED)) {
- WARN_ON_ONCE(pmu->n_active <= 0);
- pmu->n_active--;
- if (pmu->n_active == 0)
- rapl_stop_hrtimer(pmu);
-
- list_del(&event->active_entry);
-
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
- }
-
- /* check if update of sw counter is necessary */
- if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
- /*
- * Drain the remaining delta count out of a event
- * that we are disabling:
- */
- rapl_event_update(event);
- hwc->state |= PERF_HES_UPTODATE;
- }
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static int rapl_pmu_event_add(struct perf_event *event, int mode)
-{
- struct rapl_pmu *pmu = __this_cpu_read(rapl_pmu);
- struct hw_perf_event *hwc = &event->hw;
- unsigned long flags;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
-
- if (mode & PERF_EF_START)
- __rapl_pmu_event_start(pmu, event);
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-
- return 0;
-}
-
-static void rapl_pmu_event_del(struct perf_event *event, int flags)
-{
- rapl_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int rapl_pmu_event_init(struct perf_event *event)
-{
- u64 cfg = event->attr.config & RAPL_EVENT_MASK;
- int bit, msr, ret = 0;
-
- /* only look at RAPL events */
- if (event->attr.type != rapl_pmu_class.type)
- return -ENOENT;
-
- /* check only supported bits are set */
- if (event->attr.config & ~RAPL_EVENT_MASK)
- return -EINVAL;
-
- /*
- * check event is known (determines counter)
- */
- switch (cfg) {
- case INTEL_RAPL_PP0:
- bit = RAPL_IDX_PP0_NRG_STAT;
- msr = MSR_PP0_ENERGY_STATUS;
- break;
- case INTEL_RAPL_PKG:
- bit = RAPL_IDX_PKG_NRG_STAT;
- msr = MSR_PKG_ENERGY_STATUS;
- break;
- case INTEL_RAPL_RAM:
- bit = RAPL_IDX_RAM_NRG_STAT;
- msr = MSR_DRAM_ENERGY_STATUS;
- break;
- case INTEL_RAPL_PP1:
- bit = RAPL_IDX_PP1_NRG_STAT;
- msr = MSR_PP1_ENERGY_STATUS;
- break;
- default:
- return -EINVAL;
- }
- /* check event supported */
- if (!(rapl_cntr_mask & (1 << bit)))
- return -EINVAL;
-
- /* unsupported modes and filters */
- if (event->attr.exclude_user ||
- event->attr.exclude_kernel ||
- event->attr.exclude_hv ||
- event->attr.exclude_idle ||
- event->attr.exclude_host ||
- event->attr.exclude_guest ||
- event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- /* must be done before validate_group */
- event->hw.event_base = msr;
- event->hw.config = cfg;
- event->hw.idx = bit;
-
- return ret;
-}
-
-static void rapl_pmu_event_read(struct perf_event *event)
-{
- rapl_event_update(event);
-}
-
-static ssize_t rapl_get_attr_cpumask(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask);
-}
-
-static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
-
-static struct attribute *rapl_pmu_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static struct attribute_group rapl_pmu_attr_group = {
- .attrs = rapl_pmu_attrs,
-};
-
-static ssize_t rapl_sysfs_show(struct device *dev,
- struct device_attribute *attr,
- char *page)
-{
- struct perf_pmu_events_attr *pmu_attr = \
- container_of(attr, struct perf_pmu_events_attr, attr);
-
- if (pmu_attr->event_str)
- return sprintf(page, "%s", pmu_attr->event_str);
-
- return 0;
-}
-
-RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
-RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02");
-RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
-RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04");
-
-RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules");
-RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules");
-
-/*
- * we compute in 0.23 nJ increments regardless of MSR
- */
-RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
-RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10");
-
-static struct attribute *rapl_events_srv_attr[] = {
- EVENT_PTR(rapl_cores),
- EVENT_PTR(rapl_pkg),
- EVENT_PTR(rapl_ram),
-
- EVENT_PTR(rapl_cores_unit),
- EVENT_PTR(rapl_pkg_unit),
- EVENT_PTR(rapl_ram_unit),
-
- EVENT_PTR(rapl_cores_scale),
- EVENT_PTR(rapl_pkg_scale),
- EVENT_PTR(rapl_ram_scale),
- NULL,
-};
-
-static struct attribute *rapl_events_cln_attr[] = {
- EVENT_PTR(rapl_cores),
- EVENT_PTR(rapl_pkg),
- EVENT_PTR(rapl_gpu),
-
- EVENT_PTR(rapl_cores_unit),
- EVENT_PTR(rapl_pkg_unit),
- EVENT_PTR(rapl_gpu_unit),
-
- EVENT_PTR(rapl_cores_scale),
- EVENT_PTR(rapl_pkg_scale),
- EVENT_PTR(rapl_gpu_scale),
- NULL,
-};
-
-static struct attribute *rapl_events_hsw_attr[] = {
- EVENT_PTR(rapl_cores),
- EVENT_PTR(rapl_pkg),
- EVENT_PTR(rapl_gpu),
- EVENT_PTR(rapl_ram),
-
- EVENT_PTR(rapl_cores_unit),
- EVENT_PTR(rapl_pkg_unit),
- EVENT_PTR(rapl_gpu_unit),
- EVENT_PTR(rapl_ram_unit),
-
- EVENT_PTR(rapl_cores_scale),
- EVENT_PTR(rapl_pkg_scale),
- EVENT_PTR(rapl_gpu_scale),
- EVENT_PTR(rapl_ram_scale),
- NULL,
-};
-
-static struct attribute *rapl_events_knl_attr[] = {
- EVENT_PTR(rapl_pkg),
- EVENT_PTR(rapl_ram),
-
- EVENT_PTR(rapl_pkg_unit),
- EVENT_PTR(rapl_ram_unit),
-
- EVENT_PTR(rapl_pkg_scale),
- EVENT_PTR(rapl_ram_scale),
- NULL,
-};
-
-static struct attribute_group rapl_pmu_events_group = {
- .name = "events",
- .attrs = NULL, /* patched at runtime */
-};
-
-DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
-static struct attribute *rapl_formats_attr[] = {
- &format_attr_event.attr,
- NULL,
-};
-
-static struct attribute_group rapl_pmu_format_group = {
- .name = "format",
- .attrs = rapl_formats_attr,
-};
-
-const struct attribute_group *rapl_attr_groups[] = {
- &rapl_pmu_attr_group,
- &rapl_pmu_format_group,
- &rapl_pmu_events_group,
- NULL,
-};
-
-static struct pmu rapl_pmu_class = {
- .attr_groups = rapl_attr_groups,
- .task_ctx_nr = perf_invalid_context, /* system-wide only */
- .event_init = rapl_pmu_event_init,
- .add = rapl_pmu_event_add, /* must have */
- .del = rapl_pmu_event_del, /* must have */
- .start = rapl_pmu_event_start,
- .stop = rapl_pmu_event_stop,
- .read = rapl_pmu_event_read,
-};
-
-static void rapl_cpu_exit(int cpu)
-{
- struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
- int i, phys_id = topology_physical_package_id(cpu);
- int target = -1;
-
- /* find a new cpu on same package */
- for_each_online_cpu(i) {
- if (i == cpu)
- continue;
- if (phys_id == topology_physical_package_id(i)) {
- target = i;
- break;
- }
- }
- /*
- * clear cpu from cpumask
- * if was set in cpumask and still some cpu on package,
- * then move to new cpu
- */
- if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
- cpumask_set_cpu(target, &rapl_cpu_mask);
-
- WARN_ON(cpumask_empty(&rapl_cpu_mask));
- /*
- * migrate events and context to new cpu
- */
- if (target >= 0)
- perf_pmu_migrate_context(pmu->pmu, cpu, target);
-
- /* cancel overflow polling timer for CPU */
- rapl_stop_hrtimer(pmu);
-}
-
-static void rapl_cpu_init(int cpu)
-{
- int i, phys_id = topology_physical_package_id(cpu);
-
- /* check if phys_is is already covered */
- for_each_cpu(i, &rapl_cpu_mask) {
- if (phys_id == topology_physical_package_id(i))
- return;
- }
- /* was not found, so add it */
- cpumask_set_cpu(cpu, &rapl_cpu_mask);
-}
-
-static __init void rapl_hsw_server_quirk(void)
-{
- /*
- * DRAM domain on HSW server has fixed energy unit which can be
- * different than the unit from power unit MSR.
- * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
- * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
- */
- rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
-}
-
-static int rapl_cpu_prepare(int cpu)
-{
- struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
- int phys_id = topology_physical_package_id(cpu);
- u64 ms;
-
- if (pmu)
- return 0;
-
- if (phys_id < 0)
- return -1;
-
- pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
- if (!pmu)
- return -1;
- spin_lock_init(&pmu->lock);
-
- INIT_LIST_HEAD(&pmu->active_list);
-
- pmu->pmu = &rapl_pmu_class;
-
- /*
- * use reference of 200W for scaling the timeout
- * to avoid missing counter overflows.
- * 200W = 200 Joules/sec
- * divide interval by 2 to avoid lockstep (2 * 100)
- * if hw unit is 32, then we use 2 ms 1/200/2
- */
- if (rapl_hw_unit[0] < 32)
- ms = (1000 / (2 * 100)) * (1ULL << (32 - rapl_hw_unit[0] - 1));
- else
- ms = 2;
-
- pmu->timer_interval = ms_to_ktime(ms);
-
- rapl_hrtimer_init(pmu);
-
- /* set RAPL pmu for this cpu for now */
- per_cpu(rapl_pmu, cpu) = pmu;
- per_cpu(rapl_pmu_to_free, cpu) = NULL;
-
- return 0;
-}
-
-static void rapl_cpu_kfree(int cpu)
-{
- struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
-
- kfree(pmu);
-
- per_cpu(rapl_pmu_to_free, cpu) = NULL;
-}
-
-static int rapl_cpu_dying(int cpu)
-{
- struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
-
- if (!pmu)
- return 0;
-
- per_cpu(rapl_pmu, cpu) = NULL;
-
- per_cpu(rapl_pmu_to_free, cpu) = pmu;
-
- return 0;
-}
-
-static int rapl_cpu_notifier(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (long)hcpu;
-
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_UP_PREPARE:
- rapl_cpu_prepare(cpu);
- break;
- case CPU_STARTING:
- rapl_cpu_init(cpu);
- break;
- case CPU_UP_CANCELED:
- case CPU_DYING:
- rapl_cpu_dying(cpu);
- break;
- case CPU_ONLINE:
- case CPU_DEAD:
- rapl_cpu_kfree(cpu);
- break;
- case CPU_DOWN_PREPARE:
- rapl_cpu_exit(cpu);
- break;
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static int rapl_check_hw_unit(void)
-{
- u64 msr_rapl_power_unit_bits;
- int i;
-
- /* protect rdmsrl() to handle virtualization */
- if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
- return -1;
- for (i = 0; i < NR_RAPL_DOMAINS; i++)
- rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
-
- return 0;
-}
-
-static const struct x86_cpu_id rapl_cpu_match[] = {
- [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
- [1] = {},
-};
-
-static int __init rapl_pmu_init(void)
-{
- struct rapl_pmu *pmu;
- int cpu, ret;
- struct x86_pmu_quirk *quirk;
- int i;
-
- /*
- * check for Intel processor family 6
- */
- if (!x86_match_cpu(rapl_cpu_match))
- return 0;
-
- /* check supported CPU */
- switch (boot_cpu_data.x86_model) {
- case 42: /* Sandy Bridge */
- case 58: /* Ivy Bridge */
- rapl_cntr_mask = RAPL_IDX_CLN;
- rapl_pmu_events_group.attrs = rapl_events_cln_attr;
- break;
- case 63: /* Haswell-Server */
- rapl_add_quirk(rapl_hsw_server_quirk);
- rapl_cntr_mask = RAPL_IDX_SRV;
- rapl_pmu_events_group.attrs = rapl_events_srv_attr;
- break;
- case 60: /* Haswell */
- case 69: /* Haswell-Celeron */
- case 61: /* Broadwell */
- rapl_cntr_mask = RAPL_IDX_HSW;
- rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
- break;
- case 45: /* Sandy Bridge-EP */
- case 62: /* IvyTown */
- rapl_cntr_mask = RAPL_IDX_SRV;
- rapl_pmu_events_group.attrs = rapl_events_srv_attr;
- break;
- case 87: /* Knights Landing */
- rapl_add_quirk(rapl_hsw_server_quirk);
- rapl_cntr_mask = RAPL_IDX_KNL;
- rapl_pmu_events_group.attrs = rapl_events_knl_attr;
-
- default:
- /* unsupported */
- return 0;
- }
- ret = rapl_check_hw_unit();
- if (ret)
- return ret;
-
- /* run cpu model quirks */
- for (quirk = rapl_quirks; quirk; quirk = quirk->next)
- quirk->func();
- cpu_notifier_register_begin();
-
- for_each_online_cpu(cpu) {
- ret = rapl_cpu_prepare(cpu);
- if (ret)
- goto out;
- rapl_cpu_init(cpu);
- }
-
- __perf_cpu_notifier(rapl_cpu_notifier);
-
- ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
- if (WARN_ON(ret)) {
- pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
- cpu_notifier_register_done();
- return -1;
- }
-
- pmu = __this_cpu_read(rapl_pmu);
-
- pr_info("RAPL PMU detected,"
- " API unit is 2^-32 Joules,"
- " %d fixed counters"
- " %llu ms ovfl timer\n",
- hweight32(rapl_cntr_mask),
- ktime_to_ms(pmu->timer_interval));
- for (i = 0; i < NR_RAPL_DOMAINS; i++) {
- if (rapl_cntr_mask & (1 << i)) {
- pr_info("hw unit of domain %s 2^-%d Joules\n",
- rapl_domain_names[i], rapl_hw_unit[i]);
- }
- }
-out:
- cpu_notifier_register_done();
-
- return 0;
-}
-device_initcall(rapl_pmu_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
deleted file mode 100644
index 560e525..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-#include "perf_event_intel_uncore.h"
-
-static struct intel_uncore_type *empty_uncore[] = { NULL, };
-struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
-struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
-
-static bool pcidrv_registered;
-struct pci_driver *uncore_pci_driver;
-/* pci bus to socket mapping */
-int uncore_pcibus_to_physid[256] = { [0 ... 255] = -1, };
-struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
-
-static DEFINE_RAW_SPINLOCK(uncore_box_lock);
-/* mask of cpus that collect uncore events */
-static cpumask_t uncore_cpu_mask;
-
-/* constraint for the fixed counter */
-static struct event_constraint uncore_constraint_fixed =
- EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
-struct event_constraint uncore_constraint_empty =
- EVENT_CONSTRAINT(0, 0, 0);
-
-ssize_t uncore_event_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- struct uncore_event_desc *event =
- container_of(attr, struct uncore_event_desc, attr);
- return sprintf(buf, "%s", event->config);
-}
-
-struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
-{
- return container_of(event->pmu, struct intel_uncore_pmu, pmu);
-}
-
-struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
-{
- struct intel_uncore_box *box;
-
- box = *per_cpu_ptr(pmu->box, cpu);
- if (box)
- return box;
-
- raw_spin_lock(&uncore_box_lock);
- /* Recheck in lock to handle races. */
- if (*per_cpu_ptr(pmu->box, cpu))
- goto out;
- list_for_each_entry(box, &pmu->box_list, list) {
- if (box->phys_id == topology_physical_package_id(cpu)) {
- atomic_inc(&box->refcnt);
- *per_cpu_ptr(pmu->box, cpu) = box;
- break;
- }
- }
-out:
- raw_spin_unlock(&uncore_box_lock);
-
- return *per_cpu_ptr(pmu->box, cpu);
-}
-
-struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
-{
- /*
- * perf core schedules event on the basis of cpu, uncore events are
- * collected by one of the cpus inside a physical package.
- */
- return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
-}
-
-u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
- u64 count;
-
- rdmsrl(event->hw.event_base, count);
-
- return count;
-}
-
-/*
- * generic get constraint function for shared match/mask registers.
- */
-struct event_constraint *
-uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct intel_uncore_extra_reg *er;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
- unsigned long flags;
- bool ok = false;
-
- /*
- * reg->alloc can be set due to existing state, so for fake box we
- * need to ignore this, otherwise we might fail to allocate proper
- * fake state for this extra reg constraint.
- */
- if (reg1->idx == EXTRA_REG_NONE ||
- (!uncore_box_is_fake(box) && reg1->alloc))
- return NULL;
-
- er = &box->shared_regs[reg1->idx];
- raw_spin_lock_irqsave(&er->lock, flags);
- if (!atomic_read(&er->ref) ||
- (er->config1 == reg1->config && er->config2 == reg2->config)) {
- atomic_inc(&er->ref);
- er->config1 = reg1->config;
- er->config2 = reg2->config;
- ok = true;
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- if (ok) {
- if (!uncore_box_is_fake(box))
- reg1->alloc = 1;
- return NULL;
- }
-
- return &uncore_constraint_empty;
-}
-
-void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct intel_uncore_extra_reg *er;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-
- /*
- * Only put constraint if extra reg was actually allocated. Also
- * takes care of event which do not use an extra shared reg.
- *
- * Also, if this is a fake box we shouldn't touch any event state
- * (reg->alloc) and we don't care about leaving inconsistent box
- * state either since it will be thrown out.
- */
- if (uncore_box_is_fake(box) || !reg1->alloc)
- return;
-
- er = &box->shared_regs[reg1->idx];
- atomic_dec(&er->ref);
- reg1->alloc = 0;
-}
-
-u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
-{
- struct intel_uncore_extra_reg *er;
- unsigned long flags;
- u64 config;
-
- er = &box->shared_regs[idx];
-
- raw_spin_lock_irqsave(&er->lock, flags);
- config = er->config;
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- return config;
-}
-
-static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- hwc->idx = idx;
- hwc->last_tag = ++box->tags[idx];
-
- if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
- hwc->event_base = uncore_fixed_ctr(box);
- hwc->config_base = uncore_fixed_ctl(box);
- return;
- }
-
- hwc->config_base = uncore_event_ctl(box, hwc->idx);
- hwc->event_base = uncore_perf_ctr(box, hwc->idx);
-}
-
-void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
-{
- u64 prev_count, new_count, delta;
- int shift;
-
- if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
- shift = 64 - uncore_fixed_ctr_bits(box);
- else
- shift = 64 - uncore_perf_ctr_bits(box);
-
- /* the hrtimer might modify the previous event value */
-again:
- prev_count = local64_read(&event->hw.prev_count);
- new_count = uncore_read_counter(box, event);
- if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
- goto again;
-
- delta = (new_count << shift) - (prev_count << shift);
- delta >>= shift;
-
- local64_add(delta, &event->count);
-}
-
-/*
- * The overflow interrupt is unavailable for SandyBridge-EP, is broken
- * for SandyBridge. So we use hrtimer to periodically poll the counter
- * to avoid overflow.
- */
-static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
-{
- struct intel_uncore_box *box;
- struct perf_event *event;
- unsigned long flags;
- int bit;
-
- box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
- if (!box->n_active || box->cpu != smp_processor_id())
- return HRTIMER_NORESTART;
- /*
- * disable local interrupt to prevent uncore_pmu_event_start/stop
- * to interrupt the update process
- */
- local_irq_save(flags);
-
- /*
- * handle boxes with an active event list as opposed to active
- * counters
- */
- list_for_each_entry(event, &box->active_list, active_entry) {
- uncore_perf_event_update(box, event);
- }
-
- for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
- uncore_perf_event_update(box, box->events[bit]);
-
- local_irq_restore(flags);
-
- hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
- return HRTIMER_RESTART;
-}
-
-void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
-{
- hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
- HRTIMER_MODE_REL_PINNED);
-}
-
-void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
-{
- hrtimer_cancel(&box->hrtimer);
-}
-
-static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
-{
- hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- box->hrtimer.function = uncore_pmu_hrtimer;
-}
-
-static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
-{
- struct intel_uncore_box *box;
- int i, size;
-
- size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
-
- box = kzalloc_node(size, GFP_KERNEL, node);
- if (!box)
- return NULL;
-
- for (i = 0; i < type->num_shared_regs; i++)
- raw_spin_lock_init(&box->shared_regs[i].lock);
-
- uncore_pmu_init_hrtimer(box);
- atomic_set(&box->refcnt, 1);
- box->cpu = -1;
- box->phys_id = -1;
-
- /* set default hrtimer timeout */
- box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
-
- INIT_LIST_HEAD(&box->active_list);
-
- return box;
-}
-
-/*
- * Using uncore_pmu_event_init pmu event_init callback
- * as a detection point for uncore events.
- */
-static int uncore_pmu_event_init(struct perf_event *event);
-
-static bool is_uncore_event(struct perf_event *event)
-{
- return event->pmu->event_init == uncore_pmu_event_init;
-}
-
-static int
-uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
-{
- struct perf_event *event;
- int n, max_count;
-
- max_count = box->pmu->type->num_counters;
- if (box->pmu->type->fixed_ctl)
- max_count++;
-
- if (box->n_events >= max_count)
- return -EINVAL;
-
- n = box->n_events;
-
- if (is_uncore_event(leader)) {
- box->event_list[n] = leader;
- n++;
- }
-
- if (!dogrp)
- return n;
-
- list_for_each_entry(event, &leader->sibling_list, group_entry) {
- if (!is_uncore_event(event) ||
- event->state <= PERF_EVENT_STATE_OFF)
- continue;
-
- if (n >= max_count)
- return -EINVAL;
-
- box->event_list[n] = event;
- n++;
- }
- return n;
-}
-
-static struct event_constraint *
-uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct intel_uncore_type *type = box->pmu->type;
- struct event_constraint *c;
-
- if (type->ops->get_constraint) {
- c = type->ops->get_constraint(box, event);
- if (c)
- return c;
- }
-
- if (event->attr.config == UNCORE_FIXED_EVENT)
- return &uncore_constraint_fixed;
-
- if (type->constraints) {
- for_each_event_constraint(c, type->constraints) {
- if ((event->hw.config & c->cmask) == c->code)
- return c;
- }
- }
-
- return &type->unconstrainted;
-}
-
-static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- if (box->pmu->type->ops->put_constraint)
- box->pmu->type->ops->put_constraint(box, event);
-}
-
-static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
-{
- unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
- struct event_constraint *c;
- int i, wmin, wmax, ret = 0;
- struct hw_perf_event *hwc;
-
- bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
-
- for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
- c = uncore_get_event_constraint(box, box->event_list[i]);
- box->event_constraint[i] = c;
- wmin = min(wmin, c->weight);
- wmax = max(wmax, c->weight);
- }
-
- /* fastpath, try to reuse previous register */
- for (i = 0; i < n; i++) {
- hwc = &box->event_list[i]->hw;
- c = box->event_constraint[i];
-
- /* never assigned */
- if (hwc->idx == -1)
- break;
-
- /* constraint still honored */
- if (!test_bit(hwc->idx, c->idxmsk))
- break;
-
- /* not already used */
- if (test_bit(hwc->idx, used_mask))
- break;
-
- __set_bit(hwc->idx, used_mask);
- if (assign)
- assign[i] = hwc->idx;
- }
- /* slow path */
- if (i != n)
- ret = perf_assign_events(box->event_constraint, n,
- wmin, wmax, n, assign);
-
- if (!assign || ret) {
- for (i = 0; i < n; i++)
- uncore_put_event_constraint(box, box->event_list[i]);
- }
- return ret ? -EINVAL : 0;
-}
-
-static void uncore_pmu_event_start(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- int idx = event->hw.idx;
-
- if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
- return;
-
- if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
- return;
-
- event->hw.state = 0;
- box->events[idx] = event;
- box->n_active++;
- __set_bit(idx, box->active_mask);
-
- local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
- uncore_enable_event(box, event);
-
- if (box->n_active == 1) {
- uncore_enable_box(box);
- uncore_pmu_start_hrtimer(box);
- }
-}
-
-static void uncore_pmu_event_stop(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- struct hw_perf_event *hwc = &event->hw;
-
- if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
- uncore_disable_event(box, event);
- box->n_active--;
- box->events[hwc->idx] = NULL;
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
-
- if (box->n_active == 0) {
- uncore_disable_box(box);
- uncore_pmu_cancel_hrtimer(box);
- }
- }
-
- if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
- /*
- * Drain the remaining delta count out of a event
- * that we are disabling:
- */
- uncore_perf_event_update(box, event);
- hwc->state |= PERF_HES_UPTODATE;
- }
-}
-
-static int uncore_pmu_event_add(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- struct hw_perf_event *hwc = &event->hw;
- int assign[UNCORE_PMC_IDX_MAX];
- int i, n, ret;
-
- if (!box)
- return -ENODEV;
-
- ret = n = uncore_collect_events(box, event, false);
- if (ret < 0)
- return ret;
-
- hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
- if (!(flags & PERF_EF_START))
- hwc->state |= PERF_HES_ARCH;
-
- ret = uncore_assign_events(box, assign, n);
- if (ret)
- return ret;
-
- /* save events moving to new counters */
- for (i = 0; i < box->n_events; i++) {
- event = box->event_list[i];
- hwc = &event->hw;
-
- if (hwc->idx == assign[i] &&
- hwc->last_tag == box->tags[assign[i]])
- continue;
- /*
- * Ensure we don't accidentally enable a stopped
- * counter simply because we rescheduled.
- */
- if (hwc->state & PERF_HES_STOPPED)
- hwc->state |= PERF_HES_ARCH;
-
- uncore_pmu_event_stop(event, PERF_EF_UPDATE);
- }
-
- /* reprogram moved events into new counters */
- for (i = 0; i < n; i++) {
- event = box->event_list[i];
- hwc = &event->hw;
-
- if (hwc->idx != assign[i] ||
- hwc->last_tag != box->tags[assign[i]])
- uncore_assign_hw_event(box, event, assign[i]);
- else if (i < box->n_events)
- continue;
-
- if (hwc->state & PERF_HES_ARCH)
- continue;
-
- uncore_pmu_event_start(event, 0);
- }
- box->n_events = n;
-
- return 0;
-}
-
-static void uncore_pmu_event_del(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- int i;
-
- uncore_pmu_event_stop(event, PERF_EF_UPDATE);
-
- for (i = 0; i < box->n_events; i++) {
- if (event == box->event_list[i]) {
- uncore_put_event_constraint(box, event);
-
- while (++i < box->n_events)
- box->event_list[i - 1] = box->event_list[i];
-
- --box->n_events;
- break;
- }
- }
-
- event->hw.idx = -1;
- event->hw.last_tag = ~0ULL;
-}
-
-void uncore_pmu_event_read(struct perf_event *event)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- uncore_perf_event_update(box, event);
-}
-
-/*
- * validation ensures the group can be loaded onto the
- * PMU if it was the only group available.
- */
-static int uncore_validate_group(struct intel_uncore_pmu *pmu,
- struct perf_event *event)
-{
- struct perf_event *leader = event->group_leader;
- struct intel_uncore_box *fake_box;
- int ret = -EINVAL, n;
-
- fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
- if (!fake_box)
- return -ENOMEM;
-
- fake_box->pmu = pmu;
- /*
- * the event is not yet connected with its
- * siblings therefore we must first collect
- * existing siblings, then add the new event
- * before we can simulate the scheduling
- */
- n = uncore_collect_events(fake_box, leader, true);
- if (n < 0)
- goto out;
-
- fake_box->n_events = n;
- n = uncore_collect_events(fake_box, event, false);
- if (n < 0)
- goto out;
-
- fake_box->n_events = n;
-
- ret = uncore_assign_events(fake_box, NULL, n);
-out:
- kfree(fake_box);
- return ret;
-}
-
-static int uncore_pmu_event_init(struct perf_event *event)
-{
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- struct hw_perf_event *hwc = &event->hw;
- int ret;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- pmu = uncore_event_to_pmu(event);
- /* no device found for this pmu */
- if (pmu->func_id < 0)
- return -ENOENT;
-
- /*
- * Uncore PMU does measure at all privilege level all the time.
- * So it doesn't make sense to specify any exclude bits.
- */
- if (event->attr.exclude_user || event->attr.exclude_kernel ||
- event->attr.exclude_hv || event->attr.exclude_idle)
- return -EINVAL;
-
- /* Sampling not supported yet */
- if (hwc->sample_period)
- return -EINVAL;
-
- /*
- * Place all uncore events for a particular physical package
- * onto a single cpu
- */
- if (event->cpu < 0)
- return -EINVAL;
- box = uncore_pmu_to_box(pmu, event->cpu);
- if (!box || box->cpu < 0)
- return -EINVAL;
- event->cpu = box->cpu;
-
- event->hw.idx = -1;
- event->hw.last_tag = ~0ULL;
- event->hw.extra_reg.idx = EXTRA_REG_NONE;
- event->hw.branch_reg.idx = EXTRA_REG_NONE;
-
- if (event->attr.config == UNCORE_FIXED_EVENT) {
- /* no fixed counter */
- if (!pmu->type->fixed_ctl)
- return -EINVAL;
- /*
- * if there is only one fixed counter, only the first pmu
- * can access the fixed counter
- */
- if (pmu->type->single_fixed && pmu->pmu_idx > 0)
- return -EINVAL;
-
- /* fixed counters have event field hardcoded to zero */
- hwc->config = 0ULL;
- } else {
- hwc->config = event->attr.config & pmu->type->event_mask;
- if (pmu->type->ops->hw_config) {
- ret = pmu->type->ops->hw_config(box, event);
- if (ret)
- return ret;
- }
- }
-
- if (event->group_leader != event)
- ret = uncore_validate_group(pmu, event);
- else
- ret = 0;
-
- return ret;
-}
-
-static ssize_t uncore_get_attr_cpumask(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
-}
-
-static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
-
-static struct attribute *uncore_pmu_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static struct attribute_group uncore_pmu_attr_group = {
- .attrs = uncore_pmu_attrs,
-};
-
-static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
-{
- int ret;
-
- if (!pmu->type->pmu) {
- pmu->pmu = (struct pmu) {
- .attr_groups = pmu->type->attr_groups,
- .task_ctx_nr = perf_invalid_context,
- .event_init = uncore_pmu_event_init,
- .add = uncore_pmu_event_add,
- .del = uncore_pmu_event_del,
- .start = uncore_pmu_event_start,
- .stop = uncore_pmu_event_stop,
- .read = uncore_pmu_event_read,
- };
- } else {
- pmu->pmu = *pmu->type->pmu;
- pmu->pmu.attr_groups = pmu->type->attr_groups;
- }
-
- if (pmu->type->num_boxes == 1) {
- if (strlen(pmu->type->name) > 0)
- sprintf(pmu->name, "uncore_%s", pmu->type->name);
- else
- sprintf(pmu->name, "uncore");
- } else {
- sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
- pmu->pmu_idx);
- }
-
- ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
- return ret;
-}
-
-static void __init uncore_type_exit(struct intel_uncore_type *type)
-{
- int i;
-
- for (i = 0; i < type->num_boxes; i++)
- free_percpu(type->pmus[i].box);
- kfree(type->pmus);
- type->pmus = NULL;
- kfree(type->events_group);
- type->events_group = NULL;
-}
-
-static void __init uncore_types_exit(struct intel_uncore_type **types)
-{
- int i;
- for (i = 0; types[i]; i++)
- uncore_type_exit(types[i]);
-}
-
-static int __init uncore_type_init(struct intel_uncore_type *type)
-{
- struct intel_uncore_pmu *pmus;
- struct attribute_group *attr_group;
- struct attribute **attrs;
- int i, j;
-
- pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
- if (!pmus)
- return -ENOMEM;
-
- type->pmus = pmus;
-
- type->unconstrainted = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
- 0, type->num_counters, 0, 0);
-
- for (i = 0; i < type->num_boxes; i++) {
- pmus[i].func_id = -1;
- pmus[i].pmu_idx = i;
- pmus[i].type = type;
- INIT_LIST_HEAD(&pmus[i].box_list);
- pmus[i].box = alloc_percpu(struct intel_uncore_box *);
- if (!pmus[i].box)
- goto fail;
- }
-
- if (type->event_descs) {
- i = 0;
- while (type->event_descs[i].attr.attr.name)
- i++;
-
- attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
- sizeof(*attr_group), GFP_KERNEL);
- if (!attr_group)
- goto fail;
-
- attrs = (struct attribute **)(attr_group + 1);
- attr_group->name = "events";
- attr_group->attrs = attrs;
-
- for (j = 0; j < i; j++)
- attrs[j] = &type->event_descs[j].attr.attr;
-
- type->events_group = attr_group;
- }
-
- type->pmu_group = &uncore_pmu_attr_group;
- return 0;
-fail:
- uncore_type_exit(type);
- return -ENOMEM;
-}
-
-static int __init uncore_types_init(struct intel_uncore_type **types)
-{
- int i, ret;
-
- for (i = 0; types[i]; i++) {
- ret = uncore_type_init(types[i]);
- if (ret)
- goto fail;
- }
- return 0;
-fail:
- while (--i >= 0)
- uncore_type_exit(types[i]);
- return ret;
-}
-
-/*
- * add a pci uncore device
- */
-static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- struct intel_uncore_type *type;
- int phys_id;
- bool first_box = false;
-
- phys_id = uncore_pcibus_to_physid[pdev->bus->number];
- if (phys_id < 0)
- return -ENODEV;
-
- if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
- int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
- uncore_extra_pci_dev[phys_id][idx] = pdev;
- pci_set_drvdata(pdev, NULL);
- return 0;
- }
-
- type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
- box = uncore_alloc_box(type, NUMA_NO_NODE);
- if (!box)
- return -ENOMEM;
-
- /*
- * for performance monitoring unit with multiple boxes,
- * each box has a different function id.
- */
- pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
- if (pmu->func_id < 0)
- pmu->func_id = pdev->devfn;
- else
- WARN_ON_ONCE(pmu->func_id != pdev->devfn);
-
- box->phys_id = phys_id;
- box->pci_dev = pdev;
- box->pmu = pmu;
- uncore_box_init(box);
- pci_set_drvdata(pdev, box);
-
- raw_spin_lock(&uncore_box_lock);
- if (list_empty(&pmu->box_list))
- first_box = true;
- list_add_tail(&box->list, &pmu->box_list);
- raw_spin_unlock(&uncore_box_lock);
-
- if (first_box)
- uncore_pmu_register(pmu);
- return 0;
-}
-
-static void uncore_pci_remove(struct pci_dev *pdev)
-{
- struct intel_uncore_box *box = pci_get_drvdata(pdev);
- struct intel_uncore_pmu *pmu;
- int i, cpu, phys_id = uncore_pcibus_to_physid[pdev->bus->number];
- bool last_box = false;
-
- box = pci_get_drvdata(pdev);
- if (!box) {
- for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
- if (uncore_extra_pci_dev[phys_id][i] == pdev) {
- uncore_extra_pci_dev[phys_id][i] = NULL;
- break;
- }
- }
- WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
- return;
- }
-
- pmu = box->pmu;
- if (WARN_ON_ONCE(phys_id != box->phys_id))
- return;
-
- pci_set_drvdata(pdev, NULL);
-
- raw_spin_lock(&uncore_box_lock);
- list_del(&box->list);
- if (list_empty(&pmu->box_list))
- last_box = true;
- raw_spin_unlock(&uncore_box_lock);
-
- for_each_possible_cpu(cpu) {
- if (*per_cpu_ptr(pmu->box, cpu) == box) {
- *per_cpu_ptr(pmu->box, cpu) = NULL;
- atomic_dec(&box->refcnt);
- }
- }
-
- WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
- kfree(box);
-
- if (last_box)
- perf_pmu_unregister(&pmu->pmu);
-}
-
-static int __init uncore_pci_init(void)
-{
- int ret;
-
- switch (boot_cpu_data.x86_model) {
- case 45: /* Sandy Bridge-EP */
- ret = snbep_uncore_pci_init();
- break;
- case 62: /* Ivy Bridge-EP */
- ret = ivbep_uncore_pci_init();
- break;
- case 63: /* Haswell-EP */
- ret = hswep_uncore_pci_init();
- break;
- case 86: /* BDX-DE */
- ret = bdx_uncore_pci_init();
- break;
- case 42: /* Sandy Bridge */
- ret = snb_uncore_pci_init();
- break;
- case 58: /* Ivy Bridge */
- ret = ivb_uncore_pci_init();
- break;
- case 60: /* Haswell */
- case 69: /* Haswell Celeron */
- ret = hsw_uncore_pci_init();
- break;
- case 61: /* Broadwell */
- ret = bdw_uncore_pci_init();
- break;
- default:
- return 0;
- }
-
- if (ret)
- return ret;
-
- ret = uncore_types_init(uncore_pci_uncores);
- if (ret)
- return ret;
-
- uncore_pci_driver->probe = uncore_pci_probe;
- uncore_pci_driver->remove = uncore_pci_remove;
-
- ret = pci_register_driver(uncore_pci_driver);
- if (ret == 0)
- pcidrv_registered = true;
- else
- uncore_types_exit(uncore_pci_uncores);
-
- return ret;
-}
-
-static void __init uncore_pci_exit(void)
-{
- if (pcidrv_registered) {
- pcidrv_registered = false;
- pci_unregister_driver(uncore_pci_driver);
- uncore_types_exit(uncore_pci_uncores);
- }
-}
-
-/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
-static LIST_HEAD(boxes_to_free);
-
-static void uncore_kfree_boxes(void)
-{
- struct intel_uncore_box *box;
-
- while (!list_empty(&boxes_to_free)) {
- box = list_entry(boxes_to_free.next,
- struct intel_uncore_box, list);
- list_del(&box->list);
- kfree(box);
- }
-}
-
-static void uncore_cpu_dying(int cpu)
-{
- struct intel_uncore_type *type;
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- int i, j;
-
- for (i = 0; uncore_msr_uncores[i]; i++) {
- type = uncore_msr_uncores[i];
- for (j = 0; j < type->num_boxes; j++) {
- pmu = &type->pmus[j];
- box = *per_cpu_ptr(pmu->box, cpu);
- *per_cpu_ptr(pmu->box, cpu) = NULL;
- if (box && atomic_dec_and_test(&box->refcnt))
- list_add(&box->list, &boxes_to_free);
- }
- }
-}
-
-static int uncore_cpu_starting(int cpu)
-{
- struct intel_uncore_type *type;
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box, *exist;
- int i, j, k, phys_id;
-
- phys_id = topology_physical_package_id(cpu);
-
- for (i = 0; uncore_msr_uncores[i]; i++) {
- type = uncore_msr_uncores[i];
- for (j = 0; j < type->num_boxes; j++) {
- pmu = &type->pmus[j];
- box = *per_cpu_ptr(pmu->box, cpu);
- /* called by uncore_cpu_init? */
- if (box && box->phys_id >= 0) {
- uncore_box_init(box);
- continue;
- }
-
- for_each_online_cpu(k) {
- exist = *per_cpu_ptr(pmu->box, k);
- if (exist && exist->phys_id == phys_id) {
- atomic_inc(&exist->refcnt);
- *per_cpu_ptr(pmu->box, cpu) = exist;
- if (box) {
- list_add(&box->list,
- &boxes_to_free);
- box = NULL;
- }
- break;
- }
- }
-
- if (box) {
- box->phys_id = phys_id;
- uncore_box_init(box);
- }
- }
- }
- return 0;
-}
-
-static int uncore_cpu_prepare(int cpu, int phys_id)
-{
- struct intel_uncore_type *type;
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- int i, j;
-
- for (i = 0; uncore_msr_uncores[i]; i++) {
- type = uncore_msr_uncores[i];
- for (j = 0; j < type->num_boxes; j++) {
- pmu = &type->pmus[j];
- if (pmu->func_id < 0)
- pmu->func_id = j;
-
- box = uncore_alloc_box(type, cpu_to_node(cpu));
- if (!box)
- return -ENOMEM;
-
- box->pmu = pmu;
- box->phys_id = phys_id;
- *per_cpu_ptr(pmu->box, cpu) = box;
- }
- }
- return 0;
-}
-
-static void
-uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
-{
- struct intel_uncore_type *type;
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- int i, j;
-
- for (i = 0; uncores[i]; i++) {
- type = uncores[i];
- for (j = 0; j < type->num_boxes; j++) {
- pmu = &type->pmus[j];
- if (old_cpu < 0)
- box = uncore_pmu_to_box(pmu, new_cpu);
- else
- box = uncore_pmu_to_box(pmu, old_cpu);
- if (!box)
- continue;
-
- if (old_cpu < 0) {
- WARN_ON_ONCE(box->cpu != -1);
- box->cpu = new_cpu;
- continue;
- }
-
- WARN_ON_ONCE(box->cpu != old_cpu);
- if (new_cpu >= 0) {
- uncore_pmu_cancel_hrtimer(box);
- perf_pmu_migrate_context(&pmu->pmu,
- old_cpu, new_cpu);
- box->cpu = new_cpu;
- } else {
- box->cpu = -1;
- }
- }
- }
-}
-
-static void uncore_event_exit_cpu(int cpu)
-{
- int i, phys_id, target;
-
- /* if exiting cpu is used for collecting uncore events */
- if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
- return;
-
- /* find a new cpu to collect uncore events */
- phys_id = topology_physical_package_id(cpu);
- target = -1;
- for_each_online_cpu(i) {
- if (i == cpu)
- continue;
- if (phys_id == topology_physical_package_id(i)) {
- target = i;
- break;
- }
- }
-
- /* migrate uncore events to the new cpu */
- if (target >= 0)
- cpumask_set_cpu(target, &uncore_cpu_mask);
-
- uncore_change_context(uncore_msr_uncores, cpu, target);
- uncore_change_context(uncore_pci_uncores, cpu, target);
-}
-
-static void uncore_event_init_cpu(int cpu)
-{
- int i, phys_id;
-
- phys_id = topology_physical_package_id(cpu);
- for_each_cpu(i, &uncore_cpu_mask) {
- if (phys_id == topology_physical_package_id(i))
- return;
- }
-
- cpumask_set_cpu(cpu, &uncore_cpu_mask);
-
- uncore_change_context(uncore_msr_uncores, -1, cpu);
- uncore_change_context(uncore_pci_uncores, -1, cpu);
-}
-
-static int uncore_cpu_notifier(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (long)hcpu;
-
- /* allocate/free data structure for uncore box */
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_UP_PREPARE:
- uncore_cpu_prepare(cpu, -1);
- break;
- case CPU_STARTING:
- uncore_cpu_starting(cpu);
- break;
- case CPU_UP_CANCELED:
- case CPU_DYING:
- uncore_cpu_dying(cpu);
- break;
- case CPU_ONLINE:
- case CPU_DEAD:
- uncore_kfree_boxes();
- break;
- default:
- break;
- }
-
- /* select the cpu that collects uncore events */
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_DOWN_FAILED:
- case CPU_STARTING:
- uncore_event_init_cpu(cpu);
- break;
- case CPU_DOWN_PREPARE:
- uncore_event_exit_cpu(cpu);
- break;
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block uncore_cpu_nb = {
- .notifier_call = uncore_cpu_notifier,
- /*
- * to migrate uncore events, our notifier should be executed
- * before perf core's notifier.
- */
- .priority = CPU_PRI_PERF + 1,
-};
-
-static void __init uncore_cpu_setup(void *dummy)
-{
- uncore_cpu_starting(smp_processor_id());
-}
-
-static int __init uncore_cpu_init(void)
-{
- int ret;
-
- switch (boot_cpu_data.x86_model) {
- case 26: /* Nehalem */
- case 30:
- case 37: /* Westmere */
- case 44:
- nhm_uncore_cpu_init();
- break;
- case 42: /* Sandy Bridge */
- case 58: /* Ivy Bridge */
- case 60: /* Haswell */
- case 69: /* Haswell */
- case 70: /* Haswell */
- case 61: /* Broadwell */
- case 71: /* Broadwell */
- snb_uncore_cpu_init();
- break;
- case 45: /* Sandy Bridge-EP */
- snbep_uncore_cpu_init();
- break;
- case 46: /* Nehalem-EX */
- case 47: /* Westmere-EX aka. Xeon E7 */
- nhmex_uncore_cpu_init();
- break;
- case 62: /* Ivy Bridge-EP */
- ivbep_uncore_cpu_init();
- break;
- case 63: /* Haswell-EP */
- hswep_uncore_cpu_init();
- break;
- case 86: /* BDX-DE */
- bdx_uncore_cpu_init();
- break;
- default:
- return 0;
- }
-
- ret = uncore_types_init(uncore_msr_uncores);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int __init uncore_pmus_register(void)
-{
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_type *type;
- int i, j;
-
- for (i = 0; uncore_msr_uncores[i]; i++) {
- type = uncore_msr_uncores[i];
- for (j = 0; j < type->num_boxes; j++) {
- pmu = &type->pmus[j];
- uncore_pmu_register(pmu);
- }
- }
-
- return 0;
-}
-
-static void __init uncore_cpumask_init(void)
-{
- int cpu;
-
- /*
- * ony invoke once from msr or pci init code
- */
- if (!cpumask_empty(&uncore_cpu_mask))
- return;
-
- cpu_notifier_register_begin();
-
- for_each_online_cpu(cpu) {
- int i, phys_id = topology_physical_package_id(cpu);
-
- for_each_cpu(i, &uncore_cpu_mask) {
- if (phys_id == topology_physical_package_id(i)) {
- phys_id = -1;
- break;
- }
- }
- if (phys_id < 0)
- continue;
-
- uncore_cpu_prepare(cpu, phys_id);
- uncore_event_init_cpu(cpu);
- }
- on_each_cpu(uncore_cpu_setup, NULL, 1);
-
- __register_cpu_notifier(&uncore_cpu_nb);
-
- cpu_notifier_register_done();
-}
-
-
-static int __init intel_uncore_init(void)
-{
- int ret;
-
- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
- return -ENODEV;
-
- if (cpu_has_hypervisor)
- return -ENODEV;
-
- ret = uncore_pci_init();
- if (ret)
- goto fail;
- ret = uncore_cpu_init();
- if (ret) {
- uncore_pci_exit();
- goto fail;
- }
- uncore_cpumask_init();
-
- uncore_pmus_register();
- return 0;
-fail:
- return ret;
-}
-device_initcall(intel_uncore_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
deleted file mode 100644
index 72c54c2..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ /dev/null
@@ -1,343 +0,0 @@
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/perf_event.h>
-#include "perf_event.h"
-
-#define UNCORE_PMU_NAME_LEN 32
-#define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC)
-#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC)
-
-#define UNCORE_FIXED_EVENT 0xff
-#define UNCORE_PMC_IDX_MAX_GENERIC 8
-#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC
-#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1)
-
-#define UNCORE_PCI_DEV_DATA(type, idx) ((type << 8) | idx)
-#define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff)
-#define UNCORE_PCI_DEV_IDX(data) (data & 0xff)
-#define UNCORE_EXTRA_PCI_DEV 0xff
-#define UNCORE_EXTRA_PCI_DEV_MAX 3
-
-/* support up to 8 sockets */
-#define UNCORE_SOCKET_MAX 8
-
-#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
-
-struct intel_uncore_ops;
-struct intel_uncore_pmu;
-struct intel_uncore_box;
-struct uncore_event_desc;
-
-struct intel_uncore_type {
- const char *name;
- int num_counters;
- int num_boxes;
- int perf_ctr_bits;
- int fixed_ctr_bits;
- unsigned perf_ctr;
- unsigned event_ctl;
- unsigned event_mask;
- unsigned fixed_ctr;
- unsigned fixed_ctl;
- unsigned box_ctl;
- unsigned msr_offset;
- unsigned num_shared_regs:8;
- unsigned single_fixed:1;
- unsigned pair_ctr_ctl:1;
- unsigned *msr_offsets;
- struct event_constraint unconstrainted;
- struct event_constraint *constraints;
- struct intel_uncore_pmu *pmus;
- struct intel_uncore_ops *ops;
- struct uncore_event_desc *event_descs;
- const struct attribute_group *attr_groups[4];
- struct pmu *pmu; /* for custom pmu ops */
-};
-
-#define pmu_group attr_groups[0]
-#define format_group attr_groups[1]
-#define events_group attr_groups[2]
-
-struct intel_uncore_ops {
- void (*init_box)(struct intel_uncore_box *);
- void (*disable_box)(struct intel_uncore_box *);
- void (*enable_box)(struct intel_uncore_box *);
- void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
- void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
- u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
- int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
- struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
- struct perf_event *);
- void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
-};
-
-struct intel_uncore_pmu {
- struct pmu pmu;
- char name[UNCORE_PMU_NAME_LEN];
- int pmu_idx;
- int func_id;
- struct intel_uncore_type *type;
- struct intel_uncore_box ** __percpu box;
- struct list_head box_list;
-};
-
-struct intel_uncore_extra_reg {
- raw_spinlock_t lock;
- u64 config, config1, config2;
- atomic_t ref;
-};
-
-struct intel_uncore_box {
- int phys_id;
- int n_active; /* number of active events */
- int n_events;
- int cpu; /* cpu to collect events */
- unsigned long flags;
- atomic_t refcnt;
- struct perf_event *events[UNCORE_PMC_IDX_MAX];
- struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
- struct event_constraint *event_constraint[UNCORE_PMC_IDX_MAX];
- unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
- u64 tags[UNCORE_PMC_IDX_MAX];
- struct pci_dev *pci_dev;
- struct intel_uncore_pmu *pmu;
- u64 hrtimer_duration; /* hrtimer timeout for this box */
- struct hrtimer hrtimer;
- struct list_head list;
- struct list_head active_list;
- void *io_addr;
- struct intel_uncore_extra_reg shared_regs[0];
-};
-
-#define UNCORE_BOX_FLAG_INITIATED 0
-
-struct uncore_event_desc {
- struct kobj_attribute attr;
- const char *config;
-};
-
-ssize_t uncore_event_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf);
-
-#define INTEL_UNCORE_EVENT_DESC(_name, _config) \
-{ \
- .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \
- .config = _config, \
-}
-
-#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
-static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
- struct kobj_attribute *attr, \
- char *page) \
-{ \
- BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
- return sprintf(page, _format "\n"); \
-} \
-static struct kobj_attribute format_attr_##_var = \
- __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
-
-static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
-{
- return box->pmu->type->box_ctl;
-}
-
-static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
-{
- return box->pmu->type->fixed_ctl;
-}
-
-static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
-{
- return box->pmu->type->fixed_ctr;
-}
-
-static inline
-unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
-{
- return idx * 4 + box->pmu->type->event_ctl;
-}
-
-static inline
-unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
-{
- return idx * 8 + box->pmu->type->perf_ctr;
-}
-
-static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
-{
- struct intel_uncore_pmu *pmu = box->pmu;
- return pmu->type->msr_offsets ?
- pmu->type->msr_offsets[pmu->pmu_idx] :
- pmu->type->msr_offset * pmu->pmu_idx;
-}
-
-static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
-{
- if (!box->pmu->type->box_ctl)
- return 0;
- return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
-}
-
-static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
-{
- if (!box->pmu->type->fixed_ctl)
- return 0;
- return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
-}
-
-static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
-{
- return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
-{
- return box->pmu->type->event_ctl +
- (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
- uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
-{
- return box->pmu->type->perf_ctr +
- (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
- uncore_msr_box_offset(box);
-}
-
-static inline
-unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
-{
- if (box->pci_dev)
- return uncore_pci_fixed_ctl(box);
- else
- return uncore_msr_fixed_ctl(box);
-}
-
-static inline
-unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
-{
- if (box->pci_dev)
- return uncore_pci_fixed_ctr(box);
- else
- return uncore_msr_fixed_ctr(box);
-}
-
-static inline
-unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
-{
- if (box->pci_dev)
- return uncore_pci_event_ctl(box, idx);
- else
- return uncore_msr_event_ctl(box, idx);
-}
-
-static inline
-unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
-{
- if (box->pci_dev)
- return uncore_pci_perf_ctr(box, idx);
- else
- return uncore_msr_perf_ctr(box, idx);
-}
-
-static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
-{
- return box->pmu->type->perf_ctr_bits;
-}
-
-static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
-{
- return box->pmu->type->fixed_ctr_bits;
-}
-
-static inline int uncore_num_counters(struct intel_uncore_box *box)
-{
- return box->pmu->type->num_counters;
-}
-
-static inline void uncore_disable_box(struct intel_uncore_box *box)
-{
- if (box->pmu->type->ops->disable_box)
- box->pmu->type->ops->disable_box(box);
-}
-
-static inline void uncore_enable_box(struct intel_uncore_box *box)
-{
- if (box->pmu->type->ops->enable_box)
- box->pmu->type->ops->enable_box(box);
-}
-
-static inline void uncore_disable_event(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- box->pmu->type->ops->disable_event(box, event);
-}
-
-static inline void uncore_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- box->pmu->type->ops->enable_event(box, event);
-}
-
-static inline u64 uncore_read_counter(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- return box->pmu->type->ops->read_counter(box, event);
-}
-
-static inline void uncore_box_init(struct intel_uncore_box *box)
-{
- if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
- if (box->pmu->type->ops->init_box)
- box->pmu->type->ops->init_box(box);
- }
-}
-
-static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
-{
- return (box->phys_id < 0);
-}
-
-struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event);
-struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
-struct intel_uncore_box *uncore_event_to_box(struct perf_event *event);
-u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
-void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
-void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
-void uncore_pmu_event_read(struct perf_event *event);
-void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event);
-struct event_constraint *
-uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
-void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
-u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
-
-extern struct intel_uncore_type **uncore_msr_uncores;
-extern struct intel_uncore_type **uncore_pci_uncores;
-extern struct pci_driver *uncore_pci_driver;
-extern int uncore_pcibus_to_physid[256];
-extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
-extern struct event_constraint uncore_constraint_empty;
-
-/* perf_event_intel_uncore_snb.c */
-int snb_uncore_pci_init(void);
-int ivb_uncore_pci_init(void);
-int hsw_uncore_pci_init(void);
-int bdw_uncore_pci_init(void);
-void snb_uncore_cpu_init(void);
-void nhm_uncore_cpu_init(void);
-
-/* perf_event_intel_uncore_snbep.c */
-int snbep_uncore_pci_init(void);
-void snbep_uncore_cpu_init(void);
-int ivbep_uncore_pci_init(void);
-void ivbep_uncore_cpu_init(void);
-int hswep_uncore_pci_init(void);
-void hswep_uncore_cpu_init(void);
-int bdx_uncore_pci_init(void);
-void bdx_uncore_cpu_init(void);
-
-/* perf_event_intel_uncore_nhmex.c */
-void nhmex_uncore_cpu_init(void);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
deleted file mode 100644
index 2749965..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/* Nehalem-EX/Westmere-EX uncore support */
-#include "perf_event_intel_uncore.h"
-
-/* NHM-EX event control */
-#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff
-#define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00
-#define NHMEX_PMON_CTL_EN_BIT0 (1 << 0)
-#define NHMEX_PMON_CTL_EDGE_DET (1 << 18)
-#define NHMEX_PMON_CTL_PMI_EN (1 << 20)
-#define NHMEX_PMON_CTL_EN_BIT22 (1 << 22)
-#define NHMEX_PMON_CTL_INVERT (1 << 23)
-#define NHMEX_PMON_CTL_TRESH_MASK 0xff000000
-#define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \
- NHMEX_PMON_CTL_UMASK_MASK | \
- NHMEX_PMON_CTL_EDGE_DET | \
- NHMEX_PMON_CTL_INVERT | \
- NHMEX_PMON_CTL_TRESH_MASK)
-
-/* NHM-EX Ubox */
-#define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00
-#define NHMEX_U_MSR_PMON_CTR 0xc11
-#define NHMEX_U_MSR_PMON_EV_SEL 0xc10
-
-#define NHMEX_U_PMON_GLOBAL_EN (1 << 0)
-#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e
-#define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28)
-#define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29)
-#define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31)
-
-#define NHMEX_U_PMON_RAW_EVENT_MASK \
- (NHMEX_PMON_CTL_EV_SEL_MASK | \
- NHMEX_PMON_CTL_EDGE_DET)
-
-/* NHM-EX Cbox */
-#define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00
-#define NHMEX_C0_MSR_PMON_CTR0 0xd11
-#define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10
-#define NHMEX_C_MSR_OFFSET 0x20
-
-/* NHM-EX Bbox */
-#define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20
-#define NHMEX_B0_MSR_PMON_CTR0 0xc31
-#define NHMEX_B0_MSR_PMON_CTL0 0xc30
-#define NHMEX_B_MSR_OFFSET 0x40
-#define NHMEX_B0_MSR_MATCH 0xe45
-#define NHMEX_B0_MSR_MASK 0xe46
-#define NHMEX_B1_MSR_MATCH 0xe4d
-#define NHMEX_B1_MSR_MASK 0xe4e
-
-#define NHMEX_B_PMON_CTL_EN (1 << 0)
-#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1
-#define NHMEX_B_PMON_CTL_EV_SEL_MASK \
- (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
-#define NHMEX_B_PMON_CTR_SHIFT 6
-#define NHMEX_B_PMON_CTR_MASK \
- (0x3 << NHMEX_B_PMON_CTR_SHIFT)
-#define NHMEX_B_PMON_RAW_EVENT_MASK \
- (NHMEX_B_PMON_CTL_EV_SEL_MASK | \
- NHMEX_B_PMON_CTR_MASK)
-
-/* NHM-EX Sbox */
-#define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40
-#define NHMEX_S0_MSR_PMON_CTR0 0xc51
-#define NHMEX_S0_MSR_PMON_CTL0 0xc50
-#define NHMEX_S_MSR_OFFSET 0x80
-#define NHMEX_S0_MSR_MM_CFG 0xe48
-#define NHMEX_S0_MSR_MATCH 0xe49
-#define NHMEX_S0_MSR_MASK 0xe4a
-#define NHMEX_S1_MSR_MM_CFG 0xe58
-#define NHMEX_S1_MSR_MATCH 0xe59
-#define NHMEX_S1_MSR_MASK 0xe5a
-
-#define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63)
-#define NHMEX_S_EVENT_TO_R_PROG_EV 0
-
-/* NHM-EX Mbox */
-#define NHMEX_M0_MSR_GLOBAL_CTL 0xca0
-#define NHMEX_M0_MSR_PMU_DSP 0xca5
-#define NHMEX_M0_MSR_PMU_ISS 0xca6
-#define NHMEX_M0_MSR_PMU_MAP 0xca7
-#define NHMEX_M0_MSR_PMU_MSC_THR 0xca8
-#define NHMEX_M0_MSR_PMU_PGT 0xca9
-#define NHMEX_M0_MSR_PMU_PLD 0xcaa
-#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab
-#define NHMEX_M0_MSR_PMU_CTL0 0xcb0
-#define NHMEX_M0_MSR_PMU_CNT0 0xcb1
-#define NHMEX_M_MSR_OFFSET 0x40
-#define NHMEX_M0_MSR_PMU_MM_CFG 0xe54
-#define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c
-
-#define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63)
-#define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL
-#define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL
-#define NHMEX_M_PMON_ADDR_MASK_SHIFT 34
-
-#define NHMEX_M_PMON_CTL_EN (1 << 0)
-#define NHMEX_M_PMON_CTL_PMI_EN (1 << 1)
-#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2
-#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \
- (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
-#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4
-#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \
- (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
-#define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6)
-#define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7)
-#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9
-#define NHMEX_M_PMON_CTL_INC_SEL_MASK \
- (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
-#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19
-#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \
- (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
-#define NHMEX_M_PMON_RAW_EVENT_MASK \
- (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \
- NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \
- NHMEX_M_PMON_CTL_WRAP_MODE | \
- NHMEX_M_PMON_CTL_FLAG_MODE | \
- NHMEX_M_PMON_CTL_INC_SEL_MASK | \
- NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
-
-#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23))
-#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (11 + 3 * (n)))
-
-#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24))
-#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (12 + 3 * (n)))
-
-/*
- * use the 9~13 bits to select event If the 7th bit is not set,
- * otherwise use the 19~21 bits to select event.
- */
-#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
-#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
- NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
- NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
- NHMEX_M_PMON_CTL_FLAG_MODE)
-#define MBOX_INC_SEL_EXTAR_REG(c, r) \
- EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
- MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
-#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
- EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
- MBOX_SET_FLAG_SEL_MASK, \
- (u64)-1, NHMEX_M_##r)
-
-/* NHM-EX Rbox */
-#define NHMEX_R_MSR_GLOBAL_CTL 0xe00
-#define NHMEX_R_MSR_PMON_CTL0 0xe10
-#define NHMEX_R_MSR_PMON_CNT0 0xe11
-#define NHMEX_R_MSR_OFFSET 0x20
-
-#define NHMEX_R_MSR_PORTN_QLX_CFG(n) \
- ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
-#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n))
-#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n))
-#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \
- (((n) < 4 ? 0 : 0x10) + (n) * 4)
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \
- (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \
- (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
-#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \
- (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \
- (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \
- (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
-#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \
- (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)
-
-#define NHMEX_R_PMON_CTL_EN (1 << 0)
-#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1
-#define NHMEX_R_PMON_CTL_EV_SEL_MASK \
- (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
-#define NHMEX_R_PMON_CTL_PMI_EN (1 << 6)
-#define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK
-
-/* NHM-EX Wbox */
-#define NHMEX_W_MSR_GLOBAL_CTL 0xc80
-#define NHMEX_W_MSR_PMON_CNT0 0xc90
-#define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91
-#define NHMEX_W_MSR_PMON_FIXED_CTR 0x394
-#define NHMEX_W_MSR_PMON_FIXED_CTL 0x395
-
-#define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31)
-
-#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
- ((1ULL << (n)) - 1)))
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
-DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
-
-static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
-{
- wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
-}
-
-static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
- unsigned msr = uncore_msr_box_ctl(box);
- u64 config;
-
- if (msr) {
- rdmsrl(msr, config);
- config &= ~((1ULL << uncore_num_counters(box)) - 1);
- /* WBox has a fixed counter */
- if (uncore_msr_fixed_ctl(box))
- config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
- wrmsrl(msr, config);
- }
-}
-
-static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
- unsigned msr = uncore_msr_box_ctl(box);
- u64 config;
-
- if (msr) {
- rdmsrl(msr, config);
- config |= (1ULL << uncore_num_counters(box)) - 1;
- /* WBox has a fixed counter */
- if (uncore_msr_fixed_ctl(box))
- config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
- wrmsrl(msr, config);
- }
-}
-
-static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- wrmsrl(event->hw.config_base, 0);
-}
-
-static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
- wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
- else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
- wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
- else
- wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
-}
-
-#define NHMEX_UNCORE_OPS_COMMON_INIT() \
- .init_box = nhmex_uncore_msr_init_box, \
- .disable_box = nhmex_uncore_msr_disable_box, \
- .enable_box = nhmex_uncore_msr_enable_box, \
- .disable_event = nhmex_uncore_msr_disable_event, \
- .read_counter = uncore_msr_read_counter
-
-static struct intel_uncore_ops nhmex_uncore_ops = {
- NHMEX_UNCORE_OPS_COMMON_INIT(),
- .enable_event = nhmex_uncore_msr_enable_event,
-};
-
-static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_edge.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_ubox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_ubox_formats_attr,
-};
-
-static struct intel_uncore_type nhmex_uncore_ubox = {
- .name = "ubox",
- .num_counters = 1,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_U_MSR_PMON_EV_SEL,
- .perf_ctr = NHMEX_U_MSR_PMON_CTR,
- .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL,
- .ops = &nhmex_uncore_ops,
- .format_group = &nhmex_uncore_ubox_format_group
-};
-
-static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_cbox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_cbox_formats_attr,
-};
-
-/* msr offset for each instance of cbox */
-static unsigned nhmex_cbox_msr_offsets[] = {
- 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
-};
-
-static struct intel_uncore_type nhmex_uncore_cbox = {
- .name = "cbox",
- .num_counters = 6,
- .num_boxes = 10,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0,
- .perf_ctr = NHMEX_C0_MSR_PMON_CTR0,
- .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
- .msr_offsets = nhmex_cbox_msr_offsets,
- .pair_ctr_ctl = 1,
- .ops = &nhmex_uncore_ops,
- .format_group = &nhmex_uncore_cbox_format_group
-};
-
-static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
- { /* end: all zeroes */ },
-};
-
-static struct intel_uncore_type nhmex_uncore_wbox = {
- .name = "wbox",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_W_MSR_PMON_CNT0,
- .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0,
- .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR,
- .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL,
- .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_W_MSR_GLOBAL_CTL,
- .pair_ctr_ctl = 1,
- .event_descs = nhmex_uncore_wbox_events,
- .ops = &nhmex_uncore_ops,
- .format_group = &nhmex_uncore_cbox_format_group
-};
-
-static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
- int ctr, ev_sel;
-
- ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
- NHMEX_B_PMON_CTR_SHIFT;
- ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
- NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
-
- /* events that do not use the match/mask registers */
- if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
- (ctr == 2 && ev_sel != 0x4) || ctr == 3)
- return 0;
-
- if (box->pmu->pmu_idx == 0)
- reg1->reg = NHMEX_B0_MSR_MATCH;
- else
- reg1->reg = NHMEX_B1_MSR_MATCH;
- reg1->idx = 0;
- reg1->config = event->attr.config1;
- reg2->config = event->attr.config2;
- return 0;
-}
-
-static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
- if (reg1->idx != EXTRA_REG_NONE) {
- wrmsrl(reg1->reg, reg1->config);
- wrmsrl(reg1->reg + 1, reg2->config);
- }
- wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
- (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
-}
-
-/*
- * The Bbox has 4 counters, but each counter monitors different events.
- * Use bits 6-7 in the event config to select counter.
- */
-static struct event_constraint nhmex_uncore_bbox_constraints[] = {
- EVENT_CONSTRAINT(0 , 1, 0xc0),
- EVENT_CONSTRAINT(0x40, 2, 0xc0),
- EVENT_CONSTRAINT(0x80, 4, 0xc0),
- EVENT_CONSTRAINT(0xc0, 8, 0xc0),
- EVENT_CONSTRAINT_END,
-};
-
-static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
- &format_attr_event5.attr,
- &format_attr_counter.attr,
- &format_attr_match.attr,
- &format_attr_mask.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_bbox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_bbox_formats_attr,
-};
-
-static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
- NHMEX_UNCORE_OPS_COMMON_INIT(),
- .enable_event = nhmex_bbox_msr_enable_event,
- .hw_config = nhmex_bbox_hw_config,
- .get_constraint = uncore_get_constraint,
- .put_constraint = uncore_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_bbox = {
- .name = "bbox",
- .num_counters = 4,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_B0_MSR_PMON_CTL0,
- .perf_ctr = NHMEX_B0_MSR_PMON_CTR0,
- .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL,
- .msr_offset = NHMEX_B_MSR_OFFSET,
- .pair_ctr_ctl = 1,
- .num_shared_regs = 1,
- .constraints = nhmex_uncore_bbox_constraints,
- .ops = &nhmex_uncore_bbox_ops,
- .format_group = &nhmex_uncore_bbox_format_group
-};
-
-static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
- /* only TO_R_PROG_EV event uses the match/mask register */
- if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
- NHMEX_S_EVENT_TO_R_PROG_EV)
- return 0;
-
- if (box->pmu->pmu_idx == 0)
- reg1->reg = NHMEX_S0_MSR_MM_CFG;
- else
- reg1->reg = NHMEX_S1_MSR_MM_CFG;
- reg1->idx = 0;
- reg1->config = event->attr.config1;
- reg2->config = event->attr.config2;
- return 0;
-}
-
-static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
- if (reg1->idx != EXTRA_REG_NONE) {
- wrmsrl(reg1->reg, 0);
- wrmsrl(reg1->reg + 1, reg1->config);
- wrmsrl(reg1->reg + 2, reg2->config);
- wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
- }
- wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
-}
-
-static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- &format_attr_match.attr,
- &format_attr_mask.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_sbox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_sbox_formats_attr,
-};
-
-static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
- NHMEX_UNCORE_OPS_COMMON_INIT(),
- .enable_event = nhmex_sbox_msr_enable_event,
- .hw_config = nhmex_sbox_hw_config,
- .get_constraint = uncore_get_constraint,
- .put_constraint = uncore_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_sbox = {
- .name = "sbox",
- .num_counters = 4,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_S0_MSR_PMON_CTL0,
- .perf_ctr = NHMEX_S0_MSR_PMON_CTR0,
- .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL,
- .msr_offset = NHMEX_S_MSR_OFFSET,
- .pair_ctr_ctl = 1,
- .num_shared_regs = 1,
- .ops = &nhmex_uncore_sbox_ops,
- .format_group = &nhmex_uncore_sbox_format_group
-};
-
-enum {
- EXTRA_REG_NHMEX_M_FILTER,
- EXTRA_REG_NHMEX_M_DSP,
- EXTRA_REG_NHMEX_M_ISS,
- EXTRA_REG_NHMEX_M_MAP,
- EXTRA_REG_NHMEX_M_MSC_THR,
- EXTRA_REG_NHMEX_M_PGT,
- EXTRA_REG_NHMEX_M_PLD,
- EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
-};
-
-static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
- MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
- MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
- MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
- MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
- /* event 0xa uses two extra registers */
- MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
- MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
- MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
- /* events 0xd ~ 0x10 use the same extra register */
- MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
- MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
- MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
- MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
- MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
- MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
- MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
- MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
- MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
- EVENT_EXTRA_END
-};
-
-/* Nehalem-EX or Westmere-EX ? */
-static bool uncore_nhmex;
-
-static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
-{
- struct intel_uncore_extra_reg *er;
- unsigned long flags;
- bool ret = false;
- u64 mask;
-
- if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
- er = &box->shared_regs[idx];
- raw_spin_lock_irqsave(&er->lock, flags);
- if (!atomic_read(&er->ref) || er->config == config) {
- atomic_inc(&er->ref);
- er->config = config;
- ret = true;
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- return ret;
- }
- /*
- * The ZDP_CTL_FVC MSR has 4 fields which are used to control
- * events 0xd ~ 0x10. Besides these 4 fields, there are additional
- * fields which are shared.
- */
- idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
- if (WARN_ON_ONCE(idx >= 4))
- return false;
-
- /* mask of the shared fields */
- if (uncore_nhmex)
- mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
- else
- mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
- er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
-
- raw_spin_lock_irqsave(&er->lock, flags);
- /* add mask of the non-shared field if it's in use */
- if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
- if (uncore_nhmex)
- mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- else
- mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- }
-
- if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
- atomic_add(1 << (idx * 8), &er->ref);
- if (uncore_nhmex)
- mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
- NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- else
- mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
- WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- er->config &= ~mask;
- er->config |= (config & mask);
- ret = true;
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- return ret;
-}
-
-static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
-{
- struct intel_uncore_extra_reg *er;
-
- if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
- er = &box->shared_regs[idx];
- atomic_dec(&er->ref);
- return;
- }
-
- idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
- er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
- atomic_sub(1 << (idx * 8), &er->ref);
-}
-
-static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
- u64 config = reg1->config;
-
- /* get the non-shared control bits and shift them */
- idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
- if (uncore_nhmex)
- config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- else
- config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
- if (new_idx > orig_idx) {
- idx = new_idx - orig_idx;
- config <<= 3 * idx;
- } else {
- idx = orig_idx - new_idx;
- config >>= 3 * idx;
- }
-
- /* add the shared control bits back */
- if (uncore_nhmex)
- config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
- else
- config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
- config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
- if (modify) {
- /* adjust the main event selector */
- if (new_idx > orig_idx)
- hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
- else
- hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
- reg1->config = config;
- reg1->idx = ~0xff | new_idx;
- }
- return config;
-}
-
-static struct event_constraint *
-nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
- int i, idx[2], alloc = 0;
- u64 config1 = reg1->config;
-
- idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
- idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
-again:
- for (i = 0; i < 2; i++) {
- if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
- idx[i] = 0xff;
-
- if (idx[i] == 0xff)
- continue;
-
- if (!nhmex_mbox_get_shared_reg(box, idx[i],
- __BITS_VALUE(config1, i, 32)))
- goto fail;
- alloc |= (0x1 << i);
- }
-
- /* for the match/mask registers */
- if (reg2->idx != EXTRA_REG_NONE &&
- (uncore_box_is_fake(box) || !reg2->alloc) &&
- !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
- goto fail;
-
- /*
- * If it's a fake box -- as per validate_{group,event}() we
- * shouldn't touch event state and we can avoid doing so
- * since both will only call get_event_constraints() once
- * on each event, this avoids the need for reg->alloc.
- */
- if (!uncore_box_is_fake(box)) {
- if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
- nhmex_mbox_alter_er(event, idx[0], true);
- reg1->alloc |= alloc;
- if (reg2->idx != EXTRA_REG_NONE)
- reg2->alloc = 1;
- }
- return NULL;
-fail:
- if (idx[0] != 0xff && !(alloc & 0x1) &&
- idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
- /*
- * events 0xd ~ 0x10 are functional identical, but are
- * controlled by different fields in the ZDP_CTL_FVC
- * register. If we failed to take one field, try the
- * rest 3 choices.
- */
- BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
- idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
- idx[0] = (idx[0] + 1) % 4;
- idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
- if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
- config1 = nhmex_mbox_alter_er(event, idx[0], false);
- goto again;
- }
- }
-
- if (alloc & 0x1)
- nhmex_mbox_put_shared_reg(box, idx[0]);
- if (alloc & 0x2)
- nhmex_mbox_put_shared_reg(box, idx[1]);
- return &uncore_constraint_empty;
-}
-
-static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
-
- if (uncore_box_is_fake(box))
- return;
-
- if (reg1->alloc & 0x1)
- nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
- if (reg1->alloc & 0x2)
- nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
- reg1->alloc = 0;
-
- if (reg2->alloc) {
- nhmex_mbox_put_shared_reg(box, reg2->idx);
- reg2->alloc = 0;
- }
-}
-
-static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
-{
- if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
- return er->idx;
- return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
-}
-
-static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct intel_uncore_type *type = box->pmu->type;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
- struct extra_reg *er;
- unsigned msr;
- int reg_idx = 0;
- /*
- * The mbox events may require 2 extra MSRs at the most. But only
- * the lower 32 bits in these MSRs are significant, so we can use
- * config1 to pass two MSRs' config.
- */
- for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
- if (er->event != (event->hw.config & er->config_mask))
- continue;
- if (event->attr.config1 & ~er->valid_mask)
- return -EINVAL;
-
- msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
- if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
- return -EINVAL;
-
- /* always use the 32~63 bits to pass the PLD config */
- if (er->idx == EXTRA_REG_NHMEX_M_PLD)
- reg_idx = 1;
- else if (WARN_ON_ONCE(reg_idx > 0))
- return -EINVAL;
-
- reg1->idx &= ~(0xff << (reg_idx * 8));
- reg1->reg &= ~(0xffff << (reg_idx * 16));
- reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
- reg1->reg |= msr << (reg_idx * 16);
- reg1->config = event->attr.config1;
- reg_idx++;
- }
- /*
- * The mbox only provides ability to perform address matching
- * for the PLD events.
- */
- if (reg_idx == 2) {
- reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
- if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
- reg2->config = event->attr.config2;
- else
- reg2->config = ~0ULL;
- if (box->pmu->pmu_idx == 0)
- reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
- else
- reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
- }
- return 0;
-}
-
-static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
-{
- struct intel_uncore_extra_reg *er;
- unsigned long flags;
- u64 config;
-
- if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
- return box->shared_regs[idx].config;
-
- er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
- raw_spin_lock_irqsave(&er->lock, flags);
- config = er->config;
- raw_spin_unlock_irqrestore(&er->lock, flags);
- return config;
-}
-
-static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
- int idx;
-
- idx = __BITS_VALUE(reg1->idx, 0, 8);
- if (idx != 0xff)
- wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
- nhmex_mbox_shared_reg_config(box, idx));
- idx = __BITS_VALUE(reg1->idx, 1, 8);
- if (idx != 0xff)
- wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
- nhmex_mbox_shared_reg_config(box, idx));
-
- if (reg2->idx != EXTRA_REG_NONE) {
- wrmsrl(reg2->reg, 0);
- if (reg2->config != ~0ULL) {
- wrmsrl(reg2->reg + 1,
- reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
- wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
- (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
- wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
- }
- }
-
- wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
-}
-
-DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3");
-DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5");
-DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6");
-DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7");
-DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13");
-DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21");
-DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63");
-DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33");
-DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61");
-DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63");
-
-static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
- &format_attr_count_mode.attr,
- &format_attr_storage_mode.attr,
- &format_attr_wrap_mode.attr,
- &format_attr_flag_mode.attr,
- &format_attr_inc_sel.attr,
- &format_attr_set_flag_sel.attr,
- &format_attr_filter_cfg_en.attr,
- &format_attr_filter_match.attr,
- &format_attr_filter_mask.attr,
- &format_attr_dsp.attr,
- &format_attr_thr.attr,
- &format_attr_fvc.attr,
- &format_attr_pgt.attr,
- &format_attr_map.attr,
- &format_attr_iss.attr,
- &format_attr_pld.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_mbox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_mbox_formats_attr,
-};
-
-static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
- INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
- INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
- { /* end: all zeroes */ },
-};
-
-static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
- INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
- INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
- { /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
- NHMEX_UNCORE_OPS_COMMON_INIT(),
- .enable_event = nhmex_mbox_msr_enable_event,
- .hw_config = nhmex_mbox_hw_config,
- .get_constraint = nhmex_mbox_get_constraint,
- .put_constraint = nhmex_mbox_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_mbox = {
- .name = "mbox",
- .num_counters = 6,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_M0_MSR_PMU_CTL0,
- .perf_ctr = NHMEX_M0_MSR_PMU_CNT0,
- .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL,
- .msr_offset = NHMEX_M_MSR_OFFSET,
- .pair_ctr_ctl = 1,
- .num_shared_regs = 8,
- .event_descs = nhmex_uncore_mbox_events,
- .ops = &nhmex_uncore_mbox_ops,
- .format_group = &nhmex_uncore_mbox_format_group,
-};
-
-static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
- /* adjust the main event selector and extra register index */
- if (reg1->idx % 2) {
- reg1->idx--;
- hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
- } else {
- reg1->idx++;
- hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
- }
-
- /* adjust extra register config */
- switch (reg1->idx % 6) {
- case 2:
- /* shift the 8~15 bits to the 0~7 bits */
- reg1->config >>= 8;
- break;
- case 3:
- /* shift the 0~7 bits to the 8~15 bits */
- reg1->config <<= 8;
- break;
- }
-}
-
-/*
- * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
- * An event set consists of 6 events, the 3rd and 4th events in
- * an event set use the same extra register. So an event set uses
- * 5 extra registers.
- */
-static struct event_constraint *
-nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
- struct intel_uncore_extra_reg *er;
- unsigned long flags;
- int idx, er_idx;
- u64 config1;
- bool ok = false;
-
- if (!uncore_box_is_fake(box) && reg1->alloc)
- return NULL;
-
- idx = reg1->idx % 6;
- config1 = reg1->config;
-again:
- er_idx = idx;
- /* the 3rd and 4th events use the same extra register */
- if (er_idx > 2)
- er_idx--;
- er_idx += (reg1->idx / 6) * 5;
-
- er = &box->shared_regs[er_idx];
- raw_spin_lock_irqsave(&er->lock, flags);
- if (idx < 2) {
- if (!atomic_read(&er->ref) || er->config == reg1->config) {
- atomic_inc(&er->ref);
- er->config = reg1->config;
- ok = true;
- }
- } else if (idx == 2 || idx == 3) {
- /*
- * these two events use different fields in a extra register,
- * the 0~7 bits and the 8~15 bits respectively.
- */
- u64 mask = 0xff << ((idx - 2) * 8);
- if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
- !((er->config ^ config1) & mask)) {
- atomic_add(1 << ((idx - 2) * 8), &er->ref);
- er->config &= ~mask;
- er->config |= config1 & mask;
- ok = true;
- }
- } else {
- if (!atomic_read(&er->ref) ||
- (er->config == (hwc->config >> 32) &&
- er->config1 == reg1->config &&
- er->config2 == reg2->config)) {
- atomic_inc(&er->ref);
- er->config = (hwc->config >> 32);
- er->config1 = reg1->config;
- er->config2 = reg2->config;
- ok = true;
- }
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- if (!ok) {
- /*
- * The Rbox events are always in pairs. The paired
- * events are functional identical, but use different
- * extra registers. If we failed to take an extra
- * register, try the alternative.
- */
- idx ^= 1;
- if (idx != reg1->idx % 6) {
- if (idx == 2)
- config1 >>= 8;
- else if (idx == 3)
- config1 <<= 8;
- goto again;
- }
- } else {
- if (!uncore_box_is_fake(box)) {
- if (idx != reg1->idx % 6)
- nhmex_rbox_alter_er(box, event);
- reg1->alloc = 1;
- }
- return NULL;
- }
- return &uncore_constraint_empty;
-}
-
-static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct intel_uncore_extra_reg *er;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- int idx, er_idx;
-
- if (uncore_box_is_fake(box) || !reg1->alloc)
- return;
-
- idx = reg1->idx % 6;
- er_idx = idx;
- if (er_idx > 2)
- er_idx--;
- er_idx += (reg1->idx / 6) * 5;
-
- er = &box->shared_regs[er_idx];
- if (idx == 2 || idx == 3)
- atomic_sub(1 << ((idx - 2) * 8), &er->ref);
- else
- atomic_dec(&er->ref);
-
- reg1->alloc = 0;
-}
-
-static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
- int idx;
-
- idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
- NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
- if (idx >= 0x18)
- return -EINVAL;
-
- reg1->idx = idx;
- reg1->config = event->attr.config1;
-
- switch (idx % 6) {
- case 4:
- case 5:
- hwc->config |= event->attr.config & (~0ULL << 32);
- reg2->config = event->attr.config2;
- break;
- }
- return 0;
-}
-
-static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
- int idx, port;
-
- idx = reg1->idx;
- port = idx / 6 + box->pmu->pmu_idx * 4;
-
- switch (idx % 6) {
- case 0:
- wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
- break;
- case 1:
- wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
- break;
- case 2:
- case 3:
- wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
- uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
- break;
- case 4:
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
- hwc->config >> 32);
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
- break;
- case 5:
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
- hwc->config >> 32);
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
- wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
- break;
- }
-
- wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
- (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
-}
-
-DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
-DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
-DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
-DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
-
-static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
- &format_attr_event5.attr,
- &format_attr_xbr_mm_cfg.attr,
- &format_attr_xbr_match.attr,
- &format_attr_xbr_mask.attr,
- &format_attr_qlx_cfg.attr,
- &format_attr_iperf_cfg.attr,
- NULL,
-};
-
-static struct attribute_group nhmex_uncore_rbox_format_group = {
- .name = "format",
- .attrs = nhmex_uncore_rbox_formats_attr,
-};
-
-static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
- INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"),
- INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"),
- INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"),
- INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"),
- INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"),
- INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"),
- { /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
- NHMEX_UNCORE_OPS_COMMON_INIT(),
- .enable_event = nhmex_rbox_msr_enable_event,
- .hw_config = nhmex_rbox_hw_config,
- .get_constraint = nhmex_rbox_get_constraint,
- .put_constraint = nhmex_rbox_put_constraint,
-};
-
-static struct intel_uncore_type nhmex_uncore_rbox = {
- .name = "rbox",
- .num_counters = 8,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .event_ctl = NHMEX_R_MSR_PMON_CTL0,
- .perf_ctr = NHMEX_R_MSR_PMON_CNT0,
- .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK,
- .box_ctl = NHMEX_R_MSR_GLOBAL_CTL,
- .msr_offset = NHMEX_R_MSR_OFFSET,
- .pair_ctr_ctl = 1,
- .num_shared_regs = 20,
- .event_descs = nhmex_uncore_rbox_events,
- .ops = &nhmex_uncore_rbox_ops,
- .format_group = &nhmex_uncore_rbox_format_group
-};
-
-static struct intel_uncore_type *nhmex_msr_uncores[] = {
- &nhmex_uncore_ubox,
- &nhmex_uncore_cbox,
- &nhmex_uncore_bbox,
- &nhmex_uncore_sbox,
- &nhmex_uncore_mbox,
- &nhmex_uncore_rbox,
- &nhmex_uncore_wbox,
- NULL,
-};
-
-void nhmex_uncore_cpu_init(void)
-{
- if (boot_cpu_data.x86_model == 46)
- uncore_nhmex = true;
- else
- nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
- if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
- uncore_msr_uncores = nhmex_msr_uncores;
-}
-/* end of Nehalem-EX uncore support */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
deleted file mode 100644
index f78574b..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/* Nehalem/SandBridge/Haswell uncore support */
-#include "perf_event_intel_uncore.h"
-
-/* Uncore IMC PCI IDs */
-#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
-#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154
-#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150
-#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00
-#define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04
-#define PCI_DEVICE_ID_INTEL_BDW_IMC 0x1604
-
-/* SNB event control */
-#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
-#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00
-#define SNB_UNC_CTL_EDGE_DET (1 << 18)
-#define SNB_UNC_CTL_EN (1 << 22)
-#define SNB_UNC_CTL_INVERT (1 << 23)
-#define SNB_UNC_CTL_CMASK_MASK 0x1f000000
-#define NHM_UNC_CTL_CMASK_MASK 0xff000000
-#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0)
-
-#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
- SNB_UNC_CTL_UMASK_MASK | \
- SNB_UNC_CTL_EDGE_DET | \
- SNB_UNC_CTL_INVERT | \
- SNB_UNC_CTL_CMASK_MASK)
-
-#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
- SNB_UNC_CTL_UMASK_MASK | \
- SNB_UNC_CTL_EDGE_DET | \
- SNB_UNC_CTL_INVERT | \
- NHM_UNC_CTL_CMASK_MASK)
-
-/* SNB global control register */
-#define SNB_UNC_PERF_GLOBAL_CTL 0x391
-#define SNB_UNC_FIXED_CTR_CTRL 0x394
-#define SNB_UNC_FIXED_CTR 0x395
-
-/* SNB uncore global control */
-#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1)
-#define SNB_UNC_GLOBAL_CTL_EN (1 << 29)
-
-/* SNB Cbo register */
-#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700
-#define SNB_UNC_CBO_0_PER_CTR0 0x706
-#define SNB_UNC_CBO_MSR_OFFSET 0x10
-
-/* SNB ARB register */
-#define SNB_UNC_ARB_PER_CTR0 0x3b0
-#define SNB_UNC_ARB_PERFEVTSEL0 0x3b2
-#define SNB_UNC_ARB_MSR_OFFSET 0x10
-
-/* NHM global control register */
-#define NHM_UNC_PERF_GLOBAL_CTL 0x391
-#define NHM_UNC_FIXED_CTR 0x394
-#define NHM_UNC_FIXED_CTR_CTRL 0x395
-
-/* NHM uncore global control */
-#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1)
-#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32)
-
-/* NHM uncore register */
-#define NHM_UNC_PERFEVTSEL0 0x3c0
-#define NHM_UNC_UNCORE_PMC0 0x3b0
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
-DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
-
-/* Sandy Bridge uncore support */
-static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- if (hwc->idx < UNCORE_PMC_IDX_FIXED)
- wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
- else
- wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
-}
-
-static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- wrmsrl(event->hw.config_base, 0);
-}
-
-static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
-{
- if (box->pmu->pmu_idx == 0) {
- wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
- SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
- }
-}
-
-static struct uncore_event_desc snb_uncore_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
- { /* end: all zeroes */ },
-};
-
-static struct attribute *snb_uncore_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_cmask5.attr,
- NULL,
-};
-
-static struct attribute_group snb_uncore_format_group = {
- .name = "format",
- .attrs = snb_uncore_formats_attr,
-};
-
-static struct intel_uncore_ops snb_uncore_msr_ops = {
- .init_box = snb_uncore_msr_init_box,
- .disable_event = snb_uncore_msr_disable_event,
- .enable_event = snb_uncore_msr_enable_event,
- .read_counter = uncore_msr_read_counter,
-};
-
-static struct event_constraint snb_uncore_arb_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type snb_uncore_cbox = {
- .name = "cbox",
- .num_counters = 2,
- .num_boxes = 4,
- .perf_ctr_bits = 44,
- .fixed_ctr_bits = 48,
- .perf_ctr = SNB_UNC_CBO_0_PER_CTR0,
- .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
- .fixed_ctr = SNB_UNC_FIXED_CTR,
- .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
- .single_fixed = 1,
- .event_mask = SNB_UNC_RAW_EVENT_MASK,
- .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
- .ops = &snb_uncore_msr_ops,
- .format_group = &snb_uncore_format_group,
- .event_descs = snb_uncore_events,
-};
-
-static struct intel_uncore_type snb_uncore_arb = {
- .name = "arb",
- .num_counters = 2,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .perf_ctr = SNB_UNC_ARB_PER_CTR0,
- .event_ctl = SNB_UNC_ARB_PERFEVTSEL0,
- .event_mask = SNB_UNC_RAW_EVENT_MASK,
- .msr_offset = SNB_UNC_ARB_MSR_OFFSET,
- .constraints = snb_uncore_arb_constraints,
- .ops = &snb_uncore_msr_ops,
- .format_group = &snb_uncore_format_group,
-};
-
-static struct intel_uncore_type *snb_msr_uncores[] = {
- &snb_uncore_cbox,
- &snb_uncore_arb,
- NULL,
-};
-
-void snb_uncore_cpu_init(void)
-{
- uncore_msr_uncores = snb_msr_uncores;
- if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-}
-
-enum {
- SNB_PCI_UNCORE_IMC,
-};
-
-static struct uncore_event_desc snb_uncore_imc_events[] = {
- INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"),
- INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"),
-
- INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"),
- INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"),
-
- { /* end: all zeroes */ },
-};
-
-#define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff
-#define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48
-
-/* page size multiple covering all config regs */
-#define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000
-
-#define SNB_UNCORE_PCI_IMC_DATA_READS 0x1
-#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050
-#define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2
-#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054
-#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE
-
-static struct attribute *snb_uncore_imc_formats_attr[] = {
- &format_attr_event.attr,
- NULL,
-};
-
-static struct attribute_group snb_uncore_imc_format_group = {
- .name = "format",
- .attrs = snb_uncore_imc_formats_attr,
-};
-
-static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
-{
- struct pci_dev *pdev = box->pci_dev;
- int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
- resource_size_t addr;
- u32 pci_dword;
-
- pci_read_config_dword(pdev, where, &pci_dword);
- addr = pci_dword;
-
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
- pci_read_config_dword(pdev, where + 4, &pci_dword);
- addr |= ((resource_size_t)pci_dword << 32);
-#endif
-
- addr &= ~(PAGE_SIZE - 1);
-
- box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE);
- box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
-}
-
-static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
-{}
-
-static void snb_uncore_imc_disable_box(struct intel_uncore_box *box)
-{}
-
-static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{}
-
-static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{}
-
-static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- return (u64)*(unsigned int *)(box->io_addr + hwc->event_base);
-}
-
-/*
- * custom event_init() function because we define our own fixed, free
- * running counters, so we do not want to conflict with generic uncore
- * logic. Also simplifies processing
- */
-static int snb_uncore_imc_event_init(struct perf_event *event)
-{
- struct intel_uncore_pmu *pmu;
- struct intel_uncore_box *box;
- struct hw_perf_event *hwc = &event->hw;
- u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
- int idx, base;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- pmu = uncore_event_to_pmu(event);
- /* no device found for this pmu */
- if (pmu->func_id < 0)
- return -ENOENT;
-
- /* Sampling not supported yet */
- if (hwc->sample_period)
- return -EINVAL;
-
- /* unsupported modes and filters */
- if (event->attr.exclude_user ||
- event->attr.exclude_kernel ||
- event->attr.exclude_hv ||
- event->attr.exclude_idle ||
- event->attr.exclude_host ||
- event->attr.exclude_guest ||
- event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- /*
- * Place all uncore events for a particular physical package
- * onto a single cpu
- */
- if (event->cpu < 0)
- return -EINVAL;
-
- /* check only supported bits are set */
- if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
- return -EINVAL;
-
- box = uncore_pmu_to_box(pmu, event->cpu);
- if (!box || box->cpu < 0)
- return -EINVAL;
-
- event->cpu = box->cpu;
-
- event->hw.idx = -1;
- event->hw.last_tag = ~0ULL;
- event->hw.extra_reg.idx = EXTRA_REG_NONE;
- event->hw.branch_reg.idx = EXTRA_REG_NONE;
- /*
- * check event is known (whitelist, determines counter)
- */
- switch (cfg) {
- case SNB_UNCORE_PCI_IMC_DATA_READS:
- base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE;
- idx = UNCORE_PMC_IDX_FIXED;
- break;
- case SNB_UNCORE_PCI_IMC_DATA_WRITES:
- base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE;
- idx = UNCORE_PMC_IDX_FIXED + 1;
- break;
- default:
- return -EINVAL;
- }
-
- /* must be done before validate_group */
- event->hw.event_base = base;
- event->hw.config = cfg;
- event->hw.idx = idx;
-
- /* no group validation needed, we have free running counters */
-
- return 0;
-}
-
-static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- return 0;
-}
-
-static void snb_uncore_imc_event_start(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- u64 count;
-
- if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
- return;
-
- event->hw.state = 0;
- box->n_active++;
-
- list_add_tail(&event->active_entry, &box->active_list);
-
- count = snb_uncore_imc_read_counter(box, event);
- local64_set(&event->hw.prev_count, count);
-
- if (box->n_active == 1)
- uncore_pmu_start_hrtimer(box);
-}
-
-static void snb_uncore_imc_event_stop(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- struct hw_perf_event *hwc = &event->hw;
-
- if (!(hwc->state & PERF_HES_STOPPED)) {
- box->n_active--;
-
- WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
- hwc->state |= PERF_HES_STOPPED;
-
- list_del(&event->active_entry);
-
- if (box->n_active == 0)
- uncore_pmu_cancel_hrtimer(box);
- }
-
- if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
- /*
- * Drain the remaining delta count out of a event
- * that we are disabling:
- */
- uncore_perf_event_update(box, event);
- hwc->state |= PERF_HES_UPTODATE;
- }
-}
-
-static int snb_uncore_imc_event_add(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- struct hw_perf_event *hwc = &event->hw;
-
- if (!box)
- return -ENODEV;
-
- hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
- if (!(flags & PERF_EF_START))
- hwc->state |= PERF_HES_ARCH;
-
- snb_uncore_imc_event_start(event, 0);
-
- box->n_events++;
-
- return 0;
-}
-
-static void snb_uncore_imc_event_del(struct perf_event *event, int flags)
-{
- struct intel_uncore_box *box = uncore_event_to_box(event);
- int i;
-
- snb_uncore_imc_event_stop(event, PERF_EF_UPDATE);
-
- for (i = 0; i < box->n_events; i++) {
- if (event == box->event_list[i]) {
- --box->n_events;
- break;
- }
- }
-}
-
-static int snb_pci2phy_map_init(int devid)
-{
- struct pci_dev *dev = NULL;
- int bus;
-
- dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev);
- if (!dev)
- return -ENOTTY;
-
- bus = dev->bus->number;
-
- uncore_pcibus_to_physid[bus] = 0;
-
- pci_dev_put(dev);
-
- return 0;
-}
-
-static struct pmu snb_uncore_imc_pmu = {
- .task_ctx_nr = perf_invalid_context,
- .event_init = snb_uncore_imc_event_init,
- .add = snb_uncore_imc_event_add,
- .del = snb_uncore_imc_event_del,
- .start = snb_uncore_imc_event_start,
- .stop = snb_uncore_imc_event_stop,
- .read = uncore_pmu_event_read,
-};
-
-static struct intel_uncore_ops snb_uncore_imc_ops = {
- .init_box = snb_uncore_imc_init_box,
- .enable_box = snb_uncore_imc_enable_box,
- .disable_box = snb_uncore_imc_disable_box,
- .disable_event = snb_uncore_imc_disable_event,
- .enable_event = snb_uncore_imc_enable_event,
- .hw_config = snb_uncore_imc_hw_config,
- .read_counter = snb_uncore_imc_read_counter,
-};
-
-static struct intel_uncore_type snb_uncore_imc = {
- .name = "imc",
- .num_counters = 2,
- .num_boxes = 1,
- .fixed_ctr_bits = 32,
- .fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE,
- .event_descs = snb_uncore_imc_events,
- .format_group = &snb_uncore_imc_format_group,
- .perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE,
- .event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK,
- .ops = &snb_uncore_imc_ops,
- .pmu = &snb_uncore_imc_pmu,
-};
-
-static struct intel_uncore_type *snb_pci_uncores[] = {
- [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc,
- NULL,
-};
-
-static const struct pci_device_id snb_uncore_pci_ids[] = {
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* end: all zeroes */ },
-};
-
-static const struct pci_device_id ivb_uncore_pci_ids[] = {
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_E3_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* end: all zeroes */ },
-};
-
-static const struct pci_device_id hsw_uncore_pci_ids[] = {
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* end: all zeroes */ },
-};
-
-static const struct pci_device_id bdw_uncore_pci_ids[] = {
- { /* IMC */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BDW_IMC),
- .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
- },
- { /* end: all zeroes */ },
-};
-
-static struct pci_driver snb_uncore_pci_driver = {
- .name = "snb_uncore",
- .id_table = snb_uncore_pci_ids,
-};
-
-static struct pci_driver ivb_uncore_pci_driver = {
- .name = "ivb_uncore",
- .id_table = ivb_uncore_pci_ids,
-};
-
-static struct pci_driver hsw_uncore_pci_driver = {
- .name = "hsw_uncore",
- .id_table = hsw_uncore_pci_ids,
-};
-
-static struct pci_driver bdw_uncore_pci_driver = {
- .name = "bdw_uncore",
- .id_table = bdw_uncore_pci_ids,
-};
-
-struct imc_uncore_pci_dev {
- __u32 pci_id;
- struct pci_driver *driver;
-};
-#define IMC_DEV(a, d) \
- { .pci_id = PCI_DEVICE_ID_INTEL_##a, .driver = (d) }
-
-static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
- IMC_DEV(SNB_IMC, &snb_uncore_pci_driver),
- IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */
- IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
- IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */
- IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */
- IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */
- { /* end marker */ }
-};
-
-
-#define for_each_imc_pci_id(x, t) \
- for (x = (t); (x)->pci_id; x++)
-
-static struct pci_driver *imc_uncore_find_dev(void)
-{
- const struct imc_uncore_pci_dev *p;
- int ret;
-
- for_each_imc_pci_id(p, desktop_imc_pci_ids) {
- ret = snb_pci2phy_map_init(p->pci_id);
- if (ret == 0)
- return p->driver;
- }
- return NULL;
-}
-
-static int imc_uncore_pci_init(void)
-{
- struct pci_driver *imc_drv = imc_uncore_find_dev();
-
- if (!imc_drv)
- return -ENODEV;
-
- uncore_pci_uncores = snb_pci_uncores;
- uncore_pci_driver = imc_drv;
-
- return 0;
-}
-
-int snb_uncore_pci_init(void)
-{
- return imc_uncore_pci_init();
-}
-
-int ivb_uncore_pci_init(void)
-{
- return imc_uncore_pci_init();
-}
-int hsw_uncore_pci_init(void)
-{
- return imc_uncore_pci_init();
-}
-
-int bdw_uncore_pci_init(void)
-{
- return imc_uncore_pci_init();
-}
-
-/* end of Sandy Bridge uncore support */
-
-/* Nehalem uncore support */
-static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
- wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
-}
-
-static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
- wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
-}
-
-static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- if (hwc->idx < UNCORE_PMC_IDX_FIXED)
- wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
- else
- wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
-}
-
-static struct attribute *nhm_uncore_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_cmask8.attr,
- NULL,
-};
-
-static struct attribute_group nhm_uncore_format_group = {
- .name = "format",
- .attrs = nhm_uncore_formats_attr,
-};
-
-static struct uncore_event_desc nhm_uncore_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
- INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"),
- INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"),
- INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"),
- { /* end: all zeroes */ },
-};
-
-static struct intel_uncore_ops nhm_uncore_msr_ops = {
- .disable_box = nhm_uncore_msr_disable_box,
- .enable_box = nhm_uncore_msr_enable_box,
- .disable_event = snb_uncore_msr_disable_event,
- .enable_event = nhm_uncore_msr_enable_event,
- .read_counter = uncore_msr_read_counter,
-};
-
-static struct intel_uncore_type nhm_uncore = {
- .name = "",
- .num_counters = 8,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .event_ctl = NHM_UNC_PERFEVTSEL0,
- .perf_ctr = NHM_UNC_UNCORE_PMC0,
- .fixed_ctr = NHM_UNC_FIXED_CTR,
- .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL,
- .event_mask = NHM_UNC_RAW_EVENT_MASK,
- .event_descs = nhm_uncore_events,
- .ops = &nhm_uncore_msr_ops,
- .format_group = &nhm_uncore_format_group,
-};
-
-static struct intel_uncore_type *nhm_msr_uncores[] = {
- &nhm_uncore,
- NULL,
-};
-
-void nhm_uncore_cpu_init(void)
-{
- uncore_msr_uncores = nhm_msr_uncores;
-}
-
-/* end of Nehalem uncore support */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
deleted file mode 100644
index 694510a8..0000000
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
+++ /dev/null
@@ -1,2487 +0,0 @@
-/* SandyBridge-EP/IvyTown uncore support */
-#include "perf_event_intel_uncore.h"
-
-
-/* SNB-EP Box level control */
-#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0)
-#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1)
-#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8)
-#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16)
-#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \
- SNBEP_PMON_BOX_CTL_RST_CTRS | \
- SNBEP_PMON_BOX_CTL_FRZ_EN)
-/* SNB-EP event control */
-#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff
-#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00
-#define SNBEP_PMON_CTL_RST (1 << 17)
-#define SNBEP_PMON_CTL_EDGE_DET (1 << 18)
-#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21)
-#define SNBEP_PMON_CTL_EN (1 << 22)
-#define SNBEP_PMON_CTL_INVERT (1 << 23)
-#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000
-#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PMON_CTL_UMASK_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_PMON_CTL_INVERT | \
- SNBEP_PMON_CTL_TRESH_MASK)
-
-/* SNB-EP Ubox event control */
-#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000
-#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \
- (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PMON_CTL_UMASK_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_PMON_CTL_INVERT | \
- SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
-
-#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19)
-#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
- SNBEP_CBO_PMON_CTL_TID_EN)
-
-/* SNB-EP PCU event control */
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000
-#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30)
-#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31)
-#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
- (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_PMON_CTL_EV_SEL_EXT | \
- SNBEP_PMON_CTL_INVERT | \
- SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
-
-#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \
- (SNBEP_PMON_RAW_EVENT_MASK | \
- SNBEP_PMON_CTL_EV_SEL_EXT)
-
-/* SNB-EP pci control register */
-#define SNBEP_PCI_PMON_BOX_CTL 0xf4
-#define SNBEP_PCI_PMON_CTL0 0xd8
-/* SNB-EP pci counter register */
-#define SNBEP_PCI_PMON_CTR0 0xa0
-
-/* SNB-EP home agent register */
-#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40
-#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44
-#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48
-/* SNB-EP memory controller register */
-#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0
-#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0
-/* SNB-EP QPI register */
-#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228
-#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c
-#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238
-#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c
-
-/* SNB-EP Ubox register */
-#define SNBEP_U_MSR_PMON_CTR0 0xc16
-#define SNBEP_U_MSR_PMON_CTL0 0xc10
-
-#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08
-#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09
-
-/* SNB-EP Cbo register */
-#define SNBEP_C0_MSR_PMON_CTR0 0xd16
-#define SNBEP_C0_MSR_PMON_CTL0 0xd10
-#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04
-#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14
-#define SNBEP_CBO_MSR_OFFSET 0x20
-
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID 0x1f
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID 0x3fc00
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE 0x7c0000
-#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC 0xff800000
-
-#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) { \
- .event = (e), \
- .msr = SNBEP_C0_MSR_PMON_BOX_FILTER, \
- .config_mask = (m), \
- .idx = (i) \
-}
-
-/* SNB-EP PCU register */
-#define SNBEP_PCU_MSR_PMON_CTR0 0xc36
-#define SNBEP_PCU_MSR_PMON_CTL0 0xc30
-#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24
-#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34
-#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff
-#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc
-#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd
-
-/* IVBEP event control */
-#define IVBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \
- SNBEP_PMON_BOX_CTL_RST_CTRS)
-#define IVBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PMON_CTL_UMASK_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_PMON_CTL_TRESH_MASK)
-/* IVBEP Ubox */
-#define IVBEP_U_MSR_PMON_GLOBAL_CTL 0xc00
-#define IVBEP_U_PMON_GLOBAL_FRZ_ALL (1 << 31)
-#define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29)
-
-#define IVBEP_U_MSR_PMON_RAW_EVENT_MASK \
- (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PMON_CTL_UMASK_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
-/* IVBEP Cbo */
-#define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK (IVBEP_PMON_RAW_EVENT_MASK | \
- SNBEP_CBO_PMON_CTL_TID_EN)
-
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62)
-#define IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC (0x1ULL << 63)
-
-/* IVBEP home agent */
-#define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16)
-#define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK \
- (IVBEP_PMON_RAW_EVENT_MASK | \
- IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST)
-/* IVBEP PCU */
-#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
- (SNBEP_PMON_CTL_EV_SEL_MASK | \
- SNBEP_PMON_CTL_EV_SEL_EXT | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
- SNBEP_PMON_CTL_EDGE_DET | \
- SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
- SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
-/* IVBEP QPI */
-#define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK \
- (IVBEP_PMON_RAW_EVENT_MASK | \
- SNBEP_PMON_CTL_EV_SEL_EXT)
-
-#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
- ((1ULL << (n)) - 1)))
-
-/* Haswell-EP Ubox */
-#define HSWEP_U_MSR_PMON_CTR0 0x709
-#define HSWEP_U_MSR_PMON_CTL0 0x705
-#define HSWEP_U_MSR_PMON_FILTER 0x707
-
-#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL 0x703
-#define HSWEP_U_MSR_PMON_UCLK_FIXED_CTR 0x704
-
-#define HSWEP_U_MSR_PMON_BOX_FILTER_TID (0x1 << 0)
-#define HSWEP_U_MSR_PMON_BOX_FILTER_CID (0x1fULL << 1)
-#define HSWEP_U_MSR_PMON_BOX_FILTER_MASK \
- (HSWEP_U_MSR_PMON_BOX_FILTER_TID | \
- HSWEP_U_MSR_PMON_BOX_FILTER_CID)
-
-/* Haswell-EP CBo */
-#define HSWEP_C0_MSR_PMON_CTR0 0xe08
-#define HSWEP_C0_MSR_PMON_CTL0 0xe01
-#define HSWEP_C0_MSR_PMON_BOX_CTL 0xe00
-#define HSWEP_C0_MSR_PMON_BOX_FILTER0 0xe05
-#define HSWEP_CBO_MSR_OFFSET 0x10
-
-
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_TID (0x3fULL << 0)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 6)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE (0x7fULL << 17)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62)
-#define HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC (0x1ULL << 63)
-
-
-/* Haswell-EP Sbox */
-#define HSWEP_S0_MSR_PMON_CTR0 0x726
-#define HSWEP_S0_MSR_PMON_CTL0 0x721
-#define HSWEP_S0_MSR_PMON_BOX_CTL 0x720
-#define HSWEP_SBOX_MSR_OFFSET 0xa
-#define HSWEP_S_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
- SNBEP_CBO_PMON_CTL_TID_EN)
-
-/* Haswell-EP PCU */
-#define HSWEP_PCU_MSR_PMON_CTR0 0x717
-#define HSWEP_PCU_MSR_PMON_CTL0 0x711
-#define HSWEP_PCU_MSR_PMON_BOX_CTL 0x710
-#define HSWEP_PCU_MSR_PMON_BOX_FILTER 0x715
-
-
-DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
-DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
-DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
-DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
-DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
-DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
-DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
-DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
-DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
-DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
-DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
-DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
-DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
-DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
-DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
-DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
-DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
-DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
-DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
-DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
-DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
-DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
-DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
-DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
-DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
-DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
-DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
-DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
-DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
-DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
-DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
-DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
-
-static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
-{
- struct pci_dev *pdev = box->pci_dev;
- int box_ctl = uncore_pci_box_ctl(box);
- u32 config = 0;
-
- if (!pci_read_config_dword(pdev, box_ctl, &config)) {
- config |= SNBEP_PMON_BOX_CTL_FRZ;
- pci_write_config_dword(pdev, box_ctl, config);
- }
-}
-
-static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
-{
- struct pci_dev *pdev = box->pci_dev;
- int box_ctl = uncore_pci_box_ctl(box);
- u32 config = 0;
-
- if (!pci_read_config_dword(pdev, box_ctl, &config)) {
- config &= ~SNBEP_PMON_BOX_CTL_FRZ;
- pci_write_config_dword(pdev, box_ctl, config);
- }
-}
-
-static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
-
- pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
-
- pci_write_config_dword(pdev, hwc->config_base, hwc->config);
-}
-
-static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
- u64 count = 0;
-
- pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
- pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
-
- return count;
-}
-
-static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
-{
- struct pci_dev *pdev = box->pci_dev;
-
- pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT);
-}
-
-static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
-{
- u64 config;
- unsigned msr;
-
- msr = uncore_msr_box_ctl(box);
- if (msr) {
- rdmsrl(msr, config);
- config |= SNBEP_PMON_BOX_CTL_FRZ;
- wrmsrl(msr, config);
- }
-}
-
-static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
-{
- u64 config;
- unsigned msr;
-
- msr = uncore_msr_box_ctl(box);
- if (msr) {
- rdmsrl(msr, config);
- config &= ~SNBEP_PMON_BOX_CTL_FRZ;
- wrmsrl(msr, config);
- }
-}
-
-static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
- if (reg1->idx != EXTRA_REG_NONE)
- wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
-
- wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- wrmsrl(hwc->config_base, hwc->config);
-}
-
-static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
-{
- unsigned msr = uncore_msr_box_ctl(box);
-
- if (msr)
- wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
-}
-
-static struct attribute *snbep_uncore_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- NULL,
-};
-
-static struct attribute *snbep_uncore_ubox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh5.attr,
- NULL,
-};
-
-static struct attribute *snbep_uncore_cbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_tid_en.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- &format_attr_filter_tid.attr,
- &format_attr_filter_nid.attr,
- &format_attr_filter_state.attr,
- &format_attr_filter_opc.attr,
- NULL,
-};
-
-static struct attribute *snbep_uncore_pcu_formats_attr[] = {
- &format_attr_event_ext.attr,
- &format_attr_occ_sel.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh5.attr,
- &format_attr_occ_invert.attr,
- &format_attr_occ_edge.attr,
- &format_attr_filter_band0.attr,
- &format_attr_filter_band1.attr,
- &format_attr_filter_band2.attr,
- &format_attr_filter_band3.attr,
- NULL,
-};
-
-static struct attribute *snbep_uncore_qpi_formats_attr[] = {
- &format_attr_event_ext.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- &format_attr_match_rds.attr,
- &format_attr_match_rnid30.attr,
- &format_attr_match_rnid4.attr,
- &format_attr_match_dnid.attr,
- &format_attr_match_mc.attr,
- &format_attr_match_opc.attr,
- &format_attr_match_vnw.attr,
- &format_attr_match0.attr,
- &format_attr_match1.attr,
- &format_attr_mask_rds.attr,
- &format_attr_mask_rnid30.attr,
- &format_attr_mask_rnid4.attr,
- &format_attr_mask_dnid.attr,
- &format_attr_mask_mc.attr,
- &format_attr_mask_opc.attr,
- &format_attr_mask_vnw.attr,
- &format_attr_mask0.attr,
- &format_attr_mask1.attr,
- NULL,
-};
-
-static struct uncore_event_desc snbep_uncore_imc_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
- { /* end: all zeroes */ },
-};
-
-static struct uncore_event_desc snbep_uncore_qpi_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"),
- INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
- INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"),
- INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"),
- { /* end: all zeroes */ },
-};
-
-static struct attribute_group snbep_uncore_format_group = {
- .name = "format",
- .attrs = snbep_uncore_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_ubox_format_group = {
- .name = "format",
- .attrs = snbep_uncore_ubox_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_cbox_format_group = {
- .name = "format",
- .attrs = snbep_uncore_cbox_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_pcu_format_group = {
- .name = "format",
- .attrs = snbep_uncore_pcu_formats_attr,
-};
-
-static struct attribute_group snbep_uncore_qpi_format_group = {
- .name = "format",
- .attrs = snbep_uncore_qpi_formats_attr,
-};
-
-#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
- .disable_box = snbep_uncore_msr_disable_box, \
- .enable_box = snbep_uncore_msr_enable_box, \
- .disable_event = snbep_uncore_msr_disable_event, \
- .enable_event = snbep_uncore_msr_enable_event, \
- .read_counter = uncore_msr_read_counter
-
-#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
- __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \
- .init_box = snbep_uncore_msr_init_box \
-
-static struct intel_uncore_ops snbep_uncore_msr_ops = {
- SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-};
-
-#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \
- .init_box = snbep_uncore_pci_init_box, \
- .disable_box = snbep_uncore_pci_disable_box, \
- .enable_box = snbep_uncore_pci_enable_box, \
- .disable_event = snbep_uncore_pci_disable_event, \
- .read_counter = snbep_uncore_pci_read_counter
-
-static struct intel_uncore_ops snbep_uncore_pci_ops = {
- SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
- .enable_event = snbep_uncore_pci_enable_event, \
-};
-
-static struct event_constraint snbep_uncore_cbox_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
- EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type snbep_uncore_ubox = {
- .name = "ubox",
- .num_counters = 2,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .fixed_ctr_bits = 48,
- .perf_ctr = SNBEP_U_MSR_PMON_CTR0,
- .event_ctl = SNBEP_U_MSR_PMON_CTL0,
- .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
- .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
- .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
- .ops = &snbep_uncore_msr_ops,
- .format_group = &snbep_uncore_ubox_format_group,
-};
-
-static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
- SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
- SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
- EVENT_EXTRA_END
-};
-
-static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct intel_uncore_extra_reg *er = &box->shared_regs[0];
- int i;
-
- if (uncore_box_is_fake(box))
- return;
-
- for (i = 0; i < 5; i++) {
- if (reg1->alloc & (0x1 << i))
- atomic_sub(1 << (i * 6), &er->ref);
- }
- reg1->alloc = 0;
-}
-
-static struct event_constraint *
-__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
- u64 (*cbox_filter_mask)(int fields))
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct intel_uncore_extra_reg *er = &box->shared_regs[0];
- int i, alloc = 0;
- unsigned long flags;
- u64 mask;
-
- if (reg1->idx == EXTRA_REG_NONE)
- return NULL;
-
- raw_spin_lock_irqsave(&er->lock, flags);
- for (i = 0; i < 5; i++) {
- if (!(reg1->idx & (0x1 << i)))
- continue;
- if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
- continue;
-
- mask = cbox_filter_mask(0x1 << i);
- if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
- !((reg1->config ^ er->config) & mask)) {
- atomic_add(1 << (i * 6), &er->ref);
- er->config &= ~mask;
- er->config |= reg1->config & mask;
- alloc |= (0x1 << i);
- } else {
- break;
- }
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
- if (i < 5)
- goto fail;
-
- if (!uncore_box_is_fake(box))
- reg1->alloc |= alloc;
-
- return NULL;
-fail:
- for (; i >= 0; i--) {
- if (alloc & (0x1 << i))
- atomic_sub(1 << (i * 6), &er->ref);
- }
- return &uncore_constraint_empty;
-}
-
-static u64 snbep_cbox_filter_mask(int fields)
-{
- u64 mask = 0;
-
- if (fields & 0x1)
- mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
- if (fields & 0x2)
- mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
- if (fields & 0x4)
- mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
- if (fields & 0x8)
- mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
-
- return mask;
-}
-
-static struct event_constraint *
-snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
-}
-
-static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct extra_reg *er;
- int idx = 0;
-
- for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
- if (er->event != (event->hw.config & er->config_mask))
- continue;
- idx |= er->idx;
- }
-
- if (idx) {
- reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
- SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
- reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
- reg1->idx = idx;
- }
- return 0;
-}
-
-static struct intel_uncore_ops snbep_uncore_cbox_ops = {
- SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .hw_config = snbep_cbox_hw_config,
- .get_constraint = snbep_cbox_get_constraint,
- .put_constraint = snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type snbep_uncore_cbox = {
- .name = "cbox",
- .num_counters = 4,
- .num_boxes = 8,
- .perf_ctr_bits = 44,
- .event_ctl = SNBEP_C0_MSR_PMON_CTL0,
- .perf_ctr = SNBEP_C0_MSR_PMON_CTR0,
- .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL,
- .msr_offset = SNBEP_CBO_MSR_OFFSET,
- .num_shared_regs = 1,
- .constraints = snbep_uncore_cbox_constraints,
- .ops = &snbep_uncore_cbox_ops,
- .format_group = &snbep_uncore_cbox_format_group,
-};
-
-static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- u64 config = reg1->config;
-
- if (new_idx > reg1->idx)
- config <<= 8 * (new_idx - reg1->idx);
- else
- config >>= 8 * (reg1->idx - new_idx);
-
- if (modify) {
- hwc->config += new_idx - reg1->idx;
- reg1->config = config;
- reg1->idx = new_idx;
- }
- return config;
-}
-
-static struct event_constraint *
-snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct intel_uncore_extra_reg *er = &box->shared_regs[0];
- unsigned long flags;
- int idx = reg1->idx;
- u64 mask, config1 = reg1->config;
- bool ok = false;
-
- if (reg1->idx == EXTRA_REG_NONE ||
- (!uncore_box_is_fake(box) && reg1->alloc))
- return NULL;
-again:
- mask = 0xffULL << (idx * 8);
- raw_spin_lock_irqsave(&er->lock, flags);
- if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
- !((config1 ^ er->config) & mask)) {
- atomic_add(1 << (idx * 8), &er->ref);
- er->config &= ~mask;
- er->config |= config1 & mask;
- ok = true;
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- if (!ok) {
- idx = (idx + 1) % 4;
- if (idx != reg1->idx) {
- config1 = snbep_pcu_alter_er(event, idx, false);
- goto again;
- }
- return &uncore_constraint_empty;
- }
-
- if (!uncore_box_is_fake(box)) {
- if (idx != reg1->idx)
- snbep_pcu_alter_er(event, idx, true);
- reg1->alloc = 1;
- }
- return NULL;
-}
-
-static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct intel_uncore_extra_reg *er = &box->shared_regs[0];
-
- if (uncore_box_is_fake(box) || !reg1->alloc)
- return;
-
- atomic_sub(1 << (reg1->idx * 8), &er->ref);
- reg1->alloc = 0;
-}
-
-static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
-
- if (ev_sel >= 0xb && ev_sel <= 0xe) {
- reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
- reg1->idx = ev_sel - 0xb;
- reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
- }
- return 0;
-}
-
-static struct intel_uncore_ops snbep_uncore_pcu_ops = {
- SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .hw_config = snbep_pcu_hw_config,
- .get_constraint = snbep_pcu_get_constraint,
- .put_constraint = snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type snbep_uncore_pcu = {
- .name = "pcu",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0,
- .event_ctl = SNBEP_PCU_MSR_PMON_CTL0,
- .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &snbep_uncore_pcu_ops,
- .format_group = &snbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *snbep_msr_uncores[] = {
- &snbep_uncore_ubox,
- &snbep_uncore_cbox,
- &snbep_uncore_pcu,
- NULL,
-};
-
-void snbep_uncore_cpu_init(void)
-{
- if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
- uncore_msr_uncores = snbep_msr_uncores;
-}
-
-enum {
- SNBEP_PCI_QPI_PORT0_FILTER,
- SNBEP_PCI_QPI_PORT1_FILTER,
- HSWEP_PCI_PCU_3,
-};
-
-static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
- if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
- reg1->idx = 0;
- reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
- reg1->config = event->attr.config1;
- reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
- reg2->config = event->attr.config2;
- }
- return 0;
-}
-
-static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
-
- if (reg1->idx != EXTRA_REG_NONE) {
- int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
- struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx];
- if (filter_pdev) {
- pci_write_config_dword(filter_pdev, reg1->reg,
- (u32)reg1->config);
- pci_write_config_dword(filter_pdev, reg1->reg + 4,
- (u32)(reg1->config >> 32));
- pci_write_config_dword(filter_pdev, reg2->reg,
- (u32)reg2->config);
- pci_write_config_dword(filter_pdev, reg2->reg + 4,
- (u32)(reg2->config >> 32));
- }
- }
-
- pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops snbep_uncore_qpi_ops = {
- SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
- .enable_event = snbep_qpi_enable_event,
- .hw_config = snbep_qpi_hw_config,
- .get_constraint = uncore_get_constraint,
- .put_constraint = uncore_put_constraint,
-};
-
-#define SNBEP_UNCORE_PCI_COMMON_INIT() \
- .perf_ctr = SNBEP_PCI_PMON_CTR0, \
- .event_ctl = SNBEP_PCI_PMON_CTL0, \
- .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \
- .ops = &snbep_uncore_pci_ops, \
- .format_group = &snbep_uncore_format_group
-
-static struct intel_uncore_type snbep_uncore_ha = {
- .name = "ha",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_imc = {
- .name = "imc",
- .num_counters = 4,
- .num_boxes = 4,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
- .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
- .event_descs = snbep_uncore_imc_events,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_qpi = {
- .name = "qpi",
- .num_counters = 4,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .perf_ctr = SNBEP_PCI_PMON_CTR0,
- .event_ctl = SNBEP_PCI_PMON_CTL0,
- .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &snbep_uncore_qpi_ops,
- .event_descs = snbep_uncore_qpi_events,
- .format_group = &snbep_uncore_qpi_format_group,
-};
-
-
-static struct intel_uncore_type snbep_uncore_r2pcie = {
- .name = "r2pcie",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .constraints = snbep_uncore_r2pcie_constraints,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type snbep_uncore_r3qpi = {
- .name = "r3qpi",
- .num_counters = 3,
- .num_boxes = 2,
- .perf_ctr_bits = 44,
- .constraints = snbep_uncore_r3qpi_constraints,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
- SNBEP_PCI_UNCORE_HA,
- SNBEP_PCI_UNCORE_IMC,
- SNBEP_PCI_UNCORE_QPI,
- SNBEP_PCI_UNCORE_R2PCIE,
- SNBEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *snbep_pci_uncores[] = {
- [SNBEP_PCI_UNCORE_HA] = &snbep_uncore_ha,
- [SNBEP_PCI_UNCORE_IMC] = &snbep_uncore_imc,
- [SNBEP_PCI_UNCORE_QPI] = &snbep_uncore_qpi,
- [SNBEP_PCI_UNCORE_R2PCIE] = &snbep_uncore_r2pcie,
- [SNBEP_PCI_UNCORE_R3QPI] = &snbep_uncore_r3qpi,
- NULL,
-};
-
-static const struct pci_device_id snbep_uncore_pci_ids[] = {
- { /* Home Agent */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
- },
- { /* MC Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
- },
- { /* MC Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
- },
- { /* MC Channel 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
- },
- { /* MC Channel 3 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
- },
- { /* QPI Port 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
- },
- { /* QPI Port 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
- },
- { /* R2PCIe */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
- },
- { /* R3QPI Link 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
- },
- { /* R3QPI Link 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
- .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
- },
- { /* QPI Port 0 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT0_FILTER),
- },
- { /* QPI Port 0 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT1_FILTER),
- },
- { /* end: all zeroes */ }
-};
-
-static struct pci_driver snbep_uncore_pci_driver = {
- .name = "snbep_uncore",
- .id_table = snbep_uncore_pci_ids,
-};
-
-/*
- * build pci bus to socket mapping
- */
-static int snbep_pci2phy_map_init(int devid)
-{
- struct pci_dev *ubox_dev = NULL;
- int i, bus, nodeid;
- int err = 0;
- u32 config = 0;
-
- while (1) {
- /* find the UBOX device */
- ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
- if (!ubox_dev)
- break;
- bus = ubox_dev->bus->number;
- /* get the Node ID of the local register */
- err = pci_read_config_dword(ubox_dev, 0x40, &config);
- if (err)
- break;
- nodeid = config;
- /* get the Node ID mapping */
- err = pci_read_config_dword(ubox_dev, 0x54, &config);
- if (err)
- break;
- /*
- * every three bits in the Node ID mapping register maps
- * to a particular node.
- */
- for (i = 0; i < 8; i++) {
- if (nodeid == ((config >> (3 * i)) & 0x7)) {
- uncore_pcibus_to_physid[bus] = i;
- break;
- }
- }
- }
-
- if (!err) {
- /*
- * For PCI bus with no UBOX device, find the next bus
- * that has UBOX device and use its mapping.
- */
- i = -1;
- for (bus = 255; bus >= 0; bus--) {
- if (uncore_pcibus_to_physid[bus] >= 0)
- i = uncore_pcibus_to_physid[bus];
- else
- uncore_pcibus_to_physid[bus] = i;
- }
- }
-
- pci_dev_put(ubox_dev);
-
- return err ? pcibios_err_to_errno(err) : 0;
-}
-
-int snbep_uncore_pci_init(void)
-{
- int ret = snbep_pci2phy_map_init(0x3ce0);
- if (ret)
- return ret;
- uncore_pci_uncores = snbep_pci_uncores;
- uncore_pci_driver = &snbep_uncore_pci_driver;
- return 0;
-}
-/* end of Sandy Bridge-EP uncore support */
-
-/* IvyTown uncore support */
-static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
-{
- unsigned msr = uncore_msr_box_ctl(box);
- if (msr)
- wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
-}
-
-static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
-{
- struct pci_dev *pdev = box->pci_dev;
-
- pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
-}
-
-#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT() \
- .init_box = ivbep_uncore_msr_init_box, \
- .disable_box = snbep_uncore_msr_disable_box, \
- .enable_box = snbep_uncore_msr_enable_box, \
- .disable_event = snbep_uncore_msr_disable_event, \
- .enable_event = snbep_uncore_msr_enable_event, \
- .read_counter = uncore_msr_read_counter
-
-static struct intel_uncore_ops ivbep_uncore_msr_ops = {
- IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
-};
-
-static struct intel_uncore_ops ivbep_uncore_pci_ops = {
- .init_box = ivbep_uncore_pci_init_box,
- .disable_box = snbep_uncore_pci_disable_box,
- .enable_box = snbep_uncore_pci_enable_box,
- .disable_event = snbep_uncore_pci_disable_event,
- .enable_event = snbep_uncore_pci_enable_event,
- .read_counter = snbep_uncore_pci_read_counter,
-};
-
-#define IVBEP_UNCORE_PCI_COMMON_INIT() \
- .perf_ctr = SNBEP_PCI_PMON_CTR0, \
- .event_ctl = SNBEP_PCI_PMON_CTL0, \
- .event_mask = IVBEP_PMON_RAW_EVENT_MASK, \
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \
- .ops = &ivbep_uncore_pci_ops, \
- .format_group = &ivbep_uncore_format_group
-
-static struct attribute *ivbep_uncore_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- NULL,
-};
-
-static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh5.attr,
- NULL,
-};
-
-static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_tid_en.attr,
- &format_attr_thresh8.attr,
- &format_attr_filter_tid.attr,
- &format_attr_filter_link.attr,
- &format_attr_filter_state2.attr,
- &format_attr_filter_nid2.attr,
- &format_attr_filter_opc2.attr,
- &format_attr_filter_nc.attr,
- &format_attr_filter_c6.attr,
- &format_attr_filter_isoc.attr,
- NULL,
-};
-
-static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
- &format_attr_event_ext.attr,
- &format_attr_occ_sel.attr,
- &format_attr_edge.attr,
- &format_attr_thresh5.attr,
- &format_attr_occ_invert.attr,
- &format_attr_occ_edge.attr,
- &format_attr_filter_band0.attr,
- &format_attr_filter_band1.attr,
- &format_attr_filter_band2.attr,
- &format_attr_filter_band3.attr,
- NULL,
-};
-
-static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
- &format_attr_event_ext.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_thresh8.attr,
- &format_attr_match_rds.attr,
- &format_attr_match_rnid30.attr,
- &format_attr_match_rnid4.attr,
- &format_attr_match_dnid.attr,
- &format_attr_match_mc.attr,
- &format_attr_match_opc.attr,
- &format_attr_match_vnw.attr,
- &format_attr_match0.attr,
- &format_attr_match1.attr,
- &format_attr_mask_rds.attr,
- &format_attr_mask_rnid30.attr,
- &format_attr_mask_rnid4.attr,
- &format_attr_mask_dnid.attr,
- &format_attr_mask_mc.attr,
- &format_attr_mask_opc.attr,
- &format_attr_mask_vnw.attr,
- &format_attr_mask0.attr,
- &format_attr_mask1.attr,
- NULL,
-};
-
-static struct attribute_group ivbep_uncore_format_group = {
- .name = "format",
- .attrs = ivbep_uncore_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_ubox_format_group = {
- .name = "format",
- .attrs = ivbep_uncore_ubox_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_cbox_format_group = {
- .name = "format",
- .attrs = ivbep_uncore_cbox_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_pcu_format_group = {
- .name = "format",
- .attrs = ivbep_uncore_pcu_formats_attr,
-};
-
-static struct attribute_group ivbep_uncore_qpi_format_group = {
- .name = "format",
- .attrs = ivbep_uncore_qpi_formats_attr,
-};
-
-static struct intel_uncore_type ivbep_uncore_ubox = {
- .name = "ubox",
- .num_counters = 2,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .fixed_ctr_bits = 48,
- .perf_ctr = SNBEP_U_MSR_PMON_CTR0,
- .event_ctl = SNBEP_U_MSR_PMON_CTL0,
- .event_mask = IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
- .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
- .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
- .ops = &ivbep_uncore_msr_ops,
- .format_group = &ivbep_uncore_ubox_format_group,
-};
-
-static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
- SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
- SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
- SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
- SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
- EVENT_EXTRA_END
-};
-
-static u64 ivbep_cbox_filter_mask(int fields)
-{
- u64 mask = 0;
-
- if (fields & 0x1)
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
- if (fields & 0x2)
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
- if (fields & 0x4)
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
- if (fields & 0x8)
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
- if (fields & 0x10) {
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
- mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
- }
-
- return mask;
-}
-
-static struct event_constraint *
-ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
-}
-
-static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct extra_reg *er;
- int idx = 0;
-
- for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
- if (er->event != (event->hw.config & er->config_mask))
- continue;
- idx |= er->idx;
- }
-
- if (idx) {
- reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
- SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
- reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
- reg1->idx = idx;
- }
- return 0;
-}
-
-static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
- if (reg1->idx != EXTRA_REG_NONE) {
- u64 filter = uncore_shared_reg_config(box, 0);
- wrmsrl(reg1->reg, filter & 0xffffffff);
- wrmsrl(reg1->reg + 6, filter >> 32);
- }
-
- wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
- .init_box = ivbep_uncore_msr_init_box,
- .disable_box = snbep_uncore_msr_disable_box,
- .enable_box = snbep_uncore_msr_enable_box,
- .disable_event = snbep_uncore_msr_disable_event,
- .enable_event = ivbep_cbox_enable_event,
- .read_counter = uncore_msr_read_counter,
- .hw_config = ivbep_cbox_hw_config,
- .get_constraint = ivbep_cbox_get_constraint,
- .put_constraint = snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_cbox = {
- .name = "cbox",
- .num_counters = 4,
- .num_boxes = 15,
- .perf_ctr_bits = 44,
- .event_ctl = SNBEP_C0_MSR_PMON_CTL0,
- .perf_ctr = SNBEP_C0_MSR_PMON_CTR0,
- .event_mask = IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL,
- .msr_offset = SNBEP_CBO_MSR_OFFSET,
- .num_shared_regs = 1,
- .constraints = snbep_uncore_cbox_constraints,
- .ops = &ivbep_uncore_cbox_ops,
- .format_group = &ivbep_uncore_cbox_format_group,
-};
-
-static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
- IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .hw_config = snbep_pcu_hw_config,
- .get_constraint = snbep_pcu_get_constraint,
- .put_constraint = snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_pcu = {
- .name = "pcu",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0,
- .event_ctl = SNBEP_PCU_MSR_PMON_CTL0,
- .event_mask = IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &ivbep_uncore_pcu_ops,
- .format_group = &ivbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *ivbep_msr_uncores[] = {
- &ivbep_uncore_ubox,
- &ivbep_uncore_cbox,
- &ivbep_uncore_pcu,
- NULL,
-};
-
-void ivbep_uncore_cpu_init(void)
-{
- if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
- uncore_msr_uncores = ivbep_msr_uncores;
-}
-
-static struct intel_uncore_type ivbep_uncore_ha = {
- .name = "ha",
- .num_counters = 4,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type ivbep_uncore_imc = {
- .name = "imc",
- .num_counters = 4,
- .num_boxes = 8,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
- .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
- .event_descs = snbep_uncore_imc_events,
- IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-/* registers in IRP boxes are not properly aligned */
-static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
-static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
-
-static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
-
- pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
- hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
-
- pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
-}
-
-static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
- u64 count = 0;
-
- pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
- pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
-
- return count;
-}
-
-static struct intel_uncore_ops ivbep_uncore_irp_ops = {
- .init_box = ivbep_uncore_pci_init_box,
- .disable_box = snbep_uncore_pci_disable_box,
- .enable_box = snbep_uncore_pci_enable_box,
- .disable_event = ivbep_uncore_irp_disable_event,
- .enable_event = ivbep_uncore_irp_enable_event,
- .read_counter = ivbep_uncore_irp_read_counter,
-};
-
-static struct intel_uncore_type ivbep_uncore_irp = {
- .name = "irp",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .event_mask = IVBEP_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .ops = &ivbep_uncore_irp_ops,
- .format_group = &ivbep_uncore_format_group,
-};
-
-static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
- .init_box = ivbep_uncore_pci_init_box,
- .disable_box = snbep_uncore_pci_disable_box,
- .enable_box = snbep_uncore_pci_enable_box,
- .disable_event = snbep_uncore_pci_disable_event,
- .enable_event = snbep_qpi_enable_event,
- .read_counter = snbep_uncore_pci_read_counter,
- .hw_config = snbep_qpi_hw_config,
- .get_constraint = uncore_get_constraint,
- .put_constraint = uncore_put_constraint,
-};
-
-static struct intel_uncore_type ivbep_uncore_qpi = {
- .name = "qpi",
- .num_counters = 4,
- .num_boxes = 3,
- .perf_ctr_bits = 48,
- .perf_ctr = SNBEP_PCI_PMON_CTR0,
- .event_ctl = SNBEP_PCI_PMON_CTL0,
- .event_mask = IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &ivbep_uncore_qpi_ops,
- .format_group = &ivbep_uncore_qpi_format_group,
-};
-
-static struct intel_uncore_type ivbep_uncore_r2pcie = {
- .name = "r2pcie",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .constraints = snbep_uncore_r2pcie_constraints,
- IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type ivbep_uncore_r3qpi = {
- .name = "r3qpi",
- .num_counters = 3,
- .num_boxes = 2,
- .perf_ctr_bits = 44,
- .constraints = snbep_uncore_r3qpi_constraints,
- IVBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
- IVBEP_PCI_UNCORE_HA,
- IVBEP_PCI_UNCORE_IMC,
- IVBEP_PCI_UNCORE_IRP,
- IVBEP_PCI_UNCORE_QPI,
- IVBEP_PCI_UNCORE_R2PCIE,
- IVBEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *ivbep_pci_uncores[] = {
- [IVBEP_PCI_UNCORE_HA] = &ivbep_uncore_ha,
- [IVBEP_PCI_UNCORE_IMC] = &ivbep_uncore_imc,
- [IVBEP_PCI_UNCORE_IRP] = &ivbep_uncore_irp,
- [IVBEP_PCI_UNCORE_QPI] = &ivbep_uncore_qpi,
- [IVBEP_PCI_UNCORE_R2PCIE] = &ivbep_uncore_r2pcie,
- [IVBEP_PCI_UNCORE_R3QPI] = &ivbep_uncore_r3qpi,
- NULL,
-};
-
-static const struct pci_device_id ivbep_uncore_pci_ids[] = {
- { /* Home Agent 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
- },
- { /* Home Agent 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
- },
- { /* MC0 Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
- },
- { /* MC0 Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
- },
- { /* MC0 Channel 3 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
- },
- { /* MC0 Channel 4 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
- },
- { /* MC1 Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
- },
- { /* MC1 Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
- },
- { /* MC1 Channel 3 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
- },
- { /* MC1 Channel 4 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
- },
- { /* IRP */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
- },
- { /* QPI0 Port 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
- },
- { /* QPI0 Port 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
- },
- { /* QPI1 Port 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
- },
- { /* R2PCIe */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
- },
- { /* R3QPI0 Link 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
- },
- { /* R3QPI0 Link 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
- },
- { /* R3QPI1 Link 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
- .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
- },
- { /* QPI Port 0 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT0_FILTER),
- },
- { /* QPI Port 0 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT1_FILTER),
- },
- { /* end: all zeroes */ }
-};
-
-static struct pci_driver ivbep_uncore_pci_driver = {
- .name = "ivbep_uncore",
- .id_table = ivbep_uncore_pci_ids,
-};
-
-int ivbep_uncore_pci_init(void)
-{
- int ret = snbep_pci2phy_map_init(0x0e1e);
- if (ret)
- return ret;
- uncore_pci_uncores = ivbep_pci_uncores;
- uncore_pci_driver = &ivbep_uncore_pci_driver;
- return 0;
-}
-/* end of IvyTown uncore support */
-
-/* Haswell-EP uncore support */
-static struct attribute *hswep_uncore_ubox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_thresh5.attr,
- &format_attr_filter_tid2.attr,
- &format_attr_filter_cid.attr,
- NULL,
-};
-
-static struct attribute_group hswep_uncore_ubox_format_group = {
- .name = "format",
- .attrs = hswep_uncore_ubox_formats_attr,
-};
-
-static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- reg1->reg = HSWEP_U_MSR_PMON_FILTER;
- reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
- reg1->idx = 0;
- return 0;
-}
-
-static struct intel_uncore_ops hswep_uncore_ubox_ops = {
- SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .hw_config = hswep_ubox_hw_config,
- .get_constraint = uncore_get_constraint,
- .put_constraint = uncore_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_ubox = {
- .name = "ubox",
- .num_counters = 2,
- .num_boxes = 1,
- .perf_ctr_bits = 44,
- .fixed_ctr_bits = 48,
- .perf_ctr = HSWEP_U_MSR_PMON_CTR0,
- .event_ctl = HSWEP_U_MSR_PMON_CTL0,
- .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
- .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
- .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
- .num_shared_regs = 1,
- .ops = &hswep_uncore_ubox_ops,
- .format_group = &hswep_uncore_ubox_format_group,
-};
-
-static struct attribute *hswep_uncore_cbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_tid_en.attr,
- &format_attr_thresh8.attr,
- &format_attr_filter_tid3.attr,
- &format_attr_filter_link2.attr,
- &format_attr_filter_state3.attr,
- &format_attr_filter_nid2.attr,
- &format_attr_filter_opc2.attr,
- &format_attr_filter_nc.attr,
- &format_attr_filter_c6.attr,
- &format_attr_filter_isoc.attr,
- NULL,
-};
-
-static struct attribute_group hswep_uncore_cbox_format_group = {
- .name = "format",
- .attrs = hswep_uncore_cbox_formats_attr,
-};
-
-static struct event_constraint hswep_uncore_cbox_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
- EVENT_CONSTRAINT_END
-};
-
-static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
- SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
- SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
- SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
- SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
- EVENT_EXTRA_END
-};
-
-static u64 hswep_cbox_filter_mask(int fields)
-{
- u64 mask = 0;
- if (fields & 0x1)
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
- if (fields & 0x2)
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
- if (fields & 0x4)
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
- if (fields & 0x8)
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
- if (fields & 0x10) {
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
- mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
- }
- return mask;
-}
-
-static struct event_constraint *
-hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
-{
- return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
-}
-
-static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- struct extra_reg *er;
- int idx = 0;
-
- for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
- if (er->event != (event->hw.config & er->config_mask))
- continue;
- idx |= er->idx;
- }
-
- if (idx) {
- reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
- HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
- reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
- reg1->idx = idx;
- }
- return 0;
-}
-
-static void hswep_cbox_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-
- if (reg1->idx != EXTRA_REG_NONE) {
- u64 filter = uncore_shared_reg_config(box, 0);
- wrmsrl(reg1->reg, filter & 0xffffffff);
- wrmsrl(reg1->reg + 1, filter >> 32);
- }
-
- wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
-}
-
-static struct intel_uncore_ops hswep_uncore_cbox_ops = {
- .init_box = snbep_uncore_msr_init_box,
- .disable_box = snbep_uncore_msr_disable_box,
- .enable_box = snbep_uncore_msr_enable_box,
- .disable_event = snbep_uncore_msr_disable_event,
- .enable_event = hswep_cbox_enable_event,
- .read_counter = uncore_msr_read_counter,
- .hw_config = hswep_cbox_hw_config,
- .get_constraint = hswep_cbox_get_constraint,
- .put_constraint = snbep_cbox_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_cbox = {
- .name = "cbox",
- .num_counters = 4,
- .num_boxes = 18,
- .perf_ctr_bits = 48,
- .event_ctl = HSWEP_C0_MSR_PMON_CTL0,
- .perf_ctr = HSWEP_C0_MSR_PMON_CTR0,
- .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL,
- .msr_offset = HSWEP_CBO_MSR_OFFSET,
- .num_shared_regs = 1,
- .constraints = hswep_uncore_cbox_constraints,
- .ops = &hswep_uncore_cbox_ops,
- .format_group = &hswep_uncore_cbox_format_group,
-};
-
-/*
- * Write SBOX Initialization register bit by bit to avoid spurious #GPs
- */
-static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
-{
- unsigned msr = uncore_msr_box_ctl(box);
-
- if (msr) {
- u64 init = SNBEP_PMON_BOX_CTL_INT;
- u64 flags = 0;
- int i;
-
- for_each_set_bit(i, (unsigned long *)&init, 64) {
- flags |= (1ULL << i);
- wrmsrl(msr, flags);
- }
- }
-}
-
-static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
- __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .init_box = hswep_uncore_sbox_msr_init_box
-};
-
-static struct attribute *hswep_uncore_sbox_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_tid_en.attr,
- &format_attr_inv.attr,
- &format_attr_thresh8.attr,
- NULL,
-};
-
-static struct attribute_group hswep_uncore_sbox_format_group = {
- .name = "format",
- .attrs = hswep_uncore_sbox_formats_attr,
-};
-
-static struct intel_uncore_type hswep_uncore_sbox = {
- .name = "sbox",
- .num_counters = 4,
- .num_boxes = 4,
- .perf_ctr_bits = 44,
- .event_ctl = HSWEP_S0_MSR_PMON_CTL0,
- .perf_ctr = HSWEP_S0_MSR_PMON_CTR0,
- .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL,
- .msr_offset = HSWEP_SBOX_MSR_OFFSET,
- .ops = &hswep_uncore_sbox_msr_ops,
- .format_group = &hswep_uncore_sbox_format_group,
-};
-
-static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
- int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
-
- if (ev_sel >= 0xb && ev_sel <= 0xe) {
- reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
- reg1->idx = ev_sel - 0xb;
- reg1->config = event->attr.config1 & (0xff << reg1->idx);
- }
- return 0;
-}
-
-static struct intel_uncore_ops hswep_uncore_pcu_ops = {
- SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .hw_config = hswep_pcu_hw_config,
- .get_constraint = snbep_pcu_get_constraint,
- .put_constraint = snbep_pcu_put_constraint,
-};
-
-static struct intel_uncore_type hswep_uncore_pcu = {
- .name = "pcu",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .perf_ctr = HSWEP_PCU_MSR_PMON_CTR0,
- .event_ctl = HSWEP_PCU_MSR_PMON_CTL0,
- .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = HSWEP_PCU_MSR_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &hswep_uncore_pcu_ops,
- .format_group = &snbep_uncore_pcu_format_group,
-};
-
-static struct intel_uncore_type *hswep_msr_uncores[] = {
- &hswep_uncore_ubox,
- &hswep_uncore_cbox,
- &hswep_uncore_sbox,
- &hswep_uncore_pcu,
- NULL,
-};
-
-void hswep_uncore_cpu_init(void)
-{
- if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
-
- /* Detect 6-8 core systems with only two SBOXes */
- if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) {
- u32 capid4;
-
- pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3],
- 0x94, &capid4);
- if (((capid4 >> 6) & 0x3) == 0)
- hswep_uncore_sbox.num_boxes = 2;
- }
-
- uncore_msr_uncores = hswep_msr_uncores;
-}
-
-static struct intel_uncore_type hswep_uncore_ha = {
- .name = "ha",
- .num_counters = 5,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct uncore_event_desc hswep_uncore_imc_events[] = {
- INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x00,umask=0x00"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
- { /* end: all zeroes */ },
-};
-
-static struct intel_uncore_type hswep_uncore_imc = {
- .name = "imc",
- .num_counters = 5,
- .num_boxes = 8,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
- .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
- .event_descs = hswep_uncore_imc_events,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
-
-static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
-{
- struct pci_dev *pdev = box->pci_dev;
- struct hw_perf_event *hwc = &event->hw;
- u64 count = 0;
-
- pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
- pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
-
- return count;
-}
-
-static struct intel_uncore_ops hswep_uncore_irp_ops = {
- .init_box = snbep_uncore_pci_init_box,
- .disable_box = snbep_uncore_pci_disable_box,
- .enable_box = snbep_uncore_pci_enable_box,
- .disable_event = ivbep_uncore_irp_disable_event,
- .enable_event = ivbep_uncore_irp_enable_event,
- .read_counter = hswep_uncore_irp_read_counter,
-};
-
-static struct intel_uncore_type hswep_uncore_irp = {
- .name = "irp",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .ops = &hswep_uncore_irp_ops,
- .format_group = &snbep_uncore_format_group,
-};
-
-static struct intel_uncore_type hswep_uncore_qpi = {
- .name = "qpi",
- .num_counters = 5,
- .num_boxes = 3,
- .perf_ctr_bits = 48,
- .perf_ctr = SNBEP_PCI_PMON_CTR0,
- .event_ctl = SNBEP_PCI_PMON_CTL0,
- .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .num_shared_regs = 1,
- .ops = &snbep_uncore_qpi_ops,
- .format_group = &snbep_uncore_qpi_format_group,
-};
-
-static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type hswep_uncore_r2pcie = {
- .name = "r2pcie",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .constraints = hswep_uncore_r2pcie_constraints,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type hswep_uncore_r3qpi = {
- .name = "r3qpi",
- .num_counters = 4,
- .num_boxes = 3,
- .perf_ctr_bits = 44,
- .constraints = hswep_uncore_r3qpi_constraints,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
- HSWEP_PCI_UNCORE_HA,
- HSWEP_PCI_UNCORE_IMC,
- HSWEP_PCI_UNCORE_IRP,
- HSWEP_PCI_UNCORE_QPI,
- HSWEP_PCI_UNCORE_R2PCIE,
- HSWEP_PCI_UNCORE_R3QPI,
-};
-
-static struct intel_uncore_type *hswep_pci_uncores[] = {
- [HSWEP_PCI_UNCORE_HA] = &hswep_uncore_ha,
- [HSWEP_PCI_UNCORE_IMC] = &hswep_uncore_imc,
- [HSWEP_PCI_UNCORE_IRP] = &hswep_uncore_irp,
- [HSWEP_PCI_UNCORE_QPI] = &hswep_uncore_qpi,
- [HSWEP_PCI_UNCORE_R2PCIE] = &hswep_uncore_r2pcie,
- [HSWEP_PCI_UNCORE_R3QPI] = &hswep_uncore_r3qpi,
- NULL,
-};
-
-static const struct pci_device_id hswep_uncore_pci_ids[] = {
- { /* Home Agent 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
- },
- { /* Home Agent 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
- },
- { /* MC0 Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
- },
- { /* MC0 Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
- },
- { /* MC0 Channel 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
- },
- { /* MC0 Channel 3 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
- },
- { /* MC1 Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
- },
- { /* MC1 Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
- },
- { /* MC1 Channel 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
- },
- { /* MC1 Channel 3 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
- },
- { /* IRP */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
- },
- { /* QPI0 Port 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
- },
- { /* QPI0 Port 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
- },
- { /* QPI1 Port 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
- },
- { /* R2PCIe */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
- },
- { /* R3QPI0 Link 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
- },
- { /* R3QPI0 Link 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
- },
- { /* R3QPI1 Link 2 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
- .driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
- },
- { /* QPI Port 0 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT0_FILTER),
- },
- { /* QPI Port 1 filter */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- SNBEP_PCI_QPI_PORT1_FILTER),
- },
- { /* PCU.3 (for Capability registers) */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0),
- .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
- HSWEP_PCI_PCU_3),
- },
- { /* end: all zeroes */ }
-};
-
-static struct pci_driver hswep_uncore_pci_driver = {
- .name = "hswep_uncore",
- .id_table = hswep_uncore_pci_ids,
-};
-
-int hswep_uncore_pci_init(void)
-{
- int ret = snbep_pci2phy_map_init(0x2f1e);
- if (ret)
- return ret;
- uncore_pci_uncores = hswep_pci_uncores;
- uncore_pci_driver = &hswep_uncore_pci_driver;
- return 0;
-}
-/* end of Haswell-EP uncore support */
-
-/* BDX-DE uncore support */
-
-static struct intel_uncore_type bdx_uncore_ubox = {
- .name = "ubox",
- .num_counters = 2,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .perf_ctr = HSWEP_U_MSR_PMON_CTR0,
- .event_ctl = HSWEP_U_MSR_PMON_CTL0,
- .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
- .fixed_ctr = HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
- .fixed_ctl = HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
- .num_shared_regs = 1,
- .ops = &ivbep_uncore_msr_ops,
- .format_group = &ivbep_uncore_ubox_format_group,
-};
-
-static struct event_constraint bdx_uncore_cbox_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type bdx_uncore_cbox = {
- .name = "cbox",
- .num_counters = 4,
- .num_boxes = 8,
- .perf_ctr_bits = 48,
- .event_ctl = HSWEP_C0_MSR_PMON_CTL0,
- .perf_ctr = HSWEP_C0_MSR_PMON_CTR0,
- .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
- .box_ctl = HSWEP_C0_MSR_PMON_BOX_CTL,
- .msr_offset = HSWEP_CBO_MSR_OFFSET,
- .num_shared_regs = 1,
- .constraints = bdx_uncore_cbox_constraints,
- .ops = &hswep_uncore_cbox_ops,
- .format_group = &hswep_uncore_cbox_format_group,
-};
-
-static struct intel_uncore_type *bdx_msr_uncores[] = {
- &bdx_uncore_ubox,
- &bdx_uncore_cbox,
- &hswep_uncore_pcu,
- NULL,
-};
-
-void bdx_uncore_cpu_init(void)
-{
- if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
- uncore_msr_uncores = bdx_msr_uncores;
-}
-
-static struct intel_uncore_type bdx_uncore_ha = {
- .name = "ha",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type bdx_uncore_imc = {
- .name = "imc",
- .num_counters = 5,
- .num_boxes = 2,
- .perf_ctr_bits = 48,
- .fixed_ctr_bits = 48,
- .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
- .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
- .event_descs = hswep_uncore_imc_events,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-static struct intel_uncore_type bdx_uncore_irp = {
- .name = "irp",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
- .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
- .ops = &hswep_uncore_irp_ops,
- .format_group = &snbep_uncore_format_group,
-};
-
-
-static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- EVENT_CONSTRAINT_END
-};
-
-static struct intel_uncore_type bdx_uncore_r2pcie = {
- .name = "r2pcie",
- .num_counters = 4,
- .num_boxes = 1,
- .perf_ctr_bits = 48,
- .constraints = bdx_uncore_r2pcie_constraints,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
-};
-
-enum {
- BDX_PCI_UNCORE_HA,
- BDX_PCI_UNCORE_IMC,
- BDX_PCI_UNCORE_IRP,
- BDX_PCI_UNCORE_R2PCIE,
-};
-
-static struct intel_uncore_type *bdx_pci_uncores[] = {
- [BDX_PCI_UNCORE_HA] = &bdx_uncore_ha,
- [BDX_PCI_UNCORE_IMC] = &bdx_uncore_imc,
- [BDX_PCI_UNCORE_IRP] = &bdx_uncore_irp,
- [BDX_PCI_UNCORE_R2PCIE] = &bdx_uncore_r2pcie,
- NULL,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(bdx_uncore_pci_ids) = {
- { /* Home Agent 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
- .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
- },
- { /* MC0 Channel 0 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
- .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
- },
- { /* MC0 Channel 1 */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
- .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
- },
- { /* IRP */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
- .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
- },
- { /* R2PCIe */
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
- .driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
- },
- { /* end: all zeroes */ }
-};
-
-static struct pci_driver bdx_uncore_pci_driver = {
- .name = "bdx_uncore",
- .id_table = bdx_uncore_pci_ids,
-};
-
-int bdx_uncore_pci_init(void)
-{
- int ret = snbep_pci2phy_map_init(0x6f1e);
-
- if (ret)
- return ret;
- uncore_pci_uncores = bdx_pci_uncores;
- uncore_pci_driver = &bdx_uncore_pci_driver;
- return 0;
-}
-
-/* end of BDX-DE uncore support */
diff --git a/arch/x86/kernel/cpu/perf_event_knc.c b/arch/x86/kernel/cpu/perf_event_knc.c
deleted file mode 100644
index 5b0c232..0000000
--- a/arch/x86/kernel/cpu/perf_event_knc.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* Driver for Intel Xeon Phi "Knights Corner" PMU */
-
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include <asm/hardirq.h>
-
-#include "perf_event.h"
-
-static const u64 knc_perfmon_event_map[] =
-{
- [PERF_COUNT_HW_CPU_CYCLES] = 0x002a,
- [PERF_COUNT_HW_INSTRUCTIONS] = 0x0016,
- [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0028,
- [PERF_COUNT_HW_CACHE_MISSES] = 0x0029,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0012,
- [PERF_COUNT_HW_BRANCH_MISSES] = 0x002b,
-};
-
-static const u64 __initconst knc_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- /* On Xeon Phi event "0" is a valid DATA_READ */
- /* (L1 Data Cache Reads) Instruction. */
- /* We code this as ARCH_PERFMON_EVENTSEL_INT as this */
- /* bit will always be set in x86_pmu_hw_config(). */
- [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
- /* DATA_READ */
- [ C(RESULT_MISS) ] = 0x0003, /* DATA_READ_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
- [ C(RESULT_MISS) ] = 0x0004, /* DATA_WRITE_MISS */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0011, /* L1_DATA_PF1 */
- [ C(RESULT_MISS) ] = 0x001c, /* L1_DATA_PF1_MISS */
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
- [ C(RESULT_MISS) ] = 0x000e, /* CODE_CACHE_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0x10cb, /* L2_READ_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x10cc, /* L2_WRITE_HIT */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x10fc, /* L2_DATA_PF2 */
- [ C(RESULT_MISS) ] = 0x10fe, /* L2_DATA_PF2_MISS */
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
- /* DATA_READ */
- /* see note on L1 OP_READ */
- [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
- [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = 0x0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
- [ C(RESULT_MISS) ] = 0x000d, /* CODE_PAGE_WALK */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0012, /* BRANCHES */
- [ C(RESULT_MISS) ] = 0x002b, /* BRANCHES_MISPREDICTED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-
-static u64 knc_pmu_event_map(int hw_event)
-{
- return knc_perfmon_event_map[hw_event];
-}
-
-static struct event_constraint knc_event_constraints[] =
-{
- INTEL_EVENT_CONSTRAINT(0xc3, 0x1), /* HWP_L2HIT */
- INTEL_EVENT_CONSTRAINT(0xc4, 0x1), /* HWP_L2MISS */
- INTEL_EVENT_CONSTRAINT(0xc8, 0x1), /* L2_READ_HIT_E */
- INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* L2_READ_HIT_M */
- INTEL_EVENT_CONSTRAINT(0xca, 0x1), /* L2_READ_HIT_S */
- INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* L2_READ_MISS */
- INTEL_EVENT_CONSTRAINT(0xcc, 0x1), /* L2_WRITE_HIT */
- INTEL_EVENT_CONSTRAINT(0xce, 0x1), /* L2_STRONGLY_ORDERED_STREAMING_VSTORES_MISS */
- INTEL_EVENT_CONSTRAINT(0xcf, 0x1), /* L2_WEAKLY_ORDERED_STREAMING_VSTORE_MISS */
- INTEL_EVENT_CONSTRAINT(0xd7, 0x1), /* L2_VICTIM_REQ_WITH_DATA */
- INTEL_EVENT_CONSTRAINT(0xe3, 0x1), /* SNP_HITM_BUNIT */
- INTEL_EVENT_CONSTRAINT(0xe6, 0x1), /* SNP_HIT_L2 */
- INTEL_EVENT_CONSTRAINT(0xe7, 0x1), /* SNP_HITM_L2 */
- INTEL_EVENT_CONSTRAINT(0xf1, 0x1), /* L2_DATA_READ_MISS_CACHE_FILL */
- INTEL_EVENT_CONSTRAINT(0xf2, 0x1), /* L2_DATA_WRITE_MISS_CACHE_FILL */
- INTEL_EVENT_CONSTRAINT(0xf6, 0x1), /* L2_DATA_READ_MISS_MEM_FILL */
- INTEL_EVENT_CONSTRAINT(0xf7, 0x1), /* L2_DATA_WRITE_MISS_MEM_FILL */
- INTEL_EVENT_CONSTRAINT(0xfc, 0x1), /* L2_DATA_PF2 */
- INTEL_EVENT_CONSTRAINT(0xfd, 0x1), /* L2_DATA_PF2_DROP */
- INTEL_EVENT_CONSTRAINT(0xfe, 0x1), /* L2_DATA_PF2_MISS */
- INTEL_EVENT_CONSTRAINT(0xff, 0x1), /* L2_DATA_HIT_INFLIGHT_PF2 */
- EVENT_CONSTRAINT_END
-};
-
-#define MSR_KNC_IA32_PERF_GLOBAL_STATUS 0x0000002d
-#define MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL 0x0000002e
-#define MSR_KNC_IA32_PERF_GLOBAL_CTRL 0x0000002f
-
-#define KNC_ENABLE_COUNTER0 0x00000001
-#define KNC_ENABLE_COUNTER1 0x00000002
-
-static void knc_pmu_disable_all(void)
-{
- u64 val;
-
- rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
- val &= ~(KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
- wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-}
-
-static void knc_pmu_enable_all(int added)
-{
- u64 val;
-
- rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
- val |= (KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
- wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
-}
-
-static inline void
-knc_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 val;
-
- val = hwc->config;
- val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
-
- (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
-}
-
-static void knc_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 val;
-
- val = hwc->config;
- val |= ARCH_PERFMON_EVENTSEL_ENABLE;
-
- (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
-}
-
-static inline u64 knc_pmu_get_status(void)
-{
- u64 status;
-
- rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status);
-
- return status;
-}
-
-static inline void knc_pmu_ack_status(u64 ack)
-{
- wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack);
-}
-
-static int knc_pmu_handle_irq(struct pt_regs *regs)
-{
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- int handled = 0;
- int bit, loops;
- u64 status;
-
- cpuc = this_cpu_ptr(&cpu_hw_events);
-
- knc_pmu_disable_all();
-
- status = knc_pmu_get_status();
- if (!status) {
- knc_pmu_enable_all(0);
- return handled;
- }
-
- loops = 0;
-again:
- knc_pmu_ack_status(status);
- if (++loops > 100) {
- WARN_ONCE(1, "perf: irq loop stuck!\n");
- perf_event_print_debug();
- goto done;
- }
-
- inc_irq_stat(apic_perf_irqs);
-
- for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
- struct perf_event *event = cpuc->events[bit];
-
- handled++;
-
- if (!test_bit(bit, cpuc->active_mask))
- continue;
-
- if (!intel_pmu_save_and_restart(event))
- continue;
-
- perf_sample_data_init(&data, 0, event->hw.last_period);
-
- if (perf_event_overflow(event, &data, regs))
- x86_pmu_stop(event, 0);
- }
-
- /*
- * Repeat if there is more work to be done:
- */
- status = knc_pmu_get_status();
- if (status)
- goto again;
-
-done:
- knc_pmu_enable_all(0);
-
- return handled;
-}
-
-
-PMU_FORMAT_ATTR(event, "config:0-7" );
-PMU_FORMAT_ATTR(umask, "config:8-15" );
-PMU_FORMAT_ATTR(edge, "config:18" );
-PMU_FORMAT_ATTR(inv, "config:23" );
-PMU_FORMAT_ATTR(cmask, "config:24-31" );
-
-static struct attribute *intel_knc_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_inv.attr,
- &format_attr_cmask.attr,
- NULL,
-};
-
-static const struct x86_pmu knc_pmu __initconst = {
- .name = "knc",
- .handle_irq = knc_pmu_handle_irq,
- .disable_all = knc_pmu_disable_all,
- .enable_all = knc_pmu_enable_all,
- .enable = knc_pmu_enable_event,
- .disable = knc_pmu_disable_event,
- .hw_config = x86_pmu_hw_config,
- .schedule_events = x86_schedule_events,
- .eventsel = MSR_KNC_EVNTSEL0,
- .perfctr = MSR_KNC_PERFCTR0,
- .event_map = knc_pmu_event_map,
- .max_events = ARRAY_SIZE(knc_perfmon_event_map),
- .apic = 1,
- .max_period = (1ULL << 39) - 1,
- .version = 0,
- .num_counters = 2,
- .cntval_bits = 40,
- .cntval_mask = (1ULL << 40) - 1,
- .get_event_constraints = x86_get_event_constraints,
- .event_constraints = knc_event_constraints,
- .format_attrs = intel_knc_formats_attr,
-};
-
-__init int knc_pmu_init(void)
-{
- x86_pmu = knc_pmu;
-
- memcpy(hw_cache_event_ids, knc_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- return 0;
-}
diff --git a/arch/x86/kernel/cpu/perf_event_msr.c b/arch/x86/kernel/cpu/perf_event_msr.c
deleted file mode 100644
index f32ac13..0000000
--- a/arch/x86/kernel/cpu/perf_event_msr.c
+++ /dev/null
@@ -1,242 +0,0 @@
-#include <linux/perf_event.h>
-
-enum perf_msr_id {
- PERF_MSR_TSC = 0,
- PERF_MSR_APERF = 1,
- PERF_MSR_MPERF = 2,
- PERF_MSR_PPERF = 3,
- PERF_MSR_SMI = 4,
-
- PERF_MSR_EVENT_MAX,
-};
-
-static bool test_aperfmperf(int idx)
-{
- return boot_cpu_has(X86_FEATURE_APERFMPERF);
-}
-
-static bool test_intel(int idx)
-{
- if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
- boot_cpu_data.x86 != 6)
- return false;
-
- switch (boot_cpu_data.x86_model) {
- case 30: /* 45nm Nehalem */
- case 26: /* 45nm Nehalem-EP */
- case 46: /* 45nm Nehalem-EX */
-
- case 37: /* 32nm Westmere */
- case 44: /* 32nm Westmere-EP */
- case 47: /* 32nm Westmere-EX */
-
- case 42: /* 32nm SandyBridge */
- case 45: /* 32nm SandyBridge-E/EN/EP */
-
- case 58: /* 22nm IvyBridge */
- case 62: /* 22nm IvyBridge-EP/EX */
-
- case 60: /* 22nm Haswell Core */
- case 63: /* 22nm Haswell Server */
- case 69: /* 22nm Haswell ULT */
- case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */
-
- case 61: /* 14nm Broadwell Core-M */
- case 86: /* 14nm Broadwell Xeon D */
- case 71: /* 14nm Broadwell + GT3e (Intel Iris Pro graphics) */
- case 79: /* 14nm Broadwell Server */
-
- case 55: /* 22nm Atom "Silvermont" */
- case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */
- case 76: /* 14nm Atom "Airmont" */
- if (idx == PERF_MSR_SMI)
- return true;
- break;
-
- case 78: /* 14nm Skylake Mobile */
- case 94: /* 14nm Skylake Desktop */
- if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
- return true;
- break;
- }
-
- return false;
-}
-
-struct perf_msr {
- u64 msr;
- struct perf_pmu_events_attr *attr;
- bool (*test)(int idx);
-};
-
-PMU_EVENT_ATTR_STRING(tsc, evattr_tsc, "event=0x00");
-PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
-PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
-PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
-PMU_EVENT_ATTR_STRING(smi, evattr_smi, "event=0x04");
-
-static struct perf_msr msr[] = {
- [PERF_MSR_TSC] = { 0, &evattr_tsc, NULL, },
- [PERF_MSR_APERF] = { MSR_IA32_APERF, &evattr_aperf, test_aperfmperf, },
- [PERF_MSR_MPERF] = { MSR_IA32_MPERF, &evattr_mperf, test_aperfmperf, },
- [PERF_MSR_PPERF] = { MSR_PPERF, &evattr_pperf, test_intel, },
- [PERF_MSR_SMI] = { MSR_SMI_COUNT, &evattr_smi, test_intel, },
-};
-
-static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
- NULL,
-};
-
-static struct attribute_group events_attr_group = {
- .name = "events",
- .attrs = events_attrs,
-};
-
-PMU_FORMAT_ATTR(event, "config:0-63");
-static struct attribute *format_attrs[] = {
- &format_attr_event.attr,
- NULL,
-};
-static struct attribute_group format_attr_group = {
- .name = "format",
- .attrs = format_attrs,
-};
-
-static const struct attribute_group *attr_groups[] = {
- &events_attr_group,
- &format_attr_group,
- NULL,
-};
-
-static int msr_event_init(struct perf_event *event)
-{
- u64 cfg = event->attr.config;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- if (cfg >= PERF_MSR_EVENT_MAX)
- return -EINVAL;
-
- /* unsupported modes and filters */
- if (event->attr.exclude_user ||
- event->attr.exclude_kernel ||
- event->attr.exclude_hv ||
- event->attr.exclude_idle ||
- event->attr.exclude_host ||
- event->attr.exclude_guest ||
- event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- if (!msr[cfg].attr)
- return -EINVAL;
-
- event->hw.idx = -1;
- event->hw.event_base = msr[cfg].msr;
- event->hw.config = cfg;
-
- return 0;
-}
-
-static inline u64 msr_read_counter(struct perf_event *event)
-{
- u64 now;
-
- if (event->hw.event_base)
- rdmsrl(event->hw.event_base, now);
- else
- rdtscll(now);
-
- return now;
-}
-static void msr_event_update(struct perf_event *event)
-{
- u64 prev, now;
- s64 delta;
-
- /* Careful, an NMI might modify the previous event value. */
-again:
- prev = local64_read(&event->hw.prev_count);
- now = msr_read_counter(event);
-
- if (local64_cmpxchg(&event->hw.prev_count, prev, now) != prev)
- goto again;
-
- delta = now - prev;
- if (unlikely(event->hw.event_base == MSR_SMI_COUNT)) {
- delta <<= 32;
- delta >>= 32; /* sign extend */
- }
- local64_add(now - prev, &event->count);
-}
-
-static void msr_event_start(struct perf_event *event, int flags)
-{
- u64 now;
-
- now = msr_read_counter(event);
- local64_set(&event->hw.prev_count, now);
-}
-
-static void msr_event_stop(struct perf_event *event, int flags)
-{
- msr_event_update(event);
-}
-
-static void msr_event_del(struct perf_event *event, int flags)
-{
- msr_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int msr_event_add(struct perf_event *event, int flags)
-{
- if (flags & PERF_EF_START)
- msr_event_start(event, flags);
-
- return 0;
-}
-
-static struct pmu pmu_msr = {
- .task_ctx_nr = perf_sw_context,
- .attr_groups = attr_groups,
- .event_init = msr_event_init,
- .add = msr_event_add,
- .del = msr_event_del,
- .start = msr_event_start,
- .stop = msr_event_stop,
- .read = msr_event_update,
- .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
-};
-
-static int __init msr_init(void)
-{
- int i, j = 0;
-
- if (!boot_cpu_has(X86_FEATURE_TSC)) {
- pr_cont("no MSR PMU driver.\n");
- return 0;
- }
-
- /* Probe the MSRs. */
- for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
- u64 val;
-
- /*
- * Virt sucks arse; you cannot tell if a R/O MSR is present :/
- */
- if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
- msr[i].attr = NULL;
- }
-
- /* List remaining MSRs in the sysfs attrs. */
- for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
- if (msr[i].attr)
- events_attrs[j++] = &msr[i].attr->attr.attr;
- }
- events_attrs[j] = NULL;
-
- perf_pmu_register(&pmu_msr, "msr", -1);
-
- return 0;
-}
-device_initcall(msr_init);
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
deleted file mode 100644
index f2e5678..0000000
--- a/arch/x86/kernel/cpu/perf_event_p4.c
+++ /dev/null
@@ -1,1376 +0,0 @@
-/*
- * Netburst Performance Events (P4, old Xeon)
- *
- * Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
- * Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_event.h>
-
-#include <asm/perf_event_p4.h>
-#include <asm/hardirq.h>
-#include <asm/apic.h>
-
-#include "perf_event.h"
-
-#define P4_CNTR_LIMIT 3
-/*
- * array indices: 0,1 - HT threads, used with HT enabled cpu
- */
-struct p4_event_bind {
- unsigned int opcode; /* Event code and ESCR selector */
- unsigned int escr_msr[2]; /* ESCR MSR for this event */
- unsigned int escr_emask; /* valid ESCR EventMask bits */
- unsigned int shared; /* event is shared across threads */
- char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */
-};
-
-struct p4_pebs_bind {
- unsigned int metric_pebs;
- unsigned int metric_vert;
-};
-
-/* it sets P4_PEBS_ENABLE_UOP_TAG as well */
-#define P4_GEN_PEBS_BIND(name, pebs, vert) \
- [P4_PEBS_METRIC__##name] = { \
- .metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG, \
- .metric_vert = vert, \
- }
-
-/*
- * note we have P4_PEBS_ENABLE_UOP_TAG always set here
- *
- * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of
- * event configuration to find out which values are to be
- * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT
- * resgisters
- */
-static struct p4_pebs_bind p4_pebs_bind_map[] = {
- P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired, 0x0000001, 0x0000001),
- P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired, 0x0000002, 0x0000001),
- P4_GEN_PEBS_BIND(dtlb_load_miss_retired, 0x0000004, 0x0000001),
- P4_GEN_PEBS_BIND(dtlb_store_miss_retired, 0x0000004, 0x0000002),
- P4_GEN_PEBS_BIND(dtlb_all_miss_retired, 0x0000004, 0x0000003),
- P4_GEN_PEBS_BIND(tagged_mispred_branch, 0x0018000, 0x0000010),
- P4_GEN_PEBS_BIND(mob_load_replay_retired, 0x0000200, 0x0000001),
- P4_GEN_PEBS_BIND(split_load_retired, 0x0000400, 0x0000001),
- P4_GEN_PEBS_BIND(split_store_retired, 0x0000400, 0x0000002),
-};
-
-/*
- * Note that we don't use CCCR1 here, there is an
- * exception for P4_BSQ_ALLOCATION but we just have
- * no workaround
- *
- * consider this binding as resources which particular
- * event may borrow, it doesn't contain EventMask,
- * Tags and friends -- they are left to a caller
- */
-static struct p4_event_bind p4_event_bind_map[] = {
- [P4_EVENT_TC_DELIVER_MODE] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
- .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI) |
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID),
- .shared = 1,
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_BPU_FETCH_REQUEST] = {
- .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
- .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_ITLB_REFERENCE] = {
- .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
- .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_MEMORY_CANCEL] = {
- .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
- .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF),
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_MEMORY_COMPLETE] = {
- .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
- .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC),
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_LOAD_PORT_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
- .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD),
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_STORE_PORT_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
- .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST),
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_MOB_LOAD_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
- .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_PAGE_WALK_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
- .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS),
- .shared = 1,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BSQ_CACHE_REFERENCE] = {
- .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
- .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_IOQ_ALLOCATION] = {
- .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */
- .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
- .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER) |
- P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH),
- .cntr = { {2, -1, -1}, {3, -1, -1} },
- },
- [P4_EVENT_FSB_DATA_ACTIVITY] = {
- .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER),
- .shared = 1,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */
- .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
- .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2),
- .cntr = { {0, -1, -1}, {1, -1, -1} },
- },
- [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */
- .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
- .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2),
- .cntr = { {2, -1, -1}, {3, -1, -1} },
- },
- [P4_EVENT_SSE_INPUT_ASSIST] = {
- .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_PACKED_SP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_PACKED_DP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_SCALAR_SP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_SCALAR_DP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_64BIT_MMX_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_128BIT_MMX_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_X87_FP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_TC_MISC] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_MISC),
- .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH),
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_GLOBAL_POWER_EVENTS] = {
- .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING),
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_TC_MS_XFER] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER),
- .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC),
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_UOP_QUEUE_WRITES] = {
- .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
- .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD) |
- P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER) |
- P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM),
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
- .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT),
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RETIRED_BRANCH_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
- .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT),
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RESOURCE_STALL] = {
- .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
- .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_WC_BUFFER] = {
- .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER),
- .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS),
- .shared = 1,
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_B2B_CYCLES] = {
- .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask = 0,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BNR] = {
- .opcode = P4_OPCODE(P4_EVENT_BNR),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask = 0,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_SNOOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SNOOP),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask = 0,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_RESPONSE] = {
- .opcode = P4_OPCODE(P4_EVENT_RESPONSE),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .escr_emask = 0,
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_FRONT_END_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_EXECUTION_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_REPLAY_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_INSTR_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_UOPS_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_UOP_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE),
- .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_BRANCH_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_MISPRED_BRANCH_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_X87_ASSIST] = {
- .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU) |
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO) |
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO) |
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU) |
- P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_MACHINE_CLEAR] = {
- .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_INSTR_COMPLETED] = {
- .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .escr_emask =
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS),
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
-};
-
-#define P4_GEN_CACHE_EVENT(event, bit, metric) \
- p4_config_pack_escr(P4_ESCR_EVENT(event) | \
- P4_ESCR_EMASK_BIT(event, bit)) | \
- p4_config_pack_cccr(metric | \
- P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
-
-static __initconst const u64 p4_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_PEBS_METRIC__1stl_cache_load_miss_retired),
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_PEBS_METRIC__2ndl_cache_load_miss_retired),
- },
-},
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_PEBS_METRIC__dtlb_load_miss_retired),
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_PEBS_METRIC__dtlb_store_miss_retired),
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
- P4_PEBS_METRIC__none),
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
- P4_PEBS_METRIC__none),
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(NODE) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-/*
- * Because of Netburst being quite restricted in how many
- * identical events may run simultaneously, we introduce event aliases,
- * ie the different events which have the same functionality but
- * utilize non-intersected resources (ESCR/CCCR/counter registers).
- *
- * This allow us to relax restrictions a bit and run two or more
- * identical events together.
- *
- * Never set any custom internal bits such as P4_CONFIG_HT,
- * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are
- * either up to date automatically or not applicable at all.
- */
-struct p4_event_alias {
- u64 original;
- u64 alternative;
-} p4_event_aliases[] = {
- {
- /*
- * Non-halted cycles can be substituted with non-sleeping cycles (see
- * Intel SDM Vol3b for details). We need this alias to be able
- * to run nmi-watchdog and 'perf top' (or any other user space tool
- * which is interested in running PERF_COUNT_HW_CPU_CYCLES)
- * simultaneously.
- */
- .original =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
- .alternative =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_EXECUTION_EVENT) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0)|
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1)|
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2)|
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3)|
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) |
- P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3))|
- p4_config_pack_cccr(P4_CCCR_THRESHOLD(15) | P4_CCCR_COMPLEMENT |
- P4_CCCR_COMPARE),
- },
-};
-
-static u64 p4_get_alias_event(u64 config)
-{
- u64 config_match;
- int i;
-
- /*
- * Only event with special mark is allowed,
- * we're to be sure it didn't come as malformed
- * RAW event.
- */
- if (!(config & P4_CONFIG_ALIASABLE))
- return 0;
-
- config_match = config & P4_CONFIG_EVENT_ALIAS_MASK;
-
- for (i = 0; i < ARRAY_SIZE(p4_event_aliases); i++) {
- if (config_match == p4_event_aliases[i].original) {
- config_match = p4_event_aliases[i].alternative;
- break;
- } else if (config_match == p4_event_aliases[i].alternative) {
- config_match = p4_event_aliases[i].original;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(p4_event_aliases))
- return 0;
-
- return config_match | (config & P4_CONFIG_EVENT_ALIAS_IMMUTABLE_BITS);
-}
-
-static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
- /* non-halted CPU clocks */
- [PERF_COUNT_HW_CPU_CYCLES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)) |
- P4_CONFIG_ALIASABLE,
-
- /*
- * retired instructions
- * in a sake of simplicity we don't use the FSB tagging
- */
- [PERF_COUNT_HW_INSTRUCTIONS] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
-
- /* cache hits */
- [PERF_COUNT_HW_CACHE_REFERENCES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
-
- /* cache misses */
- [PERF_COUNT_HW_CACHE_MISSES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
-
- /* branch instructions retired */
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
-
- /* mispredicted branches retired */
- [PERF_COUNT_HW_BRANCH_MISSES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
-
- /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */
- [PERF_COUNT_HW_BUS_CYCLES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)) |
- p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
-};
-
-static struct p4_event_bind *p4_config_get_bind(u64 config)
-{
- unsigned int evnt = p4_config_unpack_event(config);
- struct p4_event_bind *bind = NULL;
-
- if (evnt < ARRAY_SIZE(p4_event_bind_map))
- bind = &p4_event_bind_map[evnt];
-
- return bind;
-}
-
-static u64 p4_pmu_event_map(int hw_event)
-{
- struct p4_event_bind *bind;
- unsigned int esel;
- u64 config;
-
- config = p4_general_events[hw_event];
- bind = p4_config_get_bind(config);
- esel = P4_OPCODE_ESEL(bind->opcode);
- config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
-
- return config;
-}
-
-/* check cpu model specifics */
-static bool p4_event_match_cpu_model(unsigned int event_idx)
-{
- /* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */
- if (event_idx == P4_EVENT_INSTR_COMPLETED) {
- if (boot_cpu_data.x86_model != 3 &&
- boot_cpu_data.x86_model != 4 &&
- boot_cpu_data.x86_model != 6)
- return false;
- }
-
- /*
- * For info
- * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2
- */
-
- return true;
-}
-
-static int p4_validate_raw_event(struct perf_event *event)
-{
- unsigned int v, emask;
-
- /* User data may have out-of-bound event index */
- v = p4_config_unpack_event(event->attr.config);
- if (v >= ARRAY_SIZE(p4_event_bind_map))
- return -EINVAL;
-
- /* It may be unsupported: */
- if (!p4_event_match_cpu_model(v))
- return -EINVAL;
-
- /*
- * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as
- * in Architectural Performance Monitoring, it means not
- * on _which_ logical cpu to count but rather _when_, ie it
- * depends on logical cpu state -- count event if one cpu active,
- * none, both or any, so we just allow user to pass any value
- * desired.
- *
- * In turn we always set Tx_OS/Tx_USR bits bound to logical
- * cpu without their propagation to another cpu
- */
-
- /*
- * if an event is shared across the logical threads
- * the user needs special permissions to be able to use it
- */
- if (p4_ht_active() && p4_event_bind_map[v].shared) {
- if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
- return -EACCES;
- }
-
- /* ESCR EventMask bits may be invalid */
- emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK;
- if (emask & ~p4_event_bind_map[v].escr_emask)
- return -EINVAL;
-
- /*
- * it may have some invalid PEBS bits
- */
- if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE))
- return -EINVAL;
-
- v = p4_config_unpack_metric(event->attr.config);
- if (v >= ARRAY_SIZE(p4_pebs_bind_map))
- return -EINVAL;
-
- return 0;
-}
-
-static int p4_hw_config(struct perf_event *event)
-{
- int cpu = get_cpu();
- int rc = 0;
- u32 escr, cccr;
-
- /*
- * the reason we use cpu that early is that: if we get scheduled
- * first time on the same cpu -- we will not need swap thread
- * specific flags in config (and will save some cpu cycles)
- */
-
- cccr = p4_default_cccr_conf(cpu);
- escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
- event->attr.exclude_user);
- event->hw.config = p4_config_pack_escr(escr) |
- p4_config_pack_cccr(cccr);
-
- if (p4_ht_active() && p4_ht_thread(cpu))
- event->hw.config = p4_set_ht_bit(event->hw.config);
-
- if (event->attr.type == PERF_TYPE_RAW) {
- struct p4_event_bind *bind;
- unsigned int esel;
- /*
- * Clear bits we reserve to be managed by kernel itself
- * and never allowed from a user space
- */
- event->attr.config &= P4_CONFIG_MASK;
-
- rc = p4_validate_raw_event(event);
- if (rc)
- goto out;
-
- /*
- * Note that for RAW events we allow user to use P4_CCCR_RESERVED
- * bits since we keep additional info here (for cache events and etc)
- */
- event->hw.config |= event->attr.config;
- bind = p4_config_get_bind(event->attr.config);
- if (!bind) {
- rc = -EINVAL;
- goto out;
- }
- esel = P4_OPCODE_ESEL(bind->opcode);
- event->hw.config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
- }
-
- rc = x86_setup_perfctr(event);
-out:
- put_cpu();
- return rc;
-}
-
-static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
-{
- u64 v;
-
- /* an official way for overflow indication */
- rdmsrl(hwc->config_base, v);
- if (v & P4_CCCR_OVF) {
- wrmsrl(hwc->config_base, v & ~P4_CCCR_OVF);
- return 1;
- }
-
- /*
- * In some circumstances the overflow might issue an NMI but did
- * not set P4_CCCR_OVF bit. Because a counter holds a negative value
- * we simply check for high bit being set, if it's cleared it means
- * the counter has reached zero value and continued counting before
- * real NMI signal was received:
- */
- rdmsrl(hwc->event_base, v);
- if (!(v & ARCH_P4_UNFLAGGED_BIT))
- return 1;
-
- return 0;
-}
-
-static void p4_pmu_disable_pebs(void)
-{
- /*
- * FIXME
- *
- * It's still allowed that two threads setup same cache
- * events so we can't simply clear metrics until we knew
- * no one is depending on us, so we need kind of counter
- * for "ReplayEvent" users.
- *
- * What is more complex -- RAW events, if user (for some
- * reason) will pass some cache event metric with improper
- * event opcode -- it's fine from hardware point of view
- * but completely nonsense from "meaning" of such action.
- *
- * So at moment let leave metrics turned on forever -- it's
- * ok for now but need to be revisited!
- *
- * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, 0);
- * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, 0);
- */
-}
-
-static inline void p4_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- /*
- * If event gets disabled while counter is in overflowed
- * state we need to clear P4_CCCR_OVF, otherwise interrupt get
- * asserted again and again
- */
- (void)wrmsrl_safe(hwc->config_base,
- p4_config_unpack_cccr(hwc->config) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
-}
-
-static void p4_pmu_disable_all(void)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct perf_event *event = cpuc->events[idx];
- if (!test_bit(idx, cpuc->active_mask))
- continue;
- p4_pmu_disable_event(event);
- }
-
- p4_pmu_disable_pebs();
-}
-
-/* configuration must be valid */
-static void p4_pmu_enable_pebs(u64 config)
-{
- struct p4_pebs_bind *bind;
- unsigned int idx;
-
- BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK);
-
- idx = p4_config_unpack_metric(config);
- if (idx == P4_PEBS_METRIC__none)
- return;
-
- bind = &p4_pebs_bind_map[idx];
-
- (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs);
- (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert);
-}
-
-static void p4_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int thread = p4_ht_config_thread(hwc->config);
- u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
- unsigned int idx = p4_config_unpack_event(hwc->config);
- struct p4_event_bind *bind;
- u64 escr_addr, cccr;
-
- bind = &p4_event_bind_map[idx];
- escr_addr = bind->escr_msr[thread];
-
- /*
- * - we dont support cascaded counters yet
- * - and counter 1 is broken (erratum)
- */
- WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
- WARN_ON_ONCE(hwc->idx == 1);
-
- /* we need a real Event value */
- escr_conf &= ~P4_ESCR_EVENT_MASK;
- escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
-
- cccr = p4_config_unpack_cccr(hwc->config);
-
- /*
- * it could be Cache event so we need to write metrics
- * into additional MSRs
- */
- p4_pmu_enable_pebs(hwc->config);
-
- (void)wrmsrl_safe(escr_addr, escr_conf);
- (void)wrmsrl_safe(hwc->config_base,
- (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
-}
-
-static void p4_pmu_enable_all(int added)
-{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct perf_event *event = cpuc->events[idx];
- if (!test_bit(idx, cpuc->active_mask))
- continue;
- p4_pmu_enable_event(event);
- }
-}
-
-static int p4_pmu_handle_irq(struct pt_regs *regs)
-{
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct perf_event *event;
- struct hw_perf_event *hwc;
- int idx, handled = 0;
- u64 val;
-
- cpuc = this_cpu_ptr(&cpu_hw_events);
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- int overflow;
-
- if (!test_bit(idx, cpuc->active_mask)) {
- /* catch in-flight IRQs */
- if (__test_and_clear_bit(idx, cpuc->running))
- handled++;
- continue;
- }
-
- event = cpuc->events[idx];
- hwc = &event->hw;
-
- WARN_ON_ONCE(hwc->idx != idx);
-
- /* it might be unflagged overflow */
- overflow = p4_pmu_clear_cccr_ovf(hwc);
-
- val = x86_perf_event_update(event);
- if (!overflow && (val & (1ULL << (x86_pmu.cntval_bits - 1))))
- continue;
-
- handled += overflow;
-
- /* event overflow for sure */
- perf_sample_data_init(&data, 0, hwc->last_period);
-
- if (!x86_perf_event_set_period(event))
- continue;
-
-
- if (perf_event_overflow(event, &data, regs))
- x86_pmu_stop(event, 0);
- }
-
- if (handled)
- inc_irq_stat(apic_perf_irqs);
-
- /*
- * When dealing with the unmasking of the LVTPC on P4 perf hw, it has
- * been observed that the OVF bit flag has to be cleared first _before_
- * the LVTPC can be unmasked.
- *
- * The reason is the NMI line will continue to be asserted while the OVF
- * bit is set. This causes a second NMI to generate if the LVTPC is
- * unmasked before the OVF bit is cleared, leading to unknown NMI
- * messages.
- */
- apic_write(APIC_LVTPC, APIC_DM_NMI);
-
- return handled;
-}
-
-/*
- * swap thread specific fields according to a thread
- * we are going to run on
- */
-static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
-{
- u32 escr, cccr;
-
- /*
- * we either lucky and continue on same cpu or no HT support
- */
- if (!p4_should_swap_ts(hwc->config, cpu))
- return;
-
- /*
- * the event is migrated from an another logical
- * cpu, so we need to swap thread specific flags
- */
-
- escr = p4_config_unpack_escr(hwc->config);
- cccr = p4_config_unpack_cccr(hwc->config);
-
- if (p4_ht_thread(cpu)) {
- cccr &= ~P4_CCCR_OVF_PMI_T0;
- cccr |= P4_CCCR_OVF_PMI_T1;
- if (escr & P4_ESCR_T0_OS) {
- escr &= ~P4_ESCR_T0_OS;
- escr |= P4_ESCR_T1_OS;
- }
- if (escr & P4_ESCR_T0_USR) {
- escr &= ~P4_ESCR_T0_USR;
- escr |= P4_ESCR_T1_USR;
- }
- hwc->config = p4_config_pack_escr(escr);
- hwc->config |= p4_config_pack_cccr(cccr);
- hwc->config |= P4_CONFIG_HT;
- } else {
- cccr &= ~P4_CCCR_OVF_PMI_T1;
- cccr |= P4_CCCR_OVF_PMI_T0;
- if (escr & P4_ESCR_T1_OS) {
- escr &= ~P4_ESCR_T1_OS;
- escr |= P4_ESCR_T0_OS;
- }
- if (escr & P4_ESCR_T1_USR) {
- escr &= ~P4_ESCR_T1_USR;
- escr |= P4_ESCR_T0_USR;
- }
- hwc->config = p4_config_pack_escr(escr);
- hwc->config |= p4_config_pack_cccr(cccr);
- hwc->config &= ~P4_CONFIG_HT;
- }
-}
-
-/*
- * ESCR address hashing is tricky, ESCRs are not sequential
- * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and
- * the metric between any ESCRs is laid in range [0xa0,0xe1]
- *
- * so we make ~70% filled hashtable
- */
-
-#define P4_ESCR_MSR_BASE 0x000003a0
-#define P4_ESCR_MSR_MAX 0x000003e1
-#define P4_ESCR_MSR_TABLE_SIZE (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
-#define P4_ESCR_MSR_IDX(msr) (msr - P4_ESCR_MSR_BASE)
-#define P4_ESCR_MSR_TABLE_ENTRY(msr) [P4_ESCR_MSR_IDX(msr)] = msr
-
-static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
-};
-
-static int p4_get_escr_idx(unsigned int addr)
-{
- unsigned int idx = P4_ESCR_MSR_IDX(addr);
-
- if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE ||
- !p4_escr_table[idx] ||
- p4_escr_table[idx] != addr)) {
- WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
- return -1;
- }
-
- return idx;
-}
-
-static int p4_next_cntr(int thread, unsigned long *used_mask,
- struct p4_event_bind *bind)
-{
- int i, j;
-
- for (i = 0; i < P4_CNTR_LIMIT; i++) {
- j = bind->cntr[thread][i];
- if (j != -1 && !test_bit(j, used_mask))
- return j;
- }
-
- return -1;
-}
-
-static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
-{
- unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
- int cpu = smp_processor_id();
- struct hw_perf_event *hwc;
- struct p4_event_bind *bind;
- unsigned int i, thread, num;
- int cntr_idx, escr_idx;
- u64 config_alias;
- int pass;
-
- bitmap_zero(used_mask, X86_PMC_IDX_MAX);
- bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
-
- for (i = 0, num = n; i < n; i++, num--) {
-
- hwc = &cpuc->event_list[i]->hw;
- thread = p4_ht_thread(cpu);
- pass = 0;
-
-again:
- /*
- * It's possible to hit a circular lock
- * between original and alternative events
- * if both are scheduled already.
- */
- if (pass > 2)
- goto done;
-
- bind = p4_config_get_bind(hwc->config);
- escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
- if (unlikely(escr_idx == -1))
- goto done;
-
- if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
- cntr_idx = hwc->idx;
- if (assign)
- assign[i] = hwc->idx;
- goto reserve;
- }
-
- cntr_idx = p4_next_cntr(thread, used_mask, bind);
- if (cntr_idx == -1 || test_bit(escr_idx, escr_mask)) {
- /*
- * Check whether an event alias is still available.
- */
- config_alias = p4_get_alias_event(hwc->config);
- if (!config_alias)
- goto done;
- hwc->config = config_alias;
- pass++;
- goto again;
- }
- /*
- * Perf does test runs to see if a whole group can be assigned
- * together succesfully. There can be multiple rounds of this.
- * Unfortunately, p4_pmu_swap_config_ts touches the hwc->config
- * bits, such that the next round of group assignments will
- * cause the above p4_should_swap_ts to pass instead of fail.
- * This leads to counters exclusive to thread0 being used by
- * thread1.
- *
- * Solve this with a cheap hack, reset the idx back to -1 to
- * force a new lookup (p4_next_cntr) to get the right counter
- * for the right thread.
- *
- * This probably doesn't comply with the general spirit of how
- * perf wants to work, but P4 is special. :-(
- */
- if (p4_should_swap_ts(hwc->config, cpu))
- hwc->idx = -1;
- p4_pmu_swap_config_ts(hwc, cpu);
- if (assign)
- assign[i] = cntr_idx;
-reserve:
- set_bit(cntr_idx, used_mask);
- set_bit(escr_idx, escr_mask);
- }
-
-done:
- return num ? -EINVAL : 0;
-}
-
-PMU_FORMAT_ATTR(cccr, "config:0-31" );
-PMU_FORMAT_ATTR(escr, "config:32-62");
-PMU_FORMAT_ATTR(ht, "config:63" );
-
-static struct attribute *intel_p4_formats_attr[] = {
- &format_attr_cccr.attr,
- &format_attr_escr.attr,
- &format_attr_ht.attr,
- NULL,
-};
-
-static __initconst const struct x86_pmu p4_pmu = {
- .name = "Netburst P4/Xeon",
- .handle_irq = p4_pmu_handle_irq,
- .disable_all = p4_pmu_disable_all,
- .enable_all = p4_pmu_enable_all,
- .enable = p4_pmu_enable_event,
- .disable = p4_pmu_disable_event,
- .eventsel = MSR_P4_BPU_CCCR0,
- .perfctr = MSR_P4_BPU_PERFCTR0,
- .event_map = p4_pmu_event_map,
- .max_events = ARRAY_SIZE(p4_general_events),
- .get_event_constraints = x86_get_event_constraints,
- /*
- * IF HT disabled we may need to use all
- * ARCH_P4_MAX_CCCR counters simulaneously
- * though leave it restricted at moment assuming
- * HT is on
- */
- .num_counters = ARCH_P4_MAX_CCCR,
- .apic = 1,
- .cntval_bits = ARCH_P4_CNTRVAL_BITS,
- .cntval_mask = ARCH_P4_CNTRVAL_MASK,
- .max_period = (1ULL << (ARCH_P4_CNTRVAL_BITS - 1)) - 1,
- .hw_config = p4_hw_config,
- .schedule_events = p4_pmu_schedule_events,
- /*
- * This handles erratum N15 in intel doc 249199-029,
- * the counter may not be updated correctly on write
- * so we need a second write operation to do the trick
- * (the official workaround didn't work)
- *
- * the former idea is taken from OProfile code
- */
- .perfctr_second_write = 1,
-
- .format_attrs = intel_p4_formats_attr,
-};
-
-__init int p4_pmu_init(void)
-{
- unsigned int low, high;
- int i, reg;
-
- /* If we get stripped -- indexing fails */
- BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC);
-
- rdmsr(MSR_IA32_MISC_ENABLE, low, high);
- if (!(low & (1 << 7))) {
- pr_cont("unsupported Netburst CPU model %d ",
- boot_cpu_data.x86_model);
- return -ENODEV;
- }
-
- memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- pr_cont("Netburst events, ");
-
- x86_pmu = p4_pmu;
-
- /*
- * Even though the counters are configured to interrupt a particular
- * logical processor when an overflow happens, testing has shown that
- * on kdump kernels (which uses a single cpu), thread1's counter
- * continues to run and will report an NMI on thread0. Due to the
- * overflow bug, this leads to a stream of unknown NMIs.
- *
- * Solve this by zero'ing out the registers to mimic a reset.
- */
- for (i = 0; i < x86_pmu.num_counters; i++) {
- reg = x86_pmu_config_addr(i);
- wrmsrl_safe(reg, 0ULL);
- }
-
- return 0;
-}
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
deleted file mode 100644
index 7c1a0c0..0000000
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ /dev/null
@@ -1,279 +0,0 @@
-#include <linux/perf_event.h>
-#include <linux/types.h>
-
-#include "perf_event.h"
-
-/*
- * Not sure about some of these
- */
-static const u64 p6_perfmon_event_map[] =
-{
- [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */
- [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */
- [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */
- [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */
- [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */
- [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */
-
-};
-
-static const u64 __initconst p6_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */
- [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(L1I ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */
- [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = 0,
- [ C(RESULT_MISS) ] = 0,
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */
- [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
- [ C(BPU ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */
- [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-static u64 p6_pmu_event_map(int hw_event)
-{
- return p6_perfmon_event_map[hw_event];
-}
-
-/*
- * Event setting that is specified not to count anything.
- * We use this to effectively disable a counter.
- *
- * L2_RQSTS with 0 MESI unit mask.
- */
-#define P6_NOP_EVENT 0x0000002EULL
-
-static struct event_constraint p6_event_constraints[] =
-{
- INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */
- INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
- INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
- INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
- INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
- INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
- EVENT_CONSTRAINT_END
-};
-
-static void p6_pmu_disable_all(void)
-{
- u64 val;
-
- /* p6 only has one enable register */
- rdmsrl(MSR_P6_EVNTSEL0, val);
- val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
- wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static void p6_pmu_enable_all(int added)
-{
- unsigned long val;
-
- /* p6 only has one enable register */
- rdmsrl(MSR_P6_EVNTSEL0, val);
- val |= ARCH_PERFMON_EVENTSEL_ENABLE;
- wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static inline void
-p6_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 val = P6_NOP_EVENT;
-
- (void)wrmsrl_safe(hwc->config_base, val);
-}
-
-static void p6_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 val;
-
- val = hwc->config;
-
- /*
- * p6 only has a global event enable, set on PerfEvtSel0
- * We "disable" events by programming P6_NOP_EVENT
- * and we rely on p6_pmu_enable_all() being called
- * to actually enable the events.
- */
-
- (void)wrmsrl_safe(hwc->config_base, val);
-}
-
-PMU_FORMAT_ATTR(event, "config:0-7" );
-PMU_FORMAT_ATTR(umask, "config:8-15" );
-PMU_FORMAT_ATTR(edge, "config:18" );
-PMU_FORMAT_ATTR(pc, "config:19" );
-PMU_FORMAT_ATTR(inv, "config:23" );
-PMU_FORMAT_ATTR(cmask, "config:24-31" );
-
-static struct attribute *intel_p6_formats_attr[] = {
- &format_attr_event.attr,
- &format_attr_umask.attr,
- &format_attr_edge.attr,
- &format_attr_pc.attr,
- &format_attr_inv.attr,
- &format_attr_cmask.attr,
- NULL,
-};
-
-static __initconst const struct x86_pmu p6_pmu = {
- .name = "p6",
- .handle_irq = x86_pmu_handle_irq,
- .disable_all = p6_pmu_disable_all,
- .enable_all = p6_pmu_enable_all,
- .enable = p6_pmu_enable_event,
- .disable = p6_pmu_disable_event,
- .hw_config = x86_pmu_hw_config,
- .schedule_events = x86_schedule_events,
- .eventsel = MSR_P6_EVNTSEL0,
- .perfctr = MSR_P6_PERFCTR0,
- .event_map = p6_pmu_event_map,
- .max_events = ARRAY_SIZE(p6_perfmon_event_map),
- .apic = 1,
- .max_period = (1ULL << 31) - 1,
- .version = 0,
- .num_counters = 2,
- /*
- * Events have 40 bits implemented. However they are designed such
- * that bits [32-39] are sign extensions of bit 31. As such the
- * effective width of a event for P6-like PMU is 32 bits only.
- *
- * See IA-32 Intel Architecture Software developer manual Vol 3B
- */
- .cntval_bits = 32,
- .cntval_mask = (1ULL << 32) - 1,
- .get_event_constraints = x86_get_event_constraints,
- .event_constraints = p6_event_constraints,
-
- .format_attrs = intel_p6_formats_attr,
- .events_sysfs_show = intel_event_sysfs_show,
-
-};
-
-static __init void p6_pmu_rdpmc_quirk(void)
-{
- if (boot_cpu_data.x86_mask < 9) {
- /*
- * PPro erratum 26; fixed in stepping 9 and above.
- */
- pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n");
- x86_pmu.attr_rdpmc_broken = 1;
- x86_pmu.attr_rdpmc = 0;
- }
-}
-
-__init int p6_pmu_init(void)
-{
- x86_pmu = p6_pmu;
-
- switch (boot_cpu_data.x86_model) {
- case 1: /* Pentium Pro */
- x86_add_quirk(p6_pmu_rdpmc_quirk);
- break;
-
- case 3: /* Pentium II - Klamath */
- case 5: /* Pentium II - Deschutes */
- case 6: /* Pentium II - Mendocino */
- break;
-
- case 7: /* Pentium III - Katmai */
- case 8: /* Pentium III - Coppermine */
- case 10: /* Pentium III Xeon */
- case 11: /* Pentium III - Tualatin */
- break;
-
- case 9: /* Pentium M - Banias */
- case 13: /* Pentium M - Dothan */
- break;
-
- default:
- pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model);
- return -ENODEV;
- }
-
- memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- return 0;
-}
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c
index 136ac74..f6f50c4 100644
--- a/arch/x86/kernel/cpu/rdrand.c
+++ b/arch/x86/kernel/cpu/rdrand.c
@@ -33,28 +33,27 @@ static int __init x86_rdrand_setup(char *s)
__setup("nordrand", x86_rdrand_setup);
/*
- * Force a reseed cycle; we are architecturally guaranteed a reseed
- * after no more than 512 128-bit chunks of random data. This also
- * acts as a test of the CPU capability.
+ * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation.
+ * Run the instruction a few times as a sanity check.
+ * If it fails, it is simple to disable RDRAND here.
*/
-#define RESEED_LOOP ((512*128)/sizeof(unsigned long))
+#define SANITY_CHECK_LOOPS 8
void x86_init_rdrand(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_ARCH_RANDOM
unsigned long tmp;
- int i, count, ok;
+ int i;
if (!cpu_has(c, X86_FEATURE_RDRAND))
- return; /* Nothing to do */
+ return;
- for (count = i = 0; i < RESEED_LOOP; i++) {
- ok = rdrand_long(&tmp);
- if (ok)
- count++;
+ for (i = 0; i < SANITY_CHECK_LOOPS; i++) {
+ if (!rdrand_long(&tmp)) {
+ clear_cpu_cap(c, X86_FEATURE_RDRAND);
+ pr_warn_once("rdrand: disabled\n");
+ return;
+ }
}
-
- if (count != RESEED_LOOP)
- clear_cpu_cap(c, X86_FEATURE_RDRAND);
#endif
}
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 608fb26..8cb57df 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -31,32 +31,12 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
const struct cpuid_bit *cb;
static const struct cpuid_bit cpuid_bits[] = {
- { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 },
- { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 },
- { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 },
- { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 },
- { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 },
- { X86_FEATURE_HWP, CR_EAX, 7, 0x00000006, 0 },
- { X86_FEATURE_HWP_NOTIFY, CR_EAX, 8, 0x00000006, 0 },
- { X86_FEATURE_HWP_ACT_WINDOW, CR_EAX, 9, 0x00000006, 0 },
- { X86_FEATURE_HWP_EPP, CR_EAX,10, 0x00000006, 0 },
- { X86_FEATURE_HWP_PKG_REQ, CR_EAX,11, 0x00000006, 0 },
{ X86_FEATURE_INTEL_PT, CR_EBX,25, 0x00000007, 0 },
{ X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 },
{ X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 },
{ X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
{ X86_FEATURE_PROC_FEEDBACK, CR_EDX,11, 0x80000007, 0 },
- { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 },
- { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
- { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
- { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 },
- { X86_FEATURE_TSCRATEMSR, CR_EDX, 4, 0x8000000a, 0 },
- { X86_FEATURE_VMCBCLEAN, CR_EDX, 5, 0x8000000a, 0 },
- { X86_FEATURE_FLUSHBYASID, CR_EDX, 6, 0x8000000a, 0 },
- { X86_FEATURE_DECODEASSISTS, CR_EDX, 7, 0x8000000a, 0 },
- { X86_FEATURE_PAUSEFILTER, CR_EDX,10, 0x8000000a, 0 },
- { X86_FEATURE_PFTHRESHOLD, CR_EDX,12, 0x8000000a, 0 },
{ 0, 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index 4c60eaf..cd53135 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -87,10 +87,10 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
c->x86_max_cores = (core_level_siblings / smp_num_siblings);
if (!printed) {
- printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
+ pr_info("CPU: Physical Processor ID: %d\n",
c->phys_proc_id);
if (c->x86_max_cores > 1)
- printk(KERN_INFO "CPU: Processor Core ID: %d\n",
+ pr_info("CPU: Processor Core ID: %d\n",
c->cpu_core_id);
printed = 1;
}
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c
index 3fa0e5a..3417856 100644
--- a/arch/x86/kernel/cpu/transmeta.c
+++ b/arch/x86/kernel/cpu/transmeta.c
@@ -1,6 +1,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/msr.h>
#include "cpu.h"
@@ -12,7 +12,7 @@ static void early_init_transmeta(struct cpuinfo_x86 *c)
xlvl = cpuid_eax(0x80860000);
if ((xlvl & 0xffff0000) == 0x80860000) {
if (xlvl >= 0x80860001)
- c->x86_capability[2] = cpuid_edx(0x80860001);
+ c->x86_capability[CPUID_8086_0001_EDX] = cpuid_edx(0x80860001);
}
}
@@ -33,7 +33,7 @@ static void init_transmeta(struct cpuinfo_x86 *c)
if (max >= 0x80860001) {
cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags);
if (cpu_rev != 0x02000000) {
- printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
+ pr_info("CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
(cpu_rev >> 24) & 0xff,
(cpu_rev >> 16) & 0xff,
(cpu_rev >> 8) & 0xff,
@@ -44,10 +44,10 @@ static void init_transmeta(struct cpuinfo_x86 *c)
if (max >= 0x80860002) {
cpuid(0x80860002, &new_cpu_rev, &cms_rev1, &cms_rev2, &dummy);
if (cpu_rev == 0x02000000) {
- printk(KERN_INFO "CPU: Processor revision %08X, %u MHz\n",
+ pr_info("CPU: Processor revision %08X, %u MHz\n",
new_cpu_rev, cpu_freq);
}
- printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
+ pr_info("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
(cms_rev1 >> 24) & 0xff,
(cms_rev1 >> 16) & 0xff,
(cms_rev1 >> 8) & 0xff,
@@ -76,13 +76,13 @@ static void init_transmeta(struct cpuinfo_x86 *c)
(void *)&cpu_info[56],
(void *)&cpu_info[60]);
cpu_info[64] = '\0';
- printk(KERN_INFO "CPU: %s\n", cpu_info);
+ pr_info("CPU: %s\n", cpu_info);
}
/* Unhide possibly hidden capability flags */
rdmsr(0x80860004, cap_mask, uk);
wrmsr(0x80860004, ~0, uk);
- c->x86_capability[0] = cpuid_edx(0x00000001);
+ c->x86_capability[CPUID_1_EDX] = cpuid_edx(0x00000001);
wrmsr(0x80860004, cap_mask, uk);
/* All Transmeta CPUs have a constant TSC */
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 628a059..364e583 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -62,7 +62,7 @@ static unsigned long vmware_get_tsc_khz(void)
tsc_hz = eax | (((uint64_t)ebx) << 32);
do_div(tsc_hz, 1000);
BUG_ON(tsc_hz >> 32);
- printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n",
+ pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n",
(unsigned long) tsc_hz / 1000,
(unsigned long) tsc_hz % 1000);
@@ -84,8 +84,7 @@ static void __init vmware_platform_setup(void)
if (ebx != UINT_MAX)
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
else
- printk(KERN_WARNING
- "Failed to get TSC freq from the hypervisor\n");
+ pr_warn("Failed to get TSC freq from the hypervisor\n");
}
/*
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index bd3507d..2836de3 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -58,28 +58,6 @@ static void cpuid_smp_cpuid(void *cmd_block)
&cmd->eax, &cmd->ebx, &cmd->ecx, &cmd->edx);
}
-static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
-{
- loff_t ret;
- struct inode *inode = file->f_mapping->host;
-
- mutex_lock(&inode->i_mutex);
- switch (orig) {
- case 0:
- file->f_pos = offset;
- ret = file->f_pos;
- break;
- case 1:
- file->f_pos += offset;
- ret = file->f_pos;
- break;
- default:
- ret = -EINVAL;
- }
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-
static ssize_t cpuid_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -132,7 +110,7 @@ static int cpuid_open(struct inode *inode, struct file *file)
*/
static const struct file_operations cpuid_fops = {
.owner = THIS_MODULE,
- .llseek = cpuid_seek,
+ .llseek = no_seek_end_llseek,
.read = cpuid_read,
.open = cpuid_open,
};
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 74ca2fe..9ef978d 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -35,6 +35,7 @@
#include <asm/cpu.h>
#include <asm/reboot.h>
#include <asm/virtext.h>
+#include <asm/intel_pt.h>
/* Alignment required for elf header segment */
#define ELF_CORE_HEADER_ALIGN 4096
@@ -56,10 +57,9 @@ struct crash_elf_data {
struct kimage *image;
/*
* Total number of ram ranges we have after various adjustments for
- * GART, crash reserved region etc.
+ * crash reserved region, etc.
*/
unsigned int max_nr_ranges;
- unsigned long gart_start, gart_end;
/* Pointer to elf header */
void *ehdr;
@@ -75,8 +75,6 @@ struct crash_memmap_data {
unsigned int type;
};
-int in_crash_kexec;
-
/*
* This is used to VMCLEAR all VMCSs loaded on the
* processor. And when loading kvm_intel module, the
@@ -127,12 +125,16 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
cpu_emergency_vmxoff();
cpu_emergency_svm_disable();
+ /*
+ * Disable Intel PT to stop its logging
+ */
+ cpu_emergency_stop_pt();
+
disable_local_APIC();
}
static void kdump_nmi_shootdown_cpus(void)
{
- in_crash_kexec = 1;
nmi_shootdown_cpus(kdump_nmi_callback);
disable_local_APIC();
@@ -172,6 +174,11 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
cpu_emergency_vmxoff();
cpu_emergency_svm_disable();
+ /*
+ * Disable Intel PT to stop its logging
+ */
+ cpu_emergency_stop_pt();
+
#ifdef CONFIG_X86_IO_APIC
/* Prevent crash_kexec() from deadlocking on ioapic_lock. */
ioapic_zap_locks();
@@ -193,17 +200,6 @@ static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg)
return 0;
}
-static int get_gart_ranges_callback(u64 start, u64 end, void *arg)
-{
- struct crash_elf_data *ced = arg;
-
- ced->gart_start = start;
- ced->gart_end = end;
-
- /* Not expecting more than 1 gart aperture */
- return 1;
-}
-
/* Gather all the required information to prepare elf headers for ram regions */
static void fill_up_crash_elf_data(struct crash_elf_data *ced,
@@ -218,22 +214,6 @@ static void fill_up_crash_elf_data(struct crash_elf_data *ced,
ced->max_nr_ranges = nr_ranges;
- /*
- * We don't create ELF headers for GART aperture as an attempt
- * to dump this memory in second kernel leads to hang/crash.
- * If gart aperture is present, one needs to exclude that region
- * and that could lead to need of extra phdr.
- */
- walk_iomem_res("GART", IORESOURCE_MEM, 0, -1,
- ced, get_gart_ranges_callback);
-
- /*
- * If we have gart region, excluding that could potentially split
- * a memory range, resulting in extra header. Account for that.
- */
- if (ced->gart_end)
- ced->max_nr_ranges++;
-
/* Exclusion of crash region could split memory ranges */
ced->max_nr_ranges++;
@@ -342,13 +322,6 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced,
return ret;
}
- /* Exclude GART region */
- if (ced->gart_end) {
- ret = exclude_mem_range(cmem, ced->gart_start, ced->gart_end);
- if (ret)
- return ret;
- }
-
return ret;
}
@@ -591,12 +564,12 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
/* Add ACPI tables */
cmd.type = E820_ACPI;
flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- walk_iomem_res("ACPI Tables", flags, 0, -1, &cmd,
+ walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd,
memmap_entry_callback);
/* Add ACPI Non-volatile Storage */
cmd.type = E820_NVS;
- walk_iomem_res("ACPI Non-volatile Storage", flags, 0, -1, &cmd,
+ walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, &cmd,
memmap_entry_callback);
/* Add crashk_low_res region */
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 9c30acf..8efa57a 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -135,7 +135,8 @@ print_context_stack_bp(struct thread_info *tinfo,
if (!__kernel_text_address(addr))
break;
- ops->address(data, addr, 1);
+ if (ops->address(data, addr, 1))
+ break;
frame = frame->next_frame;
ret_addr = &frame->return_address;
print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
@@ -154,10 +155,11 @@ static int print_trace_stack(void *data, char *name)
/*
* Print one address/symbol entries per line.
*/
-static void print_trace_address(void *data, unsigned long addr, int reliable)
+static int print_trace_address(void *data, unsigned long addr, int reliable)
{
touch_nmi_watchdog();
printk_stack_address(addr, reliable, data);
+ return 0;
}
static const struct stacktrace_ops print_trace_ops = {
@@ -265,9 +267,8 @@ int __die(const char *str, struct pt_regs *regs, long err)
#ifdef CONFIG_SMP
printk("SMP ");
#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk("DEBUG_PAGEALLOC ");
-#endif
+ if (debug_pagealloc_enabled())
+ printk("DEBUG_PAGEALLOC ");
#ifdef CONFIG_KASAN
printk("KASAN");
#endif
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index a102564..621b501 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -24,6 +24,7 @@
#include <asm/e820.h>
#include <asm/proto.h>
#include <asm/setup.h>
+#include <asm/cpufeature.h>
/*
* The e820 map is the map that gets modified e.g. with command line parameters
@@ -911,7 +912,7 @@ void __init finish_e820_parsing(void)
}
}
-static inline const char *e820_type_to_string(int e820_type)
+static const char *e820_type_to_string(int e820_type)
{
switch (e820_type) {
case E820_RESERVED_KERN:
@@ -925,6 +926,41 @@ static inline const char *e820_type_to_string(int e820_type)
}
}
+static unsigned long e820_type_to_iomem_type(int e820_type)
+{
+ switch (e820_type) {
+ case E820_RESERVED_KERN:
+ case E820_RAM:
+ return IORESOURCE_SYSTEM_RAM;
+ case E820_ACPI:
+ case E820_NVS:
+ case E820_UNUSABLE:
+ case E820_PRAM:
+ case E820_PMEM:
+ default:
+ return IORESOURCE_MEM;
+ }
+}
+
+static unsigned long e820_type_to_iores_desc(int e820_type)
+{
+ switch (e820_type) {
+ case E820_ACPI:
+ return IORES_DESC_ACPI_TABLES;
+ case E820_NVS:
+ return IORES_DESC_ACPI_NV_STORAGE;
+ case E820_PMEM:
+ return IORES_DESC_PERSISTENT_MEMORY;
+ case E820_PRAM:
+ return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
+ case E820_RESERVED_KERN:
+ case E820_RAM:
+ case E820_UNUSABLE:
+ default:
+ return IORES_DESC_NONE;
+ }
+}
+
static bool do_mark_busy(u32 type, struct resource *res)
{
/* this is the legacy bios/dos rom-shadow + mmio region */
@@ -967,7 +1003,8 @@ void __init e820_reserve_resources(void)
res->start = e820.map[i].addr;
res->end = end;
- res->flags = IORESOURCE_MEM;
+ res->flags = e820_type_to_iomem_type(e820.map[i].type);
+ res->desc = e820_type_to_iores_desc(e820.map[i].type);
/*
* don't register the region that could be conflicted with
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 9f9cc68..bca14c8 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -547,6 +547,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = {
INTEL_CHV_IDS(&chv_stolen_funcs),
INTEL_SKL_IDS(&gen9_stolen_funcs),
INTEL_BXT_IDS(&gen9_stolen_funcs),
+ INTEL_KBL_IDS(&gen9_stolen_funcs),
};
static void __init intel_graphics_stolen(int num, int slot, int func)
@@ -584,7 +585,7 @@ static void __init intel_graphics_stolen(int num, int slot, int func)
static void __init force_disable_hpet(int num, int slot, int func)
{
#ifdef CONFIG_HPET_TIMER
- boot_hpet_disable = 1;
+ boot_hpet_disable = true;
pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n");
#endif
}
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index eec40f5..21bf924 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -195,14 +195,14 @@ static __init void early_serial_init(char *s)
#ifdef CONFIG_PCI
static void mem32_serial_out(unsigned long addr, int offset, int value)
{
- u32 *vaddr = (u32 *)addr;
+ u32 __iomem *vaddr = (u32 __iomem *)addr;
/* shift implied by pointer type */
writel(value, vaddr + offset);
}
static unsigned int mem32_serial_in(unsigned long addr, int offset)
{
- u32 *vaddr = (u32 *)addr;
+ u32 __iomem *vaddr = (u32 __iomem *)addr;
/* shift implied by pointer type */
return readl(vaddr + offset);
}
@@ -316,7 +316,7 @@ static struct console early_serial_console = {
.index = -1,
};
-static inline void early_console_register(struct console *con, int keep_early)
+static void early_console_register(struct console *con, int keep_early)
{
if (con->index != -1) {
printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n",
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index d25097c..0b1b9ab 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -114,6 +114,10 @@ void __kernel_fpu_begin(void)
kernel_fpu_disable();
if (fpu->fpregs_active) {
+ /*
+ * Ignore return value -- we don't care if reg state
+ * is clobbered.
+ */
copy_fpregs_to_fpstate(fpu);
} else {
this_cpu_write(fpu_fpregs_owner_ctx, NULL);
@@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu)
preempt_disable();
if (fpu->fpregs_active) {
- if (!copy_fpregs_to_fpstate(fpu))
- fpregs_deactivate(fpu);
+ if (!copy_fpregs_to_fpstate(fpu)) {
+ if (use_eager_fpu())
+ copy_kernel_to_fpregs(&fpu->state);
+ else
+ fpregs_deactivate(fpu);
+ }
}
preempt_enable();
}
@@ -223,14 +231,15 @@ void fpstate_init(union fpregs_state *state)
}
EXPORT_SYMBOL_GPL(fpstate_init);
-/*
- * Copy the current task's FPU state to a new task's FPU context.
- *
- * In both the 'eager' and the 'lazy' case we save hardware registers
- * directly to the destination buffer.
- */
-static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
+int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
{
+ dst_fpu->counter = 0;
+ dst_fpu->fpregs_active = 0;
+ dst_fpu->last_cpu = -1;
+
+ if (!src_fpu->fpstate_active || !cpu_has_fpu)
+ return 0;
+
WARN_ON_FPU(src_fpu != &current->thread.fpu);
/*
@@ -243,10 +252,9 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
/*
* Save current FPU registers directly into the child
* FPU context, without any memory-to-memory copying.
- *
- * If the FPU context got destroyed in the process (FNSAVE
- * done on old CPUs) then copy it back into the source
- * context and mark the current task for lazy restore.
+ * In lazy mode, if the FPU context isn't loaded into
+ * fpregs, CR0.TS will be set and do_device_not_available
+ * will load the FPU context.
*
* We have to do all this with preemption disabled,
* mostly because of the FNSAVE case, because in that
@@ -259,19 +267,13 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
preempt_disable();
if (!copy_fpregs_to_fpstate(dst_fpu)) {
memcpy(&src_fpu->state, &dst_fpu->state, xstate_size);
- fpregs_deactivate(src_fpu);
+
+ if (use_eager_fpu())
+ copy_kernel_to_fpregs(&src_fpu->state);
+ else
+ fpregs_deactivate(src_fpu);
}
preempt_enable();
-}
-
-int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
-{
- dst_fpu->counter = 0;
- dst_fpu->fpregs_active = 0;
- dst_fpu->last_cpu = -1;
-
- if (src_fpu->fpstate_active && cpu_has_fpu)
- fpu_copy(dst_fpu, src_fpu);
return 0;
}
@@ -409,8 +411,10 @@ static inline void copy_init_fpstate_to_fpregs(void)
{
if (use_xsave())
copy_kernel_to_xregs(&init_fpstate.xsave, -1);
- else
+ else if (static_cpu_has(X86_FEATURE_FXSR))
copy_kernel_to_fxregs(&init_fpstate.fxsave);
+ else
+ copy_kernel_to_fregs(&init_fpstate.fsave);
}
/*
@@ -423,7 +427,7 @@ void fpu__clear(struct fpu *fpu)
{
WARN_ON_FPU(fpu != &current->thread.fpu); /* Almost certainly an anomaly */
- if (!use_eager_fpu()) {
+ if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) {
/* FPU state will be reallocated lazily at the first use. */
fpu__drop(fpu);
} else {
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index d14e9ac..54c86ff 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -3,8 +3,11 @@
*/
#include <asm/fpu/internal.h>
#include <asm/tlbflush.h>
+#include <asm/setup.h>
+#include <asm/cmdline.h>
#include <linux/sched.h>
+#include <linux/init.h>
/*
* Initialize the TS bit in CR0 according to the style of context-switches
@@ -12,7 +15,7 @@
*/
static void fpu__init_cpu_ctx_switch(void)
{
- if (!cpu_has_eager_fpu)
+ if (!boot_cpu_has(X86_FEATURE_EAGER_FPU))
stts();
else
clts();
@@ -75,13 +78,15 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
write_cr0(cr0);
- asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
- : "+m" (fsw), "+m" (fcw));
+ if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
+ asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
+ : "+m" (fsw), "+m" (fcw));
- if (fsw == 0 && (fcw & 0x103f) == 0x003f)
- set_cpu_cap(c, X86_FEATURE_FPU);
- else
- clear_cpu_cap(c, X86_FEATURE_FPU);
+ if (fsw == 0 && (fcw & 0x103f) == 0x003f)
+ set_cpu_cap(c, X86_FEATURE_FPU);
+ else
+ clear_cpu_cap(c, X86_FEATURE_FPU);
+ }
#ifndef CONFIG_MATH_EMULATION
if (!cpu_has_fpu) {
@@ -129,7 +134,7 @@ static void __init fpu__init_system_generic(void)
* Set up the legacy init FPU context. (xstate init might overwrite this
* with a more modern format, if the CPU supports it.)
*/
- fpstate_init_fxstate(&init_fpstate.fxsave);
+ fpstate_init(&init_fpstate);
fpu__init_system_mxcsr();
}
@@ -143,9 +148,18 @@ static void __init fpu__init_system_generic(void)
unsigned int xstate_size;
EXPORT_SYMBOL_GPL(xstate_size);
-/* Enforce that 'MEMBER' is the last field of 'TYPE': */
+/* Get alignment of the TYPE. */
+#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
+
+/*
+ * Enforce that 'MEMBER' is the last field of 'TYPE'.
+ *
+ * Align the computed size with alignment of the TYPE,
+ * because that's how C aligns structs.
+ */
#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
- BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER))
+ BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \
+ TYPE_ALIGN(TYPE)))
/*
* We append the 'struct fpu' to the task_struct:
@@ -188,7 +202,7 @@ static void __init fpu__init_task_struct_size(void)
*/
static void __init fpu__init_system_xstate_size_legacy(void)
{
- static int on_boot_cpu = 1;
+ static int on_boot_cpu __initdata = 1;
WARN_ON_FPU(!on_boot_cpu);
on_boot_cpu = 0;
@@ -248,7 +262,10 @@ static void __init fpu__init_system_xstate_size_legacy(void)
* not only saved the restores along the way, but we also have the
* FPU ready to be used for the original task.
*
- * 'eager' switching is used on modern CPUs, there we switch the FPU
+ * 'lazy' is deprecated because it's almost never a performance win
+ * and it's much more complicated than 'eager'.
+ *
+ * 'eager' switching is by default on all CPUs, there we switch the FPU
* state during every context switch, regardless of whether the task
* has used FPU instructions in that time slice or not. This is done
* because modern FPU context saving instructions are able to optimize
@@ -259,26 +276,52 @@ static void __init fpu__init_system_xstate_size_legacy(void)
* to use 'eager' restores, if we detect that a task is using the FPU
* frequently. See the fpu->counter logic in fpu/internal.h for that. ]
*/
-static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO;
+static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
-static int __init eager_fpu_setup(char *s)
+/*
+ * Find supported xfeatures based on cpu features and command-line input.
+ * This must be called after fpu__init_parse_early_param() is called and
+ * xfeatures_mask is enumerated.
+ */
+u64 __init fpu__get_supported_xfeatures_mask(void)
{
- if (!strcmp(s, "on"))
- eagerfpu = ENABLE;
- else if (!strcmp(s, "off"))
- eagerfpu = DISABLE;
- else if (!strcmp(s, "auto"))
- eagerfpu = AUTO;
- return 1;
+ /* Support all xfeatures known to us */
+ if (eagerfpu != DISABLE)
+ return XCNTXT_MASK;
+
+ /* Warning of xfeatures being disabled for no eagerfpu mode */
+ if (xfeatures_mask & XFEATURE_MASK_EAGER) {
+ pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
+ xfeatures_mask & XFEATURE_MASK_EAGER);
+ }
+
+ /* Return a mask that masks out all features requiring eagerfpu mode */
+ return ~XFEATURE_MASK_EAGER;
+}
+
+/*
+ * Disable features dependent on eagerfpu.
+ */
+static void __init fpu__clear_eager_fpu_features(void)
+{
+ setup_clear_cpu_cap(X86_FEATURE_MPX);
}
-__setup("eagerfpu=", eager_fpu_setup);
/*
* Pick the FPU context switching strategy:
+ *
+ * When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of
+ * the following is true:
+ *
+ * (1) the cpu has xsaveopt, as it has the optimization and doing eager
+ * FPU switching has a relatively low cost compared to a plain xsave;
+ * (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU
+ * switching. Should the kernel boot with noxsaveopt, we support MPX
+ * with eager FPU switching at a higher cost.
*/
static void __init fpu__init_system_ctx_switch(void)
{
- static bool on_boot_cpu = 1;
+ static bool on_boot_cpu __initdata = 1;
WARN_ON_FPU(!on_boot_cpu);
on_boot_cpu = 0;
@@ -286,19 +329,11 @@ static void __init fpu__init_system_ctx_switch(void)
WARN_ON_FPU(current->thread.fpu.fpstate_active);
current_thread_info()->status = 0;
- /* Auto enable eagerfpu for xsaveopt */
- if (cpu_has_xsaveopt && eagerfpu != DISABLE)
+ if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE)
eagerfpu = ENABLE;
- if (xfeatures_mask & XSTATE_EAGER) {
- if (eagerfpu == DISABLE) {
- pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
- xfeatures_mask & XSTATE_EAGER);
- xfeatures_mask &= ~XSTATE_EAGER;
- } else {
- eagerfpu = ENABLE;
- }
- }
+ if (xfeatures_mask & XFEATURE_MASK_EAGER)
+ eagerfpu = ENABLE;
if (eagerfpu == ENABLE)
setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
@@ -307,11 +342,42 @@ static void __init fpu__init_system_ctx_switch(void)
}
/*
+ * We parse fpu parameters early because fpu__init_system() is executed
+ * before parse_early_param().
+ */
+static void __init fpu__init_parse_early_param(void)
+{
+ if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) {
+ eagerfpu = DISABLE;
+ fpu__clear_eager_fpu_features();
+ }
+
+ if (cmdline_find_option_bool(boot_command_line, "no387"))
+ setup_clear_cpu_cap(X86_FEATURE_FPU);
+
+ if (cmdline_find_option_bool(boot_command_line, "nofxsr")) {
+ setup_clear_cpu_cap(X86_FEATURE_FXSR);
+ setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT);
+ setup_clear_cpu_cap(X86_FEATURE_XMM);
+ }
+
+ if (cmdline_find_option_bool(boot_command_line, "noxsave"))
+ fpu__xstate_clear_all_cpu_caps();
+
+ if (cmdline_find_option_bool(boot_command_line, "noxsaveopt"))
+ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+
+ if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
+ setup_clear_cpu_cap(X86_FEATURE_XSAVES);
+}
+
+/*
* Called on the boot CPU once per system bootup, to set up the initial
* FPU state that is later cloned into all processes:
*/
void __init fpu__init_system(struct cpuinfo_x86 *c)
{
+ fpu__init_parse_early_param();
fpu__init_system_early_generic(c);
/*
@@ -335,72 +401,3 @@ void __init fpu__init_system(struct cpuinfo_x86 *c)
fpu__init_system_ctx_switch();
}
-
-/*
- * Boot parameter to turn off FPU support and fall back to math-emu:
- */
-static int __init no_387(char *s)
-{
- setup_clear_cpu_cap(X86_FEATURE_FPU);
- return 1;
-}
-__setup("no387", no_387);
-
-/*
- * Disable all xstate CPU features:
- */
-static int __init x86_noxsave_setup(char *s)
-{
- if (strlen(s))
- return 0;
-
- setup_clear_cpu_cap(X86_FEATURE_XSAVE);
- setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
- setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
- setup_clear_cpu_cap(X86_FEATURE_XSAVES);
- setup_clear_cpu_cap(X86_FEATURE_AVX);
- setup_clear_cpu_cap(X86_FEATURE_AVX2);
- setup_clear_cpu_cap(X86_FEATURE_AVX512F);
- setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
- setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
- setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
- setup_clear_cpu_cap(X86_FEATURE_MPX);
-
- return 1;
-}
-__setup("noxsave", x86_noxsave_setup);
-
-/*
- * Disable the XSAVEOPT instruction specifically:
- */
-static int __init x86_noxsaveopt_setup(char *s)
-{
- setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
-
- return 1;
-}
-__setup("noxsaveopt", x86_noxsaveopt_setup);
-
-/*
- * Disable the XSAVES instruction:
- */
-static int __init x86_noxsaves_setup(char *s)
-{
- setup_clear_cpu_cap(X86_FEATURE_XSAVES);
-
- return 1;
-}
-__setup("noxsaves", x86_noxsaves_setup);
-
-/*
- * Disable FX save/restore and SSE support:
- */
-static int __init x86_nofxsr_setup(char *s)
-{
- setup_clear_cpu_cap(X86_FEATURE_FXSR);
- setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT);
- setup_clear_cpu_cap(X86_FEATURE_XMM);
-
- return 1;
-}
-__setup("nofxsr", x86_nofxsr_setup);
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index dc60810..0bc3490 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -66,7 +66,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
* presence of FP and SSE state.
*/
if (cpu_has_xsave)
- fpu->state.xsave.header.xfeatures |= XSTATE_FPSSE;
+ fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FPSSE;
return ret;
}
@@ -326,7 +326,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
* presence of FP.
*/
if (cpu_has_xsave)
- fpu->state.xsave.header.xfeatures |= XSTATE_FP;
+ fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP;
return ret;
}
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 50ec9af..31c6a60 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -56,7 +56,7 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
if (use_fxsr()) {
struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;
struct user_i387_ia32_struct env;
- struct _fpstate_ia32 __user *fp = buf;
+ struct _fpstate_32 __user *fp = buf;
convert_from_fxsr(&env, tsk);
@@ -107,7 +107,7 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
* header as well as change any contents in the memory layout.
* xrestore as part of sigreturn will capture all the changes.
*/
- xfeatures |= XSTATE_FPSSE;
+ xfeatures |= XFEATURE_MASK_FPSSE;
err |= __put_user(xfeatures, (__u32 *)&x->header.xfeatures);
@@ -165,7 +165,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
if (!static_cpu_has(X86_FEATURE_FPU))
return fpregs_soft_get(current, NULL, 0,
sizeof(struct user_i387_ia32_struct), NULL,
- (struct _fpstate_ia32 __user *) buf) ? -1 : 1;
+ (struct _fpstate_32 __user *) buf) ? -1 : 1;
if (fpregs_active()) {
/* Save the live register state to the user directly. */
@@ -207,7 +207,7 @@ sanitize_restored_xstate(struct task_struct *tsk,
* layout and not enabled by the OS.
*/
if (fx_only)
- header->xfeatures = XSTATE_FPSSE;
+ header->xfeatures = XFEATURE_MASK_FPSSE;
else
header->xfeatures &= (xfeatures_mask & xfeatures);
}
@@ -230,7 +230,7 @@ static inline int copy_user_to_fpregs_zeroing(void __user *buf, u64 xbv, int fx_
{
if (use_xsave()) {
if ((unsigned long)buf % 64 || fx_only) {
- u64 init_bv = xfeatures_mask & ~XSTATE_FPSSE;
+ u64 init_bv = xfeatures_mask & ~XFEATURE_MASK_FPSSE;
copy_kernel_to_xregs(&init_fpstate.xsave, init_bv);
return copy_user_to_fxregs(buf);
} else {
@@ -385,20 +385,19 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
*/
void fpu__init_prepare_fx_sw_frame(void)
{
- int fsave_header_size = sizeof(struct fregs_state);
int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
- if (config_enabled(CONFIG_X86_32))
- size += fsave_header_size;
-
fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
fx_sw_reserved.extended_size = size;
fx_sw_reserved.xfeatures = xfeatures_mask;
fx_sw_reserved.xstate_size = xstate_size;
- if (config_enabled(CONFIG_IA32_EMULATION)) {
+ if (config_enabled(CONFIG_IA32_EMULATION) ||
+ config_enabled(CONFIG_X86_32)) {
+ int fsave_header_size = sizeof(struct fregs_state);
+
fx_sw_reserved_ia32 = fx_sw_reserved;
- fx_sw_reserved_ia32.extended_size += fsave_header_size;
+ fx_sw_reserved_ia32.extended_size = size + fsave_header_size;
}
}
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 62fc001..6e8354f 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -31,12 +31,32 @@ static const char *xfeature_names[] =
*/
u64 xfeatures_mask __read_mostly;
-static unsigned int xstate_offsets[XFEATURES_NR_MAX] = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
-static unsigned int xstate_sizes[XFEATURES_NR_MAX] = { [ 0 ... XFEATURES_NR_MAX - 1] = -1};
+static unsigned int xstate_offsets[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
+static unsigned int xstate_sizes[XFEATURE_MAX] = { [ 0 ... XFEATURE_MAX - 1] = -1};
static unsigned int xstate_comp_offsets[sizeof(xfeatures_mask)*8];
-/* The number of supported xfeatures in xfeatures_mask: */
-static unsigned int xfeatures_nr;
+/*
+ * Clear all of the X86_FEATURE_* bits that are unavailable
+ * when the CPU has no XSAVE support.
+ */
+void fpu__xstate_clear_all_cpu_caps(void)
+{
+ setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
+ setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
+ setup_clear_cpu_cap(X86_FEATURE_XSAVES);
+ setup_clear_cpu_cap(X86_FEATURE_AVX);
+ setup_clear_cpu_cap(X86_FEATURE_AVX2);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512F);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512DQ);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512BW);
+ setup_clear_cpu_cap(X86_FEATURE_AVX512VL);
+ setup_clear_cpu_cap(X86_FEATURE_MPX);
+ setup_clear_cpu_cap(X86_FEATURE_XGETBV1);
+}
/*
* Return whether the system supports a given xfeature.
@@ -53,7 +73,7 @@ int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)
/*
* So we use FLS here to be able to print the most advanced
* feature that was requested but is missing. So if a driver
- * asks about "XSTATE_SSE | XSTATE_YMM" we'll print the
+ * asks about "XFEATURE_MASK_SSE | XFEATURE_MASK_YMM" we'll print the
* missing AVX feature - this is the most informative message
* to users:
*/
@@ -112,7 +132,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
/*
* FP is in init state
*/
- if (!(xfeatures & XSTATE_FP)) {
+ if (!(xfeatures & XFEATURE_MASK_FP)) {
fx->cwd = 0x37f;
fx->swd = 0;
fx->twd = 0;
@@ -125,7 +145,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
/*
* SSE is in init state
*/
- if (!(xfeatures & XSTATE_SSE))
+ if (!(xfeatures & XFEATURE_MASK_SSE))
memset(&fx->xmm_space[0], 0, 256);
/*
@@ -169,25 +189,43 @@ void fpu__init_cpu_xstate(void)
}
/*
+ * Note that in the future we will likely need a pair of
+ * functions here: one for user xstates and the other for
+ * system xstates. For now, they are the same.
+ */
+static int xfeature_enabled(enum xfeature xfeature)
+{
+ return !!(xfeatures_mask & (1UL << xfeature));
+}
+
+/*
* Record the offsets and sizes of various xstates contained
* in the XSAVE state memory layout.
- *
- * ( Note that certain features might be non-present, for them
- * we'll have 0 offset and 0 size. )
*/
static void __init setup_xstate_features(void)
{
- u32 eax, ebx, ecx, edx, leaf;
-
- xfeatures_nr = fls64(xfeatures_mask);
-
- for (leaf = 2; leaf < xfeatures_nr; leaf++) {
- cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx);
-
- xstate_offsets[leaf] = ebx;
- xstate_sizes[leaf] = eax;
+ u32 eax, ebx, ecx, edx, i;
+ /* start at the beginnning of the "extended state" */
+ unsigned int last_good_offset = offsetof(struct xregs_state,
+ extended_state_area);
+
+ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+ if (!xfeature_enabled(i))
+ continue;
+
+ cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+ xstate_offsets[i] = ebx;
+ xstate_sizes[i] = eax;
+ /*
+ * In our xstate size checks, we assume that the
+ * highest-numbered xstate feature has the
+ * highest offset in the buffer. Ensure it does.
+ */
+ WARN_ONCE(last_good_offset > xstate_offsets[i],
+ "x86/fpu: misordered xstate at %d\n", last_good_offset);
+ last_good_offset = xstate_offsets[i];
- printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %04x, xstate_sizes[%d]: %04x\n", leaf, ebx, leaf, eax);
+ printk(KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n", i, ebx, i, eax);
}
}
@@ -204,14 +242,14 @@ static void __init print_xstate_feature(u64 xstate_mask)
*/
static void __init print_xstate_features(void)
{
- print_xstate_feature(XSTATE_FP);
- print_xstate_feature(XSTATE_SSE);
- print_xstate_feature(XSTATE_YMM);
- print_xstate_feature(XSTATE_BNDREGS);
- print_xstate_feature(XSTATE_BNDCSR);
- print_xstate_feature(XSTATE_OPMASK);
- print_xstate_feature(XSTATE_ZMM_Hi256);
- print_xstate_feature(XSTATE_Hi16_ZMM);
+ print_xstate_feature(XFEATURE_MASK_FP);
+ print_xstate_feature(XFEATURE_MASK_SSE);
+ print_xstate_feature(XFEATURE_MASK_YMM);
+ print_xstate_feature(XFEATURE_MASK_BNDREGS);
+ print_xstate_feature(XFEATURE_MASK_BNDCSR);
+ print_xstate_feature(XFEATURE_MASK_OPMASK);
+ print_xstate_feature(XFEATURE_MASK_ZMM_Hi256);
+ print_xstate_feature(XFEATURE_MASK_Hi16_ZMM);
}
/*
@@ -233,8 +271,8 @@ static void __init setup_xstate_comp(void)
xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
if (!cpu_has_xsaves) {
- for (i = 2; i < xfeatures_nr; i++) {
- if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
+ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+ if (xfeature_enabled(i)) {
xstate_comp_offsets[i] = xstate_offsets[i];
xstate_comp_sizes[i] = xstate_sizes[i];
}
@@ -242,15 +280,16 @@ static void __init setup_xstate_comp(void)
return;
}
- xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+ xstate_comp_offsets[FIRST_EXTENDED_XFEATURE] =
+ FXSAVE_SIZE + XSAVE_HDR_SIZE;
- for (i = 2; i < xfeatures_nr; i++) {
- if (test_bit(i, (unsigned long *)&xfeatures_mask))
+ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+ if (xfeature_enabled(i))
xstate_comp_sizes[i] = xstate_sizes[i];
else
xstate_comp_sizes[i] = 0;
- if (i > 2)
+ if (i > FIRST_EXTENDED_XFEATURE)
xstate_comp_offsets[i] = xstate_comp_offsets[i-1]
+ xstate_comp_sizes[i-1];
@@ -262,7 +301,7 @@ static void __init setup_xstate_comp(void)
*/
static void __init setup_init_fpu_buf(void)
{
- static int on_boot_cpu = 1;
+ static int on_boot_cpu __initdata = 1;
WARN_ON_FPU(!on_boot_cpu);
on_boot_cpu = 0;
@@ -290,27 +329,280 @@ static void __init setup_init_fpu_buf(void)
copy_xregs_to_kernel_booting(&init_fpstate.xsave);
}
+static int xfeature_is_supervisor(int xfeature_nr)
+{
+ /*
+ * We currently do not support supervisor states, but if
+ * we did, we could find out like this.
+ *
+ * SDM says: If state component i is a user state component,
+ * ECX[0] return 0; if state component i is a supervisor
+ * state component, ECX[0] returns 1.
+ u32 eax, ebx, ecx, edx;
+ cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx;
+ return !!(ecx & 1);
+ */
+ return 0;
+}
+/*
+static int xfeature_is_user(int xfeature_nr)
+{
+ return !xfeature_is_supervisor(xfeature_nr);
+}
+*/
+
+/*
+ * This check is important because it is easy to get XSTATE_*
+ * confused with XSTATE_BIT_*.
+ */
+#define CHECK_XFEATURE(nr) do { \
+ WARN_ON(nr < FIRST_EXTENDED_XFEATURE); \
+ WARN_ON(nr >= XFEATURE_MAX); \
+} while (0)
+
+/*
+ * We could cache this like xstate_size[], but we only use
+ * it here, so it would be a waste of space.
+ */
+static int xfeature_is_aligned(int xfeature_nr)
+{
+ u32 eax, ebx, ecx, edx;
+
+ CHECK_XFEATURE(xfeature_nr);
+ cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+ /*
+ * The value returned by ECX[1] indicates the alignment
+ * of state component i when the compacted format
+ * of the extended region of an XSAVE area is used
+ */
+ return !!(ecx & 2);
+}
+
+static int xfeature_uncompacted_offset(int xfeature_nr)
+{
+ u32 eax, ebx, ecx, edx;
+
+ CHECK_XFEATURE(xfeature_nr);
+ cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+ return ebx;
+}
+
+static int xfeature_size(int xfeature_nr)
+{
+ u32 eax, ebx, ecx, edx;
+
+ CHECK_XFEATURE(xfeature_nr);
+ cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
+ return eax;
+}
+
+/*
+ * 'XSAVES' implies two different things:
+ * 1. saving of supervisor/system state
+ * 2. using the compacted format
+ *
+ * Use this function when dealing with the compacted format so
+ * that it is obvious which aspect of 'XSAVES' is being handled
+ * by the calling code.
+ */
+static int using_compacted_format(void)
+{
+ return cpu_has_xsaves;
+}
+
+static void __xstate_dump_leaves(void)
+{
+ int i;
+ u32 eax, ebx, ecx, edx;
+ static int should_dump = 1;
+
+ if (!should_dump)
+ return;
+ should_dump = 0;
+ /*
+ * Dump out a few leaves past the ones that we support
+ * just in case there are some goodies up there
+ */
+ for (i = 0; i < XFEATURE_MAX + 10; i++) {
+ cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
+ pr_warn("CPUID[%02x, %02x]: eax=%08x ebx=%08x ecx=%08x edx=%08x\n",
+ XSTATE_CPUID, i, eax, ebx, ecx, edx);
+ }
+}
+
+#define XSTATE_WARN_ON(x) do { \
+ if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) { \
+ __xstate_dump_leaves(); \
+ } \
+} while (0)
+
+#define XCHECK_SZ(sz, nr, nr_macro, __struct) do { \
+ if ((nr == nr_macro) && \
+ WARN_ONCE(sz != sizeof(__struct), \
+ "%s: struct is %zu bytes, cpu state %d bytes\n", \
+ __stringify(nr_macro), sizeof(__struct), sz)) { \
+ __xstate_dump_leaves(); \
+ } \
+} while (0)
+
+/*
+ * We have a C struct for each 'xstate'. We need to ensure
+ * that our software representation matches what the CPU
+ * tells us about the state's size.
+ */
+static void check_xstate_against_struct(int nr)
+{
+ /*
+ * Ask the CPU for the size of the state.
+ */
+ int sz = xfeature_size(nr);
+ /*
+ * Match each CPU state with the corresponding software
+ * structure.
+ */
+ XCHECK_SZ(sz, nr, XFEATURE_YMM, struct ymmh_struct);
+ XCHECK_SZ(sz, nr, XFEATURE_BNDREGS, struct mpx_bndreg_state);
+ XCHECK_SZ(sz, nr, XFEATURE_BNDCSR, struct mpx_bndcsr_state);
+ XCHECK_SZ(sz, nr, XFEATURE_OPMASK, struct avx_512_opmask_state);
+ XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state);
+ XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state);
+
+ /*
+ * Make *SURE* to add any feature numbers in below if
+ * there are "holes" in the xsave state component
+ * numbers.
+ */
+ if ((nr < XFEATURE_YMM) ||
+ (nr >= XFEATURE_MAX)) {
+ WARN_ONCE(1, "no structure for xstate: %d\n", nr);
+ XSTATE_WARN_ON(1);
+ }
+}
+
+/*
+ * This essentially double-checks what the cpu told us about
+ * how large the XSAVE buffer needs to be. We are recalculating
+ * it to be safe.
+ */
+static void do_extra_xstate_size_checks(void)
+{
+ int paranoid_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
+ int i;
+
+ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
+ if (!xfeature_enabled(i))
+ continue;
+
+ check_xstate_against_struct(i);
+ /*
+ * Supervisor state components can be managed only by
+ * XSAVES, which is compacted-format only.
+ */
+ if (!using_compacted_format())
+ XSTATE_WARN_ON(xfeature_is_supervisor(i));
+
+ /* Align from the end of the previous feature */
+ if (xfeature_is_aligned(i))
+ paranoid_xstate_size = ALIGN(paranoid_xstate_size, 64);
+ /*
+ * The offset of a given state in the non-compacted
+ * format is given to us in a CPUID leaf. We check
+ * them for being ordered (increasing offsets) in
+ * setup_xstate_features().
+ */
+ if (!using_compacted_format())
+ paranoid_xstate_size = xfeature_uncompacted_offset(i);
+ /*
+ * The compacted-format offset always depends on where
+ * the previous state ended.
+ */
+ paranoid_xstate_size += xfeature_size(i);
+ }
+ XSTATE_WARN_ON(paranoid_xstate_size != xstate_size);
+}
+
/*
* Calculate total size of enabled xstates in XCR0/xfeatures_mask.
+ *
+ * Note the SDM's wording here. "sub-function 0" only enumerates
+ * the size of the *user* states. If we use it to size a buffer
+ * that we use 'XSAVES' on, we could potentially overflow the
+ * buffer because 'XSAVES' saves system states too.
+ *
+ * Note that we do not currently set any bits on IA32_XSS so
+ * 'XCR0 | IA32_XSS == XCR0' for now.
*/
-static void __init init_xstate_size(void)
+static unsigned int __init calculate_xstate_size(void)
{
unsigned int eax, ebx, ecx, edx;
- int i;
+ unsigned int calculated_xstate_size;
if (!cpu_has_xsaves) {
+ /*
+ * - CPUID function 0DH, sub-function 0:
+ * EBX enumerates the size (in bytes) required by
+ * the XSAVE instruction for an XSAVE area
+ * containing all the *user* state components
+ * corresponding to bits currently set in XCR0.
+ */
cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
- xstate_size = ebx;
- return;
+ calculated_xstate_size = ebx;
+ } else {
+ /*
+ * - CPUID function 0DH, sub-function 1:
+ * EBX enumerates the size (in bytes) required by
+ * the XSAVES instruction for an XSAVE area
+ * containing all the state components
+ * corresponding to bits currently set in
+ * XCR0 | IA32_XSS.
+ */
+ cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
+ calculated_xstate_size = ebx;
}
+ return calculated_xstate_size;
+}
- xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
- for (i = 2; i < 64; i++) {
- if (test_bit(i, (unsigned long *)&xfeatures_mask)) {
- cpuid_count(XSTATE_CPUID, i, &eax, &ebx, &ecx, &edx);
- xstate_size += eax;
- }
- }
+/*
+ * Will the runtime-enumerated 'xstate_size' fit in the init
+ * task's statically-allocated buffer?
+ */
+static bool is_supported_xstate_size(unsigned int test_xstate_size)
+{
+ if (test_xstate_size <= sizeof(union fpregs_state))
+ return true;
+
+ pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
+ sizeof(union fpregs_state), test_xstate_size);
+ return false;
+}
+
+static int init_xstate_size(void)
+{
+ /* Recompute the context size for enabled features: */
+ unsigned int possible_xstate_size = calculate_xstate_size();
+
+ /* Ensure we have the space to store all enabled: */
+ if (!is_supported_xstate_size(possible_xstate_size))
+ return -EINVAL;
+
+ /*
+ * The size is OK, we are definitely going to use xsave,
+ * make it known to the world that we need more space.
+ */
+ xstate_size = possible_xstate_size;
+ do_extra_xstate_size_checks();
+ return 0;
+}
+
+/*
+ * We enabled the XSAVE hardware, but something went wrong and
+ * we can not use it. Disable it.
+ */
+static void fpu__init_disable_system_xstate(void)
+{
+ xfeatures_mask = 0;
+ cr4_clear_bits(X86_CR4_OSXSAVE);
+ fpu__xstate_clear_all_cpu_caps();
}
/*
@@ -320,7 +612,8 @@ static void __init init_xstate_size(void)
void __init fpu__init_system_xstate(void)
{
unsigned int eax, ebx, ecx, edx;
- static int on_boot_cpu = 1;
+ static int on_boot_cpu __initdata = 1;
+ int err;
WARN_ON_FPU(!on_boot_cpu);
on_boot_cpu = 0;
@@ -338,26 +631,28 @@ void __init fpu__init_system_xstate(void)
cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
xfeatures_mask = eax + ((u64)edx << 32);
- if ((xfeatures_mask & XSTATE_FPSSE) != XSTATE_FPSSE) {
+ if ((xfeatures_mask & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
pr_err("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n", xfeatures_mask);
BUG();
}
- /* Support only the state known to the OS: */
- xfeatures_mask = xfeatures_mask & XCNTXT_MASK;
+ xfeatures_mask &= fpu__get_supported_xfeatures_mask();
/* Enable xstate instructions to be able to continue with initialization: */
fpu__init_cpu_xstate();
-
- /* Recompute the context size for enabled features: */
- init_xstate_size();
+ err = init_xstate_size();
+ if (err) {
+ /* something went wrong, boot without any XSAVE support */
+ fpu__init_disable_system_xstate();
+ return;
+ }
update_regset_xstate_info(xstate_size, xfeatures_mask);
fpu__init_prepare_fx_sw_frame();
setup_init_fpu_buf();
setup_xstate_comp();
- pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is 0x%x bytes, using '%s' format.\n",
+ pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n",
xfeatures_mask,
xstate_size,
cpu_has_xsaves ? "compacted" : "standard");
@@ -388,7 +683,7 @@ void fpu__resume_cpu(void)
* Inputs:
* xstate: the thread's storage area for all FPU data
* xstate_feature: state which is defined in xsave.h (e.g.
- * XSTATE_FP, XSTATE_SSE, etc...)
+ * XFEATURE_MASK_FP, XFEATURE_MASK_SSE, etc...)
* Output:
* address of the state in the xsave area, or NULL if the
* field is not present in the xsave buffer.
@@ -402,7 +697,6 @@ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature)
if (!boot_cpu_has(X86_FEATURE_XSAVE))
return NULL;
- xsave = &current->thread.fpu.state.xsave;
/*
* We should not ever be requesting features that we
* have not enabled. Remember that pcntxt_mask is
@@ -439,8 +733,8 @@ EXPORT_SYMBOL_GPL(get_xsave_addr);
* Note that this only works on the current task.
*
* Inputs:
- * @xsave_state: state which is defined in xsave.h (e.g. XSTATE_FP,
- * XSTATE_SSE, etc...)
+ * @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP,
+ * XFEATURE_MASK_SSE, etc...)
* Output:
* address of the state in the xsave area or NULL if the state
* is not present or is in its 'init state'.
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 8b7b0a5..702547c 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -81,9 +81,9 @@ within(unsigned long addr, unsigned long start, unsigned long end)
static unsigned long text_ip_addr(unsigned long ip)
{
/*
- * On x86_64, kernel text mappings are mapped read-only with
- * CONFIG_DEBUG_RODATA. So we use the kernel identity mapping instead
- * of the kernel text mapping to modify the kernel text.
+ * On x86_64, kernel text mappings are mapped read-only, so we use
+ * the kernel identity mapping instead of the kernel text mapping
+ * to modify the kernel text.
*
* For 32bit kernels, these mappings are same and we can use
* kernel identity mapping to modify code.
@@ -105,14 +105,14 @@ ftrace_modify_code_direct(unsigned long ip, unsigned const char *old_code,
{
unsigned char replaced[MCOUNT_INSN_SIZE];
+ ftrace_expected = old_code;
+
/*
- * Note: Due to modules and __init, code can
- * disappear and change, we need to protect against faulting
- * as well as code changing. We do this by using the
- * probe_kernel_* functions.
- *
- * No real locking needed, this code is run through
- * kstop_machine, or before SMP starts.
+ * Note:
+ * We are paranoid about modifying text, as if a bug was to happen, it
+ * could cause us to read or write to someplace that could cause harm.
+ * Carefully read and modify the code with probe_kernel_*(), and make
+ * sure what we read is what we expected it to be before modifying it.
*/
/* read the text we want to modify */
@@ -154,6 +154,8 @@ int ftrace_make_nop(struct module *mod,
if (addr == MCOUNT_ADDR)
return ftrace_modify_code_direct(rec->ip, old, new);
+ ftrace_expected = NULL;
+
/* Normal cases use add_brk_on_nop */
WARN_ONCE(1, "invalid use of ftrace_make_nop");
return -EINVAL;
@@ -220,6 +222,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
WARN_ON(1);
+ ftrace_expected = NULL;
return -EINVAL;
}
@@ -314,6 +317,8 @@ static int add_break(unsigned long ip, const char *old)
if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT;
+ ftrace_expected = old;
+
/* Make sure it is what we expect it to be */
if (memcmp(replaced, old, MCOUNT_INSN_SIZE) != 0)
return -EINVAL;
@@ -413,6 +418,8 @@ static int remove_breakpoint(struct dyn_ftrace *rec)
ftrace_addr = ftrace_get_addr_curr(rec);
nop = ftrace_call_replace(ip, ftrace_addr);
+ ftrace_expected = nop;
+
if (memcmp(&ins[1], &nop[1], MCOUNT_INSN_SIZE - 1) != 0)
return -EINVAL;
}
@@ -556,6 +563,7 @@ void ftrace_replace_code(int enable)
run_sync();
report = "updating code";
+ count = 0;
for_ftrace_rec_iter(iter) {
rec = ftrace_rec_iter_record(iter);
@@ -563,11 +571,13 @@ void ftrace_replace_code(int enable)
ret = add_update(rec, enable);
if (ret)
goto remove_breakpoints;
+ count++;
}
run_sync();
report = "removing breakpoints";
+ count = 0;
for_ftrace_rec_iter(iter) {
rec = ftrace_rec_iter_record(iter);
@@ -575,6 +585,7 @@ void ftrace_replace_code(int enable)
ret = finish_update(rec, enable);
if (ret)
goto remove_breakpoints;
+ count++;
}
run_sync();
@@ -686,9 +697,8 @@ static inline void tramp_free(void *tramp) { }
#endif
/* Defined as markers to the end of the ftrace default trampolines */
-extern void ftrace_caller_end(void);
extern void ftrace_regs_caller_end(void);
-extern void ftrace_return(void);
+extern void ftrace_epilogue(void);
extern void ftrace_caller_op_ptr(void);
extern void ftrace_regs_caller_op_ptr(void);
@@ -735,7 +745,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
op_offset = (unsigned long)ftrace_regs_caller_op_ptr;
} else {
start_offset = (unsigned long)ftrace_caller;
- end_offset = (unsigned long)ftrace_caller_end;
+ end_offset = (unsigned long)ftrace_epilogue;
op_offset = (unsigned long)ftrace_caller_op_ptr;
}
@@ -743,7 +753,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
/*
* Allocate enough size to store the ftrace_caller code,
- * the jmp to ftrace_return, as well as the address of
+ * the jmp to ftrace_epilogue, as well as the address of
* the ftrace_ops this trampoline is used for.
*/
trampoline = alloc_tramp(size + MCOUNT_INSN_SIZE + sizeof(void *));
@@ -761,8 +771,8 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
ip = (unsigned long)trampoline + size;
- /* The trampoline ends with a jmp to ftrace_return */
- jmp = ftrace_jmp_replace(ip, (unsigned long)ftrace_return);
+ /* The trampoline ends with a jmp to ftrace_epilogue */
+ jmp = ftrace_jmp_replace(ip, (unsigned long)ftrace_epilogue);
memcpy(trampoline + size, jmp, MCOUNT_INSN_SIZE);
/*
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index f129a9a..1f4422d 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -40,13 +40,8 @@ pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
/* Wipe all early page tables except for the kernel symbol map */
static void __init reset_early_page_tables(void)
{
- unsigned long i;
-
- for (i = 0; i < PTRS_PER_PGD-1; i++)
- early_level4_pgt[i].pgd = 0;
-
+ memset(early_level4_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1));
next_early_pgt = 0;
-
write_cr3(__pa_nodebug(early_level4_pgt));
}
@@ -54,7 +49,6 @@ static void __init reset_early_page_tables(void)
int __init early_make_pgtable(unsigned long address)
{
unsigned long physaddr = address - __PAGE_OFFSET;
- unsigned long i;
pgdval_t pgd, *pgd_p;
pudval_t pud, *pud_p;
pmdval_t pmd, *pmd_p;
@@ -81,8 +75,7 @@ again:
}
pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++];
- for (i = 0; i < PTRS_PER_PUD; i++)
- pud_p[i] = 0;
+ memset(pud_p, 0, sizeof(*pud_p) * PTRS_PER_PUD);
*pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
}
pud_p += pud_index(address);
@@ -97,8 +90,7 @@ again:
}
pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++];
- for (i = 0; i < PTRS_PER_PMD; i++)
- pmd_p[i] = 0;
+ memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD);
*pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
}
pmd = (physaddr & PMD_MASK) + early_pmd_flags;
@@ -192,5 +184,13 @@ void __init x86_64_start_reservations(char *real_mode_data)
reserve_ebda_region();
+ switch (boot_params.hdr.hardware_subarch) {
+ case X86_SUBARCH_INTEL_MID:
+ x86_intel_mid_early_setup();
+ break;
+ default:
+ break;
+ }
+
start_kernel();
}
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 0e2d96f..54cdbd2 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -19,7 +19,7 @@
#include <asm/setup.h>
#include <asm/processor-flags.h>
#include <asm/msr-index.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/percpu.h>
#include <asm/nops.h>
#include <asm/bootparam.h>
@@ -152,7 +152,7 @@ ENTRY(startup_32)
movl %eax, pa(olpc_ofw_pgd)
#endif
-#ifdef CONFIG_MICROCODE_EARLY
+#ifdef CONFIG_MICROCODE
/* Early load ucode on BSP. */
call load_ucode_bsp
#endif
@@ -311,12 +311,11 @@ ENTRY(startup_32_smp)
movl %eax,%ss
leal -__PAGE_OFFSET(%ecx),%esp
-#ifdef CONFIG_MICROCODE_EARLY
+#ifdef CONFIG_MICROCODE
/* Early load ucode on AP. */
call load_ucode_ap
#endif
-
default_entry:
#define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \
X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \
@@ -390,6 +389,12 @@ default_entry:
/* Make changes effective */
wrmsr
+ /*
+ * And make sure that all the mappings we set up have NX set from
+ * the beginning.
+ */
+ orl $(1 << (_PAGE_BIT_NX - 32)), pa(__supported_pte_mask + 4)
+
enable_paging:
/*
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 1d40ca8..22fbf9d 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -38,7 +38,6 @@
#define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET)
-L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
L4_START_KERNEL = pgd_index(__START_KERNEL_map)
L3_START_KERNEL = pud_index(__START_KERNEL_map)
@@ -65,6 +64,9 @@ startup_64:
* tables and then reload them.
*/
+ /* Sanitize CPU configuration */
+ call verify_cpu
+
/*
* Compute the delta between the address I am compiled to run at and the
* address I am actually running at.
@@ -73,9 +75,7 @@ startup_64:
subq $_text - __START_KERNEL_map, %rbp
/* Is the address not 2M aligned? */
- movq %rbp, %rax
- andl $~PMD_PAGE_MASK, %eax
- testl %eax, %eax
+ testl $~PMD_PAGE_MASK, %ebp
jnz bad_address
/*
@@ -174,6 +174,9 @@ ENTRY(secondary_startup_64)
* after the boot processor executes this code.
*/
+ /* Sanitize CPU configuration */
+ call verify_cpu
+
movq $(init_level4_pgt - __START_KERNEL_map), %rax
1:
@@ -288,6 +291,8 @@ ENTRY(secondary_startup_64)
pushq %rax # target address in negative space
lretq
+#include "verify_cpu.S"
+
#ifdef CONFIG_HOTPLUG_CPU
/*
* Boot CPU0 entry point. It's called from play_dead(). Everything has been set
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 88b4da3..be0ebbb 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -12,6 +12,7 @@
#include <linux/pm.h>
#include <linux/io.h>
+#include <asm/cpufeature.h>
#include <asm/irqdomain.h>
#include <asm/fixmap.h>
#include <asm/hpet.h>
@@ -37,10 +38,10 @@
*/
unsigned long hpet_address;
u8 hpet_blockid; /* OS timer block num */
-u8 hpet_msi_disable;
+bool hpet_msi_disable;
#ifdef CONFIG_PCI_MSI
-static unsigned long hpet_num_timers;
+static unsigned int hpet_num_timers;
#endif
static void __iomem *hpet_virt_address;
@@ -86,9 +87,9 @@ static inline void hpet_clear_mapping(void)
/*
* HPET command line enable / disable
*/
-int boot_hpet_disable;
-int hpet_force_user;
-static int hpet_verbose;
+bool boot_hpet_disable;
+bool hpet_force_user;
+static bool hpet_verbose;
static int __init hpet_setup(char *str)
{
@@ -98,11 +99,11 @@ static int __init hpet_setup(char *str)
if (next)
*next++ = 0;
if (!strncmp("disable", str, 7))
- boot_hpet_disable = 1;
+ boot_hpet_disable = true;
if (!strncmp("force", str, 5))
- hpet_force_user = 1;
+ hpet_force_user = true;
if (!strncmp("verbose", str, 7))
- hpet_verbose = 1;
+ hpet_verbose = true;
str = next;
}
return 1;
@@ -111,7 +112,7 @@ __setup("hpet=", hpet_setup);
static int __init disable_hpet(char *str)
{
- boot_hpet_disable = 1;
+ boot_hpet_disable = true;
return 1;
}
__setup("nohpet", disable_hpet);
@@ -124,7 +125,7 @@ static inline int is_hpet_capable(void)
/*
* HPET timer interrupt enable / disable
*/
-static int hpet_legacy_int_enabled;
+static bool hpet_legacy_int_enabled;
/**
* is_hpet_enabled - check whether the hpet timer interrupt is enabled
@@ -230,7 +231,7 @@ static struct clock_event_device hpet_clockevent;
static void hpet_stop_counter(void)
{
- unsigned long cfg = hpet_readl(HPET_CFG);
+ u32 cfg = hpet_readl(HPET_CFG);
cfg &= ~HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
}
@@ -272,7 +273,7 @@ static void hpet_enable_legacy_int(void)
cfg |= HPET_CFG_LEGACY;
hpet_writel(cfg, HPET_CFG);
- hpet_legacy_int_enabled = 1;
+ hpet_legacy_int_enabled = true;
}
static void hpet_legacy_clockevent_register(void)
@@ -983,7 +984,7 @@ void hpet_disable(void)
cfg = *hpet_boot_cfg;
else if (hpet_legacy_int_enabled) {
cfg &= ~HPET_CFG_LEGACY;
- hpet_legacy_int_enabled = 0;
+ hpet_legacy_int_enabled = false;
}
cfg &= ~HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
@@ -1121,8 +1122,7 @@ EXPORT_SYMBOL_GPL(hpet_rtc_timer_init);
static void hpet_disable_rtc_channel(void)
{
- unsigned long cfg;
- cfg = hpet_readl(HPET_T1_CFG);
+ u32 cfg = hpet_readl(HPET_T1_CFG);
cfg &= ~HPET_TN_ENABLE;
hpet_writel(cfg, HPET_T1_CFG);
}
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index 50a3fad..2bcfb5f 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -300,6 +300,10 @@ static int arch_build_bp_info(struct perf_event *bp)
return -EINVAL;
if (bp->attr.bp_addr & (bp->attr.bp_len - 1))
return -EINVAL;
+
+ if (!boot_cpu_has(X86_FEATURE_BPEXT))
+ return -EOPNOTSUPP;
+
/*
* It's impossible to use a range breakpoint to fake out
* user vs kernel detection because bp_len - 1 can't
@@ -307,8 +311,6 @@ static int arch_build_bp_info(struct perf_event *bp)
* breakpoints, then we'll have to check for kprobe-blacklisted
* addresses anywhere in the range.
*/
- if (!cpu_has_bpext)
- return -EOPNOTSUPP;
info->mask = bp->attr.bp_len - 1;
info->len = X86_BREAKPOINT_LEN_1;
}
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 16cb827..be22f5a 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -295,16 +295,11 @@ static void unmask_8259A(void)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-static void init_8259A(int auto_eoi)
+static int probe_8259A(void)
{
unsigned long flags;
unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
unsigned char new_val;
-
- i8259A_auto_eoi = auto_eoi;
-
- raw_spin_lock_irqsave(&i8259A_lock, flags);
-
/*
* Check to see if we have a PIC.
* Mask all except the cascade and read
@@ -312,16 +307,28 @@ static void init_8259A(int auto_eoi)
* have a PIC, we will read 0xff as opposed to the
* value we wrote.
*/
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+
outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
outb(probe_val, PIC_MASTER_IMR);
new_val = inb(PIC_MASTER_IMR);
if (new_val != probe_val) {
printk(KERN_INFO "Using NULL legacy PIC\n");
legacy_pic = &null_legacy_pic;
- raw_spin_unlock_irqrestore(&i8259A_lock, flags);
- return;
}
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+ return nr_legacy_irqs();
+}
+
+static void init_8259A(int auto_eoi)
+{
+ unsigned long flags;
+
+ i8259A_auto_eoi = auto_eoi;
+
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+
outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
/*
@@ -379,6 +386,10 @@ static int legacy_pic_irq_pending_noop(unsigned int irq)
{
return 0;
}
+static int legacy_pic_probe(void)
+{
+ return 0;
+}
struct legacy_pic null_legacy_pic = {
.nr_legacy_irqs = 0,
@@ -388,6 +399,7 @@ struct legacy_pic null_legacy_pic = {
.mask_all = legacy_pic_noop,
.restore_mask = legacy_pic_noop,
.init = legacy_pic_int_noop,
+ .probe = legacy_pic_probe,
.irq_pending = legacy_pic_irq_pending_noop,
.make_irq = legacy_pic_uint_noop,
};
@@ -400,6 +412,7 @@ struct legacy_pic default_legacy_pic = {
.mask_all = mask_8259A,
.restore_mask = unmask_8259A,
.init = init_8259A,
+ .probe = probe_8259A,
.irq_pending = i8259A_irq_pending,
.make_irq = make_8259A_irq,
};
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index f8062aa..61521dc 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -462,7 +462,7 @@ void fixup_irqs(void)
* non intr-remapping case, we can't wait till this interrupt
* arrives at this cpu before completing the irq move.
*/
- irq_force_complete_move(irq);
+ irq_force_complete_move(desc);
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
break_affinity = 1;
@@ -470,6 +470,15 @@ void fixup_irqs(void)
}
chip = irq_data_get_irq_chip(data);
+ /*
+ * The interrupt descriptor might have been cleaned up
+ * already, but it is not yet removed from the radix tree
+ */
+ if (!chip) {
+ raw_spin_unlock(&desc->lock);
+ continue;
+ }
+
if (!irqd_can_move_in_process_context(data) && chip->irq_mask)
chip->irq_mask(data);
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index c767cf2..206d0b9 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -72,7 +72,7 @@ bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
{
stack_overflow_check(regs);
- if (unlikely(IS_ERR_OR_NULL(desc)))
+ if (IS_ERR_OR_NULL(desc))
return false;
generic_handle_irq_desc(desc);
diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c
index dc5fa6a..3512ba6 100644
--- a/arch/x86/kernel/irq_work.c
+++ b/arch/x86/kernel/irq_work.c
@@ -1,7 +1,7 @@
/*
* x86 specific code for irq_work
*
- * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra
*/
#include <linux/kernel.h>
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index d6178d9..ed15cd48 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -511,26 +511,31 @@ single_step_cont(struct pt_regs *regs, struct die_args *args)
return NOTIFY_STOP;
}
-static int was_in_debug_nmi[NR_CPUS];
+static DECLARE_BITMAP(was_in_debug_nmi, NR_CPUS);
static int kgdb_nmi_handler(unsigned int cmd, struct pt_regs *regs)
{
+ int cpu;
+
switch (cmd) {
case NMI_LOCAL:
if (atomic_read(&kgdb_active) != -1) {
/* KGDB CPU roundup */
- kgdb_nmicallback(raw_smp_processor_id(), regs);
- was_in_debug_nmi[raw_smp_processor_id()] = 1;
+ cpu = raw_smp_processor_id();
+ kgdb_nmicallback(cpu, regs);
+ set_bit(cpu, was_in_debug_nmi);
touch_nmi_watchdog();
+
return NMI_HANDLED;
}
break;
case NMI_UNKNOWN:
- if (was_in_debug_nmi[raw_smp_processor_id()]) {
- was_in_debug_nmi[raw_smp_processor_id()] = 0;
+ cpu = raw_smp_processor_id();
+
+ if (__test_and_clear_bit(cpu, was_in_debug_nmi))
return NMI_HANDLED;
- }
+
break;
default:
/* do nothing */
@@ -745,9 +750,7 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
int err;
-#ifdef CONFIG_DEBUG_RODATA
char opc[BREAK_INSTR_SIZE];
-#endif /* CONFIG_DEBUG_RODATA */
bpt->type = BP_BREAKPOINT;
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
@@ -756,7 +759,6 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
return err;
err = probe_kernel_write((char *)bpt->bpt_addr,
arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
-#ifdef CONFIG_DEBUG_RODATA
if (!err)
return err;
/*
@@ -773,13 +775,12 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE))
return -EINVAL;
bpt->type = BP_POKE_BREAKPOINT;
-#endif /* CONFIG_DEBUG_RODATA */
+
return err;
}
int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{
-#ifdef CONFIG_DEBUG_RODATA
int err;
char opc[BREAK_INSTR_SIZE];
@@ -796,8 +797,8 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE))
goto knl_write;
return err;
+
knl_write:
-#endif /* CONFIG_DEBUG_RODATA */
return probe_kernel_write((char *)bpt->bpt_addr,
(char *)bpt->saved_instr, BREAK_INSTR_SIZE);
}
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 1deffe6..0f05dee 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -988,7 +988,7 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
* In case the user-specified fault handler returned
* zero, try to fix up.
*/
- if (fixup_exception(regs))
+ if (fixup_exception(regs, trapnr))
return 1;
/*
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 2c7aafa..72cef58 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -32,6 +32,7 @@
static int kvmclock = 1;
static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
static int msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
+static cycle_t kvm_sched_clock_offset;
static int parse_no_kvmclock(char *arg)
{
@@ -44,6 +45,11 @@ early_param("no-kvmclock", parse_no_kvmclock);
static struct pvclock_vsyscall_time_info *hv_clock;
static struct pvclock_wall_clock wall_clock;
+struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
+{
+ return hv_clock;
+}
+
/*
* The wallclock is the time of day when we booted. Since then, some time may
* have elapsed since the hypervisor wrote the data. So we try to account for
@@ -92,6 +98,29 @@ static cycle_t kvm_clock_get_cycles(struct clocksource *cs)
return kvm_clock_read();
}
+static cycle_t kvm_sched_clock_read(void)
+{
+ return kvm_clock_read() - kvm_sched_clock_offset;
+}
+
+static inline void kvm_sched_clock_init(bool stable)
+{
+ if (!stable) {
+ pv_time_ops.sched_clock = kvm_clock_read;
+ return;
+ }
+
+ kvm_sched_clock_offset = kvm_clock_read();
+ pv_time_ops.sched_clock = kvm_sched_clock_read;
+ set_sched_clock_stable();
+
+ printk(KERN_INFO "kvm-clock: using sched offset of %llu cycles\n",
+ kvm_sched_clock_offset);
+
+ BUILD_BUG_ON(sizeof(kvm_sched_clock_offset) >
+ sizeof(((struct pvclock_vcpu_time_info *)NULL)->system_time));
+}
+
/*
* If we don't do that, there is the possibility that the guest
* will calibrate under heavy load - thus, getting a lower lpj -
@@ -248,7 +277,17 @@ void __init kvmclock_init(void)
memblock_free(mem, size);
return;
}
- pv_time_ops.sched_clock = kvm_clock_read;
+
+ if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
+ pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
+
+ cpu = get_cpu();
+ vcpu_time = &hv_clock[cpu].pvti;
+ flags = pvclock_read_flags(vcpu_time);
+
+ kvm_sched_clock_init(flags & PVCLOCK_TSC_STABLE_BIT);
+ put_cpu();
+
x86_platform.calibrate_tsc = kvm_get_tsc_khz;
x86_platform.get_wallclock = kvm_get_wallclock;
x86_platform.set_wallclock = kvm_set_wallclock;
@@ -265,23 +304,12 @@ void __init kvmclock_init(void)
kvm_get_preset_lpj();
clocksource_register_hz(&kvm_clock, NSEC_PER_SEC);
pv_info.name = "KVM";
-
- if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
- pvclock_set_flags(~0);
-
- cpu = get_cpu();
- vcpu_time = &hv_clock[cpu].pvti;
- flags = pvclock_read_flags(vcpu_time);
- if (flags & PVCLOCK_COUNTS_FROM_ZERO)
- set_sched_clock_stable();
- put_cpu();
}
int __init kvm_setup_vsyscall_timeinfo(void)
{
#ifdef CONFIG_X86_64
int cpu;
- int ret;
u8 flags;
struct pvclock_vcpu_time_info *vcpu_time;
unsigned int size;
@@ -301,11 +329,6 @@ int __init kvm_setup_vsyscall_timeinfo(void)
return 1;
}
- if ((ret = pvclock_init_vsyscall(hv_clock, size))) {
- put_cpu();
- return ret;
- }
-
put_cpu();
kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c
index ff3c3101d..92fc1a5 100644
--- a/arch/x86/kernel/livepatch.c
+++ b/arch/x86/kernel/livepatch.c
@@ -20,8 +20,6 @@
#include <linux/module.h>
#include <linux/uaccess.h>
-#include <asm/cacheflush.h>
-#include <asm/page_types.h>
#include <asm/elf.h>
#include <asm/livepatch.h>
@@ -38,12 +36,10 @@
int klp_write_module_reloc(struct module *mod, unsigned long type,
unsigned long loc, unsigned long value)
{
- int ret, numpages, size = 4;
- bool readonly;
+ size_t size = 4;
unsigned long val;
- unsigned long core = (unsigned long)mod->module_core;
- unsigned long core_ro_size = mod->core_ro_size;
- unsigned long core_size = mod->core_size;
+ unsigned long core = (unsigned long)mod->core_layout.base;
+ unsigned long core_size = mod->core_layout.size;
switch (type) {
case R_X86_64_NONE:
@@ -70,21 +66,5 @@ int klp_write_module_reloc(struct module *mod, unsigned long type,
/* loc does not point to any symbol inside the module */
return -EINVAL;
- if (loc < core + core_ro_size)
- readonly = true;
- else
- readonly = false;
-
- /* determine if the relocation spans a page boundary */
- numpages = ((loc & PAGE_MASK) == ((loc + size) & PAGE_MASK)) ? 1 : 2;
-
- if (readonly)
- set_memory_rw(loc & PAGE_MASK, numpages);
-
- ret = probe_kernel_write((void *)loc, &val, size);
-
- if (readonly)
- set_memory_ro(loc & PAGE_MASK, numpages);
-
- return ret;
+ return probe_kernel_write((void *)loc, &val, size);
}
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 819ab3f..ba7fbba 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -385,6 +385,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
return image->fops->cleanup(image->image_loader_data);
}
+#ifdef CONFIG_KEXEC_VERIFY_SIG
int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel,
unsigned long kernel_len)
{
@@ -395,6 +396,7 @@ int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel,
return image->fops->verify_sig(kernel, kernel_len);
}
+#endif
/*
* Apply purgatory relocations.
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
index 94ea120..ed48a9f 100644
--- a/arch/x86/kernel/mcount_64.S
+++ b/arch/x86/kernel/mcount_64.S
@@ -168,12 +168,14 @@ GLOBAL(ftrace_call)
restore_mcount_regs
/*
- * The copied trampoline must call ftrace_return as it
+ * The copied trampoline must call ftrace_epilogue as it
* still may need to call the function graph tracer.
+ *
+ * The code up to this label is copied into trampolines so
+ * think twice before adding any new code or changing the
+ * layout here.
*/
-GLOBAL(ftrace_caller_end)
-
-GLOBAL(ftrace_return)
+GLOBAL(ftrace_epilogue)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
GLOBAL(ftrace_graph_call)
@@ -244,14 +246,14 @@ GLOBAL(ftrace_regs_call)
popfq
/*
- * As this jmp to ftrace_return can be a short jump
+ * As this jmp to ftrace_epilogue can be a short jump
* it must not be copied into the trampoline.
* The trampoline will add the code to jump
* to the return.
*/
GLOBAL(ftrace_regs_caller_end)
- jmp ftrace_return
+ jmp ftrace_epilogue
END(ftrace_regs_caller)
@@ -278,6 +280,12 @@ trace:
/* save_mcount_regs fills in first two parameters */
save_mcount_regs
+ /*
+ * When DYNAMIC_FTRACE is not defined, ARCH_SUPPORTS_FTRACE_OPS is not
+ * set (see include/asm/ftrace.h and include/linux/ftrace.h). Only the
+ * ip and parent ip are used and the list function is called when
+ * function tracing is enabled.
+ */
call *ftrace_trace_function
restore_mcount_regs
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 30ca760..97340f2 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -408,7 +408,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
processor.cpuflag = CPU_ENABLED;
processor.cpufeature = (boot_cpu_data.x86 << 8) |
(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
- processor.featureflag = boot_cpu_data.x86_capability[0];
+ processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
processor.reserved[0] = 0;
processor.reserved[1] = 0;
for (i = 0; i < 2; i++) {
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 113e707..7f3550a 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -40,33 +40,11 @@
#include <linux/uaccess.h>
#include <linux/gfp.h>
-#include <asm/processor.h>
+#include <asm/cpufeature.h>
#include <asm/msr.h>
static struct class *msr_class;
-static loff_t msr_seek(struct file *file, loff_t offset, int orig)
-{
- loff_t ret;
- struct inode *inode = file_inode(file);
-
- mutex_lock(&inode->i_mutex);
- switch (orig) {
- case SEEK_SET:
- file->f_pos = offset;
- ret = file->f_pos;
- break;
- case SEEK_CUR:
- file->f_pos += offset;
- ret = file->f_pos;
- break;
- default:
- ret = -EINVAL;
- }
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-
static ssize_t msr_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -194,7 +172,7 @@ static int msr_open(struct inode *inode, struct file *file)
*/
static const struct file_operations msr_fops = {
.owner = THIS_MODULE,
- .llseek = msr_seek,
+ .llseek = no_seek_end_llseek,
.read = msr_read,
.write = msr_write,
.open = msr_open,
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 697f90d..04b132a 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -29,6 +29,8 @@
#include <asm/mach_traps.h>
#include <asm/nmi.h>
#include <asm/x86_init.h>
+#include <asm/reboot.h>
+#include <asm/cache.h>
#define CREATE_TRACE_POINTS
#include <trace/events/nmi.h>
@@ -68,7 +70,7 @@ struct nmi_stats {
static DEFINE_PER_CPU(struct nmi_stats, nmi_stats);
-static int ignore_nmis;
+static int ignore_nmis __read_mostly;
int unknown_nmi_panic;
/*
@@ -231,7 +233,7 @@ pci_serr_error(unsigned char reason, struct pt_regs *regs)
#endif
if (panic_on_unrecovered_nmi)
- panic("NMI: Not continuing");
+ nmi_panic(regs, "NMI: Not continuing");
pr_emerg("Dazed and confused, but trying to continue\n");
@@ -255,8 +257,16 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
reason, smp_processor_id());
show_regs(regs);
- if (panic_on_io_nmi)
- panic("NMI IOCK error: Not continuing");
+ if (panic_on_io_nmi) {
+ nmi_panic(regs, "NMI IOCK error: Not continuing");
+
+ /*
+ * If we end up here, it means we have received an NMI while
+ * processing panic(). Simply return without delaying and
+ * re-enabling NMIs.
+ */
+ return;
+ }
/* Re-enable the IOCK line, wait for a few seconds */
reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_IOCHK;
@@ -297,7 +307,7 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
pr_emerg("Do you have a strange power saving mode enabled?\n");
if (unknown_nmi_panic || panic_on_unrecovered_nmi)
- panic("NMI: Not continuing");
+ nmi_panic(regs, "NMI: Not continuing");
pr_emerg("Dazed and confused, but trying to continue\n");
}
@@ -348,8 +358,19 @@ static void default_do_nmi(struct pt_regs *regs)
return;
}
- /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
- raw_spin_lock(&nmi_reason_lock);
+ /*
+ * Non-CPU-specific NMI: NMI sources can be processed on any CPU.
+ *
+ * Another CPU may be processing panic routines while holding
+ * nmi_reason_lock. Check if the CPU issued the IPI for crash dumping,
+ * and if so, call its callback directly. If there is no CPU preparing
+ * crash dump, we simply loop here.
+ */
+ while (!raw_spin_trylock(&nmi_reason_lock)) {
+ run_crash_ipi_callback(regs);
+ cpu_relax();
+ }
+
reason = x86_platform.get_nmi_reason();
if (reason & NMI_REASON_MASK) {
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index c2130ae..f08ac28 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -74,16 +74,6 @@ void __init default_banner(void)
/* Undefined instruction for dealing with missing ops pointers. */
static const unsigned char ud2a[] = { 0x0f, 0x0b };
-unsigned paravirt_patch_nop(void)
-{
- return 0;
-}
-
-unsigned paravirt_patch_ignore(unsigned len)
-{
- return len;
-}
-
struct branch {
unsigned char opcode;
u32 delta;
@@ -133,7 +123,6 @@ static void *get_call_destination(u8 type)
.pv_time_ops = pv_time_ops,
.pv_cpu_ops = pv_cpu_ops,
.pv_irq_ops = pv_irq_ops,
- .pv_apic_ops = pv_apic_ops,
.pv_mmu_ops = pv_mmu_ops,
#ifdef CONFIG_PARAVIRT_SPINLOCKS
.pv_lock_ops = pv_lock_ops,
@@ -152,8 +141,7 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
/* If there's no function, patch it with a ud2a (BUG) */
ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
else if (opfunc == _paravirt_nop)
- /* If the operation is a nop, then nop the callsite */
- ret = paravirt_patch_nop();
+ ret = 0;
/* identity functions just return their single argument */
else if (opfunc == _paravirt_ident_32)
@@ -162,10 +150,6 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
ret = paravirt_patch_ident_64(insnbuf, len);
else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
-#ifdef CONFIG_X86_32
- type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) ||
-#endif
- type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) ||
type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret64))
/* If operation requires a jmp, then jmp */
ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
@@ -220,8 +204,6 @@ static u64 native_steal_clock(int cpu)
/* These are in entry.S */
extern void native_iret(void);
-extern void native_irq_enable_sysexit(void);
-extern void native_usergs_sysret32(void);
extern void native_usergs_sysret64(void);
static struct resource reserve_ioports = {
@@ -379,13 +361,7 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
.load_sp0 = native_load_sp0,
-#if defined(CONFIG_X86_32)
- .irq_enable_sysexit = native_irq_enable_sysexit,
-#endif
#ifdef CONFIG_X86_64
-#ifdef CONFIG_IA32_EMULATION
- .usergs_sysret32 = native_usergs_sysret32,
-#endif
.usergs_sysret64 = native_usergs_sysret64,
#endif
.iret = native_iret,
@@ -403,12 +379,6 @@ NOKPROBE_SYMBOL(native_get_debugreg);
NOKPROBE_SYMBOL(native_set_debugreg);
NOKPROBE_SYMBOL(native_load_idt);
-struct pv_apic_ops pv_apic_ops = {
-#ifdef CONFIG_X86_LOCAL_APIC
- .startup_ipi_hook = paravirt_nop,
-#endif
-};
-
#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
/* 32-bit pagetable entries */
#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32)
@@ -444,9 +414,6 @@ struct pv_mmu_ops pv_mmu_ops = {
.set_pmd = native_set_pmd,
.set_pmd_at = native_set_pmd_at,
.pte_update = paravirt_nop,
- .pte_update_defer = paravirt_nop,
- .pmd_update = paravirt_nop,
- .pmd_update_defer = paravirt_nop,
.ptep_modify_prot_start = __ptep_modify_prot_start,
.ptep_modify_prot_commit = __ptep_modify_prot_commit,
@@ -492,6 +459,5 @@ struct pv_mmu_ops pv_mmu_ops = {
EXPORT_SYMBOL_GPL(pv_time_ops);
EXPORT_SYMBOL (pv_cpu_ops);
EXPORT_SYMBOL (pv_mmu_ops);
-EXPORT_SYMBOL_GPL(pv_apic_ops);
EXPORT_SYMBOL_GPL(pv_info);
EXPORT_SYMBOL (pv_irq_ops);
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c
index c89f50a..158dc06 100644
--- a/arch/x86/kernel/paravirt_patch_32.c
+++ b/arch/x86/kernel/paravirt_patch_32.c
@@ -5,7 +5,6 @@ DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
DEF_NATIVE(pv_cpu_ops, iret, "iret");
-DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "sti; sysexit");
DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
@@ -46,7 +45,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
PATCH_SITE(pv_irq_ops, restore_fl);
PATCH_SITE(pv_irq_ops, save_fl);
PATCH_SITE(pv_cpu_ops, iret);
- PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
PATCH_SITE(pv_mmu_ops, read_cr2);
PATCH_SITE(pv_mmu_ops, read_cr3);
PATCH_SITE(pv_mmu_ops, write_cr3);
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c
index 8aa0558..e70087a 100644
--- a/arch/x86/kernel/paravirt_patch_64.c
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -13,9 +13,7 @@ DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)");
DEF_NATIVE(pv_cpu_ops, clts, "clts");
DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd");
-DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "swapgs; sti; sysexit");
DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq");
-DEF_NATIVE(pv_cpu_ops, usergs_sysret32, "swapgs; sysretl");
DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs");
DEF_NATIVE(, mov32, "mov %edi, %eax");
@@ -55,7 +53,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
PATCH_SITE(pv_irq_ops, save_fl);
PATCH_SITE(pv_irq_ops, irq_enable);
PATCH_SITE(pv_irq_ops, irq_disable);
- PATCH_SITE(pv_cpu_ops, usergs_sysret32);
PATCH_SITE(pv_cpu_ops, usergs_sysret64);
PATCH_SITE(pv_cpu_ops, swapgs);
PATCH_SITE(pv_mmu_ops, read_cr2);
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 0497f71..833b1d3 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -180,13 +180,13 @@ static void calioc2_dump_error_regs(struct iommu_table *tbl);
static void calgary_init_bitmap_from_tce_table(struct iommu_table *tbl);
static void get_tce_space_from_tar(void);
-static struct cal_chipset_ops calgary_chip_ops = {
+static const struct cal_chipset_ops calgary_chip_ops = {
.handle_quirks = calgary_handle_quirks,
.tce_cache_blast = calgary_tce_cache_blast,
.dump_error_regs = calgary_dump_error_regs
};
-static struct cal_chipset_ops calioc2_chip_ops = {
+static const struct cal_chipset_ops calioc2_chip_ops = {
.handle_quirks = calioc2_handle_quirks,
.tce_cache_blast = calioc2_tce_cache_blast,
.dump_error_regs = calioc2_dump_error_regs
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index cd99433..6ba014c 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -90,7 +90,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
again:
page = NULL;
/* CMA can be used only in the context which permits sleeping */
- if (flag & __GFP_WAIT) {
+ if (gfpflags_allow_blocking(flag)) {
page = dma_alloc_from_contiguous(dev, count, get_order(size));
if (page && page_to_phys(page) + size > dma_mask) {
dma_release_from_contiguous(dev, page, count);
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index adf0392..7c577a1 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -88,7 +88,7 @@ int __init pci_swiotlb_detect_4gb(void)
{
/* don't initialize swiotlb if iommu=off (no_iommu=1) */
#ifdef CONFIG_X86_64
- if (!no_iommu && max_pfn > MAX_DMA32_PFN)
+ if (!no_iommu && max_possible_pfn > MAX_DMA32_PFN)
swiotlb = 1;
#endif
return swiotlb;
diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c
index 4f00b63..92f7014 100644
--- a/arch/x86/kernel/pmem.c
+++ b/arch/x86/kernel/pmem.c
@@ -4,10 +4,22 @@
*/
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/ioport.h>
+
+static int found(u64 start, u64 end, void *data)
+{
+ return 1;
+}
static __init int register_e820_pmem(void)
{
struct platform_device *pdev;
+ int rc;
+
+ rc = walk_iomem_res_desc(IORES_DESC_PERSISTENT_MEMORY_LEGACY,
+ IORESOURCE_MEM, 0, -1, NULL, found);
+ if (rc <= 0)
+ return 0;
/*
* See drivers/nvdimm/e820.c for the implementation, this is
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 9f7c21c..2915d54 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -57,6 +57,9 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
*/
.io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 },
#endif
+#ifdef CONFIG_X86_32
+ .SYSENTER_stack_canary = STACK_END_MAGIC,
+#endif
};
EXPORT_PER_CPU_SYMBOL(cpu_tss);
@@ -418,9 +421,9 @@ static void mwait_idle(void)
if (!current_set_polling_and_test()) {
trace_cpu_idle_rcuidle(1, smp_processor_id());
if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
- smp_mb(); /* quirk */
+ mb(); /* quirk */
clflush((void *)&current_thread_info()->flags);
- smp_mb(); /* quirk */
+ mb(); /* quirk */
}
__monitor((void *)&current_thread_info()->flags, 0, 0);
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 737527b..9f95091 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -280,14 +280,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
set_iopl_mask(next->iopl);
/*
- * If it were not for PREEMPT_ACTIVE we could guarantee that the
- * preempt_count of all tasks was equal here and this would not be
- * needed.
- */
- task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count);
- this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count);
-
- /*
* Now maybe handle debug registers and/or IO bitmaps
*/
if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b35921a..b9d99e0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -125,7 +125,7 @@ void release_thread(struct task_struct *dead_task)
if (dead_task->mm->context.ldt) {
pr_warn("WARNING: dead process %s still has LDT? <%p/%d>\n",
dead_task->comm,
- dead_task->mm->context.ldt,
+ dead_task->mm->context.ldt->entries,
dead_task->mm->context.ldt->size);
BUG();
}
@@ -332,7 +332,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/*
* Switch FS and GS.
*
- * These are even more complicated than FS and GS: they have
+ * These are even more complicated than DS and ES: they have
* 64-bit bases are that controlled by arch_prctl. Those bases
* only differ from the values in the GDT or LDT if the selector
* is 0.
@@ -401,14 +401,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*/
this_cpu_write(current_task, next_p);
- /*
- * If it were not for PREEMPT_ACTIVE we could guarantee that the
- * preempt_count of all tasks was equal here and this would not be
- * needed.
- */
- task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count);
- this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count);
-
/* Reload esp0 and ss1. This changes current_thread_info(). */
load_sp0(tss, next);
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 558f50e..32e9d9c 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -124,21 +124,6 @@ const char *regs_query_register_name(unsigned int offset)
return NULL;
}
-static const int arg_offs_table[] = {
-#ifdef CONFIG_X86_32
- [0] = offsetof(struct pt_regs, ax),
- [1] = offsetof(struct pt_regs, dx),
- [2] = offsetof(struct pt_regs, cx)
-#else /* CONFIG_X86_64 */
- [0] = offsetof(struct pt_regs, di),
- [1] = offsetof(struct pt_regs, si),
- [2] = offsetof(struct pt_regs, dx),
- [3] = offsetof(struct pt_regs, cx),
- [4] = offsetof(struct pt_regs, r8),
- [5] = offsetof(struct pt_regs, r9)
-#endif
-};
-
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 2f355d2..99bfc02 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -140,27 +140,3 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
}
-
-#ifdef CONFIG_X86_64
-/*
- * Initialize the generic pvclock vsyscall state. This will allocate
- * a/some page(s) for the per-vcpu pvclock information, set up a
- * fixmap mapping for the page(s)
- */
-
-int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
- int size)
-{
- int idx;
-
- WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE);
-
- for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) {
- __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx,
- __pa(i) + (idx*PAGE_SIZE),
- PAGE_KERNEL_VVAR);
- }
-
- return 0;
-}
-#endif
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 176a0f9..cc457ff 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -524,7 +524,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E6XX_CU,
*/
static void force_disable_hpet_msi(struct pci_dev *unused)
{
- hpet_msi_disable = 1;
+ hpet_msi_disable = true;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 02693dd..ab0adc0 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -182,6 +182,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
},
},
+ { /* Handle problems with rebooting on the iMac10,1. */
+ .callback = set_pci_reboot,
+ .ident = "Apple iMac10,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"),
+ },
+ },
/* ASRock */
{ /* Handle problems with rebooting on ASRock Q1900DC-ITX */
@@ -718,6 +726,7 @@ static int crashing_cpu;
static nmi_shootdown_cb shootdown_callback;
static atomic_t waiting_for_crash_ipi;
+static int crash_ipi_issued;
static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
{
@@ -780,6 +789,9 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
smp_send_nmi_allbutself();
+ /* Kick CPUs looping in NMI context. */
+ WRITE_ONCE(crash_ipi_issued, 1);
+
msecs = 1000; /* Wait at most a second for the other cpus to stop */
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
mdelay(1);
@@ -788,9 +800,35 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
/* Leave the nmi callback set */
}
+
+/*
+ * Check if the crash dumping IPI got issued and if so, call its callback
+ * directly. This function is used when we have already been in NMI handler.
+ * It doesn't return.
+ */
+void run_crash_ipi_callback(struct pt_regs *regs)
+{
+ if (crash_ipi_issued)
+ crash_nmi_callback(0, regs);
+}
+
+/* Override the weak function in kernel/panic.c */
+void nmi_panic_self_stop(struct pt_regs *regs)
+{
+ while (1) {
+ /* If no CPU is preparing crash dump, we simply loop here. */
+ run_crash_ipi_callback(regs);
+ cpu_relax();
+ }
+}
+
#else /* !CONFIG_SMP */
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
{
/* No other CPUs to shoot down */
}
+
+void run_crash_ipi_callback(struct pt_regs *regs)
+{
+}
#endif
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index cd96852..4af8d06 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -200,6 +200,9 @@ static __init int add_rtc_cmos(void)
}
#endif
+ if (paravirt_enabled() && !paravirt_has(RTC))
+ return -ENODEV;
+
platform_device_register(&rtc_device);
dev_info(&rtc_device.dev,
"registered platform RTC device (no PNP device found)\n");
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a3cccbf..aa52c10 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -111,6 +111,7 @@
#include <asm/mce.h>
#include <asm/alternative.h>
#include <asm/prom.h>
+#include <asm/microcode.h>
/*
* max_low_pfn_mapped: highest direct mapped pfn under 4GB
@@ -151,21 +152,21 @@ static struct resource data_resource = {
.name = "Kernel data",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource code_resource = {
.name = "Kernel code",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
static struct resource bss_resource = {
.name = "Kernel bss",
.start = 0,
.end = 0,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+ .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
};
@@ -480,34 +481,34 @@ static void __init memblock_x86_reserve_range_setup_data(void)
#ifdef CONFIG_KEXEC_CORE
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGN (16 << 20)
+
/*
* Keep the crash kernel below this limit. On 32 bits earlier kernels
* would limit the kernel to the low 512 MiB due to mapping restrictions.
* On 64bit, old kexec-tools need to under 896MiB.
*/
#ifdef CONFIG_X86_32
-# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20)
+# define CRASH_ADDR_LOW_MAX (512 << 20)
+# define CRASH_ADDR_HIGH_MAX (512 << 20)
#else
-# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20)
-# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM
+# define CRASH_ADDR_LOW_MAX (896UL << 20)
+# define CRASH_ADDR_HIGH_MAX MAXMEM
#endif
-static void __init reserve_crashkernel_low(void)
+static int __init reserve_crashkernel_low(void)
{
#ifdef CONFIG_X86_64
- const unsigned long long alignment = 16<<20; /* 16M */
- unsigned long long low_base = 0, low_size = 0;
+ unsigned long long base, low_base = 0, low_size = 0;
unsigned long total_low_mem;
- unsigned long long base;
- bool auto_set = false;
int ret;
- total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
+ total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
+
/* crashkernel=Y,low */
- ret = parse_crashkernel_low(boot_command_line, total_low_mem,
- &low_size, &base);
- if (ret != 0) {
+ ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
+ if (ret) {
/*
* two parts from lib/swiotlb.c:
* -swiotlb size: user-specified with swiotlb= or default.
@@ -517,52 +518,52 @@ static void __init reserve_crashkernel_low(void)
* make sure we allocate enough extra low memory so that we
* don't run out of DMA buffers for 32-bit devices.
*/
- low_size = max(swiotlb_size_or_default() + (8UL<<20), 256UL<<20);
- auto_set = true;
+ low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
} else {
/* passed with crashkernel=0,low ? */
if (!low_size)
- return;
+ return 0;
}
- low_base = memblock_find_in_range(low_size, (1ULL<<32),
- low_size, alignment);
-
+ low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, CRASH_ALIGN);
if (!low_base) {
- if (!auto_set)
- pr_info("crashkernel low reservation failed - No suitable area found.\n");
+ pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
+ (unsigned long)(low_size >> 20));
+ return -ENOMEM;
+ }
- return;
+ ret = memblock_reserve(low_base, low_size);
+ if (ret) {
+ pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
+ return ret;
}
- memblock_reserve(low_base, low_size);
pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
- (unsigned long)(low_size >> 20),
- (unsigned long)(low_base >> 20),
- (unsigned long)(total_low_mem >> 20));
+ (unsigned long)(low_size >> 20),
+ (unsigned long)(low_base >> 20),
+ (unsigned long)(total_low_mem >> 20));
+
crashk_low_res.start = low_base;
crashk_low_res.end = low_base + low_size - 1;
insert_resource(&iomem_resource, &crashk_low_res);
#endif
+ return 0;
}
static void __init reserve_crashkernel(void)
{
- const unsigned long long alignment = 16<<20; /* 16M */
- unsigned long long total_mem;
- unsigned long long crash_size, crash_base;
+ unsigned long long crash_size, crash_base, total_mem;
bool high = false;
int ret;
total_mem = memblock_phys_mem_size();
/* crashkernel=XM */
- ret = parse_crashkernel(boot_command_line, total_mem,
- &crash_size, &crash_base);
+ ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
if (ret != 0 || crash_size <= 0) {
/* crashkernel=X,high */
ret = parse_crashkernel_high(boot_command_line, total_mem,
- &crash_size, &crash_base);
+ &crash_size, &crash_base);
if (ret != 0 || crash_size <= 0)
return;
high = true;
@@ -573,11 +574,10 @@ static void __init reserve_crashkernel(void)
/*
* kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
*/
- crash_base = memblock_find_in_range(alignment,
- high ? CRASH_KERNEL_ADDR_HIGH_MAX :
- CRASH_KERNEL_ADDR_LOW_MAX,
- crash_size, alignment);
-
+ crash_base = memblock_find_in_range(CRASH_ALIGN,
+ high ? CRASH_ADDR_HIGH_MAX
+ : CRASH_ADDR_LOW_MAX,
+ crash_size, CRASH_ALIGN);
if (!crash_base) {
pr_info("crashkernel reservation failed - No suitable area found.\n");
return;
@@ -587,26 +587,32 @@ static void __init reserve_crashkernel(void)
unsigned long long start;
start = memblock_find_in_range(crash_base,
- crash_base + crash_size, crash_size, 1<<20);
+ crash_base + crash_size,
+ crash_size, 1 << 20);
if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in use.\n");
return;
}
}
- memblock_reserve(crash_base, crash_size);
+ ret = memblock_reserve(crash_base, crash_size);
+ if (ret) {
+ pr_err("%s: Error reserving crashkernel memblock.\n", __func__);
+ return;
+ }
+
+ if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+ memblock_free(crash_base, crash_size);
+ return;
+ }
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(crash_size >> 20),
- (unsigned long)(crash_base >> 20),
- (unsigned long)(total_mem >> 20));
+ 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);
-
- if (crash_base >= (1ULL<<32))
- reserve_crashkernel_low();
}
#else
static void __init reserve_crashkernel(void)
@@ -1042,6 +1048,8 @@ void __init setup_arch(char **cmdline_p)
if (mtrr_trim_uncached_memory(max_pfn))
max_pfn = e820_end_of_ram_pfn();
+ max_possible_pfn = max_pfn;
+
#ifdef CONFIG_X86_32
/* max_low_pfn get updated here */
find_low_pfn_range();
@@ -1079,8 +1087,10 @@ void __init setup_arch(char **cmdline_p)
memblock_set_current_limit(ISA_END_ADDRESS);
memblock_x86_fill();
- if (efi_enabled(EFI_BOOT))
+ if (efi_enabled(EFI_BOOT)) {
+ efi_fake_memmap();
efi_find_mirror();
+ }
/*
* The EFI specification says that boot service code won't be called
@@ -1180,7 +1190,7 @@ void __init setup_arch(char **cmdline_p)
*/
clone_pgd_range(initial_page_table,
swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- KERNEL_PGD_PTRS);
+ min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
#endif
tboot_probe();
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index da52e6b..548ddf7 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -61,8 +61,40 @@
regs->seg = GET_SEG(seg) | 3; \
} while (0)
-int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+#ifdef CONFIG_X86_64
+/*
+ * If regs->ss will cause an IRET fault, change it. Otherwise leave it
+ * alone. Using this generally makes no sense unless
+ * user_64bit_mode(regs) would return true.
+ */
+static void force_valid_ss(struct pt_regs *regs)
{
+ u32 ar;
+ asm volatile ("lar %[old_ss], %[ar]\n\t"
+ "jz 1f\n\t" /* If invalid: */
+ "xorl %[ar], %[ar]\n\t" /* set ar = 0 */
+ "1:"
+ : [ar] "=r" (ar)
+ : [old_ss] "rm" ((u16)regs->ss));
+
+ /*
+ * For a valid 64-bit user context, we need DPL 3, type
+ * read-write data or read-write exp-down data, and S and P
+ * set. We can't use VERW because VERW doesn't check the
+ * P bit.
+ */
+ ar &= AR_DPL_MASK | AR_S | AR_P | AR_TYPE_MASK;
+ if (ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA) &&
+ ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN))
+ regs->ss = __USER_DS;
+}
+#endif
+
+static int restore_sigcontext(struct pt_regs *regs,
+ struct sigcontext __user *sc,
+ unsigned long uc_flags)
+{
+ unsigned long buf_val;
void __user *buf;
unsigned int tmpflags;
unsigned int err = 0;
@@ -93,21 +125,25 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
COPY(r15);
#endif /* CONFIG_X86_64 */
-#ifdef CONFIG_X86_32
COPY_SEG_CPL3(cs);
COPY_SEG_CPL3(ss);
-#else /* !CONFIG_X86_32 */
- /* Kernel saves and restores only the CS segment register on signals,
- * which is the bare minimum needed to allow mixed 32/64-bit code.
- * App's signal handler can save/restore other segments if needed. */
- COPY_SEG_CPL3(cs);
-#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_X86_64
+ /*
+ * Fix up SS if needed for the benefit of old DOSEMU and
+ * CRIU.
+ */
+ if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) &&
+ user_64bit_mode(regs)))
+ force_valid_ss(regs);
+#endif
get_user_ex(tmpflags, &sc->flags);
regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
regs->orig_ax = -1; /* disable syscall checks */
- get_user_ex(buf, &sc->fpstate);
+ get_user_ex(buf_val, &sc->fpstate);
+ buf = (void __user *)buf_val;
} get_user_catch(err);
err |= fpu__restore_sig(buf, config_enabled(CONFIG_X86_32));
@@ -163,6 +199,7 @@ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
put_user_ex(regs->cs, &sc->cs);
put_user_ex(0, &sc->gs);
put_user_ex(0, &sc->fs);
+ put_user_ex(regs->ss, &sc->ss);
#endif /* CONFIG_X86_32 */
put_user_ex(fpstate, &sc->fpstate);
@@ -196,7 +233,7 @@ static unsigned long align_sigframe(unsigned long sp)
return sp;
}
-static inline void __user *
+static void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
void __user **fpstate)
{
@@ -299,7 +336,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
if (current->mm->context.vdso)
restorer = current->mm->context.vdso +
- selected_vdso32->sym___kernel_sigreturn;
+ vdso_image_32.sym___kernel_sigreturn;
else
restorer = &frame->retcode;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
@@ -363,7 +400,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
/* Set up to return from userspace. */
restorer = current->mm->context.vdso +
- selected_vdso32->sym___kernel_rt_sigreturn;
+ vdso_image_32.sym___kernel_rt_sigreturn;
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = ksig->ka.sa.sa_restorer;
put_user_ex(restorer, &frame->pretcode);
@@ -401,6 +438,21 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
return 0;
}
#else /* !CONFIG_X86_32 */
+static unsigned long frame_uc_flags(struct pt_regs *regs)
+{
+ unsigned long flags;
+
+ if (cpu_has_xsave)
+ flags = UC_FP_XSTATE | UC_SIGCONTEXT_SS;
+ else
+ flags = UC_SIGCONTEXT_SS;
+
+ if (likely(user_64bit_mode(regs)))
+ flags |= UC_STRICT_RESTORE_SS;
+
+ return flags;
+}
+
static int __setup_rt_frame(int sig, struct ksignal *ksig,
sigset_t *set, struct pt_regs *regs)
{
@@ -420,10 +472,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
put_user_try {
/* Create the ucontext. */
- if (cpu_has_xsave)
- put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
- else
- put_user_ex(0, &frame->uc.uc_flags);
+ put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags);
put_user_ex(0, &frame->uc.uc_link);
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
@@ -457,10 +506,28 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
regs->sp = (unsigned long)frame;
- /* Set up the CS register to run signal handlers in 64-bit mode,
- even if the handler happens to be interrupting 32-bit code. */
+ /*
+ * Set up the CS and SS registers to run signal handlers in
+ * 64-bit mode, even if the handler happens to be interrupting
+ * 32-bit or 16-bit code.
+ *
+ * SS is subtle. In 64-bit mode, we don't need any particular
+ * SS descriptor, but we do need SS to be valid. It's possible
+ * that the old SS is entirely bogus -- this can happen if the
+ * signal we're trying to deliver is #GP or #SS caused by a bad
+ * SS value. We also have a compatbility issue here: DOSEMU
+ * relies on the contents of the SS register indicating the
+ * SS value at the time of the signal, even though that code in
+ * DOSEMU predates sigreturn's ability to restore SS. (DOSEMU
+ * avoids relying on sigreturn to restore SS; instead it uses
+ * a trampoline.) So we do our best: if the old SS was valid,
+ * we keep it. Otherwise we replace it.
+ */
regs->cs = __USER_CS;
+ if (unlikely(regs->ss != __USER_DS))
+ force_valid_ss(regs);
+
return 0;
}
#endif /* CONFIG_X86_32 */
@@ -487,10 +554,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
put_user_try {
/* Create the ucontext. */
- if (cpu_has_xsave)
- put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
- else
- put_user_ex(0, &frame->uc.uc_flags);
+ put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags);
put_user_ex(0, &frame->uc.uc_link);
compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
put_user_ex(0, &frame->uc.uc__pad0);
@@ -552,7 +616,11 @@ asmlinkage unsigned long sys_sigreturn(void)
set_current_blocked(&set);
- if (restore_sigcontext(regs, &frame->sc))
+ /*
+ * x86_32 has no uc_flags bits relevant to restore_sigcontext.
+ * Save a few cycles by skipping the __get_user.
+ */
+ if (restore_sigcontext(regs, &frame->sc, 0))
goto badframe;
return regs->ax;
@@ -568,16 +636,19 @@ asmlinkage long sys_rt_sigreturn(void)
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;
sigset_t set;
+ unsigned long uc_flags;
frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
+ if (__get_user(uc_flags, &frame->uc.uc_flags))
+ goto badframe;
set_current_blocked(&set);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
goto badframe;
if (restore_altstack(&frame->uc.uc_stack))
@@ -688,12 +759,18 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
signal_setup_done(failed, ksig, stepping);
}
-#ifdef CONFIG_X86_32
-#define NR_restart_syscall __NR_restart_syscall
-#else /* !CONFIG_X86_32 */
-#define NR_restart_syscall \
- test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
-#endif /* CONFIG_X86_32 */
+static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
+{
+#ifdef CONFIG_X86_64
+ if (is_ia32_task())
+ return __NR_ia32_restart_syscall;
+#endif
+#ifdef CONFIG_X86_X32_ABI
+ return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
+#else
+ return __NR_restart_syscall;
+#endif
+}
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
@@ -722,7 +799,7 @@ void do_signal(struct pt_regs *regs)
break;
case -ERESTART_RESTARTBLOCK:
- regs->ax = NR_restart_syscall;
+ regs->ax = get_nr_restart_syscall(regs);
regs->ip -= 2;
break;
}
@@ -758,6 +835,7 @@ asmlinkage long sys32_x32_rt_sigreturn(void)
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe_x32 __user *frame;
sigset_t set;
+ unsigned long uc_flags;
frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8);
@@ -765,10 +843,12 @@ asmlinkage long sys32_x32_rt_sigreturn(void)
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
+ if (__get_user(uc_flags, &frame->uc.uc_flags))
+ goto badframe;
set_current_blocked(&set);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
goto badframe;
if (compat_restore_altstack(&frame->uc.uc_stack))
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 12c8286..658777c 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -125,12 +125,12 @@ static void native_smp_send_reschedule(int cpu)
WARN_ON(1);
return;
}
- apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
+ apic->send_IPI(cpu, RESCHEDULE_VECTOR);
}
void native_send_call_func_single_ipi(int cpu)
{
- apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
+ apic->send_IPI(cpu, CALL_FUNCTION_SINGLE_VECTOR);
}
void native_send_call_func_ipi(const struct cpumask *mask)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 892ee2e5..643dbdc 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -97,6 +97,14 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);
+/* Logical package management. We might want to allocate that dynamically */
+static int *physical_to_logical_pkg __read_mostly;
+static unsigned long *physical_package_map __read_mostly;;
+static unsigned long *logical_package_map __read_mostly;
+static unsigned int max_physical_pkg_id __read_mostly;
+unsigned int __max_logical_packages __read_mostly;
+EXPORT_SYMBOL(__max_logical_packages);
+
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
unsigned long flags;
@@ -248,7 +256,98 @@ static void notrace start_secondary(void *unused)
x86_cpuinit.setup_percpu_clockev();
wmb();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+}
+
+int topology_update_package_map(unsigned int apicid, unsigned int cpu)
+{
+ unsigned int new, pkg = apicid >> boot_cpu_data.x86_coreid_bits;
+
+ /* Called from early boot ? */
+ if (!physical_package_map)
+ return 0;
+
+ if (pkg >= max_physical_pkg_id)
+ return -EINVAL;
+
+ /* Set the logical package id */
+ if (test_and_set_bit(pkg, physical_package_map))
+ goto found;
+
+ if (pkg < __max_logical_packages) {
+ set_bit(pkg, logical_package_map);
+ physical_to_logical_pkg[pkg] = pkg;
+ goto found;
+ }
+ new = find_first_zero_bit(logical_package_map, __max_logical_packages);
+ if (new >= __max_logical_packages) {
+ physical_to_logical_pkg[pkg] = -1;
+ pr_warn("APIC(%x) Package %u exceeds logical package map\n",
+ apicid, pkg);
+ return -ENOSPC;
+ }
+ set_bit(new, logical_package_map);
+ pr_info("APIC(%x) Converting physical %u to logical package %u\n",
+ apicid, pkg, new);
+ physical_to_logical_pkg[pkg] = new;
+
+found:
+ cpu_data(cpu).logical_proc_id = physical_to_logical_pkg[pkg];
+ return 0;
+}
+
+/**
+ * topology_phys_to_logical_pkg - Map a physical package id to a logical
+ *
+ * Returns logical package id or -1 if not found
+ */
+int topology_phys_to_logical_pkg(unsigned int phys_pkg)
+{
+ if (phys_pkg >= max_physical_pkg_id)
+ return -1;
+ return physical_to_logical_pkg[phys_pkg];
+}
+EXPORT_SYMBOL(topology_phys_to_logical_pkg);
+
+static void __init smp_init_package_map(void)
+{
+ unsigned int ncpus, cpu;
+ size_t size;
+
+ /*
+ * Today neither Intel nor AMD support heterogenous systems. That
+ * might change in the future....
+ */
+ ncpus = boot_cpu_data.x86_max_cores * smp_num_siblings;
+ __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus);
+
+ /*
+ * Possibly larger than what we need as the number of apic ids per
+ * package can be smaller than the actual used apic ids.
+ */
+ max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus);
+ size = max_physical_pkg_id * sizeof(unsigned int);
+ physical_to_logical_pkg = kmalloc(size, GFP_KERNEL);
+ memset(physical_to_logical_pkg, 0xff, size);
+ size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
+ physical_package_map = kzalloc(size, GFP_KERNEL);
+ size = BITS_TO_LONGS(__max_logical_packages) * sizeof(unsigned long);
+ logical_package_map = kzalloc(size, GFP_KERNEL);
+
+ pr_info("Max logical packages: %u\n", __max_logical_packages);
+
+ for_each_present_cpu(cpu) {
+ unsigned int apicid = apic->cpu_present_to_apicid(cpu);
+
+ if (apicid == BAD_APICID || !apic->apic_id_valid(apicid))
+ continue;
+ if (!topology_update_package_map(apicid, cpu))
+ continue;
+ pr_warn("CPU %u APICId %x disabled\n", cpu, apicid);
+ per_cpu(x86_bios_cpu_apicid, cpu) = BAD_APICID;
+ set_cpu_possible(cpu, false);
+ set_cpu_present(cpu, false);
+ }
}
void __init smp_store_boot_cpu_info(void)
@@ -258,6 +357,7 @@ void __init smp_store_boot_cpu_info(void)
*c = boot_cpu_data;
c->cpu_index = id;
+ smp_init_package_map();
}
/*
@@ -304,7 +404,7 @@ do { \
static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
{
- if (cpu_has_topoext) {
+ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
if (c->phys_proc_id == o->phys_proc_id &&
@@ -509,7 +609,7 @@ void __inquire_remote_apic(int apicid)
*/
#define UDELAY_10MS_DEFAULT 10000
-static unsigned int init_udelay = INT_MAX;
+static unsigned int init_udelay = UINT_MAX;
static int __init cpu_init_udelay(char *str)
{
@@ -522,14 +622,15 @@ early_param("cpu_init_udelay", cpu_init_udelay);
static void __init smp_quirk_init_udelay(void)
{
/* if cmdline changed it from default, leave it alone */
- if (init_udelay != INT_MAX)
+ if (init_udelay != UINT_MAX)
return;
/* if modern processor, use no delay */
if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
- ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF)))
+ ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF))) {
init_udelay = 0;
-
+ return;
+ }
/* else, use legacy delay */
init_udelay = UDELAY_10MS_DEFAULT;
}
@@ -629,13 +730,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
num_starts = 0;
/*
- * Paravirt / VMI wants a startup IPI hook here to set up the
- * target processor state.
- */
- startup_ipi_hook(phys_apicid, (unsigned long) start_secondary,
- stack_start);
-
- /*
* Run STARTUP IPI loop.
*/
pr_debug("#startup loops: %d\n", num_starts);
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index fdd0c64..9ee98ee 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -14,30 +14,34 @@ static int save_stack_stack(void *data, char *name)
return 0;
}
-static void
+static int
__save_stack_address(void *data, unsigned long addr, bool reliable, bool nosched)
{
struct stack_trace *trace = data;
#ifdef CONFIG_FRAME_POINTER
if (!reliable)
- return;
+ return 0;
#endif
if (nosched && in_sched_functions(addr))
- return;
+ return 0;
if (trace->skip > 0) {
trace->skip--;
- return;
+ return 0;
}
- if (trace->nr_entries < trace->max_entries)
+ if (trace->nr_entries < trace->max_entries) {
trace->entries[trace->nr_entries++] = addr;
+ return 0;
+ } else {
+ return -1; /* no more room, stop walking the stack */
+ }
}
-static void save_stack_address(void *data, unsigned long addr, int reliable)
+static int save_stack_address(void *data, unsigned long addr, int reliable)
{
return __save_stack_address(data, addr, reliable, false);
}
-static void
+static int
save_stack_address_nosched(void *data, unsigned long addr, int reliable)
{
return __save_stack_address(data, addr, reliable, true);
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 91a4496..e72a07f 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -135,7 +135,7 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
pmd = pmd_alloc(&tboot_mm, pud, vaddr);
if (!pmd)
return -1;
- pte = pte_alloc_map(&tboot_mm, NULL, pmd, vaddr);
+ pte = pte_alloc_map(&tboot_mm, pmd, vaddr);
if (!pte)
return -1;
set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
diff --git a/arch/x86/kernel/test_nx.c b/arch/x86/kernel/test_nx.c
index 3f92ce0..27538f1 100644
--- a/arch/x86/kernel/test_nx.c
+++ b/arch/x86/kernel/test_nx.c
@@ -142,7 +142,6 @@ static int test_NX(void)
* by the error message
*/
-#ifdef CONFIG_DEBUG_RODATA
/* Test 3: Check if the .rodata section is executable */
if (rodata_test_data != 0xC3) {
printk(KERN_ERR "test_nx: .rodata marker has invalid value\n");
@@ -151,7 +150,6 @@ static int test_NX(void)
printk(KERN_ERR "test_nx: .rodata section is executable\n");
ret = -ENODEV;
}
-#endif
#if 0
/* Test 4: Check if the .data section of a module is executable */
diff --git a/arch/x86/kernel/test_rodata.c b/arch/x86/kernel/test_rodata.c
index 5ecbfe5..cb4a01b 100644
--- a/arch/x86/kernel/test_rodata.c
+++ b/arch/x86/kernel/test_rodata.c
@@ -76,5 +76,5 @@ int rodata_test(void)
}
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Testcase for the DEBUG_RODATA infrastructure");
+MODULE_DESCRIPTION("Testcase for marking rodata as read-only");
MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 346eec7..06cbe25 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -83,30 +83,16 @@ gate_desc idt_table[NR_VECTORS] __page_aligned_bss;
DECLARE_BITMAP(used_vectors, NR_VECTORS);
EXPORT_SYMBOL_GPL(used_vectors);
-static inline void conditional_sti(struct pt_regs *regs)
+static inline void cond_local_irq_enable(struct pt_regs *regs)
{
if (regs->flags & X86_EFLAGS_IF)
local_irq_enable();
}
-static inline void preempt_conditional_sti(struct pt_regs *regs)
-{
- preempt_count_inc();
- if (regs->flags & X86_EFLAGS_IF)
- local_irq_enable();
-}
-
-static inline void conditional_cli(struct pt_regs *regs)
-{
- if (regs->flags & X86_EFLAGS_IF)
- local_irq_disable();
-}
-
-static inline void preempt_conditional_cli(struct pt_regs *regs)
+static inline void cond_local_irq_disable(struct pt_regs *regs)
{
if (regs->flags & X86_EFLAGS_IF)
local_irq_disable();
- preempt_count_dec();
}
void ist_enter(struct pt_regs *regs)
@@ -199,7 +185,7 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
}
if (!user_mode(regs)) {
- if (!fixup_exception(regs)) {
+ if (!fixup_exception(regs, trapnr)) {
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = trapnr;
die(str, regs, error_code);
@@ -262,7 +248,6 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = trapnr;
-#ifdef CONFIG_X86_64
if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
printk_ratelimit()) {
pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx",
@@ -271,7 +256,6 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
print_vma_addr(" in ", regs->ip);
pr_cont("\n");
}
-#endif
force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk);
}
@@ -286,7 +270,7 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
NOTIFY_STOP) {
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
do_trap(trapnr, signr, str, regs, error_code,
fill_trap_info(regs, signr, trapnr, &info));
}
@@ -361,14 +345,14 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
{
- const struct bndcsr *bndcsr;
+ const struct mpx_bndcsr *bndcsr;
siginfo_t *info;
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
if (notify_die(DIE_TRAP, "bounds", regs, error_code,
X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
return;
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
if (!user_mode(regs))
die("bounds", regs, error_code);
@@ -384,7 +368,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
* which is all zeros which indicates MPX was not
* responsible for the exception.
*/
- bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+ bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
if (!bndcsr)
goto exit_trap;
@@ -443,7 +427,7 @@ do_general_protection(struct pt_regs *regs, long error_code)
struct task_struct *tsk;
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
if (v8086_mode(regs)) {
local_irq_enable();
@@ -453,7 +437,7 @@ do_general_protection(struct pt_regs *regs, long error_code)
tsk = current;
if (!user_mode(regs)) {
- if (fixup_exception(regs))
+ if (fixup_exception(regs, X86_TRAP_GP))
return;
tsk->thread.error_code = error_code;
@@ -517,9 +501,11 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
* as we may switch to the interrupt stack.
*/
debug_stack_usage_inc();
- preempt_conditional_sti(regs);
+ preempt_disable();
+ cond_local_irq_enable(regs);
do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
- preempt_conditional_cli(regs);
+ cond_local_irq_disable(regs);
+ preempt_enable_no_resched();
debug_stack_usage_dec();
exit:
ist_exit(regs);
@@ -571,6 +557,29 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
NOKPROBE_SYMBOL(fixup_bad_iret);
#endif
+static bool is_sysenter_singlestep(struct pt_regs *regs)
+{
+ /*
+ * We don't try for precision here. If we're anywhere in the region of
+ * code that can be single-stepped in the SYSENTER entry path, then
+ * assume that this is a useless single-step trap due to SYSENTER
+ * being invoked with TF set. (We don't know in advance exactly
+ * which instructions will be hit because BTF could plausibly
+ * be set.)
+ */
+#ifdef CONFIG_X86_32
+ return (regs->ip - (unsigned long)__begin_SYSENTER_singlestep_region) <
+ (unsigned long)__end_SYSENTER_singlestep_region -
+ (unsigned long)__begin_SYSENTER_singlestep_region;
+#elif defined(CONFIG_IA32_EMULATION)
+ return (regs->ip - (unsigned long)entry_SYSENTER_compat) <
+ (unsigned long)__end_entry_SYSENTER_compat -
+ (unsigned long)entry_SYSENTER_compat;
+#else
+ return false;
+#endif
+}
+
/*
* Our handling of the processor debug registers is non-trivial.
* We do not clear them on entry and exit from the kernel. Therefore
@@ -605,11 +614,42 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
ist_enter(regs);
get_debugreg(dr6, 6);
+ /*
+ * The Intel SDM says:
+ *
+ * Certain debug exceptions may clear bits 0-3. The remaining
+ * contents of the DR6 register are never cleared by the
+ * processor. To avoid confusion in identifying debug
+ * exceptions, debug handlers should clear the register before
+ * returning to the interrupted task.
+ *
+ * Keep it simple: clear DR6 immediately.
+ */
+ set_debugreg(0, 6);
/* Filter out all the reserved bits which are preset to 1 */
dr6 &= ~DR6_RESERVED;
/*
+ * The SDM says "The processor clears the BTF flag when it
+ * generates a debug exception." Clear TIF_BLOCKSTEP to keep
+ * TIF_BLOCKSTEP in sync with the hardware BTF flag.
+ */
+ clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
+
+ if (unlikely(!user_mode(regs) && (dr6 & DR_STEP) &&
+ is_sysenter_singlestep(regs))) {
+ dr6 &= ~DR_STEP;
+ if (!dr6)
+ goto exit;
+ /*
+ * else we might have gotten a single-step trap and hit a
+ * watchpoint at the same time, in which case we should fall
+ * through and handle the watchpoint.
+ */
+ }
+
+ /*
* If dr6 has no reason to give us about the origin of this trap,
* then it's very likely the result of an icebp/int01 trap.
* User wants a sigtrap for that.
@@ -617,18 +657,10 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
if (!dr6 && user_mode(regs))
user_icebp = 1;
- /* Catch kmemcheck conditions first of all! */
+ /* Catch kmemcheck conditions! */
if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
goto exit;
- /* DR6 may or may not be cleared by the CPU */
- set_debugreg(0, 6);
-
- /*
- * The processor cleared BTF, so don't mark that we need it set.
- */
- clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
-
/* Store the virtualized DR6 value */
tsk->thread.debugreg6 = dr6;
@@ -648,24 +680,25 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
debug_stack_usage_inc();
/* It's safe to allow irq's after DR6 has been saved */
- preempt_conditional_sti(regs);
+ preempt_disable();
+ cond_local_irq_enable(regs);
if (v8086_mode(regs)) {
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code,
X86_TRAP_DB);
- preempt_conditional_cli(regs);
+ cond_local_irq_disable(regs);
+ preempt_enable_no_resched();
debug_stack_usage_dec();
goto exit;
}
- /*
- * Single-stepping through system calls: ignore any exceptions in
- * kernel space, but re-enable TF when returning to user mode.
- *
- * We already checked v86 mode above, so we can check for kernel mode
- * by just checking the CPL of CS.
- */
- if ((dr6 & DR_STEP) && !user_mode(regs)) {
+ if (WARN_ON_ONCE((dr6 & DR_STEP) && !user_mode(regs))) {
+ /*
+ * Historical junk that used to handle SYSENTER single-stepping.
+ * This should be unreachable now. If we survive for a while
+ * without anyone hitting this warning, we'll turn this into
+ * an oops.
+ */
tsk->thread.debugreg6 &= ~DR_STEP;
set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
regs->flags &= ~X86_EFLAGS_TF;
@@ -673,10 +706,19 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
si_code = get_si_code(tsk->thread.debugreg6);
if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
send_sigtrap(tsk, regs, error_code, si_code);
- preempt_conditional_cli(regs);
+ cond_local_irq_disable(regs);
+ preempt_enable_no_resched();
debug_stack_usage_dec();
exit:
+#if defined(CONFIG_X86_32)
+ /*
+ * This is the most likely code path that involves non-trivial use
+ * of the SYSENTER stack. Check that we haven't overrun it.
+ */
+ WARN(this_cpu_read(cpu_tss.SYSENTER_stack_canary) != STACK_END_MAGIC,
+ "Overran or corrupted SYSENTER stack\n");
+#endif
ist_exit(regs);
}
NOKPROBE_SYMBOL(do_debug);
@@ -696,10 +738,10 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
return;
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
if (!user_mode(regs)) {
- if (!fixup_exception(regs)) {
+ if (!fixup_exception(regs, trapnr)) {
task->thread.error_code = error_code;
task->thread.trap_nr = trapnr;
die(str, regs, error_code);
@@ -743,20 +785,19 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
dotraplinkage void
do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
{
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
}
dotraplinkage void
do_device_not_available(struct pt_regs *regs, long error_code)
{
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
- BUG_ON(use_eager_fpu());
#ifdef CONFIG_MATH_EMULATION
- if (read_cr0() & X86_CR0_EM) {
+ if (!boot_cpu_has(X86_FEATURE_FPU) && (read_cr0() & X86_CR0_EM)) {
struct math_emu_info info = { };
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
info.regs = regs;
math_emulate(&info);
@@ -765,7 +806,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
#endif
fpu__restore(&current->thread.fpu); /* interrupts still off */
#ifdef CONFIG_X86_32
- conditional_sti(regs);
+ cond_local_irq_enable(regs);
#endif
}
NOKPROBE_SYMBOL(do_device_not_available);
@@ -868,7 +909,7 @@ void __init trap_init(void)
#endif
#ifdef CONFIG_X86_32
- set_system_trap_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);
+ set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);
set_bit(IA32_SYSCALL_VECTOR, used_vectors);
#endif
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index c3f7602..5638044 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -43,6 +43,11 @@ static DEFINE_STATIC_KEY_FALSE(__use_tsc);
int tsc_clocksource_reliable;
+static u32 art_to_tsc_numerator;
+static u32 art_to_tsc_denominator;
+static u64 art_to_tsc_offset;
+struct clocksource *art_related_clocksource;
+
/*
* Use a ring-buffer like data structure, where a writer advances the head by
* writing a new data entry and a reader advances the tail when it observes a
@@ -168,21 +173,20 @@ static void cyc2ns_write_end(int cpu, struct cyc2ns_data *data)
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
- * into a shift.
+ * into a shift. The larger SC is, the more accurate the conversion, but
+ * cyc2ns_scale needs to be a 32-bit value so that 32-bit multiplication
+ * (64-bit result) can be used.
*
- * We can use khz divisor instead of mhz to keep a better precision, since
- * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ * We can use khz divisor instead of mhz to keep a better precision.
* (mathieu.desnoyers@polymtl.ca)
*
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*/
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
static void cyc2ns_data_init(struct cyc2ns_data *data)
{
data->cyc2ns_mul = 0;
- data->cyc2ns_shift = CYC2NS_SCALE_FACTOR;
+ data->cyc2ns_shift = 0;
data->cyc2ns_offset = 0;
data->__count = 0;
}
@@ -216,14 +220,14 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
if (likely(data == tail)) {
ns = data->cyc2ns_offset;
- ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+ ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, data->cyc2ns_shift);
} else {
data->__count++;
barrier();
ns = data->cyc2ns_offset;
- ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+ ns += mul_u64_u32_shr(cyc, data->cyc2ns_mul, data->cyc2ns_shift);
barrier();
@@ -257,12 +261,22 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
* time function is continuous; see the comment near struct
* cyc2ns_data.
*/
- data->cyc2ns_mul =
- DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR,
- cpu_khz);
- data->cyc2ns_shift = CYC2NS_SCALE_FACTOR;
+ clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz,
+ NSEC_PER_MSEC, 0);
+
+ /*
+ * cyc2ns_shift is exported via arch_perf_update_userpage() where it is
+ * not expected to be greater than 31 due to the original published
+ * conversion algorithm shifting a 32-bit value (now specifies a 64-bit
+ * value) - refer perf_event_mmap_page documentation in perf_event.h.
+ */
+ if (data->cyc2ns_shift == 32) {
+ data->cyc2ns_shift = 31;
+ data->cyc2ns_mul >>= 1;
+ }
+
data->cyc2ns_offset = ns_now -
- mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, CYC2NS_SCALE_FACTOR);
+ mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, data->cyc2ns_shift);
cyc2ns_write_end(cpu, data);
@@ -955,6 +969,37 @@ core_initcall(cpufreq_tsc);
#endif /* CONFIG_CPU_FREQ */
+#define ART_CPUID_LEAF (0x15)
+#define ART_MIN_DENOMINATOR (1)
+
+
+/*
+ * If ART is present detect the numerator:denominator to convert to TSC
+ */
+static void detect_art(void)
+{
+ unsigned int unused[2];
+
+ if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF)
+ return;
+
+ cpuid(ART_CPUID_LEAF, &art_to_tsc_denominator,
+ &art_to_tsc_numerator, unused, unused+1);
+
+ /* Don't enable ART in a VM, non-stop TSC required */
+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR) ||
+ !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ||
+ art_to_tsc_denominator < ART_MIN_DENOMINATOR)
+ return;
+
+ if (rdmsrl_safe(MSR_IA32_TSC_ADJUST, &art_to_tsc_offset))
+ return;
+
+ /* Make this sticky over multiple CPU init calls */
+ setup_force_cpu_cap(X86_FEATURE_ART);
+}
+
+
/* clocksource code */
static struct clocksource clocksource_tsc;
@@ -1062,6 +1107,25 @@ int unsynchronized_tsc(void)
return 0;
}
+/*
+ * Convert ART to TSC given numerator/denominator found in detect_art()
+ */
+struct system_counterval_t convert_art_to_tsc(cycle_t art)
+{
+ u64 tmp, res, rem;
+
+ rem = do_div(art, art_to_tsc_denominator);
+
+ res = art * art_to_tsc_numerator;
+ tmp = rem * art_to_tsc_numerator;
+
+ do_div(tmp, art_to_tsc_denominator);
+ res += tmp + art_to_tsc_offset;
+
+ return (struct system_counterval_t) {.cs = art_related_clocksource,
+ .cycles = res};
+}
+EXPORT_SYMBOL(convert_art_to_tsc);
static void tsc_refine_calibration_work(struct work_struct *work);
static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
@@ -1133,6 +1197,8 @@ static void tsc_refine_calibration_work(struct work_struct *work)
(unsigned long)tsc_khz % 1000);
out:
+ if (boot_cpu_has(X86_FEATURE_ART))
+ art_related_clocksource = &clocksource_tsc;
clocksource_register_khz(&clocksource_tsc, tsc_khz);
}
@@ -1176,8 +1242,6 @@ void __init tsc_init(void)
u64 lpj;
int cpu;
- x86_init.timers.tsc_pre_init();
-
if (!cpu_has_tsc) {
setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
return;
@@ -1228,6 +1292,8 @@ void __init tsc_init(void)
mark_tsc_unstable("TSCs unsynchronized");
check_system_tsc_reliable();
+
+ detect_art();
}
#ifdef CONFIG_SMP
@@ -1239,14 +1305,14 @@ void __init tsc_init(void)
*/
unsigned long calibrate_delay_is_known(void)
{
- int i, cpu = smp_processor_id();
+ int sibling, cpu = smp_processor_id();
if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC))
return 0;
- for_each_online_cpu(i)
- if (cpu_data(i).phys_proc_id == cpu_data(cpu).phys_proc_id)
- return cpu_data(i).loops_per_jiffy;
+ sibling = cpumask_any_but(topology_core_cpumask(cpu), cpu);
+ if (sibling < nr_cpu_ids)
+ return cpu_data(sibling).loops_per_jiffy;
return 0;
}
#endif
diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
index b9242ba..014ea59 100644
--- a/arch/x86/kernel/verify_cpu.S
+++ b/arch/x86/kernel/verify_cpu.S
@@ -30,14 +30,15 @@
* appropriately. Either display a message or halt.
*/
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/msr-index.h>
verify_cpu:
- pushfl # Save caller passed flags
- pushl $0 # Kill any dangerous flags
- popfl
+ pushf # Save caller passed flags
+ push $0 # Kill any dangerous flags
+ popf
+#ifndef __x86_64__
pushfl # standard way to check for cpuid
popl %eax
movl %eax,%ebx
@@ -47,30 +48,31 @@ verify_cpu:
pushfl
popl %eax
cmpl %eax,%ebx
- jz verify_cpu_no_longmode # cpu has no cpuid
+ jz .Lverify_cpu_no_longmode # cpu has no cpuid
+#endif
movl $0x0,%eax # See if cpuid 1 is implemented
cpuid
cmpl $0x1,%eax
- jb verify_cpu_no_longmode # no cpuid 1
+ jb .Lverify_cpu_no_longmode # no cpuid 1
xor %di,%di
cmpl $0x68747541,%ebx # AuthenticAMD
- jnz verify_cpu_noamd
+ jnz .Lverify_cpu_noamd
cmpl $0x69746e65,%edx
- jnz verify_cpu_noamd
+ jnz .Lverify_cpu_noamd
cmpl $0x444d4163,%ecx
- jnz verify_cpu_noamd
+ jnz .Lverify_cpu_noamd
mov $1,%di # cpu is from AMD
- jmp verify_cpu_check
+ jmp .Lverify_cpu_check
-verify_cpu_noamd:
+.Lverify_cpu_noamd:
cmpl $0x756e6547,%ebx # GenuineIntel?
- jnz verify_cpu_check
+ jnz .Lverify_cpu_check
cmpl $0x49656e69,%edx
- jnz verify_cpu_check
+ jnz .Lverify_cpu_check
cmpl $0x6c65746e,%ecx
- jnz verify_cpu_check
+ jnz .Lverify_cpu_check
# only call IA32_MISC_ENABLE when:
# family > 6 || (family == 6 && model >= 0xd)
@@ -81,59 +83,59 @@ verify_cpu_noamd:
andl $0x0ff00f00, %eax # mask family and extended family
shrl $8, %eax
cmpl $6, %eax
- ja verify_cpu_clear_xd # family > 6, ok
- jb verify_cpu_check # family < 6, skip
+ ja .Lverify_cpu_clear_xd # family > 6, ok
+ jb .Lverify_cpu_check # family < 6, skip
andl $0x000f00f0, %ecx # mask model and extended model
shrl $4, %ecx
cmpl $0xd, %ecx
- jb verify_cpu_check # family == 6, model < 0xd, skip
+ jb .Lverify_cpu_check # family == 6, model < 0xd, skip
-verify_cpu_clear_xd:
+.Lverify_cpu_clear_xd:
movl $MSR_IA32_MISC_ENABLE, %ecx
rdmsr
btrl $2, %edx # clear MSR_IA32_MISC_ENABLE_XD_DISABLE
- jnc verify_cpu_check # only write MSR if bit was changed
+ jnc .Lverify_cpu_check # only write MSR if bit was changed
wrmsr
-verify_cpu_check:
+.Lverify_cpu_check:
movl $0x1,%eax # Does the cpu have what it takes
cpuid
andl $REQUIRED_MASK0,%edx
xorl $REQUIRED_MASK0,%edx
- jnz verify_cpu_no_longmode
+ jnz .Lverify_cpu_no_longmode
movl $0x80000000,%eax # See if extended cpuid is implemented
cpuid
cmpl $0x80000001,%eax
- jb verify_cpu_no_longmode # no extended cpuid
+ jb .Lverify_cpu_no_longmode # no extended cpuid
movl $0x80000001,%eax # Does the cpu have what it takes
cpuid
andl $REQUIRED_MASK1,%edx
xorl $REQUIRED_MASK1,%edx
- jnz verify_cpu_no_longmode
+ jnz .Lverify_cpu_no_longmode
-verify_cpu_sse_test:
+.Lverify_cpu_sse_test:
movl $1,%eax
cpuid
andl $SSE_MASK,%edx
cmpl $SSE_MASK,%edx
- je verify_cpu_sse_ok
+ je .Lverify_cpu_sse_ok
test %di,%di
- jz verify_cpu_no_longmode # only try to force SSE on AMD
+ jz .Lverify_cpu_no_longmode # only try to force SSE on AMD
movl $MSR_K7_HWCR,%ecx
rdmsr
btr $15,%eax # enable SSE
wrmsr
xor %di,%di # don't loop
- jmp verify_cpu_sse_test # try again
+ jmp .Lverify_cpu_sse_test # try again
-verify_cpu_no_longmode:
- popfl # Restore caller passed flags
+.Lverify_cpu_no_longmode:
+ popf # Restore caller passed flags
movl $1,%eax
ret
-verify_cpu_sse_ok:
- popfl # Restore caller passed flags
+.Lverify_cpu_sse_ok:
+ popf # Restore caller passed flags
xorl %eax, %eax
ret
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 5246193..3dce1ca 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -175,7 +175,11 @@ static void mark_screen_rdonly(struct mm_struct *mm)
if (pud_none_or_clear_bad(pud))
goto out;
pmd = pmd_offset(pud, 0xA0000);
- split_huge_page_pmd_mm(mm, 0xA0000, pmd);
+
+ if (pmd_trans_huge(*pmd)) {
+ struct vm_area_struct *vma = find_vma(mm, 0xA0000);
+ split_huge_pmd(vma, pmd, 0xA0000);
+ }
if (pmd_none_or_clear_bad(pmd))
goto out;
pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
@@ -357,8 +361,10 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
tss = &per_cpu(cpu_tss, get_cpu());
/* make room for real-mode segments */
tsk->thread.sp0 += 16;
- if (cpu_has_sep)
+
+ if (static_cpu_has(X86_FEATURE_SEP))
tsk->thread.sysenter_cs = 0;
+
load_sp0(tss, &tsk->thread);
put_cpu();
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 74e4bf1..5af9958 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -41,29 +41,28 @@ ENTRY(phys_startup_64)
jiffies_64 = jiffies;
#endif
-#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+#if defined(CONFIG_X86_64)
/*
- * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA
- * we retain large page mappings for boundaries spanning kernel text, rodata
- * and data sections.
+ * On 64-bit, align RODATA to 2MB so we retain large page mappings for
+ * boundaries spanning kernel text, rodata and data sections.
*
* However, kernel identity mappings will have different RWX permissions
* to the pages mapping to text and to the pages padding (which are freed) the
* text section. Hence kernel identity mappings will be broken to smaller
* pages. For 64-bit, kernel text and kernel identity mappings are different,
- * so we can enable protection checks that come with CONFIG_DEBUG_RODATA,
- * as well as retain 2MB large page mappings for kernel text.
+ * so we can enable protection checks as well as retain 2MB large page
+ * mappings for kernel text.
*/
-#define X64_ALIGN_DEBUG_RODATA_BEGIN . = ALIGN(HPAGE_SIZE);
+#define X64_ALIGN_RODATA_BEGIN . = ALIGN(HPAGE_SIZE);
-#define X64_ALIGN_DEBUG_RODATA_END \
+#define X64_ALIGN_RODATA_END \
. = ALIGN(HPAGE_SIZE); \
__end_rodata_hpage_align = .;
#else
-#define X64_ALIGN_DEBUG_RODATA_BEGIN
-#define X64_ALIGN_DEBUG_RODATA_END
+#define X64_ALIGN_RODATA_BEGIN
+#define X64_ALIGN_RODATA_END
#endif
@@ -112,13 +111,11 @@ SECTIONS
EXCEPTION_TABLE(16) :text = 0x9090
-#if defined(CONFIG_DEBUG_RODATA)
/* .text should occupy whole number of pages */
. = ALIGN(PAGE_SIZE);
-#endif
- X64_ALIGN_DEBUG_RODATA_BEGIN
+ X64_ALIGN_RODATA_BEGIN
RO_DATA(PAGE_SIZE)
- X64_ALIGN_DEBUG_RODATA_END
+ X64_ALIGN_RODATA_END
/* Data */
.data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -195,6 +192,17 @@ SECTIONS
:init
#endif
+ /*
+ * Section for code used exclusively before alternatives are run. All
+ * references to such code must be patched out by alternatives, normally
+ * by using X86_FEATURE_ALWAYS CPU feature bit.
+ *
+ * See static_cpu_has() for an example.
+ */
+ .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {
+ *(.altinstr_aux)
+ }
+
INIT_DATA_SECTION(16)
.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index a0695be..cd05942 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -37,6 +37,8 @@ EXPORT_SYMBOL(__copy_user_nocache);
EXPORT_SYMBOL(_copy_from_user);
EXPORT_SYMBOL(_copy_to_user);
+EXPORT_SYMBOL_GPL(memcpy_mcsafe);
+
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(clear_page);
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 3839628..dad5fe9 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -68,7 +68,6 @@ struct x86_init_ops x86_init __initdata = {
.timers = {
.setup_percpu_clockev = setup_boot_APIC_clock,
- .tsc_pre_init = x86_init_noop,
.timer_init = hpet_time_init,
.wallclock_init = x86_init_noop,
},
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index d8a1d56..639a6e3 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -28,6 +28,8 @@ config KVM
select ANON_INODES
select HAVE_KVM_IRQCHIP
select HAVE_KVM_IRQFD
+ select IRQ_BYPASS_MANAGER
+ select HAVE_KVM_IRQ_BYPASS
select HAVE_KVM_IRQ_ROUTING
select HAVE_KVM_EVENTFD
select KVM_APIC_ARCHITECTURE
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index a1ff508..464fa47 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -13,9 +13,10 @@ kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
- hyperv.o
+ hyperv.o page_track.o
kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += assigned-dev.o iommu.o
+
kvm-intel-y += vmx.o pmu_intel.o
kvm-amd-y += svm.o pmu_amd.o
diff --git a/arch/x86/kvm/assigned-dev.c b/arch/x86/kvm/assigned-dev.c
index d090ecf..308b859 100644
--- a/arch/x86/kvm/assigned-dev.c
+++ b/arch/x86/kvm/assigned-dev.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include "irq.h"
#include "assigned-dev.h"
+#include "trace/events/kvm.h"
struct kvm_assigned_dev_kernel {
struct kvm_irq_ack_notifier ack_notifier;
@@ -50,11 +51,9 @@ struct kvm_assigned_dev_kernel {
static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
int assigned_dev_id)
{
- struct list_head *ptr;
struct kvm_assigned_dev_kernel *match;
- list_for_each(ptr, head) {
- match = list_entry(ptr, struct kvm_assigned_dev_kernel, list);
+ list_for_each_entry(match, head, list) {
if (match->assigned_dev_id == assigned_dev_id)
return match;
}
@@ -131,7 +130,42 @@ static irqreturn_t kvm_assigned_dev_thread_intx(int irq, void *dev_id)
return IRQ_HANDLED;
}
-#ifdef __KVM_HAVE_MSI
+/*
+ * Deliver an IRQ in an atomic context if we can, or return a failure,
+ * user can retry in a process context.
+ * Return value:
+ * -EWOULDBLOCK - Can't deliver in atomic context: retry in a process context.
+ * Other values - No need to retry.
+ */
+static int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq,
+ int level)
+{
+ struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
+ struct kvm_kernel_irq_routing_entry *e;
+ int ret = -EINVAL;
+ int idx;
+
+ trace_kvm_set_irq(irq, level, irq_source_id);
+
+ /*
+ * Injection into either PIC or IOAPIC might need to scan all CPUs,
+ * which would need to be retried from thread context; when same GSI
+ * is connected to both PIC and IOAPIC, we'd have to report a
+ * partial failure here.
+ * Since there's no easy way to do this, we only support injecting MSI
+ * which is limited to 1:1 GSI mapping.
+ */
+ idx = srcu_read_lock(&kvm->irq_srcu);
+ if (kvm_irq_map_gsi(kvm, entries, irq) > 0) {
+ e = &entries[0];
+ ret = kvm_arch_set_irq_inatomic(e, kvm, irq_source_id,
+ irq, level);
+ }
+ srcu_read_unlock(&kvm->irq_srcu, idx);
+ return ret;
+}
+
+
static irqreturn_t kvm_assigned_dev_msi(int irq, void *dev_id)
{
struct kvm_assigned_dev_kernel *assigned_dev = dev_id;
@@ -150,9 +184,7 @@ static irqreturn_t kvm_assigned_dev_thread_msi(int irq, void *dev_id)
return IRQ_HANDLED;
}
-#endif
-#ifdef __KVM_HAVE_MSIX
static irqreturn_t kvm_assigned_dev_msix(int irq, void *dev_id)
{
struct kvm_assigned_dev_kernel *assigned_dev = dev_id;
@@ -183,7 +215,6 @@ static irqreturn_t kvm_assigned_dev_thread_msix(int irq, void *dev_id)
return IRQ_HANDLED;
}
-#endif
/* Ack the irq line for an assigned device */
static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
@@ -340,14 +371,10 @@ static void kvm_free_assigned_device(struct kvm *kvm,
void kvm_free_all_assigned_devices(struct kvm *kvm)
{
- struct list_head *ptr, *ptr2;
- struct kvm_assigned_dev_kernel *assigned_dev;
-
- list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
- assigned_dev = list_entry(ptr,
- struct kvm_assigned_dev_kernel,
- list);
+ struct kvm_assigned_dev_kernel *assigned_dev, *tmp;
+ list_for_each_entry_safe(assigned_dev, tmp,
+ &kvm->arch.assigned_dev_head, list) {
kvm_free_assigned_device(kvm, assigned_dev);
}
}
@@ -386,7 +413,6 @@ static int assigned_device_enable_host_intx(struct kvm *kvm,
return 0;
}
-#ifdef __KVM_HAVE_MSI
static int assigned_device_enable_host_msi(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev)
{
@@ -408,9 +434,7 @@ static int assigned_device_enable_host_msi(struct kvm *kvm,
return 0;
}
-#endif
-#ifdef __KVM_HAVE_MSIX
static int assigned_device_enable_host_msix(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev)
{
@@ -443,8 +467,6 @@ err:
return r;
}
-#endif
-
static int assigned_device_enable_guest_intx(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev,
struct kvm_assigned_irq *irq)
@@ -454,7 +476,6 @@ static int assigned_device_enable_guest_intx(struct kvm *kvm,
return 0;
}
-#ifdef __KVM_HAVE_MSI
static int assigned_device_enable_guest_msi(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev,
struct kvm_assigned_irq *irq)
@@ -463,9 +484,7 @@ static int assigned_device_enable_guest_msi(struct kvm *kvm,
dev->ack_notifier.gsi = -1;
return 0;
}
-#endif
-#ifdef __KVM_HAVE_MSIX
static int assigned_device_enable_guest_msix(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev,
struct kvm_assigned_irq *irq)
@@ -474,7 +493,6 @@ static int assigned_device_enable_guest_msix(struct kvm *kvm,
dev->ack_notifier.gsi = -1;
return 0;
}
-#endif
static int assign_host_irq(struct kvm *kvm,
struct kvm_assigned_dev_kernel *dev,
@@ -492,16 +510,12 @@ static int assign_host_irq(struct kvm *kvm,
case KVM_DEV_IRQ_HOST_INTX:
r = assigned_device_enable_host_intx(kvm, dev);
break;
-#ifdef __KVM_HAVE_MSI
case KVM_DEV_IRQ_HOST_MSI:
r = assigned_device_enable_host_msi(kvm, dev);
break;
-#endif
-#ifdef __KVM_HAVE_MSIX
case KVM_DEV_IRQ_HOST_MSIX:
r = assigned_device_enable_host_msix(kvm, dev);
break;
-#endif
default:
r = -EINVAL;
}
@@ -534,16 +548,12 @@ static int assign_guest_irq(struct kvm *kvm,
case KVM_DEV_IRQ_GUEST_INTX:
r = assigned_device_enable_guest_intx(kvm, dev, irq);
break;
-#ifdef __KVM_HAVE_MSI
case KVM_DEV_IRQ_GUEST_MSI:
r = assigned_device_enable_guest_msi(kvm, dev, irq);
break;
-#endif
-#ifdef __KVM_HAVE_MSIX
case KVM_DEV_IRQ_GUEST_MSIX:
r = assigned_device_enable_guest_msix(kvm, dev, irq);
break;
-#endif
default:
r = -EINVAL;
}
@@ -826,7 +836,6 @@ out:
}
-#ifdef __KVM_HAVE_MSIX
static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm,
struct kvm_assigned_msix_nr *entry_nr)
{
@@ -906,7 +915,6 @@ msix_entry_out:
return r;
}
-#endif
static int kvm_vm_ioctl_set_pci_irq_mask(struct kvm *kvm,
struct kvm_assigned_pci_dev *assigned_dev)
@@ -1012,7 +1020,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
goto out;
break;
}
-#ifdef __KVM_HAVE_MSIX
case KVM_ASSIGN_SET_MSIX_NR: {
struct kvm_assigned_msix_nr entry_nr;
r = -EFAULT;
@@ -1033,7 +1040,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl,
goto out;
break;
}
-#endif
case KVM_ASSIGN_SET_INTX_MASK: {
struct kvm_assigned_pci_dev assigned_dev;
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 2fbea25..0029644 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -30,7 +30,7 @@ static u32 xstate_required_size(u64 xstate_bv, bool compacted)
int feature_bit = 0;
u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
- xstate_bv &= XSTATE_EXTEND_MASK;
+ xstate_bv &= XFEATURE_MASK_EXTEND;
while (xstate_bv) {
if (xstate_bv & 0x1) {
u32 eax, ebx, ecx, edx, offset;
@@ -46,12 +46,19 @@ static u32 xstate_required_size(u64 xstate_bv, bool compacted)
return ret;
}
+bool kvm_mpx_supported(void)
+{
+ return ((host_xcr0 & (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR))
+ && kvm_x86_ops->mpx_supported());
+}
+EXPORT_SYMBOL_GPL(kvm_mpx_supported);
+
u64 kvm_supported_xcr0(void)
{
u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0;
- if (!kvm_x86_ops->mpx_supported())
- xcr0 &= ~(XSTATE_BNDREGS | XSTATE_BNDCSR);
+ if (!kvm_mpx_supported())
+ xcr0 &= ~(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
return xcr0;
}
@@ -97,8 +104,7 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
- vcpu->arch.eager_fpu = use_eager_fpu() || guest_cpuid_has_mpx(vcpu);
- if (vcpu->arch.eager_fpu)
+ if (use_eager_fpu())
kvm_x86_ops->fpu_activate(vcpu);
/*
@@ -295,7 +301,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
#endif
unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
- unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0;
+ unsigned f_mpx = kvm_mpx_supported() ? F(MPX) : 0;
unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
/* cpuid 1.edx */
@@ -348,7 +354,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) |
F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) |
- F(AVX512CD);
+ F(AVX512CD) | F(CLFLUSHOPT) | F(CLWB) | F(PCOMMIT);
/* cpuid 0xD.1.eax */
const u32 kvm_supported_word10_x86_features =
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index dd05b9c..66a6581 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -2,8 +2,10 @@
#define ARCH_X86_KVM_CPUID_H
#include "x86.h"
+#include <asm/cpu.h>
int kvm_update_cpuid(struct kvm_vcpu *vcpu);
+bool kvm_mpx_supported(void);
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
u32 function, u32 index);
int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
@@ -38,6 +40,14 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
return best && (best->ecx & bit(X86_FEATURE_XSAVE));
}
+static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 1, 0);
+ return best && (best->edx & bit(X86_FEATURE_MTRR));
+}
+
static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
@@ -126,11 +136,73 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
return best && (best->ebx & bit(X86_FEATURE_RTM));
}
-static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
+static inline bool guest_cpuid_has_pcommit(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
best = kvm_find_cpuid_entry(vcpu, 7, 0);
- return best && (best->ebx & bit(X86_FEATURE_MPX));
+ return best && (best->ebx & bit(X86_FEATURE_PCOMMIT));
+}
+
+static inline bool guest_cpuid_has_rdtscp(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+ return best && (best->edx & bit(X86_FEATURE_RDTSCP));
+}
+
+/*
+ * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3
+ */
+#define BIT_NRIPS 3
+
+static inline bool guest_cpuid_has_nrips(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x8000000a, 0);
+
+ /*
+ * NRIPS is a scattered cpuid feature, so we can't use
+ * X86_FEATURE_NRIPS here (X86_FEATURE_NRIPS would be bit
+ * position 8, not 3).
+ */
+ return best && (best->edx & bit(BIT_NRIPS));
}
+#undef BIT_NRIPS
+
+static inline int guest_cpuid_family(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
+ if (!best)
+ return -1;
+
+ return x86_family(best->eax);
+}
+
+static inline int guest_cpuid_model(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
+ if (!best)
+ return -1;
+
+ return x86_model(best->eax);
+}
+
+static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
+ if (!best)
+ return -1;
+
+ return x86_stepping(best->eax);
+}
+
#endif
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9da95b9..b9b09fe 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -650,10 +650,10 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
u16 sel;
la = seg_base(ctxt, addr.seg) + addr.ea;
- *linear = la;
*max_size = 0;
switch (mode) {
case X86EMUL_MODE_PROT64:
+ *linear = la;
if (is_noncanonical_address(la))
goto bad;
@@ -662,6 +662,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
goto bad;
break;
default:
+ *linear = la = (u32)la;
usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL,
addr.seg);
if (!usable)
@@ -689,7 +690,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
if (size > *max_size)
goto bad;
}
- la &= (u32)-1;
break;
}
if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0))
@@ -2272,8 +2272,8 @@ static int emulator_has_longmode(struct x86_emulate_ctxt *ctxt)
#define GET_SMSTATE(type, smbase, offset) \
({ \
type __val; \
- int r = ctxt->ops->read_std(ctxt, smbase + offset, &__val, \
- sizeof(__val), NULL); \
+ int r = ctxt->ops->read_phys(ctxt, smbase + offset, &__val, \
+ sizeof(__val)); \
if (r != X86EMUL_CONTINUE) \
return X86EMUL_UNHANDLEABLE; \
__val; \
@@ -2484,17 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
/*
* Get back to real mode, to prepare a safe state in which to load
- * CR0/CR3/CR4/EFER. Also this will ensure that addresses passed
- * to read_std/write_std are not virtual.
- *
- * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
+ * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
+ * supports long mode.
*/
+ cr4 = ctxt->ops->get_cr(ctxt, 4);
+ if (emulator_has_longmode(ctxt)) {
+ struct desc_struct cs_desc;
+
+ /* Zero CR4.PCIDE before CR0.PG. */
+ if (cr4 & X86_CR4_PCIDE) {
+ ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
+ cr4 &= ~X86_CR4_PCIDE;
+ }
+
+ /* A 32-bit code segment is required to clear EFER.LMA. */
+ memset(&cs_desc, 0, sizeof(cs_desc));
+ cs_desc.type = 0xb;
+ cs_desc.s = cs_desc.g = cs_desc.p = 1;
+ ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
+ }
+
+ /* For the 64-bit case, this will clear EFER.LMA. */
cr0 = ctxt->ops->get_cr(ctxt, 0);
if (cr0 & X86_CR0_PE)
ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
- cr4 = ctxt->ops->get_cr(ctxt, 4);
+
+ /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
if (cr4 & X86_CR4_PAE)
ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
+
+ /* And finally go back to 32-bit mode. */
efer = 0;
ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
@@ -4455,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
/* 0xA8 - 0xAF */
I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
- II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
+ II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index a8160d2..5ff3485 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -23,13 +23,665 @@
#include "x86.h"
#include "lapic.h"
+#include "ioapic.h"
#include "hyperv.h"
#include <linux/kvm_host.h>
+#include <linux/highmem.h>
+#include <asm/apicdef.h>
#include <trace/events/kvm.h>
#include "trace.h"
+static inline u64 synic_read_sint(struct kvm_vcpu_hv_synic *synic, int sint)
+{
+ return atomic64_read(&synic->sint[sint]);
+}
+
+static inline int synic_get_sint_vector(u64 sint_value)
+{
+ if (sint_value & HV_SYNIC_SINT_MASKED)
+ return -1;
+ return sint_value & HV_SYNIC_SINT_VECTOR_MASK;
+}
+
+static bool synic_has_vector_connected(struct kvm_vcpu_hv_synic *synic,
+ int vector)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+ if (synic_get_sint_vector(synic_read_sint(synic, i)) == vector)
+ return true;
+ }
+ return false;
+}
+
+static bool synic_has_vector_auto_eoi(struct kvm_vcpu_hv_synic *synic,
+ int vector)
+{
+ int i;
+ u64 sint_value;
+
+ for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+ sint_value = synic_read_sint(synic, i);
+ if (synic_get_sint_vector(sint_value) == vector &&
+ sint_value & HV_SYNIC_SINT_AUTO_EOI)
+ return true;
+ }
+ return false;
+}
+
+static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
+ u64 data, bool host)
+{
+ int vector;
+
+ vector = data & HV_SYNIC_SINT_VECTOR_MASK;
+ if (vector < 16 && !host)
+ return 1;
+ /*
+ * Guest may configure multiple SINTs to use the same vector, so
+ * we maintain a bitmap of vectors handled by synic, and a
+ * bitmap of vectors with auto-eoi behavior. The bitmaps are
+ * updated here, and atomically queried on fast paths.
+ */
+
+ atomic64_set(&synic->sint[sint], data);
+
+ if (synic_has_vector_connected(synic, vector))
+ __set_bit(vector, synic->vec_bitmap);
+ else
+ __clear_bit(vector, synic->vec_bitmap);
+
+ if (synic_has_vector_auto_eoi(synic, vector))
+ __set_bit(vector, synic->auto_eoi_bitmap);
+ else
+ __clear_bit(vector, synic->auto_eoi_bitmap);
+
+ /* Load SynIC vectors into EOI exit bitmap */
+ kvm_make_request(KVM_REQ_SCAN_IOAPIC, synic_to_vcpu(synic));
+ return 0;
+}
+
+static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vcpu_id)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vcpu_hv_synic *synic;
+
+ if (vcpu_id >= atomic_read(&kvm->online_vcpus))
+ return NULL;
+ vcpu = kvm_get_vcpu(kvm, vcpu_id);
+ if (!vcpu)
+ return NULL;
+ synic = vcpu_to_synic(vcpu);
+ return (synic->active) ? synic : NULL;
+}
+
+static void synic_clear_sint_msg_pending(struct kvm_vcpu_hv_synic *synic,
+ u32 sint)
+{
+ struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+ struct page *page;
+ gpa_t gpa;
+ struct hv_message *msg;
+ struct hv_message_page *msg_page;
+
+ gpa = synic->msg_page & PAGE_MASK;
+ page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+ if (is_error_page(page)) {
+ vcpu_err(vcpu, "Hyper-V SynIC can't get msg page, gpa 0x%llx\n",
+ gpa);
+ return;
+ }
+ msg_page = kmap_atomic(page);
+
+ msg = &msg_page->sint_message[sint];
+ msg->header.message_flags.msg_pending = 0;
+
+ kunmap_atomic(msg_page);
+ kvm_release_page_dirty(page);
+ kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+}
+
+static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+ struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+ struct kvm_vcpu_hv_stimer *stimer;
+ int gsi, idx, stimers_pending;
+
+ trace_kvm_hv_notify_acked_sint(vcpu->vcpu_id, sint);
+
+ if (synic->msg_page & HV_SYNIC_SIMP_ENABLE)
+ synic_clear_sint_msg_pending(synic, sint);
+
+ /* Try to deliver pending Hyper-V SynIC timers messages */
+ stimers_pending = 0;
+ for (idx = 0; idx < ARRAY_SIZE(hv_vcpu->stimer); idx++) {
+ stimer = &hv_vcpu->stimer[idx];
+ if (stimer->msg_pending &&
+ (stimer->config & HV_STIMER_ENABLE) &&
+ HV_STIMER_SINT(stimer->config) == sint) {
+ set_bit(stimer->index,
+ hv_vcpu->stimer_pending_bitmap);
+ stimers_pending++;
+ }
+ }
+ if (stimers_pending)
+ kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+
+ idx = srcu_read_lock(&kvm->irq_srcu);
+ gsi = atomic_read(&synic->sint_to_gsi[sint]);
+ if (gsi != -1)
+ kvm_notify_acked_gsi(kvm, gsi);
+ srcu_read_unlock(&kvm->irq_srcu, idx);
+}
+
+static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
+{
+ struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+ struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+
+ hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
+ hv_vcpu->exit.u.synic.msr = msr;
+ hv_vcpu->exit.u.synic.control = synic->control;
+ hv_vcpu->exit.u.synic.evt_page = synic->evt_page;
+ hv_vcpu->exit.u.synic.msg_page = synic->msg_page;
+
+ kvm_make_request(KVM_REQ_HV_EXIT, vcpu);
+}
+
+static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
+ u32 msr, u64 data, bool host)
+{
+ struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+ int ret;
+
+ if (!synic->active)
+ return 1;
+
+ trace_kvm_hv_synic_set_msr(vcpu->vcpu_id, msr, data, host);
+
+ ret = 0;
+ switch (msr) {
+ case HV_X64_MSR_SCONTROL:
+ synic->control = data;
+ if (!host)
+ synic_exit(synic, msr);
+ break;
+ case HV_X64_MSR_SVERSION:
+ if (!host) {
+ ret = 1;
+ break;
+ }
+ synic->version = data;
+ break;
+ case HV_X64_MSR_SIEFP:
+ if (data & HV_SYNIC_SIEFP_ENABLE)
+ if (kvm_clear_guest(vcpu->kvm,
+ data & PAGE_MASK, PAGE_SIZE)) {
+ ret = 1;
+ break;
+ }
+ synic->evt_page = data;
+ if (!host)
+ synic_exit(synic, msr);
+ break;
+ case HV_X64_MSR_SIMP:
+ if (data & HV_SYNIC_SIMP_ENABLE)
+ if (kvm_clear_guest(vcpu->kvm,
+ data & PAGE_MASK, PAGE_SIZE)) {
+ ret = 1;
+ break;
+ }
+ synic->msg_page = data;
+ if (!host)
+ synic_exit(synic, msr);
+ break;
+ case HV_X64_MSR_EOM: {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(synic->sint); i++)
+ kvm_hv_notify_acked_sint(vcpu, i);
+ break;
+ }
+ case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+ ret = synic_set_sint(synic, msr - HV_X64_MSR_SINT0, data, host);
+ break;
+ default:
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+static int synic_get_msr(struct kvm_vcpu_hv_synic *synic, u32 msr, u64 *pdata)
+{
+ int ret;
+
+ if (!synic->active)
+ return 1;
+
+ ret = 0;
+ switch (msr) {
+ case HV_X64_MSR_SCONTROL:
+ *pdata = synic->control;
+ break;
+ case HV_X64_MSR_SVERSION:
+ *pdata = synic->version;
+ break;
+ case HV_X64_MSR_SIEFP:
+ *pdata = synic->evt_page;
+ break;
+ case HV_X64_MSR_SIMP:
+ *pdata = synic->msg_page;
+ break;
+ case HV_X64_MSR_EOM:
+ *pdata = 0;
+ break;
+ case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+ *pdata = atomic64_read(&synic->sint[msr - HV_X64_MSR_SINT0]);
+ break;
+ default:
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+int synic_set_irq(struct kvm_vcpu_hv_synic *synic, u32 sint)
+{
+ struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+ struct kvm_lapic_irq irq;
+ int ret, vector;
+
+ if (sint >= ARRAY_SIZE(synic->sint))
+ return -EINVAL;
+
+ vector = synic_get_sint_vector(synic_read_sint(synic, sint));
+ if (vector < 0)
+ return -ENOENT;
+
+ memset(&irq, 0, sizeof(irq));
+ irq.dest_id = kvm_apic_id(vcpu->arch.apic);
+ irq.dest_mode = APIC_DEST_PHYSICAL;
+ irq.delivery_mode = APIC_DM_FIXED;
+ irq.vector = vector;
+ irq.level = 1;
+
+ ret = kvm_irq_delivery_to_apic(vcpu->kvm, NULL, &irq, NULL);
+ trace_kvm_hv_synic_set_irq(vcpu->vcpu_id, sint, irq.vector, ret);
+ return ret;
+}
+
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint)
+{
+ struct kvm_vcpu_hv_synic *synic;
+
+ synic = synic_get(kvm, vcpu_id);
+ if (!synic)
+ return -EINVAL;
+
+ return synic_set_irq(synic, sint);
+}
+
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector)
+{
+ struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+ int i;
+
+ trace_kvm_hv_synic_send_eoi(vcpu->vcpu_id, vector);
+
+ for (i = 0; i < ARRAY_SIZE(synic->sint); i++)
+ if (synic_get_sint_vector(synic_read_sint(synic, i)) == vector)
+ kvm_hv_notify_acked_sint(vcpu, i);
+}
+
+static int kvm_hv_set_sint_gsi(struct kvm *kvm, u32 vcpu_id, u32 sint, int gsi)
+{
+ struct kvm_vcpu_hv_synic *synic;
+
+ synic = synic_get(kvm, vcpu_id);
+ if (!synic)
+ return -EINVAL;
+
+ if (sint >= ARRAY_SIZE(synic->sint_to_gsi))
+ return -EINVAL;
+
+ atomic_set(&synic->sint_to_gsi[sint], gsi);
+ return 0;
+}
+
+void kvm_hv_irq_routing_update(struct kvm *kvm)
+{
+ struct kvm_irq_routing_table *irq_rt;
+ struct kvm_kernel_irq_routing_entry *e;
+ u32 gsi;
+
+ irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
+ lockdep_is_held(&kvm->irq_lock));
+
+ for (gsi = 0; gsi < irq_rt->nr_rt_entries; gsi++) {
+ hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
+ if (e->type == KVM_IRQ_ROUTING_HV_SINT)
+ kvm_hv_set_sint_gsi(kvm, e->hv_sint.vcpu,
+ e->hv_sint.sint, gsi);
+ }
+ }
+}
+
+static void synic_init(struct kvm_vcpu_hv_synic *synic)
+{
+ int i;
+
+ memset(synic, 0, sizeof(*synic));
+ synic->version = HV_SYNIC_VERSION_1;
+ for (i = 0; i < ARRAY_SIZE(synic->sint); i++) {
+ atomic64_set(&synic->sint[i], HV_SYNIC_SINT_MASKED);
+ atomic_set(&synic->sint_to_gsi[i], -1);
+ }
+}
+
+static u64 get_time_ref_counter(struct kvm *kvm)
+{
+ return div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+}
+
+static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
+ bool vcpu_kick)
+{
+ struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+ set_bit(stimer->index,
+ vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+ kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
+ if (vcpu_kick)
+ kvm_vcpu_kick(vcpu);
+}
+
+static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
+{
+ struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+
+ trace_kvm_hv_stimer_cleanup(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index);
+
+ hrtimer_cancel(&stimer->timer);
+ clear_bit(stimer->index,
+ vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+ stimer->msg_pending = false;
+ stimer->exp_time = 0;
+}
+
+static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
+{
+ struct kvm_vcpu_hv_stimer *stimer;
+
+ stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
+ trace_kvm_hv_stimer_callback(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index);
+ stimer_mark_pending(stimer, true);
+
+ return HRTIMER_NORESTART;
+}
+
+/*
+ * stimer_start() assumptions:
+ * a) stimer->count is not equal to 0
+ * b) stimer->config has HV_STIMER_ENABLE flag
+ */
+static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
+{
+ u64 time_now;
+ ktime_t ktime_now;
+
+ time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+ ktime_now = ktime_get();
+
+ if (stimer->config & HV_STIMER_PERIODIC) {
+ if (stimer->exp_time) {
+ if (time_now >= stimer->exp_time) {
+ u64 remainder;
+
+ div64_u64_rem(time_now - stimer->exp_time,
+ stimer->count, &remainder);
+ stimer->exp_time =
+ time_now + (stimer->count - remainder);
+ }
+ } else
+ stimer->exp_time = time_now + stimer->count;
+
+ trace_kvm_hv_stimer_start_periodic(
+ stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index,
+ time_now, stimer->exp_time);
+
+ hrtimer_start(&stimer->timer,
+ ktime_add_ns(ktime_now,
+ 100 * (stimer->exp_time - time_now)),
+ HRTIMER_MODE_ABS);
+ return 0;
+ }
+ stimer->exp_time = stimer->count;
+ if (time_now >= stimer->count) {
+ /*
+ * Expire timer according to Hypervisor Top-Level Functional
+ * specification v4(15.3.1):
+ * "If a one shot is enabled and the specified count is in
+ * the past, it will expire immediately."
+ */
+ stimer_mark_pending(stimer, false);
+ return 0;
+ }
+
+ trace_kvm_hv_stimer_start_one_shot(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index,
+ time_now, stimer->count);
+
+ hrtimer_start(&stimer->timer,
+ ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)),
+ HRTIMER_MODE_ABS);
+ return 0;
+}
+
+static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
+ bool host)
+{
+ trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index, config, host);
+
+ stimer_cleanup(stimer);
+ if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0)
+ config &= ~HV_STIMER_ENABLE;
+ stimer->config = config;
+ stimer_mark_pending(stimer, false);
+ return 0;
+}
+
+static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
+ bool host)
+{
+ trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index, count, host);
+
+ stimer_cleanup(stimer);
+ stimer->count = count;
+ if (stimer->count == 0)
+ stimer->config &= ~HV_STIMER_ENABLE;
+ else if (stimer->config & HV_STIMER_AUTOENABLE)
+ stimer->config |= HV_STIMER_ENABLE;
+ stimer_mark_pending(stimer, false);
+ return 0;
+}
+
+static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
+{
+ *pconfig = stimer->config;
+ return 0;
+}
+
+static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
+{
+ *pcount = stimer->count;
+ return 0;
+}
+
+static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
+ struct hv_message *src_msg)
+{
+ struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+ struct page *page;
+ gpa_t gpa;
+ struct hv_message *dst_msg;
+ int r;
+ struct hv_message_page *msg_page;
+
+ if (!(synic->msg_page & HV_SYNIC_SIMP_ENABLE))
+ return -ENOENT;
+
+ gpa = synic->msg_page & PAGE_MASK;
+ page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
+ if (is_error_page(page))
+ return -EFAULT;
+
+ msg_page = kmap_atomic(page);
+ dst_msg = &msg_page->sint_message[sint];
+ if (sync_cmpxchg(&dst_msg->header.message_type, HVMSG_NONE,
+ src_msg->header.message_type) != HVMSG_NONE) {
+ dst_msg->header.message_flags.msg_pending = 1;
+ r = -EAGAIN;
+ } else {
+ memcpy(&dst_msg->u.payload, &src_msg->u.payload,
+ src_msg->header.payload_size);
+ dst_msg->header.message_type = src_msg->header.message_type;
+ dst_msg->header.payload_size = src_msg->header.payload_size;
+ r = synic_set_irq(synic, sint);
+ if (r >= 1)
+ r = 0;
+ else if (r == 0)
+ r = -EFAULT;
+ }
+ kunmap_atomic(msg_page);
+ kvm_release_page_dirty(page);
+ kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
+ return r;
+}
+
+static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+ struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+ struct hv_message *msg = &stimer->msg;
+ struct hv_timer_message_payload *payload =
+ (struct hv_timer_message_payload *)&msg->u.payload;
+
+ payload->expiration_time = stimer->exp_time;
+ payload->delivery_time = get_time_ref_counter(vcpu->kvm);
+ return synic_deliver_msg(vcpu_to_synic(vcpu),
+ HV_STIMER_SINT(stimer->config), msg);
+}
+
+static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
+{
+ int r;
+
+ stimer->msg_pending = true;
+ r = stimer_send_msg(stimer);
+ trace_kvm_hv_stimer_expiration(stimer_to_vcpu(stimer)->vcpu_id,
+ stimer->index, r);
+ if (!r) {
+ stimer->msg_pending = false;
+ if (!(stimer->config & HV_STIMER_PERIODIC))
+ stimer->config &= ~HV_STIMER_ENABLE;
+ }
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
+{
+ struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+ struct kvm_vcpu_hv_stimer *stimer;
+ u64 time_now, exp_time;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+ if (test_and_clear_bit(i, hv_vcpu->stimer_pending_bitmap)) {
+ stimer = &hv_vcpu->stimer[i];
+ if (stimer->config & HV_STIMER_ENABLE) {
+ exp_time = stimer->exp_time;
+
+ if (exp_time) {
+ time_now =
+ get_time_ref_counter(vcpu->kvm);
+ if (time_now >= exp_time)
+ stimer_expiration(stimer);
+ }
+
+ if ((stimer->config & HV_STIMER_ENABLE) &&
+ stimer->count)
+ stimer_start(stimer);
+ else
+ stimer_cleanup(stimer);
+ }
+ }
+}
+
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
+{
+ struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+ stimer_cleanup(&hv_vcpu->stimer[i]);
+}
+
+static void stimer_prepare_msg(struct kvm_vcpu_hv_stimer *stimer)
+{
+ struct hv_message *msg = &stimer->msg;
+ struct hv_timer_message_payload *payload =
+ (struct hv_timer_message_payload *)&msg->u.payload;
+
+ memset(&msg->header, 0, sizeof(msg->header));
+ msg->header.message_type = HVMSG_TIMER_EXPIRED;
+ msg->header.payload_size = sizeof(*payload);
+
+ payload->timer_index = stimer->index;
+ payload->expiration_time = 0;
+ payload->delivery_time = 0;
+}
+
+static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
+{
+ memset(stimer, 0, sizeof(*stimer));
+ stimer->index = timer_index;
+ hrtimer_init(&stimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ stimer->timer.function = stimer_timer_callback;
+ stimer_prepare_msg(stimer);
+}
+
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
+{
+ struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+ int i;
+
+ synic_init(&hv_vcpu->synic);
+
+ bitmap_zero(hv_vcpu->stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
+ for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
+ stimer_init(&hv_vcpu->stimer[i], i);
+}
+
+int kvm_hv_activate_synic(struct kvm_vcpu *vcpu)
+{
+ /*
+ * Hyper-V SynIC auto EOI SINT's are
+ * not compatible with APICV, so deactivate APICV
+ */
+ kvm_vcpu_deactivate_apicv(vcpu);
+ vcpu_to_synic(vcpu)->active = true;
+ return 0;
+}
+
static bool kvm_hv_msr_partition_wide(u32 msr)
{
bool r = false;
@@ -41,6 +693,7 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
case HV_X64_MSR_TIME_REF_COUNT:
case HV_X64_MSR_CRASH_CTL:
case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+ case HV_X64_MSR_RESET:
r = true;
break;
}
@@ -163,6 +816,12 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
data);
case HV_X64_MSR_CRASH_CTL:
return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
+ case HV_X64_MSR_RESET:
+ if (data == 1) {
+ vcpu_debug(vcpu, "hyper-v reset requested\n");
+ kvm_make_request(KVM_REQ_HV_RESET, vcpu);
+ }
+ break;
default:
vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
msr, data);
@@ -171,7 +830,16 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
return 0;
}
-static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+/* Calculate cpu time spent by current task in 100ns units */
+static u64 current_task_runtime_100ns(void)
+{
+ cputime_t utime, stime;
+
+ task_cputime_adjusted(current, &utime, &stime);
+ return div_u64(cputime_to_nsecs(utime + stime), 100);
+}
+
+static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
{
struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
@@ -205,6 +873,36 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
case HV_X64_MSR_TPR:
return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
+ case HV_X64_MSR_VP_RUNTIME:
+ if (!host)
+ return 1;
+ hv->runtime_offset = data - current_task_runtime_100ns();
+ break;
+ case HV_X64_MSR_SCONTROL:
+ case HV_X64_MSR_SVERSION:
+ case HV_X64_MSR_SIEFP:
+ case HV_X64_MSR_SIMP:
+ case HV_X64_MSR_EOM:
+ case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+ return synic_set_msr(vcpu_to_synic(vcpu), msr, data, host);
+ case HV_X64_MSR_STIMER0_CONFIG:
+ case HV_X64_MSR_STIMER1_CONFIG:
+ case HV_X64_MSR_STIMER2_CONFIG:
+ case HV_X64_MSR_STIMER3_CONFIG: {
+ int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+ return stimer_set_config(vcpu_to_stimer(vcpu, timer_index),
+ data, host);
+ }
+ case HV_X64_MSR_STIMER0_COUNT:
+ case HV_X64_MSR_STIMER1_COUNT:
+ case HV_X64_MSR_STIMER2_COUNT:
+ case HV_X64_MSR_STIMER3_COUNT: {
+ int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+ return stimer_set_count(vcpu_to_stimer(vcpu, timer_index),
+ data, host);
+ }
default:
vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
msr, data);
@@ -227,11 +925,9 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case HV_X64_MSR_HYPERCALL:
data = hv->hv_hypercall;
break;
- case HV_X64_MSR_TIME_REF_COUNT: {
- data =
- div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+ case HV_X64_MSR_TIME_REF_COUNT:
+ data = get_time_ref_counter(kvm);
break;
- }
case HV_X64_MSR_REFERENCE_TSC:
data = hv->hv_tsc_page;
break;
@@ -241,6 +937,9 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
pdata);
case HV_X64_MSR_CRASH_CTL:
return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
+ case HV_X64_MSR_RESET:
+ data = 0;
+ break;
default:
vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
return 1;
@@ -277,6 +976,34 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case HV_X64_MSR_APIC_ASSIST_PAGE:
data = hv->hv_vapic;
break;
+ case HV_X64_MSR_VP_RUNTIME:
+ data = current_task_runtime_100ns() + hv->runtime_offset;
+ break;
+ case HV_X64_MSR_SCONTROL:
+ case HV_X64_MSR_SVERSION:
+ case HV_X64_MSR_SIEFP:
+ case HV_X64_MSR_SIMP:
+ case HV_X64_MSR_EOM:
+ case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
+ return synic_get_msr(vcpu_to_synic(vcpu), msr, pdata);
+ case HV_X64_MSR_STIMER0_CONFIG:
+ case HV_X64_MSR_STIMER1_CONFIG:
+ case HV_X64_MSR_STIMER2_CONFIG:
+ case HV_X64_MSR_STIMER3_CONFIG: {
+ int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
+
+ return stimer_get_config(vcpu_to_stimer(vcpu, timer_index),
+ pdata);
+ }
+ case HV_X64_MSR_STIMER0_COUNT:
+ case HV_X64_MSR_STIMER1_COUNT:
+ case HV_X64_MSR_STIMER2_COUNT:
+ case HV_X64_MSR_STIMER3_COUNT: {
+ int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
+
+ return stimer_get_count(vcpu_to_stimer(vcpu, timer_index),
+ pdata);
+ }
default:
vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
return 1;
@@ -295,7 +1022,7 @@ int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
mutex_unlock(&vcpu->kvm->lock);
return r;
} else
- return kvm_hv_set_msr(vcpu, msr, data);
+ return kvm_hv_set_msr(vcpu, msr, data, host);
}
int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
@@ -316,6 +1043,27 @@ bool kvm_hv_hypercall_enabled(struct kvm *kvm)
return kvm->arch.hyperv.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
}
+static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
+{
+ bool longmode;
+
+ longmode = is_64_bit_mode(vcpu);
+ if (longmode)
+ kvm_register_write(vcpu, VCPU_REGS_RAX, result);
+ else {
+ kvm_register_write(vcpu, VCPU_REGS_RDX, result >> 32);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, result & 0xffffffff);
+ }
+}
+
+static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+{
+ struct kvm_run *run = vcpu->run;
+
+ kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
+ return 1;
+}
+
int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
{
u64 param, ingpa, outgpa, ret;
@@ -328,7 +1076,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
*/
if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
kvm_queue_exception(vcpu, UD_VECTOR);
- return 0;
+ return 1;
}
longmode = is_64_bit_mode(vcpu);
@@ -356,22 +1104,33 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
+ /* Hypercall continuation is not supported yet */
+ if (rep_cnt || rep_idx) {
+ res = HV_STATUS_INVALID_HYPERCALL_CODE;
+ goto set_result;
+ }
+
switch (code) {
- case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+ case HVCALL_NOTIFY_LONG_SPIN_WAIT:
kvm_vcpu_on_spin(vcpu);
break;
+ case HVCALL_POST_MESSAGE:
+ case HVCALL_SIGNAL_EVENT:
+ vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+ vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL;
+ vcpu->run->hyperv.u.hcall.input = param;
+ vcpu->run->hyperv.u.hcall.params[0] = ingpa;
+ vcpu->run->hyperv.u.hcall.params[1] = outgpa;
+ vcpu->arch.complete_userspace_io =
+ kvm_hv_hypercall_complete_userspace;
+ return 0;
default:
res = HV_STATUS_INVALID_HYPERCALL_CODE;
break;
}
+set_result:
ret = res | (((u64)rep_done & 0xfff) << 32);
- if (longmode) {
- kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
- } else {
- kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
- kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
- }
-
+ kvm_hv_hypercall_set_result(vcpu, ret);
return 1;
}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index c7bce55..60eccd4 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,9 +24,64 @@
#ifndef __ARCH_X86_KVM_HYPERV_H__
#define __ARCH_X86_KVM_HYPERV_H__
+static inline struct kvm_vcpu_hv *vcpu_to_hv_vcpu(struct kvm_vcpu *vcpu)
+{
+ return &vcpu->arch.hyperv;
+}
+
+static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
+{
+ struct kvm_vcpu_arch *arch;
+
+ arch = container_of(hv_vcpu, struct kvm_vcpu_arch, hyperv);
+ return container_of(arch, struct kvm_vcpu, arch);
+}
+
+static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+{
+ return &vcpu->arch.hyperv.synic;
+}
+
+static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+{
+ return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
+}
+
int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+
bool kvm_hv_hypercall_enabled(struct kvm *kvm);
int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
+void kvm_hv_irq_routing_update(struct kvm *kvm);
+int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
+void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
+int kvm_hv_activate_synic(struct kvm_vcpu *vcpu);
+
+void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
+
+static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
+ int timer_index)
+{
+ return &vcpu_to_hv_vcpu(vcpu)->stimer[timer_index];
+}
+
+static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
+{
+ struct kvm_vcpu_hv *hv_vcpu;
+
+ hv_vcpu = container_of(stimer - stimer->index, struct kvm_vcpu_hv,
+ stimer[0]);
+ return hv_vcpu_to_vcpu(hv_vcpu);
+}
+
+static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
+{
+ return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
+ HV_SYNIC_STIMER_COUNT);
+}
+
+void kvm_hv_process_stimers(struct kvm_vcpu *vcpu);
+
#endif
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index f90952f..a4bf5b4 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -35,6 +35,7 @@
#include <linux/kvm_host.h>
#include <linux/slab.h>
+#include "ioapic.h"
#include "irq.h"
#include "i8254.h"
#include "x86.h"
@@ -50,32 +51,9 @@
#define RW_STATE_WORD0 3
#define RW_STATE_WORD1 4
-/* Compute with 96 bit intermediate result: (a*b)/c */
-static u64 muldiv64(u64 a, u32 b, u32 c)
+static void pit_set_gate(struct kvm_pit *pit, int channel, u32 val)
{
- union {
- u64 ll;
- struct {
- u32 low, high;
- } l;
- } u, res;
- u64 rl, rh;
-
- u.ll = a;
- rl = (u64)u.l.low * (u64)b;
- rh = (u64)u.l.high * (u64)b;
- rh += (rl >> 32);
- res.l.high = div64_u64(rh, c);
- res.l.low = div64_u64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
- return res.ll;
-}
-
-static void pit_set_gate(struct kvm *kvm, int channel, u32 val)
-{
- struct kvm_kpit_channel_state *c =
- &kvm->arch.vpit->pit_state.channels[channel];
-
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
+ struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel];
switch (c->mode) {
default:
@@ -96,18 +74,16 @@ static void pit_set_gate(struct kvm *kvm, int channel, u32 val)
c->gate = val;
}
-static int pit_get_gate(struct kvm *kvm, int channel)
+static int pit_get_gate(struct kvm_pit *pit, int channel)
{
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
-
- return kvm->arch.vpit->pit_state.channels[channel].gate;
+ return pit->pit_state.channels[channel].gate;
}
-static s64 __kpit_elapsed(struct kvm *kvm)
+static s64 __kpit_elapsed(struct kvm_pit *pit)
{
s64 elapsed;
ktime_t remaining;
- struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
+ struct kvm_kpit_state *ps = &pit->pit_state;
if (!ps->period)
return 0;
@@ -127,26 +103,23 @@ static s64 __kpit_elapsed(struct kvm *kvm)
return elapsed;
}
-static s64 kpit_elapsed(struct kvm *kvm, struct kvm_kpit_channel_state *c,
+static s64 kpit_elapsed(struct kvm_pit *pit, struct kvm_kpit_channel_state *c,
int channel)
{
if (channel == 0)
- return __kpit_elapsed(kvm);
+ return __kpit_elapsed(pit);
return ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
}
-static int pit_get_count(struct kvm *kvm, int channel)
+static int pit_get_count(struct kvm_pit *pit, int channel)
{
- struct kvm_kpit_channel_state *c =
- &kvm->arch.vpit->pit_state.channels[channel];
+ struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel];
s64 d, t;
int counter;
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
-
- t = kpit_elapsed(kvm, c, channel);
- d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);
+ t = kpit_elapsed(pit, c, channel);
+ d = mul_u64_u32_div(t, KVM_PIT_FREQ, NSEC_PER_SEC);
switch (c->mode) {
case 0:
@@ -166,17 +139,14 @@ static int pit_get_count(struct kvm *kvm, int channel)
return counter;
}
-static int pit_get_out(struct kvm *kvm, int channel)
+static int pit_get_out(struct kvm_pit *pit, int channel)
{
- struct kvm_kpit_channel_state *c =
- &kvm->arch.vpit->pit_state.channels[channel];
+ struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel];
s64 d, t;
int out;
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
-
- t = kpit_elapsed(kvm, c, channel);
- d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);
+ t = kpit_elapsed(pit, c, channel);
+ d = mul_u64_u32_div(t, KVM_PIT_FREQ, NSEC_PER_SEC);
switch (c->mode) {
default:
@@ -201,29 +171,23 @@ static int pit_get_out(struct kvm *kvm, int channel)
return out;
}
-static void pit_latch_count(struct kvm *kvm, int channel)
+static void pit_latch_count(struct kvm_pit *pit, int channel)
{
- struct kvm_kpit_channel_state *c =
- &kvm->arch.vpit->pit_state.channels[channel];
-
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
+ struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel];
if (!c->count_latched) {
- c->latched_count = pit_get_count(kvm, channel);
+ c->latched_count = pit_get_count(pit, channel);
c->count_latched = c->rw_mode;
}
}
-static void pit_latch_status(struct kvm *kvm, int channel)
+static void pit_latch_status(struct kvm_pit *pit, int channel)
{
- struct kvm_kpit_channel_state *c =
- &kvm->arch.vpit->pit_state.channels[channel];
-
- WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
+ struct kvm_kpit_channel_state *c = &pit->pit_state.channels[channel];
if (!c->status_latched) {
/* TODO: Return NULL COUNT (bit 6). */
- c->status = ((pit_get_out(kvm, channel) << 7) |
+ c->status = ((pit_get_out(pit, channel) << 7) |
(c->rw_mode << 4) |
(c->mode << 1) |
c->bcd);
@@ -231,26 +195,24 @@ static void pit_latch_status(struct kvm *kvm, int channel)
}
}
+static inline struct kvm_pit *pit_state_to_pit(struct kvm_kpit_state *ps)
+{
+ return container_of(ps, struct kvm_pit, pit_state);
+}
+
static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
irq_ack_notifier);
- int value;
-
- spin_lock(&ps->inject_lock);
- value = atomic_dec_return(&ps->pending);
- if (value < 0)
- /* spurious acks can be generated if, for example, the
- * PIC is being reset. Handle it gracefully here
- */
- atomic_inc(&ps->pending);
- else if (value > 0)
- /* in this case, we had multiple outstanding pit interrupts
- * that we needed to inject. Reinject
- */
- queue_kthread_work(&ps->pit->worker, &ps->pit->expired);
- ps->irq_ack = 1;
- spin_unlock(&ps->inject_lock);
+ struct kvm_pit *pit = pit_state_to_pit(ps);
+
+ atomic_set(&ps->irq_ack, 1);
+ /* irq_ack should be set before pending is read. Order accesses with
+ * inc(pending) in pit_timer_fn and xchg(irq_ack, 0) in pit_do_work.
+ */
+ smp_mb();
+ if (atomic_dec_if_positive(&ps->pending) > 0)
+ queue_kthread_work(&pit->worker, &pit->expired);
}
void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
@@ -281,45 +243,36 @@ static void pit_do_work(struct kthread_work *work)
struct kvm_vcpu *vcpu;
int i;
struct kvm_kpit_state *ps = &pit->pit_state;
- int inject = 0;
- /* Try to inject pending interrupts when
- * last one has been acked.
+ if (atomic_read(&ps->reinject) && !atomic_xchg(&ps->irq_ack, 0))
+ return;
+
+ kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false);
+ kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false);
+
+ /*
+ * Provides NMI watchdog support via Virtual Wire mode.
+ * The route is: PIT -> LVT0 in NMI mode.
+ *
+ * Note: Our Virtual Wire implementation does not follow
+ * the MP specification. We propagate a PIT interrupt to all
+ * VCPUs and only when LVT0 is in NMI mode. The interrupt can
+ * also be simultaneously delivered through PIC and IOAPIC.
*/
- spin_lock(&ps->inject_lock);
- if (ps->irq_ack) {
- ps->irq_ack = 0;
- inject = 1;
- }
- spin_unlock(&ps->inject_lock);
- if (inject) {
- kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1, false);
- kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0, false);
-
- /*
- * Provides NMI watchdog support via Virtual Wire mode.
- * The route is: PIT -> PIC -> LVT0 in NMI mode.
- *
- * Note: Our Virtual Wire implementation is simplified, only
- * propagating PIT interrupts to all VCPUs when they have set
- * LVT0 to NMI delivery. Other PIC interrupts are just sent to
- * VCPU0, and only if its LVT0 is in EXTINT mode.
- */
- if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0)
- kvm_for_each_vcpu(i, vcpu, kvm)
- kvm_apic_nmi_wd_deliver(vcpu);
- }
+ if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0)
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ kvm_apic_nmi_wd_deliver(vcpu);
}
static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
{
struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
- struct kvm_pit *pt = ps->kvm->arch.vpit;
+ struct kvm_pit *pt = pit_state_to_pit(ps);
- if (ps->reinject || !atomic_read(&ps->pending)) {
+ if (atomic_read(&ps->reinject))
atomic_inc(&ps->pending);
- queue_kthread_work(&pt->worker, &pt->expired);
- }
+
+ queue_kthread_work(&pt->worker, &pt->expired);
if (ps->is_periodic) {
hrtimer_add_expires_ns(&ps->timer, ps->period);
@@ -328,29 +281,54 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
return HRTIMER_NORESTART;
}
-static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
+static inline void kvm_pit_reset_reinject(struct kvm_pit *pit)
{
- struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
+ atomic_set(&pit->pit_state.pending, 0);
+ atomic_set(&pit->pit_state.irq_ack, 1);
+}
+
+void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
+{
+ struct kvm_kpit_state *ps = &pit->pit_state;
+ struct kvm *kvm = pit->kvm;
+
+ if (atomic_read(&ps->reinject) == reinject)
+ return;
+
+ if (reinject) {
+ /* The initial state is preserved while ps->reinject == 0. */
+ kvm_pit_reset_reinject(pit);
+ kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
+ kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+ } else {
+ kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
+ kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+ }
+
+ atomic_set(&ps->reinject, reinject);
+}
+
+static void create_pit_timer(struct kvm_pit *pit, u32 val, int is_period)
+{
+ struct kvm_kpit_state *ps = &pit->pit_state;
+ struct kvm *kvm = pit->kvm;
s64 interval;
- if (!irqchip_in_kernel(kvm) || ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)
+ if (!ioapic_in_kernel(kvm) ||
+ ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)
return;
- interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
+ interval = mul_u64_u32_div(val, NSEC_PER_SEC, KVM_PIT_FREQ);
pr_debug("create pit timer, interval is %llu nsec\n", interval);
/* TODO The new value only affected after the retriggered */
hrtimer_cancel(&ps->timer);
- flush_kthread_work(&ps->pit->expired);
+ flush_kthread_work(&pit->expired);
ps->period = interval;
ps->is_periodic = is_period;
- ps->timer.function = pit_timer_fn;
- ps->kvm = ps->pit->kvm;
-
- atomic_set(&ps->pending, 0);
- ps->irq_ack = 1;
+ kvm_pit_reset_reinject(pit);
/*
* Do not allow the guest to program periodic timers with small
@@ -373,11 +351,9 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
HRTIMER_MODE_ABS);
}
-static void pit_load_count(struct kvm *kvm, int channel, u32 val)
+static void pit_load_count(struct kvm_pit *pit, int channel, u32 val)
{
- struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
-
- WARN_ON(!mutex_is_locked(&ps->lock));
+ struct kvm_kpit_state *ps = &pit->pit_state;
pr_debug("load_count val is %d, channel is %d\n", val, channel);
@@ -402,28 +378,33 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
case 1:
/* FIXME: enhance mode 4 precision */
case 4:
- create_pit_timer(kvm, val, 0);
+ create_pit_timer(pit, val, 0);
break;
case 2:
case 3:
- create_pit_timer(kvm, val, 1);
+ create_pit_timer(pit, val, 1);
break;
default:
- destroy_pit_timer(kvm->arch.vpit);
+ destroy_pit_timer(pit);
}
}
-void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start)
+void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val,
+ int hpet_legacy_start)
{
u8 saved_mode;
+
+ WARN_ON_ONCE(!mutex_is_locked(&pit->pit_state.lock));
+
if (hpet_legacy_start) {
/* save existing mode for later reenablement */
- saved_mode = kvm->arch.vpit->pit_state.channels[0].mode;
- kvm->arch.vpit->pit_state.channels[0].mode = 0xff; /* disable timer */
- pit_load_count(kvm, channel, val);
- kvm->arch.vpit->pit_state.channels[0].mode = saved_mode;
+ WARN_ON(channel != 0);
+ saved_mode = pit->pit_state.channels[0].mode;
+ pit->pit_state.channels[0].mode = 0xff; /* disable timer */
+ pit_load_count(pit, channel, val);
+ pit->pit_state.channels[0].mode = saved_mode;
} else {
- pit_load_count(kvm, channel, val);
+ pit_load_count(pit, channel, val);
}
}
@@ -449,7 +430,6 @@ static int pit_ioport_write(struct kvm_vcpu *vcpu,
{
struct kvm_pit *pit = dev_to_pit(this);
struct kvm_kpit_state *pit_state = &pit->pit_state;
- struct kvm *kvm = pit->kvm;
int channel, access;
struct kvm_kpit_channel_state *s;
u32 val = *(u32 *) data;
@@ -473,9 +453,9 @@ static int pit_ioport_write(struct kvm_vcpu *vcpu,
s = &pit_state->channels[channel];
if (val & (2 << channel)) {
if (!(val & 0x20))
- pit_latch_count(kvm, channel);
+ pit_latch_count(pit, channel);
if (!(val & 0x10))
- pit_latch_status(kvm, channel);
+ pit_latch_status(pit, channel);
}
}
} else {
@@ -483,7 +463,7 @@ static int pit_ioport_write(struct kvm_vcpu *vcpu,
s = &pit_state->channels[channel];
access = (val >> 4) & KVM_PIT_CHANNEL_MASK;
if (access == 0) {
- pit_latch_count(kvm, channel);
+ pit_latch_count(pit, channel);
} else {
s->rw_mode = access;
s->read_state = access;
@@ -500,17 +480,17 @@ static int pit_ioport_write(struct kvm_vcpu *vcpu,
switch (s->write_state) {
default:
case RW_STATE_LSB:
- pit_load_count(kvm, addr, val);
+ pit_load_count(pit, addr, val);
break;
case RW_STATE_MSB:
- pit_load_count(kvm, addr, val << 8);
+ pit_load_count(pit, addr, val << 8);
break;
case RW_STATE_WORD0:
s->write_latch = val;
s->write_state = RW_STATE_WORD1;
break;
case RW_STATE_WORD1:
- pit_load_count(kvm, addr, s->write_latch | (val << 8));
+ pit_load_count(pit, addr, s->write_latch | (val << 8));
s->write_state = RW_STATE_WORD0;
break;
}
@@ -526,7 +506,6 @@ static int pit_ioport_read(struct kvm_vcpu *vcpu,
{
struct kvm_pit *pit = dev_to_pit(this);
struct kvm_kpit_state *pit_state = &pit->pit_state;
- struct kvm *kvm = pit->kvm;
int ret, count;
struct kvm_kpit_channel_state *s;
if (!pit_in_range(addr))
@@ -563,20 +542,20 @@ static int pit_ioport_read(struct kvm_vcpu *vcpu,
switch (s->read_state) {
default:
case RW_STATE_LSB:
- count = pit_get_count(kvm, addr);
+ count = pit_get_count(pit, addr);
ret = count & 0xff;
break;
case RW_STATE_MSB:
- count = pit_get_count(kvm, addr);
+ count = pit_get_count(pit, addr);
ret = (count >> 8) & 0xff;
break;
case RW_STATE_WORD0:
- count = pit_get_count(kvm, addr);
+ count = pit_get_count(pit, addr);
ret = count & 0xff;
s->read_state = RW_STATE_WORD1;
break;
case RW_STATE_WORD1:
- count = pit_get_count(kvm, addr);
+ count = pit_get_count(pit, addr);
ret = (count >> 8) & 0xff;
s->read_state = RW_STATE_WORD0;
break;
@@ -597,14 +576,13 @@ static int speaker_ioport_write(struct kvm_vcpu *vcpu,
{
struct kvm_pit *pit = speaker_to_pit(this);
struct kvm_kpit_state *pit_state = &pit->pit_state;
- struct kvm *kvm = pit->kvm;
u32 val = *(u32 *) data;
if (addr != KVM_SPEAKER_BASE_ADDRESS)
return -EOPNOTSUPP;
mutex_lock(&pit_state->lock);
pit_state->speaker_data_on = (val >> 1) & 1;
- pit_set_gate(kvm, 2, val & 1);
+ pit_set_gate(pit, 2, val & 1);
mutex_unlock(&pit_state->lock);
return 0;
}
@@ -615,7 +593,6 @@ static int speaker_ioport_read(struct kvm_vcpu *vcpu,
{
struct kvm_pit *pit = speaker_to_pit(this);
struct kvm_kpit_state *pit_state = &pit->pit_state;
- struct kvm *kvm = pit->kvm;
unsigned int refresh_clock;
int ret;
if (addr != KVM_SPEAKER_BASE_ADDRESS)
@@ -625,8 +602,8 @@ static int speaker_ioport_read(struct kvm_vcpu *vcpu,
refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;
mutex_lock(&pit_state->lock);
- ret = ((pit_state->speaker_data_on << 1) | pit_get_gate(kvm, 2) |
- (pit_get_out(kvm, 2) << 5) | (refresh_clock << 4));
+ ret = ((pit_state->speaker_data_on << 1) | pit_get_gate(pit, 2) |
+ (pit_get_out(pit, 2) << 5) | (refresh_clock << 4));
if (len > sizeof(ret))
len = sizeof(ret);
memcpy(data, (char *)&ret, len);
@@ -634,33 +611,28 @@ static int speaker_ioport_read(struct kvm_vcpu *vcpu,
return 0;
}
-void kvm_pit_reset(struct kvm_pit *pit)
+static void kvm_pit_reset(struct kvm_pit *pit)
{
int i;
struct kvm_kpit_channel_state *c;
- mutex_lock(&pit->pit_state.lock);
pit->pit_state.flags = 0;
for (i = 0; i < 3; i++) {
c = &pit->pit_state.channels[i];
c->mode = 0xff;
c->gate = (i != 2);
- pit_load_count(pit->kvm, i, 0);
+ pit_load_count(pit, i, 0);
}
- mutex_unlock(&pit->pit_state.lock);
- atomic_set(&pit->pit_state.pending, 0);
- pit->pit_state.irq_ack = 1;
+ kvm_pit_reset_reinject(pit);
}
static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
{
struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier);
- if (!mask) {
- atomic_set(&pit->pit_state.pending, 0);
- pit->pit_state.irq_ack = 1;
- }
+ if (!mask)
+ kvm_pit_reset_reinject(pit);
}
static const struct kvm_io_device_ops pit_dev_ops = {
@@ -687,14 +659,10 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
return NULL;
pit->irq_source_id = kvm_request_irq_source_id(kvm);
- if (pit->irq_source_id < 0) {
- kfree(pit);
- return NULL;
- }
+ if (pit->irq_source_id < 0)
+ goto fail_request;
mutex_init(&pit->pit_state.lock);
- mutex_lock(&pit->pit_state.lock);
- spin_lock_init(&pit->pit_state.inject_lock);
pid = get_pid(task_tgid(current));
pid_nr = pid_vnr(pid);
@@ -703,36 +671,30 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
init_kthread_worker(&pit->worker);
pit->worker_task = kthread_run(kthread_worker_fn, &pit->worker,
"kvm-pit/%d", pid_nr);
- if (IS_ERR(pit->worker_task)) {
- mutex_unlock(&pit->pit_state.lock);
- kvm_free_irq_source_id(kvm, pit->irq_source_id);
- kfree(pit);
- return NULL;
- }
+ if (IS_ERR(pit->worker_task))
+ goto fail_kthread;
+
init_kthread_work(&pit->expired, pit_do_work);
- kvm->arch.vpit = pit;
pit->kvm = kvm;
pit_state = &pit->pit_state;
- pit_state->pit = pit;
hrtimer_init(&pit_state->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ pit_state->timer.function = pit_timer_fn;
+
pit_state->irq_ack_notifier.gsi = 0;
pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
- kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
- pit_state->reinject = true;
- mutex_unlock(&pit->pit_state.lock);
+ pit->mask_notifier.func = pit_mask_notifer;
kvm_pit_reset(pit);
- pit->mask_notifier.func = pit_mask_notifer;
- kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+ kvm_pit_set_reinject(pit, true);
kvm_iodevice_init(&pit->dev, &pit_dev_ops);
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, KVM_PIT_BASE_ADDRESS,
KVM_PIT_MEM_LENGTH, &pit->dev);
if (ret < 0)
- goto fail;
+ goto fail_register_pit;
if (flags & KVM_PIT_SPEAKER_DUMMY) {
kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
@@ -740,42 +702,35 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
KVM_SPEAKER_BASE_ADDRESS, 4,
&pit->speaker_dev);
if (ret < 0)
- goto fail_unregister;
+ goto fail_register_speaker;
}
return pit;
-fail_unregister:
+fail_register_speaker:
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
-
-fail:
- kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
- kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
- kvm_free_irq_source_id(kvm, pit->irq_source_id);
+fail_register_pit:
+ kvm_pit_set_reinject(pit, false);
kthread_stop(pit->worker_task);
+fail_kthread:
+ kvm_free_irq_source_id(kvm, pit->irq_source_id);
+fail_request:
kfree(pit);
return NULL;
}
void kvm_free_pit(struct kvm *kvm)
{
- struct hrtimer *timer;
-
- if (kvm->arch.vpit) {
- kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &kvm->arch.vpit->dev);
- kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
- &kvm->arch.vpit->speaker_dev);
- kvm_unregister_irq_mask_notifier(kvm, 0,
- &kvm->arch.vpit->mask_notifier);
- kvm_unregister_irq_ack_notifier(kvm,
- &kvm->arch.vpit->pit_state.irq_ack_notifier);
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- timer = &kvm->arch.vpit->pit_state.timer;
- hrtimer_cancel(timer);
- flush_kthread_work(&kvm->arch.vpit->expired);
- kthread_stop(kvm->arch.vpit->worker_task);
- kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id);
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- kfree(kvm->arch.vpit);
+ struct kvm_pit *pit = kvm->arch.vpit;
+
+ if (pit) {
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->speaker_dev);
+ kvm_pit_set_reinject(pit, false);
+ hrtimer_cancel(&pit->pit_state.timer);
+ flush_kthread_work(&pit->expired);
+ kthread_stop(pit->worker_task);
+ kvm_free_irq_source_id(kvm, pit->irq_source_id);
+ kfree(pit);
}
}
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index c84990b..2f5af07 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -22,19 +22,18 @@ struct kvm_kpit_channel_state {
};
struct kvm_kpit_state {
+ /* All members before "struct mutex lock" are protected by the lock. */
struct kvm_kpit_channel_state channels[3];
u32 flags;
bool is_periodic;
s64 period; /* unit: ns */
struct hrtimer timer;
- atomic_t pending; /* accumulated triggered timers */
- bool reinject;
- struct kvm *kvm;
u32 speaker_data_on;
+
struct mutex lock;
- struct kvm_pit *pit;
- spinlock_t inject_lock;
- unsigned long irq_ack;
+ atomic_t reinject;
+ atomic_t pending; /* accumulated triggered timers */
+ atomic_t irq_ack;
struct kvm_irq_ack_notifier irq_ack_notifier;
};
@@ -57,9 +56,11 @@ struct kvm_pit {
#define KVM_MAX_PIT_INTR_INTERVAL HZ / 100
#define KVM_PIT_CHANNEL_MASK 0x3
-void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start);
struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
void kvm_free_pit(struct kvm *kvm);
-void kvm_pit_reset(struct kvm_pit *pit);
+
+void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val,
+ int hpet_legacy_start);
+void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject);
#endif
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 856f791..9db47090 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
{
ioapic->rtc_status.pending_eoi = 0;
- bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS);
+ bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPUS);
}
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
@@ -117,16 +117,16 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
return;
new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector);
- old_val = test_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map);
+ old_val = test_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
if (new_val == old_val)
return;
if (new_val) {
- __set_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map);
+ __set_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
ioapic->rtc_status.pending_eoi++;
} else {
- __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map);
+ __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
ioapic->rtc_status.pending_eoi--;
rtc_status_pending_eoi_check_valid(ioapic);
}
@@ -156,7 +156,8 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu)
{
- if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) {
+ if (test_and_clear_bit(vcpu->vcpu_id,
+ ioapic->rtc_status.dest_map.map)) {
--ioapic->rtc_status.pending_eoi;
rtc_status_pending_eoi_check_valid(ioapic);
}
@@ -233,40 +234,31 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr)
}
-static void update_handled_vectors(struct kvm_ioapic *ioapic)
-{
- DECLARE_BITMAP(handled_vectors, 256);
- int i;
-
- memset(handled_vectors, 0, sizeof(handled_vectors));
- for (i = 0; i < IOAPIC_NUM_PINS; ++i)
- __set_bit(ioapic->redirtbl[i].fields.vector, handled_vectors);
- memcpy(ioapic->handled_vectors, handled_vectors,
- sizeof(handled_vectors));
- smp_wmb();
-}
-
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap,
- u32 *tmr)
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
{
struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
+ struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
union kvm_ioapic_redirect_entry *e;
int index;
spin_lock(&ioapic->lock);
+
+ /* Make sure we see any missing RTC EOI */
+ if (test_bit(vcpu->vcpu_id, dest_map->map))
+ __set_bit(dest_map->vectors[vcpu->vcpu_id],
+ ioapic_handled_vectors);
+
for (index = 0; index < IOAPIC_NUM_PINS; index++) {
e = &ioapic->redirtbl[index];
if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG ||
kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) ||
index == RTC_GSI) {
if (kvm_apic_match_dest(vcpu, NULL, 0,
- e->fields.dest_id, e->fields.dest_mode)) {
+ e->fields.dest_id, e->fields.dest_mode) ||
+ (e->fields.trig_mode == IOAPIC_EDGE_TRIG &&
+ kvm_apic_pending_eoi(vcpu, e->fields.vector)))
__set_bit(e->fields.vector,
- (unsigned long *)eoi_exit_bitmap);
- if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
- __set_bit(e->fields.vector,
- (unsigned long *)tmr);
- }
+ ioapic_handled_vectors);
}
}
spin_unlock(&ioapic->lock);
@@ -315,7 +307,6 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
e->bits |= (u32) val;
e->fields.remote_irr = 0;
}
- update_handled_vectors(ioapic);
mask_after = e->fields.mask;
if (mask_before != mask_after)
kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);
@@ -363,7 +354,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
*/
BUG_ON(ioapic->rtc_status.pending_eoi != 0);
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
- ioapic->rtc_status.dest_map);
+ &ioapic->rtc_status.dest_map);
ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret);
} else
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);
@@ -424,8 +415,14 @@ static void kvm_ioapic_eoi_inject_work(struct work_struct *work)
static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
struct kvm_ioapic *ioapic, int vector, int trigger_mode)
{
- int i;
+ struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
struct kvm_lapic *apic = vcpu->arch.apic;
+ int i;
+
+ /* RTC special handling */
+ if (test_bit(vcpu->vcpu_id, dest_map->map) &&
+ vector == dest_map->vectors[vcpu->vcpu_id])
+ rtc_irq_eoi(ioapic, vcpu);
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i];
@@ -433,8 +430,6 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
if (ent->fields.vector != vector)
continue;
- if (i == RTC_GSI)
- rtc_irq_eoi(ioapic, vcpu);
/*
* We are dropping lock while calling ack notifiers because ack
* notifier callbacks for assigned devices call into IOAPIC
@@ -599,7 +594,6 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
ioapic->id = 0;
memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS);
rtc_irq_eoi_tracking_reset(ioapic);
- update_handled_vectors(ioapic);
}
static const struct kvm_io_device_ops ioapic_mmio_ops = {
@@ -628,8 +622,10 @@ int kvm_ioapic_init(struct kvm *kvm)
if (ret < 0) {
kvm->arch.vioapic = NULL;
kfree(ioapic);
+ return ret;
}
+ kvm_vcpu_request_scan_ioapic(kvm);
return ret;
}
@@ -666,7 +662,6 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
ioapic->irr = 0;
ioapic->irr_delivered = 0;
- update_handled_vectors(ioapic);
kvm_vcpu_request_scan_ioapic(kvm);
kvm_ioapic_inject_all(ioapic, state->irr);
spin_unlock(&ioapic->lock);
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index ca0b0b4..7d2692a 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -9,6 +9,7 @@ struct kvm;
struct kvm_vcpu;
#define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS
+#define MAX_NR_RESERVED_IOAPIC_PINS KVM_MAX_IRQ_ROUTES
#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
#define IOAPIC_EDGE_TRIG 0
#define IOAPIC_LEVEL_TRIG 1
@@ -39,9 +40,21 @@ struct kvm_vcpu;
#define RTC_GSI -1U
#endif
+struct dest_map {
+ /* vcpu bitmap where IRQ has been sent */
+ DECLARE_BITMAP(map, KVM_MAX_VCPUS);
+
+ /*
+ * Vector sent to a given vcpu, only valid when
+ * the vcpu's bit in map is set
+ */
+ u8 vectors[KVM_MAX_VCPUS];
+};
+
+
struct rtc_status {
int pending_eoi;
- DECLARE_BITMAP(dest_map, KVM_MAX_VCPUS);
+ struct dest_map dest_map;
};
union kvm_ioapic_redirect_entry {
@@ -73,7 +86,6 @@ struct kvm_ioapic {
struct kvm *kvm;
void (*ack_notifier)(void *opaque, int irq);
spinlock_t lock;
- DECLARE_BITMAP(handled_vectors, 256);
struct rtc_status rtc_status;
struct delayed_work eoi_inject;
u32 irq_eoi[IOAPIC_NUM_PINS];
@@ -98,11 +110,12 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
return kvm->arch.vioapic;
}
-static inline bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector)
+static inline int ioapic_in_kernel(struct kvm *kvm)
{
- struct kvm_ioapic *ioapic = kvm->arch.vioapic;
- smp_rmb();
- return test_bit(vector, ioapic->handled_vectors);
+ int ret;
+
+ ret = (ioapic_irqchip(kvm) != NULL);
+ return ret;
}
void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu);
@@ -117,10 +130,12 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
int level, bool line_status);
void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id);
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
- struct kvm_lapic_irq *irq, unsigned long *dest_map);
+ struct kvm_lapic_irq *irq,
+ struct dest_map *dest_map);
int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap,
- u32 *tmr);
-
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
+ ulong *ioapic_handled_vectors);
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+ ulong *ioapic_handled_vectors);
#endif
diff --git a/arch/x86/kvm/iommu.c b/arch/x86/kvm/iommu.c
index 5c520eb..a22a488 100644
--- a/arch/x86/kvm/iommu.c
+++ b/arch/x86/kvm/iommu.c
@@ -43,11 +43,11 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm);
static void kvm_iommu_put_pages(struct kvm *kvm,
gfn_t base_gfn, unsigned long npages);
-static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
+static kvm_pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
unsigned long npages)
{
gfn_t end_gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
pfn = gfn_to_pfn_memslot(slot, gfn);
end_gfn = gfn + npages;
@@ -62,7 +62,8 @@ static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
return pfn;
}
-static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
+static void kvm_unpin_pages(struct kvm *kvm, kvm_pfn_t pfn,
+ unsigned long npages)
{
unsigned long i;
@@ -73,7 +74,7 @@ static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
{
gfn_t gfn, end_gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
int r = 0;
struct iommu_domain *domain = kvm->arch.iommu_domain;
int flags;
@@ -275,7 +276,7 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
{
struct iommu_domain *domain;
gfn_t end_gfn, gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
u64 phys;
domain = kvm->arch.iommu_domain;
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index a1ec6a50..95fcc7b 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -33,19 +33,35 @@
*/
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
- return apic_has_pending_timer(vcpu);
+ if (lapic_in_kernel(vcpu))
+ return apic_has_pending_timer(vcpu);
+
+ return 0;
}
EXPORT_SYMBOL(kvm_cpu_has_pending_timer);
/*
+ * check if there is a pending userspace external interrupt
+ */
+static int pending_userspace_extint(struct kvm_vcpu *v)
+{
+ return v->arch.pending_external_vector != -1;
+}
+
+/*
* check if there is pending interrupt from
* non-APIC source without intack.
*/
static int kvm_cpu_has_extint(struct kvm_vcpu *v)
{
- if (kvm_apic_accept_pic_intr(v))
- return pic_irqchip(v->kvm)->output; /* PIC */
- else
+ u8 accept = kvm_apic_accept_pic_intr(v);
+
+ if (accept) {
+ if (irqchip_split(v->kvm))
+ return pending_userspace_extint(v);
+ else
+ return pic_irqchip(v->kvm)->output;
+ } else
return 0;
}
@@ -57,13 +73,13 @@ static int kvm_cpu_has_extint(struct kvm_vcpu *v)
*/
int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
{
- if (!irqchip_in_kernel(v->kvm))
+ if (!lapic_in_kernel(v))
return v->arch.interrupt.pending;
if (kvm_cpu_has_extint(v))
return 1;
- if (kvm_apic_vid_enabled(v->kvm))
+ if (kvm_vcpu_apicv_active(v))
return 0;
return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
@@ -75,7 +91,7 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
*/
int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
{
- if (!irqchip_in_kernel(v->kvm))
+ if (!lapic_in_kernel(v))
return v->arch.interrupt.pending;
if (kvm_cpu_has_extint(v))
@@ -91,9 +107,16 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
*/
static int kvm_cpu_get_extint(struct kvm_vcpu *v)
{
- if (kvm_cpu_has_extint(v))
- return kvm_pic_read_irq(v->kvm); /* PIC */
- return -1;
+ if (kvm_cpu_has_extint(v)) {
+ if (irqchip_split(v->kvm)) {
+ int vector = v->arch.pending_external_vector;
+
+ v->arch.pending_external_vector = -1;
+ return vector;
+ } else
+ return kvm_pic_read_irq(v->kvm); /* PIC */
+ } else
+ return -1;
}
/*
@@ -103,7 +126,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
{
int vector;
- if (!irqchip_in_kernel(v->kvm))
+ if (!lapic_in_kernel(v))
return v->arch.interrupt.nr;
vector = kvm_cpu_get_extint(v);
@@ -117,8 +140,8 @@ EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
{
- kvm_inject_apic_timer_irqs(vcpu);
- /* TODO: PIT, RTC etc. */
+ if (lapic_in_kernel(vcpu))
+ kvm_inject_apic_timer_irqs(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 3d782a2..61ebdc1 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -83,13 +83,30 @@ static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
return kvm->arch.vpic;
}
+static inline int pic_in_kernel(struct kvm *kvm)
+{
+ int ret;
+
+ ret = (pic_irqchip(kvm) != NULL);
+ return ret;
+}
+
+static inline int irqchip_split(struct kvm *kvm)
+{
+ return kvm->arch.irqchip_split;
+}
+
static inline int irqchip_in_kernel(struct kvm *kvm)
{
struct kvm_pic *vpic = pic_irqchip(kvm);
+ bool ret;
+
+ ret = (vpic != NULL);
+ ret |= irqchip_split(kvm);
/* Read vpic before kvm->irq_routing. */
smp_rmb();
- return vpic != NULL;
+ return ret;
}
void kvm_pic_reset(struct kvm_kpic_state *s);
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 9efff9e..54ead79 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -33,6 +33,9 @@
#include "lapic.h"
+#include "hyperv.h"
+#include "x86.h"
+
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level,
bool line_status)
@@ -51,10 +54,12 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
}
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
- struct kvm_lapic_irq *irq, unsigned long *dest_map)
+ struct kvm_lapic_irq *irq, struct dest_map *dest_map)
{
int i, r = -1;
struct kvm_vcpu *vcpu, *lowest = NULL;
+ unsigned long dest_vcpu_bitmap[BITS_TO_LONGS(KVM_MAX_VCPUS)];
+ unsigned int dest_vcpus = 0;
if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
kvm_lowest_prio_delivery(irq)) {
@@ -65,6 +70,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r, dest_map))
return r;
+ memset(dest_vcpu_bitmap, 0, sizeof(dest_vcpu_bitmap));
+
kvm_for_each_vcpu(i, vcpu, kvm) {
if (!kvm_apic_present(vcpu))
continue;
@@ -78,21 +85,33 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
r = 0;
r += kvm_apic_set_irq(vcpu, irq, dest_map);
} else if (kvm_lapic_enabled(vcpu)) {
- if (!lowest)
- lowest = vcpu;
- else if (kvm_apic_compare_prio(vcpu, lowest) < 0)
- lowest = vcpu;
+ if (!kvm_vector_hashing_enabled()) {
+ if (!lowest)
+ lowest = vcpu;
+ else if (kvm_apic_compare_prio(vcpu, lowest) < 0)
+ lowest = vcpu;
+ } else {
+ __set_bit(i, dest_vcpu_bitmap);
+ dest_vcpus++;
+ }
}
}
+ if (dest_vcpus != 0) {
+ int idx = kvm_vector_to_index(irq->vector, dest_vcpus,
+ dest_vcpu_bitmap, KVM_MAX_VCPUS);
+
+ lowest = kvm_get_vcpu(kvm, idx);
+ }
+
if (lowest)
r = kvm_apic_set_irq(lowest, irq, dest_map);
return r;
}
-static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
- struct kvm_lapic_irq *irq)
+void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm_lapic_irq *irq)
{
trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data);
@@ -108,6 +127,7 @@ static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
irq->level = 1;
irq->shorthand = 0;
}
+EXPORT_SYMBOL_GPL(kvm_set_msi_irq);
int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level, bool line_status)
@@ -123,12 +143,16 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
}
-static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm)
+int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm *kvm, int irq_source_id, int level,
+ bool line_status)
{
struct kvm_lapic_irq irq;
int r;
+ if (unlikely(e->type != KVM_IRQ_ROUTING_MSI))
+ return -EWOULDBLOCK;
+
kvm_set_msi_irq(e, &irq);
if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL))
@@ -137,42 +161,6 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e,
return -EWOULDBLOCK;
}
-/*
- * Deliver an IRQ in an atomic context if we can, or return a failure,
- * user can retry in a process context.
- * Return value:
- * -EWOULDBLOCK - Can't deliver in atomic context: retry in a process context.
- * Other values - No need to retry.
- */
-int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
-{
- struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
- struct kvm_kernel_irq_routing_entry *e;
- int ret = -EINVAL;
- int idx;
-
- trace_kvm_set_irq(irq, level, irq_source_id);
-
- /*
- * Injection into either PIC or IOAPIC might need to scan all CPUs,
- * which would need to be retried from thread context; when same GSI
- * is connected to both PIC and IOAPIC, we'd have to report a
- * partial failure here.
- * Since there's no easy way to do this, we only support injecting MSI
- * which is limited to 1:1 GSI mapping.
- */
- idx = srcu_read_lock(&kvm->irq_srcu);
- if (kvm_irq_map_gsi(kvm, entries, irq) > 0) {
- e = &entries[0];
- if (likely(e->type == KVM_IRQ_ROUTING_MSI))
- ret = kvm_set_msi_inatomic(e, kvm);
- else
- ret = -EWOULDBLOCK;
- }
- srcu_read_unlock(&kvm->irq_srcu, idx);
- return ret;
-}
-
int kvm_request_irq_source_id(struct kvm *kvm)
{
unsigned long *bitmap = &kvm->arch.irq_sources_bitmap;
@@ -208,7 +196,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
goto unlock;
}
clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
- if (!irqchip_in_kernel(kvm))
+ if (!ioapic_in_kernel(kvm))
goto unlock;
kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id);
@@ -250,6 +238,16 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
srcu_read_unlock(&kvm->irq_srcu, idx);
}
+static int kvm_hv_set_sint(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm *kvm, int irq_source_id, int level,
+ bool line_status)
+{
+ if (!level)
+ return -1;
+
+ return kvm_hv_synic_set_irq(kvm, e->hv_sint.vcpu, e->hv_sint.sint);
+}
+
int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
const struct kvm_irq_routing_entry *ue)
{
@@ -288,6 +286,11 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
e->msi.address_hi = ue->u.msi.address_hi;
e->msi.data = ue->u.msi.data;
break;
+ case KVM_IRQ_ROUTING_HV_SINT:
+ e->set = kvm_hv_set_sint;
+ e->hv_sint.vcpu = ue->u.hv_sint.vcpu;
+ e->hv_sint.sint = ue->u.hv_sint.sint;
+ break;
default:
goto out;
}
@@ -297,6 +300,33 @@ out:
return r;
}
+bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
+ struct kvm_vcpu **dest_vcpu)
+{
+ int i, r = 0;
+ struct kvm_vcpu *vcpu;
+
+ if (kvm_intr_is_single_vcpu_fast(kvm, irq, dest_vcpu))
+ return true;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ if (!kvm_apic_present(vcpu))
+ continue;
+
+ if (!kvm_apic_match_dest(vcpu, NULL, irq->shorthand,
+ irq->dest_id, irq->dest_mode))
+ continue;
+
+ if (++r == 2)
+ return false;
+
+ *dest_vcpu = vcpu;
+ }
+
+ return r == 1;
+}
+EXPORT_SYMBOL_GPL(kvm_intr_is_single_vcpu);
+
#define IOAPIC_ROUTING_ENTRY(irq) \
{ .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \
.u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } }
@@ -328,3 +358,72 @@ int kvm_setup_default_irq_routing(struct kvm *kvm)
return kvm_set_irq_routing(kvm, default_routing,
ARRAY_SIZE(default_routing), 0);
}
+
+static const struct kvm_irq_routing_entry empty_routing[] = {};
+
+int kvm_setup_empty_irq_routing(struct kvm *kvm)
+{
+ return kvm_set_irq_routing(kvm, empty_routing, 0, 0);
+}
+
+void kvm_arch_post_irq_routing_update(struct kvm *kvm)
+{
+ if (ioapic_in_kernel(kvm) || !irqchip_in_kernel(kvm))
+ return;
+ kvm_make_scan_ioapic_request(kvm);
+}
+
+void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
+ ulong *ioapic_handled_vectors)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_kernel_irq_routing_entry *entry;
+ struct kvm_irq_routing_table *table;
+ u32 i, nr_ioapic_pins;
+ int idx;
+
+ /* kvm->irq_routing must be read after clearing
+ * KVM_SCAN_IOAPIC. */
+ smp_mb();
+ idx = srcu_read_lock(&kvm->irq_srcu);
+ table = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+ nr_ioapic_pins = min_t(u32, table->nr_rt_entries,
+ kvm->arch.nr_reserved_ioapic_pins);
+ for (i = 0; i < nr_ioapic_pins; ++i) {
+ hlist_for_each_entry(entry, &table->map[i], link) {
+ u32 dest_id, dest_mode;
+ bool level;
+
+ if (entry->type != KVM_IRQ_ROUTING_MSI)
+ continue;
+ dest_id = (entry->msi.address_lo >> 12) & 0xff;
+ dest_mode = (entry->msi.address_lo >> 2) & 0x1;
+ level = entry->msi.data & MSI_DATA_TRIGGER_LEVEL;
+ if (level && kvm_apic_match_dest(vcpu, NULL, 0,
+ dest_id, dest_mode)) {
+ u32 vector = entry->msi.data & 0xff;
+
+ __set_bit(vector,
+ ioapic_handled_vectors);
+ }
+ }
+ }
+ srcu_read_unlock(&kvm->irq_srcu, idx);
+}
+
+int kvm_arch_set_irq(struct kvm_kernel_irq_routing_entry *irq, struct kvm *kvm,
+ int irq_source_id, int level, bool line_status)
+{
+ switch (irq->type) {
+ case KVM_IRQ_ROUTING_HV_SINT:
+ return kvm_hv_set_sint(irq, kvm, irq_source_id, level,
+ line_status);
+ default:
+ return -EWOULDBLOCK;
+ }
+}
+
+void kvm_arch_irq_routing_update(struct kvm *kvm)
+{
+ kvm_hv_irq_routing_update(kvm);
+}
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 8d9013c..443d2a5 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -41,6 +41,7 @@
#include "trace.h"
#include "x86.h"
#include "cpuid.h"
+#include "hyperv.h"
#ifndef CONFIG_X86_64
#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@@ -128,11 +129,6 @@ static inline int apic_enabled(struct kvm_lapic *apic)
(LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
-static inline int kvm_apic_id(struct kvm_lapic *apic)
-{
- return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
-}
-
/* The logical map is definitely wrong if we have multiple
* modes at the same time. (Physical map is always right.)
*/
@@ -209,7 +205,7 @@ out:
if (old)
kfree_rcu(old, rcu);
- kvm_vcpu_request_scan_ioapic(kvm);
+ kvm_make_scan_ioapic_request(kvm);
}
static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val)
@@ -285,7 +281,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu)
struct kvm_cpuid_entry2 *feat;
u32 v = APIC_VERSION;
- if (!kvm_vcpu_has_lapic(vcpu))
+ if (!lapic_in_kernel(vcpu))
return;
feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
@@ -348,6 +344,8 @@ void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
struct kvm_lapic *apic = vcpu->arch.apic;
__kvm_apic_update_irr(pir, apic->regs);
+
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
}
EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
@@ -377,7 +375,8 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic)
if (!apic->irr_pending)
return -1;
- kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
+ if (apic->vcpu->arch.apicv_active)
+ kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
result = apic_search_irr(apic);
ASSERT(result == -1 || result >= 16);
@@ -390,7 +389,7 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
vcpu = apic->vcpu;
- if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) {
+ if (unlikely(vcpu->arch.apicv_active)) {
/* try to update RVI */
apic_clear_vector(vec, apic->regs + APIC_IRR);
kvm_make_request(KVM_REQ_EVENT, vcpu);
@@ -416,7 +415,7 @@ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
* because the processor can modify ISR under the hood. Instead
* just set SVI.
*/
- if (unlikely(kvm_x86_ops->hwapic_isr_update))
+ if (unlikely(vcpu->arch.apicv_active))
kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec);
else {
++apic->isr_count;
@@ -464,7 +463,7 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
* on the other hand isr_count and highest_isr_cache are unused
* and must be left alone.
*/
- if (unlikely(kvm_x86_ops->hwapic_isr_update))
+ if (unlikely(vcpu->arch.apicv_active))
kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
apic_find_highest_isr(apic));
else {
@@ -476,26 +475,20 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
{
- int highest_irr;
-
/* This may race with setting of irr in __apic_accept_irq() and
* value returned may be wrong, but kvm_vcpu_kick() in __apic_accept_irq
* will cause vmexit immediately and the value will be recalculated
* on the next vmentry.
*/
- if (!kvm_vcpu_has_lapic(vcpu))
- return 0;
- highest_irr = apic_find_highest_irr(vcpu->arch.apic);
-
- return highest_irr;
+ return apic_find_highest_irr(vcpu->arch.apic);
}
static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
int vector, int level, int trig_mode,
- unsigned long *dest_map);
+ struct dest_map *dest_map);
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
- unsigned long *dest_map)
+ struct dest_map *dest_map)
{
struct kvm_lapic *apic = vcpu->arch.apic;
@@ -551,15 +544,6 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu)
__clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);
}
-void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
-{
- struct kvm_lapic *apic = vcpu->arch.apic;
- int i;
-
- for (i = 0; i < 8; i++)
- apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
-}
-
static void apic_update_ppr(struct kvm_lapic *apic)
{
u32 tpr, isrv, ppr, old_ppr;
@@ -685,8 +669,33 @@ bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
}
}
+int kvm_vector_to_index(u32 vector, u32 dest_vcpus,
+ const unsigned long *bitmap, u32 bitmap_size)
+{
+ u32 mod;
+ int i, idx = -1;
+
+ mod = vector % dest_vcpus;
+
+ for (i = 0; i <= mod; i++) {
+ idx = find_next_bit(bitmap, bitmap_size, idx + 1);
+ BUG_ON(idx == bitmap_size);
+ }
+
+ return idx;
+}
+
+static void kvm_apic_disabled_lapic_found(struct kvm *kvm)
+{
+ if (!kvm->arch.disabled_lapic_found) {
+ kvm->arch.disabled_lapic_found = true;
+ printk(KERN_INFO
+ "Disabled LAPIC found during irq injection\n");
+ }
+}
+
bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
- struct kvm_lapic_irq *irq, int *r, unsigned long *dest_map)
+ struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map)
{
struct kvm_apic_map *map;
unsigned long bitmap = 1;
@@ -737,21 +746,42 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
dst = map->logical_map[cid];
- if (kvm_lowest_prio_delivery(irq)) {
+ if (!kvm_lowest_prio_delivery(irq))
+ goto set_irq;
+
+ if (!kvm_vector_hashing_enabled()) {
int l = -1;
for_each_set_bit(i, &bitmap, 16) {
if (!dst[i])
continue;
if (l < 0)
l = i;
- else if (kvm_apic_compare_prio(dst[i]->vcpu, dst[l]->vcpu) < 0)
+ else if (kvm_apic_compare_prio(dst[i]->vcpu,
+ dst[l]->vcpu) < 0)
l = i;
}
-
bitmap = (l >= 0) ? 1 << l : 0;
+ } else {
+ int idx;
+ unsigned int dest_vcpus;
+
+ dest_vcpus = hweight16(bitmap);
+ if (dest_vcpus == 0)
+ goto out;
+
+ idx = kvm_vector_to_index(irq->vector,
+ dest_vcpus, &bitmap, 16);
+
+ if (!dst[idx]) {
+ kvm_apic_disabled_lapic_found(kvm);
+ goto out;
+ }
+
+ bitmap = (idx >= 0) ? 1 << idx : 0;
}
}
+set_irq:
for_each_set_bit(i, &bitmap, 16) {
if (!dst[i])
continue;
@@ -765,12 +795,106 @@ out:
}
/*
+ * This routine tries to handler interrupts in posted mode, here is how
+ * it deals with different cases:
+ * - For single-destination interrupts, handle it in posted mode
+ * - Else if vector hashing is enabled and it is a lowest-priority
+ * interrupt, handle it in posted mode and use the following mechanism
+ * to find the destinaiton vCPU.
+ * 1. For lowest-priority interrupts, store all the possible
+ * destination vCPUs in an array.
+ * 2. Use "guest vector % max number of destination vCPUs" to find
+ * the right destination vCPU in the array for the lowest-priority
+ * interrupt.
+ * - Otherwise, use remapped mode to inject the interrupt.
+ */
+bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
+ struct kvm_vcpu **dest_vcpu)
+{
+ struct kvm_apic_map *map;
+ bool ret = false;
+ struct kvm_lapic *dst = NULL;
+
+ if (irq->shorthand)
+ return false;
+
+ rcu_read_lock();
+ map = rcu_dereference(kvm->arch.apic_map);
+
+ if (!map)
+ goto out;
+
+ if (irq->dest_mode == APIC_DEST_PHYSICAL) {
+ if (irq->dest_id == 0xFF)
+ goto out;
+
+ if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
+ goto out;
+
+ dst = map->phys_map[irq->dest_id];
+ if (dst && kvm_apic_present(dst->vcpu))
+ *dest_vcpu = dst->vcpu;
+ else
+ goto out;
+ } else {
+ u16 cid;
+ unsigned long bitmap = 1;
+ int i, r = 0;
+
+ if (!kvm_apic_logical_map_valid(map))
+ goto out;
+
+ apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
+
+ if (cid >= ARRAY_SIZE(map->logical_map))
+ goto out;
+
+ if (kvm_vector_hashing_enabled() &&
+ kvm_lowest_prio_delivery(irq)) {
+ int idx;
+ unsigned int dest_vcpus;
+
+ dest_vcpus = hweight16(bitmap);
+ if (dest_vcpus == 0)
+ goto out;
+
+ idx = kvm_vector_to_index(irq->vector, dest_vcpus,
+ &bitmap, 16);
+
+ dst = map->logical_map[cid][idx];
+ if (!dst) {
+ kvm_apic_disabled_lapic_found(kvm);
+ goto out;
+ }
+
+ *dest_vcpu = dst->vcpu;
+ } else {
+ for_each_set_bit(i, &bitmap, 16) {
+ dst = map->logical_map[cid][i];
+ if (++r == 2)
+ goto out;
+ }
+
+ if (dst && kvm_apic_present(dst->vcpu))
+ *dest_vcpu = dst->vcpu;
+ else
+ goto out;
+ }
+ }
+
+ ret = true;
+out:
+ rcu_read_unlock();
+ return ret;
+}
+
+/*
* Add a pending IRQ into lapic.
* Return 1 if successfully added and 0 if discarded.
*/
static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
int vector, int level, int trig_mode,
- unsigned long *dest_map)
+ struct dest_map *dest_map)
{
int result = 0;
struct kvm_vcpu *vcpu = apic->vcpu;
@@ -781,16 +905,28 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
case APIC_DM_LOWEST:
vcpu->arch.apic_arb_prio++;
case APIC_DM_FIXED:
+ if (unlikely(trig_mode && !level))
+ break;
+
/* FIXME add logic for vcpu on reset */
if (unlikely(!apic_enabled(apic)))
break;
result = 1;
- if (dest_map)
- __set_bit(vcpu->vcpu_id, dest_map);
+ if (dest_map) {
+ __set_bit(vcpu->vcpu_id, dest_map->map);
+ dest_map->vectors[vcpu->vcpu_id] = vector;
+ }
+
+ if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) {
+ if (trig_mode)
+ apic_set_vector(vector, apic->regs + APIC_TMR);
+ else
+ apic_clear_vector(vector, apic->regs + APIC_TMR);
+ }
- if (kvm_x86_ops->deliver_posted_interrupt)
+ if (vcpu->arch.apicv_active)
kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
else {
apic_set_irr(vector, apic);
@@ -868,16 +1004,32 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio;
}
+static bool kvm_ioapic_handles_vector(struct kvm_lapic *apic, int vector)
+{
+ return test_bit(vector, apic->vcpu->arch.ioapic_handled_vectors);
+}
+
static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)
{
- if (kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) {
- int trigger_mode;
- if (apic_test_vector(vector, apic->regs + APIC_TMR))
- trigger_mode = IOAPIC_LEVEL_TRIG;
- else
- trigger_mode = IOAPIC_EDGE_TRIG;
- kvm_ioapic_update_eoi(apic->vcpu, vector, trigger_mode);
+ int trigger_mode;
+
+ /* Eoi the ioapic only if the ioapic doesn't own the vector. */
+ if (!kvm_ioapic_handles_vector(apic, vector))
+ return;
+
+ /* Request a KVM exit to inform the userspace IOAPIC. */
+ if (irqchip_split(apic->vcpu->kvm)) {
+ apic->vcpu->arch.pending_ioapic_eoi = vector;
+ kvm_make_request(KVM_REQ_IOAPIC_EOI_EXIT, apic->vcpu);
+ return;
}
+
+ if (apic_test_vector(vector, apic->regs + APIC_TMR))
+ trigger_mode = IOAPIC_LEVEL_TRIG;
+ else
+ trigger_mode = IOAPIC_EDGE_TRIG;
+
+ kvm_ioapic_update_eoi(apic->vcpu, vector, trigger_mode);
}
static int apic_set_eoi(struct kvm_lapic *apic)
@@ -896,6 +1048,9 @@ static int apic_set_eoi(struct kvm_lapic *apic)
apic_clear_isr(vector, apic);
apic_update_ppr(apic);
+ if (test_bit(vector, vcpu_to_synic(apic->vcpu)->vec_bitmap))
+ kvm_hv_synic_send_eoi(apic->vcpu, vector);
+
kvm_ioapic_send_eoi(apic, vector);
kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
return vector;
@@ -1117,7 +1272,7 @@ static void apic_update_lvtt(struct kvm_lapic *apic)
static void apic_timer_expired(struct kvm_lapic *apic)
{
struct kvm_vcpu *vcpu = apic->vcpu;
- wait_queue_head_t *q = &vcpu->wq;
+ struct swait_queue_head *q = &vcpu->wq;
struct kvm_timer *ktimer = &apic->lapic_timer;
if (atomic_read(&apic->lapic_timer.pending))
@@ -1126,8 +1281,8 @@ static void apic_timer_expired(struct kvm_lapic *apic)
atomic_inc(&apic->lapic_timer.pending);
kvm_set_pending_timer(vcpu);
- if (waitqueue_active(q))
- wake_up_interruptible(q);
+ if (swait_active(q))
+ swake_up(q);
if (apic_lvtt_tscdeadline(apic))
ktimer->expired_tscdeadline = ktimer->tscdeadline;
@@ -1147,7 +1302,7 @@ static bool lapic_timer_int_injected(struct kvm_vcpu *vcpu)
int vec = reg & APIC_VECTOR_MASK;
void *bitmap = apic->regs + APIC_ISR;
- if (kvm_x86_ops->deliver_posted_interrupt)
+ if (vcpu->arch.apicv_active)
bitmap = apic->regs + APIC_IRR;
if (apic_test_vector(vec, bitmap))
@@ -1161,7 +1316,7 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
struct kvm_lapic *apic = vcpu->arch.apic;
u64 guest_tsc, tsc_deadline;
- if (!kvm_vcpu_has_lapic(vcpu))
+ if (!lapic_in_kernel(vcpu))
return;
if (apic->lapic_timer.expired_tscdeadline == 0)
@@ -1172,7 +1327,7 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
tsc_deadline = apic->lapic_timer.expired_tscdeadline;
apic->lapic_timer.expired_tscdeadline = 0;
- guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+ guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
trace_kvm_wait_lapic_expire(vcpu->vcpu_id, guest_tsc - tsc_deadline);
/* __delay is delay_tsc whenever the hardware has TSC, thus always. */
@@ -1240,7 +1395,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
local_irq_save(flags);
now = apic->lapic_timer.timer.base->get_time();
- guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+ guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
if (likely(tscdeadline > guest_tsc)) {
ns = (tscdeadline - guest_tsc) * 1000000ULL;
do_div(ns, this_tsc_khz);
@@ -1437,8 +1592,7 @@ static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
{
- if (kvm_vcpu_has_lapic(vcpu))
- apic_reg_write(vcpu->arch.apic, APIC_EOI, 0);
+ apic_reg_write(vcpu->arch.apic, APIC_EOI, 0);
}
EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
@@ -1488,7 +1642,7 @@ u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) ||
+ if (!lapic_in_kernel(vcpu) || apic_lvtt_oneshot(apic) ||
apic_lvtt_period(apic))
return 0;
@@ -1499,7 +1653,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) ||
+ if (!lapic_in_kernel(vcpu) || apic_lvtt_oneshot(apic) ||
apic_lvtt_period(apic))
return;
@@ -1512,9 +1666,6 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!kvm_vcpu_has_lapic(vcpu))
- return;
-
apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
| (kvm_apic_get_reg(apic, APIC_TASKPRI) & 4));
}
@@ -1523,9 +1674,6 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
{
u64 tpr;
- if (!kvm_vcpu_has_lapic(vcpu))
- return 0;
-
tpr = (u64) kvm_apic_get_reg(vcpu->arch.apic, APIC_TASKPRI);
return (tpr & 0xf0) >> 4;
@@ -1615,8 +1763,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
}
- apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm);
- apic->isr_count = kvm_x86_ops->hwapic_isr_update ? 1 : 0;
+ apic->irr_pending = vcpu->arch.apicv_active;
+ apic->isr_count = vcpu->arch.apicv_active ? 1 : 0;
apic->highest_isr_cache = -1;
update_divide_count(apic);
atomic_set(&apic->lapic_timer.pending, 0);
@@ -1650,8 +1798,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (kvm_vcpu_has_lapic(vcpu) && apic_enabled(apic) &&
- apic_lvt_enabled(apic, APIC_LVTT))
+ if (apic_enabled(apic) && apic_lvt_enabled(apic, APIC_LVTT))
return atomic_read(&apic->lapic_timer.pending);
return 0;
@@ -1748,7 +1895,7 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
struct kvm_lapic *apic = vcpu->arch.apic;
int highest_irr;
- if (!kvm_vcpu_has_lapic(vcpu) || !apic_enabled(apic))
+ if (!apic_enabled(apic))
return -1;
apic_update_ppr(apic);
@@ -1776,9 +1923,6 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!kvm_vcpu_has_lapic(vcpu))
- return;
-
if (atomic_read(&apic->lapic_timer.pending) > 0) {
kvm_apic_local_deliver(apic, APIC_LVTT);
if (apic_lvtt_tscdeadline(apic))
@@ -1805,6 +1949,12 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
apic_set_isr(vector, apic);
apic_update_ppr(apic);
apic_clear_irr(vector, apic);
+
+ if (test_bit(vector, vcpu_to_synic(vcpu)->auto_eoi_bitmap)) {
+ apic_clear_isr(vector, apic);
+ apic_update_ppr(apic);
+ }
+
return vector;
}
@@ -1828,24 +1978,27 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,
update_divide_count(apic);
start_apic_timer(apic);
apic->irr_pending = true;
- apic->isr_count = kvm_x86_ops->hwapic_isr_update ?
+ apic->isr_count = vcpu->arch.apicv_active ?
1 : count_vectors(apic->regs + APIC_ISR);
apic->highest_isr_cache = -1;
- if (kvm_x86_ops->hwapic_irr_update)
+ if (vcpu->arch.apicv_active) {
kvm_x86_ops->hwapic_irr_update(vcpu,
apic_find_highest_irr(apic));
- if (unlikely(kvm_x86_ops->hwapic_isr_update))
kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
apic_find_highest_isr(apic));
+ }
kvm_make_request(KVM_REQ_EVENT, vcpu);
- kvm_rtc_eoi_tracking_restore_one(vcpu);
+ if (ioapic_in_kernel(vcpu->kvm))
+ kvm_rtc_eoi_tracking_restore_one(vcpu);
+
+ vcpu->arch.apic_arb_prio = 0;
}
void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
{
struct hrtimer *timer;
- if (!kvm_vcpu_has_lapic(vcpu))
+ if (!lapic_in_kernel(vcpu))
return;
timer = &vcpu->arch.apic->lapic_timer.timer;
@@ -1922,7 +2075,7 @@ static void apic_sync_pv_eoi_to_guest(struct kvm_vcpu *vcpu,
/* Cache not set: could be safe but we don't bother. */
apic->highest_isr_cache == -1 ||
/* Need EOI to update ioapic. */
- kvm_ioapic_handles_vector(vcpu->kvm, apic->highest_isr_cache)) {
+ kvm_ioapic_handles_vector(apic, apic->highest_isr_cache)) {
/*
* PV EOI was disabled by apic_sync_pv_eoi_from_guest
* so we need not do anything here.
@@ -1978,7 +2131,7 @@ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
struct kvm_lapic *apic = vcpu->arch.apic;
u32 reg = (msr - APIC_BASE_MSR) << 4;
- if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
+ if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
return 1;
if (reg == APIC_ICR2)
@@ -1995,7 +2148,7 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
struct kvm_lapic *apic = vcpu->arch.apic;
u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0;
- if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
+ if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
return 1;
if (reg == APIC_DFR || reg == APIC_ICR2) {
@@ -2018,7 +2171,7 @@ int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!kvm_vcpu_has_lapic(vcpu))
+ if (!lapic_in_kernel(vcpu))
return 1;
/* if this is ICR write vector before command */
@@ -2032,7 +2185,7 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
struct kvm_lapic *apic = vcpu->arch.apic;
u32 low, high = 0;
- if (!kvm_vcpu_has_lapic(vcpu))
+ if (!lapic_in_kernel(vcpu))
return 1;
if (apic_reg_read(apic, reg, 4, &low))
@@ -2064,7 +2217,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
u8 sipi_vector;
unsigned long pe;
- if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
+ if (!lapic_in_kernel(vcpu) || !apic->pending_events)
return;
/*
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 7640379..f71183e 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -42,6 +42,9 @@ struct kvm_lapic {
unsigned long pending_events;
unsigned int sipi_vector;
};
+
+struct dest_map;
+
int kvm_create_lapic(struct kvm_vcpu *vcpu);
void kvm_free_lapic(struct kvm_vcpu *vcpu);
@@ -57,15 +60,14 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
void kvm_apic_set_version(struct kvm_vcpu *vcpu);
-void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr);
void __kvm_apic_update_irr(u32 *pir, void *regs);
void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
- unsigned long *dest_map);
+ struct dest_map *dest_map);
int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
- struct kvm_lapic_irq *irq, int *r, unsigned long *dest_map);
+ struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map);
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
@@ -104,7 +106,7 @@ static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
extern struct static_key kvm_no_apic_vcpu;
-static inline bool kvm_vcpu_has_lapic(struct kvm_vcpu *vcpu)
+static inline bool lapic_in_kernel(struct kvm_vcpu *vcpu)
{
if (static_key_false(&kvm_no_apic_vcpu))
return vcpu->arch.apic;
@@ -131,7 +133,7 @@ static inline bool kvm_apic_sw_enabled(struct kvm_lapic *apic)
static inline bool kvm_apic_present(struct kvm_vcpu *vcpu)
{
- return kvm_vcpu_has_lapic(vcpu) && kvm_apic_hw_enabled(vcpu->arch.apic);
+ return lapic_in_kernel(vcpu) && kvm_apic_hw_enabled(vcpu->arch.apic);
}
static inline int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
@@ -144,14 +146,14 @@ static inline int apic_x2apic_mode(struct kvm_lapic *apic)
return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
}
-static inline bool kvm_apic_vid_enabled(struct kvm *kvm)
+static inline bool kvm_vcpu_apicv_active(struct kvm_vcpu *vcpu)
{
- return kvm_x86_ops->vm_has_apicv(kvm);
+ return vcpu->arch.apic && vcpu->arch.apicv_active;
}
static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
{
- return kvm_vcpu_has_lapic(vcpu) && vcpu->arch.apic->pending_events;
+ return lapic_in_kernel(vcpu) && vcpu->arch.apic->pending_events;
}
static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
@@ -162,11 +164,20 @@ static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
static inline int kvm_lapic_latched_init(struct kvm_vcpu *vcpu)
{
- return kvm_vcpu_has_lapic(vcpu) && test_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+ return lapic_in_kernel(vcpu) && test_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+}
+
+static inline int kvm_apic_id(struct kvm_lapic *apic)
+{
+ return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
}
bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
void wait_lapic_expire(struct kvm_vcpu *vcpu);
+bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
+ struct kvm_vcpu **dest_vcpu);
+int kvm_vector_to_index(u32 vector, u32 dest_vcpus,
+ const unsigned long *bitmap, u32 bitmap_size);
#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index ff606f5..c512f09 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -41,6 +41,7 @@
#include <asm/cmpxchg.h>
#include <asm/io.h>
#include <asm/vmx.h>
+#include <asm/kvm_page_track.h>
/*
* When setting this variable to true it enables Two-Dimensional-Paging
@@ -259,7 +260,7 @@ static unsigned get_mmio_spte_access(u64 spte)
}
static bool set_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
- pfn_t pfn, unsigned access)
+ kvm_pfn_t pfn, unsigned access)
{
if (unlikely(is_noslot_pfn(pfn))) {
mark_mmio_spte(vcpu, sptep, gfn, access);
@@ -311,11 +312,6 @@ static int is_large_pte(u64 pte)
return pte & PT_PAGE_SIZE_MASK;
}
-static int is_rmap_spte(u64 pte)
-{
- return is_shadow_present_pte(pte);
-}
-
static int is_last_spte(u64 pte, int level)
{
if (level == PT_PAGE_TABLE_LEVEL)
@@ -325,7 +321,7 @@ static int is_last_spte(u64 pte, int level)
return 0;
}
-static pfn_t spte_to_pfn(u64 pte)
+static kvm_pfn_t spte_to_pfn(u64 pte)
{
return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
}
@@ -540,7 +536,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte)
u64 old_spte = *sptep;
bool ret = false;
- WARN_ON(!is_rmap_spte(new_spte));
+ WARN_ON(!is_shadow_present_pte(new_spte));
if (!is_shadow_present_pte(old_spte)) {
mmu_spte_set(sptep, new_spte);
@@ -587,7 +583,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte)
*/
static int mmu_spte_clear_track_bits(u64 *sptep)
{
- pfn_t pfn;
+ kvm_pfn_t pfn;
u64 old_spte = *sptep;
if (!spte_has_volatile_bits(old_spte))
@@ -595,7 +591,7 @@ static int mmu_spte_clear_track_bits(u64 *sptep)
else
old_spte = __update_clear_spte_slow(sptep, 0ull);
- if (!is_rmap_spte(old_spte))
+ if (!is_shadow_present_pte(old_spte))
return 0;
pfn = spte_to_pfn(old_spte);
@@ -781,57 +777,85 @@ static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn,
return &slot->arch.lpage_info[level - 2][idx];
}
+static void update_gfn_disallow_lpage_count(struct kvm_memory_slot *slot,
+ gfn_t gfn, int count)
+{
+ struct kvm_lpage_info *linfo;
+ int i;
+
+ for (i = PT_DIRECTORY_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
+ linfo = lpage_info_slot(gfn, slot, i);
+ linfo->disallow_lpage += count;
+ WARN_ON(linfo->disallow_lpage < 0);
+ }
+}
+
+void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ update_gfn_disallow_lpage_count(slot, gfn, 1);
+}
+
+void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ update_gfn_disallow_lpage_count(slot, gfn, -1);
+}
+
static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
{
struct kvm_memslots *slots;
struct kvm_memory_slot *slot;
- struct kvm_lpage_info *linfo;
gfn_t gfn;
- int i;
+ kvm->arch.indirect_shadow_pages++;
gfn = sp->gfn;
slots = kvm_memslots_for_spte_role(kvm, sp->role);
slot = __gfn_to_memslot(slots, gfn);
- for (i = PT_DIRECTORY_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
- linfo = lpage_info_slot(gfn, slot, i);
- linfo->write_count += 1;
- }
- kvm->arch.indirect_shadow_pages++;
+
+ /* the non-leaf shadow pages are keeping readonly. */
+ if (sp->role.level > PT_PAGE_TABLE_LEVEL)
+ return kvm_slot_page_track_add_page(kvm, slot, gfn,
+ KVM_PAGE_TRACK_WRITE);
+
+ kvm_mmu_gfn_disallow_lpage(slot, gfn);
}
static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
{
struct kvm_memslots *slots;
struct kvm_memory_slot *slot;
- struct kvm_lpage_info *linfo;
gfn_t gfn;
- int i;
+ kvm->arch.indirect_shadow_pages--;
gfn = sp->gfn;
slots = kvm_memslots_for_spte_role(kvm, sp->role);
slot = __gfn_to_memslot(slots, gfn);
- for (i = PT_DIRECTORY_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
- linfo = lpage_info_slot(gfn, slot, i);
- linfo->write_count -= 1;
- WARN_ON(linfo->write_count < 0);
- }
- kvm->arch.indirect_shadow_pages--;
+ if (sp->role.level > PT_PAGE_TABLE_LEVEL)
+ return kvm_slot_page_track_remove_page(kvm, slot, gfn,
+ KVM_PAGE_TRACK_WRITE);
+
+ kvm_mmu_gfn_allow_lpage(slot, gfn);
}
-static int has_wrprotected_page(struct kvm_vcpu *vcpu,
- gfn_t gfn,
- int level)
+static bool __mmu_gfn_lpage_is_disallowed(gfn_t gfn, int level,
+ struct kvm_memory_slot *slot)
{
- struct kvm_memory_slot *slot;
struct kvm_lpage_info *linfo;
- slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
if (slot) {
linfo = lpage_info_slot(gfn, slot, level);
- return linfo->write_count;
+ return !!linfo->disallow_lpage;
}
- return 1;
+ return true;
+}
+
+static bool mmu_gfn_lpage_is_disallowed(struct kvm_vcpu *vcpu, gfn_t gfn,
+ int level)
+{
+ struct kvm_memory_slot *slot;
+
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+ return __mmu_gfn_lpage_is_disallowed(gfn, level, slot);
}
static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
@@ -851,6 +875,17 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
return ret;
}
+static inline bool memslot_valid_for_gpte(struct kvm_memory_slot *slot,
+ bool no_dirty_log)
+{
+ if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
+ return false;
+ if (no_dirty_log && slot->dirty_bitmap)
+ return false;
+
+ return true;
+}
+
static struct kvm_memory_slot *
gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
bool no_dirty_log)
@@ -858,21 +893,25 @@ gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
struct kvm_memory_slot *slot;
slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
- if (!slot || slot->flags & KVM_MEMSLOT_INVALID ||
- (no_dirty_log && slot->dirty_bitmap))
+ if (!memslot_valid_for_gpte(slot, no_dirty_log))
slot = NULL;
return slot;
}
-static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn)
-{
- return !gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
-}
-
-static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
+static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn,
+ bool *force_pt_level)
{
int host_level, level, max_level;
+ struct kvm_memory_slot *slot;
+
+ if (unlikely(*force_pt_level))
+ return PT_PAGE_TABLE_LEVEL;
+
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, large_gfn);
+ *force_pt_level = !memslot_valid_for_gpte(slot, true);
+ if (unlikely(*force_pt_level))
+ return PT_PAGE_TABLE_LEVEL;
host_level = host_mapping_level(vcpu->kvm, large_gfn);
@@ -882,43 +921,42 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
max_level = min(kvm_x86_ops->get_lpage_level(), host_level);
for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
- if (has_wrprotected_page(vcpu, large_gfn, level))
+ if (__mmu_gfn_lpage_is_disallowed(large_gfn, level, slot))
break;
return level - 1;
}
/*
- * Pte mapping structures:
+ * About rmap_head encoding:
*
- * If pte_list bit zero is zero, then pte_list point to the spte.
- *
- * If pte_list bit zero is one, (then pte_list & ~1) points to a struct
+ * If the bit zero of rmap_head->val is clear, then it points to the only spte
+ * in this rmap chain. Otherwise, (rmap_head->val & ~1) points to a struct
* pte_list_desc containing more mappings.
- *
- * Returns the number of pte entries before the spte was added or zero if
- * the spte was not added.
- *
+ */
+
+/*
+ * Returns the number of pointers in the rmap chain, not counting the new one.
*/
static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte,
- unsigned long *pte_list)
+ struct kvm_rmap_head *rmap_head)
{
struct pte_list_desc *desc;
int i, count = 0;
- if (!*pte_list) {
+ if (!rmap_head->val) {
rmap_printk("pte_list_add: %p %llx 0->1\n", spte, *spte);
- *pte_list = (unsigned long)spte;
- } else if (!(*pte_list & 1)) {
+ rmap_head->val = (unsigned long)spte;
+ } else if (!(rmap_head->val & 1)) {
rmap_printk("pte_list_add: %p %llx 1->many\n", spte, *spte);
desc = mmu_alloc_pte_list_desc(vcpu);
- desc->sptes[0] = (u64 *)*pte_list;
+ desc->sptes[0] = (u64 *)rmap_head->val;
desc->sptes[1] = spte;
- *pte_list = (unsigned long)desc | 1;
+ rmap_head->val = (unsigned long)desc | 1;
++count;
} else {
rmap_printk("pte_list_add: %p %llx many->many\n", spte, *spte);
- desc = (struct pte_list_desc *)(*pte_list & ~1ul);
+ desc = (struct pte_list_desc *)(rmap_head->val & ~1ul);
while (desc->sptes[PTE_LIST_EXT-1] && desc->more) {
desc = desc->more;
count += PTE_LIST_EXT;
@@ -935,8 +973,9 @@ static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte,
}
static void
-pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc,
- int i, struct pte_list_desc *prev_desc)
+pte_list_desc_remove_entry(struct kvm_rmap_head *rmap_head,
+ struct pte_list_desc *desc, int i,
+ struct pte_list_desc *prev_desc)
{
int j;
@@ -947,43 +986,43 @@ pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc,
if (j != 0)
return;
if (!prev_desc && !desc->more)
- *pte_list = (unsigned long)desc->sptes[0];
+ rmap_head->val = (unsigned long)desc->sptes[0];
else
if (prev_desc)
prev_desc->more = desc->more;
else
- *pte_list = (unsigned long)desc->more | 1;
+ rmap_head->val = (unsigned long)desc->more | 1;
mmu_free_pte_list_desc(desc);
}
-static void pte_list_remove(u64 *spte, unsigned long *pte_list)
+static void pte_list_remove(u64 *spte, struct kvm_rmap_head *rmap_head)
{
struct pte_list_desc *desc;
struct pte_list_desc *prev_desc;
int i;
- if (!*pte_list) {
+ if (!rmap_head->val) {
printk(KERN_ERR "pte_list_remove: %p 0->BUG\n", spte);
BUG();
- } else if (!(*pte_list & 1)) {
+ } else if (!(rmap_head->val & 1)) {
rmap_printk("pte_list_remove: %p 1->0\n", spte);
- if ((u64 *)*pte_list != spte) {
+ if ((u64 *)rmap_head->val != spte) {
printk(KERN_ERR "pte_list_remove: %p 1->BUG\n", spte);
BUG();
}
- *pte_list = 0;
+ rmap_head->val = 0;
} else {
rmap_printk("pte_list_remove: %p many->many\n", spte);
- desc = (struct pte_list_desc *)(*pte_list & ~1ul);
+ desc = (struct pte_list_desc *)(rmap_head->val & ~1ul);
prev_desc = NULL;
while (desc) {
- for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i)
+ for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i) {
if (desc->sptes[i] == spte) {
- pte_list_desc_remove_entry(pte_list,
- desc, i,
- prev_desc);
+ pte_list_desc_remove_entry(rmap_head,
+ desc, i, prev_desc);
return;
}
+ }
prev_desc = desc;
desc = desc->more;
}
@@ -992,28 +1031,8 @@ static void pte_list_remove(u64 *spte, unsigned long *pte_list)
}
}
-typedef void (*pte_list_walk_fn) (u64 *spte);
-static void pte_list_walk(unsigned long *pte_list, pte_list_walk_fn fn)
-{
- struct pte_list_desc *desc;
- int i;
-
- if (!*pte_list)
- return;
-
- if (!(*pte_list & 1))
- return fn((u64 *)*pte_list);
-
- desc = (struct pte_list_desc *)(*pte_list & ~1ul);
- while (desc) {
- for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i)
- fn(desc->sptes[i]);
- desc = desc->more;
- }
-}
-
-static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
- struct kvm_memory_slot *slot)
+static struct kvm_rmap_head *__gfn_to_rmap(gfn_t gfn, int level,
+ struct kvm_memory_slot *slot)
{
unsigned long idx;
@@ -1021,10 +1040,8 @@ static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
return &slot->arch.rmap[level - PT_PAGE_TABLE_LEVEL][idx];
}
-/*
- * Take gfn and return the reverse mapping to it.
- */
-static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, struct kvm_mmu_page *sp)
+static struct kvm_rmap_head *gfn_to_rmap(struct kvm *kvm, gfn_t gfn,
+ struct kvm_mmu_page *sp)
{
struct kvm_memslots *slots;
struct kvm_memory_slot *slot;
@@ -1045,24 +1062,24 @@ static bool rmap_can_add(struct kvm_vcpu *vcpu)
static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
{
struct kvm_mmu_page *sp;
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
sp = page_header(__pa(spte));
kvm_mmu_page_set_gfn(sp, spte - sp->spt, gfn);
- rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp);
- return pte_list_add(vcpu, spte, rmapp);
+ rmap_head = gfn_to_rmap(vcpu->kvm, gfn, sp);
+ return pte_list_add(vcpu, spte, rmap_head);
}
static void rmap_remove(struct kvm *kvm, u64 *spte)
{
struct kvm_mmu_page *sp;
gfn_t gfn;
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
sp = page_header(__pa(spte));
gfn = kvm_mmu_page_get_gfn(sp, spte - sp->spt);
- rmapp = gfn_to_rmap(kvm, gfn, sp);
- pte_list_remove(spte, rmapp);
+ rmap_head = gfn_to_rmap(kvm, gfn, sp);
+ pte_list_remove(spte, rmap_head);
}
/*
@@ -1082,19 +1099,26 @@ struct rmap_iterator {
*
* Returns sptep if found, NULL otherwise.
*/
-static u64 *rmap_get_first(unsigned long rmap, struct rmap_iterator *iter)
+static u64 *rmap_get_first(struct kvm_rmap_head *rmap_head,
+ struct rmap_iterator *iter)
{
- if (!rmap)
+ u64 *sptep;
+
+ if (!rmap_head->val)
return NULL;
- if (!(rmap & 1)) {
+ if (!(rmap_head->val & 1)) {
iter->desc = NULL;
- return (u64 *)rmap;
+ sptep = (u64 *)rmap_head->val;
+ goto out;
}
- iter->desc = (struct pte_list_desc *)(rmap & ~1ul);
+ iter->desc = (struct pte_list_desc *)(rmap_head->val & ~1ul);
iter->pos = 0;
- return iter->desc->sptes[iter->pos];
+ sptep = iter->desc->sptes[iter->pos];
+out:
+ BUG_ON(!is_shadow_present_pte(*sptep));
+ return sptep;
}
/*
@@ -1104,14 +1128,14 @@ static u64 *rmap_get_first(unsigned long rmap, struct rmap_iterator *iter)
*/
static u64 *rmap_get_next(struct rmap_iterator *iter)
{
+ u64 *sptep;
+
if (iter->desc) {
if (iter->pos < PTE_LIST_EXT - 1) {
- u64 *sptep;
-
++iter->pos;
sptep = iter->desc->sptes[iter->pos];
if (sptep)
- return sptep;
+ goto out;
}
iter->desc = iter->desc->more;
@@ -1119,17 +1143,20 @@ static u64 *rmap_get_next(struct rmap_iterator *iter)
if (iter->desc) {
iter->pos = 0;
/* desc->sptes[0] cannot be NULL */
- return iter->desc->sptes[iter->pos];
+ sptep = iter->desc->sptes[iter->pos];
+ goto out;
}
}
return NULL;
+out:
+ BUG_ON(!is_shadow_present_pte(*sptep));
+ return sptep;
}
-#define for_each_rmap_spte(_rmap_, _iter_, _spte_) \
- for (_spte_ = rmap_get_first(*_rmap_, _iter_); \
- _spte_ && ({BUG_ON(!is_shadow_present_pte(*_spte_)); 1;}); \
- _spte_ = rmap_get_next(_iter_))
+#define for_each_rmap_spte(_rmap_head_, _iter_, _spte_) \
+ for (_spte_ = rmap_get_first(_rmap_head_, _iter_); \
+ _spte_; _spte_ = rmap_get_next(_iter_))
static void drop_spte(struct kvm *kvm, u64 *sptep)
{
@@ -1187,14 +1214,15 @@ static bool spte_write_protect(struct kvm *kvm, u64 *sptep, bool pt_protect)
return mmu_spte_update(sptep, spte);
}
-static bool __rmap_write_protect(struct kvm *kvm, unsigned long *rmapp,
+static bool __rmap_write_protect(struct kvm *kvm,
+ struct kvm_rmap_head *rmap_head,
bool pt_protect)
{
u64 *sptep;
struct rmap_iterator iter;
bool flush = false;
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep)
flush |= spte_write_protect(kvm, sptep, pt_protect);
return flush;
@@ -1211,13 +1239,13 @@ static bool spte_clear_dirty(struct kvm *kvm, u64 *sptep)
return mmu_spte_update(sptep, spte);
}
-static bool __rmap_clear_dirty(struct kvm *kvm, unsigned long *rmapp)
+static bool __rmap_clear_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head)
{
u64 *sptep;
struct rmap_iterator iter;
bool flush = false;
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep)
flush |= spte_clear_dirty(kvm, sptep);
return flush;
@@ -1234,13 +1262,13 @@ static bool spte_set_dirty(struct kvm *kvm, u64 *sptep)
return mmu_spte_update(sptep, spte);
}
-static bool __rmap_set_dirty(struct kvm *kvm, unsigned long *rmapp)
+static bool __rmap_set_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head)
{
u64 *sptep;
struct rmap_iterator iter;
bool flush = false;
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep)
flush |= spte_set_dirty(kvm, sptep);
return flush;
@@ -1260,12 +1288,12 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
struct kvm_memory_slot *slot,
gfn_t gfn_offset, unsigned long mask)
{
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
while (mask) {
- rmapp = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
- PT_PAGE_TABLE_LEVEL, slot);
- __rmap_write_protect(kvm, rmapp, false);
+ rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
+ PT_PAGE_TABLE_LEVEL, slot);
+ __rmap_write_protect(kvm, rmap_head, false);
/* clear the first set bit */
mask &= mask - 1;
@@ -1285,12 +1313,12 @@ void kvm_mmu_clear_dirty_pt_masked(struct kvm *kvm,
struct kvm_memory_slot *slot,
gfn_t gfn_offset, unsigned long mask)
{
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
while (mask) {
- rmapp = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
- PT_PAGE_TABLE_LEVEL, slot);
- __rmap_clear_dirty(kvm, rmapp);
+ rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
+ PT_PAGE_TABLE_LEVEL, slot);
+ __rmap_clear_dirty(kvm, rmap_head);
/* clear the first set bit */
mask &= mask - 1;
@@ -1319,31 +1347,36 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
}
-static bool rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
+bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
+ struct kvm_memory_slot *slot, u64 gfn)
{
- struct kvm_memory_slot *slot;
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
int i;
bool write_protected = false;
- slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
-
for (i = PT_PAGE_TABLE_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
- rmapp = __gfn_to_rmap(gfn, i, slot);
- write_protected |= __rmap_write_protect(vcpu->kvm, rmapp, true);
+ rmap_head = __gfn_to_rmap(gfn, i, slot);
+ write_protected |= __rmap_write_protect(kvm, rmap_head, true);
}
return write_protected;
}
-static bool kvm_zap_rmapp(struct kvm *kvm, unsigned long *rmapp)
+static bool rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
+{
+ struct kvm_memory_slot *slot;
+
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+ return kvm_mmu_slot_gfn_write_protect(vcpu->kvm, slot, gfn);
+}
+
+static bool kvm_zap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head)
{
u64 *sptep;
struct rmap_iterator iter;
bool flush = false;
- while ((sptep = rmap_get_first(*rmapp, &iter))) {
- BUG_ON(!(*sptep & PT_PRESENT_MASK));
+ while ((sptep = rmap_get_first(rmap_head, &iter))) {
rmap_printk("%s: spte %p %llx.\n", __func__, sptep, *sptep);
drop_spte(kvm, sptep);
@@ -1353,14 +1386,14 @@ static bool kvm_zap_rmapp(struct kvm *kvm, unsigned long *rmapp)
return flush;
}
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
+static int kvm_unmap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot, gfn_t gfn, int level,
unsigned long data)
{
- return kvm_zap_rmapp(kvm, rmapp);
+ return kvm_zap_rmapp(kvm, rmap_head);
}
-static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
+static int kvm_set_pte_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot, gfn_t gfn, int level,
unsigned long data)
{
@@ -1369,13 +1402,13 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
int need_flush = 0;
u64 new_spte;
pte_t *ptep = (pte_t *)data;
- pfn_t new_pfn;
+ kvm_pfn_t new_pfn;
WARN_ON(pte_huge(*ptep));
new_pfn = pte_pfn(*ptep);
restart:
- for_each_rmap_spte(rmapp, &iter, sptep) {
+ for_each_rmap_spte(rmap_head, &iter, sptep) {
rmap_printk("kvm_set_pte_rmapp: spte %p %llx gfn %llx (%d)\n",
sptep, *sptep, gfn, level);
@@ -1413,11 +1446,11 @@ struct slot_rmap_walk_iterator {
/* output fields. */
gfn_t gfn;
- unsigned long *rmap;
+ struct kvm_rmap_head *rmap;
int level;
/* private field. */
- unsigned long *end_rmap;
+ struct kvm_rmap_head *end_rmap;
};
static void
@@ -1476,7 +1509,7 @@ static int kvm_handle_hva_range(struct kvm *kvm,
unsigned long end,
unsigned long data,
int (*handler)(struct kvm *kvm,
- unsigned long *rmapp,
+ struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot,
gfn_t gfn,
int level,
@@ -1520,7 +1553,8 @@ static int kvm_handle_hva_range(struct kvm *kvm,
static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
unsigned long data,
- int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+ int (*handler)(struct kvm *kvm,
+ struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot,
gfn_t gfn, int level,
unsigned long data))
@@ -1543,7 +1577,7 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
}
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
+static int kvm_age_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot, gfn_t gfn, int level,
unsigned long data)
{
@@ -1553,18 +1587,19 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
BUG_ON(!shadow_accessed_mask);
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep) {
if (*sptep & shadow_accessed_mask) {
young = 1;
clear_bit((ffs(shadow_accessed_mask) - 1),
(unsigned long *)sptep);
}
+ }
trace_kvm_age_page(gfn, level, slot, young);
return young;
}
-static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
+static int kvm_test_age_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
struct kvm_memory_slot *slot, gfn_t gfn,
int level, unsigned long data)
{
@@ -1580,11 +1615,12 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
if (!shadow_accessed_mask)
goto out;
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep) {
if (*sptep & shadow_accessed_mask) {
young = 1;
break;
}
+ }
out:
return young;
}
@@ -1593,14 +1629,14 @@ out:
static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
{
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
struct kvm_mmu_page *sp;
sp = page_header(__pa(spte));
- rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp);
+ rmap_head = gfn_to_rmap(vcpu->kvm, gfn, sp);
- kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, gfn, sp->role.level, 0);
+ kvm_unmap_rmapp(vcpu->kvm, rmap_head, NULL, gfn, sp->role.level, 0);
kvm_flush_remote_tlbs(vcpu->kvm);
}
@@ -1700,8 +1736,7 @@ static void drop_parent_pte(struct kvm_mmu_page *sp,
mmu_spte_clear_no_track(parent_pte);
}
-static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
- u64 *parent_pte, int direct)
+static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, int direct)
{
struct kvm_mmu_page *sp;
@@ -1717,8 +1752,6 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
* this feature. See the comments in kvm_zap_obsolete_pages().
*/
list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
- sp->parent_ptes = 0;
- mmu_page_add_parent_pte(vcpu, sp, parent_pte);
kvm_mod_used_mmu_pages(vcpu->kvm, +1);
return sp;
}
@@ -1726,7 +1759,12 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
static void mark_unsync(u64 *spte);
static void kvm_mmu_mark_parents_unsync(struct kvm_mmu_page *sp)
{
- pte_list_walk(&sp->parent_ptes, mark_unsync);
+ u64 *sptep;
+ struct rmap_iterator iter;
+
+ for_each_rmap_spte(&sp->parent_ptes, &iter, sptep) {
+ mark_unsync(sptep);
+ }
}
static void mark_unsync(u64 *spte)
@@ -1746,7 +1784,7 @@ static void mark_unsync(u64 *spte)
static int nonpaging_sync_page(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *sp)
{
- return 1;
+ return 0;
}
static void nonpaging_invlpg(struct kvm_vcpu *vcpu, gva_t gva)
@@ -1786,6 +1824,13 @@ static int mmu_pages_add(struct kvm_mmu_pages *pvec, struct kvm_mmu_page *sp,
return (pvec->nr == KVM_PAGE_ARRAY_NR);
}
+static inline void clear_unsync_child_bit(struct kvm_mmu_page *sp, int idx)
+{
+ --sp->unsync_children;
+ WARN_ON((int)sp->unsync_children < 0);
+ __clear_bit(idx, sp->unsync_child_bitmap);
+}
+
static int __mmu_unsync_walk(struct kvm_mmu_page *sp,
struct kvm_mmu_pages *pvec)
{
@@ -1795,8 +1840,10 @@ static int __mmu_unsync_walk(struct kvm_mmu_page *sp,
struct kvm_mmu_page *child;
u64 ent = sp->spt[i];
- if (!is_shadow_present_pte(ent) || is_large_pte(ent))
- goto clear_child_bitmap;
+ if (!is_shadow_present_pte(ent) || is_large_pte(ent)) {
+ clear_unsync_child_bit(sp, i);
+ continue;
+ }
child = page_header(ent & PT64_BASE_ADDR_MASK);
@@ -1805,38 +1852,34 @@ static int __mmu_unsync_walk(struct kvm_mmu_page *sp,
return -ENOSPC;
ret = __mmu_unsync_walk(child, pvec);
- if (!ret)
- goto clear_child_bitmap;
- else if (ret > 0)
+ if (!ret) {
+ clear_unsync_child_bit(sp, i);
+ continue;
+ } else if (ret > 0) {
nr_unsync_leaf += ret;
- else
+ } else
return ret;
} else if (child->unsync) {
nr_unsync_leaf++;
if (mmu_pages_add(pvec, child, i))
return -ENOSPC;
} else
- goto clear_child_bitmap;
-
- continue;
-
-clear_child_bitmap:
- __clear_bit(i, sp->unsync_child_bitmap);
- sp->unsync_children--;
- WARN_ON((int)sp->unsync_children < 0);
+ clear_unsync_child_bit(sp, i);
}
-
return nr_unsync_leaf;
}
+#define INVALID_INDEX (-1)
+
static int mmu_unsync_walk(struct kvm_mmu_page *sp,
struct kvm_mmu_pages *pvec)
{
+ pvec->nr = 0;
if (!sp->unsync_children)
return 0;
- mmu_pages_add(pvec, sp, 0);
+ mmu_pages_add(pvec, sp, INVALID_INDEX);
return __mmu_unsync_walk(sp, pvec);
}
@@ -1873,37 +1916,35 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm,
if ((_sp)->role.direct || (_sp)->role.invalid) {} else
/* @sp->gfn should be write-protected at the call site */
-static int __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
- struct list_head *invalid_list, bool clear_unsync)
+static bool __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+ struct list_head *invalid_list)
{
if (sp->role.cr4_pae != !!is_pae(vcpu)) {
kvm_mmu_prepare_zap_page(vcpu->kvm, sp, invalid_list);
- return 1;
+ return false;
}
- if (clear_unsync)
- kvm_unlink_unsync_page(vcpu->kvm, sp);
-
- if (vcpu->arch.mmu.sync_page(vcpu, sp)) {
+ if (vcpu->arch.mmu.sync_page(vcpu, sp) == 0) {
kvm_mmu_prepare_zap_page(vcpu->kvm, sp, invalid_list);
- return 1;
+ return false;
}
- kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
- return 0;
+ return true;
}
-static int kvm_sync_page_transient(struct kvm_vcpu *vcpu,
- struct kvm_mmu_page *sp)
+static void kvm_mmu_flush_or_zap(struct kvm_vcpu *vcpu,
+ struct list_head *invalid_list,
+ bool remote_flush, bool local_flush)
{
- LIST_HEAD(invalid_list);
- int ret;
-
- ret = __kvm_sync_page(vcpu, sp, &invalid_list, false);
- if (ret)
- kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
+ if (!list_empty(invalid_list)) {
+ kvm_mmu_commit_zap_page(vcpu->kvm, invalid_list);
+ return;
+ }
- return ret;
+ if (remote_flush)
+ kvm_flush_remote_tlbs(vcpu->kvm);
+ else if (local_flush)
+ kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
}
#ifdef CONFIG_KVM_MMU_AUDIT
@@ -1913,46 +1954,38 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point) { }
static void mmu_audit_disable(void) { }
#endif
-static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+static bool kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
struct list_head *invalid_list)
{
- return __kvm_sync_page(vcpu, sp, invalid_list, true);
+ kvm_unlink_unsync_page(vcpu->kvm, sp);
+ return __kvm_sync_page(vcpu, sp, invalid_list);
}
/* @gfn should be write-protected at the call site */
-static void kvm_sync_pages(struct kvm_vcpu *vcpu, gfn_t gfn)
+static bool kvm_sync_pages(struct kvm_vcpu *vcpu, gfn_t gfn,
+ struct list_head *invalid_list)
{
struct kvm_mmu_page *s;
- LIST_HEAD(invalid_list);
- bool flush = false;
+ bool ret = false;
for_each_gfn_indirect_valid_sp(vcpu->kvm, s, gfn) {
if (!s->unsync)
continue;
WARN_ON(s->role.level != PT_PAGE_TABLE_LEVEL);
- kvm_unlink_unsync_page(vcpu->kvm, s);
- if ((s->role.cr4_pae != !!is_pae(vcpu)) ||
- (vcpu->arch.mmu.sync_page(vcpu, s))) {
- kvm_mmu_prepare_zap_page(vcpu->kvm, s, &invalid_list);
- continue;
- }
- flush = true;
+ ret |= kvm_sync_page(vcpu, s, invalid_list);
}
- kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
- if (flush)
- kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
+ return ret;
}
struct mmu_page_path {
- struct kvm_mmu_page *parent[PT64_ROOT_LEVEL-1];
- unsigned int idx[PT64_ROOT_LEVEL-1];
+ struct kvm_mmu_page *parent[PT64_ROOT_LEVEL];
+ unsigned int idx[PT64_ROOT_LEVEL];
};
#define for_each_sp(pvec, sp, parents, i) \
- for (i = mmu_pages_next(&pvec, &parents, -1), \
- sp = pvec.page[i].sp; \
+ for (i = mmu_pages_first(&pvec, &parents); \
i < pvec.nr && ({ sp = pvec.page[i].sp; 1;}); \
i = mmu_pages_next(&pvec, &parents, i))
@@ -1964,19 +1997,43 @@ static int mmu_pages_next(struct kvm_mmu_pages *pvec,
for (n = i+1; n < pvec->nr; n++) {
struct kvm_mmu_page *sp = pvec->page[n].sp;
+ unsigned idx = pvec->page[n].idx;
+ int level = sp->role.level;
- if (sp->role.level == PT_PAGE_TABLE_LEVEL) {
- parents->idx[0] = pvec->page[n].idx;
- return n;
- }
+ parents->idx[level-1] = idx;
+ if (level == PT_PAGE_TABLE_LEVEL)
+ break;
- parents->parent[sp->role.level-2] = sp;
- parents->idx[sp->role.level-1] = pvec->page[n].idx;
+ parents->parent[level-2] = sp;
}
return n;
}
+static int mmu_pages_first(struct kvm_mmu_pages *pvec,
+ struct mmu_page_path *parents)
+{
+ struct kvm_mmu_page *sp;
+ int level;
+
+ if (pvec->nr == 0)
+ return 0;
+
+ WARN_ON(pvec->page[0].idx != INVALID_INDEX);
+
+ sp = pvec->page[0].sp;
+ level = sp->role.level;
+ WARN_ON(level == PT_PAGE_TABLE_LEVEL);
+
+ parents->parent[level-2] = sp;
+
+ /* Also set up a sentinel. Further entries in pvec are all
+ * children of sp, so this element is never overwritten.
+ */
+ parents->parent[level-1] = NULL;
+ return mmu_pages_next(pvec, parents, 0);
+}
+
static void mmu_pages_clear_parents(struct mmu_page_path *parents)
{
struct kvm_mmu_page *sp;
@@ -1984,24 +2041,14 @@ static void mmu_pages_clear_parents(struct mmu_page_path *parents)
do {
unsigned int idx = parents->idx[level];
-
sp = parents->parent[level];
if (!sp)
return;
- --sp->unsync_children;
- WARN_ON((int)sp->unsync_children < 0);
- __clear_bit(idx, sp->unsync_child_bitmap);
+ WARN_ON(idx == INVALID_INDEX);
+ clear_unsync_child_bit(sp, idx);
level++;
- } while (level < PT64_ROOT_LEVEL-1 && !sp->unsync_children);
-}
-
-static void kvm_mmu_pages_init(struct kvm_mmu_page *parent,
- struct mmu_page_path *parents,
- struct kvm_mmu_pages *pvec)
-{
- parents->parent[parent->role.level-1] = NULL;
- pvec->nr = 0;
+ } while (!sp->unsync_children);
}
static void mmu_sync_children(struct kvm_vcpu *vcpu,
@@ -2012,38 +2059,36 @@ static void mmu_sync_children(struct kvm_vcpu *vcpu,
struct mmu_page_path parents;
struct kvm_mmu_pages pages;
LIST_HEAD(invalid_list);
+ bool flush = false;
- kvm_mmu_pages_init(parent, &parents, &pages);
while (mmu_unsync_walk(parent, &pages)) {
bool protected = false;
for_each_sp(pages, sp, parents, i)
protected |= rmap_write_protect(vcpu, sp->gfn);
- if (protected)
+ if (protected) {
kvm_flush_remote_tlbs(vcpu->kvm);
+ flush = false;
+ }
for_each_sp(pages, sp, parents, i) {
- kvm_sync_page(vcpu, sp, &invalid_list);
+ flush |= kvm_sync_page(vcpu, sp, &invalid_list);
mmu_pages_clear_parents(&parents);
}
- kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
- cond_resched_lock(&vcpu->kvm->mmu_lock);
- kvm_mmu_pages_init(parent, &parents, &pages);
+ if (need_resched() || spin_needbreak(&vcpu->kvm->mmu_lock)) {
+ kvm_mmu_flush_or_zap(vcpu, &invalid_list, false, flush);
+ cond_resched_lock(&vcpu->kvm->mmu_lock);
+ flush = false;
+ }
}
-}
-
-static void init_shadow_page_table(struct kvm_mmu_page *sp)
-{
- int i;
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
- sp->spt[i] = 0ull;
+ kvm_mmu_flush_or_zap(vcpu, &invalid_list, false, flush);
}
static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp)
{
- sp->write_flooding_count = 0;
+ atomic_set(&sp->write_flooding_count, 0);
}
static void clear_sp_write_flooding_count(u64 *spte)
@@ -2063,13 +2108,14 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gva_t gaddr,
unsigned level,
int direct,
- unsigned access,
- u64 *parent_pte)
+ unsigned access)
{
union kvm_mmu_page_role role;
unsigned quadrant;
struct kvm_mmu_page *sp;
bool need_sync = false;
+ bool flush = false;
+ LIST_HEAD(invalid_list);
role = vcpu->arch.mmu.base_role;
role.level = level;
@@ -2093,39 +2139,52 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
if (sp->role.word != role.word)
continue;
- if (sp->unsync && kvm_sync_page_transient(vcpu, sp))
- break;
+ if (sp->unsync) {
+ /* The page is good, but __kvm_sync_page might still end
+ * up zapping it. If so, break in order to rebuild it.
+ */
+ if (!__kvm_sync_page(vcpu, sp, &invalid_list))
+ break;
+
+ WARN_ON(!list_empty(&invalid_list));
+ kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
+ }
- mmu_page_add_parent_pte(vcpu, sp, parent_pte);
- if (sp->unsync_children) {
+ if (sp->unsync_children)
kvm_make_request(KVM_REQ_MMU_SYNC, vcpu);
- kvm_mmu_mark_parents_unsync(sp);
- } else if (sp->unsync)
- kvm_mmu_mark_parents_unsync(sp);
__clear_sp_write_flooding_count(sp);
trace_kvm_mmu_get_page(sp, false);
return sp;
}
+
++vcpu->kvm->stat.mmu_cache_miss;
- sp = kvm_mmu_alloc_page(vcpu, parent_pte, direct);
- if (!sp)
- return sp;
+
+ sp = kvm_mmu_alloc_page(vcpu, direct);
+
sp->gfn = gfn;
sp->role = role;
hlist_add_head(&sp->hash_link,
&vcpu->kvm->arch.mmu_page_hash[kvm_page_table_hashfn(gfn)]);
if (!direct) {
- if (rmap_write_protect(vcpu, gfn))
+ /*
+ * we should do write protection before syncing pages
+ * otherwise the content of the synced shadow page may
+ * be inconsistent with guest page table.
+ */
+ account_shadowed(vcpu->kvm, sp);
+ if (level == PT_PAGE_TABLE_LEVEL &&
+ rmap_write_protect(vcpu, gfn))
kvm_flush_remote_tlbs(vcpu->kvm);
- if (level > PT_PAGE_TABLE_LEVEL && need_sync)
- kvm_sync_pages(vcpu, gfn);
- account_shadowed(vcpu->kvm, sp);
+ if (level > PT_PAGE_TABLE_LEVEL && need_sync)
+ flush |= kvm_sync_pages(vcpu, gfn, &invalid_list);
}
sp->mmu_valid_gen = vcpu->kvm->arch.mmu_valid_gen;
- init_shadow_page_table(sp);
+ clear_page(sp->spt);
trace_kvm_mmu_get_page(sp, true);
+
+ kvm_mmu_flush_or_zap(vcpu, &invalid_list, false, flush);
return sp;
}
@@ -2178,7 +2237,8 @@ static void shadow_walk_next(struct kvm_shadow_walk_iterator *iterator)
return __shadow_walk_next(iterator, *iterator->sptep);
}
-static void link_shadow_page(u64 *sptep, struct kvm_mmu_page *sp, bool accessed)
+static void link_shadow_page(struct kvm_vcpu *vcpu, u64 *sptep,
+ struct kvm_mmu_page *sp)
{
u64 spte;
@@ -2186,12 +2246,14 @@ static void link_shadow_page(u64 *sptep, struct kvm_mmu_page *sp, bool accessed)
VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK);
spte = __pa(sp->spt) | PT_PRESENT_MASK | PT_WRITABLE_MASK |
- shadow_user_mask | shadow_x_mask;
-
- if (accessed)
- spte |= shadow_accessed_mask;
+ shadow_user_mask | shadow_x_mask | shadow_accessed_mask;
mmu_spte_set(sptep, spte);
+
+ mmu_page_add_parent_pte(vcpu, sp, sptep);
+
+ if (sp->unsync_children || sp->unsync)
+ mark_unsync(sptep);
}
static void validate_direct_spte(struct kvm_vcpu *vcpu, u64 *sptep,
@@ -2250,17 +2312,12 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm,
mmu_page_zap_pte(kvm, sp, sp->spt + i);
}
-static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
-{
- mmu_page_remove_parent_pte(sp, parent_pte);
-}
-
static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
{
u64 *sptep;
struct rmap_iterator iter;
- while ((sptep = rmap_get_first(sp->parent_ptes, &iter)))
+ while ((sptep = rmap_get_first(&sp->parent_ptes, &iter)))
drop_parent_pte(sp, sptep);
}
@@ -2275,7 +2332,6 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
if (parent->role.level == PT_PAGE_TABLE_LEVEL)
return 0;
- kvm_mmu_pages_init(parent, &parents, &pages);
while (mmu_unsync_walk(parent, &pages)) {
struct kvm_mmu_page *sp;
@@ -2284,7 +2340,6 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
mmu_pages_clear_parents(&parents);
zapped++;
}
- kvm_mmu_pages_init(parent, &parents, &pages);
}
return zapped;
@@ -2360,8 +2415,8 @@ static bool prepare_zap_oldest_mmu_page(struct kvm *kvm,
if (list_empty(&kvm->arch.active_mmu_pages))
return false;
- sp = list_entry(kvm->arch.active_mmu_pages.prev,
- struct kvm_mmu_page, link);
+ sp = list_last_entry(&kvm->arch.active_mmu_pages,
+ struct kvm_mmu_page, link);
kvm_mmu_prepare_zap_page(kvm, sp, invalid_list);
return true;
@@ -2414,7 +2469,7 @@ int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
}
EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page);
-static void __kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+static void kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
{
trace_kvm_mmu_unsync_page(sp);
++vcpu->kvm->stat.mmu_unsync;
@@ -2423,40 +2478,29 @@ static void __kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
kvm_mmu_mark_parents_unsync(sp);
}
-static void kvm_unsync_pages(struct kvm_vcpu *vcpu, gfn_t gfn)
+static bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
+ bool can_unsync)
{
- struct kvm_mmu_page *s;
-
- for_each_gfn_indirect_valid_sp(vcpu->kvm, s, gfn) {
- if (s->unsync)
- continue;
- WARN_ON(s->role.level != PT_PAGE_TABLE_LEVEL);
- __kvm_unsync_page(vcpu, s);
- }
-}
+ struct kvm_mmu_page *sp;
-static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
- bool can_unsync)
-{
- struct kvm_mmu_page *s;
- bool need_unsync = false;
+ if (kvm_page_track_is_active(vcpu, gfn, KVM_PAGE_TRACK_WRITE))
+ return true;
- for_each_gfn_indirect_valid_sp(vcpu->kvm, s, gfn) {
+ for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
if (!can_unsync)
- return 1;
+ return true;
- if (s->role.level != PT_PAGE_TABLE_LEVEL)
- return 1;
+ if (sp->unsync)
+ continue;
- if (!s->unsync)
- need_unsync = true;
+ WARN_ON(sp->role.level != PT_PAGE_TABLE_LEVEL);
+ kvm_unsync_page(vcpu, sp);
}
- if (need_unsync)
- kvm_unsync_pages(vcpu, gfn);
- return 0;
+
+ return false;
}
-static bool kvm_is_mmio_pfn(pfn_t pfn)
+static bool kvm_is_mmio_pfn(kvm_pfn_t pfn)
{
if (pfn_valid(pfn))
return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn));
@@ -2466,7 +2510,7 @@ static bool kvm_is_mmio_pfn(pfn_t pfn)
static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
unsigned pte_access, int level,
- gfn_t gfn, pfn_t pfn, bool speculative,
+ gfn_t gfn, kvm_pfn_t pfn, bool speculative,
bool can_unsync, bool host_writable)
{
u64 spte;
@@ -2509,7 +2553,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
* be fixed if guest refault.
*/
if (level > PT_PAGE_TABLE_LEVEL &&
- has_wrprotected_page(vcpu, gfn, level))
+ mmu_gfn_lpage_is_disallowed(vcpu, gfn, level))
goto done;
spte |= PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE;
@@ -2544,18 +2588,18 @@ done:
return ret;
}
-static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
- unsigned pte_access, int write_fault, int *emulate,
- int level, gfn_t gfn, pfn_t pfn, bool speculative,
- bool host_writable)
+static bool mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, unsigned pte_access,
+ int write_fault, int level, gfn_t gfn, kvm_pfn_t pfn,
+ bool speculative, bool host_writable)
{
int was_rmapped = 0;
int rmap_count;
+ bool emulate = false;
pgprintk("%s: spte %llx write_fault %d gfn %llx\n", __func__,
*sptep, write_fault, gfn);
- if (is_rmap_spte(*sptep)) {
+ if (is_shadow_present_pte(*sptep)) {
/*
* If we overwrite a PTE page pointer with a 2MB PMD, unlink
* the parent of the now unreachable PTE.
@@ -2580,12 +2624,12 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
if (set_spte(vcpu, sptep, pte_access, level, gfn, pfn, speculative,
true, host_writable)) {
if (write_fault)
- *emulate = 1;
+ emulate = true;
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
}
- if (unlikely(is_mmio_spte(*sptep) && emulate))
- *emulate = 1;
+ if (unlikely(is_mmio_spte(*sptep)))
+ emulate = true;
pgprintk("%s: setting spte %llx\n", __func__, *sptep);
pgprintk("instantiating %s PTE (%s) at %llx (%llx) addr %p\n",
@@ -2604,9 +2648,11 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
}
kvm_release_pfn_clean(pfn);
+
+ return emulate;
}
-static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
+static kvm_pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
bool no_dirty_log)
{
struct kvm_memory_slot *slot;
@@ -2638,9 +2684,8 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
return -1;
for (i = 0; i < ret; i++, gfn++, start++)
- mmu_set_spte(vcpu, start, access, 0, NULL,
- sp->role.level, gfn, page_to_pfn(pages[i]),
- true, true);
+ mmu_set_spte(vcpu, start, access, 0, sp->role.level, gfn,
+ page_to_pfn(pages[i]), true, true);
return 0;
}
@@ -2688,9 +2733,8 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep)
__direct_pte_prefetch(vcpu, sp, sptep);
}
-static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int map_writable, int level, gfn_t gfn, pfn_t pfn,
- bool prefault)
+static int __direct_map(struct kvm_vcpu *vcpu, int write, int map_writable,
+ int level, gfn_t gfn, kvm_pfn_t pfn, bool prefault)
{
struct kvm_shadow_walk_iterator iterator;
struct kvm_mmu_page *sp;
@@ -2702,9 +2746,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
if (iterator.level == level) {
- mmu_set_spte(vcpu, iterator.sptep, ACC_ALL,
- write, &emulate, level, gfn, pfn,
- prefault, map_writable);
+ emulate = mmu_set_spte(vcpu, iterator.sptep, ACC_ALL,
+ write, level, gfn, pfn, prefault,
+ map_writable);
direct_pte_prefetch(vcpu, iterator.sptep);
++vcpu->stat.pf_fixed;
break;
@@ -2717,10 +2761,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
base_addr &= PT64_LVL_ADDR_MASK(iterator.level);
pseudo_gfn = base_addr >> PAGE_SHIFT;
sp = kvm_mmu_get_page(vcpu, pseudo_gfn, iterator.addr,
- iterator.level - 1,
- 1, ACC_ALL, iterator.sptep);
+ iterator.level - 1, 1, ACC_ALL);
- link_shadow_page(iterator.sptep, sp, true);
+ link_shadow_page(vcpu, iterator.sptep, sp);
}
}
return emulate;
@@ -2739,7 +2782,7 @@ static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *
send_sig_info(SIGBUS, &info, tsk);
}
-static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, pfn_t pfn)
+static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn)
{
/*
* Do not cache the mmio info caused by writing the readonly gfn
@@ -2759,9 +2802,10 @@ static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, pfn_t pfn)
}
static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu,
- gfn_t *gfnp, pfn_t *pfnp, int *levelp)
+ gfn_t *gfnp, kvm_pfn_t *pfnp,
+ int *levelp)
{
- pfn_t pfn = *pfnp;
+ kvm_pfn_t pfn = *pfnp;
gfn_t gfn = *gfnp;
int level = *levelp;
@@ -2774,7 +2818,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu,
if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) &&
level == PT_PAGE_TABLE_LEVEL &&
PageTransCompound(pfn_to_page(pfn)) &&
- !has_wrprotected_page(vcpu, gfn, PT_DIRECTORY_LEVEL)) {
+ !mmu_gfn_lpage_is_disallowed(vcpu, gfn, PT_DIRECTORY_LEVEL)) {
unsigned long mask;
/*
* mmu_notifier_retry was successful and we hold the
@@ -2800,22 +2844,18 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu,
}
static bool handle_abnormal_pfn(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
- pfn_t pfn, unsigned access, int *ret_val)
+ kvm_pfn_t pfn, unsigned access, int *ret_val)
{
- bool ret = true;
-
/* The pfn is invalid, report the error! */
if (unlikely(is_error_pfn(pfn))) {
*ret_val = kvm_handle_bad_page(vcpu, gfn, pfn);
- goto exit;
+ return true;
}
if (unlikely(is_noslot_pfn(pfn)))
vcpu_cache_mmio_info(vcpu, gva, gfn, access);
- ret = false;
-exit:
- return ret;
+ return false;
}
static bool page_fault_can_be_fast(u32 error_code)
@@ -2899,7 +2939,7 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gva_t gva, int level,
* If the mapping has been changed, let the vcpu fault on the
* same address again.
*/
- if (!is_rmap_spte(spte)) {
+ if (!is_shadow_present_pte(spte)) {
ret = true;
goto exit;
}
@@ -2954,7 +2994,7 @@ exit:
}
static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
- gva_t gva, pfn_t *pfn, bool write, bool *writable);
+ gva_t gva, kvm_pfn_t *pfn, bool write, bool *writable);
static void make_mmu_pages_available(struct kvm_vcpu *vcpu);
static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, u32 error_code,
@@ -2962,14 +3002,13 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, u32 error_code,
{
int r;
int level;
- int force_pt_level;
- pfn_t pfn;
+ bool force_pt_level = false;
+ kvm_pfn_t pfn;
unsigned long mmu_seq;
bool map_writable, write = error_code & PFERR_WRITE_MASK;
- force_pt_level = mapping_level_dirty_bitmap(vcpu, gfn);
+ level = mapping_level(vcpu, gfn, &force_pt_level);
if (likely(!force_pt_level)) {
- level = mapping_level(vcpu, gfn);
/*
* This path builds a PAE pagetable - so we can map
* 2mb pages at maximum. Therefore check if the level
@@ -2979,8 +3018,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, u32 error_code,
level = PT_DIRECTORY_LEVEL;
gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
- } else
- level = PT_PAGE_TABLE_LEVEL;
+ }
if (fast_page_fault(vcpu, v, level, error_code))
return 0;
@@ -3000,11 +3038,9 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, u32 error_code,
make_mmu_pages_available(vcpu);
if (likely(!force_pt_level))
transparent_hugepage_adjust(vcpu, &gfn, &pfn, &level);
- r = __direct_map(vcpu, v, write, map_writable, level, gfn, pfn,
- prefault);
+ r = __direct_map(vcpu, write, map_writable, level, gfn, pfn, prefault);
spin_unlock(&vcpu->kvm->mmu_lock);
-
return r;
out_unlock:
@@ -3079,8 +3115,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
spin_lock(&vcpu->kvm->mmu_lock);
make_mmu_pages_available(vcpu);
- sp = kvm_mmu_get_page(vcpu, 0, 0, PT64_ROOT_LEVEL,
- 1, ACC_ALL, NULL);
+ sp = kvm_mmu_get_page(vcpu, 0, 0, PT64_ROOT_LEVEL, 1, ACC_ALL);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
vcpu->arch.mmu.root_hpa = __pa(sp->spt);
@@ -3092,9 +3127,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
make_mmu_pages_available(vcpu);
sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
- i << 30,
- PT32_ROOT_LEVEL, 1, ACC_ALL,
- NULL);
+ i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL);
root = __pa(sp->spt);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -3131,7 +3164,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
make_mmu_pages_available(vcpu);
sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL,
- 0, ACC_ALL, NULL);
+ 0, ACC_ALL);
root = __pa(sp->spt);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -3164,9 +3197,8 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
}
spin_lock(&vcpu->kvm->mmu_lock);
make_mmu_pages_available(vcpu);
- sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
- PT32_ROOT_LEVEL, 0,
- ACC_ALL, NULL);
+ sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL,
+ 0, ACC_ALL);
root = __pa(sp->spt);
++sp->root_count;
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -3287,7 +3319,7 @@ static bool is_shadow_zero_bits_set(struct kvm_mmu *mmu, u64 spte, int level)
return __is_rsvd_bits_set(&mmu->shadow_zero_check, spte, level);
}
-static bool quickly_check_mmio_pf(struct kvm_vcpu *vcpu, u64 addr, bool direct)
+static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct)
{
if (direct)
return vcpu_match_mmio_gpa(vcpu, addr);
@@ -3341,16 +3373,16 @@ exit:
return reserved;
}
-int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
+int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct)
{
u64 spte;
bool reserved;
- if (quickly_check_mmio_pf(vcpu, addr, direct))
+ if (mmio_info_in_cache(vcpu, addr, direct))
return RET_MMIO_PF_EMULATE;
reserved = walk_shadow_page_get_mmio_spte(vcpu, addr, &spte);
- if (unlikely(reserved))
+ if (WARN_ON(reserved))
return RET_MMIO_PF_BUG;
if (is_mmio_spte(spte)) {
@@ -3374,32 +3406,55 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
*/
return RET_MMIO_PF_RETRY;
}
-EXPORT_SYMBOL_GPL(handle_mmio_page_fault_common);
+EXPORT_SYMBOL_GPL(handle_mmio_page_fault);
-static int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr,
- u32 error_code, bool direct)
+static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
+ u32 error_code, gfn_t gfn)
{
- int ret;
+ if (unlikely(error_code & PFERR_RSVD_MASK))
+ return false;
- ret = handle_mmio_page_fault_common(vcpu, addr, direct);
- WARN_ON(ret == RET_MMIO_PF_BUG);
- return ret;
+ if (!(error_code & PFERR_PRESENT_MASK) ||
+ !(error_code & PFERR_WRITE_MASK))
+ return false;
+
+ /*
+ * guest is writing the page which is write tracked which can
+ * not be fixed by page fault handler.
+ */
+ if (kvm_page_track_is_active(vcpu, gfn, KVM_PAGE_TRACK_WRITE))
+ return true;
+
+ return false;
+}
+
+static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
+{
+ struct kvm_shadow_walk_iterator iterator;
+ u64 spte;
+
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+ return;
+
+ walk_shadow_page_lockless_begin(vcpu);
+ for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
+ clear_sp_write_flooding_count(iterator.sptep);
+ if (!is_shadow_present_pte(spte))
+ break;
+ }
+ walk_shadow_page_lockless_end(vcpu);
}
static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
u32 error_code, bool prefault)
{
- gfn_t gfn;
+ gfn_t gfn = gva >> PAGE_SHIFT;
int r;
pgprintk("%s: gva %lx error %x\n", __func__, gva, error_code);
- if (unlikely(error_code & PFERR_RSVD_MASK)) {
- r = handle_mmio_page_fault(vcpu, gva, error_code, true);
-
- if (likely(r != RET_MMIO_PF_INVALID))
- return r;
- }
+ if (page_fault_handle_page_track(vcpu, error_code, gfn))
+ return 1;
r = mmu_topup_memory_caches(vcpu);
if (r)
@@ -3407,7 +3462,6 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
MMU_WARN_ON(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
- gfn = gva >> PAGE_SHIFT;
return nonpaging_map(vcpu, gva & PAGE_MASK,
error_code, gfn, prefault);
@@ -3427,7 +3481,7 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)
static bool can_do_async_pf(struct kvm_vcpu *vcpu)
{
- if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
+ if (unlikely(!lapic_in_kernel(vcpu) ||
kvm_event_needs_reinjection(vcpu)))
return false;
@@ -3435,7 +3489,7 @@ static bool can_do_async_pf(struct kvm_vcpu *vcpu)
}
static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
- gva_t gva, pfn_t *pfn, bool write, bool *writable)
+ gva_t gva, kvm_pfn_t *pfn, bool write, bool *writable)
{
struct kvm_memory_slot *slot;
bool async;
@@ -3473,10 +3527,10 @@ check_hugepage_cache_consistency(struct kvm_vcpu *vcpu, gfn_t gfn, int level)
static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
bool prefault)
{
- pfn_t pfn;
+ kvm_pfn_t pfn;
int r;
int level;
- int force_pt_level;
+ bool force_pt_level;
gfn_t gfn = gpa >> PAGE_SHIFT;
unsigned long mmu_seq;
int write = error_code & PFERR_WRITE_MASK;
@@ -3484,31 +3538,22 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
MMU_WARN_ON(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
- if (unlikely(error_code & PFERR_RSVD_MASK)) {
- r = handle_mmio_page_fault(vcpu, gpa, error_code, true);
-
- if (likely(r != RET_MMIO_PF_INVALID))
- return r;
- }
+ if (page_fault_handle_page_track(vcpu, error_code, gfn))
+ return 1;
r = mmu_topup_memory_caches(vcpu);
if (r)
return r;
- if (mapping_level_dirty_bitmap(vcpu, gfn) ||
- !check_hugepage_cache_consistency(vcpu, gfn, PT_DIRECTORY_LEVEL))
- force_pt_level = 1;
- else
- force_pt_level = 0;
-
+ force_pt_level = !check_hugepage_cache_consistency(vcpu, gfn,
+ PT_DIRECTORY_LEVEL);
+ level = mapping_level(vcpu, gfn, &force_pt_level);
if (likely(!force_pt_level)) {
- level = mapping_level(vcpu, gfn);
if (level > PT_DIRECTORY_LEVEL &&
!check_hugepage_cache_consistency(vcpu, gfn, level))
level = PT_DIRECTORY_LEVEL;
gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
- } else
- level = PT_PAGE_TABLE_LEVEL;
+ }
if (fast_page_fault(vcpu, gpa, level, error_code))
return 0;
@@ -3528,8 +3573,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code,
make_mmu_pages_available(vcpu);
if (likely(!force_pt_level))
transparent_hugepage_adjust(vcpu, &gfn, &pfn, &level);
- r = __direct_map(vcpu, gpa, write, map_writable,
- level, gfn, pfn, prefault);
+ r = __direct_map(vcpu, write, map_writable, level, gfn, pfn, prefault);
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
@@ -3588,13 +3632,24 @@ static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
return false;
}
-static inline bool is_last_gpte(struct kvm_mmu *mmu, unsigned level, unsigned gpte)
+static inline bool is_last_gpte(struct kvm_mmu *mmu,
+ unsigned level, unsigned gpte)
{
- unsigned index;
+ /*
+ * PT_PAGE_TABLE_LEVEL always terminates. The RHS has bit 7 set
+ * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means
+ * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then.
+ */
+ gpte |= level - PT_PAGE_TABLE_LEVEL - 1;
+
+ /*
+ * The RHS has bit 7 set iff level < mmu->last_nonleaf_level.
+ * If it is clear, there are no large pages at this level, so clear
+ * PT_PAGE_SIZE_MASK in gpte if that is the case.
+ */
+ gpte &= level - mmu->last_nonleaf_level;
- index = level - 1;
- index |= (gpte & PT_PAGE_SIZE_MASK) >> (PT_PAGE_SIZE_SHIFT - 2);
- return mmu->last_pte_bitmap & (1 << index);
+ return gpte & PT_PAGE_SIZE_MASK;
}
#define PTTYPE_EPT 18 /* arbitrary */
@@ -3706,7 +3761,7 @@ static void
__reset_rsvds_bits_mask_ept(struct rsvd_bits_validate *rsvd_check,
int maxphyaddr, bool execonly)
{
- int pte;
+ u64 bad_mt_xwr;
rsvd_check->rsvd_bits_mask[0][3] =
rsvd_bits(maxphyaddr, 51) | rsvd_bits(3, 7);
@@ -3724,14 +3779,16 @@ __reset_rsvds_bits_mask_ept(struct rsvd_bits_validate *rsvd_check,
rsvd_bits(maxphyaddr, 51) | rsvd_bits(12, 20);
rsvd_check->rsvd_bits_mask[1][0] = rsvd_check->rsvd_bits_mask[0][0];
- for (pte = 0; pte < 64; pte++) {
- int rwx_bits = pte & 7;
- int mt = pte >> 3;
- if (mt == 0x2 || mt == 0x3 || mt == 0x7 ||
- rwx_bits == 0x2 || rwx_bits == 0x6 ||
- (rwx_bits == 0x4 && !execonly))
- rsvd_check->bad_mt_xwr |= (1ull << pte);
+ bad_mt_xwr = 0xFFull << (2 * 8); /* bits 3..5 must not be 2 */
+ bad_mt_xwr |= 0xFFull << (3 * 8); /* bits 3..5 must not be 3 */
+ bad_mt_xwr |= 0xFFull << (7 * 8); /* bits 3..5 must not be 7 */
+ bad_mt_xwr |= REPEAT_BYTE(1ull << 2); /* bits 0..2 must not be 010 */
+ bad_mt_xwr |= REPEAT_BYTE(1ull << 6); /* bits 0..2 must not be 110 */
+ if (!execonly) {
+ /* bits 0..2 must not be 100 unless VMX capabilities allow it */
+ bad_mt_xwr |= REPEAT_BYTE(1ull << 4);
}
+ rsvd_check->bad_mt_xwr = bad_mt_xwr;
}
static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
@@ -3749,13 +3806,15 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
void
reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context)
{
+ bool uses_nx = context->nx || context->base_role.smep_andnot_wp;
+
/*
* Passing "true" to the last argument is okay; it adds a check
* on bit 8 of the SPTEs which KVM doesn't use anyway.
*/
__reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check,
boot_cpu_data.x86_phys_bits,
- context->shadow_root_level, context->nx,
+ context->shadow_root_level, uses_nx,
guest_cpuid_has_gbpages(vcpu), is_pse(vcpu),
true);
}
@@ -3864,22 +3923,13 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu,
}
}
-static void update_last_pte_bitmap(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
+static void update_last_nonleaf_level(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
{
- u8 map;
- unsigned level, root_level = mmu->root_level;
- const unsigned ps_set_index = 1 << 2; /* bit 2 of index: ps */
-
- if (root_level == PT32E_ROOT_LEVEL)
- --root_level;
- /* PT_PAGE_TABLE_LEVEL always terminates */
- map = 1 | (1 << ps_set_index);
- for (level = PT_DIRECTORY_LEVEL; level <= root_level; ++level) {
- if (level <= PT_PDPE_LEVEL
- && (mmu->root_level >= PT32E_ROOT_LEVEL || is_pse(vcpu)))
- map |= 1 << (ps_set_index | (level - 1));
- }
- mmu->last_pte_bitmap = map;
+ unsigned root_level = mmu->root_level;
+
+ mmu->last_nonleaf_level = root_level;
+ if (root_level == PT32_ROOT_LEVEL && is_pse(vcpu))
+ mmu->last_nonleaf_level++;
}
static void paging64_init_context_common(struct kvm_vcpu *vcpu,
@@ -3891,7 +3941,7 @@ static void paging64_init_context_common(struct kvm_vcpu *vcpu,
reset_rsvds_bits_mask(vcpu, context);
update_permission_bitmask(vcpu, context, false);
- update_last_pte_bitmap(vcpu, context);
+ update_last_nonleaf_level(vcpu, context);
MMU_WARN_ON(!is_pae(vcpu));
context->page_fault = paging64_page_fault;
@@ -3918,7 +3968,7 @@ static void paging32_init_context(struct kvm_vcpu *vcpu,
reset_rsvds_bits_mask(vcpu, context);
update_permission_bitmask(vcpu, context, false);
- update_last_pte_bitmap(vcpu, context);
+ update_last_nonleaf_level(vcpu, context);
context->page_fault = paging32_page_fault;
context->gva_to_gpa = paging32_gva_to_gpa;
@@ -3976,7 +4026,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
}
update_permission_bitmask(vcpu, context, false);
- update_last_pte_bitmap(vcpu, context);
+ update_last_nonleaf_level(vcpu, context);
reset_tdp_shadow_zero_bits_mask(vcpu, context);
}
@@ -4053,10 +4103,12 @@ static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
g_context->inject_page_fault = kvm_inject_page_fault;
/*
- * Note that arch.mmu.gva_to_gpa translates l2_gva to l1_gpa. The
- * translation of l2_gpa to l1_gpa addresses is done using the
- * arch.nested_mmu.gva_to_gpa function. Basically the gva_to_gpa
- * functions between mmu and nested_mmu are swapped.
+ * Note that arch.mmu.gva_to_gpa translates l2_gpa to l1_gpa using
+ * L1's nested page tables (e.g. EPT12). The nested translation
+ * of l2_gva to l1_gpa is done by arch.nested_mmu.gva_to_gpa using
+ * L2's page tables as the first level of translation and L1's
+ * nested page tables as the second level of translation. Basically
+ * the gva_to_gpa functions between mmu and nested_mmu are swapped.
*/
if (!is_paging(vcpu)) {
g_context->nx = false;
@@ -4080,7 +4132,7 @@ static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
}
update_permission_bitmask(vcpu, g_context, false);
- update_last_pte_bitmap(vcpu, g_context);
+ update_last_nonleaf_level(vcpu, g_context);
}
static void init_kvm_mmu(struct kvm_vcpu *vcpu)
@@ -4151,18 +4203,6 @@ static bool need_remote_flush(u64 old, u64 new)
return (old & ~new & PT64_PERM_MASK) != 0;
}
-static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, bool zap_page,
- bool remote_flush, bool local_flush)
-{
- if (zap_page)
- return;
-
- if (remote_flush)
- kvm_flush_remote_tlbs(vcpu->kvm);
- else if (local_flush)
- kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
-}
-
static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
const u8 *new, int *bytes)
{
@@ -4212,7 +4252,8 @@ static bool detect_write_flooding(struct kvm_mmu_page *sp)
if (sp->role.level == PT_PAGE_TABLE_LEVEL)
return false;
- return ++sp->write_flooding_count >= 3;
+ atomic_inc(&sp->write_flooding_count);
+ return atomic_read(&sp->write_flooding_count) >= 3;
}
/*
@@ -4274,15 +4315,15 @@ static u64 *get_written_sptes(struct kvm_mmu_page *sp, gpa_t gpa, int *nspte)
return spte;
}
-void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
- const u8 *new, int bytes)
+static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
+ const u8 *new, int bytes)
{
gfn_t gfn = gpa >> PAGE_SHIFT;
struct kvm_mmu_page *sp;
LIST_HEAD(invalid_list);
u64 entry, gentry, *spte;
int npte;
- bool remote_flush, local_flush, zap_page;
+ bool remote_flush, local_flush;
union kvm_mmu_page_role mask = { };
mask.cr0_wp = 1;
@@ -4299,7 +4340,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
if (!ACCESS_ONCE(vcpu->kvm->arch.indirect_shadow_pages))
return;
- zap_page = remote_flush = local_flush = false;
+ remote_flush = local_flush = false;
pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
@@ -4319,8 +4360,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
if (detect_write_misaligned(sp, gpa, bytes) ||
detect_write_flooding(sp)) {
- zap_page |= !!kvm_mmu_prepare_zap_page(vcpu->kvm, sp,
- &invalid_list);
+ kvm_mmu_prepare_zap_page(vcpu->kvm, sp, &invalid_list);
++vcpu->kvm->stat.mmu_flooded;
continue;
}
@@ -4342,8 +4382,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
++spte;
}
}
- mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush);
- kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
+ kvm_mmu_flush_or_zap(vcpu, &invalid_list, remote_flush, local_flush);
kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
spin_unlock(&vcpu->kvm->mmu_lock);
}
@@ -4380,32 +4419,34 @@ static void make_mmu_pages_available(struct kvm_vcpu *vcpu)
kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
}
-static bool is_mmio_page_fault(struct kvm_vcpu *vcpu, gva_t addr)
-{
- if (vcpu->arch.mmu.direct_map || mmu_is_nested(vcpu))
- return vcpu_match_mmio_gpa(vcpu, addr);
-
- return vcpu_match_mmio_gva(vcpu, addr);
-}
-
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code,
void *insn, int insn_len)
{
int r, emulation_type = EMULTYPE_RETRY;
enum emulation_result er;
+ bool direct = vcpu->arch.mmu.direct_map || mmu_is_nested(vcpu);
+
+ if (unlikely(error_code & PFERR_RSVD_MASK)) {
+ r = handle_mmio_page_fault(vcpu, cr2, direct);
+ if (r == RET_MMIO_PF_EMULATE) {
+ emulation_type = 0;
+ goto emulate;
+ }
+ if (r == RET_MMIO_PF_RETRY)
+ return 1;
+ if (r < 0)
+ return r;
+ }
r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code, false);
if (r < 0)
- goto out;
-
- if (!r) {
- r = 1;
- goto out;
- }
+ return r;
+ if (!r)
+ return 1;
- if (is_mmio_page_fault(vcpu, cr2))
+ if (mmio_info_in_cache(vcpu, cr2, direct))
emulation_type = 0;
-
+emulate:
er = x86_emulate_instruction(vcpu, cr2, emulation_type, insn, insn_len);
switch (er) {
@@ -4419,8 +4460,6 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code,
default:
BUG();
}
-out:
- return r;
}
EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
@@ -4489,8 +4528,23 @@ void kvm_mmu_setup(struct kvm_vcpu *vcpu)
init_kvm_mmu(vcpu);
}
+void kvm_mmu_init_vm(struct kvm *kvm)
+{
+ struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker;
+
+ node->track_write = kvm_mmu_pte_write;
+ kvm_page_track_register_notifier(kvm, node);
+}
+
+void kvm_mmu_uninit_vm(struct kvm *kvm)
+{
+ struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker;
+
+ kvm_page_track_unregister_notifier(kvm, node);
+}
+
/* The return value indicates if tlb flush on all vcpus is needed. */
-typedef bool (*slot_level_handler) (struct kvm *kvm, unsigned long *rmap);
+typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head);
/* The caller should hold mmu-lock before calling this function. */
static bool
@@ -4584,9 +4638,10 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
spin_unlock(&kvm->mmu_lock);
}
-static bool slot_rmap_write_protect(struct kvm *kvm, unsigned long *rmapp)
+static bool slot_rmap_write_protect(struct kvm *kvm,
+ struct kvm_rmap_head *rmap_head)
{
- return __rmap_write_protect(kvm, rmapp, false);
+ return __rmap_write_protect(kvm, rmap_head, false);
}
void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
@@ -4622,16 +4677,16 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
}
static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm,
- unsigned long *rmapp)
+ struct kvm_rmap_head *rmap_head)
{
u64 *sptep;
struct rmap_iterator iter;
int need_tlb_flush = 0;
- pfn_t pfn;
+ kvm_pfn_t pfn;
struct kvm_mmu_page *sp;
restart:
- for_each_rmap_spte(rmapp, &iter, sptep) {
+ for_each_rmap_spte(rmap_head, &iter, sptep) {
sp = page_header(__pa(sptep));
pfn = spte_to_pfn(*sptep);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index e4202e4..58fe98a 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -56,13 +56,13 @@ void
reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
/*
- * Return values of handle_mmio_page_fault_common:
+ * Return values of handle_mmio_page_fault:
* RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction
* directly.
* RET_MMIO_PF_INVALID: invalid spte is detected then let the real page
* fault path update the mmio spte.
* RET_MMIO_PF_RETRY: let CPU fault again on the address.
- * RET_MMIO_PF_BUG: bug is detected.
+ * RET_MMIO_PF_BUG: a bug was detected (and a WARN was printed).
*/
enum {
RET_MMIO_PF_EMULATE = 1,
@@ -71,7 +71,7 @@ enum {
RET_MMIO_PF_BUG = -1
};
-int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
+int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct);
void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu);
void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly);
@@ -174,4 +174,9 @@ static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end);
+
+void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
+void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
+bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
+ struct kvm_memory_slot *slot, u64 gfn);
#endif
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index 03d518e..dcce533 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -97,7 +97,7 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
{
struct kvm_mmu_page *sp;
gfn_t gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
hpa_t hpa;
sp = page_header(__pa(sptep));
@@ -129,7 +129,7 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
{
static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
struct kvm_mmu_page *rev_sp;
struct kvm_memslots *slots;
struct kvm_memory_slot *slot;
@@ -150,8 +150,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
return;
}
- rmapp = __gfn_to_rmap(gfn, rev_sp->role.level, slot);
- if (!*rmapp) {
+ rmap_head = __gfn_to_rmap(gfn, rev_sp->role.level, slot);
+ if (!rmap_head->val) {
if (!__ratelimit(&ratelimit_state))
return;
audit_printk(kvm, "no rmap for writable spte %llx\n",
@@ -183,7 +183,7 @@ static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
return;
for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
- if (!is_rmap_spte(sp->spt[i]))
+ if (!is_shadow_present_pte(sp->spt[i]))
continue;
inspect_spte_has_rmap(kvm, sp->spt + i);
@@ -192,7 +192,7 @@ static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
{
- unsigned long *rmapp;
+ struct kvm_rmap_head *rmap_head;
u64 *sptep;
struct rmap_iterator iter;
struct kvm_memslots *slots;
@@ -203,13 +203,14 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
slots = kvm_memslots_for_spte_role(kvm, sp->role);
slot = __gfn_to_memslot(slots, sp->gfn);
- rmapp = __gfn_to_rmap(sp->gfn, PT_PAGE_TABLE_LEVEL, slot);
+ rmap_head = __gfn_to_rmap(sp->gfn, PT_PAGE_TABLE_LEVEL, slot);
- for_each_rmap_spte(rmapp, &iter, sptep)
+ for_each_rmap_spte(rmap_head, &iter, sptep) {
if (is_writable_pte(*sptep))
audit_printk(kvm, "shadow page has writable "
"mappings: gfn %llx role %x\n",
sp->gfn, sp->role.word);
+ }
}
static void audit_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
index 9e8bf13..3f8c732 100644
--- a/arch/x86/kvm/mtrr.c
+++ b/arch/x86/kvm/mtrr.c
@@ -120,14 +120,22 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
}
-static u8 mtrr_disabled_type(void)
+static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
{
/*
* Intel SDM 11.11.2.2: all MTRRs are disabled when
* IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
* memory type is applied to all of physical memory.
+ *
+ * However, virtual machines can be run with CPUID such that
+ * there are no MTRRs. In that case, the firmware will never
+ * enable MTRRs and it is obviously undesirable to run the
+ * guest entirely with UC memory and we use WB.
*/
- return MTRR_TYPE_UNCACHABLE;
+ if (guest_cpuid_has_mtrr(vcpu))
+ return MTRR_TYPE_UNCACHABLE;
+ else
+ return MTRR_TYPE_WRBACK;
}
/*
@@ -267,7 +275,7 @@ static int fixed_mtrr_addr_to_seg(u64 addr)
for (seg = 0; seg < seg_num; seg++) {
mtrr_seg = &fixed_seg_table[seg];
- if (mtrr_seg->start >= addr && addr < mtrr_seg->end)
+ if (mtrr_seg->start <= addr && addr < mtrr_seg->end)
return seg;
}
@@ -300,7 +308,6 @@ static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
*start = range->base & PAGE_MASK;
mask = range->mask & PAGE_MASK;
- mask |= ~0ULL << boot_cpu_data.x86_phys_bits;
/* This cannot overflow because writing to the reserved bits of
* variable MTRRs causes a #GP.
@@ -356,10 +363,14 @@ static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
if (var_mtrr_range_is_valid(cur))
list_del(&mtrr_state->var_ranges[index].node);
+ /* Extend the mask with all 1 bits to the left, since those
+ * bits must implicitly be 0. The bits are then cleared
+ * when reading them.
+ */
if (!is_mtrr_mask)
cur->base = data;
else
- cur->mask = data;
+ cur->mask = data | (-1LL << cpuid_maxphyaddr(vcpu));
/* add it to the list if it's enabled. */
if (var_mtrr_range_is_valid(cur)) {
@@ -426,6 +437,8 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
*pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
else
*pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
+
+ *pdata &= (1ULL << cpuid_maxphyaddr(vcpu)) - 1;
}
return 0;
@@ -670,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
}
if (iter.mtrr_disabled)
- return mtrr_disabled_type();
+ return mtrr_disabled_type(vcpu);
/* not contained in any MTRRs. */
if (type == -1)
diff --git a/arch/x86/kvm/page_track.c b/arch/x86/kvm/page_track.c
new file mode 100644
index 0000000..11f7643
--- /dev/null
+++ b/arch/x86/kvm/page_track.c
@@ -0,0 +1,222 @@
+/*
+ * Support KVM gust page tracking
+ *
+ * This feature allows us to track page access in guest. Currently, only
+ * write access is tracked.
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ * Xiao Guangrong <guangrong.xiao@linux.intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_page_track.h>
+
+#include "mmu.h"
+
+void kvm_page_track_free_memslot(struct kvm_memory_slot *free,
+ struct kvm_memory_slot *dont)
+{
+ int i;
+
+ for (i = 0; i < KVM_PAGE_TRACK_MAX; i++)
+ if (!dont || free->arch.gfn_track[i] !=
+ dont->arch.gfn_track[i]) {
+ kvfree(free->arch.gfn_track[i]);
+ free->arch.gfn_track[i] = NULL;
+ }
+}
+
+int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+ unsigned long npages)
+{
+ int i;
+
+ for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) {
+ slot->arch.gfn_track[i] = kvm_kvzalloc(npages *
+ sizeof(*slot->arch.gfn_track[i]));
+ if (!slot->arch.gfn_track[i])
+ goto track_free;
+ }
+
+ return 0;
+
+track_free:
+ kvm_page_track_free_memslot(slot, NULL);
+ return -ENOMEM;
+}
+
+static inline bool page_track_mode_is_valid(enum kvm_page_track_mode mode)
+{
+ if (mode < 0 || mode >= KVM_PAGE_TRACK_MAX)
+ return false;
+
+ return true;
+}
+
+static void update_gfn_track(struct kvm_memory_slot *slot, gfn_t gfn,
+ enum kvm_page_track_mode mode, short count)
+{
+ int index, val;
+
+ index = gfn_to_index(gfn, slot->base_gfn, PT_PAGE_TABLE_LEVEL);
+
+ val = slot->arch.gfn_track[mode][index];
+
+ if (WARN_ON(val + count < 0 || val + count > USHRT_MAX))
+ return;
+
+ slot->arch.gfn_track[mode][index] += count;
+}
+
+/*
+ * add guest page to the tracking pool so that corresponding access on that
+ * page will be intercepted.
+ *
+ * It should be called under the protection both of mmu-lock and kvm->srcu
+ * or kvm->slots_lock.
+ *
+ * @kvm: the guest instance we are interested in.
+ * @slot: the @gfn belongs to.
+ * @gfn: the guest page.
+ * @mode: tracking mode, currently only write track is supported.
+ */
+void kvm_slot_page_track_add_page(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn,
+ enum kvm_page_track_mode mode)
+{
+
+ if (WARN_ON(!page_track_mode_is_valid(mode)))
+ return;
+
+ update_gfn_track(slot, gfn, mode, 1);
+
+ /*
+ * new track stops large page mapping for the
+ * tracked page.
+ */
+ kvm_mmu_gfn_disallow_lpage(slot, gfn);
+
+ if (mode == KVM_PAGE_TRACK_WRITE)
+ if (kvm_mmu_slot_gfn_write_protect(kvm, slot, gfn))
+ kvm_flush_remote_tlbs(kvm);
+}
+
+/*
+ * remove the guest page from the tracking pool which stops the interception
+ * of corresponding access on that page. It is the opposed operation of
+ * kvm_slot_page_track_add_page().
+ *
+ * It should be called under the protection both of mmu-lock and kvm->srcu
+ * or kvm->slots_lock.
+ *
+ * @kvm: the guest instance we are interested in.
+ * @slot: the @gfn belongs to.
+ * @gfn: the guest page.
+ * @mode: tracking mode, currently only write track is supported.
+ */
+void kvm_slot_page_track_remove_page(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn,
+ enum kvm_page_track_mode mode)
+{
+ if (WARN_ON(!page_track_mode_is_valid(mode)))
+ return;
+
+ update_gfn_track(slot, gfn, mode, -1);
+
+ /*
+ * allow large page mapping for the tracked page
+ * after the tracker is gone.
+ */
+ kvm_mmu_gfn_allow_lpage(slot, gfn);
+}
+
+/*
+ * check if the corresponding access on the specified guest page is tracked.
+ */
+bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
+ enum kvm_page_track_mode mode)
+{
+ struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+ int index = gfn_to_index(gfn, slot->base_gfn, PT_PAGE_TABLE_LEVEL);
+
+ if (WARN_ON(!page_track_mode_is_valid(mode)))
+ return false;
+
+ return !!ACCESS_ONCE(slot->arch.gfn_track[mode][index]);
+}
+
+void kvm_page_track_init(struct kvm *kvm)
+{
+ struct kvm_page_track_notifier_head *head;
+
+ head = &kvm->arch.track_notifier_head;
+ init_srcu_struct(&head->track_srcu);
+ INIT_HLIST_HEAD(&head->track_notifier_list);
+}
+
+/*
+ * register the notifier so that event interception for the tracked guest
+ * pages can be received.
+ */
+void
+kvm_page_track_register_notifier(struct kvm *kvm,
+ struct kvm_page_track_notifier_node *n)
+{
+ struct kvm_page_track_notifier_head *head;
+
+ head = &kvm->arch.track_notifier_head;
+
+ spin_lock(&kvm->mmu_lock);
+ hlist_add_head_rcu(&n->node, &head->track_notifier_list);
+ spin_unlock(&kvm->mmu_lock);
+}
+
+/*
+ * stop receiving the event interception. It is the opposed operation of
+ * kvm_page_track_register_notifier().
+ */
+void
+kvm_page_track_unregister_notifier(struct kvm *kvm,
+ struct kvm_page_track_notifier_node *n)
+{
+ struct kvm_page_track_notifier_head *head;
+
+ head = &kvm->arch.track_notifier_head;
+
+ spin_lock(&kvm->mmu_lock);
+ hlist_del_rcu(&n->node);
+ spin_unlock(&kvm->mmu_lock);
+ synchronize_srcu(&head->track_srcu);
+}
+
+/*
+ * Notify the node that write access is intercepted and write emulation is
+ * finished at this time.
+ *
+ * The node should figure out if the written page is the one that node is
+ * interested in by itself.
+ */
+void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
+ int bytes)
+{
+ struct kvm_page_track_notifier_head *head;
+ struct kvm_page_track_notifier_node *n;
+ int idx;
+
+ head = &vcpu->kvm->arch.track_notifier_head;
+
+ if (hlist_empty(&head->track_notifier_list))
+ return;
+
+ idx = srcu_read_lock(&head->track_srcu);
+ hlist_for_each_entry_rcu(n, &head->track_notifier_list, node)
+ if (n->track_write)
+ n->track_write(vcpu, gpa, new, bytes);
+ srcu_read_unlock(&head->track_srcu, idx);
+}
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 736e6ab..e159a81 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -189,8 +189,11 @@ static inline unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, u64 gpte)
((gpte & VMX_EPT_EXECUTABLE_MASK) ? ACC_EXEC_MASK : 0) |
ACC_USER_MASK;
#else
- access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK;
- access &= ~(gpte >> PT64_NX_SHIFT);
+ BUILD_BUG_ON(ACC_EXEC_MASK != PT_PRESENT_MASK);
+ BUILD_BUG_ON(ACC_EXEC_MASK != 1);
+ access = gpte & (PT_WRITABLE_MASK | PT_USER_MASK | PT_PRESENT_MASK);
+ /* Combine NX with P (which is set here) to get ACC_EXEC_MASK. */
+ access ^= (gpte >> PT64_NX_SHIFT);
#endif
return access;
@@ -249,7 +252,7 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
return ret;
kvm_vcpu_mark_page_dirty(vcpu, table_gfn);
- walker->ptes[level] = pte;
+ walker->ptes[level - 1] = pte;
}
return 0;
}
@@ -456,7 +459,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
{
unsigned pte_access;
gfn_t gfn;
- pfn_t pfn;
+ kvm_pfn_t pfn;
if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte))
return false;
@@ -475,8 +478,8 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
* we call mmu_set_spte() with host_writable = true because
* pte_prefetch_gfn_to_pfn always gets a writable pfn.
*/
- mmu_set_spte(vcpu, spte, pte_access, 0, NULL, PT_PAGE_TABLE_LEVEL,
- gfn, pfn, true, true);
+ mmu_set_spte(vcpu, spte, pte_access, 0, PT_PAGE_TABLE_LEVEL, gfn, pfn,
+ true, true);
return true;
}
@@ -551,12 +554,12 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
struct guest_walker *gw,
int write_fault, int hlevel,
- pfn_t pfn, bool map_writable, bool prefault)
+ kvm_pfn_t pfn, bool map_writable, bool prefault)
{
struct kvm_mmu_page *sp = NULL;
struct kvm_shadow_walk_iterator it;
unsigned direct_access, access = gw->pt_access;
- int top_level, emulate = 0;
+ int top_level, emulate;
direct_access = gw->pte_access;
@@ -587,7 +590,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
if (!is_shadow_present_pte(*it.sptep)) {
table_gfn = gw->table_gfn[it.level - 2];
sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1,
- false, access, it.sptep);
+ false, access);
}
/*
@@ -598,7 +601,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
goto out_gpte_changed;
if (sp)
- link_shadow_page(it.sptep, sp, PT_GUEST_ACCESSED_MASK);
+ link_shadow_page(vcpu, it.sptep, sp);
}
for (;
@@ -617,20 +620,18 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
direct_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE(it.level) - 1);
sp = kvm_mmu_get_page(vcpu, direct_gfn, addr, it.level-1,
- true, direct_access, it.sptep);
- link_shadow_page(it.sptep, sp, PT_GUEST_ACCESSED_MASK);
+ true, direct_access);
+ link_shadow_page(vcpu, it.sptep, sp);
}
clear_sp_write_flooding_count(it.sptep);
- mmu_set_spte(vcpu, it.sptep, gw->pte_access, write_fault, &emulate,
- it.level, gw->gfn, pfn, prefault, map_writable);
+ emulate = mmu_set_spte(vcpu, it.sptep, gw->pte_access, write_fault,
+ it.level, gw->gfn, pfn, prefault, map_writable);
FNAME(pte_prefetch)(vcpu, gw, it.sptep);
return emulate;
out_gpte_changed:
- if (sp)
- kvm_mmu_put_page(sp, it.sptep);
kvm_release_pfn_clean(pfn);
return 0;
}
@@ -696,33 +697,25 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
int user_fault = error_code & PFERR_USER_MASK;
struct guest_walker walker;
int r;
- pfn_t pfn;
+ kvm_pfn_t pfn;
int level = PT_PAGE_TABLE_LEVEL;
- int force_pt_level;
+ bool force_pt_level = false;
unsigned long mmu_seq;
bool map_writable, is_self_change_mapping;
pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
- if (unlikely(error_code & PFERR_RSVD_MASK)) {
- r = handle_mmio_page_fault(vcpu, addr, error_code,
- mmu_is_nested(vcpu));
- if (likely(r != RET_MMIO_PF_INVALID))
- return r;
-
- /*
- * page fault with PFEC.RSVD = 1 is caused by shadow
- * page fault, should not be used to walk guest page
- * table.
- */
- error_code &= ~PFERR_RSVD_MASK;
- };
-
r = mmu_topup_memory_caches(vcpu);
if (r)
return r;
/*
+ * If PFEC.RSVD is set, this is a shadow page fault.
+ * The bit needs to be cleared before walking guest page tables.
+ */
+ error_code &= ~PFERR_RSVD_MASK;
+
+ /*
* Look up the guest pte for the faulting address.
*/
r = FNAME(walk_addr)(&walker, vcpu, addr, error_code);
@@ -738,20 +731,24 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
return 0;
}
+ if (page_fault_handle_page_track(vcpu, error_code, walker.gfn)) {
+ shadow_page_table_clear_flood(vcpu, addr);
+ return 1;
+ }
+
vcpu->arch.write_fault_to_shadow_pgtable = false;
is_self_change_mapping = FNAME(is_self_change_mapping)(vcpu,
&walker, user_fault, &vcpu->arch.write_fault_to_shadow_pgtable);
- if (walker.level >= PT_DIRECTORY_LEVEL)
- force_pt_level = mapping_level_dirty_bitmap(vcpu, walker.gfn)
- || is_self_change_mapping;
- else
- force_pt_level = 1;
- if (!force_pt_level) {
- level = min(walker.level, mapping_level(vcpu, walker.gfn));
- walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
- }
+ if (walker.level >= PT_DIRECTORY_LEVEL && !is_self_change_mapping) {
+ level = mapping_level(vcpu, walker.gfn, &force_pt_level);
+ if (likely(!force_pt_level)) {
+ level = min(walker.level, level);
+ walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
+ }
+ } else
+ force_pt_level = true;
mmu_seq = vcpu->kvm->mmu_notifier_seq;
smp_rmb();
@@ -949,7 +946,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
if (kvm_vcpu_read_guest_atomic(vcpu, pte_gpa, &gpte,
sizeof(pt_element_t)))
- return -EINVAL;
+ return 0;
if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) {
vcpu->kvm->tlbs_dirty++;
@@ -981,7 +978,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
host_writable);
}
- return !nr_present;
+ return nr_present;
}
#undef pt_element_t
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 31aa2c8..06ce377 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -257,7 +257,7 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
{
- if (vcpu->arch.apic)
+ if (lapic_in_kernel(vcpu))
kvm_apic_local_deliver(vcpu->arch.apic, APIC_LVTPC);
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2f9ed1f..9507038 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
MSR_FS_BASE,
#endif
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
+ MSR_TSC_AUX,
};
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
@@ -135,6 +136,7 @@ struct vcpu_svm {
uint64_t asid_generation;
uint64_t sysenter_esp;
uint64_t sysenter_eip;
+ uint64_t tsc_aux;
u64 next_rip;
@@ -158,7 +160,8 @@ struct vcpu_svm {
unsigned long int3_rip;
u32 apf_reason;
- u64 tsc_ratio;
+ /* cached guest cpuid flags for faster access */
+ bool nrips_enabled : 1;
};
static DEFINE_PER_CPU(u64, current_tsc_ratio);
@@ -211,7 +214,6 @@ static int nested_svm_intercept(struct vcpu_svm *svm);
static int nested_svm_vmexit(struct vcpu_svm *svm);
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code);
-static u64 __scale_tsc(u64 ratio, u64 tsc);
enum {
VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
@@ -891,20 +893,9 @@ static __init int svm_hardware_setup(void)
kvm_enable_efer_bits(EFER_FFXSR);
if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
- u64 max;
-
kvm_has_tsc_control = true;
-
- /*
- * Make sure the user can only configure tsc_khz values that
- * fit into a signed integer.
- * A min value is not calculated needed because it will always
- * be 1 on all machines and a value of 0 is used to disable
- * tsc-scaling for the vcpu.
- */
- max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
-
- kvm_max_guest_tsc_khz = max;
+ kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
+ kvm_tsc_scaling_ratio_frac_bits = 32;
}
if (nested) {
@@ -968,68 +959,6 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
seg->base = 0;
}
-static u64 __scale_tsc(u64 ratio, u64 tsc)
-{
- u64 mult, frac, _tsc;
-
- mult = ratio >> 32;
- frac = ratio & ((1ULL << 32) - 1);
-
- _tsc = tsc;
- _tsc *= mult;
- _tsc += (tsc >> 32) * frac;
- _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
-
- return _tsc;
-}
-
-static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
- u64 _tsc = tsc;
-
- if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
- _tsc = __scale_tsc(svm->tsc_ratio, tsc);
-
- return _tsc;
-}
-
-static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
- u64 ratio;
- u64 khz;
-
- /* Guest TSC same frequency as host TSC? */
- if (!scale) {
- svm->tsc_ratio = TSC_RATIO_DEFAULT;
- return;
- }
-
- /* TSC scaling supported? */
- if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
- if (user_tsc_khz > tsc_khz) {
- vcpu->arch.tsc_catchup = 1;
- vcpu->arch.tsc_always_catchup = 1;
- } else
- WARN(1, "user requested TSC rate below hardware speed\n");
- return;
- }
-
- khz = user_tsc_khz;
-
- /* TSC scaling required - calculate ratio */
- ratio = khz << 32;
- do_div(ratio, tsc_khz);
-
- if (ratio == 0 || ratio & TSC_RATIO_RSVD) {
- WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n",
- user_tsc_khz);
- return;
- }
- svm->tsc_ratio = ratio;
-}
-
static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1056,16 +985,10 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
}
-static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
+static void svm_adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, s64 adjustment)
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (host) {
- if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
- WARN_ON(adjustment < 0);
- adjustment = svm_scale_tsc(vcpu, (u64)adjustment);
- }
-
svm->vmcb->control.tsc_offset += adjustment;
if (is_guest_mode(vcpu))
svm->nested.hsave->control.tsc_offset += adjustment;
@@ -1077,16 +1000,7 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
}
-static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
- u64 tsc;
-
- tsc = svm_scale_tsc(vcpu, rdtsc());
-
- return target_tsc - tsc;
-}
-
-static void init_vmcb(struct vcpu_svm *svm, bool init_event)
+static void init_vmcb(struct vcpu_svm *svm)
{
struct vmcb_control_area *control = &svm->vmcb->control;
struct vmcb_save_area *save = &svm->vmcb->save;
@@ -1107,6 +1021,8 @@ static void init_vmcb(struct vcpu_svm *svm, bool init_event)
set_exception_intercept(svm, PF_VECTOR);
set_exception_intercept(svm, UD_VECTOR);
set_exception_intercept(svm, MC_VECTOR);
+ set_exception_intercept(svm, AC_VECTOR);
+ set_exception_intercept(svm, DB_VECTOR);
set_intercept(svm, INTERCEPT_INTR);
set_intercept(svm, INTERCEPT_NMI);
@@ -1157,8 +1073,7 @@ static void init_vmcb(struct vcpu_svm *svm, bool init_event)
init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
- if (!init_event)
- svm_set_efer(&svm->vcpu, 0);
+ svm_set_efer(&svm->vcpu, 0);
save->dr6 = 0xffff0ff0;
kvm_set_rflags(&svm->vcpu, 2);
save->rip = 0x0000fff0;
@@ -1212,7 +1127,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
if (kvm_vcpu_is_reset_bsp(&svm->vcpu))
svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
}
- init_vmcb(svm, init_event);
+ init_vmcb(svm);
kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy);
kvm_register_write(vcpu, VCPU_REGS_RDX, eax);
@@ -1233,8 +1148,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
goto out;
}
- svm->tsc_ratio = TSC_RATIO_DEFAULT;
-
err = kvm_vcpu_init(&svm->vcpu, kvm, id);
if (err)
goto free_svm;
@@ -1268,7 +1181,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
clear_page(svm->vmcb);
svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
svm->asid_generation = 0;
- init_vmcb(svm, false);
+ init_vmcb(svm);
svm_init_osvw(&svm->vcpu);
@@ -1320,11 +1233,16 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
- if (static_cpu_has(X86_FEATURE_TSCRATEMSR) &&
- svm->tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
- __this_cpu_write(current_tsc_ratio, svm->tsc_ratio);
- wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_ratio);
+ if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+ u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
+ if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
+ __this_cpu_write(current_tsc_ratio, tsc_ratio);
+ wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
+ }
}
+ /* This assumes that the kernel never uses MSR_TSC_AUX */
+ if (static_cpu_has(X86_FEATURE_RDTSCP))
+ wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
}
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
@@ -1642,20 +1560,13 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
mark_dirty(svm->vmcb, VMCB_SEG);
}
-static void update_db_bp_intercept(struct kvm_vcpu *vcpu)
+static void update_bp_intercept(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- clr_exception_intercept(svm, DB_VECTOR);
clr_exception_intercept(svm, BP_VECTOR);
- if (svm->nmi_singlestep)
- set_exception_intercept(svm, DB_VECTOR);
-
if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
- if (vcpu->guest_debug &
- (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
- set_exception_intercept(svm, DB_VECTOR);
if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
set_exception_intercept(svm, BP_VECTOR);
} else
@@ -1761,7 +1672,6 @@ static int db_interception(struct vcpu_svm *svm)
if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
svm->vmcb->save.rflags &=
~(X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_bp_intercept(&svm->vcpu);
}
if (svm->vcpu.guest_debug &
@@ -1796,6 +1706,12 @@ static int ud_interception(struct vcpu_svm *svm)
return 1;
}
+static int ac_interception(struct vcpu_svm *svm)
+{
+ kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0);
+ return 1;
+}
+
static void svm_fpu_activate(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1890,7 +1806,7 @@ static int shutdown_interception(struct vcpu_svm *svm)
* so reinitialize it.
*/
clear_page(svm->vmcb);
- init_vmcb(svm, false);
+ init_vmcb(svm);
kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
return 0;
@@ -1942,8 +1858,7 @@ static int halt_interception(struct vcpu_svm *svm)
static int vmmcall_interception(struct vcpu_svm *svm)
{
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
- kvm_emulate_hypercall(&svm->vcpu);
- return 1;
+ return kvm_emulate_hypercall(&svm->vcpu);
}
static unsigned long nested_svm_get_tdp_cr3(struct kvm_vcpu *vcpu)
@@ -2365,7 +2280,9 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2;
nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info;
nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err;
- nested_vmcb->control.next_rip = vmcb->control.next_rip;
+
+ if (svm->nrips_enabled)
+ nested_vmcb->control.next_rip = vmcb->control.next_rip;
/*
* If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have
@@ -3060,7 +2977,7 @@ static int cr8_write_interception(struct vcpu_svm *svm)
u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
/* instruction emulation calls kvm_set_cr8() */
r = cr_interception(svm);
- if (irqchip_in_kernel(svm->vcpu.kvm))
+ if (lapic_in_kernel(&svm->vcpu))
return r;
if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
return r;
@@ -3071,8 +2988,7 @@ static int cr8_write_interception(struct vcpu_svm *svm)
static u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
{
struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu));
- return vmcb->control.tsc_offset +
- svm_scale_tsc(vcpu, host_tsc);
+ return vmcb->control.tsc_offset + host_tsc;
}
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
@@ -3082,7 +2998,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
switch (msr_info->index) {
case MSR_IA32_TSC: {
msr_info->data = svm->vmcb->control.tsc_offset +
- svm_scale_tsc(vcpu, rdtsc());
+ kvm_scale_tsc(vcpu, rdtsc());
break;
}
@@ -3112,6 +3028,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_SYSENTER_ESP:
msr_info->data = svm->sysenter_esp;
break;
+ case MSR_TSC_AUX:
+ if (!boot_cpu_has(X86_FEATURE_RDTSCP))
+ return 1;
+ msr_info->data = svm->tsc_aux;
+ break;
/*
* Nobody will change the following 5 values in the VMCB so we can
* safely return them on rdmsr. They will always be 0 until LBRV is
@@ -3141,6 +3062,23 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_UCODE_REV:
msr_info->data = 0x01000065;
break;
+ case MSR_F15H_IC_CFG: {
+
+ int family, model;
+
+ family = guest_cpuid_family(vcpu);
+ model = guest_cpuid_model(vcpu);
+
+ if (family < 0 || model < 0)
+ return kvm_get_msr_common(vcpu, msr_info);
+
+ msr_info->data = 0;
+
+ if (family == 0x15 &&
+ (model >= 0x2 && model < 0x20))
+ msr_info->data = 0x1E;
+ }
+ break;
default:
return kvm_get_msr_common(vcpu, msr_info);
}
@@ -3233,6 +3171,18 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
svm->sysenter_esp = data;
svm->vmcb->save.sysenter_esp = data;
break;
+ case MSR_TSC_AUX:
+ if (!boot_cpu_has(X86_FEATURE_RDTSCP))
+ return 1;
+
+ /*
+ * This is rare, so we update the MSR here instead of using
+ * direct_access_msrs. Doing that would require a rdmsr in
+ * svm_vcpu_put.
+ */
+ svm->tsc_aux = data;
+ wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
+ break;
case MSR_IA32_DEBUGCTLMSR:
if (!boot_cpu_has(X86_FEATURE_LBRV)) {
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
@@ -3294,24 +3244,11 @@ static int msr_interception(struct vcpu_svm *svm)
static int interrupt_window_interception(struct vcpu_svm *svm)
{
- struct kvm_run *kvm_run = svm->vcpu.run;
-
kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
svm_clear_vintr(svm);
svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
mark_dirty(svm->vmcb, VMCB_INTR);
++svm->vcpu.stat.irq_window_exits;
- /*
- * If the user space waits to inject interrupts, exit as soon as
- * possible
- */
- if (!irqchip_in_kernel(svm->vcpu.kvm) &&
- kvm_run->request_interrupt_window &&
- !kvm_cpu_has_interrupt(&svm->vcpu)) {
- kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
- return 0;
- }
-
return 1;
}
@@ -3371,6 +3308,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception,
[SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception,
[SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception,
+ [SVM_EXIT_EXCP_BASE + AC_VECTOR] = ac_interception,
[SVM_EXIT_INTR] = intr_interception,
[SVM_EXIT_NMI] = nmi_interception,
[SVM_EXIT_SMI] = nop_on_interception,
@@ -3522,6 +3460,8 @@ static int handle_exit(struct kvm_vcpu *vcpu)
struct kvm_run *kvm_run = vcpu->run;
u32 exit_code = svm->vmcb->control.exit_code;
+ trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM);
+
if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE))
vcpu->arch.cr0 = svm->vmcb->save.cr0;
if (npt_enabled)
@@ -3659,9 +3599,13 @@ static void svm_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
return;
}
-static int svm_vm_has_apicv(struct kvm *kvm)
+static bool svm_get_enable_apicv(void)
+{
+ return false;
+}
+
+static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
{
- return 0;
}
static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
@@ -3754,7 +3698,6 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
*/
svm->nmi_singlestep = true;
svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_bp_intercept(vcpu);
}
static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -3993,8 +3936,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
- trace_kvm_exit(svm->vmcb->control.exit_code, vcpu, KVM_ISA_SVM);
-
if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
kvm_before_handle_nmi(&svm->vcpu);
@@ -4098,6 +4039,10 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
static void svm_cpuid_update(struct kvm_vcpu *vcpu)
{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ /* Update nrips enabled cache */
+ svm->nrips_enabled = !!guest_cpuid_has_nrips(&svm->vcpu);
}
static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
@@ -4134,7 +4079,7 @@ static int svm_get_lpage_level(void)
static bool svm_rdtscp_supported(void)
{
- return false;
+ return boot_cpu_has(X86_FEATURE_RDTSCP);
}
static bool svm_invpcid_supported(void)
@@ -4376,7 +4321,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
- .update_db_bp_intercept = update_db_bp_intercept,
+ .update_bp_intercept = update_bp_intercept,
.get_msr = svm_get_msr,
.set_msr = svm_set_msr,
.get_segment_base = svm_get_segment_base,
@@ -4425,7 +4370,8 @@ static struct kvm_x86_ops svm_x86_ops = {
.enable_irq_window = enable_irq_window,
.update_cr8_intercept = update_cr8_intercept,
.set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode,
- .vm_has_apicv = svm_vm_has_apicv,
+ .get_enable_apicv = svm_get_enable_apicv,
+ .refresh_apicv_exec_ctrl = svm_refresh_apicv_exec_ctrl,
.load_eoi_exitmap = svm_load_eoi_exitmap,
.sync_pir_to_irr = svm_sync_pir_to_irr,
@@ -4448,11 +4394,9 @@ static struct kvm_x86_ops svm_x86_ops = {
.has_wbinvd_exit = svm_has_wbinvd_exit,
- .set_tsc_khz = svm_set_tsc_khz,
.read_tsc_offset = svm_read_tsc_offset,
.write_tsc_offset = svm_write_tsc_offset,
- .adjust_tsc_offset = svm_adjust_tsc_offset,
- .compute_tsc_offset = svm_compute_tsc_offset,
+ .adjust_tsc_offset_guest = svm_adjust_tsc_offset_guest,
.read_l1_tsc = svm_read_l1_tsc,
.set_tdp_cr3 = set_tdp_cr3,
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 4eae7c3..2f1ea2f 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -129,6 +129,24 @@ TRACE_EVENT(kvm_pio,
);
/*
+ * Tracepoint for fast mmio.
+ */
+TRACE_EVENT(kvm_fast_mmio,
+ TP_PROTO(u64 gpa),
+ TP_ARGS(gpa),
+
+ TP_STRUCT__entry(
+ __field(u64, gpa)
+ ),
+
+ TP_fast_assign(
+ __entry->gpa = gpa;
+ ),
+
+ TP_printk("fast mmio at gpa 0x%llx", __entry->gpa)
+);
+
+/*
* Tracepoint for cpuid.
*/
TRACE_EVENT(kvm_cpuid,
@@ -250,7 +268,7 @@ TRACE_EVENT(kvm_inj_virq,
#define kvm_trace_sym_exc \
EXS(DE), EXS(DB), EXS(BP), EXS(OF), EXS(BR), EXS(UD), EXS(NM), \
EXS(DF), EXS(TS), EXS(NP), EXS(SS), EXS(GP), EXS(PF), \
- EXS(MF), EXS(MC)
+ EXS(MF), EXS(AC), EXS(MC)
/*
* Tracepoint for kvm interrupt injection:
@@ -974,6 +992,306 @@ TRACE_EVENT(kvm_enter_smm,
__entry->smbase)
);
+/*
+ * Tracepoint for VT-d posted-interrupts.
+ */
+TRACE_EVENT(kvm_pi_irte_update,
+ TP_PROTO(unsigned int host_irq, unsigned int vcpu_id,
+ unsigned int gsi, unsigned int gvec,
+ u64 pi_desc_addr, bool set),
+ TP_ARGS(host_irq, vcpu_id, gsi, gvec, pi_desc_addr, set),
+
+ TP_STRUCT__entry(
+ __field( unsigned int, host_irq )
+ __field( unsigned int, vcpu_id )
+ __field( unsigned int, gsi )
+ __field( unsigned int, gvec )
+ __field( u64, pi_desc_addr )
+ __field( bool, set )
+ ),
+
+ TP_fast_assign(
+ __entry->host_irq = host_irq;
+ __entry->vcpu_id = vcpu_id;
+ __entry->gsi = gsi;
+ __entry->gvec = gvec;
+ __entry->pi_desc_addr = pi_desc_addr;
+ __entry->set = set;
+ ),
+
+ TP_printk("VT-d PI is %s for irq %u, vcpu %u, gsi: 0x%x, "
+ "gvec: 0x%x, pi_desc_addr: 0x%llx",
+ __entry->set ? "enabled and being updated" : "disabled",
+ __entry->host_irq,
+ __entry->vcpu_id,
+ __entry->gsi,
+ __entry->gvec,
+ __entry->pi_desc_addr)
+);
+
+/*
+ * Tracepoint for kvm_hv_notify_acked_sint.
+ */
+TRACE_EVENT(kvm_hv_notify_acked_sint,
+ TP_PROTO(int vcpu_id, u32 sint),
+ TP_ARGS(vcpu_id, sint),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(u32, sint)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->sint = sint;
+ ),
+
+ TP_printk("vcpu_id %d sint %u", __entry->vcpu_id, __entry->sint)
+);
+
+/*
+ * Tracepoint for synic_set_irq.
+ */
+TRACE_EVENT(kvm_hv_synic_set_irq,
+ TP_PROTO(int vcpu_id, u32 sint, int vector, int ret),
+ TP_ARGS(vcpu_id, sint, vector, ret),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(u32, sint)
+ __field(int, vector)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->sint = sint;
+ __entry->vector = vector;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("vcpu_id %d sint %u vector %d ret %d",
+ __entry->vcpu_id, __entry->sint, __entry->vector,
+ __entry->ret)
+);
+
+/*
+ * Tracepoint for kvm_hv_synic_send_eoi.
+ */
+TRACE_EVENT(kvm_hv_synic_send_eoi,
+ TP_PROTO(int vcpu_id, int vector),
+ TP_ARGS(vcpu_id, vector),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(u32, sint)
+ __field(int, vector)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->vector = vector;
+ ),
+
+ TP_printk("vcpu_id %d vector %d", __entry->vcpu_id, __entry->vector)
+);
+
+/*
+ * Tracepoint for synic_set_msr.
+ */
+TRACE_EVENT(kvm_hv_synic_set_msr,
+ TP_PROTO(int vcpu_id, u32 msr, u64 data, bool host),
+ TP_ARGS(vcpu_id, msr, data, host),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(u32, msr)
+ __field(u64, data)
+ __field(bool, host)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->msr = msr;
+ __entry->data = data;
+ __entry->host = host
+ ),
+
+ TP_printk("vcpu_id %d msr 0x%x data 0x%llx host %d",
+ __entry->vcpu_id, __entry->msr, __entry->data, __entry->host)
+);
+
+/*
+ * Tracepoint for stimer_set_config.
+ */
+TRACE_EVENT(kvm_hv_stimer_set_config,
+ TP_PROTO(int vcpu_id, int timer_index, u64 config, bool host),
+ TP_ARGS(vcpu_id, timer_index, config, host),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ __field(u64, config)
+ __field(bool, host)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ __entry->config = config;
+ __entry->host = host;
+ ),
+
+ TP_printk("vcpu_id %d timer %d config 0x%llx host %d",
+ __entry->vcpu_id, __entry->timer_index, __entry->config,
+ __entry->host)
+);
+
+/*
+ * Tracepoint for stimer_set_count.
+ */
+TRACE_EVENT(kvm_hv_stimer_set_count,
+ TP_PROTO(int vcpu_id, int timer_index, u64 count, bool host),
+ TP_ARGS(vcpu_id, timer_index, count, host),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ __field(u64, count)
+ __field(bool, host)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ __entry->count = count;
+ __entry->host = host;
+ ),
+
+ TP_printk("vcpu_id %d timer %d count %llu host %d",
+ __entry->vcpu_id, __entry->timer_index, __entry->count,
+ __entry->host)
+);
+
+/*
+ * Tracepoint for stimer_start(periodic timer case).
+ */
+TRACE_EVENT(kvm_hv_stimer_start_periodic,
+ TP_PROTO(int vcpu_id, int timer_index, u64 time_now, u64 exp_time),
+ TP_ARGS(vcpu_id, timer_index, time_now, exp_time),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ __field(u64, time_now)
+ __field(u64, exp_time)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ __entry->time_now = time_now;
+ __entry->exp_time = exp_time;
+ ),
+
+ TP_printk("vcpu_id %d timer %d time_now %llu exp_time %llu",
+ __entry->vcpu_id, __entry->timer_index, __entry->time_now,
+ __entry->exp_time)
+);
+
+/*
+ * Tracepoint for stimer_start(one-shot timer case).
+ */
+TRACE_EVENT(kvm_hv_stimer_start_one_shot,
+ TP_PROTO(int vcpu_id, int timer_index, u64 time_now, u64 count),
+ TP_ARGS(vcpu_id, timer_index, time_now, count),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ __field(u64, time_now)
+ __field(u64, count)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ __entry->time_now = time_now;
+ __entry->count = count;
+ ),
+
+ TP_printk("vcpu_id %d timer %d time_now %llu count %llu",
+ __entry->vcpu_id, __entry->timer_index, __entry->time_now,
+ __entry->count)
+);
+
+/*
+ * Tracepoint for stimer_timer_callback.
+ */
+TRACE_EVENT(kvm_hv_stimer_callback,
+ TP_PROTO(int vcpu_id, int timer_index),
+ TP_ARGS(vcpu_id, timer_index),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ ),
+
+ TP_printk("vcpu_id %d timer %d",
+ __entry->vcpu_id, __entry->timer_index)
+);
+
+/*
+ * Tracepoint for stimer_expiration.
+ */
+TRACE_EVENT(kvm_hv_stimer_expiration,
+ TP_PROTO(int vcpu_id, int timer_index, int msg_send_result),
+ TP_ARGS(vcpu_id, timer_index, msg_send_result),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ __field(int, msg_send_result)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ __entry->msg_send_result = msg_send_result;
+ ),
+
+ TP_printk("vcpu_id %d timer %d msg send result %d",
+ __entry->vcpu_id, __entry->timer_index,
+ __entry->msg_send_result)
+);
+
+/*
+ * Tracepoint for stimer_cleanup.
+ */
+TRACE_EVENT(kvm_hv_stimer_cleanup,
+ TP_PROTO(int vcpu_id, int timer_index),
+ TP_ARGS(vcpu_id, timer_index),
+
+ TP_STRUCT__entry(
+ __field(int, vcpu_id)
+ __field(int, timer_index)
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_id = vcpu_id;
+ __entry->timer_index = timer_index;
+ ),
+
+ TP_printk("vcpu_id %d timer %d",
+ __entry->vcpu_id, __entry->timer_index)
+);
+
#endif /* _TRACE_KVM_H */
#undef TRACE_INCLUDE_PATH
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 6a8bc64..5e45c27 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -19,6 +19,7 @@
#include "irq.h"
#include "mmu.h"
#include "cpuid.h"
+#include "lapic.h"
#include <linux/kvm_host.h>
#include <linux/module.h>
@@ -35,6 +36,7 @@
#include "kvm_cache_regs.h"
#include "x86.h"
+#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/desc.h>
#include <asm/vmx.h>
@@ -45,6 +47,7 @@
#include <asm/debugreg.h>
#include <asm/kexec.h>
#include <asm/apic.h>
+#include <asm/irq_remapping.h>
#include "trace.h"
#include "pmu.h"
@@ -105,6 +108,8 @@ static u64 __read_mostly host_xss;
static bool __read_mostly enable_pml = 1;
module_param_named(pml, enable_pml, bool, S_IRUGO);
+#define KVM_VMX_TSC_MULTIPLIER_MAX 0xffffffffffffffffULL
+
#define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD)
#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST (X86_CR0_WP | X86_CR0_NE)
#define KVM_VM_CR0_ALWAYS_ON \
@@ -424,6 +429,9 @@ struct nested_vmx {
/* to migrate it to L2 if VM_ENTRY_LOAD_DEBUG_CONTROLS is off */
u64 vmcs01_debugctl;
+ u16 vpid02;
+ u16 last_vpid;
+
u32 nested_vmx_procbased_ctls_low;
u32 nested_vmx_procbased_ctls_high;
u32 nested_vmx_true_procbased_ctls_low;
@@ -440,14 +448,33 @@ struct nested_vmx {
u32 nested_vmx_misc_low;
u32 nested_vmx_misc_high;
u32 nested_vmx_ept_caps;
+ u32 nested_vmx_vpid_caps;
};
#define POSTED_INTR_ON 0
+#define POSTED_INTR_SN 1
+
/* Posted-Interrupt Descriptor */
struct pi_desc {
u32 pir[8]; /* Posted interrupt requested */
- u32 control; /* bit 0 of control is outstanding notification bit */
- u32 rsvd[7];
+ union {
+ struct {
+ /* bit 256 - Outstanding Notification */
+ u16 on : 1,
+ /* bit 257 - Suppress Notification */
+ sn : 1,
+ /* bit 271:258 - Reserved */
+ rsvd_1 : 14;
+ /* bit 279:272 - Notification Vector */
+ u8 nv;
+ /* bit 287:280 - Reserved */
+ u8 rsvd_2;
+ /* bit 319:288 - Notification Destination */
+ u32 ndst;
+ };
+ u64 control;
+ };
+ u32 rsvd[6];
} __aligned(64);
static bool pi_test_and_set_on(struct pi_desc *pi_desc)
@@ -467,6 +494,30 @@ static int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
return test_and_set_bit(vector, (unsigned long *)pi_desc->pir);
}
+static inline void pi_clear_sn(struct pi_desc *pi_desc)
+{
+ return clear_bit(POSTED_INTR_SN,
+ (unsigned long *)&pi_desc->control);
+}
+
+static inline void pi_set_sn(struct pi_desc *pi_desc)
+{
+ return set_bit(POSTED_INTR_SN,
+ (unsigned long *)&pi_desc->control);
+}
+
+static inline int pi_test_on(struct pi_desc *pi_desc)
+{
+ return test_bit(POSTED_INTR_ON,
+ (unsigned long *)&pi_desc->control);
+}
+
+static inline int pi_test_sn(struct pi_desc *pi_desc)
+{
+ return test_bit(POSTED_INTR_SN,
+ (unsigned long *)&pi_desc->control);
+}
+
struct vcpu_vmx {
struct kvm_vcpu vcpu;
unsigned long host_rsp;
@@ -532,8 +583,6 @@ struct vcpu_vmx {
s64 vnmi_blocked_time;
u32 exit_reason;
- bool rdtscp_enabled;
-
/* Posted interrupt descriptor */
struct pi_desc pi_desc;
@@ -547,6 +596,8 @@ struct vcpu_vmx {
/* Support for PML */
#define PML_ENTITY_NUM 512
struct page *pml_pg;
+
+ u64 current_tsc_ratio;
};
enum segment_cache_field {
@@ -563,6 +614,11 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
return container_of(vcpu, struct vcpu_vmx, vcpu);
}
+static struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
+{
+ return &(to_vmx(vcpu)->pi_desc);
+}
+
#define VMCS12_OFFSET(x) offsetof(struct vmcs12, x)
#define FIELD(number, name) [number] = VMCS12_OFFSET(name)
#define FIELD64(number, name) [number] = VMCS12_OFFSET(name), \
@@ -807,9 +863,7 @@ static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu);
static u64 construct_eptp(unsigned long root_hpa);
static void kvm_cpu_vmxon(u64 addr);
static void kvm_cpu_vmxoff(void);
-static bool vmx_mpx_supported(void);
static bool vmx_xsaves_supported(void);
-static int vmx_vm_has_apicv(struct kvm *kvm);
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
static void vmx_set_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
@@ -817,7 +871,6 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
static bool guest_state_valid(struct kvm_vcpu *vcpu);
static u32 vmx_segment_access_rights(struct kvm_segment *var);
-static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
static int alloc_identity_pagetable(struct kvm *kvm);
@@ -831,6 +884,13 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
+/*
+ * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
+ * can find which vCPU should be waken up.
+ */
+static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu);
+static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
+
static unsigned long *vmx_io_bitmap_a;
static unsigned long *vmx_io_bitmap_b;
static unsigned long *vmx_msr_bitmap_legacy;
@@ -902,25 +962,36 @@ static const u32 vmx_msr_index[] = {
MSR_EFER, MSR_TSC_AUX, MSR_STAR,
};
-static inline bool is_page_fault(u32 intr_info)
+static inline bool is_exception_n(u32 intr_info, u8 vector)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
+ (INTR_TYPE_HARD_EXCEPTION | vector | INTR_INFO_VALID_MASK);
+}
+
+static inline bool is_debug(u32 intr_info)
+{
+ return is_exception_n(intr_info, DB_VECTOR);
+}
+
+static inline bool is_breakpoint(u32 intr_info)
+{
+ return is_exception_n(intr_info, BP_VECTOR);
+}
+
+static inline bool is_page_fault(u32 intr_info)
+{
+ return is_exception_n(intr_info, PF_VECTOR);
}
static inline bool is_no_device(u32 intr_info)
{
- return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
- INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
+ return is_exception_n(intr_info, NM_VECTOR);
}
static inline bool is_invalid_opcode(u32 intr_info)
{
- return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
- INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
+ return is_exception_n(intr_info, UD_VECTOR);
}
static inline bool is_external_interrupt(u32 intr_info)
@@ -946,9 +1017,9 @@ static inline bool cpu_has_vmx_tpr_shadow(void)
return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
}
-static inline bool vm_need_tpr_shadow(struct kvm *kvm)
+static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
{
- return (cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm));
+ return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
}
static inline bool cpu_has_secondary_exec_ctrls(void)
@@ -983,7 +1054,8 @@ static inline bool cpu_has_vmx_virtual_intr_delivery(void)
static inline bool cpu_has_vmx_posted_intr(void)
{
- return vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
+ return IS_ENABLED(CONFIG_X86_LOCAL_APIC) &&
+ vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
}
static inline bool cpu_has_vmx_apicv(void)
@@ -1062,9 +1134,9 @@ static inline bool cpu_has_vmx_ple(void)
SECONDARY_EXEC_PAUSE_LOOP_EXITING;
}
-static inline bool vm_need_virtualize_apic_accesses(struct kvm *kvm)
+static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu)
{
- return flexpriority_enabled && irqchip_in_kernel(kvm);
+ return flexpriority_enabled && lapic_in_kernel(vcpu);
}
static inline bool cpu_has_vmx_vpid(void)
@@ -1113,6 +1185,12 @@ static inline bool cpu_has_vmx_pml(void)
return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
}
+static inline bool cpu_has_vmx_tsc_scaling(void)
+{
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_TSC_SCALING;
+}
+
static inline bool report_flexpriority(void)
{
return flexpriority_enabled;
@@ -1157,6 +1235,11 @@ static inline bool nested_cpu_has_virt_x2apic_mode(struct vmcs12 *vmcs12)
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE);
}
+static inline bool nested_cpu_has_vpid(struct vmcs12 *vmcs12)
+{
+ return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_VPID);
+}
+
static inline bool nested_cpu_has_apic_reg_virt(struct vmcs12 *vmcs12)
{
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_APIC_REGISTER_VIRT);
@@ -1337,13 +1420,13 @@ static void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs)
__loaded_vmcs_clear, loaded_vmcs, 1);
}
-static inline void vpid_sync_vcpu_single(struct vcpu_vmx *vmx)
+static inline void vpid_sync_vcpu_single(int vpid)
{
- if (vmx->vpid == 0)
+ if (vpid == 0)
return;
if (cpu_has_vmx_invvpid_single())
- __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0);
+ __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vpid, 0);
}
static inline void vpid_sync_vcpu_global(void)
@@ -1352,10 +1435,10 @@ static inline void vpid_sync_vcpu_global(void)
__invvpid(VMX_VPID_EXTENT_ALL_CONTEXT, 0, 0);
}
-static inline void vpid_sync_context(struct vcpu_vmx *vmx)
+static inline void vpid_sync_context(int vpid)
{
if (cpu_has_vmx_invvpid_single())
- vpid_sync_vcpu_single(vmx);
+ vpid_sync_vcpu_single(vpid);
else
vpid_sync_vcpu_global();
}
@@ -1376,7 +1459,51 @@ static inline void ept_sync_context(u64 eptp)
}
}
-static __always_inline unsigned long vmcs_readl(unsigned long field)
+static __always_inline void vmcs_check16(unsigned long field)
+{
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
+ "16-bit accessor invalid for 64-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
+ "16-bit accessor invalid for 64-bit high field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
+ "16-bit accessor invalid for 32-bit high field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
+ "16-bit accessor invalid for natural width field");
+}
+
+static __always_inline void vmcs_check32(unsigned long field)
+{
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
+ "32-bit accessor invalid for 16-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
+ "32-bit accessor invalid for natural width field");
+}
+
+static __always_inline void vmcs_check64(unsigned long field)
+{
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
+ "64-bit accessor invalid for 16-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
+ "64-bit accessor invalid for 64-bit high field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
+ "64-bit accessor invalid for 32-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
+ "64-bit accessor invalid for natural width field");
+}
+
+static __always_inline void vmcs_checkl(unsigned long field)
+{
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
+ "Natural width accessor invalid for 16-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
+ "Natural width accessor invalid for 64-bit field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
+ "Natural width accessor invalid for 64-bit high field");
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
+ "Natural width accessor invalid for 32-bit field");
+}
+
+static __always_inline unsigned long __vmcs_readl(unsigned long field)
{
unsigned long value;
@@ -1387,23 +1514,32 @@ static __always_inline unsigned long vmcs_readl(unsigned long field)
static __always_inline u16 vmcs_read16(unsigned long field)
{
- return vmcs_readl(field);
+ vmcs_check16(field);
+ return __vmcs_readl(field);
}
static __always_inline u32 vmcs_read32(unsigned long field)
{
- return vmcs_readl(field);
+ vmcs_check32(field);
+ return __vmcs_readl(field);
}
static __always_inline u64 vmcs_read64(unsigned long field)
{
+ vmcs_check64(field);
#ifdef CONFIG_X86_64
- return vmcs_readl(field);
+ return __vmcs_readl(field);
#else
- return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32);
+ return __vmcs_readl(field) | ((u64)__vmcs_readl(field+1) << 32);
#endif
}
+static __always_inline unsigned long vmcs_readl(unsigned long field)
+{
+ vmcs_checkl(field);
+ return __vmcs_readl(field);
+}
+
static noinline void vmwrite_error(unsigned long field, unsigned long value)
{
printk(KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n",
@@ -1411,7 +1547,7 @@ static noinline void vmwrite_error(unsigned long field, unsigned long value)
dump_stack();
}
-static void vmcs_writel(unsigned long field, unsigned long value)
+static __always_inline void __vmcs_writel(unsigned long field, unsigned long value)
{
u8 error;
@@ -1421,33 +1557,46 @@ static void vmcs_writel(unsigned long field, unsigned long value)
vmwrite_error(field, value);
}
-static void vmcs_write16(unsigned long field, u16 value)
+static __always_inline void vmcs_write16(unsigned long field, u16 value)
{
- vmcs_writel(field, value);
+ vmcs_check16(field);
+ __vmcs_writel(field, value);
}
-static void vmcs_write32(unsigned long field, u32 value)
+static __always_inline void vmcs_write32(unsigned long field, u32 value)
{
- vmcs_writel(field, value);
+ vmcs_check32(field);
+ __vmcs_writel(field, value);
}
-static void vmcs_write64(unsigned long field, u64 value)
+static __always_inline void vmcs_write64(unsigned long field, u64 value)
{
- vmcs_writel(field, value);
+ vmcs_check64(field);
+ __vmcs_writel(field, value);
#ifndef CONFIG_X86_64
asm volatile ("");
- vmcs_writel(field+1, value >> 32);
+ __vmcs_writel(field+1, value >> 32);
#endif
}
-static void vmcs_clear_bits(unsigned long field, u32 mask)
+static __always_inline void vmcs_writel(unsigned long field, unsigned long value)
+{
+ vmcs_checkl(field);
+ __vmcs_writel(field, value);
+}
+
+static __always_inline void vmcs_clear_bits(unsigned long field, u32 mask)
{
- vmcs_writel(field, vmcs_readl(field) & ~mask);
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000,
+ "vmcs_clear_bits does not support 64-bit fields");
+ __vmcs_writel(field, __vmcs_readl(field) & ~mask);
}
-static void vmcs_set_bits(unsigned long field, u32 mask)
+static __always_inline void vmcs_set_bits(unsigned long field, u32 mask)
{
- vmcs_writel(field, vmcs_readl(field) | mask);
+ BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000,
+ "vmcs_set_bits does not support 64-bit fields");
+ __vmcs_writel(field, __vmcs_readl(field) | mask);
}
static inline void vm_entry_controls_init(struct vcpu_vmx *vmx, u32 val)
@@ -1567,7 +1716,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
u32 eb;
eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
- (1u << NM_VECTOR) | (1u << DB_VECTOR);
+ (1u << NM_VECTOR) | (1u << DB_VECTOR) | (1u << AC_VECTOR);
if ((vcpu->guest_debug &
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
@@ -1674,6 +1823,13 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
return;
}
break;
+ case MSR_IA32_PEBS_ENABLE:
+ /* PEBS needs a quiescent period after being disabled (to write
+ * a record). Disabling PEBS through VMX MSR swapping doesn't
+ * provide that period, so a CPU could write host's record into
+ * guest's memory.
+ */
+ wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
}
for (i = 0; i < m->nr; ++i)
@@ -1711,26 +1867,31 @@ static void reload_tss(void)
static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
{
- u64 guest_efer;
- u64 ignore_bits;
+ u64 guest_efer = vmx->vcpu.arch.efer;
+ u64 ignore_bits = 0;
- guest_efer = vmx->vcpu.arch.efer;
+ if (!enable_ept) {
+ /*
+ * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing
+ * host CPUID is more efficient than testing guest CPUID
+ * or CR4. Host SMEP is anyway a requirement for guest SMEP.
+ */
+ if (boot_cpu_has(X86_FEATURE_SMEP))
+ guest_efer |= EFER_NX;
+ else if (!(guest_efer & EFER_NX))
+ ignore_bits |= EFER_NX;
+ }
/*
- * NX is emulated; LMA and LME handled by hardware; SCE meaningless
- * outside long mode
+ * LMA and LME handled by hardware; SCE meaningless outside long mode.
*/
- ignore_bits = EFER_NX | EFER_SCE;
+ ignore_bits |= EFER_SCE;
#ifdef CONFIG_X86_64
ignore_bits |= EFER_LMA | EFER_LME;
/* SCE is meaningful only in long mode on Intel */
if (guest_efer & EFER_LMA)
ignore_bits &= ~(u64)EFER_SCE;
#endif
- guest_efer &= ~ignore_bits;
- guest_efer |= host_efer & ignore_bits;
- vmx->guest_msrs[efer_offset].data = guest_efer;
- vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
clear_atomic_switch_msr(vmx, MSR_EFER);
@@ -1741,16 +1902,21 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
*/
if (cpu_has_load_ia32_efer ||
(enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
- guest_efer = vmx->vcpu.arch.efer;
if (!(guest_efer & EFER_LMA))
guest_efer &= ~EFER_LME;
if (guest_efer != host_efer)
add_atomic_switch_msr(vmx, MSR_EFER,
guest_efer, host_efer);
return false;
- }
+ } else {
+ guest_efer &= ~ignore_bits;
+ guest_efer |= host_efer & ignore_bits;
- return true;
+ vmx->guest_msrs[efer_offset].data = guest_efer;
+ vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
+
+ return true;
+ }
}
static unsigned long segment_base(u16 selector)
@@ -1895,6 +2061,52 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
preempt_enable();
}
+static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
+{
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+ struct pi_desc old, new;
+ unsigned int dest;
+
+ if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+ !irq_remapping_cap(IRQ_POSTING_CAP))
+ return;
+
+ do {
+ old.control = new.control = pi_desc->control;
+
+ /*
+ * If 'nv' field is POSTED_INTR_WAKEUP_VECTOR, there
+ * are two possible cases:
+ * 1. After running 'pre_block', context switch
+ * happened. For this case, 'sn' was set in
+ * vmx_vcpu_put(), so we need to clear it here.
+ * 2. After running 'pre_block', we were blocked,
+ * and woken up by some other guy. For this case,
+ * we don't need to do anything, 'pi_post_block'
+ * will do everything for us. However, we cannot
+ * check whether it is case #1 or case #2 here
+ * (maybe, not needed), so we also clear sn here,
+ * I think it is not a big deal.
+ */
+ if (pi_desc->nv != POSTED_INTR_WAKEUP_VECTOR) {
+ if (vcpu->cpu != cpu) {
+ dest = cpu_physical_id(cpu);
+
+ if (x2apic_enabled())
+ new.ndst = dest;
+ else
+ new.ndst = (dest << 8) & 0xFF00;
+ }
+
+ /* set 'NV' to 'notification vector' */
+ new.nv = POSTED_INTR_VECTOR;
+ }
+
+ /* Allow posting non-urgent interrupts */
+ new.sn = 0;
+ } while (cmpxchg(&pi_desc->control, old.control,
+ new.control) != old.control);
+}
/*
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
* vcpu mutex is already taken.
@@ -1943,12 +2155,37 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
+
vmx->loaded_vmcs->cpu = cpu;
}
+
+ /* Setup TSC multiplier */
+ if (kvm_has_tsc_control &&
+ vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
+ vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
+ vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
+ }
+
+ vmx_vcpu_pi_load(vcpu, cpu);
+}
+
+static void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu)
+{
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+
+ if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+ !irq_remapping_cap(IRQ_POSTING_CAP))
+ return;
+
+ /* Set SN when the vCPU is preempted */
+ if (vcpu->preempted)
+ pi_set_sn(pi_desc);
}
static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
{
+ vmx_vcpu_pi_put(vcpu);
+
__vmx_load_host_state(to_vmx(vcpu));
if (!vmm_exclusive) {
__loaded_vmcs_clear(to_vmx(vcpu)->loaded_vmcs);
@@ -2207,7 +2444,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
if (index >= 0)
move_msr_up(vmx, index, save_nmsrs++);
index = __find_msr_index(vmx, MSR_TSC_AUX);
- if (index >= 0 && vmx->rdtscp_enabled)
+ if (index >= 0 && guest_cpuid_has_rdtscp(&vmx->vcpu))
move_msr_up(vmx, index, save_nmsrs++);
/*
* MSR_STAR is only needed on long mode guests, and only
@@ -2230,15 +2467,16 @@ static void setup_msrs(struct vcpu_vmx *vmx)
/*
* reads and returns guest's timestamp counter "register"
- * guest_tsc = host_tsc + tsc_offset -- 21.3
+ * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
+ * -- Intel TSC Scaling for Virtualization White Paper, sec 1.3
*/
-static u64 guest_read_tsc(void)
+static u64 guest_read_tsc(struct kvm_vcpu *vcpu)
{
u64 host_tsc, tsc_offset;
host_tsc = rdtsc();
tsc_offset = vmcs_read64(TSC_OFFSET);
- return host_tsc + tsc_offset;
+ return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset;
}
/*
@@ -2255,22 +2493,6 @@ static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
return host_tsc + tsc_offset;
}
-/*
- * Engage any workarounds for mis-matched TSC rates. Currently limited to
- * software catchup for faster rates on slower CPUs.
- */
-static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
- if (!scale)
- return;
-
- if (user_tsc_khz > tsc_khz) {
- vcpu->arch.tsc_catchup = 1;
- vcpu->arch.tsc_always_catchup = 1;
- } else
- WARN(1, "user requested TSC rate below hardware speed\n");
-}
-
static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
{
return vmcs_read64(TSC_OFFSET);
@@ -2302,7 +2524,7 @@ static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
}
}
-static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
+static void vmx_adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, s64 adjustment)
{
u64 offset = vmcs_read64(TSC_OFFSET);
@@ -2315,11 +2537,6 @@ static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
offset + adjustment);
}
-static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
- return target_tsc - rdtsc();
-}
-
static bool guest_cpuid_has_vmx(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 1, 0);
@@ -2377,7 +2594,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
vmx->nested.nested_vmx_pinbased_ctls_high |=
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
PIN_BASED_VMX_PREEMPTION_TIMER;
- if (vmx_vm_has_apicv(vmx->vcpu.kvm))
+ if (kvm_vcpu_apicv_active(&vmx->vcpu))
vmx->nested.nested_vmx_pinbased_ctls_high |=
PIN_BASED_POSTED_INTR;
@@ -2398,7 +2615,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER |
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT;
- if (vmx_mpx_supported())
+ if (kvm_mpx_supported())
vmx->nested.nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS;
/* We support free control of debug control saving. */
@@ -2419,7 +2636,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
VM_ENTRY_LOAD_IA32_PAT;
vmx->nested.nested_vmx_entry_ctls_high |=
(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER);
- if (vmx_mpx_supported())
+ if (kvm_mpx_supported())
vmx->nested.nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS;
/* We support free control of debug control loading. */
@@ -2471,10 +2688,12 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_RDTSCP |
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
+ SECONDARY_EXEC_ENABLE_VPID |
SECONDARY_EXEC_APIC_REGISTER_VIRT |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
SECONDARY_EXEC_WBINVD_EXITING |
- SECONDARY_EXEC_XSAVES;
+ SECONDARY_EXEC_XSAVES |
+ SECONDARY_EXEC_PCOMMIT;
if (enable_ept) {
/* nested EPT: emulate EPT also to L1 */
@@ -2493,6 +2712,12 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
} else
vmx->nested.nested_vmx_ept_caps = 0;
+ if (enable_vpid)
+ vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
+ VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
+ else
+ vmx->nested.nested_vmx_vpid_caps = 0;
+
if (enable_unrestricted_guest)
vmx->nested.nested_vmx_secondary_ctls_high |=
SECONDARY_EXEC_UNRESTRICTED_GUEST;
@@ -2608,7 +2833,8 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
break;
case MSR_IA32_VMX_EPT_VPID_CAP:
/* Currently, no nested vpid support */
- *pdata = vmx->nested.nested_vmx_ept_caps;
+ *pdata = vmx->nested.nested_vmx_ept_caps |
+ ((u64)vmx->nested.nested_vmx_vpid_caps << 32);
break;
default:
return 1;
@@ -2642,7 +2868,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_EFER:
return kvm_get_msr_common(vcpu, msr_info);
case MSR_IA32_TSC:
- msr_info->data = guest_read_tsc();
+ msr_info->data = guest_read_tsc(vcpu);
break;
case MSR_IA32_SYSENTER_CS:
msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
@@ -2654,7 +2880,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = vmcs_readl(GUEST_SYSENTER_ESP);
break;
case MSR_IA32_BNDCFGS:
- if (!vmx_mpx_supported())
+ if (!kvm_mpx_supported())
return 1;
msr_info->data = vmcs_read64(GUEST_BNDCFGS);
break;
@@ -2673,7 +2899,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = vcpu->arch.ia32_xss;
break;
case MSR_TSC_AUX:
- if (!to_vmx(vcpu)->rdtscp_enabled)
+ if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
return 1;
/* Otherwise falls through */
default:
@@ -2731,7 +2957,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
vmcs_writel(GUEST_SYSENTER_ESP, data);
break;
case MSR_IA32_BNDCFGS:
- if (!vmx_mpx_supported())
+ if (!kvm_mpx_supported())
return 1;
vmcs_write64(GUEST_BNDCFGS, data);
break;
@@ -2779,7 +3005,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
clear_atomic_switch_msr(vmx, MSR_IA32_XSS);
break;
case MSR_TSC_AUX:
- if (!vmx->rdtscp_enabled)
+ if (!guest_cpuid_has_rdtscp(vcpu) && !msr_info->host_initiated)
return 1;
/* Check reserved bit, higher 32 bits should be zero */
if ((data >> 32) != 0)
@@ -2874,6 +3100,8 @@ static int hardware_enable(void)
return -EBUSY;
INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
+ INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu));
+ spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
/*
* Now we can enable the vmclear operation in kdump
@@ -3015,7 +3243,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
SECONDARY_EXEC_SHADOW_VMCS |
SECONDARY_EXEC_XSAVES |
- SECONDARY_EXEC_ENABLE_PML;
+ SECONDARY_EXEC_ENABLE_PML |
+ SECONDARY_EXEC_PCOMMIT |
+ SECONDARY_EXEC_TSC_SCALING;
if (adjust_vmx_controls(min2, opt2,
MSR_IA32_VMX_PROCBASED_CTLS2,
&_cpu_based_2nd_exec_control) < 0)
@@ -3200,7 +3430,7 @@ static void init_vmcs_shadow_fields(void)
for (i = j = 0; i < max_shadow_read_write_fields; i++) {
switch (shadow_read_write_fields[i]) {
case GUEST_BNDCFGS:
- if (!vmx_mpx_supported())
+ if (!kvm_mpx_supported())
continue;
break;
default:
@@ -3441,9 +3671,9 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
#endif
-static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
+static inline void __vmx_flush_tlb(struct kvm_vcpu *vcpu, int vpid)
{
- vpid_sync_context(to_vmx(vcpu));
+ vpid_sync_context(vpid);
if (enable_ept) {
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
@@ -3451,6 +3681,11 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
}
}
+static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
+{
+ __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid);
+}
+
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
{
ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
@@ -3644,20 +3879,21 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
if (!is_paging(vcpu)) {
hw_cr4 &= ~X86_CR4_PAE;
hw_cr4 |= X86_CR4_PSE;
- /*
- * SMEP/SMAP is disabled if CPU is in non-paging mode
- * in hardware. However KVM always uses paging mode to
- * emulate guest non-paging mode with TDP.
- * To emulate this behavior, SMEP/SMAP needs to be
- * manually disabled when guest switches to non-paging
- * mode.
- */
- hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
} else if (!(cr4 & X86_CR4_PAE)) {
hw_cr4 &= ~X86_CR4_PAE;
}
}
+ if (!enable_unrestricted_guest && !is_paging(vcpu))
+ /*
+ * SMEP/SMAP is disabled if CPU is in non-paging mode in
+ * hardware. However KVM always uses paging mode without
+ * unrestricted guest.
+ * To emulate this behavior, SMEP/SMAP needs to be manually
+ * disabled when guest switches to non-paging mode.
+ */
+ hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
+
vmcs_writel(CR4_READ_SHADOW, cr4);
vmcs_writel(GUEST_CR4, hw_cr4);
return 0;
@@ -4046,7 +4282,7 @@ out:
static int init_rmode_identity_map(struct kvm *kvm)
{
int i, idx, r = 0;
- pfn_t identity_map_pfn;
+ kvm_pfn_t identity_map_pfn;
u32 tmp;
if (!enable_ept)
@@ -4146,29 +4382,28 @@ static int alloc_identity_pagetable(struct kvm *kvm)
return r;
}
-static void allocate_vpid(struct vcpu_vmx *vmx)
+static int allocate_vpid(void)
{
int vpid;
- vmx->vpid = 0;
if (!enable_vpid)
- return;
+ return 0;
spin_lock(&vmx_vpid_lock);
vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS);
- if (vpid < VMX_NR_VPIDS) {
- vmx->vpid = vpid;
+ if (vpid < VMX_NR_VPIDS)
__set_bit(vpid, vmx_vpid_bitmap);
- }
+ else
+ vpid = 0;
spin_unlock(&vmx_vpid_lock);
+ return vpid;
}
-static void free_vpid(struct vcpu_vmx *vmx)
+static void free_vpid(int vpid)
{
- if (!enable_vpid)
+ if (!enable_vpid || vpid == 0)
return;
spin_lock(&vmx_vpid_lock);
- if (vmx->vpid != 0)
- __clear_bit(vmx->vpid, vmx_vpid_bitmap);
+ __clear_bit(vpid, vmx_vpid_bitmap);
spin_unlock(&vmx_vpid_lock);
}
@@ -4323,9 +4558,9 @@ static void vmx_disable_intercept_msr_write_x2apic(u32 msr)
msr, MSR_TYPE_W);
}
-static int vmx_vm_has_apicv(struct kvm *kvm)
+static bool vmx_get_enable_apicv(void)
{
- return enable_apicv && irqchip_in_kernel(kvm);
+ return enable_apicv;
}
static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
@@ -4369,6 +4604,22 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_SMP
if (vcpu->mode == IN_GUEST_MODE) {
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+ /*
+ * Currently, we don't support urgent interrupt,
+ * all interrupts are recognized as non-urgent
+ * interrupt, so we cannot post interrupts when
+ * 'SN' is set.
+ *
+ * If the vcpu is in guest mode, it means it is
+ * running instead of being scheduled out and
+ * waiting in the run queue, and that's the only
+ * case when 'SN' is set currently, warning if
+ * 'SN' is set.
+ */
+ WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
+
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
POSTED_INTR_VECTOR);
return true;
@@ -4431,11 +4682,6 @@ static void vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
}
-static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu)
-{
- return;
-}
-
/*
* Set up the vmcs's constant host-state fields, i.e., host-state fields that
* will not change in the lifetime of the guest.
@@ -4505,11 +4751,18 @@ static u32 vmx_pin_based_exec_ctrl(struct vcpu_vmx *vmx)
{
u32 pin_based_exec_ctrl = vmcs_config.pin_based_exec_ctrl;
- if (!vmx_vm_has_apicv(vmx->vcpu.kvm))
+ if (!kvm_vcpu_apicv_active(&vmx->vcpu))
pin_based_exec_ctrl &= ~PIN_BASED_POSTED_INTR;
return pin_based_exec_ctrl;
}
+static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+ vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_ctrl(vmx));
+}
+
static u32 vmx_exec_control(struct vcpu_vmx *vmx)
{
u32 exec_control = vmcs_config.cpu_based_exec_ctrl;
@@ -4517,7 +4770,7 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
if (vmx->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)
exec_control &= ~CPU_BASED_MOV_DR_EXITING;
- if (!vm_need_tpr_shadow(vmx->vcpu.kvm)) {
+ if (!cpu_need_tpr_shadow(&vmx->vcpu)) {
exec_control &= ~CPU_BASED_TPR_SHADOW;
#ifdef CONFIG_X86_64
exec_control |= CPU_BASED_CR8_STORE_EXITING |
@@ -4534,7 +4787,7 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
{
u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl;
- if (!vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
+ if (!cpu_need_virtualize_apic_accesses(&vmx->vcpu))
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
if (vmx->vpid == 0)
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
@@ -4548,7 +4801,7 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
if (!ple_gap)
exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
- if (!vmx_vm_has_apicv(vmx->vcpu.kvm))
+ if (!kvm_vcpu_apicv_active(&vmx->vcpu))
exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
@@ -4558,8 +4811,12 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
a current VMCS12
*/
exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS;
- /* PML is enabled/disabled in creating/destorying vcpu */
- exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
+
+ if (!enable_pml)
+ exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
+
+ /* Currently, we allow L1 guest to directly run pcommit instruction. */
+ exec_control &= ~SECONDARY_EXEC_PCOMMIT;
return exec_control;
}
@@ -4604,12 +4861,11 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx));
- if (cpu_has_secondary_exec_ctrls()) {
+ if (cpu_has_secondary_exec_ctrls())
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
vmx_secondary_exec_control(vmx));
- }
- if (vmx_vm_has_apicv(vmx->vcpu.kvm)) {
+ if (kvm_vcpu_apicv_active(&vmx->vcpu)) {
vmcs_write64(EOI_EXIT_BITMAP0, 0);
vmcs_write64(EOI_EXIT_BITMAP1, 0);
vmcs_write64(EOI_EXIT_BITMAP2, 0);
@@ -4617,7 +4873,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_write16(GUEST_INTR_STATUS, 0);
- vmcs_write64(POSTED_INTR_NV, POSTED_INTR_VECTOR);
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
vmcs_write64(POSTED_INTR_DESC_ADDR, __pa((&vmx->pi_desc)));
}
@@ -4709,7 +4965,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
seg_setup(VCPU_SREG_CS);
vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
- vmcs_write32(GUEST_CS_BASE, 0xffff0000);
+ vmcs_writel(GUEST_CS_BASE, 0xffff0000ul);
seg_setup(VCPU_SREG_DS);
seg_setup(VCPU_SREG_ES);
@@ -4745,7 +5001,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
- vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
+ vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0);
setup_msrs(vmx);
@@ -4753,7 +5009,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
if (cpu_has_vmx_tpr_shadow() && !init_event) {
vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0);
- if (vm_need_tpr_shadow(vcpu->kvm))
+ if (cpu_need_tpr_shadow(vcpu))
vmcs_write64(VIRTUAL_APIC_PAGE_ADDR,
__pa(vcpu->arch.apic->regs));
vmcs_write32(TPR_THRESHOLD, 0);
@@ -4761,7 +5017,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
- if (vmx_vm_has_apicv(vcpu->kvm))
+ if (kvm_vcpu_apicv_active(vcpu))
memset(&vmx->pi_desc, 0, sizeof(struct pi_desc));
if (vmx->vpid != 0)
@@ -4771,12 +5027,11 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
vmx_set_cr0(vcpu, cr0); /* enter rmode */
vmx->vcpu.arch.cr0 = cr0;
vmx_set_cr4(vcpu, 0);
- if (!init_event)
- vmx_set_efer(vcpu, 0);
+ vmx_set_efer(vcpu, 0);
vmx_fpu_activate(vcpu);
update_exception_bitmap(vcpu);
- vpid_sync_context(vmx);
+ vpid_sync_context(vmx->vpid);
}
/*
@@ -5104,6 +5359,9 @@ static int handle_exception(struct kvm_vcpu *vcpu)
return handle_rmode_exception(vcpu, ex_no, error_code);
switch (ex_no) {
+ case AC_VECTOR:
+ kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
+ return 1;
case DB_VECTOR:
dr6 = vmcs_readl(EXIT_QUALIFICATION);
if (!(vcpu->guest_debug &
@@ -5296,7 +5554,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
u8 cr8 = (u8)val;
err = kvm_set_cr8(vcpu, cr8);
kvm_complete_insn_gp(vcpu, err);
- if (irqchip_in_kernel(vcpu->kvm))
+ if (lapic_in_kernel(vcpu))
return 1;
if (cr8_prev <= cr8)
return 1;
@@ -5381,11 +5639,8 @@ static int handle_dr(struct kvm_vcpu *vcpu)
}
if (vcpu->guest_debug == 0) {
- u32 cpu_based_vm_exec_control;
-
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control &= ~CPU_BASED_MOV_DR_EXITING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL,
+ CPU_BASED_MOV_DR_EXITING);
/*
* No more DR vmexits; force a reload of the debug registers
@@ -5422,8 +5677,6 @@ static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val)
static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
{
- u32 cpu_based_vm_exec_control;
-
get_debugreg(vcpu->arch.db[0], 0);
get_debugreg(vcpu->arch.db[1], 1);
get_debugreg(vcpu->arch.db[2], 2);
@@ -5432,10 +5685,7 @@ static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
vcpu->arch.dr7 = vmcs_readl(GUEST_DR7);
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT;
-
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control |= CPU_BASED_MOV_DR_EXITING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL, CPU_BASED_MOV_DR_EXITING);
}
static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
@@ -5510,17 +5760,6 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
kvm_make_request(KVM_REQ_EVENT, vcpu);
++vcpu->stat.irq_window_exits;
-
- /*
- * If the user space waits to inject interrupts, exit as soon as
- * possible
- */
- if (!irqchip_in_kernel(vcpu->kvm) &&
- vcpu->run->request_interrupt_window &&
- !kvm_cpu_has_interrupt(vcpu)) {
- vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
- return 0;
- }
return 1;
}
@@ -5531,8 +5770,7 @@ static int handle_halt(struct kvm_vcpu *vcpu)
static int handle_vmcall(struct kvm_vcpu *vcpu)
{
- kvm_emulate_hypercall(vcpu);
- return 1;
+ return kvm_emulate_hypercall(vcpu);
}
static int handle_invd(struct kvm_vcpu *vcpu)
@@ -5753,10 +5991,11 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) {
skip_emulated_instruction(vcpu);
+ trace_kvm_fast_mmio(gpa);
return 1;
}
- ret = handle_mmio_page_fault_common(vcpu, gpa, true);
+ ret = handle_mmio_page_fault(vcpu, gpa, true);
if (likely(ret == RET_MMIO_PF_EMULATE))
return x86_emulate_instruction(vcpu, gpa, 0, NULL, 0) ==
EMULATE_DONE;
@@ -5910,6 +6149,25 @@ static void update_ple_window_actual_max(void)
ple_window_grow, INT_MIN);
}
+/*
+ * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
+ */
+static void wakeup_handler(void)
+{
+ struct kvm_vcpu *vcpu;
+ int cpu = smp_processor_id();
+
+ spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
+ list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu),
+ blocked_vcpu_list) {
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+
+ if (pi_test_on(pi_desc) == 1)
+ kvm_vcpu_kick(vcpu);
+ }
+ spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
+}
+
static __init int hardware_setup(void)
{
int r = -ENOMEM, i, msr;
@@ -6028,13 +6286,10 @@ static __init int hardware_setup(void)
if (!cpu_has_vmx_apicv())
enable_apicv = 0;
- if (enable_apicv)
- kvm_x86_ops->update_cr8_intercept = NULL;
- else {
- kvm_x86_ops->hwapic_irr_update = NULL;
- kvm_x86_ops->hwapic_isr_update = NULL;
- kvm_x86_ops->deliver_posted_interrupt = NULL;
- kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
+ if (cpu_has_vmx_tsc_scaling()) {
+ kvm_has_tsc_control = true;
+ kvm_max_tsc_scaling_ratio = KVM_VMX_TSC_MULTIPLIER_MAX;
+ kvm_tsc_scaling_ratio_frac_bits = 48;
}
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
@@ -6096,6 +6351,8 @@ static __init int hardware_setup(void)
kvm_x86_ops->enable_log_dirty_pt_masked = NULL;
}
+ kvm_set_posted_intr_wakeup_handler(wakeup_handler);
+
return alloc_kvm_area();
out8:
@@ -6200,8 +6457,8 @@ static struct loaded_vmcs *nested_get_current_vmcs02(struct vcpu_vmx *vmx)
if (vmx->nested.vmcs02_num >= max(VMCS02_POOL_SIZE, 1)) {
/* Recycle the least recently used VMCS. */
- item = list_entry(vmx->nested.vmcs02_pool.prev,
- struct vmcs02_list, list);
+ item = list_last_entry(&vmx->nested.vmcs02_pool,
+ struct vmcs02_list, list);
item->vmptr = vmx->nested.current_vmptr;
list_move(&item->list, &vmx->nested.vmcs02_pool);
return &item->vmcs02;
@@ -6627,7 +6884,6 @@ static int nested_vmx_check_permission(struct kvm_vcpu *vcpu)
static inline void nested_release_vmcs12(struct vcpu_vmx *vmx)
{
- u32 exec_control;
if (vmx->nested.current_vmptr == -1ull)
return;
@@ -6640,9 +6896,8 @@ static inline void nested_release_vmcs12(struct vcpu_vmx *vmx)
they were modified */
copy_shadow_to_vmcs12(vmx);
vmx->nested.sync_shadow_vmcs = false;
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
+ vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
+ SECONDARY_EXEC_SHADOW_VMCS);
vmcs_write64(VMCS_LINK_POINTER, -1ull);
}
vmx->nested.posted_intr_nv = -1;
@@ -6662,6 +6917,7 @@ static void free_nested(struct vcpu_vmx *vmx)
return;
vmx->nested.vmxon = false;
+ free_vpid(vmx->nested.vpid02);
nested_release_vmcs12(vmx);
if (enable_shadow_vmcs)
free_vmcs(vmx->nested.current_shadow_vmcs);
@@ -7038,7 +7294,6 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
gpa_t vmptr;
- u32 exec_control;
if (!nested_vmx_check_permission(vcpu))
return 1;
@@ -7070,9 +7325,8 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
vmx->nested.current_vmcs12 = new_vmcs12;
vmx->nested.current_vmcs12_page = page;
if (enable_shadow_vmcs) {
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control |= SECONDARY_EXEC_SHADOW_VMCS;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
+ vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
+ SECONDARY_EXEC_SHADOW_VMCS);
vmcs_write64(VMCS_LINK_POINTER,
__pa(vmx->nested.current_shadow_vmcs));
vmx->nested.sync_shadow_vmcs = true;
@@ -7178,7 +7432,58 @@ static int handle_invept(struct kvm_vcpu *vcpu)
static int handle_invvpid(struct kvm_vcpu *vcpu)
{
- kvm_queue_exception(vcpu, UD_VECTOR);
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 vmx_instruction_info;
+ unsigned long type, types;
+ gva_t gva;
+ struct x86_exception e;
+ int vpid;
+
+ if (!(vmx->nested.nested_vmx_secondary_ctls_high &
+ SECONDARY_EXEC_ENABLE_VPID) ||
+ !(vmx->nested.nested_vmx_vpid_caps & VMX_VPID_INVVPID_BIT)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 1;
+ }
+
+ if (!nested_vmx_check_permission(vcpu))
+ return 1;
+
+ vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
+ type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
+
+ types = (vmx->nested.nested_vmx_vpid_caps >> 8) & 0x7;
+
+ if (!(types & (1UL << type))) {
+ nested_vmx_failValid(vcpu,
+ VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+ return 1;
+ }
+
+ /* according to the intel vmx instruction reference, the memory
+ * operand is read even if it isn't needed (e.g., for type==global)
+ */
+ if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION),
+ vmx_instruction_info, false, &gva))
+ return 1;
+ if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vpid,
+ sizeof(u32), &e)) {
+ kvm_inject_page_fault(vcpu, &e);
+ return 1;
+ }
+
+ switch (type) {
+ case VMX_VPID_EXTENT_ALL_CONTEXT:
+ __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
+ nested_vmx_succeed(vcpu);
+ break;
+ default:
+ /* Trap single context invalidation invvpid calls */
+ BUG_ON(1);
+ break;
+ }
+
+ skip_emulated_instruction(vcpu);
return 1;
}
@@ -7207,6 +7512,13 @@ static int handle_pml_full(struct kvm_vcpu *vcpu)
return 1;
}
+static int handle_pcommit(struct kvm_vcpu *vcpu)
+{
+ /* we never catch pcommit instruct for L1 guest. */
+ WARN_ON(1);
+ return 1;
+}
+
/*
* The exit handlers return 1 if the exit was handled fully and guest execution
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
@@ -7257,6 +7569,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_XSAVES] = handle_xsaves,
[EXIT_REASON_XRSTORS] = handle_xrstors,
[EXIT_REASON_PML_FULL] = handle_pml_full,
+ [EXIT_REASON_PCOMMIT] = handle_pcommit,
};
static const int kvm_vmx_max_exit_handlers =
@@ -7461,6 +7774,13 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
else if (is_no_device(intr_info) &&
!(vmcs12->guest_cr0 & X86_CR0_TS))
return false;
+ else if (is_debug(intr_info) &&
+ vcpu->guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+ return false;
+ else if (is_breakpoint(intr_info) &&
+ vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+ return false;
return vmcs12->exception_bitmap &
(1u << (intr_info & INTR_INFO_VECTOR_MASK));
case EXIT_REASON_EXTERNAL_INTERRUPT:
@@ -7558,6 +7878,8 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
* the XSS exit bitmap in vmcs12.
*/
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
+ case EXIT_REASON_PCOMMIT:
+ return nested_cpu_has2(vmcs12, SECONDARY_EXEC_PCOMMIT);
default:
return true;
}
@@ -7569,10 +7891,9 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
}
-static int vmx_enable_pml(struct vcpu_vmx *vmx)
+static int vmx_create_pml_buffer(struct vcpu_vmx *vmx)
{
struct page *pml_pg;
- u32 exec_control;
pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!pml_pg)
@@ -7583,24 +7904,15 @@ static int vmx_enable_pml(struct vcpu_vmx *vmx)
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control |= SECONDARY_EXEC_ENABLE_PML;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
-
return 0;
}
-static void vmx_disable_pml(struct vcpu_vmx *vmx)
+static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
{
- u32 exec_control;
-
- ASSERT(vmx->pml_pg);
- __free_page(vmx->pml_pg);
- vmx->pml_pg = NULL;
-
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
+ if (vmx->pml_pg) {
+ __free_page(vmx->pml_pg);
+ vmx->pml_pg = NULL;
+ }
}
static void vmx_flush_pml_buffer(struct kvm_vcpu *vcpu)
@@ -7676,7 +7988,7 @@ static void dump_vmcs(void)
u32 pin_based_exec_ctrl = vmcs_read32(PIN_BASED_VM_EXEC_CONTROL);
u32 secondary_exec_control = 0;
unsigned long cr4 = vmcs_readl(GUEST_CR4);
- u64 efer = vmcs_readl(GUEST_IA32_EFER);
+ u64 efer = vmcs_read64(GUEST_IA32_EFER);
int i, n;
if (cpu_has_secondary_exec_ctrls())
@@ -7692,10 +8004,10 @@ static void dump_vmcs(void)
if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) &&
(cr4 & X86_CR4_PAE) && !(efer & EFER_LMA))
{
- pr_err("PDPTR0 = 0x%016lx PDPTR1 = 0x%016lx\n",
- vmcs_readl(GUEST_PDPTR0), vmcs_readl(GUEST_PDPTR1));
- pr_err("PDPTR2 = 0x%016lx PDPTR3 = 0x%016lx\n",
- vmcs_readl(GUEST_PDPTR2), vmcs_readl(GUEST_PDPTR3));
+ pr_err("PDPTR0 = 0x%016llx PDPTR1 = 0x%016llx\n",
+ vmcs_read64(GUEST_PDPTR0), vmcs_read64(GUEST_PDPTR1));
+ pr_err("PDPTR2 = 0x%016llx PDPTR3 = 0x%016llx\n",
+ vmcs_read64(GUEST_PDPTR2), vmcs_read64(GUEST_PDPTR3));
}
pr_err("RSP = 0x%016lx RIP = 0x%016lx\n",
vmcs_readl(GUEST_RSP), vmcs_readl(GUEST_RIP));
@@ -7716,16 +8028,16 @@ static void dump_vmcs(void)
vmx_dump_sel("TR: ", GUEST_TR_SELECTOR);
if ((vmexit_ctl & (VM_EXIT_SAVE_IA32_PAT | VM_EXIT_SAVE_IA32_EFER)) ||
(vmentry_ctl & (VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_IA32_EFER)))
- pr_err("EFER = 0x%016llx PAT = 0x%016lx\n",
- efer, vmcs_readl(GUEST_IA32_PAT));
- pr_err("DebugCtl = 0x%016lx DebugExceptions = 0x%016lx\n",
- vmcs_readl(GUEST_IA32_DEBUGCTL),
+ pr_err("EFER = 0x%016llx PAT = 0x%016llx\n",
+ efer, vmcs_read64(GUEST_IA32_PAT));
+ pr_err("DebugCtl = 0x%016llx DebugExceptions = 0x%016lx\n",
+ vmcs_read64(GUEST_IA32_DEBUGCTL),
vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS));
if (vmentry_ctl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
- pr_err("PerfGlobCtl = 0x%016lx\n",
- vmcs_readl(GUEST_IA32_PERF_GLOBAL_CTRL));
+ pr_err("PerfGlobCtl = 0x%016llx\n",
+ vmcs_read64(GUEST_IA32_PERF_GLOBAL_CTRL));
if (vmentry_ctl & VM_ENTRY_LOAD_BNDCFGS)
- pr_err("BndCfgS = 0x%016lx\n", vmcs_readl(GUEST_BNDCFGS));
+ pr_err("BndCfgS = 0x%016llx\n", vmcs_read64(GUEST_BNDCFGS));
pr_err("Interruptibility = %08x ActivityState = %08x\n",
vmcs_read32(GUEST_INTERRUPTIBILITY_INFO),
vmcs_read32(GUEST_ACTIVITY_STATE));
@@ -7754,11 +8066,12 @@ static void dump_vmcs(void)
vmcs_read32(HOST_IA32_SYSENTER_CS),
vmcs_readl(HOST_IA32_SYSENTER_EIP));
if (vmexit_ctl & (VM_EXIT_LOAD_IA32_PAT | VM_EXIT_LOAD_IA32_EFER))
- pr_err("EFER = 0x%016lx PAT = 0x%016lx\n",
- vmcs_readl(HOST_IA32_EFER), vmcs_readl(HOST_IA32_PAT));
+ pr_err("EFER = 0x%016llx PAT = 0x%016llx\n",
+ vmcs_read64(HOST_IA32_EFER),
+ vmcs_read64(HOST_IA32_PAT));
if (vmexit_ctl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
- pr_err("PerfGlobCtl = 0x%016lx\n",
- vmcs_readl(HOST_IA32_PERF_GLOBAL_CTRL));
+ pr_err("PerfGlobCtl = 0x%016llx\n",
+ vmcs_read64(HOST_IA32_PERF_GLOBAL_CTRL));
pr_err("*** Control State ***\n");
pr_err("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
@@ -7781,13 +8094,16 @@ static void dump_vmcs(void)
pr_err("IDTVectoring: info=%08x errcode=%08x\n",
vmcs_read32(IDT_VECTORING_INFO_FIELD),
vmcs_read32(IDT_VECTORING_ERROR_CODE));
- pr_err("TSC Offset = 0x%016lx\n", vmcs_readl(TSC_OFFSET));
+ pr_err("TSC Offset = 0x%016llx\n", vmcs_read64(TSC_OFFSET));
+ if (secondary_exec_control & SECONDARY_EXEC_TSC_SCALING)
+ pr_err("TSC Multiplier = 0x%016llx\n",
+ vmcs_read64(TSC_MULTIPLIER));
if (cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW)
pr_err("TPR Threshold = 0x%02x\n", vmcs_read32(TPR_THRESHOLD));
if (pin_based_exec_ctrl & PIN_BASED_POSTED_INTR)
pr_err("PostedIntrVec = 0x%02x\n", vmcs_read16(POSTED_INTR_NV));
if ((secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT))
- pr_err("EPT pointer = 0x%016lx\n", vmcs_readl(EPT_POINTER));
+ pr_err("EPT pointer = 0x%016llx\n", vmcs_read64(EPT_POINTER));
n = vmcs_read32(CR3_TARGET_COUNT);
for (i = 0; i + 1 < n; i += 4)
pr_err("CR3 target%u=%016lx target%u=%016lx\n",
@@ -7814,6 +8130,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
u32 exit_reason = vmx->exit_reason;
u32 vectoring_info = vmx->idt_vectoring_info;
+ trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX);
+
/*
* Flush logged GPAs PML buffer, this will make dirty_bitmap more
* updated. Another good is, in kvm_vm_ioctl_get_dirty_log, before
@@ -7924,10 +8242,10 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
* apicv
*/
if (!cpu_has_vmx_virtualize_x2apic_mode() ||
- !vmx_vm_has_apicv(vcpu->kvm))
+ !kvm_vcpu_apicv_active(vcpu))
return;
- if (!vm_need_tpr_shadow(vcpu->kvm))
+ if (!cpu_need_tpr_shadow(vcpu))
return;
sec_exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
@@ -8031,7 +8349,7 @@ static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
{
- if (!vmx_vm_has_apicv(vcpu->kvm))
+ if (!kvm_vcpu_apicv_active(vcpu))
return;
vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
@@ -8439,7 +8757,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmx->loaded_vmcs->launched = 1;
vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
- trace_kvm_exit(vmx->exit_reason, vcpu, KVM_ISA_VMX);
/*
* the KVM_REQ_EVENT optimization bit is only on for one entry, and if
@@ -8477,8 +8794,8 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
struct vcpu_vmx *vmx = to_vmx(vcpu);
if (enable_pml)
- vmx_disable_pml(vmx);
- free_vpid(vmx);
+ vmx_destroy_pml_buffer(vmx);
+ free_vpid(vmx->vpid);
leave_guest_mode(vcpu);
vmx_load_vmcs01(vcpu);
free_nested(vmx);
@@ -8497,7 +8814,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
if (!vmx)
return ERR_PTR(-ENOMEM);
- allocate_vpid(vmx);
+ vmx->vpid = allocate_vpid();
err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
if (err)
@@ -8530,7 +8847,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
put_cpu();
if (err)
goto free_vmcs;
- if (vm_need_virtualize_apic_accesses(kvm)) {
+ if (cpu_need_virtualize_apic_accesses(&vmx->vcpu)) {
err = alloc_apic_access_page(kvm);
if (err)
goto free_vmcs;
@@ -8545,8 +8862,10 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
goto free_vmcs;
}
- if (nested)
+ if (nested) {
nested_vmx_setup_ctls_msrs(vmx);
+ vmx->nested.vpid02 = allocate_vpid();
+ }
vmx->nested.posted_intr_nv = -1;
vmx->nested.current_vmptr = -1ull;
@@ -8559,7 +8878,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
* for the guest, etc.
*/
if (enable_pml) {
- err = vmx_enable_pml(vmx);
+ err = vmx_create_pml_buffer(vmx);
if (err)
goto free_vmcs;
}
@@ -8567,13 +8886,14 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
return &vmx->vcpu;
free_vmcs:
+ free_vpid(vmx->nested.vpid02);
free_loaded_vmcs(vmx->loaded_vmcs);
free_msrs:
kfree(vmx->guest_msrs);
uninit_vcpu:
kvm_vcpu_uninit(&vmx->vcpu);
free_vcpu:
- free_vpid(vmx);
+ free_vpid(vmx->vpid);
kmem_cache_free(kvm_vcpu_cache, vmx);
return ERR_PTR(err);
}
@@ -8648,49 +8968,68 @@ static int vmx_get_lpage_level(void)
return PT_PDPE_LEVEL;
}
+static void vmcs_set_secondary_exec_control(u32 new_ctl)
+{
+ /*
+ * These bits in the secondary execution controls field
+ * are dynamic, the others are mostly based on the hypervisor
+ * architecture and the guest's CPUID. Do not touch the
+ * dynamic bits.
+ */
+ u32 mask =
+ SECONDARY_EXEC_SHADOW_VMCS |
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+
+ u32 cur_ctl = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ (new_ctl & ~mask) | (cur_ctl & mask));
+}
+
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 exec_control;
+ u32 secondary_exec_ctl = vmx_secondary_exec_control(vmx);
- vmx->rdtscp_enabled = false;
if (vmx_rdtscp_supported()) {
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- if (exec_control & SECONDARY_EXEC_RDTSCP) {
- best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
- if (best && (best->edx & bit(X86_FEATURE_RDTSCP)))
- vmx->rdtscp_enabled = true;
- else {
- exec_control &= ~SECONDARY_EXEC_RDTSCP;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
- exec_control);
- }
+ bool rdtscp_enabled = guest_cpuid_has_rdtscp(vcpu);
+ if (!rdtscp_enabled)
+ secondary_exec_ctl &= ~SECONDARY_EXEC_RDTSCP;
+
+ if (nested) {
+ if (rdtscp_enabled)
+ vmx->nested.nested_vmx_secondary_ctls_high |=
+ SECONDARY_EXEC_RDTSCP;
+ else
+ vmx->nested.nested_vmx_secondary_ctls_high &=
+ ~SECONDARY_EXEC_RDTSCP;
}
- if (nested && !vmx->rdtscp_enabled)
- vmx->nested.nested_vmx_secondary_ctls_high &=
- ~SECONDARY_EXEC_RDTSCP;
}
/* Exposing INVPCID only when PCID is exposed */
best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
if (vmx_invpcid_supported() &&
- best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
- guest_cpuid_has_pcid(vcpu)) {
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
- exec_control);
- } else {
- if (cpu_has_secondary_exec_ctrls()) {
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
- exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
- exec_control);
- }
+ (!best || !(best->ebx & bit(X86_FEATURE_INVPCID)) ||
+ !guest_cpuid_has_pcid(vcpu))) {
+ secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID;
+
if (best)
best->ebx &= ~bit(X86_FEATURE_INVPCID);
}
+
+ if (cpu_has_secondary_exec_ctrls())
+ vmcs_set_secondary_exec_control(secondary_exec_ctl);
+
+ if (static_cpu_has(X86_FEATURE_PCOMMIT) && nested) {
+ if (guest_cpuid_has_pcommit(vcpu))
+ vmx->nested.nested_vmx_secondary_ctls_high |=
+ SECONDARY_EXEC_PCOMMIT;
+ else
+ vmx->nested.nested_vmx_secondary_ctls_high &=
+ ~SECONDARY_EXEC_PCOMMIT;
+ }
}
static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
@@ -9257,7 +9596,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
*/
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
vmx->nested.pi_pending = false;
- vmcs_write64(POSTED_INTR_NV, POSTED_INTR_VECTOR);
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
vmcs_write64(POSTED_INTR_DESC_ADDR,
page_to_phys(vmx->nested.pi_desc_page) +
(unsigned long)(vmcs12->posted_intr_desc_addr &
@@ -9298,13 +9637,13 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
if (cpu_has_secondary_exec_ctrls()) {
exec_control = vmx_secondary_exec_control(vmx);
- if (!vmx->rdtscp_enabled)
- exec_control &= ~SECONDARY_EXEC_RDTSCP;
+
/* Take the following fields only from vmcs12 */
exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_RDTSCP |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
- SECONDARY_EXEC_APIC_REGISTER_VIRT);
+ SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ SECONDARY_EXEC_PCOMMIT);
if (nested_cpu_has(vmcs12,
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS))
exec_control |= vmcs12->secondary_vm_exec_control;
@@ -9323,7 +9662,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
vmcs_write64(APIC_ACCESS_ADDR,
page_to_phys(vmx->nested.apic_access_page));
} else if (!(nested_cpu_has_virt_x2apic_mode(vmcs12)) &&
- (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))) {
+ cpu_need_virtualize_apic_accesses(&vmx->vcpu)) {
exec_control |=
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
kvm_vcpu_reload_apic_access_page(vcpu);
@@ -9433,12 +9772,24 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
if (enable_vpid) {
/*
- * Trivially support vpid by letting L2s share their parent
- * L1's vpid. TODO: move to a more elaborate solution, giving
- * each L2 its own vpid and exposing the vpid feature to L1.
+ * There is no direct mapping between vpid02 and vpid12, the
+ * vpid02 is per-vCPU for L0 and reused while the value of
+ * vpid12 is changed w/ one invvpid during nested vmentry.
+ * The vpid12 is allocated by L1 for L2, so it will not
+ * influence global bitmap(for vpid01 and vpid02 allocation)
+ * even if spawn a lot of nested vCPUs.
*/
- vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
- vmx_flush_tlb(vcpu);
+ if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02) {
+ vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->nested.vpid02);
+ if (vmcs12->virtual_processor_id != vmx->nested.last_vpid) {
+ vmx->nested.last_vpid = vmcs12->virtual_processor_id;
+ __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
+ }
+ } else {
+ vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
+ vmx_flush_tlb(vcpu);
+ }
+
}
if (nested_cpu_has_ept(vmcs12)) {
@@ -9906,7 +10257,7 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
* Additionally, restore L2's PDPTR to vmcs12.
*/
if (enable_ept) {
- vmcs12->guest_cr3 = vmcs_read64(GUEST_CR3);
+ vmcs12->guest_cr3 = vmcs_readl(GUEST_CR3);
vmcs12->guest_pdptr0 = vmcs_read64(GUEST_PDPTR0);
vmcs12->guest_pdptr1 = vmcs_read64(GUEST_PDPTR1);
vmcs12->guest_pdptr2 = vmcs_read64(GUEST_PDPTR2);
@@ -9934,7 +10285,7 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
- if (vmx_mpx_supported())
+ if (kvm_mpx_supported())
vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
if (nested_cpu_has_xsaves(vmcs12))
vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP);
@@ -10278,6 +10629,214 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm,
kvm_mmu_clear_dirty_pt_masked(kvm, memslot, offset, mask);
}
+/*
+ * This routine does the following things for vCPU which is going
+ * to be blocked if VT-d PI is enabled.
+ * - Store the vCPU to the wakeup list, so when interrupts happen
+ * we can find the right vCPU to wake up.
+ * - Change the Posted-interrupt descriptor as below:
+ * 'NDST' <-- vcpu->pre_pcpu
+ * 'NV' <-- POSTED_INTR_WAKEUP_VECTOR
+ * - If 'ON' is set during this process, which means at least one
+ * interrupt is posted for this vCPU, we cannot block it, in
+ * this case, return 1, otherwise, return 0.
+ *
+ */
+static int vmx_pre_block(struct kvm_vcpu *vcpu)
+{
+ unsigned long flags;
+ unsigned int dest;
+ struct pi_desc old, new;
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+
+ if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+ !irq_remapping_cap(IRQ_POSTING_CAP))
+ return 0;
+
+ vcpu->pre_pcpu = vcpu->cpu;
+ spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+ list_add_tail(&vcpu->blocked_vcpu_list,
+ &per_cpu(blocked_vcpu_on_cpu,
+ vcpu->pre_pcpu));
+ spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+
+ do {
+ old.control = new.control = pi_desc->control;
+
+ /*
+ * We should not block the vCPU if
+ * an interrupt is posted for it.
+ */
+ if (pi_test_on(pi_desc) == 1) {
+ spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+ list_del(&vcpu->blocked_vcpu_list);
+ spin_unlock_irqrestore(
+ &per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+ vcpu->pre_pcpu = -1;
+
+ return 1;
+ }
+
+ WARN((pi_desc->sn == 1),
+ "Warning: SN field of posted-interrupts "
+ "is set before blocking\n");
+
+ /*
+ * Since vCPU can be preempted during this process,
+ * vcpu->cpu could be different with pre_pcpu, we
+ * need to set pre_pcpu as the destination of wakeup
+ * notification event, then we can find the right vCPU
+ * to wakeup in wakeup handler if interrupts happen
+ * when the vCPU is in blocked state.
+ */
+ dest = cpu_physical_id(vcpu->pre_pcpu);
+
+ if (x2apic_enabled())
+ new.ndst = dest;
+ else
+ new.ndst = (dest << 8) & 0xFF00;
+
+ /* set 'NV' to 'wakeup vector' */
+ new.nv = POSTED_INTR_WAKEUP_VECTOR;
+ } while (cmpxchg(&pi_desc->control, old.control,
+ new.control) != old.control);
+
+ return 0;
+}
+
+static void vmx_post_block(struct kvm_vcpu *vcpu)
+{
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+ struct pi_desc old, new;
+ unsigned int dest;
+ unsigned long flags;
+
+ if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+ !irq_remapping_cap(IRQ_POSTING_CAP))
+ return;
+
+ do {
+ old.control = new.control = pi_desc->control;
+
+ dest = cpu_physical_id(vcpu->cpu);
+
+ if (x2apic_enabled())
+ new.ndst = dest;
+ else
+ new.ndst = (dest << 8) & 0xFF00;
+
+ /* Allow posting non-urgent interrupts */
+ new.sn = 0;
+
+ /* set 'NV' to 'notification vector' */
+ new.nv = POSTED_INTR_VECTOR;
+ } while (cmpxchg(&pi_desc->control, old.control,
+ new.control) != old.control);
+
+ if(vcpu->pre_pcpu != -1) {
+ spin_lock_irqsave(
+ &per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+ list_del(&vcpu->blocked_vcpu_list);
+ spin_unlock_irqrestore(
+ &per_cpu(blocked_vcpu_on_cpu_lock,
+ vcpu->pre_pcpu), flags);
+ vcpu->pre_pcpu = -1;
+ }
+}
+
+/*
+ * vmx_update_pi_irte - set IRTE for Posted-Interrupts
+ *
+ * @kvm: kvm
+ * @host_irq: host irq of the interrupt
+ * @guest_irq: gsi of the interrupt
+ * @set: set or unset PI
+ * returns 0 on success, < 0 on failure
+ */
+static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set)
+{
+ struct kvm_kernel_irq_routing_entry *e;
+ struct kvm_irq_routing_table *irq_rt;
+ struct kvm_lapic_irq irq;
+ struct kvm_vcpu *vcpu;
+ struct vcpu_data vcpu_info;
+ int idx, ret = -EINVAL;
+
+ if (!kvm_arch_has_assigned_device(kvm) ||
+ !irq_remapping_cap(IRQ_POSTING_CAP))
+ return 0;
+
+ idx = srcu_read_lock(&kvm->irq_srcu);
+ irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+ BUG_ON(guest_irq >= irq_rt->nr_rt_entries);
+
+ hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) {
+ if (e->type != KVM_IRQ_ROUTING_MSI)
+ continue;
+ /*
+ * VT-d PI cannot support posting multicast/broadcast
+ * interrupts to a vCPU, we still use interrupt remapping
+ * for these kind of interrupts.
+ *
+ * For lowest-priority interrupts, we only support
+ * those with single CPU as the destination, e.g. user
+ * configures the interrupts via /proc/irq or uses
+ * irqbalance to make the interrupts single-CPU.
+ *
+ * We will support full lowest-priority interrupt later.
+ */
+
+ kvm_set_msi_irq(e, &irq);
+ if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu)) {
+ /*
+ * Make sure the IRTE is in remapped mode if
+ * we don't handle it in posted mode.
+ */
+ ret = irq_set_vcpu_affinity(host_irq, NULL);
+ if (ret < 0) {
+ printk(KERN_INFO
+ "failed to back to remapped mode, irq: %u\n",
+ host_irq);
+ goto out;
+ }
+
+ continue;
+ }
+
+ vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
+ vcpu_info.vector = irq.vector;
+
+ trace_kvm_pi_irte_update(vcpu->vcpu_id, host_irq, e->gsi,
+ vcpu_info.vector, vcpu_info.pi_desc_addr, set);
+
+ if (set)
+ ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
+ else {
+ /* suppress notification event before unposting */
+ pi_set_sn(vcpu_to_pi_desc(vcpu));
+ ret = irq_set_vcpu_affinity(host_irq, NULL);
+ pi_clear_sn(vcpu_to_pi_desc(vcpu));
+ }
+
+ if (ret < 0) {
+ printk(KERN_INFO "%s: failed to update PI IRTE\n",
+ __func__);
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
+ srcu_read_unlock(&kvm->irq_srcu, idx);
+ return ret;
+}
+
static struct kvm_x86_ops vmx_x86_ops = {
.cpu_has_kvm_support = cpu_has_kvm_support,
.disabled_by_bios = vmx_disabled_by_bios,
@@ -10297,7 +10856,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
- .update_db_bp_intercept = update_exception_bitmap,
+ .update_bp_intercept = update_exception_bitmap,
.get_msr = vmx_get_msr,
.set_msr = vmx_set_msr,
.get_segment_base = vmx_get_segment_base,
@@ -10347,7 +10906,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
.update_cr8_intercept = update_cr8_intercept,
.set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode,
.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
- .vm_has_apicv = vmx_vm_has_apicv,
+ .get_enable_apicv = vmx_get_enable_apicv,
+ .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
.load_eoi_exitmap = vmx_load_eoi_exitmap,
.hwapic_irr_update = vmx_hwapic_irr_update,
.hwapic_isr_update = vmx_hwapic_isr_update,
@@ -10371,11 +10931,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
- .set_tsc_khz = vmx_set_tsc_khz,
.read_tsc_offset = vmx_read_tsc_offset,
.write_tsc_offset = vmx_write_tsc_offset,
- .adjust_tsc_offset = vmx_adjust_tsc_offset,
- .compute_tsc_offset = vmx_compute_tsc_offset,
+ .adjust_tsc_offset_guest = vmx_adjust_tsc_offset_guest,
.read_l1_tsc = vmx_read_l1_tsc,
.set_tdp_cr3 = vmx_set_cr3,
@@ -10394,7 +10952,12 @@ static struct kvm_x86_ops vmx_x86_ops = {
.flush_log_dirty = vmx_flush_log_dirty,
.enable_log_dirty_pt_masked = vmx_enable_log_dirty_pt_masked,
+ .pre_block = vmx_pre_block,
+ .post_block = vmx_post_block,
+
.pmu_ops = &intel_pmu_ops,
+
+ .update_pi_irte = vmx_update_pi_irte,
};
static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9a9a198..7236bd3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -51,6 +51,8 @@
#include <linux/pci.h>
#include <linux/timekeeper_internal.h>
#include <linux/pvclock_gtod.h>
+#include <linux/kvm_irqfd.h>
+#include <linux/irqbypass.h>
#include <trace/events/kvm.h>
#define CREATE_TRACE_POINTS
@@ -64,6 +66,7 @@
#include <asm/fpu/internal.h> /* Ugh! */
#include <asm/pvclock.h>
#include <asm/div64.h>
+#include <asm/irq_remapping.h>
#define MAX_IO_MSRS 256
#define KVM_MAX_MCE_BANKS 32
@@ -90,10 +93,10 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu);
static void process_nmi(struct kvm_vcpu *vcpu);
static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
-struct kvm_x86_ops *kvm_x86_ops;
+struct kvm_x86_ops *kvm_x86_ops __read_mostly;
EXPORT_SYMBOL_GPL(kvm_x86_ops);
-static bool ignore_msrs = 0;
+static bool __read_mostly ignore_msrs = 0;
module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
unsigned int min_timer_period_us = 500;
@@ -102,20 +105,28 @@ module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
static bool __read_mostly kvmclock_periodic_sync = true;
module_param(kvmclock_periodic_sync, bool, S_IRUGO);
-bool kvm_has_tsc_control;
+bool __read_mostly kvm_has_tsc_control;
EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
-u32 kvm_max_guest_tsc_khz;
+u32 __read_mostly kvm_max_guest_tsc_khz;
EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
+u8 __read_mostly kvm_tsc_scaling_ratio_frac_bits;
+EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_frac_bits);
+u64 __read_mostly kvm_max_tsc_scaling_ratio;
+EXPORT_SYMBOL_GPL(kvm_max_tsc_scaling_ratio);
+static u64 __read_mostly kvm_default_tsc_scaling_ratio;
/* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
-static u32 tsc_tolerance_ppm = 250;
+static u32 __read_mostly tsc_tolerance_ppm = 250;
module_param(tsc_tolerance_ppm, uint, S_IRUGO | S_IWUSR);
/* lapic timer advance (tscdeadline mode only) in nanoseconds */
-unsigned int lapic_timer_advance_ns = 0;
+unsigned int __read_mostly lapic_timer_advance_ns = 0;
module_param(lapic_timer_advance_ns, uint, S_IRUGO | S_IWUSR);
-static bool backwards_tsc_observed = false;
+static bool __read_mostly vector_hashing = true;
+module_param(vector_hashing, bool, S_IRUGO);
+
+static bool __read_mostly backwards_tsc_observed = false;
#define KVM_NR_SHARED_MSRS 16
@@ -622,7 +633,9 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if ((cr0 ^ old_cr0) & update_bits)
kvm_mmu_reset_context(vcpu);
- if ((cr0 ^ old_cr0) & X86_CR0_CD)
+ if (((cr0 ^ old_cr0) & X86_CR0_CD) &&
+ kvm_arch_has_noncoherent_dma(vcpu->kvm) &&
+ !kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL);
return 0;
@@ -663,9 +676,9 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
/* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now */
if (index != XCR_XFEATURE_ENABLED_MASK)
return 1;
- if (!(xcr0 & XSTATE_FP))
+ if (!(xcr0 & XFEATURE_MASK_FP))
return 1;
- if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
+ if ((xcr0 & XFEATURE_MASK_YMM) && !(xcr0 & XFEATURE_MASK_SSE))
return 1;
/*
@@ -673,23 +686,24 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
* saving. However, xcr0 bit 0 is always set, even if the
* emulated CPU does not support XSAVE (see fx_init).
*/
- valid_bits = vcpu->arch.guest_supported_xcr0 | XSTATE_FP;
+ valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
if (xcr0 & ~valid_bits)
return 1;
- if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR)))
+ if ((!(xcr0 & XFEATURE_MASK_BNDREGS)) !=
+ (!(xcr0 & XFEATURE_MASK_BNDCSR)))
return 1;
- if (xcr0 & XSTATE_AVX512) {
- if (!(xcr0 & XSTATE_YMM))
+ if (xcr0 & XFEATURE_MASK_AVX512) {
+ if (!(xcr0 & XFEATURE_MASK_YMM))
return 1;
- if ((xcr0 & XSTATE_AVX512) != XSTATE_AVX512)
+ if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
return 1;
}
kvm_put_guest_xcr0(vcpu);
vcpu->arch.xcr0 = xcr0;
- if ((xcr0 ^ old_xcr0) & XSTATE_EXTEND_MASK)
+ if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
kvm_update_cpuid(vcpu);
return 0;
}
@@ -788,7 +802,7 @@ int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
{
if (cr8 & CR8_RESERVED_BITS)
return 1;
- if (irqchip_in_kernel(vcpu->kvm))
+ if (lapic_in_kernel(vcpu))
kvm_lapic_set_tpr(vcpu, cr8);
else
vcpu->arch.cr8 = cr8;
@@ -798,7 +812,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr8);
unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
{
- if (irqchip_in_kernel(vcpu->kvm))
+ if (lapic_in_kernel(vcpu))
return kvm_lapic_get_cr8(vcpu);
else
return vcpu->arch.cr8;
@@ -940,7 +954,7 @@ static u32 msrs_to_save[] = {
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
- MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS
+ MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
};
static unsigned num_msrs_to_save;
@@ -952,6 +966,11 @@ static u32 emulated_msrs[] = {
HV_X64_MSR_TIME_REF_COUNT, HV_X64_MSR_REFERENCE_TSC,
HV_X64_MSR_CRASH_P0, HV_X64_MSR_CRASH_P1, HV_X64_MSR_CRASH_P2,
HV_X64_MSR_CRASH_P3, HV_X64_MSR_CRASH_P4, HV_X64_MSR_CRASH_CTL,
+ HV_X64_MSR_RESET,
+ HV_X64_MSR_VP_INDEX,
+ HV_X64_MSR_VP_RUNTIME,
+ HV_X64_MSR_SCONTROL,
+ HV_X64_MSR_STIMER0_CONFIG,
HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
MSR_KVM_PV_EOI_EN,
@@ -1153,7 +1172,8 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
++version;
- kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
+ if (kvm_write_guest(kvm, wall_clock, &version, sizeof(version)))
+ return;
/*
* The guest calculates current wall clock time by adding
@@ -1179,17 +1199,11 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
{
- uint32_t quotient, remainder;
-
- /* Don't try to replace with do_div(), this one calculates
- * "(dividend << 32) / divisor" */
- __asm__ ( "divl %4"
- : "=a" (quotient), "=d" (remainder)
- : "0" (0), "1" (dividend), "r" (divisor) );
- return quotient;
+ do_shl32_div32(dividend, divisor);
+ return dividend;
}
-static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
+static void kvm_get_time_scale(uint64_t scaled_hz, uint64_t base_hz,
s8 *pshift, u32 *pmultiplier)
{
uint64_t scaled64;
@@ -1197,8 +1211,8 @@ static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
uint64_t tps64;
uint32_t tps32;
- tps64 = base_khz * 1000LL;
- scaled64 = scaled_khz * 1000LL;
+ tps64 = base_hz;
+ scaled64 = scaled_hz;
while (tps64 > scaled64*2 || tps64 & 0xffffffff00000000ULL) {
tps64 >>= 1;
shift--;
@@ -1216,8 +1230,8 @@ static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
*pshift = shift;
*pmultiplier = div_frac(scaled64, tps32);
- pr_debug("%s: base_khz %u => %u, shift %d, mul %u\n",
- __func__, base_khz, scaled_khz, shift, *pmultiplier);
+ pr_debug("%s: base_hz %llu => %llu, shift %d, mul %u\n",
+ __func__, base_hz, scaled_hz, shift, *pmultiplier);
}
#ifdef CONFIG_X86_64
@@ -1240,20 +1254,59 @@ static u32 adjust_tsc_khz(u32 khz, s32 ppm)
return v;
}
-static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
+static int set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
+{
+ u64 ratio;
+
+ /* Guest TSC same frequency as host TSC? */
+ if (!scale) {
+ vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+ return 0;
+ }
+
+ /* TSC scaling supported? */
+ if (!kvm_has_tsc_control) {
+ if (user_tsc_khz > tsc_khz) {
+ vcpu->arch.tsc_catchup = 1;
+ vcpu->arch.tsc_always_catchup = 1;
+ return 0;
+ } else {
+ WARN(1, "user requested TSC rate below hardware speed\n");
+ return -1;
+ }
+ }
+
+ /* TSC scaling required - calculate ratio */
+ ratio = mul_u64_u32_div(1ULL << kvm_tsc_scaling_ratio_frac_bits,
+ user_tsc_khz, tsc_khz);
+
+ if (ratio == 0 || ratio >= kvm_max_tsc_scaling_ratio) {
+ WARN_ONCE(1, "Invalid TSC scaling ratio - virtual-tsc-khz=%u\n",
+ user_tsc_khz);
+ return -1;
+ }
+
+ vcpu->arch.tsc_scaling_ratio = ratio;
+ return 0;
+}
+
+static int kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
{
u32 thresh_lo, thresh_hi;
int use_scaling = 0;
/* tsc_khz can be zero if TSC calibration fails */
- if (this_tsc_khz == 0)
- return;
+ if (user_tsc_khz == 0) {
+ /* set tsc_scaling_ratio to a safe value */
+ vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+ return -1;
+ }
/* Compute a scale to convert nanoseconds in TSC cycles */
- kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000,
+ kvm_get_time_scale(user_tsc_khz * 1000LL, NSEC_PER_SEC,
&vcpu->arch.virtual_tsc_shift,
&vcpu->arch.virtual_tsc_mult);
- vcpu->arch.virtual_tsc_khz = this_tsc_khz;
+ vcpu->arch.virtual_tsc_khz = user_tsc_khz;
/*
* Compute the variation in TSC rate which is acceptable
@@ -1263,11 +1316,11 @@ static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
*/
thresh_lo = adjust_tsc_khz(tsc_khz, -tsc_tolerance_ppm);
thresh_hi = adjust_tsc_khz(tsc_khz, tsc_tolerance_ppm);
- if (this_tsc_khz < thresh_lo || this_tsc_khz > thresh_hi) {
- pr_debug("kvm: requested TSC rate %u falls outside tolerance [%u,%u]\n", this_tsc_khz, thresh_lo, thresh_hi);
+ if (user_tsc_khz < thresh_lo || user_tsc_khz > thresh_hi) {
+ pr_debug("kvm: requested TSC rate %u falls outside tolerance [%u,%u]\n", user_tsc_khz, thresh_lo, thresh_hi);
use_scaling = 1;
}
- kvm_x86_ops->set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
+ return set_tsc_khz(vcpu, user_tsc_khz, use_scaling);
}
static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
@@ -1313,6 +1366,48 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
}
+/*
+ * Multiply tsc by a fixed point number represented by ratio.
+ *
+ * The most significant 64-N bits (mult) of ratio represent the
+ * integral part of the fixed point number; the remaining N bits
+ * (frac) represent the fractional part, ie. ratio represents a fixed
+ * point number (mult + frac * 2^(-N)).
+ *
+ * N equals to kvm_tsc_scaling_ratio_frac_bits.
+ */
+static inline u64 __scale_tsc(u64 ratio, u64 tsc)
+{
+ return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+}
+
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
+{
+ u64 _tsc = tsc;
+ u64 ratio = vcpu->arch.tsc_scaling_ratio;
+
+ if (ratio != kvm_default_tsc_scaling_ratio)
+ _tsc = __scale_tsc(ratio, tsc);
+
+ return _tsc;
+}
+EXPORT_SYMBOL_GPL(kvm_scale_tsc);
+
+static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
+{
+ u64 tsc;
+
+ tsc = kvm_scale_tsc(vcpu, rdtsc());
+
+ return target_tsc - tsc;
+}
+
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
+{
+ return kvm_x86_ops->read_l1_tsc(vcpu, kvm_scale_tsc(vcpu, host_tsc));
+}
+EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
+
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
{
struct kvm *kvm = vcpu->kvm;
@@ -1324,7 +1419,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
u64 data = msr->data;
raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
- offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+ offset = kvm_compute_tsc_offset(vcpu, data);
ns = get_kernel_ns();
elapsed = ns - kvm->arch.last_tsc_nsec;
@@ -1381,7 +1476,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
} else {
u64 delta = nsec_to_cycles(vcpu, elapsed);
data += delta;
- offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+ offset = kvm_compute_tsc_offset(vcpu, data);
pr_debug("kvm: adjusted tsc offset by %llu\n", delta);
}
matched = true;
@@ -1438,6 +1533,20 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
EXPORT_SYMBOL_GPL(kvm_write_tsc);
+static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
+ s64 adjustment)
+{
+ kvm_x86_ops->adjust_tsc_offset_guest(vcpu, adjustment);
+}
+
+static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
+{
+ if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
+ WARN_ON(adjustment < 0);
+ adjustment = kvm_scale_tsc(vcpu, (u64) adjustment);
+ kvm_x86_ops->adjust_tsc_offset_guest(vcpu, adjustment);
+}
+
#ifdef CONFIG_X86_64
static cycle_t read_tsc(void)
@@ -1574,6 +1683,11 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
#endif
}
+void kvm_make_mclock_inprogress_request(struct kvm *kvm)
+{
+ kvm_make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
+}
+
static void kvm_gen_update_masterclock(struct kvm *kvm)
{
#ifdef CONFIG_X86_64
@@ -1599,7 +1713,7 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
static int kvm_guest_time_update(struct kvm_vcpu *v)
{
- unsigned long flags, this_tsc_khz;
+ unsigned long flags, tgt_tsc_khz;
struct kvm_vcpu_arch *vcpu = &v->arch;
struct kvm_arch *ka = &v->kvm->arch;
s64 kernel_ns;
@@ -1625,8 +1739,8 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
/* Keep irq disabled to prevent changes to the clock */
local_irq_save(flags);
- this_tsc_khz = __this_cpu_read(cpu_tsc_khz);
- if (unlikely(this_tsc_khz == 0)) {
+ tgt_tsc_khz = __this_cpu_read(cpu_tsc_khz);
+ if (unlikely(tgt_tsc_khz == 0)) {
local_irq_restore(flags);
kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
return 1;
@@ -1636,7 +1750,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
kernel_ns = get_kernel_ns();
}
- tsc_timestamp = kvm_x86_ops->read_l1_tsc(v, host_tsc);
+ tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
/*
* We may have to catch up the TSC to match elapsed wall clock
@@ -1661,11 +1775,14 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
if (!vcpu->pv_time_enabled)
return 0;
- if (unlikely(vcpu->hw_tsc_khz != this_tsc_khz)) {
- kvm_get_time_scale(NSEC_PER_SEC / 1000, this_tsc_khz,
+ if (kvm_has_tsc_control)
+ tgt_tsc_khz = kvm_scale_tsc(v, tgt_tsc_khz);
+
+ if (unlikely(vcpu->hw_tsc_khz != tgt_tsc_khz)) {
+ kvm_get_time_scale(NSEC_PER_SEC, tgt_tsc_khz * 1000LL,
&vcpu->hv_clock.tsc_shift,
&vcpu->hv_clock.tsc_to_system_mul);
- vcpu->hw_tsc_khz = this_tsc_khz;
+ vcpu->hw_tsc_khz = tgt_tsc_khz;
}
/* With all the info we got, fill in the values */
@@ -1897,6 +2014,8 @@ static void accumulate_steal_time(struct kvm_vcpu *vcpu)
static void record_steal_time(struct kvm_vcpu *vcpu)
{
+ accumulate_steal_time(vcpu);
+
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;
@@ -2047,12 +2166,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
if (!(data & KVM_MSR_ENABLED))
break;
- vcpu->arch.st.last_steal = current->sched_info.run_delay;
-
- preempt_disable();
- accumulate_steal_time(vcpu);
- preempt_enable();
-
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
break;
@@ -2091,6 +2204,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
case HV_X64_MSR_CRASH_CTL:
+ case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
return kvm_hv_set_msr_common(vcpu, msr, data,
msr_info->host_initiated);
case MSR_IA32_BBL_CR_CTL3:
@@ -2295,6 +2409,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
case HV_X64_MSR_CRASH_CTL:
+ case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT:
return kvm_hv_get_msr_common(vcpu,
msr_info->index, &msr_info->data);
break;
@@ -2434,6 +2549,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_HYPERV:
case KVM_CAP_HYPERV_VAPIC:
case KVM_CAP_HYPERV_SPIN:
+ case KVM_CAP_HYPERV_SYNIC:
case KVM_CAP_PCI_SEGMENT:
case KVM_CAP_DEBUGREGS:
case KVM_CAP_X86_ROBUST_SINGLESTEP:
@@ -2448,6 +2564,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ENABLE_CAP_VM:
case KVM_CAP_DISABLE_QUIRKS:
case KVM_CAP_SET_BOOT_CPU_ID:
+ case KVM_CAP_SPLIT_IRQCHIP:
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
case KVM_CAP_ASSIGN_DEV_IRQ:
case KVM_CAP_PCI_2_3:
@@ -2585,6 +2702,11 @@ static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu)
return kvm_arch_has_noncoherent_dma(vcpu->kvm);
}
+static inline void kvm_migrate_timers(struct kvm_vcpu *vcpu)
+{
+ set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests);
+}
+
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
/* Address WBINVD may be executed by guest */
@@ -2611,7 +2733,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (tsc_delta < 0)
mark_tsc_unstable("KVM discovered backwards TSC");
if (check_tsc_unstable()) {
- u64 offset = kvm_x86_ops->compute_tsc_offset(vcpu,
+ u64 offset = kvm_compute_tsc_offset(vcpu,
vcpu->arch.last_guest_tsc);
kvm_x86_ops->write_tsc_offset(vcpu, offset);
vcpu->arch.tsc_catchup = 1;
@@ -2627,7 +2749,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
vcpu->cpu = cpu;
}
- accumulate_steal_time(vcpu);
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
}
@@ -2641,7 +2762,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s)
{
- kvm_x86_ops->sync_pir_to_irr(vcpu);
+ if (vcpu->arch.apicv_active)
+ kvm_x86_ops->sync_pir_to_irr(vcpu);
+
memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s);
return 0;
@@ -2656,17 +2779,50 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
return 0;
}
+static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu)
+{
+ return (!lapic_in_kernel(vcpu) ||
+ kvm_apic_accept_pic_intr(vcpu));
+}
+
+/*
+ * if userspace requested an interrupt window, check that the
+ * interrupt window is open.
+ *
+ * No need to exit to userspace if we already have an interrupt queued.
+ */
+static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu)
+{
+ return kvm_arch_interrupt_allowed(vcpu) &&
+ !kvm_cpu_has_interrupt(vcpu) &&
+ !kvm_event_needs_reinjection(vcpu) &&
+ kvm_cpu_accept_dm_intr(vcpu);
+}
+
static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
if (irq->irq >= KVM_NR_INTERRUPTS)
return -EINVAL;
- if (irqchip_in_kernel(vcpu->kvm))
+
+ if (!irqchip_in_kernel(vcpu->kvm)) {
+ kvm_queue_interrupt(vcpu, irq->irq, false);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ return 0;
+ }
+
+ /*
+ * With in-kernel LAPIC, we only use this to inject EXTINT, so
+ * fail for in-kernel 8259.
+ */
+ if (pic_in_kernel(vcpu->kvm))
return -ENXIO;
- kvm_queue_interrupt(vcpu, irq->irq, false);
- kvm_make_request(KVM_REQ_EVENT, vcpu);
+ if (vcpu->arch.pending_external_vector != -1)
+ return -EEXIST;
+ vcpu->arch.pending_external_vector = irq->irq;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
return 0;
}
@@ -2829,7 +2985,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR &&
- kvm_vcpu_has_lapic(vcpu))
+ lapic_in_kernel(vcpu))
vcpu->arch.apic->sipi_vector = events->sipi_vector;
if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
@@ -2842,7 +2998,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK;
else
vcpu->arch.hflags &= ~HF_SMM_INSIDE_NMI_MASK;
- if (kvm_vcpu_has_lapic(vcpu)) {
+ if (lapic_in_kernel(vcpu)) {
if (events->smi.latched_init)
set_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
else
@@ -2905,7 +3061,7 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
* Copy each region from the possibly compacted offset to the
* non-compacted offset.
*/
- valid = xstate_bv & ~XSTATE_FPSSE;
+ valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
while (valid) {
u64 feature = valid & -valid;
int index = fls64(feature) - 1;
@@ -2943,7 +3099,7 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
* Copy each region from the non-compacted offset to the
* possibly compacted offset.
*/
- valid = xstate_bv & ~XSTATE_FPSSE;
+ valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
while (valid) {
u64 feature = valid & -valid;
int index = fls64(feature) - 1;
@@ -2971,7 +3127,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
&vcpu->arch.guest_fpu.state.fxsave,
sizeof(struct fxregs_state));
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
- XSTATE_FPSSE;
+ XFEATURE_MASK_FPSSE;
}
}
@@ -2991,7 +3147,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
return -EINVAL;
load_xsave(vcpu, (u8 *)guest_xsave->region);
} else {
- if (xstate_bv & ~XSTATE_FPSSE)
+ if (xstate_bv & ~XFEATURE_MASK_FPSSE)
return -EINVAL;
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
guest_xsave->region, sizeof(struct fxregs_state));
@@ -3051,6 +3207,20 @@ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
return 0;
}
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+ struct kvm_enable_cap *cap)
+{
+ if (cap->flags)
+ return -EINVAL;
+
+ switch (cap->cap) {
+ case KVM_CAP_HYPERV_SYNIC:
+ return kvm_hv_activate_synic(vcpu);
+ default:
+ return -EINVAL;
+ }
+}
+
long kvm_arch_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -3068,7 +3238,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
switch (ioctl) {
case KVM_GET_LAPIC: {
r = -EINVAL;
- if (!vcpu->arch.apic)
+ if (!lapic_in_kernel(vcpu))
goto out;
u.lapic = kzalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
@@ -3086,7 +3256,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
case KVM_SET_LAPIC: {
r = -EINVAL;
- if (!vcpu->arch.apic)
+ if (!lapic_in_kernel(vcpu))
goto out;
u.lapic = memdup_user(argp, sizeof(*u.lapic));
if (IS_ERR(u.lapic))
@@ -3175,7 +3345,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_vapic_addr va;
r = -EINVAL;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!lapic_in_kernel(vcpu))
goto out;
r = -EFAULT;
if (copy_from_user(&va, argp, sizeof va))
@@ -3302,9 +3472,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (user_tsc_khz == 0)
user_tsc_khz = tsc_khz;
- kvm_set_tsc_khz(vcpu, user_tsc_khz);
+ if (!kvm_set_tsc_khz(vcpu, user_tsc_khz))
+ r = 0;
- r = 0;
goto out;
}
case KVM_GET_TSC_KHZ: {
@@ -3315,6 +3485,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = kvm_set_guest_paused(vcpu);
goto out;
}
+ case KVM_ENABLE_CAP: {
+ struct kvm_enable_cap cap;
+
+ r = -EFAULT;
+ if (copy_from_user(&cap, argp, sizeof(cap)))
+ goto out;
+ r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+ break;
+ }
default:
r = -EINVAL;
}
@@ -3424,63 +3603,78 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
- int r = 0;
+ struct kvm_kpit_state *kps = &kvm->arch.vpit->pit_state;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state));
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ BUILD_BUG_ON(sizeof(*ps) != sizeof(kps->channels));
+
+ mutex_lock(&kps->lock);
+ memcpy(ps, &kps->channels, sizeof(*ps));
+ mutex_unlock(&kps->lock);
+ return 0;
}
static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
- int r = 0;
+ int i;
+ struct kvm_pit *pit = kvm->arch.vpit;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
- kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ mutex_lock(&pit->pit_state.lock);
+ memcpy(&pit->pit_state.channels, ps, sizeof(*ps));
+ for (i = 0; i < 3; i++)
+ kvm_pit_load_count(pit, i, ps->channels[i].count, 0);
+ mutex_unlock(&pit->pit_state.lock);
+ return 0;
}
static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
- int r = 0;
-
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
sizeof(ps->channels));
ps->flags = kvm->arch.vpit->pit_state.flags;
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
memset(&ps->reserved, 0, sizeof(ps->reserved));
- return r;
+ return 0;
}
static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
- int r = 0, start = 0;
+ int start = 0;
+ int i;
u32 prev_legacy, cur_legacy;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
+ struct kvm_pit *pit = kvm->arch.vpit;
+
+ mutex_lock(&pit->pit_state.lock);
+ prev_legacy = pit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
if (!prev_legacy && cur_legacy)
start = 1;
- memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
- sizeof(kvm->arch.vpit->pit_state.channels));
- kvm->arch.vpit->pit_state.flags = ps->flags;
- kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ memcpy(&pit->pit_state.channels, &ps->channels,
+ sizeof(pit->pit_state.channels));
+ pit->pit_state.flags = ps->flags;
+ for (i = 0; i < 3; i++)
+ kvm_pit_load_count(pit, i, pit->pit_state.channels[i].count,
+ start && i == 0);
+ mutex_unlock(&pit->pit_state.lock);
+ return 0;
}
static int kvm_vm_ioctl_reinject(struct kvm *kvm,
struct kvm_reinject_control *control)
{
- if (!kvm->arch.vpit)
+ struct kvm_pit *pit = kvm->arch.vpit;
+
+ if (!pit)
return -ENXIO;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- kvm->arch.vpit->pit_state.reinject = control->pit_reinject;
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+
+ /* pit->pit_state.lock was overloaded to prevent userspace from getting
+ * an inconsistent state after running multiple KVM_REINJECT_CONTROL
+ * ioctls in parallel. Use a separate lock if that ioctl isn't rare.
+ */
+ mutex_lock(&pit->pit_state.lock);
+ kvm_pit_set_reinject(pit, control->pit_reinject);
+ mutex_unlock(&pit->pit_state.lock);
+
return 0;
}
@@ -3555,6 +3749,28 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
kvm->arch.disabled_quirks = cap->args[0];
r = 0;
break;
+ case KVM_CAP_SPLIT_IRQCHIP: {
+ mutex_lock(&kvm->lock);
+ r = -EINVAL;
+ if (cap->args[0] > MAX_NR_RESERVED_IOAPIC_PINS)
+ goto split_irqchip_unlock;
+ r = -EEXIST;
+ if (irqchip_in_kernel(kvm))
+ goto split_irqchip_unlock;
+ if (atomic_read(&kvm->online_vcpus))
+ goto split_irqchip_unlock;
+ r = kvm_setup_empty_irq_routing(kvm);
+ if (r)
+ goto split_irqchip_unlock;
+ /* Pairs with irqchip_in_kernel. */
+ smp_wmb();
+ kvm->arch.irqchip_split = true;
+ kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
+ r = 0;
+split_irqchip_unlock:
+ mutex_unlock(&kvm->lock);
+ break;
+ }
default:
r = -EINVAL;
break;
@@ -3668,7 +3884,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
r = -ENXIO;
- if (!irqchip_in_kernel(kvm))
+ if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
goto get_irqchip_out;
r = kvm_vm_ioctl_get_irqchip(kvm, chip);
if (r)
@@ -3692,7 +3908,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
r = -ENXIO;
- if (!irqchip_in_kernel(kvm))
+ if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
goto set_irqchip_out;
r = kvm_vm_ioctl_set_irqchip(kvm, chip);
if (r)
@@ -3845,16 +4061,17 @@ static void kvm_init_msr_list(void)
/*
* Even MSRs that are valid in the host may not be exposed
- * to the guests in some cases. We could work around this
- * in VMX with the generic MSR save/load machinery, but it
- * is not really worthwhile since it will really only
- * happen with nested virtualization.
+ * to the guests in some cases.
*/
switch (msrs_to_save[i]) {
case MSR_IA32_BNDCFGS:
if (!kvm_x86_ops->mpx_supported())
continue;
break;
+ case MSR_TSC_AUX:
+ if (!kvm_x86_ops->rdtscp_supported())
+ continue;
+ break;
default:
break;
}
@@ -3890,7 +4107,7 @@ static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
do {
n = min(len, 8);
- if (!(vcpu->arch.apic &&
+ if (!(lapic_in_kernel(vcpu) &&
!kvm_iodevice_write(vcpu, &vcpu->arch.apic->dev, addr, n, v))
&& kvm_io_bus_write(vcpu, KVM_MMIO_BUS, addr, n, v))
break;
@@ -3910,7 +4127,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
do {
n = min(len, 8);
- if (!(vcpu->arch.apic &&
+ if (!(lapic_in_kernel(vcpu) &&
!kvm_iodevice_read(vcpu, &vcpu->arch.apic->dev,
addr, n, v))
&& kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v))
@@ -4059,6 +4276,15 @@ static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt,
return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
}
+static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt,
+ unsigned long addr, void *val, unsigned int bytes)
+{
+ struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+ int r = kvm_vcpu_read_guest(vcpu, addr, val, bytes);
+
+ return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE;
+}
+
int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
gva_t addr, void *val,
unsigned int bytes,
@@ -4134,7 +4360,7 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
ret = kvm_vcpu_write_guest(vcpu, gpa, val, bytes);
if (ret < 0)
return 0;
- kvm_mmu_pte_write(vcpu, gpa, val, bytes);
+ kvm_page_track_write(vcpu, gpa, val, bytes);
return 1;
}
@@ -4392,7 +4618,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
return X86EMUL_CMPXCHG_FAILED;
kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
- kvm_mmu_pte_write(vcpu, gpa, new, bytes);
+ kvm_page_track_write(vcpu, gpa, new, bytes);
return X86EMUL_CONTINUE;
@@ -4794,6 +5020,7 @@ static const struct x86_emulate_ops emulate_ops = {
.write_gpr = emulator_write_gpr,
.read_std = kvm_read_guest_virt_system,
.write_std = kvm_write_guest_virt_system,
+ .read_phys = kvm_read_guest_phys_system,
.fetch = kvm_fetch_guest_virt,
.read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated,
@@ -4935,7 +5162,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2,
int emulation_type)
{
gpa_t gpa = cr2;
- pfn_t pfn;
+ kvm_pfn_t pfn;
if (emulation_type & EMULTYPE_NO_REEXECUTE)
return false;
@@ -5666,7 +5893,7 @@ void kvm_arch_exit(void)
int kvm_vcpu_halt(struct kvm_vcpu *vcpu)
{
++vcpu->stat.halt_exits;
- if (irqchip_in_kernel(vcpu->kvm)) {
+ if (lapic_in_kernel(vcpu)) {
vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
return 1;
} else {
@@ -5701,6 +5928,12 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
}
+void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.apicv_active = false;
+ kvm_x86_ops->refresh_apicv_exec_ctrl(vcpu);
+}
+
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
{
unsigned long nr, a0, a1, a2, a3, ret;
@@ -5765,17 +5998,10 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
return emulator_write_emulated(ctxt, rip, instruction, 3, NULL);
}
-/*
- * Check if userspace requested an interrupt window, and that the
- * interrupt window is open.
- *
- * No need to exit to userspace if we already have an interrupt queued.
- */
static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
{
- return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) &&
- vcpu->run->request_interrupt_window &&
- kvm_arch_interrupt_allowed(vcpu));
+ return vcpu->run->request_interrupt_window &&
+ likely(!pic_in_kernel(vcpu->kvm));
}
static void post_kvm_run_save(struct kvm_vcpu *vcpu)
@@ -5786,13 +6012,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
kvm_run->flags = is_smm(vcpu) ? KVM_RUN_X86_SMM : 0;
kvm_run->cr8 = kvm_get_cr8(vcpu);
kvm_run->apic_base = kvm_get_apic_base(vcpu);
- if (irqchip_in_kernel(vcpu->kvm))
- kvm_run->ready_for_interrupt_injection = 1;
- else
- kvm_run->ready_for_interrupt_injection =
- kvm_arch_interrupt_allowed(vcpu) &&
- !kvm_cpu_has_interrupt(vcpu) &&
- !kvm_event_needs_reinjection(vcpu);
+ kvm_run->ready_for_interrupt_injection =
+ pic_in_kernel(vcpu->kvm) ||
+ kvm_vcpu_ready_for_interrupt_injection(vcpu);
}
static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -5802,7 +6024,10 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
if (!kvm_x86_ops->update_cr8_intercept)
return;
- if (!vcpu->arch.apic)
+ if (!lapic_in_kernel(vcpu))
+ return;
+
+ if (vcpu->arch.apicv_active)
return;
if (!vcpu->arch.apic->vapic_addr)
@@ -6141,20 +6366,30 @@ static void process_smi(struct kvm_vcpu *vcpu)
kvm_mmu_reset_context(vcpu);
}
+void kvm_make_scan_ioapic_request(struct kvm *kvm)
+{
+ kvm_make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
+}
+
static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
{
u64 eoi_exit_bitmap[4];
- u32 tmr[8];
if (!kvm_apic_hw_enabled(vcpu->arch.apic))
return;
- memset(eoi_exit_bitmap, 0, 32);
- memset(tmr, 0, 32);
+ bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
- kvm_ioapic_scan_entry(vcpu, eoi_exit_bitmap, tmr);
+ if (irqchip_split(vcpu->kvm))
+ kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
+ else {
+ if (vcpu->arch.apicv_active)
+ kvm_x86_ops->sync_pir_to_irr(vcpu);
+ kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
+ }
+ bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors,
+ vcpu_to_synic(vcpu)->vec_bitmap, 256);
kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
- kvm_apic_update_tmr(vcpu, tmr);
}
static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
@@ -6167,7 +6402,7 @@ void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
{
struct page *page = NULL;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!lapic_in_kernel(vcpu))
return;
if (!kvm_x86_ops->set_apic_access_page_addr)
@@ -6205,8 +6440,10 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
{
int r;
- bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
- vcpu->run->request_interrupt_window;
+ bool req_int_win =
+ dm_request_for_irq_injection(vcpu) &&
+ kvm_cpu_accept_dm_intr(vcpu);
+
bool req_immediate_exit = false;
if (vcpu->requests) {
@@ -6257,6 +6494,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_pmu_handle_event(vcpu);
if (kvm_check_request(KVM_REQ_PMI, vcpu))
kvm_pmu_deliver_pmi(vcpu);
+ if (kvm_check_request(KVM_REQ_IOAPIC_EOI_EXIT, vcpu)) {
+ BUG_ON(vcpu->arch.pending_ioapic_eoi > 255);
+ if (test_bit(vcpu->arch.pending_ioapic_eoi,
+ vcpu->arch.ioapic_handled_vectors)) {
+ vcpu->run->exit_reason = KVM_EXIT_IOAPIC_EOI;
+ vcpu->run->eoi.vector =
+ vcpu->arch.pending_ioapic_eoi;
+ r = 0;
+ goto out;
+ }
+ }
if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
vcpu_scan_ioapic(vcpu);
if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
@@ -6267,6 +6515,40 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
r = 0;
goto out;
}
+ if (kvm_check_request(KVM_REQ_HV_RESET, vcpu)) {
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_RESET;
+ r = 0;
+ goto out;
+ }
+ if (kvm_check_request(KVM_REQ_HV_EXIT, vcpu)) {
+ vcpu->run->exit_reason = KVM_EXIT_HYPERV;
+ vcpu->run->hyperv = vcpu->arch.hyperv.exit;
+ r = 0;
+ goto out;
+ }
+
+ /*
+ * KVM_REQ_HV_STIMER has to be processed after
+ * KVM_REQ_CLOCK_UPDATE, because Hyper-V SynIC timers
+ * depend on the guest clock being up-to-date
+ */
+ if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
+ kvm_hv_process_stimers(vcpu);
+ }
+
+ /*
+ * KVM_REQ_EVENT is not set when posted interrupts are set by
+ * VT-d hardware, so we have to update RVI unconditionally.
+ */
+ if (kvm_lapic_enabled(vcpu)) {
+ /*
+ * Update architecture specific hints for APIC
+ * virtual interrupt delivery.
+ */
+ if (vcpu->arch.apicv_active)
+ kvm_x86_ops->hwapic_irr_update(vcpu,
+ kvm_lapic_find_highest_irr(vcpu));
}
if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
@@ -6285,13 +6567,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_x86_ops->enable_irq_window(vcpu);
if (kvm_lapic_enabled(vcpu)) {
- /*
- * Update architecture specific hints for APIC
- * virtual interrupt delivery.
- */
- if (kvm_x86_ops->hwapic_irr_update)
- kvm_x86_ops->hwapic_irr_update(vcpu,
- kvm_lapic_find_highest_irr(vcpu));
update_cr8_intercept(vcpu);
kvm_lapic_sync_to_vapic(vcpu);
}
@@ -6334,6 +6609,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (req_immediate_exit)
smp_send_reschedule(vcpu->cpu);
+ trace_kvm_entry(vcpu->vcpu_id);
+ wait_lapic_expire(vcpu);
__kvm_guest_enter();
if (unlikely(vcpu->arch.switch_db_regs)) {
@@ -6346,8 +6623,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
}
- trace_kvm_entry(vcpu->vcpu_id);
- wait_lapic_expire(vcpu);
kvm_x86_ops->run(vcpu);
/*
@@ -6357,12 +6632,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
* KVM_DEBUGREG_WONT_EXIT again.
*/
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
- int i;
-
WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
kvm_x86_ops->sync_dirty_debug_regs(vcpu);
- for (i = 0; i < KVM_NR_DB_REGS; i++)
- vcpu->arch.eff_db[i] = vcpu->arch.db[i];
+ kvm_update_dr0123(vcpu);
+ kvm_update_dr6(vcpu);
+ kvm_update_dr7(vcpu);
+ vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
}
/*
@@ -6375,8 +6650,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (hw_breakpoint_active())
hw_breakpoint_restore();
- vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu,
- rdtsc());
+ vcpu->arch.last_guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
vcpu->mode = OUTSIDE_GUEST_MODE;
smp_wmb();
@@ -6427,10 +6701,15 @@ out:
static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
{
- if (!kvm_arch_vcpu_runnable(vcpu)) {
+ if (!kvm_arch_vcpu_runnable(vcpu) &&
+ (!kvm_x86_ops->pre_block || kvm_x86_ops->pre_block(vcpu) == 0)) {
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
kvm_vcpu_block(vcpu);
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
+
+ if (kvm_x86_ops->post_block)
+ kvm_x86_ops->post_block(vcpu);
+
if (!kvm_check_request(KVM_REQ_UNHALT, vcpu))
return 1;
}
@@ -6467,10 +6746,12 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
for (;;) {
- if (kvm_vcpu_running(vcpu))
+ if (kvm_vcpu_running(vcpu)) {
r = vcpu_enter_guest(vcpu);
- else
+ } else {
r = vcpu_block(kvm, vcpu);
+ }
+
if (r <= 0)
break;
@@ -6478,9 +6759,10 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
if (kvm_cpu_has_pending_timer(vcpu))
kvm_inject_pending_timer_irqs(vcpu);
- if (dm_request_for_irq_injection(vcpu)) {
- r = -EINTR;
- vcpu->run->exit_reason = KVM_EXIT_INTR;
+ if (dm_request_for_irq_injection(vcpu) &&
+ kvm_vcpu_ready_for_interrupt_injection(vcpu)) {
+ r = 0;
+ vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
++vcpu->stat.request_irq_exits;
break;
}
@@ -6607,7 +6889,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
/* re-sync apic's tpr */
- if (!irqchip_in_kernel(vcpu->kvm)) {
+ if (!lapic_in_kernel(vcpu)) {
if (kvm_set_cr8(vcpu, kvm_run->cr8) != 0) {
r = -EINVAL;
goto out;
@@ -6770,7 +7052,7 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
- if (!kvm_vcpu_has_lapic(vcpu) &&
+ if (!lapic_in_kernel(vcpu) &&
mp_state->mp_state != KVM_MP_STATE_RUNNABLE)
return -EINVAL;
@@ -6931,7 +7213,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
*/
kvm_set_rflags(vcpu, rflags);
- kvm_x86_ops->update_db_bp_intercept(vcpu);
+ kvm_x86_ops->update_bp_intercept(vcpu);
r = 0;
@@ -7005,7 +7287,7 @@ static void fx_init(struct kvm_vcpu *vcpu)
/*
* Ensure guest xcr0 is valid for loading
*/
- vcpu->arch.xcr0 = XSTATE_FP;
+ vcpu->arch.xcr0 = XFEATURE_MASK_FP;
vcpu->arch.cr0 |= X86_CR0_ET;
}
@@ -7046,7 +7328,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
* Every 255 times fpu_counter rolls over to 0; a guest that uses
* the FPU in bursts will revert to loading it on demand.
*/
- if (!vcpu->arch.eager_fpu) {
+ if (!use_eager_fpu()) {
if (++vcpu->fpu_counter < 5)
kvm_make_request(KVM_REQ_DEACTIVATE_FPU, vcpu);
}
@@ -7280,6 +7562,20 @@ int kvm_arch_hardware_setup(void)
if (r != 0)
return r;
+ if (kvm_has_tsc_control) {
+ /*
+ * Make sure the user can only configure tsc_khz values that
+ * fit into a signed integer.
+ * A min value is not calculated needed because it will always
+ * be 1 on all machines.
+ */
+ u64 max = min(0x7fffffffULL,
+ __scale_tsc(kvm_max_tsc_scaling_ratio, tsc_khz));
+ kvm_max_guest_tsc_khz = max;
+
+ kvm_default_tsc_scaling_ratio = 1ULL << kvm_tsc_scaling_ratio_frac_bits;
+ }
+
kvm_init_msr_list();
return 0;
}
@@ -7307,10 +7603,11 @@ bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
{
- return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL);
+ return irqchip_in_kernel(vcpu->kvm) == lapic_in_kernel(vcpu);
}
struct static_key kvm_no_apic_vcpu __read_mostly;
+EXPORT_SYMBOL_GPL(kvm_no_apic_vcpu);
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
@@ -7321,6 +7618,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
BUG_ON(vcpu->kvm == NULL);
kvm = vcpu->kvm;
+ vcpu->arch.apicv_active = kvm_x86_ops->get_enable_apicv();
vcpu->arch.pv.pv_unhalted = false;
vcpu->arch.emulate_ctxt.ops = &emulate_ops;
if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_reset_bsp(vcpu))
@@ -7376,6 +7674,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
kvm_async_pf_hash_reset(vcpu);
kvm_pmu_init(vcpu);
+ vcpu->arch.pending_external_vector = -1;
+
+ kvm_hv_vcpu_init(vcpu);
+
return 0;
fail_free_mce_banks:
@@ -7394,6 +7696,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
int idx;
+ kvm_hv_vcpu_uninit(vcpu);
kvm_pmu_destroy(vcpu);
kfree(vcpu->arch.mce_banks);
kvm_free_lapic(vcpu);
@@ -7401,7 +7704,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
kvm_mmu_destroy(vcpu);
srcu_read_unlock(&vcpu->kvm->srcu, idx);
free_page((unsigned long)vcpu->arch.pio_data);
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!lapic_in_kernel(vcpu))
static_key_slow_dec(&kvm_no_apic_vcpu);
}
@@ -7436,6 +7739,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn);
INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn);
+ kvm_page_track_init(kvm);
+ kvm_mmu_init_vm(kvm);
+
return 0;
}
@@ -7562,6 +7868,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kfree(kvm->arch.vioapic);
kvm_free_vcpus(kvm);
kfree(rcu_dereference_check(kvm->arch.apic_map, 1));
+ kvm_mmu_uninit_vm(kvm);
}
void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
@@ -7583,6 +7890,8 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
free->arch.lpage_info[i - 1] = NULL;
}
}
+
+ kvm_page_track_free_memslot(free, dont);
}
int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
@@ -7591,6 +7900,7 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
int i;
for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+ struct kvm_lpage_info *linfo;
unsigned long ugfn;
int lpages;
int level = i + 1;
@@ -7605,15 +7915,16 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
if (i == 0)
continue;
- slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
- sizeof(*slot->arch.lpage_info[i - 1]));
- if (!slot->arch.lpage_info[i - 1])
+ linfo = kvm_kvzalloc(lpages * sizeof(*linfo));
+ if (!linfo)
goto out_free;
+ slot->arch.lpage_info[i - 1] = linfo;
+
if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->arch.lpage_info[i - 1][0].write_count = 1;
+ linfo[0].disallow_lpage = 1;
if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->arch.lpage_info[i - 1][lpages - 1].write_count = 1;
+ linfo[lpages - 1].disallow_lpage = 1;
ugfn = slot->userspace_addr >> PAGE_SHIFT;
/*
* If the gfn and userspace address are not aligned wrt each
@@ -7625,10 +7936,13 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
unsigned long j;
for (j = 0; j < lpages; ++j)
- slot->arch.lpage_info[i - 1][j].write_count = 1;
+ linfo[j].disallow_lpage = 1;
}
}
+ if (kvm_page_track_create_memslot(slot, npages))
+ goto out_free;
+
return 0;
out_free:
@@ -7788,6 +8102,9 @@ static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
kvm_cpu_has_interrupt(vcpu))
return true;
+ if (kvm_hv_has_stimer_pending(vcpu))
+ return true;
+
return false;
}
@@ -8028,7 +8345,65 @@ bool kvm_arch_has_noncoherent_dma(struct kvm *kvm)
}
EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma);
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
+ struct irq_bypass_producer *prod)
+{
+ struct kvm_kernel_irqfd *irqfd =
+ container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+ if (kvm_x86_ops->update_pi_irte) {
+ irqfd->producer = prod;
+ return kvm_x86_ops->update_pi_irte(irqfd->kvm,
+ prod->irq, irqfd->gsi, 1);
+ }
+
+ return -EINVAL;
+}
+
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
+ struct irq_bypass_producer *prod)
+{
+ int ret;
+ struct kvm_kernel_irqfd *irqfd =
+ container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+ if (!kvm_x86_ops->update_pi_irte) {
+ WARN_ON(irqfd->producer != NULL);
+ return;
+ }
+
+ WARN_ON(irqfd->producer != prod);
+ irqfd->producer = NULL;
+
+ /*
+ * When producer of consumer is unregistered, we change back to
+ * remapped mode, so we can re-use the current implementation
+ * when the irq is masked/disabed or the consumer side (KVM
+ * int this case doesn't want to receive the interrupts.
+ */
+ ret = kvm_x86_ops->update_pi_irte(irqfd->kvm, prod->irq, irqfd->gsi, 0);
+ if (ret)
+ printk(KERN_INFO "irq bypass consumer (token %p) unregistration"
+ " fails: %d\n", irqfd->consumer.token, ret);
+}
+
+int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set)
+{
+ if (!kvm_x86_ops->update_pi_irte)
+ return -EINVAL;
+
+ return kvm_x86_ops->update_pi_irte(kvm, host_irq, guest_irq, set);
+}
+
+bool kvm_vector_hashing_enabled(void)
+{
+ return vector_hashing;
+}
+EXPORT_SYMBOL_GPL(kvm_vector_hashing_enabled);
+
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr);
@@ -8043,3 +8418,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_write_tsc_offset);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ple_window);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pml_full);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pi_irte_update);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2f822cd..007940f 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -179,10 +179,11 @@ int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
int page_num);
+bool kvm_vector_hashing_enabled(void);
-#define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
- | XSTATE_BNDREGS | XSTATE_BNDCSR \
- | XSTATE_AVX512)
+#define KVM_SUPPORTED_XCR0 (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
+ | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
+ | XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512)
extern u64 host_xcr0;
extern u64 kvm_supported_xcr0(void);
@@ -192,4 +193,19 @@ extern unsigned int min_timer_period_us;
extern unsigned int lapic_timer_advance_ns;
extern struct static_key kvm_no_apic_vcpu;
+
+/* Same "calling convention" as do_div:
+ * - divide (n << 32) by base
+ * - put result in n
+ * - return remainder
+ */
+#define do_shl32_div32(n, base) \
+ ({ \
+ u32 __quot, __rem; \
+ asm("divl %2" : "=a" (__quot), "=d" (__rem) \
+ : "rm" (base), "0" (0), "1" ((u32) n)); \
+ n = __quot; \
+ __rem; \
+ })
+
#endif
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index a0d09f6..fd57d3a 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -1414,6 +1414,7 @@ __init void lguest_init(void)
pv_info.kernel_rpl = 1;
/* Everyone except Xen runs with this set. */
pv_info.shared_kernel_pmd = 1;
+ pv_info.features = 0;
/*
* We set up all the lguest overrides for sensitive operations. These
@@ -1472,7 +1473,6 @@ __init void lguest_init(void)
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu;
pv_mmu_ops.pte_update = lguest_pte_update;
- pv_mmu_ops.pte_update_defer = lguest_pte_update;
#ifdef CONFIG_X86_LOCAL_APIC
/* APIC read/write intercepts */
@@ -1520,12 +1520,6 @@ __init void lguest_init(void)
*/
reserve_top_address(lguest_data.reserve_mem);
- /*
- * If we don't initialize the lock dependency checker now, it crashes
- * atomic_notifier_chain_register, then paravirt_disable_iospace.
- */
- lockdep_init();
-
/* Hook in our special panic hypercall code. */
atomic_notifier_chain_register(&panic_notifier_list, &paniced);
@@ -1535,7 +1529,7 @@ __init void lguest_init(void)
*/
cpu_detect(&new_cpu_data);
/* head.S usually sets up the first capability word, so do it here. */
- new_cpu_data.x86_capability[0] = cpuid_edx(1);
+ new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1);
/* Math is always hard! */
set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index f258788..a501fa2 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -16,7 +16,7 @@ clean-files := inat-tables.c
obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o
-lib-y := delay.o misc.o cmdline.o
+lib-y := delay.o misc.o cmdline.o cpu.o
lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o
lib-y += memcpy_$(BITS).o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S
index a2fe51b..65be7cf 100644
--- a/arch/x86/lib/clear_page_64.S
+++ b/arch/x86/lib/clear_page_64.S
@@ -1,5 +1,5 @@
#include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
/*
diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
index 422db00..5cc78bf 100644
--- a/arch/x86/lib/cmdline.c
+++ b/arch/x86/lib/cmdline.c
@@ -21,12 +21,16 @@ static inline int myisspace(u8 c)
* @option: option string to look for
*
* Returns the position of that @option (starts counting with 1)
- * or 0 on not found.
+ * or 0 on not found. @option will only be found if it is found
+ * as an entire word in @cmdline. For instance, if @option="car"
+ * then a cmdline which contains "cart" will not match.
*/
-int cmdline_find_option_bool(const char *cmdline, const char *option)
+static int
+__cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
+ const char *option)
{
char c;
- int len, pos = 0, wstart = 0;
+ int pos = 0, wstart = 0;
const char *opptr = NULL;
enum {
st_wordstart = 0, /* Start of word/after whitespace */
@@ -37,11 +41,11 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
if (!cmdline)
return -1; /* No command line */
- len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE);
- if (!len)
- return 0;
-
- while (len--) {
+ /*
+ * This 'pos' check ensures we do not overrun
+ * a non-NULL-terminated 'cmdline'
+ */
+ while (pos < max_cmdline_size) {
c = *(char *)cmdline++;
pos++;
@@ -58,18 +62,35 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
/* fall through */
case st_wordcmp:
- if (!*opptr)
+ if (!*opptr) {
+ /*
+ * We matched all the way to the end of the
+ * option we were looking for. If the
+ * command-line has a space _or_ ends, then
+ * we matched!
+ */
if (!c || myisspace(c))
return wstart;
- else
- state = st_wordskip;
- else if (!c)
+ /*
+ * We hit the end of the option, but _not_
+ * the end of a word on the cmdline. Not
+ * a match.
+ */
+ } else if (!c) {
+ /*
+ * Hit the NULL terminator on the end of
+ * cmdline.
+ */
return 0;
- else if (c != *opptr++)
- state = st_wordskip;
- else if (!len) /* last word and is matching */
- return wstart;
- break;
+ } else if (c == *opptr++) {
+ /*
+ * We are currently matching, so continue
+ * to the next character on the cmdline.
+ */
+ break;
+ }
+ state = st_wordskip;
+ /* fall through */
case st_wordskip:
if (!c)
@@ -82,3 +103,8 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
return 0; /* Buffer overrun */
}
+
+int cmdline_find_option_bool(const char *cmdline, const char *option)
+{
+ return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
+}
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
index 009f982..24ef1c2 100644
--- a/arch/x86/lib/copy_page_64.S
+++ b/arch/x86/lib/copy_page_64.S
@@ -1,7 +1,7 @@
/* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
#include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
/*
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
index 982ce34..2b0ef26 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -10,7 +10,7 @@
#include <asm/current.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
#include <asm/asm.h>
#include <asm/smap.h>
@@ -232,17 +232,31 @@ ENDPROC(copy_user_enhanced_fast_string)
/*
* copy_user_nocache - Uncached memory copy with exception handling
- * This will force destination/source out of cache for more performance.
+ * This will force destination out of cache for more performance.
+ *
+ * Note: Cached memory copy is used when destination or size is not
+ * naturally aligned. That is:
+ * - Require 8-byte alignment when size is 8 bytes or larger.
+ * - Require 4-byte alignment when size is 4 bytes.
*/
ENTRY(__copy_user_nocache)
ASM_STAC
+
+ /* If size is less than 8 bytes, go to 4-byte copy */
cmpl $8,%edx
- jb 20f /* less then 8 bytes, go to byte copy loop */
+ jb .L_4b_nocache_copy_entry
+
+ /* If destination is not 8-byte aligned, "cache" copy to align it */
ALIGN_DESTINATION
+
+ /* Set 4x8-byte copy count and remainder */
movl %edx,%ecx
andl $63,%edx
shrl $6,%ecx
- jz 17f
+ jz .L_8b_nocache_copy_entry /* jump if count is 0 */
+
+ /* Perform 4x8-byte nocache loop-copy */
+.L_4x8b_nocache_copy_loop:
1: movq (%rsi),%r8
2: movq 1*8(%rsi),%r9
3: movq 2*8(%rsi),%r10
@@ -262,60 +276,106 @@ ENTRY(__copy_user_nocache)
leaq 64(%rsi),%rsi
leaq 64(%rdi),%rdi
decl %ecx
- jnz 1b
-17: movl %edx,%ecx
+ jnz .L_4x8b_nocache_copy_loop
+
+ /* Set 8-byte copy count and remainder */
+.L_8b_nocache_copy_entry:
+ movl %edx,%ecx
andl $7,%edx
shrl $3,%ecx
- jz 20f
-18: movq (%rsi),%r8
-19: movnti %r8,(%rdi)
+ jz .L_4b_nocache_copy_entry /* jump if count is 0 */
+
+ /* Perform 8-byte nocache loop-copy */
+.L_8b_nocache_copy_loop:
+20: movq (%rsi),%r8
+21: movnti %r8,(%rdi)
leaq 8(%rsi),%rsi
leaq 8(%rdi),%rdi
decl %ecx
- jnz 18b
-20: andl %edx,%edx
- jz 23f
+ jnz .L_8b_nocache_copy_loop
+
+ /* If no byte left, we're done */
+.L_4b_nocache_copy_entry:
+ andl %edx,%edx
+ jz .L_finish_copy
+
+ /* If destination is not 4-byte aligned, go to byte copy: */
+ movl %edi,%ecx
+ andl $3,%ecx
+ jnz .L_1b_cache_copy_entry
+
+ /* Set 4-byte copy count (1 or 0) and remainder */
movl %edx,%ecx
-21: movb (%rsi),%al
-22: movb %al,(%rdi)
+ andl $3,%edx
+ shrl $2,%ecx
+ jz .L_1b_cache_copy_entry /* jump if count is 0 */
+
+ /* Perform 4-byte nocache copy: */
+30: movl (%rsi),%r8d
+31: movnti %r8d,(%rdi)
+ leaq 4(%rsi),%rsi
+ leaq 4(%rdi),%rdi
+
+ /* If no bytes left, we're done: */
+ andl %edx,%edx
+ jz .L_finish_copy
+
+ /* Perform byte "cache" loop-copy for the remainder */
+.L_1b_cache_copy_entry:
+ movl %edx,%ecx
+.L_1b_cache_copy_loop:
+40: movb (%rsi),%al
+41: movb %al,(%rdi)
incq %rsi
incq %rdi
decl %ecx
- jnz 21b
-23: xorl %eax,%eax
+ jnz .L_1b_cache_copy_loop
+
+ /* Finished copying; fence the prior stores */
+.L_finish_copy:
+ xorl %eax,%eax
ASM_CLAC
sfence
ret
.section .fixup,"ax"
-30: shll $6,%ecx
+.L_fixup_4x8b_copy:
+ shll $6,%ecx
addl %ecx,%edx
- jmp 60f
-40: lea (%rdx,%rcx,8),%rdx
- jmp 60f
-50: movl %ecx,%edx
-60: sfence
+ jmp .L_fixup_handle_tail
+.L_fixup_8b_copy:
+ lea (%rdx,%rcx,8),%rdx
+ jmp .L_fixup_handle_tail
+.L_fixup_4b_copy:
+ lea (%rdx,%rcx,4),%rdx
+ jmp .L_fixup_handle_tail
+.L_fixup_1b_copy:
+ movl %ecx,%edx
+.L_fixup_handle_tail:
+ sfence
jmp copy_user_handle_tail
.previous
- _ASM_EXTABLE(1b,30b)
- _ASM_EXTABLE(2b,30b)
- _ASM_EXTABLE(3b,30b)
- _ASM_EXTABLE(4b,30b)
- _ASM_EXTABLE(5b,30b)
- _ASM_EXTABLE(6b,30b)
- _ASM_EXTABLE(7b,30b)
- _ASM_EXTABLE(8b,30b)
- _ASM_EXTABLE(9b,30b)
- _ASM_EXTABLE(10b,30b)
- _ASM_EXTABLE(11b,30b)
- _ASM_EXTABLE(12b,30b)
- _ASM_EXTABLE(13b,30b)
- _ASM_EXTABLE(14b,30b)
- _ASM_EXTABLE(15b,30b)
- _ASM_EXTABLE(16b,30b)
- _ASM_EXTABLE(18b,40b)
- _ASM_EXTABLE(19b,40b)
- _ASM_EXTABLE(21b,50b)
- _ASM_EXTABLE(22b,50b)
+ _ASM_EXTABLE(1b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(2b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(3b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(4b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(5b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(6b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(7b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(8b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(9b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(10b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(11b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(12b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(13b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(14b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(15b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(16b,.L_fixup_4x8b_copy)
+ _ASM_EXTABLE(20b,.L_fixup_8b_copy)
+ _ASM_EXTABLE(21b,.L_fixup_8b_copy)
+ _ASM_EXTABLE(30b,.L_fixup_4b_copy)
+ _ASM_EXTABLE(31b,.L_fixup_4b_copy)
+ _ASM_EXTABLE(40b,.L_fixup_1b_copy)
+ _ASM_EXTABLE(41b,.L_fixup_1b_copy)
ENDPROC(__copy_user_nocache)
diff --git a/arch/x86/lib/cpu.c b/arch/x86/lib/cpu.c
new file mode 100644
index 0000000..aa417a9
--- /dev/null
+++ b/arch/x86/lib/cpu.c
@@ -0,0 +1,35 @@
+#include <linux/module.h>
+
+unsigned int x86_family(unsigned int sig)
+{
+ unsigned int x86;
+
+ x86 = (sig >> 8) & 0xf;
+
+ if (x86 == 0xf)
+ x86 += (sig >> 20) & 0xff;
+
+ return x86;
+}
+EXPORT_SYMBOL_GPL(x86_family);
+
+unsigned int x86_model(unsigned int sig)
+{
+ unsigned int fam, model;
+
+ fam = x86_family(sig);
+
+ model = (sig >> 4) & 0xf;
+
+ if (fam >= 0x6)
+ model += ((sig >> 16) & 0xf) << 4;
+
+ return model;
+}
+EXPORT_SYMBOL_GPL(x86_model);
+
+unsigned int x86_stepping(unsigned int sig)
+{
+ return sig & 0xf;
+}
+EXPORT_SYMBOL_GPL(x86_stepping);
diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
index 1318f75..28a6654 100644
--- a/arch/x86/lib/csum-wrappers_64.c
+++ b/arch/x86/lib/csum-wrappers_64.c
@@ -135,7 +135,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto, __wsum sum)
+ __u32 len, __u8 proto, __wsum sum)
{
__u64 rest, sum64;
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c
index e912b2f..2f07c29 100644
--- a/arch/x86/lib/delay.c
+++ b/arch/x86/lib/delay.c
@@ -102,7 +102,7 @@ static void delay_mwaitx(unsigned long __loops)
* Use cpu_tss as a cacheline-aligned, seldomly
* accessed per-cpu variable as the monitor target.
*/
- __monitorx(this_cpu_ptr(&cpu_tss), 0, 0);
+ __monitorx(raw_cpu_ptr(&cpu_tss), 0, 0);
/*
* AMD, like Intel, supports the EAX hint and EAX=0xf
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
index 16698bb..cbb8ee5 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -1,7 +1,7 @@
/* Copyright 2002 Andi Kleen */
#include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
/*
@@ -177,3 +177,120 @@ ENTRY(memcpy_orig)
.Lend:
retq
ENDPROC(memcpy_orig)
+
+#ifndef CONFIG_UML
+/*
+ * memcpy_mcsafe - memory copy with machine check exception handling
+ * Note that we only catch machine checks when reading the source addresses.
+ * Writes to target are posted and don't generate machine checks.
+ */
+ENTRY(memcpy_mcsafe)
+ cmpl $8, %edx
+ /* Less than 8 bytes? Go to byte copy loop */
+ jb .L_no_whole_words
+
+ /* Check for bad alignment of source */
+ testl $7, %esi
+ /* Already aligned */
+ jz .L_8byte_aligned
+
+ /* Copy one byte at a time until source is 8-byte aligned */
+ movl %esi, %ecx
+ andl $7, %ecx
+ subl $8, %ecx
+ negl %ecx
+ subl %ecx, %edx
+.L_copy_leading_bytes:
+ movb (%rsi), %al
+ movb %al, (%rdi)
+ incq %rsi
+ incq %rdi
+ decl %ecx
+ jnz .L_copy_leading_bytes
+
+.L_8byte_aligned:
+ /* Figure out how many whole cache lines (64-bytes) to copy */
+ movl %edx, %ecx
+ andl $63, %edx
+ shrl $6, %ecx
+ jz .L_no_whole_cache_lines
+
+ /* Loop copying whole cache lines */
+.L_cache_w0: movq (%rsi), %r8
+.L_cache_w1: movq 1*8(%rsi), %r9
+.L_cache_w2: movq 2*8(%rsi), %r10
+.L_cache_w3: movq 3*8(%rsi), %r11
+ movq %r8, (%rdi)
+ movq %r9, 1*8(%rdi)
+ movq %r10, 2*8(%rdi)
+ movq %r11, 3*8(%rdi)
+.L_cache_w4: movq 4*8(%rsi), %r8
+.L_cache_w5: movq 5*8(%rsi), %r9
+.L_cache_w6: movq 6*8(%rsi), %r10
+.L_cache_w7: movq 7*8(%rsi), %r11
+ movq %r8, 4*8(%rdi)
+ movq %r9, 5*8(%rdi)
+ movq %r10, 6*8(%rdi)
+ movq %r11, 7*8(%rdi)
+ leaq 64(%rsi), %rsi
+ leaq 64(%rdi), %rdi
+ decl %ecx
+ jnz .L_cache_w0
+
+ /* Are there any trailing 8-byte words? */
+.L_no_whole_cache_lines:
+ movl %edx, %ecx
+ andl $7, %edx
+ shrl $3, %ecx
+ jz .L_no_whole_words
+
+ /* Copy trailing words */
+.L_copy_trailing_words:
+ movq (%rsi), %r8
+ mov %r8, (%rdi)
+ leaq 8(%rsi), %rsi
+ leaq 8(%rdi), %rdi
+ decl %ecx
+ jnz .L_copy_trailing_words
+
+ /* Any trailing bytes? */
+.L_no_whole_words:
+ andl %edx, %edx
+ jz .L_done_memcpy_trap
+
+ /* Copy trailing bytes */
+ movl %edx, %ecx
+.L_copy_trailing_bytes:
+ movb (%rsi), %al
+ movb %al, (%rdi)
+ incq %rsi
+ incq %rdi
+ decl %ecx
+ jnz .L_copy_trailing_bytes
+
+ /* Copy successful. Return true */
+.L_done_memcpy_trap:
+ xorq %rax, %rax
+ ret
+ENDPROC(memcpy_mcsafe)
+
+ .section .fixup, "ax"
+ /* Return false for any failure */
+.L_memcpy_mcsafe_fail:
+ mov $1, %rax
+ ret
+
+ .previous
+
+ _ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w6, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_cache_w7, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_copy_trailing_words, .L_memcpy_mcsafe_fail)
+ _ASM_EXTABLE_FAULT(.L_copy_trailing_bytes, .L_memcpy_mcsafe_fail)
+#endif
diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
index ca2afdd..90ce01b 100644
--- a/arch/x86/lib/memmove_64.S
+++ b/arch/x86/lib/memmove_64.S
@@ -6,7 +6,7 @@
* - Copyright 2011 Fenghua Yu <fenghua.yu@intel.com>
*/
#include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
#undef memmove
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
index 2661fad..c9c8122 100644
--- a/arch/x86/lib/memset_64.S
+++ b/arch/x86/lib/memset_64.S
@@ -1,7 +1,7 @@
/* Copyright 2002 Andi Kleen, SuSE Labs */
#include <linux/linkage.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/alternative-asm.h>
.weak memset
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..004c861 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
#include <linux/module.h>
#include <linux/preempt.h>
#include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <asm/msr-trace.h>
struct msr *msrs_alloc(void)
{
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
{
return __flip_bit(msr, bit, false);
}
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+ trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+ trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+ trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 816488c..d388de7 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -353,8 +353,12 @@ AVXcode: 1
17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
18: Grp16 (1A)
19:
-1a: BNDCL Ev,Gv | BNDCU Ev,Gv | BNDMOV Gv,Ev | BNDLDX Gv,Ev,Gv
-1b: BNDCN Ev,Gv | BNDMOV Ev,Gv | BNDMK Gv,Ev | BNDSTX Ev,GV,Gv
+# Intel SDM opcode map does not list MPX instructions. For now using Gv for
+# bnd registers and Ev for everything else is OK because the instruction
+# decoder does not use the information except as an indication that there is
+# a ModR/M byte.
+1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
+1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
1c:
1d:
1e:
@@ -732,6 +736,12 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
# 0x0f 0x38 0xc0-0xff
+c8: sha1nexte Vdq,Wdq
+c9: sha1msg1 Vdq,Wdq
+ca: sha1msg2 Vdq,Wdq
+cb: sha256rnds2 Vdq,Wdq
+cc: sha256msg1 Vdq,Wdq
+cd: sha256msg2 Vdq,Wdq
db: VAESIMC Vdq,Wdq (66),(v1)
dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -790,6 +800,7 @@ AVXcode: 3
61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
+cc: sha1rnds4 Vdq,Wdq,Ib
df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
f0: RORX Gy,Ey,Ib (F2),(v)
EndTable
@@ -874,7 +885,7 @@ GrpTable: Grp7
2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
3: LIDT Ms
4: SMSW Mw/Rv
-5:
+5: rdpkru (110),(11B) | wrpkru (111),(11B)
6: LMSW Ew
7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
EndTable
@@ -888,6 +899,9 @@ EndTable
GrpTable: Grp9
1: CMPXCHG8B/16B Mq/Mdq
+3: xrstors
+4: xsavec
+5: xsaves
6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
EndTable
@@ -932,8 +946,8 @@ GrpTable: Grp15
3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
4: XSAVE
5: XRSTOR | lfence (11B)
-6: XSAVEOPT | mfence (11B)
-7: clflush | sfence (11B)
+6: XSAVEOPT | clwb (66) | mfence (11B)
+7: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B)
EndTable
GrpTable: Grp16
diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c
index dd76a05..024f6e9 100644
--- a/arch/x86/math-emu/fpu_aux.c
+++ b/arch/x86/math-emu/fpu_aux.c
@@ -169,6 +169,76 @@ void fxch_i(void)
fpu_tag_word = tag_word;
}
+static void fcmovCC(void)
+{
+ /* fcmovCC st(i) */
+ int i = FPU_rm;
+ FPU_REG *st0_ptr = &st(0);
+ FPU_REG *sti_ptr = &st(i);
+ long tag_word = fpu_tag_word;
+ int regnr = top & 7;
+ int regnri = (top + i) & 7;
+ u_char sti_tag = (tag_word >> (regnri * 2)) & 3;
+
+ if (sti_tag == TAG_Empty) {
+ FPU_stack_underflow();
+ clear_C1();
+ return;
+ }
+ reg_copy(sti_ptr, st0_ptr);
+ tag_word &= ~(3 << (regnr * 2));
+ tag_word |= (sti_tag << (regnr * 2));
+ fpu_tag_word = tag_word;
+}
+
+void fcmovb(void)
+{
+ if (FPU_EFLAGS & X86_EFLAGS_CF)
+ fcmovCC();
+}
+
+void fcmove(void)
+{
+ if (FPU_EFLAGS & X86_EFLAGS_ZF)
+ fcmovCC();
+}
+
+void fcmovbe(void)
+{
+ if (FPU_EFLAGS & (X86_EFLAGS_CF|X86_EFLAGS_ZF))
+ fcmovCC();
+}
+
+void fcmovu(void)
+{
+ if (FPU_EFLAGS & X86_EFLAGS_PF)
+ fcmovCC();
+}
+
+void fcmovnb(void)
+{
+ if (!(FPU_EFLAGS & X86_EFLAGS_CF))
+ fcmovCC();
+}
+
+void fcmovne(void)
+{
+ if (!(FPU_EFLAGS & X86_EFLAGS_ZF))
+ fcmovCC();
+}
+
+void fcmovnbe(void)
+{
+ if (!(FPU_EFLAGS & (X86_EFLAGS_CF|X86_EFLAGS_ZF)))
+ fcmovCC();
+}
+
+void fcmovnu(void)
+{
+ if (!(FPU_EFLAGS & X86_EFLAGS_PF))
+ fcmovCC();
+}
+
void ffree_(void)
{
/* ffree st(i) */
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index 4dae511..afbc4d8 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -71,7 +71,7 @@
#include "fpu_system.h"
-#include <asm/sigcontext.h> /* for struct _fpstate */
+#include <uapi/asm/sigcontext.h> /* for struct _fpstate */
#include <asm/math_emu.h>
#include <linux/linkage.h>
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
index 3d8f2e4..e945fed 100644
--- a/arch/x86/math-emu/fpu_entry.c
+++ b/arch/x86/math-emu/fpu_entry.c
@@ -40,49 +40,33 @@
#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
-#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
+/* fcmovCC and f(u)comi(p) are enabled if CPUID(1).EDX(15) "cmov" is set */
-/* WARNING: These codes are not documented by Intel in their 80486 manual
- and may not work on FPU clones or later Intel FPUs. */
-
-/* Changes to support the un-doc codes provided by Linus Torvalds. */
-
-#define _d9_d8_ fstp_i /* unofficial code (19) */
-#define _dc_d0_ fcom_st /* unofficial code (14) */
-#define _dc_d8_ fcompst /* unofficial code (1c) */
-#define _dd_c8_ fxch_i /* unofficial code (0d) */
-#define _de_d0_ fcompst /* unofficial code (16) */
-#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
-#define _df_c8_ fxch_i /* unofficial code (0f) */
-#define _df_d0_ fstp_i /* unofficial code (17) */
-#define _df_d8_ fstp_i /* unofficial code (1f) */
+/* WARNING: "u" entries are not documented by Intel in their 80486 manual
+ and may not work on FPU clones or later Intel FPUs.
+ Changes to support them provided by Linus Torvalds. */
static FUNC const st_instr_table[64] = {
- fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
- fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
- fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
- fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
- fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
- fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
- fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
- fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+/* Opcode: d8 d9 da db */
+/* dc dd de df */
+/* c0..7 */ fadd__, fld_i_, fcmovb, fcmovnb,
+/* c0..7 */ fadd_i, ffree_, faddp_, ffreep,/*u*/
+/* c8..f */ fmul__, fxch_i, fcmove, fcmovne,
+/* c8..f */ fmul_i, fxch_i,/*u*/ fmulp_, fxch_i,/*u*/
+/* d0..7 */ fcom_st, fp_nop, fcmovbe, fcmovnbe,
+/* d0..7 */ fcom_st,/*u*/ fst_i_, fcompst,/*u*/ fstp_i,/*u*/
+/* d8..f */ fcompst, fstp_i,/*u*/ fcmovu, fcmovnu,
+/* d8..f */ fcompst,/*u*/ fstp_i, fcompp, fstp_i,/*u*/
+/* e0..7 */ fsub__, FPU_etc, __BAD__, finit_,
+/* e0..7 */ fsubri, fucom_, fsubrp, fstsw_,
+/* e8..f */ fsubr_, fconst, fucompp, fucomi_,
+/* e8..f */ fsub_i, fucomp, fsubp_, fucomip,
+/* f0..7 */ fdiv__, FPU_triga, __BAD__, fcomi_,
+/* f0..7 */ fdivri, __BAD__, fdivrp, fcomip,
+/* f8..f */ fdivr_, FPU_trigb, __BAD__, __BAD__,
+/* f8..f */ fdiv_i, __BAD__, fdivp_, __BAD__,
};
-#else /* Support only documented FPU op-codes */
-
-static FUNC const st_instr_table[64] = {
- fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
- fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
- fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
- fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
- fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
- fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
- fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
- fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
-};
-
-#endif /* NO_UNDOC_CODE */
-
#define _NONE_ 0 /* Take no special action */
#define _REG0_ 1 /* Need to check for not empty st(0) */
#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
@@ -94,36 +78,18 @@ static FUNC const st_instr_table[64] = {
#define _REGIc 0 /* Compare st(0) and st(rm) */
#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
-#ifndef NO_UNDOC_CODE
-
-/* Un-documented FPU op-codes supported by default. (see above) */
-
static u_char const type_table[64] = {
- _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
- _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
- _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
- _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
- _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
- _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+/* Opcode: d8 d9 da db dc dd de df */
+/* c0..7 */ _REGI_, _NONE_, _REGIn, _REGIn, _REGIi, _REGi_, _REGIp, _REGi_,
+/* c8..f */ _REGI_, _REGIn, _REGIn, _REGIn, _REGIi, _REGI_, _REGIp, _REGI_,
+/* d0..7 */ _REGIc, _NONE_, _REGIn, _REGIn, _REGIc, _REG0_, _REGIc, _REG0_,
+/* d8..f */ _REGIc, _REG0_, _REGIn, _REGIn, _REGIc, _REG0_, _REGIc, _REG0_,
+/* e0..7 */ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+/* e8..f */ _REGI_, _NONE_, _REGIc, _REGIc, _REGIi, _REGIc, _REGIp, _REGIc,
+/* f0..7 */ _REGI_, _NONE_, _null_, _REGIc, _REGIi, _null_, _REGIp, _REGIc,
+/* f8..f */ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
};
-#else /* Support only documented FPU op-codes */
-
-static u_char const type_table[64] = {
- _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
- _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
- _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
- _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
- _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
-};
-
-#endif /* NO_UNDOC_CODE */
-
#ifdef RE_ENTRANT_CHECKING
u_char emulating = 0;
#endif /* RE_ENTRANT_CHECKING */
diff --git a/arch/x86/math-emu/fpu_proto.h b/arch/x86/math-emu/fpu_proto.h
index 9779df4..caff438 100644
--- a/arch/x86/math-emu/fpu_proto.h
+++ b/arch/x86/math-emu/fpu_proto.h
@@ -46,6 +46,14 @@ extern void fstsw_(void);
extern void fp_nop(void);
extern void fld_i_(void);
extern void fxch_i(void);
+extern void fcmovb(void);
+extern void fcmove(void);
+extern void fcmovbe(void);
+extern void fcmovu(void);
+extern void fcmovnb(void);
+extern void fcmovne(void);
+extern void fcmovnbe(void);
+extern void fcmovnu(void);
extern void ffree_(void);
extern void ffreep(void);
extern void fst_i_(void);
@@ -108,6 +116,10 @@ extern void fcompp(void);
extern void fucom_(void);
extern void fucomp(void);
extern void fucompp(void);
+extern void fcomi_(void);
+extern void fcomip(void);
+extern void fucomi_(void);
+extern void fucomip(void);
/* reg_constant.c */
extern void fconst(void);
/* reg_ld_str.c */
diff --git a/arch/x86/math-emu/load_store.c b/arch/x86/math-emu/load_store.c
index 2931ff3..95228ff 100644
--- a/arch/x86/math-emu/load_store.c
+++ b/arch/x86/math-emu/load_store.c
@@ -33,11 +33,12 @@
#define pop_0() { FPU_settag0(TAG_Empty); top++; }
+/* index is a 5-bit value: (3-bit FPU_modrm.reg field | opcode[2,1]) */
static u_char const type_table[32] = {
- _PUSH_, _PUSH_, _PUSH_, _PUSH_,
- _null_, _null_, _null_, _null_,
- _REG0_, _REG0_, _REG0_, _REG0_,
- _REG0_, _REG0_, _REG0_, _REG0_,
+ _PUSH_, _PUSH_, _PUSH_, _PUSH_, /* /0: d9:fld f32, db:fild m32, dd:fld f64, df:fild m16 */
+ _null_, _REG0_, _REG0_, _REG0_, /* /1: d9:undef, db,dd,df:fisttp m32/64/16 */
+ _REG0_, _REG0_, _REG0_, _REG0_, /* /2: d9:fst f32, db:fist m32, dd:fst f64, df:fist m16 */
+ _REG0_, _REG0_, _REG0_, _REG0_, /* /3: d9:fstp f32, db:fistp m32, dd:fstp f64, df:fistp m16 */
_NONE_, _null_, _NONE_, _PUSH_,
_NONE_, _PUSH_, _null_, _PUSH_,
_NONE_, _null_, _NONE_, _REG0_,
@@ -45,15 +46,19 @@ static u_char const type_table[32] = {
};
u_char const data_sizes_16[32] = {
- 4, 4, 8, 2, 0, 0, 0, 0,
- 4, 4, 8, 2, 4, 4, 8, 2,
+ 4, 4, 8, 2,
+ 0, 4, 8, 2, /* /1: d9:undef, db,dd,df:fisttp */
+ 4, 4, 8, 2,
+ 4, 4, 8, 2,
14, 0, 94, 10, 2, 10, 0, 8,
14, 0, 94, 10, 2, 10, 2, 8
};
static u_char const data_sizes_32[32] = {
- 4, 4, 8, 2, 0, 0, 0, 0,
- 4, 4, 8, 2, 4, 4, 8, 2,
+ 4, 4, 8, 2,
+ 0, 4, 8, 2, /* /1: d9:undef, db,dd,df:fisttp */
+ 4, 4, 8, 2,
+ 4, 4, 8, 2,
28, 0, 108, 10, 2, 10, 0, 8,
28, 0, 108, 10, 2, 10, 2, 8
};
@@ -65,6 +70,7 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
FPU_REG *st0_ptr;
u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
u_char loaded_tag;
+ int sv_cw;
st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
@@ -111,7 +117,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
}
switch (type) {
- case 000: /* fld m32real */
+ /* type is a 5-bit value: (3-bit FPU_modrm.reg field | opcode[2,1]) */
+ case 000: /* fld m32real (d9 /0) */
clear_C1();
loaded_tag =
FPU_load_single((float __user *)data_address, &loaded_data);
@@ -123,13 +130,13 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
}
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
- case 001: /* fild m32int */
+ case 001: /* fild m32int (db /0) */
clear_C1();
loaded_tag =
FPU_load_int32((long __user *)data_address, &loaded_data);
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
- case 002: /* fld m64real */
+ case 002: /* fld m64real (dd /0) */
clear_C1();
loaded_tag =
FPU_load_double((double __user *)data_address,
@@ -142,12 +149,44 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
}
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
- case 003: /* fild m16int */
+ case 003: /* fild m16int (df /0) */
clear_C1();
loaded_tag =
FPU_load_int16((short __user *)data_address, &loaded_data);
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
+ /* case 004: undefined (d9 /1) */
+ /* fisttp are enabled if CPUID(1).ECX(0) "sse3" is set */
+ case 005: /* fisttp m32int (db /1) */
+ clear_C1();
+ sv_cw = control_word;
+ control_word |= RC_CHOP;
+ if (FPU_store_int32
+ (st0_ptr, st0_tag, (long __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ control_word = sv_cw;
+ break;
+ case 006: /* fisttp m64int (dd /1) */
+ clear_C1();
+ sv_cw = control_word;
+ control_word |= RC_CHOP;
+ if (FPU_store_int64
+ (st0_ptr, st0_tag, (long long __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ control_word = sv_cw;
+ break;
+ case 007: /* fisttp m16int (df /1) */
+ clear_C1();
+ sv_cw = control_word;
+ control_word |= RC_CHOP;
+ if (FPU_store_int16
+ (st0_ptr, st0_tag, (short __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ control_word = sv_cw;
+ break;
case 010: /* fst m32real */
clear_C1();
FPU_store_single(st0_ptr, st0_tag,
diff --git a/arch/x86/math-emu/reg_compare.c b/arch/x86/math-emu/reg_compare.c
index ecce55f..b77360f 100644
--- a/arch/x86/math-emu/reg_compare.c
+++ b/arch/x86/math-emu/reg_compare.c
@@ -249,6 +249,54 @@ static int compare_st_st(int nr)
return 0;
}
+static int compare_i_st_st(int nr)
+{
+ int f, c;
+ FPU_REG *st_ptr;
+
+ if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+ FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
+ }
+
+ partial_status &= ~SW_C0;
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN) {
+ FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ }
+
+ switch (c & 7) {
+ case COMP_A_lt_B:
+ f = X86_EFLAGS_CF;
+ break;
+ case COMP_A_eq_B:
+ f = X86_EFLAGS_ZF;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x122);
+ f = 0;
+ break;
+#endif /* PARANOID */
+ }
+ FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | f;
+ if (c & COMP_Denormal) {
+ return denormal_operand() < 0;
+ }
+ return 0;
+}
+
static int compare_u_st_st(int nr)
{
int f = 0, c;
@@ -299,6 +347,58 @@ static int compare_u_st_st(int nr)
return 0;
}
+static int compare_ui_st_st(int nr)
+{
+ int f = 0, c;
+ FPU_REG *st_ptr;
+
+ if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+ FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
+ }
+
+ partial_status &= ~SW_C0;
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN) {
+ FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+ if (c & COMP_SNaN) { /* This is the only difference between
+ un-ordered and ordinary comparisons */
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ }
+ return 0;
+ }
+
+ switch (c & 7) {
+ case COMP_A_lt_B:
+ f = X86_EFLAGS_CF;
+ break;
+ case COMP_A_eq_B:
+ f = X86_EFLAGS_ZF;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL | 0x123);
+ f = 0;
+ break;
+#endif /* PARANOID */
+ }
+ FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | f;
+ if (c & COMP_Denormal) {
+ return denormal_operand() < 0;
+ }
+ return 0;
+}
+
/*---------------------------------------------------------------------------*/
void fcom_st(void)
@@ -348,3 +448,31 @@ void fucompp(void)
} else
FPU_illegal();
}
+
+/* P6+ compare-to-EFLAGS ops */
+
+void fcomi_(void)
+{
+ /* fcomi st(i) */
+ compare_i_st_st(FPU_rm);
+}
+
+void fcomip(void)
+{
+ /* fcomip st(i) */
+ if (!compare_i_st_st(FPU_rm))
+ FPU_pop();
+}
+
+void fucomi_(void)
+{
+ /* fucomi st(i) */
+ compare_ui_st_st(FPU_rm);
+}
+
+void fucomip(void)
+{
+ /* fucomip st(i) */
+ if (!compare_ui_st_st(FPU_rm))
+ FPU_pop();
+}
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index a482d10..f9d38a4 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_SMP) += tlb.o
obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o
+obj-$(CONFIG_X86_PTDUMP_CORE) += dump_pagetables.o
+obj-$(CONFIG_X86_PTDUMP) += debug_pagetables.o
obj-$(CONFIG_HIGHMEM) += highmem_32.o
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
new file mode 100644
index 0000000..bfcffdf
--- /dev/null
+++ b/arch/x86/mm/debug_pagetables.c
@@ -0,0 +1,46 @@
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/pgtable.h>
+
+static int ptdump_show(struct seq_file *m, void *v)
+{
+ ptdump_walk_pgd_level(m, NULL);
+ return 0;
+}
+
+static int ptdump_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, ptdump_show, NULL);
+}
+
+static const struct file_operations ptdump_fops = {
+ .owner = THIS_MODULE,
+ .open = ptdump_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *pe;
+
+static int __init pt_dump_debug_init(void)
+{
+ pe = debugfs_create_file("kernel_page_tables", S_IRUSR, NULL, NULL,
+ &ptdump_fops);
+ if (!pe)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __exit pt_dump_debug_exit(void)
+{
+ debugfs_remove_recursive(pe);
+}
+
+module_init(pt_dump_debug_init);
+module_exit(pt_dump_debug_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
+MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables");
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index f0cedf3..99bfb19 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -32,6 +32,8 @@ struct pg_state {
const struct addr_marker *marker;
unsigned long lines;
bool to_dmesg;
+ bool check_wx;
+ unsigned long wx_pages;
};
struct addr_marker {
@@ -87,7 +89,7 @@ static struct addr_marker address_markers[] = {
{ 0/* VMALLOC_START */, "vmalloc() Area" },
{ 0/*VMALLOC_END*/, "vmalloc() End" },
# ifdef CONFIG_HIGHMEM
- { 0/*PKMAP_BASE*/, "Persisent kmap() Area" },
+ { 0/*PKMAP_BASE*/, "Persistent kmap() Area" },
# endif
{ 0/*FIXADDR_START*/, "Fixmap Area" },
#endif
@@ -155,7 +157,7 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
pt_dump_cont_printf(m, dmsg, " ");
if ((level == 4 && pr & _PAGE_PAT) ||
((level == 3 || level == 2) && pr & _PAGE_PAT_LARGE))
- pt_dump_cont_printf(m, dmsg, "pat ");
+ pt_dump_cont_printf(m, dmsg, "PAT ");
else
pt_dump_cont_printf(m, dmsg, " ");
if (pr & _PAGE_GLOBAL)
@@ -198,8 +200,8 @@ static void note_page(struct seq_file *m, struct pg_state *st,
* we have now. "break" is either changing perms, levels or
* address space marker.
*/
- prot = pgprot_val(new_prot) & PTE_FLAGS_MASK;
- cur = pgprot_val(st->current_prot) & PTE_FLAGS_MASK;
+ prot = pgprot_val(new_prot);
+ cur = pgprot_val(st->current_prot);
if (!st->level) {
/* First entry */
@@ -214,6 +216,16 @@ static void note_page(struct seq_file *m, struct pg_state *st,
const char *unit = units;
unsigned long delta;
int width = sizeof(unsigned long) * 2;
+ pgprotval_t pr = pgprot_val(st->current_prot);
+
+ if (st->check_wx && (pr & _PAGE_RW) && !(pr & _PAGE_NX)) {
+ WARN_ONCE(1,
+ "x86/mm: Found insecure W+X mapping at address %p/%pS\n",
+ (void *)st->start_address,
+ (void *)st->start_address);
+ st->wx_pages += (st->current_address -
+ st->start_address) / PAGE_SIZE;
+ }
/*
* Now print the actual finished series
@@ -269,13 +281,13 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
{
int i;
pte_t *start;
+ pgprotval_t prot;
start = (pte_t *) pmd_page_vaddr(addr);
for (i = 0; i < PTRS_PER_PTE; i++) {
- pgprot_t prot = pte_pgprot(*start);
-
+ prot = pte_flags(*start);
st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
- note_page(m, st, prot, 4);
+ note_page(m, st, __pgprot(prot), 4);
start++;
}
}
@@ -287,18 +299,19 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
{
int i;
pmd_t *start;
+ pgprotval_t prot;
start = (pmd_t *) pud_page_vaddr(addr);
for (i = 0; i < PTRS_PER_PMD; i++) {
st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT);
if (!pmd_none(*start)) {
- pgprotval_t prot = pmd_val(*start) & PTE_FLAGS_MASK;
-
- if (pmd_large(*start) || !pmd_present(*start))
+ if (pmd_large(*start) || !pmd_present(*start)) {
+ prot = pmd_flags(*start);
note_page(m, st, __pgprot(prot), 3);
- else
+ } else {
walk_pte_level(m, st, *start,
P + i * PMD_LEVEL_MULT);
+ }
} else
note_page(m, st, __pgprot(0), 3);
start++;
@@ -318,19 +331,20 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
{
int i;
pud_t *start;
+ pgprotval_t prot;
start = (pud_t *) pgd_page_vaddr(addr);
for (i = 0; i < PTRS_PER_PUD; i++) {
st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT);
if (!pud_none(*start)) {
- pgprotval_t prot = pud_val(*start) & PTE_FLAGS_MASK;
-
- if (pud_large(*start) || !pud_present(*start))
+ if (pud_large(*start) || !pud_present(*start)) {
+ prot = pud_flags(*start);
note_page(m, st, __pgprot(prot), 2);
- else
+ } else {
walk_pmd_level(m, st, *start,
P + i * PUD_LEVEL_MULT);
+ }
} else
note_page(m, st, __pgprot(0), 2);
@@ -344,13 +358,29 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
#define pgd_none(a) pud_none(__pud(pgd_val(a)))
#endif
-void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
+static inline bool is_hypervisor_range(int idx)
+{
+#ifdef CONFIG_X86_64
+ /*
+ * ffff800000000000 - ffff87ffffffffff is reserved for
+ * the hypervisor.
+ */
+ return (idx >= pgd_index(__PAGE_OFFSET) - 16) &&
+ (idx < pgd_index(__PAGE_OFFSET));
+#else
+ return false;
+#endif
+}
+
+static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
+ bool checkwx)
{
#ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) &init_level4_pgt;
#else
pgd_t *start = swapper_pg_dir;
#endif
+ pgprotval_t prot;
int i;
struct pg_state st = {};
@@ -359,16 +389,20 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
st.to_dmesg = true;
}
+ st.check_wx = checkwx;
+ if (checkwx)
+ st.wx_pages = 0;
+
for (i = 0; i < PTRS_PER_PGD; i++) {
st.current_address = normalize_addr(i * PGD_LEVEL_MULT);
- if (!pgd_none(*start)) {
- pgprotval_t prot = pgd_val(*start) & PTE_FLAGS_MASK;
-
- if (pgd_large(*start) || !pgd_present(*start))
+ if (!pgd_none(*start) && !is_hypervisor_range(i)) {
+ if (pgd_large(*start) || !pgd_present(*start)) {
+ prot = pgd_flags(*start);
note_page(m, &st, __pgprot(prot), 1);
- else
+ } else {
walk_pud_level(m, &st, *start,
i * PGD_LEVEL_MULT);
+ }
} else
note_page(m, &st, __pgprot(0), 1);
@@ -378,30 +412,28 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
/* Flush out the last page */
st.current_address = normalize_addr(PTRS_PER_PGD*PGD_LEVEL_MULT);
note_page(m, &st, __pgprot(0), 0);
+ if (!checkwx)
+ return;
+ if (st.wx_pages)
+ pr_info("x86/mm: Checked W+X mappings: FAILED, %lu W+X pages found.\n",
+ st.wx_pages);
+ else
+ pr_info("x86/mm: Checked W+X mappings: passed, no W+X pages found.\n");
}
-static int ptdump_show(struct seq_file *m, void *v)
+void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
{
- ptdump_walk_pgd_level(m, NULL);
- return 0;
+ ptdump_walk_pgd_level_core(m, pgd, false);
}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
-static int ptdump_open(struct inode *inode, struct file *filp)
+void ptdump_walk_pgd_level_checkwx(void)
{
- return single_open(filp, ptdump_show, NULL);
+ ptdump_walk_pgd_level_core(NULL, NULL, true);
}
-static const struct file_operations ptdump_fops = {
- .open = ptdump_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int pt_dump_init(void)
+static int __init pt_dump_init(void)
{
- struct dentry *pe;
-
#ifdef CONFIG_X86_32
/* Not a compile-time constant on x86-32 */
address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
@@ -412,11 +444,6 @@ static int pt_dump_init(void)
address_markers[FIXADDR_START_NR].start_address = FIXADDR_START;
#endif
- pe = debugfs_create_file("kernel_page_tables", 0600, NULL, NULL,
- &ptdump_fops);
- if (!pe)
- return -ENOMEM;
-
return 0;
}
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 903ec1e..9dd7e4b 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -3,6 +3,9 @@
#include <linux/sort.h>
#include <asm/uaccess.h>
+typedef bool (*ex_handler_t)(const struct exception_table_entry *,
+ struct pt_regs *, int);
+
static inline unsigned long
ex_insn_addr(const struct exception_table_entry *x)
{
@@ -13,11 +16,56 @@ ex_fixup_addr(const struct exception_table_entry *x)
{
return (unsigned long)&x->fixup + x->fixup;
}
+static inline ex_handler_t
+ex_fixup_handler(const struct exception_table_entry *x)
+{
+ return (ex_handler_t)((unsigned long)&x->handler + x->handler);
+}
-int fixup_exception(struct pt_regs *regs)
+bool ex_handler_default(const struct exception_table_entry *fixup,
+ struct pt_regs *regs, int trapnr)
{
- const struct exception_table_entry *fixup;
- unsigned long new_ip;
+ regs->ip = ex_fixup_addr(fixup);
+ return true;
+}
+EXPORT_SYMBOL(ex_handler_default);
+
+bool ex_handler_fault(const struct exception_table_entry *fixup,
+ struct pt_regs *regs, int trapnr)
+{
+ regs->ip = ex_fixup_addr(fixup);
+ regs->ax = trapnr;
+ return true;
+}
+EXPORT_SYMBOL_GPL(ex_handler_fault);
+
+bool ex_handler_ext(const struct exception_table_entry *fixup,
+ struct pt_regs *regs, int trapnr)
+{
+ /* Special hack for uaccess_err */
+ current_thread_info()->uaccess_err = 1;
+ regs->ip = ex_fixup_addr(fixup);
+ return true;
+}
+EXPORT_SYMBOL(ex_handler_ext);
+
+bool ex_has_fault_handler(unsigned long ip)
+{
+ const struct exception_table_entry *e;
+ ex_handler_t handler;
+
+ e = search_exception_tables(ip);
+ if (!e)
+ return false;
+ handler = ex_fixup_handler(e);
+
+ return handler == ex_handler_fault;
+}
+
+int fixup_exception(struct pt_regs *regs, int trapnr)
+{
+ const struct exception_table_entry *e;
+ ex_handler_t handler;
#ifdef CONFIG_PNPBIOS
if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
@@ -33,42 +81,34 @@ int fixup_exception(struct pt_regs *regs)
}
#endif
- fixup = search_exception_tables(regs->ip);
- if (fixup) {
- new_ip = ex_fixup_addr(fixup);
-
- if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
- /* Special hack for uaccess_err */
- current_thread_info()->uaccess_err = 1;
- new_ip -= 0x7ffffff0;
- }
- regs->ip = new_ip;
- return 1;
- }
+ e = search_exception_tables(regs->ip);
+ if (!e)
+ return 0;
- return 0;
+ handler = ex_fixup_handler(e);
+ return handler(e, regs, trapnr);
}
/* Restricted version used during very early boot */
int __init early_fixup_exception(unsigned long *ip)
{
- const struct exception_table_entry *fixup;
+ const struct exception_table_entry *e;
unsigned long new_ip;
+ ex_handler_t handler;
- fixup = search_exception_tables(*ip);
- if (fixup) {
- new_ip = ex_fixup_addr(fixup);
+ e = search_exception_tables(*ip);
+ if (!e)
+ return 0;
- if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
- /* uaccess handling not supported during early boot */
- return 0;
- }
+ new_ip = ex_fixup_addr(e);
+ handler = ex_fixup_handler(e);
- *ip = new_ip;
- return 1;
- }
+ /* special handling not supported during early boot */
+ if (handler != ex_handler_default)
+ return 0;
- return 0;
+ *ip = new_ip;
+ return 1;
}
/*
@@ -133,6 +173,8 @@ void sort_extable(struct exception_table_entry *start,
i += 4;
p->fixup += i;
i += 4;
+ p->handler += i;
+ i += 4;
}
sort(start, finish - start, sizeof(struct exception_table_entry),
@@ -145,6 +187,8 @@ void sort_extable(struct exception_table_entry *start,
i += 4;
p->fixup -= i;
i += 4;
+ p->handler -= i;
+ i += 4;
}
}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index eef44d9..03898ae 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -287,6 +287,9 @@ static noinline int vmalloc_fault(unsigned long address)
if (!pmd_k)
return -1;
+ if (pmd_huge(*pmd_k))
+ return 0;
+
pte_k = pte_offset_kernel(pmd_k, address);
if (!pte_present(*pte_k))
return -1;
@@ -360,8 +363,6 @@ void vmalloc_sync_all(void)
* 64-bit:
*
* Handle a fault on the vmalloc area
- *
- * This assumes no large pages in there.
*/
static noinline int vmalloc_fault(unsigned long address)
{
@@ -403,17 +404,23 @@ static noinline int vmalloc_fault(unsigned long address)
if (pud_none(*pud_ref))
return -1;
- if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
+ if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
BUG();
+ if (pud_huge(*pud))
+ return 0;
+
pmd = pmd_offset(pud, address);
pmd_ref = pmd_offset(pud_ref, address);
if (pmd_none(*pmd_ref))
return -1;
- if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+ if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
BUG();
+ if (pmd_huge(*pmd))
+ return 0;
+
pte_ref = pte_offset_kernel(pmd_ref, address);
if (!pte_present(*pte_ref))
return -1;
@@ -656,7 +663,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
int sig;
/* Are we prepared to handle this kernel fault? */
- if (fixup_exception(regs)) {
+ if (fixup_exception(regs, X86_TRAP_PF)) {
/*
* Any interrupt that takes a fault gets the fixup. This makes
* the below recursive fault logic only apply to a faults from
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index 81bf3d2..f8d0b5e 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -9,6 +9,7 @@
#include <linux/vmstat.h>
#include <linux/highmem.h>
#include <linux/swap.h>
+#include <linux/memremap.h>
#include <asm/pgtable.h>
@@ -63,6 +64,16 @@ retry:
#endif
}
+static void undo_dev_pagemap(int *nr, int nr_start, struct page **pages)
+{
+ while ((*nr) - nr_start) {
+ struct page *page = pages[--(*nr)];
+
+ ClearPageReferenced(page);
+ put_page(page);
+ }
+}
+
/*
* The performance critical leaf functions are made noinline otherwise gcc
* inlines everything into a single function which results in too much
@@ -71,7 +82,9 @@ retry:
static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
+ struct dev_pagemap *pgmap = NULL;
unsigned long mask;
+ int nr_start = *nr;
pte_t *ptep;
mask = _PAGE_PRESENT|_PAGE_USER;
@@ -89,13 +102,21 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
return 0;
}
- if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
+ if (pte_devmap(pte)) {
+ pgmap = get_dev_pagemap(pte_pfn(pte), pgmap);
+ if (unlikely(!pgmap)) {
+ undo_dev_pagemap(nr, nr_start, pages);
+ pte_unmap(ptep);
+ return 0;
+ }
+ } else if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
pte_unmap(ptep);
return 0;
}
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
page = pte_page(pte);
get_page(page);
+ put_dev_pagemap(pgmap);
SetPageReferenced(page);
pages[*nr] = page;
(*nr)++;
@@ -110,35 +131,62 @@ static inline void get_head_page_multiple(struct page *page, int nr)
{
VM_BUG_ON_PAGE(page != compound_head(page), page);
VM_BUG_ON_PAGE(page_count(page) == 0, page);
- atomic_add(nr, &page->_count);
+ page_ref_add(page, nr);
SetPageReferenced(page);
}
+static int __gup_device_huge_pmd(pmd_t pmd, unsigned long addr,
+ unsigned long end, struct page **pages, int *nr)
+{
+ int nr_start = *nr;
+ unsigned long pfn = pmd_pfn(pmd);
+ struct dev_pagemap *pgmap = NULL;
+
+ pfn += (addr & ~PMD_MASK) >> PAGE_SHIFT;
+ do {
+ struct page *page = pfn_to_page(pfn);
+
+ pgmap = get_dev_pagemap(pfn, pgmap);
+ if (unlikely(!pgmap)) {
+ undo_dev_pagemap(nr, nr_start, pages);
+ return 0;
+ }
+ SetPageReferenced(page);
+ pages[*nr] = page;
+ get_page(page);
+ put_dev_pagemap(pgmap);
+ (*nr)++;
+ pfn++;
+ } while (addr += PAGE_SIZE, addr != end);
+ return 1;
+}
+
static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
unsigned long mask;
- pte_t pte = *(pte_t *)&pmd;
struct page *head, *page;
int refs;
mask = _PAGE_PRESENT|_PAGE_USER;
if (write)
mask |= _PAGE_RW;
- if ((pte_flags(pte) & mask) != mask)
+ if ((pmd_flags(pmd) & mask) != mask)
return 0;
+
+ VM_BUG_ON(!pfn_valid(pmd_pfn(pmd)));
+ if (pmd_devmap(pmd))
+ return __gup_device_huge_pmd(pmd, addr, end, pages, nr);
+
/* hugepages are never "special" */
- VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL);
- VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+ VM_BUG_ON(pmd_flags(pmd) & _PAGE_SPECIAL);
refs = 0;
- head = pte_page(pte);
+ head = pmd_page(pmd);
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
do {
VM_BUG_ON_PAGE(compound_head(page) != head, page);
pages[*nr] = page;
- if (PageTail(page))
- get_huge_page_tail(page);
(*nr)++;
page++;
refs++;
@@ -159,18 +207,7 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
pmd_t pmd = *pmdp;
next = pmd_addr_end(addr, end);
- /*
- * The pmd_trans_splitting() check below explains why
- * pmdp_splitting_flush has to flush the tlb, to stop
- * this gup-fast code from running while we set the
- * splitting bit in the pmd. Returning zero will take
- * the slow path that will call wait_split_huge_page()
- * if the pmd is still in splitting state. gup-fast
- * can't because it has irq disabled and
- * wait_split_huge_page() would never return as the
- * tlb flush IPI wouldn't run.
- */
- if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+ if (pmd_none(pmd))
return 0;
if (unlikely(pmd_large(pmd) || !pmd_present(pmd))) {
/*
@@ -195,27 +232,24 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
unsigned long mask;
- pte_t pte = *(pte_t *)&pud;
struct page *head, *page;
int refs;
mask = _PAGE_PRESENT|_PAGE_USER;
if (write)
mask |= _PAGE_RW;
- if ((pte_flags(pte) & mask) != mask)
+ if ((pud_flags(pud) & mask) != mask)
return 0;
/* hugepages are never "special" */
- VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL);
- VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+ VM_BUG_ON(pud_flags(pud) & _PAGE_SPECIAL);
+ VM_BUG_ON(!pfn_valid(pud_pfn(pud)));
refs = 0;
- head = pte_page(pte);
+ head = pud_page(pud);
page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
do {
VM_BUG_ON_PAGE(compound_head(page) != head, page);
pages[*nr] = page;
- if (PageTail(page))
- get_huge_page_tail(page);
(*nr)++;
page++;
refs++;
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index eecb207a..a6d7392 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -104,20 +104,6 @@ void __kunmap_atomic(void *kvaddr)
}
EXPORT_SYMBOL(__kunmap_atomic);
-struct page *kmap_atomic_to_page(void *ptr)
-{
- unsigned long idx, vaddr = (unsigned long)ptr;
- pte_t *pte;
-
- if (vaddr < FIXADDR_START)
- return virt_to_page(ptr);
-
- idx = virt_to_fix(vaddr);
- pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
- return pte_page(*pte);
-}
-EXPORT_SYMBOL(kmap_atomic_to_page);
-
void __init set_highmem_pages_init(void)
{
struct zone *zone;
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 42982b2..740d7ac 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -173,10 +173,10 @@ static __init int setup_hugepagesz(char *opt)
}
__setup("hugepagesz=", setup_hugepagesz);
-#ifdef CONFIG_CMA
+#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA)
static __init int gigantic_pages_init(void)
{
- /* With CMA we can allocate gigantic pages at runtime */
+ /* With compaction or CMA we can allocate gigantic pages at runtime */
if (cpu_has_gbpages && !size_to_hstate(1UL << PUD_SHIFT))
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
return 0;
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 1d8a83d..9d56f27 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -150,13 +150,14 @@ static int page_size_mask;
static void __init probe_page_size_mask(void)
{
-#if !defined(CONFIG_DEBUG_PAGEALLOC) && !defined(CONFIG_KMEMCHECK)
+#if !defined(CONFIG_KMEMCHECK)
/*
- * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages.
+ * For CONFIG_KMEMCHECK or pagealloc debugging, identity mapping will
+ * use small pages.
* This will simplify cpa(), which otherwise needs to support splitting
* large pages into small in interrupt context, etc.
*/
- if (cpu_has_pse)
+ if (cpu_has_pse && !debug_pagealloc_enabled())
page_size_mask |= 1 << PG_LEVEL_2M;
#endif
@@ -354,7 +355,7 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
}
for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
+ pr_debug(" [mem %#010lx-%#010lx] page %s\n",
mr[i].start, mr[i].end - 1,
page_size_string(&mr[i]));
@@ -401,7 +402,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
unsigned long ret = 0;
int nr_range, i;
- pr_info("init_memory_mapping: [mem %#010lx-%#010lx]\n",
+ pr_debug("init_memory_mapping: [mem %#010lx-%#010lx]\n",
start, end - 1);
memset(mr, 0, sizeof(mr));
@@ -666,21 +667,22 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
* mark them not present - any buggy init-section access will
* create a kernel page fault:
*/
-#ifdef CONFIG_DEBUG_PAGEALLOC
- printk(KERN_INFO "debug: unmapping init [mem %#010lx-%#010lx]\n",
- begin, end - 1);
- set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-#else
- /*
- * We just marked the kernel text read only above, now that
- * we are going to free part of that, we need to make that
- * writeable and non-executable first.
- */
- set_memory_nx(begin, (end - begin) >> PAGE_SHIFT);
- set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
+ if (debug_pagealloc_enabled()) {
+ pr_info("debug: unmapping init [mem %#010lx-%#010lx]\n",
+ begin, end - 1);
+ set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
+ } else {
+ /*
+ * We just marked the kernel text read only above, now that
+ * we are going to free part of that, we need to make that
+ * writeable and non-executable first.
+ */
+ set_memory_nx(begin, (end - begin) >> PAGE_SHIFT);
+ set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
- free_reserved_area((void *)begin, (void *)end, POISON_FREE_INITMEM, what);
-#endif
+ free_reserved_area((void *)begin, (void *)end,
+ POISON_FREE_INITMEM, what);
+ }
}
void free_initmem(void)
@@ -693,14 +695,12 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void __init free_initrd_mem(unsigned long start, unsigned long end)
{
-#ifdef CONFIG_MICROCODE_EARLY
/*
* Remember, initrd memory may contain microcode or other useful things.
* Before we lose initrd mem, we need to find a place to hold them
* now that normal virtual memory is enabled.
*/
save_microcode_in_initrd();
-#endif
/*
* end could be not aligned, and We can not align that,
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 7562f42..bd7a9b9 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -388,7 +388,6 @@ repeat:
}
pte_t *kmap_pte;
-pgprot_t kmap_prot;
static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr)
{
@@ -405,8 +404,6 @@ static void __init kmap_init(void)
*/
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-
- kmap_prot = PAGE_KERNEL;
}
#ifdef CONFIG_HIGHMEM
@@ -871,7 +868,6 @@ static noinline int do_test_wp_bit(void)
return flag;
}
-#ifdef CONFIG_DEBUG_RODATA
const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data);
@@ -957,6 +953,6 @@ void mark_rodata_ro(void)
set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
#endif
mark_nxdata_nx();
+ if (__supported_pte_mask & _PAGE_NX)
+ debug_checkwx();
}
-#endif
-
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index df48430..214afda 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/memory_hotplug.h>
+#include <linux/memremap.h>
#include <linux/nmi.h>
#include <linux/gfp.h>
#include <linux/kcore.h>
@@ -52,6 +53,7 @@
#include <asm/numa.h>
#include <asm/cacheflush.h>
#include <asm/init.h>
+#include <asm/uv/uv.h>
#include <asm/setup.h>
#include "mm_internal.h"
@@ -714,6 +716,12 @@ static void __meminit free_pagetable(struct page *page, int order)
{
unsigned long magic;
unsigned int nr_pages = 1 << order;
+ struct vmem_altmap *altmap = to_vmem_altmap((unsigned long) page);
+
+ if (altmap) {
+ vmem_altmap_free(altmap, nr_pages);
+ return;
+ }
/* bootmem page has reserved flag */
if (PageReserved(page)) {
@@ -814,8 +822,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
if (phys_addr < (phys_addr_t)0x40000000)
return;
- if (IS_ALIGNED(addr, PAGE_SIZE) &&
- IS_ALIGNED(next, PAGE_SIZE)) {
+ if (PAGE_ALIGNED(addr) && PAGE_ALIGNED(next)) {
/*
* Do not free direct mapping pages since they were
* freed when offlining, or simplely not in use.
@@ -1018,13 +1025,19 @@ int __ref arch_remove_memory(u64 start, u64 size)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
+ struct page *page = pfn_to_page(start_pfn);
+ struct vmem_altmap *altmap;
struct zone *zone;
int ret;
- zone = page_zone(pfn_to_page(start_pfn));
- kernel_physical_mapping_remove(start, start + size);
+ /* With altmap the first mapped page is offset from @start */
+ altmap = to_vmem_altmap((unsigned long) page);
+ if (altmap)
+ page += vmem_altmap_offset(altmap);
+ zone = page_zone(page);
ret = __remove_pages(zone, start_pfn, nr_pages);
WARN_ON_ONCE(ret);
+ kernel_physical_mapping_remove(start, start + size);
return ret;
}
@@ -1062,7 +1075,6 @@ void __init mem_init(void)
mem_init_print_info(NULL);
}
-#ifdef CONFIG_DEBUG_RODATA
const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data);
@@ -1150,9 +1162,9 @@ void mark_rodata_ro(void)
free_init_pages("unused kernel",
(unsigned long) __va(__pa_symbol(rodata_end)),
(unsigned long) __va(__pa_symbol(_sdata)));
-}
-#endif
+ debug_checkwx();
+}
int kern_addr_valid(unsigned long addr)
{
@@ -1192,26 +1204,13 @@ int kern_addr_valid(unsigned long addr)
static unsigned long probe_memory_block_size(void)
{
- /* start from 2g */
- unsigned long bz = 1UL<<31;
+ unsigned long bz = MIN_MEMORY_BLOCK_SIZE;
- if (totalram_pages >= (64ULL << (30 - PAGE_SHIFT))) {
- pr_info("Using 2GB memory block size for large-memory system\n");
- return 2UL * 1024 * 1024 * 1024;
- }
-
- /* less than 64g installed */
- if ((max_pfn << PAGE_SHIFT) < (16UL << 32))
- return MIN_MEMORY_BLOCK_SIZE;
-
- /* get the tail size */
- while (bz > MIN_MEMORY_BLOCK_SIZE) {
- if (!((max_pfn << PAGE_SHIFT) & (bz - 1)))
- break;
- bz >>= 1;
- }
+ /* if system is UV or has 64GB of RAM or more, use large blocks */
+ if (is_uv_system() || ((max_pfn << PAGE_SHIFT) >= (64UL << 30)))
+ bz = 2UL << 30; /* 2GB */
- printk(KERN_DEBUG "memory block size : %ldMB\n", bz >> 20);
+ pr_info("x86/mm: Memory block size: %ldMB\n", bz >> 20);
return bz;
}
@@ -1234,7 +1233,7 @@ static void __meminitdata *p_start, *p_end;
static int __meminitdata node_start;
static int __meminit vmemmap_populate_hugepages(unsigned long start,
- unsigned long end, int node)
+ unsigned long end, int node, struct vmem_altmap *altmap)
{
unsigned long addr;
unsigned long next;
@@ -1257,7 +1256,7 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
if (pmd_none(*pmd)) {
void *p;
- p = vmemmap_alloc_block_buf(PMD_SIZE, node);
+ p = __vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
if (p) {
pte_t entry;
@@ -1268,7 +1267,7 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
/* check to see if we have contiguous blocks */
if (p_end != p || node_start != node) {
if (p_start)
- printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
+ pr_debug(" [%lx-%lx] PMD -> [%p-%p] on node %d\n",
addr_start, addr_end-1, p_start, p_end-1, node_start);
addr_start = addr;
node_start = node;
@@ -1278,7 +1277,8 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
addr_end = addr + PMD_SIZE;
p_end = p + PMD_SIZE;
continue;
- }
+ } else if (altmap)
+ return -ENOMEM; /* no fallback */
} else if (pmd_large(*pmd)) {
vmemmap_verify((pte_t *)pmd, node, addr, next);
continue;
@@ -1292,11 +1292,16 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
{
+ struct vmem_altmap *altmap = to_vmem_altmap(start);
int err;
if (cpu_has_pse)
- err = vmemmap_populate_hugepages(start, end, node);
- else
+ err = vmemmap_populate_hugepages(start, end, node, altmap);
+ else if (altmap) {
+ pr_err_once("%s: no cpu support for altmap allocations\n",
+ __func__);
+ err = -ENOMEM;
+ } else
err = vmemmap_populate_basepages(start, end, node);
if (!err)
sync_global_pgds(start, end - 1, 0);
@@ -1366,7 +1371,7 @@ void register_page_bootmem_memmap(unsigned long section_nr,
void __meminit vmemmap_populate_print_last(void)
{
if (p_start) {
- printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
+ pr_debug(" [%lx-%lx] PMD -> [%p-%p] on node %d\n",
addr_start, addr_end-1, p_start, p_end-1, node_start);
p_start = NULL;
p_end = NULL;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index b9c78f3..0d8d53d 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -194,8 +194,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
* Check if the request spans more than any BAR in the iomem resource
* tree.
*/
- WARN_ONCE(iomem_map_sanity_check(unaligned_phys_addr, unaligned_size),
- KERN_INFO "Info: mapping multiple BARs. Your kernel is fine.");
+ if (iomem_map_sanity_check(unaligned_phys_addr, unaligned_size))
+ pr_warn("caller %pS mapping multiple BARs\n", caller);
return ret_addr;
err_free_area:
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 9ce5da2..1b1110f 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -120,11 +120,22 @@ void __init kasan_init(void)
kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
(void *)KASAN_SHADOW_END);
- memset(kasan_zero_page, 0, PAGE_SIZE);
-
load_cr3(init_level4_pgt);
__flush_tlb_all();
- init_task.kasan_depth = 0;
- pr_info("Kernel address sanitizer initialized\n");
+ /*
+ * kasan_zero_page has been used as early shadow memory, thus it may
+ * contain some garbage. Now we can clear and write protect it, since
+ * after the TLB flush no one should write to it.
+ */
+ memset(kasan_zero_page, 0, PAGE_SIZE);
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+ pte_t pte = __pte(__pa(kasan_zero_page) | __PAGE_KERNEL_RO);
+ set_pte(&kasan_zero_pte[i], pte);
+ }
+ /* Flush TLBs again to be sure that write protection applied. */
+ __flush_tlb_all();
+
+ init_task.kasan_depth = 0;
+ pr_info("KernelAddressSanitizer initialized\n");
}
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 637ab34..ddb2244 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -33,7 +33,7 @@
struct kmmio_fault_page {
struct list_head list;
struct kmmio_fault_page *release_next;
- unsigned long page; /* location of the fault page */
+ unsigned long addr; /* the requested address */
pteval_t old_presence; /* page presence prior to arming */
bool armed;
@@ -70,9 +70,16 @@ unsigned int kmmio_count;
static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE];
static LIST_HEAD(kmmio_probes);
-static struct list_head *kmmio_page_list(unsigned long page)
+static struct list_head *kmmio_page_list(unsigned long addr)
{
- return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)];
+ unsigned int l;
+ pte_t *pte = lookup_address(addr, &l);
+
+ if (!pte)
+ return NULL;
+ addr &= page_level_mask(l);
+
+ return &kmmio_page_table[hash_long(addr, KMMIO_PAGE_HASH_BITS)];
}
/* Accessed per-cpu */
@@ -98,15 +105,19 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
}
/* You must be holding RCU read lock. */
-static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
+static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long addr)
{
struct list_head *head;
struct kmmio_fault_page *f;
+ unsigned int l;
+ pte_t *pte = lookup_address(addr, &l);
- page &= PAGE_MASK;
- head = kmmio_page_list(page);
+ if (!pte)
+ return NULL;
+ addr &= page_level_mask(l);
+ head = kmmio_page_list(addr);
list_for_each_entry_rcu(f, head, list) {
- if (f->page == page)
+ if (f->addr == addr)
return f;
}
return NULL;
@@ -137,10 +148,10 @@ static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old)
static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
{
unsigned int level;
- pte_t *pte = lookup_address(f->page, &level);
+ pte_t *pte = lookup_address(f->addr, &level);
if (!pte) {
- pr_err("no pte for page 0x%08lx\n", f->page);
+ pr_err("no pte for addr 0x%08lx\n", f->addr);
return -1;
}
@@ -156,7 +167,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
return -1;
}
- __flush_tlb_one(f->page);
+ __flush_tlb_one(f->addr);
return 0;
}
@@ -176,12 +187,12 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
int ret;
WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n"));
if (f->armed) {
- pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n",
- f->page, f->count, !!f->old_presence);
+ pr_warning("double-arm: addr 0x%08lx, ref %d, old %d\n",
+ f->addr, f->count, !!f->old_presence);
}
ret = clear_page_presence(f, true);
- WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"),
- f->page);
+ WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming at 0x%08lx failed.\n"),
+ f->addr);
f->armed = true;
return ret;
}
@@ -191,7 +202,7 @@ static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
{
int ret = clear_page_presence(f, false);
WARN_ONCE(ret < 0,
- KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
+ KERN_ERR "kmmio disarming at 0x%08lx failed.\n", f->addr);
f->armed = false;
}
@@ -215,6 +226,12 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
struct kmmio_context *ctx;
struct kmmio_fault_page *faultpage;
int ret = 0; /* default to fault not handled */
+ unsigned long page_base = addr;
+ unsigned int l;
+ pte_t *pte = lookup_address(addr, &l);
+ if (!pte)
+ return -EINVAL;
+ page_base &= page_level_mask(l);
/*
* Preemption is now disabled to prevent process switch during
@@ -227,7 +244,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
preempt_disable();
rcu_read_lock();
- faultpage = get_kmmio_fault_page(addr);
+ faultpage = get_kmmio_fault_page(page_base);
if (!faultpage) {
/*
* Either this page fault is not caused by kmmio, or
@@ -239,7 +256,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
ctx = &get_cpu_var(kmmio_ctx);
if (ctx->active) {
- if (addr == ctx->addr) {
+ if (page_base == ctx->addr) {
/*
* A second fault on the same page means some other
* condition needs handling by do_page_fault(), the
@@ -267,9 +284,9 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
ctx->active++;
ctx->fpage = faultpage;
- ctx->probe = get_kmmio_probe(addr);
+ ctx->probe = get_kmmio_probe(page_base);
ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
- ctx->addr = addr;
+ ctx->addr = page_base;
if (ctx->probe && ctx->probe->pre_handler)
ctx->probe->pre_handler(ctx->probe, regs, addr);
@@ -354,12 +371,11 @@ out:
}
/* You must be holding kmmio_lock. */
-static int add_kmmio_fault_page(unsigned long page)
+static int add_kmmio_fault_page(unsigned long addr)
{
struct kmmio_fault_page *f;
- page &= PAGE_MASK;
- f = get_kmmio_fault_page(page);
+ f = get_kmmio_fault_page(addr);
if (f) {
if (!f->count)
arm_kmmio_fault_page(f);
@@ -372,26 +388,25 @@ static int add_kmmio_fault_page(unsigned long page)
return -1;
f->count = 1;
- f->page = page;
+ f->addr = addr;
if (arm_kmmio_fault_page(f)) {
kfree(f);
return -1;
}
- list_add_rcu(&f->list, kmmio_page_list(f->page));
+ list_add_rcu(&f->list, kmmio_page_list(f->addr));
return 0;
}
/* You must be holding kmmio_lock. */
-static void release_kmmio_fault_page(unsigned long page,
+static void release_kmmio_fault_page(unsigned long addr,
struct kmmio_fault_page **release_list)
{
struct kmmio_fault_page *f;
- page &= PAGE_MASK;
- f = get_kmmio_fault_page(page);
+ f = get_kmmio_fault_page(addr);
if (!f)
return;
@@ -420,18 +435,27 @@ int register_kmmio_probe(struct kmmio_probe *p)
int ret = 0;
unsigned long size = 0;
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
+ unsigned int l;
+ pte_t *pte;
spin_lock_irqsave(&kmmio_lock, flags);
if (get_kmmio_probe(p->addr)) {
ret = -EEXIST;
goto out;
}
+
+ pte = lookup_address(p->addr, &l);
+ if (!pte) {
+ ret = -EINVAL;
+ goto out;
+ }
+
kmmio_count++;
list_add_rcu(&p->list, &kmmio_probes);
while (size < size_lim) {
if (add_kmmio_fault_page(p->addr + size))
pr_err("Unable to set page fault.\n");
- size += PAGE_SIZE;
+ size += page_level_size(l);
}
out:
spin_unlock_irqrestore(&kmmio_lock, flags);
@@ -506,11 +530,17 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
struct kmmio_fault_page *release_list = NULL;
struct kmmio_delayed_release *drelease;
+ unsigned int l;
+ pte_t *pte;
+
+ pte = lookup_address(p->addr, &l);
+ if (!pte)
+ return;
spin_lock_irqsave(&kmmio_lock, flags);
while (size < size_lim) {
release_kmmio_fault_page(p->addr + size, &release_list);
- size += PAGE_SIZE;
+ size += page_level_size(l);
}
list_del_rcu(&p->list);
kmmio_count--;
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 844b06d..d2dc043 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -69,14 +69,14 @@ unsigned long arch_mmap_rnd(void)
{
unsigned long rnd;
- /*
- * 8 bits of randomness in 32bit mmaps, 20 address space bits
- * 28 bits of randomness in 64bit mmaps, 40 address space bits
- */
if (mmap_is_ia32())
- rnd = (unsigned long)get_random_int() % (1<<8);
+#ifdef CONFIG_COMPAT
+ rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
+#else
+ rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
+#endif
else
- rnd = (unsigned long)get_random_int() % (1<<28);
+ rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
return rnd << PAGE_SHIFT;
}
@@ -94,18 +94,6 @@ static unsigned long mmap_base(unsigned long rnd)
}
/*
- * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
- * does, but not when emulating X86_32
- */
-static unsigned long mmap_legacy_base(unsigned long rnd)
-{
- if (mmap_is_ia32())
- return TASK_UNMAPPED_BASE;
- else
- return TASK_UNMAPPED_BASE + rnd;
-}
-
-/*
* This function, called very early during the creation of a new
* process VM image, sets up which VM layout function to use:
*/
@@ -116,7 +104,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
if (current->flags & PF_RANDOMIZE)
random_factor = arch_mmap_rnd();
- mm->mmap_legacy_base = mmap_legacy_base(random_factor);
+ mm->mmap_legacy_base = TASK_UNMAPPED_BASE + random_factor;
if (mmap_is_legacy()) {
mm->mmap_base = mm->mmap_legacy_base;
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 134948b..ef05755 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -101,19 +101,19 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
switch (type) {
case REG_TYPE_RM:
regno = X86_MODRM_RM(insn->modrm.value);
- if (X86_REX_B(insn->rex_prefix.value) == 1)
+ if (X86_REX_B(insn->rex_prefix.value))
regno += 8;
break;
case REG_TYPE_INDEX:
regno = X86_SIB_INDEX(insn->sib.value);
- if (X86_REX_X(insn->rex_prefix.value) == 1)
+ if (X86_REX_X(insn->rex_prefix.value))
regno += 8;
break;
case REG_TYPE_BASE:
regno = X86_SIB_BASE(insn->sib.value);
- if (X86_REX_B(insn->rex_prefix.value) == 1)
+ if (X86_REX_B(insn->rex_prefix.value))
regno += 8;
break;
@@ -123,7 +123,7 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
break;
}
- if (regno > nr_registers) {
+ if (regno >= nr_registers) {
WARN_ONCE(1, "decoded an instruction with an invalid register");
return -EINVAL;
}
@@ -237,7 +237,8 @@ bad_opcode:
*/
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
{
- const struct bndreg *bndregs, *bndreg;
+ const struct mpx_bndreg_state *bndregs;
+ const struct mpx_bndreg *bndreg;
siginfo_t *info = NULL;
struct insn insn;
uint8_t bndregno;
@@ -258,13 +259,13 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
goto err_out;
}
/* get bndregs field from current task's xsave area */
- bndregs = get_xsave_field_ptr(XSTATE_BNDREGS);
+ bndregs = get_xsave_field_ptr(XFEATURE_MASK_BNDREGS);
if (!bndregs) {
err = -EINVAL;
goto err_out;
}
/* now go select the individual register in the set of 4 */
- bndreg = &bndregs[bndregno];
+ bndreg = &bndregs->bndreg[bndregno];
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
@@ -306,7 +307,7 @@ err_out:
static __user void *mpx_get_bounds_dir(void)
{
- const struct bndcsr *bndcsr;
+ const struct mpx_bndcsr *bndcsr;
if (!cpu_feature_enabled(X86_FEATURE_MPX))
return MPX_INVALID_BOUNDS_DIR;
@@ -315,7 +316,7 @@ static __user void *mpx_get_bounds_dir(void)
* The bounds directory pointer is stored in a register
* only accessible if we first do an xsave.
*/
- bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+ bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
if (!bndcsr)
return MPX_INVALID_BOUNDS_DIR;
@@ -489,10 +490,10 @@ out_unmap:
static int do_mpx_bt_fault(void)
{
unsigned long bd_entry, bd_base;
- const struct bndcsr *bndcsr;
+ const struct mpx_bndcsr *bndcsr;
struct mm_struct *mm = current->mm;
- bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR);
+ bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);
if (!bndcsr)
return -EINVAL;
/*
@@ -585,6 +586,29 @@ static unsigned long mpx_bd_entry_to_bt_addr(struct mm_struct *mm,
}
/*
+ * We only want to do a 4-byte get_user() on 32-bit. Otherwise,
+ * we might run off the end of the bounds table if we are on
+ * a 64-bit kernel and try to get 8 bytes.
+ */
+int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret,
+ long __user *bd_entry_ptr)
+{
+ u32 bd_entry_32;
+ int ret;
+
+ if (is_64bit_mm(mm))
+ return get_user(*bd_entry_ret, bd_entry_ptr);
+
+ /*
+ * Note that get_user() uses the type of the *pointer* to
+ * establish the size of the get, not the destination.
+ */
+ ret = get_user(bd_entry_32, (u32 __user *)bd_entry_ptr);
+ *bd_entry_ret = bd_entry_32;
+ return ret;
+}
+
+/*
* Get the base of bounds tables pointed by specific bounds
* directory entry.
*/
@@ -604,7 +628,7 @@ static int get_bt_addr(struct mm_struct *mm,
int need_write = 0;
pagefault_disable();
- ret = get_user(bd_entry, bd_entry_ptr);
+ ret = get_user_bd_entry(mm, &bd_entry, bd_entry_ptr);
pagefault_enable();
if (!ret)
break;
@@ -699,11 +723,23 @@ static unsigned long mpx_get_bt_entry_offset_bytes(struct mm_struct *mm,
*/
static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
{
- unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
- if (is_64bit_mm(mm))
- return virt_space / MPX_BD_NR_ENTRIES_64;
- else
- return virt_space / MPX_BD_NR_ENTRIES_32;
+ unsigned long long virt_space;
+ unsigned long long GB = (1ULL << 30);
+
+ /*
+ * This covers 32-bit emulation as well as 32-bit kernels
+ * running on 64-bit harware.
+ */
+ if (!is_64bit_mm(mm))
+ return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
+
+ /*
+ * 'x86_virt_bits' returns what the hardware is capable
+ * of, and returns the full >32-bit adddress space when
+ * running 32-bit kernels on 64-bit hardware.
+ */
+ virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
+ return virt_space / MPX_BD_NR_ENTRIES_64;
}
/*
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index c3b3f65..f70c1ff 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -465,46 +465,67 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
return true;
}
+/*
+ * Mark all currently memblock-reserved physical memory (which covers the
+ * kernel's own memory ranges) as hot-unswappable.
+ */
static void __init numa_clear_kernel_node_hotplug(void)
{
- int i, nid;
- nodemask_t numa_kernel_nodes = NODE_MASK_NONE;
- unsigned long start, end;
- struct memblock_region *r;
+ nodemask_t reserved_nodemask = NODE_MASK_NONE;
+ struct memblock_region *mb_region;
+ int i;
/*
+ * We have to do some preprocessing of memblock regions, to
+ * make them suitable for reservation.
+ *
* At this time, all memory regions reserved by memblock are
- * used by the kernel. Set the nid in memblock.reserved will
- * mark out all the nodes the kernel resides in.
+ * used by the kernel, but those regions are not split up
+ * along node boundaries yet, and don't necessarily have their
+ * node ID set yet either.
+ *
+ * So iterate over all memory known to the x86 architecture,
+ * and use those ranges to set the nid in memblock.reserved.
+ * This will split up the memblock regions along node
+ * boundaries and will set the node IDs as well.
*/
for (i = 0; i < numa_meminfo.nr_blks; i++) {
- struct numa_memblk *mb = &numa_meminfo.blk[i];
+ struct numa_memblk *mb = numa_meminfo.blk + i;
+ int ret;
- memblock_set_node(mb->start, mb->end - mb->start,
- &memblock.reserved, mb->nid);
+ ret = memblock_set_node(mb->start, mb->end - mb->start, &memblock.reserved, mb->nid);
+ WARN_ON_ONCE(ret);
}
/*
- * Mark all kernel nodes.
+ * Now go over all reserved memblock regions, to construct a
+ * node mask of all kernel reserved memory areas.
*
- * When booting with mem=nn[kMG] or in a kdump kernel, numa_meminfo
- * may not include all the memblock.reserved memory ranges because
- * trim_snb_memory() reserves specific pages for Sandy Bridge graphics.
+ * [ Note, when booting with mem=nn[kMG] or in a kdump kernel,
+ * numa_meminfo might not include all memblock.reserved
+ * memory ranges, because quirks such as trim_snb_memory()
+ * reserve specific pages for Sandy Bridge graphics. ]
*/
- for_each_memblock(reserved, r)
- if (r->nid != MAX_NUMNODES)
- node_set(r->nid, numa_kernel_nodes);
+ for_each_memblock(reserved, mb_region) {
+ if (mb_region->nid != MAX_NUMNODES)
+ node_set(mb_region->nid, reserved_nodemask);
+ }
- /* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */
+ /*
+ * Finally, clear the MEMBLOCK_HOTPLUG flag for all memory
+ * belonging to the reserved node mask.
+ *
+ * Note that this will include memory regions that reside
+ * on nodes that contain kernel memory - entire nodes
+ * become hot-unpluggable:
+ */
for (i = 0; i < numa_meminfo.nr_blks; i++) {
- nid = numa_meminfo.blk[i].nid;
- if (!node_isset(nid, numa_kernel_nodes))
- continue;
+ struct numa_memblk *mb = numa_meminfo.blk + i;
- start = numa_meminfo.blk[i].start;
- end = numa_meminfo.blk[i].end;
+ if (!node_isset(mb->nid, reserved_nodemask))
+ continue;
- memblock_clear_hotplug(start, end - start);
+ memblock_clear_hotplug(mb->start, mb->end - mb->start);
}
}
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 2c44c07..4d0b262 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -33,7 +33,7 @@ struct cpa_data {
pgd_t *pgd;
pgprot_t mask_set;
pgprot_t mask_clr;
- int numpages;
+ unsigned long numpages;
int flags;
unsigned long pfn;
unsigned force_split : 1;
@@ -66,6 +66,9 @@ void update_page_count(int level, unsigned long pages)
static void split_page_count(int level)
{
+ if (direct_pages_count[level] == 0)
+ return;
+
direct_pages_count[level]--;
direct_pages_count[level - 1] += PTRS_PER_PTE;
}
@@ -103,12 +106,6 @@ static inline unsigned long highmap_end_pfn(void)
#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
-# define debug_pagealloc 1
-#else
-# define debug_pagealloc 0
-#endif
-
static inline int
within(unsigned long addr, unsigned long start, unsigned long end)
{
@@ -129,14 +126,16 @@ within(unsigned long addr, unsigned long start, unsigned long end)
*/
void clflush_cache_range(void *vaddr, unsigned int size)
{
- unsigned long clflush_mask = boot_cpu_data.x86_clflush_size - 1;
+ const unsigned long clflush_size = boot_cpu_data.x86_clflush_size;
+ void *p = (void *)((unsigned long)vaddr & ~(clflush_size - 1));
void *vend = vaddr + size;
- void *p;
+
+ if (p >= vend)
+ return;
mb();
- for (p = (void *)((unsigned long)vaddr & ~clflush_mask);
- p < vend; p += boot_cpu_data.x86_clflush_size)
+ for (; p < vend; p += clflush_size)
clflushopt(p);
mb();
@@ -278,7 +277,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
__pa_symbol(__end_rodata) >> PAGE_SHIFT))
pgprot_val(forbidden) |= _PAGE_RW;
-#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+#if defined(CONFIG_X86_64)
/*
* Once the kernel maps the text as RO (kernel_set_to_readonly is set),
* kernel text mappings for the large page aligned text, rodata sections
@@ -417,15 +416,31 @@ phys_addr_t slow_virt_to_phys(void *__virt_addr)
phys_addr_t phys_addr;
unsigned long offset;
enum pg_level level;
- unsigned long pmask;
pte_t *pte;
pte = lookup_address(virt_addr, &level);
BUG_ON(!pte);
- pmask = page_level_mask(level);
- offset = virt_addr & ~pmask;
- phys_addr = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT;
- return (phys_addr | offset);
+
+ /*
+ * pXX_pfn() returns unsigned long, which must be cast to phys_addr_t
+ * before being left-shifted PAGE_SHIFT bits -- this trick is to
+ * make 32-PAE kernel work correctly.
+ */
+ switch (level) {
+ case PG_LEVEL_1G:
+ phys_addr = (phys_addr_t)pud_pfn(*(pud_t *)pte) << PAGE_SHIFT;
+ offset = virt_addr & ~PUD_PAGE_MASK;
+ break;
+ case PG_LEVEL_2M:
+ phys_addr = (phys_addr_t)pmd_pfn(*(pmd_t *)pte) << PAGE_SHIFT;
+ offset = virt_addr & ~PMD_PAGE_MASK;
+ break;
+ default:
+ phys_addr = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT;
+ offset = virt_addr & ~PAGE_MASK;
+ }
+
+ return (phys_addr_t)(phys_addr | offset);
}
EXPORT_SYMBOL_GPL(slow_virt_to_phys);
@@ -458,7 +473,7 @@ static int
try_preserve_large_page(pte_t *kpte, unsigned long address,
struct cpa_data *cpa)
{
- unsigned long nextpage_addr, numpages, pmask, psize, addr, pfn;
+ unsigned long nextpage_addr, numpages, pmask, psize, addr, pfn, old_pfn;
pte_t new_pte, old_pte, *tmp;
pgprot_t old_prot, new_prot, req_prot;
int i, do_split = 1;
@@ -478,17 +493,21 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
switch (level) {
case PG_LEVEL_2M:
-#ifdef CONFIG_X86_64
+ old_prot = pmd_pgprot(*(pmd_t *)kpte);
+ old_pfn = pmd_pfn(*(pmd_t *)kpte);
+ break;
case PG_LEVEL_1G:
-#endif
- psize = page_level_size(level);
- pmask = page_level_mask(level);
+ old_prot = pud_pgprot(*(pud_t *)kpte);
+ old_pfn = pud_pfn(*(pud_t *)kpte);
break;
default:
do_split = -EINVAL;
goto out_unlock;
}
+ psize = page_level_size(level);
+ pmask = page_level_mask(level);
+
/*
* Calculate the number of pages, which fit into this large
* page starting at address:
@@ -504,7 +523,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* up accordingly.
*/
old_pte = *kpte;
- old_prot = req_prot = pgprot_large_2_4k(pte_pgprot(old_pte));
+ req_prot = pgprot_large_2_4k(old_prot);
pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr);
pgprot_val(req_prot) |= pgprot_val(cpa->mask_set);
@@ -530,10 +549,10 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
req_prot = canon_pgprot(req_prot);
/*
- * old_pte points to the large page base address. So we need
+ * old_pfn points to the large page base pfn. So we need
* to add the offset of the virtual address:
*/
- pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT);
+ pfn = old_pfn + ((address & (psize - 1)) >> PAGE_SHIFT);
cpa->pfn = pfn;
new_prot = static_protections(req_prot, address, pfn);
@@ -544,7 +563,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* the pages in the range we try to preserve:
*/
addr = address & pmask;
- pfn = pte_pfn(old_pte);
+ pfn = old_pfn;
for (i = 0; i < (psize >> PAGE_SHIFT); i++, addr += PAGE_SIZE, pfn++) {
pgprot_t chk_prot = static_protections(req_prot, addr, pfn);
@@ -574,7 +593,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* The address is aligned and the number of pages
* covers the full page.
*/
- new_pte = pfn_pte(pte_pfn(old_pte), new_prot);
+ new_pte = pfn_pte(old_pfn, new_prot);
__set_pmd_pte(kpte, address, new_pte);
cpa->flags |= CPA_FLUSHTLB;
do_split = 0;
@@ -591,7 +610,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
struct page *base)
{
pte_t *pbase = (pte_t *)page_address(base);
- unsigned long pfn, pfninc = 1;
+ unsigned long ref_pfn, pfn, pfninc = 1;
unsigned int i, level;
pte_t *tmp;
pgprot_t ref_prot;
@@ -608,26 +627,33 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
}
paravirt_alloc_pte(&init_mm, page_to_pfn(base));
- ref_prot = pte_pgprot(pte_clrhuge(*kpte));
- /* promote PAT bit to correct position */
- if (level == PG_LEVEL_2M)
+ switch (level) {
+ case PG_LEVEL_2M:
+ ref_prot = pmd_pgprot(*(pmd_t *)kpte);
+ /* clear PSE and promote PAT bit to correct position */
ref_prot = pgprot_large_2_4k(ref_prot);
+ ref_pfn = pmd_pfn(*(pmd_t *)kpte);
+ break;
-#ifdef CONFIG_X86_64
- if (level == PG_LEVEL_1G) {
+ case PG_LEVEL_1G:
+ ref_prot = pud_pgprot(*(pud_t *)kpte);
+ ref_pfn = pud_pfn(*(pud_t *)kpte);
pfninc = PMD_PAGE_SIZE >> PAGE_SHIFT;
+
/*
- * Set the PSE flags only if the PRESENT flag is set
+ * Clear the PSE flags if the PRESENT flag is not set
* otherwise pmd_present/pmd_huge will return true
* even on a non present pmd.
*/
- if (pgprot_val(ref_prot) & _PAGE_PRESENT)
- pgprot_val(ref_prot) |= _PAGE_PSE;
- else
+ if (!(pgprot_val(ref_prot) & _PAGE_PRESENT))
pgprot_val(ref_prot) &= ~_PAGE_PSE;
+ break;
+
+ default:
+ spin_unlock(&pgd_lock);
+ return 1;
}
-#endif
/*
* Set the GLOBAL flags only if the PRESENT flag is set
@@ -643,13 +669,16 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
/*
* Get the target pfn from the original entry:
*/
- pfn = pte_pfn(*kpte);
+ pfn = ref_pfn;
for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc)
set_pte(&pbase[i], pfn_pte(pfn, canon_pgprot(ref_prot)));
- if (pfn_range_is_mapped(PFN_DOWN(__pa(address)),
- PFN_DOWN(__pa(address)) + 1))
- split_page_count(level);
+ if (virt_addr_valid(address)) {
+ unsigned long pfn = PFN_DOWN(__pa(address));
+
+ if (pfn_range_is_mapped(pfn, pfn + 1))
+ split_page_count(level);
+ }
/*
* Install the new, split up pagetable.
@@ -679,10 +708,10 @@ static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
{
struct page *base;
- if (!debug_pagealloc)
+ if (!debug_pagealloc_enabled())
spin_unlock(&cpa_lock);
base = alloc_pages(GFP_KERNEL | __GFP_NOTRACK, 0);
- if (!debug_pagealloc)
+ if (!debug_pagealloc_enabled())
spin_lock(&cpa_lock);
if (!base)
return -ENOMEM;
@@ -1093,8 +1122,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
/*
* Ignore all non primary paths.
*/
- if (!primary)
+ if (!primary) {
+ cpa->numpages = 1;
return 0;
+ }
/*
* Ignore the NULL PTE for kernel identity mapping, as it is expected
@@ -1302,10 +1333,10 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
cpa->numpages = 1;
- if (!debug_pagealloc)
+ if (!debug_pagealloc_enabled())
spin_lock(&cpa_lock);
ret = __change_page_attr(cpa, checkalias);
- if (!debug_pagealloc)
+ if (!debug_pagealloc_enabled())
spin_unlock(&cpa_lock);
if (ret)
return ret;
@@ -1321,7 +1352,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
* CPA operation. Either a large page has been
* preserved or a single page update happened.
*/
- BUG_ON(cpa->numpages > numpages);
+ BUG_ON(cpa->numpages > numpages || !cpa->numpages);
numpages -= cpa->numpages;
if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY))
cpa->curpage++;
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 188e3e0..04e2e71 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -12,6 +12,7 @@
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/pfn_t.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fs.h>
@@ -586,7 +587,7 @@ int free_memtype(u64 start, u64 end)
entry = rbt_memtype_erase(start, end);
spin_unlock(&memtype_lock);
- if (!entry) {
+ if (IS_ERR(entry)) {
pr_info("x86/PAT: %s:%d freeing invalid memtype [mem %#010Lx-%#010Lx]\n",
current->comm, current->pid, start, end - 1);
return -EINVAL;
@@ -942,14 +943,14 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
return -EINVAL;
}
- *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
+ *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) |
cachemode2protval(pcm));
return 0;
}
int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
- unsigned long pfn)
+ pfn_t pfn)
{
enum page_cache_mode pcm;
@@ -957,8 +958,8 @@ int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
return 0;
/* Set prot based on lookup */
- pcm = lookup_memtype((resource_size_t)pfn << PAGE_SHIFT);
- *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
+ pcm = lookup_memtype(pfn_t_to_phys(pfn));
+ *prot = __pgprot((pgprot_val(*prot) & (~_PAGE_CACHE_MASK)) |
cachemode2protval(pcm));
return 0;
@@ -992,6 +993,16 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
vma->vm_flags &= ~VM_PAT;
}
+/*
+ * untrack_pfn_moved is called, while mremapping a pfnmap for a new region,
+ * with the old vma after its pfnmap page table has been removed. The new
+ * vma has a new pfnmap to the same pfn & cache type with VM_PAT set.
+ */
+void untrack_pfn_moved(struct vm_area_struct *vma)
+{
+ vma->vm_flags &= ~VM_PAT;
+}
+
pgprot_t pgprot_writecombine(pgprot_t prot)
{
return __pgprot(pgprot_val(prot) |
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
index 6393108..2f77022 100644
--- a/arch/x86/mm/pat_rbtree.c
+++ b/arch/x86/mm/pat_rbtree.c
@@ -98,8 +98,13 @@ static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
return last_lower; /* Returns NULL if there is no overlap */
}
-static struct memtype *memtype_rb_exact_match(struct rb_root *root,
- u64 start, u64 end)
+enum {
+ MEMTYPE_EXACT_MATCH = 0,
+ MEMTYPE_END_MATCH = 1
+};
+
+static struct memtype *memtype_rb_match(struct rb_root *root,
+ u64 start, u64 end, int match_type)
{
struct memtype *match;
@@ -107,7 +112,12 @@ static struct memtype *memtype_rb_exact_match(struct rb_root *root,
while (match != NULL && match->start < end) {
struct rb_node *node;
- if (match->start == start && match->end == end)
+ if ((match_type == MEMTYPE_EXACT_MATCH) &&
+ (match->start == start) && (match->end == end))
+ return match;
+
+ if ((match_type == MEMTYPE_END_MATCH) &&
+ (match->start < start) && (match->end == end))
return match;
node = rb_next(&match->rb);
@@ -117,7 +127,7 @@ static struct memtype *memtype_rb_exact_match(struct rb_root *root,
match = NULL;
}
- return NULL; /* Returns NULL if there is no exact match */
+ return NULL; /* Returns NULL if there is no match */
}
static int memtype_rb_check_conflict(struct rb_root *root,
@@ -210,12 +220,36 @@ struct memtype *rbt_memtype_erase(u64 start, u64 end)
{
struct memtype *data;
- data = memtype_rb_exact_match(&memtype_rbroot, start, end);
- if (!data)
- goto out;
+ /*
+ * Since the memtype_rbroot tree allows overlapping ranges,
+ * rbt_memtype_erase() checks with EXACT_MATCH first, i.e. free
+ * a whole node for the munmap case. If no such entry is found,
+ * it then checks with END_MATCH, i.e. shrink the size of a node
+ * from the end for the mremap case.
+ */
+ data = memtype_rb_match(&memtype_rbroot, start, end,
+ MEMTYPE_EXACT_MATCH);
+ if (!data) {
+ data = memtype_rb_match(&memtype_rbroot, start, end,
+ MEMTYPE_END_MATCH);
+ if (!data)
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (data->start == start) {
+ /* munmap: erase this node */
+ rb_erase_augmented(&data->rb, &memtype_rbroot,
+ &memtype_rb_augment_cb);
+ } else {
+ /* mremap: update the end value of this node */
+ rb_erase_augmented(&data->rb, &memtype_rbroot,
+ &memtype_rb_augment_cb);
+ data->end = start;
+ data->subtree_max_end = data->end;
+ memtype_rb_insert(&memtype_rbroot, data);
+ return NULL;
+ }
- rb_erase_augmented(&data->rb, &memtype_rbroot, &memtype_rb_augment_cb);
-out:
return data;
}
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index fb0a9dd..4eb287e 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -414,7 +414,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
if (changed && dirty) {
*ptep = entry;
- pte_update_defer(vma->vm_mm, address, ptep);
+ pte_update(vma->vm_mm, address, ptep);
}
return changed;
@@ -431,7 +431,6 @@ int pmdp_set_access_flags(struct vm_area_struct *vma,
if (changed && dirty) {
*pmdp = entry;
- pmd_update_defer(vma->vm_mm, address, pmdp);
/*
* We had a write-protection fault here and changed the pmd
* to to more permissive. No need to flush the TLB for that,
@@ -469,9 +468,6 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma,
ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,
(unsigned long *)pmdp);
- if (ret)
- pmd_update(vma->vm_mm, addr, pmdp);
-
return ret;
}
#endif
@@ -509,20 +505,6 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma,
return young;
}
-
-void pmdp_splitting_flush(struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmdp)
-{
- int set;
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- set = !test_and_set_bit(_PAGE_BIT_SPLITTING,
- (unsigned long *)pmdp);
- if (set) {
- pmd_update(vma->vm_mm, address, pmdp);
- /* need tlb flush only to serialize against gup-fast */
- flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
- }
-}
#endif
/**
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c
index 90555bf..8bea847 100644
--- a/arch/x86/mm/setup_nx.c
+++ b/arch/x86/mm/setup_nx.c
@@ -4,6 +4,7 @@
#include <asm/pgtable.h>
#include <asm/proto.h>
+#include <asm/cpufeature.h>
static int disable_nx;
@@ -31,15 +32,14 @@ early_param("noexec", noexec_setup);
void x86_configure_nx(void)
{
- if (cpu_has_nx && !disable_nx)
- __supported_pte_mask |= _PAGE_NX;
- else
+ /* If disable_nx is set, clear NX on all new mappings going forward. */
+ if (disable_nx)
__supported_pte_mask &= ~_PAGE_NX;
}
void __init x86_report_nx(void)
{
- if (!cpu_has_nx) {
+ if (!boot_cpu_has(X86_FEATURE_NX)) {
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
"missing in CPU!\n");
} else {
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
index c2aea63..b5f8218 100644
--- a/arch/x86/mm/srat.c
+++ b/arch/x86/mm/srat.c
@@ -203,6 +203,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
pr_warn("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n",
(unsigned long long)start, (unsigned long long)end - 1);
+ max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
+
return 0;
out_err_bad_srat:
bad_srat();
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 8ddb5d0..8f4cc3d 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -161,7 +161,10 @@ void flush_tlb_current_task(void)
preempt_disable();
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
+
+ /* This is an implicit full barrier that synchronizes with switch_mm. */
local_flush_tlb();
+
trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL);
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL);
@@ -188,17 +191,29 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
unsigned long base_pages_to_flush = TLB_FLUSH_ALL;
preempt_disable();
- if (current->active_mm != mm)
+ if (current->active_mm != mm) {
+ /* Synchronize with switch_mm. */
+ smp_mb();
+
goto out;
+ }
if (!current->mm) {
leave_mm(smp_processor_id());
+
+ /* Synchronize with switch_mm. */
+ smp_mb();
+
goto out;
}
if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB))
base_pages_to_flush = (end - start) >> PAGE_SHIFT;
+ /*
+ * Both branches below are implicit full barriers (MOV to CR or
+ * INVLPG) that synchronize with switch_mm.
+ */
if (base_pages_to_flush > tlb_single_page_flush_ceiling) {
base_pages_to_flush = TLB_FLUSH_ALL;
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
@@ -228,10 +243,18 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long start)
preempt_disable();
if (current->active_mm == mm) {
- if (current->mm)
+ if (current->mm) {
+ /*
+ * Implicit full barrier (INVLPG) that synchronizes
+ * with switch_mm.
+ */
__flush_tlb_one(start);
- else
+ } else {
leave_mm(smp_processor_id());
+
+ /* Synchronize with switch_mm. */
+ smp_mb();
+ }
}
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 70efcd0..4286f36 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -193,7 +193,7 @@ struct jit_context {
32 /* space for rbx, r13, r14, r15 */ + \
8 /* space for skb_copy_bits() buffer */)
-#define PROLOGUE_SIZE 51
+#define PROLOGUE_SIZE 48
/* emit x64 prologue code for BPF program and check it's size.
* bpf_tail_call helper will skip it while jumping into another program
@@ -229,11 +229,15 @@ static void emit_prologue(u8 **pprog)
/* mov qword ptr [rbp-X],r15 */
EMIT3_off32(0x4C, 0x89, 0xBD, -STACKSIZE + 24);
- /* clear A and X registers */
- EMIT2(0x31, 0xc0); /* xor eax, eax */
- EMIT3(0x4D, 0x31, 0xED); /* xor r13, r13 */
+ /* Clear the tail call counter (tail_call_cnt): for eBPF tail calls
+ * we need to reset the counter to 0. It's done in two instructions,
+ * resetting rax register to 0 (xor on eax gets 0 extended), and
+ * moving it to the counter location.
+ */
- /* clear tail_cnt: mov qword ptr [rbp-X], rax */
+ /* xor eax, eax */
+ EMIT2(0x31, 0xc0);
+ /* mov qword ptr [rbp-X], rax */
EMIT3_off32(0x48, 0x89, 0x85, -STACKSIZE + 32);
BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
@@ -455,6 +459,18 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
}
case BPF_ALU | BPF_MOV | BPF_K:
+ /* optimization: if imm32 is zero, use 'xor <dst>,<dst>'
+ * to save 3 bytes.
+ */
+ if (imm32 == 0) {
+ if (is_ereg(dst_reg))
+ EMIT1(add_2mod(0x40, dst_reg, dst_reg));
+ b2 = 0x31; /* xor */
+ b3 = 0xC0;
+ EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
+ break;
+ }
+
/* mov %eax, imm32 */
if (is_ereg(dst_reg))
EMIT1(add_1mod(0x40, dst_reg));
@@ -469,6 +485,20 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
return -EINVAL;
}
+ /* optimization: if imm64 is zero, use 'xor <dst>,<dst>'
+ * to save 7 bytes.
+ */
+ if (insn[0].imm == 0 && insn[1].imm == 0) {
+ b1 = add_2mod(0x48, dst_reg, dst_reg);
+ b2 = 0x31; /* xor */
+ b3 = 0xC0;
+ EMIT3(b1, b2, add_2reg(b3, dst_reg, dst_reg));
+
+ insn++;
+ i++;
+ break;
+ }
+
/* movabsq %rax, imm64 */
EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
EMIT(insn[0].imm, 4);
@@ -1109,7 +1139,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
bpf_flush_icache(header, image + proglen);
set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)image;
- prog->jited = true;
+ prog->jited = 1;
}
out:
kfree(addrs);
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index 4e664bd..cb31a44 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -23,12 +23,13 @@ static int backtrace_stack(void *data, char *name)
return 0;
}
-static void backtrace_address(void *data, unsigned long addr, int reliable)
+static int backtrace_address(void *data, unsigned long addr, int reliable)
{
unsigned int *depth = data;
if ((*depth)--)
oprofile_add_trace(addr);
+ return 0;
}
static struct stacktrace_ops backtrace_ops = {
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 50d86c0..660a83c 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -24,7 +24,6 @@
#include <asm/nmi.h>
#include <asm/apic.h>
#include <asm/processor.h>
-#include <asm/cpufeature.h>
#include "op_x86_model.h"
#include "op_counter.h"
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 5c6fc35..97062a6 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -23,6 +23,8 @@ obj-y += bus_numa.o
obj-$(CONFIG_AMD_NB) += amd_bus.o
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
+obj-$(CONFIG_VMD) += vmd.o
+
ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index ff99117..3cd6983 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,16 +4,15 @@
#include <linux/irq.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <linux/pci-acpi.h>
#include <asm/numa.h>
#include <asm/pci_x86.h>
struct pci_root_info {
- struct acpi_device *bridge;
- char name[16];
+ struct acpi_pci_root_info common;
struct pci_sysdata sd;
#ifdef CONFIG_PCI_MMCONFIG
bool mcfg_added;
- u16 segment;
u8 start_bus;
u8 end_bus;
#endif
@@ -178,15 +177,18 @@ static int check_segment(u16 seg, struct device *dev, char *estr)
return 0;
}
-static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
- u8 end, phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
{
- int result;
- struct device *dev = &info->bridge->dev;
+ int result, seg;
+ struct pci_root_info *info;
+ struct acpi_pci_root *root = ci->root;
+ struct device *dev = &ci->bridge->dev;
- info->start_bus = start;
- info->end_bus = end;
+ info = container_of(ci, struct pci_root_info, common);
+ info->start_bus = (u8)root->secondary.start;
+ info->end_bus = (u8)root->secondary.end;
info->mcfg_added = false;
+ seg = info->sd.domain;
/* return success if MMCFG is not in use */
if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
@@ -195,7 +197,8 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
if (!(pci_probe & PCI_PROBE_MMCONF))
return check_segment(seg, dev, "MMCONFIG is disabled,");
- result = pci_mmconfig_insert(dev, seg, start, end, addr);
+ result = pci_mmconfig_insert(dev, seg, info->start_bus, info->end_bus,
+ root->mcfg_addr);
if (result == 0) {
/* enable MMCFG if it hasn't been enabled yet */
if (raw_pci_ext_ops == NULL)
@@ -208,134 +211,55 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
return 0;
}
-static void teardown_mcfg_map(struct pci_root_info *info)
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
{
+ struct pci_root_info *info;
+
+ info = container_of(ci, struct pci_root_info, common);
if (info->mcfg_added) {
- pci_mmconfig_delete(info->segment, info->start_bus,
- info->end_bus);
+ pci_mmconfig_delete(info->sd.domain,
+ info->start_bus, info->end_bus);
info->mcfg_added = false;
}
}
#else
-static int setup_mcfg_map(struct pci_root_info *info,
- u16 seg, u8 start, u8 end,
- phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
{
return 0;
}
-static void teardown_mcfg_map(struct pci_root_info *info)
+
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
{
}
#endif
-static void validate_resources(struct device *dev, struct list_head *crs_res,
- unsigned long type)
+static int pci_acpi_root_get_node(struct acpi_pci_root *root)
{
- LIST_HEAD(list);
- struct resource *res1, *res2, *root = NULL;
- struct resource_entry *tmp, *entry, *entry2;
-
- BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
- root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
-
- list_splice_init(crs_res, &list);
- resource_list_for_each_entry_safe(entry, tmp, &list) {
- bool free = false;
- resource_size_t end;
-
- res1 = entry->res;
- if (!(res1->flags & type))
- goto next;
-
- /* Exclude non-addressable range or non-addressable portion */
- end = min(res1->end, root->end);
- if (end <= res1->start) {
- dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
- res1);
- free = true;
- goto next;
- } else if (res1->end != end) {
- dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
- res1, (unsigned long long)end + 1,
- (unsigned long long)res1->end);
- res1->end = end;
- }
-
- resource_list_for_each_entry(entry2, crs_res) {
- res2 = entry2->res;
- if (!(res2->flags & type))
- continue;
-
- /*
- * I don't like throwing away windows because then
- * our resources no longer match the ACPI _CRS, but
- * the kernel resource tree doesn't allow overlaps.
- */
- if (resource_overlaps(res1, res2)) {
- res2->start = min(res1->start, res2->start);
- res2->end = max(res1->end, res2->end);
- dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
- res2, res1);
- free = true;
- goto next;
- }
- }
+ int busnum = root->secondary.start;
+ struct acpi_device *device = root->device;
+ int node = acpi_get_node(device->handle);
-next:
- resource_list_del(entry);
- if (free)
- resource_list_free_entry(entry);
- else
- resource_list_add_tail(entry, crs_res);
+ if (node == NUMA_NO_NODE) {
+ node = x86_pci_root_bus_node(busnum);
+ if (node != 0 && node != NUMA_NO_NODE)
+ dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
+ node);
}
+ if (node != NUMA_NO_NODE && !node_online(node))
+ node = NUMA_NO_NODE;
+
+ return node;
}
-static void add_resources(struct pci_root_info *info,
- struct list_head *resources,
- struct list_head *crs_res)
+static int pci_acpi_root_init_info(struct acpi_pci_root_info *ci)
{
- struct resource_entry *entry, *tmp;
- struct resource *res, *conflict, *root = NULL;
-
- validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM);
- validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO);
-
- resource_list_for_each_entry_safe(entry, tmp, crs_res) {
- res = entry->res;
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
- else if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- else
- BUG_ON(res);
-
- conflict = insert_resource_conflict(root, res);
- if (conflict) {
- dev_info(&info->bridge->dev,
- "ignoring host bridge window %pR (conflicts with %s %pR)\n",
- res, conflict->name, conflict);
- resource_list_destroy_entry(entry);
- }
- }
-
- list_splice_tail(crs_res, resources);
+ return setup_mcfg_map(ci);
}
-static void release_pci_root_info(struct pci_host_bridge *bridge)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
{
- struct resource *res;
- struct resource_entry *entry;
- struct pci_root_info *info = bridge->release_data;
-
- resource_list_for_each_entry(entry, &bridge->windows) {
- res = entry->res;
- if (res->parent &&
- (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
- release_resource(res);
- }
-
- teardown_mcfg_map(info);
- kfree(info);
+ teardown_mcfg_map(ci);
+ kfree(container_of(ci, struct pci_root_info, common));
}
/*
@@ -358,50 +282,47 @@ static bool resource_is_pcicfg_ioport(struct resource *res)
res->start == 0xCF8 && res->end == 0xCFF;
}
-static void probe_pci_root_info(struct pci_root_info *info,
- struct acpi_device *device,
- int busnum, int domain,
- struct list_head *list)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
- int ret;
+ struct acpi_device *device = ci->bridge;
+ int busnum = ci->root->secondary.start;
struct resource_entry *entry, *tmp;
+ int status;
- sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
- info->bridge = device;
- ret = acpi_dev_get_resources(device, list,
- acpi_dev_filter_resource_type_cb,
- (void *)(IORESOURCE_IO | IORESOURCE_MEM));
- if (ret < 0)
- dev_warn(&device->dev,
- "failed to parse _CRS method, error code %d\n", ret);
- else if (ret == 0)
- dev_dbg(&device->dev,
- "no IO and memory resources present in _CRS\n");
- else
- resource_list_for_each_entry_safe(entry, tmp, list) {
- if ((entry->res->flags & IORESOURCE_DISABLED) ||
- resource_is_pcicfg_ioport(entry->res))
+ status = acpi_pci_probe_root_resources(ci);
+ if (pci_use_crs) {
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
+ if (resource_is_pcicfg_ioport(entry->res))
resource_list_destroy_entry(entry);
- else
- entry->res->name = info->name;
- }
+ return status;
+ }
+
+ resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+ dev_printk(KERN_DEBUG, &device->dev,
+ "host bridge window %pR (ignored)\n", entry->res);
+ resource_list_destroy_entry(entry);
+ }
+ x86_pci_root_bus_resources(busnum, &ci->resources);
+
+ return 0;
}
+static struct acpi_pci_root_ops acpi_pci_root_ops = {
+ .pci_ops = &pci_root_ops,
+ .init_info = pci_acpi_root_init_info,
+ .release_info = pci_acpi_root_release_info,
+ .prepare_resources = pci_acpi_root_prepare_resources,
+};
+
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
- struct acpi_device *device = root->device;
- struct pci_root_info *info;
int domain = root->segment;
int busnum = root->secondary.start;
- struct resource_entry *res_entry;
- LIST_HEAD(crs_res);
- LIST_HEAD(resources);
+ int node = pci_acpi_root_get_node(root);
struct pci_bus *bus;
- struct pci_sysdata *sd;
- int node;
if (pci_ignore_seg)
- domain = 0;
+ root->segment = domain = 0;
if (domain && !pci_domains_supported) {
printk(KERN_WARNING "pci_bus %04x:%02x: "
@@ -410,71 +331,33 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
return NULL;
}
- node = acpi_get_node(device->handle);
- if (node == NUMA_NO_NODE) {
- node = x86_pci_root_bus_node(busnum);
- if (node != 0 && node != NUMA_NO_NODE)
- dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
- node);
- }
-
- if (node != NUMA_NO_NODE && !node_online(node))
- node = NUMA_NO_NODE;
-
- info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
- if (!info) {
- printk(KERN_WARNING "pci_bus %04x:%02x: "
- "ignored (out of memory)\n", domain, busnum);
- return NULL;
- }
-
- sd = &info->sd;
- sd->domain = domain;
- sd->node = node;
- sd->companion = device;
-
bus = pci_find_bus(domain, busnum);
if (bus) {
/*
* If the desired bus has been scanned already, replace
* its bus->sysdata.
*/
- memcpy(bus->sysdata, sd, sizeof(*sd));
- kfree(info);
- } else {
- /* insert busn res at first */
- pci_add_resource(&resources, &root->secondary);
+ struct pci_sysdata sd = {
+ .domain = domain,
+ .node = node,
+ .companion = root->device
+ };
- /*
- * _CRS with no apertures is normal, so only fall back to
- * defaults or native bridge info if we're ignoring _CRS.
- */
- probe_pci_root_info(info, device, busnum, domain, &crs_res);
- if (pci_use_crs) {
- add_resources(info, &resources, &crs_res);
- } else {
- resource_list_for_each_entry(res_entry, &crs_res)
- dev_printk(KERN_DEBUG, &device->dev,
- "host bridge window %pR (ignored)\n",
- res_entry->res);
- resource_list_free(&crs_res);
- x86_pci_root_bus_resources(busnum, &resources);
- }
-
- if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
- (u8)root->secondary.end, root->mcfg_addr))
- bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
- sd, &resources);
-
- if (bus) {
- pci_scan_child_bus(bus);
- pci_set_host_bridge_release(
- to_pci_host_bridge(bus->bridge),
- release_pci_root_info, info);
- } else {
- resource_list_free(&resources);
- teardown_mcfg_map(info);
- kfree(info);
+ memcpy(bus->sysdata, &sd, sizeof(sd));
+ } else {
+ struct pci_root_info *info;
+
+ info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
+ if (!info)
+ dev_err(&root->device->dev,
+ "pci_bus %04x:%02x: ignored (out of memory)\n",
+ domain, busnum);
+ else {
+ info->sd.domain = domain;
+ info->sd.node = node;
+ info->sd.companion = root->device;
+ bus = acpi_pci_root_create(root, &acpi_pci_root_ops,
+ &info->common, &info->sd);
}
}
@@ -487,9 +370,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
pcie_bus_configure_settings(child);
}
- if (bus && node != NUMA_NO_NODE)
- dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
-
return bus;
}
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index 7bcf06a..6eb3c8a 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -50,18 +50,9 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
if (!found)
pci_add_resource(resources, &info->busn);
- list_for_each_entry(root_res, &info->resources, list) {
- struct resource *res;
- struct resource *root;
+ list_for_each_entry(root_res, &info->resources, list)
+ pci_add_resource(resources, &root_res->res);
- res = &root_res->res;
- pci_add_resource(resources, res);
- if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- else
- root = &iomem_resource;
- insert_resource(root, res);
- }
return;
default_resources:
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index dc78a4a..381a43c 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -12,7 +12,6 @@
#include <linux/dmi.h>
#include <linux/slab.h>
-#include <asm-generic/pci-bridge.h>
#include <asm/acpi.h>
#include <asm/segment.h>
#include <asm/io.h>
@@ -641,6 +640,43 @@ unsigned int pcibios_assign_all_busses(void)
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
}
+#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
+static LIST_HEAD(dma_domain_list);
+static DEFINE_SPINLOCK(dma_domain_list_lock);
+
+void add_dma_domain(struct dma_domain *domain)
+{
+ spin_lock(&dma_domain_list_lock);
+ list_add(&domain->node, &dma_domain_list);
+ spin_unlock(&dma_domain_list_lock);
+}
+EXPORT_SYMBOL_GPL(add_dma_domain);
+
+void del_dma_domain(struct dma_domain *domain)
+{
+ spin_lock(&dma_domain_list_lock);
+ list_del(&domain->node);
+ spin_unlock(&dma_domain_list_lock);
+}
+EXPORT_SYMBOL_GPL(del_dma_domain);
+
+static void set_dma_domain_ops(struct pci_dev *pdev)
+{
+ struct dma_domain *domain;
+
+ spin_lock(&dma_domain_list_lock);
+ list_for_each_entry(domain, &dma_domain_list, node) {
+ if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
+ pdev->dev.archdata.dma_ops = domain->dma_ops;
+ break;
+ }
+ }
+ spin_unlock(&dma_domain_list_lock);
+}
+#else
+static void set_dma_domain_ops(struct pci_dev *pdev) {}
+#endif
+
int pcibios_add_device(struct pci_dev *dev)
{
struct setup_data *data;
@@ -670,23 +706,26 @@ int pcibios_add_device(struct pci_dev *dev)
pa_data = data->next;
iounmap(data);
}
+ set_dma_domain_ops(dev);
return 0;
}
-int pcibios_alloc_irq(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
{
- return pcibios_enable_irq(dev);
-}
+ int err;
-void pcibios_free_irq(struct pci_dev *dev)
-{
- if (pcibios_disable_irq)
- pcibios_disable_irq(dev);
+ if ((err = pci_enable_resources(dev, mask)) < 0)
+ return err;
+
+ if (!pci_dev_msi_enabled(dev))
+ return pcibios_enable_irq(dev);
+ return 0;
}
-int pcibios_enable_device(struct pci_dev *dev, int mask)
+void pcibios_disable_device (struct pci_dev *dev)
{
- return pci_enable_resources(dev, mask);
+ if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
+ pcibios_disable_irq(dev);
}
int pci_ext_cfg_avail(void)
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index e585655..b7de192 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -297,14 +297,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_r
*
* The standard boot ROM sequence for an x86 machine uses the BIOS
* to select an initial video card for boot display. This boot video
- * card will have it's BIOS copied to C0000 in system RAM.
+ * card will have its BIOS copied to 0xC0000 in system RAM.
* IORESOURCE_ROM_SHADOW is used to associate the boot video
* card with this copy. On laptops this copy has to be used since
* the main ROM may be compressed or combined with another image.
* See pci_map_rom() for use of this flag. Before marking the device
* with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set
- * by either arch cde or vga-arbitration, if so only apply the fixup to this
- * already determined primary video card.
+ * by either arch code or vga-arbitration; if so only apply the fixup to this
+ * already-determined primary video card.
*/
static void pci_fixup_video(struct pci_dev *pdev)
@@ -312,6 +312,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
struct pci_dev *bridge;
struct pci_bus *bus;
u16 config;
+ struct resource *res;
/* Is VGA routed to us? */
bus = pdev->bus;
@@ -336,8 +337,18 @@ static void pci_fixup_video(struct pci_dev *pdev)
if (!vga_default_device() || pdev == vga_default_device()) {
pci_read_config_word(pdev, PCI_COMMAND, &config);
if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
- pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
- dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n");
+ res = &pdev->resource[PCI_ROM_RESOURCE];
+
+ pci_disable_rom(pdev);
+ if (res->parent)
+ release_resource(res);
+
+ res->start = 0xC0000;
+ res->end = res->start + 0x20000 - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
+ IORESOURCE_PCI_FIXED;
+ dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n",
+ res);
}
}
}
@@ -540,3 +551,10 @@ static void twinhead_reserve_killing_zone(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone);
+
+static void pci_bdwep_bar(struct pci_dev *dev)
+{
+ dev->non_compliant_bars = 1;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar);
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c
index 0d24e7c..8b93e63 100644
--- a/arch/x86/pci/intel_mid_pci.c
+++ b/arch/x86/pci/intel_mid_pci.c
@@ -215,7 +215,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
int polarity;
int ret;
- if (pci_has_managed_irq(dev))
+ if (dev->irq_managed && dev->irq > 0)
return 0;
switch (intel_mid_identify_cpu()) {
@@ -256,13 +256,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{
- if (pci_has_managed_irq(dev)) {
+ if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
+ dev->irq > 0) {
mp_unmap_irq(dev->irq);
dev->irq_managed = 0;
- /*
- * Don't reset dev->irq here, otherwise
- * intel_mid_pci_irq_enable() will fail on next call.
- */
}
}
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 32e7034..9bd1154 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
struct pci_dev *temp_dev;
int irq;
- if (pci_has_managed_irq(dev))
+ if (dev->irq_managed && dev->irq > 0)
return 0;
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
@@ -1230,7 +1230,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
}
dev = temp_dev;
if (irq >= 0) {
- pci_set_managed_irq(dev, irq);
+ dev->irq_managed = 1;
+ dev->irq = irq;
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
return 0;
@@ -1256,10 +1257,24 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0;
}
+bool mp_should_keep_irq(struct device *dev)
+{
+ if (dev->power.is_prepared)
+ return true;
+#ifdef CONFIG_PM
+ if (dev->power.runtime_status == RPM_SUSPENDING)
+ return true;
+#endif
+
+ return false;
+}
+
static void pirq_disable_irq(struct pci_dev *dev)
{
- if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) {
+ if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
+ dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq);
- pci_reset_managed_irq(dev);
+ dev->irq = 0;
+ dev->irq_managed = 0;
}
}
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 5b662c0..ea6f380 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -54,7 +54,7 @@ void pcibios_scan_specific_bus(int busn)
}
EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus);
-int __init pci_subsys_init(void)
+static int __init pci_subsys_init(void)
{
/*
* The init function returns an non zero value when
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 9b83b90..9770e55 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
+ u16 number = 0, mask = 0;
WARN_ON(seg);
if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
@@ -189,53 +190,35 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (result)
- : "1" (PCIBIOS_READ_CONFIG_BYTE),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
- /*
- * Zero-extend the result beyond 8 bits, do not trust the
- * BIOS having done it:
- */
- *value &= 0xff;
+ number = PCIBIOS_READ_CONFIG_BYTE;
+ mask = 0xff;
break;
case 2:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (result)
- : "1" (PCIBIOS_READ_CONFIG_WORD),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
- /*
- * Zero-extend the result beyond 16 bits, do not trust the
- * BIOS having done it:
- */
- *value &= 0xffff;
+ number = PCIBIOS_READ_CONFIG_WORD;
+ mask = 0xffff;
break;
case 4:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (result)
- : "1" (PCIBIOS_READ_CONFIG_DWORD),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
+ number = PCIBIOS_READ_CONFIG_DWORD;
break;
}
+ __asm__("lcall *(%%esi); cld\n\t"
+ "jc 1f\n\t"
+ "xor %%ah, %%ah\n"
+ "1:"
+ : "=c" (*value),
+ "=a" (result)
+ : "1" (number),
+ "b" (bx),
+ "D" ((long)reg),
+ "S" (&pci_indirect));
+ /*
+ * Zero-extend the result beyond 8 or 16 bits, do not trust the
+ * BIOS having done it:
+ */
+ if (mask)
+ *value &= mask;
+
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return (int)((result & 0xff00) >> 8);
@@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
+ u16 number = 0;
WARN_ON(seg);
if ((bus > 255) || (devfn > 255) || (reg > 255))
@@ -256,43 +240,27 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (result)
- : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
- "c" (value),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
+ number = PCIBIOS_WRITE_CONFIG_BYTE;
break;
case 2:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (result)
- : "0" (PCIBIOS_WRITE_CONFIG_WORD),
- "c" (value),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
+ number = PCIBIOS_WRITE_CONFIG_WORD;
break;
case 4:
- __asm__("lcall *(%%esi); cld\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (result)
- : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
- "c" (value),
- "b" (bx),
- "D" ((long)reg),
- "S" (&pci_indirect));
+ number = PCIBIOS_WRITE_CONFIG_DWORD;
break;
}
+ __asm__("lcall *(%%esi); cld\n\t"
+ "jc 1f\n\t"
+ "xor %%ah, %%ah\n"
+ "1:"
+ : "=a" (result)
+ : "0" (number),
+ "c" (value),
+ "b" (bx),
+ "D" ((long)reg),
+ "S" (&pci_indirect));
+
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return (int)((result & 0xff00) >> 8);
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c
new file mode 100644
index 0000000..7792aba
--- /dev/null
+++ b/arch/x86/pci/vmd.c
@@ -0,0 +1,756 @@
+/*
+ * Volume Management Device driver
+ * Copyright (c) 2015, 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.
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/pci.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+
+#include <asm/irqdomain.h>
+#include <asm/device.h>
+#include <asm/msi.h>
+#include <asm/msidef.h>
+
+#define VMD_CFGBAR 0
+#define VMD_MEMBAR1 2
+#define VMD_MEMBAR2 4
+
+/*
+ * Lock for manipulating VMD IRQ lists.
+ */
+static DEFINE_RAW_SPINLOCK(list_lock);
+
+/**
+ * struct vmd_irq - private data to map driver IRQ to the VMD shared vector
+ * @node: list item for parent traversal.
+ * @rcu: RCU callback item for freeing.
+ * @irq: back pointer to parent.
+ * @virq: the virtual IRQ value provided to the requesting driver.
+ *
+ * Every MSI/MSI-X IRQ requested for a device in a VMD domain will be mapped to
+ * a VMD IRQ using this structure.
+ */
+struct vmd_irq {
+ struct list_head node;
+ struct rcu_head rcu;
+ struct vmd_irq_list *irq;
+ unsigned int virq;
+};
+
+/**
+ * struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
+ * @irq_list: the list of irq's the VMD one demuxes to.
+ * @vmd_vector: the h/w IRQ assigned to the VMD.
+ * @index: index into the VMD MSI-X table; used for message routing.
+ * @count: number of child IRQs assigned to this vector; used to track
+ * sharing.
+ */
+struct vmd_irq_list {
+ struct list_head irq_list;
+ struct vmd_dev *vmd;
+ unsigned int vmd_vector;
+ unsigned int index;
+ unsigned int count;
+};
+
+struct vmd_dev {
+ struct pci_dev *dev;
+
+ spinlock_t cfg_lock;
+ char __iomem *cfgbar;
+
+ int msix_count;
+ struct msix_entry *msix_entries;
+ struct vmd_irq_list *irqs;
+
+ struct pci_sysdata sysdata;
+ struct resource resources[3];
+ struct irq_domain *irq_domain;
+ struct pci_bus *bus;
+
+#ifdef CONFIG_X86_DEV_DMA_OPS
+ struct dma_map_ops dma_ops;
+ struct dma_domain dma_domain;
+#endif
+};
+
+static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
+{
+ return container_of(bus->sysdata, struct vmd_dev, sysdata);
+}
+
+/*
+ * Drivers managing a device in a VMD domain allocate their own IRQs as before,
+ * but the MSI entry for the hardware it's driving will be programmed with a
+ * destination ID for the VMD MSI-X table. The VMD muxes interrupts in its
+ * domain into one of its own, and the VMD driver de-muxes these for the
+ * handlers sharing that VMD IRQ. The vmd irq_domain provides the operations
+ * and irq_chip to set this up.
+ */
+static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+ struct vmd_irq *vmdirq = data->chip_data;
+ struct vmd_irq_list *irq = vmdirq->irq;
+
+ msg->address_hi = MSI_ADDR_BASE_HI;
+ msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_DEST_ID(irq->index);
+ msg->data = 0;
+}
+
+/*
+ * We rely on MSI_FLAG_USE_DEF_CHIP_OPS to set the IRQ mask/unmask ops.
+ */
+static void vmd_irq_enable(struct irq_data *data)
+{
+ struct vmd_irq *vmdirq = data->chip_data;
+
+ raw_spin_lock(&list_lock);
+ list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list);
+ raw_spin_unlock(&list_lock);
+
+ data->chip->irq_unmask(data);
+}
+
+static void vmd_irq_disable(struct irq_data *data)
+{
+ struct vmd_irq *vmdirq = data->chip_data;
+
+ data->chip->irq_mask(data);
+
+ raw_spin_lock(&list_lock);
+ list_del_rcu(&vmdirq->node);
+ raw_spin_unlock(&list_lock);
+}
+
+/*
+ * XXX: Stubbed until we develop acceptable way to not create conflicts with
+ * other devices sharing the same vector.
+ */
+static int vmd_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+{
+ return -EINVAL;
+}
+
+static struct irq_chip vmd_msi_controller = {
+ .name = "VMD-MSI",
+ .irq_enable = vmd_irq_enable,
+ .irq_disable = vmd_irq_disable,
+ .irq_compose_msi_msg = vmd_compose_msi_msg,
+ .irq_set_affinity = vmd_irq_set_affinity,
+};
+
+static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info,
+ msi_alloc_info_t *arg)
+{
+ return 0;
+}
+
+/*
+ * XXX: We can be even smarter selecting the best IRQ once we solve the
+ * affinity problem.
+ */
+static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd)
+{
+ int i, best = 0;
+
+ raw_spin_lock(&list_lock);
+ for (i = 1; i < vmd->msix_count; i++)
+ if (vmd->irqs[i].count < vmd->irqs[best].count)
+ best = i;
+ vmd->irqs[best].count++;
+ raw_spin_unlock(&list_lock);
+
+ return &vmd->irqs[best];
+}
+
+static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
+ unsigned int virq, irq_hw_number_t hwirq,
+ msi_alloc_info_t *arg)
+{
+ struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(arg->desc)->bus);
+ struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
+
+ if (!vmdirq)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&vmdirq->node);
+ vmdirq->irq = vmd_next_irq(vmd);
+ vmdirq->virq = virq;
+
+ irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip,
+ vmdirq, handle_simple_irq, vmd, NULL);
+ return 0;
+}
+
+static void vmd_msi_free(struct irq_domain *domain,
+ struct msi_domain_info *info, unsigned int virq)
+{
+ struct vmd_irq *vmdirq = irq_get_chip_data(virq);
+
+ /* XXX: Potential optimization to rebalance */
+ raw_spin_lock(&list_lock);
+ vmdirq->irq->count--;
+ raw_spin_unlock(&list_lock);
+
+ kfree_rcu(vmdirq, rcu);
+}
+
+static int vmd_msi_prepare(struct irq_domain *domain, struct device *dev,
+ int nvec, msi_alloc_info_t *arg)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+ if (nvec > vmd->msix_count)
+ return vmd->msix_count;
+
+ memset(arg, 0, sizeof(*arg));
+ return 0;
+}
+
+static void vmd_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+ arg->desc = desc;
+}
+
+static struct msi_domain_ops vmd_msi_domain_ops = {
+ .get_hwirq = vmd_get_hwirq,
+ .msi_init = vmd_msi_init,
+ .msi_free = vmd_msi_free,
+ .msi_prepare = vmd_msi_prepare,
+ .set_desc = vmd_set_desc,
+};
+
+static struct msi_domain_info vmd_msi_domain_info = {
+ .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX,
+ .ops = &vmd_msi_domain_ops,
+ .chip = &vmd_msi_controller,
+};
+
+#ifdef CONFIG_X86_DEV_DMA_OPS
+/*
+ * VMD replaces the requester ID with its own. DMA mappings for devices in a
+ * VMD domain need to be mapped for the VMD, not the device requiring
+ * the mapping.
+ */
+static struct device *to_vmd_dev(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
+
+ return &vmd->dev->dev;
+}
+
+static struct dma_map_ops *vmd_dma_ops(struct device *dev)
+{
+ return to_vmd_dev(dev)->archdata.dma_ops;
+}
+
+static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr,
+ gfp_t flag, struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->alloc(to_vmd_dev(dev), size, addr, flag,
+ attrs);
+}
+
+static void vmd_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t addr, struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->free(to_vmd_dev(dev), size, vaddr, addr,
+ attrs);
+}
+
+static int vmd_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t addr, size_t size,
+ struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->mmap(to_vmd_dev(dev), vma, cpu_addr, addr,
+ size, attrs);
+}
+
+static int vmd_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t addr, size_t size,
+ struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->get_sgtable(to_vmd_dev(dev), sgt, cpu_addr,
+ addr, size, attrs);
+}
+
+static dma_addr_t vmd_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->map_page(to_vmd_dev(dev), page, offset, size,
+ dir, attrs);
+}
+
+static void vmd_unmap_page(struct device *dev, dma_addr_t addr, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ vmd_dma_ops(dev)->unmap_page(to_vmd_dev(dev), addr, size, dir, attrs);
+}
+
+static int vmd_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ return vmd_dma_ops(dev)->map_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+}
+
+static void vmd_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ vmd_dma_ops(dev)->unmap_sg(to_vmd_dev(dev), sg, nents, dir, attrs);
+}
+
+static void vmd_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+ vmd_dma_ops(dev)->sync_single_for_cpu(to_vmd_dev(dev), addr, size, dir);
+}
+
+static void vmd_sync_single_for_device(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+ vmd_dma_ops(dev)->sync_single_for_device(to_vmd_dev(dev), addr, size,
+ dir);
+}
+
+static void vmd_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ vmd_dma_ops(dev)->sync_sg_for_cpu(to_vmd_dev(dev), sg, nents, dir);
+}
+
+static void vmd_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ vmd_dma_ops(dev)->sync_sg_for_device(to_vmd_dev(dev), sg, nents, dir);
+}
+
+static int vmd_mapping_error(struct device *dev, dma_addr_t addr)
+{
+ return vmd_dma_ops(dev)->mapping_error(to_vmd_dev(dev), addr);
+}
+
+static int vmd_dma_supported(struct device *dev, u64 mask)
+{
+ return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);
+}
+
+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+static u64 vmd_get_required_mask(struct device *dev)
+{
+ return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));
+}
+#endif
+
+static void vmd_teardown_dma_ops(struct vmd_dev *vmd)
+{
+ struct dma_domain *domain = &vmd->dma_domain;
+
+ if (vmd->dev->dev.archdata.dma_ops)
+ del_dma_domain(domain);
+}
+
+#define ASSIGN_VMD_DMA_OPS(source, dest, fn) \
+ do { \
+ if (source->fn) \
+ dest->fn = vmd_##fn; \
+ } while (0)
+
+static void vmd_setup_dma_ops(struct vmd_dev *vmd)
+{
+ const struct dma_map_ops *source = vmd->dev->dev.archdata.dma_ops;
+ struct dma_map_ops *dest = &vmd->dma_ops;
+ struct dma_domain *domain = &vmd->dma_domain;
+
+ domain->domain_nr = vmd->sysdata.domain;
+ domain->dma_ops = dest;
+
+ if (!source)
+ return;
+ ASSIGN_VMD_DMA_OPS(source, dest, alloc);
+ ASSIGN_VMD_DMA_OPS(source, dest, free);
+ ASSIGN_VMD_DMA_OPS(source, dest, mmap);
+ ASSIGN_VMD_DMA_OPS(source, dest, get_sgtable);
+ ASSIGN_VMD_DMA_OPS(source, dest, map_page);
+ ASSIGN_VMD_DMA_OPS(source, dest, unmap_page);
+ ASSIGN_VMD_DMA_OPS(source, dest, map_sg);
+ ASSIGN_VMD_DMA_OPS(source, dest, unmap_sg);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_cpu);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_single_for_device);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_cpu);
+ ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);
+ ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);
+ ASSIGN_VMD_DMA_OPS(source, dest, dma_supported);
+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+ ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
+#endif
+ add_dma_domain(domain);
+}
+#undef ASSIGN_VMD_DMA_OPS
+#else
+static void vmd_teardown_dma_ops(struct vmd_dev *vmd) {}
+static void vmd_setup_dma_ops(struct vmd_dev *vmd) {}
+#endif
+
+static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
+ unsigned int devfn, int reg, int len)
+{
+ char __iomem *addr = vmd->cfgbar +
+ (bus->number << 20) + (devfn << 12) + reg;
+
+ if ((addr - vmd->cfgbar) + len >=
+ resource_size(&vmd->dev->resource[VMD_CFGBAR]))
+ return NULL;
+
+ return addr;
+}
+
+/*
+ * CPU may deadlock if config space is not serialized on some versions of this
+ * hardware, so all config space access is done under a spinlock.
+ */
+static int vmd_pci_read(struct pci_bus *bus, unsigned int devfn, int reg,
+ int len, u32 *value)
+{
+ struct vmd_dev *vmd = vmd_from_bus(bus);
+ char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+ unsigned long flags;
+ int ret = 0;
+
+ if (!addr)
+ return -EFAULT;
+
+ spin_lock_irqsave(&vmd->cfg_lock, flags);
+ switch (len) {
+ case 1:
+ *value = readb(addr);
+ break;
+ case 2:
+ *value = readw(addr);
+ break;
+ case 4:
+ *value = readl(addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+ return ret;
+}
+
+/*
+ * VMD h/w converts non-posted config writes to posted memory writes. The
+ * read-back in this function forces the completion so it returns only after
+ * the config space was written, as expected.
+ */
+static int vmd_pci_write(struct pci_bus *bus, unsigned int devfn, int reg,
+ int len, u32 value)
+{
+ struct vmd_dev *vmd = vmd_from_bus(bus);
+ char __iomem *addr = vmd_cfg_addr(vmd, bus, devfn, reg, len);
+ unsigned long flags;
+ int ret = 0;
+
+ if (!addr)
+ return -EFAULT;
+
+ spin_lock_irqsave(&vmd->cfg_lock, flags);
+ switch (len) {
+ case 1:
+ writeb(value, addr);
+ readb(addr);
+ break;
+ case 2:
+ writew(value, addr);
+ readw(addr);
+ break;
+ case 4:
+ writel(value, addr);
+ readl(addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ spin_unlock_irqrestore(&vmd->cfg_lock, flags);
+ return ret;
+}
+
+static struct pci_ops vmd_ops = {
+ .read = vmd_pci_read,
+ .write = vmd_pci_write,
+};
+
+static void vmd_attach_resources(struct vmd_dev *vmd)
+{
+ vmd->dev->resource[VMD_MEMBAR1].child = &vmd->resources[1];
+ vmd->dev->resource[VMD_MEMBAR2].child = &vmd->resources[2];
+}
+
+static void vmd_detach_resources(struct vmd_dev *vmd)
+{
+ vmd->dev->resource[VMD_MEMBAR1].child = NULL;
+ vmd->dev->resource[VMD_MEMBAR2].child = NULL;
+}
+
+/*
+ * VMD domains start at 0x1000 to not clash with ACPI _SEG domains.
+ */
+static int vmd_find_free_domain(void)
+{
+ int domain = 0xffff;
+ struct pci_bus *bus = NULL;
+
+ while ((bus = pci_find_next_bus(bus)) != NULL)
+ domain = max_t(int, domain, pci_domain_nr(bus));
+ return domain + 1;
+}
+
+static int vmd_enable_domain(struct vmd_dev *vmd)
+{
+ struct pci_sysdata *sd = &vmd->sysdata;
+ struct resource *res;
+ u32 upper_bits;
+ unsigned long flags;
+ LIST_HEAD(resources);
+
+ res = &vmd->dev->resource[VMD_CFGBAR];
+ vmd->resources[0] = (struct resource) {
+ .name = "VMD CFGBAR",
+ .start = 0,
+ .end = (resource_size(res) >> 20) - 1,
+ .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
+ };
+
+ /*
+ * If the window is below 4GB, clear IORESOURCE_MEM_64 so we can
+ * put 32-bit resources in the window.
+ *
+ * There's no hardware reason why a 64-bit window *couldn't*
+ * contain a 32-bit resource, but pbus_size_mem() computes the
+ * bridge window size assuming a 64-bit window will contain no
+ * 32-bit resources. __pci_assign_resource() enforces that
+ * artificial restriction to make sure everything will fit.
+ *
+ * The only way we could use a 64-bit non-prefechable MEMBAR is
+ * if its address is <4GB so that we can convert it to a 32-bit
+ * resource. To be visible to the host OS, all VMD endpoints must
+ * be initially configured by platform BIOS, which includes setting
+ * up these resources. We can assume the device is configured
+ * according to the platform needs.
+ */
+ res = &vmd->dev->resource[VMD_MEMBAR1];
+ upper_bits = upper_32_bits(res->end);
+ flags = res->flags & ~IORESOURCE_SIZEALIGN;
+ if (!upper_bits)
+ flags &= ~IORESOURCE_MEM_64;
+ vmd->resources[1] = (struct resource) {
+ .name = "VMD MEMBAR1",
+ .start = res->start,
+ .end = res->end,
+ .flags = flags,
+ .parent = res,
+ };
+
+ res = &vmd->dev->resource[VMD_MEMBAR2];
+ upper_bits = upper_32_bits(res->end);
+ flags = res->flags & ~IORESOURCE_SIZEALIGN;
+ if (!upper_bits)
+ flags &= ~IORESOURCE_MEM_64;
+ vmd->resources[2] = (struct resource) {
+ .name = "VMD MEMBAR2",
+ .start = res->start + 0x2000,
+ .end = res->end,
+ .flags = flags,
+ .parent = res,
+ };
+
+ sd->domain = vmd_find_free_domain();
+ if (sd->domain < 0)
+ return sd->domain;
+
+ sd->node = pcibus_to_node(vmd->dev->bus);
+
+ vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info,
+ NULL);
+ if (!vmd->irq_domain)
+ return -ENODEV;
+
+ pci_add_resource(&resources, &vmd->resources[0]);
+ pci_add_resource(&resources, &vmd->resources[1]);
+ pci_add_resource(&resources, &vmd->resources[2]);
+ vmd->bus = pci_create_root_bus(&vmd->dev->dev, 0, &vmd_ops, sd,
+ &resources);
+ if (!vmd->bus) {
+ pci_free_resource_list(&resources);
+ irq_domain_remove(vmd->irq_domain);
+ return -ENODEV;
+ }
+
+ vmd_attach_resources(vmd);
+ vmd_setup_dma_ops(vmd);
+ dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain);
+ pci_rescan_bus(vmd->bus);
+
+ WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj,
+ "domain"), "Can't create symlink to domain\n");
+ return 0;
+}
+
+static irqreturn_t vmd_irq(int irq, void *data)
+{
+ struct vmd_irq_list *irqs = data;
+ struct vmd_irq *vmdirq;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node)
+ generic_handle_irq(vmdirq->virq);
+ rcu_read_unlock();
+
+ return IRQ_HANDLED;
+}
+
+static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct vmd_dev *vmd;
+ int i, err;
+
+ if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20))
+ return -ENOMEM;
+
+ vmd = devm_kzalloc(&dev->dev, sizeof(*vmd), GFP_KERNEL);
+ if (!vmd)
+ return -ENOMEM;
+
+ vmd->dev = dev;
+ err = pcim_enable_device(dev);
+ if (err < 0)
+ return err;
+
+ vmd->cfgbar = pcim_iomap(dev, VMD_CFGBAR, 0);
+ if (!vmd->cfgbar)
+ return -ENOMEM;
+
+ pci_set_master(dev);
+ if (dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64)) &&
+ dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)))
+ return -ENODEV;
+
+ vmd->msix_count = pci_msix_vec_count(dev);
+ if (vmd->msix_count < 0)
+ return -ENODEV;
+
+ vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs),
+ GFP_KERNEL);
+ if (!vmd->irqs)
+ return -ENOMEM;
+
+ vmd->msix_entries = devm_kcalloc(&dev->dev, vmd->msix_count,
+ sizeof(*vmd->msix_entries),
+ GFP_KERNEL);
+ if (!vmd->msix_entries)
+ return -ENOMEM;
+ for (i = 0; i < vmd->msix_count; i++)
+ vmd->msix_entries[i].entry = i;
+
+ vmd->msix_count = pci_enable_msix_range(vmd->dev, vmd->msix_entries, 1,
+ vmd->msix_count);
+ if (vmd->msix_count < 0)
+ return vmd->msix_count;
+
+ for (i = 0; i < vmd->msix_count; i++) {
+ INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
+ vmd->irqs[i].vmd_vector = vmd->msix_entries[i].vector;
+ vmd->irqs[i].index = i;
+
+ err = devm_request_irq(&dev->dev, vmd->irqs[i].vmd_vector,
+ vmd_irq, 0, "vmd", &vmd->irqs[i]);
+ if (err)
+ return err;
+ }
+
+ spin_lock_init(&vmd->cfg_lock);
+ pci_set_drvdata(dev, vmd);
+ err = vmd_enable_domain(vmd);
+ if (err)
+ return err;
+
+ dev_info(&vmd->dev->dev, "Bound to PCI domain %04x\n",
+ vmd->sysdata.domain);
+ return 0;
+}
+
+static void vmd_remove(struct pci_dev *dev)
+{
+ struct vmd_dev *vmd = pci_get_drvdata(dev);
+
+ vmd_detach_resources(vmd);
+ pci_set_drvdata(dev, NULL);
+ sysfs_remove_link(&vmd->dev->dev.kobj, "domain");
+ pci_stop_root_bus(vmd->bus);
+ pci_remove_root_bus(vmd->bus);
+ vmd_teardown_dma_ops(vmd);
+ irq_domain_remove(vmd->irq_domain);
+}
+
+#ifdef CONFIG_PM
+static int vmd_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ pci_save_state(pdev);
+ return 0;
+}
+
+static int vmd_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ pci_restore_state(pdev);
+ return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(vmd_dev_pm_ops, vmd_suspend, vmd_resume);
+
+static const struct pci_device_id vmd_ids[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x201d),},
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, vmd_ids);
+
+static struct pci_driver vmd_drv = {
+ .name = "vmd",
+ .id_table = vmd_ids,
+ .probe = vmd_probe,
+ .remove = vmd_remove,
+ .driver = {
+ .pm = &vmd_dev_pm_ops,
+ },
+};
+module_pci_driver(vmd_drv);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.6");
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index ff31ab4..beac4df 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -196,7 +196,10 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
error:
- dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
+ if (ret == -ENOSYS)
+ dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
+ else if (ret)
+ dev_err(&dev->dev, "Xen PCI frontend error: %d!\n", ret);
free:
kfree(v);
return ret;
diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c
index 5ca8ead..81c769e 100644
--- a/arch/x86/platform/atom/punit_atom_debug.c
+++ b/arch/x86/platform/atom/punit_atom_debug.c
@@ -25,8 +25,6 @@
#include <asm/cpu_device_id.h>
#include <asm/iosf_mbi.h>
-/* Side band Interface port */
-#define PUNIT_PORT 0x04
/* Power gate status reg */
#define PWRGT_STATUS 0x61
/* Subsystem config/status Video processor */
@@ -85,9 +83,8 @@ static int punit_dev_state_show(struct seq_file *seq_file, void *unused)
seq_puts(seq_file, "\n\nPUNIT NORTH COMPLEX DEVICES :\n");
while (punit_devp->name) {
- status = iosf_mbi_read(PUNIT_PORT, BT_MBI_PMC_READ,
- punit_devp->reg,
- &punit_pwr_status);
+ status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
+ punit_devp->reg, &punit_pwr_status);
if (status) {
seq_printf(seq_file, "%9s : Read Failed\n",
punit_devp->name);
diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c
index d7f997f..ea48449 100644
--- a/arch/x86/platform/efi/efi-bgrt.c
+++ b/arch/x86/platform/efi/efi-bgrt.c
@@ -50,11 +50,16 @@ void __init efi_bgrt_init(void)
bgrt_tab->version);
return;
}
- if (bgrt_tab->status != 1) {
- pr_err("Ignoring BGRT: invalid status %u (expected 1)\n",
+ if (bgrt_tab->status & 0xfe) {
+ pr_err("Ignoring BGRT: reserved status bits are non-zero %u\n",
bgrt_tab->status);
return;
}
+ if (bgrt_tab->status != 1) {
+ pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n",
+ bgrt_tab->status);
+ return;
+ }
if (bgrt_tab->image_type != 0) {
pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n",
bgrt_tab->image_type);
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 6a28ded..ad28540 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -194,7 +194,7 @@ static void __init do_add_efi_memmap(void)
int __init efi_memblock_x86_reserve_range(void)
{
struct efi_info *e = &boot_params.efi_info;
- unsigned long pmap;
+ phys_addr_t pmap;
if (efi_enabled(EFI_PARAVIRT))
return 0;
@@ -209,7 +209,7 @@ int __init efi_memblock_x86_reserve_range(void)
#else
pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32));
#endif
- memmap.phys_map = (void *)pmap;
+ memmap.phys_map = pmap;
memmap.nr_map = e->efi_memmap_size /
e->efi_memdesc_size;
memmap.desc_size = e->efi_memdesc_size;
@@ -222,7 +222,7 @@ int __init efi_memblock_x86_reserve_range(void)
return 0;
}
-static void __init print_efi_memmap(void)
+void __init efi_print_memmap(void)
{
#ifdef EFI_DEBUG
efi_memory_desc_t *md;
@@ -524,7 +524,7 @@ void __init efi_init(void)
return;
if (efi_enabled(EFI_DBG))
- print_efi_memmap();
+ efi_print_memmap();
efi_esrt_init();
}
@@ -1017,24 +1017,6 @@ u32 efi_mem_type(unsigned long phys_addr)
return 0;
}
-u64 efi_mem_attributes(unsigned long phys_addr)
-{
- efi_memory_desc_t *md;
- void *p;
-
- if (!efi_enabled(EFI_MEMMAP))
- return 0;
-
- for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
- md = p;
- if ((md->phys_addr <= phys_addr) &&
- (phys_addr < (md->phys_addr +
- (md->num_pages << EFI_PAGE_SHIFT))))
- return md->attribute;
- }
- return 0;
-}
-
static int __init arch_parse_efi_cmdline(char *str)
{
if (!str) {
@@ -1044,8 +1026,6 @@ static int __init arch_parse_efi_cmdline(char *str)
if (parse_option_str(str, "old_map"))
set_bit(EFI_OLD_MEMMAP, &efi.flags);
- if (parse_option_str(str, "debug"))
- set_bit(EFI_DBG, &efi.flags);
return 0;
}
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 1c7380d..ed30e79 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -8,6 +8,7 @@
#include <linux/memblock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
+#include <linux/dmi.h>
#include <asm/efi.h>
#include <asm/uv/uv.h>
@@ -130,6 +131,27 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
EXPORT_SYMBOL_GPL(efi_query_variable_store);
/*
+ * Helper function for efi_reserve_boot_services() to figure out if we
+ * can free regions in efi_free_boot_services().
+ *
+ * Use this function to ensure we do not free regions owned by somebody
+ * else. We must only reserve (and then free) regions:
+ *
+ * - Not within any part of the kernel
+ * - Not the BIOS reserved area (E820_RESERVED, E820_NVS, etc)
+ */
+static bool can_free_region(u64 start, u64 size)
+{
+ if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end))
+ return false;
+
+ if (!e820_all_mapped(start, start+size, E820_RAM))
+ return false;
+
+ return true;
+}
+
+/*
* The UEFI specification makes it clear that the operating system is free to do
* whatever it wants with boot services code after ExitBootServices() has been
* called. Ignoring this recommendation a significant bunch of EFI implementations
@@ -146,26 +168,50 @@ void __init efi_reserve_boot_services(void)
efi_memory_desc_t *md = p;
u64 start = md->phys_addr;
u64 size = md->num_pages << EFI_PAGE_SHIFT;
+ bool already_reserved;
if (md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA)
continue;
- /* Only reserve where possible:
- * - Not within any already allocated areas
- * - Not over any memory area (really needed, if above?)
- * - Not within any part of the kernel
- * - Not the bios reserved area
- */
- if ((start + size > __pa_symbol(_text)
- && start <= __pa_symbol(_end)) ||
- !e820_all_mapped(start, start+size, E820_RAM) ||
- memblock_is_region_reserved(start, size)) {
- /* Could not reserve, skip it */
- md->num_pages = 0;
- memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n",
- start, start+size-1);
- } else
+
+ already_reserved = memblock_is_region_reserved(start, size);
+
+ /*
+ * Because the following memblock_reserve() is paired
+ * with free_bootmem_late() for this region in
+ * efi_free_boot_services(), we must be extremely
+ * careful not to reserve, and subsequently free,
+ * critical regions of memory (like the kernel image) or
+ * those regions that somebody else has already
+ * reserved.
+ *
+ * A good example of a critical region that must not be
+ * freed is page zero (first 4Kb of memory), which may
+ * contain boot services code/data but is marked
+ * E820_RESERVED by trim_bios_range().
+ */
+ if (!already_reserved) {
memblock_reserve(start, size);
+
+ /*
+ * If we are the first to reserve the region, no
+ * one else cares about it. We own it and can
+ * free it later.
+ */
+ if (can_free_region(start, size))
+ continue;
+ }
+
+ /*
+ * We don't own the region. We must not free it.
+ *
+ * Setting this bit for a boot services region really
+ * doesn't make sense as far as the firmware is
+ * concerned, but it does provide us with a way to tag
+ * those regions that must not be paired with
+ * free_bootmem_late().
+ */
+ md->attribute |= EFI_MEMORY_RUNTIME;
}
}
@@ -182,8 +228,8 @@ void __init efi_free_boot_services(void)
md->type != EFI_BOOT_SERVICES_DATA)
continue;
- /* Could not reserve boot area */
- if (!size)
+ /* Do not free, someone else owns it: */
+ if (md->attribute & EFI_MEMORY_RUNTIME)
continue;
free_bootmem_late(start, size);
@@ -248,6 +294,16 @@ out:
return ret;
}
+static const struct dmi_system_id sgi_uv1_dmi[] = {
+ { NULL, "SGI UV1",
+ { DMI_MATCH(DMI_PRODUCT_NAME, "Stoutland Platform"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+ DMI_MATCH(DMI_BIOS_VENDOR, "SGI.COM"),
+ }
+ },
+ { } /* NULL entry stops DMI scanning */
+};
+
void __init efi_apply_memmap_quirks(void)
{
/*
@@ -260,10 +316,8 @@ void __init efi_apply_memmap_quirks(void)
efi_unmap_memmap();
}
- /*
- * UV doesn't support the new EFI pagetable mapping yet.
- */
- if (is_uv_system())
+ /* UV2+ BIOS has a fix for this issue. UV1 still needs the quirk. */
+ if (dmi_check_system(sgi_uv1_dmi))
set_bit(EFI_OLD_MEMMAP, &efi.flags);
}
diff --git a/arch/x86/platform/geode/alix.c b/arch/x86/platform/geode/alix.c
index 76b6632..1865c19 100644
--- a/arch/x86/platform/geode/alix.c
+++ b/arch/x86/platform/geode/alix.c
@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/string.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
@@ -35,6 +35,11 @@
#define BIOS_SIGNATURE_COREBOOT 0x500
#define BIOS_REGION_SIZE 0x10000
+/*
+ * This driver is not modular, but to keep back compatibility
+ * with existing use cases, continuing with module_param is
+ * the easiest way forward.
+ */
static bool force = 0;
module_param(force, bool, 0444);
/* FIXME: Award bios is not automatically detected as Alix platform */
@@ -192,9 +197,4 @@ static int __init alix_init(void)
return 0;
}
-
-module_init(alix_init);
-
-MODULE_AUTHOR("Ed Wildgoose <kernel@wildgooses.com>");
-MODULE_DESCRIPTION("PCEngines ALIX System Setup");
-MODULE_LICENSE("GPL");
+device_initcall(alix_init);
diff --git a/arch/x86/platform/geode/geos.c b/arch/x86/platform/geode/geos.c
index aa733fb..4fcdb91 100644
--- a/arch/x86/platform/geode/geos.c
+++ b/arch/x86/platform/geode/geos.c
@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/string.h>
-#include <linux/module.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
@@ -120,9 +119,4 @@ static int __init geos_init(void)
return 0;
}
-
-module_init(geos_init);
-
-MODULE_AUTHOR("Philip Prindeville <philipp@redfish-solutions.com>");
-MODULE_DESCRIPTION("Traverse Technologies Geos System Setup");
-MODULE_LICENSE("GPL");
+device_initcall(geos_init);
diff --git a/arch/x86/platform/geode/net5501.c b/arch/x86/platform/geode/net5501.c
index 927e38c..a2f6b98 100644
--- a/arch/x86/platform/geode/net5501.c
+++ b/arch/x86/platform/geode/net5501.c
@@ -20,7 +20,6 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/string.h>
-#include <linux/module.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
@@ -146,9 +145,4 @@ static int __init net5501_init(void)
return 0;
}
-
-module_init(net5501_init);
-
-MODULE_AUTHOR("Philip Prindeville <philipp@redfish-solutions.com>");
-MODULE_DESCRIPTION("Soekris net5501 System Setup");
-MODULE_LICENSE("GPL");
+device_initcall(net5501_init);
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 01d54ea..90bb997 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -61,7 +61,7 @@
enum intel_mid_timer_options intel_mid_timer_options;
/* intel_mid_ops to store sub arch ops */
-struct intel_mid_ops *intel_mid_ops;
+static struct intel_mid_ops *intel_mid_ops;
/* getter function for sub arch ops*/
static void *(*get_intel_mid_ops[])(void) = INTEL_MID_OPS_INIT;
enum intel_mid_cpu_type __intel_mid_cpu_chip;
@@ -138,7 +138,7 @@ static void intel_mid_arch_setup(void)
intel_mid_ops = get_intel_mid_ops[__intel_mid_cpu_chip]();
else {
intel_mid_ops = get_intel_mid_ops[INTEL_MID_CPU_CHIP_PENWELL]();
- pr_info("ARCH: Unknown SoC, assuming PENWELL!\n");
+ pr_info("ARCH: Unknown SoC, assuming Penwell!\n");
}
out:
@@ -214,12 +214,10 @@ static inline int __init setup_x86_intel_mid_timer(char *arg)
else if (strcmp("lapic_and_apbt", arg) == 0)
intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT;
else {
- pr_warn("X86 INTEL_MID timer option %s not recognised"
- " use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n",
- arg);
+ pr_warn("X86 INTEL_MID timer option %s not recognised use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n",
+ arg);
return -EINVAL;
}
return 0;
}
__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer);
-
diff --git a/arch/x86/platform/intel-mid/mfld.c b/arch/x86/platform/intel-mid/mfld.c
index 23381d2..1eb47b6 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -52,10 +52,7 @@ static unsigned long __init mfld_calibrate_tsc(void)
/* mark tsc clocksource as reliable */
set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
- if (fast_calibrate)
- return fast_calibrate;
-
- return 0;
+ return fast_calibrate;
}
static void __init penwell_arch_setup(void)
diff --git a/arch/x86/platform/intel-mid/mrfl.c b/arch/x86/platform/intel-mid/mrfl.c
index aaca917..bd1adc6 100644
--- a/arch/x86/platform/intel-mid/mrfl.c
+++ b/arch/x86/platform/intel-mid/mrfl.c
@@ -81,10 +81,7 @@ static unsigned long __init tangier_calibrate_tsc(void)
/* mark tsc clocksource as reliable */
set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
- if (fast_calibrate)
- return fast_calibrate;
-
- return 0;
+ return fast_calibrate;
}
static void __init tangier_arch_setup(void)
diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c
index ce992e8..5ee360a 100644
--- a/arch/x86/platform/intel-mid/sfi.c
+++ b/arch/x86/platform/intel-mid/sfi.c
@@ -197,10 +197,9 @@ static int __init sfi_parse_gpio(struct sfi_table_header *table)
num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
pentry = (struct sfi_gpio_table_entry *)sb->pentry;
- gpio_table = kmalloc(num * sizeof(*pentry), GFP_KERNEL);
+ gpio_table = kmemdup(pentry, num * sizeof(*pentry), GFP_KERNEL);
if (!gpio_table)
return -1;
- memcpy(gpio_table, pentry, num * sizeof(*pentry));
gpio_num_entry = num;
pr_debug("GPIO pin info:\n");
diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c
index 0ee619f..17d6d22 100644
--- a/arch/x86/platform/intel-quark/imr.c
+++ b/arch/x86/platform/intel-quark/imr.c
@@ -1,5 +1,5 @@
/**
- * imr.c
+ * imr.c -- Intel Isolated Memory Region driver
*
* Copyright(c) 2013 Intel Corporation.
* Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
@@ -31,7 +31,6 @@
#include <linux/debugfs.h>
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/module.h>
#include <linux/types.h>
struct imr_device {
@@ -111,23 +110,19 @@ static int imr_read(struct imr_device *idev, u32 imr_id, struct imr_regs *imr)
u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base;
int ret;
- ret = iosf_mbi_read(QRK_MBI_UNIT_MM, QRK_MBI_MM_READ,
- reg++, &imr->addr_lo);
+ ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_lo);
if (ret)
return ret;
- ret = iosf_mbi_read(QRK_MBI_UNIT_MM, QRK_MBI_MM_READ,
- reg++, &imr->addr_hi);
+ ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->addr_hi);
if (ret)
return ret;
- ret = iosf_mbi_read(QRK_MBI_UNIT_MM, QRK_MBI_MM_READ,
- reg++, &imr->rmask);
+ ret = iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->rmask);
if (ret)
return ret;
- return iosf_mbi_read(QRK_MBI_UNIT_MM, QRK_MBI_MM_READ,
- reg++, &imr->wmask);
+ return iosf_mbi_read(QRK_MBI_UNIT_MM, MBI_REG_READ, reg++, &imr->wmask);
}
/**
@@ -139,11 +134,9 @@ static int imr_read(struct imr_device *idev, u32 imr_id, struct imr_regs *imr)
* @idev: pointer to imr_device structure.
* @imr_id: IMR entry to write.
* @imr: IMR structure representing address and access masks.
- * @lock: indicates if the IMR lock bit should be applied.
* @return: 0 on success or error code passed from mbi_iosf on failure.
*/
-static int imr_write(struct imr_device *idev, u32 imr_id,
- struct imr_regs *imr, bool lock)
+static int imr_write(struct imr_device *idev, u32 imr_id, struct imr_regs *imr)
{
unsigned long flags;
u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base;
@@ -151,35 +144,22 @@ static int imr_write(struct imr_device *idev, u32 imr_id,
local_irq_save(flags);
- ret = iosf_mbi_write(QRK_MBI_UNIT_MM, QRK_MBI_MM_WRITE, reg++,
- imr->addr_lo);
+ ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_lo);
if (ret)
goto failed;
- ret = iosf_mbi_write(QRK_MBI_UNIT_MM, QRK_MBI_MM_WRITE,
- reg++, imr->addr_hi);
+ ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_hi);
if (ret)
goto failed;
- ret = iosf_mbi_write(QRK_MBI_UNIT_MM, QRK_MBI_MM_WRITE,
- reg++, imr->rmask);
+ ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->rmask);
if (ret)
goto failed;
- ret = iosf_mbi_write(QRK_MBI_UNIT_MM, QRK_MBI_MM_WRITE,
- reg++, imr->wmask);
+ ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->wmask);
if (ret)
goto failed;
- /* Lock bit must be set separately to addr_lo address bits. */
- if (lock) {
- imr->addr_lo |= IMR_LOCK;
- ret = iosf_mbi_write(QRK_MBI_UNIT_MM, QRK_MBI_MM_WRITE,
- reg - IMR_NUM_REGS, imr->addr_lo);
- if (ret)
- goto failed;
- }
-
local_irq_restore(flags);
return 0;
failed:
@@ -228,11 +208,12 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused)
if (imr_is_enabled(&imr)) {
base = imr_to_phys(imr.addr_lo);
end = imr_to_phys(imr.addr_hi) + IMR_MASK;
+ size = end - base + 1;
} else {
base = 0;
end = 0;
+ size = 0;
}
- size = end - base;
seq_printf(s, "imr%02i: base=%pa, end=%pa, size=0x%08zx "
"rmask=0x%08x, wmask=0x%08x, %s, %s\n", i,
&base, &end, size, imr.rmask, imr.wmask,
@@ -277,17 +258,6 @@ static int imr_debugfs_register(struct imr_device *idev)
}
/**
- * imr_debugfs_unregister - unregister debugfs hooks.
- *
- * @idev: pointer to imr_device structure.
- * @return:
- */
-static void imr_debugfs_unregister(struct imr_device *idev)
-{
- debugfs_remove(idev->file);
-}
-
-/**
* imr_check_params - check passed address range IMR alignment and non-zero size
*
* @base: base address of intended IMR.
@@ -341,11 +311,10 @@ static inline int imr_address_overlap(phys_addr_t addr, struct imr_regs *imr)
* @size: physical size of region in bytes must be aligned to 1KiB.
* @read_mask: read access mask.
* @write_mask: write access mask.
- * @lock: indicates whether or not to permanently lock this region.
* @return: zero on success or negative value indicating error.
*/
int imr_add_range(phys_addr_t base, size_t size,
- unsigned int rmask, unsigned int wmask, bool lock)
+ unsigned int rmask, unsigned int wmask)
{
phys_addr_t end;
unsigned int i;
@@ -418,7 +387,7 @@ int imr_add_range(phys_addr_t base, size_t size,
imr.rmask = rmask;
imr.wmask = wmask;
- ret = imr_write(idev, reg, &imr, lock);
+ ret = imr_write(idev, reg, &imr);
if (ret < 0) {
/*
* In the highly unlikely event iosf_mbi_write failed
@@ -429,7 +398,7 @@ int imr_add_range(phys_addr_t base, size_t size,
imr.addr_hi = 0;
imr.rmask = IMR_READ_ACCESS_ALL;
imr.wmask = IMR_WRITE_ACCESS_ALL;
- imr_write(idev, reg, &imr, false);
+ imr_write(idev, reg, &imr);
}
failed:
mutex_unlock(&idev->lock);
@@ -525,7 +494,7 @@ static int __imr_remove_range(int reg, phys_addr_t base, size_t size)
imr.rmask = IMR_READ_ACCESS_ALL;
imr.wmask = IMR_WRITE_ACCESS_ALL;
- ret = imr_write(idev, reg, &imr, false);
+ ret = imr_write(idev, reg, &imr);
failed:
mutex_unlock(&idev->lock);
@@ -587,6 +556,7 @@ static void __init imr_fixup_memmap(struct imr_device *idev)
{
phys_addr_t base = virt_to_phys(&_text);
size_t size = virt_to_phys(&__end_rodata) - base;
+ unsigned long start, end;
int i;
int ret;
@@ -594,18 +564,24 @@ static void __init imr_fixup_memmap(struct imr_device *idev)
for (i = 0; i < idev->max_imr; i++)
imr_clear(i);
+ start = (unsigned long)_text;
+ end = (unsigned long)__end_rodata - 1;
+
/*
- * Setup a locked IMR around the physical extent of the kernel
+ * Setup an unlocked IMR around the physical extent of the kernel
* from the beginning of the .text secton to the end of the
* .rodata section as one physically contiguous block.
+ *
+ * We don't round up @size since it is already PAGE_SIZE aligned.
+ * See vmlinux.lds.S for details.
*/
- ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, true);
+ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU);
if (ret < 0) {
- pr_err("unable to setup IMR for kernel: (%p - %p)\n",
- &_text, &__end_rodata);
+ pr_err("unable to setup IMR for kernel: %zu KiB (%lx - %lx)\n",
+ size / 1024, start, end);
} else {
- pr_info("protecting kernel .text - .rodata: %zu KiB (%p - %p)\n",
- size / 1024, &_text, &__end_rodata);
+ pr_info("protecting kernel .text - .rodata: %zu KiB (%lx - %lx)\n",
+ size / 1024, start, end);
}
}
@@ -614,7 +590,6 @@ static const struct x86_cpu_id imr_ids[] __initconst = {
{ X86_VENDOR_INTEL, 5, 9 }, /* Intel Quark SoC X1000. */
{}
};
-MODULE_DEVICE_TABLE(x86cpu, imr_ids);
/**
* imr_init - entry point for IMR driver.
@@ -640,22 +615,4 @@ static int __init imr_init(void)
imr_fixup_memmap(idev);
return 0;
}
-
-/**
- * imr_exit - exit point for IMR code.
- *
- * Deregisters debugfs, leave IMR state as-is.
- *
- * return:
- */
-static void __exit imr_exit(void)
-{
- imr_debugfs_unregister(&imr_dev);
-}
-
-module_init(imr_init);
-module_exit(imr_exit);
-
-MODULE_AUTHOR("Bryan O'Donoghue <pure.logic@nexus-software.ie>");
-MODULE_DESCRIPTION("Intel Isolated Memory Region driver");
-MODULE_LICENSE("Dual BSD/GPL");
+device_initcall(imr_init);
diff --git a/arch/x86/platform/intel-quark/imr_selftest.c b/arch/x86/platform/intel-quark/imr_selftest.c
index 278e4da..f5bad40 100644
--- a/arch/x86/platform/intel-quark/imr_selftest.c
+++ b/arch/x86/platform/intel-quark/imr_selftest.c
@@ -1,5 +1,5 @@
/**
- * imr_selftest.c
+ * imr_selftest.c -- Intel Isolated Memory Region self-test driver
*
* Copyright(c) 2013 Intel Corporation.
* Copyright(c) 2015 Bryan O'Donoghue <pure.logic@nexus-software.ie>
@@ -15,7 +15,6 @@
#include <asm/imr.h>
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/module.h>
#include <linux/types.h>
#define SELFTEST KBUILD_MODNAME ": "
@@ -61,30 +60,30 @@ static void __init imr_self_test(void)
int ret;
/* Test zero zero. */
- ret = imr_add_range(0, 0, 0, 0, false);
+ ret = imr_add_range(0, 0, 0, 0);
imr_self_test_result(ret < 0, "zero sized IMR\n");
/* Test exact overlap. */
- ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
+ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test overlap with base inside of existing. */
base += size - IMR_ALIGN;
- ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
+ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test overlap with end inside of existing. */
base -= size + IMR_ALIGN * 2;
- ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, false);
+ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU);
imr_self_test_result(ret < 0, fmt_over, __va(base), __va(base + size));
/* Test that a 1 KiB IMR @ zero with read/write all will bomb out. */
ret = imr_add_range(0, IMR_ALIGN, IMR_READ_ACCESS_ALL,
- IMR_WRITE_ACCESS_ALL, false);
+ IMR_WRITE_ACCESS_ALL);
imr_self_test_result(ret < 0, "1KiB IMR @ 0x00000000 - access-all\n");
/* Test that a 1 KiB IMR @ zero with CPU only will work. */
- ret = imr_add_range(0, IMR_ALIGN, IMR_CPU, IMR_CPU, false);
+ ret = imr_add_range(0, IMR_ALIGN, IMR_CPU, IMR_CPU);
imr_self_test_result(ret >= 0, "1KiB IMR @ 0x00000000 - cpu-access\n");
if (ret >= 0) {
ret = imr_remove_range(0, IMR_ALIGN);
@@ -93,8 +92,7 @@ static void __init imr_self_test(void)
/* Test 2 KiB works. */
size = IMR_ALIGN * 2;
- ret = imr_add_range(0, size, IMR_READ_ACCESS_ALL,
- IMR_WRITE_ACCESS_ALL, false);
+ ret = imr_add_range(0, size, IMR_READ_ACCESS_ALL, IMR_WRITE_ACCESS_ALL);
imr_self_test_result(ret >= 0, "2KiB IMR @ 0x00000000\n");
if (ret >= 0) {
ret = imr_remove_range(0, size);
@@ -106,7 +104,6 @@ static const struct x86_cpu_id imr_ids[] __initconst = {
{ X86_VENDOR_INTEL, 5, 9 }, /* Intel Quark SoC X1000. */
{}
};
-MODULE_DEVICE_TABLE(x86cpu, imr_ids);
/**
* imr_self_test_init - entry point for IMR driver.
@@ -125,13 +122,4 @@ static int __init imr_self_test_init(void)
*
* return:
*/
-static void __exit imr_self_test_exit(void)
-{
-}
-
-module_init(imr_self_test_init);
-module_exit(imr_self_test_exit);
-
-MODULE_AUTHOR("Bryan O'Donoghue <pure.logic@nexus-software.ie>");
-MODULE_DESCRIPTION("Intel Isolated Memory Region self-test driver");
-MODULE_LICENSE("Dual BSD/GPL");
+device_initcall(imr_self_test_init);
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 5c9f63f..8dd8005 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -28,6 +28,7 @@
#include <linux/nmi.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/clocksource.h>
#include <asm/apic.h>
#include <asm/current.h>
@@ -376,38 +377,42 @@ static void uv_nmi_wait(int master)
atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus());
}
+/* Dump Instruction Pointer header */
static void uv_nmi_dump_cpu_ip_hdr(void)
{
- printk(KERN_DEFAULT
- "\nUV: %4s %6s %-32s %s (Note: PID 0 not listed)\n",
+ pr_info("\nUV: %4s %6s %-32s %s (Note: PID 0 not listed)\n",
"CPU", "PID", "COMMAND", "IP");
}
+/* Dump Instruction Pointer info */
static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs)
{
- printk(KERN_DEFAULT "UV: %4d %6d %-32.32s ",
- cpu, current->pid, current->comm);
-
+ pr_info("UV: %4d %6d %-32.32s ", cpu, current->pid, current->comm);
printk_address(regs->ip);
}
-/* Dump this cpu's state */
+/*
+ * Dump this CPU's state. If action was set to "kdump" and the crash_kexec
+ * failed, then we provide "dump" as an alternate action. Action "dump" now
+ * also includes the show "ips" (instruction pointers) action whereas the
+ * action "ips" only displays instruction pointers for the non-idle CPU's.
+ * This is an abbreviated form of the "ps" command.
+ */
static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs)
{
const char *dots = " ................................. ";
- if (uv_nmi_action_is("ips")) {
- if (cpu == 0)
- uv_nmi_dump_cpu_ip_hdr();
+ if (cpu == 0)
+ uv_nmi_dump_cpu_ip_hdr();
- if (current->pid != 0)
- uv_nmi_dump_cpu_ip(cpu, regs);
+ if (current->pid != 0 || !uv_nmi_action_is("ips"))
+ uv_nmi_dump_cpu_ip(cpu, regs);
- } else if (uv_nmi_action_is("dump")) {
- printk(KERN_DEFAULT
- "UV:%sNMI process trace for CPU %d\n", dots, cpu);
+ if (uv_nmi_action_is("dump")) {
+ pr_info("UV:%sNMI process trace for CPU %d\n", dots, cpu);
show_regs(regs);
}
+
this_cpu_write(uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE);
}
@@ -469,8 +474,7 @@ static void uv_nmi_dump_state(int cpu, struct pt_regs *regs, int master)
uv_nmi_trigger_dump(tcpu);
}
if (ignored)
- printk(KERN_DEFAULT "UV: %d CPUs ignored NMI\n",
- ignored);
+ pr_alert("UV: %d CPUs ignored NMI\n", ignored);
console_loglevel = saved_console_loglevel;
pr_alert("UV: process trace complete\n");
@@ -492,8 +496,9 @@ static void uv_nmi_touch_watchdogs(void)
touch_nmi_watchdog();
}
-#if defined(CONFIG_KEXEC_CORE)
static atomic_t uv_nmi_kexec_failed;
+
+#if defined(CONFIG_KEXEC_CORE)
static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
{
/* Call crash to dump system state */
@@ -502,10 +507,9 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
crash_kexec(regs);
pr_emerg("UV: crash_kexec unexpectedly returned, ");
+ atomic_set(&uv_nmi_kexec_failed, 1);
if (!kexec_crash_image) {
pr_cont("crash kernel not loaded\n");
- atomic_set(&uv_nmi_kexec_failed, 1);
- uv_nmi_sync_exit(1);
return;
}
pr_cont("kexec busy, stalling cpus while waiting\n");
@@ -514,9 +518,6 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
/* If crash exec fails the slaves should return, otherwise stall */
while (atomic_read(&uv_nmi_kexec_failed) == 0)
mdelay(10);
-
- /* Crash kernel most likely not loaded, return in an orderly fashion */
- uv_nmi_sync_exit(0);
}
#else /* !CONFIG_KEXEC_CORE */
@@ -524,6 +525,7 @@ static inline void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs)
{
if (master)
pr_err("UV: NMI kdump: KEXEC not supported in this kernel\n");
+ atomic_set(&uv_nmi_kexec_failed, 1);
}
#endif /* !CONFIG_KEXEC_CORE */
@@ -613,9 +615,14 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
master = (atomic_read(&uv_nmi_cpu) == cpu);
/* If NMI action is "kdump", then attempt to do it */
- if (uv_nmi_action_is("kdump"))
+ if (uv_nmi_action_is("kdump")) {
uv_nmi_kdump(cpu, master, regs);
+ /* Unexpected return, revert action to "dump" */
+ if (master)
+ strncpy(uv_nmi_action, "dump", strlen(uv_nmi_action));
+ }
+
/* Pause as all cpus enter the NMI handler */
uv_nmi_wait(master);
@@ -640,6 +647,7 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
atomic_set(&uv_nmi_cpus_in_nmi, -1);
atomic_set(&uv_nmi_cpu, -1);
atomic_set(&uv_in_nmi, 0);
+ atomic_set(&uv_nmi_kexec_failed, 0);
}
uv_nmi_touch_watchdogs();
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 9ab5279..d5f6499 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -23,6 +23,7 @@
#include <asm/debugreg.h>
#include <asm/cpu.h>
#include <asm/mmu_context.h>
+#include <linux/dmi.h>
#ifdef CONFIG_X86_32
__visible unsigned long saved_context_ebx;
@@ -32,6 +33,29 @@ __visible unsigned long saved_context_eflags;
#endif
struct saved_context saved_context;
+static void msr_save_context(struct saved_context *ctxt)
+{
+ struct saved_msr *msr = ctxt->saved_msrs.array;
+ struct saved_msr *end = msr + ctxt->saved_msrs.num;
+
+ while (msr < end) {
+ msr->valid = !rdmsrl_safe(msr->info.msr_no, &msr->info.reg.q);
+ msr++;
+ }
+}
+
+static void msr_restore_context(struct saved_context *ctxt)
+{
+ struct saved_msr *msr = ctxt->saved_msrs.array;
+ struct saved_msr *end = msr + ctxt->saved_msrs.num;
+
+ while (msr < end) {
+ if (msr->valid)
+ wrmsrl(msr->info.msr_no, msr->info.reg.q);
+ msr++;
+ }
+}
+
/**
* __save_processor_state - save CPU registers before creating a
* hibernation image and before restoring the memory state from it
@@ -111,6 +135,7 @@ static void __save_processor_state(struct saved_context *ctxt)
#endif
ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE,
&ctxt->misc_enable);
+ msr_save_context(ctxt);
}
/* Needed by apm.c */
@@ -229,6 +254,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
x86_platform.restore_sched_clock_state();
mtrr_bp_restore();
perf_restore_debug_store();
+ msr_restore_context(ctxt);
}
/* Needed by apm.c */
@@ -320,3 +346,69 @@ static int __init bsp_pm_check_init(void)
}
core_initcall(bsp_pm_check_init);
+
+static int msr_init_context(const u32 *msr_id, const int total_num)
+{
+ int i = 0;
+ struct saved_msr *msr_array;
+
+ if (saved_context.saved_msrs.array || saved_context.saved_msrs.num > 0) {
+ pr_err("x86/pm: MSR quirk already applied, please check your DMI match table.\n");
+ return -EINVAL;
+ }
+
+ msr_array = kmalloc_array(total_num, sizeof(struct saved_msr), GFP_KERNEL);
+ if (!msr_array) {
+ pr_err("x86/pm: Can not allocate memory to save/restore MSRs during suspend.\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < total_num; i++) {
+ msr_array[i].info.msr_no = msr_id[i];
+ msr_array[i].valid = false;
+ msr_array[i].info.reg.q = 0;
+ }
+ saved_context.saved_msrs.num = total_num;
+ saved_context.saved_msrs.array = msr_array;
+
+ return 0;
+}
+
+/*
+ * The following section is a quirk framework for problematic BIOSen:
+ * Sometimes MSRs are modified by the BIOSen after suspended to
+ * RAM, this might cause unexpected behavior after wakeup.
+ * Thus we save/restore these specified MSRs across suspend/resume
+ * in order to work around it.
+ *
+ * For any further problematic BIOSen/platforms,
+ * please add your own function similar to msr_initialize_bdw.
+ */
+static int msr_initialize_bdw(const struct dmi_system_id *d)
+{
+ /* Add any extra MSR ids into this array. */
+ u32 bdw_msr_id[] = { MSR_IA32_THERM_CONTROL };
+
+ pr_info("x86/pm: %s detected, MSR saving is needed during suspending.\n", d->ident);
+ return msr_init_context(bdw_msr_id, ARRAY_SIZE(bdw_msr_id));
+}
+
+static struct dmi_system_id msr_save_dmi_table[] = {
+ {
+ .callback = msr_initialize_bdw,
+ .ident = "BROADWELL BDX_EP",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "GRANTLEY"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "E63448-400"),
+ },
+ },
+ {}
+};
+
+static int pm_check_save_msr(void)
+{
+ dmi_check_system(msr_save_dmi_table);
+ return 0;
+}
+
+device_initcall(pm_check_save_msr);
diff --git a/arch/x86/ras/Kconfig b/arch/x86/ras/Kconfig
index 10fea5f..df280da 100644
--- a/arch/x86/ras/Kconfig
+++ b/arch/x86/ras/Kconfig
@@ -1,11 +1,9 @@
config AMD_MCE_INJ
tristate "Simple MCE injection interface for AMD processors"
- depends on RAS && EDAC_DECODE_MCE && DEBUG_FS
+ depends on RAS && EDAC_DECODE_MCE && DEBUG_FS && AMD_NB
default n
help
This is a simple debugfs interface to inject MCEs and test different
aspects of the MCE handling code.
WARNING: Do not even assume this interface is staying stable!
-
-
diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 17e35b5..55d38cf 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -17,7 +17,11 @@
#include <linux/cpu.h>
#include <linux/string.h>
#include <linux/uaccess.h>
+#include <linux/pci.h>
+
#include <asm/mce.h>
+#include <asm/amd_nb.h>
+#include <asm/irq_vectors.h>
#include "../kernel/cpu/mcheck/mce-internal.h"
@@ -30,16 +34,21 @@ static struct dentry *dfs_inj;
static u8 n_banks;
#define MAX_FLAG_OPT_SIZE 3
+#define NBCFG 0x44
enum injection_type {
SW_INJ = 0, /* SW injection, simply decode the error */
HW_INJ, /* Trigger a #MC */
+ DFR_INT_INJ, /* Trigger Deferred error interrupt */
+ THR_INT_INJ, /* Trigger threshold interrupt */
N_INJ_TYPES,
};
static const char * const flags_options[] = {
[SW_INJ] = "sw",
[HW_INJ] = "hw",
+ [DFR_INT_INJ] = "df",
+ [THR_INT_INJ] = "th",
NULL
};
@@ -129,12 +138,9 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf,
{
char buf[MAX_FLAG_OPT_SIZE], *__buf;
int err;
- size_t ret;
if (cnt > MAX_FLAG_OPT_SIZE)
- cnt = MAX_FLAG_OPT_SIZE;
-
- ret = cnt;
+ return -EINVAL;
if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;
@@ -150,9 +156,9 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf,
return err;
}
- *ppos += ret;
+ *ppos += cnt;
- return ret;
+ return cnt;
}
static const struct file_operations flags_fops = {
@@ -185,6 +191,55 @@ static void trigger_mce(void *info)
asm volatile("int $18");
}
+static void trigger_dfr_int(void *info)
+{
+ asm volatile("int %0" :: "i" (DEFERRED_ERROR_VECTOR));
+}
+
+static void trigger_thr_int(void *info)
+{
+ asm volatile("int %0" :: "i" (THRESHOLD_APIC_VECTOR));
+}
+
+static u32 get_nbc_for_node(int node_id)
+{
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+ u32 cores_per_node;
+
+ cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket();
+
+ return cores_per_node * node_id;
+}
+
+static void toggle_nb_mca_mst_cpu(u16 nid)
+{
+ struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
+ u32 val;
+ int err;
+
+ if (!F3)
+ return;
+
+ err = pci_read_config_dword(F3, NBCFG, &val);
+ if (err) {
+ pr_err("%s: Error reading F%dx%03x.\n",
+ __func__, PCI_FUNC(F3->devfn), NBCFG);
+ return;
+ }
+
+ if (val & BIT(27))
+ return;
+
+ pr_err("%s: Set D18F3x44[NbMcaToMstCpuEn] which BIOS hasn't done.\n",
+ __func__);
+
+ val |= BIT(27);
+ err = pci_write_config_dword(F3, NBCFG, val);
+ if (err)
+ pr_err("%s: Error writing F%dx%03x.\n",
+ __func__, PCI_FUNC(F3->devfn), NBCFG);
+}
+
static void do_inject(void)
{
u64 mcg_status = 0;
@@ -205,6 +260,26 @@ static void do_inject(void)
if (!(i_mce.status & MCI_STATUS_PCC))
mcg_status |= MCG_STATUS_RIPV;
+ /*
+ * Ensure necessary status bits for deferred errors:
+ * - MCx_STATUS[Deferred]: make sure it is a deferred error
+ * - MCx_STATUS[UC] cleared: deferred errors are _not_ UC
+ */
+ if (inj_type == DFR_INT_INJ) {
+ i_mce.status |= MCI_STATUS_DEFERRED;
+ i_mce.status |= (i_mce.status & ~MCI_STATUS_UC);
+ }
+
+ /*
+ * For multi node CPUs, logging and reporting of bank 4 errors happens
+ * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for
+ * Fam10h and later BKDGs.
+ */
+ if (static_cpu_has(X86_FEATURE_AMD_DCM) && b == 4) {
+ toggle_nb_mca_mst_cpu(amd_get_nb_id(cpu));
+ cpu = get_nbc_for_node(amd_get_nb_id(cpu));
+ }
+
get_online_cpus();
if (!cpu_online(cpu))
goto err;
@@ -225,7 +300,16 @@ static void do_inject(void)
toggle_hw_mce_inject(cpu, false);
- smp_call_function_single(cpu, trigger_mce, NULL, 0);
+ switch (inj_type) {
+ case DFR_INT_INJ:
+ smp_call_function_single(cpu, trigger_dfr_int, NULL, 0);
+ break;
+ case THR_INT_INJ:
+ smp_call_function_single(cpu, trigger_thr_int, NULL, 0);
+ break;
+ default:
+ smp_call_function_single(cpu, trigger_mce, NULL, 0);
+ }
err:
put_online_cpus();
@@ -290,6 +374,11 @@ static const char readme_msg[] =
"\t handle the error. Be warned: might cause system panic if MCi_STATUS[PCC] \n"
"\t is set. Therefore, consider setting (debugfs_mountpoint)/mce/fake_panic \n"
"\t before injecting.\n"
+"\t - \"df\": Trigger APIC interrupt for Deferred error. Causes deferred \n"
+"\t error APIC interrupt handler to handle the error if the feature is \n"
+"\t is present in hardware. \n"
+"\t - \"th\": Trigger APIC interrupt for Threshold errors. Causes threshold \n"
+"\t APIC interrupt handler to handle the error. \n"
"\n";
static ssize_t
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
index 2730d77..3e75fcf 100644
--- a/arch/x86/realmode/rm/Makefile
+++ b/arch/x86/realmode/rm/Makefile
@@ -70,3 +70,4 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \
-I$(srctree)/arch/x86/boot
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
+UBSAN_SANITIZE := n
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index a8fecc2..3ee2bb6 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -17,7 +17,7 @@ obj-y = bug.o bugs_$(BITS).o delay.o fault.o ksyms.o ldt.o \
ifeq ($(CONFIG_X86_32),y)
obj-y += checksum_32.o
-obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+obj-$(CONFIG_ELF_CORE) += elfcore.o
subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o
subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o
diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h
index 755481f..00c3190 100644
--- a/arch/x86/um/asm/barrier.h
+++ b/arch/x86/um/asm/barrier.h
@@ -3,7 +3,7 @@
#include <asm/asm.h>
#include <asm/segment.h>
-#include <asm/cpufeature.h>
+#include <asm/cpufeatures.h>
#include <asm/cmpxchg.h>
#include <asm/nops.h>
@@ -36,13 +36,6 @@
#endif /* CONFIG_X86_PPRO_FENCE */
#define dma_wmb() barrier()
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-
-#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
-
-#define read_barrier_depends() do { } while (0)
-#define smp_read_barrier_depends() do { } while (0)
+#include <asm-generic/barrier.h>
#endif
diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h
index ee94018..54d96f1 100644
--- a/arch/x86/um/asm/checksum.h
+++ b/arch/x86/um/asm/checksum.h
@@ -87,8 +87,8 @@ static inline __sum16 csum_fold(__wsum sum)
* 32bit unfolded.
*/
static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
+ __u8 proto, __wsum sum)
{
asm(" addl %1, %0\n"
" adcl %2, %0\n"
@@ -104,9 +104,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h
index ab77b6f..83a75f8 100644
--- a/arch/x86/um/asm/checksum_32.h
+++ b/arch/x86/um/asm/checksum_32.h
@@ -13,7 +13,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
__asm__(
diff --git a/arch/x86/um/asm/syscall.h b/arch/x86/um/asm/syscall.h
index 9fe77b7..11ab90d 100644
--- a/arch/x86/um/asm/syscall.h
+++ b/arch/x86/um/asm/syscall.h
@@ -1,8 +1,13 @@
#ifndef __UM_ASM_SYSCALL_H
#define __UM_ASM_SYSCALL_H
+#include <asm/syscall-generic.h>
#include <uapi/linux/audit.h>
+typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
+
static inline int syscall_get_arch(void)
{
#ifdef CONFIG_X86_32
diff --git a/arch/x86/um/os-Linux/task_size.c b/arch/x86/um/os-Linux/task_size.c
index 8502ad3..5adb6a2 100644
--- a/arch/x86/um/os-Linux/task_size.c
+++ b/arch/x86/um/os-Linux/task_size.c
@@ -109,7 +109,7 @@ unsigned long os_get_top_address(void)
exit(1);
}
- printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("0x%lx\n", bottom << UM_KERN_PAGE_SHIFT);
printf("Locating the top of the address space ... ");
fflush(stdout);
@@ -134,7 +134,7 @@ out:
exit(1);
}
top <<= UM_KERN_PAGE_SHIFT;
- printf("0x%x\n", top);
+ printf("0x%lx\n", top);
return top;
}
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index a29756f2..47c78d5 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -68,6 +68,7 @@ static const int reg_offsets[] = {
[EFL] = HOST_EFLAGS,
[UESP] = HOST_SP,
[SS] = HOST_SS,
+ [ORIG_EAX] = HOST_ORIG_AX,
};
int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -83,6 +84,7 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
case EAX:
case EIP:
case UESP:
+ case ORIG_EAX:
break;
case FS:
if (value && (value & 3) != 3)
@@ -108,9 +110,6 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
value &= FLAG_MASK;
child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
return 0;
- case ORIG_EAX:
- child->thread.regs.regs.syscall = value;
- return 0;
default :
panic("Bad register in putreg() : %d\n", regno);
}
@@ -143,8 +142,6 @@ unsigned long getreg(struct task_struct *child, int regno)
regno >>= 2;
switch (regno) {
- case ORIG_EAX:
- return child->thread.regs.regs.syscall;
case FS:
case GS:
case DS:
@@ -163,6 +160,7 @@ unsigned long getreg(struct task_struct *child, int regno)
case EDI:
case EBP:
case EFL:
+ case ORIG_EAX:
break;
default:
panic("Bad register in getreg() : %d\n", regno);
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 06934a8..14fcd01 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -211,7 +211,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
if (err)
return 1;
- err = convert_fxsr_from_user(&fpx, sc.fpstate);
+ err = convert_fxsr_from_user(&fpx, (void *)sc.fpstate);
if (err)
return 1;
@@ -227,7 +227,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
{
struct user_i387_struct fp;
- err = copy_from_user(&fp, sc.fpstate,
+ err = copy_from_user(&fp, (void *)sc.fpstate,
sizeof(struct user_i387_struct));
if (err)
return 1;
@@ -291,7 +291,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
#endif
#undef PUTREG
sc.oldmask = mask;
- sc.fpstate = to_fp;
+ sc.fpstate = (unsigned long)to_fp;
err = copy_to_user(to, &sc, sizeof(struct sigcontext));
if (err)
@@ -468,12 +468,10 @@ long sys_sigreturn(void)
struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
sigset_t set;
struct sigcontext __user *sc = &frame->sc;
- unsigned long __user *oldmask = &sc->oldmask;
- unsigned long __user *extramask = frame->extramask;
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
- if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
- copy_from_user(&set.sig[1], extramask, sig_size))
+ if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
+ copy_from_user(&set.sig[1], frame->extramask, sig_size))
goto segfault;
set_current_blocked(&set);
@@ -505,6 +503,7 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
{
struct rt_sigframe __user *frame;
int err = 0, sig = ksig->sig;
+ unsigned long fp_to;
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16);
@@ -526,7 +525,10 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
set->sig[0]);
- err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
+
+ fp_to = (unsigned long)&frame->fpstate;
+
+ err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate);
if (sizeof(*set) == 16) {
err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
diff --git a/arch/x86/um/stub_32.S b/arch/x86/um/stub_32.S
index b972649..9881680 100644
--- a/arch/x86/um/stub_32.S
+++ b/arch/x86/um/stub_32.S
@@ -1,6 +1,5 @@
#include <as-layout.h>
- .globl syscall_stub
.section .__syscall_stub, "ax"
.globl batch_syscall_stub
diff --git a/arch/x86/um/stub_64.S b/arch/x86/um/stub_64.S
index 7160b20..ba914b3 100644
--- a/arch/x86/um/stub_64.S
+++ b/arch/x86/um/stub_64.S
@@ -1,25 +1,9 @@
#include <as-layout.h>
- .globl syscall_stub
.section .__syscall_stub, "ax"
-syscall_stub:
- syscall
- /* We don't have 64-bit constants, so this constructs the address
- * we need.
- */
- movq $(STUB_DATA >> 32), %rbx
- salq $32, %rbx
- movq $(STUB_DATA & 0xffffffff), %rcx
- or %rcx, %rbx
- movq %rax, (%rbx)
- int3
-
.globl batch_syscall_stub
batch_syscall_stub:
- mov $(STUB_DATA >> 32), %rbx
- sal $32, %rbx
- mov $(STUB_DATA & 0xffffffff), %rax
- or %rax, %rbx
+ mov $(STUB_DATA), %rbx
/* load pointer to first operation */
mov %rbx, %rsp
add $0x10, %rsp
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index bd16d6c..bfce503 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -7,6 +7,7 @@
#include <linux/sys.h>
#include <linux/cache.h>
#include <generated/user_constants.h>
+#include <asm/syscall.h>
#define __NO_STUBS
@@ -24,15 +25,13 @@
#define old_mmap sys_old_mmap
-#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ;
+#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_32.h>
#undef __SYSCALL_I386
-#define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym,
+#define __SYSCALL_I386(nr, sym, qual) [ nr ] = sym,
-typedef asmlinkage void (*sys_call_ptr_t)(void);
-
-extern asmlinkage void sys_ni_syscall(void);
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
/*
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index a75d8700..f306413 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -7,6 +7,7 @@
#include <linux/sys.h>
#include <linux/cache.h>
#include <generated/user_constants.h>
+#include <asm/syscall.h>
#define __NO_STUBS
@@ -34,18 +35,13 @@
#define stub_execveat sys_execveat
#define stub_rt_sigreturn sys_rt_sigreturn
-#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
-#define __SYSCALL_X32(nr, sym, compat) /* Not supported */
-
-#define __SYSCALL_64(nr, sym, compat) extern asmlinkage void sym(void) ;
+#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_64.h>
#undef __SYSCALL_64
-#define __SYSCALL_64(nr, sym, compat) [ nr ] = sym,
-
-typedef void (*sys_call_ptr_t)(void);
+#define __SYSCALL_64(nr, sym, qual) [ nr ] = sym,
-extern void sys_ni_syscall(void);
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
/*
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index ce7e360..470564b 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -9,14 +9,12 @@
#include <asm/types.h>
#ifdef __i386__
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_32.h>
};
#else
-#define __SYSCALL_64(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_X32(nr, sym, compat) /* Not supported */
+#define __SYSCALL_64(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_64.h>
};
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
index acda713..abf4901 100644
--- a/arch/x86/xen/apic.c
+++ b/arch/x86/xen/apic.c
@@ -64,7 +64,7 @@ static u32 xen_apic_read(u32 reg)
if (reg != APIC_ID)
return 0;
- ret = HYPERVISOR_dom0_op(&op);
+ ret = HYPERVISOR_platform_op(&op);
if (ret)
return 0;
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 993b7a7..2c26108 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -75,6 +75,7 @@
#include <asm/mwait.h>
#include <asm/pci_x86.h>
#include <asm/pat.h>
+#include <asm/cpu.h>
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
@@ -414,7 +415,7 @@ static bool __init xen_check_mwait(void)
set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
- if ((HYPERVISOR_dom0_op(&op) == 0) &&
+ if ((HYPERVISOR_platform_op(&op) == 0) &&
(buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) {
cpuid_leaf5_ecx_val = cx;
cpuid_leaf5_edx_val = dx;
@@ -1191,7 +1192,7 @@ static const struct pv_info xen_info __initconst = {
#ifdef CONFIG_X86_64
.extra_user_64bit_cs = FLAT_USER_CS64,
#endif
-
+ .features = 0,
.name = "Xen",
};
@@ -1228,10 +1229,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.iret = xen_iret,
#ifdef CONFIG_X86_64
- .usergs_sysret32 = xen_sysret32,
.usergs_sysret64 = xen_sysret64,
-#else
- .irq_enable_sysexit = xen_sysexit,
#endif
.load_tr_desc = paravirt_nop,
@@ -1264,12 +1262,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.end_context_switch = xen_end_context_switch,
};
-static const struct pv_apic_ops xen_apic_ops __initconst = {
-#ifdef CONFIG_X86_LOCAL_APIC
- .startup_ipi_hook = paravirt_nop,
-#endif
-};
-
static void xen_reboot(int reason)
{
struct sched_shutdown r = { .reason = reason };
@@ -1373,7 +1365,7 @@ static void __init xen_boot_params_init_edd(void)
info->params.length = sizeof(info->params);
set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params,
&info->params);
- ret = HYPERVISOR_dom0_op(&op);
+ ret = HYPERVISOR_platform_op(&op);
if (ret)
break;
@@ -1391,7 +1383,7 @@ static void __init xen_boot_params_init_edd(void)
op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE;
for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) {
op.u.firmware_info.index = nr;
- ret = HYPERVISOR_dom0_op(&op);
+ ret = HYPERVISOR_platform_op(&op);
if (ret)
break;
mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature;
@@ -1534,8 +1526,9 @@ asmlinkage __visible void __init xen_start_kernel(void)
/* Install Xen paravirt ops */
pv_info = xen_info;
+ if (xen_initial_domain())
+ pv_info.features |= PV_SUPPORTED_RTC;
pv_init_ops = xen_init_ops;
- pv_apic_ops = xen_apic_ops;
if (!xen_pvh_domain()) {
pv_cpu_ops = xen_cpu_ops;
@@ -1661,7 +1654,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
cpu_detect(&new_cpu_data);
set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
new_cpu_data.wp_works_ok = 1;
- new_cpu_data.x86_capability[0] = cpuid_edx(1);
+ new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1);
#endif
if (xen_start_info->mod_start) {
@@ -1697,7 +1690,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
xen_start_info->console.domU.mfn = 0;
xen_start_info->console.domU.evtchn = 0;
- if (HYPERVISOR_dom0_op(&op) == 0)
+ if (HYPERVISOR_platform_op(&op) == 0)
boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags;
/* Make sure ACS will be enabled */
@@ -1885,8 +1878,10 @@ EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);
static void xen_set_cpu_features(struct cpuinfo_x86 *c)
{
- if (xen_pv_domain())
+ if (xen_pv_domain()) {
clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+ set_cpu_cap(c, X86_FEATURE_XENPV);
+ }
}
const struct hypervisor_x86 x86_hyper_xen = {
@@ -1899,3 +1894,17 @@ const struct hypervisor_x86 x86_hyper_xen = {
.set_cpu_features = xen_set_cpu_features,
};
EXPORT_SYMBOL(x86_hyper_xen);
+
+#ifdef CONFIG_HOTPLUG_CPU
+void xen_arch_register_cpu(int num)
+{
+ arch_register_cpu(num);
+}
+EXPORT_SYMBOL(xen_arch_register_cpu);
+
+void xen_arch_unregister_cpu(int num)
+{
+ arch_unregister_cpu(num);
+}
+EXPORT_SYMBOL(xen_arch_unregister_cpu);
+#endif
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 1580e7a..e079500 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -133,7 +133,7 @@ static int __init xlated_setup_gnttab_pages(void)
kfree(pages);
return -ENOMEM;
}
- rc = alloc_xenballooned_pages(nr_grant_frames, pages, 0 /* lowmem */);
+ rc = alloc_xenballooned_pages(nr_grant_frames, pages);
if (rc) {
pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 9c479fe..c913ca4 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2436,7 +2436,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
.flush_tlb_others = xen_flush_tlb_others,
.pte_update = paravirt_nop,
- .pte_update_defer = paravirt_nop,
.pgd_alloc = xen_pgd_alloc,
.pgd_free = xen_pgd_free,
@@ -2495,14 +2494,9 @@ void __init xen_init_mmu_ops(void)
{
x86_init.paging.pagetable_init = xen_pagetable_init;
- /* Optimization - we can use the HVM one but it has no idea which
- * VCPUs are descheduled - which means that it will needlessly IPI
- * them. Xen knows so let it do the job.
- */
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
- pv_mmu_ops.flush_tlb_others = xen_flush_tlb_others;
+ if (xen_feature(XENFEAT_auto_translated_physmap))
return;
- }
+
pv_mmu_ops = xen_mmu_ops;
memset(dummy_mapping, 0xff, PAGE_SIZE);
@@ -2888,6 +2882,7 @@ static int do_remap_gfn(struct vm_area_struct *vma,
addr += range;
if (err_ptr)
err_ptr += batch;
+ cond_resched();
}
out:
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 660b3cf..cab9f76 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -530,7 +530,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
* the new pages are installed with cmpxchg; if we lose the race then
* simply free the page we allocated and use the one that's there.
*/
-static bool alloc_p2m(unsigned long pfn)
+int xen_alloc_p2m_entry(unsigned long pfn)
{
unsigned topidx;
unsigned long *top_mfn_p, *mid_mfn;
@@ -540,6 +540,9 @@ static bool alloc_p2m(unsigned long pfn)
unsigned long addr = (unsigned long)(xen_p2m_addr + pfn);
unsigned long p2m_pfn;
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return 0;
+
ptep = lookup_address(addr, &level);
BUG_ON(!ptep || level != PG_LEVEL_4K);
pte_pg = (pte_t *)((unsigned long)ptep & ~(PAGE_SIZE - 1));
@@ -548,7 +551,7 @@ static bool alloc_p2m(unsigned long pfn)
/* PMD level is missing, allocate a new one */
ptep = alloc_p2m_pmd(addr, pte_pg);
if (!ptep)
- return false;
+ return -ENOMEM;
}
if (p2m_top_mfn && pfn < MAX_P2M_PFN) {
@@ -566,7 +569,7 @@ static bool alloc_p2m(unsigned long pfn)
mid_mfn = alloc_p2m_page();
if (!mid_mfn)
- return false;
+ return -ENOMEM;
p2m_mid_mfn_init(mid_mfn, p2m_missing);
@@ -592,7 +595,7 @@ static bool alloc_p2m(unsigned long pfn)
p2m = alloc_p2m_page();
if (!p2m)
- return false;
+ return -ENOMEM;
if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
p2m_init(p2m);
@@ -625,8 +628,9 @@ static bool alloc_p2m(unsigned long pfn)
HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
}
- return true;
+ return 0;
}
+EXPORT_SYMBOL(xen_alloc_p2m_entry);
unsigned long __init set_phys_range_identity(unsigned long pfn_s,
unsigned long pfn_e)
@@ -688,7 +692,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
- if (!alloc_p2m(pfn))
+ int ret;
+
+ ret = xen_alloc_p2m_entry(pfn);
+ if (ret < 0)
return false;
return __set_phys_to_machine(pfn, mfn);
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index 724a087..9466354 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -11,7 +11,7 @@
#include "pmu.h"
/* x86_pmu.handle_irq definition */
-#include "../kernel/cpu/perf_event.h"
+#include "../events/perf_event.h"
#define XENPMU_IRQ_PROCESSING 1
struct xenpmu {
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 1c30e4a..7ab2951 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -212,7 +212,7 @@ static unsigned long __init xen_find_pfn_range(unsigned long *min_pfn)
e_pfn = PFN_DOWN(entry->addr + entry->size);
/* We only care about E820 after this */
- if (e_pfn < *min_pfn)
+ if (e_pfn <= *min_pfn)
continue;
s_pfn = PFN_UP(entry->addr);
@@ -829,6 +829,8 @@ char * __init xen_memory_setup(void)
addr = xen_e820_map[0].addr;
size = xen_e820_map[0].size;
while (i < xen_e820_map_entries) {
+ bool discard = false;
+
chunk_size = size;
type = xen_e820_map[i].type;
@@ -843,10 +845,11 @@ char * __init xen_memory_setup(void)
xen_add_extra_mem(pfn_s, n_pfns);
xen_max_p2m_pfn = pfn_s + n_pfns;
} else
- type = E820_UNUSABLE;
+ discard = true;
}
- xen_align_and_add_e820_region(addr, chunk_size, type);
+ if (!discard)
+ xen_align_and_add_e820_region(addr, chunk_size, type);
addr += chunk_size;
size -= chunk_size;
@@ -965,17 +968,8 @@ char * __init xen_auto_xlated_memory_setup(void)
static void __init fiddle_vdso(void)
{
#ifdef CONFIG_X86_32
- /*
- * This could be called before selected_vdso32 is initialized, so
- * just fiddle with both possible images. vdso_image_32_syscall
- * can't be selected, since it only exists on 64-bit systems.
- */
- u32 *mask;
- mask = vdso_image_32_int80.data +
- vdso_image_32_int80.sym_VDSO32_NOTE_MASK;
- *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
- mask = vdso_image_32_sysenter.data +
- vdso_image_32_sysenter.sym_VDSO32_NOTE_MASK;
+ u32 *mask = vdso_image_32.data +
+ vdso_image_32.sym_VDSO32_NOTE_MASK;
*mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
#endif
}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 3f4ebf0..3c6d17f 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -112,7 +112,7 @@ asmlinkage __visible void cpu_bringup_and_idle(int cpu)
xen_pvh_secondary_vcpu_init(cpu);
#endif
cpu_bringup();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
static void xen_smp_intr_free(unsigned int cpu)
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index feddabd..7f664c4 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -1,6 +1,7 @@
#include <linux/types.h>
#include <linux/tick.h>
+#include <xen/xen.h>
#include <xen/interface/xen.h>
#include <xen/grant_table.h>
#include <xen/events.h>
@@ -33,7 +34,8 @@ static void xen_hvm_post_suspend(int suspend_cancelled)
{
#ifdef CONFIG_XEN_PVHVM
int cpu;
- xen_hvm_init_shared_info();
+ if (!suspend_cancelled)
+ xen_hvm_init_shared_info();
xen_callback_vector();
xen_unplug_emulated_devices();
if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
@@ -68,26 +70,16 @@ static void xen_pv_post_suspend(int suspend_cancelled)
void xen_arch_pre_suspend(void)
{
- int cpu;
-
- for_each_online_cpu(cpu)
- xen_pmu_finish(cpu);
-
if (xen_pv_domain())
xen_pv_pre_suspend();
}
void xen_arch_post_suspend(int cancelled)
{
- int cpu;
-
if (xen_pv_domain())
xen_pv_post_suspend(cancelled);
else
xen_hvm_post_suspend(cancelled);
-
- for_each_online_cpu(cpu)
- xen_pmu_init(cpu);
}
static void xen_vcpu_notify_restore(void *data)
@@ -106,10 +98,20 @@ static void xen_vcpu_notify_suspend(void *data)
void xen_arch_resume(void)
{
+ int cpu;
+
on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
+
+ for_each_online_cpu(cpu)
+ xen_pmu_init(cpu);
}
void xen_arch_suspend(void)
{
+ int cpu;
+
+ for_each_online_cpu(cpu)
+ xen_pmu_finish(cpu);
+
on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
}
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index f1ba6a0..a0a4e55 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -16,6 +16,7 @@
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/pvclock_gtod.h>
+#include <linux/timekeeper_internal.h>
#include <asm/pvclock.h>
#include <asm/xen/hypervisor.h>
@@ -32,86 +33,12 @@
#define TIMER_SLOP 100000
#define NS_PER_TICK (1000000000LL / HZ)
-/* runstate info updated by Xen */
-static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
-
/* snapshots of runstate info */
static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot);
/* unused ns of stolen time */
static DEFINE_PER_CPU(u64, xen_residual_stolen);
-/* return an consistent snapshot of 64-bit time/counter value */
-static u64 get64(const u64 *p)
-{
- u64 ret;
-
- if (BITS_PER_LONG < 64) {
- u32 *p32 = (u32 *)p;
- u32 h, l;
-
- /*
- * Read high then low, and then make sure high is
- * still the same; this will only loop if low wraps
- * and carries into high.
- * XXX some clean way to make this endian-proof?
- */
- do {
- h = p32[1];
- barrier();
- l = p32[0];
- barrier();
- } while (p32[1] != h);
-
- ret = (((u64)h) << 32) | l;
- } else
- ret = *p;
-
- return ret;
-}
-
-/*
- * Runstate accounting
- */
-static void get_runstate_snapshot(struct vcpu_runstate_info *res)
-{
- u64 state_time;
- struct vcpu_runstate_info *state;
-
- BUG_ON(preemptible());
-
- state = this_cpu_ptr(&xen_runstate);
-
- /*
- * The runstate info is always updated by the hypervisor on
- * the current CPU, so there's no need to use anything
- * stronger than a compiler barrier when fetching it.
- */
- do {
- state_time = get64(&state->state_entry_time);
- barrier();
- *res = *state;
- barrier();
- } while (get64(&state->state_entry_time) != state_time);
-}
-
-/* return true when a vcpu could run but has no real cpu to run on */
-bool xen_vcpu_stolen(int vcpu)
-{
- return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable;
-}
-
-void xen_setup_runstate_info(int cpu)
-{
- struct vcpu_register_runstate_memory_area area;
-
- area.addr.v = &per_cpu(xen_runstate, cpu);
-
- if (HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area,
- cpu, &area))
- BUG();
-}
-
static void do_stolen_accounting(void)
{
struct vcpu_runstate_info state;
@@ -119,7 +46,7 @@ static void do_stolen_accounting(void)
s64 runnable, offline, stolen;
cputime_t ticks;
- get_runstate_snapshot(&state);
+ xen_get_runstate_snapshot(&state);
WARN_ON(state.state != RUNSTATE_running);
@@ -194,26 +121,46 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
unsigned long was_set, void *priv)
{
/* Protected by the calling core code serialization */
- static struct timespec next_sync;
+ static struct timespec64 next_sync;
struct xen_platform_op op;
- struct timespec now;
+ struct timespec64 now;
+ struct timekeeper *tk = priv;
+ static bool settime64_supported = true;
+ int ret;
- now = __current_kernel_time();
+ now.tv_sec = tk->xtime_sec;
+ now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
/*
* We only take the expensive HV call when the clock was set
* or when the 11 minutes RTC synchronization time elapsed.
*/
- if (!was_set && timespec_compare(&now, &next_sync) < 0)
+ if (!was_set && timespec64_compare(&now, &next_sync) < 0)
return NOTIFY_OK;
- op.cmd = XENPF_settime;
- op.u.settime.secs = now.tv_sec;
- op.u.settime.nsecs = now.tv_nsec;
- op.u.settime.system_time = xen_clocksource_read();
+again:
+ if (settime64_supported) {
+ op.cmd = XENPF_settime64;
+ op.u.settime64.mbz = 0;
+ op.u.settime64.secs = now.tv_sec;
+ op.u.settime64.nsecs = now.tv_nsec;
+ op.u.settime64.system_time = xen_clocksource_read();
+ } else {
+ op.cmd = XENPF_settime32;
+ op.u.settime32.secs = now.tv_sec;
+ op.u.settime32.nsecs = now.tv_nsec;
+ op.u.settime32.system_time = xen_clocksource_read();
+ }
+
+ ret = HYPERVISOR_platform_op(&op);
- (void)HYPERVISOR_dom0_op(&op);
+ if (ret == -ENOSYS && settime64_supported) {
+ settime64_supported = false;
+ goto again;
+ }
+ if (ret < 0)
+ return NOTIFY_BAD;
/*
* Move the next drift compensation time 11 minutes
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
index fd92a64..feb6d40 100644
--- a/arch/x86/xen/xen-asm_32.S
+++ b/arch/x86/xen/xen-asm_32.S
@@ -35,20 +35,6 @@ check_events:
ret
/*
- * We can't use sysexit directly, because we're not running in ring0.
- * But we can easily fake it up using iret. Assuming xen_sysexit is
- * jumped to with a standard stack frame, we can just strip it back to
- * a standard iret frame and use iret.
- */
-ENTRY(xen_sysexit)
- movl PT_EAX(%esp), %eax /* Shouldn't be necessary? */
- orl $X86_EFLAGS_IF, PT_EFLAGS(%esp)
- lea PT_EIP(%esp), %esp
-
- jmp xen_iret
-ENDPROC(xen_sysexit)
-
-/*
* This is run where a normal iret would be run, with the same stack setup:
* 8: eflags
* 4: cs
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index f22667a..cc8acc4 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -68,25 +68,6 @@ ENTRY(xen_sysret64)
ENDPATCH(xen_sysret64)
RELOC(xen_sysret64, 1b+1)
-ENTRY(xen_sysret32)
- /*
- * We're already on the usermode stack at this point, but
- * still with the kernel gs, so we can easily switch back
- */
- movq %rsp, PER_CPU_VAR(rsp_scratch)
- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
-
- pushq $__USER32_DS
- pushq PER_CPU_VAR(rsp_scratch)
- pushq %r11
- pushq $__USER32_CS
- pushq %rcx
-
- pushq $0
-1: jmp hypercall_iret
-ENDPATCH(xen_sysret32)
-RELOC(xen_sysret32, 1b+1)
-
/*
* Xen handles syscall callbacks much like ordinary exceptions, which
* means we have:
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 1399423..4140b07 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -139,9 +139,6 @@ DECL_ASM(void, xen_restore_fl_direct, unsigned long);
/* These are not functions, and cannot be called normally */
__visible void xen_iret(void);
-#ifdef CONFIG_X86_32
-__visible void xen_sysexit(void);
-#endif
__visible void xen_sysret32(void);
__visible void xen_sysret64(void);
__visible void xen_adjust_exception_frame(void);
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3bd3504..7e9464b 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -15,8 +15,8 @@ config XTENSA
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select HAVE_DMA_API_DEBUG
- select HAVE_DMA_ATTRS
select HAVE_FUNCTION_TRACER
+ select HAVE_FUTEX_CMPXCHG if !MMU
select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_OPROFILE
select HAVE_PERF_EVENTS
@@ -397,9 +397,21 @@ config SIMDISK1_FILENAME
source "mm/Kconfig"
-source "drivers/pcmcia/Kconfig"
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order"
+ 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.
-source "drivers/pci/hotplug/Kconfig"
+ 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.
+
+source "drivers/pcmcia/Kconfig"
config PLATFORM_WANT_DEFAULT_MEM
def_bool n
@@ -408,7 +420,7 @@ config DEFAULT_MEM_START
hex "Physical address of the default memory area start"
depends on PLATFORM_WANT_DEFAULT_MEM
default 0x00000000 if MMU
- default 0x40000000 if !MMU
+ default 0x60000000 if !MMU
help
This is a fallback start address of the default memory area, it is
used when no physical memory size is passed through DTB or through
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index f9e6a06..709b574 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -101,6 +101,10 @@ zImage: vmlinux
%.dtb:
$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
+dtbs: scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts
+
define archhelp
@echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
+ @echo ' dtbs - Build device tree blobs for enabled boards'
endef
diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S
index 958b33a..e54f2c9 100644
--- a/arch/xtensa/boot/boot-elf/boot.lds.S
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -40,17 +40,4 @@ SECTIONS
*(.bss)
__bss_end = .;
}
-
-#ifdef CONFIG_MMU
- /*
- * This is a remapped copy of the Reset Vector Code.
- * It keeps gdb in sync with the PC after switching
- * to the temporary mapping used while setting up
- * the V2 MMU mappings for Linux.
- */
- .ResetVector.remapped_text 0x46000000 (INFO):
- {
- *(.ResetVector.remapped_text)
- }
-#endif
}
diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S
index 9341a57..e6bf313 100644
--- a/arch/xtensa/boot/boot-elf/bootstrap.S
+++ b/arch/xtensa/boot/boot-elf/bootstrap.S
@@ -58,8 +58,6 @@ _SetupMMU:
wsr a0, ps
rsync
- Offset = _SetupMMU - _ResetVector
-
#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
initialize_mmu
#endif
@@ -74,29 +72,3 @@ reset:
movi a3, 0
movi a4, 0
jx a0
-
-#ifdef CONFIG_MMU
- .align 4
-
- .section .ResetVector.remapped_text, "x"
- .global _RemappedResetVector
-
- /* Do org before literals */
- .org 0
-
-_RemappedResetVector:
- .begin no-absolute-literals
- .literal_position
-
- _j _RemappedSetupMMU
-
- /* Position Remapped code at the same location as the original code */
- . = _RemappedResetVector + Offset
-
-_RemappedSetupMMU:
-#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
- initialize_mmu
-#endif
-
- .end no-absolute-literals
-#endif
diff --git a/arch/xtensa/boot/dts/Makefile b/arch/xtensa/boot/dts/Makefile
index 5f711bb..a15e241 100644
--- a/arch/xtensa/boot/dts/Makefile
+++ b/arch/xtensa/boot/dts/Makefile
@@ -12,4 +12,9 @@ ifneq ($(CONFIG_BUILTIN_DTB),"")
obj-$(CONFIG_OF) += $(BUILTIN_DTB)
endif
-clean-files := *.dtb.S
+dtstree := $(srctree)/$(src)
+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+
+always += $(dtb-y)
+clean-files += *.dtb *.dtb.S
+
diff --git a/arch/xtensa/boot/dts/kc705_nommu.dts b/arch/xtensa/boot/dts/kc705_nommu.dts
new file mode 100644
index 0000000..65f3d74
--- /dev/null
+++ b/arch/xtensa/boot/dts/kc705_nommu.dts
@@ -0,0 +1,17 @@
+/dts-v1/;
+/include/ "xtfpga.dtsi"
+/include/ "xtfpga-flash-128m.dtsi"
+
+/ {
+ compatible = "cdns,xtensa-kc705";
+ chosen {
+ bootargs = "earlycon=uart8250,mmio32,0x9d050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug";
+ };
+ memory@0 {
+ device_type = "memory";
+ reg = <0x60000000 0x10000000>;
+ };
+ soc {
+ ranges = <0x00000000 0x90000000 0x10000000>;
+ };
+};
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig
index f3dfe0d..44c6764 100644
--- a/arch/xtensa/configs/iss_defconfig
+++ b/arch/xtensa/configs/iss_defconfig
@@ -169,7 +169,6 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
diff --git a/arch/xtensa/configs/nommu_kc705_defconfig b/arch/xtensa/configs/nommu_kc705_defconfig
new file mode 100644
index 0000000..337d5ba
--- /dev/null
+++ b/arch/xtensa/configs/nommu_kc705_defconfig
@@ -0,0 +1,131 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_MEMCG=y
+CONFIG_NAMESPACES=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PERF_EVENTS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_XTENSA_VARIANT_CUSTOM=y
+CONFIG_XTENSA_VARIANT_CUSTOM_NAME="de212"
+# CONFIG_XTENSA_VARIANT_MMU is not set
+CONFIG_XTENSA_UNALIGNED_USER=y
+CONFIG_PREEMPT=y
+# CONFIG_PCI is not set
+CONFIG_XTENSA_PLATFORM_XTFPGA=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="earlycon=uart8250,mmio32,0x9d050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"
+CONFIG_USE_OF=y
+CONFIG_BUILTIN_DTB="kc705_nommu"
+CONFIG_DEFAULT_MEM_SIZE=0x10000000
+CONFIG_BINFMT_FLAT=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_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_MTD=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_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_BROADCOM 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_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MARVELL_PHY=y
+# CONFIG_WLAN 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_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_HW_RANDOM=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_ROOT_NFS=y
+CONFIG_SUNRPC_DEBUG=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_NOMMU_REGIONS=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_STACKTRACE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+CONFIG_RCU_TRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_LD_NO_RELAX is not set
+# CONFIG_CRYPTO_ECHAINIV is not set
+CONFIG_CRYPTO_ANSI_CPRNG=y
diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h
index 755320f..746dcc8 100644
--- a/arch/xtensa/include/asm/asmmacro.h
+++ b/arch/xtensa/include/asm/asmmacro.h
@@ -35,9 +35,10 @@
* __loop as
* restart loop. 'as' register must not have been modified!
*
- * __endla ar, at, incr
+ * __endla ar, as, incr
* ar start address (modified)
- * as scratch register used by macro
+ * as scratch register used by __loops/__loopi macros or
+ * end address used by __loopt macro
* inc increment
*/
@@ -97,7 +98,7 @@
.endm
/*
- * loop from ar to ax
+ * loop from ar to as
*/
.macro __loopt ar, as, at, incr_log2
diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h
index 93795d0..fd8017c 100644
--- a/arch/xtensa/include/asm/atomic.h
+++ b/arch/xtensa/include/asm/atomic.h
@@ -47,7 +47,7 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_read(v) READ_ONCE((v)->counter)
/**
* atomic_set - set atomic variable
@@ -56,7 +56,7 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic_set(v,i) ((v)->counter = (i))
+#define atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
#if XCHAL_HAVE_S32C1I
#define ATOMIC_OP(op) \
diff --git a/arch/xtensa/include/asm/barrier.h b/arch/xtensa/include/asm/barrier.h
index 5b88774..956596e 100644
--- a/arch/xtensa/include/asm/barrier.h
+++ b/arch/xtensa/include/asm/barrier.h
@@ -13,8 +13,8 @@
#define rmb() barrier()
#define wmb() mb()
-#define smp_mb__before_atomic() barrier()
-#define smp_mb__after_atomic() barrier()
+#define __smp_mb__before_atomic() barrier()
+#define __smp_mb__after_atomic() barrier()
#include <asm-generic/barrier.h>
diff --git a/arch/xtensa/include/asm/cacheasm.h b/arch/xtensa/include/asm/cacheasm.h
index 60e1877..e0f9e11 100644
--- a/arch/xtensa/include/asm/cacheasm.h
+++ b/arch/xtensa/include/asm/cacheasm.h
@@ -73,7 +73,9 @@
.macro ___unlock_dcache_all ar at
+#if XCHAL_DCACHE_SIZE
__loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
@@ -90,30 +92,38 @@
.macro ___flush_invalidate_dcache_all ar at
+#if XCHAL_DCACHE_SIZE
__loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___flush_dcache_all ar at
+#if XCHAL_DCACHE_SIZE
__loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_dcache_all ar at
+#if XCHAL_DCACHE_SIZE
__loop_cache_all \ar \at dii __stringify(DCACHE_WAY_SIZE) \
XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_icache_all ar at
+#if XCHAL_ICACHE_SIZE
__loop_cache_all \ar \at iii __stringify(ICACHE_WAY_SIZE) \
XCHAL_ICACHE_LINEWIDTH
+#endif
.endm
@@ -121,28 +131,36 @@
.macro ___flush_invalidate_dcache_range ar as at
+#if XCHAL_DCACHE_SIZE
__loop_cache_range \ar \as \at dhwbi XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___flush_dcache_range ar as at
+#if XCHAL_DCACHE_SIZE
__loop_cache_range \ar \as \at dhwb XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_dcache_range ar as at
+#if XCHAL_DCACHE_SIZE
__loop_cache_range \ar \as \at dhi XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_icache_range ar as at
+#if XCHAL_ICACHE_SIZE
__loop_cache_range \ar \as \at ihi XCHAL_ICACHE_LINEWIDTH
+#endif
.endm
@@ -150,27 +168,35 @@
.macro ___flush_invalidate_dcache_page ar as
+#if XCHAL_DCACHE_SIZE
__loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___flush_dcache_page ar as
+#if XCHAL_DCACHE_SIZE
__loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_dcache_page ar as
+#if XCHAL_DCACHE_SIZE
__loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH
+#endif
.endm
.macro ___invalidate_icache_page ar as
+#if XCHAL_ICACHE_SIZE
__loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
+#endif
.endm
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 5f67ace..397d6a1 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -55,9 +55,14 @@ extern void __flush_dcache_range(unsigned long, unsigned long);
extern void __flush_invalidate_dcache_page(unsigned long);
extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
#else
-# define __flush_dcache_range(p,s) do { } while(0)
-# define __flush_dcache_page(p) do { } while(0)
-# define __flush_invalidate_dcache_page(p) __invalidate_dcache_page(p)
+static inline void __flush_dcache_page(unsigned long va)
+{
+}
+static inline void __flush_dcache_range(unsigned long va, unsigned long sz)
+{
+}
+# define __flush_invalidate_dcache_all() __invalidate_dcache_all()
+# define __flush_invalidate_dcache_page(p) __invalidate_dcache_page(p)
# define __flush_invalidate_dcache_range(p,s) __invalidate_dcache_range(p,s)
#endif
@@ -174,99 +179,4 @@ extern void copy_from_user_page(struct vm_area_struct*, struct page*,
#endif
-#define XTENSA_CACHEBLK_LOG2 29
-#define XTENSA_CACHEBLK_SIZE (1 << XTENSA_CACHEBLK_LOG2)
-#define XTENSA_CACHEBLK_MASK (7 << XTENSA_CACHEBLK_LOG2)
-
-#if XCHAL_HAVE_CACHEATTR
-static inline u32 xtensa_get_cacheattr(void)
-{
- u32 r;
- asm volatile(" rsr %0, cacheattr" : "=a"(r));
- return r;
-}
-
-static inline u32 xtensa_get_dtlb1(u32 addr)
-{
- u32 r = addr & XTENSA_CACHEBLK_MASK;
- return r | ((xtensa_get_cacheattr() >> (r >> (XTENSA_CACHEBLK_LOG2-2)))
- & 0xF);
-}
-#else
-static inline u32 xtensa_get_dtlb1(u32 addr)
-{
- u32 r;
- asm volatile(" rdtlb1 %0, %1" : "=a"(r) : "a"(addr));
- asm volatile(" dsync");
- return r;
-}
-
-static inline u32 xtensa_get_cacheattr(void)
-{
- u32 r = 0;
- u32 a = 0;
- do {
- a -= XTENSA_CACHEBLK_SIZE;
- r = (r << 4) | (xtensa_get_dtlb1(a) & 0xF);
- } while (a);
- return r;
-}
-#endif
-
-static inline int xtensa_need_flush_dma_source(u32 addr)
-{
- return (xtensa_get_dtlb1(addr) & ((1 << XCHAL_CA_BITS) - 1)) >= 4;
-}
-
-static inline int xtensa_need_invalidate_dma_destination(u32 addr)
-{
- return (xtensa_get_dtlb1(addr) & ((1 << XCHAL_CA_BITS) - 1)) != 2;
-}
-
-static inline void flush_dcache_unaligned(u32 addr, u32 size)
-{
- u32 cnt;
- if (size) {
- cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr)
- + XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE;
- while (cnt--) {
- asm volatile(" dhwb %0, 0" : : "a"(addr));
- addr += XCHAL_DCACHE_LINESIZE;
- }
- asm volatile(" dsync");
- }
-}
-
-static inline void invalidate_dcache_unaligned(u32 addr, u32 size)
-{
- int cnt;
- if (size) {
- asm volatile(" dhwbi %0, 0 ;" : : "a"(addr));
- cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr)
- - XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE;
- while (cnt-- > 0) {
- asm volatile(" dhi %0, %1" : : "a"(addr),
- "n"(XCHAL_DCACHE_LINESIZE));
- addr += XCHAL_DCACHE_LINESIZE;
- }
- asm volatile(" dhwbi %0, %1" : : "a"(addr),
- "n"(XCHAL_DCACHE_LINESIZE));
- asm volatile(" dsync");
- }
-}
-
-static inline void flush_invalidate_dcache_unaligned(u32 addr, u32 size)
-{
- u32 cnt;
- if (size) {
- cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr)
- + XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE;
- while (cnt--) {
- asm volatile(" dhwbi %0, 0" : : "a"(addr));
- addr += XCHAL_DCACHE_LINESIZE;
- }
- asm volatile(" dsync");
- }
-}
-
#endif /* _XTENSA_CACHEFLUSH_H */
diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h
index 0593de6..ec35074 100644
--- a/arch/xtensa/include/asm/checksum.h
+++ b/arch/xtensa/include/asm/checksum.h
@@ -123,9 +123,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
#ifdef __XTENSA_EL__
@@ -157,9 +156,8 @@ static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* 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)
+ __u32 len, __u8 proto,
+ __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
@@ -177,7 +175,7 @@ static __inline__ __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
+ __u32 len, __u8 proto,
__wsum sum)
{
unsigned int __dummy;
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h
index 4427f38..3fc1170 100644
--- a/arch/xtensa/include/asm/dma-mapping.h
+++ b/arch/xtensa/include/asm/dma-mapping.h
@@ -13,8 +13,6 @@
#include <asm/cache.h>
#include <asm/io.h>
-#include <asm-generic/dma-coherent.h>
-
#include <linux/mm.h>
#include <linux/scatterlist.h>
@@ -30,9 +28,17 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &xtensa_dma_map_ops;
}
-#include <asm-generic/dma-mapping-common.h>
-
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ return (dma_addr_t)paddr;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ return (phys_addr_t)daddr;
+}
+
#endif /* _XTENSA_DMA_MAPPING_H */
diff --git a/arch/xtensa/include/asm/gpio.h b/arch/xtensa/include/asm/gpio.h
deleted file mode 100644
index b3799d8..0000000
--- a/arch/xtensa/include/asm/gpio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __LINUX_GPIO_H
-#warning Include linux/gpio.h instead of asm/gpio.h
-#include <linux/gpio.h>
-#endif
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h
index e256f22..7a1e075 100644
--- a/arch/xtensa/include/asm/initialize_mmu.h
+++ b/arch/xtensa/include/asm/initialize_mmu.h
@@ -161,7 +161,8 @@
#endif /* defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU &&
XCHAL_HAVE_SPANNING_WAY */
-#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS
+#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS && \
+ (XCHAL_DCACHE_SIZE || XCHAL_ICACHE_SIZE)
/* Enable data and instruction cache in the DEFAULT_MEMORY region
* if the processor has DTLB and ITLB.
*/
@@ -175,14 +176,18 @@
1:
sub a9, a9, a8
2:
+#if XCHAL_DCACHE_SIZE
rdtlb1 a3, a5
- ritlb1 a4, a5
and a3, a3, a6
- and a4, a4, a6
or a3, a3, a7
- or a4, a4, a7
wdtlb a3, a5
+#endif
+#if XCHAL_ICACHE_SIZE
+ ritlb1 a4, a5
+ and a4, a4, a6
+ or a4, a4, a7
witlb a4, a5
+#endif
add a5, a5, a8
bltu a8, a9, 1b
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 867840f..74fed0b 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -25,15 +25,6 @@
#ifdef CONFIG_MMU
-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF)
-extern unsigned long xtensa_kio_paddr;
-
-static inline unsigned long xtensa_get_kio_paddr(void)
-{
- return xtensa_kio_paddr;
-}
-#endif
-
/*
* Return the virtual address for the specified bus memory.
* Note that we currently don't support any address outside the KIO segment.
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h
index e438a00..5d6bd93 100644
--- a/arch/xtensa/include/asm/pci.h
+++ b/arch/xtensa/include/asm/pci.h
@@ -55,9 +55,6 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
#endif /* __KERNEL__ */
-/* Implement the pci_ DMA API in terms of the generic device dma_ one */
-#include <asm-generic/pci-dma-compat.h>
-
/* Generic PCI */
#include <asm-generic/pci.h>
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index a5e929a..fb02fdc 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -18,7 +18,11 @@
* We only use two ring levels, user and kernel space.
*/
+#ifdef CONFIG_MMU
#define USER_RING 1 /* user ring level */
+#else
+#define USER_RING 0
+#endif
#define KERNEL_RING 0 /* kernel ring level */
/*
diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h
index a46c53f..288c776 100644
--- a/arch/xtensa/include/asm/vectors.h
+++ b/arch/xtensa/include/asm/vectors.h
@@ -21,13 +21,26 @@
#include <variant/core.h>
#include <platform/hardware.h>
+#if XCHAL_HAVE_PTP_MMU
#define XCHAL_KIO_CACHED_VADDR 0xe0000000
#define XCHAL_KIO_BYPASS_VADDR 0xf0000000
#define XCHAL_KIO_DEFAULT_PADDR 0xf0000000
+#else
+#define XCHAL_KIO_BYPASS_VADDR XCHAL_KIO_PADDR
+#define XCHAL_KIO_DEFAULT_PADDR 0x90000000
+#endif
#define XCHAL_KIO_SIZE 0x10000000
-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF)
+#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF)
#define XCHAL_KIO_PADDR xtensa_get_kio_paddr()
+#ifndef __ASSEMBLY__
+extern unsigned long xtensa_kio_paddr;
+
+static inline unsigned long xtensa_get_kio_paddr(void)
+{
+ return xtensa_kio_paddr;
+}
+#endif
#else
#define XCHAL_KIO_PADDR XCHAL_KIO_DEFAULT_PADDR
#endif
@@ -48,6 +61,9 @@
#define LOAD_MEMORY_ADDRESS 0xD0003000
#endif
+#define RESET_VECTOR1_VADDR (VIRTUAL_MEMORY_ADDRESS + \
+ XCHAL_RESET_VECTOR1_PADDR)
+
#else /* !defined(CONFIG_MMU) */
/* MMU Not being used - Virtual == Physical */
@@ -60,6 +76,8 @@
/* Loaded just above possibly live vectors */
#define LOAD_MEMORY_ADDRESS (PLATFORM_DEFAULT_MEM_START + 0x3000)
+#define RESET_VECTOR1_VADDR (XCHAL_RESET_VECTOR1_VADDR)
+
#endif /* CONFIG_MMU */
#define XC_VADDR(offset) (VIRTUAL_MEMORY_ADDRESS + offset)
@@ -67,14 +85,6 @@
/* Used to set VECBASE register */
#define VECBASE_RESET_VADDR VIRTUAL_MEMORY_ADDRESS
-#define RESET_VECTOR_VECOFS (XCHAL_RESET_VECTOR_VADDR - \
- VECBASE_RESET_VADDR)
-#define RESET_VECTOR_VADDR XC_VADDR(RESET_VECTOR_VECOFS)
-
-#define RESET_VECTOR1_VECOFS (XCHAL_RESET_VECTOR1_VADDR - \
- VECBASE_RESET_VADDR)
-#define RESET_VECTOR1_VADDR XC_VADDR(RESET_VECTOR1_VECOFS)
-
#if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE
#define USER_VECTOR_VADDR XC_VADDR(XCHAL_USER_VECOFS)
diff --git a/arch/xtensa/include/uapi/asm/mman.h b/arch/xtensa/include/uapi/asm/mman.h
index 201aec0..9e079d4 100644
--- a/arch/xtensa/include/uapi/asm/mman.h
+++ b/arch/xtensa/include/uapi/asm/mman.h
@@ -74,6 +74,12 @@
*/
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
+#define MCL_ONFAULT 4 /* lock all pages that are faulted in */
+
+/*
+ * Flags for mlock
+ */
+#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */
#define MADV_NORMAL 0 /* no further special treatment */
#define MADV_RANDOM 1 /* expect random page references */
@@ -82,6 +88,7 @@
#define MADV_DONTNEED 4 /* don't need these pages */
/* common parameters: try to keep these consistent across architectures */
+#define MADV_FREE 8 /* free pages only if memory pressure */
#define MADV_REMOVE 9 /* remove these pages & resources */
#define MADV_DONTFORK 10 /* don't inherit across fork */
#define MADV_DOFORK 11 /* do inherit across fork */
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h
index 4120af0..81435d9 100644
--- a/arch/xtensa/include/uapi/asm/socket.h
+++ b/arch/xtensa/include/uapi/asm/socket.h
@@ -96,4 +96,9 @@
#define SO_ATTACH_BPF 50
#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#define SO_CNX_ADVICE 53
+
#endif /* _XTENSA_SOCKET_H */
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 50137bc..4db7302 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_SMP) += smp.o mxhead.o
obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
AFLAGS_head.o += -mtext-section-literals
+AFLAGS_mxhead.o += -mtext-section-literals
# In the Xtensa architecture, assembly generates literals which must always
# precede the L32R instruction with a relative offset less than 256 kB.
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 5041303..db5c176 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -367,8 +367,10 @@ common_exception:
s32i a2, a1, PT_SYSCALL
movi a2, 0
s32i a3, a1, PT_EXCVADDR
+#if XCHAL_HAVE_LOOPS
xsr a2, lcount
s32i a2, a1, PT_LCOUNT
+#endif
/* It is now save to restore the EXC_TABLE_FIXUP variable. */
@@ -429,11 +431,12 @@ common_exception:
rsync # PS.WOE => rsync => overflow
/* Save lbeg, lend */
-
+#if XCHAL_HAVE_LOOPS
rsr a4, lbeg
rsr a3, lend
s32i a4, a1, PT_LBEG
s32i a3, a1, PT_LEND
+#endif
/* Save SCOMPARE1 */
@@ -724,13 +727,14 @@ common_exception_exit:
wsr a3, sar
/* Restore LBEG, LEND, LCOUNT */
-
+#if XCHAL_HAVE_LOOPS
l32i a2, a1, PT_LBEG
l32i a3, a1, PT_LEND
wsr a2, lbeg
l32i a2, a1, PT_LCOUNT
wsr a3, lend
wsr a2, lcount
+#endif
/* We control single stepping through the ICOUNTLEVEL register. */
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 15a461e..9ed5564 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -249,7 +249,7 @@ ENTRY(_startup)
__loopt a2, a3, a4, 2
s32i a0, a2, 0
- __endla a2, a4, 4
+ __endla a2, a3, 4
#if XCHAL_DCACHE_IS_WRITEBACK
diff --git a/arch/xtensa/kernel/mxhead.S b/arch/xtensa/kernel/mxhead.S
index 77a161a..9f38437 100644
--- a/arch/xtensa/kernel/mxhead.S
+++ b/arch/xtensa/kernel/mxhead.S
@@ -48,8 +48,6 @@ _SetupOCD:
rsync
_SetupMMU:
- Offset = _SetupMMU - _SecondaryResetVector
-
#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
initialize_mmu
#endif
@@ -62,24 +60,3 @@ _SetupMMU:
jx a3
.end no-absolute-literals
-
-
- .section .SecondaryResetVector.remapped_text, "ax"
- .global _RemappedSecondaryResetVector
-
- .org 0 # Need to do org before literals
-
-_RemappedSecondaryResetVector:
- .begin no-absolute-literals
- .literal_position
-
- _j _RemappedSetupMMU
- . = _RemappedSecondaryResetVector + Offset
-
-_RemappedSetupMMU:
-
-#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
- initialize_mmu
-#endif
-
- .end no-absolute-literals
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index fb75ebf..cd66698 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -15,14 +15,15 @@
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
*/
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
#include <linux/gfp.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
#include <linux/module.h>
-#include <asm/io.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/types.h>
#include <asm/cacheflush.h>
+#include <asm/io.h>
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
@@ -47,17 +48,36 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
}
EXPORT_SYMBOL(dma_cache_sync);
+static void do_cache_op(dma_addr_t dma_handle, size_t size,
+ void (*fn)(unsigned long, unsigned long))
+{
+ unsigned long off = dma_handle & (PAGE_SIZE - 1);
+ unsigned long pfn = PFN_DOWN(dma_handle);
+ struct page *page = pfn_to_page(pfn);
+
+ if (!PageHighMem(page))
+ fn((unsigned long)bus_to_virt(dma_handle), size);
+ else
+ while (size > 0) {
+ size_t sz = min_t(size_t, size, PAGE_SIZE - off);
+ void *vaddr = kmap_atomic(page);
+
+ fn((unsigned long)vaddr + off, sz);
+ kunmap_atomic(vaddr);
+ off = 0;
+ ++page;
+ size -= sz;
+ }
+}
+
static void xtensa_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction dir)
{
- void *vaddr;
-
switch (dir) {
case DMA_BIDIRECTIONAL:
case DMA_FROM_DEVICE:
- vaddr = bus_to_virt(dma_handle);
- __invalidate_dcache_range((unsigned long)vaddr, size);
+ do_cache_op(dma_handle, size, __invalidate_dcache_range);
break;
case DMA_NONE:
@@ -73,13 +93,11 @@ static void xtensa_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction dir)
{
- void *vaddr;
-
switch (dir) {
case DMA_BIDIRECTIONAL:
case DMA_TO_DEVICE:
- vaddr = bus_to_virt(dma_handle);
- __flush_dcache_range((unsigned long)vaddr, size);
+ if (XCHAL_DCACHE_IS_WRITEBACK)
+ do_cache_op(dma_handle, size, __flush_dcache_range);
break;
case DMA_NONE:
@@ -171,7 +189,6 @@ static dma_addr_t xtensa_map_page(struct device *dev, struct page *page,
{
dma_addr_t dma_handle = page_to_phys(page) + offset;
- BUG_ON(PageHighMem(page));
xtensa_sync_single_for_device(dev, dma_handle, size, dir);
return dma_handle;
}
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 28fc57e..9735691 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -190,7 +190,7 @@ static int __init parse_bootparam(const bp_tag_t* tag)
#ifdef CONFIG_OF
bool __initdata dt_memory_scan = false;
-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
+#if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
EXPORT_SYMBOL(xtensa_kio_paddr);
@@ -334,7 +334,10 @@ extern char _Level5InterruptVector_text_end;
extern char _Level6InterruptVector_text_start;
extern char _Level6InterruptVector_text_end;
#endif
-
+#ifdef CONFIG_SMP
+extern char _SecondaryResetVector_text_start;
+extern char _SecondaryResetVector_text_end;
+#endif
#ifdef CONFIG_S32C1I_SELFTEST
@@ -506,6 +509,10 @@ void __init setup_arch(char **cmdline_p)
__pa(&_Level6InterruptVector_text_end), 0);
#endif
+#ifdef CONFIG_SMP
+ mem_reserve(__pa(&_SecondaryResetVector_text_start),
+ __pa(&_SecondaryResetVector_text_end), 0);
+#endif
parse_early_param();
bootmem_init();
diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c
index 4d02e38..fc4ad21 100644
--- a/arch/xtensa/kernel/smp.c
+++ b/arch/xtensa/kernel/smp.c
@@ -157,7 +157,7 @@ void secondary_start_kernel(void)
complete(&cpu_running);
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
static void mx_cpu_start(void *p)
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index b97767d..b9ad9fe 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -148,7 +148,7 @@ void __init time_init(void)
local_timer_setup(0);
setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction);
sched_clock_register(ccount_sched_clock_read, 32, ccount_freq);
- clocksource_of_init();
+ clocksource_probe();
}
/*
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index abcdb52..fc25318 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -478,6 +478,9 @@ _DoubleExceptionVector_handle_exception:
ENDPROC(_DoubleExceptionVector)
+ .end literal_prefix
+
+ .text
/*
* Fixup handler for TLB miss in double exception handler for window owerflow.
* We get here with windowbase set to the window that was being spilled and
@@ -587,7 +590,6 @@ ENTRY(window_overflow_restore_a0_fixup)
ENDPROC(window_overflow_restore_a0_fixup)
- .end literal_prefix
/*
* Debug interrupt vector
*
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index fc1bc2b..c417cbe 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -166,8 +166,6 @@ SECTIONS
RELOCATE_ENTRY(_DebugInterruptVector_text,
.DebugInterruptVector.text);
#if defined(CONFIG_SMP)
- RELOCATE_ENTRY(_SecondaryResetVector_literal,
- .SecondaryResetVector.literal);
RELOCATE_ENTRY(_SecondaryResetVector_text,
.SecondaryResetVector.text);
#endif
@@ -282,17 +280,11 @@ SECTIONS
#if defined(CONFIG_SMP)
- SECTION_VECTOR (_SecondaryResetVector_literal,
- .SecondaryResetVector.literal,
- RESET_VECTOR1_VADDR - 4,
- SIZEOF(.DoubleExceptionVector.text),
- .DoubleExceptionVector.text)
-
SECTION_VECTOR (_SecondaryResetVector_text,
.SecondaryResetVector.text,
RESET_VECTOR1_VADDR,
- 4,
- .SecondaryResetVector.literal)
+ SIZEOF(.DoubleExceptionVector.text),
+ .DoubleExceptionVector.text)
. = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
@@ -306,31 +298,6 @@ SECTIONS
_end = .;
- /* only used by the boot loader */
-
- . = ALIGN(0x10);
- .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
-
- .ResetVector.text RESET_VECTOR_VADDR :
- {
- *(.ResetVector.text)
- }
-
-
- /*
- * This is a remapped copy of the Secondary Reset Vector Code.
- * It keeps gdb in sync with the PC after switching
- * to the temporary mapping used while setting up
- * the V2 MMU mappings for Linux.
- *
- * Only debug information about this section is put in the kernel image.
- */
- .SecondaryResetVector.remapped_text 0x46000000 (INFO):
- {
- *(.SecondaryResetVector.remapped_text)
- }
-
-
.xt.lit : { *(.xt.lit) }
.xt.prop : { *(.xt.prop) }
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S
index ace1892..7ea4dd6 100644
--- a/arch/xtensa/lib/usercopy.S
+++ b/arch/xtensa/lib/usercopy.S
@@ -222,8 +222,8 @@ __xtensa_copy_user:
loopnez a7, .Loop2done
#else /* !XCHAL_HAVE_LOOPS */
beqz a7, .Loop2done
- slli a10, a7, 4
- add a10, a10, a3 # a10 = end of last 16B source chunk
+ slli a12, a7, 4
+ add a12, a12, a3 # a12 = end of last 16B source chunk
#endif /* !XCHAL_HAVE_LOOPS */
.Loop2:
EX(l32i, a7, a3, 4, l_fixup)
@@ -241,7 +241,7 @@ __xtensa_copy_user:
EX(s32i, a9, a5, 12, s_fixup)
addi a5, a5, 16
#if !XCHAL_HAVE_LOOPS
- blt a3, a10, .Loop2
+ blt a3, a12, .Loop2
#endif /* !XCHAL_HAVE_LOOPS */
.Loop2done:
bbci.l a4, 3, .L12
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index c9784c1..7f4a1fd 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -146,7 +146,7 @@ good_area:
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
if (flags & VM_FAULT_MAJOR)
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
- else if (flags & VM_FAULT_MINOR)
+ else
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
return;
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
index 5ece856..35c8222 100644
--- a/arch/xtensa/mm/tlb.c
+++ b/arch/xtensa/mm/tlb.c
@@ -245,7 +245,7 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
page_mapcount(p));
if (!page_count(p))
rc |= TLB_INSANE;
- else if (page_mapped(p))
+ else if (page_mapcount(p))
rc |= TLB_SUSPICIOUS;
} else {
rc |= TLB_INSANE;
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 70cb408..c54505d 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -28,10 +28,6 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
-
#define SERIAL_MAX_NUM_LINES 1
#define SERIAL_TIMER_VALUE (HZ / 10)
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index da7d182..3918205 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -61,7 +61,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t"
#endif
+#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t"
+#endif
"movi a2, 0x1f\n\t"
"wsr a2, ps\n\t"
"isync\n\t"
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index fa84ca9..f58a4e6 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -101,7 +101,7 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
spin_unlock(&dev->lock);
}
-static void simdisk_make_request(struct request_queue *q, struct bio *bio)
+static blk_qc_t simdisk_make_request(struct request_queue *q, struct bio *bio)
{
struct simdisk *dev = q->queuedata;
struct bio_vec bvec;
@@ -119,6 +119,7 @@ static void simdisk_make_request(struct request_queue *q, struct bio *bio)
}
bio_endio(bio);
+ return BLK_QC_T_NONE;
}
static int simdisk_open(struct block_device *bdev, fmode_t mode)
@@ -226,16 +227,12 @@ static ssize_t proc_read_simdisk(struct file *file, char __user *buf,
static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- char *tmp = kmalloc(count + 1, GFP_KERNEL);
+ char *tmp = memdup_user_nul(buf, count);
struct simdisk *dev = PDE_DATA(file_inode(file));
int err;
- if (tmp == NULL)
- return -ENOMEM;
- if (copy_from_user(tmp, buf, count)) {
- err = -EFAULT;
- goto out_free;
- }
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
err = simdisk_detach(dev);
if (err != 0)
@@ -243,8 +240,6 @@ static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
if (count > 0 && tmp[count - 1] == '\n')
tmp[count - 1] = 0;
- else
- tmp[count] = 0;
if (tmp[0])
err = simdisk_attach(dev, tmp);
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c
index b90555c..5f4bd71 100644
--- a/arch/xtensa/platforms/xt2000/setup.c
+++ b/arch/xtensa/platforms/xt2000/setup.c
@@ -72,7 +72,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t"
#endif
+#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t"
+#endif
"movi a2, 0x1f\n\t"
"wsr a2, ps\n\t"
"isync\n\t"
@@ -111,7 +113,7 @@ void platform_heartbeat(void)
}
//#define RS_TABLE_SIZE 2
-//#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+//#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF|UPF_SKIP_TEST)
#define _SERIAL_PORT(_base,_irq) \
{ \
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h
index 0a55bb9..dbeea2b 100644
--- a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h
+++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h
@@ -12,13 +12,15 @@
* This file contains the hardware configuration of the XTAVNET boards.
*/
+#include <asm/types.h>
+
#ifndef __XTENSA_XTAVNET_HARDWARE_H
#define __XTENSA_XTAVNET_HARDWARE_H
/* Memory configuration. */
-#define PLATFORM_DEFAULT_MEM_START CONFIG_DEFAULT_MEM_START
-#define PLATFORM_DEFAULT_MEM_SIZE CONFIG_DEFAULT_MEM_SIZE
+#define PLATFORM_DEFAULT_MEM_START __XTENSA_UL(CONFIG_DEFAULT_MEM_START)
+#define PLATFORM_DEFAULT_MEM_SIZE __XTENSA_UL(CONFIG_DEFAULT_MEM_SIZE)
/* Interrupt configuration. */
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
index b4cf70e..e9f65f7 100644
--- a/arch/xtensa/platforms/xtfpga/setup.c
+++ b/arch/xtensa/platforms/xtfpga/setup.c
@@ -63,7 +63,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t"
#endif
+#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t"
+#endif
"movi a2, 0x1f\n\t"
"wsr a2, ps\n\t"
"isync\n\t"
diff --git a/arch/xtensa/variants/de212/include/variant/core.h b/arch/xtensa/variants/de212/include/variant/core.h
new file mode 100644
index 0000000..59e91e4
--- /dev/null
+++ b/arch/xtensa/variants/de212/include/variant/core.h
@@ -0,0 +1,594 @@
+/*
+ * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa
+ * processor CORE configuration
+ *
+ * See <xtensa/config/core.h>, which includes this file, for more details.
+ */
+
+/* Xtensa processor core configuration information.
+
+ Copyright (c) 1999-2015 Tensilica Inc.
+
+ 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. */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+ Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ * configured, and a value of 0 otherwise. These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+ ISA
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
+#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG 1 /* debug option */
+#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
+#define XCHAL_LOOP_BUFFER_SIZE 0 /* zero-ov. loop instr buffer size */
+#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */
+#define XCHAL_HAVE_DEPBITS 0 /* DEPBITS instruction */
+#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32 1 /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R 1 /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS 0 /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
+#define XCHAL_HAVE_ABS 1 /* ABS instruction */
+/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
+/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION 0 /* speculation */
+#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS 1 /* */
+#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID 1 /* processor ID register */
+#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */
+#define XCHAL_HAVE_MX 0 /* MX core (Tensilica internal) */
+#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */
+#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */
+#define XCHAL_HAVE_PSO 0 /* Power Shut-Off */
+#define XCHAL_HAVE_PSO_CDM 0 /* core/debug/mem pwr domains */
+#define XCHAL_HAVE_PSO_FULL_RETENTION 0 /* all regs preserved on PSO */
+#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */
+#define XCHAL_HAVE_CP 0 /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG 0 /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16 1 /* MAC16 package */
+
+#define XCHAL_HAVE_FUSION 0 /* Fusion*/
+#define XCHAL_HAVE_FUSION_FP 0 /* Fusion FP option */
+#define XCHAL_HAVE_FUSION_LOW_POWER 0 /* Fusion Low Power option */
+#define XCHAL_HAVE_FUSION_AES 0 /* Fusion BLE/Wifi AES-128 CCM option */
+#define XCHAL_HAVE_FUSION_CONVENC 0 /* Fusion Conv Encode option */
+#define XCHAL_HAVE_FUSION_LFSR_CRC 0 /* Fusion LFSR-CRC option */
+#define XCHAL_HAVE_FUSION_BITOPS 0 /* Fusion Bit Operations Support option */
+#define XCHAL_HAVE_FUSION_AVS 0 /* Fusion AVS option */
+#define XCHAL_HAVE_FUSION_16BIT_BASEBAND 0 /* Fusion 16-bit Baseband option */
+#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */
+#define XCHAL_HAVE_HIFI4 0 /* HiFi4 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI4_VFPU 0 /* HiFi4 Audio Engine VFPU option */
+#define XCHAL_HAVE_HIFI3 0 /* HiFi3 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI3_VFPU 0 /* HiFi3 Audio Engine VFPU option */
+#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */
+#define XCHAL_HAVE_HIFI_MINI 0
+
+
+#define XCHAL_HAVE_VECTORFPU2005 0 /* vector or user floating-point pkg */
+#define XCHAL_HAVE_USER_DPFPU 0 /* user DP floating-point pkg */
+#define XCHAL_HAVE_USER_SPFPU 0 /* user DP floating-point pkg */
+#define XCHAL_HAVE_FP 0 /* single prec floating point */
+#define XCHAL_HAVE_FP_DIV 0 /* FP with DIV instructions */
+#define XCHAL_HAVE_FP_RECIP 0 /* FP with RECIP instructions */
+#define XCHAL_HAVE_FP_SQRT 0 /* FP with SQRT instructions */
+#define XCHAL_HAVE_FP_RSQRT 0 /* FP with RSQRT instructions */
+#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */
+#define XCHAL_HAVE_DFP_DIV 0 /* DFP with DIV instructions */
+#define XCHAL_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/
+#define XCHAL_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */
+#define XCHAL_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/
+#define XCHAL_HAVE_DFP_ACCEL 0 /* double precision FP acceleration pkg */
+#define XCHAL_HAVE_DFP_accel XCHAL_HAVE_DFP_ACCEL /* for backward compatibility */
+
+#define XCHAL_HAVE_DFPU_SINGLE_ONLY 0 /* DFPU Coprocessor, single precision only */
+#define XCHAL_HAVE_DFPU_SINGLE_DOUBLE 0 /* DFPU Coprocessor, single and double precision */
+#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
+#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
+#define XCHAL_HAVE_PDX4 0 /* PDX4 */
+#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */
+#define XCHAL_HAVE_CONNXD2_DUALLSFLIX 0 /* ConnX D2 & Dual LoadStore Flix */
+#define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */
+#define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */
+#define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */
+#define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */
+#define XCHAL_HAVE_BBENEP 0 /* ConnX BBENEP pkgs */
+#define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */
+#define XCHAL_HAVE_BSP3_TRANSPOSE 0 /* BSP3 & transpose32x32 */
+#define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */
+#define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */
+#define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */
+#define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */
+#define XCHAL_HAVE_FLIX3 0 /* basic 3-way FLIX option */
+#define XCHAL_HAVE_GRIVPEP 0 /* GRIVPEP is General Release of IVPEP */
+#define XCHAL_HAVE_GRIVPEP_HISTOGRAM 0 /* Histogram option on GRIVPEP */
+
+
+/*----------------------------------------------------------------------
+ MISC
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_LOADSTORE_UNITS 1 /* load/store units */
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH 4 /* data width in bytes */
+#define XCHAL_DATA_PIPE_DELAY 1 /* d-side pipeline delay
+ (1 = 5-stage, 2 = 7-stage) */
+#define XCHAL_CLOCK_GATING_GLOBAL 0 /* global clock gating */
+#define XCHAL_CLOCK_GATING_FUNCUNIT 0 /* funct. unit clock gating */
+/* In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
+#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */
+#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/
+
+#define XCHAL_SW_VERSION 1100002 /* sw version of this header */
+
+#define XCHAL_CORE_ID "de212" /* alphanum core name
+ (CoreID) set in the Xtensa
+ Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID 0x0005A985 /* 22-bit sw build ID */
+
+/*
+ * These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0 0xC283DFFE /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1 0x1C85A985 /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME "LX6.0.2" /* full version name */
+#define XCHAL_HW_VERSION_MAJOR 2600 /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR 2 /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION 260002 /* major*100+minor */
+#define XCHAL_HW_REL_LX6 1
+#define XCHAL_HW_REL_LX6_0 1
+#define XCHAL_HW_REL_LX6_0_2 1
+#define XCHAL_HW_CONFIGID_RELIABLE 1
+/* If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR 2600 /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR 2 /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION 260002 /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR 2600 /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR 2 /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION 260002 /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE 8192 /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE 8192 /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */
+#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */
+
+#define XCHAL_HAVE_PREFETCH 0 /* PREFCTL register */
+#define XCHAL_HAVE_PREFETCH_L1 0 /* prefetch to L1 dcache */
+#define XCHAL_PREFETCH_CASTOUT_LINES 0 /* dcache pref. castout bufsz */
+#define XCHAL_PREFETCH_ENTRIES 0 /* cache prefetch entries */
+#define XCHAL_PREFETCH_BLOCK_ENTRIES 0 /* prefetch block streams */
+#define XCHAL_HAVE_CACHE_BLOCKOPS 0 /* block prefetch for caches */
+#define XCHAL_HAVE_ICACHE_TEST 1 /* Icache test instructions */
+#define XCHAL_HAVE_DCACHE_TEST 1 /* Dcache test instructions */
+#define XCHAL_HAVE_ICACHE_DYN_WAYS 0 /* Icache dynamic way support */
+#define XCHAL_HAVE_DCACHE_DYN_WAYS 0 /* Dcache dynamic way support */
+
+
+
+
+/****************************************************************************
+ Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
+
+/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
+
+/* Number of cache sets in log2(lines per way): */
+#define XCHAL_ICACHE_SETWIDTH 7
+#define XCHAL_DCACHE_SETWIDTH 7
+
+/* Cache set associativity (number of ways): */
+#define XCHAL_ICACHE_WAYS 2
+#define XCHAL_DCACHE_WAYS 2
+
+/* Cache features: */
+#define XCHAL_ICACHE_LINE_LOCKABLE 1
+#define XCHAL_DCACHE_LINE_LOCKABLE 1
+#define XCHAL_ICACHE_ECC_PARITY 0
+#define XCHAL_DCACHE_ECC_PARITY 0
+
+/* Cache access size in bytes (affects operation of SICW instruction): */
+#define XCHAL_ICACHE_ACCESS_SIZE 4
+#define XCHAL_DCACHE_ACCESS_SIZE 4
+
+#define XCHAL_DCACHE_BANKS 1 /* number of banks */
+
+/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
+#define XCHAL_CA_BITS 4
+
+/* Whether MEMCTL register has anything useful */
+#define XCHAL_USE_MEMCTL (((XCHAL_LOOP_BUFFER_SIZE > 0) || \
+ XCHAL_DCACHE_IS_COHERENT || \
+ XCHAL_HAVE_ICACHE_DYN_WAYS || \
+ XCHAL_HAVE_DCACHE_DYN_WAYS) && \
+ (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0))
+
+
+/*----------------------------------------------------------------------
+ INTERNAL I/D RAM/ROMs and XLMI
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM 1 /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */
+#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */
+
+/* Instruction RAM 0: */
+#define XCHAL_INSTRAM0_VADDR 0x40000000 /* virtual address */
+#define XCHAL_INSTRAM0_PADDR 0x40000000 /* physical address */
+#define XCHAL_INSTRAM0_SIZE 131072 /* size in bytes */
+#define XCHAL_INSTRAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */
+
+/* Data RAM 0: */
+#define XCHAL_DATARAM0_VADDR 0x3FFE0000 /* virtual address */
+#define XCHAL_DATARAM0_PADDR 0x3FFE0000 /* physical address */
+#define XCHAL_DATARAM0_SIZE 131072 /* size in bytes */
+#define XCHAL_DATARAM0_ECC_PARITY 0 /* ECC/parity type, 0=none */
+#define XCHAL_DATARAM0_BANKS 1 /* number of banks */
+
+/* XLMI Port 0: */
+#define XCHAL_XLMI0_VADDR 0x3FFC0000 /* virtual address */
+#define XCHAL_XLMI0_PADDR 0x3FFC0000 /* physical address */
+#define XCHAL_XLMI0_SIZE 131072 /* size in bytes */
+#define XCHAL_XLMI0_ECC_PARITY 0 /* ECC/parity type, 0=none */
+
+#define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/
+
+
+/*----------------------------------------------------------------------
+ INTERRUPTS and TIMERS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS 17 /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels
+ (not including level zero) */
+#define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */
+ /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/* Masks of interrupts at each interrupt level: */
+#define XCHAL_INTLEVEL1_MASK 0x001F80FF
+#define XCHAL_INTLEVEL2_MASK 0x00000100
+#define XCHAL_INTLEVEL3_MASK 0x00200E00
+#define XCHAL_INTLEVEL4_MASK 0x00001000
+#define XCHAL_INTLEVEL5_MASK 0x00002000
+#define XCHAL_INTLEVEL6_MASK 0x00000000
+#define XCHAL_INTLEVEL7_MASK 0x00004000
+
+/* Masks of interrupts at each range 1..n of interrupt levels: */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F80FF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F81FF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F8FFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF
+
+/* Level of each interrupt: */
+#define XCHAL_INT0_LEVEL 1
+#define XCHAL_INT1_LEVEL 1
+#define XCHAL_INT2_LEVEL 1
+#define XCHAL_INT3_LEVEL 1
+#define XCHAL_INT4_LEVEL 1
+#define XCHAL_INT5_LEVEL 1
+#define XCHAL_INT6_LEVEL 1
+#define XCHAL_INT7_LEVEL 1
+#define XCHAL_INT8_LEVEL 2
+#define XCHAL_INT9_LEVEL 3
+#define XCHAL_INT10_LEVEL 3
+#define XCHAL_INT11_LEVEL 3
+#define XCHAL_INT12_LEVEL 4
+#define XCHAL_INT13_LEVEL 5
+#define XCHAL_INT14_LEVEL 7
+#define XCHAL_INT15_LEVEL 1
+#define XCHAL_INT16_LEVEL 1
+#define XCHAL_INT17_LEVEL 1
+#define XCHAL_INT18_LEVEL 1
+#define XCHAL_INT19_LEVEL 1
+#define XCHAL_INT20_LEVEL 1
+#define XCHAL_INT21_LEVEL 3
+#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */
+#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with
+ EXCSAVE/EPS/EPC_n, RFI n) */
+
+/* Type of each interrupt: */
+#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI
+#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE
+
+/* Masks of interrupts for each type of interrupt: */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000
+#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F
+#define XCHAL_INTTYPE_MASK_TIMER 0x00002440
+#define XCHAL_INTTYPE_MASK_NMI 0x00004000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
+#define XCHAL_INTTYPE_MASK_PROFILING 0x00000000
+
+/* Interrupt numbers assigned to specific interrupt sources: */
+#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */
+
+/* Interrupt numbers for levels at which only one interrupt is configured: */
+#define XCHAL_INTLEVEL2_NUM 8
+#define XCHAL_INTLEVEL4_NUM 12
+#define XCHAL_INTLEVEL5_NUM 13
+#define XCHAL_INTLEVEL7_NUM 14
+/* (There are many interrupts each at level(s) 1, 3.) */
+
+
+/*
+ * External interrupt mapping.
+ * These macros describe how Xtensa processor interrupt numbers
+ * (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ * map to external BInterrupt<n> pins, for those interrupts
+ * configured as external (level-triggered, edge-triggered, or NMI).
+ * See the Xtensa processor databook for more details.
+ */
+
+/* Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number: */
+#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */
+#define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */
+#define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */
+#define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */
+#define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM 16 /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM 17 /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM 18 /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM 19 /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM 20 /* (intlevel 1) */
+#define XCHAL_EXTINT16_NUM 21 /* (intlevel 3) */
+/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */
+#define XCHAL_INT0_EXTNUM 0 /* (intlevel 1) */
+#define XCHAL_INT1_EXTNUM 1 /* (intlevel 1) */
+#define XCHAL_INT2_EXTNUM 2 /* (intlevel 1) */
+#define XCHAL_INT3_EXTNUM 3 /* (intlevel 1) */
+#define XCHAL_INT4_EXTNUM 4 /* (intlevel 1) */
+#define XCHAL_INT5_EXTNUM 5 /* (intlevel 1) */
+#define XCHAL_INT8_EXTNUM 6 /* (intlevel 2) */
+#define XCHAL_INT9_EXTNUM 7 /* (intlevel 3) */
+#define XCHAL_INT12_EXTNUM 8 /* (intlevel 4) */
+#define XCHAL_INT14_EXTNUM 9 /* (intlevel 7) */
+#define XCHAL_INT15_EXTNUM 10 /* (intlevel 1) */
+#define XCHAL_INT16_EXTNUM 11 /* (intlevel 1) */
+#define XCHAL_INT17_EXTNUM 12 /* (intlevel 1) */
+#define XCHAL_INT18_EXTNUM 13 /* (intlevel 1) */
+#define XCHAL_INT19_EXTNUM 14 /* (intlevel 1) */
+#define XCHAL_INT20_EXTNUM 15 /* (intlevel 1) */
+#define XCHAL_INT21_EXTNUM 16 /* (intlevel 3) */
+
+
+/*----------------------------------------------------------------------
+ EXCEPTIONS and VECTORS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
+ number: 1 == XEA1 (old)
+ 2 == XEA2 (new)
+ 0 == XEAX (extern) or TX */
+#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
+#define XCHAL_HAVE_HALT 0 /* halt architecture option */
+#define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */
+#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */
+#define XCHAL_VECBASE_RESET_VADDR 0x60000000 /* VECBASE reset value */
+#define XCHAL_VECBASE_RESET_PADDR 0x60000000
+#define XCHAL_RESET_VECBASE_OVERLAP 0
+
+#define XCHAL_RESET_VECTOR0_VADDR 0x50000000
+#define XCHAL_RESET_VECTOR0_PADDR 0x50000000
+#define XCHAL_RESET_VECTOR1_VADDR 0x40000400
+#define XCHAL_RESET_VECTOR1_PADDR 0x40000400
+#define XCHAL_RESET_VECTOR_VADDR 0x50000000
+#define XCHAL_RESET_VECTOR_PADDR 0x50000000
+#define XCHAL_USER_VECOFS 0x00000340
+#define XCHAL_USER_VECTOR_VADDR 0x60000340
+#define XCHAL_USER_VECTOR_PADDR 0x60000340
+#define XCHAL_KERNEL_VECOFS 0x00000300
+#define XCHAL_KERNEL_VECTOR_VADDR 0x60000300
+#define XCHAL_KERNEL_VECTOR_PADDR 0x60000300
+#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x600003C0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x600003C0
+#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR 0x60000000
+#define XCHAL_WINDOW_VECTORS_PADDR 0x60000000
+#define XCHAL_INTLEVEL2_VECOFS 0x00000180
+#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x60000180
+#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x60000180
+#define XCHAL_INTLEVEL3_VECOFS 0x000001C0
+#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x600001C0
+#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x600001C0
+#define XCHAL_INTLEVEL4_VECOFS 0x00000200
+#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x60000200
+#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x60000200
+#define XCHAL_INTLEVEL5_VECOFS 0x00000240
+#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x60000240
+#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x60000240
+#define XCHAL_INTLEVEL6_VECOFS 0x00000280
+#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x60000280
+#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x60000280
+#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS 0x000002C0
+#define XCHAL_NMI_VECTOR_VADDR 0x600002C0
+#define XCHAL_NMI_VECTOR_PADDR 0x600002C0
+#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+ DEBUG MODULE
+ ----------------------------------------------------------------------*/
+
+/* Misc */
+#define XCHAL_HAVE_DEBUG_ERI 1 /* ERI to debug module */
+#define XCHAL_HAVE_DEBUG_APB 0 /* APB to debug module */
+#define XCHAL_HAVE_DEBUG_JTAG 1 /* JTAG to debug module */
+
+/* On-Chip Debug (OCD) */
+#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option (to LX4) */
+#define XCHAL_HAVE_OCD_LS32DDR 1 /* L32DDR/S32DDR (faster OCD) */
+
+/* TRAX (in core) */
+#define XCHAL_HAVE_TRAX 1 /* TRAX in debug module */
+#define XCHAL_TRAX_MEM_SIZE 262144 /* TRAX memory size in bytes */
+#define XCHAL_TRAX_MEM_SHAREABLE 0 /* start/end regs; ready sig. */
+#define XCHAL_TRAX_ATB_WIDTH 0 /* ATB width (bits), 0=no ATB */
+#define XCHAL_TRAX_TIME_WIDTH 0 /* timestamp bitwidth, 0=none */
+
+/* Perf counters */
+#define XCHAL_NUM_PERF_COUNTERS 0 /* performance counters */
+
+
+/*----------------------------------------------------------------------
+ MMU
+ ----------------------------------------------------------------------*/
+
+/* See core-matmap.h header file for more details. */
+
+#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */
+#define XCHAL_SPANNING_WAY 0 /* TLB spanning way number */
+#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table
+ [autorefill] and protection)
+ usable for an MMU-based OS */
+/* If none of the above last 4 are set, it's a custom TLB configuration. */
+
+#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/arch/xtensa/variants/de212/include/variant/tie-asm.h b/arch/xtensa/variants/de212/include/variant/tie-asm.h
new file mode 100644
index 0000000..7775535
--- /dev/null
+++ b/arch/xtensa/variants/de212/include/variant/tie-asm.h
@@ -0,0 +1,170 @@
+/*
+ * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE
+ *
+ * NOTE: This header file is not meant to be included directly.
+ */
+
+/* This header file contains assembly-language definitions (assembly
+ macros, etc.) for this specific Xtensa processor's TIE extensions
+ and options. It is customized to this Xtensa processor configuration.
+
+ Copyright (c) 1999-2015 Cadence Design Systems Inc.
+
+ 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. */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/* Selection parameter values for save-area save/restore macros: */
+/* Option vs. TIE: */
+#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
+#define XTHAL_SAS_ANYOT 0x0003 /* both of the above */
+/* Whether used automatically by compiler: */
+#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
+#define XTHAL_SAS_ANYCC 0x000C /* both of the above */
+/* ABI handling across function calls: */
+#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
+#define XTHAL_SAS_ANYABI 0x0070 /* all of the above three */
+/* Misc */
+#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
+#define XTHAL_SAS3(optie,ccuse,abi) ( ((optie) & XTHAL_SAS_ANYOT) \
+ | ((ccuse) & XTHAL_SAS_ANYCC) \
+ | ((abi) & XTHAL_SAS_ANYABI) )
+
+
+ /*
+ * Macro to store all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Required parameters:
+ * ptr Save area pointer address register (clobbered)
+ * (register must contain a 4 byte aligned address).
+ * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS
+ * registers are clobbered, the remaining are unused).
+ * Optional parameters:
+ * continue If macro invoked as part of a larger store sequence, set to 1
+ * if this is not the first in the sequence. Defaults to 0.
+ * ofs Offset from start of larger sequence (from value of first ptr
+ * in sequence) at which to store. Defaults to next available space
+ * (or 0 if <continue> is 0).
+ * select Select what category(ies) of registers to store, as a bitmask
+ * (see XTHAL_SAS_xxx constants). Defaults to all registers.
+ * alloc Select what category(ies) of registers to allocate; if any
+ * category is selected here that is not in <select>, space for
+ * the corresponding registers is skipped without doing any store.
+ */
+ .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+ xchal_sa_start \continue, \ofs
+ // Optional caller-saved registers used by default by the compiler:
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select)
+ xchal_sa_align \ptr, 0, 1016, 4, 4
+ rsr.ACCLO \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+0
+ rsr.ACCHI \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+4
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 8
+ .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+ xchal_sa_align \ptr, 0, 1016, 4, 4
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 8
+ .endif
+ // Optional caller-saved registers not used by default by the compiler:
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+ xchal_sa_align \ptr, 0, 1004, 4, 4
+ rsr.SCOMPARE1 \at1 // conditional store option
+ s32i \at1, \ptr, .Lxchal_ofs_+0
+ rsr.M0 \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+4
+ rsr.M1 \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+8
+ rsr.M2 \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+12
+ rsr.M3 \at1 // MAC16 option
+ s32i \at1, \ptr, .Lxchal_ofs_+16
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 20
+ .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+ xchal_sa_align \ptr, 0, 1004, 4, 4
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 20
+ .endif
+ .endm // xchal_ncp_store
+
+ /*
+ * Macro to load all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Required parameters:
+ * ptr Save area pointer address register (clobbered)
+ * (register must contain a 4 byte aligned address).
+ * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS
+ * registers are clobbered, the remaining are unused).
+ * Optional parameters:
+ * continue If macro invoked as part of a larger load sequence, set to 1
+ * if this is not the first in the sequence. Defaults to 0.
+ * ofs Offset from start of larger sequence (from value of first ptr
+ * in sequence) at which to load. Defaults to next available space
+ * (or 0 if <continue> is 0).
+ * select Select what category(ies) of registers to load, as a bitmask
+ * (see XTHAL_SAS_xxx constants). Defaults to all registers.
+ * alloc Select what category(ies) of registers to allocate; if any
+ * category is selected here that is not in <select>, space for
+ * the corresponding registers is skipped without doing any load.
+ */
+ .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+ xchal_sa_start \continue, \ofs
+ // Optional caller-saved registers used by default by the compiler:
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select)
+ xchal_sa_align \ptr, 0, 1016, 4, 4
+ l32i \at1, \ptr, .Lxchal_ofs_+0
+ wsr.ACCLO \at1 // MAC16 option
+ l32i \at1, \ptr, .Lxchal_ofs_+4
+ wsr.ACCHI \at1 // MAC16 option
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 8
+ .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+ xchal_sa_align \ptr, 0, 1016, 4, 4
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 8
+ .endif
+ // Optional caller-saved registers not used by default by the compiler:
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+ xchal_sa_align \ptr, 0, 1004, 4, 4
+ l32i \at1, \ptr, .Lxchal_ofs_+0
+ wsr.SCOMPARE1 \at1 // conditional store option
+ l32i \at1, \ptr, .Lxchal_ofs_+4
+ wsr.M0 \at1 // MAC16 option
+ l32i \at1, \ptr, .Lxchal_ofs_+8
+ wsr.M1 \at1 // MAC16 option
+ l32i \at1, \ptr, .Lxchal_ofs_+12
+ wsr.M2 \at1 // MAC16 option
+ l32i \at1, \ptr, .Lxchal_ofs_+16
+ wsr.M3 \at1 // MAC16 option
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 20
+ .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+ xchal_sa_align \ptr, 0, 1004, 4, 4
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 20
+ .endif
+ .endm // xchal_ncp_load
+
+
+#define XCHAL_NCP_NUM_ATMPS 1
+
+#define XCHAL_SA_NUM_ATMPS 1
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/arch/xtensa/variants/de212/include/variant/tie.h b/arch/xtensa/variants/de212/include/variant/tie.h
new file mode 100644
index 0000000..b8a061a
--- /dev/null
+++ b/arch/xtensa/variants/de212/include/variant/tie.h
@@ -0,0 +1,136 @@
+/*
+ * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration
+ *
+ * NOTE: This header file is not meant to be included directly.
+ */
+
+/* This header file describes this specific Xtensa processor's TIE extensions
+ that extend basic Xtensa core functionality. It is customized to this
+ Xtensa processor configuration.
+
+ Copyright (c) 1999-2015 Cadence Design Systems Inc.
+
+ 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. */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM 0 /* number of coprocessors */
+#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
+
+/* Save area for non-coprocessor optional and custom (TIE) state: */
+#define XCHAL_NCP_SA_SIZE 28
+#define XCHAL_NCP_SA_ALIGN 4
+
+/* Total save area for optional and custom state (NCP + CPn): */
+#define XCHAL_TOTAL_SA_SIZE 32 /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN 4 /* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE: caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ * dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ * s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ * ccused = set if used by compiler without special options or code
+ * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ * name = lowercase reg name (no quotes)
+ * galign = group byte alignment (power of 2) (galign >= align)
+ * align = register byte alignment (power of 2)
+ * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ * (not including any pad bytes required to galign this or next reg)
+ * dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ * base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ * regnum = reg index in regfile, or special/TIE-user reg number
+ * bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ * gapsz = intervening bits, if bitsz bits not stored contiguously
+ * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ * reset = register reset value (or 0 if undefined at reset)
+ * x = reserved for future use (0 until then)
+ *
+ * To filter out certain registers, e.g. to expand only the non-global
+ * registers used by the compiler, you can do something like this:
+ *
+ * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p)
+ * #define SELCC0(p...)
+ * #define SELCC1(abikind,p...) SELAK##abikind(p)
+ * #define SELAK0(p...) REG(p)
+ * #define SELAK1(p...) REG(p)
+ * #define SELAK2(p...)
+ * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ * ...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM 7
+#define XCHAL_NCP_SA_LIST(s) \
+ XCHAL_SA_REG(s,1,0,0,1, acclo, 4, 4, 4,0x0210, sr,16 , 32,0,0,0) \
+ XCHAL_SA_REG(s,1,0,0,1, acchi, 4, 4, 4,0x0211, sr,17 , 8,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1, m0, 4, 4, 4,0x0220, sr,32 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1, m1, 4, 4, 4,0x0221, sr,33 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1, m2, 4, 4, 4,0x0222, sr,34 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1, m3, 4, 4, 4,0x0223, sr,35 , 32,0,0,0)
+
+#define XCHAL_CP0_SA_NUM 0
+#define XCHAL_CP0_SA_LIST(s) /* empty */
+
+#define XCHAL_CP1_SA_NUM 0
+#define XCHAL_CP1_SA_LIST(s) /* empty */
+
+#define XCHAL_CP2_SA_NUM 0
+#define XCHAL_CP2_SA_LIST(s) /* empty */
+
+#define XCHAL_CP3_SA_NUM 0
+#define XCHAL_CP3_SA_LIST(s) /* empty */
+
+#define XCHAL_CP4_SA_NUM 0
+#define XCHAL_CP4_SA_LIST(s) /* empty */
+
+#define XCHAL_CP5_SA_NUM 0
+#define XCHAL_CP5_SA_LIST(s) /* empty */
+
+#define XCHAL_CP6_SA_NUM 0
+#define XCHAL_CP6_SA_LIST(s) /* empty */
+
+#define XCHAL_CP7_SA_NUM 0
+#define XCHAL_CP7_SA_LIST(s) /* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
+#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
+/* Byte length of instruction from its first byte, per FLIX. */
+#define XCHAL_BYTE0_FORMAT_LENGTHS \
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,\
+ 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
OpenPOWER on IntegriCloud